Python Terminal Game, Knock Knock Jokes - Help Wanted!

Hi guys, I’m creating my first terminal game. It’s to be a fun little Knock Knock Terminal game, where you choose the category of jokes, and then code will randomly output Knock Knock jokes that you can interact with.

I’m trying to go through the jokes and have them be randomly chosen with the ‘random’ module, but am not having any luck with finding where my error is. If you could please give it a look and point me in the right direction. Please and Thank you!

import random
# this module will allow a random joke to be selected



# Knock Knock Class
class KnockKnockJokes:
    def __init__(self, player1, category):
        self.player1 = player1
        self.category = category
    
    def __repr__(self):
        message = f"So you've chosen to do the most bamboozlin of {self.category} Knock Knock Jokes! Very well, we shall begin!"
        return message
    
    def InitalKnock(self):
        print("\nKnock Knock...")

    # NEED TO FIGURE OUT HOW TO GET THIS PART TO WORK NEEP TO LOOP THROUGH DICTIONARIES AND GET THE JOKE
    def whosThere(self, response, jokes):
        lc_response = response.lower()

        # chooses a random joke
        chosen_joke = random.choice(jokes)
        punchline = chosen_joke['punchline']

        if lc_response == str and (response == "whos there?" or "whos there"):
            return punchline
        else:
            return "Pssssttttt!!! You're supposed to say, 'Who's there?' >.<"
    
    def punchline(self, who_response, punchline_pt1, final_punchline):
        if who_response == f"{punchline_pt1} who?":
            return final_punchline + "Ba Dum Ta Tss!"
        else:
            return "Pretend you're an owl and say, who?"

# the ANimal Jokes
animal_jokes = [
    {'punchline':'Moose', "final_punchline":'Moose you bein\' so nosy!'},
    {'punchline':'Poodle', "final_punchline":'Poodle a lil mustard on my hot dog please!'},
    {'punchline':'Iguana', "final_punchline":'Iguana hold your hand.'},
    {'punchline':'Goat', "final_punchline":'Goat to the door and find out!'},
    {'punchline':'Alpaca', "final_punchline":'Alpaca the trunk, you pack-a the suitcase!'}
    ]

# The Food jokes
food_jokes = [
    {'punchline':'Peas', "final_punchline":'Peas to meet you!'},
    {'punchline':'Potatoes', "final_punchline":'Potatoes don\'t have a last name silly!'},
    {'punchline':'Ice-cream Soda', "final_punchline":'ICE SCREAM SODA WHOLE WORLD CAN HEAR ME!'},
    {'punchline':'Muffin', "final_punchline":'Theres muffin the matter with me. I\'m doing fine!'},
    {'punchline':'Butter', "final_punchline":'Butter bring an umbrella - it looks like it\'s rainin\'!'}
]

# The spooky jokes
spooky_jokes = [
    {'punchline':'Harry', "final_punchline":'Harry spider crawling up your back!'},
    {'punchline':'Ivana', "final_punchline":'Ivana suck your blood!'},
    {'punchline':'Ooze', "final_punchline":'Ooze that monster under yer bed!'},
    {'punchline':'Howie', "final_punchline":'Howie gonna hide this dead body?'},
    {'punchline':'Doughnut', "final_punchline":'Doughnut worry, I shall give yer a swift death!'}
]

# the random jokes
out_of_this_world_jokes = [
    {'punchline':'Ash', "final_punchline":'Sounds like you have a cold!'},
    {'punchline':'Sadie', "final_punchline":'Sadie magic word and watch me disappear!'},
    {'punchline':'Cash', "final_punchline":'No thanks, I\'ll have some peanuts.'},
    {'punchline':'Luke', "final_punchline":'Luke through the peephole and find out!'},
    {'punchline':'Roach', "final_punchline":'Roach you an email last week and i\'m still waiting for a response.'}
]

# PLayer & Welcome
player = input("\nWelcome to the World of Knock Knock Jokes! Now please tell us, who is there?\n")
joke_categories = ['Animal', 'Food', 'Spooky', 'Out of this WORLD!']
print(f"\nNow, {player}, from the categories shown, please choose your category:")
for joke in joke_categories:
    print(joke)

player_category = input("\nChoose wisely.... ")

print("\nExcellent Choice!\n")



# makes sure ot lowercase whatever was typed by player
category_lowercase = player_category.lower()
if category_lowercase == "animal":
    animal_player = KnockKnockJokes(player, player_category)
    print(animal_player)
    # The game begins
    animal_player.InitalKnock()
    # the player responds
    player_response = input()
    # respond to the player's 'whos there'
    animal_player.whosThere(player_response, animal_jokes)

Hi Codew.jaz,

This is pretty cool code. If you add a print statement to the last line you’ll see some output.

   animal_player.whosThere(player_response, animal_jokes)

However, once the punchline is returned, the program terminates.

There are a few things you should consider.

  1. You should implement some logic to handle If the user inputs an incorrect category.
  2. You should consider storing all jokes in a one dictionary for easier lookup.

I hope you do not mind, I refactored your code a little to show you what I mean.

import random
import time

jokes = {

    'animal': [
        {'punchline': 'Moose', "final_punchline": 'Moose you bein\' so nosy!'},
        {'punchline': 'Poodle', "final_punchline": 'Poodle a lil mustard on my hot dog please!'},
        {'punchline': 'Iguana', "final_punchline": 'Iguana hold your hand.'},
        {'punchline': 'Goat', "final_punchline": 'Goat to the door and find out!'},
        {'punchline': 'Alpaca', "final_punchline": 'Alpaca the trunk, you pack-a the suitcase!'}
    ],
    'food': [
        {'punchline': 'Peas', "final_punchline": 'Peas to meet you!'},
        {'punchline': 'Potatoes', "final_punchline": 'Potatoes don\'t have a last name silly!'},
        {'punchline': 'Ice-cream Soda', "final_punchline": 'ICE SCREAM SODA WHOLE WORLD CAN HEAR ME!'},
        {'punchline': 'Muffin', "final_punchline": 'Theres muffin the matter with me. I\'m doing fine!'},
        {'punchline': 'Butter', "final_punchline": 'Butter bring an umbrella - it looks like it\'s rainin\'!'}
    ],
    'spooky': [
        {'punchline': 'Harry', "final_punchline": 'Harry spider crawling up your back!'},
        {'punchline': 'Ivana', "final_punchline": 'Ivana suck your blood!'},
        {'punchline': 'Ooze', "final_punchline": 'Ooze that monster under yer bed!'},
        {'punchline': 'Howie', "final_punchline": 'Howie gonna hide this dead body?'},
        {'punchline': 'Doughnut', "final_punchline": 'Doughnut worry, I shall give yer a swift death!'}
    ],
    'otw': [
        {'punchline': 'Ash', "final_punchline": 'Sounds like you have a cold!'},
        {'punchline': 'Sadie', "final_punchline": 'Sadie magic word and watch me disappear!'},
        {'punchline': 'Cash', "final_punchline": 'No thanks, I\'ll have some peanuts.'},
        {'punchline': 'Luke', "final_punchline": 'Luke through the peephole and find out!'},
        {'punchline': 'Roach', "final_punchline": 'Roach you an email last week and i\'m still waiting for a response.'}
    ]
}


