Devin.KR

AI 개발 · 기본

바이브 코딩 따라하기 - 요청문 그대로 따라 만드는 가계부 앱

첫 기능 - 지출 한 건 기록하고 보여 주기

기록 하나를 사전으로, 목록에 쌓기, 금액은 정수 원 단위, 보기 좋게 출력(천 단위 쉼표), 체크포인트 출력 확인

개발자KR · 원고 갱신

이 장에서 배우는 것

앞 장에서 정한 가계부의 첫 기능을 실제로 움직여 본다. 이번에는 지출 이름과 금액을 한 묶음으로 만들고, 그 묶음을 목록에 쌓은 뒤 화면에 보여 준다. 시작은 지출 한 건이다. 한 건이 제대로 보이면 같은 방법으로 세 건까지 늘린다. 저장이나 사용자 입력을 붙이기 전에, 기록을 담는 모양과 출력 모양부터 확인하는 과정이다.

AI에게 작은 변경을 요청하고, 받은 코드를 main.py에 반영하고, 직접 실행하는 순서로 진행한다. AI의 설명이 그럴듯해도 터미널에 나온 값이 다르면 다음 단계로 넘어가지 않는다. 이 장에서 사용할 금액과 이름은 모두 정해져 있으므로 누구나 같은 결과를 확인할 수 있다.

  • 지출 이름과 금액을 사전이라는 한 묶음에 담는다.
  • 여러 기록을 목록에 넣고 들어간 순서대로 출력한다.
  • 금액을 정수 원 단위로 보관하고 출력할 때 천 단위 쉼표를 붙인다.
  • 기대 출력, 코드 차이, 확인용 검사로 AI가 만든 결과를 점검한다.

이번 장에서 만들 것

점심을 먹고 8,200원을 썼다고 하자. 화면에 “점심 8,200원”이라고 적을 수는 있다. 그러나 이후에 지출을 계산하려면 이름과 금액을 구분해서 보관해야 한다. 화면에 보이는 문장만 만드는 대신, 프로그램 안에는 계산할 수 있는 금액을 남겨 두어야 한다.

이번에 만드는 프로그램은 정해진 지출 세 건을 기록하고 출력한 뒤 바로 끝난다. 실행 중에 이름이나 금액을 묻지 않는다. 날짜, 분류, 파일 저장, 월별 합계도 넣지 않는다. 지금 확인할 대상은 “한 건을 제대로 담고, 여러 건을 빠짐없이 보여 주는가”이다.

프로그램에 넣을 고정 입력과 기대 표시
순서지출 이름보관할 금액화면에 보일 금액
1커피45004,500원
2점심82008,200원
3버스21002,100원

main.py는 파이썬 프로그램을 적어 둘 파일 이름이다. 별도 설치가 필요한 외부 패키지는 사용하지 않는다. macOS나 Linux에서 Python 3.12 이상을 준비하고, main.py가 있는 폴더에서 실행한다. 이 장의 파일은 앞 장의 파일이 없어도 혼자 실행된다.

따라하기

다음 일곱 단계를 같은 순서로 진행한다. 각 단계의 요청문을 AI에게 보내고, 받은 파이썬 코드를 main.py에 반영한다. AI 답은 매번 다를 수 있다. 아래의 답변 요지는 반드시 같은 문장을 돌려받아야 한다는 뜻이 아니라, 답에 포함되어야 할 작업 범위를 보여 준다. 결과가 다르면 현재 코드와 실제 출력을 AI에게 함께 전달해 범위를 좁혀 고친다.

터미널은 명령을 입력하고 프로그램의 출력을 읽는 창이다. 아래에 나오는 실행 명령은 터미널에 입력한다. 명령 자체를 main.py 안에 적지 않는다. 매번 실행이 끝나고 명령을 입력할 수 있는 상태로 돌아오는 것까지 확인한다.

단계 1. 지출 한 건을 한 묶음으로 만든다

