언유상씨의 건전한 취미생활
Python으로 전화번호부 프로그램 제작하기 본문
과제 겸 취미생활 겸 해서 전화번호부 프로그램을 제작 해 보았다.
부족한 부분도 많지만 고쳐 나갈 수 있었으면 좋겠다.
1. 전체 코드
print("""
##########
# #
# ########## #
# # # #
### ###
# # #
# # # #
# # # #
# # #
# #
############
--------------------
|PHONE BOOK PROGRAM|
--------------------
""")
name_book = ['김철수','김철수','최영희']
num_book = ['12341234', '23452345', '34563456']
job_book = ['무직', '강사', '청소부']
old_book = [48, 24, 55]
ad_book = ['서울시 동작구', '서울시 강서구', '수원시 영통구']
while True:
mode = int(input("모드를 선택하십시오.\n1. User / 2. Admin / 3. 종료 / 0. 프로그램 정보"))
password_chk = 0
while True:
if (mode == 1):
while True:
order = input('Welcome!\n1. 검색 / 2. 전체조회 \n이 외의 아무키나 누르면 종료됩니다.')
if (order == '1'):
order_1 = int(input('이름으로 검색 : 1 전화번호로 검색 : 2'))
if (order_1 == 1):
name_book_length = len(name_book)
yoso = input('이름을 입력해 주십시오.데이터가 없는 경우 메뉴로 돌아갑니다.')
count = 0
for i in range(0,name_book_length, 1):
if (name_book[i] == yoso):
count = count + 1
if (count == 0):
break
elif (count == 1):
print(name_book[i], num_book[i], job_book[i], old_book[i],ad_book[i])
elif (count >= 2):
same_name = input('%d 명의 중복 인원이 존재합니다.\n확인하고 싶은 사람의 번호를 입력하시오.' % count)
num_book_length = len(num_book)
for i in range (0, num_book_length, 1):
if (num_book[i] == same_name):
print(name_book[i], num_book[i], job_book[i], old_book[i], ad_book[i])
if (order_1 == 2):
yoso_1 = input('전화번호를 입력해 주십시오.데이터가 없는 경우 메뉴로 돌아갑니다.\n(-는 제외) 010)')
num_book_length = len(num_book)
for i in range(0, num_book_length, 1):
if ( num_book[i] == yoso_1):
print(name_book[i], num_book[i], job_book[i], old_book[i], ad_book[i])
elif (order == '2'):
name_book_length = len(name_book)
for i in range(0, name_book_length, 1):
print(name_book[i], num_book[i], job_book[i], old_book[i], ad_book[i])
else:
answer = input('프로그램을 종료할까요? [y] / [n]')
if (answer == 'y'):
exit()
else:
print('메뉴로 돌아갑니다.')
elif (mode == 2):
password = input('암호를 입력하십시오\n(0번을 입력하시면 모드 선택으로 돌아갑니다.)')
if (password == 'pyaming'):
while True:
ms = int(input('Admin Mode\n1. 검색 / 2. 추가 / 3. 삭제 / 4. 수정 / 5. 전체조회 / 6. 로그아웃 / 0. 종료'))
if (ms == 1):
order_1 = int(input('이름으로 검색 : 1 전화번호로 검색 : 2'))
if (order_1 == 1):
name_book_length = len(name_book)
yoso = input('이름을 입력해 주십시오.데이터가 없는 경우 메뉴로 돌아갑니다.')
count = 0
for i in range(0, name_book_length, 1):
if (name_book[i] == yoso):
count = count + 1
if (count == 0):
break
elif (count == 1):
print(name_book[i], num_book[i], job_book[i], old_book[i], ad_book[i])
elif (count >= 2):
same_name = input('%d 명의 중복 인원이 존재합니다.\n확인하고 싶은 사람의 번호를 입력하시오.' % count)
num_book_length = len(num_book)
for i in range(0, num_book_length, 1):
if (num_book[i] == same_name):
print(name_book[i], num_book[i], job_book[i], old_book[i], ad_book[i])
if (order_1 == 2):
yoso_1 = input('전화번호를 입력해 주십시오.데이터가 없는 경우 메뉴로 돌아갑니다.\n(-는 제외) 010)')
num_book_length = len(num_book)
for i in range(0, num_book_length, 1):
if (num_book[i] == yoso_1):
print(name_book[i], num_book[i], job_book[i], old_book[i],ad_book[i])
if (ms == 2):
name = input('이름 :')
num = input('번호(-를 제외해 주십시오) : 010)')
num_chk = list(num)
len_num_chk = len(num_chk)
if (len_num_chk == 8):
num_book_length = len(num_book)
for h in range(0, num_book_length, 1):
count_1 = 0
if (num_book[h] == num):
count_1 = 0
count_1 = count_1 + 1
break
if (count_1 == 0):
job = input('직업 :')
old = input('나이 :')
address = input('주소 :')
name_book.append(name)
num_book.append(num)
job_book.append(job)
old_book.append(old)
ad_book.append(address)
print('추가 되었습니다.')
else:
print('이미 저장된 번호 입니다. 메뉴로 돌아갑니다.')
else:
print('올바르지 못한 형식입니다. 메뉴로 돌아갑니다.')
elif (ms == 3):
num_book_length = len(num_book)
del_data = input('삭제하고 싶은 사람의 이름를 입력하시오. 데이터가 없는 경우 메뉴로 돌아갑니다.')
count = 0
for i in range (0, num_book_length, 1):
if (name_book[i] == del_data):
count = count + 1
if (count == 0):
continue
if (count == 1):
chk = (input('삭제 하시겠습니까? [y]/[n]'))
if (chk == 'y'):
for i in range(0, num_book_length, 1):
num_book_length = len(num_book)
if (name_book[i] == del_data):
del(name_book[i], num_book[i], job_book[i], old_book[i], ad_book[k])
print('삭제가 완료되었습니다.')
break
else :
same_name = input('%d 명의 중복 인원이 존재합니다.\n삭제하고 싶은 사람의 번호를 입력하시오.' % count)
num_book_length = len(num_book)
for k in range (0, num_book_length, 1):
if (num_book[k] == same_name):
del (name_book[k], num_book[k], job_book[k], old_book[k], ad_book[k])
print('삭제가 완료되었습니다.')
break
elif(ms == 4):
change = input('수정하고 싶은 사람의 이름을 입력해 주십시오.')
count = 0
num_book_length = len(num_book)
for i in range(0, num_book_length, 1):
if (name_book[i] == change):
count = count + 1
if (count == 0):
print('존재하지 않는 사람입니다.')
continue
elif (count == 1):
change_chk = int(input('무엇을 수정하시겠습니까?\n1. 이름 / 2. 번호 / 3. 직업 / 4. 나이 / 5. 주소'))
if (change_chk == 1):
change_name = input('무엇으로 수정하시겠습니까?')
name_book_length = len(name_book)
for i in range(0, name_book_length, 1):
if (name_book[i] == change):
name_book.insert(i, change_name)
del (name_book[i+1])
print('변경이 완료되었습니다.')
elif (change_chk == 2):
change_num = input('무엇으로 수정하시겠습니까?')
change_num_chk = list(change_num)
len_change_num_chk = len(change_num_chk)
if (len_change_num_chk == 8):
num_book_length = len(num_book)
for h in range(0, num_book_length, 1):
count_1 = 0
if (num_book[h] == change_num):
count_1 = 0
count_1 = count_1 + 1
if (count_1 == 0):
num_book.insert(i, change_num)
del (num_book[i + 1])
print('변경이 완료되었습니다.')
else:
print ('이미 저장되어 있는 번호입니다. 메뉴로 돌아갑니다.')
else:
print('잘못된 형식입니다.')
elif(change_chk == 3):
change_job = input('무엇으로 수정하시겠습니까?')
job_book.insert(i, change_job)
del (job_book[i + 1])
print('변경이 완료되었습니다.')
elif(change_chk == 4):
change_old = input('무엇으로 수정하시겠습니까?')
old_book.insert(i, change_old)
del (old_book[i + 1])
print('변경이 완료되었습니다.')
elif(change_chk == 5):
change_ad = input('무엇으로 수정하시겠습니까?')
ad_book.insert(i, change_ad)
else :
print('잘못된 명령입니다.')
elif (count >= 2):
same_name = input('%d 명의 중복 인원이 존재합니다.\n수정하고 싶은 사람의 번호를 입력하시오.' % count)
name_book_length = len(name_book)
for k in range(0, name_book_length, 1):
if (num_book[k] == same_name):
change_chk = int(input('무엇을 수정하시겠습니까?\n1. 이름 / 2. 번호 / 3. 직업 / 4. 나이'))
if (change_chk == 1):
change_name = input('무엇으로 수정하시겠습니까?')
name_book_length = len(name_book)
for i in range(0, name_book_length, 1):
if (name_book[i] == change):
name_book.insert(k, change_name)
del (name_book[k + 1])
print('변경이 완료되었습니다.')
break
elif (change_chk == 2):
change_num = input('무엇으로 수정하시겠습니까?')
change_num_chk = list(change_num)
len_change_num_chk = len(change_num_chk)
if (len_change_num_chk == 8):
num_book_length = len(num_book)
count_1 = 0
for h in range(0, num_book_length, 1):
if (num_book[h] == change_num):
count_1 = count_1 + 1
if (count_1 == 0):
num_book.insert(k, change_num)
del (num_book[k + 1])
print('변경이 완료되었습니다.')
break
else:
print('이미 저장되어 있는 번호입니다. 메뉴로 돌아갑니다.')
else:
print('잘못된 형식입니다.')
elif (change_chk == 3):
change_job = input('무엇으로 수정하시겠습니까?')
job_book.insert(k, change_job)
del (job_book[k + 1])
print('변경이 완료되었습니다.')
break
elif (change_chk == 4):
change_old = int(input('무엇으로 수정하시겠습니까?'))
old_book.insert(k, change_old)
del (old_book[k + 1])
print('변경이 완료되었습니다.')
break
elif (change_chk == 5):
change_ad = input('무엇으로 수정하시겠습니까?')
ad_book.insert(k, change_ad)
del (ad_book[k + 1])
print('변경이 완료되었습니다.')
else:
print('잘못된 명령입니다.')
break
elif(ms == 5):
name_book_length = len(name_book)
for i in range(0, name_book_length, 1):
print(name_book[i], num_book[i], job_book [i],old_book[i],ad_book[i])
elif(ms == 6):
break
elif(ms == 0):
out_chk = input('프로그램을 종료하시겠습니까? [y]/[n]')
if (out_chk == 'y'):
exit()
else:
print('메뉴로 돌아갑니다.')
elif (password == '0'):
break
else:
password_chk = password_chk + 1
protect = int(10 - password_chk)
print('비밀번호가 잘못되었습니다. %d회 틀릴경우 모든 데이터가 삭제됩니다.' % protect)
if (password_chk == 10):
name_book = []
num_book = []
job_book = []
old_book = []
break
if (mode == 3):
print('프로그램을 종료합니다')
exit()
if (mode == 0):
print ('''
___________________________________
| PHONE NUMBER PROGRAM |
| |
| 제작자 : 핫빠 |
| 출시일 : 2019.04.28 |
| ver. 1.0.0 |
| 테스터 : |
| 광명사는 A군 |
| 대구사는 B양 |
| 서울사는 C양 |
|__________________________________|
''')
break
2. 사용된 문법
print ()
if - elif - else 문
for 문
while 문
break, continue
리스트 []
list()
len()
append()
insert()
del()
exit()
3. 프로그램을 짜면서 고민했던 부분들
User와 Admin의 경계를 어디에 설정해야 하는가
첫 번째 문제였다. 우선적으로 떠오른 형태는 고전적인 책 형식의 전화번호부였기에, User는 검색과 전체 조회의 권한을 부여하고, Admin에게는 검색과 전체 조회 외에도 추가, 삭제, 수정을 할 수 있는 권한을 부여하였다.

