1. 프로젝트 목표
지금까지 배운 파이썬 기초 문법을 모두 활용하여 간단한 ‘주소록 관리 프로그램’을 만들어 봅니다. 이 프로젝트를 통해 변수, 자료구조, 조건문, 반복문, 함수, 파일 입출력 등 핵심적인 개념들을 실제로 어떻게 사용하는지 경험하게 될 것입니다.
2. 핵심 사용 개념
- 변수와 자료구조: 주소록 데이터를 저장하기 위해 딕셔너리(
Dictionary)를 사용합니다. - 제어문:
if-elif-else를 사용하여 사용자의 메뉴 선택에 따라 다른 기능을 수행합니다. - 반복문:
while문을 사용해 프로그램이 종료되지 않고 계속해서 사용자 입력을 받을 수 있도록 합니다.for문을 사용해 주소록의 모든 연락처를 출력합니다. - 함수: 각 기능(추가, 보기, 검색, 삭제 등)을 별도의 함수로 만들어 코드의 재사용성과 가독성을 높입니다.
- 파일 입출력: 주소록 데이터를 파일(
contacts.txt)에 저장하고, 프로그램 시작 시 파일에서 데이터를 읽어와서 프로그램이 종료되어도 데이터가 유지되도록 합니다.
3. 구현할 기능 명세
- 연락처 추가: 새로운 이름과 전화번호를 주소록에 추가합니다.
- 연락처 전체 보기: 주소록에 저장된 모든 연락처 정보를 출력합니다.
- 연락처 검색: 이름으로 특정 연락처를 찾아 전화번호를 출력합니다.
- 연락처 삭제: 이름으로 특정 연락처를 찾아 주소록에서 삭제합니다.
- 파일 저장 및 불러오기: 프로그램 종료 시 연락처 정보를 파일에 자동으로 저장하고, 시작 시 자동으로 불러옵니다.
- 종료: 프로그램을 종료합니다.
4. 단계별 제작 가이드
1단계: 프로젝트 파일 준비
먼저, 프로젝트를 진행할 폴더에 두 개의 파일을 생성합니다.
main.py: 파이썬 코드를 작성할 메인 파일입니다.contacts.txt: 연락처 데이터가 저장될 텍스트 파일입니다. 처음에는 빈 파일로 만들어 둡니다.
2단계: 주소록 데이터 구조 정의 및 불러오기/저장하기 함수 작성
우리는 주소록 데이터를 파이썬의 딕셔너리로 관리할 것입니다. {'이름': '전화번호'} 형태로 말이죠.
main.py 파일에 파일에서 연락처를 불러오고, 파일에 연락처를 저장하는 함수를 먼저 작성합니다.
# main.py
# 1. 파일에서 주소록 불러오기
def load_contacts():
contacts = {}
try:
with open("contacts.txt", "r") as file:
for line in file:
name, phone = line.strip().split(',')
contacts[name] = phone
except FileNotFoundError:
# 파일이 없는 경우, 빈 딕셔너리 반환
pass
return contacts
# 2. 주소록을 파일에 저장하기
def save_contacts(contacts):
with open("contacts.txt", "w") as file:
for name, phone in contacts.items():
file.write(f"{name},{phone}\n")
load_contacts:contacts.txt파일을 열어 한 줄씩 읽고, 쉼표(,)를 기준으로 이름과 전화번호를 분리하여 딕셔너리에 저장합니다. 파일이 없으면FileNotFoundError가 발생하지만,try-except로 처리하여 프로그램이 중단되지 않고 빈 딕셔너리를 반환하도록 합니다.save_contacts: 주소록 딕셔너리를 파일에 저장합니다. 각 항목은 “이름,전화번호” 형식으로 한 줄씩 저장됩니다.
3단계: 메뉴 출력 및 사용자 입력 처리 반복문 작성
사용자에게 어떤 기능을 제공하는지 보여주고, 선택을 받아 처리하는 메인 루프를 만듭니다.
# main.py 이어서...
def main():
# 프로그램 시작 시 주소록을 불러옵니다.
contacts = load_contacts()
while True:
print("\n--- 주소록 관리 프로그램 ---")
print("1. 연락처 추가")
print("2. 연락처 전체 보기")
print("3. 연락처 검색")
print("4. 연락처 삭제")
print("5. 종료")
print("--------------------------")
choice = input("원하는 기능의 번호를 입력하세요: ")
if choice == '1':
# 연락처 추가 기능 (나중에 함수로 만듭니다)
pass
elif choice == '2':
# 연락처 전체 보기 기능 (나중에 함수로 만듭니다)
pass
elif choice == '3':
# 연락처 검색 기능 (나중에 함수로 만듭니다)
pass
elif choice == '4':
# 연락처 삭제 기능 (나중에 함수로 만듭니다)
pass
elif choice == '5':
# 프로그램 종료 전 주소록 저장
save_contacts(contacts)
print("프로그램을 종료합니다. 변경사항이 저장되었습니다.")
break
else:
print("잘못된 입력입니다. 1부터 5까지의 숫자를 입력해주세요.")
# 프로그램의 시작점
if __name__ == "__main__":
main()
main함수 안에서while True무한 루프를 돌며 메뉴를 보여줍니다.- 사용자가 ‘5’를 입력하면
save_contacts함수를 호출해 현재까지의 변경사항을 파일에 저장하고break를 통해 루프를 빠져나가 프로그램을 종료합니다.
4단계: 각 기능별 함수 구현
이제 각 메뉴에 해당하는 기능을 함수로 만들어 main 함수의 if 문 안에서 호출하도록 코드를 완성합니다.
# 연락처 추가 함수
def add_contact(contacts):
name = input("추가할 이름: ")
phone = input("전화번호: ")
contacts[name] = phone
print(f"'{name}'님의 연락처가 추가되었습니다.")
# 연락처 전체 보기 함수
def view_all_contacts(contacts):
if not contacts:
print("주소록이 비어있습니다.")
else:
print("\n--- 전체 주소록 ---")
for name, phone in contacts.items():
print(f"이름: {name}, 전화번호: {phone}")
print("--------------------")
# 연락처 검색 함수
def search_contact(contacts):
name = input("검색할 이름: ")
if name in contacts:
print(f"이름: {name}, 전화번호: {contacts[name]}")
else:
print(f"'{name}'님의 연락처를 찾을 수 없습니다.")
# 연락처 삭제 함수
def delete_contact(contacts):
name = input("삭제할 이름: ")
if name in contacts:
del contacts[name]
print(f"'{name}'님의 연락처가 삭제되었습니다.")
else:
print(f"'{name}'님의 연락처를 찾을 수 없습니다.")
5단계: 완성된 코드로 합치기
이제 위에서 만든 함수들을 main 함수와 연결하여 전체 프로그램을 완성합니다.
main 함수의 if 문 안에 있던 pass 키워드를 지우고 각 기능에 맞는 함수를 호출하도록 수정합니다.
# main 함수의 if문 수정 부분
...
if choice == '1':
add_contact(contacts)
elif choice == '2':
view_all_contacts(contacts)
elif choice == '3':
search_contact(contacts)
elif choice == '4':
delete_contact(contacts)
...
5. 전체 코드
# main.py
# 1. 파일에서 주소록 불러오기
def load_contacts():
"""
contacts.txt 파일에서 주소록을 불러와 딕셔너리로 반환합니다.
파일이 없으면 빈 딕셔너리를 반환합니다.
"""
contacts = {}
try:
with open("contacts.txt", "r", encoding='utf-8') as file:
for line in file:
# 빈 줄이 있을 경우 건너뛰기
if not line.strip():
continue
name, phone = line.strip().split(',')
contacts[name] = phone
except FileNotFoundError:
pass
return contacts
# 2. 주소록을 파일에 저장하기
def save_contacts(contacts):
"""
주소록 딕셔너리를 contacts.txt 파일에 저장합니다.
"""
with open("contacts.txt", "w", encoding='utf-8') as file:
for name, phone in contacts.items():
file.write(f"{name},{phone}\n")
# 3. 연락처 추가 함수
def add_contact(contacts):
"""
사용자로부터 이름과 전화번호를 입력받아 주소록에 추가합니다.
"""
name = input("추가할 이름: ")
phone = input("전화번호: ")
contacts[name] = phone
print(f"'{name}'님의 연락처가 추가되었습니다.")
# 4. 연락처 전체 보기 함수
def view_all_contacts(contacts):
"""
주소록에 있는 모든 연락처를 출력합니다.
"""
if not contacts:
print("주소록이 비어있습니다.")
else:
print("\n--- 전체 주소록 ---")
for name, phone in contacts.items():
print(f"이름: {name}, 전화번호: {phone}")
print("--------------------")
# 5. 연락처 검색 함수
def search_contact(contacts):
"""
사용자로부터 이름을 입력받아 해당 연락처를 검색하고 출력합니다.
"""
name = input("검색할 이름: ")
if name in contacts:
print(f"이름: {name}, 전화번호: {contacts[name]}")
else:
print(f"'{name}'님의 연락처를 찾을 수 없습니다.")
# 6. 연락처 삭제 함수
def delete_contact(contacts):
"""
사용자로부터 이름을 입력받아 해당 연락처를 삭제합니다.
"""
name = input("삭제할 이름: ")
if name in contacts:
del contacts[name]
print(f"'{name}'님의 연락처가 삭제되었습니다.")
else:
print(f"'{name}'님의 연락처를 찾을 수 없습니다.")
# 7. 메인 로직
def main():
"""
프로그램의 주 로직을 담당하며, 사용자 메뉴를 출력하고 입력을 처리합니다.
"""
# 프로그램 시작 시 주소록을 불러옵니다.
contacts = load_contacts()
while True:
print("\n--- 주소록 관리 프로그램 ---")
print("1. 연락처 추가")
print("2. 연락처 전체 보기")
print("3. 연락처 검색")
print("4. 연락처 삭제")
print("5. 종료")
print("--------------------------")
choice = input("원하는 기능의 번호를 입력하세요: ")
if choice == '1':
add_contact(contacts)
elif choice == '2':
view_all_contacts(contacts)
elif choice == '3':
search_contact(contacts)
elif choice == '4':
delete_contact(contacts)
elif choice == '5':
# 프로그램 종료 전 주소록 저장
save_contacts(contacts)
print("프로그램을 종료합니다. 변경사항이 저장되었습니다.")
break
else:
print("잘못된 입력입니다. 1부터 5까지의 숫자를 입력해주세요.")
# 프로그램의 시작점
if __name__ == "__main__":
main()
참고: 한글이 깨지지 않도록 open() 함수에 encoding='utf-8' 옵션을 추가했습니다.
6. 추가 도전 과제
프로그램을 완성했다면, 아래 기능들을 추가하여 더 발전시켜 보세요.
- 연락처 수정 기능: 기존 연락처의 전화번호를 수정하는 기능을 추가해 보세요.
- 입력값 검증: 전화번호를 입력할 때 숫자와 하이픈(-)만 입력받도록 확인하는 로직을 추가해 보세요.
- 상세 정보 추가: 전화번호 외에 이메일, 생일 등의 정보를 추가로 저장하고 관리할 수 있도록 프로그램을 확장해 보세요. (힌트: 딕셔너리의 값을 단순한 문자열이 아닌 또 다른 딕셔너리로 만들 수 있습니다.
{'홍길동': {'전화번호': '010-1234-5678', '이메일': 'honggildong@nst21c.com'}})
댓글 남기기