-2

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

  • 1
    Have you looked at the other 100+ "caesar cipher doesn't work" questions and answers on SO? They all come down to the same thing. – zaph Nov 13 '17 at 02:05
  • @zaph I have. However I could not find anyone that is using tkinter having the same problem as me – Oğuzhan Esen Nov 13 '17 at 02:15
  • 1
    Have you tried taking tkinter out of the equation until you get the encryption/decryption working, so that you know where the problem actually lies? – Bryan Oakley Nov 13 '17 at 03:28
  • @Bryan Oakley Yes i have, the original program is working fine. But it wasn't object oriented, so the problem might have something to do with that. – Oğuzhan Esen Nov 13 '17 at 03:33

1 Answers1

0

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()
cdlane
  • 40,441
  • 5
  • 32
  • 81