336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

try-except 구문 추가

피보나치수열이란?

https://ko.wikipedia.org/wiki/피보나치_수 

를 참고하길 바란다.


 


위 정의를 가지고 해당 과제를 풀이하면,


f(n) 의 n = 0 이라면 0, n = 1 이라면 1, 이후는 f(n) = f(n-1) + f(n-2) 로 정의된다.


그렇다면 코드로 옮기기 위해서는 초기 값인 n = 0 과 n = 1 를 사용하여 코드를 작성하면 된다.


입력으로 f(n)에 필요한 n 이 음이 아닌 정수일 경우 코드를 작성해본다.


작성의 형태로 

1. 반복문을 이용하는 방법

2. 리스트를 이용하는 방법

3. 함수를 이용하는 방법

4. 행렬을 이용하는 방법

.. 생각나는 건 이정도가 생각나는데


여기서는 1,2,3 의 방법까지만 사용하겠다.


4번은 한 번 생각해보는 것을 추천한다.


1. 반복문을 이용하는 방법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
n_want = input() # n을 입력받음
#n_want = int(raw_input()) 도 가능.
 
n_2 = 0 # f(n-2)를 의미, 초기값 f(0) = 0
n_1 = 1 # f(n-1)를 의미, 초기값 f(1) = 1
n_0 = 0 # f(n)를 의미, 초기값으로 값을 주지 않음. while loop에서 계산
 
if(n_want == 0): # case ; f(0)
    print n_2
elif(n_want == 1): # case ; f(1)
    print n_1
else# case ; f(n), n > 1
    step = 2
    while(True):
        n_0 = n_1 + n_2 # f(n)을 계산한다.
 
        if(step == n_want): # step이 n이 되었을 경우, 원하는 n값이 되었으므로 출력
            print n_0 # 현재 f(n) 값을 출력한다.
            break
        else# step이 n 이 아닐 경우 n_want 값보다 작으므로 다음 step.
            step += 1  # step은 n을 의미
            n_2 = n_1  # n-2 ; 현재값, 이전 값 갱신
            n_1 = n_0  # n-1 ; 현재값, 이전 값 갱신
cs

위와 같이 작성하는 방법도 있고, 여러가지 방법으로 작성하는 방법이 있으니 위 코드는 예시일뿐 다 다른 방식으로 작성될 수 있다.

n_want ; 구하고 싶은 n값을 입력받는 변수.

n_2 ; f(n-2)를 의미하는 변수, 초기값으로 0을 가진다. f(0) = 0

n_1 ; f(n-1)를 의미하는 변수, 초기값으로 1을 가진다. f(1) = 1

n_0 ; f(n)을 의미하는 변수, 초기값으로 0을 가지지만 의미없는 값이며, if-elif-else 구문에서 else: 내부에 while loop로 값을 계산하기에 의미없는 값을 부여한다.

step ; 현재 f(n)에 n이 몇번째 값인지 알기 위한 변수이며, n_want와 동일해지면 값을 while loop에서 계산을 하였으므로 출력한다.


더 코드를 간결하게 작성한다면, 아래와 같을 수도 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 처음 n을 구하는 값을 0부터 시작하는 값이 아닌 n-2, n-1로 구성하여
# n값이 0부터 계산되어 질 수 있게 한다.
n_want = input()
n_2 = -1 # f(-2)
n_1 = 1  # f(-1)
n_0 = 0  # f(n), n>=0
 
step = 0
while(True):
    n_0 = n_1 + n_2
    if(step == n_want):
        print n_0
        break
    step += 1
    n_2 = n_1
    n_1 = n_0
 
cs


위 방법에서는 처음 f(n)을 구할 때 값을 구해놓은 상태로 if-elif-else 문을 통하여 0, 1 번째 값을 출력하였지만, 규칙을 이용하여 n_0 변수가 음이 아닌 정수의 값을 가질 때부터 구할 수 있게 하였다.


