22.09.21(수) Today I Learned

정형빈·2022년 9월 22일
0

TIL

목록 보기
15/71

9/21 오늘의 시간표

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 [실습] 실무적용 알고리즘 실습

자료구조와 알고리즘 시간표 편성 마지막날이다. 오늘이 지나면 이제 팀도 바뀌고 새롭게 장고에 대해 배우는 시간을 갖게 되기 때문에 사실상 오늘이 파이썬 문법을 공부하는 마지막날이 되는 것이다. 지금의 나는 파이썬 문법에 대해 충분히 이해하고 따라갈 수 있지만 막상 스스로 해야하는 상황이오면 아직은 헤메이는 부분이 있는 것 같다. 물론 거북이반 수업을 들으며 많이 나아진 편이지만 솔직히 혼자 해보라고 한다면 아직은 조금 무섭다. 경험이 부족해 겁을 많이 먹고 있어 그런 것도 있겠지만 역시 일단은 오늘까지 확실하게 복습하며 다시 한번 확실히 짚고가는 수 밖에는 없으니 복습을 제대로 해봐야겠다.

자료구조와 알고리즘 원격강의

-> 파이썬 문법 복습

오늘도 과감하게 알고리즘 원격강의보다 파이썬에 시간을 투자하는 방향으로 결정했고 오늘은 역시 지금까지 배운 것을 최종적으로 되짚는 시간이 필요하다고 생각했다.

