객체지향 프로그래밍(OOP)

JOOYEUN SEO·2024년 8월 24일

100 Days of Python

목록 보기
16/76
post-thumbnail

절차지향 프로그래밍(Procedural Programming)

  • 프로그래밍의 초기 패러다임
  • 위에서 아래로 일을 처리하고 필요할 때는 함수 안으로 들어감
  • 프로그래밍이 복잡해지고 서로 얽힌 관계가 많을수록 관리하기 힘들어지는 단점

객체지향 프로그래밍(Object Oriented Programming)

  • 크고 복잡한 프로젝트를 작은 별개의 모듈들로 나누는 방법
  • 다른 사람들과 협업이 가능하고 각자 맡은 부분만 해내면 되므로 생산성이 올라감
  • 모듈은 같은 기능이 필요할 시 재사용 가능

❖ OOP 사용법: 클래스와 객체

클래스(class)
청사진, Blueplrint에 비유(청사진 하나로 다양한 버전의 객체를 생성)

객체(object)
청사진으로부터 만들어진 개별 객체

객체지향 → 실생활 객체의 모델을 만듦
예) 👩‍💼 레스토랑 운영

  • 🛎️ 웨이터 클래스
    • 🤵 Henry 객체
    • 🤵‍♀️ Betty 객체
      ...

      웨이터 객체에 대한 구성 요소

      1. 가진 것(has) → 속성(attributes)
      모델로 만든 객체에 관한 데이터변수로 표현

      is_holding_plate = True
         tables_reponsible = \[4, 5, 6]


      2. 하는 것(dose) → 메소드(methods)
      모델로 만든 특정 객체가 할 수 있는 기능함수로 구현

      def take_order(table order):
           # takes order to chef
       def take_payment(amount):
           # add monet to restaurant
  • 🧹 청소부 클래스
  • 🍳 주방장 클래스

❖ 객체를 만들고 속성과 메소드에 접근

# 클래스로부터 객체 생성
car = CarBlueprint()

# 객체의 속성에 접근(객체 car를 식별하고, 점 표기법으로 speed 속성을 얻음)
car.speed

# 객체의 메소드에 접근(객체 car를 식별하고, 점 표기법으로 관련된 함수를 호출)
car.stop()

클래스

  • CarBlueprint
  • 클래스 이름파스칼 표기법으로 지음
    (각 단어의 첫 글자를 대문자로 표기)
  • 클래스 이름 뒤에 괄호를 붙여야 객체 활성화 가능

객체

  • car
  • CarBlueprint를 토대로 만들어짐
  • 객체 이름은 클래스 이름과 같지만 소문자스네이크 케이스 표기법으로 지음
    (클래스 이름을 모두 소문자로 바꾼 후, 각 단어를 언더바로 분리)

🐢 Turtle Graphics 라이브러리

💡 외부 라이브러리
다른 누군가가 만들어 놓은 청사진으로 객체를 만드는 것

화면에 그래픽을 띄우는 기능을 제공하는 라이브러리

# turtle 모듈의 Turtle, Screen 클래스를 사용하기 위해 임포트
from turtle import Turtle, Screen

# 클래스로부터 객체 timmy 생성
timmy = Turtle()

# 객체에서 메소드에 접근
timmy.shape("turtle")           # 객체의 모양을 커서에서 거북이로 변경
timmy.color("green4")           # 객체의 색깔을 검정에서 지정한 색으로 변경
timmy.forward(100)              # 객체가 지정한 걸음 수만큼 앞으로 이동


# 클래스로부터 timmy가 보일 창 객체 생성
my_screen = Screen()

# 객체에서 속성에 접근
print(my_screen.canvheight)     # 캔버스의 높이가 출력

# 객체에서 메소드에 접근 (해당 메소드는 터틀 모듈을 사용한 모든 작업이 끝난 후 실행되어야 함)
my_screen.exitonclick()         # 스크린을 클릭해서 코드에서 나가기 전까지 캔버스가 유지됨

◇ PyPi로 파이썬 패키지 추가

모듈 : 하나의 파일
  vs
패키지 : 다른 사람이 쓴 코드 묶음(파일들의 모음)

PyPi(Python Package Index)

  • 다른 개발자가 만든 패키지를 검색하는 사이트
  • PyPi에서 찾은 패키지를 사용하려면 설치 필요(MAC)
    1. PycharmSettingsProject: 프로젝트이름Python Interpreter
    2. + → 패키지 이름 검색 후 선택 → Install Package
    3. 패키지 이름으로 import
      (코드 확인 : import 후 패키지 이름에서 우클릭 → Go ToImplementation)

◇ 객체 속성 변경 및 메소드 호출

prettytable : 아스키 형식으로 표를 나타내는 간단한 라이브러리(PyPi 링크)

from prettytable import PrettyTable

# 객체 생성
pokemon_table = PrettyTable()

# 메소드 호출(데이터를 한 열씩 추가)
pokemon_table.add_column("Pokemon Name", ['Pikachu', 'Squirtle', 'Charmander'])
pokemon_table.add_column("Type", ['Electric', 'Water', 'Fire'])

# 속성 변경(테이블 스타일 변경)
pokemon_table.align = "l"   # 왼쪽 정렬(기본값은 가운데 정렬인 c)
[ 출력 결과 ]

+--------------+----------+
| Pokemon Name | Type     |
+--------------+----------+
| Pikachu      | Electric |
| Squirtle     | Water    |
| Charmander   | Fire     |
+--------------+----------+

🗂️ Day16 프로젝트 : OOP 커피 머신

