본문으로 건너뛰기

함수 하나씩 만들고 확인하기

파이썬 목차작은 프로그램 만들기레슨 58 / 59

목차

앞 레슨에서 나눈 세 함수(load_orders, calc_total, make_report)의 안쪽을 하나씩 채웁니다. 핵심 습관은 세 함수를 다 짜고 나서 한꺼번에 돌리는 것이 아니라, 함수를 하나 만들 때마다 작은 시험 값으로 바로 불러 결과를 눈으로 확인하고 다음 함수로 넘어가는 것입니다.

문제를 단계로 나누기와 값을 찍어 보며 고치기를 먼저 읽어야 이해됩니다.

앞 레슨에서 나눈 세 함수 뼈대 펼쳐 보기
def load_orders(path):
    return {'커피': 2}


def calc_total(sold, menu):
    return 12500


def make_report(sold, total):
    return f'합계: {total}원'

9단계 중 1단계. 함수를 하나 만들 때마다 작은 시험 값으로 바로 불러 결과를 확인하며 프로그램을 키웁니다.

1첫째 함수 load_orders 만들고 확인하기

먼저 시험용 orders.txt 파일을 준비하고, 파일을 한 줄씩 읽어 메뉴별 판매 수량 딕셔너리를 돌려주는 load_orders(path)를 만듭니다.

fn = 'orders.txt'
with open(fn, 'w') as f:
    f.write('커피,2\n')
    f.write('라테,1\n')
    f.write('쿠키,1\n')
def load_orders(path):
    sold = {}
    with open(path, 'r') as f:
        for line in f:
            s = line.strip()
            row = s.split(',')
            m = row[0]
            n = int(row[1])
            old = sold.get(m, 0)
            sold[m] = old + n
    return sold

두 번째 함수를 짜러 가기 전에, 지금 만든 load_orders가 제대로 동작하는지 한 줄을 찍어 바로 확인합니다.

sold = load_orders('orders.txt')
print(sold)
실행 결과
{'커피': 2, '라테': 1, '쿠키': 1}

기대한 딕셔너리가 정확히 나왔으니 load_orders는 안심하고 다음 단계로 넘어갈 수 있습니다.

2둘째 함수 calc_total 만들고 작은 값으로 확인하기

이번에는 판매 수량 sold와 가격표 menu를 받아 총매출을 구하는 calc_total(sold, menu)⁠를 만듭니다. 이 함수를 시험할 때는 파일을 다시 읽지 않고 작은 딕셔너리를 직접 넘겨 봅니다.

def calc_total(sold, menu):
    total = 0
    for m, n in sold.items():
        total += menu[m] * n
    return total
sold = {
    '커피': 2,
    '라테': 1,
    '쿠키': 1,
}
menu = {
    '커피': 4000,
    '라테': 4500,
    '쿠키': 2000,
}
print(calc_total(sold, menu))
실행 결과
14500

4000 * 2 + 4500 * 1 + 2000 * 1⁠인 14500이 찍혔습니다. 만약 여기서 다른 수가 나왔다면 첫째 함수가 아니라 방금 짠 calc_total 안만 살펴보면 됩니다.

3셋째 함수 make_report 만들고 확인하기

마지막으로 메뉴별 판매 줄과 합계 줄을 줄바꿈('\n')으로 이어 붙이는 make_report(sold, tot)⁠를 만들고 확인합니다.

def make_report(sold, tot):
    out = []
    for m, n in sold.items():
        s = f'{m}: {n}잔'
        out.append(s)
    out.append(f'합계: {tot}원')
    return '\n'.join(out)


sold = {
    '커피': 2,
    '라테': 1,
    '쿠키': 1,
}
print(make_report(sold, 14500))
실행 결과
커피: 2잔
라테: 1잔
쿠키: 1잔
합계: 14500원

그렇다면 만약 calc_total 안에서 total = 0을 for 반복문 안에 잘못 적었다면 마지막 줄의 합계는 얼마로 찍힐까요? 먼저 맞혀 보세요.

생각 비교하기

