22.09.13(화) Today I Learned

정형빈·2022년 9월 13일
0

TIL

목록 보기
9/71

9/13 오늘의 시간표

09:00 ~ 10:00 [실시간] 파이썬 문법
10:00 ~ 11:00 [실시간] 파이썬 문법
11:00 ~ 12:00 [실시간] 파이썬 문법
12:00 ~ 13:00 [실시간] 파이썬 문법
13:00 ~ 14:00 점심식사
14:00 ~ 15:00 [실시간] 파이썬 문법
15:00 ~ 16:00 [실시간] 파이썬 문법
16:00 ~ 17:00 [실시간] 파이썬 문법
17:00 ~ 18:00 [실시간] 파이썬 문법
18:00 ~ 19:00 저녁식사
19:00 ~ 20:00 [실습] 실무적용 알고리즘 실습
20:00 ~ 21:00 [실습] 실무적용 알고리즘 실습

이제는 너무 익숙해져버린 그 시간표 그대로이다. 연휴를 쉬고온 튜터님의 강의를 들으면 상쾌하게 아침을 출발했다.

파이썬 실시간 강의

- 이창호 튜터님 진행

오전 파이썬 실시간 강의 우선 첫 강의로는 추석 연휴동안 숙제로 내 주신 숫자야구 게임 만들기에 대한 풀이를 해주셨다. 전체적인 풀이 방법은 내가 참고한 것과 크게 다른 부분은 없었지만 파이썬의 코드가 워낙 다양하다보니 내가 한 방법과 다른 방법으로 만들어진 것도 있었다.
예를 들자면 랜덤한 숫자 N개를 뽑아내는 과정을 3가지 케이스로 알려주셨는데

import random

length = int(input())


# Case 1

number_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
random.shuffle(number_list)

random_numbers = number_list[0:length] 

print(random_numbers)




# Case 2

number_list = [x for x in range(10)]

random_number = []

for _ in range(length):
    random_number.append(number_list.pop(random.randrange(0, len(number_list))))

print(random_number)




# Case 3

random_numbers = set()

while len(random_numbers) < length:
    random_numbers.add(random.randint(0, 9))
    
    random_numbers = list(random_numbers)
    random.shuffle(random_numbers)
    print(random_numbers)

이렇게 세 종류를 설명해 주셨다. 나는 케이스 3번에서 살짝만 다른 느낌으로 코드를 만들었는데 1번 케이스의 경우 randint함수 없이 좀 더 직관적으로 만들 수 있지만 숫자의 범위가 0~9가 아니라 훨씬 더 커지면 작업이 복잡해질 수도 있을 것 같고 2번 케이스역시 숫자가 커지면 pop을 통해 지워야 할 숫자가 많아져서 코드의 계산시간이 길어질 것 같아서 숫자가 더 커지는 경우에는 3번방법을 활용하는 것이 좋겠다는 생각이 들었다.

이후 다시 원래의 강의로 돌아와 파이썬 심화 문법에 대한 설명을 해 주셨고 아래는 그 요약본이다.

class에 대한 이해

class란?

  • 클래스를 선언하는것은 과자 틀을 만드는 것이고, 선언된 과자틀(class)로
    과자(instance)를 만든다고 생각하면 된다.
  • 선언 후 바로 사용되는 함수와 다르게 클래스는 인스턴스를 생성하여 사용하게 된다.
  • class 내부에 선언되는 메소드는 기본적으로 self라는 인자를 가지고 있다.
  • self는 클래스 내에서 전역 변수와 같이 사용된다.

용어 정리

- 인스턴스(instance) : class를 사용해 생성된 객체
- 메소드(method) : 메소드란 클래스 내에 선언된 함수이며, 클래스 함수라고도 한다.
- self : 메소드를 선언할 때에는 항상 첫번째 인자로 self를 넣어줘야 한다.
		 클래스 안에 있는 변수나 함수 정보를 담고 있다.
  • class의 기본 구조
    class CookieFrame(): # CookieFrame이라는 이름의 class 선언
        def set_cookie_name(self, name): 
            self.name = name
    
    cookie1 = CookieFrame()
    cookie2 = CookieFrame()
    
    cookie1.set_cookie_name("cookie1") # 메소드의 첫 번째 인자 self는 무시된다.
    cookie2.set_cookie_name("cookie2")
    
    print(cookie1.name) # cookie1
    print(cookie2.name) # cookie2
  • __init__ 함수
    # class에 __init__메소드를 사용할 경우 인스턴스 생성 시 해당 메소드가 실행된다.
    class CookieFrame():
        def __init__(self, name):
            print(f"생성 된 과자의 이름은 {name} 입니다!")
            self.name = name
    
    cookie1 = CookieFrame("cookie1") # 생성 된 과자의 이름은 cookie1 입니다!
    cookie2 = CookieFrame("cookie2") # 생성 된 과자의 이름은 cookie2 입니다!