① 보낼 요청문

혼자 쓰는 가계부의 첫 기능을 main.py 한 파일로 만들어 줘. Python 3.12 이상 표준 기능만 사용해 줘. 사용자 입력 없이 record = {"name": "커피", "amount": 4500}으로 지출 한 건을 만들고, 이름과 금액을 각각 한 줄에 출력해 줘. 금액은 정수 원 단위로 보관해 줘. 파일 저장, 날짜, 분류, 함수는 아직 추가하지 말아 줘. 실행하면 바로 끝나는 전체 코드를 보여 줘.

② AI가 돌려줄 내용의 요지

지출 이름과 금액을 record라는 사전에 담고, name과 amount에 해당하는 값을 print로 출력하는 코드다. 이 답의 표현과 설명은 실행할 때마다 달라질 수 있다.

사전(dict)은 이름표와 값을 짝지어 보관하는 자료다. 여기서 name과 amount는 값을 찾을 때 쓰는 이름표인 키다. name에 대응하는 값은 커피이고, amount에 대응하는 값은 4500이다. record는 이 묶음을 가리키는 변수다. 변수는 프로그램에서 값을 다시 사용할 수 있도록 붙이는 이름이다.

③ 직접 확인할 것

받은 코드를 main.py에 저장하고 다음 명령을 실행한다.

python3 main.py

커피
4500

코드에서 4500에 따옴표가 없는지도 확인한다. "4500"은 글자인 문자열이고, 4500은 계산에 사용할 수 있는 정수다. 이 둘은 화면에서 비슷하게 보여도 프로그램 안에서는 종류가 다르다.

④ 체크포인트

커피와 4500이 순서대로 출력되고 프로그램이 끝나면 다음 단계로 간다. 입력을 기다리거나 다른 메시지가 나오면 요청 범위를 다시 전달해 고친다.

단계 2. 기록을 목록에 넣는다

① 보낼 요청문

현재 main.py를 고쳐 줘. 빈 목록 records를 만들고, 앞에서 만든 record를 records.append(record)로 한 번 넣어 줘. record를 직접 출력하는 대신 records[0]에서 이름과 금액을 꺼내 각각 한 줄에 출력해 줘. 출력은 이전 단계와 같아야 한다. 바뀐 부분도 설명해 줘.

② AI가 돌려줄 내용의 요지

records = []로 목록을 만들고 append로 기록을 끝에 추가한다. 첫 번째 기록은 records[0]으로 꺼낸다. 답변의 문장은 달라질 수 있지만 출력값은 유지한다.

목록(list)은 여러 값을 순서대로 담는 자료다. 빈 대괄호 []는 아직 아무것도 없는 목록을 뜻한다. append는 목록의 맨 뒤에 값 하나를 추가하는 동작이다. 파이썬은 목록의 위치를 0부터 센다. 따라서 첫 기록의 위치는 0이다.

지출 한 건은 이름과 금액을 담은 사전이며 목록의 첫 위치에 들어간다

records[0]["name"]은 두 번에 나누어 읽으면 된다. 먼저 records에서 첫 기록을 꺼내고, 그 기록에서 name 값을 꺼낸다. 처음에는 기호가 길게 느껴져도 “목록에서 한 건, 한 건에서 이름”이라는 순서만 따라가면 된다.

③ 직접 확인할 것

python3 main.py

커피
4500

출력은 그대로지만 코드에는 빈 목록을 만드는 줄과 기록을 추가하는 줄이 생겼는지 확인한다. 출력이 같다는 이유만으로 내부 변경까지 맞다고 판단하지 않는다.

④ 체크포인트

목록에 기록을 한 번 넣었고, 목록에서 꺼낸 값이 이전과 같으면 다음 단계로 간다. append를 두 번 적지 않았는지도 살핀다.

단계 3. 정해진 입력 세 건을 차례로 쌓는다

① 보낼 요청문

