22.09.15(목) Today I Learned

정형빈·2022년 9월 15일
0

TIL

목록 보기
11/71

9/15 오늘의 시간표

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

파이썬 실시간 강의 오늘이 그 마지막날이다. 어느덧 이 시간표에 너무 익숙해져 버렸는데 벌써 이번이 마지막이라니...

파이썬 실시간 강의

- 이창호 튜터님

오전에는 창호 튜터님이 진행하는 마지막 파이썬 실시간 강의가 있었다. 확실히 마지막 날이라 그동안 배운 것들 중 가장 난이도가 있었고 특히 객체지향은 이해해보려고 몇번을 다시봐도 완벽하게 이해가 안되서 찜찜한 느낌이다.

함수 심화

  • 인자에 기본값 지정해주기
    # 함수를 선언할 때 인자에 기본값을 지정해줄 수 있다.
    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}"
    
    함수 심화, 패킹 언패킹에 대해서는 원격 강의나 알고리즘 실습 등에서 한번쯤은 들어보거나 사용해봤기 때문에 튜터님의 설명을 듣고 예제를 보니 금방 이해를 할 수 있었지만 객체지향은 진짜 정말 내가 본 모든 파이썬 문법 중 가장 이해가 안가는 부분이었다. 늘 그렇듯 머리속에 넣어는 뒀지만 완전히 자리잡지는 못했기 때문에 실제로 사용해보면서 감을 익히는 수밖에 없을 것 같다.

알고리즘 실습

-문자열

오늘은 파이썬 과제가 나오지 않아서 오랜만에 알고리즘 실습 문제를 많이 풀어볼 수 있었다. 그동안 파이썬 문법을 따라가고 과제를 하는데 급급했기 때문에 당일 할당량을 못풀고 다음날로 미루는 일이 많았는데 오늘 최대한 밀린걸 따라잡기위해 노력해보았다.

2675번 문자열 단계

문제
문자열 S를 입력받은 후에, 각 문자를 R번 반복해 새 문자열 P를 만든 후 출력하는 프로그램을 작성하시오. 즉, 첫 번째 문자를 R번 반복하고, 두 번째 문자를 R번 반복하는 식으로 P를 만들면 된다. S에는 QR Code "alphanumeric" 문자만 들어있다.

QR Code "alphanumeric" 문자는 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ$%*+-./: 이다.

입력
첫째 줄에 테스트 케이스의 개수 T(1 ≤ T ≤ 1,000)가 주어진다. 각 테스트 케이스는 반복 횟수 R(1 ≤ R ≤ 8), 문자열 S가 공백으로 구분되어 주어진다. S의 길이는 적어도 1이며, 20글자를 넘지 않는다.

출력
각 테스트 케이스에 대해 P를 출력한다.

T = int(input())

for _ in range(T):
    R, S = input().split()
    for x in S:
        print(x*int(R), end='')
    print()

풀이
첫 줄에서 테스트케이스의 수 T를 input 값으로 받고 두번째 줄부터 테스트케이스를 T회 반복하도록 for문을 작성해준다. 이 테스트케이스는 반복횟수(R)와 반복할 문자열(S)을 공백으로 구분되어 받는다. 그리고 이 R과 S의 값을 input값으로 받아 다시 for문을 만들어 S안의 변수 x를 R회만큼 반복입력하도록 설정한다. 이때 한 줄로 출력이 되도록 end=''를 사용해주었다. 마지막으로 빈칸을 print 해준 것은 출력값이 나온 뒤 다음 입력값을 넣기 위해 줄바꿈을 해주기 위해서이다.

1157번 단어 공부

문제
알파벳 대소문자로 된 단어가 주어지면, 이 단어에서 가장 많이 사용된 알파벳이 무엇인지 알아내는 프로그램을 작성하시오. 단, 대문자와 소문자를 구분하지 않는다.

입력
첫째 줄에 알파벳 대소문자로 이루어진 단어가 주어진다. 주어지는 단어의 길이는 1,000,000을 넘지 않는다.

출력
첫째 줄에 이 단어에서 가장 많이 사용된 알파벳을 대문자로 출력한다. 단, 가장 많이 사용된 알파벳이 여러 개 존재하는 경우에는 ?를 출력한다.

