简体   繁体   中英

How can I optimize my code for my Spanish Translation Program?

I am currently a student obtaining a Bachelor's in Computer Science, and I am writing a python program in the little spare time that I have to help me learn Spanish. It's definitely not an extravagant program that I'm going to publish or anything, just for me to have fun and mess around with. I just learned the basic GUI structure of python programming with Tkinter, and I am just trying to be pointed in the right direction to optimize my code to make it smaller and not look so basic. I have 3500 lines of code so far, so I won't upload the whole code, but here is the structure of pretty much my entire program

def _months( self ):
    #Framework for the Month Window
    Frame.__init__( self )
    self.master.title( "Months" )
    self.grid()
    labelfont = ( "times", 18, "bold" )
    homefont = ( "times", 10, "bold" )

    self._monthMenuImage = PhotoImage( file = 'mexicoWater.gif' )
    self._monthBackgroundLabel = Label( self, image = self._monthMenuImage )
    self._monthBackgroundLabel.place( x = 0, y = 0 )
    self.grid_propagate(0)
    self["height"] = 600
    self["width"] = 800

    #January button
    self._januaryButton = Button( self, text = "January",
                                  command = self._switchJanuary )
    self._januaryButton.config( font = labelfont, bg = self.water2 )
    self._januaryButton.config( height = 0, width = 10 )
    self._januaryButton.place( x = 65, y = 325 )

    #February button
    self._februaryButton = Button( self, text = "February",
                                   command = self._switchFebruary )
    self._februaryButton.config( font = labelfont, bg = self.water2 )
    self._februaryButton.config( height = 0, width = 10 )
    self._februaryButton.place( x = 315, y = 325 )

    #March button
    self._marchButton = Button( self, text = "March",
                                command = self._switchMarch )
    self._marchButton.config( font = labelfont, bg = self.water2 )
    self._marchButton.config( height = 0, width = 10 )
    self._marchButton.place( x = 565, y = 325 )

The "command = self._switch...." leads to different methods such as

 def _switchJanuary( self ):
    if self._januaryButton["text"] == "January":
        self._januaryButton.config( bg = self.water1 )
        self._januaryButton["text"] = "Enero"
    else:
        self._januaryButton["text"] = "January"
        self._januaryButton.config( bg = self.water2 )

def _switchFebruary( self ):
    if self._februaryButton["text"] == "February":
        self._februaryButton.config( bg = self.water1 )
        self._februaryButton["text"] = "Febrero"
    else:
        self._februaryButton["text"] = "February"
        self._februaryButton.config( bg = self.water2 )

def _switchMarch( self ):
    if self._marchButton["text"] == "March":
        self._marchButton.config( bg = self.water1 )
        self._marchButton["text"] = "Marzo"
    else:
        self._marchButton["text"] = "March"
        self._marchButton.config( bg = self.water2 )

"self.water1" and "self.water2" are just cool blue colors that I declared as class variables earlier on.

This is the basic structure of my entire code, with months, days, numbers and such. I'm just trying to find a way to make the code smaller, because I want to add a lot of different features to the program without it being a million lines. I've been told to use a dictionary, in which I could access the key values to translate the words instead of having to have each Button lead to a different method, but I am lost. Any help would be greatly appreciated. Thank you for your time!

The best way to archive a smarter (generic) code is the right level of abstraction. If you look closely you will see a pattern in every of those methods. In every method you have two different strings. Like you have already mentioned it is perfect for a dictionary, where the english word remark the key and the spanish word is the value. You have to define a dictionary with all needed word. Than you can create your Buttons, with reference to your generic method. This generic method has a the Button as a paramter. Now you check if the button-text matches the keys, if not check if the button-text matches those values. I hope you get the idea now. Here is a small working example:

from Tkinter import Tk, Frame, Button

def translate(button):
    if button["text"] in monthdict.keys():
        button.config(bg="Red", text=monthdict[button["text"]])
    else:
        for key, val in monthdict.iteritems():
           if val in button["text"]:
               button.config(bg="Blue", text=key)

root = Tk()
mainframe = Frame(root)
mainframe.pack()
monthdict = {"January": "Enero", "February": "Febrero", "March": "Marzo"}

janbutton = Button(mainframe, text="January", bg="Blue", command= lambda: translate(janbutton))
janbutton.pack()
febbutton = Button(mainframe, text="February", bg="Blue", command= lambda: translate(febbutton))
febbutton.pack()
marchbutton = Button(mainframe, text="March", bg="Blue", command= lambda: translate(marchbutton))
marchbutton.pack()
root.mainloop()

Even here you can optimize. Maybe a smarter way to get the key from a given value in the translate method. Or a smarter way to add the buttons. For example you can use a foreach to create the button. They only problem is that you have to find a way to pass the button as a value to the function.

EDIT:

It kinda bugged me that the foreach didn't worked for creating the buttons right. So the solution is to use binding for each button, with the event parameter you get access to your Button again:

from Tkinter import Tk, Frame, Button

def translate(event):
    if event.widget["text"] in monthdict.keys():
        event.widget.config(bg="Red", text=monthdict[event.widget["text"]])
    else:
        for key, val in monthdict.iteritems():
           if val in event.widget["text"]:
               event.widget.config(bg="Blue", text=key)

root = Tk()
mainframe = Frame(root)
mainframe.pack()
monthdict = {"January": "Enero", "February": "Febrero", "March": "Marzo"}
buttondict = {}

for key in monthdict.keys():
    buttondict[key] = Button(mainframe, text=key, bg="Blue")
    buttondict[key].bind("<Button-1>", translate)
    buttondict[key].pack()

root.mainloop()

With buttondict you still has access to the created Buttons. If i count it right this optimzed 120 lines of code to 13 lines.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM