Script stuck in if statement at elif - python

I created a password generator, which creates random passwords out of symbols, numbers and characters. There I have an input, where the user must enter a value and it has to be numeric. So I tried to solve this with elif. But, even when expected number (int) is entered, the loop is still stuck at elif. Here my code:
def PasswordGenerationFunc():
password = None
passwordLength = inputPasswordLength.get()
userName = inputUsername.get()
if len(passwordLength) == 0:
ResultDisplay.configure(text="Length of password is mandatory.", fg="red")
elif type(passwordLength) != int:
ResultDisplay.configure(text="Only digits are allowed." + passwordLength, fg="red")
else:
passwordLength = int(passwordLength)
if passwordLength > maxPasswordLength:
ResultDisplay.configure(text="The limit of password length are 20 characters.", fg="red")
else:
if userName != "":
password = "".join([random.choice(passwordConstructor) for i in range(passwordLength)])
ResultDisplay.configure(text="Generated password for " + userName + " is:\n" + password, fg="white")
else:
password = "".join([random.choice(passwordConstructor) for i in range(passwordLength)])
ResultDisplay.configure(text="Generated password is: \n" + password, fg="white")
In
ResultDisplay.configure(text="Only digits are allowed." + passwordLength, fg="red")
I print out passwordLength to check if wrong values were passed, but was not the case. I am so into the loop, I might ignoring some logic.
Expected behaviour:
User enters letters, loop stops at elif. User enters digits, loop enters else condition.
Now:
User enters digits, loop still stops at elif.
Here my full code, so you might understand it better:
# This is a small tool to generate passwords
# IMPORTS
from datetime import datetime
import random
from tkinter import *
# VARIABLES
date = datetime.now()
dateFormat = str(date.strftime("%d-%m-%Y %H:%M:%S"))
lowerCase = "abcdefghijklmnopqrstuvwxyz"
upperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
numbers = "0123456789"
symbols = "!?%&##+*"
passwordConstructor = lowerCase + upperCase + numbers + symbols
maxPasswordLength: int = 20
bgColor_1 = "black"
# MAKE OUTPUT SELECTABLE
# GENERATE PASSWORD FUNCTION
def PasswordGenerationFunc():
password = None
passwordLength = inputPasswordLength.get()
userName = inputUsername.get()
if len(passwordLength) == 0:
ResultDisplay.configure(text="Length of password is mandatory.", fg="red")
#elif type(passwordLength) != int:
elif isinstance(passwordLength, int):
ResultDisplay.configure(text="Only digits are allowed.", fg="red")
else:
passwordLength = int(passwordLength)
if passwordLength > maxPasswordLength:
ResultDisplay.configure(text="The limit of password length are 20 characters.", fg="red")
else:
if userName != "":
password = "".join([random.choice(passwordConstructor) for i in range(passwordLength)])
ResultDisplay.configure(text="Generated password for " + userName + " is:\n" + password, fg="white")
else:
password = "".join([random.choice(passwordConstructor) for i in range(passwordLength)])
ResultDisplay.configure(text="Generated password is: \n" + password, fg="white")
# SCREEN
screen = Tk()
screen.geometry("450x400")
screen.configure(bg="black")
screen.title("PASSWORD GENERATOR")
# TITLE
Title = Label(screen, text="PASSWORD GENERATOR", font=("Arial Bold", 18), fg="green")
Title.configure(bg="black")
Title.pack(pady=20)
# MAIN FRAME
MainFrame = Frame(screen)
MainFrame.configure(bg="black")
MainFrame.pack(pady=5)
# INPUT USERNAME
usernameLabel = Label(MainFrame, text="Please enter username:", font=("Arial Bold", 14))
usernameLabel.configure(bg="black")
usernameLabel.pack()
inputUsername = Entry(MainFrame, font=("Arial Bold", 12))
inputUsername.pack()
# INPUT PASSWORD LENGTH
passwordLengthLabel = Label(MainFrame, text="Please enter length of password:", font=("Arial Bold", 14))
passwordLengthLabel.configure(bg="black")
passwordLengthLabel.pack()
inputPasswordLength = Entry(MainFrame, font=("Arial Bold", 12))
inputPasswordLength.pack()
# GENERATE BUTTON
GenerateBtn = Button(MainFrame, text="GENERATE", font=("Arial", 14), command=PasswordGenerationFunc, bg="black")
GenerateBtn.pack(pady=10)
# DISPLAY RESULT
ResultDisplay = Label(MainFrame, text="", font=("Arial", 14))
ResultDisplay.configure(bg="black")
ResultDisplay.pack(pady=15)
# COPY TO CLIPBOARD BUTTON
#CopyBtn = Button(MainFrame, text="COPY", font=("Arial", 14), bg="black")
#CopyBtn.clipboard_append(password)
#CopyBtn.pack(pady=10)
# WINDOW
screen.mainloop()

