22.09.14(수) Today I Learned

정형빈·2022년 9월 14일
0

TIL

목록 보기
10/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 [실습] 실무적용 알고리즘 실습

어제도 오늘도 내일도 이 시간표가 그대로 유지된다.

파이썬 실시간 강의

- 이창호 튜터님

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)
    ]

파이썬 오늘의 과제

- 파이썬 심화 문법 사용해보기

아래 과제는 모두 클래스를 활용해서 풀어주세요

1. 계산기 심화

요구조건

  • 클래스를 활용해 작성했던 계산기 코드를 활용해주세요
  • 기존처럼 사용자의 입력을 받고 출력하되, try / except를 활용해 사용자의 입력을 검증하는 코드를 추가해주세요
    • 두 번쨰 숫자에 0을 입력하고 나누기를 시도할 경우 “0으로 나눌 수 없습니다” 문구를 출력해주세요
    • 숫자가 아닌 다른 값을 입력했을 경우 “숫자만 입력 가능합니다” 라는 문구를 출력해 주세요
  • 입출력 예제
    calc = Calc()
    clac.set_number(20, 10)
    print(calc.plus()) # 더한 값
    print(calc.minus()) # 뺀 값
    print(calc.multiple()) # 곱한 값
    print(calc.divide()) # 나눈 값

바로 어제 만든 계산기에서 try / except를 사용하는 코드 몇 가지만 추가하면 되는 간단한 과제였다. 원래 만든 계산기에서도 if문을 이용하여 0으로 나누면 오류알림이 뜨도록 설정해 두었기 때문에 금방 고칠 수 있었다.

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())

원래 만들었던 계산기의 코드이고 계산 함수 부분을 try, except 구문을 이용하도록 수정하였다.

class Calc():
    def set_number(self, num1, num2):
        self.num1 = num1
        self.num2 = num2
    def plus(self):
        try:
            return self.num1 + self.num2
        except ValueError: 
            print("숫자만 입력 가능합니다.")
    def minus(self):
        try:
            return self.num1 - self.num2
        except ValueError: 
            print("숫자만 입력 가능합니다.")
    def multiple(self):
        try:
            return self.num1 * self.num2
        except ValueError: 
            print("숫자만 입력 가능합니다.")
    def divide(self):
        try:
            return int(self.num1) / int(self.num2)
        except ValueError: 
            print("숫자만 입력 가능합니다.")
        except ZeroDivisionError:
            print("0으로는 나눌 수 없습니다.")

    
calc = Calc()
calc.set_number(20, 0)
print(calc.plus()) # 더한 값
print(calc.minus()) # 뺀 값
print(calc.multiple()) # 곱한 값
print(calc.divide()) # 나눈 값

이렇게 수정했더니 0으로 나누었을때 print가 두번 적용되는 문제점이 발생했다.

class Calc():
    def set_number(self, num1, num2):
        self.num1 = num1
        self.num2 = num2
    def plus(self):
        try:
            return self.num1 + self.num2
        except ValueError: 
            return "숫자만 입력 가능합니다."
    def minus(self):
        try:
            return self.num1 - self.num2
        except ValueError: 
            return "숫자만 입력 가능합니다."
    def multiple(self):
        try:
            return self.num1 * self.num2
        except ValueError: 
            return "숫자만 입력 가능합니다."
    def divide(self):
        try:
            return int(self.num1) / int(self.num2)
        except ValueError: 
            return "숫자만 입력 가능합니다."
        except ZeroDivisionError:
            return "0으로는 나눌 수 없습니다."

    
calc = Calc()
calc.set_number(20, 0)
print(calc.plus()) # 더한 값
print(calc.minus()) # 뺀 값
print(calc.multiple()) # 곱한 값
print(calc.divide()) # 나눈 값

위와 같이 print()대신 return을 사용하여 중복현상을 방지해서 최종수정이 완료되었다.

2. 리스트 필터 및 정렬

요구조건

  • filter 혹은 리스트 축약식을 사용해 코드를 작성해주세요
  • 제공 된 사용자들 중 나이가 20살 미만인 사람들은 제외해주세요
  • 사용자들을 나이 순으로 정렬해주세요
  • 입출력 예제
    people = [
        ("Blake Howell", "Jamaica", 18, "aw@jul.bw"),
        ("Peter Bowen", "Burundi", 30, "vinaf@rilkov.il"),
        ("Winnie Hall", "Palestinian Territories", 22, "moci@pacivhe.net"),
        ("Alfred Schwartz", "Syria", 29, "ic@tolseuc.pr"),
        ("Carrie Palmer", "Mauritius", 28, "fenlofi@tor.aq"),
        ("Rose Tyler", "Martinique", 17, "as@forebjab.et"),
        ("Katharine Little", "Anguilla", 29, "am@kifez.et"),
        ("Brent Peterson", "Svalbard & Jan Mayen", 22, "le@wekciga.lr"),
        ("Lydia Thornton", "Puerto Rico", 19, "lefvoru@itbewuk.at"),
        ("Richard Newton", "Pitcairn Islands", 17, "da@lasowiwa.su"),
        ("Eric Townsend", "Svalbard & Jan Mayen", 22, "jijer@cipzo.gp"),
        ("Trevor Hines", "Dominican Republic", 15, "ev@hivew.tm"),
        ("Inez Little", "Namibia", 26, "meewi@mirha.ye"),
        ("Lloyd Aguilar", "Swaziland", 16, "oza@emneme.bb"),
        ("Erik Lane", "Turkey", 30, "efumazza@va.hn"),
    ]
    
    # some code
    
    print(people)
    
    """
    [('Winnie Hall', 'Palestinian Territories', 22, 'moci@pacivhe.net'),
     ('Brent Peterson', 'Svalbard & Jan Mayen', 22, 'le@wekciga.lr'),
     ('Eric Townsend', 'Svalbard & Jan Mayen', 22, 'jijer@cipzo.gp'),
     ('Inez Little', 'Namibia', 26, 'meewi@mirha.ye'),
     ('Carrie Palmer', 'Mauritius', 28, 'fenlofi@tor.aq'),
     ('Alfred Schwartz', 'Syria', 29, 'ic@tolseuc.pr'),
     ('Katharine Little', 'Anguilla', 29, 'am@kifez.et'),
     ('Peter Bowen', 'Burundi', 30, 'vinaf@rilkov.il'),
     ('Erik Lane', 'Turkey', 30, 'efumazza@va.hn')]
    """