main.py를 세 건의 고정 입력으로 확장해 줘. sample_inputs에는 ("커피", 4500), ("점심", 8200), ("버스", 2100)을 이 순서로 넣어 줘. for name, amount in sample_inputs: 반복문 안에서 매번 새 사전을 만들고 records에 추가해 줘. 그다음 별도의 반복문으로 records의 각 기록을 읽어 이름과 금액을 한 줄에 출력해 줘. 이 단계에서는 쉼표와 원 표시 없이 커피 4500 같은 모양으로 출력해 줘.

② AI가 돌려줄 내용의 요지

입력 목록을 도는 반복문에서 새 record를 만들고, 출력용 반복문에서 쌓인 기록을 읽는다. 답변은 달라질 수 있으며 입력 순서와 출력 순서는 같아야 한다.

반복문은 같은 동작을 여러 값에 차례로 적용하는 문법이다. for로 시작하는 줄 아래에서 오른쪽으로 들여쓴 코드가 반복된다. 여기서는 입력 한 쌍을 읽을 때마다 이름은 name에, 금액은 amount에 들어간다. 괄호로 묶은 ("커피", 4500)은 두 값을 한 쌍으로 담은 튜플(tuple)이다.

기록을 만드는 반복문과 출력하는 반복문을 따로 두는 이유도 있다. 첫 반복문이 끝나면 records에 세 건이 모두 모인다. 둘째 반복문은 그 결과를 화면에 보여 준다. records = []를 첫 반복문 안에 두면 매번 목록이 비워지므로, 빈 목록을 만드는 줄은 반복문 앞에 한 번만 둔다.

③ 직접 확인할 것

python3 main.py

커피 4500
점심 8200
버스 2100

마지막 기록만 보이지 않는지, 이름과 금액이 서로 바뀌지 않았는지 확인한다. 들여쓰기는 공백 네 칸으로 맞춘다. 새 사전을 만드는 줄과 append 줄은 같은 깊이로 들여쓴다.

④ 체크포인트

세 줄이 정해진 순서로 나오고, 각 줄의 이름과 금액이 표와 일치하면 다음 단계로 간다.

단계 4. 금액을 읽기 좋게 표시한다

① 보낼 요청문

records 안의 amount는 계속 정수로 유지해 줘. 출력 부분만 f-string으로 바꾸고, 금액에는 : 만이 아니라 :, 형식 지정을 사용해 천 단위 쉼표를 붙여 줘. 각 줄은 커피 | 4,500원 모양이어야 한다. 이름과 금액 사이에는 공백, 세로줄, 공백을 넣어 줘. 출력 문자열을 records에 다시 저장하지 말아 줘.

② AI가 돌려줄 내용의 요지

f-string 안에서 금액에 :,를 붙여 표시하고 원 글자를 덧붙인다. 저장된 정수는 그대로다. AI 답의 설명은 달라질 수 있다.

f-string은 따옴표 앞에 f를 붙이고 중괄호 안에 값을 넣는 문자열 작성 방식이다. 중괄호 안의 콜론 뒤에는 값을 보여 줄 형식을 적을 수 있다. {record['amount']:,}에서 쉼표는 정수를 천 단위로 끊어 표시하라는 뜻이다. 쉼표와 원은 출력할 때만 붙는다.

③ 직접 확인할 것

python3 main.py

커피 | 4,500원
점심 | 8,200원
버스 | 2,100원

4,500이라는 모양을 만들려고 입력을 "4,500"으로 바꾸지 않았는지 코드도 읽는다. 보기 좋게 만드는 작업과 보관할 값을 바꾸는 작업은 구분해야 한다.

④ 체크포인트

세 금액에 쉼표가 보이고, sample_inputs의 금액에는 따옴표와 쉼표가 없으면 다음 단계로 간다.

단계 5. 제목과 기록 수를 붙인다

① 보낼 요청문

