AI 개발 · 기본
바이브 코딩 시대의 기본서 - 처음 AI 와 함께 만드는 프로그램
종합 실습 - 나만의 단어장 프로그램 처음부터 끝까지
네 칸 요청문으로 시작, 작게 나눠 시키기(저장·추가·퀴즈·통계), 각 단계마다 실행과 검사, 버전 남기기, 마지막 점검표, 완성 코드는 임시 폴더의 JSON 파일에 단어를 저장하고 seed 고정 퀴즈와 오답 통계를 출력하는 단어장(스크립트로 정해진 입력을 넣어 자동 실행)
개발자KR · 원고 갱신
이 장에서 배우는 것
앞 장에서 AI가 만든 답을 판단하려면 작은 코드라도 직접 읽어 볼 수 있어야 한다는 점을 살펴보았다. 이제 그 판단을 하나의 프로그램에 적용한다. 만들 것은 영어 단어와 뜻을 저장하고, 퀴즈를 낸 뒤, 어떤 단어를 틀렸는지 보여 주는 작은 단어장이다. 기능의 수보다 중요한 것은 각 기능이 약속대로 움직이는지 확인하는 과정이다.
이번 실습은 사람이 키보드로 답을 입력할 때까지 기다리지 않는다. 프로그램 안에 정해진 입력을 넣어 두고 저장, 추가, 퀴즈, 통계를 차례로 실행한다. 실행할 때마다 같은 결과가 나오므로 AI가 코드를 고친 뒤에도 이전 결과와 비교하기 쉽다. 이 장을 마치면 다음 일을 할 수 있다.
- 목적·입력·출력·예시 네 칸으로 프로그램의 범위를 정한다.
- 저장·추가·퀴즈·통계를 나누어 요청하고 단계마다 검사한다.
- 임시 폴더에 저장한 파일을 다시 읽어 저장 결과를 확인한다.
- 변경 전후의 코드와 실행 결과를 비교하고 버전을 남긴다.
- 완성 여부를 마지막 점검표로 판단한다.
문제 상황
외우고 싶은 단어를 메모 파일에 적다 보니 같은 단어를 두 번 적기도 하고, 자주 틀리는 단어가 무엇인지 놓치기도 한다. AI에게 “단어장 프로그램을 만들어 줘”라고 부탁하면 여러 기능이 한꺼번에 붙을 수 있다. 처음 보는 화면과 긴 코드가 생기면 어느 부분이 저장을 담당하는지, 퀴즈 답은 어떻게 채점하는지 확인하기 어렵다.
그래서 이번에는 화면 꾸미기나 회원 가입을 제외하고 세 단어만 다룬다. apple은 사과, book은 책, cat은 고양이로 저장한다. 같은 단어를 다시 추가하면 거절하고, 퀴즈에서는 cat에만 잘못된 답을 넣는다. 통계에 cat의 오답이 한 번으로 나타나면 우리가 정한 작은 시나리오가 끝난다.
파일은 임시 폴더에 만든다. 임시 폴더는 실습에 쓰고 지울 목적으로 운영체제가 마련해 주는 폴더다. 이번 프로그램에서는 실행이 끝날 때 폴더와 파일도 지운다. 따라서 다음 실행까지 단어를 보관하는 개인용 단어장은 아니다. 먼저 한 번의 실행 안에서 파일 저장과 다시 읽기가 제대로 되는지 배우는 실습용 완성본이다.
이 차이는 요청문에 미리 적어야 한다. “저장한다”는 말만으로는 실행이 끝난 뒤에도 남겨야 하는지 알 수 없기 때문이다. AI에게 맡기기 전에 저장의 범위와 종료 조건을 사람이 결정한다.
네 칸 요청문으로 완료 조건을 정한다
요청문의 네 칸은 길게 쓸 필요가 없다. 대신 입력과 출력을 구체적으로 적는다. 여기서 입력은 반드시 키보드 입력만 뜻하지 않는다. 프로그램 안에 미리 적어 둔 단어와 답도 입력이다. 다음 내용을 AI에게 보낼 첫 요청문으로 사용할 수 있다.
목적: 처음 코드를 배우는 사람이 읽고 검사할 수 있는 작은 단어장을 만든다. Python 3.12 이상에서 표준 라이브러리만 사용하고 main.py 한 파일로 작성한다.
입력: apple/사과, book/책, cat/고양이를 순서대로 추가한다. apple/사과를 다시 추가해 중복 거절을 확인한다. 퀴즈 답은 apple에는 사과, book에는 책, cat에는 강아지로 프로그램 안에 미리 정한다.
출력: 추가 결과, 파일에서 다시 읽은 단어 수, 단어별 퀴즈 결과, 정답 수, 단어별 누적 오답 수를 출력한다. 퀴즈는 seed 7로 순서를 섞되 결과 표시는 단어 이름순으로 한다. 임시 폴더의 JSON 파일을 사용하고 종료할 때 삭제한다.
예시: 세 단어를 저장하고 중복 추가는 거절한다. 퀴즈 결과는 3문제 중 2문제 정답이며 cat의 오답 수만 1이다. 실행은 입력을 기다리지 않고 끝나야 한다.
JSON은 목록이나 이름과 값의 쌍을 텍스트로 기록하는 파일 형식이다. 이 실습에서는 단어 하나를 영어, 뜻, 출제 횟수, 오답 횟수로 나누어 기록한다. 파일 이름이 words.json이라고 해서 저장이 저절로 되는 것은 아니다. 코드가 내용을 쓰고, 다시 읽고, 그 결과까지 확인해야 한다.
| 약속 | 검사 방법 | 기대 결과 |
|---|---|---|
| 같은 단어를 중복 저장하지 않는다 | apple을 두 번 추가한다 | 두 번째 추가를 거절하고 세 단어만 남는다 |
| 단어를 파일에 저장한다 | 저장 직후 파일을 다시 읽는다 | 읽은 목록과 메모리의 목록이 같다 |
| 오답만 별도로 센다 | cat에 강아지라고 답한다 | cat의 오답 수가 1이 된다 |
| 입력을 기다리지 않는다 | 실행 명령을 한 번 보낸다 | 결과를 출력하고 종료한다 |
이 표는 AI의 설명보다 먼저 확인할 기준이다. AI가 “모두 구현했다”고 답해도 각 행을 직접 검사한다. 특히 출력에 “저장 완료”라는 문장이 있다는 사실과 실제 파일에 내용이 있다는 사실은 서로 다르다.
저장·추가·퀴즈·통계를 작게 나누어 시킨다
최종 요구를 먼저 공유하더라도 구현 요청은 작게 나눌 수 있다. 첫 단계에서는 파일에 빈 목록을 쓰고 다시 읽는 부분만 만든다. 다음 단계에서 단어 추가와 중복 검사를 붙인다. 그다음 퀴즈를 붙이고 마지막에 통계를 계산한다. 한 단계가 끝날 때마다 실행해야 어느 변경에서 결과가 달라졌는지 알기 쉽다.
먼저 저장과 읽기만 작성해 줘. 임시 폴더에 words.json을 만들고 빈 목록을 저장한 뒤 다시 읽어 같은지 검사해 줘. 임시 경로 자체는 출력하지 말아 줘.
임시 경로에는 실행마다 달라지는 이름이 들어갈 수 있다. 따라서 최종 출력에는 경로를 넣지 않는다. 다음 요청에서는 추가할 부분과 유지할 조건을 함께 적는다.
저장과 읽기 검사를 유지하면서 단어 추가를 붙여 줘. 같은 영어 단어가 있으면 거절하고, 새 단어에는 출제 횟수와 오답 횟수를 0으로 넣어 줘. 예시의 세 단어와 중복 추가 한 번을 자동으로 실행해 줘.
이제 seed 7로 출제 순서를 섞는 퀴즈를 붙여 줘. 답은 요청문에 정한 값으로 자동 공급해 줘. 출제할 때마다 횟수를 늘리고 틀렸을 때만 오답 수를 늘려 줘. 결과는 영어 단어순으로 출력해 줘.
마지막으로 파일을 다시 읽어 통계를 출력해 줘. 정답은 2개, cat의 오답은 1개인지 코드로 검사해 줘. 변경한 부분과 각 검사를 설명해 줘.
seed는 난수 생성의 출발값이다. 같은 방식으로 seed를 지정하면 같은 실행 환경에서 섞는 결과를 재현할 수 있다. 다만 이 프로그램은 섞인 출제 순서와 표시 순서를 분리한다. 채점할 때는 섞인 순서를 쓰고, 결과를 보여 줄 때는 단어순으로 정렬한다. 그래서 독자는 예상 출력과 실제 출력을 쉽게 맞춰 볼 수 있다.
AI의 답에서 “검사했다”는 표현을 발견하면 어떤 입력으로 실행했는지 확인한다. 실행 기록이 없으면 자신의 터미널에서 실행한다. 코드가 길어졌다는 사실은 진행의 근거가 되지 않는다. 작은 약속이 하나씩 통과하는 것이 진행의 근거다.
파일 확인과 버전 기록을 작업의 일부로 둔다
프로그램이 실행 중에 들고 있는 값과 파일에 적힌 값은 구분해야 한다. 단어 목록에 새 항목을 넣었어도 파일 쓰기를 하지 않으면 파일 내용은 예전 상태다. 반대로 파일에 잘 썼어도 프로그램이 다른 값을 출력하면 결과를 잘못 이해할 수 있다. 이번 코드는 추가 직후와 퀴즈 직후에 파일을 읽어 두 상태가 같은지 확인한다.
검사에는 assert라는 문장을 사용한다. assert 뒤의 조건이 참이면 계속 진행하고, 거짓이면 그 자리에서 실행을 멈추며 오류를 낸다. 정상일 때 별도 문구가 나오지 않으므로 예상 출력이 끝까지 나오는지 함께 본다. 이는 이번 실습의 작은 검사 장치다. 사용자가 잘못 입력한 내용을 안내하는 기능과는 역할이 다르다.
실행이 통과한 뒤에는 main.py를 별도 보관 폴더에 복사해 둔다. 예를 들어 저장만 통과한 파일은 main_v1.py, 추가까지 통과한 파일은 main_v2.py로 남길 수 있다. 보관 파일은 실행용 main.py와 구분되는 폴더에 둔다. 각 파일 옆에는 어떤 입력과 결과를 확인했는지 짧게 기록한다.
다음 변경을 받으면 차이 비교(diff)로 바뀐 줄을 읽는다. 비교 도구는 두 파일에서 추가·삭제·수정된 부분을 보여 준다. 퀴즈만 요청했는데 파일 경로나 중복 검사까지 바뀌었다면 이유를 확인하고 다시 검사한다. 파일 복사는 되돌아갈 지점을 만들고, 차이 비교는 무엇이 달라졌는지 알려 준다.
변경 전 파일을 before.py로 보관했다면 터미널에서 diff -u before.py main.py로 비교할 수 있다. 이 명령은 프로그램 실행 명령과 별도로 사용한다. 차이가 있으면 비교 내용이 출력되며 종료 상태가 1일 수 있다.
실행 결과도 버전과 함께 남긴다. “잘 됨”보다 “단어 3개, 정답 2/3, cat 오답 1 확인”이 나중에 더 유용하다. 이번 실습에서는 저장, 추가, 퀴즈, 통계가 각각 통과한 시점을 기록하면 충분하다.
완성 코드
다음 코드를 main.py에 저장한다. 빈 줄을 포함해 90줄 이내이며 외부 패키지는 필요하지 않다. 파일을 만들고 지우는 범위는 프로그램이 만든 임시 폴더 안이다. 단어 추가 결과 네 줄이 먼저 나오고, 파일 확인과 퀴즈 및 통계가 이어진다.
import json
import random
import tempfile
from pathlib import Path
def save_words(path, words):
text = json.dumps(words, ensure_ascii=False, indent=2)
path.write_text(text, encoding="utf-8")
def load_words(path):
return json.loads(path.read_text(encoding="utf-8"))
def add_word(path, words, english, meaning):
if any(word["english"] == english for word in words):
return False
words.append({
"english": english,
"meaning": meaning,
"asked": 0,
"wrong": 0,
})
save_words(path, words)
return True
def run_quiz(path, words, answers):
questions = words.copy()
random.Random(7).shuffle(questions)
results = []
for word in questions:
english = word["english"]
answer = answers[english]
correct = answer == word["meaning"]
word["asked"] += 1
if not correct:
word["wrong"] += 1
results.append((english, answer, correct))
save_words(path, words)
return sorted(results)
def main():
with tempfile.TemporaryDirectory() as folder:
path = Path(folder) / "words.json"
save_words(path, [])
words = load_words(path)
assert words == []
additions = [
("apple", "사과"), ("book", "책"),
("cat", "고양이"), ("apple", "사과"),
]
for english, meaning in additions:
added = add_word(path, words, english, meaning)
status = "추가" if added else "중복 거절"
print(f"{english}: {status}")
assert len(words) == 3
assert load_words(path) == words
print(f"파일 확인: {len(words)}개")
answers = {"apple": "사과", "book": "책", "cat": "강아지"}
results = run_quiz(path, words, answers)
correct_count = sum(correct for _, _, correct in results)
assert correct_count == 2
print("퀴즈 결과")
for english, answer, correct in results:
label = "정답" if correct else "오답"
print(f"{english}: {answer} - {label}")
print(f"정답 수: {correct_count}/{len(results)}")
saved = load_words(path)
assert saved == words
assert all(word["asked"] == 1 for word in saved)
assert {w["english"]: w["wrong"] for w in saved} == {
"apple": 0, "book": 0, "cat": 1,
}
print("오답 통계")
for word in sorted(saved, key=lambda item: item["english"]):
print(f'{word["english"]}: {word["wrong"]}/{word["asked"]}')
print("임시 폴더 정리 완료")
if __name__ == "__main__":
main()
줄별 해설
같은 일을 하는 줄끼리 묶어 읽는다. 먼저 import로 시작하는 네 줄은 필요한 도구를 가져온다. json은 파일에 기록할 텍스트를 만들고 읽는다. random은 출제 순서를 섞는다. tempfile은 임시 폴더를 마련한다. pathlib에서 가져온 Path는 폴더와 파일의 경로를 다루는 도구다.
def는 이름을 붙인 작업 묶음인 함수를 정의한다. 괄호 안 이름은 함수를 부를 때 전달받을 값이다. save_words의 path는 저장할 위치이고 words는 단어 목록이다. 들여쓴 줄은 그 함수에 속한다. 들여쓰기를 지우거나 임의로 바꾸지 않는다.
json.dumps는 목록을 JSON 텍스트로 바꾼다. ensure_ascii=False는 한글을 읽을 수 있는 문자로 남기고, indent=2는 내용을 들여써서 보기 쉽게 만든다. write_text는 그 텍스트를 파일에 쓴다. encoding="utf-8"은 한글을 저장하고 읽는 문자 처리 방식을 명시한다. load_words에서는 read_text로 읽은 텍스트를 json.loads로 다시 목록으로 바꾸어 돌려준다.
add_word의 첫 조건은 목록에 같은 영어 단어가 하나라도 있는지 확인한다. any는 안쪽 검사 중 하나라도 참이면 참이 된다. 이 코드에서 중복은 영어 문자열이 정확히 같은 경우다. 대문자 Apple과 소문자 apple을 같은 단어로 처리하는 기능은 넣지 않았다. 중복이면 return False로 함수를 끝내므로 추가와 파일 쓰기를 건너뛴다.
words.append는 목록 끝에 단어 하나를 붙인다. 중괄호 안의 영어, 뜻, 두 횟수는 이름과 값을 짝지어 담는 사전이다. asked와 wrong은 각각 출제 횟수와 오답 횟수다. 새 단어의 두 값은 0에서 시작한다. 추가한 다음에는 save_words로 파일을 갱신하고 True를 돌려준다.
run_quiz의 words.copy()는 목록의 순서를 따로 바꿀 수 있도록 얕은 복사본을 만든다. 얕은 복사는 바깥 목록만 새로 만들고 그 안의 단어 사전은 함께 가리킨다. 따라서 questions를 섞어도 원래 목록 순서는 유지되지만, 단어 사전의 횟수를 바꾸면 words에서도 그 변경이 보인다. 이번 코드에서는 이 성질을 이용해 채점 뒤 words를 저장한다.
random.Random(7)은 seed가 7인 난수 도구를 만든다. shuffle은 questions 자체의 순서를 섞는다. for는 섞인 목록에서 단어를 하나씩 꺼내 같은 작업을 반복한다. answers[english]는 해당 영어 단어에 미리 배정한 답을 꺼낸다. 출제 순서가 바뀌어도 cat에는 강아지라는 답이 들어간다.
==는 두 값이 같은지 비교한다. answer와 저장된 뜻이 같으면 correct가 True가 된다. asked의 += 1은 기존 출제 횟수에 1을 더한다. if not correct는 틀렸을 때만 안쪽 줄을 실행한다. 결과 목록에는 영어, 입력한 답, 정답 여부를 한 묶음으로 넣는다. 마지막에 파일을 저장하고 sorted로 결과를 정렬해 돌려준다. 결과 묶음의 첫 값이 영어이므로 영어 단어순으로 정렬된다.
main은 실습의 순서를 모은 함수다. with tempfile.TemporaryDirectory()는 임시 폴더를 만들고, 들여쓴 작업이 끝나면 정리한다. Path(folder) / "words.json"에서 /는 숫자 나눗셈이 아니라 경로를 이어 붙이는 역할을 한다. 빈 목록을 먼저 저장하고 읽어 파일의 시작 상태부터 검사한다.
additions는 정해진 추가 입력 네 개를 담은 목록이다. for english, meaning은 각 묶음에서 영어와 뜻을 나누어 받는다. status를 정하는 줄은 added가 참이면 추가, 거짓이면 중복 거절을 선택한다. f로 시작하는 문자열은 중괄호 안 값을 출력 문장에 끼워 넣는다. 그다음 assert 두 줄로 단어 수와 파일 내용을 확인한다.
answers는 자동으로 공급할 퀴즈 답이다. sum은 정답 여부를 합산한다. 이 계산에서 True는 1, False는 0으로 더해진다. 밑줄 이름 _는 여기서 사용하지 않을 영어와 답을 받는 표시다. 결과를 출력하는 반복문에서는 정답 여부에 따라 표시 문구를 정한다.
saved에는 퀴즈 뒤 파일을 다시 읽은 목록을 넣는다. all은 모든 단어의 출제 횟수가 1인지 확인한다. 그다음 중괄호로 만든 비교용 사전은 영어별 오답 수가 기대값과 같은지 검사한다. 통계 출력의 key=lambda는 정렬 기준을 짧게 적는 표현이다. 여기서는 각 항목의 english 값을 기준으로 정렬한다.
정리 완료 문장은 with의 들여쓰기 바깥에 있다. 따라서 폴더 정리가 끝난 다음 출력된다. 마지막 두 줄은 이 파일을 직접 실행했을 때 main을 호출하는 시작점이다. 함수를 정의하는 것만으로는 실습이 시작되지 않으므로 이 호출이 필요하다.
실행 결과
터미널에서 main.py가 있는 폴더로 이동한 뒤 다음 명령을 실행한다. 아래 인용문은 명령이고, 이어지는 상자는 프로그램의 예상 출력이다.
python3 main.py
apple: 추가
book: 추가
cat: 추가
apple: 중복 거절
파일 확인: 3개
퀴즈 결과
apple: 사과 - 정답
book: 책 - 정답
cat: 강아지 - 오답
정답 수: 2/3
오답 통계
apple: 0/1
book: 0/1
cat: 1/1
임시 폴더 정리 완료
통계의 0/1은 한 번 출제해서 오답이 0번이라는 뜻이다. cat의 1/1은 한 번 출제해서 한 번 틀렸다는 뜻이다. 정답 수와 통계의 분자가 서로 다른 것을 확인한다. 정답 수의 분자는 맞힌 개수이고, 오답 통계의 분자는 틀린 개수다.
한 번 더 실행해도 같은 출력이 나와야 한다. 매번 새 임시 폴더를 만들기 때문에 두 번째 실행의 cat 오답 수가 2로 늘어나지는 않는다. 누적은 한 번의 실행 안에서 같은 단어 목록을 계속 사용할 때를 뜻한다. 이후 영구 보관 기능으로 확장한다면 실행 사이의 누적을 별도로 검사해야 한다.
실무에서 자주 틀리는 것
목록만 바꾸고 저장했다고 생각한다
메모리에 담긴 목록이 바뀌어도 이미 기록한 파일은 자동으로 갱신되지 않는다. 다음 두 코드는 차이를 보여 주는 독립 실행 예다. 틀린 예에서는 파일에 쓰기 전에 만든 텍스트를 사용한다.
import json
words = []
text = json.dumps(words)
words.append({"english": "apple"})
print(json.loads(text))
[]
고친 예에서는 목록을 바꾼 다음 저장할 텍스트를 만든다. 완성 코드의 add_word에서도 추가 뒤에 save_words를 호출한다.
import json
words = []
words.append({"english": "apple"})
text = json.dumps(words)
print(json.loads(text))
[{'english': 'apple'}]
맞힌 단어도 오답으로 센다
오답 수를 늘리는 줄이 조건문 바깥에 있으면 정답에도 오답이 쌓인다. 틀린 예에서는 correct가 참인데도 wrong이 늘어난다.
correct = True
wrong = 0
wrong += 1
print(wrong)
1
고친 예에서는 틀린 경우에만 증가시킨다. 이때 들여쓰기가 실행 조건을 결정한다.
correct = True
wrong = 0
if not correct:
wrong += 1
print(wrong)
0
기존 목록을 가리키는 것을 복사라고 생각한다
다른 이름에 대입하는 것만으로는 새 목록이 생기지 않는다. 틀린 예에서는 questions와 words가 같은 목록을 가리켜 원래 순서까지 바뀐다.
words = ["apple", "book"]
questions = words
questions.reverse()
print(words)
['book', 'apple']
고친 예는 목록을 복사해 순서를 따로 바꾼다. 다만 안쪽에 사전이 들어 있으면 사전까지 새로 만들어지는 것은 아니라는 점을 완성 코드와 함께 기억한다.
words = ["apple", "book"]
questions = words.copy()
questions.reverse()
print(words)
['apple', 'book']
한눈에 보기
마지막 점검은 “실행됐다” 한 항목으로 끝내지 않는다. 입력, 저장, 채점, 출력, 되돌릴 지점을 나누어 본다. 다음 표를 실제 실행 결과와 대조하면 마무리할 수 있다.
| 점검 대상 | 통과 기준 | 확인 근거 |
|---|---|---|
| 요청 범위 | 네 칸의 목적과 예시를 충족한다 | 단어 추가부터 통계까지 연결된다 |
| 자동 실행 | 키보드 입력 없이 종료한다 | 마지막 정리 문구까지 출력된다 |
| 중복 처리 | 두 번째 apple을 거절한다 | 단어 수가 3이다 |
| 파일 저장 | 다시 읽은 값이 목록과 같다 | 추가 뒤와 퀴즈 뒤 검사가 통과한다 |
| 채점과 통계 | 정답 2개, cat 오답 1개다 | 기대값 검사와 출력이 일치한다 |
| 반복 가능성 | 다시 실행해도 출력이 같다 | seed와 입력이 고정되어 있다 |
| 변경 검토 | 요청과 바뀐 줄의 관계를 설명한다 | 이전 파일과 차이를 읽었다 |
| 버전 보관 | 통과한 코드와 결과가 남아 있다 | 별도 보관본과 검사 메모가 있다 |
이 프로그램은 공백을 정리하거나 뜻이 여러 개인 단어를 처리하지 않는다. 정답 비교도 문자열이 정확히 같은지로 판단한다. 이런 제한을 요청문과 코드에서 설명할 수 있다면 현재 완성 범위를 이해한 것이다. 다음 기능이 필요해지면 기대 입력과 출력을 먼저 추가한 뒤 작은 변경으로 진행한다.
연습 문제
- cat의 자동 답을 고양이로 바꾸려 한다. 실행 전에 정답 수와 오답 통계가 어떻게 달라질지 적고, 입력과 검사 조건을 함께 수정한다.
- 한 번의 실행 안에서 같은 답으로 퀴즈를 두 번 실시하려 한다. 두 번째 퀴즈까지 끝난 뒤 각 단어의 출제 횟수와 오답 횟수를 예상한다. AI에게 보낼 요청문도 작성한다.
- 단어장에 dog/개를 추가하고 정답을 공급하려 한다. 바꿔야 할 입력, 검사 조건, 예상 출력을 적는다. 한 곳만 수정했을 때 생길 수 있는 문제도 설명한다.
- 통계 기능을 붙인 뒤 파일 읽기 검사가 사라졌다. 출력은 예상과 같다. 이 변경을 그대로 받아들일지 판단하고, AI에게 보낼 수정 요청과 다시 확인할 항목을 적는다.
정답과 해설
첫 번째 문제에서는 answers의 cat 값을 고양이로 바꾼다. 정답 수 검사는 3으로, 영어별 오답 수 검사의 cat 값은 0으로 수정한다. 출력에서는 cat이 정답으로 바뀌고 정답 수가 3/3, cat의 오답 통계가 0/1이 된다. 입력만 바꾸고 기존 검사를 그대로 두면 assert가 멈춘다. 요구가 달라질 때 기대값도 함께 바꾸어야 한다.
두 번째 문제에서는 모든 단어의 출제 횟수가 2가 된다. apple과 book의 오답 수는 0이고 cat의 오답 수는 2다. 통계는 각각 0/2, 0/2, 2/2가 된다. 매 퀴즈의 정답 수는 2/3이다. 두 번째 호출이 끝난 뒤 파일을 다시 읽어 검사해야 한다. 첫 호출 뒤 읽은 saved를 그대로 출력하면 최신 통계가 아니다.
같은 실행 안에서 같은 answers로 퀴즈를 두 번 실행하도록 바꿔 줘. 각 회차의 정답 수를 표시하고, 마지막 파일을 다시 읽어 출제 횟수가 모두 2이며 cat의 오답 수가 2인지 검사해 줘. 변경 전후의 차이와 예상 출력도 설명해 줘.
세 번째 문제에서는 additions에 dog와 개를 넣고 answers에도 dog의 답을 넣는다. 단어 수 검사는 4, 정답 수 검사는 3으로 바꾼다. 오답 비교용 사전에 dog의 값 0도 추가한다. 모든 단어의 출제 횟수는 여전히 1이다. 출력에는 dog 추가, 파일 확인 4개, dog 정답, 정답 수 3/4, dog 통계 0/1이 반영된다. 추가 입력만 넣으면 퀴즈가 answers에서 dog를 찾지 못해 멈춘다.
네 번째 문제에서는 출력만으로 저장을 확인할 수 없으므로 파일 읽기 검사를 복구한다. 통계를 메모리 값으로 출력하면 파일 저장이 빠졌어도 같은 화면이 나올 수 있다. 차이 비교에서 사라진 읽기와 검사 줄을 확인하고, 복구한 뒤 정해진 실행을 다시 수행한다.
통계 출력 전에 파일을 다시 읽는 처리와 저장값 비교 검사를 복구해 줘. 읽은 값으로 통계를 출력하고, 출제 횟수와 영어별 오답 수도 검사해 줘. 요청한 통계 기능과 관계없이 삭제된 검사가 더 있는지 변경 전 파일과 비교해 설명해 줘.
작은 단어장을 완성하는 동안 사람이 맡은 일은 코드를 모두 타이핑하는 것이 아니었다. 무엇을 만들지 정하고, 확인할 입력을 고르고, 실제 결과를 읽고, 바뀐 줄을 검토했다. 다음 프로그램에서도 먼저 가장 작은 예시 하나를 정한다. 그 예시가 실행과 검사를 통과할 때마다 다음 기능을 붙이면 자신이 설명할 수 있는 프로그램을 조금씩 넓혀 갈 수 있다.
READER FEEDBACK
질문·의견
내용에 관한 질문이나 더 나은 설명을 위한 의견을 남겨 주세요. 오탈자는 위의 제보 양식이 더 빨리 반영됩니다. 이 댓글은 원래 게시글과 같은 자리에 쌓입니다.
댓글 0
아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.