2015년 2학기 공업수학 중간고사 시험지

이름:

학번:

시험지 작성 요령

  • 예제코드를 보면서 문제의 내용을 이해하도록 노력한다.
  • 문제별로 '해야 할 일' 에서 요구하는 방향으로 변경된 코드의 빈자리를 채우거나 답을 한다.

문제 1

세 개의 숫자를 입력받는 함수 interval_point는 아래 기능을 구현한다.

숫자 ab는 구간의 처음과 끝을 나타낸다. 숫자 x01 사이의 값이다. 그러면 interval_point(a, b, x)a에서 출발하여 x비율만큼 b 방향으로 이동할 때 갈 수 있는 위치를 되돌려준다.

interval_point 함수를 다음과 같이 정의할 수 있다.


In [1]:
def interval_point(a, b, x):
    if a < b:
        return (b-a)*x + a
    else:
        return a - (a-b)*x

활용 예제


In [2]:
interval_point(0, 1, 0.5)


Out[2]:
0.5

In [3]:
interval_point(3, 2, 0.2)


Out[3]:
2.8
해야 할 일 1 (5점)

위 코드를 if 조건문을 사용하지 않도록 수정하고자 한다. 아래 코드의 빈칸 (A)를 채워라.

def interval_point_no_if(a, b, x):
    return (A)

문제 2

아래 코드는 오류가 발생할 경우를 대비하여 예외처리를 사용한 코드이다.


In [4]:
while True:
    try:
        x = float(raw_input("Please type a new number: "))
        inverse = 1.0 / x
        print("The inverse of {} is {}.".format(x, inverse))
        break
    except ValueError:
        print("You should have given either an int or a float")
    except ZeroDivisionError:
        print("The input number is {} which cannot be inversed.".format(int(x)))


Please type a new number: 3
The inverse of 3.0 is 0.333333333333.
해야 할 일 2 (10점)

아래 코드가 하는 일을 설명하고 발생할 수 있는 예외들을 나열하며, 예외처리를 어떻게 하는지 설명하라.

문제 3

콤마(',')로 구분된 문자들이 저장되어 있는 파일을 csv(comma separated value) 파일이라 부른다. 숫자들로만 구성된 csv 파일을 인자로 받아서 각 줄별로 포함된 숫자들과 숫자들의 합을 계산하여 보여주는 함수 print_line_sum_of_file과 관련된 문제이다.

예를 들어 test.txt 파일에 아래 내용이 들어 있다고 가정하면 아래의 결과가 나와야 한다.

1,3,5,8
0,4,7
1,18

In [1]: print_line_sum_of_file("test.txt")
out[1]: 1 + 3 + 5 + 8 = 17
        0 + 4 + 7 = 11
        1 + 18 = 19

text.txt 파일을 생성하는 방법은 다음과 같다.


In [5]:
f = open("test.txt", 'w')
f.write("1,3,5,8\n0,4,7\n1,18")
f.close()

또한 print_line_sum_of_file을 예를 들어 다음과 같이 작성할 수 있다.


In [6]:
def print_line_sum_of_file(filename):
    g = open("test.txt", 'r')
    h = g.readlines()
    g.close()
    
    for line in h:
        sum = 0
        k = line.strip().split(',')
        for i in range(len(k)):
            if i < len(k) -1:
                print(k[i] + " +"),
            else:
                print(k[i] + " ="),
            sum = sum + int(k[i])
        print(sum)

위 함수를 이전에 작성한 예제 파일에 적용하면 예상된 결과과 나온다.


In [7]:
print_line_sum_of_file("test.txt")


1 + 3 + 5 + 8 = 17
0 + 4 + 7 = 11
1 + 18 = 19
해야 할 일 3 (5점)

그런데 위와 같이 정의하면 숫자가 아닌 문자열이 포함되어 있을 경우 ValueError가 발생한다. ValuError가 어디에서 발생하는지 답하라.

해야 할 일 4 (10점)

