Auspice by Goorm, Manage by DAVIAN @ KAIST

과제 1. 나만의 python & 알고리즘 함수 만들기

1. 파이썬 내장함수 만들기

Python에는 사용자의 편의를 위해서 여러가지 함수를 내장하고 있다. 다음 사진이 python 내장함수의 목록을 보여준다.

자세한 내용은 링크에서 확인해 볼 수 있으며, 문서 안에서 몇 가지 예시를 제시하고 있다. 다음은 python 공식 문서에서 제시하는 all 함수의 예시를 my_all 함수로 재작성한 예시이다.

def my_all(iterable):
    for element in iterable:
        if not element:
            return False
    return True

test1 = [True, 7 == 4, 3 > 7, False]
test2 = [3 < 5, 10 == 10, True, 'something']

# Assert 문은 이하의 식의 참인지 검사합니다.
assert all(test1) == my_all(test1) == False
assert all(test2) == my_all(test2) == True

print("통과")
통과

아래의 함수들은 자주 사용되는 내장 함수들의 목록이다. 위의 코드 예시와 같이 몇 가지 함수들을 내장 함수를 쓰지 않고 따라 만들어보자.
(단, 편의를 위해 엄격하게 만들지 않고 test를 통과할 정도만 작성하여도 무방하다.)

1-1. abs

def my_abs(number):
    number = number ** 2
    number = number ** 0.5
    return number

test1 = 1.7
test2 = -8
assert abs(test1) == my_abs(test1)
assert abs(test2) == my_abs(test2)
print("통과")
통과

1-2. round

import math

def my_round(number, ndgits=None):
    number = str(number)
    number = number.split('.')
    decimal_num = int(number[0])
    float_num = int(number[1])
    
    if not ndgits:
        if int(str(float_num)[0]) > 5:
            return decimal_num + 1
    elif ndgits:
        if int(str(float_num)[ndgits]) > 5:
            ans = str(decimal_num),'.',str(int(str(float_num)[:ndgits])+1)
            return float(''.join(ans))
            
test = 1.74789
assert round(test) == my_round(test)
assert round(test, 3) == my_round(test, 3)
assert round(-test, 2) == my_round(-test, 2)
print("통과")
통과

1-3. any

def my_any(iterable):
    if True in iterable:
        return True
    else:
        return False/

test1 = [True, 7 == 4, 'Something', False]
test2 = [3 > 5, 10 != 10, False, '', None]

assert any(test1) == my_any(test1)
assert any(test2) == my_any(test2)
print("통과")
통과

1-4. enumerate

def my_enumerate(sequence, start=0):
    ans = []
    for i in sequence:
        ans.append((start, i))
        start += 1
    return ans

test1 = [60, 50, 20, 10]
test2 = [True, None, 'test']

assert list(enumerate(test1)) == list(my_enumerate(test1))
assert list(enumerate(test2, 12)) == list(my_enumerate(test2, 12))
print("통과")
통과

1-5. max & min

def my_max(*args):
    max_ = 0 # 본래 max or min 값을 0 or 10으로 설정하면 안되지만.. 간단한 구현을 위해 0 or 10으로 설정함.    
    for i in args:
        if i > max_:
            max_ = i
    return max_

def my_min(*args):
    min_ = 10
    for j in args:
        if j < min_:
            min_ = j
    return min_

test = [7, 4, 2, 6, 8]

assert max(*test) == my_max(*test) and min(*test) == my_min(*test)
assert max(7, 4, 2, 5) == my_max(7, 4, 2, 5) and min(7, 4, 2, 5) == my_min(7, 4, 2, 5)
print("통과")
통과

1-6. range

실제론 함수가 아니지만 함수 같이 만들어보자.

def my_range(*args):
    if len(args) == 1:
        start = 0
        end = args[0]
        step = 1
    elif len(args) == 2:
        start = args[0]
        end = args[1]
        step = 1
    elif len(args) == 3:
        start = args[0]
        end = args[1]
        step = args[2]
        
    ans = []
    
    if step > 0:
        while start < end:
            ans.append(start)
            start += step
        return ans
    else:
        while start > end:
            ans.append(start)
            start += step
        return ans
        
    
assert list(range(10)) == list(my_range(10))
assert list(range(3, 10)) == list(my_range(3, 10))
assert list(range(3, 10, 2)) == list(my_range(3, 10, 2))
assert list(range(10, 3, -2)) == list(my_range(10, 3, -2))
print("통과")
통과

1-7. reversed

def my_reversed(seq):
    return seq[::-1]

test = [7, 4, 2, 6, 8]

assert list(reversed(test)) == list(my_reversed(test))
print("통과")
통과

1-8. filter

def my_filter(function, iterable):
    ans = []
    for num in iterable:
        if function(num):
            ans.append(num)
    return ans

def test_function(number):
    return number > 5
test = [1, 7, 5, 2, 9, 11]

# 역슬래시 "\"를 이용하면 평가식을 다음 줄로 나눌 수 있다.
assert list(filter(test_function, test)) == list(my_filter(test_function, test)) \
    == list(filter(lambda x: x > 5, test))
print("통과")
통과

1-9. map

def my_map(function, iterable):
    ans = []
    for num in iterable:
        fixed_num = function(num)
        ans.append(fixed_num)
    return ans

def test_function(number):
    return number * 2
test = [1, 7, 5, 2, 9, 11]

assert list(map(test_function, test)) == list(my_map(test_function, test)) \
    == list(map(lambda x: x * 2, test))
