Day 15 of the Anvil Advent Calendar

Build a web app every day until Christmas, with nothing but 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 😬 .

Canvas Component

The anvil Canvas component, with a background image and mouse events, 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)
    self.write_joke()

Batteries Included

Anvil’s client-side python 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.init_components(**properties)

        self.jokes = list(app_tables.crackers.search())
        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)))
        ...

Share the laughter

Once the Anvil Data Tables service was added, I created 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:


Give the Gift of Python

Share this post: