3
\$\begingroup\$

I have been trying to make a simple "quiz" program in Python. What I plan to make is, say, a quiz of 3 rounds and each round having 3 questions. And at the end of the every round, the program will prompt the user to go for the "bonus" question or not.

print("Mathematics Quiz")
question1 = "Who is president of USA?"
options1 = "a.Myslef\nb. His dad\nc. His mom\nd. Barack Obama\n"
print(question1)
print(options1)

while True:
    response = input("Hit 'a', 'b', 'c' or 'd' for your answer\n")

    if response == "d":
        break
    else:
        print("Incorrect!!! Try again.")

        while True:
            response = input("Hit 'a', 'b', 'c' or 'd' for your answer\n")

            if response == "d":
                stop = True
                break
            else:
                print("Incorrect!!! You ran out of your attempts")
                stop = True
                break
        if stop:
            break

# DO the same for the next questions of your round (copy-paste-copy-paste).
# At the end of the round, paste the following code for the bonus question.

# Now the program will ask the user to go for the bonus question or not

while True:
    bonus = input("Would you like to give a try to the bonus question?\nHit 'y' for yes and 'n' for no.\n")

    if bonus == "y":
        print("Who invented Facebook?")
        print("a. Me\nb. His dad\nc. Mark Zuckerberg\nd. Aliens")

        while True:
            response = input("Hit 'a', 'b', 'c' or 'd' for your answer\n")

            if response == "c":
                break
            else:
                print("Incorrect!!! Try again.")

            while True:
                response = input("Hit 'a', 'b', 'c' or 'd' for your answer\n")


                if response == "c":
                    stop = True
                    break
                else:
                    print("Incorrect!!! You ran out of your attempts")
                    stop = True
                    break
            if stop:
                break
        break
    elif bonus == "n":
        break
    else:
        print("INVALID INPUT!!! Only hit 'y' or 'n' for your response")

# Now do the same as done above for the next round and another bonus question.

Now this code is very long for a single question and I don't think this is the "true" programming. I don't want to copy-paste it again and again. I was wondering is there any way to shorten the code using class or defining functions or something like that?

\$\endgroup\$
0

4 Answers 4

4
\$\begingroup\$
import string

NUMBER_OF_ATTEMPTS = 2
ENTER_ANSWER = 'Hit %s for your answer\n'
TRY_AGAIN = 'Incorrect!!! Try again.'
NO_MORE_ATTEMPTS = 'Incorrect!!! You ran out of your attempts'

def question(message, options, correct, attempts=NUMBER_OF_ATTEMPTS):
    '''
    message - string 
    options - list
    correct - int (Index of list which holds the correct answer)
    attempts - int
    '''
    optionLetters = string.ascii_lowercase[:len(options)]
    print message
    print ' '.join('%s: %s' % (letter, answer) for letter, answer in zip(optionLetters, options))
    while attempts > 0:
        response = input(ENTER_ANSWER % ', '.join(optionLetters)) # For python 3
        #response = raw_input(ENTER_ANSWER % ', '.join(optionLetters)) # For python 2
        if response == optionLetters[correct]:
            return True
        else:
            attempts -= 1
            print TRY_AGAIN

    print NO_MORE_ATTEMPTS
    return False


print("Mathematics Quiz")

# question1 and question2 will be 'True' or 'False' 
question1 = question('Who is president of USA?', ['myself', 'His Dad', 'His Mom', 'Barack Obama'], 3)
question2 = question('Who invented Facebook?', ['Me', 'His Dad', 'Mark Zuckerberg', 'Aliens', 'Someone else'], 2)

I'm not sure which python you are using. Try both line 20 or line 21 to see which works best for you.

Overall this function allows you to enter in questions with as many responses as you want and it will do the rest for you.

Good luck.

