본문 바로가기

SK네트웍스 Family AI캠프 10기/Daily 회고

7일차. 클래스 & 라이브러리

더보기
더보기

 

7일 차 회고.

 

 토이 프로젝트의 주제를 아직도 정하지 못했다. 그리고 내가 이 토이 프로젝트에 참여하는 것이 맞는지 의구심이 든다. 사실 이제는 정말로 선택과 집중을 할 때라 내가 하는 모든 일 하나하나가 다 선택이고, 그에 대한 결과를 내가 온전히 감당해야 하기 때문에 너무 어려운 것 같다. 프로젝트가 중요하긴 하지만 아직 배우는 단계이고, 배운 것을 내가 흡수할 수 있어야 하는데 그 시간을 줄이면서 프로젝트를 하는 것이기 때문에 고민이 된다. 프로젝트를 안 하게 된다면 자격증이나 코딩 테스트 공부를 할 수 있을 것이라서 계속 생각해봐야 할 것 같다.

 

 

 

 

1. 클래스

 

 

1-1. 상속(Inheritance)

 

자식 클래스는 부모 클래스에서 정의한 변수나 함수를 새로 생성하거나 수정할 수 있다.

class Parent:
    hello = "Hello"		# 클래스에 정의된 변수
    
    def __init__(self, name:str="Parent"):
        self.name = name	# 객체화할 때 정의되는 변수
    
    def print_hi(self):
        print("Hi")

class Child(Parent):
    def __init__(self):
        super().__init__(name="Child")	# super(): 부모 클래스(Parent)
        
        self.hello = "World"		# 부모 클래스의 변수 수정
        self.space = "Space"		# 부모 클래스에 없는 변수 생성
        
        def print_name(self):		# 부모 클래스에 없는 함수 생성
            print(self.name)
        
        def print_hi(self):		# 부모 클래스의 함수 수정
            print("HI")

mother = Parent()
print(mother.name, mother.hello)	# Parent Hello

ine = Child()
print(ine.name, ine.hello, ine.space)	# Child World Space
ine.print_name()	# Child
ine.print_hi()		# HI

 

 

1-2. 기사 vs. 마법사 게임 - 상속 사용

 

import random

class Person:
    def __init__(self, hp=80, attack=10):
        self.hp = hp
        self.attack = attack
    
    def perform_attack(self, who):
        self.attack_amount = self.attack
        if random.random() > 0.8:
            self.attack_amount *= 2
        print(f"{who} | Attack: {int(self.attack_amount)}")
        return self.attack_amount
        

class Knight(Person):
    def __init__(self):
        super().__init__(hp=100, attack=20)
    
    def perform_attack(self):
        return super().perform_attack(who="Knight")
    
    def perform_defend(self, attack_amount):
        if random.random() > 0.5:
            self.hp -= (attack_amount * 0.5)
            print(f"Knight | Defense Success. HP: {int(self.hp)}")
            return
        
        self.hp -= attack_amount
        print(f"Knight | HP: {int(self.hp)}")

        if self.hp <= 0:
            print("Knight | Defeat")

class Mage(Person):
    mp = 100

    def __init__(self):
        super().__init__(hp=50, attack=20)
    
    def perform_attack(self):
        return super().perform_attack(who="Mage")
    
    def perform_defend(self, attack_amount):
        if random.random() > 0.5:
            self.mp += 10
            if self.mp > 100:
                self.mp = 100
            print(f"Mage | Defense Success. HP: {int(self.hp)}, MP: {int(self.mp)}")
            return
        
        self.hp -= attack_amount
        print(f"Mage | HP: {int(self.hp)}, MP: {int(self.mp)}")

        if self.hp <= 0:
            print("Mage | Defeat")

 

knight = Knight()
mage = Mage()

def game():
    turn = random.choice(("knight", "mage"))

    i = 1

    while True:
        print("")
        print(f"Turn {i} \n")
        if turn == "knight":
            knight_attack = knight.perform_attack()
            mage.perform_defend(knight_attack)
            if mage.hp <= 0:
                break
            mage_attack = mage.perform_attack()
            knight.perform_defend(mage_attack)
            if knight.hp <= 0:
                break

        mage_attack = mage.perform_attack()
        knight.perform_defend(mage_attack)
        if knight.hp <= 0:
            break
        knight_attack = knight.perform_attack()
        mage.perform_defend(knight_attack)
        if mage.hp <= 0:
            break

        i += 1
        print("")
        print("-" * 33)

