Python Programming
  • Home
  • Intro
    • History & Background
    • Python Setup
  • QPB
    • Part I: Chapter 1-3
    • Part II
    • 5. Lists, Tuples, Sets
  • Exercises
    • Chapter 5: Lists, Tuples, Sets
    • Chapter 6: Strings
    • Chapter 7: Dictionaries
    • Chapter 8: Control flow
    • Chapter 9: Functions
    • Chapter 14: Exceptions
    • Chapter 15: Classes
  • Exploring Data
    • NumPy & pandas
    • Visualization
  • Library System
  • Netflix Movie Analysis
    • Notes
    • Project-Native
    • Project-pandas
  • References
    • QPB Part 1
    • QPB Part 2
    • QPB Part 3
    • QPB Part 4

On this page

  • 문제 1: 기본 클래스 정의와 인스턴스 변수
  • 문제 2: 클래스 변수와 인스턴스 변수
  • 문제 3: 정적 메서드 활용
  • 문제 4: 클래스 메서드와 대체 생성자
  • 문제 5: 상속 기본
  • 문제 6: Private 변수와 메서드
  • 문제 7: @property 데코레이터 활용
  • 문제 8: 메서드 오버라이딩과 다형성
  • 문제 9: 클래스 변수와 인스턴스 추적
  • 문제 10**: 종합 - 온라인 쇼핑몰 시스템

Exercises: Chapter 15

Chapter 15: Classes and Object-Oriented Programming - 연습문제

문제 1: 기본 클래스 정의와 인스턴스 변수

책(Book) 클래스를 정의하세요.

요구사항:

  1. __init__ 메서드에서 제목(title), 저자(author), 가격(price)을 초기화
  2. 가격의 기본값은 10000원
  3. 책 정보를 출력하는 display_info() 메서드 구현
  4. 할인된 가격을 계산하는 get_discounted_price(discount_rate) 메서드 구현

힌트: self 키워드를 사용하여 인스턴스 변수에 접근하세요.

# 테스트
book1 = Book("Python 프로그래밍", "홍길동")
book1.display_info()  # "제목: Python 프로그래밍, 저자: 홍길동, 가격: 10000원"
book1.get_discounted_price(0.2)  # 8000.0
class Book:
    """
    책 정보를 관리하는 클래스
    """
    # 여기에 코드를 작성하세요
    pass


# 테스트

문제 2: 클래스 변수와 인스턴스 변수

학생(Student) 클래스를 만들어 총 학생 수를 추적하세요.

요구사항:

  1. 클래스 변수 total_students로 총 학생 수 관리
  2. 인스턴스 변수로 이름(name), 학번(student_id) 저장
  3. 학생이 생성될 때마다 total_students 1증가
  4. 클래스 메서드 get_total_students()로 총 학생 수 반환
  5. 인스턴스 메서드 introduce()로 자기소개 출력

힌트: 클래스 변수는 클래스 정의 내부에서 직접 할당하고, self.__class__.변수명 또는 클래스명.변수명으로 접근합니다.

class Student:
    """
    학생 정보를 관리하는 클래스
    """
    # 여기에 코드를 작성하세요
    pass


# 테스트

문제 3: 정적 메서드 활용

온도 변환 유틸리티 클래스를 만드세요.

요구사항:

  1. TemperatureConverter 클래스 생성
  2. 정적 메서드 celsius_to_fahrenheit(celsius) - 섭씨를 화씨로 변환
  3. 정적 메서드 fahrenheit_to_celsius(fahrenheit) - 화씨를 섭씨로 변환
  4. 정적 메서드 is_freezing_celsius(celsius) - 섭씨 온도가 0도 이하인지 확인

힌트: - @staticmethod 데코레이터 사용 - 화씨 = 섭씨 × 9/5 + 32 - 섭씨 = (화씨 - 32) × 5/9

class TemperatureConverter:
    """
    온도 변환 유틸리티 클래스
    """
    # 여기에 코드를 작성하세요
    pass


# 테스트
# 인스턴스 생성 없이 바로 사용

문제 4: 클래스 메서드와 대체 생성자

날짜(Date) 클래스를 만들고 여러 방식으로 인스턴스를 생성할 수 있도록 하세요.

요구사항:

  1. __init__(year, month, day)로 기본 생성자 구현
  2. 클래스 메서드 from_string(date_string) - “YYYY-MM-DD” 형식 문자열에서 생성
  3. 클래스 메서드 today() - 오늘 날짜로 인스턴스 생성 (datetime 모듈 사용)
  4. 인스턴스 메서드 display() - “YYYY년 MM월 DD일” 형식으로 출력

