본문 바로가기

코딩과 AI와 자동화/코딩

파이썬 미니 프로젝트: 리스트/딕셔너리 + 함수로 “할 일(To-Do) 관리 프로그램” 완성하기 (파이썬 기초 6편)

반응형

이전 글(파이썬 기초 5편)에서 def / return / 매개변수로 “함수를 쓰는 법”을 정리했다면, 이번 글은 그걸 작동하는 프로그램으로 연결하는 단계입니다.


핵심은 단 하나입니다.

  • 데이터는 리스트/딕셔너리에 저장
  • 입력(Input) / 처리(Process) / 출력(Output)을 함수로 분리
  • 그리고 마지막에 메뉴형 프로그램(콘솔)로 묶어서 “완성”하기

 

이번 글에서 만들 결과물은 “할 일(To-Do) 관리 프로그램”입니다. (가계부 요약기로 확장도 가능하도록 설계합니다.)


왜 To-Do 프로그램이 좋을까?

초보가 가장 많이 검색하는 키워드가 “파이썬 미니 프로젝트 / 리스트 딕셔너리 예제 / 함수로 프로그램 만들기 / 콘솔 메뉴 프로그램” 계열입니다.

To-Do는 기능이 직관적이라 코딩 학습 글인데도 진입장벽이 낮고, 저장/공유도 잘 됩니다.


오늘 만들 프로그램 기능

 

오늘은 “작동”에 집중해서 아래 기능만 넣습니다.

  1. 할 일 추가
  2. 할 일 목록 보기
  3. 완료 처리(체크)
  4. 통계(전체/완료/미완료)

데이터 구조 설계: 리스트 안에 딕셔너리 넣기

가장 깔끔하고 확장 가능한 형태가 이 조합입니다.

 

  • todos는 리스트(list)
  • 각 할 일은 딕셔너리(dict)

 

예시(이런 형태로 저장됩니다):

todos = [
    {"id": 1, "title": "운동 20분", "done": False},
    {"id": 2, "title": "파이썬 복습", "done": True},
]

이 구조를 쓰면 좋은 점:

  • 리스트라서 여러 개를 순서대로 저장하기 쉽고
  • 딕셔너리라서 title, done 같은 의미 있는 키로 관리가 쉽습니다.

함수 설계: 입력/처리/출력을 분리하는 이유

초보가 자주 하는 실수는, 모든 코드를 한 곳에 몰아넣는 것입니다.
대신 아래처럼 역할을 나눕니다.

  • 입력: 사용자로부터 값 받기
  • 처리: 데이터 수정/검색/통계 계산
  • 출력: 화면에 보기 좋게 보여주기

이렇게 나누면:

  • 코드가 길어져도 찾기 쉽고
  • 기능을 추가할 때 덜 부서집니다.
  • 무엇보다 “프로그램처럼 보이는” 형태가 됩니다.

완성 코드: 메뉴형 To-Do 관리 프로그램(복붙 후 바로 실행)

아래 코드는 그대로 복사해서 실행하면 됩니다. (Python 3.x)

def print_menu():
    print("\n===== To-Do 관리 프로그램 =====")
    print("1) 할 일 추가")
    print("2) 할 일 목록 보기")
    print("3) 완료 처리")
    print("4) 통계 보기")
    print("0) 종료")


def add_todo(todos, next_id):
    title = input("할 일을 입력하세요: ").strip()
    if not title:
        print("빈 내용은 추가할 수 없습니다.")
        return next_id  # id 증가 없이 종료

    todos.append({"id": next_id, "title": title, "done": False})
    print(f"추가 완료: [{next_id}] {title}")
    return next_id + 1


def show_todos(todos):
    if not todos:
        print("할 일이 없습니다. 먼저 추가해보세요.")
        return

    print("\n----- 할 일 목록 -----")
    for item in todos:
        mark = "✅" if item["done"] else "⬜"
        print(f'{mark} [{item["id"]}] {item["title"]}')


def complete_todo(todos):
    if not todos:
        print("완료 처리할 할 일이 없습니다.")
        return

    try:
        target_id = int(input("완료 처리할 id를 입력하세요: ").strip())
    except ValueError:
        print("숫자(id)만 입력해주세요.")
        return

    for item in todos:
        if item["id"] == target_id:
            if item["done"]:
                print("이미 완료된 항목입니다.")
            else:
                item["done"] = True
                print(f'완료 처리: [{item["id"]}] {item["title"]}')
            return

    print("해당 id를 찾을 수 없습니다.")


def show_stats(todos):
    total = len(todos)
    done = sum(1 for x in todos if x["done"])
    not_done = total - done

    print("\n----- 통계 -----")
    print(f"전체: {total}")
    print(f"완료: {done}")
    print(f"미완료: {not_done}")

    if total > 0:
        rate = (done / total) * 100
        print(f"완료율: {rate:.1f}%")


def main():
    todos = []
    next_id = 1

    while True:
        print_menu()
        choice = input("메뉴 번호를 선택하세요: ").strip()

        if choice == "1":
            next_id = add_todo(todos, next_id)
        elif choice == "2":
            show_todos(todos)
        elif choice == "3":
            complete_todo(todos)
        elif choice == "4":
            show_stats(todos)
        elif choice == "0":
            print("프로그램을 종료합니다.")
            break
        else:
            print("메뉴 번호를 다시 선택해주세요.")


if __name__ == "__main__":
    main()


“교육 글”답게 체크 포인트 3개만 기억하기

이 프로젝트에서 진짜 중요한 건 기능이 아니라 구조입니다.

 

  1. 리스트/딕셔너리로 데이터 저장: todos = [ {...}, {...} ]
  2. 함수 분리: add / show / complete / stats
  3. main()에서 메뉴로 묶기: 프로그램처럼 실행 흐름 만들기
반응형