print("-" * 33)
print("")
print("Initial Statement")
print("Knight")
print(f"| HP: {knight.hp}, Attack: {knight.attack}")
print("Mage")
print(f"| HP: {mage.hp}, MP: {mage.mp}, Attack: {mage.attack}")
print("")
print("-" * 33)
game()
print("Game End")

 

 

1-3. public & private

 

class 내부뿐만 아니라 외부에서도 접근할 수 있는 것을 public이라고 한다.

반면, class 내부에서만 접근할 수 있고 외부에서는 접근할 수 없는 것을 private이라고 한다.

private 변수 및 함수를 만들 때는 변수명 앞에 '__'를 붙인다.

class Student:
    def __init__(self):
        self.school_name = "School"	# public attribute
        self.__name = "INe"		# private attribute
    
    def print_name(self):		# public method
        print(f"{self.school_name}")
    
    def __print_name(self):		# private method
        print(f"{self.school_name}")

s = Student()
s.print_name()	# School
print(s.school_name)	# School
s.__print_name()	# AttributeError
print(s.__name)		# AttributeError

 

private 변수 및 함수는 클래스 내에서 호출하여 사용할 수 있다.

class Student:
    def __init__(self):
        self.school_name = "School"	# public attribute
        self.__name = "INe"		# private attribute
    
    def print_name(self):		# public method
        self.__print_name()
    
    def __print_name(self):		# private method
        print(f"{self.__name}")

s = Student()
s.print_name()	# INe

 

 

1-4. 매직 메소드(Magic Method)

 

매직 메소드는 이미 Python에 정의되어 있기 때문에, 클래스 내부에서 오버라이딩하여 사용할 수 있다.

이는 직접 호출해서 사용하는 것이 아니라, 정해진 규칙에 따라 스스로 호출된다.

class Student:
    def __init__(self, name:str):
        self.name = name
        self.lst = [1, 2, 3, 4, 5]
    
    def print_hello(self):
        print("Hello")
        
    def __len__(self):			# Magic Method
        return len(self.name)
        
    def __getitem__(self, index:int):	# Magic Method
        return self.lst[index]
        
    def __call__(self):			# Magic Method
        return len(self.name)
        
s = Student("INe")
s.print_hello()
# Hello
len(s)		# __len__()
# 3
s[3]		# __getitem__()
# 4
s()		# __call__()
# 3

 

 

 

2. 라이브러리

 

 

2-1. 표준 라이브러리

 

Python을 설치하게 되면 자동으로 사용할 수 있는 모듈이 생성되는데, 이를 표준 라이브러리라고 한다.

 

2-1-1. Collections

Counter는 시퀀스 자료형의 데이터 값 개수를 딕셔너리 형태로 반환한다.

from collections import Counter

lst = ['a', 'a', 'b', 'b', 'b', 'c']

counter = Counter(lst)

print(counter)		# Counter({'b': 3, 'a': 2, 'c': 1})
type(counter)		# collections.Counter

list(counter.elements())	# ['a', 'a', 'b', 'b', 'b', 'c']

counter.most_common(1)		# [('b', 3)]

-----------------------

lst1 = ['a', 'a', 'b', 'c']
lst2 = ['a', 'b', 'b', 'c']

counter1 = Counter(lst1)
counter2 = Counter(lst2)

print(counter1)		# Counter({'a': 2, 'b': 1, 'c': 1})
print(counter2)		# Counter({'b': 2, 'a': 1, 'c': 1})

counter1 + counter2	# Counter({'a': 3, 'b': 3, 'c': 2})
counter1 - counter2	# Counter({'a': 1})
counter1 & counter2	# Counter({'a': 1, 'b': 1, 'c': 1})
counter1 | counter2	# Counter({'a': 2, 'b': 2, 'c': 1})

 

2-1-2. Math

math 모듈은 수학과 관련된 모듈로, 수학 연산을 할 때 자주 사용한다.

import math

math.pi			# 3.141592653589793
math.e			# 2.718281828459045
math.log(10)		# 2.302585092994046
math.exp(10)		# 22026.465794806718
math.pow(3, 5)		# 243.0
math.sqrt(100)		# 10.0
math.ceil(3.33)		# 4
math.floor(3.66)	# 4

 

2-1-3. Datetime

datetime 모듈은 날짜와 시간에 관련된 모듈로, 날짜 형식을 만들 때 자주 사용한다.

datetime 모듈은 날짜와 시간을 구할 때 사용한다.

from datetime import datetime

