패스워드 매니저 만들기를 업그레이드한다.
- 데이터 저장하는 방식을 json으로 바꾸기
- 예상되는 오류에 대한 예외처리
- 사용자에게 편리하도록 기능(search)을 추가
- if~else와 예외처리를 비교
https://olivia-blackcherry.tistory.com/183
1. 데이터 저장 방식 json으로 변경하기
save_data() 함수 부분만 수정되었다.
from tkinter import *
from tkinter import messagebox
import random
import pyperclip
import json
print('#'.join(['a','b','c']))
# ---------------------------- PASSWORD GENERATOR ------------------------------- #
def safe_password():
letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
symbols = ['!', '#', '$', '%', '&', '(', ')', '*', '+']
nr_letters = random.randint(8, 10)
nr_symbols = random.randint(2, 4)
nr_numbers = random.randint(2, 4)
letters_list = [random.choice(letters) for char in range(nr_letters)]
symbols_list = [random.choice(symbols) for char in range(nr_symbols)]
numbers_list = [random.choice(numbers) for char in range(nr_numbers)]
password_list= letters_list + symbols_list + numbers_list
random.shuffle(password_list)
password = ''.join(password_list)
password_input.insert(0,password)
pyperclip.copy(password)
# ---------------------------- SAVE PASSWORD ------------------------------- #
def save_data():
save_website = website_input.get()
save_email= email_username_input.get()
save_password = password_input.get()
save_all = f"{save_website}, {save_email}, {save_password}"
new_data = {
save_website:{
"email": save_email,
"password": save_password
}
}
if len(save_website)<1 or len(save_email)<1 or len(save_password)<1:
messagebox.showerror(title="에러", message="입력한 값이 너무 짧습니다")
else:
is_ok = messagebox.askokcancel(title= save_website, message=f"이대로 저장해도 될까요?\n{save_all}")
if is_ok:
with open(file="data.json") as f:
new_json_data = json.load(f)
new_json_data.update(new_data)
with open(file = "data.json", mode="w") as f:
json.dump(new_json_data, f, indent=4)
website_input.delete(0, END)
email_username_input.delete(0, END)
password_input.delete(0, END)
# ---------------------------- UI SETUP ------------------------------- #
window = Tk()
window.config(padx=50, pady=50, bg="white")
window.title("my password manager")
canvas = Canvas(width=200, height=200, bg= "white", highlightthickness=0)
picture = PhotoImage(file = "paswd.png")
picture = picture.subsample(2,2)
canvas.create_image(100, 90, image=picture)
canvas.grid(row=0, column=1)
#Label
website = Label(text="website", font=("Courier", 10, "bold"), bg="white")
website.grid(row= 1, column=0)
email_username = Label(text="Email/Username", font=("Courier", 10, "bold"), bg="white")
email_username.grid(row= 2, column=0)
password = Label(text="password", font=("Courier", 10, "bold"), bg="white")
password.grid(row= 3, column=0)
#Entry
website_input= Entry(width=40)
website_input.grid(row=1, column=1, columnspan=2)
website_input.focus()
email_username_input= Entry(width=40)
email_username_input.grid(row=2, column=1, columnspan=2)
email_username_input.insert(0, "olivia@coding.co.kr")
password_input=Entry(width=24)
password_input.grid(row=3, column=1)
#Button
generate_password = Button(text="Generate Password", width=15, command=safe_password)
generate_password.grid(row=3, column=2)
add = Button(text="Add", width=40, command=save_data)
add.grid(row=4, column=1, columnspan=2)
window.mainloop()
2. save_data() 함수 예외처리하기
FileNotFound Error에 대한 예외처리를 한다.
from tkinter import *
from tkinter import messagebox
import random
import pyperclip
import json
print('#'.join(['a','b','c']))
# ---------------------------- PASSWORD GENERATOR ------------------------------- #
def safe_password():
letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
symbols = ['!', '#', '$', '%', '&', '(', ')', '*', '+']
nr_letters = random.randint(8, 10)
nr_symbols = random.randint(2, 4)
nr_numbers = random.randint(2, 4)
letters_list = [random.choice(letters) for char in range(nr_letters)]
symbols_list = [random.choice(symbols) for char in range(nr_symbols)]
numbers_list = [random.choice(numbers) for char in range(nr_numbers)]
password_list= letters_list + symbols_list + numbers_list
random.shuffle(password_list)
password = ''.join(password_list)
password_input.insert(0,password)
pyperclip.copy(password)
# ---------------------------- SAVE PASSWORD ------------------------------- #
def save_data():
save_website = website_input.get()
save_email= email_username_input.get()
save_password = password_input.get()
save_all = f"{save_website}, {save_email}, {save_password}"
new_data = {
save_website:{
"email": save_email,
"password": save_password
}
}
if len(save_website)<1 or len(save_email)<1 or len(save_password)<1:
messagebox.showerror(title="에러", message="입력한 값이 너무 짧습니다")
else:
is_ok = messagebox.askokcancel(title= save_website, message=f"이대로 저장해도 될까요?\n{save_all}")
if is_ok:
try:
with open(file="data.json") as f:
new_json_data = json.load(f)
except FileNotFoundError:
with open(file="data.json", mode="w") as f:
json.dump(new_data, f, indent=4)
else:
new_json_data.update(new_data)
with open(file = "data.json", mode="w") as f:
json.dump(new_json_data, f, indent=4)
finally:
website_input.delete(0, END)
email_username_input.delete(0, END)
password_input.delete(0, END)
# ---------------------------- UI SETUP ------------------------------- #
window = Tk()
window.config(padx=50, pady=50, bg="white")
window.title("my password manager")
canvas = Canvas(width=200, height=200, bg= "white", highlightthickness=0)
picture = PhotoImage(file = "paswd.png")
picture = picture.subsample(2,2)
canvas.create_image(100, 90, image=picture)
canvas.grid(row=0, column=1)
#Label
website = Label(text="website", font=("Courier", 10, "bold"), bg="white")
website.grid(row= 1, column=0)
email_username = Label(text="Email/Username", font=("Courier", 10, "bold"), bg="white")
email_username.grid(row= 2, column=0)
password = Label(text="password", font=("Courier", 10, "bold"), bg="white")
password.grid(row= 3, column=0)
#Entry
website_input= Entry(width=40)
website_input.grid(row=1, column=1, columnspan=2)
website_input.focus()
email_username_input= Entry(width=40)
email_username_input.grid(row=2, column=1, columnspan=2)
email_username_input.insert(0, "olivia@coding.co.kr")
password_input=Entry(width=24)
password_input.grid(row=3, column=1)
#Button
generate_password = Button(text="Generate Password", width=15, command=safe_password)
generate_password.grid(row=3, column=2)
add = Button(text="Add", width=40, command=save_data)
add.grid(row=4, column=1, columnspan=2)
window.mainloop()
3. 데이터 파일에서 저장 정보 찾는 버튼 만들기
website를 입력하고 Search 버튼을 누르면 해당 id, password가 나오도록 만든다.
def info_search():
save_website = website_input.get()
with open(file="data.json") as f:
for_search_data = json.load(f)
search_email = for_search_data[save_website]["email"]
search_password = for_search_data[save_website]["password"]
messagebox.showinfo(title="your email and password",
message=f"email: {search_email}, password: {search_password}")
search = Button(text="Search", width=15, command=info_search)
search.grid(row=1, column=2)
4. info_search()함수 예외처리
FileNotFoundError와 KeyError
def info_search():
save_website = website_input.get()
try:
with open(file ="data3.json") as f:
for_search_data = json.load(f)
except FileNotFoundError:
messagebox.showinfo(title="경고", message="저장된 정보가 없습니다. 새로운 정보를 저장해주세요")
else:
try:
search_email = for_search_data[save_website]["email"]
search_password = for_search_data[save_website]["password"]
except KeyError:
print("키에러")
messagebox.showinfo(title="Warning", message="No infomation")
else:
print("성공")
messagebox.showinfo(title="your email and password", message=f"email: {search_email}, password: {search_password}")
5. 예외처리 대신 if~else 구문 쓰기
사실 try~except~else 구문은
if~ else와 그 원리가 같다.
두 상황을 좀더 비교 설명해보면
예외 exception적인 상황은
매번 일어나는 것이 아니라 꽤 드물게 일어나는 것이라고 본다.
반면 if~else는 생활 속에서 아주 빈번하게 일어나는 경우의 수라고 볼 수 있다.
따라서
if~else로 처리할 수 있다면, 가급적 if~else로 쓰는 것이 좋고,
예외처리 밖에 사용할 수 없는 경우,
즉 다른 쉬운 대안이 없을 때만 try~except~else~finally 구문을 쓰면 좋다.
def info_search():
save_website = website_input.get()
try:
with open(file ="data.json") as f:
for_search_data = json.load(f)
except FileNotFoundError:
messagebox.showinfo(title="경고", message="저장된 정보가 없습니다. 새로운 정보를 저장해주세요")
else:
if save_website in for_search_data:
search_email = for_search_data[save_website]["email"]
search_password = for_search_data[save_website]["password"]
messagebox.showinfo(title="your email and password",
message=f"email: {search_email}, password: {search_password}")
else:
messagebox.showinfo(title="Warning", message="No infomation")
'파이썬 > 파이썬(python) 중급' 카테고리의 다른 글
[31-2 파이썬] tkinter 위치, 정렬 anchor, justify (0) | 2022.09.24 |
---|---|
[31-1 파이썬] 언어별 자주 쓰이는 단어 모음 frequency lists (1) | 2022.09.20 |
[30-5 파이썬] JSON, json.dump(), json.load(), json.update(), 제이슨 (1) | 2022.09.19 |
[30-4 파이썬] 예외처리 연습문제- while, 함수 재귀호출 사용하기, json파일 (0) | 2022.09.19 |
[30-3 파이썬] 예외처리 raise 키워드 (1) | 2022.09.19 |