블로그 이미지
조이키트 블로그
아두이노, 라즈베리파이, 반도체 센서/모듈 활용

calendar

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

Notice

250x250
2023. 8. 28. 15:52 파이썬
728x90
반응형

다음 코드는 간단한 해시 함수를 사용하여 정수가 키인 딕셔너리를 구현하고 있다. 여기에서 기본적인 아이디어는 intDict 클래스의 인스턴스를 해시 버킷 리스트로 나타내는 것이며, 각 버킷은 키/값의 쌍들로 이루어진 리스트이다. 각 버킷을 리스트로 구현함으로 버킷에 해시되는 값들을 리스트에 저장하여 충돌을 해결할 수 있다. 인스턴스 변수 buckets는 numBuckets의 개수만큼의 빈 리스트로 초기화한다. dictkey키로 엔트리를 검색하거나 저장하려고 할 때 해시함수 %를 사용하여 dictkey를 정수로 반환하고 그 정수를 사용하여 buckets를 인덱스하여 해당하는 dictkey와 연관된 해시 버킷을 찾아낸다. 그 다음엔 그 버킷을 선형적으로 검색하여 dictkey키로 된 엔트리가 있는지 확인한다. 검색을 하는 경우에는 그 키로 된 엔트리가 없다면 None을 반환한다. 저장을 하려고 하는 경우에는 이미 들어가 있는 엔트리가 있다면 그 엔트리의 값을 대체하거나 엔트리가 없다면 새로운 엔트리를 추가한다.

# 해싱을 사용하여 딕셔너리 구현하기
class intDict(object):
    def __init__(self, numBuckets):
        self.buckets = []
        self.numBuckets = numBuckets
        for i in range(numBuckets):
            self.buckets.append([])

    def addEntry(self, dictKey, dictVal):
        hashBucket = self.buckets[dictKey%self.numBuckets]
        for i in range(len(hashBucket)):
            if hashBucket[i][0] == dictKey:
                hashBucket[i] = (dictKey, dictVal)
                return
        hashBucket.append((dictKey, dictVal))

    def getValue(self, dicKey):
        hashBucket = self.buckets[dicKey%self.numBuckets]
        for e in hashBucket:
            if e[0] == dicKey:
                return e[1]
            return None
        
    def __str__(self):
        result = '{'
        for b in self.buckets:
            for e in b:
                result = result + str(e[0]) + ':' + str(e[1]) + ', '
                return result[:-1] + '}'
            
import random
D = intDict(29)
for i in range(20):
    key = random.randint(0, 10**5)
    D.addEntry(key, i)

print('The value of the intDict is:')
print(D)
print('\n', 'The buckets are:')
for hashBucket in D.buckets:
    print(' ', hashBucket)

__str__ 메소드에서 보면 요소들이 추가된 순서에 관계없이 키가 해시하려는 값의 순서로 딕셔너리를 만들고 있다는 것을  알 수가 있다. 이것이 dict 자료형의 키의 순서를 왜 예측할 수 없는지를 설명해준다. 위의 코드는 먼저 20개의 엔트리로 intDict를 만든다. 엔트리의 값은 정수 0에서 19이다. 키는 0과 10^5 -1 사이의 정수 중 하나를 임의로 선택한다. 그 다음에는 클래스에 정의된 __str__ 메소드를 사용하여 intDict를 출력한다. 마직막으로 D.bucket을 반복하여서 각 해시 버킷을 출력한다.

 

출력 결과

The value of the intDict is:
{957:7,}

 The buckets are:
  [(957, 7)]
  [(96745, 4), (19373, 5), (1567, 19)]
  [(86799, 12)]
  []
  []
  [(79726, 1)]
  []
  [(43101, 10), (36112, 18)]
  [(74886, 16)]
  []
  []
  [(62042, 13)]
  []
  [(68018, 6)]
  []
  []
  []
  [(83508, 17)]
  [(192, 2)]
  []
  []
  [(10722, 3), (99839, 14)]
  []
  [(34620, 0)]
  [(18381, 9), (33490, 11)]
  []
  []
  [(22792, 15)]
  [(79952, 8)]

만약 추상화 장벽을 무시하고 intDict을 직접 살펴보면 많은 해시 버킷이 비어있는 것을 확인할 수 있다. 비어있지 않은 버킷은 충돌 횟수에 따라 하나에서 세 개의 튜플을 갖고 있다.

728x90
반응형
posted by 조이키트 블로그
2023. 8. 28. 14:35 파이썬
728x90
반응형

합병 정렬은 전형적인 분할정복 알고리즘으로 볼 수 있으며 1945년에 존 폰 노이만이 개발하였고 아직까지도 많이 사용되고 있다. 분할 정복 알고리즘처럼 재귀적으로 가장 쉽게 설명할 수 있다.

1. 리스트의 길이가 0이나 1일 때 리스트는 이미 정렬된 상태이다.

2. 리스트에 한 개 이상의 요소가 들어있으면 리스트를  두 개의 리스트로 나눈 후에 합병정렬을  사용하여 나뉘어진 리스트를 정렬한다.

3. 결과를 합병한다.

우선 각 리스트의 첫 번째 요소를 보고 둘 중 작은 요소를 결과 리스트의 끝으로 옮기는 것이다. 만약 둘 중 하나의 리스트가 비게 되면, 남아있는 리스트의 요소들을 모두 결과 리스트에 옮기면 된다.

 

다음 코드는 두 개의 배치 함수를 정의하고 있으며 이 두 함수를 이용하여 두 가지 방법으로 리스트를 정렬하고 있다. 각 함수는 표준 파이썬 모듈 string을 가져와서 그 모듈의 split 함수를 사용한다. split의 인자는 두개의 문자열들이고 두번 째 인자는 문자열을 부분열로 나눌 때 사용하는 구분자를 나타낸다. 

# 이름 리스트 정렬하기
def merge(left, right, compare):
    result = []
    i, j = 0, 0
    while i < len(left) and j < len(right):
        if compare(left[i], right[j]):
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1

    while (i < len(left)):
        result.append(left[i])
        i += 1
    while (j < len(right)):
        result.append(right[j])
        j += 1
    return result

import operator

def mergeSort(L, compare = operator.lt):
    if len(L) < 2:
        return L[:]
    else:
        middle = len(L)//2
        left = mergeSort(L[:middle], compare)
        right = mergeSort(L[middle:], compare)
        return merge(left, right, compare)
    