🔍 유의 사항

  • Day15 프로젝트 : 커피 머신OOP 버전으로 제작
    • 다양한 객체를 사용해 다양한 일을 대신하도록 하는 것이 목표
    • 미리 주어진 파일 3개에 있는 클래스만 이용해서 코드를 작성해야 함
      (외부 라이브러리를 이용하는 것과 비슷)
    • 객체들이 구체적으로 어떻게 해서 데이터를 처리하고 필요한 기능을 수행하는지는 중요하지 않음
  • 커피 머신 설명서 링크

📄 menu.py

class MenuItem:
    """Models each Menu Item."""
    def __init__(self, name, water, milk, coffee, cost):
        self.name = name
        self.cost = cost
        self.ingredients = {
            "water": water,
            "milk": milk,
            "coffee": coffee
        }


class Menu:
    """Models the Menu with drinks."""
    def __init__(self):
        self.menu = [
            MenuItem(name="latte", water=200, milk=150, coffee=24, cost=2.5),
            MenuItem(name="espresso", water=50, milk=0, coffee=18, cost=1.5),
            MenuItem(name="cappuccino", water=250, milk=50, coffee=24, cost=3),
        ]

    def get_items(self):
        """Returns all the names of the available menu items"""
        options = ""
        for item in self.menu:
            options += f"{item.name}/"
        return options

    def find_drink(self, order_name):
        """Searches the menu for a particular drink by name.
        Returns that item if it exists, otherwise returns None"""
        for item in self.menu:
            if item.name == order_name:
                return item
        print("Sorry that item is not available.")

📄 coffee_maker.py

class CoffeeMaker:
    """Models the machine that makes the coffee"""
    def __init__(self):
        self.resources = {
            "water": 300,
            "milk": 200,
            "coffee": 100,
        }

    def report(self):
        """Prints a report of all resources."""
        print(f"Water: {self.resources['water']}ml")
        print(f"Milk: {self.resources['milk']}ml")
        print(f"Coffee: {self.resources['coffee']}g")

    def is_resource_sufficient(self, drink):
        """Returns True when order can be made, False if ingredients are insufficient."""
        can_make = True
        for item in drink.ingredients:
            if drink.ingredients[item] > self.resources[item]:
                print(f"Sorry there is not enough {item}.")
                can_make = False
        return can_make

    def make_coffee(self, order):
        """Deducts the required ingredients from the resources."""
        for item in order.ingredients:
            self.resources[item] -= order.ingredients[item]
        print(f"Here is your {order.name} ☕️. Enjoy!")

📄 money_machine.py

class MoneyMachine:

    CURRENCY = "$"

    COIN_VALUES = {
        "quarters": 0.25,
        "dimes": 0.10,
        "nickles": 0.05,
        "pennies": 0.01
    }

    def __init__(self):
        self.profit = 0
        self.money_received = 0

    def report(self):
        """Prints the current profit"""
        print(f"Money: {self.CURRENCY}{self.profit}")

    def process_coins(self):
        """Returns the total calculated from coins inserted."""
        print("Please insert coins.")
        for coin in self.COIN_VALUES:
            self.money_received += int(input(f"How many {coin}?: ")) * self.COIN_VALUES[coin]
        return self.money_received

    def make_payment(self, cost):
        """Returns True when payment is accepted, or False if insufficient."""
        self.process_coins()
        if self.money_received >= cost:
            change = round(self.money_received - cost, 2)
            print(f"Here is {self.CURRENCY}{change} in change.")
            self.profit += cost
            self.money_received = 0
            return True
        else:
            print("Sorry that's not enough money. Money refunded.")
            self.money_received = 0
            return False

⌨️ 작성한 코드

from menu import Menu, MenuItem
from coffee_maker import CoffeeMaker
from money_machine import MoneyMachine

menu = Menu()
coffee_maker = CoffeeMaker()
money_machine = MoneyMachine()

machine_on = True

while machine_on:
    choice = input(f"What do you want? ({menu.get_items()}) : ")
    if choice == 'off':
        machine_on = False
    elif choice == 'report':
        coffee_maker.report()
        money_machine.report()
    else:
        drink = menu.find_drink(choice)
        if drink is not None:
            if coffee_maker.is_resource_sufficient(drink):
                if money_machine.make_payment(drink.cost):
                    coffee_maker.make_coffee(drink)
[ 출력 결과 ]

What do you want? (latte/espresso/cappuccino/) : ❚lettte
Sorry that item is not available.
What do you want? (latte/espresso/cappuccino/) : ❚latte
Please insert coins.
How many quarters?: ❚10
How many dimes?: ❚5
How many nickles?: ❚5
How many pennies?: ❚5
Here is $0.8 in change.
Here is your latte ☕️. Enjoy!
What do you want? (latte/espresso/cappuccino/) : ❚cappuccino
Sorry there is not enough water.
What do you want? (latte/espresso/cappuccino/) : ❚report
Water: 100ml
Milk: 50ml
Coffee: 76g
Money: $2.5
What do you want? (latte/espresso/cappuccino/) : ❚off

🖍️ 답안

from menu import Menu
from coffee_maker import CoffeeMaker
from money_machine import MoneyMachine

money_machine = MoneyMachine()
coffee_maker = CoffeeMaker()
menu = Menu()

is_on = True

while is_on:
    options = menu.get_items()
    choice = input(f"What would you like? ({options}): ")
    if choice == "off":
        is_on = False
    elif choice == "report":
        coffee_maker.report()
        money_machine.report()
    else:
        drink = menu.find_drink(choice)
        
        if coffee_maker.is_resource_sufficient(drink) and money_machine.make_payment(drink.cost):
          coffee_maker.make_coffee(drink)
  • 커피를 만드려면 남은 재고와 넣은 금액이 둘 다 충분해야 하므로 if문에서 and로 함께 묶음
  • 답안에서는 drink에 잘못된 입력값이 들어갔을 경우에 대한 대처가 없음




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

0개의 댓글