This is a 100 Days challenge to learn a new language (Python). 100 Days of Code - The Complete Python Pro Bootcamp
I will post some notes to motivate myself to finish this challenge.
Project - Quiz App
Revise the Quiz Project in Day 17.
#1 Call Trivia API to get the question instead of hard-coded in txt file
#2 Use Tkinter to improve the User Experience
#3 Review OOP Design
Ex: data.py
import requests
# Prepare parameters for API
parameters = {
"amount": 10,
"category": 18, # Science - Computers
"type": 'boolean',
}
# Sends a GET request.
response = requests.get("https://opentdb.com/api.php", params=parameters)
# Raises HTTPError, if one occurred.
response.raise_for_status()
# Returns the json-encoded content of a response, if any.
res= response.json()
question_data = res["results"]
Ex: question_model.py
class Question:
def __init__(self, q_text, q_answer):
self.text = q_text
self.answer = q_answer
Ex: quiz_brain.py
import html
class QuizBrain:
def __init__(self, q_list):
self.question_number = 0
self.score = 0
self.question_list = q_list
self.current_question = None
def still_has_questions(self):
return self.question_number < len(self.question_list)
def next_question(self):
self.current_question = self.question_list[self.question_number]
self.question_number += 1
question_text = html.unescape(self.current_question.text)
return f"Q.{self.question_number}: {question_text} (True/False): "
def check_answer(self, user_answer: str) -> bool:
correct_answer = self.current_question.answer
if user_answer.lower() == correct_answer.lower():
self.score += 1
return True
return False
Ex: ui.py
import tkinter as tk
from quiz_brain import QuizBrain
THEME_COLOR = "#375362"
class QuizInterface:
def __init__(self, quiz_brain: QuizBrain):
self.quiz_brain = quiz_brain
# Init Tkinter
self.root = tk.Tk()
self.root.title("Quizzler")
self.root.config(padx=20, pady=20, background=THEME_COLOR)
# Score Counter
self.score_label = tk.Label(
text="Score: 0",
foreground='white',
background=THEME_COLOR)
self.score_label.grid(row=0, column=1)
# Init canvas
self.canvas = tk.Canvas(
width=300, height=250, background='white', highlightthickness=0
)
# Question Text
self.question_text = self.canvas.create_text(
150, 125, width=280, text="",
fill="black", font=('Arial', 15, "italic")
)
self.canvas.grid(row=1, column=0, columnspan=2, pady=50)
# True Btn
true_image = tk.PhotoImage(file="images/true.png")
self.true_btn = tk.Button(
image=true_image, command=self.true_btn_clicked)
self.true_btn.config(
background=THEME_COLOR,
activebackground=THEME_COLOR)
self.true_btn.grid(row=2, column=0)
# False Btn
false_image = tk.PhotoImage(file="images/false.png")
self.false_btn = tk.Button(
image=false_image, command=self.false_btn_clicked)
self.false_btn.config(
background=THEME_COLOR,
activebackground=THEME_COLOR)
self.false_btn.grid(row=2, column=1)
# Get the next question
self.get_next_question()
# Start the Event Loop
self.root.mainloop()
def get_next_question(self):
# Config white bg for canvas
self.canvas.config(background='white')
# No more questions
if not self.quiz_brain.still_has_questions():
# Show game over info
self.canvas.itemconfig(self.question_text, text="No more questions")
# Disable buttons
self.true_btn.config(state='disabled')
self.false_btn.config(state='disabled')
return
# Not finish all questions yet
quiz_text = self.quiz_brain.next_question()
self.canvas.itemconfig(self.question_text, text=quiz_text)
def true_btn_clicked(self):
self.show_feedback(self.quiz_brain.check_answer("true"))
def false_btn_clicked(self):
self.show_feedback(self.quiz_brain.check_answer("false"))
def show_feedback(self, is_correct: bool):
# Config bg of canvas based on the correction of answer
if is_correct:
self.canvas.config(background='green')
else:
self.canvas.config(background='red')
# Update Score Label
self.score_label.config(text=f"Score: {self.quiz_brain.score}")
# 1 second delay show the next question
self.root.after(1000, self.get_next_question)
Ex: main.py
from question_model import Question
from data import question_data
from quiz_brain import QuizBrain
from ui import QuizInterface
question_bank = []
for question in question_data:
question_text = question["question"]
question_answer = question["correct_answer"]
new_question = Question(question_text, question_answer)
question_bank.append(new_question)
quiz = QuizBrain(question_bank)
quiz_ui = QuizInterface(quiz)
No comments:
Post a Comment