Search code examples
pythontkintercaesar-cipher

Tkinter GUI for caesar cipher doesn't work as intended


I made a tkinter GUI for the caesar cipher program but it doesn't work properly. I type my message in the first entry box, enter the key in the second one, then click encrypt/decrypt, and the result shows up in the third entry box. But i never get the correct results.

Also sometimes if i use a key that is higher than 6, or enter multiple words, i get the following error:

Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\PC\AppData\Local\Programs\Python\Python35-32\lib\tkinter\__init__.py", line 1549, in __call__
return self.func(*args)
File "C:/Users/PC/PycharmProjects/oyun/sezarUIing.py", line 33, in Encrypt
self.translation = self.translation + self.LETTERS[sayı]
IndexError: string index out of range

here is the code:

from tkinter import *

class Sezar(Frame):
    def __init__(self,pencere):
        Frame.__init__(self,pencere)
        self.pencere = pencere

        self.Lab1 = Label(pencere, text="Enter your message: ",relief= GROOVE, width=20).place(x=20,y=30)

        self.Lab2 = Label(pencere, text="Enter key: ", relief=GROOVE, width=20).place(x=20, y=90)

        self.Ent1 = Entry(pencere,width=30)
        self.Ent1.place(x=170,y=30)

        self.Ent2 = Entry(pencere,width=30)
        self.Ent2.place(x=170,y=90)

        self.But1 = Button(pencere, text="Encrypt", relief=GROOVE,font="bold",command= self.Encrypt).place(x=50,y=150)
        self.But1 = Button(pencere, text="Decrypt", relief=GROOVE, font="bold",command= self.Decrypt).place(x=110, y=150)

        self.RESULT = Entry(pencere, width=30)
        self.RESULT.place(x=170,y=200)

        self.LETTERS = "abcdefghijklmnopqrstuvwxyz"
        self.translation = ""


    def Encrypt(self):
        for num in self.Ent1.get():
            if num in self.LETTERS:
                sayı = self.LETTERS.find(num)
                sayı = sayı + int(self.Ent2.get())
                self.translation = self.translation + self.LETTERS[sayı]
                self.RESULT.insert(0,self.translation)
            else:
                self.translation = self.translation + num


    def Decrypt(self):
        for num in self.Ent1.get():
            if num in self.LETTERS:
                sayı = self.LETTERS.find(num)
                sayı = sayı - int(self.Ent2.get())
                if sayı >= 0:
                    sayı = sayı - len(self.LETTERS)
                elif sayı <= 0:
                    sayı = sayı + len(self.LETTERS)
                self.translation = self.translation + self.LETTERS[sayı]
                self.RESULT.insert(0,self.translation)
            else:
                self.translation = self.translation + num

if __name__ == "__main__":
    root = Tk()
    root.title("Sezar")
    root.geometry("400x300+50+50")
    Sezar(root).pack(side="top",fill = "both")
    root.mainloop()

He is an example of the error and what is expected

Example of the error: Error

Intended result: Expected


Solution

  • Your error message was due to you not using modular arithmetic in your Encrypt() method (you had implemented such in your Decrypt() method.)

    Other problems include not clearing self.RESULT before adding new text; not clearing self.translation before appending the results from a new translation; not controlling letter case; not updating self.RESULT at an appropriate place in your code (if text ends in a number, it's not reflected in the translation).

    Below's my rework of your code addressing the above issues:

    from tkinter import *
    
    class Sezar(Frame):
        LETTERS = "abcdefghijklmnopqrstuvwxyz"
    
        def __init__(self, pencere):
            Frame.__init__(self, pencere)
            self.pencere = pencere
    
            Label(pencere, text="Enter your message: ", relief=GROOVE, width=20).place(x=20, y=30)
            self.Ent1 = Entry(pencere, width=30)
            self.Ent1.place(x=170, y=30)
    
            Label(pencere, text="Enter key: ", relief=GROOVE, width=20).place(x=20, y=90)
            self.Ent2 = Entry(pencere, width=30)
            self.Ent2.place(x=170, y=90)
    
            Button(pencere, text="Encrypt", relief=GROOVE, font="bold", command=self.Encrypt).place(x=50, y=150)
            Button(pencere, text="Decrypt", relief=GROOVE, font="bold", command=self.Decrypt).place(x=110, y=150)
    
            self.RESULT = Entry(pencere, width=30)
            self.RESULT.place(x=170, y=200)
    
        def Encrypt(self):
            key = int(self.Ent2.get())
            length = len(self.LETTERS)
    
            translation = ''
    
            for character in self.Ent1.get():
                if character.lower() in self.LETTERS:
                    sayı = self.LETTERS.find(character.lower())
                    sayı = (sayı + key) % length
                    translation += self.LETTERS[sayı]
                else:
                    translation += character
    
            self.RESULT.delete(0, END)
            self.RESULT.insert(0, translation)
    
        def Decrypt(self):
            key = int(self.Ent2.get())
            length = len(self.LETTERS)
    
            translation = ''
    
            for character in self.Ent1.get():
                if character.lower() in self.LETTERS:
                    sayı = self.LETTERS.find(character.lower())
                    sayı = (sayı - key) % length
                    translation += self.LETTERS[sayı]
                else:
                    translation += character
    
            self.RESULT.delete(0, END)
            self.RESULT.insert(0, translation)
    
    if __name__ == "__main__":
        root = Tk()
        root.title("Sezar")
        root.geometry("400x300+50+50")
        Sezar(root).pack(side="top", fill="both")
        root.mainloop()