Python 기초 - 3

프로그래머가 하는일 - 추상화(abstraction)

  • 절차 지향

    • procedure, procedural oriented

    • 절치 지향보다는 프로시져 지향이라고 하는 것이 맞다.

  • 객체 지향

    • OOP(Object-Oriented Programming)
  • 인터페이스(interface)와 구현(implementation)

    1. interface

      • function signature

      • 사용자들에게 제공(사용법만 알면 함수를 사용 가능하도록 함)

    2. implementation

      • 함수를 직접 만들기(내부 구현)

      • 함수 이름은 기능을 명확하게 표현해야 함

      • 매개 변수는 어떻게 설계하고 무엇을 인자로 받을 것인지 생각해야 함

      • 결과 값으로 어떤 결과를 반환할 것인지 생각해야 함

        1
        2
        3
        4
        5
        6
        7
        def func(a, b):
        """
        func(integer, integer) -> integer
        두 값을 인자로 받고
        결과는 그 두 값을 더한 값
        """
        return a + b
      • ctrl + ]를 사용하면 indent됨(범위를 지정하여 사용 가능)

      • 함수 안에 “”” “”” 사이에 함수 설명을 넣을 수 있음

      • ‘->’에는 반환되는 자료형을 써주는 것이 좋음

        1
        2
        3
        4
        5
        6
        7
        help(func)
        >> Help on function func in module __main__:

        func(a, b)
        func(integer, integer) -> integer
        두 값을 인자로 받고
        결과는 그 두 값을 더한 값
      • 사용자 입력 받기

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        input_data = input("무엇이든 입력하세요 : ")
        >> 무엇이든 입력하세요 : 여기에 입력

        type(input_data)
        >> str

        data = int(input("숫자를 입력하세요 : ")) # int형변환
        >> 숫자를 입력하세요 : 1

        type(data)
        >> int

Coding Practice

  • 가위바위보 게임

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    def get_player_choice():
    """
    get_player_choice() -> string
    string : {'바위', '가위', '보'}
    결과값이 위 세 값 중에 하나임을 보장한다.
    """
    player = input("바위, 가위, 보 중에 한 가지를 입력하세요 : ")
    while player != '바위' and player != '가위' and player != '보' :
    player = input('다시 입력하세요 : ')

    # while문에 직접 조건을 넣음

    return player


    import random

    # 0 --> '바위'
    # 1 --> '가위'
    # 2 --> '보'
    # random 내장 함수를 이용하기 위해 import로 random 모듈을 불러옴
    # Tuple 이용

    def get_computer_choice():
    """
    get_computer_choice() -> string
    string = {'바위', '가위', '보'}
    """
    choice_tu = ('바위', '가위', '보')
    computer = choice_tu[random.randint(0,2)]

    # 정수형 랜덤 숫자를 받음

    return computer


    def who_wins(player, computer):
    """
    who_wins(player, computer) -> string
    string = {'player', 'computer', 'draw'}
    """
    if player == '바위':
    if computer == '바위':
    winner = 'draw'
    elif computer == '가위':
    winner = 'player'
    else:
    winner = 'computer'

    elif player == '가위':
    if computer == '바위':
    winner = 'computer'
    elif computer == '가위':
    winner = 'draw'
    else:
    winner = 'player'

    else:
    if computer == '바위':
    winner = 'player'
    elif computer == '가위':
    winner = 'computer'
    else:
    winner = 'draw'

    return winner


    def play_one():
    """
    play_one() -> string
    string = {'player', 'computer', 'draw'}
    한 판에 대해서
    플레이어가 이기면 "플레이어 승" 출력
    컴퓨터가 이기면 "컴퓨터 승" 출력
    비기면 "무승부" 출력
    무승부가 나면 둘 중에 한 명이 이길 때까지 반복
    """
    while True:
    player = get_player_choice()
    computer = get_computer_choice()
    winner = who_wins(player, computer)

    if winner == 'player':
    print('플레이어 승!')
    return 'player'

    elif winner == 'computer':
    print('컴퓨터 승!')
    return 'computer'

    else:
    print('무승부')
    pass

    # pass는 실행할 것이 아무것도 없다는 의미
    # pass는 아무런 동작을 하지 않고 다음 코드를 실행
    # continue는 다음 순번의 loop를 실행
    # pass와 continue의 차이 알기


    def play():
    while True:
    try:
    user_num_games = int(input("1: 3판2선승, 2: 5판3선승: "))
    if user_num_games != 1 and user_num_games != 2:
    print("1 또는 2의 값만 입력하세요.")
    continue
    else:
    break

    except ValueError:
    print("숫자가 아닌 값을 입력하셨습니다. 다시 입력하세요.")


    #user_num_games --> 1 or 2
    num_games = 3 if user_num_games == 1 else 5

    #3판 2선승 --> 2승 or 5판 3선승 --> 3승
    count = 2 if num_games == 3 else 3

    win_list = []

    # 리스트를 만들어서 이긴 대상을 리스트 인덱스로 넣어둔다.
    # 리스트 내장 함수 count를 사용하여 선승을 판단한다.
    # for문 내부에 i라는 변수를 사용하지 않으면 _로 표시해도 무관하다.

    for _ in range(num_games):
    win_list.append(play_one())

    print('player : ', win_list.count('player'),'승', 'computer : ', win_list.count('computer'),'승')

    if win_list.count('player') >= count:
    print("플레이어 우승!")
    break

    elif win_list.count('computer') >= count:
    print("컴퓨터 우승!")
    break

    play()
    >> 1: 32선승, 2: 53선승: 1
    바위, 가위, 보 중에 한 가지를 입력하세요 : 바위
    무승부
    바위, 가위, 보 중에 한 가지를 입력하세요 : 가위
    컴퓨터 승!
    player : 0 승 computer : 1
    바위, 가위, 보 중에 한 가지를 입력하세요 : 보
    컴퓨터 승!
    player : 0 승 computer : 2
    컴퓨터 우승!

