하루 동안 쌓인 주문 기록 파일 orders.txt를 읽어 메뉴별 판매 수량과 총매출을 계산하고 영수증으로 정리하는 작은 프로그램을 세 레슨에 걸쳐 만듭니다. 첫걸음은 코딩을 시작하기 전에 문제를 입력 → 처리 → 출력 세 단계와 함수들로 나누는 것입니다.
파일 읽어 모으기와 세기: 메뉴별로 모으기, 돌려받은 값 쓰기를 먼저 읽어야 이해됩니다. 이 단원은 레슨마다 앞 레슨의 코드를 이어서 키우며, 폰만 쓰는 분도 단계 나누기와 빈칸·출력 예측으로 끝까지 따라올 수 있습니다.
1문제를 입력 · 처리 · 출력 세 단계로 나누기
우리가 풀려는 문제를 한 문장으로 적으면 이렇습니다.
주문 기록 파일(
orders.txt)에서 메뉴와 수량을 읽어 메뉴별 판매 수와 총매출을 구한 뒤, 요약 영수증을 만든다.
이 문제를 처음부터 한 덩어리 코드로 짜려 하면 파일 열기, 쉼표 쪼개기, 딕셔너리 누적, 가격 곱하기, 문자열 합치기가 한꺼번에 뒤엉켜 어디서부터 손을 대야 할지 막막해집니다. 먼저 일을 입력 · 처리 · 출력 세 단계로 쪼개고, 단계마다 함수 하나씩 맡깁니다.
세 함수가 주고받는 값(입력과 돌려주는 값)을 표로 정리하면 각 함수가 해야 할 일이 또렷해집니다.
| 단계 | 함수 이름 | 받는 값(매개변수) | 돌려주는 값(return) |
|---|---|---|---|
| 1. 입력 | load_orders(path) | 파일 경로 'orders.txt' | 메뉴별 수량 딕셔너리 {'커피': 2, ...} |
| 2. 처리 | calc_total(sold, menu) | 판매 수량 sold, 가격표 menu | 총매출 정수 14500 |
| 3. 출력 | make_report(sold, total) | 판매 수량 sold, 총매출 total | 영수증 문자열 |
2함수 뼈대부터 먼저 세우기
안쪽 코드를 다 채우기 전에, 세 함수의 이름과 매개변수, 그리고 전체가 이어지는 흐름을 뼈대 코드로 먼저 적어 봅니다. 아직 구현하지 않은 자리는 임시 값이나 주석으로 두고 흐름이 맞는지 확인합니다.
def load_orders(path):
# 1. 메뉴별 수량 딕셔너리 반환
return {'커피': 2, '라테': 1}
def calc_total(sold, menu):
# 2. 총매출 정수 반환
return 12500
def make_report(sold, total):
# 3. 요약 영수증 문자열 반환
return f'합계: {total}원'
이렇게 뼈대를 세워 두면 전체 프로그램의 마지막 세 줄은 처음부터 끝까지 바뀌지 않습니다.
m = {'커피': 4000, '라테': 4500}
sold = load_orders('orders.txt')
total = calc_total(sold, m)
print(make_report(sold, total))
합계: 12500원load_orders가 만든 sold 딕셔너리가 calc_total과 make_report로 들어가고, calc_total이 구한 total이 make_report로 들어갑니다. 이제 다음 레슨에서 세 함수의 안쪽을 하나씩 채우기만 하면 됩니다.
그렇다면 만약 load_orders가 return sold 대신 함수 안에서 print(sold)만 하고 끝난다면, 그다음 줄 total = calc_total(sold, menu)에서 sold에는 무엇이 들어갈까요? 먼저 생각해 보세요.
생각 비교하기
return이 없는 함수는 늘 None을 돌려주므로(규칙 5), sold에 None이 들어갑니다. 그러면 calc_total(sold, menu) 안에서 sold를 딕셔너리처럼 읽으려 할 때 곧바로 오류가 납니다. 단계마다 나눈 함수들이 바통을 이어받으려면 결과를 print가 아니라 return으로 돌려주어야 합니다.
자주 틀리는 곳
1. 처음부터 한 덩어리로 다 쓰고 나서야 처음 실행해 본다
틀린 생각: 입력부터 출력까지 30줄을 한 번에 다 적은 뒤에 실행해 보는 것이 빠르다.
여러 단계가 한 덩어리로 섞여 있으면 오류가 났을 때 파일 읽기가 틀렸는지, 딕셔너리 합산이 틀렸는지, 영수증 줄 만들기가 틀렸는지 찾기가 훨씬 어렵습니다.
맞는 규칙: 먼저 입력 · 처리 · 출력 단계로 함수를 나누어 뼈대를 세우고, 함수마다 무엇을 받아 무엇을 돌려줄지부터 정합니다.
2. 무엇을 하는지 드러나지 않는 함수 이름을 짓는다
틀린 생각: 함수 이름은 짧을수록 좋으니 f1, f2, f3이나 do_it으로 짓는다.
s = f1('orders.txt')와 t = f2(s, menu)처럼 적어 두면 몇 분만 지나도 어느 함수가 파일을 읽고 어느 함수가 매출을 계산하는지 다시 위아래로 오가며 읽어야 합니다.
맞는 규칙: 함수 이름은 load_orders, calc_total, make_report처럼 그 함수가 하는 일이나 돌려주는 값이 한눈에 드러나게 짓습니다.
확인 문제
1. 하루 주문 기록 정리 프로그램의 세 함수가 실행되는 올바른 차례를 고르세요.
- ①
calc_total→load_orders→make_report - ②
load_orders→calc_total→make_report - ③
make_report→load_orders→calc_total
힌트
먼저 파일에서 판매 수량(sold)을 읽어 와야 총매출(total)을 계산할 수 있고, 두 값이 모두 있어야 영수증을 만들 수 있습니다.
정답
**② load_orders → calc_total → make_report**입니다. 입력(load_orders)이 만든 sold를 처리(calc_total)에 넘겨 total을 구하고, 둘을 출력(make_report)에 넘겨 영수증을 만듭니다.
2. 아래 코드에서 세 함수가 차례대로 값을 주고받도록 빈칸 (가)와 (나)에 알맞은 변수 이름을 쓰세요.
m = {'커피': 4000, '쿠키': 2000}
sold = load_orders('orders.txt')
total = calc_total(_(가)_, m)
text = make_report(sold, _(나)_)
힌트
2번 줄에서 파일로부터 읽어 온 판매 수량 딕셔너리가 어느 이름에 붙었는지, 3번 줄에서 구한 총매출이 어느 이름에 붙었는지 보세요.
정답
(가):sold(나):total
load_orders가 돌려준 sold를 calc_total(sold, menu)에 넘기고, calc_total이 돌려준 total을 make_report(sold, total)에 넘깁니다.
3. 출석부 파일(names.txt)을 읽어 출석 인원수를 세고 결과 문장을 만드는 프로그램을 두 함수로 나누려 합니다. count_names(path) 함수가 마지막 줄에서 해야 할 일로 알맞은 것을 고르세요.
- ① 인원수를
print(cnt)로 화면에 찍고 끝낸다 - ② 인원수를
return cnt로 부른 자리에 돌려준다
힌트
다음 단계 함수가 그 인원수를 넘겨받아 결과 문장을 만들어야 합니다.
정답
② 인원수를 return cnt로 부른 자리에 돌려준다입니다. return으로 돌려주어야 다음 함수에 인자로 넘겨 쓸 수 있습니다.
아래 뼈대 코드에서 calc_total이 14500을 돌려주도록 바꾸어 실행해 보세요.
처음 펼 때 약 6MB를 받습니다.컴퓨터에서 해 보기
파이썬 3.14. Tab을 누르면 다음 단추나 칸으로 갑니다. 들여쓰기는 빈칸 네 개입니다. Enter는 앞줄 들여쓰기를 잇고, 콜론 뒤에서는 한 단계 더 들여 씁니다. Ctrl+Enter로 실행합니다.
'실행'을 누르면 여기에 나옵니다.
여기서 쓴 코드 · 내 예상은 저장하지도 운영자에게 보내지도 않습니다. 페이지를 새로 열면 처음 코드입니다.