How to create a quiz with Flask

Flask, a web framework for Python, provides a lightweight yet powerful way to build web applications. Here we’ll walk through the process of creating a simple quiz application using Flask. This interactive quiz will allow users to answer questions, submit their responses, and receive a score.

Creating a quiz with Flask

To create a quiz app in Flask, we need a Python script app.py for the backend logic and HTML templates layout.html, quiz.html, result.html along with a CSS stylesheet style.css for front-end styling. Let’s create it as follows:

Step 1: Ensure that you have Flask installed. If not, run the following command in your terminal or command prompt:

pip install Flask

Step 2: Create a directory for your project and set up the following structure:

Application folder hierarchy
Application folder hierarchy

Step 3: Now, let’s create HTML templates.

  • layout.html: The file below contains the basic structure shared across different pages:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
<title>{{ title }}</title>
</head>
<body>
<div class="container">
{% block content %}{% endblock %}
</div>
</body>
</html>
  • quiz.html: The file below contains the structure for the quiz page.

{% extends "layout.html" %}
{% block content %}
<h1>{{ quiz_title }}</h1>
<form method="POST" action="{{ url_for('quiz') }}">
{% for question in questions %}
<fieldset>
<legend>{{ question['question_text'] }}</legend>
{% for option in question['options'] %}
<label>
<input type="radio" name="{{ question['id'] }}" value="{{ option }}">
{{ option }}
</label><br>
{% endfor %}
</fieldset>
{% endfor %}
<button type="submit">Submit</button>
</form>
{% endblock %}
  • result.html: This file below contains the structure for the result page.

{% extends "layout.html" %}
{% block content %}
<h1>Quiz Result</h1>
<p>Your score: {{ score }} out of {{ total_questions }}</p>
<a href="{{ url_for('home') }}">Back to Home</a>
{% endblock %}

Step 4: Now, let’s create a style.css file for styling.

body {
font-family: Arial, sans-serif;
}
.container {
max-width: 600px;
margin: 0 auto;
}
fieldset {
margin-bottom: 10px;
}
button {
margin-top: 10px;
}

Step 5: Let’s create a Flask application to handle quiz logic.

from flask import Flask, render_template, request
app = Flask(__name__)
# Sample quiz data
quiz_data = {
'title': 'Python Programming Quiz',
'questions': [
{
'id': 1,
'question_text': 'What is the capital of France?',
'options': ['Paris', 'Berlin', 'London', 'Madrid'],
'correct_answer': 'Paris'
},
{
'id': 2,
'question_text': 'Which programming language is this quiz about?',
'options': ['Java', 'Python', 'C++', 'JavaScript'],
'correct_answer': 'Python'
},
{
'id': 3,
'question_text': 'Which of the following is used in pencils?',
'options': ['Graphite', 'Iron', 'Carbon', 'Silicon'],
'correct_answer': 'Graphite'
},
# Add more questions as needed
]
}
@app.route('/')
def home():
return render_template('quiz.html', title=quiz_data['title'], quiz_title=quiz_data['title'], questions=quiz_data['questions'])
@app.route('/quiz', methods=['POST'])
def quiz():
user_answers = {key: value for key, value in request.form.items()}
score, total_questions = calculate_score(user_answers)
return render_template('result.html', title='Quiz Result', score=score, total_questions=total_questions)
def calculate_score(user_answers):
score = 0
total_questions = len(quiz_data['questions'])
for question in quiz_data['questions']:
question_id = question['id']
user_answer = user_answers.get(str(question_id)) # Convert question_id to string
if user_answer and user_answer == question['correct_answer']:
score += 1
return score, total_questions
if __name__ == '__main__':
app.run(debug = True, host = "0.0.0.0", port = 3000)

Step 6: Run our Flask application using the command below:

python3 app.py

Let’s try it out!

We have followed all the steps above and the resultant project is as follows:

{% extends "layout.html" %}

{% block content %}
    <h1>Quiz Result</h1>
    <p>Your score: {{ score }} out of {{ total_questions }}</p>
    <a href="{{ url_for('home') }}">Back to Home</a>
{% endblock %}
Quiz application using Flask

Code explanation

  • In the /layout.html file:

    • Line 1: We declare the document type and specify the content is in HTML.

    • Lines 3–8: We set up the document’s head section, defining the character set as UTF-8, configuring viewport settings for responsiveness, and link the stylesheet style.css using Flask’s url_for function.

    • Lines 9–10: We open the body section, creating a container div with a class of container for content alignment.

    • Line 11: We initiate a block structure using Jinja templating, allowing dynamic content insertion in child templates.

    • Lines 12–14: We close the body and HTML tags, concluding the HTML document.

  • In the quiz.html file:

    • Line 1: We inherit from the base template layout.html to extend the layout structure.

    • Lines 3–6: We define the content block for this specific template. Display the quiz title and present a form for user input with questions and multiple-choice options dynamically rendered using Jinja templating.

    • Lines 7–15: We iterate each question, creating a fieldset with a legend for the question text and radio buttons for each multiple-choice option.

    • Line 17: We include a submit button to submit the quiz form.

  • In the result.html file:

    • Line 1: We inherit from the base template layout.html to extend the layout structure.

    • Lines 3–6: We define the content block for this specific template. It displays the quiz result, showing the user’s score out of the total number of questions and providing a link to return to the home page.

  • In the style.css file:

    • Lines 1–3: We specify that the default font for the entire document body is Arial or sans-serif if Arial is unavailable.

    • Lines 5–8: We style the container class, limiting its maximum width to 600 pixels and centering it horizontally by setting the left and right margins to auto.

    • Lines 10–12: We add a bottom margin of 10 pixels for all fieldsets, providing space between them.

    • Lines 14–16: We apply a top margin of 10 pixels for all buttons, creating space above them.

  • In the app.py file:

    • Line 1: We import the necessary modules from Flask for creating a web application.

    • Lines 2–29: We define a Flask application (app) and create sample quiz data, including questions, options, and correct answer.

    • Lines 31–33: We set up a route (/) that renders the home page with the quiz questions and options using the quiz.html template.

    • Lines 35–39: We create a route (/quiz) that handles user submissions via POST method, and calculates the quiz score using the calculate_score function, and render the result page with the user’s score.

    • Lines 41–51: We define the calculate_score function, which iterates through the quiz questions, compares user answers with correct answers and calculates the score.

    • Lines 53–54: Run the Flask application with debugging enabled on host 0.0.0.0 and port 3000 if the script is executed directly.

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved