1 #!/usr/local/bin/python3
2 """tkinter password generator"""
8 DEFAULT_USE_LOWER = True
9 DEFAULT_USE_UPPER = True
10 DEFAULT_USE_NUMBERS = True
11 DEFAULT_USE_SYMBOLS = True
14 def generate_password(
15 length=8, uselower=True, useupper=True, usenums=True, usesymbols=False
17 """Create a radom password based on the options passed"""
20 ran = random.SystemRandom()
22 chars.append(string.ascii_lowercase)
24 chars.append(string.ascii_uppercase)
26 chars.append(string.digits)
28 chars.append(string.punctuation)
29 for _ in range(length):
30 chosen_list = ran.choice(chars)
31 chosen_char = chosen_list[ran.randint(0, len(chosen_list) - 1)]
32 generated_string += chosen_char
33 return generated_string
39 def __init__(self, master):
40 master.title("Password Generator")
41 master.resizable(False, False)
42 master.rowconfigure([0, 1], weight=1)
45 # set password options variables
47 "pass_length": tk.IntVar(value=DEFAULT_LENGTH),
48 "use_lower": tk.IntVar(value=DEFAULT_USE_LOWER),
49 "use_upper": tk.IntVar(value=DEFAULT_USE_UPPER),
50 "use_numbers": tk.IntVar(value=DEFAULT_USE_NUMBERS),
51 "use_symbols": tk.IntVar(value=DEFAULT_USE_SYMBOLS),
54 # make a frame for password options and output
55 frame_main = tk.Frame(master)
56 frame_main.grid(row=0, column=0, sticky="ew")
57 frame_main.columnconfigure(0, minsize=700)
59 # make checkboxes for password options
60 check_lower = tk.Checkbutton(
62 text="Include lowercase letters",
63 variable=self.options["use_lower"],
64 command=self.output_pass,
66 check_lower.grid(row=0, column=0, sticky="w", pady=2)
67 check_upper = tk.Checkbutton(
69 text="Include uppercase letters",
70 variable=self.options["use_upper"],
71 command=self.output_pass,
73 check_upper.grid(row=1, column=0, sticky="w", pady=2)
74 check_numbers = tk.Checkbutton(
76 text="Include numbers",
77 variable=self.options["use_numbers"],
78 command=self.output_pass,
80 check_numbers.grid(row=2, column=0, sticky="w", pady=2)
81 check_symbols = tk.Checkbutton(
83 text="Include symbols",
84 variable=self.options["use_symbols"],
85 command=self.output_pass,
87 check_symbols.grid(row=3, column=0, sticky="w", pady=2)
89 # make a scale for password length
90 scale_length = tk.Scale(
95 variable=self.options["pass_length"],
96 command=self.change_password_length,
98 scale_length.set(DEFAULT_LENGTH)
99 scale_length.grid(row=4, column=0, sticky="ew")
100 self.label_length = tk.Label(
101 frame_main, text=f"Password length: {DEFAULT_LENGTH}"
103 self.label_length.grid(row=5, column=0)
105 # make an entry for the resulting password
106 self.entry_password = tk.Entry(frame_main)
107 self.entry_password.grid(row=6, columnspan=2, sticky="ew", pady=5)
109 # make a frame for the generate and copy buttons
110 frame_buttons = tk.Frame(master)
111 frame_buttons.grid(row=1, column=0)
112 frame_buttons.columnconfigure([0, 1], weight=1, minsize=150)
114 # make a button for generating passwords
115 button_generate = tk.Button(
116 frame_buttons, text="\u21BB", width=10, command=self.output_pass
118 button_generate.grid(row=0, column=0, pady=5)
120 # make a button for copying the generated password to the clipboard
121 self.button_copy = tk.Button(
122 frame_buttons, text="Copy to Clipboard", command=self.copy_password
124 self.button_copy.grid(row=0, column=1, pady=5)
125 self.label_copy = tk.Label(frame_buttons)
129 def change_password_length(self, newval):
130 """Displays the new len of the passwords and then outputs it"""
131 self.label_length.config(text=f"Password length: {newval}")
134 def copy_password(self):
135 """Copies the password to the clipboard and displays a message"""
136 if self.entry_password.get():
137 self.master.clipboard_clear()
138 self.master.clipboard_append(self.entry_password.get())
139 self.label_copy.grid(row=1, columnspan=2)
142 def flash(self, dur, count, first=0):
143 """Flash a message when the password gets copied to the clipboard"""
145 self.button_copy.configure(state="disabled")
149 self.label_copy.grid_forget()
150 self.button_copy.configure(state="normal")
152 if self.label_copy["text"]:
153 self.label_copy.config(text="")
155 self.label_copy.config(text="Password copied to clipboard!!")
156 self.label_copy.after(dur, lambda: self.flash(dur, count - 0.5, first))
158 def output_pass(self):
159 """Display the generated password"""
160 self.entry_password.delete(0, tk.END)
161 values = [value.get() for value in self.options.values()]
163 password = generate_password(*values)
164 self.entry_password.insert(0, password)
167 if __name__ == "__main__":