이제 데이터 파일에 숫자가 아닌 문자열이 포함되어 있을 경우도 다룰 수 있도록 print_line_sum_of_file를 수정해야 한다. 예를 들어 숫자가 아닌 문자가 포함되어 있는 단어가 있을 경우 단어의 길이를 덧셈에 추가하도록 해보자.

예제:

test.txt 파일에 아래 내용이 들어 있다고 가정하면 아래 결과가 나와야 한다.

1,3,5,8
1,cat4,7
co2ffee


In [1]: print_line_sum_of_file("test.txt")
out[1]: 1 + 3 + 5 + 8 = 17
        1 + cat4 + 7 = 12
        co2ffee = 7

예를 들어 다음과 같이 수정할 수 있다. 빈 칸 (A)와 (B)를 채워라.

f = open("test.txt", 'w')
f.write("1,3,5,8\n1,cat4,7\nco2ffee")
f.close()

def print_line_sum_of_file(filename):
    g = open("test.txt", 'r')
    h = g.readlines()
    g.close()

    for line in h:
        sum = 0
        k = line.strip().split(',')
        for i in range(len(k)):
            if i < len(k) - 1:
                print(k[i] + " +"),
            else:
                print(k[i] + " ="),
            try:
                (A)
            except ValueError:
                (B)
        print(sum)

문제 4

함수를 리턴값으로 갖는 고계함수(higer-order function)를 다루는 문제이다.

먼저 다음의 함수들을 살펴보자.


In [8]:
def linear_1(a, b):
    return a + b

def linear_2(a, b):
    return a * 2 + b

동일한 방식을 반복하면 임의의 자연수 n에 대해 linear_n 함수를 정의할 수 있다. 즉,

linear_n(a, b) = a * n + b

이 만족되는 함수를 무한히 많이 만들 수 있다. 그런데 그런 함수들을 위와같은 방식으로 정의하는 것은 매우 비효율적이다. 한 가지 대안은 변수를 하나 더 추가하는 것이다.


In [9]:
def linear_gen(n, a, b):
    return a * n + b

위와 같이 linear_gen 함수를 정의한 다음에 특정 n에 대해 linear_n 이 필요하다면 아래와 같이 간단하게 정의해서 사용할 수 있다.

예를 들어 n = 10인 경우이다.


In [10]:
def linear_10(a, b):
    return linear_gen(10, a, b)
해야 할 일 5 (10점)

그런데 이 방식은 특정 linear_n을 사용하고자 할 때마다 def 키워드를 이용하여 함수를 정의해야 하는 단점이 있다. 그런데 고계함수를 활용하면 def 키워드를 한 번만 사용해도 모든 수 n에 대해 linear_n 함수를 필요할 때마다 사용할 수 있다.

예를 들어 아래 등식이 만족시키는 고계함수 linear_high를 정의할 수 있다.

linear_10(3, 5) = linear_high(10)(3, 5)
linear_15(2, 7) = linear_high(15)(2, 7)

아래 코드가 위 등식을 만족시키도록 빈자리 (A)와 (B)를 채워라.

def linear_high(n):
    def linear_n(a, b):
        (A)
    return (B)

문제 5

이름이 없는 무명함수를 다루는 문제이다.

무명함수는 간단하게 정의할 수 있는 함수를 한 번만 사용하고자 할 경우에 굳이 함수 이름이 필요없다고 판단되면 사용할 수 있다. 예를 들어 앞서 linear_high 함수를 정의할 때 사용된 linear_n 함수의 경우가 그렇다.

  • linear_n 함수는 linear_high 함수가 호출될 때만 의미를 갖는 함수이며 그 이외에는 존재하지 않는 함수가 된다.

따라서 그냥 linear_n 함수를 물어보면 파이썬 해석기가 전혀 알지 못하며 NameError가 발생한다.

해야 할 일 6 (5점)