today = datetime.now()
today		# 2025-01-15 15:34:08.369493

print(f"년: {today.year}")		# 년: 2025
print(f"월: {today.month}")		# 월: 1
print(f"일: {today.day}")		# 일: 15
print(f"시: {today.hour}")		# 시: 15
print(f"분: {today.minute}")		# 분: 34
print(f"초: {today.second}")		# 초: 8
print(f"밀리초: {today.microsecond}")	# 밀리초: 369493

print(today.date())		# 2025-01-15
print(today.time())		# 15:34:08.369493
print(today.weekday())	# 2

dic_week = {0: '월', 1: '화', 2: '수', 3: '목', 4: '금', 5: '토', 6: '일'}
print(dic_week[today.weekday()])	# 수

today.strftime("%Y / %m / %d, %A")	# 2025 / 01 / 15, Wednesday
today.strftime("%H : %M : %S")		# 15 : 34 : 08

date = "2015-01-01 01:01:01"
datetime.strptime(date, "%Y-%m-%d %H:%M:%S")	# datetime.datetime(2015, 1, 1, 1, 1, 1)

 

timedelta 모듈은 두 날짜의 차이를 구할 때 사용한다.

from datetime import datetime, timedelta

str_today = "2015-01-01 01:01:01"
today = datetime.strptime(str_today, "%Y-%m-%d %H:%M:%S")
print(today)			# 2015-01-01 01:01:01

new_today = today + timedelta(days=1, hours=10, minutes=20)
print(new_today)		# 2015-01-02 11:21:01
print(new_today - today)	# 1 day, 10:20:00

 

2-1-4. Time

Time 모듈은 시간과 관련된 기능을 다룰 때 사용한다.

import time

for i in [1, 2, 3, 4, 5]:
    print(i)
    time.sleep(3)	# 3초 정지
# 1 -> 3초 정지
# 2 -> 3초 정지
# 3 -> 3초 정지
# 4 -> 3초 정지
# 5 -> 3초 정지

 

 

2-2. 라이브러리

 

외부 라이브러리는 먼저 pip install을 통해 설치해야 한다.

pip install python-dateutil

 

2-2-1. dateutil

timedelta 모듈은 일, 시간의 차이만 구할 수 있지만, dateutil 모듈은 년, 월의 차이도 구할 수 있다.

from dateutil.relativedelta import relativedelta

from dateutil.relativedelta import relativedelta

str_today = "2015-01-01 01:01:01"
today = datetime.strptime(str_today, "%Y-%m-%s %H:%M:%S")

new_date = today + relativedelta(years=5, months=2, days=10, hours=2)
print(new_date)		# 2020-03-11 03:01:01

 

tz 모듈은 timezone을 이용하여 날짜 및 시간을 구할 때 사용한다.

from datetime import datetime
from dateutil import tz

utc_timezone = tz.tzutc()

utc_now = datetime.now(utc_timezone)
print(utc_now)		# 2025-01-15 08:11:21.260430+00:00

ko_timezone = tz.gettz("Asia/Korea")
ko_now = datetime.now(korea_timezone)
print(ko_now)		# 2025-01-15 17:11:21.663562

 

 

 

3. 인코딩 & 디코딩

 

 

3-1. 인코딩

 

Python에서 문자열은 유니코드로 처리한다. 인코딩은 이러한 문자열을 byte 코드로 변환하는 것이다.

korean_str = "한글"

encoded = korean_str.encode('utf-8')
print(encoded)		# b'\xed\x95\x9c\xea\xb8\x80'

encoded = korean_str.encode('euc-kr')
print(encoded)		# b'\xc7\xd1\xb1\xdb'

 

 

3-2. 디코딩

 

디코딩은 byte 코드를 문자열로 변환하는 것이다.

korean_str = b'\xed\x95\x9c\xea\xb8\x80'

decoded = korean_str.decode('utf-8')
print(decoded)		# 한글

korean_str = b'\xc7\xd1\xb1\xdb'

decoded = korean_str.decode('euc-kr')
print(decoded)		# 한글

 

 

'SK네트웍스 Family AI캠프 10기 > Daily 회고' 카테고리의 다른 글

9일차. DCL & DML  (0) 2025.01.17
8일차. MySQL & 데이터베이스 & DDL  (0) 2025.01.16
6일차. 함수 & 클래스  (0) 2025.01.14
5일차. 함수  (0) 2025.01.13
4일차. 제어문 & 예외 처리  (0) 2025.01.10