from string import *
def lastNameFirstName(name1, name2):
    name1 = name1.split(' ')
    name2 = name2.split(' ')
    if name1[1] != name2[1]:
        return name1[1] < name2[1]
    else : 
        return name1[0] < name2[0]
    
def firstNameLastName(name1, name2):
    name1 = name1.split(' ')
    name2 = name2.split(' ')
    if name1[0] != name2[0]:
        return name1[0] < name2[0]
    else:
        return name1[1] < name2[1]
    
L = ['Chris Terman', 'Tom Brady', 'Eric Grimson', 'Gisels Bundchen']
newL = mergeSort(L, lastNameFirstName)
print('Sorted by last name =', newL)
newL = mergeSort(L, firstNameLastName)
print('Sorted by first name =', newL)

L = [3, 5, 2]
D = {'a' : 12, 'c' : 5, 'b' : 'dog'}
print(sorted(L))
L.sort()
print(L)
print(sorted(D))

파이썬 함수 sorted은 리스트나 딕셔너리처럼 반복 가능한 객체를 첫 번째 인자로 받아서 정렬된 새로운 리스트를 반환한다.

 

출력 결과

Sorted by last name = ['Tom Brady', 'Gisels Bundchen', 'Eric Grimson', 'Chris Terman']
Sorted by first name = ['Chris Terman', 'Eric Grimson', 'Gisels Bundchen', 'Tom Brady']
[2, 3, 5]
[2, 3, 5]
['a', 'b', 'c']

sorted 함수를 딕셔너리에 실행하면 딕셔너리의 키 값으로 정렬한 리스트를 반환한다. list.sort 메소드와 sorted 함수 모두 두 개의 추가 매개변수를 사용할 수가 있다. key 매개변수는 합병정렬에서 compare와 같은 역할을 하는 것으로 비교 함수를 제공하기 위한 것이다. reverse 매개변수는 리스트가 오름차순인지 내림차순인지를 지정해준다. 다음 코드는 L의 요소들을 내림차순으로 정렬하여 출력한다.

L = [[1,2,3], (3,2,1,0), 'abc']
print(sorted(L, key = len, reverse=True))

출력 결과

[(3, 2, 1, 0), [1, 2, 3], 'abc']

list.sort 메소드와 sorted 함수는 안전 정렬 함수이다. 즉 비교할 때 두 개의 요소가 같다면 원래 리스트의 순서가 상대적으로 적용되어 최종 리스트에도 원래 순서로 유지가 된다.

728x90
반응형
posted by 조이키트 블로그
2023. 8. 16. 10:30 파이썬
728x90
반응형

알고리즘의 실행 시간과 입력 규모의 관계를 말할 때에는 점근 표기법이라는 것을 공식적으로 사용한다.

점근 표기법은 입력 규모가 무한대로 갈 때의 알고리즘의 복잡도를 의미한다.

# 점근 표기법
def f(x):
    ans = 0
    for i in range(1000): # Loop that takes constant time
        ans += 1
    print('Number of additions so far', ans)

    for i in range(x): # Loop that takes time x
        ans += 1
    print('Number of additions so far', ans)

    for i in range(x): # Nested loops take time x**2
        for j in range(x):
            ans += 1
            ans += 1
    print('Number of additions so far', ans)
    return ans


print(f(2))

위의 코드를 보면 각 줄의 코드를 실행할 때 한 단위의 시간이 걸린다고 가정한다면 이 함수의 실행 시간은 1000 + x + 2x^2로 표현할 수 있다. 상수 1000은 첫 번째 반복문이 실행되는 횟수에 해당한다. x는 두 번째 반복문이 실행되는 횟수에 해당한다. 마지막으로 2x^2는 중첩된 반복문에 있는 두 개의 문장을 실행한 것에 해당한다.

만약 f(2)을 호출한다면 다음과 같이 출력된다.

Number of additions so far 1000
Number of additions so far 1002
Number of additions so far 1010
1010

 

728x90
반응형
posted by 조이키트 블로그
2023. 8. 12. 17:35 파이썬
728x90
반응형

프로그램은 Mertagate 클래스와 다음과 같은 세 가지 종류에 해당하는 하위 클래스로 구성한다.

1. 포인트가 없는 고정 금리 대출

2. 포인트가 있는 고정 금리 대출

3. 초기 티져금리로 시작하고 대출 기간 동안 금리가 올라가는 대출

# 대출(Mortgage) 기본 클래스
def findPayment(loan, r, m):
    return loan*((r*(1+r)**m)/((1+r)**m - 1))

class Mortgage(object):
    def __init__(self, loan, annRate, months):
        self.loan = loan
        self.rate = annRate/12.0
        self.months = months
        self.paid = [0.0]
        self.owed = [loan]
        self.payment = findPayment(loan, self.rate, months)
        self.legend = None

    def makePayment(self):
        self.paid.append(self.payment)
        reduction = self.payment - self.owed[-1]*self.rate
        self.owed.append(self.owed[-1] - reduction)

    def getTotalPaid(self):
        return sum(self.paid)
    
    def __str__(self):
        return self.legend

 위의 코드를 보면 추상 클래스 Mertgate가 있다. 이 클래스는 각 하위 클래스에서 함께 사용하는 메소드를 가지고 있지만 직접 인스턴스를 생성하기 위한 클래스는 아니다.

def findPayment(loan, r, m):
    return loan*((r*(1+r)**m)/((1+r)**m - 1))

첫 번째 함수 findPayment는 주어진 기간에 대출을 모두 갚기 위해 은행에 상환해야 할 원금과 이자를 포함한 고정된 월 납입금을 계산해준다.

class Mortgage(object):
    def __init__(self, loan, annRate, months):
        self.loan = loan
        self.rate = annRate/12.0
        self.months = months
        self.paid = [0.0]
        self.owed = [loan]
        self.payment = findPayment(loan, self.rate, months)
        self.legend = None

__init__을 살펴보면 모든 Mertgage의 인스턴스들이 가지고 있는 인스턴스 변수들은 다음과 같다. 초기 대출 금액, 한달 금리, 대출 기간 개월 수, 매월 초에 상환된 금액 리스트(첫 번째 달에는 아무 금액도 상환하지 않기 때문에 리스트는 0.0으로 시작한다.) 매월 초에 미결제된 잔액의 리스트, 매월 내는 납입금(findPayment 함수가 반환하는 값으로 초기화 된다.) 모든 Mertgate의 하위 클래스들은 __init__은 제일 먼저 Mertgage.__init__을 호출하고 그 다음에 self.legend를 각각 하위 클래스에 쓰여져 있는 설명대로 알맞게 초기화해야 한다.

    def makePayment(self):
        self.paid.append(self.payment)
        reduction = self.payment - self.owed[-1]*self.rate
        self.owed.append(self.owed[-1] - reduction)

