Day17 - The Quiz Project & the Benefit of OOP

Goal: what we will make by the end of the day

How to create your own Class in Python

  1. Naming convention

    a. https://en.wikipedia.org/wiki/Naming_convention_(programming)

    b. Class naming rule: PascalCase: 第一字母大寫, 其餘複合字母第一個字母都大寫 (Most programming language)

    c. Method or Attribute naming rule: camelCase: 第一字母小寫, 其餘複合字母第一個字母都大寫 (like Java )

    d. Class is a Blueprint that contains attribute and method

    e. Method or Attribute naming rule: snake_case (like Python, c, c++, Java script)

    f. Python naming Styles:

補充:

  1. Class initialize

    a. to set(variables, counters, switches, etc.) to their starting values at the beginning of a program or subprogram.

    b. to clear (internal memory, a disk, etc.) of previous data in preparation for use.

  2. Working with Attributes : Class Constructions and the __ init __ () function

    #initialize attributes

    1. be invoked every time you create a new object from this class

    2. def __ init __ (self):

    3. def __ init __(self, attribute):

    class User:
    	def __init__(self,user_id, username):
    			self.id = user_id
    			self.username = username
    			self.follower = 0 #default value
    	
    user_1 = User("001", "Brad")
    print(user_1.username)
    
    1. Adding Methods to a Class
    class User:
    	def __init__(self,user_id, username):
    		self.id = user_id
    		self.username = username
    		self.follower = 0 #default value
    		self.following = 0
    
    	def follow(self, user):
    		user.followers +=1
    		self.following +=1
    
    
    user_1 = User("001", "Brad")
    user_2 = User("002", "Jack")
    
    user_1.follow(user_2)
    print(user_1.followers)
    print(user_1.following)
    print(user_2.followers)
    print(user_2.following)
    
    
    #result:
    0
    1
    1
    0
    

補充: How to Write Beautiful Python Code With PEP 8

補充:

https://www.amazon.com/Unified-Modeling-Language-User-Guide/dp/0321267974

The Quiz Project - Sequence Diagram for OOP

補充說明:

data.py

#Target to create lots of Question objects and then put them into a list like this.

question_bank = [

Question(q1, a1),

Question(q2, a2),

Question(q3, a3),

...

]

question_data = [
    {
        "category": "Science: Computers",
        "type": "boolean",
        "difficulty": "medium",
        "question": "The HTML5 standard was published in 2014.",
        "correct_answer": "True",
        "incorrect_answers": [
            "False"
        ]
    },
    {
        "category": "Science: Computers",
        "type": "boolean",
        "difficulty": "medium",
        "question": "The first computer bug was formed by faulty wires.",
        "correct_answer": "False",
        "incorrect_answers": [
            "True"
        ]
    },
    {
        "category": "Science: Computers",
        "type": "boolean",
        "difficulty": "medium",
        "question": "FLAC stands for 'Free Lossless Audio Condenser'.",
        "correct_answer": "False",
        "incorrect_answers": [
            "True"
        ]
    },
    {
        "category": "Science: Computers",
        "type": "boolean",
        "difficulty": "medium",
        "question": "All program codes have to be compiled into an executable file in order to be run. This file can then be executed on any machine.",
        "correct_answer": "False",
        "incorrect_answers": [
            "True"
        ]
    },
    {
        "category": "Science: Computers",
        "type": "boolean",
        "difficulty": "easy",
        "question": "Linus Torvalds created Linux and Git.",
        "correct_answer": "True",
        "incorrect_answers": [
            "False"
        ]
    },
    {
        "category": "Science: Computers",
        "type": "boolean",
        "difficulty": "easy",
        "question": "The programming language 'Python' is based off a modified version of 'JavaScript'",
        "correct_answer": "False",
        "incorrect_answers": [
            "True"
        ]
    },
    {
        "category": "Science: Computers",
        "type": "boolean",
        "difficulty": "medium",
        "question": "AMD created the first consumer 64-bit processor.",
        "correct_answer": "True",
        "incorrect_answers": [
            "False"
        ]
    },
    {
        "category": "Science: Computers",
        "type": "boolean",
        "difficulty": "easy",
        "question": "'HTML' stands for Hypertext Markup Language.",
        "correct_answer": "True",
        "incorrect_answers": [
            "False"
        ]
    },
    {
        "category": "Science: Computers",
        "type": "boolean",
        "difficulty": "easy",
        "question": "In most programming languages, the operator ++ is equivalent to the statement '+= 1'.",
        "correct_answer": "True",
        "incorrect_answers": [
            "False"
        ]
    },
    {
        "category": "Science: Computers",
        "type": "boolean",
        "difficulty": "hard",
        "question": "The IBM PC used an Intel 8008 microprocessor clocked at 4.77 MHz and 8 kilobytes of memory.",
        "correct_answer": "False",
        "incorrect_answers": [
            "True"
        ]
    }
]