현재 출력의 맨 앞에 지출 기록을 한 줄로 출력해 줘. 세 건을 모두 출력한 뒤에는 len(records)를 사용해 체크포인트: 3건 기록됨을 출력해 줘. 3을 출력문에 직접 적지 말고 목록의 실제 길이를 넣어 줘. 빈 줄이나 장식 문자는 추가하지 말아 줘.

② AI가 돌려줄 내용의 요지

출력 반복문 앞에 제목을 넣고, 반복문 뒤에서 목록 길이를 출력한다. 답변 표현은 달라질 수 있으며 마지막 안내는 한 번만 나온다.

len은 목록에 값이 몇 개 들어 있는지 알려 주는 기본 기능이다. 마지막 줄을 직접 “3건”이라고 적으면 입력을 바꾸어도 안내가 그대로 남는다. 실제 목록 길이를 사용하면 화면에 표시하는 건수가 기록 수를 따라간다.

③ 직접 확인할 것

python3 main.py

지출 기록
커피 | 4,500원
점심 | 8,200원
버스 | 2,100원
체크포인트: 3건 기록됨

출력은 모두 다섯 줄이어야 한다. 마지막 안내가 세 번 나오면 그 출력문이 반복문 안에 들어갔을 가능성이 있다. 제목과 마지막 안내는 출력 반복문과 같은 왼쪽 위치에 둔다.

④ 체크포인트

제목 한 줄, 지출 세 줄, 마지막 안내 한 줄이 나오면 다음 단계로 간다.

단계 6. 눈으로 놓치기 쉬운 값을 검사한다

① 보낼 요청문

제목을 출력하기 전에 확인용 assert 세 개를 추가해 줘. records의 길이가 3인지, records가 기대한 세 사전의 목록과 같은지, 모든 amount의 자료형이 정확히 int인지 확인해 줘. 기대 목록은 코드에 직접 적어 줘. 검사가 통과하면 추가 출력 없이 기존 다섯 줄만 보여 줘. 이 검사는 고정 예제의 개발 중 확인용이라고 설명해 줘.

② AI가 돌려줄 내용의 요지

건수, 전체 기록값, 금액의 자료형을 assert로 확인한다. 조건이 맞으면 계속 실행하고 틀리면 AssertionError로 멈춘다. 답변의 구성은 달라질 수 있다.

자료형은 값의 종류를 뜻한다. int는 정수의 자료형이다. assert는 뒤에 적은 조건이 맞는지 확인하는 문장이다. 목록 전체를 비교하면 이름과 금액뿐 아니라 기록 순서도 확인할 수 있다. all은 안에 제시한 조건이 모두 맞을 때 참이 된다. 완성 코드에서는 각 기록의 금액을 하나씩 검사하는 데 쓴다.

③ 직접 확인할 것

python3 main.py

기대 결과는 단계 5의 다섯 줄과 같다. 검사 통과 메시지를 따로 넣지 않았으므로 출력이 늘어나지 않는다. 검사가 실패하면 마지막 체크포인트까지 도달하지 못한다. 오류가 나면 오류 이름만 지우려고 하지 말고 입력, 새 사전 생성 위치, 목록에 추가하는 위치를 다시 확인한다.

검사가 실제로 작동하는지도 한 번 확인한다. 첫 입력의 4500을 잠시 4501로 바꾸어 실행하면, 기대 목록과 다르므로 AssertionError로 멈춰야 한다. 오류에 표시되는 파일 경로와 줄 번호는 환경에 따라 달라질 수 있다. 확인한 뒤에는 반드시 4500으로 복원하고 다시 실행한다.

④ 체크포인트

값을 잠시 틀리게 바꾸었을 때 검사가 실패하고, 복원한 뒤에는 원래 다섯 줄이 나오면 다음 단계로 간다. assert는 실행 옵션에 따라 생략될 수 있으므로 실제 사용자 입력을 검증하는 수단으로 대신 쓰지 않는다. 여기서는 기본 실행 명령으로 고정 예제를 확인한다.