makePayment 메소드는 대출 납입금을 기록하기 위한 용도이다. 각 납입금은 대출 잔액으로 인한 이자를 포함한 것이며, 그 나머지는 대출 잔금을 줄여 나간다. 이것 때문에 makePayment는 self.paid와 self.owed이 두 값 모두를 갱신한다.

    def getTotalPaid(self):
        return sum(self.paid)

getTotalPaid 메소드는 일련의 숫자들의 합을 반환해주는 파이썬 내장 함수 sum을 사용한다. 만약 숫자가 아닌 값이 있다면 예의를 발생한다.

다음 코드는 두 종류의 대출의 클래스를 구현하고 있다. 각 클래스는 __init__ 함수를 올버라이드하고 있으며 Mortgage에서 또 다른 세 가지 메소드를 상속받고 있다.

# 고정 금리 대출 클래스
class Fixed(Mortgage):
    def __init__(self, loan, r, months):
        Mortgage.__init__(self, loan, r, months)
        self.legend = 'Fixed, ' + str(r*100) + '%'

class FixedWithPts(Mortgage):
    def __init__(self, loan, r, months, pts):
        Mortgage.__init__(self, loan, r, months)
        self.pts = pts
        self.paid = [loan*(pts/100.0)]
        self.legend = 'Fixed, ' + str(r*100) + '%, '\
        + str(pts) + ' points'

 다음은 Mortgage의 세번쨰 하위 클래스이다. TwoRate 클래스는 마치 두 개의 다른 금리를 가지고 있는 대출을 병합한 것처럼 다루고 있다. self.paid가 0.0으로 초기화되어 있기 때문에 지불한 횟수보다 하나 더 많은 값을 가지고 있다. 때문에 makePayment는 len(self.paid)를 self.teaserMonths + 1과 비교하고 있는 것이다.

# 티져금리와 대출
class TwoRate(Mortgage):
    def __init__(self, loan, r, months, teaserRate, teaserMonths):
        Mortgage.__init__(self, loan, teaserRate, months)
        self.teaserMonths = teaserMonths
        self.teaserRate = teaserRate
        self.nextRate = r/12.0
        self.legend = str(teaserRate*100)\
        + '% for' + str(self.teaserMonths)\
        + 'months, then' + str(r*100) + '%'

    def makePayment(self):
        if len(self.paid) == self.teaserMonths + 1:
            self.rate = self.nextRate
            self.payment = findPayment(self.owed[-1], self.rate, self.months - self.teaserMonths)
        Mortgage.makePayment(self)

다음은 세 종류의 대출 모두의 비용을 샘플 매개변수로 계산 후 출력해주는 함수는 함수이다. 각 종류마다 클래스들을 생성한 후, 주어진 햇수로 매달 상환해야 할 금액을 계산한다. 끝으로 각 대출마다 총 상환액을 출력한다. 

# 대출 금액 계산하기
def compareMortgages(amt, years, fixedRate, pts, ptsRate, varRate1, varRate2, varMonths):
    totMonths = years*12
    fixed1 = Fixed(amt, fixedRate, totMonths)
    fixed2 = FixedWithPts(amt, ptsRate, totMonths, pts)
    twoRate = TwoRate(amt, varRate2, totMonths, varRate1, varMonths)
    morts = [fixed1, fixed2, twoRate]
    for m in range(totMonths):
        for mort in morts:
            mort.makePayment()
        for m in morts:
            print(m)
            print('Total payment = $' + str(int(m.getTotalPaid())))

출력 결과

Fixed, 7.000000000000001%
Total payment = $479017
Fixed, 5.0%, 3.25 points
Total payment = $393011
4.5% for 48 months, then 9.5%
Total payment = $551444
728x90
반응형

'파이썬' 카테고리의 다른 글

파이썬 (합병 정렬과 이름 리스트 정렬하기)  (0) 2023.08.28
(파이썬) 점근 표기법  (0) 2023.08.16
(파이썬) Grades 클래스  (0) 2023.08.12
(파이썬) 상속/Inheritance  (0) 2023.08.09
(파이썬) Person 클래스  (0) 2023.08.09
posted by 조이키트 블로그
2023. 8. 12. 12:58 파이썬
728x90
반응형

아래 코드는 여러 학생들의 성적을 관리할 수 있는 클래스이다. 리스트와 딕셔너리를 사용하여 Grades 클래스의 인스턴스들을 구현하였다. 리스트는 수업의 학생들을 관리하고 딕셔너리는 각 학생들의 일련번호를 성적에 연결하고 있다.

getGrades는 한 학생의 성적 리스트를 복사해서 반환하고, getStudents는 학생 리스트를 복사해서 반환하고 있다. 

# Grades 클래스
def Grades(object):
    def __init__(self):
        self.students = []
        self.grades = {}
        self.isSorted = True

def addStudent(self, student):
    if student in self.students:
        raise ValueError('Duplicate student')
    self.students.append(student)
    self.grades[student.getIdNum()] = []
    self.isSorted = False

def addGrade(self, student, grade):
    try:
        self.grade[student.getIdNum()].append(grade)
    except:
        raise ValueError('Student not in mapping')
    
def getGrades(self, student):
    try:
        return self.grades[student.getIdNum()][:]
    except:
        raise ValueError('Student not in mapping')
    
def getStudents(self):
    if not self.isSorted:
        self.students.sort()
        self.isSorted = True
    return self.students[:]

isSorted의 인스턴스 변수는 학생 리스트에서 새로운 학생들이 추가되고 난 이후에 정렬되었는지 아닌지를 알기 위해서 사용된다. 이것을 통해 getStudents가 이미 정렬된 리스트를 또 다시 정렬하지 않도록 도와준다.

728x90
반응형

'파이썬' 카테고리의 다른 글