mutable 자료형과 immutable 자료형

  • mutable과 immutable이란?
    muteble은 값이 변한다는 의미이며, immutable은 값이 변하지 않는다는 의미이다.
    int, str, list 등 자료형은 각각 muteble 혹은 immuteble한 속성을 가지고 있다.
    
    a = 10
    b = a
    
    b += 5
    
    와 같은 코드가 있을 때 a에 담긴 자료형이 muteble 속성인지 immuteble 속성인지에 따라
    출력했을 때 결과가 달라지게 된다.
  • immutable 속성을 가진 자료형
    • int, float, str, tuple
  • mutable 속성을 가진 자료형
    • list, dict
  • 코드에서 mutable과 immutable의 차이 비교해보기
    immutable = "String is immutable!!"
    mutable = ["list is mutable!!"]
     
    string = immutable
    list_ = mutable
    
    string += " immutable string!!"
    list_.append("mutable list!!")
    
    print(immutable)
    print(mutable)
    print(string)
    print(list_)
    
    # result print
    """
    String is immutable!!
    ['list is mutable!!', 'mutable list!!']
    String is immutable!! immutable string!!
    ['list is mutable!!', 'mutable list!!']
    """

파이썬 오늘의 과제

- 클래스 활용해보기

오늘은 무려 과제가 3개나 된다!라고 하기보다는 튜터님이 우리들의 수준 파악을 위해 난이도별로 과제를 내주셔서 첫번째 문제를 풀면 두번째 문제로 넘어가고 막히면 막히는 대로 거기까지만 진행한 뒤 진행 상황을 제출란에 표시하는 것이다.

1. 도형 넓이 계산기

요구조건

  • 인스턴스를 선언할 때 가로, 세로 길이를 받을 수 있는 클래스를 선언해 주세요
  • 인스턴스에서 사각형, 삼각형, 원의 넓이를 구하는 메소드를 생성해주세요
    • 원의 넓이를 계산할 때는 세로 길이는 무시하고, 가로 길이를 원의 지름이라 가정하고 계산해 주세요
  • 입출력 예제
    area = Area(10, 20)
    print(area.square()) # 사각형의 넓이
    print(area.triangle()) # 삼각형의 넓이
    print(area.circle()) # 원의 넓이

코드작성시작!

class Area():
    def __init__(self, width, height):
        self.width = width
        self.height = height
    def square(self, width, height):
        return width * height
    def triangle(self, width, height):
        return width * height /2
    def circle(width, height):
        return (width / 2) ** 2 * 3.14

area = Area(10, 20)
print(area.square())
print(area.triangle())
print(area.circle())

클래스를 활용하는 과제니까 먼저 클래스 선언부터 해 주었다. 입력값이 Area(10, 20)이기 때문에 클래스 이름도 Area()로 하고 __init__ 함수를 이용해 받아온 값을 각각 width와 height라고 선언해 두었다. 그리고 도형 계산식을 만들었는데 초등학생때의 기억을 되새겨 사각형, 삼각형, 원의 계산식을 따와서 메소드 생성을 하고 area에 Area(10, 20)의 값을 준 뒤 각 도형 계산식에 대입하면 끝! 인줄 알았는데 예상치 못한 오류가 발생하였다. Line13에서 오류가 발생하였는데 그말은 즉 area.square()함수가 가로와 세로의 값을 받아오지 못한다는 말이었다. 그래서 함수의 계산식도 바꿔보고 __init__함수도 재설정 해보고 내가 아는 선에서는 모든 해결법을 총 동원해보고 혹시 몰라 구글링까지 해봤지만 구글에도 평범한 도형계산식만 있지 class를 활용한 케이스는 없는 것 같아 결국 튜터님을 찾아가 질문해보았고 늘 그렇듯 해답은 간단한 것이었다.

class Area():
    def __init__(self, width, height):
        self.width = width
        self.height = height
    def square(self):
        return self.width * self.height
    def triangle(self):
        return self.width * self.height /2
    def circle(self):
        return (self.width / 2) ** 2 * 3.14
        
area = Area(10, 20)
print(area.square())
print(area.triangle())
print(area.circle())

이미 __init__함수를 통해 width와 height값을 받아왔는데 도형계산식에서 또다시 width와 height값을 받아오려고 했기 때문에 해당 값을 받아올 곳이 없었던 것이었다. 결국 도형 계산식에 요구되는 width와 height를 모두 없애고 대신 self.width와 self.height를 받아와 계산하도록 하니까 답은 쉽게 나왔다.

풀고보니 굉장히 쉽고 황당한 실수지만 막상 막히는 상황이 오니 해결책을 찾는데 눈앞이 깜깜한것을 직접 느꼈다. 하지만 초보이기 때문에 충분히 할 수 있는 실수이고 오히려 실수를 한 번 했으니 앞으로 이런 일이 발생하게 되면 당황하지 않고 해결할 수 있을테니 오히려 좋다고 생각하겠다.

2. 계산기 만들어보기(with class)

요구조건

  • 설정한 숫자를 계산해줄 클래스를 선언해주세요
  • 메소드를 호출해서 num1, num2를 설정할 수 있도록 해주세요
  • 입력된 숫자의 더하기, 빼기, 곱하기, 나누기 연산 결과를 구하는 메소드를 생성해주세요
  • 입출력 예제
    calc = Calc()
    clac.set_number(20, 10)
    print(calc.plus()) # 더한 값
    print(calc.minus()) # 뺀 값
    print(calc.multiple()) # 곱한 값
    print(calc.divide()) # 나눈 값

