Candidate: Paul Honey Assessed by: Nicholas Tollervey
Python (2023) ~ Grade 1 (Initial)
You're having a laugh!
I would like to design a joke generator, aimed at children, which will tell a joke based on a topic and/or some inputs of the users' choosing.
Attached files
Filename (click to download) | Size | Uploaded by |
---|
Code_grab_1.PNG | 24.9 KB | honeyp |
Markdown code
![Code_grab_1.PNG](/media/assessment/7362c701/2022-12-03/07-09-52/Code_grab_1.PNG "Code_grab_1.PNG")
Code_grab_1.PNG | 24.9 KB | honeyp |
Markdown code
![Code_grab_1.PNG](/media/assessment/7362c701/2022-12-03/07-10-06/Code_grab_1.PNG "Code_grab_1.PNG")
Code_grab_2.PNG | 56.1 KB | honeyp |
Markdown code
![Code_grab_2.PNG](/media/assessment/7362c701/2022-12-03/08-15-45/Code_grab_2.PNG "Code_grab_2.PNG")
Aliens_and_squares.py | 1.1 KB | honeyp |
Markdown code
```Python
from pygame.transform import flip
alien = Actor('alien', topleft=(20, 30)) # Load alien sprites
alien2 = Actor('alien', topright=(880, 30))
alien3 = Actor('alien', bottomleft=(20, 570))
alien4 = Actor('alien', bottomright=(880, 570))
WIDTH = 900 # Window size
HEIGHT = 600
# RED = 200, 0, 0 # Rectangle colour
# BOX = Rect((450, 60), (50, 100)) # Recangle position and size
XY = (100, 100)
def draw():
screen.fill((3, 70, 26)) # Set window background colour
#screen.draw.rect(BOX, RED) # Draws rectangle
screen.draw.filled_rect(Rect((450, 60), (XY)), 'gold') # Draws rectangle with position size and colour
screen.draw.filled_rect(Rect((250, 150), (XY)), 'cyan')
alien.draw() # Draws alien sprite
screen.blit(flip(alien2._surf, True, False), alien2.topleft)
alien3.draw()
screen.blit(flip(alien4._surf, True, False), alien4.topleft)
```
Alien_and_box.py | 267 bytes | honeyp |
Markdown code
```Python
alien = Actor("alien", topleft=(20, 30))
WIDTH = 900
HEIGHT = 600
RED = 200, 0, 0
BOX = Rect((450, 60), (50, 100))
def draw():
screen.fill((3, 70, 26))
screen.draw.rect(BOX, RED)
alien.draw()
def update():
#alien.angle = 45
alien.angle -= 9
```
Code_grab_3.PNG | 9.1 KB | honeyp |
Markdown code
![Code_grab_3.PNG](/media/assessment/7362c701/2022-12-04/21-21-45/Code_grab_3.PNG "Code_grab_3.PNG")
laugh1.wav | 2.3 MB | honeyp |
Markdown code
[laugh1.wav](/media/assessment/7362c701/2022-12-07/19-00-57/laugh1.wav){target="_blank"}
hahaha.png | 19.8 KB | honeyp |
Markdown code
![hahaha.png](/media/assessment/7362c701/2022-12-07/19-01-38/hahaha.png "hahaha.png")
button_animals.png | 6.7 KB | honeyp |
Markdown code
![button_animals.png](/media/assessment/7362c701/2022-12-07/19-01-39/button_animals.png "button_animals.png")
button_food.png | 5.3 KB | honeyp |
Markdown code
![button_food.png](/media/assessment/7362c701/2022-12-07/19-01-39/button_food.png "button_food.png")
button_reset.png | 3.8 KB | honeyp |
Markdown code
![button_reset.png](/media/assessment/7362c701/2022-12-07/19-01-39/button_reset.png "button_reset.png")
button_silly.png | 5.3 KB | honeyp |
Markdown code
![button_silly.png](/media/assessment/7362c701/2022-12-07/19-01-39/button_silly.png "button_silly.png")
button_school.png | 6.1 KB | honeyp |
Markdown code
![button_school.png](/media/assessment/7362c701/2022-12-07/19-01-39/button_school.png "button_school.png")
Code_grades_emails.eml | 1.3 KB | honeyp |
Markdown code
[Code_grades_emails.eml](/media/assessment/7362c701/2022-12-10/19-38-03/Code_grades_emails.eml){target="_blank"}
bean.png | 116.4 KB | honeyp |
Markdown code
![bean.png](/media/assessment/7362c701/2023-01-03/05-10-28/bean.png "bean.png")
stage.png | 210.6 KB | honeyp |
Markdown code
![stage.png](/media/assessment/7362c701/2023-01-03/05-10-28/stage.png "stage.png")
micstand.png | 4.4 KB | honeyp |
Markdown code
![micstand.png](/media/assessment/7362c701/2023-01-03/05-10-28/micstand.png "micstand.png")
lol.png | 135.1 KB | honeyp |
Markdown code
![lol.png](/media/assessment/7362c701/2023-01-03/05-10-28/lol.png "lol.png")
neon_mic.png | 30.8 KB | honeyp |
Markdown code
![neon_mic.png](/media/assessment/7362c701/2023-01-03/05-10-28/neon_mic.png "neon_mic.png")
rofl.png | 15.0 KB | honeyp |
Markdown code
![rofl.png](/media/assessment/7362c701/2023-01-03/05-10-28/rofl.png "rofl.png")
laugh2.wav | 194.0 KB | honeyp |
Markdown code
[laugh2.wav](/media/assessment/7362c701/2023-01-03/05-11-09/laugh2.wav){target="_blank"}
drum.wav | 674.4 KB | honeyp |
Markdown code
[drum.wav](/media/assessment/7362c701/2023-01-03/05-11-09/drum.wav){target="_blank"}
slow_clap.wav | 2.9 MB | honeyp |
Markdown code
[slow_clap.wav](/media/assessment/7362c701/2023-01-03/05-11-10/slow_clap.wav){target="_blank"}
Paul_Honey_Grade_1_-_Joke_Generator.py | 4.4 KB | honeyp |
Markdown code
```Python
"""
The "You're Having a Laugh" Joke Generator
"""
import random
WIDTH = 900 # Window size
HEIGHT = 600
joke = False
"""
Section 1 - Backgrounds, popups and sounds
"""
stage = Actor("stage", midtop=(450, 0)) # Background images
neon_mic = Actor("neon_mic", topleft=(0, 195))
mic = Actor("micstand", center=(430, 375))
comedy = Actor("comedy", center=(450, 70))
laugh_emoji = Actor("laugh_emoji", midright=(880, 280))
laugh_emoji.angle = -30
background_images = [stage, comedy, neon_mic, mic, laugh_emoji]
raspberry = Actor("raspberry", topright=(485, 125)) # Randomly generated images
haha = Actor("haha", center=(400,300))
bean = Actor("bean", bottomright=(900, 600))
lol = Actor("lol", center=(375, 300))
rofl = Actor("rofl", center=(430, 400))
funny_image = [raspberry, haha, bean, lol, rofl]
audience_laugh = sounds.laugh1 # Randomly generated sounds
girl_laugh = sounds.laugh2
badum_tish = sounds.drum
slow_clap = sounds.slow_clap
funny_sound = [audience_laugh, girl_laugh, badum_tish, slow_clap]
"""
Section 2 - Joke Lists
Add your own!
"""
animal_jokes = [
[
"How do you tell the difference between a bull and a cow?",
"It is either one or the udder!"
],
[
"Why do hummingbirds hum?",
"Because they don't know the words!"
],
[
"What kind of dog does a magician have?",
"A Labracadabrador!"
],
[
"What do frogs order at fast-food restaurants",
"French flies!"
],
]
food_jokes = [
[
"Which vegetable do sailors hate the most?",
"Leeks!"
],
[
"What do you call a cheese that's not yours?",
"Nacho cheese!"
],
[
"What kind of key opens a banana?",
"A mon-key!"
],
[
"Why do bees have sticky hair?",
"Because they use honeycombs!"
],
]
silly_jokes = [
[
"If you're English in the kitchen and English in the living room,\
\n\nwhat are you in the bathroom?",
"European!"
],
[
"What are mummies favourite lunches?",
"Wraps!"
],
[
"What gives you the power to walk through a wall?",
"A door!"
],
[
"What happens when you wear a snow suit inside?",
"It melts all over the carpet."
],
]
school_jokes = [
[
"Why did the music teacher need a ladder?",
"To reach the high notes."
],
[
"What do elves learn in school?",
"The elf-abet!"
],
[
"Why did the nose not want to go to school?",
"He was tired of getting picked on!"
],
[
"Why did the student eat his homework?",
"Because his teacher told him it would be a piece of cake!"
],
]
"""
Section 3 - Buttons list
Can you think of your own categories?
"""
top_left_button = Actor("button_animals", topleft=(100, 150))
top_right_button = Actor("button_food", topright=(800, 150))
bottom_left_button = Actor("button_silly", bottomleft=(100, 450))
bottom_right_button = Actor("button_school", bottomright=(800, 450))
reset_button = Actor("button_reset", midbottom=(450, 575))
buttons = [top_left_button, top_right_button, bottom_left_button, bottom_right_button]
"""
Section 4 - The code which tells your jokes
"""
def draw():
[backgrounds.draw() for backgrounds in background_images]
[joke_categories.draw() for joke_categories in buttons]
if joke:
"""
After joke category is selected,
display random joke and images,
play random sound.
"""
draw_image = random.choice(funny_image)
draw_image.draw()
screen.draw.text(
"\n\n".join(random.choice(joke)),
center=(450, 300),
fontname="rabbit_on_the_moon",
fontsize=36,
color="darkorange1",
owidth=1.5,
ocolor="black"
)
play_sound = random.choice(funny_sound)
play_sound.play()
reset_button.draw()
def on_mouse_down(pos, button):
"""
click a button to select a joke category
"""
global joke
if button == mouse.LEFT and buttons[0].collidepoint(pos):
joke = animal_jokes
elif button == mouse.LEFT and buttons[1].collidepoint(pos):
joke = food_jokes
elif button == mouse.LEFT and buttons[2].collidepoint(pos):
joke = silly_jokes
elif button == mouse.LEFT and buttons[3].collidepoint(pos):
joke = school_jokes
elif button == mouse.LEFT and reset_button.collidepoint(pos):
joke = ""
```
Rabbit_on_the_Moon_Font.zip | 597.8 KB | honeyp |
Markdown code
[Rabbit_on_the_Moon_Font.zip](/media/assessment/7362c701/2023-01-09/08-36-41/Rabbit_on_the_Moon_Font.zip){target="_blank"}
Joke_Generator_Images.zip | 773.2 KB | honeyp |
Markdown code
[Joke_Generator_Images.zip](/media/assessment/7362c701/2023-01-09/08-36-57/Joke_Generator_Images.zip){target="_blank"}
Joke_Generator_Sounds.zip | 5.2 MB | honeyp |
Markdown code
[Joke_Generator_Sounds.zip](/media/assessment/7362c701/2023-01-09/08-37-18/Joke_Generator_Sounds.zip){target="_blank"}
Joke_Generator_User_Guide.docx | 9.0 MB | honeyp |
Markdown code
[Joke_Generator_User_Guide.docx](/media/assessment/7362c701/2023-01-09/08-37-33/Joke_Generator_User_Guide.docx){target="_blank"}
Joke_Generator_User_Guide.pdf | 4.5 MB | honeyp |
Markdown code
[Joke_Generator_User_Guide.pdf](/media/assessment/7362c701/2023-01-09/08-37-35/Joke_Generator_User_Guide.pdf){target="_blank"}
Email_to_children_1.PNG | 90.6 KB | honeyp |
Markdown code
![Email_to_children_1.PNG](/media/assessment/7362c701/2023-01-09/08-44-37/Email_to_children_1.PNG "Email_to_children_1.PNG")
Email_to_children_2.PNG | 95.6 KB | honeyp |
Markdown code
![Email_to_children_2.PNG](/media/assessment/7362c701/2023-01-09/08-44-42/Email_to_children_2.PNG "Email_to_children_2.PNG")
Paul_Honey_Grade_1_-_Joke_Generator.py | 4.4 KB | honeyp |
Markdown code
```Python
"""
The "You're Having a Laugh" Joke Generator
"""
import random
WIDTH = 900 # Window size
HEIGHT = 600
joke = False
"""
Section 1 - Joke Lists
Add your own!
"""
animal_jokes = [
[
"How do you tell the difference between a bull and a cow?",
"It is either one or the udder!"
],
[
"Why do hummingbirds hum?",
"Because they don't know the words!"
],
[
"What kind of dog does a magician have?",
"A Labracadabrador!"
],
[
"What do frogs order at fast-food restaurants",
"French flies!"
],
]
food_jokes = [
[
"Which vegetable do sailors hate the most?",
"Leeks!"
],
[
"What do you call a cheese that's not yours?",
"Nacho cheese!"
],
[
"What kind of key opens a banana?",
"A mon-key!"
],
[
"Why do bees have sticky hair?",
"Because they use honeycombs!"
],
]
silly_jokes = [
[
"If you're English in the kitchen and English in the living room,\
\n\nwhat are you in the bathroom?",
"European!"
],
[
"What are mummies favourite lunches?",
"Wraps!"
],
[
"What gives you the power to walk through a wall?",
"A door!"
],
[
"What happens when you wear a snow suit inside?",
"It melts all over the carpet."
],
]
school_jokes = [
[
"Why did the music teacher need a ladder?",
"To reach the high notes."
],
[
"What do elves learn in school?",
"The elf-abet!"
],
[
"Why did the nose not want to go to school?",
"He was tired of getting picked on!"
],
[
"Why did the student eat his homework?",
"Because his teacher told him it would be a piece of cake!"
],
]
"""
Section 2 - Buttons list
Can you think of your own categories?
"""
top_left_button = Actor("button_animals", topleft=(100, 150))
top_right_button = Actor("button_food", topright=(800, 150))
bottom_left_button = Actor("button_silly", bottomleft=(100, 450))
bottom_right_button = Actor("button_school", bottomright=(800, 450))
reset_button = Actor("button_reset", midbottom=(450, 575))
buttons = [top_left_button, top_right_button, bottom_left_button, bottom_right_button]
"""
Section 3 - Backgrounds, popups and sounds
"""
stage = Actor("stage", midtop=(450, 0)) # Background images
neon_mic = Actor("neon_mic", topleft=(0, 195))
mic = Actor("micstand", center=(430, 375))
comedy = Actor("comedy", center=(450, 70))
laugh_emoji = Actor("laugh_emoji", midright=(880, 280))
laugh_emoji.angle = -30
background_images = [stage, comedy, neon_mic, mic, laugh_emoji]
raspberry = Actor("raspberry", topright=(485, 125)) # Randomly generated images
haha = Actor("haha", center=(400,300))
bean = Actor("bean", bottomright=(900, 600))
lol = Actor("lol", center=(375, 300))
rofl = Actor("rofl", center=(430, 400))
funny_image = [raspberry, haha, bean, lol, rofl]
audience_laugh = sounds.laugh1 # Randomly generated sounds
girl_laugh = sounds.laugh2
badum_tish = sounds.drum
slow_clap = sounds.slow_clap
funny_sound = [audience_laugh, girl_laugh, badum_tish, slow_clap]
"""
Section 4 - The code which tells your jokes
"""
def draw():
[backgrounds.draw() for backgrounds in background_images]
[joke_categories.draw() for joke_categories in buttons]
if joke:
"""
After joke category is selected,
display random joke and images,
play random sound.
"""
draw_image = random.choice(funny_image)
draw_image.draw()
screen.draw.text(
"\n\n".join(random.choice(joke)),
center=(450, 300),
fontname="rabbit_on_the_moon",
fontsize=36,
color="darkorange1",
owidth=1.5,
ocolor="black"
)
play_sound = random.choice(funny_sound)
play_sound.play()
reset_button.draw()
def on_mouse_down(pos, button):
"""
click a button to select a joke category
"""
global joke
if button == mouse.LEFT and buttons[0].collidepoint(pos):
joke = animal_jokes
elif button == mouse.LEFT and buttons[1].collidepoint(pos):
joke = food_jokes
elif button == mouse.LEFT and buttons[2].collidepoint(pos):
joke = silly_jokes
elif button == mouse.LEFT and buttons[3].collidepoint(pos):
joke = school_jokes
elif button == mouse.LEFT and reset_button.collidepoint(pos):
joke = ""
```
Joke_Generator_User_Guide.pdf | 4.5 MB | honeyp |
Markdown code
[Joke_Generator_User_Guide.pdf](/media/assessment/7362c701/2023-01-09/23-06-42/Joke_Generator_User_Guide.pdf){target="_blank"}
Joke_Generator_User_Guide.docx | 9.0 MB | honeyp |
Markdown code
[Joke_Generator_User_Guide.docx](/media/assessment/7362c701/2023-01-09/23-06-42/Joke_Generator_User_Guide.docx){target="_blank"}
Status: Closed (results delivered). 96/100 ~ Pass with DISTINCTION (22/01/2023).
Paul Honey ~ 02 Dec 2022 9 p.m. (updated: 02 Dec 2022 9:01 p.m.)
Getting started
My ten year old son is very quick witted, constantly coming up with new jokes and one liners and wanting to write them down. I'd like to produce a simple joke generator, one which he can contribute to and get some fun from, that will output a joke based on certain inputs.
I have spoken to my son, who thinks it is a good idea, and asked him to think of some jokes while I am away with work. I plan to aim the program at his age group of 9/10/11 year olds.
My initial idea is to maybe have one or more drop down menus where the user picks a category of joke and then perhaps some other descriptors. Once selected they hit a generate button and a joke is selected based on the selected inputs.
Because I want an interactive program I have initially decided to utilise Pygame Zero for my project
Paul Honey ~ 03 Dec 2022 10:09 a.m. (updated: 03 Dec 2022 10:12 a.m.)
Experimenting
Simple picture and shape placement
Because the program is aimed at children, I'd like to include some fun images/shapes, relevant to the theme, and engaging background colours. At first I have just been playing around with image placement, animation, playing with size and shape of rectangles and colouring the shapes and backgrounds.
Code
alien = Actor('alien', topleft=(20, 30)) #Load alien sprite
WIDTH = 900 # Set window size
HEIGHT = 600
RED = 200, 0, 0 # Set rectangle colour
BOX = Rect((450, 60), (50, 100)) # Set rectangle position and size
def draw():
screen.fill((3, 70, 26)) # Background colour
screen.draw.rect(BOX, RED) # Draw rectangle
alien.draw() # Draw alien
Alien and a Box
I don't plan on using the alien sprite in my final program, I am just using it for convenience at the minute as I familiarise myself with placing and manipulating images.
Playing around
I thought it might be fun to have images spinning in the background so I also added the following to the end of the code:
def update():
alien.angle -= 9 # Updates the position of the alien, in this case spins clockwise at a set speed
Creating an image filled background
I also played around with adding multiple of the same images, changing positions and trying to flip the image at different positions:
Code
from pygame.transform import flip
alien = Actor('alien', topleft=(20, 30)) # Load alien sprites
alien2 = Actor('alien', topright=(880, 30))
alien3 = Actor('alien', bottomleft=(20, 570))
alien4 = Actor('alien', bottomright=(880, 570))
WIDTH = 900 # Window size
HEIGHT = 600
# RED = 200, 0, 0 # Rectangle colour
# BOX = Rect((450, 60), (50, 100)) # Recangle position and size
def draw():
screen.fill((3, 70, 26)) # Set window background colour
#screen.draw.rect(BOX, RED) # Draws rectangle
screen.draw.filled_rect(Rect((450, 60), (100, 100)), 'gold') # Draw squares with position size and colour
screen.draw.filled_rect(Rect((250, 150), (100, 100)), 'cyan')
alien.draw() # Draws alien sprites
screen.blit(flip(alien2._surf, True, False), alien2.topleft) # Mirrors/flips the alien image
alien3.draw()
screen.blit(flip(alien4._surf, True, False), alien4.topleft)
Aliens and Squares
I found a list of callable colours, for the filled squares, from the following link:
https://robocoast.tech/wp-content/uploads/2021/05/PyGame-Zero-Introduction-Booklet.pdf
I had played with just rotating the aliens through a set number of degrees using the following:
def update():
alien.angle = 45
I tried doing something similar with the squares I'd drawn, however a solution for this was overly complex
Coding justification
I struggled with trying to mirror/flip the alien image. There were a few differing, and sometimes complicated, methods for how to achieve the outcome shown in the above Aliens and Squares image. I went for an adaptation of the solution I found at the following link, presented by user dryabov:
https://github.com/lordmauve/pgzero/issues/3
As I think I understand it, when and image is drawn, it is assigned to a surface. The first line of the code imports the surface flipping (horizontally or vertically) functionality from pygame.transform. Pygame.transform offers functionality for resizing and repositioning surface pixels.
The code screen.blit(flip(alien2._surf, True, False), alien2.topleft)
uses the blit command to draw the image alien2 and flips it about the y axis using the topleft point of the image as the reference point.
Reflection so far
I am slightly unhappy with how some of this code is written I feel there must be a more efficient way of calling the alien image, manipulating and positioning it differently without having to assign it multiple times. I also wonder if there is a simpler solution for flipping images about the x or y axis.
Paul Honey ~ 03 Dec 2022 12:31 p.m.
from pygame.transform import flip
alien = Actor('alien', topleft=(20, 30)) # Load alien sprites
alien2 = Actor('alien', topright=(880, 30))
alien3 = Actor('alien', bottomleft=(20, 570))
alien4 = Actor('alien', bottomright=(880, 570))
WIDTH = 900 # Window size
HEIGHT = 600
# RED = 200, 0, 0 # Rectangle colour
# BOX = Rect((450, 60), (50, 100)) # Recangle position and size
XY = (100, 100)
def draw():
screen.fill((3, 70, 26)) # Set window background colour
#screen.draw.rect(BOX, RED) # Draws rectangle
screen.draw.filled_rect(Rect((450, 60), (XY)), 'gold') # Draws rectangle with position size and colour
screen.draw.filled_rect(Rect((250, 150), (XY)), 'cyan')
alien.draw() # Draws alien sprite
screen.blit(flip(alien2._surf, True, False), alien2.topleft)
alien3.draw()
screen.blit(flip(alien4._surf, True, False), alien4.topleft)
alien = Actor("alien", topleft=(20, 30))
WIDTH = 900
HEIGHT = 600
RED = 200, 0, 0
BOX = Rect((450, 60), (50, 100))
def draw():
screen.fill((3, 70, 26))
screen.draw.rect(BOX, RED)
alien.draw()
def update():
#alien.angle = 45
alien.angle -= 9
Paul Honey ~ 04 Dec 2022 10:03 p.m. (updated: 05 Dec 2022 11:22 a.m.)
Texting
Struggling to write on screen
Today I have been mostly failing to get text to display on screen when I click a mouse button. I was finding I could get the text to display with no issues if I added it directly into my def draw():
function, but as soon as I added my mouse click function and tried again, the text would not display.
Code
from pygame.transform import flip
alien = Actor("alien", topleft=(20, 30)) # Load alien sprites
alien2 = Actor("alien", topright=(880, 30))
alien3 = Actor("alien", bottomleft=(20, 570))
alien4 = Actor("alien", bottomright=(880, 570))
WIDTH = 900 # Window size
HEIGHT = 600
# RED = 200, 0, 0 # Rectangle colour
# BOX = Rect((450, 60), (50, 100)) # Recangle position and size
XY = (100, 100)
def draw():
screen.fill((3, 70, 26)) # Set window background colour
#screen.draw.rect(BOX, RED) # Draws rectangle
screen.draw.filled_rect(Rect((450, 60), (XY)), "gold") # Draws rectangle with position size and colour
screen.draw.filled_rect(Rect((250, 150), (XY)), "cyan")
alien.draw() # Draws alien sprite
screen.blit(flip(alien2._surf, True, False), alien2.topleft) # Flip and reposition alien sprite
alien3.draw()
screen.blit(flip(alien4._surf, True, False), alien4.topleft)
#if on_mouse_down(pos):
def on_mouse_down(pos):
screen.draw.text("hello", (300, 300))
I reasoned that the draw function is always being updated and rewritten, thus the green background is constantly being drawn over my text. Hence, when I comment out the background fill, the text is visible, as nothing else being drawn which will obscure it.
Trying something else
The rest of the day's coding was spent trying a lot of different ideas, often in desperation, all ending up with pretty much the same results. I'm just going to post some of the code configurations below, with some explanatory headings/sentences, and hopefully it'll convey my thought process.
Using on_mouse_down to call another function
from pygame.transform import flip
alien = Actor("alien", topleft=(20, 30)) # Load alien sprites
alien2 = Actor("alien", topright=(880, 30))
alien3 = Actor("alien", bottomleft=(20, 570))
alien4 = Actor("alien", bottomright=(880, 570))
WIDTH = 900 # Window size
HEIGHT = 600
# RED = 200, 0, 0 # Rectangle colour
# BOX = Rect((450, 60), (50, 100)) # Recangle position and size
XY = (100, 100)
def draw():
screen.fill((3, 70, 26)) # Set window background colour
#screen.draw.rect(BOX, RED) # Draws rectangle
screen.draw.filled_rect(Rect((450, 60), (XY)), "gold") # Draws rectangle with position size and colour
screen.draw.filled_rect(Rect((250, 150), (XY)), "cyan")
alien.draw() # Draws alien sprite
screen.blit(flip(alien2._surf, True, False), alien2.topleft) # Flip and reposition alien sprite
alien3.draw()
screen.blit(flip(alien4._surf, True, False), alien4.topleft)
def on_mouse_down(pos):
set_joke_display()
def set_joke_display():
screen.draw.text("hello", (XY))
Again, commenting out screen.fill will display the text. Also played around with just using XY for both shape size and text position.
Maybe font rendering will work...
from pygame.transform import flip
import pygame
pygame.font.init
alien = Actor("alien", topleft=(20, 30)) # Load alien sprites
alien2 = Actor("alien", topright=(880, 30))
alien3 = Actor("alien", bottomleft=(20, 570))
alien4 = Actor("alien", bottomright=(880, 570))
BLUE = (0, 0, 200)
font = pygame.font.SysFont(None, 24)
joke = font.render('hello', True, BLUE)
WIDTH = 900 # Window size
HEIGHT = 600
# RED = 200, 0, 0 # Rectangle colour
# BOX = Rect((450, 60), (50, 100)) # Recangle position and size
XY = (100, 100)
def draw():
screen.fill((3, 70, 26)) # Set window background colour
#screen.draw.rect(BOX, RED) # Draws rectangle
screen.draw.filled_rect(Rect((450, 60), (XY)), "gold") # Draws rectangle with position size and colour
screen.draw.filled_rect(Rect((250, 150), (XY)), "cyan")
alien.draw() # Draws alien sprite
screen.blit(flip(alien2._surf, True, False), alien2.topleft) # Flip and reposition alien sprite
alien3.draw()
screen.blit(flip(alien4._surf, True, False), alien4.topleft)
def on_mouse_down(pos):
screen.blit(joke, (300, 300))
#def set_joke_display():
After scouring Google for assistance I cam across the following:
https://pygame.readthedocs.io/en/latest/4_text/text.html#:~:text=Pygame%20does%20not%20provide%20a%20direct%20way%20to,method%20render%20%28%29%20can%20only%20render%20single%20lines.
Here, and on one or two other sites I visited, it was mentioned that:
"Pygame does not provide a direct way to write text onto a Surface object. The method render() must be used to create a Surface object from the text, which then can be blit to the screen."
This made me think of when I'd used blit for drawing my flipped alien image surfaces in my earlier code and so I was hopeful it might yield a better result... I was left disappointed.
if only
from pygame.transform import flip
import pygame
pygame.font.init
alien = Actor("alien", topleft=(20, 30)) # Load alien sprites
alien2 = Actor("alien", topright=(880, 30))
alien3 = Actor("alien", bottomleft=(20, 570))
alien4 = Actor("alien", bottomright=(880, 570))
BLUE = (0, 0, 200)
font = pygame.font.SysFont(None, 24)
joke = font.render('hello', True, BLUE)
WIDTH = 900 # Window size
HEIGHT = 600
# RED = 200, 0, 0 # Rectangle colour
# BOX = Rect((450, 60), (50, 100)) # Recangle position and size
XY = (100, 100)
def draw():
screen.fill((3, 70, 26)) # Set window background colour
#screen.draw.rect(BOX, RED) # Draws rectangle
screen.draw.filled_rect(Rect((450, 60), (XY)), "gold") # Draws rectangle with position size and colour
screen.draw.filled_rect(Rect((250, 150), (XY)), "cyan")
alien.draw() # Draws alien sprite
screen.blit(flip(alien2._surf, True, False), alien2.topleft) # Flip and reposition alien sprite
alien3.draw()
screen.blit(flip(alien4._surf, True, False), alien4.topleft)
if joke():
screen.blit(joke, (300, 300))
def on_mouse_down():
joke = True
#def on_mouse_down(pos):
#def set_joke_display():
Unfortunately this produced the following error:
I tried many variations with if statements throughout both my mouse-click draw and render attempts, including if joke = True,
and if on_mouse_down(pos):
, but was ultimately left scratching my head and crying into my coffee(s).
Seeking help
At this point I had to admit defeat and emailed my mentor asking for some guidance. He introduced me to the concept of using flags and also using the global variable combined with an if statement. I will be including the email chain as part of my evidence but below is the code I have produced from the feedback:
Working Text Display
from pygame.transform import flip
alien = Actor("alien", topleft=(20, 30)) # Load alien sprites
alien2 = Actor("alien", topright=(880, 30))
alien3 = Actor("alien", bottomleft=(20, 570))
alien4 = Actor("alien", bottomright=(880, 570))
WIDTH = 900 # Window size
HEIGHT = 600
# RED = 200, 0, 0 # Rectangle colour
# BOX = Rect((450, 60), (50, 100)) # Recangle position and size
XY = (100, 100)
TELL_JOKE = False # Flag the output (Joke) as being not true
def draw():
screen.fill((3, 70, 26)) # Set window background colour
#screen.draw.rect(BOX, RED) # Draws rectangle
screen.draw.filled_rect(Rect((450, 60), (XY)), "gold") # Draws rectangle with position size and colour
screen.draw.filled_rect(Rect((250, 150), (XY)), "cyan")
alien.draw() # Draws alien sprite
screen.blit(flip(alien2._surf, True, False), alien2.topleft) # Flip and reposition alien sprite
alien3.draw()
screen.blit(flip(alien4._surf, True, False), alien4.topleft)
if TELL_JOKE: # Once the Joke state has changed to true in on_mouse_down
screen.draw.text("hello", (300, 300)) # Display the joke on screen
def on_mouse_down(): # When the mouse is clicked
global TELL_JOKE # Make the operations happening to the Joke globally available
TELL_JOKE = True # And changes the state of the joke from false to true
At the moment this isn't particularly representative of my final project, but once I'm comfortable with the the functionality of the different elements I wish to achieve, I will start to piece it all together with those final elements.
Paul Honey ~ 07 Dec 2022 7:37 p.m. (updated: 11 Dec 2022 7:19 a.m.)
Starting to Take Shape
Making Lists and Checking them Twice
Based on what I've learned so far with regards to image/text placement/manipulation, flags, if statements and mouse clicks, I was able to create several lists of jokes, each assigned to a category and get them to print to screen based on a pushbutton associated with that category of joke. I now have something which more closely resembles my idea of a working joke generator and was able to put the elements together relatively quickly from the groundwork I'd already laid.
Code
"""
The "You're Having a Laugh" joke generator
"""
from pygame.transform import flip
import random
laugh = Actor("haha", topleft=(50, 30)) # Load images/buttons and set their positions
animal_button = Actor("button_animals", topleft=(100, 100))
food_button = Actor("button_food", topright=(800, 100))
silly_button = Actor("button_silly", bottomleft=(100, 500))
school_button = Actor("button_school", bottomright=(800, 500))
WIDTH = 900 # Window size
HEIGHT = 600
print_joke = (450, 300) # Joke screen position
AUDIENCE_LAUGH = sounds.laugh1 # Load laughter
#List of animal jokes
ANIMAL_JOKES = ["How do you tell the difference \
between a bull and a cow? \n\nIt is either one or \
the udder!", "Why do hummingbirds hum? \n\nBecause \
they don’t know the words!", "What kind of dog does \
a magician have? \n\nA Labracadabrador!", "What do \
frogs order at fast-food restaurants? \n\nFrench \
flies!"]
#KNOCK_KNOCK_JOKES = ["Knock, knock.\nWho’s there? \
#Dozen. \nDozen who? \nDozen anyone want to let me in?"]
#List of food jokes
FOOD_JOKES = ["Which vegetable do sailors hate the \
\n\nLeeks!", "What do you call a cheese that’s not \
yours? \n\nNacho cheese!", "What kind of key opens \
a banana? \n\nA mon-key!", "Why do bees have sticky \
haie? \n\nBecause they use honeycombs!"]
#List of silly jokes
SILLY_JOKES = ["If you’re English in the kitchen \
and English in the living room, what are you in the \
bathroom? \n\nEuropean!", "What are mummies \
favourite lunches? \n\nWraps!", "What gives you the \
power to walk through a wall? \n\nA door!", "What \
happens when you wear a snow suit inside? \n\nIt \
melts all over the carpet."]
#List of school jokes
SCHOOL_JOKES = ["Why did the music teacher need a \
ladder? \n\nTo reach the high notes.", "What do \
elves learn in school? \n\nThe elf-abet!", "Why did \
the nose not want to go to school? \n\nHe was tired \
of getting picked on!", "Why did the student eat \
his homework? \n\nBecause his teacher told him it \
would be a piece of cake!"]
rect1 = (100, 100) # Background shape sizes
rect2 = (65, 125)
rect3 = (35, 30)
ANIMAL_JOKE = False # Setting flags
FOOD_JOKE = False
SILLY_JOKE = False
SCHOOL_JOKE = False
def draw():
screen.fill((3, 70, 26)) # Set window background colour
screen.draw.filled_rect(Rect((50, 60), rect1), "gold") # Draw rectangles
screen.draw.filled_rect(Rect((40, 75), rect2), "cyan")
screen.draw.filled_rect(Rect((95, 145), rect3), "red")
screen.draw.filled_rect(Rect((50, 440), rect1), "gold")
screen.draw.filled_rect(Rect((40, 400), rect2), "cyan")
screen.draw.filled_rect(Rect((95, 425), rect3), "red")
#screen.blit(flip(alien2._surf, True, False), alien2.topleft)
animal_button.draw() # Draw pushbuttons
food_button.draw()
silly_button.draw()
school_button.draw()
if ANIMAL_JOKE: # Once the Animal Joke flag has changed to true in on_mouse_down
laugh.draw() # Display the joke and laugh image on screen, play laughter
screen.draw.text(random.choice(ANIMAL_JOKES), center=(print_joke))
AUDIENCE_LAUGH.play()
elif FOOD_JOKE: # As per Animal flag
laugh.draw()
screen.draw.text(random.choice(FOOD_JOKES), center=(print_joke))
AUDIENCE_LAUGH.play()
elif SILLY_JOKE: # As above
laugh.draw()
screen.draw.text(random.choice(SILLY_JOKES), center=(print_joke))
AUDIENCE_LAUGH.play()
elif SCHOOL_JOKE: # As above
laugh.draw()
screen.draw.text(random.choice(SCHOOL_JOKES), center=(print_joke))
AUDIENCE_LAUGH.play()
def on_mouse_down(pos, button): # When the left mouse button is clicked on the animal button
if button == mouse.LEFT and animal_button.collidepoint(pos):
global ANIMAL_JOKE # Make the operations happening to the Joke flag available globally
ANIMAL_JOKE = True # Set the animal joke flag to true
elif button == mouse.LEFT and food_button.collidepoint(pos): # Sets the Food joke flag to true
global FOOD_JOKE
FOOD_JOKE = True
elif button == mouse.LEFT and silly_button.collidepoint(pos): # Sets the silly joke flag to true
global SILLY_JOKE
SILLY_JOKE = True
elif button == mouse.LEFT and school_button.collidepoint(pos): # Sets the school joke glag to true
global SCHOOL_JOKE
SCHOOL_JOKE = True
Laughter wav file obtained from the following source:
Laughter image obtained from the following site:
I created the free-use pushbuttons at the following site:
Click Minded - Button Generator
Additional Learning
The main, new topics I had to research to get to this stage were:
- The Random Module
- elif
- Spreading code over several lines with \
- Formatting my displayed text with \n
- I'd also looked at how to select individual items in a list, for printing, drawing etc. with
list[item's position in list]
With the last bullet point, if I wanted to select, for example, the second joke in my FOOD_JOKES list to print every time I hit the food button, I would change
screen.draw.text(random.choice(FOOD_JOKES), center=(print_joke))
to
screen.draw.text(FOOD_JOKES[1], center=(print_joke))
Further work
- I would like to add a reset button, which pops up upon displaying the joke, so that the user can select a new input without having to close/re-open.
- I would like to run this past my son and get him to select/provide his own jokes for the categories and give me ideas for some of the aesthetics, other images to add to be engaging, as it's his age group it is aimed at.
- I will probably fiddle around with the layout, likely increasing the window size so things don't feel too cramped by the time I add in additional comedic background images
Paul Honey ~ 07 Dec 2022 9:04 p.m. (updated: 08 Dec 2022 1:10 p.m.)
Tidying up my Code
So, I've just had a bit of a eureka moment with making my code a bit neater. My background as an instrumentation and controls engineer involves having to look after equipment which is controlled by PLCs. The people who program said PLCs often call entire function blocks as subroutines within other function blocks. I knew, due to the amount of repetition in my code, that I must be able to do something similar, but was a bit unsure how to do this whilst still individually addressing the unique parts of the code within those repeated lines.
I achieved this by making a global value, (JOKE) within my on_mouse_down routine. This is then assigned to a Joke category based on which button is pressed and passed to my new category_selection routine. This routine contains all the info on drawing items and playing the laughter once a particular pushbutton is pressed, with the global JOKE value taking the place of the individual joke category lists. This saves having my code repeat the same three lines at each if elif statement in my draw routine.
I also realised I could make the JOKE value and all the flags global at the very start of the on_mouse_down routine, instead of having to repeat the global assignment at the start of the mouse click if/elif routines.
Code
"""
The "You're Having a Laugh" joke generator
"""
from pygame.transform import flip
import random
laugh = Actor("haha", topleft=(50, 30)) # Load images/buttons and set their positions
animal_button = Actor("button_animals", topleft=(100, 85))
food_button = Actor("button_food", topright=(800, 85))
silly_button = Actor("button_silly", bottomleft=(100, 515))
school_button = Actor("button_school", bottomright=(800, 515))
reset_button = Actor("button_reset", midbottom=(450, 575))
WIDTH = 900 # Window size
HEIGHT = 600
print_joke = (450, 300) # Joke screen position
AUDIENCE_LAUGH = sounds.laugh1 # Load laughter
#List of animal jokes
ANIMAL_JOKES = ["How do you tell the difference \
between a bull and a cow? \n\nIt is either one or \
the udder!", "Why do hummingbirds hum? \n\nBecause \
they don’t know the words!", "What kind of dog does \
a magician have? \n\nA Labracadabrador!", "What do \
frogs order at fast-food restaurants? \n\nFrench \
flies!"]
#KNOCK_KNOCK_JOKES = ["Knock, knock.\nWho’s there? \
#Dozen. \nDozen who? \nDozen anyone want to let me in?"]
#List of food jokes
FOOD_JOKES = ["Which vegetable do sailors hate the \
\n\nLeeks!", "What do you call a cheese that’s not \
yours? \n\nNacho cheese!", "What kind of key opens \
a banana? \n\nA mon-key!", "Why do bees have sticky \
hair? \n\nBecause they use honeycombs!"]
#List of silly jokes
SILLY_JOKES = ["If you’re English in the kitchen \
and English in the living room, what are you in the \
bathroom? \n\nEuropean!", "What are mummies \
favourite lunches? \n\nWraps!", "What gives you the \
power to walk through a wall? \n\nA door!", "What \
happens when you wear a snow suit inside? \n\nIt \
melts all over the carpet."]
#List of school jokes
SCHOOL_JOKES = ["Why did the music teacher need a \
ladder? \n\nTo reach the high notes.", "What do \
elves learn in school? \n\nThe elf-abet!", "Why did \
the nose not want to go to school? \n\nHe was tired \
of getting picked on!", "Why did the student eat \
his homework? \n\nBecause his teacher told him it \
would be a piece of cake!"]
rect1 = (100, 100) # Background shape sizes
rect2 = (65, 125)
rect3 = (35, 30)
ANIMAL_JOKE = False # Setting flags
FOOD_JOKE = False
SILLY_JOKE = False
SCHOOL_JOKE = False
def draw():
screen.fill((3, 70, 26)) # Set window background colour
screen.draw.filled_rect(Rect((50, 60), rect1), "gold") # Draw rectangles
screen.draw.filled_rect(Rect((40, 75), rect2), "cyan")
screen.draw.filled_rect(Rect((95, 145), rect3), "red")
screen.draw.filled_rect(Rect((50, 440), rect1), "gold")
screen.draw.filled_rect(Rect((40, 400), rect2), "cyan")
screen.draw.filled_rect(Rect((95, 425), rect3), "red")
screen.draw.filled_rect(Rect((750, 60), rect1), "gold")
screen.draw.filled_rect(Rect((795, 75), rect2), "cyan")
screen.draw.filled_rect(Rect((770, 145), rect3), "red")
screen.draw.filled_rect(Rect((750, 440), rect1), "gold")
screen.draw.filled_rect(Rect((795, 400), rect2), "cyan")
screen.draw.filled_rect(Rect((770, 425), rect3), "red")
#screen.blit(flip(alien2._surf, True, False), alien2.topleft)
animal_button.draw() # Draw pushbuttons
food_button.draw()
silly_button.draw()
school_button.draw()
if ANIMAL_JOKE: # Once the Animal Joke flag has changed to true in on_mouse_down
category_selection() # Display the joke and laugh image on screen, play laughter
elif FOOD_JOKE: # As per Animal flag
category_selection()
elif SILLY_JOKE: # As above
category_selection()
elif SCHOOL_JOKE: # As above
category_selection()
reset_button.draw()
def on_mouse_down(pos, button):
global JOKE, SILLY_JOKE, ANIMAL_JOKE, FOOD_JOKE, SCHOOL_JOKE # When the left mouse button is clicked on the animal button
if button == mouse.LEFT and animal_button.collidepoint(pos):
ANIMAL_JOKE = True
JOKE = ANIMAL_JOKES # Set the animal joke flag to true
elif button == mouse.LEFT and food_button.collidepoint(pos): # Sets the Food joke flag to true
FOOD_JOKE = True
JOKE = FOOD_JOKES
elif button == mouse.LEFT and silly_button.collidepoint(pos): # Sets the silly joke flag to true
SILLY_JOKE = True
JOKE = SILLY_JOKES
elif button == mouse.LEFT and school_button.collidepoint(pos): # Sets the school joke glag to true
SCHOOL_JOKE = True
JOKE = SCHOOL_JOKES
def category_selection():
laugh.draw()
screen.draw.text(random.choice(JOKE), center=(print_joke))
AUDIENCE_LAUGH.play()
Paul Honey ~ 10 Dec 2022 7:33 p.m. (updated: 10 Dec 2022 7:52 p.m.)
First Submission
More struggles
I have been looking at ways to try and get my reset button to start the program over but I have been coming up blank. One method I played around with is below. I separated my draw function branching off a separate function which contained just the joke category flag manipulations. I added a function at the start which just calls the draw function, I then also added a restart function at the end which I tried, using flags to loop back around to the starting function in order to reset the entire thing. Obviously this didn't work.
Code
WIDTH = 900
HEIGHT = 600
"""
The "You're Having a Laugh" joke generator
"""
#from pygame.transform import flip
import random
laugh = Actor("haha", topleft=(50, 30)) # Load images/buttons and set their positions
animal_button = Actor("button_animals", topleft=(100, 85))
food_button = Actor("button_food", topright=(800, 85))
silly_button = Actor("button_silly", bottomleft=(100, 515))
school_button = Actor("button_school", bottomright=(800, 515))
reset_button = Actor("button_reset", midbottom=(450, 575))
WIDTH = 900 # Window size
HEIGHT = 600
print_joke = (450, 300) # Joke screen position
audience_laugh = sounds.laugh1
#transparent = (0, 0, 0, 0)# Load laughter
#List of animal jokes
animal_jokes = ["How do you tell the difference \
between a bull and a cow? \n\nIt is either one or \
the udder!", "Why do hummingbirds hum? \n\nBecause \
they don’t know the words!", "What kind of dog does \
a magician have? \n\nA Labracadabrador!", "What do \
frogs order at fast-food restaurants? \n\nFrench \
flies!"]
#KNOCK_KNOCK_JOKES = ["Knock, knock.\nWho’s there? \
#Dozen. \nDozen who? \nDozen anyone want to let me in?"]
#List of food jokes
food_jokes = ["Which vegetable do sailors hate the \
\n\nLeeks!", "What do you call a cheese that’s not \
yours? \n\nNacho cheese!", "What kind of key opens \
a banana? \n\nA mon-key!", "Why do bees have sticky \
hair? \n\nBecause they use honeycombs!"]
#List of silly jokes
silly_jokes = ["If you’re English in the kitchen \
and English in the living room, what are you in the \
bathroom? \n\nEuropean!", "What are mummies \
favourite lunches? \n\nWraps!", "What gives you the \
power to walk through a wall? \n\nA door!", "What \
happens when you wear a snow suit inside? \n\nIt \
melts all over the carpet."]
#List of school jokes
school_jokes = ["Why did the music teacher need a \
ladder? \n\nTo reach the high notes.", "What do \
elves learn in school? \n\nThe elf-abet!", "Why did \
the nose not want to go to school? \n\nHe was tired \
of getting picked on!", "Why did the student eat \
his homework? \n\nBecause his teacher told him it \
would be a piece of cake!"]
rect1 = (100, 100) # Background shape sizes
rect2 = (65, 125)
rect3 = (35, 30)
animal_joke = False # Setting flags
food_joke = False
silly_joke = False
school_joke = False
start = True
def tell_a_joke():
start = False
draw()
def draw():
screen.fill((3, 70, 26)) # Set window background colour
screen.draw.filled_rect(Rect((50, 60), rect1), "gold") # Draw rectangles
screen.draw.filled_rect(Rect((40, 75), rect2), "cyan")
screen.draw.filled_rect(Rect((95, 145), rect3), "red")
screen.draw.filled_rect(Rect((50, 440), rect1), "gold")
screen.draw.filled_rect(Rect((40, 400), rect2), "cyan")
screen.draw.filled_rect(Rect((95, 425), rect3), "red")
screen.draw.filled_rect(Rect((750, 60), rect1), "gold")
screen.draw.filled_rect(Rect((795, 75), rect2), "cyan")
screen.draw.filled_rect(Rect((770, 145), rect3), "red")
screen.draw.filled_rect(Rect((750, 440), rect1), "gold")
screen.draw.filled_rect(Rect((795, 400), rect2), "cyan")
screen.draw.filled_rect(Rect((770, 425), rect3), "red")
#screen.blit(flip(alien2._surf, True, False), alien2.topleft)
animal_button.draw() # Draw pushbuttons
food_button.draw()
silly_button.draw()
school_button.draw()
Tell_Joke()
def on_mouse_down(button, pos):
global JOKE, animal_joke, food_joke, silly_joke, school_joke # When the left mouse button is clicked on the animal button
if button == mouse.LEFT and animal_button.collidepoint(pos):
animal_joke = True
JOKE = animal_jokes # Set the animal joke flag to true
elif button == mouse.LEFT and food_button.collidepoint(pos): # Sets the Food joke flag to true
food_joke = True
JOKE = food_jokes
elif button == mouse.LEFT and silly_button.collidepoint(pos): # Sets the silly joke flag to true
silly_joke = True
JOKE = silly_jokes
elif button == mouse.LEFT and school_button.collidepoint(pos): # Sets the school joke flag to true
school_joke = True
JOKE = school_jokes
elif button == mouse.LEFT and reset_button.collidepoint(pos):
restart()
def Tell_Joke():
if animal_joke: # Once the Animal Joke flag has changed to true in on_mouse_down
selected_joke() # Display the joke and laugh image on screen, play laughter
elif food_joke: # As per Animal flag
selected_joke()
elif silly_joke: # As above
selected_joke()
elif school_joke: # As above
selected_joke()
def selected_joke():
laugh.draw()
screen.draw.text(random.choice(JOKE), center=(print_joke))
audience_laugh.play()
reset_button.draw()
restart()
def restart():
global start
start = True
I also tried having a main():
function at the start, indenting everything below to be a part of just this function and then attempting to loop back around to that at the end, with no success. I also tried making certain elements transparent when the reset button was clicked on but again had no luck.
Submission
As a result of the above issues, I have decided to enter the last known "good" bit of code so that I can get some feedback and hopefully some hints to point me in the right direction with a few unfinished items and things I'm unhappy with.
The code was written using the mu editor in PygameZero mode, so it is probably best run in this mode. Once the game window opens, clicking on a category of joke will randomly display a joke based on said category accompanied by laughter.
Below is what I have so far:
Code
"""
The "You're Having a Laugh" joke generator
"""
#from pygame.transform import flip
import random
laugh = Actor("haha", topleft=(50, 30)) # Load images/buttons and set their positions
animal_button = Actor("button_animals", topleft=(100, 85))
food_button = Actor("button_food", topright=(800, 85))
silly_button = Actor("button_silly", bottomleft=(100, 515))
school_button = Actor("button_school", bottomright=(800, 515))
reset_button = Actor("button_reset", midbottom=(450, 575))
WIDTH = 900 # Window size
HEIGHT = 600
print_joke = (450, 300) # Joke screen position
audience_laugh = sounds.laugh1 # Load laughter
#List of animal jokes
animal_jokes = ["How do you tell the difference \
between a bull and a cow? \n\nIt is either one or \
the udder!", "Why do hummingbirds hum? \n\nBecause \
they don’t know the words!", "What kind of dog does \
a magician have? \n\nA Labracadabrador!", "What do \
frogs order at fast-food restaurants? \n\nFrench \
flies!"]
#KNOCK_KNOCK_JOKES = ["Knock, knock.\nWho’s there? \
#Dozen. \nDozen who? \nDozen anyone want to let me in?"]
#List of food jokes
food_jokes = ["Which vegetable do sailors hate the \
\n\nLeeks!", "What do you call a cheese that’s not \
yours? \n\nNacho cheese!", "What kind of key opens \
a banana? \n\nA mon-key!", "Why do bees have sticky \
hair? \n\nBecause they use honeycombs!"]
#List of silly jokes
silly_jokes = ["If you’re English in the kitchen \
and English in the living room, what are you in the \
bathroom? \n\nEuropean!", "What are mummies \
favourite lunches? \n\nWraps!", "What gives you the \
power to walk through a wall? \n\nA door!", "What \
happens when you wear a snow suit inside? \n\nIt \
melts all over the carpet."]
#List of school jokes
school_jokes = ["Why did the music teacher need a \
ladder? \n\nTo reach the high notes.", "What do \
elves learn in school? \n\nThe elf-abet!", "Why did \
the nose not want to go to school? \n\nHe was tired \
of getting picked on!", "Why did the student eat \
his homework? \n\nBecause his teacher told him it \
would be a piece of cake!"]
rect1 = (100, 100) # Background shape sizes
rect2 = (65, 125)
rect3 = (35, 30)
animal_joke = False # Setting flags
food_joke = False
silly_joke = False
school_joke = False
def draw():
screen.fill((3, 70, 26)) # Set window background colour
screen.draw.filled_rect(Rect((50, 60), rect1), "gold") # Draw rectangles for background
screen.draw.filled_rect(Rect((40, 75), rect2), "cyan")
screen.draw.filled_rect(Rect((95, 145), rect3), "red")
screen.draw.filled_rect(Rect((50, 440), rect1), "gold")
screen.draw.filled_rect(Rect((40, 400), rect2), "cyan")
screen.draw.filled_rect(Rect((95, 425), rect3), "red")
screen.draw.filled_rect(Rect((750, 60), rect1), "gold")
screen.draw.filled_rect(Rect((795, 75), rect2), "cyan")
screen.draw.filled_rect(Rect((770, 145), rect3), "red")
screen.draw.filled_rect(Rect((750, 440), rect1), "gold")
screen.draw.filled_rect(Rect((795, 400), rect2), "cyan")
screen.draw.filled_rect(Rect((770, 425), rect3), "red")
#screen.blit(flip(alien2._surf, True, False), alien2.topleft)
animal_button.draw() # Draw pushbuttons
food_button.draw()
silly_button.draw()
school_button.draw()
if animal_joke: # Once the Animal Joke flag has changed to true in on_mouse_down
category_selection() # Run the category_selection function
elif food_joke: # As per Animal flag
category_selection()
elif silly_joke: # As above
category_selection()
elif school_joke: # As above
category_selection()
def on_mouse_down(pos, button):
global JOKE, animal_joke, food_joke, silly_joke, school_joke # When the left mouse button is clicked on the animal button
if button == mouse.LEFT and animal_button.collidepoint(pos): # Set the animal joke flag to true
animal_joke = True
JOKE = animal_jokes
elif button == mouse.LEFT and food_button.collidepoint(pos): # Sets the Food joke flag to true
food_joke = True
JOKE = food_jokes
elif button == mouse.LEFT and silly_button.collidepoint(pos): # Sets the silly joke flag to true
silly_joke = True
JOKE = silly_jokes
elif button == mouse.LEFT and school_button.collidepoint(pos): # Sets the school joke flag to true
school_joke = True
JOKE = school_jokes
def category_selection(): # Tell the joke
laugh.draw()
screen.draw.text(random.choice(JOKE), center=(print_joke)) # Pics a random joke from the category selected by the user
audience_laugh.play()
reset_button.draw() # To be used for starting over
Things I'd like to improve upon
- Obviously I'd like a working reset button
- I still feel I can slim down sections of my code making it more efficient
- At the moment, once a joke has been "told", you can click anywhere on the screen and another joke from that category displays. Clicking on another category displays that category's random joke. I want noting to be selectable apart from reset
- Maybe splitting the joke and the punchline, so selecting the category displays the setup then maybe an "Answer" button pops up to click on and display the joke
- Or perhaps just having a delay between the setup and then the punchline, laughter, reset button etc.
- I'd like to be more adventurous with the aesthetic, maybe having a chromatic background scheme?
- Perhaps have the laughter image start small and expand to fill the screen, just something to make things a little more dynamic.
- As I'm late home from being offshore, due to weather, I've emailed my son canvassing him for jokes to include, which I can replace some of my current ones with. When I eventually get home I plan to have him work on a colour scheme with me for the game and adding more background, comedy related images.
Paul Honey ~ 10 Dec 2022 7:38 p.m.
Nicholas Tollervey ~ 14 Dec 2022 2:11 p.m.
Hi Paul,
First of all, many congratulations on getting your project this far. My job, as mentor, will be to help you improve the code, support you as you refine the project and, ultimately, assess the project against the requirements for grade 1. Reading your project diary tells me you've had quite an adventure and I've thoroughly enjoyed following along with your triumphs, trials and tribulations. Let's see how we can get things in a great shape for both your son (most importantly), and the requirements for grading!
I've copied your code into Mu, and downloaded all the game assets. My first slight niggle (but very easy to fix) was that the hahaha.png
was actually referred to in the code as haha
. Hence PyGameZero couldn't find it. I simply renamed hahaha.png
to haha.png
and it worked.
I have to admit, for the first five minutes I just sat at my computer grinning like the Cheshire Cat. 😁 The colourful user interface, the canned laughter, the fondue cheesiness of the jokes... 🧀 as a dad with joke loving kids, this project has hit all the right notes for me. 🤡
I really appreciated how you told the story of creating your project. Your writing is thoughtful, engaging and clearly demonstrates how you have learned the necessary Python to deliver your project and meet the requirements for grade 1. Really well done..! This is the sort of evidence I want to see as a mentor assessing the project for grading. Keep up the good work in this respect.
I have some feedback on the code (I'm taking the most recent version as my starting point):
- Code layout. Clicking on the "Tidy" button in Mu will re-organise (but not re-write) your code into a standard layout, so it's easier to read. If you try it, you'll see the lists of jokes start to look odd... but read on for a way to overcome this.
- Code quality. Clicking on the "Check" button in Mu will tell you places where you could improve the quality of the code (although this doesn't check if your code has bugs!). Quality could mean several things, such as a line being too long (in which case, the "Tidy" button is your friend), or pointing out clutter, like variables your declare but never actually use.
- Comments. You have used meaningful names in your code, which means that
food_joke = True
tells me everything I need to know. Therefore, comments like# Sets the food joke flag to true
are a bit superfluous to requirements and clutter up the code. The general rule-of-thumb is to add comments where you need to either explain your intention, describe something that isn't at first obvious, or highlight something being the way it is because of historical reasons. If your code is readable (you've used meaningful names for things, so the code tells the story of what's happening), then you don't need to explain yourself. In addition, to comment a function use this "triple quote" pattern (and this might only be what's needed to describe your intention):
def my_function():
"""
This is where I write my comments for the function.
It can be over several lines.
"""
return "Hello"
- Screen background. A lot of the code contains
screen.draw.filled_rect(Rect((50, 60), rect1), "gold")
type statements. You could save yourself a lot of this code by just using an image for the background, and drawing it before you draw the buttons (so they appear on top). You just have to make sure your background image is the same dimensions as the game window, and use something like this in thedraw
function:screen.blit("background_filename", (0, 0))
Perhaps the background could be of something like a "standup" stage with a mic..? (Phoenix Nights..?) - Joke lists. I notice that each joke has a set-up and a punchline. Perhaps you could organise the jokes as a list of 2-item lists? I think it would make it much easier to read and understand what a joke contains. It means that when you select the joke, you'd need to concatenate the two parts together. Perhaps something like this..?
my_jokes = [
["setup 1", "punchline 1"],
["setup 2", "punchline 2"],
# ... etc ...
]
my_other_jokes = [
["setup 3", "punchline 3"],
["setup 4", "punchline 4"],
# ... etc ...
]
and to select the joke:
the_joke = "\n\n".join(random.choice(my_jokes))
The "\n\n".join(...)
bit simply tells Python to join the two parts of the list (containing the setup and punchline for the randomly selected joke) together with newlines ("\n\n"
). So, the list ("setup", "punchline")
becomes "setup\n\npunchline"
.
- Font size. The size of the joke's text is a bit small. I have to wear my glasses to see it. I think PyGameZero's text formatting documentation will help out here.
- Randomness. You already select random jokes from a list. When you click a button, why not select from a random list of audio responses..? For instance, in addition to the canned laughter, you could have b'dum tish, sad trombone, moaning (tough crowd) or even individual reactions like this one ("you 'avin a larf?"). You could also update the background to a random image whenever you click one of the joke buttons. The possibilities are endless..! 🤣
- Flags. Do you need all the flags? It feels to me like you probably only need one flag. All those existing flags make it difficult to understand the code and perhaps explain the strange behaviour when clicking the user interface. Let's call that single flag something meaningful like,
the_joke
. Next, in thedraw
function, only do ascreen.draw.text(... whatever ...)
if there's something inthe_joke
. In Python anything that is empty is also the equivalent toFalse
and any collection with items in it is equivalent toTrue
. Since a string is a collection of characters, then""
(empty string) is the same asFalse
and"a string"
(a string with characters in it) is evaluated asTrue
. As a result you could just doif the_joke
in the draw function to work out if there's anything to display. It's in this block of code that you should also draw thereset_button
andlaugh
. You could then delete thecategory_selection
function (thus simplifying the code). 👍 - Joke selection. This only needs to happen in the
on_mouse_click
function right..? Depending on which button is clicked you just need to setthe_joke
to the randomly selected joke from the appropriate list. Finally, you only need to play the sound effects if a new joke is selected when the user clicks. How might you check this? - Reset button. Given the situation with flags and joke selection in the previous two points, you'd only need to set
the_joke = ""
so thedraw
function stops drawing the joke onto the screen. This would be yet another check inon_mouse_down
, but for thereset_button.collidepoint
. - Documentation. It feels like the app needs some humorous documentation in the form of a "manual". Perhaps these instructions could also explain how users (your son) could add new jokes or edit existing ones..?
I've really enjoyed reading about your project so far, and exploring your code too. I think this could evolve into a really funky project. I also hope my feedback and suggestions make sense. If in doubt, just ask here and I'll reply. In addition to assessing your project, I'm also here to help and the interactions we have also form part of the basis of my assessment. So just dive in and let me know how you get on.
Bravo on everything so far, and I look forward to seeing how this shapes up.
🚀
Paul Honey ~ 19 Dec 2022 11:44 p.m. (updated: 19 Dec 2022 11:52 p.m.)
Trying to refine my project
Comment Tidy-up
Based on assessor feedback I have managed to drastically tidy up my code. I had previously used the Mu "Check" function, and could see that I was getting error messages about my code being too long on certain lines. However, because it didn't stop my game from running, and mainly because I was being pig headed with how I was used to representing comments from my limited machine coding exposure, I kept the comments using hash-tags off to the right of my code. This is often how a lot of comments are presented by the programmers who write the PLC code, using statement lists, for the equipment on which I work. Therefore I just reverted to what I was used to.
I see now it is much better just to use triple quotes at the start of a function to give a brief description. Especially, as you've mentioned Nicholas, if the code is relatively self explanatory. I think I was also commenting everything from the point of view that the person reading it might have zero experience and so explaining everything might be advantageous.
Cutting out Unnecessary Code
Based on my mentor's advice, I replaced my individual flags with a single tell_joke
flag. This single flag is set to true regardless of which button is clicked on, which is still used to select which list of jokes is selected for random joke display. This has meant I can get rid of all the elif statements in my draw function. Therefore:
if animal_joke:
category_selection()
elif food_joke:
category_selection()
elif silly_joke:
category_selection()
elif school_joke:
category_selection()
Has been replaced with:
if tell_joke:
laugh.draw()
bean.draw()
screen.draw.text("\n\n".join(random.choice(JOKE)), center=(print_joke), fontname="rabbit_on_the_moon", fontsize=36,
color="#AAFF00") #, gcolor="#66AA00", owidth=1.5, ocolor="black", alpha=0.8)
audience_laugh.play()
reset_button.draw()
As a result of the slim-lining advice given, I could see that this single if statement could replace the separate category_selection function I had previously written. I've also incorporated the advice to separate my joke setups and punchlines in each list so they may be read more easily in the code, hence the "\n\n".join part of the above code.
Playing around with Fonts
You can also see in the above code that I've tried to play around with how my joke text. Just to start me off I copied some of the text formatting code from the Pygame Zero tutorial site linked to me by Nicholas:
Unfortunately I was presented with the following error upon clicking one of the joke category pushbuttons:
pygame 2.1.2 (SDL 2.0.18, Python 3.8.12)
Hello from the pygame community. https://www.pygame.org/contribute.html
Traceback (most recent call last):
File "C:\Local\Programs\MUEDIT~1\Python\lib\runpy.py", line 194, in _run_module_as_main
return _run_code(code, main_globals, None,
File "C:\Local\Programs\MUEDIT~1\Python\lib\runpy.py", line 87, in _run_code
exec(code, run_globals)
File "C:\Local\python\mu\mu_venv-38-20221122-201713\lib\site-packages\pgzero\__main__.py", line 3, in <module>
main()
File "C:\Local\python\mu\mu_venv-38-20221122-201713\lib\site-packages\pgzero\runner.py", line 93, in main
run_mod(mod)
File "C:\Local\python\mu\mu_venv-38-20221122-201713\lib\site-packages\pgzero\runner.py", line 113, in run_mod
PGZeroGame(mod).run()
File "C:\Local\python\mu\mu_venv-38-20221122-201713\lib\site-packages\pgzero\game.py", line 217, in run
self.mainloop()
File "C:\Local\python\mu\mu_venv-38-20221122-201713\lib\site-packages\pgzero\game.py", line 256, in mainloop
draw()
File "paul honey grade 1 - joke generator.py", line 97, in draw
screen.draw.text("\n\n".join(random.choice(JOKE)), center=(print_joke), fontname="rabbit_on_the_moon", fontsize=36,
File "C:\Local\python\mu\mu_venv-38-20221122-201713\lib\site-packages\pgzero\screen.py", line 61, in text
ptext.draw(*args, surf=self._surf, **kwargs)
File "C:\Local\python\mu\mu_venv-38-20221122-201713\lib\site-packages\pgzero\ptext.py", line 439, in draw
tsurf = getsurf(text, fontname, fontsize, sysfontname, bold, italic, underline, width, widthem,
File "C:\Local\python\mu\mu_venv-38-20221122-201713\lib\site-packages\pgzero\ptext.py", line 280, in getsurf
surf0 = getsurf(text, fontname, fontsize, sysfontname, bold, italic, underline,
File "C:\Local\python\mu\mu_venv-38-20221122-201713\lib\site-packages\pgzero\ptext.py", line 311, in getsurf
surf0 = getsurf(text, fontname, fontsize, sysfontname, bold, italic, underline,
File "C:\Local\python\mu\mu_venv-38-20221122-201713\lib\site-packages\pgzero\ptext.py", line 349, in getsurf
(1.0 - m) * array[:, :, j] + m * gcolor[j]).astype(array.dtype)
ValueError: operands could not be broadcast together with shapes (50,) (0,49)
I narrowed the error down to the colour gradient portion. Once this was removed, the code ran without error.
The Changes so Far
I have not finished implementing all the changes I wish to make. My son has found a selection of funny images for me to use from https://openclipart.org/, which I've started to include. We have also bought him a joke book for Christmas, which hopefully he can use to populate the program with his own jokes, once I have written a how to guide. Below is my altered code, it's not yet ready for further review, but it's getting late and just wanted to make sure I'd logged everything I'd done so far whilst still fresh in my mind.
Code
"""
The "You're Having a Laugh" joke generator
"""
# from pygame.transform import flip
import random
laugh = Actor("haha", topleft=(50, 30)) # Load images/buttons and set their positions
bean = Actor("bean", bottomright=(900, 600))
animal_button = Actor("button_animals", topleft=(100, 85))
food_button = Actor("button_food", topright=(800, 85))
silly_button = Actor("button_silly", bottomleft=(100, 515))
school_button = Actor("button_school", bottomright=(800, 515))
reset_button = Actor("button_reset", midbottom=(450, 575))
WIDTH = 900 # Window size
HEIGHT = 600
print_joke = (450, 300) # Joke screen position
audience_laugh = sounds.laugh1 # Load laughter
animal_jokes = [
[
"How do you tell the difference between a bull and a cow?",
"It is either one or the udder!",
],
["Why do hummingbirds hum?", "Because they don’t know the words!"],
["What kind of dog does a magician have?", "A Labracadabrador!"],
["What do frogs order at fast-food restaurants", "French flies!"],
]
# KNOCK_KNOCK_JOKES = ["Knock, knock.\nWho’s there? \
# Dozen. \nDozen who? \nDozen anyone want to let me in?"]
food_jokes = [
["Which vegetable do sailors hate the most?", "Leeks!"],
["What do you call a cheese that’s not yours?" "Nacho cheese!"],
["What kind of key opens a banana?", "A mon-key!"],
["Why do bees have sticky hair?, Because they use honeycombs!"],
]
silly_jokes = [
[
"If you’re English in the kitchen and English in the living room, \n\nwhat are you in the bathroom?",
"European!",
],
["What are mummies favourite lunches?", "Wraps!"],
["What gives you the power to walk through a wall?", "A door!"],
["What happens when you wear a snow suit inside?", "It melts all over the carpet."],
]
# List of school jokes
school_jokes = [
["Why did the music teacher need a ladder?", "To reach the high notes."],
["What do elves learn in school?", "The elf-abet!"],
[
"Why did the nose not want to go to school?",
"He was tired of getting picked on!",
],
[
"Why did the student eat his homework?",
"Because his teacher told him it would be a piece of cake!",
],
]
rect1 = (100, 100) # Background shape sizes
rect2 = (65, 125)
rect3 = (35, 30)
tell_joke = False
def draw():
screen.fill((3, 70, 26)) # Set window background colour
screen.draw.filled_rect(
Rect((50, 60), rect1), "gold"
) # Draw rectangles for background
screen.draw.filled_rect(Rect((40, 75), rect2), "cyan")
screen.draw.filled_rect(Rect((95, 145), rect3), "red")
screen.draw.filled_rect(Rect((50, 440), rect1), "gold")
screen.draw.filled_rect(Rect((40, 400), rect2), "cyan")
screen.draw.filled_rect(Rect((95, 425), rect3), "red")
screen.draw.filled_rect(Rect((750, 60), rect1), "gold")
screen.draw.filled_rect(Rect((795, 75), rect2), "cyan")
screen.draw.filled_rect(Rect((770, 145), rect3), "red")
screen.draw.filled_rect(Rect((750, 440), rect1), "gold")
screen.draw.filled_rect(Rect((795, 400), rect2), "cyan")
screen.draw.filled_rect(Rect((770, 425), rect3), "red")
# screen.blit(flip(alien2._surf, True, False), alien2.topleft)
animal_button.draw() # Draw pushbuttons
food_button.draw()
silly_button.draw()
school_button.draw()
if tell_joke:
laugh.draw()
bean.draw()
screen.draw.text("\n\n".join(random.choice(JOKE)), center=(print_joke), fontname="rabbit_on_the_moon", fontsize=36,
color="#AAFF00", owidth=1.5, ocolor="black", alpha=0.8)
audience_laugh.play()
reset_button.draw() # Run the category_selection function
def on_mouse_down(pos, button):
"""
click a button to select a joke category
"""
global JOKE, tell_joke # food_joke, silly_joke, school_joke
if button == mouse.LEFT and animal_button.collidepoint(pos):
tell_joke = True
JOKE = animal_jokes
elif button == mouse.LEFT and food_button.collidepoint(pos):
tell_joke = True
JOKE = food_jokes
elif button == mouse.LEFT and silly_button.collidepoint(pos):
tell_joke = True
JOKE = silly_jokes
elif button == mouse.LEFT and school_button.collidepoint(pos):
tell_joke = True
JOKE = school_jokes
elif button == mouse.LEFT and reset_button.collidepoint(pos):
tell_joke = ""
NB: I've now also got a working reset button, which just sets my flag back to false to remove everything implemented when the category buttons are clicked. I notice it doesn't cut the audio off however, and jokes are still cycled through if a click is made elsewhere on the screen. As previously mentioned, I just want the entire screen, apart from the reset button, to become inactive once a joke is told. Therefore I still need to work on this.
Nicholas Tollervey ~ 21 Dec 2022 6:16 p.m.
Hi Paul,
Thank you so much for the updates, and well done on making such good progress towards a version of the project that simplifies how it works, and does so more efficiently. I have some feedback and reminders/requests for further refinement:
- With the latest version of the code that you posted, I see the following error message when I try to run the game (I think you need to upload something, so I have a copy):
KeyError: "No image found like 'bean'. Are you sure the image exists?"
- Given what I said about the truth-iness (or not) of a Python list with or without items in it, do you actually need
tell_joke
..? If not, remove it..! - The code looks so much better. Great work on reorganising things and formatting it neatly, it makes it much easier to read.
- Well done on debugging the font problem. It'd helpful for me (and more evidence for the assessment) if you could explain your approach. Just telling me the story of how you went about finding and fixing the problem would suffice. It's also worth noting that, "I Googled the error message, and just did what the first result told me to do" is a perfectly valid story. Knowing what to Google and how to refine your code from the results is a valuable skill.
- While I appreciate the effort you've put in so far, I'm also aware this is still a work in progress. Telling your story with first or second draft versions of the code is a good thing since it helps me observe growth and refinement. All part of the grading journey to experience, and good to see.
- What are you in the bathroom? European! 🤣 This code is great fun to review. 👏
I'm looking forward to seeing how this shapes up further, what further refinements you may make and how your son finds using it. Very much in the spirit of a Christmas cracker for the 21st century.
Paul Honey ~ 03 Jan 2023 5:24 a.m. (updated: 03 Jan 2023 6:46 a.m.)
Debug
With regards to the previous error code, at the portion shown below:
File "C:\Local\python\mu\mu_venv-38-20221122-201713\lib\site-packages\pgzero\ptext.py", line 349, in getsurf
(1.0 - m) * array[:, :, j] + m * gcolor[j]).astype(array.dtype)
ValueError: operands could not be broadcast together with shapes (50,) (0,49)
The part of the message gcolor[j]).astype(array.dtype)
led me to believe it was an issue with the colour gradient part of the code. I commented out this part of the code using a #, which also removed the subsequent code for outline thickness, colour and how transparent the text was. When running my code with this removed the text would display with no issues. I then just deleted the gcolour part and put the outline and transparency settings back in, to check these wouldn't cause any issues, which they did not. I have decided to remove transparency and just have the text solid however. As I think this looks better.
Updated Code
After the assessor feedback I have altered my code to the following:
"""
The "You're Having a Laugh" Joke Generator
"""
import random
WIDTH = 900 # Window size
HEIGHT = 600
stage = Actor("stage", midtop=(450, 0)) # Background images
neon_mic = Actor("neon_mic", topleft=(0, 0))
mic = Actor("micstand", center=(430, 375))
laugh = Actor("haha", center=(450, 300)) # Randomly generated images
bean = Actor("bean", bottomright=(900, 600))
lol = Actor("lol", center=(375, 300))
rofl = Actor("rofl", center=(430, 400))
funny_image = [laugh, bean, lol, rofl]
audience_laugh = sounds.laugh1 # Randomly generated sounds
girl_laugh = sounds.laugh2
badum_tish = sounds.drum
slow_clap = sounds.slow_clap
funny_sound = [audience_laugh, girl_laugh, badum_tish, slow_clap]
"""
Section 1 - Joke Lists
Add your own!
"""
animal_jokes = [
[
"How do you tell the difference between a bull and a cow?",
"It is either one or the udder!"
],
[
"Why do hummingbirds hum?",
"Because they don't know the words!"
],
[
"What kind of dog does a magician have?",
"A Labracadabrador!"
],
[
"What do frogs order at fast-food restaurants",
"French flies!"
],
]
food_jokes = [
[
"Which vegetable do sailors hate the most?",
"Leeks!"
],
[
"What do you call a cheese that's not yours?",
"Nacho cheese!"
],
[
"What kind of key opens a banana?",
"A mon-key!"
],
[
"Why do bees have sticky hair?",
"Because they use honeycombs!"
],
]
silly_jokes = [
[
"If you're English in the kitchen and English in the living room,\
\n\nwhat are you in the bathroom?",
"European!"
],
[
"What are mummies favourite lunches?",
"Wraps!"
],
[
"What gives you the power to walk through a wall?",
"A door!"
],
[
"What happens when you wear a snow suit inside?",
"It melts all over the carpet."
],
]
school_jokes = [
[
"Why did the music teacher need a ladder?",
"To reach the high notes."
],
[
"What do elves learn in school?",
"The elf-abet!"
],
[
"Why did the nose not want to go to school?",
"He was tired of getting picked on!"
],
[
"Why did the student eat his homework?",
"Because his teacher told him it would be a piece of cake!"
],
]
"""
Section 2 - Buttons list
Can you think of your own categories?
"""
top_left_button = Actor("button_animals", topleft=(100, 150))
top_right_button = Actor("button_food", topright=(800, 150))
bottom_left_button = Actor("button_silly", bottomleft=(100, 450))
bottom_right_button = Actor("button_school", bottomright=(800, 450))
reset_button = Actor("button_reset", midbottom=(450, 575))
buttons = [top_left_button, top_right_button, bottom_left_button, bottom_right_button]
joke = False
def draw():
stage.draw()
neon_mic.draw()
mic.draw()
buttons[0].draw()
buttons[1].draw()
buttons[2].draw()
buttons[3].draw()
if joke:
"""
After joke category is selected,
display random joke and images,
play random sound.
"""
draw_image = random.choice(funny_image)
draw_image.draw()
screen.draw.text(
"\n\n".join(random.choice(joke)),
center=(450, 300),
fontname="rabbit_on_the_moon",
fontsize=36,
color="darkorange1",
owidth=1.5,
ocolor="black"
)
play_sound = random.choice(funny_sound)
play_sound.play()
reset_button.draw()
def on_mouse_down(pos, button):
"""
click a button to select a joke category
"""
global joke
if button == mouse.LEFT and buttons[0].collidepoint(pos):
joke = animal_jokes
elif button == mouse.LEFT and buttons[1].collidepoint(pos):
joke = food_jokes
elif button == mouse.LEFT and buttons[2].collidepoint(pos):
joke = silly_jokes
elif button == mouse.LEFT and buttons[3].collidepoint(pos):
joke = school_jokes
elif button == mouse.LEFT and reset_button.collidepoint(pos):
joke = ""
Code update justifications
I removed the separate line of code which sets the position of the joke and just set it's position to 450, 300 in the draw function.
[
"How do you tell the difference between a bull and a cow?",
"It is either one or the udder!"
],
I have laid each of the jokes out in this way, despite the tidy button rearranging how they're displayed, to make it easier for a user to change the joke setups and punchlines. Otherwise Mu will tidy the code to look like the following:
[
"How do you tell the difference between a bull and a cow?",
"It is either one or the udder!",
],
["Why do hummingbirds hum?", "Because they don't know the words!"],
Having a mixture of how the code is arranged, due to line length, I found to be visually jarring. I felt it might be confusing for the user, should they wish to replace the current jokes with their own, to have two different layouts to contend with.
I have renamed the buttons from their category names to their physical positions when displayed on screen. This is so that if the user wishes to create their own categories, they can create a new pushbutton, place it into the images folder and they only have one small piece of code to change e.g. top_left_button = Actor("button_animals", topleft=(100, 150))
can become top_left_button = Actor("button_holidays", topleft=(100, 150))
, instead of having to go all the way through the code and change several instances where a button name has been used. Obviously they would also need to change the name of the corresponding joke list. But this will all be detailed in the user guide I am currently putting together.
I put all the buttons into a list, as I was hoping to be able to just draw all list items at once. I tried the following:
buttons[0, 1, 2, 3].draw()
However I get the following error message:
pygame 2.1.2 (SDL 2.0.18, Python 3.8.12)
Hello from the pygame community. https://www.pygame.org/contribute.html
Traceback (most recent call last):
File "C:\Users\406850\AppData\Local\Programs\MUEDIT~1\Python\lib\runpy.py", line 194, in _run_module_as_main
return _run_code(code, main_globals, None,
File "C:\Users\406850\AppData\Local\Programs\MUEDIT~1\Python\lib\runpy.py", line 87, in _run_code
exec(code, run_globals)
File "C:\Users\406850\AppData\Local\python\mu\mu_venv-38-20221122-201713\lib\site-packages\pgzero\__main__.py", line 3, in <module>
main()
File "C:\Users\406850\AppData\Local\python\mu\mu_venv-38-20221122-201713\lib\site-packages\pgzero\runner.py", line 93, in main
run_mod(mod)
File "C:\Users\406850\AppData\Local\python\mu\mu_venv-38-20221122-201713\lib\site-packages\pgzero\runner.py", line 113, in run_mod
PGZeroGame(mod).run()
File "C:\Users\406850\AppData\Local\python\mu\mu_venv-38-20221122-201713\lib\site-packages\pgzero\game.py", line 217, in run
self.mainloop()
File "C:\Users\406850\AppData\Local\python\mu\mu_venv-38-20221122-201713\lib\site-packages\pgzero\game.py", line 256, in mainloop
draw()
File "paul honey grade 1 - joke generator.py", line 124, in draw
buttons[0, 1, 2, 3].draw()
TypeError: list indices must be integers or slices, not tuple
---------- FINISHED ----------
exit code: 1 status: 0
I have not been able to decipher why pygame won't accept this, but will allow each item in the list to be drawn separately. I tried just drawing one button at first, then tried different methods to add in one more at a time, but was unsuccessful. When I only had one button on screen I noticed that if I clicked the positions where the other buttons should have been, their respective jokes still displayed. Is that because my pygame mouse click command is looking for a click at the position of where the button would be, regardless of whether it has actually been drawn?
I have left the buttons in a list for the minute. This is in the hopes I can make the draw section of the code more concise if all list items can be drawn with just one line of code. However, I will remove the list and just draw each button individually if necessary.
I have also put some more images into a list to be drawn at random after the program detects the mouse click. At first, I couldn't get them to display without crashing the program, this was just with writing draw(random.choice(funny_image)) within the draw function. After some research it looked like I needed to assign the randomly generated image to another parameter. I tried putting the assignment at the beginning of the code, i.e. outside of the draw function, but this caused only the same, randomly selected image to be displayed each time a joke button was pressed, even after pushing the reset button.
I needed to put both of the following lines of code into the if joke
section of the draw function in order to have a new image selected at random each time.
draw_image = random.choice(funny_image)
draw_image.draw()
I hope this all makes sense. I am currently working nightshifts with an awful cold and so my explanations and grammar might not be up to par. But I hope I've explained myself coherently enough.
I am currently writing a user guide, but wanted to get my latest code updates critiqued, as something close to my finalised code will need to be included within said guide.
My son picked some of the images for me to include when the joke is randomly generated, including the Mr Bean image, which caused him to burst out laughing when he found it on the clipart website.
I will also provide links to all the extra images and sounds I have gathered for my program.
Paul Honey ~ 04 Jan 2023 4:47 a.m. (updated: 04 Jan 2023 5:37 a.m.)
Further Revision
List Drawing
After Googling the error I was receiving when trying to draw my entire list list object has no attribute draw
, I discovered I could draw an entire set of list items at once using a for loop:
def draw
[backgrounds.draw() for backgrounds in background_images]
[joke_categories.draw() for joke_categories in buttons]
Here I have now assigned all my background images and pushbuttons to their own lists in order to draw them all at once. As I understand it, an ordinary list can't have draw attributed to it, however individual list items may. This is why my previous buttons[0].draw()
code would work but buttons[0:3].draw()
would return an error. My new code now reassigns each individual list item, in order that they may all be drawn at once.
Error Handling
I tried reordering the code to the following:
def draw
[for backgrounds in background_images backgrounds.draw()]
To me this makes more sense "grammatically" so I thought I would test it out. However, I was greeted with a syntax error:
[for backgrounds in background_images backgrounds.draw()]
^
SyntaxError: invalid syntax
A syntax error occurs when the code is initially executed, known as parsing (Invalid Syntax). Python cannot understand what is written and so returns an error straight away. This differs from some of my earlier errors, for example when I tried to include coding for displayed text colour gradients, which would cause my program to crash, after initially running, when trying to interact with it. This would be considered a runtime error i.e. unexpectedly exiting the program when an error occurs trying to execute a specific line of code (Runtime Error examples).
Although, at present, I don't know the specifics behind why the line of code in question has to be ordered the way it does to prevent the syntax error in question.
New Code
"""
The "You're Having a Laugh" Joke Generator
"""
import random
WIDTH = 900 # Window size
HEIGHT = 600
stage = Actor("stage", midtop=(450, 0)) # Background images
neon_mic = Actor("neon_mic", topleft=(0, 195))
mic = Actor("micstand", center=(430, 375))
comedy = Actor("comedy", center=(450, 70))
laugh_emoji = Actor("laugh_emoji", midright=(880, 280))
laugh_emoji.angle = -30
background_images = [stage, comedy, neon_mic, mic, laugh_emoji]
laugh = Actor("hahaha", center=(450, 300)) # Randomly generated images
haha = Actor("haha", center=(400,300))
bean = Actor("bean", bottomright=(900, 600))
lol = Actor("lol", center=(375, 300))
rofl = Actor("rofl", center=(430, 400))
funny_image = [laugh, bean, lol, rofl, haha]
audience_laugh = sounds.laugh1 # Randomly generated sounds
girl_laugh = sounds.laugh2
badum_tish = sounds.drum
slow_clap = sounds.slow_clap
funny_sound = [audience_laugh, girl_laugh, badum_tish, slow_clap]
"""
Section 1 - Joke Lists
Add your own!
"""
animal_jokes = [
[
"How do you tell the difference between a bull and a cow?",
"It is either one or the udder!"
],
[
"Why do hummingbirds hum?",
"Because they don't know the words!"
],
[
"What kind of dog does a magician have?",
"A Labracadabrador!"
],
[
"What do frogs order at fast-food restaurants",
"French flies!"
],
]
food_jokes = [
[
"Which vegetable do sailors hate the most?",
"Leeks!"
],
[
"What do you call a cheese that's not yours?",
"Nacho cheese!"
],
[
"What kind of key opens a banana?",
"A mon-key!"
],
[
"Why do bees have sticky hair?",
"Because they use honeycombs!"
],
]
silly_jokes = [
[
"If you're English in the kitchen and English in the living room,\
\n\nwhat are you in the bathroom?",
"European!"
],
[
"What are mummies favourite lunches?",
"Wraps!"
],
[
"What gives you the power to walk through a wall?",
"A door!"
],
[
"What happens when you wear a snow suit inside?",
"It melts all over the carpet."
],
]
school_jokes = [
[
"Why did the music teacher need a ladder?",
"To reach the high notes."
],
[
"What do elves learn in school?",
"The elf-abet!"
],
[
"Why did the nose not want to go to school?",
"He was tired of getting picked on!"
],
[
"Why did the student eat his homework?",
"Because his teacher told him it would be a piece of cake!"
],
]
"""
Section 2 - Buttons list
Can you think of your own categories?
"""
top_left_button = Actor("button_animals", topleft=(100, 150))
top_right_button = Actor("button_food", topright=(800, 150))
bottom_left_button = Actor("button_silly", bottomleft=(100, 450))
bottom_right_button = Actor("button_school", bottomright=(800, 450))
reset_button = Actor("button_reset", midbottom=(450, 575))
buttons = [top_left_button, top_right_button, bottom_left_button, bottom_right_button]
joke = False
def draw():
[backgrounds.draw() for backgrounds in background_images]
[joke_categories.draw() for joke_categories in buttons]
if joke:
"""
After joke category is selected,
display random joke and images,
play random sound.
"""
draw_image = random.choice(funny_image)
draw_image.draw()
screen.draw.text(
"\n\n".join(random.choice(joke)),
center=(450, 300),
fontname="rabbit_on_the_moon",
fontsize=36,
color="darkorange1",
owidth=1.5,
ocolor="black"
)
play_sound = random.choice(funny_sound)
play_sound.play()
reset_button.draw()
def on_mouse_down(pos, button):
"""
click a button to select a joke category
"""
global joke
if button == mouse.LEFT and buttons[0].collidepoint(pos):
joke = animal_jokes
elif button == mouse.LEFT and buttons[1].collidepoint(pos):
joke = food_jokes
elif button == mouse.LEFT and buttons[2].collidepoint(pos):
joke = silly_jokes
elif button == mouse.LEFT and buttons[3].collidepoint(pos):
joke = school_jokes
elif button == mouse.LEFT and reset_button.collidepoint(pos):
joke = ""
I have now added in more background images, all of which are able to be drawn by just adding them into my list. The following links are for all the additional images and sounds which are now present in my program:
Comedy sign haha Neon laugh emoji ROFL Neon mic Mic Stand Stage Slow Clap Comedy Drums Girl's Laugh
Next Steps
I think I will re-upload all my images/sounds etc. in zip files as evidence, just to make sure I haven't missed anything. I will also finish off my user guide for submission and perhaps email everything back home to see if my son is able to have a go at running/customising the program whilst I'm not there.
I will also not be 100% happy with my program unless I can work out how to make my the entire screen inactive apart from the reset button once the reset button displays, thus forcing the user to reset each time in order to then be able to activate another joke. I am quite happy with how I have progressed so far though.
Nicholas Tollervey ~ 07 Jan 2023 5:16 p.m.
Hi Paul,
It's great to see this progress, and the app is looking and feeling a lot more polished. Well done. I also appreciate the explanations for why you take one approach rather than another. I have a few points of feedback, explanations and questions for you.
- Drawing things in a list. You've inadvertently found something called a list comprehension. It's a way of acting on all the items in a list, to produce a new list. The syntax is as follows:
new_list = [do_something(x) for x in some_other_list]
This is a rather good introductory guide. While you're not assigning the result of your list comprehension, it is being evaluated and you are doing something in the "do_something" part of it... i.e. the background.draw()
call.
The reason you were getting a syntax error is simply because it looked like you were trying to write a list comprehension, but you weren't writing it in the way Python expected (i.e. the syntax was wrong). I hope the article to which I link throws more light on the subject, and please don't hesitate to ask if you want to know more. (Aside: deliberate use of list comprehensions is not expected until grade 4.)
- Please can you attach the font's
.ttf
file please. I think it should berabbit_on_the_moon.ttf
or something like it? - Similarly, I'm not sure I have all the correct files for the images. Zipping up your
images
,sounds
,fonts
andmusic
directories, then uploading them (once you have a final version of the assets), would solve this problem. - Yes please on the user guide..!
- Just my personal view after trying out your project, but don't sweat the reset button. It feels like it's working just fine. You could change the text to "Click screen to reset" or something like that... so you don't have to worry about making the whole screen inactive except for the button. It helps to be pragmatic! 😄
It feels like this is VERY close to being in a place where I can make an assessment, give you a mark and (most importantly) the written feedback about how you've got on. From my point of view, I think I'm waiting on:
- Zip files for all the assets
- Final tidy-ups to your satisfaction.
- Perhaps a description of how you're testing the project at this stage (what does your son think?)
- The user guide for adding new jokes.
- A definitive "final" version of your code.
Keep up the good work..! You're almost there.
Paul Honey ~ 09 Jan 2023 8:47 a.m.
Tying everything together
I think I'm at a point now where I'm happy with everything. I've stopped worrying about disabling the screen before resetting. I think children my son's ago will get some enjoyment from it regardless.
To that end I've emailed both my kids my user guide, which has all the files they need attached in the word document, to get their feedback. Hopefully this'll act as a little product test. My youngest is 10 and my eldest 14, so I've asked him to help his brother if he gets stuck and mum isn't able. I have also told him to have a go at messing around with the code and program on his own though.
There are a bunch of extra images in my user guide, one of which I've added to my generator, swapping out one of the previous images. These images are all just stock pictures I pulled from Word.
I hope everything is present and correct. Please let me know if something seems like it's missing. I'm unsure when the children might get around to trying it out, but if you'd like to wait for their feedback before grading then I can attach it as evidence later on.
I have perhaps been a bit obvious with some of the descriptions within my code, when using the tripple quotes, but this is because I'm hoping it'll make it a little easier for primary school children to navigate around code when broken up into sections with their own headings.
The Code
"""
The "You're Having a Laugh" Joke Generator
"""
import random
WIDTH = 900 # Window size
HEIGHT = 600
joke = False
"""
Section 1 - Backgrounds, popups and sounds
"""
stage = Actor("stage", midtop=(450, 0)) # Background images
neon_mic = Actor("neon_mic", topleft=(0, 195))
mic = Actor("micstand", center=(430, 375))
comedy = Actor("comedy", center=(450, 70))
laugh_emoji = Actor("laugh_emoji", midright=(880, 280))
laugh_emoji.angle = -30
background_images = [stage, comedy, neon_mic, mic, laugh_emoji]
raspberry = Actor("raspberry", topright=(485, 125)) # Randomly generated images
haha = Actor("haha", center=(400,300))
bean = Actor("bean", bottomright=(900, 600))
lol = Actor("lol", center=(375, 300))
rofl = Actor("rofl", center=(430, 400))
funny_image = [raspberry, haha, bean, lol, rofl]
audience_laugh = sounds.laugh1 # Randomly generated sounds
girl_laugh = sounds.laugh2
badum_tish = sounds.drum
slow_clap = sounds.slow_clap
funny_sound = [audience_laugh, girl_laugh, badum_tish, slow_clap]
"""
Section 2 - Joke Lists
Add your own!
"""
animal_jokes = [
[
"How do you tell the difference between a bull and a cow?",
"It is either one or the udder!"
],
[
"Why do hummingbirds hum?",
"Because they don't know the words!"
],
[
"What kind of dog does a magician have?",
"A Labracadabrador!"
],
[
"What do frogs order at fast-food restaurants",
"French flies!"
],
]
food_jokes = [
[
"Which vegetable do sailors hate the most?",
"Leeks!"
],
[
"What do you call a cheese that's not yours?",
"Nacho cheese!"
],
[
"What kind of key opens a banana?",
"A mon-key!"
],
[
"Why do bees have sticky hair?",
"Because they use honeycombs!"
],
]
silly_jokes = [
[
"If you're English in the kitchen and English in the living room,\
\n\nwhat are you in the bathroom?",
"European!"
],
[
"What are mummies favourite lunches?",
"Wraps!"
],
[
"What gives you the power to walk through a wall?",
"A door!"
],
[
"What happens when you wear a snow suit inside?",
"It melts all over the carpet."
],
]
school_jokes = [
[
"Why did the music teacher need a ladder?",
"To reach the high notes."
],
[
"What do elves learn in school?",
"The elf-abet!"
],
[
"Why did the nose not want to go to school?",
"He was tired of getting picked on!"
],
[
"Why did the student eat his homework?",
"Because his teacher told him it would be a piece of cake!"
],
]
"""
Section 3 - Buttons list
Can you think of your own categories?
"""
top_left_button = Actor("button_animals", topleft=(100, 150))
top_right_button = Actor("button_food", topright=(800, 150))
bottom_left_button = Actor("button_silly", bottomleft=(100, 450))
bottom_right_button = Actor("button_school", bottomright=(800, 450))
reset_button = Actor("button_reset", midbottom=(450, 575))
buttons = [top_left_button, top_right_button, bottom_left_button, bottom_right_button]
"""
Section 4 - The code which tells your jokes
"""
def draw():
[backgrounds.draw() for backgrounds in background_images]
[joke_categories.draw() for joke_categories in buttons]
if joke:
"""
After joke category is selected,
display random joke and images,
play random sound.
"""
draw_image = random.choice(funny_image)
draw_image.draw()
screen.draw.text(
"\n\n".join(random.choice(joke)),
center=(450, 300),
fontname="rabbit_on_the_moon",
fontsize=36,
color="darkorange1",
owidth=1.5,
ocolor="black"
)
play_sound = random.choice(funny_sound)
play_sound.play()
reset_button.draw()
def on_mouse_down(pos, button):
"""
click a button to select a joke category
"""
global joke
if button == mouse.LEFT and buttons[0].collidepoint(pos):
joke = animal_jokes
elif button == mouse.LEFT and buttons[1].collidepoint(pos):
joke = food_jokes
elif button == mouse.LEFT and buttons[2].collidepoint(pos):
joke = silly_jokes
elif button == mouse.LEFT and buttons[3].collidepoint(pos):
joke = school_jokes
elif button == mouse.LEFT and reset_button.collidepoint(pos):
joke = ""
Joke_Generator_User_Guide.docx
Paul Honey ~ 09 Jan 2023 11:10 p.m.
Code Adjustment
I've decided to make a slight adjustment to my code, just in the way things are ordered. Originally I hadn't planned on having a section in the guide for customising the various background images, popups and sounds. This is why I included it at the beginning of the code, instead of grouped with the other images. However it has been niggling at me that all the background/popup images, as well as the category buttons, aren't more or less grouped together. Especially now they have instructions in the guide for customisation.
Therefore, I've updated the code and the user guide, and re-uploaded below. I think this will flow better in the user guide for anyone reading it as well.
Code
"""
The "You're Having a Laugh" Joke Generator
"""
import random
WIDTH = 900 # Window size
HEIGHT = 600
joke = False
"""
Section 1 - Joke Lists
Add your own!
"""
animal_jokes = [
[
"How do you tell the difference between a bull and a cow?",
"It is either one or the udder!"
],
[
"Why do hummingbirds hum?",
"Because they don't know the words!"
],
[
"What kind of dog does a magician have?",
"A Labracadabrador!"
],
[
"What do frogs order at fast-food restaurants",
"French flies!"
],
]
food_jokes = [
[
"Which vegetable do sailors hate the most?",
"Leeks!"
],
[
"What do you call a cheese that's not yours?",
"Nacho cheese!"
],
[
"What kind of key opens a banana?",
"A mon-key!"
],
[
"Why do bees have sticky hair?",
"Because they use honeycombs!"
],
]
silly_jokes = [
[
"If you're English in the kitchen and English in the living room,\
\n\nwhat are you in the bathroom?",
"European!"
],
[
"What are mummies favourite lunches?",
"Wraps!"
],
[
"What gives you the power to walk through a wall?",
"A door!"
],
[
"What happens when you wear a snow suit inside?",
"It melts all over the carpet."
],
]
school_jokes = [
[
"Why did the music teacher need a ladder?",
"To reach the high notes."
],
[
"What do elves learn in school?",
"The elf-abet!"
],
[
"Why did the nose not want to go to school?",
"He was tired of getting picked on!"
],
[
"Why did the student eat his homework?",
"Because his teacher told him it would be a piece of cake!"
],
]
"""
Section 2 - Buttons list
Can you think of your own categories?
"""
top_left_button = Actor("button_animals", topleft=(100, 150))
top_right_button = Actor("button_food", topright=(800, 150))
bottom_left_button = Actor("button_silly", bottomleft=(100, 450))
bottom_right_button = Actor("button_school", bottomright=(800, 450))
reset_button = Actor("button_reset", midbottom=(450, 575))
buttons = [top_left_button, top_right_button, bottom_left_button, bottom_right_button]
"""
Section 3 - Backgrounds, popups and sounds
"""
stage = Actor("stage", midtop=(450, 0)) # Background images
neon_mic = Actor("neon_mic", topleft=(0, 195))
mic = Actor("micstand", center=(430, 375))
comedy = Actor("comedy", center=(450, 70))
laugh_emoji = Actor("laugh_emoji", midright=(880, 280))
laugh_emoji.angle = -30
background_images = [stage, comedy, neon_mic, mic, laugh_emoji]
raspberry = Actor("raspberry", topright=(485, 125)) # Randomly generated images
haha = Actor("haha", center=(400,300))
bean = Actor("bean", bottomright=(900, 600))
lol = Actor("lol", center=(375, 300))
rofl = Actor("rofl", center=(430, 400))
funny_image = [raspberry, haha, bean, lol, rofl]
audience_laugh = sounds.laugh1 # Randomly generated sounds
girl_laugh = sounds.laugh2
badum_tish = sounds.drum
slow_clap = sounds.slow_clap
funny_sound = [audience_laugh, girl_laugh, badum_tish, slow_clap]
"""
Section 4 - The code which tells your jokes
"""
def draw():
[backgrounds.draw() for backgrounds in background_images]
[joke_categories.draw() for joke_categories in buttons]
if joke:
"""
After joke category is selected,
display random joke and images,
play random sound.
"""
draw_image = random.choice(funny_image)
draw_image.draw()
screen.draw.text(
"\n\n".join(random.choice(joke)),
center=(450, 300),
fontname="rabbit_on_the_moon",
fontsize=36,
color="darkorange1",
owidth=1.5,
ocolor="black"
)
play_sound = random.choice(funny_sound)
play_sound.play()
reset_button.draw()
def on_mouse_down(pos, button):
"""
click a button to select a joke category
"""
global joke
if button == mouse.LEFT and buttons[0].collidepoint(pos):
joke = animal_jokes
elif button == mouse.LEFT and buttons[1].collidepoint(pos):
joke = food_jokes
elif button == mouse.LEFT and buttons[2].collidepoint(pos):
joke = silly_jokes
elif button == mouse.LEFT and buttons[3].collidepoint(pos):
joke = school_jokes
elif button == mouse.LEFT and reset_button.collidepoint(pos):
joke = ""
Joke_Generator_User_Guide.docx
Nicholas Tollervey ~ 11 Jan 2023 4:01 p.m.
Hi Paul,
I think I have enough evidence to be able to write up an assessment. This is a three step process:
- I write up my assessment.
- A third party checks it, points out corrections or advises on ways I can improve my feedback to you.
- Once the review is approved in step 2, you get your results.
I think you should get your results over the weekend or at the start of next week. 🚀
Paul Honey ~ 18 Jan 2023 3:44 a.m. (updated: 18 Jan 2023 3:47 a.m.)
The Final Product
The below video gives a quick demonstration of the generator in action, with a quick scroll through the code at the start.
The Random Joke Generator