힌트: @classmethod 데코레이터를 사용하고, 첫 번째 매개변수는 cls입니다.

# 테스트
date1 = Date(2025, 12, 1)
date2 = Date.from_string("2025-12-25")
date3 = Date.today()
from datetime import datetime

class Date:
    """
    날짜를 표현하는 클래스
    """
    # 여기에 코드를 작성하세요
    pass


# 테스트

문제 5: 상속 기본

도형(Shape) 부모 클래스와 이를 상속받는 자식 클래스들을 만드세요.

요구사항:

  1. Shape 클래스: x, y 좌표를 가지며, move(dx, dy) 메서드 구현
  2. Rectangle 클래스: Shape를 상속받고 width, height 추가, area() 메서드 구현
  3. Circle 클래스: Shape를 상속받고 radius 추가, area() 메서드 구현 (원의 넓이 = π × r²)
  4. 각 자식 클래스의 __init__에서 super().__init__()를 호출하여 부모 클래스 초기화

힌트: super()를 사용하여 부모 클래스의 메서드를 호출하세요.

import math

class Shape:
    """
    기본 도형 클래스
    """
    # 여기에 코드를 작성하세요
    pass


class Rectangle(Shape):
    """
    직사각형 클래스
    """
    # 여기에 코드를 작성하세요
    pass


class Circle(Shape):
    """
    원 클래스
    """
    # 여기에 코드를 작성하세요
    pass


# 테스트

문제 6: Private 변수와 메서드

은행 계좌(BankAccount) 클래스를 만들되, 잔액을 외부에서 직접 접근할 수 없도록 하세요.

요구사항:

  1. Private 인스턴스 변수 __balance로 잔액 관리
  2. deposit(amount) 메서드로만 입금 가능
  3. withdraw(amount) 메서드로만 출금 가능 (잔액 부족 시 False 반환)
  4. get_balance() 메서드로 잔액 조회
  5. Private 메서드 __validate_amount(amount)로 금액 검증 (0보다 큰지 확인)

힌트: Private 변수/메서드는 이름 앞에 __ (double underscore)를 붙입니다.

class BankAccount:
    """
    은행 계좌 클래스
    """
    # 여기에 코드를 작성하세요
    pass


# 테스트

문제 7: @property 데코레이터 활용

직원(Employee) 클래스를 만들어 연봉 정보를 관리하되, 월급은 자동으로 계산되도록 하세요.

요구사항:

  1. Private 변수 _annual_salary로 연봉 저장
  2. @property를 사용하여 annual_salary getter 구현
  3. @annual_salary.setter를 사용하여 setter 구현 (음수 불가)
  4. @property를 사용하여 monthly_salary getter 구현 (읽기 전용, 연봉/12)
  5. 연봉을 인상하는 raise_salary(percentage) 메서드 구현

힌트: property는 getter와 setter를 메서드처럼 정의하지만, 속성처럼 접근할 수 있게 해줍니다.

class Employee:
    """
    직원 정보 관리 클래스
    """
    # 여기에 코드를 작성하세요
    pass


# 테스트

문제 8: 메서드 오버라이딩과 다형성

동물(Animal) 클래스와 이를 상속받는 여러 동물 클래스들을 만드세요.

요구사항:

  1. Animal 부모 클래스: name 속성과 speak() 메서드 (“동물이 소리냅니다” 반환)
  2. Dog 클래스: speak() 오버라이딩 (“멍멍!” 반환)
  3. Cat 클래스: speak() 오버라이딩 (“야옹!” 반환)
  4. Bird 클래스: speak() 오버라이딩하되, super()로 부모 메서드도 호출 후 “짹짹!” 추가
  5. 여러 동물 객체를 리스트에 담아 반복문으로 speak() 호출 (다형성 시연)

힌트: 메서드 오버라이딩은 부모 클래스의 메서드를 자식 클래스에서 재정의하는 것입니다.

class Animal:
    """
    동물 기본 클래스
    """
    # 여기에 코드를 작성하세요
    pass


class Dog(Animal):
    # 여기에 코드를 작성하세요
    pass


class Cat(Animal):
    # 여기에 코드를 작성하세요
    pass


class Bird(Animal):
    # 여기에 코드를 작성하세요
    pass


# 테스트 - 다형성 시연

문제 9: 클래스 변수와 인스턴스 추적

제품(Product) 클래스를 만들어 생성된 모든 제품 인스턴스를 추적하세요.