S = input().upper()
unique_S = list(set(S))

count_list = []
for x in unique_S:
    count = S.count(x)
    count_list.append(count)
    
if count_list.count(max(count_list)) > 1 :
    print("?")
else :
    max_index = count_list.index(max(count_list))
    print(unique_S[max_index])

풀이

첫 줄에서 input값을 받는데 대문자와 소문자를 구분하지 않기 때문에 .upper()를 적용해 전부 대문자로 input값을 받아준다. 그리고 이 S에서 중복된 값을 제거해주기 위해 set함수를 적용한 뒤 list로 만들어준다. count_list를 비어있는 list로 만들어주고 for문을 만들어서 S에 같은 알파벳이 몇번 들어가는지 count해서 count_list에 넣어준다. 이 count_list에서 가장 큰 수가 1보다 크면, 즉 가장 많이 사용된 알파벳이 2개 이상이면 ?를 출력하고 아닐경우 가장 많이 사용된 알파벳이 몇번째 index값인지 구해서 그 index값을 Unique_S에서 찾아 출력하도록 코드를 작성했다.

파이썬 오늘의 과제

-if문, while문, for문

7시가 되어도 과제가 올라오지 않아서 오늘은 과제가 없는가보다 하고 알고리즘 문제를 풀기 시작했지만 늦은시각에 과제가 도착했다. 대신 튜터님도 난이도를 고려해서 심화 문법 문제를 내기보단 기초 문법을 튼튼히하는 쪽으로 과제를 내주셔서 생각보다 금방 해낼 수 있을것 같아서 알고리즘 문제풀이를 멈추고 과제풀이에 들어갔다.

1. 조건문

요구조건

  • 사용자의 시험 점수를 입력받아 등급을 출력하는 코드를 만들어주세요
    • 등급표
      • 91~100 : A
      • 81~90 : B
      • 71~80 : C
      • ~71 : F
  • 입출력 예제
    def get_grade(score):
        # some code
    
    score = int(input())
    grade = get_grade(score)
    print(grade) # A ~ F

코드작성시작

def get_grade(score):
    if 100>= score > 90:
        return "A"
    elif 90 >= score > 80:
        return "B"
    elif 80 >= score > 70:
        return "C"
    else:
        return "F"
    
score = int(input())
grade = get_grade(score)
print(grade) # A ~ F

if문은 워낙 많이 사용해봤기 때문에 난이도를 높게 설정하지 않은 이상 쉽게 풀 수 있었다.

2. 반복문(while)

요구조건

  • 사용자의 입력을 받아 반복하는 프로그램을 만들어주세요
  • 사용자가 숫자를 입력했을 경우 입력값에 2배를 곱한 수를 출력해주세요
  • 사용자가 문자를 입력했을 경우 “입력한 문자는 {} 입니다.” 라는 문구를 출력해주세요
    • {} 자리에는 사용자가 입력한 문자가 들어가야 합니다.
  • 사용자가 exit을 입력하거나 숫자가 5회 이상 입력됐을 경우 프로그램을 종료시켜주세요

코드작성시작

count = 0
while True:
    a = input()
    if a.isdigit() == True:
        print(int(a)*2)
        count += 1
    elif a.isdigit() == False:
        print(f"입력한 문자는 {a} 입니다.")
    else:
        print("값을 다시 입력해 주세요.")
    if a == "exit" or count == 5:
        print("숫자를 5번 입력하셨습니다. 프로그램을 종료합니다.")
        break

while문은 if문 만큼 자주 사용해 보지는 못했지만 개념은 이해하고 있기에 어렵지 않게 코드를 작성할 수 있었다. 다만 입력값 a가 정수인지 문자열인지 판단하는 법을 모르겠어서 이 부분은 구글링을 통해 .isdigit()이라는 함수를 검색해 사용하게 되었다.

3. 반복문(for)