First, convert the input to int.
try:
passwordLength = int(input("Your message "))
except ValueError:
print(f"Input is not a valid integer. Please try again.")
Modify the if conditions for an integer input as follows:
if passwordLength == 0:
pass # your output here
else:
pass # your logic to generate a password

To compare objects and its datatype use isinstance(object, type):
isinstance(3, int) ===> True
isinstance(3, str) ===> False

Related

Python Password Change program with tkinter

I am having trouble getting these checks to work. it is for a password change program using tkinter. The aim is to make sure the password has both capital and lowercase letters, and is more than 8 characters long. the code always outputs false, even when the password should pass all the checks.
def check_password():
global oldpassword_entry
oldpasswordcheck= oldpassword_entry.get()
global newpassword_entry
newpasswordcheck= newpassword_entry.get()
global newpasswordconfirmed_entry
newpasswordconfirmedcheck= newpasswordconfirmed_entry.get()
if oldpasswordcheck == oldpassword:
if (any(x.isupper() for x in newpasswordcheck) and any(x.islower() for x in newpasswordcheck) and any(x.isdigit() for x in newpasswordcheck) and len(s) >= 8):
if newpasswordcheck == newpasswordconfirmedcheck:
passwordtrue = 'true'
print(passwordtrue)
showoldpasswordchange_label.configure(text=newpasswordconfirmedcheck)
else:
passwordtrue = 'false'
print(passwordtrue)
else:
passwordtrue = 'false'
print(passwordtrue)
else:
passwordtrue = 'false'
print(passwordtrue)
okaybutton_button = ttk.Button(root, text= "Okay", width= 20, command= check_password)
the variables at the start of the function come from the entries here:
showoldpassword_label = tk.Label(root, text = 'Current Password: ', font=('calibre',10, 'bold'))
showoldpasswordchange_label = tk.Label(root, text = 'PasswordExample', font=('calibre',10, 'bold'))
oldpassword_label = tk.Label(root, text = 'Old Password: ', font=('calibre',10, 'bold'))
oldpassword_entry = tk.Entry(root, font=('calibre',10,'normal'), show = '*')
newpassword_label = tk.Label(root, text = 'New Password: ', font=('calibre',10, 'bold'))
newpassword_entry = tk.Entry(root, font=('calibre',10,'normal'), show = '*')
newpasswordconfirmed_label = tk.Label(root, text = 'Confirm Password: ', font=('calibre',10, 'bold'))
newpasswordconfirmed_entry = tk.Entry(root, font=('calibre',10,'normal'), show = '*')
when the code is run it makes this box:
What is s in if (any(x.isupper() for x in newpasswordcheck) and any(x.islower() for x in newpasswordcheck) and any(x.isdigit() for x in newpasswordcheck) and len(s) >= 8):
Maybe just swap s for newpasswordcheck?
The code otherwise looks right to me, i havn't tried it though just read it and im missing s and oldpassword which i'm guessing is the current password as a string?

How to save progress to a text file?

