Level 2 Python: Creating Your Own Quiz

Welcome to the first Level 2 Python post! 

Level 2 Python projects are projects meant for those who have a grasp on the basics of Python already. If you are familiar with most of the Super Simple Python projects and can do each of them in under 30 minutes, you’re ready to go. The goal of the Level 2 Python projects is to get you familiar with using well known Python libraries, building more logically complex applications, and learning API development.

In this post, we’ll go over how to create your own quiz application. This covers the “building more logically complex applications” part of Level 2 Python. Before we get into the code make sure you have a solid understanding of the basics of Python classes. For this project we’ll make two classes – Question and Quiz – and two methods – make_quiz and take_quiz

Making The Question Class

Let’s think about this. What should go into a quiz question? This will be a multiple choice quiz, so a Question class should have a question, and some answer choice. In this example, we’ll just assume that it has four answer choices, but you can set this up with however many answer choices you’d like. We should also know what the correct answer to the question is. We’ll pass all of these as parameters to the constructor.

What else should we be able to do with a question? How about being able to verify if an answer is correct? Let’s create a method that checks if the passed in answer is the correct answer. It’ll take answer as a parameter and compare it to the answer we stored in the correct answer instance attribute.

# Question Class
class Question:
    # requires a question, four answer choices, and which one is correct
    def __init__(self, question: str, a: str, b: str, c: str, d: str, correct: str):
        self.question = question
        self.a = a
        self.b = b
        self.c = c
        self.d = d
        self.correct = correct
   
    def is_right(self, answer):
        if answer == self.correct:
            return True
        else:
            return False

That’s all we need in a question, let’s move on to what should go into a Quiz.

Making The Quiz Class

What should go into a Quiz? Let’s initialize it with questions and answers. We should expect questions in the form of a dictionary. This is purely a design choice, you may also accept your questions in the form of a list. If you do so, you’ll need to make some minor changes in the way the give_quiz works. I chose a dictionary for a safe way to match it to answers by index. If we want to extend the class into the ability to delete questions, this will be important.
At the bare minimum our Quiz class should have a way to access the number of questions, add questions, give the quiz, and score the quiz. Here I’ve used an annotation to declare that num_questions is a property. This means we will be able to call it without the () usually put at the end of method calls.

# Quiz Class
class Quiz:
    def __init__(self, questions:dict = {}):
        self.questions = questions
        self.answers = {}
       
    @property
    def num_questions(self):
        return len(self.questions)
 
    def add_question(self, question: Question):
        index = self.num_questions
        self.questions[index] = question

Giving and Scoring the Quiz

Now that we’ve made a way to create the quiz and add questions, let’s create a way to give the quiz and score the quiz. For the give_quiz function, we’ll just loop through each of the Question items in our Quiz questions. For each of the questions, we’ll print out the question and answer choices. Then we’ll ask the users what they’re answer choice is and save that in the answers dictionary we created.

For scoring the quiz, all we have to do is keep track of the number of correct questions and use the is_right() function from the Question item to see if the recorded answer matches the correct one.

     def give_quiz(self):
        for index, question in self.questions.items():
            print(question.question)
            print(f"A: {question.a}")
            print(f"B: {question.b}")
            print(f"C: {question.c}")
            print(f"D: {question.d}")
            answer = input("Type Your Answer Here: ")
            self.answers[index] = answer
 
    def score(self):
        num_questions = self.num_questions
        num_correct = 0
        for index in range(num_questions):
            question = self.questions[index]
            answer = self.answers[index]
            if question.is_right(answer):
                num_correct += 1
        return f"You scored {num_correct} out of {num_questions}"

That is all there is to a basic Quiz, now let’s make a way to ask users for questions they want to add to the Quiz and take it. The full code for the Quiz class should look like this:

