자신에게 친절할 것 :)

Web Developing/Python

[python] 객체와 클래스 연습

Tashapark 2024. 7. 20. 20:59
728x90
반응형

# 코드잇 객체 지향 프로그래밍 in Python 로드맵 따라가는 중

 


 

- 솔직히.. 설명까지 해가면서 정리를 할 시간은 없고 국비지원 강의를 들으면서 

oop 수업에서 클래스 설명을 하시는 데 너무 아찔해서.. 주말이 온 김에 이전에 들으려다가 미뤄뒀던 

코드잇 강의를 듣고 있다. 

- 국비지원은 온라인 이러닝이 따라올 수 없는 깊이로 코드와 메모리를 설명해주셔서 많은 것을 배우지만, 

시간 관계 상 많은 예시나 코드를 직접 짜볼 시간을 많이 주시지 못하기 때문에 

본 강의를 들으면서 연습을 하고 있다. 

 

++ 다만, 객체와 클래스를 본 코드잇 강의('객체와 클래스')로 처음 듣는다면, 이해하기가 어려움. 

but, 이미 어딘가에서 들어봤다면 정리/복습용(recap)으로 좋음

 

+++ 국비지원은 파이참을 통해서 강의를 하시고 

if __name__ == '__main__':

- main을 명시해서 코드를 읽는 지점을 명시하는 데 

이전까지 vscode와 온라인 강의에서는 이를 명시하지 않는다. 

- 그래서 지금도 어떤 경우에 쓰는지 모르겠어. 자바의 메인과 비슷한 거 같긴한데.

+++ 코드잇 강의도 main이 명시되지 않음. 

 


- 이 포스트는 코드잇 강의를 들으며 짠 코드만 올려놓고,

1) 클래스의 원형을 익히고, 

2) 내 코드가 틀린 이유를 확인하고,

3) 정답 코드를 보기 위함. 


<객체와 클래스 연습>

- self. --> 주소값임을 잊지 말 것... 

- 선언된 순간부터 클래스 내에서는 모든 변수에 계속 붙어다님.  

 

-   강의 

class User:
    #n 매직 변수, 특수 메소드 __init__ 메소드는 인스턴스 생성시 자동으로 만들어짐. 
    def __init__(self, name, email, password): #인스턴스 변수 생성 및 초기화: 변수 개수가 늘어나도 쓰기 어렵지 않음
        self.name = name
        self.email = email
        self.password = password

    def say_hello(self):
        print(f"안녕하세요! 저는 {self.name}입니다!")

    def login(self, email, password): #메소드 정의 시, class 파라미터에 맨 처음에 self를 꼭 넣어야 함. 
        if self.email == email and self.password == password: #셀프 붙인 것과 아닌 것은 명백히 다름. 
            print("로그인 성공, 환영합니다")
            self.say_hello()
        else:
            print("로그인 실패, 없는 아이디이거나 잘못된 비밀번호입니다.")
    
    def __str__(self): #user1()출력하면 주소값이 나오기 때문에, __str__로 값을 넣어주는 것
        return f"사용자: {self.name}, 이메일: {self.email}"



user1 = User("강영훈", "younghoon@codeit.xyz", "12345")
user2 = User("이윤수","yoonsoo@codeit.xyz","abcde")


print(user1)
print(user2)

# 이렇게 계속 쓰면 힘드니깐, 이니셜라이즈로 해줌. 
# user1 = User()
# user2 = User()

# print(type(user1))
# print(type(user2))

# user1.name ="강영훈"
# user1.email = "younghoon@codeit.xyz"
# user1.password = "12345"

# user2.name ="이윤수"
# user2.email = "yoonsoo@codeit.xyz"
# user2.password = "abcde"

 


-   인스타그램  팔로워랑 팔로잉 수 확인하기

class User:
    # 인스턴스 변수 설정
    def __init__(self, name, email, password):
        self.name = name
        self.email = email
        self.password = password

        self.following_list = []    # 이 유저가 팔로우하는 유저 리스트
        self.followers_list = []    # 이 유저를 팔로우하는 유저 리스트

    # 팔로우
    def follow(self, another_user):
        # 여기에 코드를 작성하세요
        self.following_list.append(another_user)
        another_user.followers_list.append(self) #거꾸로를 생각 못했어 ㅎ
        

    # 내가 몇 명을 팔로우하는지 리턴
    def num_following(self):
        # 여기에 코드를 작성하세요
        num_following = len(self.following_list)
        return num_following

    # 나를 몇 명이 팔로우하는지 리턴
    def num_followers(self):
        # 여기에 코드를 작성하세요
        num_followers = len(self.followers_list)
        return num_followers

# 유저들 생성
user1 = User("Young", "young@codeit.kr", "123456")
user2 = User("Yoonsoo", "yoonsoo@codeit.kr", "abcdef")
user3 = User("Taeho", "taeho@codeit.kr", "123abc")
user4 = User("Lisa", "lisa@codeit.kr", "abc123")

# 유저마다 서로 관심 있는 유저를 팔로우
user1.follow(user2)
user1.follow(user3)
user2.follow(user1)
user2.follow(user3)
user2.follow(user4)
user4.follow(user1)

# 유저 이름, 자신의 팔로워 수, 자신이 팔로우하는 사람 수를 출력합니다
print(user1.name, user1.num_followers(), user1.num_following())
print(user2.name, user2.num_followers(), user2.num_following())
print(user3.name, user3.num_followers(), user3.num_following())
print(user4.name, user4.num_followers(), user4.num_following())

 


-   메뉴만들기