linear_n 함수의 정의가 매우 단순하다. 따라서 굳이 이름을 줄 필요가 없이 람다(lambda) 기호를 이용하여 함수를 정의하면 편리하다. 문제 4에서 linear_high 함수와 동일한 기능을 수행하는 함수 linear_high_lambda 함수를 아래와 같이 정의하고자 한다. 빈 칸 (A)를 채워라.

def linear_high_lambda(n):
    return (A)

문제 6

문자열로 구성된 리스트 names가 있다.


In [11]:
names = ["Koh", "Kang", "Park", "Kwon", "Lee", "Yi", "Kim", "Jin"]

K로 시작하는 이름으로만 구성된 리스트는 파이썬 내장함수 filter를 이용하여 만들 수 있다.


In [12]:
def StartsWithK(s):
    return s[0] == 'K'
K_names = filter(StartsWithK, names)
K_names


Out[12]:
['Koh', 'Kang', 'Kwon', 'Kim']
해야 할 일 7 (15점)

filter 함수를 사용하지 않으면서 동일한 기능을 수행하는 코드를 작성하고자 하면 다음과 같이 할 수 있다. 빈칸 (A), (B), (C)를 채워라.

K_names = []
for name in names:
    if (A) : 
        (B)
    else:
        (C)
해야 할 일 8 (5점)

K로 시작하는 이름만으로 구성된 리스트를 글자 순서의 역순으로 정렬하고자 한다. 아래 코드가 리스트 관련 특정 메소드를 사용하도록 빈 자리 (D)를 채워라.

K_names.(D)

문제 7

파이썬 내장함수 map의 기능은 아래 예제에서 확인할 수 있다.


In [13]:
map(lambda x : x ** 2, range(5))


Out[13]:
[0, 1, 4, 9, 16]

map 함수를 사용하지 않는 방식은 다음과 같다.


In [14]:
def list_square(num):
    L = []
    for i in range(num):
        L.append(i ** 2)
    return L
list_square(5)


Out[14]:
[0, 1, 4, 9, 16]
해야 할 일 9 (10점)

list_square 함수와 동일한 기능을 수행하는 함수 list_square_comp 함수를 리스트 조건제시법을 활용하여 아래처럼 구현하고자 한다. 빈자리 (A)를 채워라.

def list_square_comp(num):
    return (A)

문제 8

다섯 개의 도시명과 각 도시의 인구수로 이루어진 두 개의 리스트가 아래처럼 있다.


In [15]:
cities = ['A', 'B', 'C', 'D', 'E']
populations = [20, 30, 140, 80, 25]

도시이름과 인구수를 쌍으로 갖는 리스트를 구현하는 방법은 아래와 같다.


In [16]:
city_pop = []
for i in range(len(cities)):
    city_pop.append((cities[i], populations[i]))
city_pop


Out[16]:
[('A', 20), ('B', 30), ('C', 140), ('D', 80), ('E', 25)]

city_pop를 이용하여 예를 들어 C 도시의 인구수를 확인하는 방법은 다음과 같다.


In [17]:
city_pop[2][1]


Out[17]:
140
해야 할 일 10 (15점)

그런데 위와같은 코딩은 사용하기에 매우 불편하다. 그래서 아래와 같은 기능을 수행하는 함수 show_city_pop 함수를 구현하고자 한다.

show_city_pop("B") = 30
show_city_pop("E") = 25

아래 코드의 빈자리 (A)를 완성하라.

def show_pop_city(s):

(A)


.
해야할 일 11 (10점)

도시이름을 키(key)로, 인구수를 키값(key value)로 사용하는 사전(해시 테이블) 자료형인 city_pop_hash를 구현할 수 있다. 즉, 다음이 성립해야 한다.

city_pop_hash = {'A': 20, 'B': 30, 'C': 140, 'D': 80, 'E': 25}

그러면 아래 등식이 성립한다.

city_pop_hash["B"] = 30
city_pop_hash["E"] = 25

city_pop_hash 사전을 구현하는 코드를 작성하라.