OOP의 장점

JOOYEUN SEO·2024년 8월 25일

100 Days of Python

목록 보기
17/76
post-thumbnail

❖ 클래스 생성

먼저 빈 클래스 생성

# 인스타그램 유저 모델링 1
# 클래스 생성
class User:
    pass


# 객체 생성
user_1 = User()
  • 콜론 밑으로 클래스 안에 들어갈 코드는 모두 들여쓰기
  • 클래스나 함수 정의 시 내용이 빈 상태로 밑에 다른 코드를 입력하면 들여쓰기 오류 발생
    pass 키워드로 일단 넘어가면 나중에 작성 가능

💡 파이썬 프로그램의 작명 규칙

👨‍🦰 PascalCase : 클래스 이름으로 사용됨
🐪 camelCase : 파이썬에서는 카멜 케이스를 많이 쓰지 않음
🐍 snake_case : 클래스 이름 외 모든 경우

◇ 속성, 클래스 생성자, init() 함수 활용

▷ 속성 추가 방법 1 : 해당 개체에서 직접 입력

class User:
    pass


user_1 = User()

# 속성 추가
user_1.id = '001'

print(user_1.id)
001

방법 1은 직접 입력하면서 실수할 가능성이 크기 때문에 비추천

▷ 속성 추가 방법 2 : 생성자와 __init__() 함수 활용

  • 생성자(constructor)
    • 청사진의 일부
    • 객체가 생성될 때 무슨 일이 일어나야 하는지 명시
    • 객체가 초기화(initialise)될 때, 변수나 카운터의 시작 값을 정할 수 있음
    • __init__() 함수 활용
  • __init__() 함수
    • 특별한 기능을 가진 메소드
    • 함수 내에서 속성을 초기화하거나 시작 값을 지정
    • 클래스에서 새로운 객체를 만들 때마다 호출
    • Car 클래스 예시
      # 클래스 생성
       class Car:
           def __init__(self, seats):
               self.seats = seats
       # 객체 생성
       my_car = Car(5)
       # 출력 시 5 출력 (방법 1처럼  my_car.seats = 5  와 같음)
       print(my_car.seats)
      • self
        • 생성되고 있거나 초기화되고 있는 실제 객체
        • __init__ 메소드 안의 self. 으로 입력된 것은 속성으로 변환됨
          • 클래스 안의 어디서나 엑세스 할 수 있게 된다
          • 한 번 쓴 후 다른 곳에서 다시 쓰이지 않을 것에는 self. 을 붙일 필요 없음
      • 매개변수(파라미터)
        • Car 클래스로부터 객체가 생성될 때 전달됨
        • 전달된 데이터를 받아 함수 안에서 객체의 속성값 설정 가능
        • 0개부터 원하는 개수만큼 설정 가능
# 인스타그램 유저 모델링 2
class User:
    def __init__(self, user_id, username):
        self.id = user_id
        self.username = username
        self.followers = 0
        # 새 객체가 생성될 때마다 해당 함수가 호출됨을 확인
        print("New user being created...")


user_1 = User('001', 'angela')
user_2 = User('002', 'Ben')

print(user_1.id)
print(user_1.followers)
New user being created...
New user being created...
001
0
  • 일반적으로 매개변수 이름 = 속성 이름 (항상 규칙을 지킬 필요는 없음)
  • self.followers = 0 은 어떤 객체를 생성해도 항상 디폴트 값 0으로 시작하는 속성
    (매개변수로 값을 설정하지 않음)

◇ 클래스에 메소드 추가

# 인스타그램 유저 모델링 3
class User:
    def __init__(self, user_id, username):
        self.id = user_id
        self.username = username
        # 계정을 처음 생성시 팔로워, 팔로잉은 0에서 시작(기본값을 가지는 속성들)
        self.followers = 0
        self.following = 0


    def follow(self, user):
        user.followers += 1
        self.following += 1


user_1 = User('001', 'angela')
user_2 = User('002', 'Ben')

