I'm currently working on v1 of a password generator. I've been working on the visual elements, and now started working on the actual password generation. I've been coding this on my android device using pydroid 3 and tkinter.
I made the program to have three tickboxes for uppercase, numbers and special characters; along with an input field for the desired password length. I created the first if-statement that is executed when all the tickboxes are selected, but testing it results in a "PY_VAR4" result when tapping the Generation button, the 4 increasing every time the button is pressed (PY_VAR4, PY_VAR5, etc).
Do y'all have any suggestions for how I can fix this? I tried playing around with different ways to change the text of the result label using variables or a label["text"] = "text"
code but that doesn't seem to resolve the issue. I also tested the password length variable (plugging it directly into the result label) and the tick box variables and it seems to work. I've come to the conclusion that it must be something within the if statement or generation code, but I haven't been able to figure out what it might be. I'm not sure what else to test and play around with at this point.
Here's the code:
import tkinter as tk
import random
import string
#randomized password based on ticked boxes
def final(event):
password = tk.StringVar(value="")
password_length = size.get()
if uppercase_on == True and special_chars_on == True and numbers_on == True:
characters = string.ascii_letters string.digits string.punctuation
password = "".join(secret.choice(characters) for i in range(password_length))
result["textvariable"] = password
# start of gui
window = tk.Tk()
# some variables.
no_result = tk.StringVar(value="")
# title
title_text = tk.Label(
text="Aero's Pawsword Generator",
fg="brown",
bg="grey",
height=5
)
# Action prompt text
action_descriptor = tk.Label(
text="Select the appropriate option and tap Generate!",
height=5
)
#size input field text
size_text = tk.Label(text="Size")
size = tk.Entry(
width=3,
fg="grey"
)
# uppercase tick box variable
uppercase_on = tk.BooleanVar(value=False)
upper = tk.Checkbutton(
text="Uppercase Included",
variable=uppercase_on,
onvalue=True,
offvalue=False,
height=3
)
# special characters tick box variable
special_chars_on = tk.BooleanVar(value=False)
special_chars = tk.Checkbutton(
text = "Special Characters Included",
variable=special_chars_on,
onvalue=True,
offvalue=False,
height=3
)
# numbers tick box variable
numbers_on = tk.BooleanVar(value=False)
numbers = tk.Checkbutton(
text="Numbers Included",
variable=numbers_on,
onvalue=True,
offvalue=False,
height=3
)
# generate button
generate = tk.Button(
text="Generate",
width=5,
height=2,
bg="grey",
fg="brown"
)
# results label, empty until something has been generated
result = tk.Label(
textvariable=no_result,
height=5
)
# pack all elements
title_text.pack(fill=tk.X)
action_descriptor.pack(fill=tk.X)
size_text.pack(fill=tk.X)
size.pack()
upper.pack()
special_chars.pack()
numbers.pack()
generate.pack()
result.pack(fill=tk.X)
generate.bind("<Button-1>", final)
window.mainloop()
CodePudding user response:
You do have issues with your final(). Here is a version that works:
#randomized password based on ticked boxes
def final(event):
password = "" # tk.StringVar(value="")
password_length = size.get()
password_length = int(password_length) if password_length else 8
characters = string.ascii_lowercase
if uppercase_on.get():
characters = string.ascii_uppercase
if special_chars_on.get():
characters = string.punctuation
if numbers_on.get():
characters = string.digits
password = "".join(random.choice(characters) for i in range(password_length))
no_result.set(password)
# result["textvariable"] = password
A few changes to note:
You were changing the type of
password
in your function. You started it as a StringVar and then changed it to a string inside theif
. Be careful about using the same variable for more than one purpose. It makes the code harder to follow and debug. And it leads to errors.Your if was always satisfied because you have to access the value of a StringVar (or other Tkinter variable) using the .get() method. Otherwise you're getting the actual Tkinter variable which Python treats as a logical True.
You needed to separate out the different components of your password. So, I assumed the default password would be 8 characters, all lower case. Then, you can override that with the checkboxes and Entry widget (for password length).
CodePudding user response:
you have missed some ...
def final():
password = tk.StringVar(value="")
password_length = size.get()
if uppercase_on.get() == True and special_chars_on.get() == True and numbers_on.get() == True:
characters = string.ascii_letters string.digits string.punctuation
for i in range(int(password_length)) :
password.set(str(password.get()) random.choice(characters))
no_result.set(str(password.get()))
and
# generate button
generate = tk.Button(
text="Generate",
width=5,
height=2,
bg="grey",
fg="brown",
command=final
)
and at last removed binding
upper.pack()
special_chars.pack()
numbers.pack()
generate.pack()
result.pack()
window.mainloop()