pass와 continue

  1. pass

    • 실행할 코드가 없다는 것을 의미

    • 다음 코드를 실행

      1
      2
      3
      4
      5
      for i in range(1, 5):
      if i == 3:
      pass
      print(i, end = ' ') # 3일 때에도 print 함수를 실행함
      >> 1 2 3 4
  2. continue

    • 조건이 참이 되면 다음 순번으로 강제 이동

      1
      2
      3
      4
      5
      for i in range(1, 5):
      if i == 3:
      continue
      print(i, end = ' ') # 3일 때 loop의 다음 순번으로 이동, print 함수를 실행하지 않음
      >> 1 2 4

packing과 unpacking

  1. packing

    • tuple로 선언하지 않았음

    • type은 tuple로 나옴 = packing이 되었음

      1
      2
      3
      container = 1, 2, 3, 4, 5
      type(container)
      >> tuple
  2. unpacking

    • 위 container 변수를 unpacking 함

    • 변수 앞에 *를 붙여주면 묶음

      1
      2
      3
      4
      5
      6
      7
      8
      9
      a, b, *c = container
      a
      >> 1

      b
      >> 2

      c
      >> [3, 4, 5]
    • dictionary에서 items()도 unpacking

      1
      2
      3
      4
      dic = {'a' : 1, 'b' : 2}
      for k, v in dic.items():
      print(k,v, end = ' ')
      >> a 1 b 2
  3. packing과 unpacking 활용

    • 함수에서 매개변수 앞에 *를 붙여주면 가변인자로 받을 수 있다.

      1
      2
      3
      4
      5
      def sum_int(*args):  # 함수에서 가변인자 받는 방법
      s = 0
      for arg in args:
      s += arg
      return s
    • 아래와 같이 1, 2, 3, 4, 5의 가변인자가 들어오면 tuple로 packing이 됨

      1
      2
      sum_int(1, 2, 3, 4, 5)
      >> 15
    • 아래와 같이 list 형태로 가변인자를 넣게 되면 하나의 데이터로 인식하여 에러 발생

      1
      2
      3
      4
      li = [1, 2, 3, 4]

      sum_int(li)
      >> TypeError: unsupported operand type(s) for +=: 'int' and 'list'
    • 따라서 *를 붙여서 다시 unpacking하여 사용

      1
      2
      3
      # *를 붙여서 다시 unpacking하여 사용
      sum_int(*li)
      >> 10
    • 아래와 같은 매개변수의 형태로 모든 인자를 다 받을 수 있다.

      • args : non keyword arguments

      • kwargs : keyword arguments

    • kwargs는 dictionary를 packing할 때 사용한다.(keyword가 존재)

    • 함수를 정의할 때, *args, **kwargs는 가변인자를 받겠다는 의미이다.

      1
      2
      3
      4
      5
      6
      7
      def sum_int(*args, **kwargs):
      print(args)
      print(kwargs)

      sum_int(1, 2, 3, age = 100, weight = 100)
      >> (1, 2, 3)
      {'age': 100, 'weight': 100}
    • keyword가 없는 인자는 앞에, keyword가 있는 인자는 뒤에 위치해야 한다.

    • keyword 인자 뒤에 keyword가 없는 인자가 존재하면 에러가 발생한다.

      1
      2
      sum_int(1, 2, 3, age = 100, weight = 100, 4)
      >> SyntaxError: positional argument follows keyword argument
    • 함수를 호출하는 입장에서의 *, **는 unpacking을 의미한다.

      1
      2
      3
      sum_int(*li, **dic)
      >> (1, 2, 3, 4)
      {'a': 1, 'b': 2}