# user_1이 user_2를 팔로우
user_1.follow(user_2)
print(user_1.followers)
print(user_1.following)
print(user_2.followers)
print(user_2.following)
0
1
1
0

self 키워드

  • 메소드는 일반 함수와 달리 항상 첫 매개변수로 self 매개변수 필요
  • 클래스 청사진 내부에서 클래스로부터 만들어지는 객체를 지칭하는 방법

🗂️ Day17 프로젝트 : OX 퀴즈

플레이어에게 문제를 제시하고 true(O) 또는 false(X)를 선택하게 한 뒤,
결과를 알려주고 점수를 부여하는 게임

1. 질문 클래스 생성

🔍 유의 사항

  • 📄 question_model.py에 작성
  • 문제(question) 객체에서 특정 값으로 초기화되어야 하는 속성
    • 문제 텍스트에 관한 text
    • 문제 정답에 대한 answer

⌨️ question_model.py

class Question:

    def __init__(self, text, answer):
        self.text = text
        self.answer = answer

2. 데이터로부터 질문 객체 리스트 생성

🔍 유의 사항

  • 📄 question_model.pydata.py를 활용하여 📄 main.py에 작성
  • data.py에 준비된 질문과 답은 주어진 형식에 맞지 않아 경고가 뜨는 상태
    • 자동 일괄 들여쓰기 : 원하는 만큼 드래그 → CodeAuto-indent Lines
    • 너무 긴 문자열 나누기 : 끊을 자리에서 엔터 → 자동으로 앞뒤에 따옴표가 붙어서 다음 줄로 내려감
      (두 줄로 보이지만 출력은 한 줄로 됨)
    • 사전에 없는 단어 : 단어 위에 마우스 커서 → 💡Save '단어' to project-level dictionary
  • question_data를 question 객체들을 모은 question_bank 리스트로 변경

📄 data.py

question_data = [
    {"text": "A slug's blood is green.", "answer": "True"},
    {"text": "The loudest animal is the African Elephant.", "answer": "False"},
    {...},
    {...},
    {...},
    {...},
    {...},
    {...},
    {...},
    {...},
    {...},
    {...}
]

⌨️ main.py

from question_model import Question
from data import question_data

question_bank = []
for question in question_data:
    new_question = Question(question["text"], question["answer"])
    question_bank.append(new_question)

3. 질문을 하고 답변을 요구하는 클래스 생성

🔍 유의 사항

  • 📄 quiz_brain.pyQuizBrain 클래스 작성
  • TODO
    1. 플레이어에게 질문을 제시
    2. 답변이 맞았는지 체크
    3. 퀴즈 목록의 마지막까지 왔는지 확인
  • 속성
    • question_number = 0 : 1번째 질문부터 시작
    • question_list : 객체가 초기화될 때 전달되는 질문 리스트
  • 메소드
    • next_question() : 질문 리스트에서 다음 질문을 가져와서 보여주고 답변을 요구하는 함수
      (첫 번째 질문의 question_number 값은 0이지만 플레이어에게 출력은 1이 되어야 함에 주의)

⌨️ quiz_brain.py

class QuizBrain:

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


    def next_question(self):
        current_question = self.question_list[self.question_number]
        self.question_number += 1
        input(f"Q.{self.question_number}: {current_question.text} (True/False)? : ")

⌨️ main.py

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


question_bank = []
for question in question_data:
    new_question = Question(question["text"], question["answer"])
    question_bank.append(new_question)

quiz = QuizBrain(question_bank)
quiz.next_question()

4. 새로운 질문을 계속 보여주는 방법

🔍 유의 사항

  • 📄 quiz_brain.pyQuizBrain 클래스에 작성
  • 메소드 추가
    • still_has_questions() : 참/거짓 값 반환
  • 📄 main.py에 while문을 추가하여 퀴즈가 아직 남아있는지 확인
    • 질문 번호와 질문 리스트의 길이의 관계가 힌트

⌨️ quiz_brain.py

class QuizBrain:

    def __init__(self, question_list):
        self.question_number = 0
        self.question_list = question_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
        input(f"Q.{self.question_number}: {current_question.text} (True/False)? : ")