프로그램이 시작될 때 그림 출력하기
참고 자료로 제시된 pdf중 하나에 프로그램을 실행시킬 때 전화기 모양의 그림이 나오는 것을 볼 수 있었다. 좋은 아이디어인 것 같아 print (""" """)을 사용해 그림을 출력 했다.

전화번호 값 제대로 받기
전화번호 입력에 조건을 걸어두지 않으면 새로운 번호를 추가하는 과정에서 전화번호를 끝까지 치지 않고 엔터를 눌러버렸을 때 [나머지 정보 입력 - 수정] 혹은 [나머지 정보 입력 - 삭제 - 추가] 의 비효율적인 방식을 이용해야 할 수도 있기에 전화번호가 010으로 시작하는 사람들만 사용할 수 있다는 문제점을 안고도 코드를 짜게 되었다.
num = input('번호(-를 제외해 주십시오) : 010)')
num_chk = list(num)
len_num_chk = len(num_chk)
if (len_num_chk == 8):
num_book_length = len(num_book)
번호를 문자열 형태로 받은 뒤(정수형으로 받는 경우 첫 숫자가 0인 경우 처리 할 수 없는 문제 발생.), 그 번호를 list ()를 이용해 리스트로 만들고, len ()을 이용하여 원소의 개수를 구하는 방식으로 전화번호가 8자리임을 확인하고 다음 정보를 받았다.