단계 7. 바뀐 코드와 최종 출력을 함께 확인한다

① 보낼 요청문

현재 main.py를 아래에 붙인다. 이번 기능의 범위 안에서 검토해 줘. 입력 세 건이 고정되어 있는지, 반복할 때마다 새 사전을 만드는지, 금액이 정수로 남는지, 쉼표는 출력에만 붙는지 확인해 줘. 파일 저장이나 다른 기능은 추가하지 말아 줘. 수정이 필요하면 수정 전후 차이와 이유를 먼저 설명하고 전체 코드를 보여 줘.

② AI가 돌려줄 내용의 요지

현재 코드가 요구를 만족하는지 항목별로 살피고, 필요한 변경이 있으면 해당 부분의 차이를 설명한다. 검토 답변은 매번 달라질 수 있으며, 실행하지 않았다면 실행했다고 단정하지 않아야 한다.

요청문 뒤에 자신의 현재 main.py 내용을 붙여 보낸다. AI의 검토는 보조 자료다. 편집기의 파일 비교 기능으로 수정 전후 차이(diff)를 직접 살핀다. diff는 어느 줄이 추가되거나 삭제되거나 바뀌었는지 보여 주는 비교다. 이번 단계에서 저장 기능이나 입력 대기 코드가 생겼다면 요청 범위를 벗어난 변경이다.

③ 직접 확인할 것

python3 -W error -c 'import ast, pathlib; compile(pathlib.Path("main.py").read_text(encoding="utf-8"), "main.py", "exec", flags=ast.PyCF_ONLY_AST)'

이 명령은 파일을 읽어 문법을 검사하며, 경고도 오류로 취급한다. 통과하면 아무것도 출력하지 않는다. 이어서 실제 동작을 확인한다.

python3 main.py

단계 5의 다섯 줄이 그대로 나와야 한다. 같은 명령을 한 번 더 실행해도 결과가 같아야 한다. 앞선 실행에서 쌓은 기록이 다음 실행에 더해지지 않는다.

④ 체크포인트

코드 차이를 검토했고, 문법 검사가 조용히 통과했고, 실제 출력이 기대한 다섯 줄과 같으면 이 장의 기능을 마친다. 아래 완성 코드와 비교해 빠진 검사가 없는지도 확인한다.

완성 코드

다음 내용을 main.py에 저장한다. 앞의 단계에서 만든 코드 대신 이 코드만 저장해도 실행된다. 파이썬 파일은 한글을 담을 수 있도록 UTF-8로 저장한다.

sample_inputs = [
    ("커피", 4500),
    ("점심", 8200),
    ("버스", 2100),
]

records = []
for name, amount in sample_inputs:
    record = {"name": name, "amount": amount}
    records.append(record)

assert len(records) == 3
assert records == [
    {"name": "커피", "amount": 4500},
    {"name": "점심", "amount": 8200},
    {"name": "버스", "amount": 2100},
]
assert all(type(record["amount"]) is int for record in records)

print("지출 기록")
for record in records:
    print(f"{record['name']} | {record['amount']:,}원")
print(f"체크포인트: {len(records)}건 기록됨")

완성 코드는 외부 파일을 읽거나 만들지 않는다. 실행할 때마다 빈 목록으로 시작해 같은 세 건을 담는다. 화면에 기록이 남아 보여도 프로그램이 끝난 뒤 목록을 파일에 보관하는 기능은 아직 없다.

줄별 해설

빈 줄도 세면 완성 코드는 23줄이다. 코드를 고쳐 줄 위치가 달라졌다면 줄 번호보다 실제 문장을 기준으로 찾아간다.