self.question_number < len(self.question_list)은 참/거짓 값을 반환하므로 자체를 return하면 간단

⌨️ main.py

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


question_bank = []
for question in question_data:
    new_question = Question(question["text"], question["answer"])
    question_bank.append(new_question)

quiz = QuizBrain(question_bank)

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

5. 답변을 확인하고 점수 유지하기

🔍 유의 사항

  • 📄 quiz_brain.pyQuizBrain 클래스에 작성
    • 속성 추가
      • score = 0 : 디폴트 값 0에서 시작하고, 답을 맞힐 때마다 1씩 증가
    • 메소드 추가
      • check_answer() : 플레이어의 답변이 맞는지 확인하고, 점수를 기록
  • 📄 main.py에서 퀴즈를 다 풀었을 경우 문구와 최종 점수를 출력하도록 작성

⌨️ quiz_brain.py

class QuizBrain:

    def __init__(self, question_list):
        self.question_number = 0
        self.score = 0
        self.question_list = question_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)


    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 a wrong.")
        print(f"The correct answer was {correct_answer}.")
        print(f"Your current score is: {self.score}/{self.question_number}\n")

next_question 함수 마지막에 check_answer 함수가 실행됨

⌨️ main.py

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


question_bank = []
for question in question_data:
    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}")

6. OOP의 이점: 새로운 질문을 얻기 위해 Open Trivia DB 활용

Open Trivia DB

  • 사용자 제공의 일반 상식 문제 데이터베이스 (무료이용)
  • 3,000개 이상의 검증된 질문 보유
  • 사용법
    1. API → 질문 개수, 카테고리, 난이도, 문제 유형 선택 → GENERATE API URL
    2. 생성된 URL로 가서 JSON(자바스크립트 객체 표기법) 형식의 데이터 복사
    3. 📄 data.py의 question_data의 내용을 지우고 복사한 내용 붙여넣기
      { "response_code": 0, "result": [ {...}, {...}, {...}, {...}, {...} ] }
    4. 블록잡기 → CodeReformat Code
    5. 4번을 2번 반복하면 키 result의 [ ] 내부가 질문 개수만큼의 딕셔너리로 구성됨
    6. 필요 없는 부분들을 지워서 question_data를 딕셔너리를 가진 리스트로 변경
    7. 📄 main.py에서 이전의 키값들을 새로 바뀐 리스트의 키값에 맞게 수정
###########################################📄 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)

    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")

⌨️ data.py

question_data = [
     {
         "type": "boolean",
         "difficulty": "easy",
         "category": "Science: Computers",
         "question": "Time on Computers is measured via the EPOX System.",
         "correct_answer": "False",
         "incorrect_answers": ["True"]
     },
     {...},
     {...},
     {...},
]

⌨️ main.py

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


question_bank = []
for question in question_data:
    new_question = Question(question["question"], question["correct_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}")
[ 출력 결과 ]

Q.1: Time on Computers is measured via the EPOX System. (True/False)? : ❚False
You got it right!
The correct answer was False.
Your current score is: 1/1

Q.2: Ada Lovelace is often considered the first computer programmer. (True/False)? : ❚False
That's a wrong.
The correct answer was True.
Your current score is: 1/2

Q.3: RAM stands for Random Access Memory. (True/False)? : ❚True
You got it right!
The correct answer was True.
Your current score is: 2/3

Q.4: Linus Torvalds created Linux and Git. (True/False)? : ❚True
You got it right!
The correct answer was True.
Your current score is: 3/4

You've completed the quiz.
Your final score was: 3/4

data.py와 main.py 외에 다른 파일들은 건드리지 않아도 프로그램을 수정 가능 → 모듈 방식의 장점




▷ Angela Yu, [Python 부트캠프 : 100개의 프로젝트로 Python 개발 완전 정복], Udemy, https://www.udemy.com/course/best-100-days-python/?couponCode=ST3MT72524

0개의 댓글