0

I want to ask the user if they want to play again using the while loop. This is my code. How can I do it? I am receiving an error if I stack another while loop above my other while. I am not sure if I am doing it right.

QM = ["The average of first 50 natural numbers is _____\na. 25.30\nb. 25.5\nc. 25.00\nd. 12.25\nAnswer: ",
      "A clock strikes once at 1 o’clock, twice at 2 o’clock, thrice at 3 o’clock and so on. How many times will it strike in 24 hours?\na. 78\nb. 136\nc. 156\nd. 196\nAnswer: ",
      "106 × 106 – 94 × 94 = ?\na. 2004\nb. 2400\nc. 1904\nd. 1906\nAnswer: ",
      "Which of the following numbers gives 240 when added to its own square?\na. 15\nb. 16\nc. 18\nd. 20\nAnswer: ",
      "If David’s age is 27 years old in 2011. What was his age in 2003?\na. 17 years\nb. 37 years\nc. 20 years\nd. 19 years\nAnswer: ",
      "What is 7% equal to?\na. 0.007\nb. 0.07\nc. 0.7\nd. 7\nAnswer: ",
      "I am a number. I have 7 in the ones place. I am less than 80 but greater than 70. What is my number?\na. 71\nb. 73\nc. 75\nd. 77\nAnswer: ",
      "How many years are there in a decade?\na. 5\nb. 10\nc. 15\nd. 20\nAnswer: ",
      "What is the square of 15?\na. 15\nb. 30\nc. 252\nd. 225\nAnswer: ",
      "In a century how many months are there?\na. 12\nb. 120\nc. 1200\nd. 12,000\nAnswer: ",
      "If a number has an even number or zero at its unit place; the number is always divisible by ____\na. 2\nb. 5\nc. 3\nd. 7\nAnswer: ",
      "An acute angle is ____\na. 90 degree.\nb. less than 90 degree.\nc. more than 90 degree.\nd. None of these.\nAnswer: ",
      "What is the opposite of 6?\na. 6\nb. 5\nc. 4\nd. -6\nAnswer: ",
      "Absolute value of -20 or |-20| is ________\na. 0\nb. -20\nc. |-20|\nd. 20\nAnswer: ",
      "Which of these following set of numbers are factors of 24?\na. 2, 3, 4, 6, 8\nb. 1, 5, 12, 18\nc. 4, 7, 24\nd. 3, 9, 12\nAnswer: "
      ]

questionsEM = [
    Question(QM[0], "b"),
    Question(QM[1], "c"),
    Question(QM[2], "b"),
    Question(QM[3], "a"),
    Question(QM[4], "d"),
    Question(QM[5], "b"),
    Question(QM[6], "d"),
    Question(QM[7], "b"),
    Question(QM[8], "d"),
    Question(QM[9], "c"),
    Question(QM[10], "a"),
    Question(QM[11], "b"),
    Question(QM[12], "d"),
    Question(QM[13], "d"),
    Question(QM[14], "a"),
]

print("=====QUIZ APPLICATION=====")
print ("=====INSTRUCTION====")
print ("""Every subject, they have their own difficulties. Every difficulties consists of 10 questions.
The difficulties are: Easy, Medium, and Hard.""")
print ("THE SUBJECTS FOR THE QUIZ ARE:")

I want to start here the program again if the user wanted to play again.

    print("1. Math")
    print ("2. English")
    print ("3. Science")
    while True:
        subj = input("Choose a subject by typing the number: ")
        subj = int(subj)
        if subj > 3:
            print("The number does not define the subject.")
            continue
        else:
            if subj == 1:
                print("===================================")
                print("You have chosen the subject Math")
                print("First difficulty will be EASY.")
                print("Let's proceed to the quiz! GOOD LUCK!\n")
                def run_EM(questionsEM):
                    score = 0
                    random.shuffle(questionsEM)
                    for question in questionsEM[:10]:
                        answer = input(question.prompt).lower()
                        if answer == question.answer:
                            score += 1
                            print("Correct")
                        else:
                            print("Wrong")
                            print("You got " + str(score) + "/" + str(10) + " correct")
                            print("Game Over! You did not passed the easy level")

