데이터 프로젝트 미니 실습
데이터 프로젝트 미니 실습: 리스트+딕셔너리로 “간단 메모장” 만들기
이전까지 리스트, 딕셔너리, 문자열, 파일 입출력까지 쭉 달려왔잖아요?
그래서 이번 3-5는 “드디어 써먹는 날”입니다. 사실은 솔직히 말하면, 공부만 하다 보면 금방 손이 멈추더라고요. 그래서 오늘은 데이터 관리 프로그램을 아주 작게라도 완성해볼게요. 나름 실속 있게요!
이번에 만들 프로그램: 할 일(또는 메모) 관리기
기능은 일부러 단순하게 잡을 거예요.
- 메모/할 일 추가
- 목록 보기
- 삭제
- (중요) 파일로 저장하고, 다시 실행하면 불러오기
즉, “데이터 구조 감 잡기 + 파일 저장 감각”까지 한 번에 갑니다. 어때요, 좀 기대되지 않나요? 😄
준비물: 우리가 써먹을 자료구조
여기서 감이 확 와야 다음 챕터(알고리즘 흐름)로도 자연스럽게 넘어가요.
- 리스트: “메모 목록”을 한 줄에 쭉 모아두기
- 딕셔너리: 각 메모의 속성(제목/내용/시간 같은 거)을 묶기
- 문자열: 입력값 다루기, 파일 저장용 문자열 만들기
- 파일 입출력: 프로그램 종료 후에도 데이터 유지하기
최종 목표 코드 맛보기 (먼저 전체 흐름)
아래 코드는 “실습용 완성본” 스타일로 작성할게요.
다만 지금 당장 완벽히 이해하려고 애쓰지 말고, 흐름을 먼저 잡는 것이 목표예요.
import json
import os
FILENAME = "memo_data.json"
def load_data():
if not os.path.exists(FILENAME):
return []
with open(FILENAME, "r", encoding="utf-8") as f:
return json.load(f)
def save_data(data):
with open(FILENAME, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
def show_menu():
print("\n=== 데이터 프로젝트: 간단 메모 관리자 ===")
print("1) 추가")
print("2) 목록 보기")
print("3) 삭제")
print("4) 종료")
return input("원하는 번호를 입력하세요: ")
def add_memo(data):
title = input("제목을 입력하세요: ").strip()
if not title:
print("제목은 비면 안 돼요. 음... 한 번 더!")
return
content = input("내용을 입력하세요: ").strip()
# 딕셔너리로 메모 1개를 표현
memo = {
"title": title,
"content": content
}
data.append(memo)
print("저장 완료! 나름 멋지다 😎")
def list_memos(data):
if not data:
print("아직 메모가 없어요. 먼저 추가해볼까요?")
return
print("\n--- 메모 목록 ---")
for i, memo in enumerate(data, start=1):
print(f"{i}) {memo['title']}")
def delete_memo(data):
if not data:
print("삭제할 메모가 없어요.")
return
list_memos(data)
raw = input("삭제할 번호를 입력하세요: ").strip()
try:
idx = int(raw) - 1
if idx < 0 or idx >= len(data):
print("번호가 범위를 벗어났어요. 오타였을 수도! 확인해줘요.")
return
removed = data.pop(idx)
print(f"삭제 완료: {removed['title']}")
except ValueError:
print("숫자를 입력해야 해요. 나 방금... 감탄사만 입력받은 느낌?")
def main():
data = load_data()
save_data(data) # 파일 없으면 생성 흐름을 좀 안정적으로(초기화 느낌)
while True:
choice = show_menu()
if choice == "1":
add_memo(data)
save_data(data)
elif choice == "2":
list_memos(data)
elif choice == "3":
delete_memo(data)
save_data(data)
elif choice == "4":
print("안녕! 데이터는 저장돼 있어요.")
break
else:
print("그런 번호는 없어요. 1~4 중에서 골라줘요!")
if __name__ == "__main__":
main()
코드가 “왜 이렇게” 구성됐는지 쉽게 설명해볼게요
여기서부터가 진짜 중요한 포인트!
내가 예전에 막 만들다가 제일 자주 했던 실패담이 있어요.
“추가만 되는데 저장이 안 돼요…?”
“삭제는 되는데 다시 실행하면 왜 다시 살아있지…?”
이런 거 대부분 파일 저장 타이밍 때문에 생기거든요. 그래서 이번엔 일부러 저장을 확실히 넣었습니다.
1) load_data() : 실행할 때 파일 읽기
- 파일이 없으면 빈 리스트
[]로 시작 - 있으면 JSON으로 읽어서 리스트 형태로 반환
리스트는 “메모 여러 개”를 담는 그릇이죠.
2) save_data(data) : 바뀔 때마다 저장
추가/삭제하고 나면 바로 저장합니다.
솔직히 말하면, 처음엔 저장을 “마지막에 한 번만” 하고 싶어져요.
근데 그러면 중간에 실수로 종료되면 데이터가 증발해요… 😭
그래서 저는 “바뀔 때마다 저장”을 선택했어요. 안전하게!
3) 메모 1개는 딕셔너리로
memo = {
"title": title,
"content": content
}
이렇게 하면 나중에 메모를 확장하기 좋아요. 예를 들면:
created_attagspriority
같은 것도 나중에 그냥 필드만 추가하면 되거든요.
사실은 딕셔너리가 “데이터 묶음”에 딱이에요.
직접 해보기: 입력 실수 대비 작은 팁
여기서 제가 좋아하는 방식 하나!
프로그램이 틀렸을 때 그냥 터지지 않고, “친절하게 다시 입력해라”가 나오게 했어요.
- 삭제할 때 숫자가 아니면
ValueError처리 - 범위를 벗어나면 안내 메시지
이런 방어 코드가 있으면, 친구가 고장냈을 때도 안 부서지고 계속 돌아가요.
나름 개발의 재미가 여기서 나옵니다. 아! 그리고 유머도요. 😅
간단 확장 미션 (선택!)
오늘 실습을 “끝”내기 싫으면, 딱 하나만 더 추가해보면 좋아요.
- 제목으로 검색하기
- 목록에서 제목에 포함된 메모만 보여주기
- 내용 길이 제한
- 너무 길면 자르거나 경고하기
- 중복 제목 허용/제한
- 같은 제목이면 추가하지 말기
이 중에 하나만 해도, 다음 챕터에서 “문제 해결 흐름” 잡을 때 엄청 편해져요.
다음 글 예고: 문제 해결 흐름으로 넘어가기
자, 여기까지 오면 우리가 뭘 했는지 정리하면:
- 리스트/딕셔너리로 데이터를 담았고
- 파일로 저장해서 유지했고
- 입력을 받고
- 조건에 따라 동작이 달라졌죠
근데 사실 이제부터가 진짜 재밌는 구간이에요.
다음은 4-1. 문제 해결 흐름 이해하기로 갑니다.
“어떤 문제를 만나면, 어떻게 풀 순서(흐름)를 잡아야 하는지”를
이 실습처럼 자연스럽게 연결해서 다룰 거예요.
원하면, 내가 이 미니 프로젝트를 좀 더 ‘예쁘게’ 바꾼 버전(번호 대신 고유 ID 부여, 검색/수정 기능 추가)도 다음에 같이 만들어줄게요.
지금은 어떤 확장을 해보고 싶어요?