(파이썬) 점근 표기법  (0) 2023.08.16
(파이썬) 대출 금액 계산 프로그램  (0) 2023.08.12
(파이썬) 상속/Inheritance  (0) 2023.08.09
(파이썬) Person 클래스  (0) 2023.08.09
(파이썬) 추상 데이터 타입과 클래스  (0) 2023.08.07
posted by 조이키트 블로그
2023. 8. 5. 10:22 파이썬
728x90
반응형

 

# 문자 번역하기
EtoF = {'bread':'pain', 'wine':'vin', 'with':'avec', 'I':'Je',
        'eat':'mange', 'drink':'bois', 'John':'Jean',
        'friends':'amis', 'and':'et', 'of':'du', 'red':'rouge'}
FtoE = {'pain':'bread', 'vin':'wine', 'avec':'with', 'Je':'I',
        'mange':'eat', 'bois':'drink', 'Jean':'John',
        'amis':'friends', 'et':'and', 'du':'of', 'rouge':'red'}

dicts = {'English to French' :EtoF, 'French to English':FtoE}

def translateWord(word, dictionary):
    if word in dictionary.keys():
        return dictionary[word]
    elif word !='':
        return '"' + word + '"'
    return word

def translate(phrase, dicts, direction):
    UCLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    LCLetters = 'abcdefghijklmnopqrstuvwxyz'
    letters = UCLetters + LCLetters
    directionay = dicts[direction]
    translation = ''
    word = ''
    for c in phrase:
        if c in letters:
            word = word + c
        else:
             translation = translation + translateWord(word, directionay) + c
             word = ''
    return translation + ' ' + translateWord(word, directionay)

print(translate('I drink good red wine, and eat bread.',dicts, 'English to French'))
print(translate('Je bois du vin rouge.',dicts, 'French to English'))

 

출력 결과

Je bois "good" rouge vin, et mange pain. 
I drink of wine red.

리스트와 같이 딕셔너리에는 많은 유용한 메소드들이 있다. 튜플처럼 변형 불가능한 객체들은 딕셔너리의 키로 사용할 수 있다.

 

딕셔너리에 공통적으로 사용 가능한 연산들

len(d) : d에 들어있는 개수를 반환한다.

d.keys() : d에 들어있는 키들을 리스트로 반환한다.               (python 2.x)

                 d에 들어있는 키들을 dict_keys로 반환한다.         (python 3.x)

d.values() : d에 들어있는  값들을 리스트로 반환한다.            (python 2.x)

                    d에 들어있는 키들을 dict_values로 반환한다.   (python 3.x)

k in d : d에 키 k가 있을 때 True를 반환한다.

d[k] : d에서 키 k와 쌍인 값을 반환한다.

d.get(k, v) : d에 k가 있을 때 d[k]를 반환하며 없을 경우 v를 반환한다.

d[k] = v : d에서 값 v를 키 k와 연결한다. 만약 k에 이미 연결된 값이 있을 경우 그 값을 대체한다.

del d[k] : 키 k를 d에서 제거한다.

for k in d : d에 들어있는 키를 하나씩 돌아가면서 접근한다.

728x90
반응형
posted by 조이키트 블로그
2023. 8. 4. 14:22 파이썬
728x90
반응형

시퀀스 자료형의 공통점과 차이점

seq[i] : 시퀀스에서 i번째 요소를 반환한다.

len(seq) : 시퀀스의 길이를 반환한다.

seq1 + seq2 : 두 시퀀스를 합친것을 반환한다.

n * seq : seq를 n번동안 반복한 시퀀스를 반환한다.

seq[start:end] : 시퀀스의 슬라이스를 반환한다.

e in seq : 시퀀스에 e가 있으면 True를 반환하고 없으면 False를 반환한다.

for e in seq : 시퀀스의 요소들을 하나씩 돌아가면서 접근한다.

 

자료형 구성 요소의 자료형 예시 가변성
str 문자 ' ', 'a', 'abc' 없음
tuple 모든 자료형 ( ), (3, ), ('abc', 4) 없음
list 모든 자료형 [ ], [3], ['abc'],  있음

 

리스트는 변형 가능하기 때문에 계산하면서 점차적으로 리스트를 구성할 수 있다.

다음의 코드는 어떤 리스트에 있는 짝수 값들을 가진 리스트를 점차적으로 만든다.

evenElems = []
for e in L:
    if e%2 == 0:
        evenElems.append(e)

튜플은 불변성이기 때문에 엘리어싱 또한 걱정할 필요가 없다는 장점이 있다. 또한 리스트와 다르게 딕셔너리에서 키로 사용할 수 있다. 

문자열은 문자만 담을 수 있기 때문에 튜플이나 리스트처럼 다양하게 사용하는 것이 제한되어 있다. 반면에 문자열을 사용하다 보면 많은 내장 메소드 때문에 편하게 프로그래밍을 할 수 있다.

728x90
반응형
posted by 조이키트 블로그
2023. 8. 4. 13:57 파이썬
728x90
반응형

파이썬에서 함수는 일급 객체이다. 즉 함수는 int나 list와 같은 모든 자료형들과 같이 객체로 취급할 수 있다는 뜻이다. 함수에도 자료형이 있기 때문에 예를 들어 type (fact)라는 수식을 입력하면 <type 'function'>이라는 결과가 나온다.

# 함수를 리스트의 요소로 사용하기
def applyToEach(L, f):
    for i in range(len(L)):
        L[i] = f(L[i])

def factR(n):
    if n == 1:
        return n
    else:
        return n*factR(n-1)
    
def fib(n):
    if n == 0 or n ==1:
        return 1
    else:
        return fib(n-1) + fib(n-2)

L = [1, -2, 3.33]
print('L =', L)
print('Apply abs to each element of L.')
applyToEach(L, abs) # 절대 값
print('L =', L)
print('Apply int ot each element of', L)
applyToEach(L, int) 
print('L =', L)
print('Apply factorial to each element of', L)
applyToEach(L, factR)
print('L =', L)
print('Apply Fibonnaci to each element of', L)
applyToEach(L, fib)
print('L =', L)

함수 applyToEach는 함수로 된 인자를 가지고 있기 때문에 고차함수라 불린다 . 처음 호출되었을 때 applyToEach는 단항 내장 함수인 abs를 각 요소에 적용하여  리스트 L을 변형시킨다. 두 번째 호출되었을 때는 각 요소를 형식 변환한다. 세번째 호출되었을 때는 각 요소들에 정의된 factR 함수를 적용한다. 네 번째 호출되었을 때는 각 요소들에게 정의된 fib 함수를 적용한다. 

 

