Hello!! What's up guys! Happy to meet you today for coding together!
Today, we'll finish super heroes quiz we started since two weeks.
If you didn't read last article about part 1, check here.
Write our questions
For this quiz, we need to ask some questions to player. To do it, let's create a folder called Questions. I'll be fun if we handle txt and csv files in this app. So firstly, we'll write txt files which contains questions. We'll create also empty csv files. Next, we'll use questions which are in txt files to fill out csv files. Ready ? Let's go!🏁
Questions files are on github, in this repo. After create files, let's code script which permit to handle theses files.
Quiz file
Import section
Create a file called quiz.py at project root. We'll write our script inside it. In this file, because we use csv file and pathlib, let's import them.
import pathlib
import csv
import random
We also import random to ask questions to player randomly.
Let's declare our variables
we'll use variables to precise where our questions are stored (in txt files, which are source paths) and where we want to save it (into csv files, which will be destination paths).
# Common path
questions_path = pathlib.Path.cwd() / 'Questions'
# Specific questions source path
dc_questions_src_path = questions_path / 'dc_questions.txt'
hyper_questions_src_path = questions_path / 'hyper_questions.txt'
marvel_questions_src_path = questions_path / 'marvel_questions.txt'
# Specific questions destination path
dc_questions_dest_path = questions_path / 'dc_questions.csv'
hyper_questions_dest_path = questions_path / 'hyper_questions.csv'
marvel_questions_dest_path = questions_path / 'marvel_questions.csv'
questions_list = [] # we will store questions in here
quiz_resume = {} # store player game
question_num = 1 # asked question number
score = 0 # player score
Code functions now
As we've specifics questions for specifics kind of heroes, how can we make that when player (user) chooses an heroes team, we ask him team specific questions ?
Firstly, as you can see, questions are written in 'txt' files. In this script, remember that we want to manage csv files (write and read), so let's add an additional step layer. Here, we must write different csv files which will contains specifics heroes team questions from '.txt' files. Next, we'll read '.csv' files in order to ask randomly, questions about heroes team which chosen by player. Let's begin by write '.csv' files from '.txt' files.
...
def write_heroes_questions(txt_path, csv_path):
"""Take a txt file and write a csv file from it
with two main information:
- the question
- the answer"""
questions_dict = {} # it will collect questions and answers
# Fill out questions dictionary with questions and answers
with open(txt_path, 'r') as source_file:
for question_answer in source_file:
the_question = question_answer.split(':')[0] # get the question
the_answer = question_answer.split(':')[1] # get the answer
the_answer = the_answer.rstrip()
questions_dict[the_question] = the_answer
'''Note:
1) We use split method to convert into list questions and answers,
also separate questions to answers and assign them to correct
variables. As we know, first part (or left part) corresponds to
question and second part (or right part) corresponds to answer.
2) We use rsplit method for removing newlines in answers.
'''
# Write csv file from questions dictionary
with open(csv_path, 'w') as the_file:
csv_writer = csv.writer(the_file)
csv_writer.writerow(['Question', 'Answer']) # write header of csv file
for question, answer in questions_dict.items():
csv_writer.writerow([question, answer])
To summarize in a simple way what we do, we create a function. This function take questions which are in txt file and write them into csv file.
Now we can learn and write a csv file from txt file, define a function which read a csv file and ask questions.
...
def assign_heroes_questions(csv_file):
"""Get a csv file, then write questions and answers"""
questions_answers_dict = {}
with open(csv_file, 'r') as the_file:
questions_answer = csv.reader(the_file)
next(questions_answer)
for line in questions_answer:
the_question = line[0]
the_answer = line[1]
questions_answers_dict[the_question] = the_answer
questions_list.append(the_question)
return questions_answers_dict
def ask_heroes_questions(csv_file, quiz_resume):
"""Ask questions randomly"""
questions_answer = assign_heroes_questions(csv_file)
choosen_question = random.choice(questions_list)
user_answer = input(f'{choosen_question}: ')
correct_answer = ''
global score
global question_num
for question_value, answer_value in questions_answer.items():
if choosen_question == question_value:
if user_answer.lower() == answer_value:
print(f'Great: your answer is correct: {answer_value}')
score += 4 # gain scores
else:
print(f'No! You\'ve failed. The correct answer is: {answer_value}')
print(f'Your score: {score}pt')
quiz_resume[f'Question n°{question_num}: {choosen_question}'] = f'Correct answer: {answer_value}'
quiz_resume[f'Your answer at question n°{question_num}: '] = f'{user_answer}'
question_num += 1
Ouf, we did great job. Now, it's time to attack scenario. So, roll up your sleeves, we move to the last part of the application!
The scenario
We've wrote 90% of app. Now, it's time to finish it!
Create a file called heroes.py at project root. First thing to do is import modules we need.
import heroes_list
import book
import quiz
import pathlib
from PyPDF2 import PdfFileReader, PdfFileWriter
Don't forget to install PyPDF2.
Fine. Now we imported file, we can now build the scenario You ouhhh, i'm so excited! Okay, let's be serious. First thing we'll do is to display a welcome text then, ask player's name. Then, we'll declare some variables which need for scenario.
...
print('Welcome to MEGA HEROE QUIZ!')
player_name = input('Please, enter your name (max: 13 characters): ')
game_over = False
correct_choice = False
player_team = []
team_folder = ''
The book generated will need player name. It's obvious to make sure that player didn't forgot enter it and be sure that it isn't too long, before ask him to choose one team.
...
while not player_name or player_name == ' ' or len(player_name) > 13:
player_name = input('Please, enter your name (max: 13 characters): ')
print(f'Well {player_name}! now, next step.')
while not correct_choice:
player_team_num = input(f'Choose your team number:\n\
1- DC Comic team\n\
2- Hyper team\n\
3- Marvel team\n\
')
# Check that player choice is a number and is between 1 and 3
try:
player_team_num = int(player_team_num)
correct_choice = True
if player_team_num < 1 or player_team_num > 3:
correct_choice = False
print('Make sure to choose a team number.')
else:
correct_choice = True
except ValueError:
print('Sorry, you didn\'t choose a team number.')
correct_choice = False
# Fill out correct team list
player_team = heroes_list.fill_on_number(player_team_num)
# Now, show him chosen team members.
print(f'\nGreat! Check your team hereoes.')
for heroe in player_team:
print(f'- {heroe}')
At this step, after player chooses a team, we must ask him correct questions (questions about chosen team members). So define a function which do this job.
def quiz_process(player_team_num):
"""Belongs to player team num, proceed to questions"""
if player_team_num == 1:
questions_src = quiz.dc_questions_src_path
questions_dest = quiz.dc_questions_dest_path
team_folder = 'dc_comic'
elif player_team_num == 2:
questions_src = quiz.hyper_questions_src_path
questions_dest = quiz.hyper_questions_dest_path
team_folder = 'hyper'
else:
questions_src = quiz.marvel_questions_src_path
questions_dest = quiz.marvel_questions_dest_path
team_folder = 'marvel'
# Write questions
quiz.write_heroes_questions(questions_src, questions_dest)
# Ask questions
quiz.ask_heroes_questions(questions_dest, quiz.quiz_resume)
return team_folder
Now, last step is to use previous function to ask him four questions (for exemple) before end game, generate book.
print('Now, it\'s quiz time!\n')
for i in range(0, 5):
the_team = quiz_process(player_team_num)
# Book conception
heroes_name_list = heroes_list.choose_bonus_picture(player_team)
cover_page = heroes_list.choose_cover_page(heroes_name_list)
heroes_team = pathlib.Path.cwd() / 'Heroes' / f'{the_team}'
cover_heroe = heroes_team / f'{cover_page}.pdf'
book.conceive_book(player_name, heroes_team, cover_heroe,
quiz.score, quiz.quiz_resume, heroes_name_list)
Well done! We've finished this episode. Hope that it permit you to practice what you learned. You can optimize this script:
- make a top score board
- i add a folder called Stories in which you'll find a html file. This file contains some heroes story. You can use theses stories and implement them in final pdf file. For instance, you can add story of heroes who is on cover page.
This folder can be clone on warehouse repo
With this, you know now what kind of scripts you can code, for this moment.
Here is my result of this app.
Full script is available in this repo.
Bye bye and see you next time for another script !