class KnockKnockJokes:
    # Make categories list a Class attribute
    CATEGORIES = ['Animal', 'Food', 'Spooky', 'OTW (Out of this WORLD!)']

    def __init__(self):
        self.category = None
        # a username should not be an attribute perhaps?

    def get_joke_category(self) -> list:
        """Retrieves and returns a list of the selected joke categories"""
        print(f"Please choose your category:")
        for joke in KnockKnockJokes.CATEGORIES:
            print(f'\t- {joke}')
        player_category = input("\nChoose wisely....\n> ")
        # This returns a list of the selected joke categories
        self.category = player_category
        return jokes.get(player_category)

    def initialize_joke(self):
        """Initialize joke function, handles all the logic of the program"""
        player = input("\nWelcome to the World of Knock Knock Jokes! Now please tell us, who is there?\n> ")
        print(f"\nNow, {player}, from the categories shown, please choose your category:")

        # Main loop for continuous play
        while True:
            # Get joke category
            selected_category: list = self.get_joke_category()
            # (!) NOTE: the jokes are being selected by the key value the user inputs.
            # Therefore, the user must enter the correct dictionary key of each category in the joke
            # dictionary - (i.e., animal, food, spooky, otw). You should include this in the instructions.

            # Now select one random joke from list:
            joke: dict = random.choice(selected_category)
            message = f"So you've chosen to do the most bamboozlin of {self.category} Knock Knock Jokes! Very well, we shall begin!"
            print(message)

            # Begin knock-knock joke
            print('Knock knock...')
            while True:
                user_input = input('> ')
                if user_input not in ['whos there?', 'whos there']:
                    print("Pssssttttt!!! You're supposed to say, 'Who's there?' >.<")
                    # If the input value is incorrect, Continue to ask for input
                    continue
                else:
                    punchline = joke['punchline']
                    print(punchline)
                    # Second while loop to validate next input from user:
                    while True:
                        user_input = input('> ')
                        if user_input != f'{punchline} who':
                            print('Enter punuchline + "who"')
                            # If the input value is incorrect, Continue to ask for input
                            continue
                        else:
                            print(joke['final_punchline'] + '\n')
                            # A little delay to read the final punchline
                            time.sleep(2)
                            # Break from second while loop
                            break

                # breaking from main loop
                break


if __name__ == '__main__':
    joke = KnockKnockJokes()
    print(joke.initialize_joke())

Screen shot

There are probably some glitches and bugs in this code. Let me know if you have any further questions or comments.

Best regards,

1 Like

Hi Seraph776!

I love what you’ve done with my code and thank you for the tips!!
I took a break from looking at it and came back a few days later to finally figure some things out!

This is the changed/updated code that I had come up with.

# File finally acting as it should
import random
# this module will allow a random joke to be selected



# Knock Knock Class
class KnockKnockJokes:
    def __init__(self, player1, category):
        self.player1 = player1
        self.category = category
    
    def __repr__(self):
        # message initiated for the player
        message = f"So you've chosen to do the most bamboozlin of {self.category} Knock Knock Jokes! Very well, we shall begin!"
        return message
    
    def InitalKnock(self):
        # First set of Knock kNock
        print("\nKnock Knock...")
        # the player responds
        self.response = input() # added to the class instead of being out of it

    def finishTheJoke(self, jokes):
        lc_response = self.response.lower()

        # chooses a random joke
        chosen_joke = random.choice(jokes)
        # gets the first punchline to choosen joke / self added so it can be accessed
        punchline = chosen_joke[0]
        final_punchline = chosen_joke[1]
        if self.response == "whos there?" or self.response == "whos there":
            print(punchline) #changed from return to print
        else:
            print("Pssssttttt!!! You're supposed to say, 'Who's there?' >.<")
    
        who_response = input()
        lc_whoRsp = who_response.lower()
        if (lc_whoRsp ==  f"{punchline.lower()} who?") or (lc_whoRsp == f"{punchline.lower()} who"):
            print(f"{final_punchline}\nBa Dum Ta Tss!")
        else:
            print("Pretend you're an owl and say, who! Try Again!")

# the ANimal Jokes
animal_jokes = [
    ['Moose', 'Moose you bein\' so nosy!'],
    ['Poodle', 'Poodle a lil mustard on my hot dog please!'],
    ['Iguana', 'Iguana hold your hand.'],
    ['Goat', 'Goat to the door and find out!'],
    ['Alpaca', 'Alpaca the trunk, you pack-a the suitcase!']
    ]

# The Food jokes
food_jokes = [
    ['Peas', 'Peas to meet you!'],
    ['Potatoes', 'Potatoes don\'t have a last name silly!'],
    ['Ice-cream Soda', 'ICE SCREAM SODA WHOLE WORLD CAN HEAR ME!'],
    ['Muffin', 'Theres muffin the matter with me. I\'m doing fine!'],
    ['Butter', 'Butter bring an umbrella - it looks like it\'s rainin\'!']
]

