3

I have some code which asks the user to input 26 characters to make their own encryption code and if it's 26 characters long and is not the alphabet or the preset encryption_code, the code will change the encryption_code to whatever they've entered.

import tkinter
from tkinter import *
from tkinter import ttk
from tkinter.ttk import *

encryption_code = 'LFWOAYUISVKMNXPBDCRJTQEGHZ'

window = tkinter.Tk()    
window.title("Encryption/Decryption")

change_frame = tkinter.Frame(window)
changed_frame = tkinter.Frame(window)

encrypt_entry = tkinter.Entry(change_frame)

def code_change():
    global changed_frame
    global encrypt_entry
    print(len(encrypt_entry.get()))
    if encrypt_entry.get() == 'LFWOAYUISVKMNXPBDCRJTQEGHZ' or 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':
        encrypt_entry.delete(0, tkinter.END)
        changed_incorrect.configure(background=window.cget('bg'))
        changed_incorrect.config(text="Please enter a different code", foreground='red')
        changed_incorrect.pack()
        changed_frame.pack()

    if len(encrypt_entry.get()) == 26:
        encryption_code = encrypt_entry.get()
        encrypt_entry.delete(0, tkinter.END)
        changed_label.configure(background=window.cget('bg'))
        changed_label.config(text="You have successfully changed the encryption code!")
        change_header.config(text=str(encryption_code))
        changed_incorrect.pack_forget()
        changed_label.pack()
        changed_frame.pack()

    elif len(encrypt_entry.get()) < 26 or len(encrypt_entry.get()) > 26:
        changed_incorrect.configure(background=window.cget('bg'))
        changed_incorrect.config(text="Please enter only 26 characters", foreground='red')
        changed_label.pack_forget()
        changed_incorrect.pack()
        changed_frame.pack()

change_label = tkinter.Label(change_frame, text="Please enter your own encryption code in block capitals", font=('Helvetica', 12))
change_header = tkinter.Label(change_frame, text="Make sure it is all 26 letters and do not repeat a letter to prevent errors", font=('Helvetica', 12))
change_confirm = ttk.Button(change_frame, text="Confirm", width=20,  command=code_change)

changed_label = tkinter.Label(changed_frame, text="You have successfully changed the encryption code!", font=('Helvetica', 14))
changed_incorrect = tkinter.Label(changed_frame, text="Please enter your code again", font=('Helvetica', 14))

change_label.pack()
change_header.pack()
encrypt_entry.pack()
change_confirm.pack()
change_frame.pack()

window.mainloop()

My problem is whenever I try and input 26 characters e.g. QWERTYUIOPASDFGHJKLZXCVBNM, it tells me I haven't entered 26 characters when it clearly is 26 characters and the message is only meant to pop up if the user hasn't entered 26 characters.

UPDATE: using print(len(encrypt_entry.get())) has shown me that my entry is 26 but my code is saying it's not 26 characters.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
Inkblot
  • 708
  • 2
  • 8
  • 19

2 Answers2

3

The issue is in the first if statement -

if encrypt_entry.get() == 'LFWOAYUISVKMNXPBDCRJTQEGHZ' or 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':

This is always True, since the grouping of boolean expressions makes it -

if (encrypt_entry.get() == 'LFWOAYUISVKMNXPBDCRJTQEGHZ') or ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'):

And all non-empty strings are True in boolean context. This causes the program to delete whatever is in the entry, and hence you get the error from second if condition. You can instead do -

encryptgetted = encrypt_entry.get()
if encryptgetted == 'LFWOAYUISVKMNXPBDCRJTQEGHZ' or encryptgetted == 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':
Anand S Kumar
  • 88,551
  • 18
  • 188
  • 176
  • But what do I do when I want a preset code but the user can change it if they choose to? – Inkblot Oct 29 '15 at 10:27
  • What do you mean? Can you give an example? – Anand S Kumar Oct 29 '15 at 10:28
  • This is a snippet from my program. It is an encryption program with the encryption code already set. If the user wants to change the preset code, there's a button which takes them here. But if I use your suggestion they'd have to enter their own encryption code to begin with which I don't want to happen. – Inkblot Oct 29 '15 at 10:30
  • I don't make any such logical changes . My suggestion just fixes the if condition to make it do what you intended to do. – Anand S Kumar Oct 29 '15 at 11:17
  • 1
    I do not see where Anand S Kumars code does change the behavior in a matter of forcing an input. The only change made inside the answer was grouping the if clause correctly to get your desired behavior. Your previous code made it delete input from Entry widgets. `encrypt_entry.delete(0, tkinter.END)` after first `if statement`. – R4PH43L Oct 29 '15 at 11:18
  • My bad I read that wrong. I thought you meant to change `encryption_code` to `encryptgetted` – Inkblot Oct 29 '15 at 11:30
  • No, I am just doing that, so that we don't call `encrypt_entry.get()` twice in the same `if` condition. If you use `encrypt_entry.get()` instead of `encryptgetted` , it would work in same way. – Anand S Kumar Oct 29 '15 at 11:33
2

You have a couple of problems. First is this statement:

if encrypt_entry.get() == 'LFWOAYUISVKMNXPBDCRJTQEGHZ' or 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':

When you use an expression like if x == "a" or "b", it's the same as if you did if (x == "a") or ("b"), which is the same as if (x == "a") or ("b" != "").

Since the second condition will always be true in your code if the entry field is not empty, this whole condition will always be true. So, that block of code is getting executed for everything except the case where the entry field is blank.

The second problem is that inside this first "if" you are deleting everything in the entry widget. Since every "if" block is re-fetching the contents, all of the following "if" statements will be getting an empty string.

The correct way to code this is to get the value exactly once at the start of your program, then make proper use of else so that you only go through one block of code:

user_input = encrypt_entry.get()
if (user_input == 'LFWOAYUISVKMNXPBDCRJTQEGHZ' or 
    user_input == 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'):
    ...
elif (len(user_input) == 26):
    ...
else
    ...
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685