print("통과")
통과

1-10. sum

def my_sum(iterable, start=0):
    tot = 0
    for num in iterable:
        tot += num
    return tot

test = [7, 4, 2, 6, 8]

assert sum(test) == my_sum(test)
assert sum(range(10)) == my_sum(my_range(10))
assert sum(filter(lambda x: x % 2, range(1, 20, 3))) \
    == my_sum(my_filter(lambda x: x % 2, my_range(1, 20, 3)))
print("통과")
통과

1-11. zip

def my_zip(*iterables):
    if len(iterables) == 2:
        ans = []
        for idx in range(len(iterables[0])):
            ans.append((iterables[0][idx],iterables[1][idx])) # iterables[0]~[1] 설정하는게 헷갈려서 임시로 했습니다..
        return ans
    else:
        ans = []
        for idx in range(len(iterables[0])):
            ans.append((iterables[0][idx],iterables[1][idx],iterables[2][idx])) # iterables[0]~[2] 설정하는게 헷갈려서 임시로 했습니다..
        return ans
        
        
test1 = (1, 2, 3)
test2 = (10, 2, 30)
assert list(zip(test1, test2)) == list(my_zip(test1, test2))

test3 = [(10, 20, 30, 40), (55, 22, 66, 70), (False, True, True, False)]
assert list(zip(*test3)) == list(my_zip(*test3))
print("통과")
통과

1-12. sorted

정렬 알고리즘은 어떠한 것을 써도 무방하다. 쉬운 정렬 알고리즘으로 일반적으로 삽입정렬, 선택정렬, 그리고 버블정렬을 꼽는다.

더 심도 있게 공부 할 것.

def my_sorted(iterable, key=None, reverse=False):
    
    if key == None:
        for a in range(1, len(iterable)):
            for b in range(a, 0, -1):
                if iterable[b] < iterable[b-1]:
                    iterable[b], iterable[b-1] = iterable[b-1], iterable[b]
                else:
                    break
        if not reverse:
            return iterable
        else:
            return iterable[::-1]
    else:
        for a in range(1, len(iterable)):
            for b in range(a, 0, -1):
                if iterable[b][1] < iterable[b-1][1]:
                    iterable[b], iterable[b-1] = iterable[b-1], iterable[b]
                else:
                    break
        if not reverse:
            return iterable
        else:
            return iterable[::-1]
        
    
    if not reverse:
        return iterable
    else:
        return iterable[::-1]

test1 = [7, 4, 2, 6, 8]
assert sorted(test1) == my_sorted(test1)
test2 = [(1, 2), (6, 2), (5, 3), (10, 5)]
assert sorted(test2) == my_sorted(test2) \
   and sorted(test2, reverse=True) == my_sorted(test2, reverse=True) \
   and sorted(test2, key=lambda x: x[1]) == my_sorted(test2, key=lambda x: x[1])
print("통과")
통과

2. 알고리즘 함수 만들기

몇 가지 간단한 알고리즘 함수를 만들어보자.

2-1. 피보나치 수열 만들기

숫자 $N$가 주어졌을때,다피보나치 길이 $N$의 피보나치 수열을 생성하는 함수를 작성해보자. 시작은 1부터다.

def fibonacci(number):
    ans = []
    curr_ , next_ = 0, 1
    for _ in range(number):
        curr_, next_ = next_, curr_ + next_
        ans.append(curr_)
    return ans

assert list(fibonacci(10)) == [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
assert sum(fibonacci(5)) == 12
print("통과") 
통과

2-2. 순열 만들기

수열 $S$가 주어졌을때 그 안에서 $N$를 뽑아 순열을 만드는 함수를 작성해보자. 순서는 상관없다.
(힌트: 재귀 함수를 써보자)

더 심도 있게 공부 할 것.

def my_permutations(seq, number):
    results = []
    prev_elements = []
    
    def dfs(elements) :
        if len(elements) == (len(seq) - number) :
            results.append(tuple(map(int,prev_elements[:]))) # for set..(hash)
        
        for e in elements :
            next_elements = elements[:]
            next_elements.remove(e)
            
            prev_elements.append(e)
            dfs(next_elements)
            prev_elements.pop()
            
    dfs(seq)
    return results

from itertools import permutations
test = [1, 2, 3, 4]

assert set(permutations(test, 2)) == set(my_permutations(test, 2)) \
   and set(permutations(test, 3)) == set(my_permutations(test, 3))
print("통과") 
통과

2-3. 조합 만들기

수열 $S$가 주어졌을때 그 안에서 $N$를 뽑아 조합을 만드는 함수를 작성해보자. 순서는 상관없다.
(힌트: 재귀 함수를 써보자)

더 심도 있게 공부 할 것.

def my_combinations(iterable, r):
    pool = tuple(iterable)
    n = len(pool)
    if r > n:
        return
    indices = list(range(r))
    yield tuple(pool[i] for i in indices)
    while True:
        for i in reversed(range(r)):
            if indices[i] != i + n - r:
                break
        else:
            return
        indices[i] += 1
        for j in range(i+1, r):
            indices[j] = indices[j-1] + 1
        yield tuple(pool[i] for i in indices) # **yield**

from itertools import combinations
test = [1, 2, 3, 4]

assert set(combinations(test, 2)) == set(my_combinations(test, 2)) \
   and set(combinations(test, 3)) == set(my_combinations(test, 3))
print("통과") 
통과

댓글남기기