# The spooky jokes
spooky_jokes = [
    ['Harry', 'Harry spider crawling up your back!'],
    ['Ivana', 'Ivana suck your blood!'],
    ['Ooze', 'Ooze that monster under yer bed!'],
    ['Howie', 'Howie gonna hide this dead body?'],
    ['Doughnut', 'Doughnut worry, I shall give yer a swift death!']
]

# the random jokes
out_of_this_world_jokes = [
    ['Ash', 'Sounds like you have a cold!'],
    ['Sadie', 'Sadie magic word and watch me disappear!'],
    ['Cash', 'No thanks, I\'ll have some peanuts.'],
    ['Luke', 'Luke through the peephole and find out!'],
    ['Roach', 'Roach you an email last week and i\'m still waiting for a response.']
]

# PLayer & Welcome
player = input("\nWelcome to the World of Knock Knock Jokes! Now please tell us, who is there?\n")
joke_categories = ['Animal', 'Food', 'Spooky', 'Out of this WORLD!']
print(f"\nNow, {player}, from the categories shown, please choose your category:")
for joke in joke_categories:
    print(joke)

player_category = input("\nChoose wisely.... ")

print("\nExcellent Choice!\n")



# makes sure ot lowercase whatever was typed by player
category_lowercase = player_category.lower()
if category_lowercase == "animal":
    animal_player = KnockKnockJokes(player, player_category)
    print(animal_player)
    # The game begins
    animal_player.InitalKnock()
    # respond to the player's 'whos there' and finish the joke
    animal_player.finishTheJoke(animal_jokes)

if category_lowercase == "food":
    food_player = KnockKnockJokes(player, player_category)
    print(food_player)
    # The game begins
    food_player.InitalKnock()
    # respond to the player's 'whos there' and finish the joke
    food_player.finishTheJoke(food_jokes)

if category_lowercase == "spooky":
    spooky_player = KnockKnockJokes(player, player_category)
    print(spooky_player)
    # The game begins
    spooky_player.InitalKnock()
    # respond to the player's 'whos there' and finish the joke
    spooky_player.finishTheJoke(spooky_jokes)

if category_lowercase == "out of this world":
    out_of_this_world_player = KnockKnockJokes(player, player_category)
    print(out_of_this_world_player)
    # The game begins
    out_of_this_world_player.InitalKnock()
    # respond to the player's 'whos there' and finish the joke
    out_of_this_world_player.finishTheJoke(out_of_this_world_jokes)

Couple of things I realized about my code:

  1. I tried to implement a while loop because I knew that if someone inputted the wrong thing or completed the joke, it would just terminate. So I tried putting that in various places, but couldn’t find the correct one which resulted in my code glitching multiple times.

  2. I realized I could probably put elif after the first if statement instead of just multiple if statements

  3. I like how you managed to make the dictionaries work. I had a lot of trouble with that one, and after tinkering around and doing some research, I came across the fact of just having them be lists instead of dictionaries. It made it easier for me to use the random module on the jokes.

  4. This code works really well in VSCode (aside from the fact it terminates quickly without the loop), however, when I try to run the file outside of that editor, it terminates immediately after the first punchline gets replied to. Do you have any idea as to why that may be? If not, that is okay! I will be researching that on my own as well to try and find it out!

Again, Thank you!

I am glad I could help! You’re final code looks great!

You mentioned:

it terminates immediately after the first punchline gets replied to.

Did you mean the final_punchline? From my perspective, our code completes the joke; however, cuts off after the final punchline is delivered. To resolve this, just enclose the block of code in a while loop:

# Your code:

# PLayer & Welcome
player = input("\nWelcome to the World of Knock Knock Jokes! Now please tell us, who is there?\n")

# Put a while loop here for continous game play:
# (!) NOTE: You should add some logic for the user to break the the loop
while True:
    joke_categories = ['Animal', 'Food', 'Spooky', 'Out of this WORLD!']
    print(f"\nNow, {player}, from the categories shown, please choose your category:")
    for joke in joke_categories:
        print(joke)

    player_category = input("\nChoose wisely.... ")
    print("\nExcellent Choice!\n")

Does this resolve your issue of the program terminating after the punchline? If you have any questions, please don’t hesitate to ask. Again, great job with your code!