Ask if the user want to play again

                         #again = str(input("Do you want to play again? [Y] / [N]: "))
                         #if again == "N" or "n":
                               break
                        if score == 10:
                            print("You got " + str(score) + "/" + str(10) + " correct")
                            print("==============================")
                            print("YOU MOVED ON FROM EASY LEVEL. LET'S GO FOR THE MEDIUM LEVEL. STARTING NOW.....")
                            print("==============================")
                            import QuestionMM
                run_EM(questionsEM)
                break
  • Could provide the entire code? It is hard to understand. – Mazen Jun 13 '21 at 13:58
  • Edited the code. I just included the Math question and Answer since I only show the condition if the subj is equals to 1. – candy mincy Jun 13 '21 at 14:01
  • So you are trying to exit the while loop when the user inputs again as N or n, correct? – Mazen Jun 13 '21 at 14:02
  • How about if you declare a variable at the start of the code `check = True` and put `while check:`. At the end of the code you can ask : Do you want to play again. If they Answer No then u can pass check as False or else Itll just loop again – Aryan Garg Jun 13 '21 at 14:03
  • @Mazen yes. I want to end the program if the user selects "n" and if "y", i want to start the loop starting in the print ("Math") print ("Science") print ("English") – candy mincy Jun 13 '21 at 14:05
  • Regarding code structure--why are you defining a function inside a conditional --hardly ever, if ever a good practice and makes the code confusing? Also, why are you importing in an if condition--also confusing? – DarrylG Jun 13 '21 at 14:05
  • @AryanGarg I'll try it. Thanks. :) – candy mincy Jun 13 '21 at 14:05
  • See also https://stackoverflow.com/questions/23294658/asking-the-user-for-input-until-they-give-a-valid-response?r=SearchResults – tripleee Jun 13 '21 at 14:07

2 Answers2

1

Your bug was this:

if again == "N" or "n":

your if condition has two conditions: again == "N" or "n". again == "N" is a valid condition which could be True if again equals "N" and False if again is equal to anything else. However, your second condition "n" will always be True as conditioning on a string that isn't empty ("") will yield to True condition.

import QuestionMM
def run_EM(questionsEM):
    score = 0
    random.shuffle(questionsEM)
    for question in questionsEM[:10]:
        answer = input(question.prompt).lower()
        ...
        again_request = str(input("Do you want to play again? [Y] / [N]: "))
        if again_request == "N" or again_request == "n":
            return False
        ...
    return True
QM = [...]
questionsEM = [...]
...
again = True
while again:
    subj = input("Choose a subject by typing the number: ")
    subj = int(subj)
    if subj > 3:
        print("The number does not define the subject.")
        continue
    else:
        if subj == 1:
            ...
            again = run_EM(questionsEM)

UPDATE

After looking at your code again, it seems that you have another issue which is you are setting again value inside a function, so you would need to return a value for the while loop to stop. I have updated the code accordingly.

Thanks @DarrylG for the feedback!

Mazen
  • 486
  • 4
  • 8
  • 1
    I'm not downvoting since you're correct about the if condition. However, an answer should not repeat the poster's extremely bad coding style of having the function definition and an import within their if condition but provide the cleaner alternative. – DarrylG Jun 13 '21 at 14:15
  • 1
    Better (thus my upvote), but you may also want to add `import QuestionMM` at the top to show the poster where imports go normally. – DarrylG Jun 13 '21 at 14:30
  • This helps me! Thanks! I figured it out. – candy mincy Jun 13 '21 at 15:10
  • Awesome! Could you set my answer as the answer to your question? Thanks! – Mazen Jun 13 '21 at 15:11
0

The use of break in the while loop when the user don't want to perform the game again is good. Another way you can do this is as follows:

playAgain = True
while playAgain:
    # Game body here
    ans = str(input("Do you want to play again? [Y] / [N]: "))
    if (ans == "N") or (ans == "n"):
        playAgain = False

Also, as much as possible, don't try to define your functions inside an if condition, just call it and define it outside the calling function.

niconnex
  • 21
  • 6