1
2
3
4
5
6
7
8
9
10
11
n_want = input()
n_2, n_1 = -11
n_0 = 0
 
step = 0
while(step <= n_want):
    n_0 = n_1 + n_2
    print step, n_0
    step += 1
    n_2, n_1 = n_1, n_0
print n_0
cs


동일한 방법이지만, 초기값을 선언할 때 python 에서는 저런 형태의 초깃값 선언을 할 수 있으므로 python doc을 참고하고 사용하길 바란다.

 

2. 리스트를 이용하는 방법


위와 구현하는 생각은 동일하다. 하지만 list의 성질을 이용하여 아래와 같이 코드를 작성할 수 있다. 

1
2
3
4
5
6
kth = input()
fibo = [0,1# 초깃값
while(len(fibo)-1 < kth): # 피보나치수를 계산
    fibo.append(fibo[len(fibo)-1+ fibo[len(fibo)-2])
print (fibo[kth]) # 피보나치 수를 출력
 
cs


kth ; k번째 피보나치를 수를 구하기 위한 입력으로 받는다.

fibo ; list형으로 초기값으로 fibo[0] 으로 0 , fibo[1] 으로 1을 넣어 초기값을 결정해둔다.

fibo.append(variable) ; 이 내용은 아래 doc을 참고하길 바란다.

https://docs.python.org/2/tutorial/datastructures.html

 

3. 함수를 이용하는 방법

1
2
3
4
5
6
7
8
9
10
def fibo_fn(n):
    fibo = [01]
    while (len(fibo) - 1 < n):
        fibo.append(fibo[len(fibo) - 1+ fibo[len(fibo) - 2])
    return fibo[n]
 
# main code
nth = input()
print (fibo_fn(nth))
 
cs


위와 같이 함수를 

def fibo_fn(n): 으로 선언 및 정의를 한다. 함수의 정의로는 아래 doc을 참고하길 바란다.

https://docs.python.org/2/tutorial/controlflow.html#defining-functions


1
2
3
4
5
6
7
8
9
10
11
12
def fibo_fn(n):
    if(n==0):
        return 0
    elif(n==1):
        return 1
    elif(n>1):
        return fibo_fn(n-2+ fibo_fn(n-1)
 
# main code
nth = input()
print (fibo_fn(nth))
 
cs
함수를 사용하여 재귀함수로 작성할 수도 있다. 하지만 입력의 nth 값이 커진다면, runtime 에러를 받을 수 있다. 이에 대해 궁금하다면 아래 링크를 참고하길 바란다.

 

try-except

try-except 아래 doc참고 

https://docs.python.org/2/tutorial/errors.html


try-except 구문은 에러에 대한 예외처리를 하기 위한 구문이다. 
예시로 
1
2
3
4
5
6
7
integer = 2
string = 'string'
 
try:
    print integer+string ##error
except:
    print '<except> error'
cs


위와 같은 코드를 작성했을 때, try-except 구문에서 에러를 처리할 수 있다. 

1
print str(integer)+string
cs

5번째 줄에 작성된 코드를 위와 같이 수정하면 에러가 생기지 않는다. 이런 경우를 처리하고자 try-except 구문을 사용할 수 있다. 


위 피보나치의 문제의 입력으로 음이 아닌 정수를 입력받았을 때를 try-except로 처리도 가능하다.

1. 잘못 입력되었을 경우, 잘못된 입력임을 보여주고 프로그램 종료하는 경우.

2. 잘못 입력되었을 경우, 옳은 값을 입력받을 때까지 계속적인 값을 입력받은 경우.


우선 1의 경우를 구현해보면 

1
2
3
4
5
6
7
8
9
10
11
12
13
def fibo_fn(n):
    fibo = [01]
    while (len(fibo) - 1 < n):
        fibo.append(fibo[len(fibo) - 1+ fibo[len(fibo) - 2])
    return fibo[n]
 
# main code
try:
    nth = input() # error check
    print (fibo_fn(nth))
except:
    print 'incorrect input'
 
cs


잘못된 입력값을 받았을 경우 체크를 한 후 except 문을 실행한다. 

하지만 위 경우에서는 음의 아닌 정수가 아닌, 모든 정수를 입력받아도 허용이 되므로, 음의 정수를 입력받으면 에러를 발생시키는 코드를 작성해본다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def fibo_fn(n):
    fibo = [01]
    while (len(fibo) - 1 < n):
        fibo.append(fibo[len(fibo) - 1+ fibo[len(fibo) - 2])
    return fibo[n]
 
# main code
try:
    nth = input() # error check
############ add code #############
    if(nth < 0):
        error # 이 경우 강제로 에러를 발생시킨다.
############ add code #############
    print (fibo_fn(nth))
except:
    print 'incorrect input'
cs


위와 같이 nth이 음이 아닌 정수를 입력을 받았을 경우에 강제로 error를 발생시킴으로 except 문으로 넘어갈 수 있다.


2. 잘못 입력되었을 경우,

    옳은 값을 입력받을 때까지 계속적인 값을 입력받은 경우.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def fibo_fn(n):
    fibo = [01]
    while (len(fibo) - 1 < n):
        fibo.append(fibo[len(fibo) - 1+ fibo[len(fibo) - 2])
    return fibo[n]
 
# main code
while(True):
    try:
        nth = input() # error check
 
        if(nth < 0):
            error # 이 경우 강제로 에러를 발생시킨다.
 
        print (fibo_fn(nth))
        break
    except:
        print 'incorrect input'
cs


while loop를 무한 반복문으로 설정(while(True):) 한후 내부에서 try-except 문을 작성하면 된다. 

정상적으로 된 경우 try: 의 모든 줄을 수행한 후 마지막 break 문으로 무한 루프를 빠져나가게 된다. 


그리고 try-except 문 내부에 여러 에러가 동시에 있을 경우에 except문을 분기시켜 실행할 수 있다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
try:
    print("try")
    #print(2/'string') # typeerror
    #print(2 / 0) # ZeroDivision Error
    #print(2 / b) # Type Error
except ZeroDivisionError: # 0으로 나누는 경우가 있을 경우에 해당 except문을 실행한다.
    print "ZeroDivision Error"
except NameError: # 선언되지 않은 변수, 함수등 을 사용하는 경우 except
    print "Name Error"
except TypeError: # 타입이 맞지 않는 경우, except 
    print "Type Error"
else# 정상적으로 try clause가 실행될 경우, else 
    print "try clause + add Code"
//....source
cs


try구문 내부에 여러가지 에러를 삽입해보았다. 

만약 try구문 내부에서

ZeroDivisionError 가 발생하게 되면, except ZeroDivisionError: 로 이동하게 되고 해당 except 구문의 코드를 실행한 후 14번째 코드를 실행하게 된다.

NameError의 경우 에는 8번째 줄의 except 문을 실행하고, 14번 줄로 이동하여 코드를 실행한다.

TypeError의 경우 10번째 줄을 실행하고, 14번 줄로 이동하여 코드를 실행한다.


try 구문이 올바른 구문이라면 else: 문으로 이동하여 코드를 실행하게 된다. 


그리고 다음 줄에 있는 코드들을 실행하게 된다.


만약 위에 명시한 에러를 제외하고 모든 에러를 처리하려면 except: 를 추가하면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
try:
    print "try"
    #print(2/'string') # typeerror
    L = []
    print L[4# indexError
    #print(2 / 0) # ZeroDivision Error
    #print(2 / b) # Type Error
except ZeroDivisionError:
    print "ZeroDivision Error"
except NameError:
    print "Name Error"
except TypeError:
    print "Type Error"
except: ### add, other error
    print "Other Error"
else:
    print "try clause + add Code"
cs


이해를 돕고자 아래 그림을 첨부한다. 





try-except 구문을 BOJ에 있는 A+B-4 적용하여 풀어볼 수 있다.

https://www.acmicpc.net/problem/10951

End try-except


+ Recent posts