출력 결과

L = [1, -2, 3.33]
Apply abs to each element of L.
L = [1, 2, 3.33]
Apply int ot each element of [1, 2, 3.33]
L = [1, 2, 3]
Apply factorial to each element of [1, 2, 3]
L = [1, 2, 6]
Apply Fibonnaci to each element of [1, 2, 6]
L = [1, 2, 13]
728x90
반응형
posted by 조이키트 블로그
2023. 8. 4. 13:57 파이썬
728x90
반응형

파이썬에서 함수는 일급 객체이다. 즉 함수는 int나 list와 같은 모든 자료형들과 같이 객체로 취급할 수 있다는 뜻이다. 함수에도 자료형이 있기 때문에 예를 들어 type (fact)라는 수식을 입력하면 <type 'function'>이라는 결과가 나온다.

# 함수를 리스트의 요소로 사용하기
def applyToEach(L, f):
    for i in range(len(L)):
        L[i] = f(L[i])

def factR(n):
    if n == 1:
        return n
    else:
        return n*factR(n-1)
    
def fib(n):
    if n == 0 or n ==1:
        return 1
    else:
        return fib(n-1) + fib(n-2)

L = [1, -2, 3.33]
print('L =', L)
print('Apply abs to each element of L.')
applyToEach(L, abs) # 절대 값
print('L =', L)
print('Apply int ot each element of', L)
applyToEach(L, int) 
print('L =', L)
print('Apply factorial to each element of', L)
applyToEach(L, factR)
print('L =', L)
print('Apply Fibonnaci to each element of', L)
applyToEach(L, fib)
print('L =', L)

함수 applyToEach는 함수로 된 인자를 가지고 있기 때문에 고차함수라 불린다 . 처음 호출되었을 때 applyToEach는 단항 내장 함수인 abs를 각 요소에 적용하여  리스트 L을 변형시킨다. 두 번째 호출되었을 때는 각 요소를 형식 변환한다. 세번째 호출되었을 때는 각 요소들에 정의된 factR 함수를 적용한다. 네 번째 호출되었을 때는 각 요소들에게 정의된 fib 함수를 적용한다. 

 

출력 결과

L = [1, -2, 3.33]
Apply abs to each element of L.
L = [1, 2, 3.33]
Apply int ot each element of [1, 2, 3.33]
L = [1, 2, 3]
Apply factorial to each element of [1, 2, 3]
L = [1, 2, 6]
Apply Fibonnaci to each element of [1, 2, 6]
L = [1, 2, 13]
728x90
반응형
posted by 조이키트 블로그
2023. 8. 4. 13:53 파이썬
728x90
반응형

파이썬에서 함수는 일급 객체이다. 즉 함수는 int나 list와 같은 모든 자료형들과 같이 객체로 취급할 수 있다는 뜻이다. 함수에도 자료형이 있기 때문에 예를 들어 type (fact)라는 수식을 입력하면 <type 'function'>이라는 결과가 나온다.

# 함수를 리스트의 요소로 사용하기
def applyToEach(L, f):
    for i in range(len(L)):
        L[i] = f(L[i])

def factR(n):
    if n == 1:
        return n
    else:
        return n*factR(n-1)
    
def fib(n):
    if n == 0 or n ==1:
        return 1
    else:
        return fib(n-1) + fib(n-2)

L = [1, -2, 3.33]
print('L =', L)
print('Apply abs to each element of L.')
applyToEach(L, abs) # 절대 값
print('L =', L)
print('Apply int ot each element of', L)
applyToEach(L, int) 
print('L =', L)
print('Apply factorial to each element of', L)
applyToEach(L, factR)
print('L =', L)
print('Apply Fibonnaci to each element of', L)
applyToEach(L, fib)
print('L =', L)

함수 applyToEach는 함수로 된 인자를 가지고 있기 때문에 고차함수라 불린다 . 처음 호출되었을 때 applyToEach는 단항 내장 함수인 abs를 각 요소에 적용하여  리스트 L을 변형시킨다. 두 번째 호출되었을 때는 각 요소를 형식 변환한다. 세번째 호출되었을 때는 각 요소들에 정의된 factR 함수를 적용한다. 네 번째 호출되었을 때는 각 요소들에게 정의된 fib 함수를 적용한다. 

 

출력 결과

L = [1, -2, 3.33]
Apply abs to each element of L.
L = [1, 2, 3.33]
Apply int ot each element of [1, 2, 3.33]
L = [1, 2, 3]
Apply factorial to each element of [1, 2, 3]
L = [1, 2, 6]
Apply Fibonnaci to each element of [1, 2, 6]
L = [1, 2, 13]
728x90
반응형
posted by 조이키트 블로그
2023. 8. 4. 13:03 파이썬
728x90
반응형

리스트 조건 제시법은 시퀀스로 된 값들을 다룰 수 있는 간편한 방법을 제공한다. 새로운 리스트가 생성되고 어떤 시퀀스(예를 들어 또 다른 리스트에 있는 요소들)에 있는 값에 대해 주어진 작업을 수행하고, 그 결과값으로 새로운 리스트를 생성한다.

# 리스트 조건 제시법
L = [x**2 for x in range(1,7)]
print(L)

출력 결과

[1, 4, 9, 16, 25, 36]

리스트 조건 제시법의 for문 뒤에는 하나 이상의 if나 for문로 생성된 값에 적용할 for문이 따라올 수 있다. 이렇게 추가되는 구문들은 첫 번째 for문에서 생성한 일련의 값들을 수정하고 조건 제시법과 연관된 작업을 적용시킨 새로운 일련의 값들을 생성한다.

mixed = [1, 2, 'a', 3, 4.0]
print([x**2 for x in mixed if type(x) == int])

이 코드는 mixed에 있는 리스트를 제곱한 후에[1, 4, 9]를 출력한다.

[1, 4, 9]

 

728x90
반응형
posted by 조이키트 블로그
2023. 8. 4. 12:36 파이썬
728x90
반응형

리스트 조건 제시법은 시퀀스로 된 값들을 다룰 수 있는 간편한 방법을 제공한다. 새로운 리스트가 생성되고 어떤 시퀀스(예를 들어 또 다른 리스트에 있는 요소들)에 있는 값에 대해 주어진 작업을 수행하고, 그 결과값으로 새로운 리스트를 생성한다.

# 리스트 조건 제시법
L = [x**2 for x in range(1,7)]
print(L)

