# Simple quiz program

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:

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

while True:

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("a. Me\nb. His dad\nc. Mark Zuckerberg\nd. Aliens")

while True:

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

while True:

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?

import string

NUMBER_OF_ATTEMPTS = 2
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.

• 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. – Preetika Sharma Feb 17 '13 at 14:32
• 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. – Mark Feb 17 '13 at 14:56
• 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. – Preetika Sharma Feb 17 '13 at 16:03

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')
}

'''Asks random question from 'questions 'dictionary and returns

item = random.choice(list(questions.items()))
question = item[0]
print(question, variants)

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

asking = True
attempts = 0

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


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. :)

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

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