완성 코드의 줄과 각 줄이 하는 일
줄내용확인할 점
1~5sample_inputs에 이름과 금액 세 쌍을 둔다.금액은 따옴표 없는 정수이며 입력 순서가 고정되어 있다.
7빈 records 목록을 만든다.반복문 밖에서 한 번만 만든다.
8입력 쌍을 차례로 읽는다.각 쌍의 첫 값은 name, 둘째 값은 amount에 들어간다.
9이름과 금액으로 새 사전을 만든다.반복할 때마다 별도의 기록이 생긴다.
10사전을 목록 끝에 추가한다.입력 순서대로 기록이 쌓인다.
12기록이 세 건인지 검사한다.추가를 빼먹거나 중복하지 않았는지 확인한다.
13~17전체 목록을 기대 목록과 비교한다.이름, 금액, 순서가 모두 맞아야 한다.
18각 금액의 자료형을 검사한다.문자열이나 소수가 섞이면 통과하지 못한다.
20제목을 출력한다.반복문 앞에 있으므로 한 번만 나온다.
21~22각 기록을 쉼표가 있는 금액으로 출력한다.표시 모양을 바꾸어도 저장한 정수는 바뀌지 않는다.
23실제 목록 길이를 출력한다.반복문 뒤에서 한 번만 나온다.

records라는 목록과 record라는 한 건의 이름을 구별해서 읽는다. 8~10줄에서 record는 새로 만든 한 건을 가리킨다. 21~22줄에서는 이미 모아 둔 목록을 읽으면서 각 한 건을 가리킨다. 같은 이름을 다시 사용하지만, 출력 반복문에서는 사전을 새로 만들거나 목록에 추가하지 않는다.

18줄의 type은 값의 자료형을 알려 준다. is int는 그 자료형이 정수형인지 확인한다. 이 검사가 따로 필요한 이유는 4500과 4500.0이 값 비교에서는 같다고 판단되기 때문이다. 전체 목록 비교만으로는 “금액을 정수로 보관한다”는 조건까지 확인할 수 없다.

금액은 정수 4500으로 보관하고 출력할 때만 4,500원이라는 표시를 만든다

그림처럼 보관하는 값과 보여 주는 모양은 다르다. 22줄은 금액에 쉼표와 원을 붙인 새 문자열을 만들어 출력한다. 그 결과를 record["amount"]에 대입하는 문장이 없으므로 원래 금액은 정수로 남는다.

실행 결과

main.py가 있는 폴더에서 다음 명령을 실행한다.

python3 main.py

예상 출력은 다음과 같다. 제목과 마지막 체크포인트를 포함해 다섯 줄이며 빈 줄은 없다.

지출 기록
커피 | 4,500원
점심 | 8,200원
버스 | 2,100원
체크포인트: 3건 기록됨

이 출력은 현재 실행에서 세 건을 만들었다는 뜻이다. 마지막 체크포인트가 보인다는 것은 그 앞의 assert 검사도 통과했다는 뜻이다. 단, 이는 정해진 예제가 확인되었다는 범위의 근거다. 앞으로 추가할 모든 기능이나 모든 입력까지 검사한 것은 아니다.

출력이 다르면 AI에게 보낼 때 기대 출력과 실제 출력을 함께 적는다. 예를 들어 “버스만 나온다”는 설명보다 “기대 출력은 세 건인데 실제 출력은 버스 한 건이다. records를 만드는 위치와 반복문 들여쓰기를 확인해 줘”라고 요청하면 확인할 범위가 분명해진다.

실무에서 자주 틀리는 것

다음 코드는 각각 따로 실행할 수 있는 짧은 비교 예제다. 잘못된 예도 문법은 맞지만, 지출 기록의 의도와 다른 결과를 만든다. 완성 코드에 이어 붙이지 말고 동작을 비교하는 데 사용한다.

금액을 쉼표가 들어간 글자로 보관한다

다음은 잘못된 예다. 따옴표 때문에 금액이 문자열로 보관된다. 출력이 보기 좋다는 이유만으로 기록 형태까지 맞는 것은 아니다.