# Quiz Class
class Quiz:
    def __init__(self, questions:dict = {}):
        self.questions = questions
        self.answers = {}
       
    @property
    def num_questions(self):
        return len(self.questions)
 
    def add_question(self, question: Question):
        index = self.num_questions
        self.questions[index] = question
 
     def give_quiz(self):
        for index, question in self.questions.items():
            print(question.question)
            print(f"A: {question.a}")
            print(f"B: {question.b}")
            print(f"C: {question.c}")
            print(f"D: {question.d}")
            answer = input("Type Your Answer Here: ")
            self.answers[index] = answer
 
    def score(self):
        num_questions = self.num_questions
        num_correct = 0
        for index in range(num_questions):
            question = self.questions[index]
            answer = self.answers[index]
            if question.is_right(answer):
                num_correct += 1
        return f"You scored {num_correct} out of {num_questions}"

Creating a Method to Make a Quiz

How can we create a Quiz? We have two choices due to the constructor we made. Either we can pass it a dictionary of questions or we can simply initialize an empty Quiz and add questions as we go. This method will initialize and empty Quiz and ask the user to input questions. We’ll use a while loop that keeps track of whether or not we’re still asking questions.

To start, we’ll ask the user for a question then for each of the four multiple choices and the correct answer. We’ll use that input for creating a Question item which we will then put into the Quiz instance we made earlier. After each question, we’ll ask the user if there are any more questions to add. If they say no (n) we’ll exit the loop and return the created Quiz.

# initialize quiz and ask for questions
def make_quiz():
    quiz = Quiz()
    adding_questions = True
    while adding_questions:
        _question = input("What is the question? ")
        _a = input("What is option A? ")
        _b = input("What is option B? ")
        _c = input("What is option C? ")
        _d = input("What is option D? ")
        _correct = input("Which of the answers is correct? ")
        _question = Question(_question, _a, _b,_c, _d, _correct)
        quiz.add_question(_question)
        still_adding = input("Are there more questions to add?(y/n) ").lower()
        if still_adding == "n":
            adding_questions = False
    return quiz

Creating a Method to Take a Quiz

We’ve already set up all the methods we need to take a quiz. Let’s create a method that will actually allow us to take the quiz. This method will take in one argument, the quiz we want to take. The method will expect that object to be in the form of the Quiz class. All we do in this method is use the give_quiz method followed by the score method that we’ve already created. Then we print out the results. Note that I’ve also added a line to return the results to the function caller. It’s really up to you how you want to handle showing the user the results, but you can do both. Just remember that if you choose to return the results, you’ll have to print them out when you call this function later.

def take_quiz(quiz: Quiz):
    quiz.give_quiz()
    results = quiz.score()
    print(results)
    return results

Taking a Quiz

Before we take the quiz we can opt to have the user make a quiz using the make_quiz function, or we can create a premade quiz. For this example, I’ve opted for a premade quiz. If you’d like to have the user create the quiz instead, you can use this code:

_quiz = make_quiz()
take_quiz(_quiz)

To make a premade quiz, we simply make some questions and instantiate a Quiz object with them. To give the premade quiz, we just call take_quiz on it.

q1 = Question("Who's the best software content creator?", "Yujian Tang", "Tom Brady", "Taylor Swift", "Michael Jordan", "Yujian Tang")
q2 = Question("What's the name of the most comprehensive Text API on the web?", "A Text API", "Another Text API", "I Don't Know", "The Text API", "The Text API")
q3 = Question("Which Python Blog is the best?", "Some Python Blog", "Medium", "PythonAlgos", "Some other Python Blog", "PythonAlgos")
q4 = Question("Which of the following letters is B?", "A", "B", "C", "D", "B")
_quiz = Quiz({
    0: q1,
    1: q2,
    2: q3,
    3: q4
})
take_quiz(_quiz)

When we run this and take the quiz we should see something like the image below.

How could you extend this or change this? You could add a function to delete quiz questions. Maybe have the quiz score based on the answer choice (ie use A, B, C, or D) and not the answer value. Or maybe you could have the quiz be given in a random order. That’s pretty much it, I hope you’ve learned from this, feel free to ask any questions in the comments below!

I run this site to help you and others like you find cool projects and practice software skills. If this is helpful for you and you enjoy your ad free site, please help fund this site by donating below! If you can’t donate right now, please think of us next time.

Yujian Tang

Leave a Reply

Discover more from PythonAlgos

Subscribe now to keep reading and get access to the full archive.

Continue reading