Python boot camp by Dr.Angela day17

#How to create class 1

```python:class1.py
class User:
  pass

user1 = User( )
user1.name = "Jack"
user1.id = "001"

user2 = User( )
user2.name = "Mike"
user2.id = "002"

```

こんなことを毎回やるのか？ばかばかしいだろう。そのためにConstruct (コンストラクタ)というものを学習する。

#Constractor (コンストラクタ)
初期化関数：通常は変数の初期値や初期化することに用いることが多い。pythonでは\_\_init\_\_関数を設置することでコンストラクタを作成する。

```contractor.py
class Car:

  def __init__(self):         #pythonインタプリタが初期化するものだと認識する
  #initialise attributes
```
#How to create class 2

```python:instagram.py
class User:
    def __init__(self,user_id,username):
        self.id = user_id
        self.username = username
        self.followers = 0
        self.following = 0
    
    def follow(self,user):
        self.followers += 1
        self.following += 1

user_1 = User("001","Jack")
user_2 = User("002","Mike")

print(user_1)
print(user_2)

print(user_1.id)
print(user_2.username)

user_1.follow(user_2)       #user_2 = フォローする人, user_1 = フォローされる人
print(user_1.followers)
print(user_1.following)
user_2.follow(user_1)       #user_1 = フォローする人, user_2 = フォローされる人
print(user_2.followers)
print(user_2.following)

#出力結果
<__main__.User object at 0x000001D2F697A790>     #格納場所が出力された
<__main__.User object at 0x000001D2F69B3310>
001     #user_1のid
Mike    #user_2のusername
1       #user_1のフォロワーは1人増えた(=user_2の分)
1       #user_1のフォロイーも1人増えた(=user_2の分)
1       #user_2の関しても同様に増える
1
```

#Mission>> Quiz game program
https://opentdb.com/api_config.php からクイズデータベースを持ってきて、出題数がすべて終わるまでクイズを繰り返すプログラム。[〇問/〇問]正解中というような表記をつける。オブジェクト指向型プログラミングの最大のメリットとして__モジュールの再利用__が挙げられる。これを実感してみるべくこの課題に取り組む。

```python:main.py
from question_model import Question
from data import question_data
from quiz_brain import QuizBrain

question_bank = []

for question in question_data:
    q_text = question["text"]          #ここのキーワードを変更すればどんなデータでもmain.py
    q_answer = question["answer"]      #だけをいじればデータを入れ替えることができる
    get_question = Question(q_text,q_answer)
    question_bank.append(get_question)

quiz = QuizBrain(question_bank)

# <初見で書いたコード>
#quiz.next_question()  #初回の質問
# while q_answer == user_answer:
#     quiz = QuizBrain(question_bank)
#     quiz.next_question()
# else:
#     print("\nIncorrect!!\nGAME OVER")

while quiz.still_has_question():
    quiz.next_question()

#main関数ではquiz.check_answer()は呼ばない。なぜなら、こいつはnext_question()の中で
#呼び出しているから。QuizBrainの中では先にcheck_answerが出てこないとダメなのでは？と思った
#けど、QuizBrainを読み込んだ時点で、def()系は全て読み込んでいるのだから、
#next_question()guestionが呼び出されている時点で全てのdef()は把握済なので順序は関係ない。

print("Completely you win!!")
```

```python:question_model.py
class Question:
    
    def __init__(self,q_text,q_answer):
        self.text = q_text
        self.answer = q_answer
```

```python:quiz_brain.py
class QuizBrain:
    
    def __init__(self,q_list):
        self.question_number = 0
        self.question_list = q_list
        self.score = 0

    def still_has_question(self):
        bank_len = len(self.question_list)
        return self.question_number < bank_len
        #これだけでTrue or Falseをreturnしてくれる。前に学習したよね。
    
    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}[T/F]? ")
        if user_answer == "T" or "t":
            user_answer = "True"
        elif user_answer == "F" or "f":
            user_answer = "False"
        correct_answer = current_question.answer
        self.check_answer(user_answer,correct_answer)
    
    def check_answer(self,user_answer,correct_answer):
        if user_answer == correct_answer:
            self.score += 1
            print("\nYou are correct.")
        else:
            print("\nYou are incorrect!!")
        print(f"Your current score is: {self.score}/{self.question_number}\n")
```

```python:data.py
question_data = [
{"text": "A slug's blood is green.", "answer": "True"},
{"text": "The loudest animal is the African Elephant.", "answer": "False"},
{"text": "Approximately one quarter of human bones are in the feet.", "answer": "True"},
{"text": "The total surface area of a human lungs is the size of a football pitch.", "answer": "True"},
{"text": "In West Virginia, USA, if you accidentally hit an animal with your car, you are free to take it home to eat.", "answer": "True"},
{"text": "In London, UK, if you happen to die in the House of Parliament, you are entitled to a state funeral.", "answer": "False"},
{"text": "It is illegal to pee in the Ocean in Portugal.", "answer": "True"},
{"text": "You can lead a cow down stairs but not up stairs.", "answer": "False"},
{"text": "Google was originally called 'Backrub'.", "answer": "True"},
{"text": "Buzz Aldrin's mother's maiden name was 'Moon'.", "answer": "True"},
{"text": "No piece of square dry paper can be folded in half more than 7 times.", "answer": "False"},
{"text": "A few ounces of chocolate can to kill a small dog.", "answer": "True"}
]
```
今回はdata.pyの型が"text","answer"なのでmain.pyのキーワードでそれらを指定したが、たとえデータが変わったとしても、このキーワードを変更すればあとは何もいじらなくてもクイズが成り立つ。これがモジュール性の最大のメリット。