record = {"name": "커피", "amount": "4,500"}
print(record["amount"])

고친 예에서는 정수를 보관하고 출력 형식만 지정한다. 원 단위 정수로 정했으므로 4500.0처럼 소수로 적을 필요도 없다.

record = {"name": "커피", "amount": 4500}
print(f"{record['amount']:,}원")

반복할 때마다 목록을 새로 만든다

다음은 잘못된 예다. 새 입력을 읽을 때마다 records가 빈 목록으로 바뀐다. 실행하면 마지막 버스 기록만 남는다.

sample_inputs = [("커피", 4500), ("버스", 2100)]
for name, amount in sample_inputs:
    records = []
    records.append({"name": name, "amount": amount})
print(records)

고친 예에서는 빈 목록을 반복문 앞에서 만든다. 그러면 이전에 넣은 기록 뒤에 다음 기록이 붙는다.

sample_inputs = [("커피", 4500), ("버스", 2100)]
records = []
for name, amount in sample_inputs:
    records.append({"name": name, "amount": amount})
print(records)

사전 하나를 계속 고쳐서 여러 번 넣는다

다음은 잘못된 예다. 목록에 사전을 넣는 동작이 사전 내용을 자동으로 복사해 주는 것은 아니다. 같은 사전을 두 번 넣고 그 내용을 고치면, 목록의 두 위치에서 같은 변경 결과를 보게 된다.

record = {"name": "커피", "amount": 4500}
records = []
records.append(record)
record["name"] = "버스"
record["amount"] = 2100
records.append(record)
print(records)

고친 예에서는 매번 새 사전을 만든다. 같은 record라는 변수 이름을 써도 새 중괄호로 만든 사전은 별개의 기록이다.

records = []
for name, amount in [("커피", 4500), ("버스", 2100)]:
    record = {"name": name, "amount": amount}
    records.append(record)
print(records)

체크포인트 건수를 직접 적는다

다음은 잘못된 예다. 기록은 한 건인데 안내는 세 건이라고 나온다. 안내 문장을 출력했다는 사실만으로 실제 상태를 확인했다고 볼 수 없다.

records = [{"name": "커피", "amount": 4500}]
print("체크포인트: 3건 기록됨")

고친 예에서는 목록 길이를 읽는다. 이 예제는 한 건이므로 안내에도 1건이라고 나온다. 완성 코드에서는 같은 방식으로 세 건을 표시한다.

records = [{"name": "커피", "amount": 4500}]
print(f"체크포인트: {len(records)}건 기록됨")

한눈에 보기

첫 기록 기능을 만드는 규칙과 검증 방법
대상이번 장의 규칙직접 확인할 것
지출 한 건name과 amount를 가진 사전으로 만든다.이름과 금액이 같은 사전에 들어 있는가.
여러 기록새 사전을 목록 끝에 추가한다.세 건이 입력 순서대로 남는가.
금액정수 원 단위로 보관한다.따옴표, 소수점, 표시용 쉼표가 없는가.
화면 표시출력할 때 천 단위 쉼표와 원을 붙인다.4,500원처럼 읽기 좋게 나오는가.
검증코드 차이와 검사 결과, 실제 출력을 함께 본다.요청하지 않은 변경이 없고 다섯 줄이 일치하는가.

한 단계가 끝날 때마다 요청문, 반영한 코드, 실제 출력을 함께 남겨 두면 다음 수정의 기준이 된다. 실행 결과만 남기면 금액의 자료형을 놓칠 수 있고, 코드만 읽으면 들여쓰기나 출력 순서의 문제를 지나칠 수 있다. 두 가지를 함께 확인하는 습관을 이어 간다.

연습 문제