중복 값 처리
여러 가지 방법을 생각하고 자문을 구하면서 내린 결론은 ‘동명이인은 존재할 수 있지만 같은 번호는 존재 할 수 없다’는 것이다.
동명이인을 처리하는 방법은 다음과 같다. (이름으로 정보를 검색하는 상황)
for i in range(0,name_book_length, 1):
if (name_book[i] == yoso):
count = count + 1
if (count == 0):
break
elif (count == 1):
print(name_book[i], num_book[i], job_book[i], old_book[i])
elif (count >= 2):
same_name = input('%d 명의 중복 인원이 존재합니다.\n확인하고 싶은 사람의 번호를 입력하시오.' % count)
num_book_length = len(num_book)
for i in range (0, num_book_length, 1):
if (num_book[i] == same_name):
print(name_book[i], num_book[i], job_book[i], old_book[i])

이름만 들어있는 name_list 라는 리스트에서 입력받은 이름과 같은 이름이 있는지를 for 문과 count 라는 변수로 확인한다. 동명이인이 아니라면 그냥 정보를 출력하고, 동명이인이 있다면 몇 명의 사람이 겹치는지를 출력한 뒤, 정보를 얻고 싶은 사람의 전화번호를 입력 받아 전화번호만 들어있는 num_list에서 입력 받은 값과 같은 값이 있는지를 검색하고, 리스트의 인덱스 값을 이용해 정보를 출력하는 방식을 사용했다.
보안 관련
별도의 비밀번호를 요하지 않는 User와는 달리 Admin은 접근 시 비밀번호를 요한다. 따라서 정보에 변화를 줄 수 있는 Admin에 대한 비정상적인 접근을 막기 위해, 비밀번호를 여러 번 틀렸을 때의 패널티를 주려고 하였다.
총 두 가지 방식으로 계획하였으나 한 가지 방식의 문제점으로 인해 한가지 방식만 채택하게 되었다.
1. n번 틀린 경우 시간 제한 걸기 (편의상 비밀번호는 123으로 하겠다.)
protect = 0
while True:
password = input(‘비밀번호를 입력하시오’)
if (password != ‘123’):
protect == protect + 1
protect_num = int (5 - protect)
print ('%d 회 더 틀리면 잠시 동안 입력이 불가능합니다.' % protect_num)
if (protect == 5):
while True:
time = time +1
if (time == 3200000):
break
와 같은 방식으로 시간 패널티를 부여하려 했으나.
time 이 큰 수에 도달하기까지에 시간이 너무나도 짧기도 하고, 프로그램이 구동되는 환경에 따라 시간 패널티가 제각각이었다. 그래서 아이폰이 채택하고 있는 방식을 차용했는데, 다음과 같다.
2. n번 틀린 경우 전체 데이터 삭제
password_chk = password_chk + 1
protect = int(10 - password_chk)
print('비밀번호가 잘못되었습니다. %d회 틀릴경우 모든 데이터가 삭제됩니다.' % protect)
if (password_chk == 10):
name_book = []
num_book = []
job_book = []
old_book = []
break
틀려도 되는 횟수를 5번 더 늘렸지만, 패널티는 더 강하게 했다. 이 프로그램이 내장하고 있는 모든 리스트를 초기화시켜버리는 데이터 삭제 기능이다. (리스트 자체를 날려버리면 에러가 나버린다.) 따라서 Admin으로 접근을 하다가 비밀번호를 10번 틀리고, Mode 선택으로 들어가 User로 접근하게 되면 검색할 수 있는 데이터는 남아있지 않다.