출력 결과

[1, 4, 9, 16, 25, 36]

리스트 조건 제시법의 for문 뒤에는 하나 이상의 if나 for문로 생성된 값에 적용할 for문이 따라올 수 있다. 이렇게 추가되는 구문들은 첫 번째 for문에서 생성한 일련의 값들을 수정하고 조건 제시법과 연관된 작업을 적용시킨 새로운 일련의 값들을 생성한다.

mixed = [1, 2, 'a', 3, 4.0]
print([x**2 for x in mixed if type(x) == int])

이 코드는 mixed에 있는 리스트를 제곱한 후에[1, 4, 9]를 출력한다.

[1, 4, 9]

 

728x90
반응형
posted by 조이키트 블로그
2023. 8. 4. 12:25 파이썬
728x90
반응형

파이썬은 for문에서 반복문이 한 번 돌고 날 때마다 증가되는 내부 카운터를 사용하여 리스트에서 실행되는 지점을 따라가도록 설계되었다. 만약 카운터의 값이 증가하다가 리스트 길이와 같은 값에 도달하면 반복문이 종료된다.

# 복제하기(Cloning)
def removeDups(L1, L2):
    for e1 in L1:
        if e1 in L1:
            L1.remove(e1)

L1 = [1,2,3,4]
L2 = [1,2,4,6]
removeDups(L1, L2)
print('L1 =', L1)

위 예제의 경우 숨겨진 카운터가 0에서 시작하여 L1[0]이 L2에 있다는 것을 발견하고는 리스트에서 제거한다. 그래서 L1의 길이가 3이 된다. 그리고서 카운터는 1 증가하고 L1[1]이 L2에 있는지 확인하게 된다. 하지만 이것은 L1[1]이 원래 가지고 있었던 값(즉 2)가 아니라 2가 제거된 후의 L1[1]의 값, 즉 3이다. 그러므로 보시다시피 리스트가 반복문 안에서 수정된다면 원하는 결과를 얻지 못하게 되는것이다.

 

출력결과

L1 = [2, 4]
728x90
반응형
posted by 조이키트 블로그
2023. 8. 4. 12:06 파이썬
728x90
반응형

파이썬은 for문에서 반복문이 한 번 돌고 날 때마다 증가되는 내부 카운터를 사용하여 리스트에서 실행되는 지점을 따라가도록 설계되었다. 만약 카운터의 값이 증가하다가 리스트 길이와 같은 값에 도달하면 반복문이 종료된다.

# 복제하기(Cloning)
def removeDups(L1, L2):
    for e1 in L1:
        if e1 in L1:
            L1.remove(e1)

L1 = [1,2,3,4]
L2 = [1,2,4,6]
removeDups(L1, L2)
print('L1 =', L1)

위 예제의 경우 숨겨진 카운터가 0에서 시작하여 L1[0]이 L2에 있다는 것을 발견하고는 리스트에서 제거한다. 그래서 L1의 길이가 3이 된다. 그리고서 카운터는 1 증가하고 L1[1]이 L2에 있는지 확인하게 된다. 하지만 이것은 L1[1]이 원래 가지고 있었던 값(즉 2)가 아니라 2가 제거된 후의 L1[1]의 값, 즉 3이다. 그러므로 보시다시피 리스트가 반복문 안에서 수정된다면 원하는 결과를 얻지 못하게 되는것이다.

 

출력결과

L1 = [2, 4]
728x90
반응형
posted by 조이키트 블로그
2023. 8. 4. 10:16 파이썬
728x90
반응형

튜플과 마찬가지로 for문을 사용하여 리스트의 모든 요소를 돌아가며 접근할 수 있다.

# for문을 사용한 리스트와 가변성
Techs = ['MIT', 'Caltech']
Ivys = ['Harvard', 'Yale', 'Brown']

Univs = [Techs, Ivys]
Univs1 = [['MIT', 'Caltech'], ['Harvard', 'Yale', 'Brown']]
Techs.append('RPI')

for e in Univs:
    print('Univs contains', e)
    print('which contains')
    for u in e:
        print(' ', u)

출력 결과

Univs contains ['MIT', 'Caltech', 'RPI']
which contains
  MIT
  Caltech
  RPI
Univs contains ['Harvard', 'Yale', 'Brown']
which contains
  Harvard
  Yale
  Brown

Techs.append(RPI) 명령어처럼 리스트에 또 다른 리스트를 끝에 추가할 떄 추가하는 리스트의 구조는 유지된다. 즉 리스트 형태로 리스트 끝에 삽입되는 것이다. 만약 원래의 리스트 구조를 유지하지 않고 리스트에 있는 요소를 다른 리스트에 삽입하려고 한다면 리스트 합치기나 extend 메소드를 사용하면 된다.

# extend와 append를 사용한 리스트의 접근성
L1 = [1,2,3]
L2 = [4,5,6]
L3 = L1 + L2
print('L3 =', L3)
L1.extend(L2)
print('L1 =', L1)
L1.append(L2)
print('L1 =', L1)

출력 결과

L3 = [1, 2, 3, 4, 5, 6]
L1 = [1, 2, 3, 4, 5, 6]
L1 = [1, 2, 3, 4, 5, 6, [4, 5, 6]]

리스트에 삽입할 때 연산자 +를 사용하거나 extend를 사용한 경우 삽입하려는 값이 리스트 형태로 삽입되지 않고 요소들만 삽입된 것을 볼 수 있다. 출력된 결과를 보면 연산자 +는 새로운 리스트를 생성하고 반환한다. 그와 반대로 extend와 append는 L1을 변형시킨다.

 

※ 리스트에 관한 몇 개의 주요 메소드들

L.append(e) : L의 끝에 객체 e를 추가한다.

L.count(e) : L안에 있는 e의 개수를 반환한다.

L.insert(i, e) : L의 i번째 인덱스에 객체 e를 삽입한다.

L.extend(L1) : L1의 요소들을 L의 끝에 추가한다.

L.remove(e) : L에서 나타나는 첫 번째 e를 삭제한다.

L.index(e) : L에서 나타나는 첫 번째 e의 인덱스를 반환한다. 만약 e가 L에 없는 경우 예외가 발행한다.

L.pop(i) : L의 i번째 인덱스에 있는 값을 반환과 동시에 리스트에서 제거한다. i의 값이 생략된 경우 i는 디폴드 값인 -1가 되며 L의 마지막 요소를 반환하고 리스트에서 제거한다.