답안코드

people = [
    ("Blake Howell", "Jamaica", 18, "aw@jul.bw"),
    ("Peter Bowen", "Burundi", 30, "vinaf@rilkov.il"),
    ("Winnie Hall", "Palestinian Territories", 22, "moci@pacivhe.net"),
    ("Alfred Schwartz", "Syria", 29, "ic@tolseuc.pr"),
    ("Carrie Palmer", "Mauritius", 28, "fenlofi@tor.aq"),
    ("Rose Tyler", "Martinique", 17, "as@forebjab.et"),
    ("Katharine Little", "Anguilla", 29, "am@kifez.et"),
    ("Brent Peterson", "Svalbard & Jan Mayen", 22, "le@wekciga.lr"),
    ("Lydia Thornton", "Puerto Rico", 19, "lefvoru@itbewuk.at"),
    ("Richard Newton", "Pitcairn Islands", 17, "da@lasowiwa.su"),
    ("Eric Townsend", "Svalbard & Jan Mayen", 22, "jijer@cipzo.gp"),
    ("Trevor Hines", "Dominican Republic", 15, "ev@hivew.tm"),
    ("Inez Little", "Namibia", 26, "meewi@mirha.ye"),
    ("Lloyd Aguilar", "Swaziland", 16, "oza@emneme.bb"),
    ("Erik Lane", "Turkey", 30, "efumazza@va.hn"),
]

people = [x for x in people if x[2] >= 20]
people.sort(key=lambda x : x[2])

print(people)

people 안에서 나이는 2번 인덱스값이므로 x[2]가 사용자의 나이가 된다. 우선 리스트 축약식을 활용하여 나이가 20세 미만인 사람들을 값에서 제외하고 그 다음줄에서 .sort를 사용하여 나이순으로 people내의 사용자들을 정렬하였다. 굉장히 쉬운 코드이지만 리스트 축약식과 .sort를 둘 다 적용시키는 방법을 몰라서 코드를 굉장히 많이 수정했고 수많은 시행착오 끝에 두 번에 걸쳐 코드를 따로 적용시키는 것이 답이라는걸 알게 되었다. 아니면 단순히 실력이 부족해 이 두 가지를 한줄로 정리하는 방법이 있는데 내가 알지 못할 뿐일 수도 있겠다. 하지만 그래도 시간은 좀 오래걸려도 혼자서 과제를 해결한 것이 기쁘므로 지금은 그냥 넘어가겠다.

알고리즘 실습

10809번 알파벳 찾기

문제
알파벳 소문자로만 이루어진 단어 S가 주어진다. 각각의 알파벳에 대해서, 단어에 포함되어 있는 경우에는 처음 등장하는 위치를, 포함되어 있지 않은 경우에는 -1을 출력하는 프로그램을 작성하시오.

입력
첫째 줄에 단어 S가 주어진다. 단어의 길이는 100을 넘지 않으며, 알파벳 소문자로만 이루어져 있다.

출력
각각의 알파벳에 대해서, a가 처음 등장하는 위치, b가 처음 등장하는 위치, ... z가 처음 등장하는 위치를 공백으로 구분해서 출력한다.

만약, 어떤 알파벳이 단어에 포함되어 있지 않다면 -1을 출력한다. 단어의 첫 번째 글자는 0번째 위치이고, 두 번째 글자는 1번째 위치이다.

S = input()
alphabet = list(range(97,123))

for x in alphabet :
    print(S.find(chr(x)))

풀이
첫 줄에서 input값 S를 받는다.
둘째줄에서는 알파벳 리스트를 아스키 코드를 통해 받는데 아스키 코드의 값은 구글링을 통해 찾아보았다. for문을 만들어 변수x를 선언하고 x를 아스키코드에 해당하는 숫자를 문자열로 변환시키는 함수 chr을 사용했다. 그리고 find 함수를 사용해 S의 안에 chr함수로 변환된 함수가 있는지 찾아 맞는 값을 구하도록 코드를 만들었다.
아스키코드와 chr함수에 대한 이해가 필요해서 혼자서 해보려고 하기보다는 빠르게 구글링을 하는 쪽을 택해서 문제를 풀고 대신 이해가 될때까지 확실하게 여러번 문제를 확인해보았다.

오늘 할 일을 끝내고

오늘도 엄청 열심히 한 것 같은데 막상 TIL을 써보려하니 생각보다 내용이 별로 없었다. 아무래도 과제를 구글링 없이 직접 풀어보려고 노력하다보니 거기에 시간을 많이 써서 그런 것 같다. 그래서 자연스럽게 알고리즘 실습 문제를 많이 풀지 못하고 있어서 점점 밀리고 있는데 어제 튜터님이 팀별 상담에서 알고리즘 문제풀기보단 지금 하고있는 파이썬 기초를 확실하게 이해하는 것이 중요하다고 하셨기 때문에 조바심을 가지지 않고 계속 문제를 이해하고 최대한 직접 풀어보려고 노력하는 쪽으로 해보려고한다.

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

0개의 댓글