\$\endgroup\$
3
  • \$\begingroup\$ Thank you. It worked. Only I had to change string.lowercase to string.ascii_lowercase since I am using Python 3x. I think I need some good practice with defining functions. \$\endgroup\$
    – Preetika Sharma
    Feb 17, 2013 at 14:32
  • \$\begingroup\$ Good spot, I updated my answer. Seems both Python 2 and 3 have ascii_lowercase, but lowercase got removed in 3. Indeed use functions where ever you can. \$\endgroup\$
    – Mark
    Feb 17, 2013 at 14:56
  • \$\begingroup\$ You still skipped the print parentheses at these places: print(message), print statement below that, print statements after attempts -=1. I apologize for not mentioning them before. \$\endgroup\$ Feb 17, 2013 at 16:03
3
\$\begingroup\$

You can also use dictionary to prepare questions and then simply ask them in some order (random in this case):

import random

# Dictionary of questions and answers

questions = {
            'Who is president of USA?':
            ('\na. Myslef\nb. His dad\nc. His mom\nd. Barack Obama\n', 'd'),
            'What is the capital of USA?':
            ('\na. Zimbabwe\nb. New York\nc. Washington\nd. Do not exist', 'c')
            }

def ask_question(questions):
    '''Asks random question from 'questions 'dictionary and returns
       players's attempt and correct answer.'''

    item = random.choice(list(questions.items()))
    question = item[0]
    (variants, answer) = item[1]
    print(question, variants)
    attempt = input('\nHit \'a\', \'b\', \'c\' or \'d\' for your answer\n')
    return (attempt, answer)

# Questions loop
tries = 0
for questions_number in range(5):
    while True: # Asking 1 question
        attempt, answer = ask_question(questions)
        if attempt not in {'a', 'b', 'c', 'd'}:
            print('INVALID INPUT!!! Only hit \'y\' or \'n\' for your response')
        elif attempt == answer:
            print('Correct')
            stop_asking = False
            break
        elif tries == 1: # Specify the number of tries to fail the answer        
            print('Incorrect!!! You ran out of your attempts')
            stop_asking = True
            break
        else:
            tries += 1
            print('Incorrect!!! Try again.')
    if stop_asking:
        break

You can use this as template and modify code a bit to add bonus check or just enclose part of loop in another function which will be called in main loop.

Plus with minor edit you can import questions and answers from text file.

\$\endgroup\$
1
\$\begingroup\$
asking = True
attempts = 0
while asking == True:
    response = input("Hit 'a', 'b', 'c' or 'd' for your answer\n")

    if response == "d":
        asking = False
    else:
        if attempts < 1: # 1 = Max Attempts
            print("Incorrect!!! Try again.")
            attempts += 1
        else:
            print("Incorrect!!! You ran out of your attempts")
            asking = False

The second part follows the same pattern and serves as a good exercise.

The main thing here is to note you're chaining while loops to loop, instead of actually letting the while loop loop. :)

\$\endgroup\$
4
  • \$\begingroup\$ Yeah, but still I have to copy-paste the code for every question, don't I? \$\endgroup\$
    – Preetika Sharma
    Feb 17, 2013 at 12:44
  • \$\begingroup\$ @PreetikaSharma Look into functions, I gave you a link in the comments to your question. \$\endgroup\$
    – Jonas Wielicki
    Feb 17, 2013 at 12:45
  • \$\begingroup\$ Just parametrize what varies for each question and move it into a function, as suggested. \$\endgroup\$ Feb 17, 2013 at 12:48
  • \$\begingroup\$ @JonasWielicki Oops, I thought, that was just the comment. Let me see now. \$\endgroup\$
    – Preetika Sharma
    Feb 17, 2013 at 12:49
0
\$\begingroup\$

As Jonas Wielicki said, your best option would be to use functions.

However, you can shorten the code first to the answer Javier Villa gave:

 asking = True
 attempts = 0
 while asking == True:
     response = input("Hit 'a', 'b', 'c' or 'd' for your answer\n")

     if response == "d":
         asking = False
     else:
         if attempts < 1: # 1 = Max Attempts
             print("Incorrect!!! Try again.")
             attempts += 1

         else: print("Incorrect!!! You ran out of your attempts")
             asking = False

For more tips on improving the speed and performance, see performance tips.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.