L.sort() : L에 있는 요소들을 오름차순으로 정렬한다.

L.reverse() : L에 있는 요소들의 순서를 반대로 배열한다.

728x90
반응형
posted by 조이키트 블로그
2023. 8. 4. 00:50 파이썬
728x90
반응형

튜플과 마찬가지로 리스트 또한 순서가 있는 일련의 값들인데, 인덱스를 사용하여 각 값을 구분한다. list 자료형을 표현하는 문법은 튜플과 매우 비슷하지만 차이점은 소괄호() 대신 대괄호[]를 사용한다는 것이다. 리스트와 튜플에는 매우 중요한 차이점이 하나 있다. 리스트는 변형이 가능한 반면에 튜플과 문자열은 변형이 불가능하다. 변형 불가능한 객체들을 생성하는데 사용할 수 있는 많은 연산자들이 있으며 또한 이러한 자료형을 가진 객체도 변수들과 바인딩한다. 반면에 list 자료형의 객체들은 생성된 이후에 수정이 가능하다.

객체를 변형시키는 것과 변수에 객체를 변수에 대입하는 것의 차이가 처음에는 미묘하게 보일 수 있다. 하지만 파이썬에서 변수는 객체에 붙이는 라벨처럼 이름에 불과하다는 것을 되새긴다면 좀 더 명확하게 이해하는데 도움이 될 것이다.

 

다음 두 줄의 서술문이 실행된다고 가정하면 인터프리터는 두 개의 새로운 리스트를 생성하고 Techs는 ['MIT', 'Caltech'], Ivys는 ['Harvard', 'Yale', 'Brown']에 바인딩한다.

# 리스트와 가변성
Techs = ['MIT', 'Caltech']
Ivys = ['Harvard', 'Yale', 'Brown']

다음의 대입문을 보면 새로운 리스트를 생성하고 변수와 바인딩한다. 

Univs = [Techs, Ivys]
Univs1 = [['MIT', 'Caltech'], ['Harvard', 'Yale', 'Brown']]

출력 결과는 다음과 같다.

print('Univs = ', Univs)
print('Univs1 = ', Univs1)
print(Univs == Univs1) # test value equality
Univs =  [['MIT', 'Caltech'], ['Harvard', 'Yale', 'Brown']]
Univs1 =  [['MIT', 'Caltech'], ['Harvard', 'Yale', 'Brown']]
True

출력 결과를 보면 보기에는 Univs와 Univs1이 마치 같은 값에 바인딩된 것처럼 보이지만 매우 다른 값에 바인딩되어 있다.

Univs와 Univs1가 다른 값에 바인딩되어 있는 것은 파이썬 내장 함수 id를 사용하여 증명할 수 있다. id는 각 객체의 고유한 정수 식별자를 반환하여 두 객체가 동일한지 검사할 때 사용할 수 있다.

print(Univs == Univs1) # test value equality
print(id(Univs) == id(Univs1)) # test object equality
print('Id of Univs =', id(Univs))
print('Id of Univs1 =', id(Univs1))

출력 결과는 다음과 같다.

True
False
Id of Univs = 4364976768
Id of Univs1 = 4364976960

위의 그림을 보면 Univs의 요소들은 Techs와 Ivys가 바인딩된 리스트가 복제된것이이 아니며 또 하나의 리스트이다. Univs1의 요소들은 Univs와 같은 요소들을 담고 있는 리스트이지만 Univs와는 다른 개별적인 리스트이다. 다음의 코크를 실행해보면 더 잘 알 수 있다.

print('Ids of Univs[0] and Univs[1]', id(Univs[0]), id(Univs[1]))
print('Ids of Univs1[0] and Univs1[1]', id(Univs1[0]), id(Univs1[1]))

출력 결과는 다음과 같다.

Id of Univs1 = 4364976960
Ids of Univs[0] and Univs[1] 4364784896 4364884672
Ids of Univs1[0] and Univs1[1] 4364785024 4364976832

이것이 뭐가 그렇게 중요할지는 모르지만 리스트가 변형 가능하기 때문에 중요하다.

Techs.append('RPI')

append 메소드는 새로운 리스트를 생성하지 않고, 이미 존재하고 있는 리스트 Techs에 문자열 'RPI'로 된 새로운 요소를 맨 끝에 집어 넣어서 리스트를 변형시킨다.

Univs는 아직도 같은 두 개의 리스트를 가지고 있지만 그 중 하나의 리스트는 값이 바뀌었다.

따라서 다음의 print문을 수행하면 다음과 같이 출력한다.

Techs = ['MIT', 'Caltech']
Ivys = ['Harvard', 'Yale', 'Brown']

Univs = [Techs, Ivys]
Univs1 = [['MIT', 'Caltech'], ['Harvard', 'Yale', 'Brown']]
Techs.append('RPI')

print('Univs = ', Univs)
print('Univs1 = ', Univs1)

출력결과

Univs =  [['MIT', 'Caltech', 'RPI'], ['Harvard', 'Yale', 'Brown']]
Univs1 =  [['MIT', 'Caltech'], ['Harvard', 'Yale', 'Brown']]

이것을 엘리어싱이라고 부른다. 한 개의 같은 리스트 객체에 두 개의 개별적인 경로가 있는 것이다. 첫 번째 경로는 변수 Techs를 통하여 또 다른 경로는 Univs에 바인딩된 list 객체의 첫 번째 요소를 통한다. 두 경로 중 어느것이든 사용하여 객체를 변형시킬 수가 있으며, 두 경로 모두를 통해서 변형된 효과를 볼 수 있다.

728x90
반응형
posted by 조이키트 블로그
2023. 8. 3. 22:47 파이썬
728x90
반응형

튜플은 문자열과 같이 일련의 요소들이 순서대로 나열된 것이다. 튜플과 문자열의 차이점은 튜플의 요소들은 문자가 아니어도 된다는 것이다. 어떤 자료형도 튜플의 요소가 될 수 있으며 일련의 요소들이 다 같은 자료형이 아니어도 된다.

튜플의 상수는 갈호 안에 쉼표로 나누어진 리스트를 써서 표현한다. 튜플은 문자열과 같이 합치기, 인덱스, 슬라이스를 적용할 수 있다.

for문을 사용하면 튜플의 요소들을 돌아가면서 한 개씩 접근할 수 있다.

