Python trivia game for one player from the terminal with two possible themes

I’m excited to share my recent project, a Python trivia game for one player from the terminal with two possible themes. I would love to hear your thoughts. I’m particularly interested in getting feedback on improving the class and the methods I used. Thanks!

Project Github: GitHub - codecnt/triviagame

Feel free to also provide feedback on the first technical article:

This is neat, using json to drive your program. Unfortunately, you’re not entirely doing that.

You’ve hard coded the theme choices in the code. You really should be plucking them out of the json data. The program should have no knowledge of what’s in that data, only the structure.

Also, you should only load that source data once: never load it again.

So, we call something like this once, for the entire program:

def load_all_questions():
    with open ('questionsen.json') as json_file_q_en:
        python_dict_q_en = json.load(json_file_q_en)
    return python_dict_q_en["trivia_game"]

Getting a list of available themes should be easy if you know the structure, which you do:

def avail_themes(all_questions):
    return [x['theme'] for x in all_questions]

Or, if you’re unfamiliar with comprehensions:

def avail_themes(all_questions):
    result = []
    for x in all_questions:
        result.append(x['theme'])
    return result

I like that I can enter just a number for the theme. I don’t like that the rest of the time I have to type out the answer.

Here’s a function you could write:

def ask_question(question, choices):
    # returns the choice num, you code here

Running it should look something like:

choices = ['Apples', 'Oranges']
choice = ask_question("What would you like?", choices)
print("you chose", choices[choice])

Result:

What would you like?
1) Apples
2) Oranges
Choice: 4
4 is not a valid choice, please try again.

What would you like?
1) Apples
2) Oranges
Choice: pear
pear is not a valid choice, please try again.

What would you like?
1) Apples
2) Oranges
Choice: 2
you chose Oranges

Once you have your ask_question set up you should find other ways to simplify what you have.

Don’t want to throw any more at you, so good luck and have fun.

2 Likes

Thank you @baavgai, for your detailed feedback! I appreciate the time and effort you’ve taken to review my project. Since this is my very first coding project, I found myself frequently resorting to online resources to understand and implement your feedback.

I find the project’s current version much more organised than my original code – your guidance on loading the source data just once is a valuable insight that I incorporated.

It was a great suggestion to enhance the user experience by creating a function to handle question-asking and choice selection. Your example made it easy to explore the path and implement it.

Thank you once again for your thorough feedback. Your expertise and input have been instrumental in creating a second version of my project trivia3.py - https://github.com/codecnt/triviagame/blob/main/trivia3.py , my original assignment required the use of classes. Still, I can’t see any way it would benefit the project. Your insights would be greatly appreciated.

Cheers,

I find the project’s current version much more organised than my original code

Agreed. Excellent job!

my original assignment required the use of classes. Still, I can’t see any way it would benefit the project.

You are correct. You don’t always need classes and often they’ll offer you little gain.

In this context, I’d use the json to build objects. e.g.

class Theme:
    def __init__(self, raw):
        self.name = raw["theme"]
        self.introduction = raw["introduction"]
        self.sections = [Section(x) for x in raw["sections"]]

class Game:
    def __init__(self, questions_filename = 'questionsen.json'):
        with open(questions_filename, 'r') as fh:
            data = json.load(fh)
            self.themes = [Theme(x) for x in data["trivia_game"]]
        self.player_name = 'Player 1'
        self.chosen_theme = None
        self.done = False

    def start(self):
        self.player_name = 'Alice' # input("Welcome to trivia. Please enter a name for player one and hit enter: ")
        print("Hi, {} If you need to stop the game at any point press ctrl + C".format(self.player_name))
        self.chosen_theme = self.select_theme()

    def select_theme(self):
        # actual code here
        return self.themes[0];

    def theme_choices(self):
        return [x.name for x in self.themes]

    def end_game(self):
        print("Game Over")
        self.done = True

    def play(self):
        # your code here, some quick test code
        self.end_game()


# nice, proper, game loop
game = Game()
game.start()
while not game.done:
    game.play()

You’ll obviously write classes like Section and Question and fill in the blanks.

The fundamental idea here is that your load that json, build internal objects with the logic you want, and never look at that raw json again. The Game instance should have all the game state it needs: themes, player, score, etc.

Your Theme class might have a something like def ask_questions(self): and all the logic can go there. Or it can live elsewhere. The Question class might have a ask method.

Programming becomes a game of organization once you’ve solidified your logic.