#! /usr/bin/python # File: switches5.py by David MacKay (December 2005) # Makes 7 switches with 7 bulbs and connections between them # Allows the user to configure any connections, # including Alan's configuration (0111111,...) # and David's (0110001,...) # # License: this is completely free software # You may do anything with it. from Tkinter import * def flipswitch(k): print "switch",k for n in range(N) : ## for each bulb n if c[k][n].get() : ## if the bulb n is connected to switch k bulbs[n].invoke() ## then press the bulb button pass def flipbulb(x): print "bulb",x ## report that bulb x has been flipped pass root = Tk() ## create a Tk root widget. This is an ordinary window K = 7 ## number of switches N = K ## number of bulbs switchrow = 2 ## where to put the switches in the grid bulbrow = switchrow+1 ## where to put the bulbs ## make labels and put them on these two rows switchlabel = Label(root, text="switches", bg="white" ) switchlabel.grid(row=switchrow,column=0) bulblabel = Label(root, text="bulbs") bulblabel.grid(row=bulbrow,column=0) ## make the switches s =[] switches = [] for k in range(K) : s.append( IntVar() ) ## this makes the integer variable s[k] functionname = eval('lambda: flipswitch('+str(k)+')' ) ## create the string lambda: flipswitch(1) ## and evaluate it, thus creating a function ## this makes switches[k] switches.append( Checkbutton( root , text=k , command=functionname , variable=s[k] , bg="white" ) ) switches[k].grid(row=switchrow,column=k+1) ## make the bulbs b=[] bulbs = [] for n in range(N) : b.append( IntVar() ) ## this makes the integer variable b[n] functionname = eval('lambda: flipbulb('+str(n)+')' ) ## create the string lambda: flipbulb(1) ## and evaluate it, thus creating a function ## this makes switches[k]: bulbs.append( Checkbutton( root , text=n , command=functionname , variable=b[n] , selectcolor="yellow") ) bulbs[n].grid(row=bulbrow,column=n+1) ## create the connection variables and objects connectionrow = bulbrow + 2 c = [] ## c is going to be a list of lists (a matrix) which we will use like this: c[k][n] connections = [] connectionlabel = Label(root, text='Connections' ) connectionlabel.grid(row=connectionrow,column=0) for k in range(K) : c.append([]) ## make a place for the objects c[k][n] to live rowlabel = Label(root, text=k ) rowlabel.grid(row=connectionrow+k+1,column=0) for n in range(N) : c[k].append( IntVar() ) ## this makes the integer c[k][n] thisb = Checkbutton( root , variable=c[k][n] ) connections.append( thisb ) thisb.grid( row = connectionrow + k +1 , column=n+1 ) def setconnections ( alanrule ) : ## set the connection variables in the 1011111 configuration (if alanrule==1) ## or set the connection variables in the 1011000 configuration (otherwise) for k in range(K) : if alanrule : for n in range(N) : if k==n: c[k][n].set(0) else: c[k][n].set(1) else : for n in range(N) : c[k][n].set(0) c[k][k-1].set(1) c[k][k-6].set(1) c[k][k-5].set(1) pass def setbulbs ( value ) : ## set the bulbs to 'value' for n in range(N) : b[n].set(value) pass # make a red quit button quit = Button( root , borderwidth=3, padx=12,pady=12,text="quit" , fg="red", \ activebackground="red1",command=root.quit ) quit.grid(row=0,column=0) # make buttons that invoke the alan and david connection schemes alan = Button( root , borderwidth=3, text="alan" , bg="green", command=lambda:setconnections(1)) alan.grid(row=0,column=1, columnspan=3) david = Button( root , borderwidth=3, text="david" , bg="lightblue", command=lambda:setconnections(0)) david.grid(row=0,column=4, columnspan=3) # make two more useful buttons that invoke the "setbulbs" function bottomrow = connectionrow + 1 + K allOn = Button( root , borderwidth=3, text="all bulbs on" , bg="yellow", \ command=lambda:setbulbs(1),activebackground="lightyellow1") allOn.grid(row=bottomrow,column=1, columnspan=3) allOff = Button( root , borderwidth=3, text="all bulbs off" , bg="lightblue3",\ command=lambda:setbulbs(0),activebackground="lightblue1") allOff.grid(row=bottomrow,column=4, columnspan=3) # set up the connections in the "David" scheme setconnections(0) # make the GUI go! root.mainloop()