완성 코드를 보관한 뒤 복사본에서 연습한다. 각 문제는 원래 완성 코드에서 따로 시작한다. 기대값을 바꿀 때도 실제 출력과 코드를 함께 확인한다.

  1. 커피 금액을 4500에서 4800으로 바꾼다. 검사를 통과하려면 어느 부분을 함께 고쳐야 하는지 찾고, 달라질 출력 한 줄을 적는다.
  2. 고정 입력의 마지막에 ("문구", 13000)을 추가한다. 건수 검사와 기대 목록을 알맞게 고치고 마지막 두 줄의 출력을 적는다. 출력문에 4를 직접 적지 않는다.
  3. 첫 입력의 금액만 "4500"으로 바꾸면 왜 검사를 통과하지 못하는지 설명한다. 쉼표를 표시하면서도 정수 보관 규칙을 지키는 방법을 적는다.
  4. 코드를 실행하지 않은 AI가 “검증을 마쳤다”라고 답했다. 이번 장의 완성 여부를 판단하려면 직접 무엇을 확인해야 하는지 세 가지를 적는다.

정답과 해설

1. 입력과 기대 목록의 금액을 함께 고친다. sample_inputs의 커피 금액을 4800으로 바꾸고, assert records == 뒤에 적은 기대 목록에서도 커피 금액을 4800으로 바꾼다. 기록 수와 자료형은 그대로다. 달라지는 출력 한 줄은 다음과 같다.

커피 | 4,800원

입력만 바꾸면 기대 목록 비교가 실패한다. 먼저 요구한 변경이 커피 금액 수정인지 확인한 뒤, 그 요구에 맞춰 기대값을 고친다. 오류를 없애기 위해 실제 결과를 무조건 기대값으로 복사하면 잘못된 동작까지 받아들일 수 있다.

2. 네 번째 기록과 그 기대값을 추가한다. sample_inputs 끝에 문구 입력을 넣고, assert len(records) == 3을 assert len(records) == 4로 바꾼다. 기대 목록 끝에는 {"name": "문구", "amount": 13000}을 추가한다. 마지막 두 줄은 다음과 같다.

문구 | 13,000원
체크포인트: 4건 기록됨

목록 길이로 안내를 만들었으므로 마지막 출력문은 고칠 필요가 없다. 고정 예제의 건수 검사와 기대 목록은 예제 내용이 바뀌었으므로 함께 수정해야 한다.

3. 따옴표가 붙으면 문자열이 된다. "4500"은 정수 4500과 다르므로 전체 목록 비교에서 실패한다. 정수 자료형 검사도 통과할 수 없는 값이다. 입력은 4500으로 유지하고 출력할 때 {record['amount']:,}를 사용한다. 현재는 고정 입력을 직접 적으므로 문자열을 정수로 바꾸는 처리까지 추가할 필요가 없다.

4. 코드 차이, 검사 통과, 실제 출력을 직접 확인한다. 먼저 수정 전후 차이를 읽어 요청한 변경만 들어갔는지 살핀다. 이어 문법 검사 명령이 경고나 오류 없이 끝나는지 확인한다. 마지막으로 python3 main.py를 실행해 assert가 통과하고 정해진 다섯 줄이 나오는지 비교한다. AI가 제공한 예상 출력과 자신의 터미널에서 나온 실제 출력은 구분해서 기록한다.

여기까지 확인한 main.py를 남겨 둔다. 다음 장에서는 지금 목록에 모은 기록을 JSON 파일에 저장하고 다시 불러오는 기능을 붙인다.

오탈자·오류 제보 비공개로 접수되어 원고 수정에 반영됩니다

이메일 등 개인정보는 받지 않습니다. 답변이 필요한 질문은 아래 댓글을 이용해 주세요.

READER FEEDBACK

질문·의견

내용에 관한 질문이나 더 나은 설명을 위한 의견을 남겨 주세요. 오탈자는 위의 제보 양식이 더 빨리 반영됩니다. 이 댓글은 원래 게시글과 같은 자리에 쌓입니다.

댓글 0

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

댓글을 남기려면 로그인이 필요합니다.