코드작성시작!

class Calc():
    def set_number(self, num1, num2):
        self.num1 = num1
        self.num2 = num2
    def plus(self):
        return self.num1 + self.num2
    def minus(self):
        return self.num1 - self.num2
    def multiple(self):
        return self.num1 * self.num2
    def divide(self):
        if self.num2 == 0:
            print("0으로는 나눌 수 없습니다!")
        else:
            return self.num1 / self.num2
    
calc = Calc()
calc.set_number(20,10)
print(calc.plus())
print(calc.minus())
print(calc.multiple())
print(calc.divide())

계산기 만들기는 이미 한번 해봤기 때문에 오히려 1번보다 하기 쉬웠다. 1번에서 실수도 한번 저질렀으니 같은 실수를 반복하지만 않으면 너무 수월하게 해결되는 과제였다.

3. 프로필 관리 기능 만들어보기

요구조건

  • 사용자들의 프로필을 관리할 수 있는 클래스를 선언해주세요
  • 메소드를 호출해서 사용자의 프로필을 설정할 수 있도록 해주세요
  • 사용자의 정보를 각각 출력할 수 있는 메소드를 만들어주세요
  • 입출력 예제
    profile = Profile()
    profile.set_profile({
        "name": "lee",
        "gender": "man",
        "birthday": "01/01",
        "age": 32,
        "phone": "01012341234",
        "email": "python@sparta.com",
    })
    
    print(profile.get_name()) # 이름 출력
    print(profile.get_gender()) # 성별 출력
    print(profile.get_birthday()) # 생일 출력
    print(profile.get_age()) # 나이 출력
    print(profile.get_phone()) # 핸드폰번호 출력
    print(profile.email()) # 이메일 출력

코드작성시작!

class Profile():
    def __init__(self):
        self.profile = {
            "name": "-",
            "gender": "-",
            "birthday": "-",
            "age": "-",
            "phone": "-",
            "email": "-"
        }
        
    def set_profile(self, profile):
        self.profile = profile
        
    def get_name(self):
        return self.profile["name"]
    def get_gender(self):
        return self.profile["gender"]
    def get_birthday(self):
        return self.profile["birthday"]
    def get_age(self):
        return self.profile["age"]
    def get_phone(self):
        return self.profile["phone"]
    def get_email(self):
        return self.profile["email"]


profile = Profile()
profile.set_profile({
    "name": "lee",
    "gender": "man",
    "birthday": "01/01",
    "age": 32,
    "phone": "01012341234",
    "email": "python@sparta.com",
})

print(profile.get_name()) # 이름 출력
print(profile.get_gender()) # 성별 출력
print(profile.get_birthday()) # 생일 출력
print(profile.get_age()) # 나이 출력
print(profile.get_phone()) # 핸드폰번호 출력
print(profile.get_email()) # 이메일 출력

어디서 많이 본 듯 한 내용이었는데 역시 오늘 강의 class 활용해보기의 내용과 거의 같은 문제였다. 다른점이 있다면 getprofile을 통해 프로필을 통째로 불러오는 것이 아니라 프로필 dictionary 안에 있는 각 key값들을 하나 하나 꺼내오게 한다는 점이 다른 점이었다. class 활용해보기에서 사용된 코드를 그대로 가져와 붙여넣고 조금만 수정하면 매우 쉬운 과제이지만 그렇게 하면 과제를 하는 의미가 없으니 처음부터 직접 코드를 다시 다 만들었다. 대신 get_profile로 한번에 정보를 가져오는 것이 아니라 'get가져올key값' 으로 하나씩만 가져왔는데 이 때 return값을 새로 받아올 때 전에 배웠던 ["key"]를 통해 dictionary에서 key에 해당하는 value 값만 가져오도록 설정해주었다.

오늘 할 일을 끝내고

오늘 배운 클래스가 난해하고 내용이 어렵다고 판단하셨는지 오늘치 알고리즘 실습은 따로 주어진 할당량이 없었다. 확실히 클래스라는 부분이 과제를 하는 와중에도 이해가 안가서 그냥 이해하기보단 먼저 부딪혀보는 쪽을 선택해서 끝냈는데 활용 자체는 엄청나게 어렵지는 않았다. 하지만 아직도 도대체 왜 어째서 이것을 사용해야하는지는 알 수가 없다. django를 배우게되면 알게 된다는데 아직은 그때가 오지 않았으니 일단은 클래스를 다룰 줄 알게 된 것에 만족하도록 하겠다. 덕분에 오늘은 조금 시간적 여유가 있어서 강의를 듣다 놓친부분도 다시 들을 수 있게되었고 못 푼 알고리즘 문제도 한번 더 시도할 시간이 생겨서 너무 좋았다 놓친 부분들은 오늘 다시 잡고 가는걸로 하고 내일부터는 다시 내일의 배울 것들에 집중하도록 하겠다.

profile
스파르타 내일배움캠프 3기 수강생 정형빈

0개의 댓글