I am trying to save progress as a text file. I've tried pickle but it didn't work.
Here's the code; I want to ask at the start if they want to load or start a new game and at any point of the guessing process if they want to save their progress.
# Username and password system to get into the puzzle
Username = []
Password = []
while Username != "Username":
Username = input("Please enter your username: ")
while Password != "Password":
Password = input("Please enter your password: ")
#Import Modules
import tkinter as tkr
import string
import random
import os
import time
from collections import OrderedDict
while True:
#Define Root From tkinter
root = tkr.Tk()
root.configure(background="white")
root.configure(highlightbackground="grey")
root.iconbitmap("PuzzleIcon.ico")
#Inputs for title etc...
Title = input("Please enter the Title of your puzzle: ")
Phrase = input("Please enter the phrase you would like to be encoded: ").upper()
giveaways = str(input("Please enter the letters you want to giveaway with no spaces: ")).upper()
giveaways = giveaways + " "
giveaways = "".join(OrderedDict.fromkeys(giveaways))
root.title(Title)
#Define alphabet and numbers
Alphabet = list(string.ascii_uppercase)
Numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]
random.shuffle(Numbers)
# Specifies the numbers to put under the phrase
AlphabetNumbersToDisplay = []
Numbers.append(" ")
Alphabet.append(" ")
for letter in Phrase:
n = 0
found = False
while n < len(Alphabet) and found == False:
if letter == Alphabet[n]:
AlphabetNumbersToDisplay.append(Numbers[n])
found = True
n = n + 1
# Defines the tkinter window
def tkinterDisplay():
for i in range (0, len(Alphabet)):
tkr.Label(root, text=Alphabet[i], fg="black", bg="white", width=3).grid(row=0, column=i)
for i in range (0, len(Numbers)):
if Alphabet[i] in giveaways:
tkr.Label(root, text=Numbers[i], fg="black", bg="white", width=3).grid(row=1, column=i)
else:
tkr.Label(root, text= "__", fg="black", bg="white", width=3).grid(row=1, column=i)
tkr.Label(root, text=" ", fg = "white",bg="white").grid(row=2)
for i in range(0, len(Phrase)):
if Phrase[i] in giveaways:
tkr.Label(root, text=Phrase[i], fg= "black", bg="white", width = 3).grid(row = 3, column =i)
else:
tkr.Label(root, text="__", fg= "black", bg="white", width = 3).grid(row = 3, column =i)
for i in range(0, len(AlphabetNumbersToDisplay)):
tkr.Label(root, text=AlphabetNumbersToDisplay[i], fg= "black", bg="white", width = 3).grid(row = 4, column =i)
winMessage = "Well done! You Won!".upper()
for i in range(0, len(winMessage)):
if len(giveaways) == 27:
tkr.Label(root, text=" ", fg = "white",bg="white").grid(row=5)
tkr.Label(root, text=winMessage[i], fg="red", bg="white", width = 3).grid(row = 6, column=i)
# Guessing system for the program
def Guessing():
tkinterDisplay()
while True:
try:
GuessNum = int(input("Please enter the number of your guess: "))
break
except ValueError:
print("Your answer must be a number!")
while True:
try:
GuessLetter = str(input("Please enter the letter you want to guess: ")).upper()
break
except ValueError:
print("Your answer must be a letter!")
foundMatch = False
for i in range(0, len(Alphabet)):
if Alphabet[i] == GuessLetter and Numbers[i] == GuessNum:
global giveaways
foundMatch = True
giveaways = giveaways + Alphabet[i]
if foundMatch == False:
print("They do not match, try again!")
elif foundMatch == True and len(giveaways) < 27:
print("Well done! Keep going!")
while len(giveaways) < 27:
Guessing()
tkinterDisplay()
def Clear():
os.system("cls")
if len(giveaways) == 27:
tkinterDisplay()
print("Well done! You won! The phrase you guessed was: " + Phrase)
Restart = input("Would you like to play again? (Y/N): ").upper()
if Restart == "N":
break
elif Restart == "Y":
print("Restarting Puzzle...")
time.sleep(.1500)
root.destroy()
Clear()
continue
root.mainloop()
This is a very broad question. Building a 'save' option may well be as much work as the rest of the game again. You need to consider the following:
What data is needed to fully define the state of the game at any given point (this is what goes in the text file)
What logic is needed to reconstruct a game in a saved state (you'll need to write new code for this)
How and when to give your users the chance to load/save (this affects the gameplay experience)

How to clear listbox entries when pressing a button?

I am using a Listbox in order to display some text when I press a button. However, when I press this button again to re-display, it just puts the text below the original text in the listbox. I have searched for ways to fix this problem but I cannot seem to find one that works for my specific program. The point of my program is to check a password entered by a user.
Here is my code:
#!/usr/bin/env python
#Imports
from tkinter import *
from random import *
import string
#Root And GUI Title
root = Tk()
root.wm_title("Password Checker")
#Top Frame
topFrame = Frame(root)
topFrame.grid(row=0)
#Bottom Frame And Geometry And Check Labels
bottomFrame = Frame(root)
bottomFrame.grid(row=10)
root.geometry("1000x1000")
checkLabel = Label(root)
checkCap = Label(root)
checkLow = Label(root)
checkSymb = Label(root)
checkDig = Label(root)
listbox = Listbox(root)
listbox.grid(row=6, column=1)
#Checker Function
def checker():
if len(passEntry.get()) < 8 or len(passEntry.get()) > 24:
listbox.insert(END, "Invalid Length")
listbox.grid(row=1, column=1)
if len(passEntry.get()) >= 8 and len(passEntry.get()) <= 24:
#checkLabel.config(text="Valid Length")
#checkLabel.grid(row=10, column = 1)
listbox.insert(END, "Valid Length")
cap = re.search("[A-Z]", passEntry.get())
if cap:
#checkCap.config(text="Okay Capitals")
#checkCap.grid(row=11, column = 1)
listbox.insert(END, "Okay Capitals")
else:
#checkCap.config(text="No Capitals")
#checkCap.grid(row=11, column = 1)
listbox.insert(END, "No Capitals")
low = re.search("[a-z]", passEntry.get())
if low:
#checkLow.config(text="Okay Lowercase")
#checkLow.grid(row=12, column = 1)
listbox.insert(END, "Okay Lowercase")
else:
#checkLow.config(text="No Lowercase")
#checkLow.grid(row=12, column = 1)
listbox.insert(END, "No Lowercase")
symb = re.search("[!£$%^&*()]", passEntry.get())
if symb:
#checkSymb.config(text="Okay Symbols")
#checkSymb.grid(row=13, column= 1)
listbox.insert(END, "Okay Symbols")
else:
#checkSymb.config(text="No Symbols")
#checkSymb.grid(row=13, column = 1)
listbox.insert(END, "No Symbols")
dig = re.search("[0-9]", passEntry.get())
if dig:
#checkDig.config(text="Okay Digits")
#checkDig.grid(row=14, column = 1)
listbox.insert(END, "Okay Digits")
else:
#checkDig.config(text="No Digits")
#checkDig.grid(row=14, column = 1)
global noDigits
noDigits = listbox.insert(END, "No Digits")
#Password Entry
passEntryLabel = Label(root, text="Password")
passEntryLabel.grid(row=0, column=3)
passEntry = Entry(root)
PAR = passEntry.get()
passEntry.grid(row=0, column=4)
checkButton = Button(root, text="Check Password", command=checker)
checkButton.grid(row=0, column=7)
#Mainloop
root.mainloop()
When I enter a first password:
First Password Entry
When I enter a second password:
Second Password Entry
After entering the second password it just puts the next set of checks below the old ones, so how would I make it that the old set gets deleted when entering the second password? Thanks.
Simply add the documented:
listbox.delete('0', 'end')
in order to delete all entries in listbox to, -- the method that updates your Listbox, checker as the first line.

Python Tkinter label refresh

I'm trying to build a gui that creates a password and i've got as far as generating the password and making it appear in a label. However when the button is clicked multiple times it appears the old password doesnt dissapear, it just overlays on top. I'm also getting an error that i cant seem to rectify, although it doesnt seem to affect the gui.
The code so far is:
from tkinter import *
import random
myGui = Tk()
myGui.geometry('300x200+700+250')
myGui.title('Password Generator')
def passwordgen():
password = ''
for i in range(8):
##----runs the for loop 8 times
if (i == 0) or (i == 4):
password = password + chr(random.randint(97, 122))
if (i == 1) or (i == 5):
password = password + chr(random.randint(65, 90))
if (i == 2) or (i == 6):
password = password + chr(random.randint(48, 57))
if (i == 3) or (i == 7):
password = password + chr(random.randint(33, 47))
passLabel = Label(myGui, text=password)
passLabel.grid(row=0, column=1, sticky=E)
genPassBtn = Button(myGui, text="Generate Password", command=passwordgen)
genPassBtn.bind("<Button-1>", passwordgen)
genPassBtn.grid(row=0, column=0, sticky=W)
myGui.mainloop()
The error i receive is:
return self.func(*args)
TypeError: passwordgen() takes 0 positional arguments but 1 was given
The outcome i am hoping to achieve is to create a gui that generates a password, generates a hash value for generated password, checks the password strength, loads the generated hash to a text file and then can verify the password against stored hashes.
Further on now and from advice received i have amended the code and added extra to check the strength. The code now looks like this:
from tkinter import *
import random
myGui = Tk()
myGui.geometry('300x200+700+250')
myGui.title('Password Generator')
def passwordgen():
password = ''
for i in range(8):
##----runs the for loop 8 times
if (i == 0) or (i == 4):
password = password + chr(random.randint(97, 122))
if (i == 1) or (i == 5):
password = password + chr(random.randint(65, 90))
if (i == 2) or (i == 6):
password = password + chr(random.randint(48, 57))
if (i == 3) or (i == 7):
password = password + chr(random.randint(33, 47))
strPassword.set(password)
def checkPassword():
strength = ['Blank', 'Very Weak', 'Weak', 'Medium', 'Strong', 'Very Strong']
score = 1
password = strPassword.get()
if len(password) < 1:
return strength[0]
if len(password) < 4:
return strength[1]
if len(password) >= 8:
score += 1
if re.search('[0-9]', password):
score += 1
if re.search('[a-z]', password) and re.search('[A-Z]', password):
score += 1
if re.search('.', password):
score += 1
passwordStrength.set(strength[score])
genPassBtn = Button(myGui, text="Generate Password", command=passwordgen)
strPassword = StringVar()
lblPassword = Label(myGui, textvariable=strPassword)
lblPassword.grid(row=0, column=1, sticky=W)
genPassBtn.grid(row=0, column=0, sticky=W)
passwordStrength = StringVar()
checkStrBtn = Button(myGui, text="Check Strength", command=checkPassword)
checkStrBtn.grid(row=1, column=0)
checkStrLab = Label(myGui, textvariable=passwordStrength)
checkStrLab.grid(row=1, column=1)
myGui.mainloop()
Try this example.
from tkinter import *
import random
myGui = Tk()
myGui.geometry('300x200+700+250')
myGui.title('Password Generator')
def passwordgen():
password = ''
for i in range(8):
##----runs the for loop 8 times
if (i == 0) or (i == 4):
password = password + chr(random.randint(97, 122))
if (i == 1) or (i == 5):
password = password + chr(random.randint(65, 90))
if (i == 2) or (i == 6):
password = password + chr(random.randint(48, 57))
if (i == 3) or (i == 7):
password = password + chr(random.randint(33, 47))
strPassword.set(password)
genPassBtn = Button(myGui, text="Generate Password", command=passwordgen)
strPassword = StringVar()
lblPassword = Label(myGui, textvariable=strPassword)
lblPassword.grid(row=0,column=1, sticky=W)
genPassBtn.grid(row=0, column=0, sticky=W)
myGui.mainloop()
Here's what I've done
Rather than creating a new label each time, I change the text of a label using the StringVar called strPassword.
You don't need to bind a button to a click to call a function, using Button(... , command=myFunction) does this already.

entry.get() function won't change value of a variable

I have some code which asks the user to enter a word they'd like to encrypt and then the program will encrypt the word and display it on a label.
I was wondering why the following code works:
import tkinter
letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
encryption_code = 'LFWOAYUISVKMNXPBDCRJTQEGHZ'
letters += letters.lower()
encryption_code += encryption_code.lower()
window = tkinter.Tk()
encryption_code_entry = tkinter.Entry(window)
entry = tkinter.Entry(window)
enc = dict(zip(letters,encryption_code))
string = 'hello world'
encr = "".join([enc.get(ch, ch) for ch in string])
def encrypt():
encrypt_label.pack()
entry.pack()
encrypt_confirm.pack()
encrypt_button.destroy()
def display_encrypt():
display_enc = encr
encrypted_label.pack()
new_message.config(text=str(display_enc))
new_message.pack()
encrypt_confirm = tkinter.Button(window, text="Confirm", command=display_encrypt)
new_message = tkinter.Label(window, text="", font=('Helvetica', 10))
encrypted_label = tkinter.Label(window, text="Your message " + entry.get() + " has been encrypted into the following: ")
encrypt_button = tkinter.Button(window, text="Encrypt", command=encrypt)
encrypt_button.pack()
encrypt_label = tkinter.Label(window, text="Please enter the message you'd like to encrypt", font=('Helvetica', 14))
window.mainloop()
But if I change string = 'hello world' (which is what I'd like to do) to string = entry.get() nothing is displayedonnew_message`. Also,
encrypted_label = tkinter.Label(window, text="Your message " + entry.get() + "has been encrypted into the following: ")
doesn't display what the user typed in the entry box so I'm almost 100% sure I'm misusing the entry.get() function.
You in fact need to have the entry.get() under display_encrypt().
Every time the encrypt_confirm button is pressed, it calls display_encrypt which will then in turn be able to get the current string in entry every time it is pressed by the user.
I edited your code a bit and it seems to be working.
Notice that I have removed string and encr as they were now redundant variables.
import tkinter
letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
encryption_code = 'LFWOAYUISVKMNXPBDCRJTQEGHZ'
letters += letters.lower()
encryption_code += encryption_code.lower()
window = tkinter.Tk()
encryption_code_entry = tkinter.Entry(window)
entry = tkinter.Entry(window)
enc = dict(zip(letters,encryption_code))
string = 'hello world'
def encrypt():
encrypt_label.pack()
entry.pack()
encrypt_confirm.pack()
encrypt_button.destroy()
def display_encrypt():
display_enc = "".join([enc.get(ch, ch) for ch in entry.get()])
encrypted_label.pack()
new_message.config(text=str(display_enc))
new_message.pack()
encrypt_confirm = tkinter.Button(window, text="Confirm", command=display_encrypt)
new_message = tkinter.Label(window, text="", font=('Helvetica', 10))
encrypted_label = tkinter.Label(window, text="Your message " + entry.get() + " has been encrypted into the following: ")
encrypt_button = tkinter.Button(window, text="Encrypt", command=encrypt)
encrypt_button.pack()
encrypt_label = tkinter.Label(window, text="Please enter the message you'd like to encrypt", font=('Helvetica', 14))
window.mainloop()
You are calling entry.get() well before the user ever has a chance to enter anything. You need to call it and reset the label in response to an event, such as the user pressing <Return>, clicking a button, etc.

Categories