4. 순서도 (프로그램 진행 방식)
조금 복잡해 보이기는 하지만, 다음과 같다.

5. 구현하고 싶은 기능들 (추후 업데이트를 노려보는 것들)
전화번호 내부에서의 이름 순 정렬
프로세싱에서 배운 유니코드를 활용하여 글자를 유니코드로 바꾼 뒤 대소비교 프로그램을 이용해서 가나다 순으로 정렬할 수 있을 것 같다.
프로그램을 종료해도 Admin이 설정한 값이 유지되는 프로그램
지금은 프로그램을 껐다가 킬 때마다 모든 리스트가 초기화 되어 버려서 전화번호를 저장한다는 의미가 거의 없는 상황이다. 만약 외부 문서와 연결해 데이터를 계속 저장할 수 있다면 훨씬 더 괜찮은 코드가 될 것 같다.
비밀번호를 틀렸을 때의 시간 딜레이
while 문이 아닌 다른 방식으로 비밀번호를 n번 틀렸을 때 시간 패널티를 부여하고 싶다.
간결한 코드
이렇게 긴 양은 처음 써보는 것이라 중구난방이고 오류가 나지 않을 정도로만 적어놓은 코드이지, 효율적으로 만들어진 코드는 아닌 것 같다. 조금이라도 더 짧은 코드로 정리해 보고 싶다.
선택적으로 입력받는 항목들
예시코드를 보면 어떤 정보들은 입력이 선택적이다. 아무것도 입력하지 않고 엔터만 눌렀을 때 if문을 활용해서 리스트에 'null'이라는 변수를 입력시킬 수 있을 것 같다.
6. 참고 자료
print (""" """)사용법
http://www.tcpschool.com/python/function_about
7. 마치며
심심할때 마다 고민했던 프로그램이었는데 생각보다 구현하지 못한 기능이 많아서 아쉽습니다ㅜ
만약에 코드를 보시다가 수정해야 될 것 같은 부분(효율적인 방식 혹은 논리적 결함)이나 실행 중에 발생하신 오류를 알려 주시면 감사드리겠습니다!
'건전한 학습생활 - python' 카테고리의 다른 글
[Error] TypeError: an integer is required (got type bytes) (0) | 2024.01.10 |
---|---|
파이썬 웹크롤링을 사용한 날씨 정보 프로그램 - 2 (GUI, 메일전송까지) (2) | 2019.11.23 |
파이썬 웹크롤링을 사용한 날씨 정보 프로그램 - 1 (GUI, 메일전송까지) (0) | 2019.11.22 |
Python으로 글자수 세기 프로그램 제작하기 (0) | 2019.06.02 |