1-4 변수선언과 자료형

  • 변수 : a = b, a = 2처럼 특정 값에 새로운 값을 부여하는 것
  • 변수에 숫자 값을 주어서 연산을 하는 것 또한 가능
  • 사칙연산은 물론이고 제곱(ab), 나누기를 했을 때의 몫(a//b), 나누기를 했을 때의 나머지(a%b)등의 계산도 가능하다.
  • x=True y=False 등의 참/거짓을 나타내는 것 또한 가능
  • x = 3 > 2면 x=True, y= 1 > 4면 y=False 등

    1-5 문자열 다루기

  • 문자열 : 변수에서 문자열은 ‘ ’나 “ ”로 구분한다.
  • 값을 숫자로 주더라도 ‘ ’나 “ ”안에 있다면 문자열
  • 문자열 + 숫자를 할 경우 에러가 발생함으로 주의!
  • len()함수를 사용시 문자열의 길이를 구할 수 있음

    ex)
    print(len("abcde")) # 5
    print(len("Hello, Sparta!")) # 14
    print(len("안녕하세요.")) # 6

    1-6 리스트와 딕셔너리

  • 리스트는 순서가 있는 다른 자료형들의 모임이다.
  • 리스트도 len()함수를 통해 길이를 잴 수 있다.

    ex)
    a = [1, 5, 2]
    print(len(a)) # 3

    b = [1, 3, [2, 0], 1]
    print(len(b)) # 4

  • 순서가 있기 때문에 문자열에서러럼 인덱싱과 슬라이싱이 가능하다. 리스트의 요소로 리스트를 넣는 것이 가능하다.

    ex)
    a = [1, 2, [2, 3], 0]
    print(a[2]) # [2, 3]
    print(a[2][0]) # 2

  • .append()를 이용하여 리스트안에 값을 추가할 수 있다.
  • .sort()를 이용하여 리스트의 값들을 크기순으로 정렬 가능하고 .sort(reverse=True)를 사용시 역순 정렬도 가능하다.
  • in과 not in을 사용하여 리스트 안에 찾고자 하는 값이 있는지 찾을 수도 있다.
  • 딕셔너리는 key와 value로 이루어진 자료의 모음집이다.

    ex)
    person = {"name":"Bob", "age": 21}
    print(person["name"])

  • 딕셔너리의 요소에는 순서가 없기 때문에 인덱싱을 사용할 수 없다.
  • 딕셔너리의 값을 업데이트 하거나 새로운 쌍의 자료를 넣을 수도 있다.

    ex)
    person = {"name":"Bob", "age": 21}
    person["name"] = "Robert"
    print(person) # {'name': 'Robert', 'age': 21}

    person["height"] = 174.8
    print(person) # {'name': 'Robert', 'age': 21, 'height': 174.8}

  • 딕셔너리의 밸류로는 아무 자료형이나 넣을 수 있고 다른 딕셔너리를 넣는 것 또한 가능하다.

    ex)
    person = {"name":"Alice", "age": 16, "scores": {"math": 81, "science": 92, "Korean": 84}}
    print(person["scores"]) # {'math': 81, 'science': 92, 'Korean': 84}
    print(person["scores"]["science"]) # 92

  • 리스트와 마찬가지로 in과 not in으로 딕셔너리 안에 해당 요소가 있는지 확인할 수 있다.

    1-7 조건문

  • if조건문은 조건을 만족했을 때만 특정 코드를 실행하도록 하는 문법이다.
  • else는 조건을 만족하지 않을 때 특정 코드를 실행하도록 하는 문법이다.
  • elif는 다양한 조건을 판단할 때 쓰인다.

    ex)
    age = 27
    if age < 20:
    print("청소년입니다.")
    elif age < 65:
    print("성인입니다.")
    else:
    print("무료로 이용하세요!")

    1-8 반복문

  • 반복문이란 특정 부분(리스트나 문자열 등)을 반복해서 실행하는 구조로 for문, while문,do문 등이 있다.

    for문

    fruits = ['사과', '배', '감', '귤']

    for fruit in fruits:

    print(fruit) # 사과,배,감,귤

    1-9 함수

  • 함수: 반복적으로 사용하는 코드들에 이름을 붙여놓은 것

    함수선언 : def 함수명(매개변수):

    					<수행할 문장1>
    
    					<수행할 문장2>

    def check_gender(pin):

    num = int(pin.split('-')[1][0])

    if num % 2 == 0:

    print('여성')

    else:

    print('남성')

    my_pin = "200101-3012345"

    check_gender(my_pin)

    결과값 : 남성

    1-11 튜플, 집합

  • 튜플 : 튜플은 리스트와 비슷하지만 불변이기 때문에 값을 추가하거나 수정하는 것이 불가능하다.
  • 집합(set) : 집합은 말 그대로 집합을 구현한다. 집합 내에 존재하는 중복이 제거되어 결과가 나온다. 교집합( & ), 합집합( | ), 차집합 ( - ) 등을 구하는 것도 가능하다.

    1-12 f-string

  • 변수로 더 직관적인 문자열을 만들 수 있다.

    ex)
    scores = [
    {'name':'영수','score':70},
    {'name':'영희','score':65},
    {'name':'기찬','score':75},
    {'name':'희수','score':23},
    {'name':'서경','score':99},
    {'name':'미주','score':100},
    {'name':'병태','score':32}
    ]

    for s in scores:
    name = s['name']
    score = str(s['score'])
    print(f'{name}은 {score}점입니다')

    1-13 예외처리

  • try-except : try구문을 실행하다 에러가 발생했을 때 except를 사용하면 에러를 넘길 수 있다.

    1-14 파일불러오기

  • from A import 함수로 다른 파일을 불러오는 것이 가능하다.

    1-15 한줄의 마법

  • if문 : (참일 때 값) if (조건) else (거짓일 때 값)의 삼항 연산자를 통해 한줄로 줄일 수 있다.
  • for문

    ex)
    a_list = [1, 3, 2, 5, 1, 2]

    b_list = []
    for a in a_list:
    b_list.append(a*2)

    print(b_list)

    a_list = [1, 3, 2, 5, 1, 2]

    b_list = [a*2 for a in a_list]

    print(b_list)

    1-16 map, filter, lambda식

  • map : 저장할 변수 = map(함수이름, 대응할 일련의 요소)

    ex)
    def check_adult(person):
    if person['age'] > 20:
    return '성인'
    else:
    return '청소년'

    result = map(check_adult, people)
    print(list(result))

    def check_adult(person):
    return '성인' if person['age'] > 20 else '청소년'

    result = map(check_adult, people)
    print(list(result))

    result = map(lambda x: ('성인' if x['age'] > 20 else '청소년'), people)
    print(list(result))

  • filter = map함수와 유사하나 리스트 내의 요소 중 특정한 것만 골라내는 함수

    ex)
    filter :
    result = filter(lambda x: x['age'] > 20, people)
    print(list(result))

    1-17 함수 심화

  • 함수에 인수를 넣을 때, 어떤 매개변수에 어떤 값을 넣을지 정해줄 수 있다. 이때 넣는 순서는 상관이 없다.
  • 특정 매개변수에 디폴트 값을 지정해줄 수 있다.
  • 여러 개의 인수를 하나의 매개변수로 받을 때 관례적으로 args라는 이름을 사용한다.
  • 키워드변수를 여러개 받는 법 def get_kwargs(**kwargs): print(kwargs)

    get_kwargs(name='bob')
    get_kwargs(name='john', age='27')

    1-18 클래스

  • 클래스 : 객체를 정의해 놓은 틀, 특징을 갖고 그 특징에 맞게 재생산이 가능하다.
      ex)
      class Monster():
        hp = 100
        alive = True
    
        def damage(self, attack):
            self.hp = self.hp - attack
            if self.hp < 0:
                self.alive = False
    
        def status_check(self):
            if self.alive:
                print('살아있다')
            else:
                print('죽었다')
                           >

    m = Monster()
    m.damage(120)

    m2 = Monster()
    m2.damage(90)

    m.status_check()
    m2.status_check()

    코드 컨벤션

    코드 컨벤션이란 코드를 개발하다보면 타인이 작성한 코드를 알아 볼 수 없는 경우가 빈번하게 발생하기 때문에 이를 방지하기 위해 스타일을 통일하는 '약속' 같은 것이다. 코드 컨벤션은 개발하는 언어에 따라서 다르기 때문에 본인이 개발에 사용하는 언어에 따라 코드 컨벤션의 스타일도 바뀌는 것에 유의해야 한다.

    파이썬에서는 네이밍 컨벤션으로 변수 / 함수를 네이밍할 때는 Snake 표기법을, Class를 네이밍할 때는 Pascal 표기법을 사용한다.
    Pascal 표기법은 각 단어를 대문자로 구분하는 표기법이고(PythonIsVeryGood)
    Snake 표기법은 각 단어를 언더바(_)로 구분하는 표기법이다.(python_is_very_good)

    변수 선언하기

    • 선언할 변수 명 = 변수에 넣고 싶은 값 과 같은 형태로 변수를 선언할 수 있습니다.
      • description = “변수를 선언 하는 방법입니다.”
    • 변수를 선언할 때에는 두 개 이상의 변수를 한번에 선언할 수도 있습니다.
      • a, b, c = 1, 2, 3
    • 변수의 가장 첫 번째 문자에는 숫자를 사용할 수 없습니다.
    • I(대문자 i), l(소문자 L), O(대문자 o)와 같은 문자를 단일 문자 변수로 선언하는 것을 권장하지 않습니다. (폰트에 따라 I, l, 1 혹은 0, O 문자를 구분하지 못할 수 있기 때문입니다.)
    • list, type, class와 같이 python에서 이미 선언 되어 있는 단어를 변수 명으로 선언하고 싶을 때는 중복을 피하기 위에 변수 명 뒤에 언더바( _ )를 추가하여 선언합니다.
      • list_ = [1,2,3,4]

    자료형의 종류와 특징

    • integer
      • 정수 자료형
      • number = 10 과 같이 사용되며, 정수 자료형이기 때문에 소수점은 지원하지 않습니다.
      • 사칙연산과 같은 계산식을 지원합니다.
    • float
      • 실수 자료형
      • number = 10.3 과 같이 사용되며, 소수점을 지원합니다.
      • integer와 마찬가지로 사칙연산과 같은 계산식을 지원합니다.
    • string
      • 문자열 자료형
      • hello = "world!!" 와 같이 사용되며, 변수에 문자를 저장할 수 있습니다.
      • 파이썬에서는 따옴표( ‘ )와 쌍따옴표( “ )를 구분하지 않습니다.
    • list
      • numbers = [1, 2, 3, 4, 5] 와 같이 사용되며 1개 이상의 값을 한 변수에 담아 사용할 수 있습니다.
      • list 요소에는 integer, float, string, dictionary, list 등 다양한 자료형을 담을 수 있습니다.
    • tuple
      • numbers = (1, 2, 3 ,4, 5)와 같이 사용되며 리스트와 동일한 방법으로 선언할 수 있습니다.
      • tuple 자료형은 값을 선언한 후 요소들을 변경하거나 삭제할 수 없습니다.
    • set
      • numbers = {1, 2, 3, 4, 5}와 같이 사용되며 리스트와 동일한 방법으로 선언할 수 있습니다.
      • set 자료형은 중복 된 데이터를 담을 수 없습니다.
    • dict
      • members = {”1”: “lee”, “2”: “park”, “3”: “kim”} 과 같이 사용되며 {key: value} 쌍으로 이루어져 있습니다.
      • key에는 integer, float, string 자료형이, value에는 integer, float, string, dictionary, list 등 다양한 자료형을 담을 수 있습니다.
    • boolean
      • flag = True 와 같이 사용되며 True 혹은 False 두 값만 사용할 수 있습니다.
      • 일반적으로 분기문( if ) 혹은 합격 / 불합격과 같은 상태를 나타낼 때 사용됩니다.

    자료형 활용하기

    • 사칙연산

      • 파이썬에서는 integer(정수 자료형)와 float(실수 자료형) 자료형에서 활용할 수 있는 다양한 종류의 사칙연산을 지원하고 있다.(사칙연산,제곱,나누기의 몫,나누기의 나머지 등등)
      • 변수에 값을 할당하고 수식을 사용할 때는 연산 축약 문법을 활용할 수 있다.
        # num에 정수를 할당하고, 할당된 값에 1을 더하고 싶을 때
        
        # case 1
        num = 10
        num = num + 1
        # result: 11
        
        # case 2
        num = 10
        num += 1
        # result: 11
        
        # case 1, 2 모두 동일한 동작을 하고 동일한 결과를 내는 수식이다.
        # 이와 같은 축약식은 + 이외에 다른 수식에서도 사용할 수 있다.
        
        num -= 3  # num = num - 3
        num *= 3  # num = num * 3
        num **= 3 # num = num ** 3
        num /= 3  # num = num / 3
        num //= 3 # num = num // 3
        num %= 3  # num = num % 3
    • string

      • 문자열에서는 + 와 * 연산 기호를 지원한다.
      • python 버전이 3.6일 경우 fstring을 활용해 문자열과 변수를 함께 다룰 수 있다.
    • list

      • list 자료형 선언 시 list 안에 들어있는 각 요소는 0부터 시작해 순서대로 index 번호를 가지며, indexing과 slicing 기능을 활용해 활용해 원하는 값을 가져올 수 있다.
      • list 자료형에서는 값을 원하는대로 추가(append), 수정, 삭제(remove)할 수 있다.
      • list 자료형의 요소에는 숫자나 문자 이외에도 다양한 자료형을 사용할 수 있다.
      • len() 함수를 사용해 list의 길이를 구할수 있다.
    • tuple

      • tuple 자료형 또한 list와 동일한 indexing 기능을 활용할 수 있다.
      • tuple 자료형에서는 요소의 값을 수정하거나 삭제할 수 없으며, 추가만 가능하다.
      • tuple 자료형 또한 list와 동일하게 요소에 다양한 자료형을 사용할 수 있다.
      • len() 함수를 사용해 tuple의 길이를 구할수 있다.
    • set

      • set 자료형은 중복 된 값을 포함하지 않고, indexing과 slicing 기능을 지원하지 않는다.
      • len() 함수를 사용해 set 자료형의 길이를 구할 수 있다.
    • dictionary(중요!!)

      • dictionary 자료형은 key: value로 구성되며, key를 사용해 value를 가져올 수 있다.
      • 만약 존재하지 않는 key로 value를 가져오려 시도할 때에는 에러가 발생한다.(.get을 사용한다면 key가 없을 때 사용될 값을 지정하여 에러가 발생하지 않도록 할 수 있다.)
      • dictionary 자료형에서는 자유롭게 값을 추가, 수정, 삭제(del)할 수 있다.

    자료형 변환

    • python에서는 특정 값의 자료형을 조건이 맞을 경우 자유롭게 변환할 수 있다.
      • string → int
      • list → tuple → set
      • any → string
      • 이외에도 다양한 자료형들을 변환할 수 있다.

    함수

    • def 함수명(): 과 같은 형태로 선언할 수 있다.
    • 함수를 선언할 때에는 인자를 받고, 원하는 로직을 수행한 후 결과를 리턴해 줄 수 있다.

    다른 파일에 있는 코드 import해서 사용하기

    • import “파일명”을 사용해 다른 파일에 선언된 코드를 가져와서 사용할 수 있다.
    • from을 사용하면 더 다양한 방법으로 파일을 import할 수 있다.
      • from a import * : a 파일에 있는 모든 함수를 import 한다.
    • 다른 폴더에 있는 파일을 import하는 것도 가능하다
      • from folder import b : 폴더안에 있는 b를 import 한다.
    • 다른 파일의 변수 또한 함수와 동일한 방법으로 from / import를 사용할 수 있다.
    • from과 import의 이해를 돕기 위한 팁
      • python에서 다른 파일에 있는 코드를 사용할 때에는 어디서(from) 어떤(import) 것을
        가져와서 사용할지 지정해 줘야 한다.

    값 비교하기

    • 다양한 비교 연산자들을 사용해 값을 비교하고, 결과가 True인지 False인지 판단할 수 있다. 비교 결과는 조건문에서 많이 사용된다.

    조건문

    • 특정 비교 결과 혹은 값이 True 혹은 False일 경우 실행 될 로직을 정의한다.
    • and, or을 사용해 2개 이상의 조건을 복합적으로 사용할 수 있다.
    • 비어있는 string, list 등은 분기문에서 False로 판단한다.
    • 특정 값이 True인지 False인지는 bool() 함수를 사용해 확인할 수 있다.

    반복문

    • while 혹은 for문을 사용해 반복문을 사용할 수 있다.
    • for문
      • list, tuple, set 자료형의 요소들로 반복문을 사용할 수 있다.
      • enumerate()를 사용해 반복되는 요소가 몇번째인지 확인할 수 있다.
      • dictionary 자료형의 key 혹은 value로 반복문을 사용할 수 있다.
      • range() 함수를 활용하면 원하는 만큼 반복문을 사용할 수 있다.
      • continue를 활용해 특정 상황에서 아무런 동작도 하지 않고 넘어갈 수 있다.
      • break를 활용해 특정 상황에서 반복문을 중지시킬수 있다.
    • while문
      • 사용 방법은 for문과 크게 다르지 않지만, 조건을 다루는 방식에 차이가 있다.
      • 대부분의 경우 while문은 반복 할 횟수가 정해져 있지 않을 때 사용한다.

    자주 사용되는 모듈 및 패턴

    • type() / 값의 자료형 확인해보기
    • split() / string을 list로 변환하기
    • join() / list를 string으로 변환하기
    • pprint() / 코드 예쁘게 출력하기
    • random / 랜덤한 로직이 필요할 때
    • time / 시간 다루기
    • datetime / 날짜 다루기

    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!!']
      """

    4. Python 심화

    try / exception을 활용한 에러 처리

    • python에서는 try / except 문법을 사용해 에러가 발생했을 때 처리를 해줄수 있습니다.
      number = "num"
      
      try: # try 구문 안에서 에러가 발생할 경우 except로 넘어감
          number = int(number) # "num"을 숫자로 바꾸는 과정에서 에러 발생
      except: # 에러가 발생했을 때 처리
          print(f"{number}은(는) 숫자가 아닙니다.")
    • 에러 종류에 따라 다른 로직 처리
      number = input()
      
      try:
          int(number)
          10 / number
      
      except ValueError: # int로 변환하는 과정에서 에러가 발생했을 떄
          print(f"{number}은(는) 숫자가 아닙니다.")
          
      except ZeroDivisionError: # 0으로 나누면서 에러가 발생했을 때
          print("0으로는 나눌수 없습니다.")
          
      except Exception as e: # 위에서 정의하지 않은 에러가 발생했을 때(권장하지 않음)
          print(f"예상하지 못한 에러가 발생했습니다. error : {e}")
      
      # except 문법 또한 if / elif와 같이 연달아서 작성할 수 있습니다.

    stacktrace의 이해

    • stacktrace란?

    stacktrace는 python 뿐만이 아닌 대부분의 개발 언어에서 사용되는 개념이다.
    에러가 발생했을 때 에러가 발생 한 위치를 찾아내기 위해 호출 된 함수의 목록을 보여주고 개발자는 stacktrace를 따라가며 에러가 발생한 위치를 추적할 수 있다.

    • 예제 코드 보기
      def 집까지_걸어가기():
          print(error) # 선언되지 않은 변수를 호출했기 때문에 에러 발생
      
      def 버스_탑승():
          집까지_걸어가기()
      
      def 환승():
          버스_탑승()
      
      def 지하철_탑승():
          환승()
      
      def 퇴근하기():
          지하철_탑승()
      
      퇴근하기()
      
      """
      Traceback (most recent call last):
        File "sample.py", line 17, in <module>
          퇴근하기()
        File "sample.py", line 15, in 퇴근하기
          지하철_탑승()
        File "sample.py", line 12, in 지하철_탑승
          환승()
        File "sample.py", line 9, in 환승
          버스_탑승()
        File "sample.py", line 5, in 버스_탑승
          집까지_걸어가기()
        File "sample.py", line 2, in 집까지_걸어가기
          print(error)
      NameError: name 'error' is not defined. Did you mean: 'OSError'?
      """

    축약식(Comprehension)

    • 축약식이란?
      축약식은 긴 코드를 간략하게 줄일수 있다는 장점이 있지만, 남용할 경우 가독성이
      떨어지고 추후 코드 관리가 힘들수 있기 때문에 필요할 때만 사용하는 것을 권장합니다.
      
      list, set, tuple, dict 자료형이 축약식을 지원합니다.
      
      기본적인 구조는 똑같으며, 어떤 괄호 기호를 사용하는지 / 어떤 형태로 사용하는지에
      따라 저장되는 자료형이 달라집니다.
      
      축약식은 모두 동일한 구조를 가지고 있기 때문에 한 가지 자료형에 익숙해지면 다른
      자료형에도 적용해서 사용할 수 있습니다.
    • list / tuple / set 축약식 활용법
      # 기본적인 활용 방법
      # [list에 담길 값 for 요소 in 리스트]
      numbers = [x for x in range(5)] # [0, 1, 2, 3, 4]
      
      # 조건문은 축약식 뒷부분에 작성하며, 축약식이 True인 경우 list에 값이 담긴다.
      even_numbers = [x for x in range(10) if x % 2 == 0] # [0, 2, 4, 6, 8]
      
      # 아래와 같이 활용할 수도 있다.
      people = [
          ("lee", 32),
          ("kim", 23),
          ("park", 27),
          ("hong", 29),
          ("kang", 26)
      ]
      
      average_age = sum([x[1] for x in people]) / len(people)
      print(average_age) # 27.4
      
      #list 축약식의 []를 ()혹은 {}로 바꿔주면 tuple, set 축약식을 사용하실수 있습니다.
    • dictionary 축약식 활용법
      # dictionary 축약식의 구조는 list와 동일하지만, key / value 형태로 지정해야 합니다.
      people = [
          ("lee", 32, "man"),
          ("kim", 23, "man"),
          ("park", 27, "woman"),
          ("hong", 29, "man"),
          ("kang", 26, "woman")
      ]
      
      people = {name: {"age": age, "gender": gender} for name, age, gender in people}
      print(people)
      
      # result print
      """
      {
          'lee': {'age': 32,
                   'gender': 'man'},
          'kim': {'age': 23,
                   'gender': 'man'},
          'park': {'age': 27,
                   'gender': 'woman'},
          'hong': {'age': 29,
                   'gender': 'man'},
          'kang': {'age': 26,
                   'gender': 'woman'}
       }
      """

    lambda / map / filter / sort 활용하기

    • lambda 함수란?
      python에서 lambda 함수는 다른 말로 익명 함수(anonymous function)라고도 불립니다.
      
      lambda 함수는 주로 map / filter / sort 함수와 함께 사용됩니다.
    • map 함수 활용해보기
      # map은 함수와 리스트를 인자로 받아 리스트의 요소들로 함수를 호출해줍니다.
      string_numbers = ["1", "2", "3"]
      integer_numbers = list(map(int, string_numbers))
      print(integer_numbers) # [1, 2, 3]
      
      # map 함수를 사용하지 않는 경우 아래와 같이 구현할 수 있습니다.
      string_numbers = ["1", "2", "3"]
      integer_numbers = []
      
      for i in string_numbers:
          integer_numbers.append(int(i))
      
      print(integer_numbers) # [1, 2, 3]
      
      # list 축약식으로도 동일한 기능을 구현할 수 있습니다.
      # map과 list 축약식 중 어떤걸 써야 할지 고민된다면 [이 글](https://stackoverflow.com/questions/1247486/list-comprehension-vs-map?answertab=scoredesc#tab-top)을 읽어보시는것을 추천합니다.
      string_numbers = ["1", "2", "3"]
      integer_numbers = [int(x) for x in string_numbers]
      print(integer_numbers) # [1, 2, 3]
      
      # map 함수와 lambda 함수를 함께 사용하면 더 다채로운 기능을 구현할 수 있습니다.
      numbers = [1, 2, 3, 4]
      double_numbers = list(map(lambda x: x*2, numbers))
      print(double_numbers) # [2, 4, 6, 8]
    • filter 함수 활용해보기
      # filter 함수는 map과 유사한 구조를 가지고 있으며, 조건이 참인 경우 저장합니다.
      numbers = [1, 2, 3, 4, 5, 6, 7, 8]
      
      even_numbers = list(filter(lambda x: x%2 == 0, numbers))
      print(even_numbers) # [2, 4, 6, 8]
      
      # filter 함수 또한 list 축약식으로 동일한 기능을 구현할 수 있습니다.
      numbers = [1, 2, 3, 4, 5, 6, 7, 8]
      
      even_numbers = [x for x in numbers if x%2 == 0]
      print(even_numbers) # [2, 4, 6, 8]
    • sort 함수 활용해보기
      # sort 함수를 사용하면 list를 순서대로 정렬할 수 있습니다.
      numbers = [5, 3, 2, 4, 6, 1]
      numbers.sort()
      print(numbers) # [1, 2, 3, 4, 5, 6]
      
      # sort와 lambda 함수를 같이 사용하면 복잡한 구조의 list도 정렬할 수 있습니다.
      people = [
          ("lee", 32),
          ("kim", 23),
          ("park", 27),
          ("hong", 29),
          ("kang", 26)
      ]
      
      # 나이 순으로 정렬하기
      people.sort(key=lambda x: x[1])
      print(people)
      
      # result print
      """
      [
          ("kim", 23),
          ("kang", 26),
          ("park", 27),
          ("hong", 29),
          ("lee", 32)
      ]

    함수 심화

    • 인자에 기본값 지정해주기
      # 함수를 선언할 때 인자에 기본값을 지정해줄 수 있다.
      EXPRESSION = {
              0: lambda x, y: x + y ,
              1: lambda x, y: x - y ,
              2: lambda x, y: x * y ,
              3: lambda x, y: x / y
          }
      
      def calc(num1, num2, option=None): # 인자로 option이 들어오지 않는 경우 기본값 할당
          """
          option
           - 0: 더하기
           - 1: 빼기
           - 2: 곱하기
           - 3: 나누기
          """
          return EXPRESSION[option](num1, num2) if option in EXPRESSION.keys() else False
      
      print(calc(10, 20))    # False
      print(calc(10, 20, 0)) # 30
      print(calc(10, 20, 1)) # -10
      print(calc(10, 20, 2)) # 200
      print(calc(10, 20, 3)) # 0.5
    • args / kwargs에 대한 이해
      args(arguments)와 keyword arguments(kwargs)는 함수에서 인자로 받을 값들의 갯수가
      불규칙하거나 많을 때 주로 사용된다.
      
      인자로 받을 값이 정해져있지 않기 때문에 함수를 더 동적으로 사용할 수 있다.
      
      함수를 선언할 때 args는 앞에 *를 붙여 명시하고, kwargs는 앞에 **를 붙여 명시한다.
      • args 활용하기
        def add(*args):
            # args = (1, 2, 3, 4)
            result = 0
            for i in args:
                result += i
                
            return result
        
        print(add())           # 0
        print(add(1, 2, 3))    # 6
        print(add(1, 2, 3, 4)) # 10
      • kwargs 활용하기
        def set_profile(**kwargs):
            """
            kwargs = {
                name: "lee",
                gender: "man",
                age: 32,
                birthday: "01/01",
                email: "python@sparta.com"
            }
            """
            profile = {}
            profile["name"] = kwargs.get("name", "-")
            profile["gender"] = kwargs.get("gender", "-")
            profile["birthday"] = kwargs.get("birthday", "-")
            profile["age"] = kwargs.get("age", "-")
            profile["phone"] = kwargs.get("phone", "-")
            profile["email"] = kwargs.get("email", "-")
            
            return profile
        
        profile = set_profile(
            name="lee",
            gender="man",
            age=32,
            birthday="01/01",
            email="python@sparta.com",
        )
        
        print(profile)
        # result print
        """
        {   
            'name': 'lee',
            'gender': 'man',
            'birthday': '01/01',
            'age': 32,
            'phone': '-',
            'email': 'python@sparta.com'
        }
        """
      • args / kwargs 같이 사용해보기
        def print_arguments(a, b, *args, **kwargs):
            print(a)
            print(b)
            print(args)
            print(kwargs)
            
        print_arguments(
            1, # a
            2, # b
            3, 4, 5, 6, # args
            hello="world", keyword="argument" # kwargs
        )
        
        # result print
        """
        1
        2
        (3, 4, 5, 6)
        {'hello': 'hello', 'world': 'world'}
        """

    패킹과 언패킹

    • 패킹과 언패킹이란?
      패킹(packing)과 언패킹(unpacking)은 단어의 뜻 그대로 요소들을 묶어주거나 풀어주는
      것을 의미한다.
      
      list 혹은 dictionary의 값을 함수에 입력할 때 주로 사용된다.
    • list에서의 활용
      def add(*args):
          result = 0
          for i in args:
              result += i
              
          return result
      
      numbers = [1, 2, 3, 4]
      
      print(add(*numbers)) # 10
      
      """아래 코드와 동일
      print(add(1, 2, 3, 4))
      """
    • dictionary에서의 활용
      def set_profile(**kwargs):
          profile = {}
          profile["name"] = kwargs.get("name", "-")
          profile["gender"] = kwargs.get("gender", "-")
          profile["birthday"] = kwargs.get("birthday", "-")
          profile["age"] = kwargs.get("age", "-")
          profile["phone"] = kwargs.get("phone", "-")
          profile["email"] = kwargs.get("email", "-")
          
          return profile
      
      user_profile = {
          "name": "lee",
          "gender": "man",
          "age": 32,
          "birthday": "01/01",
          "email": "python@sparta.com",
      }
      
      print(set_profile(**user_profile))
      """ 아래 코드와 동일
      profile = set_profile(
          name="lee",
          gender="man",
          age=32,
          birthday="01/01",
          email="python@sparta.com",
      )
      """
      
      # result print
      """
      {
          'name': 'lee',
          'gender': 'man',
          'birthday': '01/01',
          'age': 32,
          'phone': '-',
          'email': 'python@sparta.com'
      }
      
      """

    객체지향

    • 객체지향(Object-Oriented Programming)이란??
      객체지향이란 객체를 모델링하는 방향으로 코드를 작성하는 것을 의미한다.
      영어로는 Object-Oriented Programming이라고 하며 앞자를 따 OOP라고 불린다.
      
      파이썬 뿐만이 아닌, 다양한 언어들에서 프로젝트를 개발하며 사용되는
      개발 방식 중 하나다.
    • 객체지향의 특성
      • 캡슐화
        • 특정 데이터의 액세스를 제한해 데이터가 직접적으로 수정되는 것을 방지하며, 검증 된 데이터만을 사용할 수 있다.
      • 추상화
        • 사용되는 객체의 특성 중, 필요한 부분만 사용하고 필요하지 않은 부분은 제거하는 것을 의미한다.
      • 상속
        • 상속은 기존에 작성 된 클래스의 내용을 수정하지 않고 그대로 사용하기 위해 사용되는 방식이다.
        • 클래스를 선언할 때 상속받을 클래스를 지정할 수 있다.
      • 다형성
        • 하나의 객체가 다른 여러 객체로 재구성되는 것을 의미한다.
        • 오버라이드, 오버로드가 다향성을 나타내는 대표적인 예시이다.
    • 객체지향의 장/단점
      • 장점
        • 클래스의 상속을 활용하기 때문에 코드의 재사용성이 높아진다.
        • 데이터를 검증하는 과정이 있기 때문에 신뢰도가 높다.
        • 모델링을 하기 수월하다.
        • 보안성이 높다.
      • 단점
        • 난이도가 높다.
        • 코드의 실행 속도가 비교적 느린 편이다.
        • 객체의 역활과 기능을 정의하고 이해해야 하기 때문에 개발 속도가 느려진다.
    • 객체지향 예제 코드
      import re
      
      # 숫자, 알파벳으로 시작하고 중간에 - 혹은 _가 포함될 수 있으며 숫자, 알파벳으로 끝나야 한다.
      # @
      # 알파벳, 숫자로 시작해야 하며 . 뒤에 2자의 알파벳이 와야 한다.
      email_regex = re.compile(r'([A-Za-z0-9]+[.-_])*[A-Za-z0-9]+@[A-Za-z0-9-]+(\.[A-Z|a-z]{2,})+')
      
      class Attendance:
          count = 0
              
          def attendance(self):
              self.count += 1
          
          @property
          def attendance_count(self):
              return self.count
      
      class Profile(Attendance):
          def __init__(self, name, age, email):
              self.__name = name # __를 붙여주면 class 내부에서만 사용하겠다는 뜻
              self.__age = age
              self.__email = email
          
          @property # 읽기 전용 속성
          def name(self):
              return self.__name
          
          @name.setter # 쓰기 전용 속성
          def name(self, name):
              if isinstance(name, str) and len(name) >= 2:
                  print("이름은 2자 이상 문자만 입력 가능합니다.")
                  
              else:
                  self.__name = name
          
          @property
          def age(self):
              return self.__age
          
          @age.setter
          def age(self, age):
              if isinstance(age, int):
                  self.__age = age
                  
              else:
                  print("나이에는 숫자만 입력 가능합니다.")
              
          @property
          def email(self):
              return self.__email
          
          @email.setter
          def email(self, email):
              if re.fullmatch(email_regex, email):
                  self.__email = email
              else:
                  print("유효하지 않은 이메일입니다.")
              
          def attendance(self): # override
              super().attendance() # 부모 메소드 사용하기
              self.count += 1
          
          def __str__(self):
              return f"{self.__name} / {self.__age}"
          
          def __repr__(self):
              return f"{self.__name}"
      

    그동안 들었던 모든 파이썬 원격&실시간 강의의 요약본들을 모아보았다. 이렇게 잔뜩 적어두었지만 막상 공부할 때는 한번씩 읽고 이런 내용이었지 하고 넘어가서 금방 끝나는 시간이었지만 알찬 시간이었고 이렇게 한번에 요약해 둔걸로 나중에 찾아볼 일이 있으면 여기서 한번에 볼 수 있으니 편하고 좋은 것 같다.

    그러고 나서는 오늘 거북이반에서 배울 내용과 어제 수업에서 튜터님이 내주신 과제풀이에 힘썼다.
    먼저 오늘의 과제는 원의 넓이를 구하는 클래스 함수를 만드는 것이었다.

    class Circle:
        pi = 3.14
    
        def __init__(self, radius):
            self.radius = radius
        
        def getArea(self):
            return self.radius * self.radius * self.pi
    
        def getCircumference(self):
            return self.radius * self.pi * 2
    
    
    c = Circle(5)
    
    print("반지름은 : ", c.radius)
    print("넓이는 : ", c.getArea())
    print("둘레는 : ", c.getCircumference())
    
    
    # getArea라는 메소드를 클래스 안에서 만들고, 6번줄은 지워주세요
    # 6번줄의 기능을 getArea라는 메소드에서 할수있게끔 로직을 만들어주시고
    # 15번줄도 수정해서 getArea라는 메소드를 통해서 넓이를 print 할 수 있게 수정해주세요!

    Circle이라는 클래스 안에 3개의 메소드를 만들고 각각 반지름을 등록, 원의 넓이, 원의 둘레를 구하도록 했다.

    거북이반

    오늘 거북이반은 클래스 강의를 마무리하는 시간을 가졌다.

    오늘 할 일을 마치며

    좋던 싫던 오늘이 파이썬 문법을 졸업하게 되는 날이다. 정말 열심히 공부했지만 공부를 아무리 해도 부족한 느낌이라 걱정이 앞선다. 내일부터 시작될 장고는 내가 앞으로 취업하게될 경우 사용하게 될 주 무기이기 때문에 학습의 중요도는 더 올라갈 것이다. 빨리 장고를 배우고싶은 마음 반 두려움 반이라서 앞으로가 어떻게 될지 알 수 없는 것이 매우 재미있다.

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

    0개의 댓글