DEV Community

Cover image for Cracker Jokes as a Service with Python
Meredydd Luff
Meredydd Luff

Posted on

Cracker Jokes as a Service with Python

Christmas crackers from the local supermarket often have the worst jokes. We say, 'there must be a better way'. Save up your favourite jokes this Christmas and hear the sound of guffaws 🤣 , not the silence of cringing faces 😬 .

It's database-backed, it's on the Web, it's in Python...and we didn't have to write a line of Javascript -- yep, we used Anvil:

The sample data is the most interesting part, really

Canvas Component

The anvil Canvas component gives us access to the browser's drawing APIs, along with easy mouse events -- so that seemed like the perfect way to build this app:

def draw_background(self):
    img = URLMedia('_/theme/cracker.png')
    c = self.canvas
    m = self.margin
    c.draw_image(img, m, 0, c.get_width() - 2*m, c.get_height())

def canvas_mouse_up(self, x, y, button, **event_args):
    """This method is called when a mouse button is pressed on this component"""
    if (x < self.margin):
        self.idx = (self.idx - 1) % len(self.jokes)
    elif x > self.w - self.margin:
        self.idx = (self.idx + 1) % len(self.jokes)
Enter fullscreen mode Exit fullscreen mode

Batteries Included

Anvil's Python in the browser comes with Python's batteries included philosophy, from your favourite python libraries to f-strings.

import itertools
import textwrap
import random

class TellJokes(TellJokesTemplate):

    def __init__(self, **properties):

        self.jokes = list(
        self.idx = 0
        self.QorA = itertools.cycle('QA') # switch between Q and A
        self.margin = 80
        self.laughing = '🤣😂😹😆🙈'
        self.text = 'Click To Start Telling Jokes 🎅'

    def write_joke(self, text=None):
        if text is None:
            QorA = next(self.QorA)
            text = f"{QorA}. {self.jokes[self.idx][QorA]}"
            if QorA is 'A':
                text += ' ' + random.choice(self.laughing) # add a random laugh emoji

        # wrap lines for readability
        wrapped_text = textwrap.wrap(text, int(self.canvas.get_width() - 2*self.margin)/35)))
Enter fullscreen mode Exit fullscreen mode

Share the laughter

I used the Anvil Data Tables service to create a database, then built a UI with a DataGrid component. Now I can send the app to the family -- let's hope they come up with some better jokes than I did 🙄 .

View the source code

Want to play with the app yourself? Check out the source code:

Open source code >>

Top comments (0)