요구조건

  • 입출력 예제에 있는 사람들 중, 평균 성적이 70점 이상인 사용자의 이름과 나이를 출력해주세요
  • 입출력 예제
    users = [
        {"name": "Ronald", "age": 30, "math_score": 93, "science_score": 65, "english_score": 93, "social_score": 92},
        {"name": "Amelia", "age": 24, "math_score": 88, "science_score": 52, "english_score": 78, "social_score": 91},
        {"name": "Nathaniel", "age": 28, "math_score": 48, "science_score": 40, "english_score": 49, "social_score": 91},
        {"name": "Sally", "age": 29, "math_score": 100, "science_score": 69, "english_score": 67, "social_score": 82},
        {"name": "Alexander", "age": 30, "math_score": 69, "science_score": 52, "english_score": 98, "social_score": 44},
        {"name": "Madge", "age": 22, "math_score": 52, "science_score": 63, "english_score": 54, "social_score": 47},
        {"name": "Trevor", "age": 23, "math_score": 89, "science_score": 88, "english_score": 69, "social_score": 93},
        {"name": "Andre", "age": 23, "math_score": 50, "science_score": 56, "english_score": 99, "social_score": 54},
        {"name": "Rodney", "age": 16, "math_score": 66, "science_score": 55, "english_score": 58, "social_score": 43},
        {"name": "Raymond", "age": 26, "math_score": 49, "science_score": 55, "english_score": 95, "social_score": 82},
        {"name": "Scott", "age": 15, "math_score": 85, "science_score": 92, "english_score": 56, "social_score": 85},
        {"name": "Jeanette", "age": 28, "math_score": 48, "science_score": 65, "english_score": 77, "social_score": 94},
        {"name": "Sallie", "age": 25, "math_score": 42, "science_score": 72, "english_score": 95, "social_score": 44},
        {"name": "Richard", "age": 21, "math_score": 71, "science_score": 95, "english_score": 61, "social_score": 59},
        {"name": "Callie", "age": 15, "math_score": 98, "science_score": 50, "english_score": 100, "social_score": 74},
    ]
    
    def get_filter_user(users):
        # some code
        return filter_users
    
    filter_users = get_filter_user(users)
    pprint(filter_users)
    """
    [{'age': 30, 'name': 'Ronald'},
     {'age': 24, 'name': 'Amelia'},
     {'age': 29, 'name': 'Sally'},
     {'age': 23, 'name': 'Trevor'},
     {'age': 26, 'name': 'Raymond'},
     {'age': 15, 'name': 'Scott'},
     {'age': 28, 'name': 'Jeanette'},
     {'age': 21, 'name': 'Richard'},
     {'age': 15, 'name': 'Callie'}]
    """

대망의 마지막 문제인데 어떻게 풀어야 할지는 알 것 같다.
for문으로 users내에서 평균 점수가 70이 넘는 사람을 추려내 filter_users로 따로 빼낸 다음 filter_users에서 age와 name 값만 출력하면 되는 간단한 문제라고 생각했는데 하나의 for문 안에서 평균점수가 70점이 넘는 사람을 구하는 것, 그 사람들만 따로 분류해 내는 것, 그 사람들의 age와 name값만 나오게 하는 것. 이 세가지를 한번에 하는 것을 어떻게 하는지 몰라 구글링도 하고 오랜시간 고민을 해 보았지만 답이 나오지않아 결국 이 문제는 해설을 듣거나 따로 튜터님께 질문을 해보는 시간을 가져야 할 것 같다.

오늘 할 일을 끝내고

드디어 길고 길었던 파이썬 실시간 강의가 끝이 났다. 하지만 나는 아직도 부족한 것이 많은 것 같은데 벌써 이렇게 끝을 내고 다음으로 넘어가도 되는 건지 의구심이 계속 들고 있다. 내일부터는 새로운 강의가 시작되고 그에 따른 아침 발제도 있을 예정인데 지금까지 배운 것들도 머리속에서 완전히 정리가 안된 상황이라 조금 무섭다. 다행히도 따로 거북이반이라고해서 파이썬 문법 복습을 집중적으로 해주는 반을 따로 개설해 주신다고 하시니 그쪽에서 조금 더 많은 공부와 문제풀이를 통해 파이썬에 능숙해지도록 계속 노력을 해야할 것 같다.

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

0개의 댓글