삼항 연산자

  • ‘참인 경우의 값’ if ‘조건’ else ‘거짓인 경우의 값’

    • if문의 일반 사용 예

      1
      2
      3
      4
      5
      6
      a = 10
      if a >= 10:
      print('good!')
      else:
      print('bad!')
      >> good!
    • 삼항 연산자 적용 예

      1
      2
      3
      4
      5
      # if 조건문 결과는 앞에, else 조건문 결과는 뒤에 위치시킨다.
      # if else 간에 ':'를 붙이지 않아도 된다.

      print('good!') if a >= 10 else print('bad!')
      >> good!

재귀 함수(recursive function, recursion)

  • 자기가 자기 자신을 호출하는 함수

  • 기저 조건(base case) = 종료 조건, 탈출 조건

  1. Basic

    • 기저 조건을 반드시 정해줘야 한다.(종료, 탈출)

    • 재귀하는 과정에서 자기 자신을 만날 때마다 blocking이 걸린다.

    • blocking이 걸린 다음에 함수가 호출되며 stack frame에 쌓인다.

    • 함수가 쌓일 수 있는 stack frame 공간이 정해져 있다.

    • 정해진 stack frame을 넘어버리면 stack overflow가 발생한다.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      def func(num):
      # 기저 조건(base case)
      # 종료 조건
      # 탈출 조건
      if num <= 0:
      return

      print(num, end = ' ')
      func(num - 1)

      func(5)
      >> 5 4 3 2 1
  2. Basic function example

  • factorial(계승)

    • 점화식 –> fac(num) = fac(num - 1)*num

    • 기저 조건 –> if num == 1 return 1

      1
      2
      3
      4
      5
      6
      7
      8
      9
      def factorial(num):
      if num == 1:
      return 1

      return factorial(num - 1) * num

      for num in range(1, 10):
      print(factorial(num), end = ' ')
      >> 1 2 6 24 120 720 5040 40320 362880
  • fibonacci(피보나치)

    • 점화식 : fibo(n) = fibo(n - 2) + fibo(n - 1)

    • 기저 조건 : if n == 1 or n == 2 then return 1

      1
      2
      3
      4
      5
      6
      7
      8
      9
      def fibonacci(n):
      if n == 1 or n == 2:
      return 1

      return fibonacci(n - 2) + fibonacci(n - 1)

      for n in range(1, 10):
      print(fibonacci(n), end = ' ')
      >> 1 1 2 3 5 8 13 21 34
Share