Search code examples
pythonwhile-loopnested-loops

(Python) Trouble making the user input promt another quiz question or break the loop


I'm pretty new to programming, so please pardon me!

***EDIT 2: Ok so this is the full thing. Everything is working fine except when I try to break out of the while enthusiasm is True: loop, I just keep getting more and more questions (the loop keeps running)

I'm building a Python trivia quiz, and I managed all the answer input loop to work (doesn't allow invalid input, breaks the loop succesfully)

I want the program to ask the user "Would you like another question? (y/n)" and stop the program if 'n'.

The problem is no matter what I tried, I keep getting more trivia questions! Thanks in advance

import requests
import pprint
import json
import html
print("Welcome to the ultimate test of knowledge and valour, The Internet Quiz!")
print("You will be given an array of multiple choice questions in general knowledge")
input("Press Enter to start!")

y_n = ["y", "n"]
import random
q_num = 1
score = 0
enthusiasm = True
while enthusiasm is True:
    r = requests.get("https://opentdb.com/api.php?amount=1&category=9&type=multiple")
    question = json.loads(r.text)
    first = question['results'][0]['correct_answer']
    second = question['results'][0]['incorrect_answers'][0]
    third = question['results'][0]['incorrect_answers'][1]
    fourth = question['results'][0]['incorrect_answers'][2]
    print("--------------------------------------------------------")
    print("Question number " + str(q_num)+ ":")
    print(html.unescape(question['results'][0]['question']))
    options = [first,second,third,fourth]
    random.shuffle(options)
    for X in options:
        print(html.unescape(X))
    legend = (
        (options[0], 1),
        (options[1], 2),
        (options[2], 3),
        (options[3], 4)
        )

    error = False
    while error is False:
            
        guess = input("Please enter the number of your answer(1-4):")
        try:
            guess = int(guess)
        except:
            print("Your answer must be a number between 1-4.")
            continue
        if guess <1 or guess > 4:
            print("Your answer must be a number between 1-4.")
            continue
        else:
            error = True

        
        if (first, guess) in legend:
            score += 1
            q_num += 1

            print("Correct! \nCurrent score: " +str(score))
            
            acid = True
            while acid is True:
                yesno=input("Would you like another question? (y/n)")     
                try:
                    yesno = str(yesno.lower())
                except:
                    print("Invalid input. Please enter y/n.")
                    continue
                if yesno.lower() != "y" and yesno.lower() != "n":
                    print("Invalid input. Please enter y/n.")
                    continue
                elif yesno.lower() == "y":
                    break
            
                else:
                    acid=False
                    error=True
                continue
        
        
        
        else:
            print("Incorrect! Better hit the books, buddy! \nCurrent score: " +str(score)) 
            q_num += 1
            acid = True
            while acid is True:
                yesno=input("Would you like another question? (y/n)")     
                try:
                    yesno = str(yesno.lower())
                except:
                    print("Invalid input. Please enter y/n.")
                    continue
                if yesno.lower() != "y" and yesno.lower() != "n":
                    print("Invalid input. Please enter y/n.")
                    continue
                elif yesno.lower() == "y":
                    break
            
                else:
                    acid=False
                    error=True
            continue

Solution

  • You have two while loops:

    while enthusiasm is True:
    

    and

    while error is False
    

    Let's look at what happens when you ask if the user wants another question (simplified a little):

                yesno=input("Would you like another question? (y/n)")     
                if yesno.lower() == "y":
                    break            
                else:
                    error=True
    

    You set error to True, but you do not set enthusiasm to False, so the loop starts again at the top. Looking further, enthusiasm never gets set to False, so that condition will always start over. Simply writing

    else:
        error = True
        enthusiasm = False
    

    would be fine. I also would recommend thinking about if you want two loops, and what the purpose of the enthusiasm variable is.


    There's a lot of other refactoring that can be done here, but not that you probably should write

    while not error:
    

    instead of explicitely checking if error "is" False. Similarly,

    while enthusiasm:
    

    is a good check on a boolean

    Similarly,

                yesno=input("Would you like another question? (y/n)")     
                try:
                    yesno = str(yesno.lower())
                except:
                    print("Invalid input. Please enter y/n.")
                    continue
                if yesno.lower() != "y" and yesno.lower() != "n":
    

    can be improved. You don't need to cast yesno to a string, becuase that's what happens when it comes from input. You don't need the try/except either (you may have taken this from an int cast, elsewhere). Since you've already converted yesno to lower once, you don't need to keep doing that every time you compare it to a y or n.