요구사항:

  1. 클래스 변수 all_products로 모든 제품 인스턴스를 리스트에 저장
  2. 인스턴스 변수: name (제품명), price (가격), quantity (수량)
  3. __init__에서 생성된 인스턴스를 all_products에 추가
  4. 클래스 메서드 total_inventory_value() - 모든 제품의 총 재고 가치 계산 (가격 × 수량의 합)
  5. 클래스 메서드 find_by_name(name) - 이름으로 제품 찾기
  6. 정적 메서드 is_expensive(price) - 가격이 100,000원 이상인지 확인

힌트: self.__class__.all_products.append(self)를 사용하여 인스턴스를 리스트에 추가하세요.

class Product:
    """
    제품 정보 관리 및 인스턴스 추적 클래스
    """
    # 여기에 코드를 작성하세요
    pass


# 테스트

문제 10**: 종합 - 온라인 쇼핑몰 시스템

온라인 쇼핑몰의 주문 시스템을 클래스로 구현하세요. 이 문제는 지금까지 배운 모든 개념을 종합적으로 활용합니다.

시나리오:

고객(Customer)이 여러 상품(Item)을 장바구니(ShoppingCart)에 담고 주문(Order)을 생성하는 시스템입니다.

요구사항:

1. Item 클래스

  • 인스턴스 변수: name, price, stock (재고 수량)
  • 클래스 변수: _all_items (모든 상품 인스턴스를 담는 private 리스트)
  • 클래스 메서드 find_by_name(name) - 이름으로 상품 찾기
  • 메서드 reduce_stock(quantity) - 재고 감소 (재고 부족 시 False 반환)

2. Customer 클래스

  • 인스턴스 변수: name, email
  • 클래스 변수: total_customers (총 고객 수)
  • Property: email (setter에서 ‘@’ 포함 여부 검증)

3. ShoppingCart 클래스

  • 인스턴스 변수: customer (Customer 객체), _items (private 딕셔너리: {Item: quantity})
  • 메서드 add_item(item, quantity) - 장바구니에 상품 추가
  • 메서드 remove_item(item) - 장바구니에서 상품 제거
  • Property total_price (읽기 전용) - 장바구니 총 가격 계산
  • 메서드 checkout() - Order 객체 생성 및 재고 감소

4. Order 클래스

  • 클래스 변수: order_count (주문 번호 생성용)
  • 인스턴스 변수: order_id, customer, items (딕셔너리), total_price
  • 클래스 메서드 from_cart(cart) - ShoppingCart에서 Order 생성
  • 메서드 display_order() - 주문 정보 출력

힌트:

  1. Item 클래스:
    • __init__에서 self.__class__._all_items.append(self) 사용
    • find_by_name은 @classmethod로 구현하고 리스트 컴프리헨션 활용
  2. Customer 클래스:
    • @property와 @email.setter를 사용하여 이메일 검증
    • if '@' not in email: raise ValueError("유효하지 않은 이메일")
  3. ShoppingCart 클래스:
    • _items는 딕셔너리로 관리: {item_object: quantity}
    • total_price는 @property로 구현: sum(item.price * qty for item, qty in self._items.items())
    • checkout()에서 각 상품의 reduce_stock() 호출 후 Order.from_cart(self) 반환
  4. Order 클래스:
    • order_count를 증가시켜 고유한 order_id 생성
    • from_cart에서 cls(cart.customer, dict(cart._items), cart.total_price) 형태로 생성

테스트 시나리오:

# 상품 생성
laptop = Item("노트북", 1500000, 10)
mouse = Item("마우스", 30000, 50)
keyboard = Item("키보드", 80000, 30)

# 고객 생성
customer = Customer("홍길동", "hong@example.com")

# 장바구니에 상품 추가
cart = ShoppingCart(customer)
cart.add_item(laptop, 1)
cart.add_item(mouse, 2)
print(f"장바구니 총액: {cart.total_price:,}원")  # 1,560,000원

# 주문하기
order = cart.checkout()
order.display_order()
class Item:
    """
    상품 클래스
    """
    _all_items = []
    
    # 여기에 코드를 작성하세요
    pass


class Customer:
    """
    고객 클래스
    """
    total_customers = 0
    
    # 여기에 코드를 작성하세요
    pass


class ShoppingCart:
    """
    장바구니 클래스
    """
    # 여기에 코드를 작성하세요
    pass


class Order:
    """
    주문 클래스
    """
    order_count = 0
    
    # 여기에 코드를 작성하세요
    pass


# 테스트
Chapter 14: Exceptions

This work © 2025 by Sungkyun Cho is licensed under CC BY-NC-SA 4.0