바퀴마다 total이 다시 0으로 초기화되므로 앞선 커피(8000)와 라테(4500)는 사라지고 마지막 항목인 쿠키 1잔 값(2000)만 남아 합계: 2000원이 찍힙니다. 이처럼 결과가 이상할 때도 calc_total 하나만 따로 불러 보면 어느 함수에서 틀렸는지 금방 좁힐 수 있습니다.

자주 틀리는 곳

1. 함수를 하나도 확인하지 않고 세 개를 다 쓴 뒤 처음 실행한다

틀린 생각: 어차피 마지막에 전체를 실행할 것이니 함수를 하나씩 확인할 필요가 없다.

세 함수를 다 쓴 뒤 마지막 출력이 틀리면, 파일을 잘못 읽은 것인지(load_orders), 곱셈 합산이 틀린 것인지(calc_total), 문자열 합치기가 틀린 것인지(make_report) 처음부터 다 뒤져야 합니다.

맞는 규칙: 함수를 하나 완성할 때마다 한 줄짜리 시험 호출로 기대한 값이 나오는지 먼저 확인합니다.

2. 함수를 시험할 때마다 늘 실제 파일부터 읽어야 한다고 생각한다

틀린 생각: calc_total을 시험하려면 반드시 orders.txt 파일을 먼저 만들어 읽어야 한다.

calc_total(sold, menu)⁠는 딕셔너리 두 개를 받는 함수입니다. 작은 딕셔너리 {'커피': 2}와 {'커피': 4000}을 직접 넘기면 파일과 상관없이 계산만 빠르게 시험할 수 있습니다.

맞는 규칙: 각 함수는 작은 딕셔너리나 리스트를 직접 인자로 넘겨 독립적으로 시험할 수 있습니다.

확인 문제

1. 방금 작성한 calc_total(sold, menu) 함수만 따로 시험해 보려고 합니다. 가장 간단한 시험 방법을 고르세요.

  • ① orders.txt 파일을 새로 쓰고 load_orders와 make_report까지 모두 부른다
  • ② 작은 딕셔너리 {'커피': 2}와 {'커피': 4000}을 넘겨 8000이 찍히는지 본다
힌트

calc_total이 필요로 하는 두 인자(sold, menu)만 가장 작은 딕셔너리로 넘겨 보면 됩니다.

정답

②입니다. 작은 딕셔너리를 바로 넘겨 계산 결과가 암산(8000)과 맞는지 확인하는 것이 가장 빠르고 정확합니다.

2. make_report 안에서 줄 리스트 out을 줄바꿈 문자('\n')로 이어 한 문자열로 돌려주려고 합니다. 빈칸을 채우세요.

def make_report(sold, tot):
    out = []
    for m, n in sold.items():
        s = f'{m}: {n}잔'
        out.append(s)
    out.append(f'합계: {tot}원')
    return ________.join(out)
힌트

구분자 문자열 뒤에 .join(리스트)를 붙입니다. 줄바꿈 문자는 '\n'입니다.

정답

'\n'입니다 (return '\n'.join(out)).

3. 아래 load_orders에서 같은 메뉴가 두 줄('커피,2' 뒤 '커피,1')에 나누어 나와도 수량이 합쳐지도록 빈칸에 알맞은 식을 쓰세요.

sold = {}
rows = ['커피,2', '커피,1']
for s in rows:
    row = s.split(',')
    m = row[0]
    n = int(row[1])
    prev = sold.get(m, 0)
    sold[m] = prev + ___
print(sold)
힌트

줄마다 수량이 1이 아니라 n(int(row[1]))이므로 이전 값 prev에 n을 더합니다.

정답

n입니다.

sold = {}
rows = ['커피,2', '커피,1']
for s in rows:
    row = s.split(',')
    m = row[0]
    n = int(row[1])
    prev = sold.get(m, 0)
    sold[m] = prev + n
print(sold)
실행 결과
{'커피': 3}

아래 코드에서 sold의 '쿠키' 수량을 3으로 바꾸면 합계가 얼마로 바뀌는지 실행해 확인해 보세요.

처음 펼 때 약 6MB를 받습니다.컴퓨터에서 해 보기

끝까지 내려오면 저절로 표시됩니다. 이 기기에만 저장합니다.

파이썬 목차로