question_model.py

'''Quiz: Project Part1: Creating the Questions Class'''
class Questions:
	def __init __ (self,text,answer):
		self.text = text
		self.answer = answer
		

question_model.py

class Question:
    def __init__(self, q_text, q_answer):
        self.text = q_text
        self.answer = q_answer
		

quiz_brain.py

class QuizBrain:

    def __init__(self, q_list):
        self.question_number = 0
        self.score = 0
        self.question_list = q_list

    def still_has_questions(self):
        return self.question_number < len(self.question_list)
    
    def next_question(self):
        current_question = self.question_list[self.question_number]
        self.question_number += 1
        user_answer = input(f"Q.{self.question_number}: {current_question.text} (True/False): ")
        self.check_answer(user_answer, current_question.answer)
    
    '''Quiz Project Part5: Checking Answers and Keeping Score'''
    def check_answer(self, user_answer, correct_answer):
        if user_answer.lower() == correct_answer.lower():
            self.score += 1
            print("You got it right!")
        else:
            print("That's wrong.")
        print(f"The correct answer was: {correct_answer}.")
        print(f"Your current score is: {self.score}/{self.question_number}")
        print("\n")
		

main.py

from question_model import Question
from data import question_data
from quiz_brain import QuizBrain

'''Quiz Project Part2: Creating the List of  Question Objects from the Data'''

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 Project Part3: The QuizBrian and the next_question() method'''
quiz = QuizBrain(question_bank)

'''Quiz Project Part 4: How to continue showing new Questions'''
while quiz.still_has_questions():
    quiz.next_question()

print("You've completed the quiz")
print(f"Your final score was: {quiz.score}/{quiz.question_number}")
		

補充:

The Benefits of OOP: Use Open Trivia DB to Get New Questions

  1. Open Trivia DB provides API for retrieve dynamic Question
  1. Generate API URL

Generate API URL

  1. Python Internet Access using Urllib.Request and urlopen()

webdata.py (my code)

#透過API改寫資料源串接

import urllib.request as req
import ssl
import json

def getOpenData():
    #use ssl module to pass htttps certification
    ssl._create_default_https_context = ssl._create_unverified_context
    response  = req.urlopen('https://opentdb.com/api.php?amount=10&category=23&difficulty=easy&type=boolean')
    #get the result code and print it, if normal response code is 200
    print ("result code: " + str(response.getcode()))

    # read the data from the URL and print it, here data type is bytes
    #data = str(response.read())
    #make bytes data and transform as dictionary object
    data = json.loads(response.read().decode('utf-8'))
    #{[{[]}]} ==> 題庫的資料結構, 需要抽絲剝繭
    #print(type(data['results']))
    data_002 = [i for i in data['results']]
    #print(data_002)
    return data_002

if __name__ == "__main__":
    getOpenData()
		

main.py (my code)

#抽換成我改寫的WEB API

#改寫Angela的主程式只有很簡單的改了題庫相關的2行程式碼 (<=====部分)

from question_model import Question
from data import question_data
from webdata import getOpenData # <===== 修改本行 <=====
from quiz_brain import QuizBrain

question_bank = []
#rewirte data module as webdata module for reterive question DB via web API
for question in getOpenData(): # <===== 修改本行 <=====
    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)

while quiz.still_has_questions():
    quiz.next_question()

print("You've completed the quiz")
print(f"Your final score was: {quiz.score}/{quiz.question_number}")
		

資料來源:本文源自 Brad Chao Notion 筆記,感謝授權轉載。

1個讚