ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Python Programming (4) - 함수
    Python Programming 2020. 3. 28. 06:42
    728x90
    4.Python_Function

    4. 함수

    함수 - function

    • 함수는 하나의 관련 작업을 수행하는 데 사용되는 재사용 가능한 코드 블록이다.

      • 함수는 응용 프로그램의 모듈성을 높이고 코드 재사용 수준을 높인다.
    • Python은 기본적으로 많은 내장 함수를 제공한다.

    • 문자열 등을 다루면서 함수를 사용한 경험을 상기해 보자.

      • len("Python programming")
    • 필요에 따라 함수를 생성하여 원하는 기능을 따로 분리하여 사용하는 법을 익혀보자.

      • Python에서 제공하는 함수 뿐만 아니라 사용자 정의의 새로운 함수를 만드는 법.
      • Decomposition and abstraction

    함수 정의의 규칙

    • 함수 블록은 키워드 def와 함수 이름 및 괄호()로 시작한다.

    • 모든 입력 매개 변수는 괄호 안에 있어야 한다. 이 괄호 안에 매개 변수를 정의할 수도 있다.

    • 모든 함수 내의 코드 블록은 콜론(:)으로 시작되고 들여쓰기를 하여야 한다.

    • return [expression] 명령문은 함수를 종료하고 호출자에게 결과를 전달한다.

    def function_name(< argument >):   
       < something to do >

    함수 예제

    • 제곱 후 1을 더해서 반환하는 함수
    In [1]:
    def square_plus_one(x):
        ans = x ** 2 + 1
        return ans
    

    • 함수는 인자(argument)를 입력 받아 x라는 매개 변수(parameter)에 대입
    • x**2 + 1 의 계산을 수행한 후
    • 결과를 ans에 대입하여 반환(return)하고 있음

    • 함수의 정의가 완료되었으면 이 함수를 이용하여 계산을 할 수 있다.

      • square_plus_one(10) 등을 수행해 보자.
      • 10이라는 인자를 입력 받아 x라는 매개 변수에 대입하여 계산을 수행한 후 결과를 전달한다.
    In [2]:
    square_plus_one(10)
    
    Out[2]:
    101

    함수 예제(2)

    • 제곱근 반환 함수
    In [3]:
    def my_sqrt(x):
        ans = 0
        increment = 1
        while increment >= 0.0001:
            ans += increment
            if ans**2 == x:
                break
            elif ans**2>x:
                ans -= increment
                increment = increment/10.0
        return ans
    

    함수 사용

    • 함수를 정의하였으면 이를 활용할 수 있음
    In [4]:
    print(my_sqrt(2))
    
    1.4142
    
    In [5]:
    y = 16 
    print(my_sqrt(y))
    
    4
    
    In [6]:
    z = 12 
    print(my_sqrt(z*12))
    
    12
    
    In [7]:
    x = my_sqrt(100) 
    print(x*x)
    
    100
    

    returnprint

    • 함수를 처음 접하는 경우 returnprint의 개념을 혼동하는 경우가 많다.
    • 이는 Jupyter notebook 등에서 함수를 실행할 때, return 값을 자동으로 화면에 출력하도록 하기 때문이다.
    • 실제로는 둘은 전혀 다른 개념이므로 절대로 혼동하지 않도록 한다.
    • return의 궁극적인 목적은 함수의 계산 결과를 반환하여 이차적으로 활용할 수 있도록 하는 것이고,
    • print는 단순히 화면에 출력하여 프로그래머가 눈으로 값을 확인할 수 있게 한다.
      • 함수 내에서 사용되는 print는 함수 본체 중의 일부일 뿐이다.
    • 다음 두 함수를 비교해 보자.
    In [8]:
    def this_func_print(x):
        print(x ** 2 + 1)
    
    def this_func_return(x):
        return x ** 2 + 1
    

    단순히 함수를 실행시켰을 경우, Jupyter notebook이나 콘솔에서의 실행 결과는 비슷해 보인다.

    In [9]:
    this_func_print(2)
    
    5
    
    In [10]:
    this_func_return(2)
    
    Out[10]:
    5

    하지만, this_func_return의 결과는 다른 변수에 할당하여, 이차적으로 활용할 수 있는 반면, this_func_print는 그렇지 않다.

    In [11]:
    y = this_func_return(2) # this_func_return(2)의 결과 5가 y에 대입된다.
    print(y / 10)           # y를 다른 계산에 활용할 수 있다. 5/10 = 0.5
    
    0.5
    

    this_func_printreturn은 존재하지 않으며, python에서는 이를 None이라는 값으로 처리한다.
    따라서 다음 코드에서 y의 값은 None에 불과하며 이를 이차적으로 활용할 방안은 많지 않다.

    In [12]:
    y = this_func_print(2)   # this_func_print(2) 결과는 5로 정상 출력되지만
    print(y)                 # y는 None으로 큰 의미가 없음, 즉 다른 계산에 활용할 수 없다.
    
    5
    None
    

    인자가 없는 경우

    • 함수는 아무런 인자를 받지 않을 수 있음
    • 빈 괄호 ()로 표현된다.
    In [13]:
    def print_something():
        print("This function does nothing.")
    
    • 위 함수는 아무런 인자를 받지 않을 뿐만 아니라, 아무런 반환값도 없음 (None을 반환)
      • return을 찾을 수 없다.
      • print_something() 함수를 실행해 보자.
    In [14]:
    print_something()
    
    This function does nothing.
    
    • 인자가 필요하지만 함수 호출 시 입력하지 않았을 경우 에러가 발생한다.
    In [15]:
    def printme(stri):
        print("Input is :", stri)
        return
    
    printme()
    
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-15-93e492e75154> in <module>()
          3     return
          4 
    ----> 5 printme()
    
    TypeError: printme() missing 1 required positional argument: 'str'
    • 다음과 같이 인자가 어떤 값을 입력받는지 확실히 표현할 수도 있다.
      • (stri = "My string")이라고 표현한 것에 주목하자.
    In [16]:
    def printme(stri):
        print("Input is :", stri)
        return
    
    
    printme(stri = "My string")
    
    Input is : My string
    

    여러 개의 인자를 받는 함수

    • 함수는 여러 개의 인자를 받을 수 있다.
    In [17]:
    def printinfo(name, age):
        print("Name: ", name)
        print("Age: ", age)
        return
    
    printinfo(age=50, name="miki")
    
    Name:  miki
    Age:  50
    
    In [18]:
    def my_max(x, y):
        if x >= y:
              return x
        else:
              return y
    
    In [19]:
    my_max(10,12)
    
    Out[19]:
    12

    여러 개의 인자를 받는 함수(2)

    • 최대공약수를 구하는 함수
    In [20]:
    def my_GCD(x, y):
        j = 1
        ans = 1
        while j <= x and j <= y:
            if x%j == 0 and y%j == 0:
                ans = j
            j += 1
        return ans
    
    In [21]:
    my_GCD(24, 84)
    
    Out[21]:
    12
    • 최소공배수를 구하는 함수도 만들어 보자.

    예제

    In [22]:
    def printName(firstName, lastName, reverse):
        if reverse:
              print(lastName + ', ' + firstName)
        else:
              print(firstName, lastName)
    
    • 다음은 동치
    In [23]:
    printName('Kyungsub', 'Lee', False)
    printName('Kyungsub', 'Lee', reverse=False)
    printName(lastName='Lee', firstName='Kyungsub', reverse=False)
    
    Kyungsub Lee
    Kyungsub Lee
    Kyungsub Lee
    

    default parameter

    • 함수 생성 시 다음과 같이 default parameter를 설정할 수 있다.
    • default parameter는 입력값이 따로 없을 때, 미리 설정된 default값을 이용한다.
    In [24]:
    def printName(firstName, lastName, reverse = False):
        if reverse:
             print(lastName + ', ' + firstName)
        else:
             print(firstName, lastName)
                
    printName('Kyungsub', 'Lee')
    
    Kyungsub Lee
    
    In [25]:
    printName('Kyungsub', 'Lee', True)
    
    Lee, Kyungsub
    
    In [26]:
    def printinfo( name, age = 35 ):
        print("Name: ", name)
        print("Age: ", age)
        return
    
    In [27]:
    printinfo( age=50, name="miki" )
    printinfo( name="miki" )
    
    Name:  miki
    Age:  50
    Name:  miki
    Age:  35
    

    지역 변수(local variable)

    • 함수 내의 변수는 함수 내에서만 존재하는 변수
    In [28]:
    def my_func():
        x = 20
        
    x = 10
    my_func()
    print(x)
    
    10
    
    • 함수 내의 지역 변수와 함수 바깥의 전역 변수(global variable)이 분리되어 있음을 주의
    In [29]:
    def my_func():
        x = 20
        return x
    
    x = 10
    x = my_func()
    print(x)
    
    20
    
    In [30]:
    def increase(x):
        x = x + 1
        
    x=1
    increase(x)
    print(x)
    
    1
    

    def increase(x): x = x + 1 return x

    x = 1 x = increase(x) print(x)

    변수 scope 더 살펴보기

    변수의 scope는 해당 변수가 파이썬 인터프리터에게 보이거나 액세스 가능한 범위를 나타낸다.

    다음의 예제에서 변수 x는 함수 내에 존재하지 않기 때문에, 함수 바깥에서 정의된 x의 값을 가져온다.

    In [31]:
    x = 1
    def print_x():
        print(x)
        
    print_x()
    
    1
    

    다음은 함수 밖에 x가 정의되어 있어 있지만, 함수 내에서 x가 다시 정의되다.
    이 경우 함수 내에서 x를 사용할 때는, 함수 내에서 정의된 x가 우선 순위를 가진다.

    In [32]:
    x = 1
    def print_x():
        x = 2
        print(x)
        
    print_x()
    
    2
    

    농장 문제

    • 농장에 돼지들과 닭들이 있다. 총 머리의 수는 20개, 총 다리의 수는 56개이다. 돼지와 닭의 수는 각각 얼마인가?
      • Brute force 방법으로 풀어보자.
    In [33]:
    for x in range(0,21):
        y = 20 - x
        if 4*x + 2*y == 56:
             break
    print(x, y)
    
    8 12
    

    농장 문제 – 함수

    • 임의의 머리 수와 다리 수가 주어졌을 때, 돼지와 닭의 수를 구하는 함수를 작성해 보자.
    In [34]:
    def farm(numHeads, numLegs):
        for x in range(0, numHeads + 1):
            y = numHeads - x
            if 4*x + 2*y == numLegs:
                  return x, y
    
    In [35]:
    print(farm(20, 56))
    
    (8, 12)
    
    In [36]:
    print(farm(20, 60))
    
    (10, 10)
    

    None

    • Python에서 없는 값을 나타내기 위해 사용되는 값
    • None을 이용하여 해가 없는 경우를 대비하여 보자.
    In [37]:
    def farm(numHeads, numLegs):
        for x in range(0, numHeads + 1):
            y = numHeads - x
            if 4*x + 2*y == numLegs:
                return x, y
        return None, None
    
    farm(100,10)
    
    Out[37]:
    (None, None)
    • 앞의 예제에서 return이 두 번 등장함을 볼 수 있음
      • 첫 번째 return은 방정식의 조건이 만족하면 다리의 숫자를 return하고 함수를 종료
      • 두 번째 return은 방정식의 조건을 만족하는 해가 없을 때 None을 반환

    함수를 호출하는 함수

    In [38]:
    def farm_UI():
        heads = int(input('Enter the number of heads : '))
        legs = int(input('Enther the number of legs : '))
        pigs, chickens = farm(heads, legs)
        if pigs == None:
            print('No solution')
        else:
            print('Number of pigs : ', pigs)
            print('Number of chickens : ', chickens)
            
    farm_UI()
    
    Enter the number of heads : 50
    Enther the number of legs : 160
    Number of pigs :  30
    Number of chickens :  20
    

    Built-in function

    lambda

    lambda는 비교적 간단한 함수를 생성할 때 사용하는 키워드로 def와 비슷한 역할을 한다.

    • lambda arguments: expression
    In [39]:
    def my_add_plus_one1(x, y): return x + y + 1
    

    위 함수 정의는 다음의 방법으로 거의 똑같이 구현할 수 있다.

    • lambda: 사이에 parameter들이 오며, :뒤에 return값을 배치한다.
    In [40]:
    my_add_plus_one2 = lambda x, y: x + y + 1
    
    In [41]:
    my_add_plus_one2(1, 2)
    
    Out[41]:
    4

    lambda 방법의 장점은 함수에 특별히 이름을 붙이지 않아도 함수를 사용가능 하도록 한다는 점이다.

    • 이를 anonymous function이라고도 부른다.
    In [42]:
    (lambda x, y: x + y + 1)(1, 2)
    
    Out[42]:
    4

    Module

    Math module

    • import math
    • math.sqrt(x)
      • x의 제곱근 반환
    • math.exp(x)
      • e**x 반환
    • math.sin(x)
      • sin 함수값 반환
    • math.pi
      • 3.141592…
    In [43]:
    import math
    math.sqrt(71)
    
    Out[43]:
    8.426149773176359
    In [44]:
    math.sin(math.pi / 2)
    
    Out[44]:
    1.0
    In [45]:
    math.log(4) / math.log(2)
    
    Out[45]:
    2.0
    In [46]:
    math.log(4) % math.log(2)
    
    Out[46]:
    0.0
    In [47]:
    math.log(8) / math.log(2)
    
    Out[47]:
    3.0
    In [48]:
    # 실수 간의 나머지를 계산할 때는 주의하여야 한다.
    math.log(8) % math.log(2)
    
    Out[48]:
    0.6931471805599452

    division - 나누기

    • 다음은 Python 3.x에서는 해당되지 않는 내용이다.

    • Python 2.x에서는 나누기(/)를 사용시 기본적으로 정수를 먼저 반환하려고 함.

      • 5/2 = 2
    • 실수 나누기를 하고 싶은 경우

      • 5/2.0 혹은 5/float(2)
    • 만약 default로 실수를 반환하는 나누기(/)를 사용하고 싶을 때, 다음 import문을 사용할 수 있음

    In [49]:
    from __future__ import division
    5/2
    
    Out[49]:
    2.5
    In [50]:
    5//2
    
    Out[50]:
    2

    Random module

    • import random
    • random.random()
      • 0이상 1이하의 랜덤값 반환
    • random.uniform(a,b)
      • a이상 b이하에서 uniform 분포를 가지는 랜덤값 반환
    • random.randint(a,b)
      • a이상 b이하의 랜덤 정수 반환
    • random.gauss(mu, sigma), random.normalvariate(mu, sigma)
      • 평균 mu, 표준편차 sigma의 정규 분포를 가지는 랜덤값 반환
    In [51]:
    import random
    random.random()
    
    Out[51]:
    0.10668914840319754
    In [52]:
    random.uniform(0, 10)
    
    Out[52]:
    6.341924961487889
    In [53]:
    random.randint(1, 5)
    
    Out[53]:
    3
    In [54]:
    random.gauss(0, 1)
    
    Out[54]:
    0.6654604009008476

    예제 : 랜덤 숫자를 맞추는 프로그램

    1부터 100까지의 숫자를 랜덤으로 생성 후 키보드 입력을 통해 그 숫자를 맞추는 프로그램

    In [55]:
    import random
    def guess():
        a = random.randint(1, 100)
        while(True):
            x = input("Guess the number between 1 to 100 (type q to quit) : ")
            
            if a == "q":
                return
            elif a == int(x):
                print("Correct!")
                return
            elif a < int(x):
                print("The number is smaller than your guess, try again.")
            elif a > int(x):
                print("The number is larger than your guess, try again.")
            else:
                print("Please input appropriate number.")
    
    In [56]:
    guess()
    
    Guess the number between 1 to 100 (type q to quit) : 50
    The number is smaller than your guess, try again.
    Guess the number between 1 to 100 (type q to quit) : 25
    The number is larger than your guess, try again.
    Guess the number between 1 to 100 (type q to quit) : 32
    The number is larger than your guess, try again.
    Guess the number between 1 to 100 (type q to quit) : 41
    The number is smaller than your guess, try again.
    Guess the number between 1 to 100 (type q to quit) : 36
    Correct!
    

    t – 랜덤 변수

    • gauss() 함수와 gammavariate() 함수를 이용하여 t-분포를 따르는 랜덤 변수를 생성하는 함수
    In [57]:
    import math 
    import random
    
    def student_t(nu): # nu equals number of degrees of freedom
        x = random.gauss(0.0, 1.0)
        y = 2.0*random.gammavariate(0.5*nu, 2.0)
        return x / (math.sqrt(y/nu))
    
    In [58]:
    student_t(10)
    
    Out[58]:
    -0.4360479212496367

    모듈 파일을 불러오는 다양한 방법

    In [59]:
    import random  
    random.randint(1, 10)
    
    Out[59]:
    10
    In [60]:
    from random import *  
    randint(1, 10)
    
    Out[60]:
    7
    In [61]:
    import random as r   
    r.randint(1, 10)
    
    Out[61]:
    2

    모듈에 대한 여러 가지

    • 파이썬 스크립트 파일로 모듈을 만들 수 있음
      • 기본 작업 directory에 저장하여 import 할 수 있음
    • 모듈 변경과 갱신
      • 혹시 모듈을 변경하였다면 reload 명령을 이용하여 갱신
        • reload(fibo)
    728x90

    댓글

Designed by Tistory.