I created a Caesar Cipher Program in Tkinter, to help me learn the Model-View-Controller concepts and Tkinter in general. The code works, but it is a mess, and I want some help on cleaning it up, reducing junk, and just making it better.
import string
import tkinter as tk
from tkinter import ttk
class TextIO(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent
self.inputLabel = ttk.Label(self, text = "Input:")
self.inputLabel.grid(row = 0, column = 0)
self.inputString = tk.Text(self)
self.inputString.grid(row = 1, column = 0)
self.outputLabel = ttk.Label(self, text = "Output:")
self.outputLabel.grid(row = 2, column = 0)
self.output = tk.Text(self)
self.output.insert("0.0", "Type -1 in shift if you want all shifts when decrypting")
self.output.grid(row = 3, column = 0)
class ButtonBox(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent
self.shift = tk.Frame(self)
self.shift.grid(row = 0, column = 0)
self.shiftLabel = ttk.Label(self.shift, text = "Shift:")
self.shiftLabel.grid(row = 0, column = 0)
self.amountShift = ttk.Entry(self.shift, width = 5)
self.amountShift.grid(row = 0, column = 1)
self.encryptButton = ttk.Button(self, text = "Encrypt")
self.encryptButton.grid(row = 0, column = 2)
self.decryptButton = ttk.Button(self, text = "Decrypt")
self.decryptButton.grid(row = 0, column = 3)
class Model:
def encrypt(self, message, shift):
shift = int(shift % 26)
ALPHALOWER = string.ascii_lowercase
ALPHAUPPER = string.ascii_uppercase
#Shift letters based on the 'shift' amount
shiftLower = ALPHALOWER[shift:26] + ALPHALOWER[0:shift]
shiftUpper = ALPHAUPPER[shift:26] + ALPHAUPPER[0:shift]
lowerMapping = dict(zip(ALPHALOWER, shiftLower))#Entry: {a: b, b: c}
upperMapping = dict(zip(ALPHAUPPER, shiftUpper))
encrypted = ''
#For every character in unencrypted, find if it is a letter,
for index, char in enumerate(message):
if char.isalpha() is True:
#Then if it is, look for the key in lowerMapping, and if it
#isn't found, look in upperMapping
try:
encrypted += lowerMapping[char]
#Returns the shifted letter
except KeyError:
encrypted += upperMapping[char]
else:
#If it is not a letter, just add it to the string
encrypted += char
return encrypted
def decrypt(self, message, shift):
if shift == -1:
allDecryptions = {}
for i in range(0, 26):
allDecryptions[i] = self.encrypt(message, i)
allDecryptionsString = ''
for i in range(0, 26):
allDecryptionsString += str(i) + ': ' + allDecryptions[i]
return allDecryptionsString
else:
shift = int(shift % 26)
decrypted = self.encrypt(message, -shift)#Negative Shift
return decrypted
class MainWindow(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent
self.model = Model()
self.UserIO = TextIO(self)
self.UserIO.grid(row = 0, column = 0)
self.Buttons = ButtonBox(self)
self.Buttons.grid(row = 1, column = 0)
self.Buttons.encryptButton.config(command = self.Encrypt)
self.Buttons.decryptButton.config(command = self.Decrypt)
def Encrypt(self):
message = self.UserIO.inputString.get("1.0", tk.END)
try:
shift = int(self.Buttons.amountShift.get())
except ValueError:
tk.messagebox.showerror("Invalid Shift",
"You did not enter a valid shift, assumed 1")
shift = 1
self.UserIO.output.delete("1.0", tk.END)
self.UserIO.output.insert("1.0", self.model.encrypt(message, shift))
def Decrypt(self):
message = self.UserIO.inputString.get("1.0", tk.END)
try:
shift = int(self.Buttons.amountShift.get())
except ValueError:
tk.messagebox.showerror("Invalid Shift",
"You did not enter a valid shift,assumed 1")
shift = 1
self.UserIO.output.delete("1.0", tk.END)
self.UserIO.output.insert("1.0", self.model.decrypt(message, shift))
root = tk.Tk()
root.resizable(width = False, height = False)
MainWindow(root).pack()
root.mainloop()
The program uses 2 section for the 'view' of the GUI, a 'TextIO' box of two tk.Text()
s, and a ButtonBox
with the shift for the CaesarCipher and the Encrypt and Decrypt buttons. I included the encrypt()
and decrypt()
in the Model, I'm not sure if that is the proper way to do that, and the Controller
is the MainWindow