class MenuItem:
    # 음식 메뉴를 나타내는 클래스
    def __init__(self, name, price):
        # 여기에 코드를 작성하세요
        self.name = name
        self.price = price
        

    def __str__(self):
        # 여기에 코드를 작성하세요
        return f'{self.name} 가격: {self.price}'


# 메뉴 인스턴스 생성
burger = MenuItem("햄버거", 4000)
coke = MenuItem("콜라", 1500)
fries = MenuItem("후렌치 후라이", 1500)

# 메뉴 인스턴스 출력
print(burger)
print(coke)
print(fries)

 

 


-   게임 캐릭터 만들기

- 이거 재밌었는데, 어떻게 함수들을 서로 참조해야 할지 고민하느라 계속 틀렸음. 

- 결국 해설을 보고 풀음. 

- 너무 지나치게 if를 많이 사용해서 온 사방군데에 사용한 것이 문제였고 get_attcked()의 조건을 순서대로 만들려고 하다가 꼬였음. 

- 주석 처리도 되어 있지만, ternary expression을 연습할 것. 

- 값 if 조건  else 값 --> 인듯?

 self.hp = self.hp - damage if self.hp >= damage else 0
 #if self.hp >= damage:
 #               self.hp = self.hp - damage
 #           else: 
 #               self.hp = 0

 

 

class GameCharacter:
    # 게임 캐릭터 클래스
    def __init__(self, name, hp, power):
        # 게임 캐릭터는 속성으로 이름, hp, 공격력을 갖는다
        self.name = name
        self.hp = hp
        self.power = power


    def is_alive(self):
        # 게임 캐릭터가 살아있는지(체력이 0이 넘는지) 확인하는 메소드
        return self.hp > 0
        
    def get_attacked(self, damage):
        """
        게임 캐릭터가 살아있으면 공격한 캐릭터의 공격력만큼 체력을 깎는 메소드
        조건:    
            1. 이미 캐릭터가 죽었으면 죽었다는 메시지를 출력한다
            2. 남은 체력보다 공격력이 더 크면 체력은 0이 된다
        """
        
        if self.is_alive():
            if self.hp >= damage:
                self.hp = self.hp - damage
            else: 
                self.hp = 0
            #self.hp = self.hp - damage if self.hp >= damage else 0
        else:
            print(f'{self.name}님은 이미 죽었습니다.')
            
    def attack(self, other_character):
        # 게임 캐릭터가 살아있으면 파라미터로 받은 다른 캐릭터의 체력을 자신의 공격력만큼 깎는다
       if self.is_alive():
           return other_character.get_attacked(self.power)
     

    def __str__(self):
        # 게임 캐릭터의 의미있는 정보를 포함한 문자열을 리턴한다
        return f'{self.name}님의 hp는 {self.hp}만큼 남았습니다.'
       
        
# 게임 캐릭터 인스턴스 생성                        
character_1 = GameCharacter("Ww영훈전사wW", 200, 30)
character_2 = GameCharacter("Xx지웅최고xX", 100, 50)

# 게임 캐릭터 인스턴스들 서로 공격
character_1.attack(character_2)
character_2.attack(character_1)
character_2.attack(character_1)
character_2.attack(character_1)
character_2.attack(character_1)
character_2.attack(character_1)

# 게임 캐릭터 인스턴스 출력
print(character_1)
print(character_2)

 

 


-   블로그 유저 만들기

- 이것도 재밌었는데, 어떻게 함수들을 서로 참조해야 할지 고민하느라 계속 틀렸음. 

def show_all_posts(self):
        # 블로그 유저의 모든 게시글 출력
        for post in self.posts:
            print(post)
        #print(self.posts) #이러면 주소값이 나와.

- 모든 게시글 출력 부분에 자꾸 self.posts를 넣어서.. 대체 어떻게 해야 하지 하다가 해설 봤음.

- for문...을 쓰면 되는데 자꾸.. 떠올리지를 못함 ㅜ

 

class Post:
    # 게시글 클래스
    def __init__(self, date, content):
        # 게시글은 속성으로 작성 날짜와 내용을 갖는다
        self.date = date
        self.content = content

    def __str__(self):
        # 게시글의 정보를 문자열로 리턴하는 메소드
        return "작성 날짜: {}\n내용: {}".format(self.date, self.content)
    
    
class BlogUser:
    # 블로그 유저 클래스
    def __init__(self, name):
        """
        블로그 유저는 속성으로 이름, 게시글들을 갖는다
        posts는 빈 배열로 초기화한다
        """
        self.name = name
        self.posts = []

    def add_post(self, date, content):
        # 새로운 게시글 추가
        self.posts.append(Post(date, content))
        # 새로운 게시글 추가 # 나눠서 할 수도
        #new_post = Post(date, content)
        #self.posts.append(new_post)

    def show_all_posts(self):
        # 블로그 유저의 모든 게시글 출력
        for post in self.posts:
            print(post)
        #print(self.posts) #이러면 주소값이 나와.

    def __str__(self):
        # 간단한 인사와 이름을 문자열로 리턴
        return f'안녕하세요 {self.name}입니다.\n'
    
    

# 블로그 유저 인스턴스 생성
blog_user_1 = BlogUser("성태호")

# 블로그 유저 인스턴스 출력(인사, 이름)
print(blog_user_1)

# 블로그 유저 게시글 2개 추가
blog_user_1.add_post("2019년 8월 30일", """
오늘은 내 생일이었다.
많은 사람들이 축하해줬다.
행복했다.
""")

blog_user_1.add_post("2019년 8월 31일", """
재밌는 코딩 교육 사이트를 찾았다.
코드잇이란 곳인데 최고다.
같이 공부하실 분들은 www.codeit.kr로 오세요!
""")

# 블로그 유저의 모든 게시글 출력
blog_user_1.show_all_posts()
728x90
반응형