# 20과 100의 공통분모를 출력한 후에 구한 모든 공통분모의 합을 출력
def findDivisors (n1, n2):
    divisors = () #the empty tuple
    for i in range(1, min(n1, n2) + 1):
        if n1%i == 0 and n2%i == 0:
            divisors = divisors + (i,)
    return divisors


divisors = findDivisors(20, 100)
print('20과 100의 공통분모 : ', divisors)
total = 0
for d in divisors:
    total += d
print('공통분모의 합 : ', total)

출력결과

20과 100의 공통분모 :  (1, 2, 4, 5, 10, 20)
공통분모의 합 :  42
728x90
반응형
posted by 조이키트 블로그
2023. 8. 2. 15:50 파이썬
728x90
반응형

모듈이란 파이썬 정의들과 서술문들을 담고 있는 .py 파일이다. 예를 들어 다음의 코드를 담고 있는 circle.py 파일을 생성한다.

pi = 3.14159

def area(radius):
    return pi*(radius**2)

def circumference(radius):
    return 2*pi*radius

def sphereSurface(radius):
    return 4.0*area(radius)

def sphereVolueme(radius):
    return (4.0/3.0*pi*(radius**3))

print('원의 넓이 : ', area(3))
print('원의 둘레 : ', circumference(3))
print('구의 겉넓이 : ', sphereSurface(3))
print('구의 부피 : ', sphereVolueme(3))

위 프로그램을 출력하면 다음과 같은 결과가 나온다.

출력결과

원의 넓이 :  28.27431
원의 둘레 :  18.849539999999998
구의 겉넓이 :  113.09724
구의 부피 :  113.09723999999999

다음 다른 프로그램에서 import문을 통해서 모듈에 접근할 수 있다.

프로그램 파일을 하나 만들고 import 문을 사용하여 위의 함수들을 호출하는 코딩을 만든다. 

import circle

print(circle.pi)
print(circle.area(3))
print(circle.circumference(3))
print(circle.sphereSurface(3))
print(circle.sphereVolueme(3))

그러면 다음과 같이 출력 결과가 나온다. 

원의 넓이 :  28.27431
원의 둘레 :  18.849539999999998
구의 겉넓이 :  113.09724
구의 부피 :  113.09723999999999
3.14159
28.27431
18.849539999999998
113.09724
113.09723999999999

위의 출력 결과에서 본것처럼 import circle을 호출할 경우 circle.py에 있는 출력결과가 나오고, 또한 파일안에 정의한 개별 함수도 호출된것을 볼 수 있다.  import M을 수행하면 모듈 M을 자기 영역에 바인딩하여 그 내용을 모두 가져온다. 그러므로 import를 할 때에는 점 표기법을 사용하여 어떤 모듈에 정의된 이름을 사용할 것인지 명시해주어야 한다. 예를 들어 circle.py 파일 밖에서 pi와 circle.pi는 두 개의 다른 객체일 수 있는 것이다.

 

프로그램을 import 할 때 모듈 이름을 생략하고 모듈 안에 정의된 이름을 접근할 수 있는 방법이 있다. 서술문 from M import*을 사용하면 사용 중인 영역에서 M에 정의된 모든 객체들을 바인딩하게 된다. 

from circle import *
print(pi)
print(area(3))

 

출력결과

원의 넓이 :  28.27431
원의 둘레 :  18.849539999999998
구의 겉넓이 :  113.09724
구의 부피 :  113.09723999999999
3.14159
28.27431
728x90
반응형
posted by 조이키트 블로그
2023. 8. 2. 15:18 파이썬
728x90
반응형

각 함수 안에 있는 global numFibCalls는 파이썬에게 numFibCalls가 모듈의 가장 바깥 영역에 정의되어야 함을 알려준다. 만약 global numFibCalls라는 코드가 없다면, 두 함수 모두에서 numFibCalls는 지역변수가 되었을 것이다. fib와 testFib 함수에서 numFibCalls가 참조하는 어떤 객체든지 아무런 제한없이 접근할 수 있다. testFib는 호출될 때마다 numFibCalls를 0에 바인딩하며, fib은 실행될 때마다 numFibCalls의 값을 1씩 증가시킨다.

# 전역 변수의 사용
def fib(x):
    global numFibCalls
    numFibCalls += 1
    if x == 0 or x == 1:
        return 1
    else: 
        return fib(x-1) + fib(x-2)
    
def testFib(n):
    for i in range(n+1):
        global numFibCalls
        numFibCalls = 0
        print('fib of', i, '=', fib(i))
        print('fib called', numFibCalls, 'times.')

print('testFib :', testFib(5))

 

출력결과

fib of 0 = 1
fib called 1 times.
fib of 1 = 1
fib called 1 times.
fib of 2 = 2
fib called 3 times.
fib of 3 = 3
fib called 5 times.
fib of 4 = 5
fib called 9 times.
fib of 5 = 8
fib called 15 times.
testFib : None
728x90
반응형
posted by 조이키트 블로그
2023. 8. 2. 14:03 파이썬
728x90
반응형

각 함수 안에 있는 global numFibCalls는 파이썬에게 numFibCalls가 모듈의 가장 바깥 영역에 정의되어야 함을 알려준다.

만약 global numFibCalls라는 코드가 없다면, 두 함수 모두에서 numFibCalls는 지역변수가 되었을 것이다.

fib와 testFib 함수에서 numFibCalls가 참조하는 어떤 객체든지 아무런 제한없이 접근할 수 있다.

testFib는 호출될 때마다 numFibCalls를 0에 바인딩하며, fib은 실행될 때마다 numFibCalls의 값을 1씩 증가시킨다.

# 전역 변수의 사용
def fib(x):
    global numFibCalls
    numFibCalls += 1
    if x == 0 or x == 1:
        return 1
    else: 
        return fib(x-1) + fib(x-2)
    
def testFib(n):
    for i in range(n+1):
        global numFibCalls
        numFibCalls = 0
        print('fib of', i, '=', fib(i))
        print('fib called', numFibCalls, 'times.')

print('testFib :', testFib(5))

 

출력결과

fib of 0 = 1
fib called 1 times.
fib of 1 = 1
fib called 1 times.
fib of 2 = 2
fib called 3 times.
fib of 3 = 3
fib called 5 times.
fib of 4 = 5
fib called 9 times.
fib of 5 = 8
fib called 15 times.
testFib : None
728x90
반응형
posted by 조이키트 블로그
prev 1 2 next