[Tutor] Shortening the code of a finsihed program.

Alan Gauld alan.gauld at btinternet.com
Fri Nov 25 02:01:05 CET 2011


On 24/11/11 16:20, Mic wrote:

> and then try to put these parts togheter into a large program, I decided
> to post my entire program.

Its usually better to paste long programs into a pastebin web site and 
give us a link.
This saves cluttering up people mail with long messages, and also the 
pastebin rendering will usually be easier to read with syntax coloring etc.

> achieve. I apologize if my English is flawed, but I hope it is
> understandable.

Your English is excellent and no barrier to understanding what you are 
trying to do.

> #Importing necessary modules.
> from tkinter import*
> import os
>
> chair1_color="green"
> chair1_value=False
>
> chair2_color="green"
> chair2_value=False

You already got some help on how to avoid these global variables by 
creating a subclass of Button. These then become two attributes of the 
new ChairButton class

> #Creates the Main Menu Window.
> class Main_Menu_Window(Frame):
>    def __init__(self,master):
>      super(Main_Menu_Window,self).__init__(master)
>      self.grid()
>      self.create_mainmenu_widgets()
>
>    #Creates the widgets in the window.
>    def create_mainmenu_widgets(self):
>
>       self.instructions=Label(self, text="Welcome to our online booking system")
>       self.instructions.grid()
>
>       self.to_booking_window=Button(self, text="Book/Unbook your ticket",
>                                    command=self.book_unbookmode)
>       self.to_booking_window.grid()
>
>       self.exit_program=Button(self, text="Exit Program",
>                               command=self.exit_program)
>       self.exit_program.grid()
>
>    #Creates a method that quits the program if the user presses the button
>    "Exit Program"
>    def exit_program(self):
>        root.destroy()
>
>    #Creates a new window where you book your tickets if you press the
>    # button "Book/Unbook your ticket".
>    def book_unbookmode(self):
>        class BookOrUnbookTicketWindow(Frame):

While its perfectly legal Python to create a class inside a method its 
very unusual in practice and very restricting in the use of the class. 
Its nearly always better to declare all your classes at the top level of 
the program.


>           def __init__(self,master):
>               super(BookOrUnbookTicketWindow,self).__init__(master)
>               self.grid()
>               self.create_book_unbookmode_widgets()
>
>          #Creates widgets to place in the BookOrUnBookTicketWindow.
>          def create_book_unbookmode_widgets(self):
>              self.instructions_bookticket=Label(self, text="""To book a chair, click
> on a green chair. It then turns red, which means that you have booked
> the chair.
> if you wish to unbook your chair, press the red button once. It will
> then turn green, which means that you have unbooked
> your ticket, and the chair is now bookable again.""")
>              self.instructions_bookticket.grid()
>
> #Creates two chairs. It should be more, but this is just used as an
> example. To get more chairs, this code in the section below
> #this comment will need to be shortened somehow, otherwise the code
> would be way too long.

Because you post lost all the formatting, I'm not sure where this code 
is supposed to sit... This is again where a pastebin would help.

> self.chair1=Button(self, bg=chair1_color, text="01",
> command=self.chair1_clicked)
> self.chair1.grid()
>
> self.chair2=Button(self, bg=chair2_color, text="02",
> command=self.chair2_clicked)
> self.chair2.grid()
>
> def chair1_clicked(self):
> """ This method runs if chair one is clicked"""
>
> def change_chair1_value():
> global chair1_value
> chair1_value=not chair1_value

And this is repeating all the bad habits from your original posts. If 
you adopt the ChairButton class approach all of this becomes much 
clearer and simpler.

> change_chair1_value()
>
> if chair1_value:
>
> self.chair1.configure(bg="Red")
> text_file=open("New_York_Canada_15_00_Chair1","w")
> text_file.write( "New York-Canada\nSeat:1")#Notice that I want the Seat
> number written into the
> #textfile should be 1, if you press chair one,
> #2 if you press chair 2, 3 if you press chair 3 and so on.
> #However, the text should be "New York-Canada should
> # be the same for all chairs.
> text_file.close()
>
> def change_chair1_color_red():
> global chair1_color
> chair1_color=("red")
> change_chair1_color_red()
>
>
>
>
> else:
> self.chair1.configure(bg="green")
> os.remove ("New_York_Canada_15_00_Chair1")
> #The file is supposed to be removed because
> #it means that you have unbooked your ticket.
>
>
>
>
> def change_chair1_color_green():
> global chair1_color
> chair1_color=("green")
> change_chair1_color_green()
>
>
> #-------------------------------------------------
> def chair2_clicked(self):
> """ Ths method runs if chair two is clicked"""
>
> def change_chair2_value():
> global chair2_value
> chair2_value=not chair2_value
>
> change_chair2_value()
>
> if chair2_value:
>
> self.chair2.configure(bg="Red")
> text_file=open("New_York_Canada_15_00_Chair2","w")#The file name should
> end with 1 if chair one is pressed.
> #if chair2 is pressed, it should end with chair2. If chair three is
> #pressed it should end with chair3, and so on. The start of the filname
> #"New_York_Canada_15_00_ should be the same for all chairs.
>
> text_file.write( "New York-Canada\nSeat:2")#Notice that I want the Seat
> number written into the
> #textfile should be 1, if you press chair one,
> #2 if you press chair 2, 3 if you press chair 3 and so on.
> #However, the text should be "New York-Canada should
> # be the same for all chairs.
> text_file.close()
>
> def change_chair2_color_red():
> global chair2_color
> chair2_color=("red")
> change_chair2_color_red()
>
> else:
> self.chair2.configure(bg="green")
> os.remove ("New_York_Canada_15_00_Chair2")
> #The file is supposed to be removed because
> #it means that you have unbooked your ticket.
>
> def change_chair2_color_green():
> global chair2_color
> chair2_color=("green")
> change_chair2_color_green
> #-------------------------------------------------
> #As seen above, the two functions are very similiar. I have no
> #idea how to make this code shorter and more elegant. The program
> #is already fullfilling its purpose. But instead of writing a function
> #for each chair I want to solve it somehow.

Use the ChairButton technique from the earlier thread.

def ChairButton(Button):
     def __init__(self, *args, **kwargs):
         self.value = False
         self.color = "green"
         super....

etc...

> root=Tk()
> root.title("Book/Unbooking Mode")
> root.geometry("800x800")
> app=BookOrUnbookTicketWindow(root)
> root.mainloop()
>
> root=Tk()

You should only ever have one Tk() object in a Tkinter program.

If you need two windows open at the same time you should either make one 
a child of the other and launch the second from the firsts initialiser. 
Or make one a subclass of TopLevel rather than Frame

> root.title("Online Booking System")
> root.geometry("200x200")
> app=Main_Menu_Window(root)
> root.mainloop()

And again you should only have one mainloop running, otherwise things 
would get very confusing with events winding up in the wrong windows 
event queue etc.

HTH,
-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/



More information about the Tutor mailing list