🌱
기초 (Basic)
1~9주차 통합 · 프로젝트 설계 · 디버깅
10주차 — 기초 종합 실습
지금까지 배운 입력·조건·반복·자료구조·함수를 자연스럽게 조합해 작은 프로그램을 완성합니다. To-Do List, 단어장 퀴즈, 가계부, 숫자 야구 중 하나를 골라 만들어보세요.
종합실습프로젝트디버깅캡스톤
소요 시간
⏱ 3시간 이상 (분할)
난이도
📊 완전 초보
선수 조건
🎯 1~9주차 전부
결과물
직접 동작하는 콘솔 프로그램 1개 + README + 시연 자료
이 강의에서 배우는 것
- 1지금까지 배운 모든 내용을 합쳐 작은 프로그램을 완성한다
- 2입력·조건·반복·자료구조·함수를 자연스럽게 조합한다
- 3디버깅과 코드 정리 경험을 쌓는다
1. 프로젝트 설계 절차
- 요구사항 정리 — 무엇을 만드는지, 어떤 입출력인지 종이에 적기
- 데이터 구조 결정 — 리스트? 딕셔너리? 둘 다?
- 함수 분리 — 작은 단위로 (입력 받기, 처리, 출력 등)
- 흐름 작성 — main 루프, 종료 조건
- 점진적으로 만들기 — 한 번에 다 짜지 말고 한 기능씩 동작 확인
2. 디버깅 기초
print 디버깅
가장 단순하고 강력한 방법.
python
def calc(x, y):
print(f"DEBUG: x={x}, y={y}")
result = x / y
print(f"DEBUG: result={result}")
return result에러 메시지 읽기
가장 아래의 한 줄이 핵심.
text
Traceback (most recent call last):
File "main.py", line 10, in <module>
print(scores[5])
IndexError: list index out of range→ "10번째 줄에서 리스트 인덱스 범위 초과"
3. 골격 예제 — 미니 To-Do List
examples/todo_skeleton.py 참고. 함수로 분리하고, 메인 루프에서 조립.
4. 자주 하는 실수
- 한꺼번에 모든 기능 구현 시도 — 작게 잘라서 단계별로
- 함수 분리 없이 한 덩어리 코드 — 읽기 어렵고 디버깅 힘듦
- 에러를 try: ... except: pass 로 숨김 — 어디서 뭐가 잘못됐는지 모름
- 변수명을 a, b, temp 로 — 의미 있는 이름 (scores, user_input)
5. FAQ
Q1. 어디서부터 시작해야 할지 모르겠어요.
"프로그램이 시작되면 무엇이 화면에 나오는가" → "사용자가 무엇을 입력하는가" → 그 흐름을 그대로 코드로.
Q2. 막히면 어떻게 해요?
한 줄씩 print로 출력해서 데이터를 확인. 그래도 안 되면 검색 (StackOverflow). 그래도 안 되면 질문.
6. 다음 단계
기초 과정을 마쳤습니다! 🎉
- 중급 과정 — 함수 심화, OOP, 파일 I/O
- 실습 도전 — Lv1 기초응용, Lv2 자료구조 콘솔 프로젝트
💻 예제 (examples)
실제로 실행해 결과를 확인할 수 있는 예제 코드입니다.
todo_skeleton.py— To-Do List 골격 — 함수 분리 + main 루프
CODE
def show_menu():
print("\n[명령] add / list / done <번호> / del <번호> / quit")
def add_todo(todos, text):
todos.append({"text": text, "done": False})
def show_list(todos):
if not todos:
print("(비어 있음)")
return
for i, t in enumerate(todos, start=1):
mark = "x" if t["done"] else " "
print(f"{i}. [{mark}] {t['text']}")
def main():
todos = []
while True:
show_menu()
cmd = input("> ").strip()
if cmd == "quit":
break
elif cmd == "list":
show_list(todos)
elif cmd.startswith("add "):
add_todo(todos, cmd[4:])
print("추가됨")
# done, del 도 비슷한 패턴
if __name__ == "__main__":
main()
▶ 실행 결과
[명령] add / list / done <번호> / del <번호> / quit
> add 우유 사기
추가됨
> list
1. [ ] 우유 사기
> quitdebug_demo.py— print 디버깅 + try-except 맛보기
CODE
def divide(a, b):
print(f"DEBUG: a={a}, b={b}")
try:
result = a / b
except ZeroDivisionError as e:
print(f"에러: {e}")
return None
print(f"DEBUG: result={result}")
return result
print(divide(10, 2))
print(divide(10, 0))
▶ 실행 결과
DEBUG: a=10, b=2
DEBUG: result=5.0
5.0
DEBUG: a=10, b=0
에러: division by zero
None📝 과제 (exercises)
직접 풀어보고, 막힐 때 정답을 펼쳐 비교해보세요.
과제 1
콘솔 To-Do List
목표: 할 일 추가/조회/완료/삭제 명령이 모두 동작하는 콘솔 프로그램.
요구사항
- 데이터 구조: 리스트 + 딕셔너리 조합
- 명령: add, list, done <번호>, del <번호>, quit
- 잘못된 명령 / 존재하지 않는 번호 처리
입출력 예시
> add 우유 사기
추가됨
> list
1. [ ] 우유 사기
2. [x] 책 읽기
> done 1
1번 완료
> del 2
2번 삭제채점
- · 5개 명령 모두 동작 — 60%
- · 잘못된 입력 처리 — 20%
- · 코드 정리(함수 분리) — 20%
▶정답 코드 펼치기 / 접기
SOLUTION
def add_todo(todos, text):
todos.append({"text": text, "done": False})
def list_todos(todos):
if not todos:
print("(비어 있음)")
return
for i, t in enumerate(todos, start=1):
mark = "x" if t["done"] else " "
print(f"{i}. [{mark}] {t['text']}")
def done_todo(todos, idx):
if 1 <= idx <= len(todos):
todos[idx-1]["done"] = True
print(f"{idx}번 완료")
else:
print("번호 오류")
def del_todo(todos, idx):
if 1 <= idx <= len(todos):
del todos[idx-1]
print(f"{idx}번 삭제")
else:
print("번호 오류")
def main():
todos = []
while True:
cmd = input("> ").strip()
if cmd == "quit":
break
elif cmd == "list":
list_todos(todos)
elif cmd.startswith("add "):
add_todo(todos, cmd[4:])
print("추가됨")
elif cmd.startswith("done "):
try:
done_todo(todos, int(cmd[5:]))
except ValueError:
print("숫자를 입력하세요")
elif cmd.startswith("del "):
try:
del_todo(todos, int(cmd[4:]))
except ValueError:
print("숫자를 입력하세요")
else:
print("알 수 없는 명령")
main()
▶ 실행 결과
> add 우유 사기
추가됨
> list
1. [ ] 우유 사기
> done 1
1번 완료
> quit과제 2
단어장 퀴즈
목표: 영-한 단어장으로 랜덤 퀴즈를 출제한다.
요구사항
- 단어장은 코드 안에 딕셔너리로 (10개 이상)
- 10문제 출제 (중복 가능)
- 정답/오답 즉시 알림
- 마지막에 점수 출력
입출력 예시
[1/10] apple의 뜻은? 사과
정답!
[2/10] book의 뜻은? 가방
오답. 정답: 책
...
총점: 7 / 10▶정답 코드 펼치기 / 접기
SOLUTION
import random
vocab = {
"apple": "사과", "book": "책", "cat": "고양이", "dog": "강아지",
"egg": "달걀", "fish": "물고기", "garden": "정원", "house": "집",
"ice": "얼음", "jacket": "재킷",
}
words = list(vocab.keys())
score = 0
for i in range(1, 11):
word = random.choice(words)
answer = input(f"[{i}/10] {word}의 뜻은? ").strip()
if answer == vocab[word]:
print("정답!")
score += 1
else:
print(f"오답. 정답: {vocab[word]}")
print(f"\n총점: {score} / 10")
▶ 실행 결과
[1/10] apple의 뜻은? 사과
정답!
[2/10] book의 뜻은? 가방
오답. 정답: 책
...
총점: 7 / 10과제 3
간이 가계부
목표: 수입/지출을 기록하고 잔액과 카테고리별 합계를 보여준다.
요구사항
- 데이터: [{type, amount, category, memo}, ...]
- 명령: add, list, summary, quit
- summary: 수입 합계, 지출 합계, 잔액, 카테고리별 지출
입출력 예시
> add
수입/지출: 지출
금액: 5000
카테고리: 식비
메모: 점심
추가됨
> summary
수입: 100,000원
지출: 35,000원
잔액: 65,000원
[지출 카테고리별]
식비: 20,000원
교통: 10,000원
기타: 5,000원▶정답 코드 펼치기 / 접기
SOLUTION
entries = []
def add_entry():
t = input("수입/지출: ")
amount = int(input("금액: "))
category = input("카테고리: ")
memo = input("메모: ")
entries.append({"type": t, "amount": amount, "category": category, "memo": memo})
print("추가됨")
def show_summary():
income = sum(e["amount"] for e in entries if e["type"] == "수입")
expense = sum(e["amount"] for e in entries if e["type"] == "지출")
print(f"수입: {income:,}원")
print(f"지출: {expense:,}원")
print(f"잔액: {income - expense:,}원")
cat = {}
for e in entries:
if e["type"] == "지출":
cat[e["category"]] = cat.get(e["category"], 0) + e["amount"]
print("\n[지출 카테고리별]")
for c, v in sorted(cat.items(), key=lambda x: -x[1]):
print(f"{c}: {v:,}원")
while True:
cmd = input("> ").strip()
if cmd == "quit":
break
elif cmd == "add":
add_entry()
elif cmd == "summary":
show_summary()
elif cmd == "list":
for i, e in enumerate(entries, start=1):
print(f"{i}. {e['type']} {e['amount']:,}원 ({e['category']}) {e['memo']}")
▶ 실행 결과
> add
수입/지출: 수입
금액: 100000
카테고리: 월급
메모: 11월 월급
추가됨
> summary
수입: 100,000원
지출: 0원
잔액: 100,000원
> quit