203 files
765.5 KB
212.1k tokens
2280 symbols
1 requests
Download .txt
Showing preview only (818K chars total). Download the full file or copy to clipboard to get everything.
Repository: PacktPublishing/Tkinter-GUI-Application-Development-Blueprints-Second-Edition
Branch: master
Commit: 1e160c057502
Files: 203
Total size: 765.5 KB

Directory structure:
gitextract_ux_6jgor/

├── Chapter 01/
│   ├── 1.01.py
│   ├── 1.02.py
│   ├── 1.03.py
│   ├── 1.04.py
│   ├── 1.05.py
│   ├── 1.06.py
│   ├── 1.07.py
│   ├── 1.08.py
│   ├── 1.09.py
│   ├── 1.10.py
│   ├── 1.11.py
│   ├── 1.12.py
│   ├── gir.xbm
│   ├── optionDB.txt
│   ├── readme.txt
│   └── textcontent.txt
├── Chapter 02/
│   ├── 2.01.py
│   ├── 2.02.py
│   ├── 2.03.py
│   ├── 2.04.py
│   ├── 2.05.py
│   ├── 2.06.py
│   ├── 2.07.py
│   ├── 2.08.py
│   ├── 2.09.py
│   ├── 2.10.py
│   ├── 2.11.py
│   ├── 2.12.py
│   └── readme.txt
├── Chapter 03/
│   ├── 3.01.py
│   ├── 3.02.py
│   ├── 3.03.py
│   ├── 3.04.py
│   ├── 3.05.py
│   ├── 3.06.py
│   ├── 3.07.py
│   ├── 3.08.py
│   ├── 3.09.py
│   ├── 3.10.py
│   ├── 3.11.py
│   ├── 3.12.py
│   └── readme.txt
├── Chapter 04/
│   ├── 4.01/
│   │   ├── configurations.py
│   │   ├── controller.py
│   │   ├── exceptions.py
│   │   ├── model.py
│   │   └── view.py
│   ├── 4.02/
│   │   ├── configurations.py
│   │   ├── controller.py
│   │   ├── exceptions.py
│   │   ├── model.py
│   │   ├── piece.py
│   │   └── view.py
│   ├── 4.03/
│   │   ├── configurations.py
│   │   ├── controller.py
│   │   ├── exceptions.py
│   │   ├── model.py
│   │   ├── piece.py
│   │   └── view.py
│   ├── 4.04/
│   │   ├── configurations.py
│   │   ├── controller.py
│   │   ├── exceptions.py
│   │   ├── model.py
│   │   ├── piece.py
│   │   └── view.py
│   ├── 4.05/
│   │   ├── configurations.py
│   │   ├── controller.py
│   │   ├── exceptions.py
│   │   ├── model.py
│   │   ├── piece.py
│   │   └── view.py
│   ├── 4.06/
│   │   ├── configurations.py
│   │   ├── controller.py
│   │   ├── exceptions.py
│   │   ├── model.py
│   │   ├── piece.py
│   │   └── view.py
│   ├── 4.07/
│   │   ├── chess_options.ini
│   │   ├── configurations.py
│   │   ├── controller.py
│   │   ├── exceptions.py
│   │   ├── model.py
│   │   ├── piece.py
│   │   ├── preferenceswindow.py
│   │   └── view.py
│   └── readme.txt
├── Chapter 05/
│   ├── 5.01/
│   │   ├── model.py
│   │   ├── player.py
│   │   └── view.py
│   ├── 5.02/
│   │   ├── model.py
│   │   ├── player.py
│   │   └── view.py
│   ├── 5.03/
│   │   ├── model.py
│   │   ├── player.py
│   │   └── view.py
│   ├── 5.04/
│   │   ├── model.py
│   │   ├── player.py
│   │   └── view.py
│   ├── 5.05/
│   │   ├── model.py
│   │   ├── player.py
│   │   ├── seekbar.py
│   │   └── view.py
│   ├── 5.06/
│   │   ├── helpers.py
│   │   ├── model.py
│   │   ├── player.py
│   │   ├── seekbar.py
│   │   └── view.py
│   ├── 5.07/
│   │   ├── helpers.py
│   │   ├── model.py
│   │   ├── player.py
│   │   ├── seekbar.py
│   │   └── view.py
│   ├── 5.08/
│   │   ├── helpers.py
│   │   ├── model.py
│   │   ├── player.py
│   │   ├── seekbar.py
│   │   └── view.py
│   ├── 5.09/
│   │   ├── helpers.py
│   │   ├── model.py
│   │   ├── player.py
│   │   ├── pygleterror.py
│   │   ├── seekbar.py
│   │   └── view.py
│   └── readme.txt
├── Chapter 06/
│   ├── 6.01.py
│   ├── 6.02.py
│   ├── 6.03.py
│   ├── 6.04.py
│   ├── 6.05.py
│   ├── 6.06.py
│   ├── 6.07.py
│   ├── 6.08.py
│   ├── 6.09.py
│   ├── framework.py
│   └── supershapes.py
├── Chapter 07/
│   ├── 7.01/
│   │   ├── constants.py
│   │   └── view.py
│   ├── 7.02/
│   │   ├── constants.py
│   │   └── view.py
│   ├── 7.03/
│   │   ├── audio.py
│   │   ├── constants.py
│   │   └── view.py
│   ├── 7.04/
│   │   ├── audio.py
│   │   ├── constants.py
│   │   └── view.py
│   ├── 7.05/
│   │   ├── audio.py
│   │   ├── constants.py
│   │   └── view.py
│   ├── 7.06/
│   │   ├── audio.py
│   │   ├── constants.py
│   │   └── view.py
│   ├── 7.07/
│   │   ├── audio.py
│   │   ├── constants.py
│   │   ├── score_maker.py
│   │   └── view.py
│   ├── handle_widget_resize.py
│   ├── json/
│   │   ├── chords.json
│   │   ├── progressions.json
│   │   └── scales.json
│   ├── nonresponsive.py
│   └── responsive.py
├── Chapter 08/
│   ├── 8.01_screensaver.py
│   ├── 8.02_pie_chart.py
│   ├── 8.03_bar_graph.py
│   ├── 8.04_scatter_plot.py
│   ├── 8.05_matplotlib_embedding_graphs.py
│   ├── 8.06_polar_plot.py
│   ├── 8.07_gravity_simulation.py
│   ├── 8.08_Mandelbrot.py
│   ├── 8.09_vornoi_diagram.py
│   ├── 8.10_spring_pendulum.py
│   ├── 8.11_chaos_game.py
│   ├── 8.12_phyllotaxis.py
│   └── 8.13_3D_graphics.py
├── Chapter 09/
│   ├── 9.01_race_condition.py
│   ├── 9.02_lock_demo.py
│   ├── 9.03_threading_with queue.py
│   ├── 9.04_game_of_ snake.py
│   ├── 9.05_urllib_demo.py
│   ├── 9.06_weather_ reporter.py
│   ├── 9.07_socket_demo.py
│   ├── 9.08_port_scanner.py
│   ├── 9.09_chat_server.py
│   ├── 9.10_chat_client.py
│   ├── 9.11_phonebook.py
│   ├── 9.12_async_demo.py
│   ├── 9.13.arduino_sketch.ino
│   ├── 9.14_read_from_serial_port.py
│   └── readme.txt
├── Chapter 10/
│   ├── 10.01_trace_variable.py
│   ├── 10.02_widget_traversal.py
│   ├── 10.03_validation_mode_demo.py
│   ├── 10.04_percent _substitutions _demo.py
│   ├── 10.05_key_validation.py
│   ├── 10.06_focus_out _validation.py
│   ├── 10.07_formatting_entry_widget_to_display_date.py
│   ├── 10.08_font_demo.py
│   ├── 10.09_all_fonts_on_a_system.py
│   ├── 10.10_font_selector.py
│   ├── 10.11_reading_from_command_line.py
│   └── 10.12_tkinter_class_hierarchy.py
├── LICENSE
└── README.md

================================================
FILE CONTENTS
================================================

================================================
FILE: Chapter 01/1.01.py
================================================
"""
Code illustration: 1.01
Your first GUI application - the top level window
Tkinter GUI Application Development Blueprints
"""

import tkinter as tk
root = tk.Tk()
root.mainloop()


================================================
FILE: Chapter 01/1.02.py
================================================
"""
Code illustration: 1.02
Adding some widgets
Tkinter GUI Application Development Blueprints
"""

import tkinter as tk
root =tk.Tk()
my_label = tk.Label(root, text="I am a label widget")  #(1)
my_button = tk.Button(root, text="I am a button")  #(2)
my_label.pack()  #(3)
my_button.pack()  #(4)
root.mainloop()


================================================
FILE: Chapter 01/1.03.py
================================================
"""
Code illustration: 01.03
A demonstration of all core tkinter widgets
Tkinter GUI Application Development Blueprints
"""

import tkinter as tk

root = tk.Tk()
root.title('I am a Top Level Widget, parent to other widgets')
#create a frame widget for placing menu
my_menu_bar = tk.Frame(root, relief='raised', bd=2)
my_menu_bar.pack(fill=tk.X)

# Create  Menu Widget 1 and Sub Menu 1
my_menu_button = tk.Menubutton(
    my_menu_bar,
    text='Menu tk.Button Widget 1',
)
my_menu_button.pack(side=tk.LEFT)
#menu widget
my_menu = tk.Menu(my_menu_button, tearoff=0)
my_menu_button['menu'] = my_menu
my_menu.add('command', label='Menu Widget 1')  #Add Sub Menu 1

# Create  Menu2 and Submenu2
menu_button_2 = tk.Menubutton(
    my_menu_bar,
    text='Menu 2',
)
menu_button_2.pack(side=tk.LEFT)
my_menu_2 = tk.Menu(menu_button_2, tearoff=0)
menu_button_2['menu'] = my_menu_2
my_menu_2.add('command', label='Sub Menu 2')  # Add Sub Menu 2

#
#
# my_frame_1  and its contents
#

# creating a frame (my_frame_1)
my_frame_1 = tk.Frame(root, bd=2, relief=tk.SUNKEN)
my_frame_1.pack(side=tk.LEFT)

# add label to to my_frame_1
tk.Label(my_frame_1, text='I am a tk.Label widget').pack()

#add entry widget to my_frame_1
tv = tk.StringVar()  #discussed later
tk.Entry(my_frame_1, textvariable=tv).pack()
tv.set('I am an entry widget')

#add button widget to my_frame_1
tk.Button(my_frame_1, text='tk.Button widget').pack()

#add check button widget to my_frame_1
tk.Checkbutton(my_frame_1, text='Checktk.Button Widget').pack()

#add radio buttons to my_frame_1
tk.Radiobutton(my_frame_1, text='Radio tk.Button  Un', value=1).pack()
tk.Radiobutton(my_frame_1, text='Radio tk.Button  Dos', value=2).pack()
tk.Radiobutton(my_frame_1, text='Radio tk.Button  Tres', value=3).pack()

#tk.OptionMenu Widget
tk.Label(my_frame_1, text='Example of tk.OptionMenu Widget:').pack()
tk.OptionMenu(my_frame_1, '', "Option A", "Option B", "Option C").pack()

#adding my_image image
tk.Label(my_frame_1, text='Image Fun with Bitmap Class:').pack()
my_image = tk.BitmapImage(file="gir.xbm")
my_label = tk.Label(my_frame_1, image=my_image)
my_label.image = my_image  # keep a reference!
my_label.pack()

#
#
# frame2 and widgets it contains.
#
#

#create another frame(my_frame_2) to hold a list box, Spinbox Widget,Scale Widget, :
my_frame_2 = tk.Frame(root, bd=2, relief=tk.GROOVE)
my_frame_2.pack(side=tk.RIGHT)

#add Photimage Class Widget to my_frame_2
tk.Label(
    my_frame_2, text='Image displayed with \nPhotoImage class widget:').pack()
dance_photo = tk.PhotoImage(file='dance.gif')
dance_photo_label = tk.Label(my_frame_2, image=dance_photo)
dance_photo_label.image = dance_photo
dance_photo_label.pack()

#add my_listbox widget to my_frame_2
tk.Label(my_frame_2, text='Below is an example of my_listbox widget:').pack()
my_listbox = tk.Listbox(my_frame_2, height=4)
for line in ['Listbox Choice 1', 'Choice 2', 'Choice 3', 'Choice 4']:
  my_listbox.insert(tk.END, line)
my_listbox.pack()

#spinbox widget
tk.Label(my_frame_2, text='Below is an example of spinbox widget:').pack()
tk.Spinbox(my_frame_2, values=(1, 2, 4, 8, 10)).pack()

#scale widget
tk.Scale(
    my_frame_2, from_=0.0, to=100.0, label='Scale widget',
    orient=tk.HORIZONTAL).pack()

#LabelFrame
label_frame = tk.LabelFrame(
    my_frame_2, text="LabelFrame Widget", padx=10, pady=10)
label_frame.pack(padx=10, pady=10)
tk.Entry(label_frame).pack()

#message widget
tk.Message(my_frame_2, text='I am a Message widget').pack()

#
#
# tk.Frame 3
#
#

my_frame_3 = tk.Frame(root, bd=2, relief=tk.SUNKEN)

#text widget and associated tk.Scrollbar widget
my_text = tk.Text(my_frame_3, height=10, width=40)
file_object = open('textcontent.txt')
file_content = file_object.read()
file_object.close()
my_text.insert(tk.END, file_content)
my_text.pack(side=tk.LEFT, fill=tk.X, padx=5)

#add scrollbar widget to the text widget
my_scrollbar = tk.Scrollbar(my_frame_3, orient=tk.VERTICAL, command=my_text.yview)
my_scrollbar.pack()
my_text.configure(yscrollcommand=my_scrollbar.set)
my_frame_3.pack()

#
#
# tk.Frame 4
#
#
#create another frame(my_frame_4)
my_frame_4 = tk.Frame(root)
my_frame_4.pack()

my_canvas = tk.Canvas(my_frame_4, bg='white', width=340, height=80)
my_canvas.pack()
my_canvas.create_oval(20, 15, 60, 60, fill='red')
my_canvas.create_oval(40, 15, 60, 60, fill='grey')
my_canvas.create_text(
    130, 38, text='I am a tk.Canvas Widget', font=('arial', 8, 'bold'))

#
#
# A paned window widget
#
#

tk.Label(root, text='Below is an example of Paned window widget:').pack()
tk.Label(
    root,
    text='Notice you can adjust the size of each pane by dragging it').pack()
my_paned_window_1 = tk.PanedWindow()
my_paned_window_1.pack(fill=tk.BOTH, expand=2)
left_pane_text = tk.Text(my_paned_window_1, height=6, width=15)
my_paned_window_1.add(left_pane_text)
my_paned_window_2 = tk.PanedWindow(my_paned_window_1, orient=tk.VERTICAL)
my_paned_window_1.add(my_paned_window_2)
top_pane_text = tk.Text(my_paned_window_2, height=3, width=3)
my_paned_window_2.add(top_pane_text)
bottom_pane_text = tk.Text(my_paned_window_2, height=3, width=3)
my_paned_window_2.add(bottom_pane_text)

root.mainloop()


================================================
FILE: Chapter 01/1.04.py
================================================
"""
Code illustration: 1.04
A demonstration of some of pack() options
Tkinter GUI Application Development Blueprints
"""
import tkinter as tk
root = tk.Tk()

frame = tk.Frame(root)
# demo of side and fill options
tk.Label(frame, text="Pack Demo of side and fill").pack()
tk.Button(frame, text="A").pack(side=tk.LEFT, fill=tk.Y)
tk.Button(frame, text="B").pack(side=tk.TOP, fill=tk.X)
tk.Button(frame, text="C").pack(side=tk.RIGHT, fill=tk.NONE)
tk.Button(frame, text="D").pack(side=tk.TOP, fill=tk.BOTH)
frame.pack()  # note the top frame does not expand nor does it fill in
#X or Y directions

# demo of expand options - best understood by expanding the root widget
# and seeing the effect on all the three buttons below.
tk.Label(root, text="Pack Demo of expand").pack()
tk.Button(root, text="I do not expand").pack()
tk.Button(root, text="I do not fill x but I expand").pack(expand=1)
tk.Button(root, text="I fill x and expand").pack(fill=tk.X, expand=1)

root.mainloop()


================================================
FILE: Chapter 01/1.05.py
================================================
"""
Code illustration: 1.05
Where to use pack() options

@Tkinter GUI Application Development Blueprints
"""

import tkinter as tk
root = tk.Tk()
parent = tk.Frame(root)

#placing widgets top-down
tk.Button(parent, text='ALL IS WELL').pack(fill=tk.X)
tk.Button(parent, text='BACK TO BASICS').pack(fill=tk.X)
tk.Button(parent, text='CATCH ME IF U CAN').pack(fill=tk.X)
#placing widgets side by side
tk.Button(parent, text='LEFT').pack(side=tk.LEFT)
tk.Button(parent, text='CENTER').pack(side=tk.LEFT)
tk.Button(parent, text='RIGHT').pack(side=tk.LEFT)
parent.pack()
root.mainloop()


================================================
FILE: Chapter 01/1.06.py
================================================
"""
Code illustration: 1.06
Simple example of grid Geometry Manager

@Tkinter GUI Application Development Blueprints
"""
import tkinter as tk
root = tk.Tk()
tk.Label(root, text="Username").grid(row=0, sticky=tk.W)
tk.Label(root, text="Password").grid(row=1, sticky=tk.W)
tk.Entry(root).grid(row=0, column=1, sticky=tk.E)
tk.Entry(root).grid(row=1, column=1, sticky=tk.E)
tk.Button(root, text="Login").grid(row=2, column=1, sticky=tk.E)
root.mainloop()


================================================
FILE: Chapter 01/1.07.py
================================================
"""
Code illustration: 1.07
A demonstration of grid() geometry manager options
@Tkinter GUI Application Development Blueprints
"""
import tkinter as tk
parent = tk.Tk()
parent.title('Find & Replace')

tk.Label(parent, text="Find:").grid(row=0, column=0, sticky='e')
tk.Entry(parent, width=60).grid(row=0, column=1, padx=2, pady=2, sticky='we', columnspan=9)

tk.Label(parent, text="Replace:").grid(row=1, column=0, sticky='e')
tk.Entry(parent).grid(row=1, column=1, padx=2, pady=2, sticky='we', columnspan=9)

tk.Button(parent, text="Find").grid(row=0, column=10, sticky='e'+'w', padx=2, pady=2)
tk.Button(parent, text="Find All").grid(row=1, column=10, sticky='e'+'w', padx=2)
tk.Button(parent, text="Replace").grid(row=2, column=10, sticky='e'+'w', padx=2)
tk.Button(parent, text="Replace All").grid(row=3, column=10, sticky='e'+'w', padx=2)


tk.Checkbutton(parent, text='Match whole word only ').grid(row =2, column=1, columnspan=4,sticky='w')
tk.Checkbutton(parent, text='Match Case').grid(row =3, column=1, columnspan=4,sticky='w')
tk.Checkbutton(parent, text='Wrap around').grid(row =4, column=1, columnspan=4,sticky='w')



tk.Label(parent, text="Direction:").grid(row=2, column=6,sticky='w')
tk.Radiobutton(parent, text='Up',  value=1).grid(row=3, column=6, columnspan=6, sticky='w')
tk.Radiobutton(parent, text='Down',  value=2).grid(row=3, column=7,columnspan=2, sticky='e')


parent.mainloop()


================================================
FILE: Chapter 01/1.08.py
================================================
"""
Code illustration: 1.08
A demonstration of common place() options

@Tkinter GUI Application Development Blueprints
"""
import tkinter as tk
root = tk.Tk()
# Absolute positioning
tk.Button(root, text="Absolute Placement").place(x=20, y=10)
# Relative positioning
tk.Button(
    root, text="Relative").place(
        relx=0.8, rely=0.2, relwidth=0.5, width=10, anchor=tk.NE)
root.mainloop()


================================================
FILE: Chapter 01/1.09.py
================================================
"""
Code illustration: 1.09
A demonstration of event binding with the bind() method

@Tkinter GUI Application Development Blueprints
"""
import tkinter as tk

root = tk.Tk()
tk.Label(root, text='Click at different \n locations in the frame below').pack()
def callback(event): ##(2)
    print(dir(event))##(3) Inspecting the instance event
    print("you clicked at", event.x, event.y )##(4)


frame = tk.Frame(root, bg='khaki', width=130, height=80)
frame.bind("<Button-1>", callback)##(1)
frame.pack()

root.mainloop()


================================================
FILE: Chapter 01/1.10.py
================================================
"""
Code illustration: 1.10
A demonstration of events and the information available in it.

@Tkinter GUI Application Development Blueprints
"""
import tkinter as tk

def show_event_details(event):
  print('='*50)
  print("EventKeySymbol=" + str(event.keysym))
  print("EventType=" + str(event.type))
  print("EventWidgetId=" + str(event.widget))
  print("EventCoordinate (x,y)=(" + str(event.x)+","+str(event.y)+")")
  print("Time:", str(event.time))

root = tk.Tk()

button = tk.Button(root, text="tk.Button Bound to: \n Keyboard Enter & Mouse Click") #create button
button.pack(pady=5,padx=4)
button.focus_force()
button.bind("<Button-1>", show_event_details)  #bind button to mouse click
button.bind("<Return>", show_event_details)#bind button to Enter Key


tk.Label(text="tk.Entry is Bound to Mouseclick \n, FocusIn and Keypress Event").pack()
entry = tk.Entry(root) #creating entry widget
entry.pack()


#binding entry widget to mouse click and focus in
entry.bind("<Button-1>", show_event_details) # left mouse click
entry.bind("<Button-2>", show_event_details) # right mouse click
entry.bind("<FocusIn>", show_event_details)

#binding entry widget alphabets and numbers from keyboard
alpha_num_keys = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789'
for key in alpha_num_keys:
    entry.bind("<KeyPress-%s>"%key, show_event_details)

#binding entry widget to keysym
keysyms = ['Alt_L', 'Alt_R','BackSpace', 'Cancel', 'Caps_Lock','Control_L',
           'Control_R','Delete', 'Down', 'End', 'Escape', 'Execute','F1',
           'F2', 'Home', 'Insert', 'Left','Linefeed','KP_0','KP_1','KP_2',
           'KP_3','KP_4','KP_5','KP_6','KP_7','KP_8','KP_9','KP_Add',
           'KP_Decimal','KP_Divide']
for i in keysyms:
    entry.bind("<KeyPress-%s>"%i, show_event_details)


#binding tk.Canvas widget to Motion Event
tk.Label(text="Canvas Bound to Motion Event\n(Hover over the area \nto see motion event )").pack()
canvas = tk.Canvas(root, background='white',width=100, height=30)
canvas.pack()
canvas.bind('<Motion>', show_event_details)


tk.Label(text="Entry Widget Bound to \n<Any KeyPress>").pack()
entry_1 = tk.Entry(root) #creating entry widget
entry_1.pack(pady=7)
#binding entry widget to mouse click and focus in
entry_1.bind("<Any KeyPress>", show_event_details) # right mouse click


root.mainloop()


================================================
FILE: Chapter 01/1.11.py
================================================
"""
Code illustration: 1.11
A demonstration of tkinter Variable Class
IntVar, StringVar & BooleanVar

@Tkinter GUI Application Development Blueprints
"""
import tkinter as tk
root = tk.Tk()

def show():
    print( "You entered:")
    print( "Employee Number: "+ str(employee_number.get()))
    print( "Login Password: "+ password.get())
    print( "Remember Me: "+ str(remember_me.get()))
    print( '*'*30)

#demo of IntVar
tk.Label(root, text="Employee Number:").grid(row=1, column=1)
employee_number = tk.IntVar()
tk.Entry(root, width=40, textvariable=employee_number).grid(row=1, column=2, columnspan=2)
employee_number.set("120350")


#demo of StringVar
tk.Label(root, text="Login Password:").grid(row=2, column=1, sticky='w')
password = tk.StringVar() # defines the widget state as string
tk.Entry(root,width=40, show="*",  textvariable=password).grid(row=2, column=2, columnspan=2)
password.set("mysecretpassword")

tk.Button(root,text="Login", command=show).grid(row=3, column=3)

#demo of Boolean var
remember_me = tk.BooleanVar()
tk.Checkbutton(root, text="Remember Me", variable=remember_me).grid(row=3, column=2)
remember_me.set(True)



root.mainloop()


================================================
FILE: Chapter 01/1.12.py
================================================
"""
Code illustration: 1.12
A demonstration of tkinter styling

@Tkinter GUI Application Development Blueprints
"""

import tkinter as tk
root = tk.Tk()
root.configure(background='#4D4D4D')  #top level styling

# connecting to the external styling optionDB.txt
root.option_readfile('optionDB.txt')

#widget specific styling
text = tk.Text(
    root,
    background='#101010',
    foreground="#D6D6D6",
    borderwidth=18,
    relief='sunken',
    width=17,
    height=5)
text.insert(
    tk.END,
    "Style is knowing who you are,what you want to say, and not giving a damn."
)
text.grid(row=0, column=0, columnspan=6, padx=5, pady=5)

# all the below widgets derive their styling from optionDB.txt file
tk.Button(root, text='*').grid(row=1, column=1)
tk.Button(root, text='^').grid(row=1, column=2)
tk.Button(root, text='#').grid(row=1, column=3)
tk.Button(root, text='<').grid(row=2, column=1)
tk.Button(
    root, text='OK', cursor='target').grid(
        row=2, column=2)  #changing cursor style
tk.Button(root, text='>').grid(row=2, column=3)
tk.Button(root, text='+').grid(row=3, column=1)
tk.Button(root, text='v').grid(row=3, column=2)
tk.Button(root, text='-').grid(row=3, column=3)
for i in range(10):
  tk.Button(
      root, text=str(i)).grid(
          column=3 if i % 3 == 0 else (1 if i % 3 == 1 else 2),
          row=4 if i <= 3 else (5 if i <= 6 else 6))

root.mainloop()


================================================
FILE: Chapter 01/gir.xbm
================================================
#define 1026234pirate_width 226
#define 1026234pirate_height 199
static char 1026234pirate_bits[] = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 
  0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x01, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x02, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x05, 0x80, 0x00, 0x40, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 
  0x02, 0x40, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 
  0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x04, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x6A, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x95, 0x5B, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x6A, 
  0xA4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x54, 0x02, 0xA0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x00, 0x16, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x06, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x40, 0x80, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x80, 0x00, 0x58, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xC0, 0x02, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xA0, 0x01, 
  0x54, 0x05, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB8, 
  0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x60, 0x06, 0x40, 0x80, 0xA9, 0x1A, 0xA0, 0x00, 0x28, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x05, 0x60, 0x40, 0x5A, 0xF4, 
  0x60, 0x80, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x80, 0x02, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x0A, 0x50, 0xB0, 0x03, 0x00, 0x81, 0x81, 0x0A, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x70, 0x00, 0x03, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28, 0x00, 0x00, 0x42, 0x01, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x03, 0x60, 0xB3, 
  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 
  0x54, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0xC0, 0x08, 0x02, 0x90, 0xDE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x40, 0x02, 0x86, 0x02, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x5A, 0x05, 0xD8, 0x29, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x14, 0xA8, 
  0x09, 0x02, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xA5, 
  0x1A, 0x7C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x14, 0x06, 0x18, 0x18, 0x04, 0x06, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0xB0, 0xDA, 0x55, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x04, 0x08, 0x10, 0x0A, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x58, 0x27, 0xAA, 0x0F, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x0A, 0x05, 0x05, 0x01, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 
  0xCF, 0x97, 0x95, 0x35, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x0A, 0xA2, 0x32, 0x08, 0x01, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x50, 0x79, 0xB5, 0x6A, 0xAA, 0x08, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x0A, 
  0x43, 0x21, 0x0E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xEE, 0x75, 
  0xAD, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0xD0, 0x06, 0x0A, 0x05, 0xB0, 0x12, 0x80, 0x02, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0xA0, 0x33, 0x97, 0x56, 0x3D, 0x20, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0F, 0x1A, 0x86, 0x61, 0x10, 
  0x0E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9E, 0xDC, 0xF6, 0x06, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x04, 0x09, 0x91, 0x0A, 0x02, 0x82, 0x06, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0xE8, 0x77, 0x0B, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x02, 0xA0, 0x45, 0x81, 0x01, 
  0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD0, 0xAF, 0x1D, 0x0A, 0x82, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 
  0x0E, 0x06, 0x80, 0x02, 0x00, 0x6A, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 
  0x5F, 0x02, 0x04, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x18, 0x12, 0x08, 0x60, 0x80, 0x00, 0x10, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0xD8, 0x5F, 0x01, 0x00, 0x86, 0x01, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x0C, 0x50, 
  0x57, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0xAF, 0x02, 
  0x18, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x28, 0x16, 0xA0, 0x05, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0xBE, 0x55, 0x42, 0x18, 0xA0, 0x01, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x18, 0x00, 0x00, 0x10, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x2A, 0xE2, 0x60, 0x44, 
  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x20, 0xA4, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0xAF, 0x15, 0xC4, 0x54, 0x95, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x40, 0xA0, 0x58, 0x01, 0x00, 0x26, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x0A, 0x02, 0xA8, 0x6A, 0x02, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xB0, 0xA0, 
  0x05, 0x80, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0x15, 
  0x2C, 0x6B, 0xA5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x14, 0x40, 0xC0, 0x02, 0x50, 0x05, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0xFA, 0x0A, 0xD0, 0x95, 0x7A, 0x02, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0xE9, 0xAA, 
  0x02, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFD, 0x05, 0x68, 0x2A, 
  0x75, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 
  0x05, 0x00, 0x00, 0x56, 0x55, 0x00, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x40, 0xFF, 0x03, 0x90, 0xD5, 0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x26, 0x00, 0x58, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x05, 0x50, 0x9A, 0x57, 0x01, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xFF, 
  0x01, 0xA0, 0xD5, 0xAB, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0xA0, 0xFF, 0x01, 0x60, 0xEA, 0xE7, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xFE, 0x02, 0x80, 
  0x95, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x50, 0x7D, 0x01, 0x80, 0x5A, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x18, 0x80, 0x01, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xDA, 0x00, 0x00, 0xA5, 0x15, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x38, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 
  0x7D, 0x00, 0x00, 0x5A, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x1C, 0x00, 0x05, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0xB0, 0xFA, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 
  0x04, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFD, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0xFA, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 
  0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x5A, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0xFA, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFA, 0x2B, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x40, 0xFA, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFE, 0x3D, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x40, 0xFB, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE5, 0x1C, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xAB, 
  0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0xE0, 0x57, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xAB, 0x05, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0xD0, 0xD7, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xDB, 0x07, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 
  0xE5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x58, 0xD5, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0xEA, 0x01, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0xFE, 0x97, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x69, 0x02, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0xFF, 0xAB, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xFF, 0xAB, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x80, 0xFF, 0xD5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x6B, 0x00, 0x00, 
  0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0xA0, 0xFF, 0x97, 0x00, 0x00, 0x00, 0x60, 0x38, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xFF, 0x37, 0x00, 0x00, 0x00, 0x50, 
  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xFE, 
  0x7B, 0x00, 0x00, 0x00, 0x20, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x68, 0xFA, 0x7D, 0x00, 0x00, 0x00, 0x54, 0x28, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0x55, 0x7E, 0x00, 
  0x00, 0x80, 0xAA, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0xE5, 0xA9, 0x5D, 0x00, 0x00, 0x1A, 0x54, 0x05, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFA, 0x57, 0x12, 0x00, 0x00, 0xCE, 
  0xA8, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xFA, 
  0xA9, 0x2A, 0x00, 0x80, 0x0B, 0x28, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x80, 0xFD, 0x97, 0x17, 0x00, 0x40, 0x06, 0x60, 0x56, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xFE, 0xFB, 0x2B, 
  0x00, 0x00, 0x00, 0x64, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0xA0, 0xF5, 0xF5, 0x17, 0x00, 0x00, 0x1C, 0x04, 0xFA, 0x01, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x5A, 0xFE, 0x1F, 0x00, 0x00, 
  0x6A, 0x09, 0xE4, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xA6, 
  0xA9, 0xFD, 0x17, 0x00, 0x00, 0xB4, 0x06, 0xFB, 0x01, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x40, 0x00, 0x49, 0xFA, 0x55, 0xFE, 0x0B, 0x00, 0x00, 0x7A, 0x5B, 
  0x6A, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xDF, 0xB4, 0xFE, 0xAB, 0xFE, 
  0x17, 0x00, 0x00, 0x94, 0xA5, 0xB9, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xFF, 
  0x5F, 0x6B, 0xFF, 0x57, 0xFC, 0x15, 0x00, 0x00, 0xAC, 0x55, 0xDA, 0x0A, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0xDA, 0xFF, 0xE7, 0x97, 0xFF, 0xAF, 0xFF, 0x0B, 0x00, 
  0x00, 0x54, 0xAB, 0x60, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xA5, 0xFF, 0xDB, 0x5F, 
  0xFF, 0x57, 0xFE, 0x05, 0x00, 0x00, 0xA8, 0x36, 0xA0, 0x1F, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x70, 0x5A, 0x2D, 0xC5, 0xAF, 0xFF, 0xAF, 0xBB, 0x0A, 0x00, 0x00, 0x50, 
  0x09, 0xE0, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xD5, 0xAA, 0xDA, 0xA7, 0xFF, 0x67, 
  0xAA, 0x05, 0x00, 0x00, 0x40, 0x02, 0x40, 0x27, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xAA, 
  0x55, 0x67, 0xDA, 0xFF, 0xFB, 0x55, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 
  0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x80, 0x7F, 0x55, 0xDA, 0xAF, 0x6D, 0xFF, 0xF9, 0xAA, 0x05, 
  0x00, 0x00, 0x00, 0x00, 0x80, 0xAD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xAA, 0xA5, 0x5F, 
  0x91, 0xFF, 0xF5, 0x55, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0xC0, 0x5F, 0xAA, 0xAF, 0x27, 0xA9, 0xB6, 0x3A, 0xA9, 0x01, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0xE7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xBF, 0x55, 0x5F, 0xF9, 0x5F, 0x59, 
  0x95, 0x5E, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xA0, 0x5F, 
  0xEA, 0xFF, 0xF6, 0x9F, 0xAA, 0xF8, 0xBF, 0x01, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0xF6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x58, 0x55, 0xAB, 0xD5, 0xFF, 0xFD, 0x7F, 0x55, 0xFF, 0xFF, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFA, 0x03, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xA2, 0xDA, 0xD5, 0xFF, 
  0xFB, 0xFF, 0x9A, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF6, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x04, 0x54, 0xF5, 0xEB, 0xFF, 0xF7, 0xFF, 0xE5, 0xFF, 0xBF, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0xFC, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA8, 0xFA, 0xE5, 0xFF, 0xFF, 0xFF, 
  0xD7, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x06, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x50, 
  0xB5, 0xFB, 0xFF, 0xE7, 0xFF, 0xEB, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0xA8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x01, 0x90, 0x55, 0xF6, 0xFF, 0x5F, 0xFF, 0xD7, 0xFF, 
  0x5F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0F, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x78, 0xAA, 0xE9, 
  0xFF, 0xA3, 0xFF, 0xEB, 0xFF, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0xB8, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x80, 0x00, 0xA8, 0x3F, 0xE7, 0xFF, 0x5B, 0xFE, 0x5B, 0xFF, 0x2F, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x64, 0xFF, 0xF8, 0xFF, 0x6F, 
  0xF9, 0xA5, 0xFE, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x3F, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 
  0xE8, 0xFF, 0xAA, 0xFF, 0xAF, 0x5A, 0x5D, 0xDB, 0x0A, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0xD0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x40, 0x00, 0xD4, 0xFF, 0xD5, 0xFF, 0x57, 0xA5, 0xAA, 
  0xA5, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xE4, 0xFF, 
  0xBA, 0xFF, 0xAB, 0x6E, 0x95, 0x9B, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0xE0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x50, 0x00, 0xE8, 0xFF, 0x75, 0xFE, 0x57, 0xBF, 0xEA, 0x57, 0x05, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xAF, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x00, 0xE8, 0xFF, 0xFB, 0x69, 
  0xD1, 0x7F, 0xE9, 0x57, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 
  0xAB, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x06, 
  0x00, 0xF8, 0xFF, 0xF9, 0x97, 0xED, 0xFF, 0xF6, 0xAF, 0x02, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x60, 0x5E, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0xD0, 0xFF, 0xFD, 0x5A, 0xFA, 0xFF, 
  0xEB, 0x57, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xAD, 0x06, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x00, 0x00, 0xA8, 
  0xFF, 0x53, 0xA5, 0xE5, 0x7F, 0xD6, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x80, 0xDE, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x14, 0x00, 0x00, 0x50, 0xFA, 0x96, 0xDA, 0xFA, 0xBF, 0xAA, 0x65, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xE4, 0x07, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0xA0, 0x55, 0xE9, 
  0x5F, 0xF5, 0x7F, 0xD5, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x80, 0xDF, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x05, 
  0x00, 0x00, 0x50, 0xA6, 0xDA, 0xBF, 0xFA, 0xBF, 0xEA, 0x0F, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xDF, 0x2B, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x58, 0x02, 0x00, 0x00, 0xA0, 0xFD, 0xF5, 0x5F, 0xF5, 
  0x7F, 0xF5, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xBF, 
  0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4, 0x01, 0x00, 0x00, 
  0x00, 0xFF, 0xF9, 0xBF, 0xDC, 0x1F, 0xFA, 0x07, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x80, 0xBF, 0xFA, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x28, 0x02, 0x00, 0x00, 0x80, 0xFE, 0xFB, 0x7F, 0xBD, 0xEF, 0xF5, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xF9, 0x75, 
  0xFE, 0x01, 0x00, 0x00, 0x00, 0x00, 0xB8, 0x01, 0x00, 0x00, 0x00, 0xFD, 
  0xFE, 0xBF, 0xBF, 0x57, 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x80, 0xFE, 0xFD, 0x99, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 
  0x02, 0x00, 0x00, 0x00, 0xFC, 0xFD, 0x5F, 0x7F, 0x69, 0x1D, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFC, 0xFF, 0xF6, 0x5E, 
  0x00, 0x00, 0x40, 0x00, 0xD0, 0x02, 0x00, 0x00, 0x00, 0x60, 0xFA, 0x5F, 
  0x7F, 0x5A, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0xAE, 0xFB, 0x77, 0xA5, 0xE5, 0x01, 0x00, 0x00, 0x00, 0xA8, 0x01, 0x00, 
  0x00, 0x00, 0x80, 0xE5, 0xAF, 0xBE, 0xE5, 0x01, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0xD9, 0xFD, 0xA8, 0x9F, 0xFA, 0x03, 0x00, 
  0x40, 0x00, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x99, 0x67, 0x5D, 0x88, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0xBB, 
  0x55, 0x5E, 0xED, 0x07, 0x00, 0x20, 0x00, 0xD8, 0x00, 0x00, 0x00, 0x00, 
  0xA0, 0x11, 0x04, 0x00, 0xBC, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x5A, 0x75, 0xAD, 0xAA, 0xD1, 0x07, 0x00, 0x60, 0x00, 
  0x30, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x15, 0x00, 0x00, 0x9C, 0x02, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFA, 0xBB, 0xDE, 0x76, 
  0xAA, 0xC7, 0x02, 0x60, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1C, 
  0x00, 0x00, 0x5C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0xF0, 0x4F, 0x7F, 0xFD, 0x67, 0x2A, 0x04, 0x40, 0x00, 0x10, 0x00, 
  0x00, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, 0x6E, 0x02, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x9F, 0x7E, 0xFC, 0xFD, 0x05, 
  0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x1C, 0x00, 0x00, 
  0xE4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 
  0x7F, 0xFF, 0xFF, 0xD3, 0x1A, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x60, 0x28, 0x00, 0x00, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0xF0, 0xAF, 0xFE, 0xFE, 0x9B, 0x29, 0x18, 0x10, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x18, 0x00, 0x00, 0xD8, 0x01, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x5F, 0x79, 
  0xFE, 0xE7, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 
  0x01, 0x00, 0x00, 0x42, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0xA0, 0x65, 0xA2, 0xF9, 0xFB, 0x2B, 0x00, 0x08, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0xA0, 0x1C, 0x00, 0x00, 0xAE, 0x01, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBB, 0x5D, 0xF6, 0xFD, 
  0x17, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 
  0x00, 0x6E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x7E, 0x7E, 0xAB, 0xFF, 0x15, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0xE0, 0x30, 0x00, 0x00, 0x9E, 0x01, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBD, 0xFF, 0x55, 0xF7, 0x1B, 0x80, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x38, 0x00, 0x00, 0x9E, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 
  0xFE, 0xAA, 0xE6, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0xA0, 0x19, 0x00, 0x00, 0xEE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0xA0, 0xFE, 0x55, 0x9D, 0x1A, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x08, 0x00, 0x00, 0xE6, 0x01, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xFD, 0xEB, 
  0xD7, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x11, 
  0x00, 0x00, 0xD8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x80, 0xFE, 0xF4, 0xCB, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x40, 0x2D, 0x00, 0x00, 0xA6, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7E, 0xFB, 0xFF, 0x07, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x10, 0x00, 0x00, 
  0xD8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0xE5, 0xF7, 0xEF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x40, 0x29, 0x00, 0x00, 0x5C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCD, 0xF7, 0xF7, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x15, 0x00, 0x00, 0xD8, 0x01, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x13, 
  0xEB, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 
  0x29, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x0B, 0x80, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0xE0, 0x1C, 0x00, 0x00, 0xFC, 0x01, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x18, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1D, 0x00, 
  0x00, 0xE8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x09, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x40, 0x19, 0x00, 0x00, 0xD4, 0x01, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1A, 0x00, 0x36, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x28, 0x00, 0x00, 0x6C, 
  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x15, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x40, 0x15, 0x00, 0x00, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x80, 0x09, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x21, 0x00, 0x00, 0x6A, 0x01, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 
  0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x3F, 
  0x00, 0x00, 0xDC, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x0D, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x80, 0x29, 0x00, 0x00, 0x6C, 0x03, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x3E, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1B, 0x00, 0x00, 
  0x94, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x80, 0x0D, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x80, 0x27, 0x00, 0x00, 0xA4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x16, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x78, 0x00, 0x00, 0xD8, 0x03, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 
  0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 
  0x77, 0x00, 0x00, 0xB4, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x80, 0x09, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x80, 0x38, 0x00, 0x00, 0xF8, 0x01, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x36, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x3B, 0x00, 
  0x00, 0x78, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x80, 0x07, 0x00, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x80, 0x20, 0x00, 0x00, 0xA4, 0x01, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0E, 0x00, 0x14, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x19, 0x00, 0x00, 0x98, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 
  0x0A, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0xE0, 0x29, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x80, 0x0D, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x68, 0x00, 0x00, 0xE8, 0x01, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x09, 0x00, 
  0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x1A, 
  0x00, 0x00, 0x18, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x09, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x40, 0x19, 0x00, 0x00, 0xA0, 0x07, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0B, 0x00, 0x06, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x66, 0x00, 0x00, 
  0x98, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x0C, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x80, 0xE2, 0x00, 0x00, 0xA8, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x09, 0x00, 0x12, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDD, 0x01, 0x00, 0xD0, 0xFE, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x0C, 
  0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 
  0xAA, 0x02, 0x00, 0xE8, 0x6B, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x30, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x09, 0x00, 0xF0, 0xB7, 0x0F, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0x06, 0x00, 0x03, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF9, 0x95, 
  0x00, 0xF0, 0xAF, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0xFE, 0x03, 0x80, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0xFA, 0x7B, 0x01, 0xA0, 0x5F, 0x2A, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xE7, 0x05, 0xC0, 0x15, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF5, 0x7B, 0x01, 0x90, 
  0xEF, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xBD, 
  0x02, 0xE8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0xFA, 0xBD, 0x03, 0x40, 0xD9, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x51, 0x03, 0x58, 0x1F, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4, 0xEC, 0x03, 0x40, 0xDB, 0x05, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB8, 0x00, 0xBA, 
  0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 
  0x9B, 0x03, 0x00, 0xA7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0xF6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x80, 0x67, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };


================================================
FILE: Chapter 01/optionDB.txt
================================================
*Button*borderwidth:3
*Button*relief: raised
*Button*width: 3
*Button*height: 1
*Button*pady:3


================================================
FILE: Chapter 01/readme.txt
================================================
====================================================================
Code Readme
Tkinter GUI Application Development Blueprints
Chapter 1: List of Programs
====================================================================

1.01  : Your first GUI application - the top level window
1.02  : Adding some widgets
1.03  : A demonstration of all core tkinter widgets
1.04  : A demonstration of some of pack() options
1.05  : Where to use pack() options
1.06  : Simple example of grid Geometry Manager
1.07  : A demonstration of common grid() options
1.08  : A demonstration of common place() options
1.09  : A demonstration of event binding with the bind() method
1.10  : A demonstration of all Widget Binding
1.11  : A demonstration of tkinter Variable Class IntVar, StringVar & BooleanVar
1.12  : A demonstration of tkinter styling


File Extension: .py
Requires Python 3.4.0 Installation to run.
@author: Bhaskar Chauhdary


================================================
FILE: Chapter 01/textcontent.txt
================================================
I am a text-widget.
Tkinter includes 21 core widgets. This program demonstrates all of them.

See if you can identify all of them

1) Toplevel Widget**
2) Button Widget
3) Canvas Widget 
4) Checkbutton Widget
5) Entry Widget
6) Frame Widget
7) Label Widget
8) LabelFrame Widget
9) Listbox Widget
10) Menu Widget
11) Menubutton Widget
12) Message Widget
13) OptionMenu Widget
14) PanedWindow Widget
15) Radiobutton Widget
16) Scale Widget
17) Scrollbar Widget
18) Spinbox Widget
19) Text Widget
20) Bitmap Class Widget
21) Image Class Widget 

**  (hint - the window which houses all other widgets)




================================================
FILE: Chapter 02/2.01.py
================================================
"""
Code illustration: 2.01
Text Editor Code
Step 1: Adding Top-level
Step 2: Add Menubuttons

@Tkinter GUI Application Development Blueprints
"""
from tkinter import Tk, Menu


PROGRAM_NAME = "Footprint Editor"

root = Tk()
root.geometry('350x350')
root.title(PROGRAM_NAME)

menu_bar = Menu(root)  # menu begins

file_menu = Menu(menu_bar, tearoff=0)
# all file menu-items will be added here next
menu_bar.add_cascade(label='File', menu=file_menu)

edit_menu = Menu(menu_bar, tearoff=0)
menu_bar.add_cascade(label='Edit', menu=edit_menu)

view_menu = Menu(menu_bar, tearoff=0)
menu_bar.add_cascade(label='View', menu=view_menu)

about_menu = Menu(menu_bar, tearoff=0)
menu_bar.add_cascade(label='About',  menu=about_menu)

root.config(menu=menu_bar)  # menu ends

root.mainloop()


================================================
FILE: Chapter 02/2.02.py
================================================
"""
Code illustration: 2.02
Text Editor Code
Step 3: Adding  Menu items to each menu
Step 4: Adding labels to hold shortcut toolbar and line number

@Tkinter GUI Application Development Blueprints
"""
from tkinter import Tk, PhotoImage, Menu, Frame, Text, Scrollbar


PROGRAM_NAME = "Footprint Editor"

root = Tk()
root.geometry('350x350')
root.title(PROGRAM_NAME)

# getting icons ready for compound menu
new_file_icon = PhotoImage(file='icons/new_file.gif')
open_file_icon = PhotoImage(file='icons/open_file.gif')
save_file_icon = PhotoImage(file='icons/save.gif')
cut_icon = PhotoImage(file='icons/cut.gif')
copy_icon = PhotoImage(file='icons/copy.gif')
paste_icon = PhotoImage(file='icons/paste.gif')
undo_icon = PhotoImage(file='icons/undo.gif')
redo_icon = PhotoImage(file='icons/redo.gif')

menu_bar = Menu(root)  # menu begins

file_menu = Menu(menu_bar, tearoff=0)
file_menu.add_command(label='New', accelerator='Ctrl+N',
                      compound='left', image=new_file_icon, underline=0)
file_menu.add_command(label='Open', accelerator='Ctrl+O',
                      compound='left', image=open_file_icon, underline=0)
file_menu.add_command(label='Save', accelerator='Ctrl+S',
                      compound='left', image=save_file_icon, underline=0)
file_menu.add_command(label='Save as', accelerator='Shift+Ctrl+S')
file_menu.add_separator()
file_menu.add_command(label='Exit', accelerator='Alt+F4')
menu_bar.add_cascade(label='File', menu=file_menu)


edit_menu = Menu(menu_bar, tearoff=0)
edit_menu.add_command(label='Undo', accelerator='Ctrl+Z',
                      compound='left', image=undo_icon)
edit_menu.add_command(label='Redo', accelerator='Ctrl+Y',
                      compound='left', image=redo_icon)
edit_menu.add_separator()
edit_menu.add_command(label='Cut', accelerator='Ctrl+X',
                      compound='left', image=cut_icon)
edit_menu.add_command(label='Copy', accelerator='Ctrl+C',
                      compound='left', image=copy_icon)
edit_menu.add_command(label='Paste', accelerator='Ctrl+V',
                      compound='left', image=paste_icon)
edit_menu.add_separator()
edit_menu.add_command(label='Find', underline=0, accelerator='Ctrl+F')
edit_menu.add_separator()
edit_menu.add_command(label='Select All', underline=7, accelerator='Ctrl+A')
menu_bar.add_cascade(label='Edit', menu=edit_menu)


view_menu = Menu(menu_bar, tearoff=0)
# View menu-items displays some variations
# so we tackle view menu code to be entered here in a later section
menu_bar.add_cascade(label='View', menu=view_menu)


about_menu = Menu(menu_bar, tearoff=0)
about_menu.add_command(label='About')
about_menu.add_command(label='Help')
menu_bar.add_cascade(label='About',  menu=about_menu)

root.config(menu=menu_bar)  # menu ends

# add top shortcut bar & left line number bar
shortcut_bar = Frame(root,  height=25, background='light sea green')
shortcut_bar.pack(expand='no', fill='x')

line_number_bar = Text(root, width=4, padx=3, takefocus=0,  border=0,
                       background='khaki', state='disabled',  wrap='none')
line_number_bar.pack(side='left',  fill='y')


# add the main content Text widget and Scrollbar widget
content_text = Text(root, wrap='word')
content_text.pack(expand='yes', fill='both')
scroll_bar = Scrollbar(content_text)
content_text.configure(yscrollcommand=scroll_bar.set)
scroll_bar.config(command=content_text.yview)
scroll_bar.pack(side='right', fill='y')

root.mainloop()


================================================
FILE: Chapter 02/2.03.py
================================================
"""
Code illustration: 2.03

Adding View Menu Items to demonstrate
other Types of Menu Items
    1. Checkbutton menu-item
    2. Radiobutton menu-item
    3. Cascade menu-item

@Tkinter GUI Application Development Blueprints
"""

from tkinter import Tk, PhotoImage, Menu, Frame, Text, Scrollbar, IntVar, \
    StringVar


PROGRAM_NAME = "Footprint Editor"

root = Tk()
root.geometry('350x350')
root.title(PROGRAM_NAME)

new_file_icon = PhotoImage(file='icons/new_file.gif')
open_file_icon = PhotoImage(file='icons/open_file.gif')
save_file_icon = PhotoImage(file='icons/save.gif')
cut_icon = PhotoImage(file='icons/cut.gif')
copy_icon = PhotoImage(file='icons/copy.gif')
paste_icon = PhotoImage(file='icons/paste.gif')
undo_icon = PhotoImage(file='icons/undo.gif')
redo_icon = PhotoImage(file='icons/redo.gif')

menu_bar = Menu(root)
file_menu = Menu(menu_bar, tearoff=0)
file_menu.add_command(label='New', accelerator='Ctrl+N',
                      compound='left', image=new_file_icon, underline=0)
file_menu.add_command(label='Open', accelerator='Ctrl+O',
                      compound='left', image=open_file_icon, underline=0)
file_menu.add_command(label='Save', accelerator='Ctrl+S',
                      compound='left', image=save_file_icon, underline=0)
file_menu.add_command(label='Save as', accelerator='Shift+Ctrl+S')
file_menu.add_separator()
file_menu.add_command(label='Exit', accelerator='Alt+F4')
menu_bar.add_cascade(label='File', menu=file_menu)
edit_menu = Menu(menu_bar, tearoff=0)
edit_menu.add_command(label='Undo', accelerator='Ctrl+Z',
                      compound='left', image=undo_icon)
edit_menu.add_command(label='Redo', accelerator='Ctrl+Y',
                      compound='left', image=redo_icon)
edit_menu.add_separator()
edit_menu.add_command(label='Cut', accelerator='Ctrl+X',
                      compound='left', image=cut_icon)
edit_menu.add_command(label='Copy', accelerator='Ctrl+C',
                      compound='left', image=copy_icon)
edit_menu.add_command(label='Paste', accelerator='Ctrl+V',
                      compound='left', image=paste_icon)
edit_menu.add_separator()
edit_menu.add_command(label='Find', underline=0, accelerator='Ctrl+F')
edit_menu.add_separator()
edit_menu.add_command(label='Select All', underline=7, accelerator='Ctrl+A')
menu_bar.add_cascade(label='Edit', menu=edit_menu)

##
# Implementing Checkbutton, Radiobutton and Cascade menu-items under View Menu in this iteration
##
view_menu = Menu(menu_bar, tearoff=0)
show_line_number = IntVar()
show_line_number.set(1)
view_menu.add_checkbutton(label='Show Line Number', variable=show_line_number)
show_cursor_info = IntVar()
show_cursor_info.set(1)
view_menu.add_checkbutton(
    label='Show Cursor Location at Bottom', variable=show_cursor_info)
highlight_line = IntVar()
view_menu.add_checkbutton(label='Highlight Current Line', onvalue=1,
                          offvalue=0, variable=highlight_line)
themes_menu = Menu(menu_bar, tearoff=0)
view_menu.add_cascade(label='Themes', menu=themes_menu)

"""
color scheme is defined with dictionary elements like -
        theme_name : foreground_color.background_color
"""
color_schemes = {
    'Default': '#000000.#FFFFFF',
    'Greygarious': '#83406A.#D1D4D1',
    'Aquamarine': '#5B8340.#D1E7E0',
    'Bold Beige': '#4B4620.#FFF0E1',
    'Cobalt Blue': '#ffffBB.#3333aa',
    'Olive Green': '#D1E7E0.#5B8340',
    'Night Mode': '#FFFFFF.#000000',
}

theme_choice = StringVar()
theme_choice.set('Default')
for k in sorted(color_schemes):
    themes_menu.add_radiobutton(label=k, variable=theme_choice)
menu_bar.add_cascade(label='View', menu=view_menu)


#
# End of View menu implementation in this iteration
#

about_menu = Menu(menu_bar, tearoff=0)
about_menu.add_command(label='About')
about_menu.add_command(label='Help')
menu_bar.add_cascade(label='About',  menu=about_menu)
root.config(menu=menu_bar)

shortcut_bar = Frame(root,  height=25, background='light sea green')
shortcut_bar.pack(expand='no', fill='x')
line_number_bar = Text(root, width=4, padx=3, takefocus=0,  border=0,
                       background='khaki', state='disabled',  wrap='none')
line_number_bar.pack(side='left',  fill='y')

content_text = Text(root, wrap='word')
content_text.pack(expand='yes', fill='both')
scroll_bar = Scrollbar(content_text)
content_text.configure(yscrollcommand=scroll_bar.set)
scroll_bar.config(command=content_text.yview)
scroll_bar.pack(side='right', fill='y')

root.mainloop()


================================================
FILE: Chapter 02/2.04.py
================================================
"""
Code illustration: 2.04

leveraging Text widget built-in options for
    1. Cut
    2. Copy
    3. Paste
    4. Undo
    5. Redo

@Tkinter GUI Application Development Blueprints
"""

from tkinter import Tk, PhotoImage, Menu, Frame, Text, Scrollbar, IntVar, \
    StringVar

PROGRAM_NAME = "Footprint Editor"

root = Tk()
root.geometry('350x350')
root.title(PROGRAM_NAME)

# Adding Text Widget Built-in Functionality


def cut():
    content_text.event_generate("<<Cut>>")
    return "break"


def copy():
    content_text.event_generate("<<Copy>>")
    return "break"


def paste():
    content_text.event_generate("<<Paste>>")
    return "break"


def undo():
    content_text.event_generate("<<Undo>>")
    return "break"


def redo(event=None):
    content_text.event_generate("<<Redo>>")
    return 'break'

# end of this iteration

new_file_icon = PhotoImage(file='icons/new_file.gif')
open_file_icon = PhotoImage(file='icons/open_file.gif')
save_file_icon = PhotoImage(file='icons/save.gif')
cut_icon = PhotoImage(file='icons/cut.gif')
copy_icon = PhotoImage(file='icons/copy.gif')
paste_icon = PhotoImage(file='icons/paste.gif')
undo_icon = PhotoImage(file='icons/undo.gif')
redo_icon = PhotoImage(file='icons/redo.gif')

menu_bar = Menu(root)
file_menu = Menu(menu_bar, tearoff=0)
file_menu.add_command(label='New', accelerator='Ctrl+N',
                      compound='left', image=new_file_icon, underline=0)
file_menu.add_command(label='Open', accelerator='Ctrl+O',
                      compound='left', image=open_file_icon, underline=0)
file_menu.add_command(label='Save', accelerator='Ctrl+S',
                      compound='left', image=save_file_icon, underline=0)
file_menu.add_command(label='Save as', accelerator='Shift+Ctrl+S')
file_menu.add_separator()
file_menu.add_command(label='Exit', accelerator='Alt+F4')
menu_bar.add_cascade(label='File', menu=file_menu)

edit_menu = Menu(menu_bar, tearoff=0)
edit_menu.add_command(label='Undo', accelerator='Ctrl+Z',
                      compound='left', image=undo_icon, command=undo)
edit_menu.add_command(label='Redo', accelerator='Ctrl+Y',
                      compound='left', image=redo_icon, command=redo)
edit_menu.add_separator()
edit_menu.add_command(label='Cut', accelerator='Ctrl+X',
                      compound='left', image=cut_icon, command=cut)
edit_menu.add_command(label='Copy', accelerator='Ctrl+C',
                      compound='left', image=copy_icon, command=copy)
edit_menu.add_command(label='Paste', accelerator='Ctrl+V',
                      compound='left', image=paste_icon, command=paste)
edit_menu.add_separator()
edit_menu.add_command(label='Find', underline=0, accelerator='Ctrl+F')
edit_menu.add_separator()
edit_menu.add_command(label='Select All', underline=7, accelerator='Ctrl+A')
menu_bar.add_cascade(label='Edit', menu=edit_menu)


view_menu = Menu(menu_bar, tearoff=0)
show_line_number = IntVar()
show_line_number.set(1)
view_menu.add_checkbutton(label='Show Line Number', variable=show_line_number)
show_cursor_info = IntVar()
show_cursor_info.set(1)
view_menu.add_checkbutton(
    label='Show Cursor Location at Bottom', variable=show_cursor_info)
highlight_line = IntVar()
view_menu.add_checkbutton(label='Highlight Current Line', onvalue=1,
                          offvalue=0, variable=highlight_line)
themes_menu = Menu(menu_bar, tearoff=0)
view_menu.add_cascade(label='Themes', menu=themes_menu)

color_schemes = {
    'Default': '#000000.#FFFFFF',
    'Greygarious': '#83406A.#D1D4D1',
    'Aquamarine': '#5B8340.#D1E7E0',
    'Bold Beige': '#4B4620.#FFF0E1',
    'Cobalt Blue': '#ffffBB.#3333aa',
    'Olive Green': '#D1E7E0.#5B8340',
    'Night Mode': '#FFFFFF.#000000',
}

theme_choice = StringVar()
theme_choice.set('Default')
for k in sorted(color_schemes):
    themes_menu.add_radiobutton(label=k, variable=theme_choice)
menu_bar.add_cascade(label='View', menu=view_menu)

about_menu = Menu(menu_bar, tearoff=0)
about_menu.add_command(label='About')
about_menu.add_command(label='Help')
menu_bar.add_cascade(label='About',  menu=about_menu)
root.config(menu=menu_bar)

shortcut_bar = Frame(root,  height=25, background='light sea green')
shortcut_bar.pack(expand='no', fill='x')
line_number_bar = Text(root, width=4, padx=3, takefocus=0,  border=0,
                       background='khaki', state='disabled',  wrap='none')
line_number_bar.pack(side='left',  fill='y')

content_text = Text(root, wrap='word', undo=1)
content_text.pack(expand='yes', fill='both')
scroll_bar = Scrollbar(content_text)
content_text.configure(yscrollcommand=scroll_bar.set)
scroll_bar.config(command=content_text.yview)
scroll_bar.pack(side='right', fill='y')

# handling redo quirk
content_text.bind('<Control-y>', redo)
content_text.bind('<Control-Y>', redo)


root.mainloop()


================================================
FILE: Chapter 02/2.05.py
================================================
"""
Code illustration: 2.05

Text Widget Indexing and Tagging explained using
implementation of:
    1. select_all
    2. find_text


@Tkinter GUI Application Development Blueprints
"""

from tkinter import Tk, PhotoImage, Menu, Frame, Text, Scrollbar, IntVar, \
    StringVar

PROGRAM_NAME = "Footprint Editor"

root = Tk()
root.geometry('350x350')
root.title(PROGRAM_NAME)

# Implementing select_all and find_text functions


def select_all(event=None):
    content_text.tag_add('sel', '1.0', 'end')
    return "break"


def find_text(event=None):
    search_toplevel = Tk.Toplevel(root)
    search_toplevel.title('Find Text')
    search_toplevel.transient(root)
    search_toplevel.resizable(False, False)
    Label(search_toplevel, text="Find All:").grid(row=0, column=0, sticky='e')
    search_entry_widget = Entry(
        search_toplevel, width=25)
    search_entry_widget.grid(row=0, column=1, padx=2, pady=2, sticky='we')
    search_entry_widget.focus_set()
    ignore_case_value = IntVar()
    Checkbutton(search_toplevel, text='Ignore Case', variable=ignore_case_value).grid(
        row=1, column=1, sticky='e', padx=2, pady=2)
    Button(search_toplevel, text="Find All", underline=0,
           command=lambda: search_output(
               search_entry_widget.get(), ignore_case_value.get(),
               content_text, search_toplevel, search_entry_widget)
           ).grid(row=0, column=2, sticky='e' + 'w', padx=2, pady=2)

    def close_search_window():
        content_text.tag_remove('match', '1.0', END)
        search_toplevel.destroy()
    search_toplevel.protocol('WM_DELETE_WINDOW', close_search_window)
    return "break"


def search_output(needle, if_ignore_case, content_text,
                  search_toplevel, search_box):
    content_text.tag_remove('match', '1.0', END)
    matches_found = 0
    if needle:
        start_pos = '1.0'
        while True:
            start_pos = content_text.search(needle, start_pos,
                                                   nocase=if_ignore_case, stopindex=END)
            if not start_pos:
                break
            end_pos = '{}+{}c'.format(start_pos, len(needle))
            content_text.tag_add('match', start_pos, end_pos)
            matches_found += 1
            start_pos = end_pos
        content_text.tag_config(
            'match', foreground='red', background='yellow')
    search_box.focus_set()
    search_toplevel.title('{} matches found'.format(matches_found))


def cut():
    content_text.event_generate("<<Cut>>")
    return "break"


def copy():
    content_text.event_generate("<<Copy>>")
    return "break"


def paste():
    content_text.event_generate("<<Paste>>")
    return "break"


def undo():
    content_text.event_generate("<<Undo>>")
    return "break"


def redo(event=None):
    content_text.event_generate("<<Redo>>")
    return 'break'

new_file_icon = PhotoImage(file='icons/new_file.gif')
open_file_icon = PhotoImage(file='icons/open_file.gif')
save_file_icon = PhotoImage(file='icons/save.gif')
cut_icon = PhotoImage(file='icons/cut.gif')
copy_icon = PhotoImage(file='icons/copy.gif')
paste_icon = PhotoImage(file='icons/paste.gif')
undo_icon = PhotoImage(file='icons/undo.gif')
redo_icon = PhotoImage(file='icons/redo.gif')

menu_bar = Menu(root)
file_menu = Menu(menu_bar, tearoff=0)
file_menu.add_command(label='New', accelerator='Ctrl+N',
                      compound='left', image=new_file_icon, underline=0)
file_menu.add_command(label='Open', accelerator='Ctrl+O',
                      compound='left', image=open_file_icon, underline=0)
file_menu.add_command(label='Save', accelerator='Ctrl+S',
                      compound='left', image=save_file_icon, underline=0)
file_menu.add_command(label='Save as', accelerator='Shift+Ctrl+S')
file_menu.add_separator()
file_menu.add_command(label='Exit', accelerator='Alt+F4')
menu_bar.add_cascade(label='File', menu=file_menu)

edit_menu = Menu(menu_bar, tearoff=0)
edit_menu.add_command(label='Undo', accelerator='Ctrl+Z',
                      compound='left', image=undo_icon, command=undo)
edit_menu.add_command(label='Redo', accelerator='Ctrl+Y',
                      compound='left', image=redo_icon, command=redo)
edit_menu.add_separator()
edit_menu.add_command(label='Cut', accelerator='Ctrl+X',
                      compound='left', image=cut_icon, command=cut)
edit_menu.add_command(label='Copy', accelerator='Ctrl+C',
                      compound='left', image=copy_icon, command=copy)
edit_menu.add_command(label='Paste', accelerator='Ctrl+V',
                      compound='left', image=paste_icon, command=paste)
edit_menu.add_separator()
edit_menu.add_command(label='Find', underline=0,
                      accelerator='Ctrl+F', command=find_text)
edit_menu.add_separator()
edit_menu.add_command(label='Select All', underline=7,
                      accelerator='Ctrl+A', command=select_all)
menu_bar.add_cascade(label='Edit', menu=edit_menu)


view_menu = Menu(menu_bar, tearoff=0)
show_line_number = IntVar()
show_line_number.set(1)
view_menu.add_checkbutton(label='Show Line Number', variable=show_line_number)
show_cursor_info = IntVar()
show_cursor_info.set(1)
view_menu.add_checkbutton(
    label='Show Cursor Location at Bottom', variable=show_cursor_info)
highlight_line = IntVar()
view_menu.add_checkbutton(label='Highlight Current Line', onvalue=1,
                          offvalue=0, variable=highlight_line)
themes_menu = Menu(menu_bar, tearoff=0)
view_menu.add_cascade(label='Themes', menu=themes_menu)

color_schemes = {
    'Default': '#000000.#FFFFFF',
    'Greygarious': '#83406A.#D1D4D1',
    'Aquamarine': '#5B8340.#D1E7E0',
    'Bold Beige': '#4B4620.#FFF0E1',
    'Cobalt Blue': '#ffffBB.#3333aa',
    'Olive Green': '#D1E7E0.#5B8340',
    'Night Mode': '#FFFFFF.#000000',
}

theme_choice = StringVar()
theme_choice.set('Default')
for k in sorted(color_schemes):
    themes_menu.add_radiobutton(label=k, variable=theme_choice)
menu_bar.add_cascade(label='View', menu=view_menu)

about_menu = Menu(menu_bar, tearoff=0)
about_menu.add_command(label='About')
about_menu.add_command(label='Help')
menu_bar.add_cascade(label='About',  menu=about_menu)
root.config(menu=menu_bar)

shortcut_bar = Frame(root,  height=25, background='light sea green')
shortcut_bar.pack(expand='no', fill='x')
line_number_bar = Text(root, width=4, padx=3, takefocus=0,  border=0,
                       background='khaki', state='disabled',  wrap='none')
line_number_bar.pack(side='left',  fill='y')

content_text = Text(root, wrap='word', undo=1)
content_text.pack(expand='yes', fill='both')
scroll_bar = Scrollbar(content_text)
content_text.configure(yscrollcommand=scroll_bar.set)
scroll_bar.config(command=content_text.yview)
scroll_bar.pack(side='right', fill='y')


content_text.bind('<Control-f>', find_text)
content_text.bind('<Control-F>', find_text)
content_text.bind('<Control-A>', select_all)
content_text.bind('<Control-a>', select_all)
content_text.bind('<Control-y>', redo)
content_text.bind('<Control-Y>', redo)


root.mainloop()


================================================
FILE: Chapter 02/2.06.py
================================================
"""
Code illustration: 2.06
A demonstration of different types of top-level window

@Tkinter GUI Application Development Blueprints
"""


from tkinter import Tk, Label, Toplevel

root = Tk()

# top level window
root.title('Toplevel Window')
root.geometry('300x300')
Label(root, text='I am the Main Toplevel window\n All other windows here are my children').pack()


# child toplevel
child_toplevel = Toplevel(root)
Label(child_toplevel, text='I am a child of root\n If i loose focus, I may hide below the top level, \n I am destroyed, if root is destroyed').pack()
child_toplevel.geometry('400x100+300+300')


# transient window
transient_toplevel = Toplevel(root)
Label(transient_toplevel, text='I am a transient window of root\n I always stay on top of my parent\n I get hidden if my parent window is minimized').pack()
transient_toplevel.transient(root)


# no window decoration
no_window_decoration = Toplevel(root, bg='black')
Label(no_window_decoration, text='I am a top-level with no window manager\n I cannot be resized or moved',
      bg='black', fg='white').pack()
no_window_decoration.overrideredirect(1)
no_window_decoration.geometry('250x100+700+500')


root.mainloop()


================================================
FILE: Chapter 02/2.07.py
================================================
"""
Code illustration: 2.07

Adding features:
    File > New
    File > Open
    File > Save
    File > Save As


@Tkinter GUI Application Development Blueprints
"""
import os
from tkinter import Tk, PhotoImage, Menu, Frame, Text, Scrollbar, IntVar, \
    StringVar, END

import tkinter.filedialog


PROGRAM_NAME = "Footprint Editor"
file_name = None

root = Tk()
root.geometry('350x350')
root.title(PROGRAM_NAME)

# new_file, open_file, save, save_as implementation


def new_file(event=None):
    root.title("Untitled")
    global file_name
    file_name = None
    content_text.delete(1.0, END)


def open_file(event=None):
    input_file_name = tkinter.filedialog.askopenfilename(defaultextension=".txt",
                                                         filetypes=[("All Files", "*.*"), ("Text Documents", "*.txt")])
    if input_file_name:
        global file_name
        file_name = input_file_name
        root.title('{} - {}'.format(os.path.basename(file_name), PROGRAM_NAME))
        content_text.delete(1.0, END)
        with open(file_name) as _file:
            content_text.insert(1.0, _file.read())


def write_to_file(file_name):
    try:
        content = content_text.get(1.0, 'end')
        with open(file_name, 'w') as the_file:
            the_file.write(content)
    except IOError:
        pass  # in actual we will show a error message box.
        # we discuss message boxes in the next section so ignored here.


def save_as(event=None):
    input_file_name = tkinter.filedialog.asksaveasfilename(defaultextension=".txt",
                                                           filetypes=[("All Files", "*.*"), ("Text Documents", "*.txt")])
    if input_file_name:
        global file_name
        file_name = input_file_name
        write_to_file(file_name)
        root.title('{} - {}'.format(os.path.basename(file_name), PROGRAM_NAME))
    return "break"


def save(event=None):
    global file_name
    if not file_name:
        save_as()
    else:
        write_to_file(file_name)
    return "break"

# End of iteration


def select_all(event=None):
    content_text.tag_add('sel', '1.0', 'end')
    return "break"


def find_text(event=None):
    search_toplevel = Toplevel(root)
    search_toplevel.title('Find Text')
    search_toplevel.transient(root)
    search_toplevel.resizable(False, False)
    Label(search_toplevel, text="Find All:").grid(row=0, column=0, sticky='e')
    search_entry_widget = Entry(
        search_toplevel, width=25)
    search_entry_widget.grid(row=0, column=1, padx=2, pady=2, sticky='we')
    search_entry_widget.focus_set()
    ignore_case_value = IntVar()
    Checkbutton(search_toplevel, text='Ignore Case', variable=ignore_case_value).grid(
        row=1, column=1, sticky='e', padx=2, pady=2)
    Button(search_toplevel, text="Find All", underline=0,
           command=lambda: search_output(
               search_entry_widget.get(), ignore_case_value.get(),
               content_text, search_toplevel, search_entry_widget)
           ).grid(row=0, column=2, sticky='e' + 'w', padx=2, pady=2)

    def close_search_window():
        content_text.tag_remove('match', '1.0', END)
        search_toplevel.destroy()
    search_toplevel.protocol('WM_DELETE_WINDOW', close_search_window)
    return "break"


def search_output(needle, if_ignore_case, content_text,
                  search_toplevel, search_box):
    content_text.tag_remove('match', '1.0', END)
    matches_found = 0
    if needle:
        start_pos = '1.0'
        while True:
            start_pos = content_text.search(needle, start_pos,
                                            nocase=if_ignore_case, stopindex=END)
            if not start_pos:
                break
            end_pos = '{}+{}c'.format(start_pos, len(needle))
            content_text.tag_add('match', start_pos, end_pos)
            matches_found += 1
            start_pos = end_pos
        content_text.tag_config(
            'match', foreground='red', background='yellow')
    search_box.focus_set()
    search_toplevel.title('{} matches found'.format(matches_found))


def cut():
    content_text.event_generate("<<Cut>>")
    return "break"


def copy():
    content_text.event_generate("<<Copy>>")
    return "break"


def paste():
    content_text.event_generate("<<Paste>>")
    return "break"


def undo():
    content_text.event_generate("<<Undo>>")
    return "break"


def redo(event=None):
    content_text.event_generate("<<Redo>>")
    return 'break'

new_file_icon = PhotoImage(file='icons/new_file.gif')
open_file_icon = PhotoImage(file='icons/open_file.gif')
save_file_icon = PhotoImage(file='icons/save.gif')
cut_icon = PhotoImage(file='icons/cut.gif')
copy_icon = PhotoImage(file='icons/copy.gif')
paste_icon = PhotoImage(file='icons/paste.gif')
undo_icon = PhotoImage(file='icons/undo.gif')
redo_icon = PhotoImage(file='icons/redo.gif')

menu_bar = Menu(root)
file_menu = Menu(menu_bar, tearoff=0)
file_menu.add_command(label='New', accelerator='Ctrl+N', compound='left',
                      image=new_file_icon, underline=0, command=new_file)
file_menu.add_command(label='Open', accelerator='Ctrl+O', compound='left',
                      image=open_file_icon, underline=0, command=open_file)
file_menu.add_command(label='Save', accelerator='Ctrl+S',
                      compound='left', image=save_file_icon, underline=0, command=save)
file_menu.add_command(
    label='Save as', accelerator='Shift+Ctrl+S', command=save_as)
file_menu.add_separator()
file_menu.add_command(label='Exit', accelerator='Alt+F4')
menu_bar.add_cascade(label='File', menu=file_menu)

edit_menu = Menu(menu_bar, tearoff=0)
edit_menu.add_command(label='Undo', accelerator='Ctrl+Z',
                      compound='left', image=undo_icon, command=undo)
edit_menu.add_command(label='Redo', accelerator='Ctrl+Y',
                      compound='left', image=redo_icon, command=redo)
edit_menu.add_separator()
edit_menu.add_command(label='Cut', accelerator='Ctrl+X',
                      compound='left', image=cut_icon, command=cut)
edit_menu.add_command(label='Copy', accelerator='Ctrl+C',
                      compound='left', image=copy_icon, command=copy)
edit_menu.add_command(label='Paste', accelerator='Ctrl+V',
                      compound='left', image=paste_icon, command=paste)
edit_menu.add_separator()
edit_menu.add_command(label='Find', underline=0,
                      accelerator='Ctrl+F', command=find_text)
edit_menu.add_separator()
edit_menu.add_command(label='Select All', underline=7,
                      accelerator='Ctrl+A', command=select_all)
menu_bar.add_cascade(label='Edit', menu=edit_menu)


view_menu = Menu(menu_bar, tearoff=0)
show_line_number = IntVar()
show_line_number.set(1)
view_menu.add_checkbutton(label='Show Line Number', variable=show_line_number)
show_cursor_info = IntVar()
show_cursor_info.set(1)
view_menu.add_checkbutton(
    label='Show Cursor Location at Bottom', variable=show_cursor_info)
highlight_line = IntVar()
view_menu.add_checkbutton(label='Highlight Current Line', onvalue=1,
                          offvalue=0, variable=highlight_line)
themes_menu = Menu(menu_bar, tearoff=0)
view_menu.add_cascade(label='Themes', menu=themes_menu)

color_schemes = {
    'Default': '#000000.#FFFFFF',
    'Greygarious': '#83406A.#D1D4D1',
    'Aquamarine': '#5B8340.#D1E7E0',
    'Bold Beige': '#4B4620.#FFF0E1',
    'Cobalt Blue': '#ffffBB.#3333aa',
    'Olive Green': '#D1E7E0.#5B8340',
    'Night Mode': '#FFFFFF.#000000',
}

theme_choice = StringVar()
theme_choice.set('Default')
for k in sorted(color_schemes):
    themes_menu.add_radiobutton(label=k, variable=theme_choice)
menu_bar.add_cascade(label='View', menu=view_menu)

about_menu = Menu(menu_bar, tearoff=0)
about_menu.add_command(label='About')
about_menu.add_command(label='Help')
menu_bar.add_cascade(label='About',  menu=about_menu)
root.config(menu=menu_bar)

shortcut_bar = Frame(root,  height=25, background='light sea green')
shortcut_bar.pack(expand='no', fill='x')
line_number_bar = Text(root, width=4, padx=3, takefocus=0,  border=0,
                       background='khaki', state='disabled',  wrap='none')
line_number_bar.pack(side='left',  fill='y')

content_text = Text(root, wrap='word', undo=1)
content_text.pack(expand='yes', fill='both')
scroll_bar = Scrollbar(content_text)
content_text.configure(yscrollcommand=scroll_bar.set)
scroll_bar.config(command=content_text.yview)
scroll_bar.pack(side='right', fill='y')

# Shortcut key bindings for this iteration
content_text.bind('<Control-N>', new_file)
content_text.bind('<Control-n>', new_file)
content_text.bind('<Control-O>', open_file)
content_text.bind('<Control-o>', open_file)
content_text.bind('<Control-S>', save)
content_text.bind('<Control-s>', save)
# Iteration ends

content_text.bind('<Control-f>', find_text)
content_text.bind('<Control-F>', find_text)
content_text.bind('<Control-A>', select_all)
content_text.bind('<Control-a>', select_all)
content_text.bind('<Control-y>', redo)
content_text.bind('<Control-Y>', redo)


root.mainloop()


================================================
FILE: Chapter 02/2.08.py
================================================
"""
Code illustration: 2.08
A demonstration of tkinter.messagebox
showinfo
showwarning
showerror
askquestion
askokcancel
askyesno
askyesnocancel
askretrycancel

@Tkinter GUI Application Development Blueprints
"""


from tkinter import Tk, Frame, Label, Button, BOTH, LEFT

import tkinter.messagebox as tmb

root = Tk()

fr1 = Frame(root)
fr2 = Frame(root)
opt = {'fill': BOTH, 'side': LEFT, 'padx': 2, 'pady': 3}


# Demo of tkinter.messagebox
Label(fr1, text="Demo of tkinter.messagebox").pack()
Button(fr1, text='info', command=lambda: tmb.showinfo(
    "Show Info", "This is FYI")).pack(opt)
Button(fr1, text='warning', command=lambda: tmb.showwarning(
    "Show Warning", "Don't be silly")).pack(opt)
Button(fr1, text='error', command=lambda: tmb.showerror(
    "Show Error", "It leaked")).pack(opt)
Button(fr1, text='question', command=lambda: tmb.askquestion(
    "Ask Question", "Can you read this ?")).pack(opt)
Button(fr2, text='okcancel', command=lambda: tmb.askokcancel(
    "Ask OK Cancel", "Say Ok or Cancel?")).pack(opt)
Button(fr2, text='yesno', command=lambda: tmb.askyesno(
    "Ask Yes-No", "Say yes or no?")).pack(opt)
Button(fr2, text='yesnocancel', command=lambda: tmb.askyesnocancel(
    "Yes-No-Cancel", "Say yes no cancel")).pack(opt)
Button(fr2, text='retrycancel', command=lambda: tmb.askretrycancel(
    "Ask Retry Cancel", "Retry or what?")).pack(opt)


fr1.pack()
fr2.pack()

root.mainloop()


================================================
FILE: Chapter 02/2.09.py
================================================
"""
Code illustration: 2.09

Adding:
    About, Help Message Box
    'Really Quit ?' Prompt  to exit button

@Tkinter GUI Application Development Blueprints
"""
import os
from tkinter import Tk, PhotoImage, Menu, Frame, Text, Scrollbar, IntVar, \
    StringVar, END

import tkinter.filedialog
import tkinter.messagebox

PROGRAM_NAME = "Footprint Editor"
file_name = None

root = Tk()
root.geometry('350x350')
root.title(PROGRAM_NAME)

# about, help and exit messagebox


def display_about_messagebox(event=None):
    tkinter.messagebox.showinfo(
        "About", PROGRAM_NAME + "\nTkinter GUI Application\n Development Blueprints")


def display_help_messagebox(event=None):
    tkinter.messagebox.showinfo(
        "Help", "Help Book: \nTkinter GUI Application\n Development Blueprints",
        icon='question')


def exit_editor(event=None):
    if tkinter.messagebox.askokcancel("Quit?", "Really quit?"):
        root.destroy()

# keyboard shortcut for help added towards the last of this program
# iteration ends


def new_file(event=None):
    root.title("Untitled")
    global file_name
    file_name = None
    content_text.delete(1.0, END)


def open_file(event=None):
    input_file_name = tkinter.filedialog.askopenfilename(defaultextension=".txt",
                                                         filetypes=[("All Files", "*.*"), ("Text Documents", "*.txt")])
    if input_file_name:
        global file_name
        file_name = input_file_name
        root.title('{} - {}'.format(os.path.basename(file_name), PROGRAM_NAME))
        content_text.delete(1.0, END)
        with open(file_name) as _file:
            content_text.insert(1.0, _file.read())


def write_to_file(file_name):
    try:
        content = content_text.get(1.0, 'end')
        with open(file_name, 'w') as the_file:
            the_file.write(content)
    except IOError:
        tkinter.messagebox.showwarning("Save", "Could not save the file.")


def save_as(event=None):
    input_file_name = tkinter.filedialog.asksaveasfilename(defaultextension=".txt",
                                                           filetypes=[("All Files", "*.*"), ("Text Documents", "*.txt")])
    if input_file_name:
        global file_name
        file_name = input_file_name
        write_to_file(file_name)
        root.title('{} - {}'.format(os.path.basename(file_name), PROGRAM_NAME))
    return "break"

def save(event=None):
    global file_name
    if not file_name:
        save_as()
    else:
        write_to_file(file_name)
    return "break"


def select_all(event=None):
    content_text.tag_add('sel', '1.0', 'end')
    return "break"


def find_text(event=None):
    search_toplevel = Toplevel(root)
    search_toplevel.title('Find Text')
    search_toplevel.transient(root)
    search_toplevel.resizable(False, False)
    Label(search_toplevel, text="Find All:").grid(row=0, column=0, sticky='e')
    search_entry_widget = Entry(
        search_toplevel, width=25)
    search_entry_widget.grid(row=0, column=1, padx=2, pady=2, sticky='we')
    search_entry_widget.focus_set()
    ignore_case_value = IntVar()
    Checkbutton(search_toplevel, text='Ignore Case', variable=ignore_case_value).grid(
        row=1, column=1, sticky='e', padx=2, pady=2)
    Button(search_toplevel, text="Find All", underline=0,
           command=lambda: search_output(
               search_entry_widget.get(), ignore_case_value.get(),
               content_text, search_toplevel, search_entry_widget)
           ).grid(row=0, column=2, sticky='e' + 'w', padx=2, pady=2)

    def close_search_window():
        content_text.tag_remove('match', '1.0', END)
        search_toplevel.destroy()
    search_toplevel.protocol('WM_DELETE_WINDOW', close_search_window)
    return "break"


def search_output(needle, if_ignore_case, content_text,
                  search_toplevel, search_box):
    content_text.tag_remove('match', '1.0', END)
    matches_found = 0
    if needle:
        start_pos = '1.0'
        while True:
            start_pos = content_text.search(needle, start_pos,
                                                   nocase=if_ignore_case, stopindex=END)
            if not start_pos:
                break
            end_pos = '{}+{}c'.format(start_pos, len(needle))
            content_text.tag_add('match', start_pos, end_pos)
            matches_found += 1
            start_pos = end_pos
        content_text.tag_config(
            'match', foreground='red', background='yellow')
    search_box.focus_set()
    search_toplevel.title('{} matches found'.format(matches_found))


def cut():
    content_text.event_generate("<<Cut>>")
    return "break"


def copy():
    content_text.event_generate("<<Copy>>")
    return "break"


def paste():
    content_text.event_generate("<<Paste>>")
    return "break"


def undo():
    content_text.event_generate("<<Undo>>")
    return "break"


def redo(event=None):
    content_text.event_generate("<<Redo>>")
    return 'break'

new_file_icon = PhotoImage(file='icons/new_file.gif')
open_file_icon = PhotoImage(file='icons/open_file.gif')
save_file_icon = PhotoImage(file='icons/save.gif')
cut_icon = PhotoImage(file='icons/cut.gif')
copy_icon = PhotoImage(file='icons/copy.gif')
paste_icon = PhotoImage(file='icons/paste.gif')
undo_icon = PhotoImage(file='icons/undo.gif')
redo_icon = PhotoImage(file='icons/redo.gif')

menu_bar = Menu(root)
file_menu = Menu(menu_bar, tearoff=0)
file_menu.add_command(label='New', accelerator='Ctrl+N', compound='left',
                      image=new_file_icon, underline=0, command=new_file)
file_menu.add_command(label='Open', accelerator='Ctrl+O', compound='left',
                      image=open_file_icon, underline=0, command=open_file)
file_menu.add_command(label='Save', accelerator='Ctrl+S',
                      compound='left', image=save_file_icon, underline=0, command=save)
file_menu.add_command(
    label='Save as', accelerator='Shift+Ctrl+S', command=save_as)
file_menu.add_separator()
file_menu.add_command(label='Exit', accelerator='Alt+F4', command=exit_editor)
menu_bar.add_cascade(label='File', menu=file_menu)

edit_menu = Menu(menu_bar, tearoff=0)
edit_menu.add_command(label='Undo', accelerator='Ctrl+Z',
                      compound='left', image=undo_icon, command=undo)
edit_menu.add_command(label='Redo', accelerator='Ctrl+Y',
                      compound='left', image=redo_icon, command=redo)
edit_menu.add_separator()
edit_menu.add_command(label='Cut', accelerator='Ctrl+X',
                      compound='left', image=cut_icon, command=cut)
edit_menu.add_command(label='Copy', accelerator='Ctrl+C',
                      compound='left', image=copy_icon, command=copy)
edit_menu.add_command(label='Paste', accelerator='Ctrl+V',
                      compound='left', image=paste_icon, command=paste)
edit_menu.add_separator()
edit_menu.add_command(label='Find', underline=0,
                      accelerator='Ctrl+F', command=find_text)
edit_menu.add_separator()
edit_menu.add_command(label='Select All', underline=7,
                      accelerator='Ctrl+A', command=select_all)
menu_bar.add_cascade(label='Edit', menu=edit_menu)


view_menu = Menu(menu_bar, tearoff=0)
show_line_number = IntVar()
show_line_number.set(1)
view_menu.add_checkbutton(label='Show Line Number', variable=show_line_number)
show_cursor_info = IntVar()
show_cursor_info.set(1)
view_menu.add_checkbutton(
    label='Show Cursor Location at Bottom', variable=show_cursor_info)
highlight_line = IntVar()
view_menu.add_checkbutton(label='Highlight Current Line', onvalue=1,
                          offvalue=0, variable=highlight_line)
themes_menu = Menu(menu_bar, tearoff=0)
view_menu.add_cascade(label='Themes', menu=themes_menu)

color_schemes = {
    'Default': '#000000.#FFFFFF',
    'Greygarious': '#83406A.#D1D4D1',
    'Aquamarine': '#5B8340.#D1E7E0',
    'Bold Beige': '#4B4620.#FFF0E1',
    'Cobalt Blue': '#ffffBB.#3333aa',
    'Olive Green': '#D1E7E0.#5B8340',
    'Night Mode': '#FFFFFF.#000000',
}

theme_choice = StringVar()
theme_choice.set('Default')
for k in sorted(color_schemes):
    themes_menu.add_radiobutton(label=k, variable=theme_choice)
menu_bar.add_cascade(label='View', menu=view_menu)

about_menu = Menu(menu_bar, tearoff=0)
about_menu.add_command(label='About', command=display_about_messagebox)
about_menu.add_command(label='Help', command=display_help_messagebox)
menu_bar.add_cascade(label='About',  menu=about_menu)
root.config(menu=menu_bar)

shortcut_bar = Frame(root,  height=25, background='light sea green')
shortcut_bar.pack(expand='no', fill='x')
line_number_bar = Text(root, width=4, padx=3, takefocus=0,  border=0,
                       background='khaki', state='disabled',  wrap='none')
line_number_bar.pack(side='left',  fill='y')

content_text = Text(root, wrap='word', undo=1)
content_text.pack(expand='yes', fill='both')
scroll_bar = Scrollbar(content_text)
content_text.configure(yscrollcommand=scroll_bar.set)
scroll_bar.config(command=content_text.yview)
scroll_bar.pack(side='right', fill='y')

# added keyboard shortcut for help
content_text.bind('<KeyPress-F1>', display_help_messagebox)
# ends


content_text.bind('<Control-N>', new_file)
content_text.bind('<Control-n>', new_file)
content_text.bind('<Control-O>', open_file)
content_text.bind('<Control-o>', open_file)
content_text.bind('<Control-S>', save)
content_text.bind('<Control-s>', save)
content_text.bind('<Control-f>', find_text)
content_text.bind('<Control-F>', find_text)
content_text.bind('<Control-A>', select_all)
content_text.bind('<Control-a>', select_all)
content_text.bind('<Control-y>', redo)
content_text.bind('<Control-Y>', redo)

root.protocol('WM_DELETE_WINDOW', exit_editor)
root.mainloop()


================================================
FILE: Chapter 02/2.10.py
================================================
"""
Code illustration: 2.10

Adding Shortcut Icons toolbar
Displaying Line Numbers
Highlighting Current Line


@Tkinter GUI Application Development Blueprints
"""

import os
from tkinter import Tk, PhotoImage, Menu, Frame, Text, Scrollbar, IntVar, \
    StringVar, BooleanVar, Button, END
import tkinter.filedialog
import tkinter.messagebox

PROGRAM_NAME = "Footprint Editor"
file_name = None

root = Tk()
root.geometry('350x350')
root.title(PROGRAM_NAME)


def update_line_numbers(event=None):
    line_numbers = get_line_numbers()
    line_number_bar.config(state='normal')
    line_number_bar.delete('1.0', 'end')
    line_number_bar.insert('1.0', line_numbers)
    line_number_bar.config(state='disabled')


def highlight_line(interval=100):
    content_text.tag_remove("active_line", 1.0, "end")
    content_text.tag_add(
        "active_line", "insert linestart", "insert lineend+1c")
    content_text.after(interval, toggle_highlight)


def undo_highlight():
    content_text.tag_remove("active_line", 1.0, "end")


def toggle_highlight(event=None):
    if to_highlight_line.get():
        highlight_line()
    else:
        undo_highlight()


def on_content_changed(event=None):
    update_line_numbers()


def get_line_numbers():
    output = ''
    if show_line_number.get():
        row, col = content_text.index("end").split('.')
        for i in range(1, int(row)):
            output += str(i) + '\n'
    return output


def display_about_messagebox(event=None):
    tkinter.messagebox.showinfo(
        "About", PROGRAM_NAME + "\nTkinter GUI Application\n Development Blueprints")


def display_help_messagebox(event=None):
    tkinter.messagebox.showinfo(
        "Help", "Help Book: \nTkinter GUI Application\n Development Blueprints",
        icon='question')


def exit_editor(event=None):
    if tkinter.messagebox.askokcancel("Quit?", "Really quit?"):
        root.destroy()


def new_file(event=None):
    root.title("Untitled")
    global file_name
    file_name = None
    content_text.delete(1.0, END)
    on_content_changed()


def open_file(event=None):
    input_file_name = tkinter.filedialog.askopenfilename(defaultextension=".txt",
                                                         filetypes=[("All Files", "*.*"), ("Text Documents", "*.txt")])
    if input_file_name:
        global file_name
        file_name = input_file_name
        root.title('{} - {}'.format(os.path.basename(file_name), PROGRAM_NAME))
        content_text.delete(1.0, END)
        with open(file_name) as _file:
            content_text.insert(1.0, _file.read())
    on_content_changed()


def write_to_file(file_name):
    try:
        content = content_text.get(1.0, 'end')
        with open(file_name, 'w') as the_file:
            the_file.write(content)
    except IOError:
        tkinter.messagebox.showwarning("Save", "Could not save the file.")


def save_as(event=None):
    input_file_name = tkinter.filedialog.asksaveasfilename(defaultextension=".txt",
                                                           filetypes=[("All Files", "*.*"), ("Text Documents", "*.txt")])
    if input_file_name:
        global file_name
        file_name = input_file_name
        write_to_file(file_name)
        root.title('{} - {}'.format(os.path.basename(file_name), PROGRAM_NAME))
    return "break"

def save(event=None):
    global file_name
    if not file_name:
        save_as()
    else:
        write_to_file(file_name)
    return "break"


def select_all(event=None):
    content_text.tag_add('sel', '1.0', 'end')
    return "break"


def find_text(event=None):
    search_toplevel = Toplevel(root)
    search_toplevel.title('Find Text')
    search_toplevel.transient(root)
    search_toplevel.resizable(False, False)
    Label(search_toplevel, text="Find All:").grid(row=0, column=0, sticky='e')
    search_entry_widget = Entry(
        search_toplevel, width=25)
    search_entry_widget.grid(row=0, column=1, padx=2, pady=2, sticky='we')
    search_entry_widget.focus_set()
    ignore_case_value = IntVar()
    Checkbutton(search_toplevel, text='Ignore Case', variable=ignore_case_value).grid(
        row=1, column=1, sticky='e', padx=2, pady=2)
    Button(search_toplevel, text="Find All", underline=0,
           command=lambda: search_output(
               search_entry_widget.get(), ignore_case_value.get(),
               content_text, search_toplevel, search_entry_widget)
           ).grid(row=0, column=2, sticky='e' + 'w', padx=2, pady=2)

    def close_search_window():
        content_text.tag_remove('match', '1.0', END)
        search_toplevel.destroy()
    search_toplevel.protocol('WM_DELETE_WINDOW', close_search_window)
    return "break"


def search_output(needle, if_ignore_case, content_text,
                  search_toplevel, search_box):
    content_text.tag_remove('match', '1.0', END)
    matches_found = 0
    if needle:
        start_pos = '1.0'
        while True:
            start_pos = content_text.search(needle, start_pos,
                                                   nocase=if_ignore_case, stopindex=END)
            if not start_pos:
                break
            end_pos = '{}+{}c'.format(start_pos, len(needle))
            content_text.tag_add('match', start_pos, end_pos)
            matches_found += 1
            start_pos = end_pos
        content_text.tag_config(
            'match', foreground='red', background='yellow')
    search_box.focus_set()
    search_toplevel.title('{} matches found'.format(matches_found))


def cut():
    content_text.event_generate("<<Cut>>")
    on_content_changed()
    return "break"


def copy():
    content_text.event_generate("<<Copy>>")
    return "break"


def paste():
    content_text.event_generate("<<Paste>>")
    on_content_changed()
    return "break"


def undo():
    content_text.event_generate("<<Undo>>")
    on_content_changed()
    return "break"


def redo(event=None):
    content_text.event_generate("<<Redo>>")
    on_content_changed()
    return 'break'

new_file_icon = PhotoImage(file='icons/new_file.gif')
open_file_icon = PhotoImage(file='icons/open_file.gif')
save_file_icon = PhotoImage(file='icons/save.gif')
cut_icon = PhotoImage(file='icons/cut.gif')
copy_icon = PhotoImage(file='icons/copy.gif')
paste_icon = PhotoImage(file='icons/paste.gif')
undo_icon = PhotoImage(file='icons/undo.gif')
redo_icon = PhotoImage(file='icons/redo.gif')

menu_bar = Menu(root)
file_menu = Menu(menu_bar, tearoff=0)
file_menu.add_command(label='New', accelerator='Ctrl+N', compound='left',
                      image=new_file_icon, underline=0, command=new_file)
file_menu.add_command(label='Open', accelerator='Ctrl+O', compound='left',
                      image=open_file_icon, underline=0, command=open_file)
file_menu.add_command(label='Save', accelerator='Ctrl+S',
                      compound='left', image=save_file_icon, underline=0, command=save)
file_menu.add_command(
    label='Save as', accelerator='Shift+Ctrl+S', command=save_as)
file_menu.add_separator()
file_menu.add_command(label='Exit', accelerator='Alt+F4', command=exit_editor)
menu_bar.add_cascade(label='File', menu=file_menu)

edit_menu = Menu(menu_bar, tearoff=0)
edit_menu.add_command(label='Undo', accelerator='Ctrl+Z',
                      compound='left', image=undo_icon, command=undo)
edit_menu.add_command(label='Redo', accelerator='Ctrl+Y',
                      compound='left', image=redo_icon, command=redo)
edit_menu.add_separator()
edit_menu.add_command(label='Cut', accelerator='Ctrl+X',
                      compound='left', image=cut_icon, command=cut)
edit_menu.add_command(label='Copy', accelerator='Ctrl+C',
                      compound='left', image=copy_icon, command=copy)
edit_menu.add_command(label='Paste', accelerator='Ctrl+V',
                      compound='left', image=paste_icon, command=paste)
edit_menu.add_separator()
edit_menu.add_command(label='Find', underline=0,
                      accelerator='Ctrl+F', command=find_text)
edit_menu.add_separator()
edit_menu.add_command(label='Select All', underline=7,
                      accelerator='Ctrl+A', command=select_all)
menu_bar.add_cascade(label='Edit', menu=edit_menu)


view_menu = Menu(menu_bar, tearoff=0)
show_line_number = IntVar()
show_line_number.set(1)
view_menu.add_checkbutton(label='Show Line Number', variable=show_line_number,
                          command=update_line_numbers)
show_cursor_info = IntVar()
show_cursor_info.set(1)
view_menu.add_checkbutton(
    label='Show Cursor Location at Bottom', variable=show_cursor_info)
to_highlight_line = BooleanVar()
view_menu.add_checkbutton(label='Highlight Current Line', onvalue=1,
                          offvalue=0, variable=to_highlight_line, command=toggle_highlight)
themes_menu = Menu(menu_bar, tearoff=0)
view_menu.add_cascade(label='Themes', menu=themes_menu)

color_schemes = {
    'Default': '#000000.#FFFFFF',
    'Greygarious': '#83406A.#D1D4D1',
    'Aquamarine': '#5B8340.#D1E7E0',
    'Bold Beige': '#4B4620.#FFF0E1',
    'Cobalt Blue': '#ffffBB.#3333aa',
    'Olive Green': '#D1E7E0.#5B8340',
    'Night Mode': '#FFFFFF.#000000',
}

theme_choice = StringVar()
theme_choice.set('Default')
for k in sorted(color_schemes):
    themes_menu.add_radiobutton(label=k, variable=theme_choice)
menu_bar.add_cascade(label='View', menu=view_menu)

about_menu = Menu(menu_bar, tearoff=0)
about_menu.add_command(label='About', command=display_about_messagebox)
about_menu.add_command(label='Help', command=display_help_messagebox)
menu_bar.add_cascade(label='About',  menu=about_menu)
root.config(menu=menu_bar)

shortcut_bar = Frame(root,  height=25)
shortcut_bar.pack(expand='no', fill='x')

# adding shortcut icons
icons = ('new_file', 'open_file', 'save', 'cut', 'copy', 'paste',
         'undo', 'redo', 'find_text')
for i, icon in enumerate(icons):
    tool_bar_icon = PhotoImage(file='icons/{}.gif'.format(icon))
    cmd = eval(icon)
    tool_bar = Button(shortcut_bar, image=tool_bar_icon, command=cmd)
    tool_bar.image = tool_bar_icon
    tool_bar.pack(side='left')


line_number_bar = Text(root, width=4, padx=3, takefocus=0,  border=0,
                       background='khaki', state='disabled',  wrap='none')
line_number_bar.pack(side='left',  fill='y')

content_text = Text(root, wrap='word', undo=1)
content_text.pack(expand='yes', fill='both')
scroll_bar = Scrollbar(content_text)
content_text.configure(yscrollcommand=scroll_bar.set)
scroll_bar.config(command=content_text.yview)
scroll_bar.pack(side='right', fill='y')

content_text.bind('<KeyPress-F1>', display_help_messagebox)
content_text.bind('<Control-N>', new_file)
content_text.bind('<Control-n>', new_file)
content_text.bind('<Control-O>', open_file)
content_text.bind('<Control-o>', open_file)
content_text.bind('<Control-S>', save)
content_text.bind('<Control-s>', save)
content_text.bind('<Control-f>', find_text)
content_text.bind('<Control-F>', find_text)
content_text.bind('<Control-A>', select_all)
content_text.bind('<Control-a>', select_all)
content_text.bind('<Control-y>', redo)
content_text.bind('<Control-Y>', redo)

# added in this iteration
content_text.bind('<Any-KeyPress>', on_content_changed)
content_text.tag_configure('active_line', background='ivory2')
###

root.protocol('WM_DELETE_WINDOW', exit_editor)
root.mainloop()


================================================
FILE: Chapter 02/2.11.py
================================================
"""
Code illustration: 2.11

Adding cursor location info at bottom
Adding Color Theme

@Tkinter GUI Application Development Blueprints
"""
import os
from tkinter import Tk, PhotoImage, Menu, Frame, Text, Scrollbar, IntVar, \
    StringVar, BooleanVar, Button, END, Label, INSERT
import tkinter.filedialog
import tkinter.messagebox

PROGRAM_NAME = "Footprint Editor"
file_name = None

root = Tk()
root.geometry('350x350')
root.title(PROGRAM_NAME)

# show cursor info at bottom


def show_cursor_info_bar():
    show_cursor_info_checked = show_cursor_info.get()
    if show_cursor_info_checked:
        cursor_info_bar.pack(expand='no', fill=None, side='right', anchor='se')
    else:
        cursor_info_bar.pack_forget()


def update_cursor_info_bar(event=None):
    row, col = content_text.index(INSERT).split('.')
    line_num, col_num = str(int(row)), str(int(col) + 1)  # col starts at 0
    infotext = "Line: {0} | Column: {1}".format(line_num, col_num)
    cursor_info_bar.config(text=infotext)


# change themes
def change_theme(event=None):
    selected_theme = theme_choice.get()
    fg_bg_colors = color_schemes.get(selected_theme)
    foreground_color, background_color = fg_bg_colors.split('.')
    content_text.config(
        background=background_color, fg=foreground_color)


def update_line_numbers(event=None):
    line_numbers = get_line_numbers()
    line_number_bar.config(state='normal')
    line_number_bar.delete('1.0', 'end')
    line_number_bar.insert('1.0', line_numbers)
    line_number_bar.config(state='disabled')


def highlight_line(interval=100):
    content_text.tag_remove("active_line", 1.0, "end")
    content_text.tag_add(
        "active_line", "insert linestart", "insert lineend+1c")
    content_text.after(interval, toggle_highlight)


def undo_highlight():
    content_text.tag_remove("active_line", 1.0, "end")

def toggle_highlight(event=None):
    if to_highlight_line.get():
        highlight_line()
    else:
        undo_highlight()

def on_content_changed(event=None):
    update_line_numbers()
    update_cursor_info_bar()


def get_line_numbers():
    output = ''
    if show_line_number.get():
        row, col = content_text.index("end").split('.')
        for i in range(1, int(row)):
            output += str(i) + '\n'
    return output


def update_line_numbers(event=None):
    line_numbers = get_line_numbers()
    line_number_bar.config(state='normal')
    line_number_bar.delete('1.0', 'end')
    line_number_bar.insert('1.0', line_numbers)
    line_number_bar.config(state='disabled')


def display_about_messagebox(event=None):
    tkinter.messagebox.showinfo(
        "About", PROGRAM_NAME + "\nTkinter GUI Application\n Development Blueprints")


def display_help_messagebox(event=None):
    tkinter.messagebox.showinfo(
        "Help", "Help Book: \nTkinter GUI Application\n Development Blueprints",
        icon='question')


def exit_editor(event=None):
    if tkinter.messagebox.askokcancel("Quit?", "Really quit?"):
        root.destroy()


def new_file(event=None):
    root.title("Untitled")
    global file_name
    file_name = None
    content_text.delete(1.0, END)
    on_content_changed()


def open_file(event=None):
    input_file_name = tkinter.filedialog.askopenfilename(defaultextension=".txt",
                                                         filetypes=[("All Files", "*.*"), ("Text Documents", "*.txt")])
    if input_file_name:
        global file_name
        file_name = input_file_name
        root.title('{} - {}'.format(os.path.basename(file_name), PROGRAM_NAME))
        content_text.delete(1.0, END)
        with open(file_name) as _file:
            content_text.insert(1.0, _file.read())
    on_content_changed()


def write_to_file(file_name):
    try:
        content = content_text.get(1.0, 'end')
        with open(file_name, 'w') as the_file:
            the_file.write(content)
    except IOError:
        tkinter.messagebox.showwarning("Save", "Could not save the file.")


def save_as(event=None):
    input_file_name = tkinter.filedialog.asksaveasfilename(defaultextension=".txt",
                                                           filetypes=[("All Files", "*.*"), ("Text Documents", "*.txt")])
    if input_file_name:
        global file_name
        file_name = input_file_name
        write_to_file(file_name)
        root.title('{} - {}'.format(os.path.basename(file_name), PROGRAM_NAME))
    return "break"

def save(event=None):
    global file_name
    if not file_name:
        save_as()
    else:
        write_to_file(file_name)
    return "break"


def select_all(event=None):
    content_text.tag_add('sel', '1.0', 'end')
    return "break"


def find_text(event=None):
    search_toplevel = Toplevel(root)
    search_toplevel.title('Find Text')
    search_toplevel.transient(root)
    search_toplevel.resizable(False, False)
    Label(search_toplevel, text="Find All:").grid(row=0, column=0, sticky='e')
    search_entry_widget = Entry(
        search_toplevel, width=25)
    search_entry_widget.grid(row=0, column=1, padx=2, pady=2, sticky='we')
    search_entry_widget.focus_set()
    ignore_case_value = IntVar()
    Checkbutton(search_toplevel, text='Ignore Case', variable=ignore_case_value).grid(
        row=1, column=1, sticky='e', padx=2, pady=2)
    Button(search_toplevel, text="Find All", underline=0,
           command=lambda: search_output(
               search_entry_widget.get(), ignore_case_value.get(),
               content_text, search_toplevel, search_entry_widget)
           ).grid(row=0, column=2, sticky='e' + 'w', padx=2, pady=2)

    def close_search_window():
        content_text.tag_remove('match', '1.0', END)
        search_toplevel.destroy()
    search_toplevel.protocol('WM_DELETE_WINDOW', close_search_window)
    return "break"


def search_output(needle, if_ignore_case, content_text,
                  search_toplevel, search_box):
    content_text.tag_remove('match', '1.0', END)
    matches_found = 0
    if needle:
        start_pos = '1.0'
        while True:
            start_pos = content_text.search(needle, start_pos,
                                            nocase=if_ignore_case, stopindex=END)
            if not start_pos:
                break
            end_pos = '{}+{}c'.format(start_pos, len(needle))
            content_text.tag_add('match', start_pos, end_pos)
            matches_found += 1
            start_pos = end_pos
        content_text.tag_config(
            'match', foreground='red', background='yellow')
    search_box.focus_set()
    search_toplevel.title('{} matches found'.format(matches_found))


def cut():
    content_text.event_generate("<<Cut>>")
    on_content_changed()
    return "break"


def copy():
    content_text.event_generate("<<Copy>>")
    return "break"


def paste():
    content_text.event_generate("<<Paste>>")
    on_content_changed()
    return "break"


def undo():
    content_text.event_generate("<<Undo>>")
    on_content_changed()
    return "break"


def redo(event=None):
    content_text.event_generate("<<Redo>>")
    on_content_changed()
    return 'break'

new_file_icon = PhotoImage(file='icons/new_file.gif')
open_file_icon = PhotoImage(file='icons/open_file.gif')
save_file_icon = PhotoImage(file='icons/save.gif')
cut_icon = PhotoImage(file='icons/cut.gif')
copy_icon = PhotoImage(file='icons/copy.gif')
paste_icon = PhotoImage(file='icons/paste.gif')
undo_icon = PhotoImage(file='icons/undo.gif')
redo_icon = PhotoImage(file='icons/redo.gif')

menu_bar = Menu(root)
file_menu = Menu(menu_bar, tearoff=0)
file_menu.add_command(label='New', accelerator='Ctrl+N', compound='left',
                      image=new_file_icon, underline=0, command=new_file)
file_menu.add_command(label='Open', accelerator='Ctrl+O', compound='left',
                      image=open_file_icon, underline=0, command=open_file)
file_menu.add_command(label='Save', accelerator='Ctrl+S',
                      compound='left', image=save_file_icon, underline=0, command=save)
file_menu.add_command(
    label='Save as', accelerator='Shift+Ctrl+S', command=save_as)
file_menu.add_separator()
file_menu.add_command(label='Exit', accelerator='Alt+F4', command=exit_editor)
menu_bar.add_cascade(label='File', menu=file_menu)

edit_menu = Menu(menu_bar, tearoff=0)
edit_menu.add_command(label='Undo', accelerator='Ctrl+Z',
                      compound='left', image=undo_icon, command=undo)
edit_menu.add_command(label='Redo', accelerator='Ctrl+Y',
                      compound='left', image=redo_icon, command=redo)
edit_menu.add_separator()
edit_menu.add_command(label='Cut', accelerator='Ctrl+X',
                      compound='left', image=cut_icon, command=cut)
edit_menu.add_command(label='Copy', accelerator='Ctrl+C',
                      compound='left', image=copy_icon, command=copy)
edit_menu.add_command(label='Paste', accelerator='Ctrl+V',
                      compound='left', image=paste_icon, command=paste)
edit_menu.add_separator()
edit_menu.add_command(label='Find', underline=0,
                      accelerator='Ctrl+F', command=find_text)
edit_menu.add_separator()
edit_menu.add_command(label='Select All', underline=7,
                      accelerator='Ctrl+A', command=select_all)
menu_bar.add_cascade(label='Edit', menu=edit_menu)


view_menu = Menu(menu_bar, tearoff=0)
show_line_number = IntVar()
show_line_number.set(1)
view_menu.add_checkbutton(label='Show Line Number', variable=show_line_number,
                          command=update_line_numbers)
show_cursor_info = IntVar()
show_cursor_info.set(1)
view_menu.add_checkbutton(
    label='Show Cursor Location at Bottom', variable=show_cursor_info, command=show_cursor_info_bar)
to_highlight_line = BooleanVar()
view_menu.add_checkbutton(label='Highlight Current Line', onvalue=1,
                          offvalue=0, variable=to_highlight_line, command=toggle_highlight)
themes_menu = Menu(menu_bar, tearoff=0)
view_menu.add_cascade(label='Themes', menu=themes_menu)

color_schemes = {
    'Default': '#000000.#FFFFFF',
    'Greygarious': '#83406A.#D1D4D1',
    'Aquamarine': '#5B8340.#D1E7E0',
    'Bold Beige': '#4B4620.#FFF0E1',
    'Cobalt Blue': '#ffffBB.#3333aa',
    'Olive Green': '#D1E7E0.#5B8340',
    'Night Mode': '#FFFFFF.#000000',
}

theme_choice = StringVar()
theme_choice.set('Default')
for k in sorted(color_schemes):
    themes_menu.add_radiobutton(
        label=k, variable=theme_choice, command=change_theme)
menu_bar.add_cascade(label='View', menu=view_menu)

about_menu = Menu(menu_bar, tearoff=0)
about_menu.add_command(label='About', command=display_about_messagebox)
about_menu.add_command(label='Help', command=display_help_messagebox)
menu_bar.add_cascade(label='About',  menu=about_menu)
root.config(menu=menu_bar)

shortcut_bar = Frame(root,  height=25)
shortcut_bar.pack(expand='no', fill='x')

icons = ('new_file', 'open_file', 'save', 'cut', 'copy', 'paste',
         'undo', 'redo', 'find_text')
for i, icon in enumerate(icons):
    tool_bar_icon = PhotoImage(file='icons/{}.gif'.format(icon))
    cmd = eval(icon)
    tool_bar = Button(shortcut_bar, image=tool_bar_icon, command=cmd)
    tool_bar.image = tool_bar_icon
    tool_bar.pack(side='left')

line_number_bar = Text(root, width=4, padx=3, takefocus=0,  border=0,
                       background='khaki', state='disabled',  wrap='none')
line_number_bar.pack(side='left',  fill='y')

content_text = Text(root, wrap='word', undo=1)
content_text.pack(expand='yes', fill='both')
scroll_bar = Scrollbar(content_text)
content_text.configure(yscrollcommand=scroll_bar.set)
scroll_bar.config(command=content_text.yview)
scroll_bar.pack(side='right', fill='y')

# add cursor info label
cursor_info_bar = Label(content_text, text='Line: 1 | Column: 1')
cursor_info_bar.pack(expand='no', fill=None, side='right', anchor='se')


content_text.bind('<KeyPress-F1>', display_help_messagebox)
content_text.bind('<Control-N>', new_file)
content_text.bind('<Control-n>', new_file)
content_text.bind('<Control-O>', open_file)
content_text.bind('<Control-o>', open_file)
content_text.bind('<Control-S>', save)
content_text.bind('<Control-s>', save)
content_text.bind('<Control-f>', find_text)
content_text.bind('<Control-F>', find_text)
content_text.bind('<Control-A>', select_all)
content_text.bind('<Control-a>', select_all)
content_text.bind('<Control-y>', redo)
content_text.bind('<Control-Y>', redo)
content_text.bind('<Any-KeyPress>', on_content_changed)
content_text.tag_configure('active_line', background='ivory2')

root.protocol('WM_DELETE_WINDOW', exit_editor)
root.mainloop()


================================================
FILE: Chapter 02/2.12.py
================================================
"""
Code illustration: 2.12.py
Features Added:
    Add context/ Pop-up Menu
    Set focus on launch

@Tkinter GUI Application Development Blueprints
"""

import os
from tkinter import Tk, PhotoImage, Menu, Frame, Text, Scrollbar, IntVar, \
    StringVar, BooleanVar, Button, END, Label, INSERT
import tkinter.filedialog
import tkinter.messagebox

PROGRAM_NAME = "Footprint Editor"
file_name = None

root = Tk()
root.geometry('350x350')
root.title(PROGRAM_NAME)

# show pop-up menu


def show_popup_menu(event):
    popup_menu.tk_popup(event.x_root, event.y_root)


def show_cursor_info_bar():
    show_cursor_info_checked = show_cursor_info.get()
    if show_cursor_info_checked:
        cursor_info_bar.pack(expand='no', fill=None, side='right', anchor='se')
    else:
        cursor_info_bar.pack_forget()


def update_cursor_info_bar(event=None):
    row, col = content_text.index(INSERT).split('.')
    line_num, col_num = str(int(row)), str(int(col) + 1)  # col starts at 0
    infotext = "Line: {0} | Column: {1}".format(line_num, col_num)
    cursor_info_bar.config(text=infotext)


def change_theme(event=None):
    selected_theme = theme_choice.get()
    fg_bg_colors = color_schemes.get(selected_theme)
    foreground_color, background_color = fg_bg_colors.split('.')
    content_text.config(
        background=background_color, fg=foreground_color)


def update_line_numbers(event=None):
    line_numbers = get_line_numbers()
    line_number_bar.config(state='normal')
    line_number_bar.delete('1.0', 'end')
    line_number_bar.insert('1.0', line_numbers)
    line_number_bar.config(state='disabled')


def highlight_line(interval=100):
    content_text.tag_remove("active_line", 1.0, "end")
    content_text.tag_add(
        "active_line", "insert linestart", "insert lineend+1c")
    content_text.after(interval, toggle_highlight)


def undo_highlight():
    content_text.tag_remove("active_line", 1.0, "end")


def toggle_highlight(event=None):
    if to_highlight_line.get():
        highlight_line()
    else:
        undo_highlight()


def on_content_changed(event=None):
    update_line_numbers()
    update_cursor_info_bar()


def get_line_numbers():
    output = ''
    if show_line_number.get():
        row, col = content_text.index("end").split('.')
        for i in range(1, int(row)):
            output += str(i) + '\n'
    return output


def display_about_messagebox(event=None):
    tkinter.messagebox.showinfo(
        "About", "{}{}".format(PROGRAM_NAME, "\nTkinter GUI Application\n Development Blueprints"))


def display_help_messagebox(event=None):
    tkinter.messagebox.showinfo(
        "Help", "Help Book: \nTkinter GUI Application\n Development Blueprints",
        icon='question')


def exit_editor(event=None):
    if tkinter.messagebox.askokcancel("Quit?", "Really quit?"):
        root.destroy()


def new_file(event=None):
    root.title("Untitled")
    global file_name
    file_name = None
    content_text.delete(1.0, END)
    on_content_changed()


def open_file(event=None):
    input_file_name = tkinter.filedialog.askopenfilename(defaultextension=".txt",
                                                         filetypes=[("All Files", "*.*"), ("Text Documents", "*.txt")])
    if input_file_name:
        global file_name
        file_name = input_file_name
        root.title('{} - {}'.format(os.path.basename(file_name), PROGRAM_NAME))
        content_text.delete(1.0, END)
        with open(file_name) as _file:
            content_text.insert(1.0, _file.read())
        on_content_changed()


def write_to_file(file_name):
    try:
        content = content_text.get(1.0, 'end')
        with open(file_name, 'w') as the_file:
            the_file.write(content)
    except IOError:
        tkinter.messagebox.showwarning("Save", "Could not save the file.")


def save_as(event=None):
    input_file_name = tkinter.filedialog.asksaveasfilename(defaultextension=".txt",
                                                           filetypes=[("All Files", "*.*"), ("Text Documents", "*.txt")])
    if input_file_name:
        global file_name
        file_name = input_file_name
        write_to_file(file_name)
        root.title('{} - {}'.format(os.path.basename(file_name), PROGRAM_NAME))
    return "break"


def save(event=None):
    global file_name
    if not file_name:
        save_as()
    else:
        write_to_file(file_name)
    return "break"


def select_all(event=None):
    content_text.tag_add('sel', '1.0', 'end')
    return "break"


def find_text(event=None):
    search_toplevel = Toplevel(root)
    search_toplevel.title('Find Text')
    search_toplevel.transient(root)

    Label(search_toplevel, text="Find All:").grid(row=0, column=0, sticky='e')

    search_entry_widget = Entry(
        search_toplevel, width=25)
    search_entry_widget.grid(row=0, column=1, padx=2, pady=2, sticky='we')
    search_entry_widget.focus_set()
    ignore_case_value = IntVar()
    Checkbutton(search_toplevel, text='Ignore Case', variable=ignore_case_value).grid(
        row=1, column=1, sticky='e', padx=2, pady=2)
    Button(search_toplevel, text="Find All", underline=0,
           command=lambda: search_output(
               search_entry_widget.get(), ignore_case_value.get(),
               content_text, search_toplevel, search_entry_widget)
           ).grid(row=0, column=2, sticky='e' + 'w', padx=2, pady=2)

    def close_search_window():
        content_text.tag_remove('match', '1.0', END)
        search_toplevel.destroy()
    search_toplevel.protocol('WM_DELETE_WINDOW', close_search_window)
    return "break"


def search_output(needle, if_ignore_case, content_text,
                  search_toplevel, search_box):
    content_text.tag_remove('match', '1.0', END)
    matches_found = 0
    if needle:
        start_pos = '1.0'
        while True:
            start_pos = content_text.search(needle, start_pos,
                                            nocase=if_ignore_case, stopindex=END)
            if not start_pos:
                break
            end_pos = '{}+{}c'.format(start_pos, len(needle))
            content_text.tag_add('match', start_pos, end_pos)
            matches_found += 1
            start_pos = end_pos
        content_text.tag_config(
            'match', foreground='red', background='yellow')
    search_box.focus_set()
    search_toplevel.title('{} matches found'.format(matches_found))


def cut():
    content_text.event_generate("<<Cut>>")
    on_content_changed()
    return "break"


def copy():
    content_text.event_generate("<<Copy>>")
    return "break"


def paste():
    content_text.event_generate("<<Paste>>")
    on_content_changed()
    return "break"


def undo():
    content_text.event_generate("<<Undo>>")
    on_content_changed()
    return "break"


def redo(event=None):
    content_text.event_generate("<<Redo>>")
    on_content_changed()
    return 'break'

new_file_icon = PhotoImage(file='icons/new_file.gif')
open_file_icon = PhotoImage(file='icons/open_file.gif')
save_file_icon = PhotoImage(file='icons/save.gif')
cut_icon = PhotoImage(file='icons/cut.gif')
copy_icon = PhotoImage(file='icons/copy.gif')
paste_icon = PhotoImage(file='icons/paste.gif')
undo_icon = PhotoImage(file='icons/undo.gif')
redo_icon = PhotoImage(file='icons/redo.gif')

menu_bar = Menu(root)
file_menu = Menu(menu_bar, tearoff=0)
file_menu.add_command(label='New', accelerator='Ctrl+N', compound='left',
                      image=new_file_icon, underline=0, command=new_file)
file_menu.add_command(label='Open', accelerator='Ctrl+O', compound='left',
                      image=open_file_icon, underline=0, command=open_file)
file_menu.add_command(label='Save', accelerator='Ctrl+S',
                      compound='left', image=save_file_icon, underline=0, command=save)
file_menu.add_command(
    label='Save as', accelerator='Shift+Ctrl+S', command=save_as)
file_menu.add_separator()
file_menu.add_command(label='Exit', accelerator='Alt+F4', command=exit_editor)
menu_bar.add_cascade(label='File', menu=file_menu)

edit_menu = Menu(menu_bar, tearoff=0)
edit_menu.add_command(label='Undo', accelerator='Ctrl+Z',
                      compound='left', image=undo_icon, command=undo)
edit_menu.add_command(label='Redo', accelerator='Ctrl+Y',
                      compound='left', image=redo_icon, command=redo)
edit_menu.add_separator()
edit_menu.add_command(label='Cut', accelerator='Ctrl+X',
                      compound='left', image=cut_icon, command=cut)
edit_menu.add_command(label='Copy', accelerator='Ctrl+C',
                      compound='left', image=copy_icon, command=copy)
edit_menu.add_command(label='Paste', accelerator='Ctrl+V',
                      compound='left', image=paste_icon, command=paste)
edit_menu.add_separator()
edit_menu.add_command(label='Find', underline=0,
                      accelerator='Ctrl+F', command=find_text)
edit_menu.add_separator()
edit_menu.add_command(label='Select All', underline=7,
                      accelerator='Ctrl+A', command=select_all)
menu_bar.add_cascade(label='Edit', menu=edit_menu)


view_menu = Menu(menu_bar, tearoff=0)
show_line_number = IntVar()
show_line_number.set(1)
view_menu.add_checkbutton(label='Show Line Number', variable=show_line_number,
                          command=update_line_numbers)
show_cursor_info = IntVar()
show_cursor_info.set(1)
view_menu.add_checkbutton(
    label='Show Cursor Location at Bottom', variable=show_cursor_info, command=show_cursor_info_bar)
to_highlight_line = BooleanVar()
view_menu.add_checkbutton(label='Highlight Current Line', onvalue=1,
                          offvalue=0, variable=to_highlight_line, command=toggle_highlight)
themes_menu = Menu(menu_bar, tearoff=0)
view_menu.add_cascade(label='Themes', menu=themes_menu)

color_schemes = {
    'Default': '#000000.#FFFFFF',
    'Greygarious': '#83406A.#D1D4D1',
    'Aquamarine': '#5B8340.#D1E7E0',
    'Bold Beige': '#4B4620.#FFF0E1',
    'Cobalt Blue': '#ffffBB.#3333aa',
    'Olive Green': '#D1E7E0.#5B8340',
    'Night Mode': '#FFFFFF.#000000',
}

theme_choice = StringVar()
theme_choice.set('Default')
for k in sorted(color_schemes):
    themes_menu.add_radiobutton(
        label=k, variable=theme_choice, command=change_theme)
menu_bar.add_cascade(label='View', menu=view_menu)

about_menu = Menu(menu_bar, tearoff=0)
about_menu.add_command(label='About', command=display_about_messagebox)
about_menu.add_command(label='Help', command=display_help_messagebox)
menu_bar.add_cascade(label='About',  menu=about_menu)
root.config(menu=menu_bar)

shortcut_bar = Frame(root,  height=25)
shortcut_bar.pack(expand='no', fill='x')

icons = ('new_file', 'open_file', 'save', 'cut', 'copy', 'paste',
         'undo', 'redo', 'find_text')
for i, icon in enumerate(icons):
    tool_bar_icon = PhotoImage(file='icons/{}.gif'.format(icon))
    cmd = eval(icon)
    tool_bar = Button(shortcut_bar, image=tool_bar_icon, command=cmd)
    tool_bar.image = tool_bar_icon
    tool_bar.pack(side='left')

line_number_bar = Text(root, width=4, padx=3, takefocus=0,  border=0,
                       background='khaki', state='disabled',  wrap='none')
line_number_bar.pack(side='left',  fill='y')

content_text = Text(root, wrap='word', undo=1)
content_text.pack(expand='yes', fill='both')
scroll_bar = Scrollbar(content_text)
content_text.configure(yscrollcommand=scroll_bar.set)
scroll_bar.config(command=content_text.yview)
scroll_bar.pack(side='right', fill='y')
cursor_info_bar = Label(content_text, text='Line: 1 | Column: 1')
cursor_info_bar.pack(expand='no', fill=None, side='right', anchor='se')


content_text.bind('<KeyPress-F1>', display_help_messagebox)
content_text.bind('<Control-N>', new_file)
content_text.bind('<Control-n>', new_file)
content_text.bind('<Control-O>', open_file)
content_text.bind('<Control-o>', open_file)
content_text.bind('<Control-S>', save)
content_text.bind('<Control-s>', save)
content_text.bind('<Control-f>', find_text)
content_text.bind('<Control-F>', find_text)
content_text.bind('<Control-A>', select_all)
content_text.bind('<Control-a>', select_all)
content_text.bind('<Control-y>', redo)
content_text.bind('<Control-Y>', redo)
content_text.bind('<Any-KeyPress>', on_content_changed)
content_text.tag_configure('active_line', background='ivory2')

# set up the pop-up menu
popup_menu = Menu(content_text)
for i in ('cut', 'copy', 'paste', 'undo', 'redo'):
    cmd = eval(i)
    popup_menu.add_command(label=i, compound='left', command=cmd)
popup_menu.add_separator()
popup_menu.add_command(label='Select All', underline=7, command=select_all)
content_text.bind('<Button-3>', show_popup_menu)


# bind right mouse click to show pop up and set focus to text widget on launch
content_text.bind('<Button-3>', show_popup_menu)
content_text.focus_set()

root.protocol('WM_DELETE_WINDOW', exit_editor)
root.mainloop()


================================================
FILE: Chapter 02/readme.txt
================================================
====================================================================
Code Readme
Tkinter GUI Application Development Blueprints
Chapter 2: Make a Text-Editor
====================================================================
List of code samples:-

2.01:   Add top-level window/ Add menubuttons
2.02:   Add menu-items within each menu button/ Add labels to hold shortcut toolbar and line number
2.03 :  View Menu items - showing different types of menu items
2.04:   Leveraging power of text widget built-in options
2.05:   Indexing and tagging - implementation of 'select all' and 'find all'
2.06:   A demonstration of different types of top-level window
2.07:   Adding File>New,File>Open,File>Save and File>Save As functionality
2.08:   A demonstration of tkMessageBox
2.09:   Add About, Help & Quit Functionality
2.10:   Add shortcut icon toolbar/ display line numbers/ highlight current line
2.11:   Add infobar
2.12:   Add contextual menu 

@author: Bhaskar Chaudahary
@publisher: Packt Publishing 


================================================
FILE: Chapter 03/3.01.py
================================================
"""
Code illustration: 3.01
    - Creating OOP Based GUI structure

Chapter 3 : Programmable Drum Machine
Tkinter GUI Application Development Blueprints
"""
from tkinter import Tk

PROGRAM_NAME = ' Explosion Drum Machine '


class DrumMachine:

    def __init__(self, root):
        self.root = root
        self.root.title(PROGRAM_NAME)


if __name__ == '__main__':
    root = Tk()
    DrumMachine(root)
    root.mainloop()


================================================
FILE: Chapter 03/3.02.py
================================================
"""
Code illustration: 3.02
    - Defining & Initializing the Data Structure

Chapter 3 : Programmable Drum Machine
Tkinter GUI Application Development Blueprints
"""

from tkinter import Tk

PROGRAM_NAME = ' Explosion Drum Machine '
MAX_NUMBER_OF_PATTERNS = 10
MAX_NUMBER_OF_DRUM_SAMPLES = 5
INITIAL_NUMBER_OF_UNITS = 4
INITIAL_BPU = 4
INITIAL_BEATS_PER_MINUTE = 240


class DrumMachine:

    def __init__(self, root):
        self.root = root
        self.root.title(PROGRAM_NAME)
        self.beats_per_minute = INITIAL_BEATS_PER_MINUTE
        self.all_patterns = [None] * MAX_NUMBER_OF_PATTERNS
        self.init_all_patterns()

    def init_all_patterns(self):
        self.all_patterns = [
            {
                'list_of_drum_files': [None] * MAX_NUMBER_OF_DRUM_SAMPLES,
                'number_of_units': INITIAL_NUMBER_OF_UNITS,
                'bpu': INITIAL_BPU,
                'is_button_clicked_list':
                self.init_is_button_clicked_list(
                    MAX_NUMBER_OF_DRUM_SAMPLES,
                    INITIAL_NUMBER_OF_UNITS * INITIAL_BPU
                )
            }
            for k in range(MAX_NUMBER_OF_PATTERNS)]

    def init_is_button_clicked_list(self, num_of_rows, num_of_columns):
        return [[False] * num_of_columns for x in range(num_of_rows)]


if __name__ == '__main__':
    root = Tk()
    DrumMachine(root)
    root.mainloop()


================================================
FILE: Chapter 03/3.03.py
================================================
"""
Code illustration: 3.03
    Displaying All Visual Elements:

        Methods newly defined and implemented here:
            - init_gui()
            - create_top_bar()
            - create_left_drum_loader()
            - create_right_button_matrix()
            - create_play_bar()
            - find_number_of_columns()
            - display_button_color()
            - display_all_button_colors()
            - get_button_value()
            - on_button_clicked()
            - process_button_clicked()
            - set_button_value()

        Methods added as command callback, defined here but not yet implemented
            - on_pattern_changed()
            - on_number_of_units_changed()
            - on_bpu_changed()
            - on_open_file_button_clicked()
            - on_button_clicked()
            - on_play_button_clicked()
            - on_stop_button_clicked()
            - on_loop_button_toggled()
            - on_beats_per_minute_changed()

Chapter 3 : Programmable Drum Machine
Tkinter GUI Application Development Blueprints
"""
"""
Code illustration: 3.12
    applying ttk themes to our play button, stop button, loopbutton
    adding separators

        new imports here:
            - from tkinter import ttk
        methods modified here:
            - create_play_bar()

Chapter 3 : Programmable Drum Machine
Tkinter GUI Application Development Blueprints
"""
from tkinter import Tk, Entry, W, E, N, S, PhotoImage, Checkbutton, Button, \
        Menu, Frame, Label, Spinbox


PROGRAM_NAME = ' Explosion Drum Machine '
MAX_NUMBER_OF_PATTERNS = 10
MAX_NUMBER_OF_DRUM_SAMPLES = 5
MAX_NUMBER_OF_UNITS = 5
MAX_BPU = 5
INITIAL_NUMBER_OF_UNITS = 4
INITIAL_BPU = 4
INITIAL_BEATS_PER_MINUTE = 240
MIN_BEATS_PER_MINUTE = 80
MAX_BEATS_PER_MINUTE = 360
COLOR_1 = 'grey55'
COLOR_2 = 'khaki'
BUTTON_CLICKED_COLOR = 'green'


class DrumMachine:

    def __init__(self, root):
        self.root = root
        self.root.title(PROGRAM_NAME)
        self.all_patterns = [None] * MAX_NUMBER_OF_PATTERNS
        self.beats_per_minute = INITIAL_BEATS_PER_MINUTE
        self.current_pattern_index = 0
        self.drum_load_entry_widget = [None] * MAX_NUMBER_OF_DRUM_SAMPLES
        self.init_all_patterns()
        self.init_gui()

    def init_all_patterns(self):
        self.all_patterns = [
            {
                'list_of_drum_files': [None] * MAX_NUMBER_OF_DRUM_SAMPLES,
                'number_of_units': INITIAL_NUMBER_OF_UNITS,
                'bpu': INITIAL_BPU,
                'is_button_clicked_list':
                self.init_is_button_clicked_list(
                    MAX_NUMBER_OF_DRUM_SAMPLES,
                    INITIAL_NUMBER_OF_UNITS * INITIAL_BPU
                )
            }
            for k in range(MAX_NUMBER_OF_PATTERNS)]

    def on_pattern_changed(self):
        pass

    def on_number_of_units_changed(self):
        pass

    def on_bpu_changed(self):
        pass

    def on_open_file_button_clicked(self, drum_index):
        pass

    def on_play_button_clicked(self):
        pass

    def on_stop_button_clicked(self):
        pass

    def on_loop_button_toggled(self):
        pass

    def on_beats_per_minute_changed(self):
        pass

    def init_is_button_clicked_list(self, num_of_rows, num_of_columns):
        return [[False] * num_of_columns for x in range(num_of_rows)]

    def get_button_value(self, row, col):
        return self.all_patterns[self.current_pattern_index][
            'is_button_clicked_list'][row][col]

    def find_number_of_columns(self):
        return int(self.number_of_units_widget.get()) * int(self.bpu_widget.get())

    def process_button_clicked(self, row, col):
        self.set_button_value(row, col, not self.get_button_value(row, col))
        self.display_button_color(row, col)

    def set_button_value(self, row, col, bool_value):
        self.all_patterns[self.current_pattern_index][
            'is_button_clicked_list'][row][col] = bool_value

    def on_button_clicked(self, row, col):
        def event_handler():
            self.process_button_clicked(row, col)
        return event_handler

    def display_all_button_colors(self):
        number_of_columns = self.find_number_of_columns()
        for r in range(MAX_NUMBER_OF_DRUM_SAMPLES):
            for c in range(number_of_columns):
                self.display_button_color(r, c)

    def display_button_color(self, row, col):
        bpu = int(self.bpu_widget.get())
        original_color = COLOR_1 if ((col//bpu) % 2) else COLOR_2
        button_color = BUTTON_CLICKED_COLOR if self.get_button_value(
            row, col) else original_color
        self.buttons[row][col].config(background=button_color)

    def create_play_bar(self):
        playbar_frame = Frame(self.root, height=15)
        start_row = MAX_NUMBER_OF_DRUM_SAMPLES + 10
        playbar_frame.grid(row=start_row, columnspan=13,
                           sticky=W + E, padx=15, pady=10)
        self.play_icon = PhotoImage(file="images/play.gif")
        self.play_button = Button(
            playbar_frame, text='Play',  image=self.play_icon, compound='left', command=self.on_play_button_clicked)
        self.play_button.grid(row=start_row, column=1, padx=2)
        Button(playbar_frame, text='Stop', command=self.on_stop_button_clicked).grid(
            row=start_row, column=3, padx=2)
        self.loopbutton = Checkbutton(
            playbar_frame, text='Loop', command=self.on_loop_button_toggled, textvariable=True)
        self.loopbutton.grid(row=start_row, column=16, padx=5)
        Label(playbar_frame, text='Beats Per Minute').grid(
            row=start_row, column=25)
        self.beats_per_minute_widget = Spinbox(playbar_frame, from_=MIN_BEATS_PER_MINUTE, to=MAX_BEATS_PER_MINUTE, width=5,
                increment=5.0, command=self.on_beats_per_minute_changed)
        self.beats_per_minute_widget.grid(row=start_row, column=30)
        self.beats_per_minute_widget.delete(0,"end")
        self.beats_per_minute_widget.insert(0,INITIAL_BEATS_PER_MINUTE)
        photo = PhotoImage(file='images/signature.gif')
        label = Label(playbar_frame, image=photo)
        label.image = photo
        label.grid(row=start_row, column=50, padx=1, sticky='w')

    def create_right_button_matrix(self):
        right_frame = Frame(self.root)
        right_frame.grid(row=10, column=6, sticky=W +
                         E + N + S, padx=15, pady=4)
        self.buttons = [[None for x in range(
            self.find_number_of_columns())] for x in range(MAX_NUMBER_OF_DRUM_SAMPLES)]
        for row in range(MAX_NUMBER_OF_DRUM_SAMPLES):
            for col in range(self.find_number_of_columns()):
                self.buttons[row][col] = Button(
                    right_frame, command=self.on_button_clicked(row, col))
                self.buttons[row][col].grid(row=row, column=col)
                self.display_button_color(row, col)

    def create_left_drum_loader(self):
        left_frame = Frame(self.root)
        left_frame.grid(row=10, column=0, columnspan=6, sticky=W + E + N + S)
        open_file_icon = PhotoImage(file='images/openfile.gif')
        for i in range(MAX_NUMBER_OF_DRUM_SAMPLES):
            open_file_button = Button(left_frame, image=open_file_icon,
                                      command=self.on_open_file_button_clicked(i))
            open_file_button.image = open_file_icon
            open_file_button.grid(row=i, column=0,  padx=5, pady=4)
            self.drum_load_entry_widget[i] = Entry(left_frame)
            self.drum_load_entry_widget[i].grid(
                row=i, column=4, padx=7, pady=4)

    def create_top_bar(self):
        topbar_frame = Frame(self.root, height=25)
        topbar_frame.grid(row=0, columnspan=12, rowspan=10, padx=5, pady=5)

        Label(topbar_frame, text='Pattern Number:').grid(row=0, column=1)
        self.pattern_index_widget = Spinbox(topbar_frame, from_=0, to=MAX_NUMBER_OF_PATTERNS - 1, width=5,
                command=self.on_pattern_changed)
        self.pattern_index_widget.grid(row=0, column=2)
        self.current_pattern_name_widget = Entry(topbar_frame)
        self.current_pattern_name_widget.grid(row=0, column=3, padx=7, pady=2)

        Label(topbar_frame, text='Number of Units:').grid(row=0, column=4)
        self.number_of_units_widget = Spinbox(topbar_frame, from_=1, to=MAX_NUMBER_OF_UNITS, width=5,
                command=self.on_number_of_units_changed)
        self.number_of_units_widget.delete(0,"end")
        self.number_of_units_widget.insert(0,INITIAL_NUMBER_OF_UNITS)
        self.number_of_units_widget.grid(row=0, column=5)
        Label(topbar_frame, text='BPUs:').grid(row=0, column=6)
        self.bpu_widget = Spinbox(topbar_frame, from_=1, to=MAX_BPU, width=5,
                command=self.on_bpu_changed)
        self.bpu_widget.grid(row=0, column=7)
        self.bpu_widget.delete(0,"end")
        self.bpu_widget.insert(0,INITIAL_BPU)


    def create_top_menu(self):
        self.menu_bar = Menu(self.root)
        self.file_menu = Menu(self.menu_bar, tearoff=0)
        self.file_menu.add_command(label="Load Project")
        self.file_menu.add_command(label="Save Project")
        self.file_menu.add_separator()
        self.file_menu.add_command(label="Exit")
        self.menu_bar.add_cascade(label="File", menu=self.file_menu)
        self.about_menu = Menu(self.menu_bar, tearoff=0)
        self.about_menu.add_command(label="About")
        self.menu_bar.add_cascade(label="About", menu=self.about_menu)
        self.root.config(menu=self.menu_bar)

    def init_gui(self):
        self.create_top_menu()
        self.create_top_bar()
        self.create_left_drum_loader()
        self.create_right_button_matrix()
        self.create_play_bar()


if __name__ == '__main__':
    root = Tk()
    DrumMachine(root)
    root.mainloop()


================================================
FILE: Chapter 03/3.04.py
================================================
"""
Code illustration: 3.04
    - Adding all the getter & setter methods for our data structure.
            - get_current_pattern_dict()
            - get_bpu()
            - set_bpu()
            - get_number_of_units()
            - set_number_of_units()
            - get_list_of_drum_files()
            - get_drum_file_path(drum_index)
            - set_drum_file_path(drum_index, file_path)
            - get_is_button_clicked_list()
            - set_is_button_clicked_list(num_of_rows, num_of_columns)
            - get_beats_per_minute()
            - set_beats_per_minute()
    - Defining on_number_of_units_changed() method
    - Defining  on_bpu_changed() method

Chapter 3 : Programmable Drum Machine
Tkinter GUI Application Development Blueprints
"""
from tkinter import Tk, Entry, W, E, N, S, PhotoImage, Checkbutton, Button, \
        Menu, Frame, Label, Spinbox



PROGRAM_NAME = ' Explosion Drum Machine '
MAX_NUMBER_OF_PATTERNS = 10
MAX_NUMBER_OF_DRUM_SAMPLES = 5
MAX_NUMBER_OF_UNITS = 5
MAX_BPU = 5
INITIAL_NUMBER_OF_UNITS = 4
INITIAL_BPU = 4
INITIAL_BEATS_PER_MINUTE = 240
MIN_BEATS_PER_MINUTE = 80
MAX_BEATS_PER_MINUTE = 360
COLOR_1 = 'grey55'
COLOR_2 = 'khaki'
BUTTON_CLICKED_COLOR = 'green'


class DrumMachine:

    def __init__(self, root):
        self.root = root
        self.root.title(PROGRAM_NAME)
        self.all_patterns = [None] * MAX_NUMBER_OF_PATTERNS
        self.beats_per_minute = INITIAL_BEATS_PER_MINUTE
        self.current_pattern_index = 0
        self.drum_load_entry_widget = [None] * MAX_NUMBER_OF_DRUM_SAMPLES
        self.init_all_patterns()
        self.init_gui()

    #
    # getters and setters begins
    #

    def get_current_pattern_dict(self):
        return self.all_patterns[self.current_pattern_index]

    def get_bpu(self):
        return self.get_current_pattern_dict()['bpu']

    def set_bpu(self):
        self.get_current_pattern_dict()['bpu'] = int(self.bpu_widget.get())

    def get_number_of_units(self):
        return self.get_current_pattern_dict()['number_of_units']

    def set_number_of_units(self):
        self.get_current_pattern_dict(
        )['number_of_units'] = int(self.number_of_units_widget.get())

    def get_list_of_drum_files(self):
        return self.get_current_pattern_dict()['list_of_drum_files']

    def get_drum_file_path(self, drum_index):
        return self.get_list_of_drum_files()[drum_index]

    def set_drum_file_path(self, drum_index, file_path):
        self.get_list_of_drum_files()[drum_index] = file_path

    def get_is_button_clicked_list(self):
        return self.get_current_pattern_dict()['is_button_clicked_list']

    def set_is_button_clicked_list(self, num_of_rows, num_of_columns):
        self.get_current_pattern_dict()['is_button_clicked_list'] = [
            [False] * num_of_columns for x in range(num_of_rows)]


    def init_all_patterns(self):
        self.all_patterns = [
            {
                'list_of_drum_files': [None] * MAX_NUMBER_OF_DRUM_SAMPLES,
                'number_of_units': INITIAL_NUMBER_OF_UNITS,
                'bpu': INITIAL_BPU,
                'is_button_clicked_list':
                self.init_is_button_clicked_list(
                    MAX_NUMBER_OF_DRUM_SAMPLES,
                    INITIAL_NUMBER_OF_UNITS * INITIAL_BPU
                )
            }
            for k in range(MAX_NUMBER_OF_PATTERNS)]

    def on_pattern_changed(self):
        pass

    def on_number_of_units_changed(self):
        self.set_number_of_units()
        self.set_is_button_clicked_list(MAX_NUMBER_OF_DRUM_SAMPLES,
                                        self.find_number_of_columns())
        self.create_right_button_matrix()

    def on_bpu_changed(self):
        self.set_bpu()
        self.set_is_button_clicked_list(MAX_NUMBER_OF_DRUM_SAMPLES,
                                        self.find_number_of_columns())
        self.create_right_button_matrix()


    def on_open_file_button_clicked(self, drum_index):
        pass

    def on_play_button_clicked(self):
        pass

    def on_stop_button_clicked(self):
        pass

    def on_loop_button_toggled(self):
        pass

    def on_beats_per_minute_changed(self):
        pass

    def init_is_button_clicked_list(self, num_of_rows, num_of_columns):
        return [[False] * num_of_columns for x in range(num_of_rows)]

    def get_button_value(self, row, col):
        return self.all_patterns[self.current_pattern_index][
            'is_button_clicked_list'][row][col]

    def find_number_of_columns(self):
        return int(self.number_of_units_widget.get()) * int(self.bpu_widget.get())

    def process_button_clicked(self, row, col):
        self.set_button_value(row, col, not self.get_button_value(row, col))
        self.display_button_color(row, col)

    def set_button_value(self, row, col, bool_value):
        self.all_patterns[self.current_pattern_index][
            'is_button_clicked_list'][row][col] = bool_value

    def on_button_clicked(self, row, col):
        def event_handler():
            self.process_button_clicked(row, col)
        return event_handler

    def display_all_button_colors(self):
        number_of_columns = self.find_number_of_columns()
        for r in range(MAX_NUMBER_OF_DRUM_SAMPLES):
            for c in range(number_of_columns):
                self.display_button_color(r, c)

    def display_button_color(self, row, col):
        bpu = int(self.bpu_widget.get())
        original_color = COLOR_1 if ((col//bpu) % 2) else COLOR_2
        button_color = BUTTON_CLICKED_COLOR if self.get_button_value(
            row, col) else original_color
        self.buttons[row][col].config(background=button_color)

    def create_play_bar(self):
        playbar_frame = Frame(self.root, height=15)
        start_row = MAX_NUMBER_OF_DRUM_SAMPLES + 10
        playbar_frame.grid(row=start_row, columnspan=13,
                           sticky=W + E, padx=15, pady=10)
        self.play_icon = PhotoImage(file="images/play.gif")
        self.play_button = Button(
            playbar_frame, text='Play',  image=self.play_icon, compound='left', command=self.on_play_button_clicked)
        self.play_button.grid(row=start_row, column=1, padx=2)
        Button(playbar_frame, text='Stop', command=self.on_stop_button_clicked).grid(
            row=start_row, column=3, padx=2)
        self.loopbutton = Checkbutton(
            playbar_frame, text='Loop', command=self.on_loop_button_toggled)
        self.loopbutton.grid(row=start_row, column=16, padx=5)
        Label(playbar_frame, text='Beats Per Minute').grid(
            row=start_row, column=25)
        self.beats_per_minute_widget = Spinbox(playbar_frame, from_=MIN_BEATS_PER_MINUTE, to=MAX_BEATS_PER_MINUTE, width=5,
                increment=5.0, command=self.on_beats_per_minute_changed)
        self.beats_per_minute_widget.grid(row=start_row, column=30)
        self.beats_per_minute_widget.delete(0,"end")
        self.beats_per_minute_widget.insert(0,INITIAL_BEATS_PER_MINUTE)
        photo = PhotoImage(file='images/signature.gif')
        label = Label(playbar_frame, image=photo)
        label.image = photo
        label.grid(row=start_row, column=50, padx=1, sticky='w')

    def create_right_button_matrix(self):
        right_frame = Frame(self.root)
        right_frame.grid(row=10, column=6, sticky=W +
                         E + N + S, padx=15, pady=4)
        self.buttons = [[None for x in range(
            self.find_number_of_columns())] for x in range(MAX_NUMBER_OF_DRUM_SAMPLES)]
        for row in range(MAX_NUMBER_OF_DRUM_SAMPLES):
            for col in range(self.find_number_of_columns()):
                self.buttons[row][col] = Button(
                    right_frame, command=self.on_button_clicked(row, col))
                self.buttons[row][col].grid(row=row, column=col)
                self.display_button_color(row, col)

    def create_left_drum_loader(self):
        left_frame = Frame(self.root)
        left_frame.grid(row=10, column=0, columnspan=6, sticky=W + E + N + S)
        open_file_icon = PhotoImage(file='images/openfile.gif')
        for i in range(MAX_NUMBER_OF_DRUM_SAMPLES):
            open_file_button = Button(left_frame, image=open_file_icon,
                                      command=self.on_open_file_button_clicked(i))
            open_file_button.image = open_file_icon
            open_file_button.grid(row=i, column=0,  padx=5, pady=4)
            self.drum_load_entry_widget[i] = Entry(left_frame)
            self.drum_load_entry_widget[i].grid(
                row=i, column=4, padx=7, pady=4)

    def create_top_bar(self):
        topbar_frame = Frame(self.root, height=25)
        topbar_frame.grid(row=0, columnspan=12, rowspan=10, padx=5, pady=5)

        Label(topbar_frame, text='Pattern Number:').grid(row=0, column=1)
        self.pattern_index_widget = Spinbox(topbar_frame, from_=0, to=MAX_NUMBER_OF_PATTERNS - 1, width=5,
                command=self.on_pattern_changed)
        self.pattern_index_widget.grid(row=0, column=2)
        self.current_pattern_name_widget = Entry(topbar_frame)
        self.current_pattern_name_widget.grid(row=0, column=3, padx=7, pady=2)

        Label(topbar_frame, text='Number of Units:').grid(row=0, column=4)
        self.number_of_units_widget = Spinbox(topbar_frame, from_=1, to=MAX_NUMBER_OF_UNITS, width=5,
                command=self.on_number_of_units_changed)
        self.number_of_units_widget.delete(0,"end")
        self.number_of_units_widget.insert(0,INITIAL_NUMBER_OF_UNITS)
        self.number_of_units_widget.grid(row=0, column=5)
        Label(topbar_frame, text='BPUs:').grid(row=0, column=6)
        self.bpu_widget = Spinbox(topbar_frame, from_=1, to=MAX_BPU, width=5,
                command=self.on_bpu_changed)
        self.bpu_widget.grid(row=0, column=7)
        self.bpu_widget.delete(0,"end")
        self.bpu_widget.insert(0,INITIAL_BPU)


    def create_top_menu(self):
        self.menu_bar = Menu(self.root)
        self.file_menu = Menu(self.menu_bar, tearoff=0)
        self.file_menu.add_command(label="Load Project")
        self.file_menu.add_command(label="Save Project")
        self.file_menu.add_separator()
        self.file_menu.add_command(label="Exit")
        self.menu_bar.add_cascade(label="File", menu=self.file_menu)
        self.about_menu = Menu(self.menu_bar, tearoff=0)
        self.about_menu.add_command(label="About")
        self.menu_bar.add_cascade(label="About", menu=self.about_menu)
        self.root.config(menu=self.menu_bar)

    def init_gui(self):
        self.create_top_menu()
        self.create_top_bar()
        self.create_left_drum_loader()
        self.create_right_button_matrix()
        self.create_play_bar()


if __name__ == '__main__':
    root = Tk()
    DrumMachine(root)
    root.mainloop()


================================================
FILE: Chapter 03/3.05.py
================================================
"""
Code illustration: 3.05
    - Loading drum samples

        New modules imported here:
            - os, tkinter.filedialog

        New methods implemented here
            on_open_file_button_clicked():
            display_all_drum_file_names():
            display_drum_name():


Chapter 3 : Programmable Drum Machine
Tkinter GUI Application Development Blueprints
"""
import os
from tkinter import Tk, Entry, W, E, N, S, PhotoImage, Checkbutton, Button, \
        Menu, Frame, Label, Spinbox, END

from tkinter import filedialog

PROGRAM_NAME = ' Explosion Drum Machine '
MAX_NUMBER_OF_PATTERNS = 10
MAX_NUMBER_OF_DRUM_SAMPLES = 5
MAX_NUMBER_OF_UNITS = 5
MAX_BPU = 5
INITIAL_NUMBER_OF_UNITS = 4
INITIAL_BPU = 4
INITIAL_BEATS_PER_MINUTE = 240
MIN_BEATS_PER_MINUTE = 80
MAX_BEATS_PER_MINUTE = 360
COLOR_1 = 'grey55'
COLOR_2 = 'khaki'
BUTTON_CLICKED_COLOR = 'green'


class DrumMachine:

    def __init__(self, root):
        self.root = root
        self.root.title(PROGRAM_NAME)
        self.all_patterns = [None] * MAX_NUMBER_OF_PATTERNS
        self.beats_per_minute = INITIAL_BEATS_PER_MINUTE
        self.current_pattern_index = 0
        self.drum_load_entry_widget = [None] * MAX_NUMBER_OF_DRUM_SAMPLES
        self.init_all_patterns()
        self.init_gui()

    def on_open_file_button_clicked(self, drum_index):
        def event_handler():
            file_path = filedialog.askopenfilename(defaultextension=".wav",
                                                   filetypes=[("Wave Files", "*.wav"), ("OGG Files", "*.ogg")])
            if not file_path:
                return
            self.set_drum_file_path(drum_index, file_path)
            self.display_all_drum_file_names()
        return event_handler

    def display_all_drum_file_names(self):
        for i, drum_name in enumerate(self.get_list_of_drum_files()):
            self.display_drum_name(i, drum_name)

    def display_drum_name(self, text_widget_num, file_path):
        if file_path is None:
            return
        drum_name = os.path.basename(file_path)
        self.drum_load_entry_widget[text_widget_num].delete(0, END)
        self.drum_load_entry_widget[text_widget_num].insert(0, drum_name)



    #
    # getters and setters begins
    #

    def get_current_pattern_dict(self):
        return self.all_patterns[self.current_pattern_index]

    def get_bpu(self):
        return self.get_current_pattern_dict()['bpu']

    def set_bpu(self):
        self.get_current_pattern_dict()['bpu'] = int(self.bpu_widget.get())

    def get_number_of_units(self):
        return self.get_current_pattern_dict()['number_of_units']

    def set_number_of_units(self):
        self.get_current_pattern_dict(
        )['number_of_units'] = int(self.number_of_units_widget.get())

    def get_list_of_drum_files(self):
        return self.get_current_pattern_dict()['list_of_drum_files']

    def get_drum_file_path(self, drum_index):
        return self.get_list_of_drum_files()[drum_index]

    def set_drum_file_path(self, drum_index, file_path):
        self.get_list_of_drum_files()[drum_index] = file_path

    def get_is_button_clicked_list(self):
        return self.get_current_pattern_dict()['is_button_clicked_list']

    def set_is_button_clicked_list(self, num_of_rows, num_of_columns):
        self.get_current_pattern_dict()['is_button_clicked_list'] = [
            [False] * num_of_columns for x in range(num_of_rows)]


    def init_all_patterns(self):
        self.all_patterns = [
            {
                'list_of_drum_files': [None] * MAX_NUMBER_OF_DRUM_SAMPLES,
                'number_of_units': INITIAL_NUMBER_OF_UNITS,
                'bpu': INITIAL_BPU,
                'is_button_clicked_list':
                self.init_is_button_clicked_list(
                    MAX_NUMBER_OF_DRUM_SAMPLES,
                    INITIAL_NUMBER_OF_UNITS * INITIAL_BPU
                )
            }
            for k in range(MAX_NUMBER_OF_PATTERNS)]

    def on_pattern_changed(self):
        pass

    def on_number_of_units_changed(self):
        self.set_number_of_units()
        self.set_is_button_clicked_list(MAX_NUMBER_OF_DRUM_SAMPLES,
                                        self.find_number_of_columns())
        self.create_right_button_matrix()

    def on_bpu_changed(self):
        self.set_bpu()
        self.set_is_button_clicked_list(MAX_NUMBER_OF_DRUM_SAMPLES,
                                        self.find_number_of_columns())
        self.create_right_button_matrix()


    def on_play_button_clicked(self):
        pass

    def on_stop_button_clicked(self):
        pass

    def on_loop_button_toggled(self):
        pass

    def on_beats_per_minute_changed(self):
        pass

    def init_is_button_clicked_list(self, num_of_rows, num_of_columns):
        return [[False] * num_of_columns for x in range(num_of_rows)]

    def get_button_value(self, row, col):
        return self.all_patterns[self.current_pattern_index][
            'is_button_clicked_list'][row][col]

    def find_number_of_columns(self):
        return int(self.number_of_units_widget.get()) * int(self.bpu_widget.get())

    def process_button_clicked(self, row, col):
        self.set_button_value(row, col, not self.get_button_value(row, col))
        self.display_button_color(row, col)

    def set_button_value(self, row, col, bool_value):
        self.all_patterns[self.current_pattern_index][
            'is_button_clicked_list'][row][col] = bool_value

    def on_button_clicked(self, row, col):
        def event_handler():
            self.process_button_clicked(row, col)
        return event_handler

    def display_all_button_colors(self):
        number_of_columns = self.find_number_of_columns()
        for r in range(MAX_NUMBER_OF_DRUM_SAMPLES):
            for c in range(number_of_columns):
                self.display_button_color(r, c)

    def display_button_color(self, row, col):
        bpu = int(self.bpu_widget.get())
        original_color = COLOR_1 if ((col//bpu) % 2) else COLOR_2
        button_color = BUTTON_CLICKED_COLOR if self.get_button_value(
            row, col) else original_color
        self.buttons[row][col].config(background=button_color)

    def create_play_bar(self):
        playbar_frame = Frame(self.root, height=15)
        start_row = MAX_NUMBER_OF_DRUM_SAMPLES + 10
        playbar_frame.grid(row=start_row, columnspan=13,
                           sticky=W + E, padx=15, pady=10)
        self.play_icon = PhotoImage(file="images/play.gif")
        self.play_button = Button(
            playbar_frame, text='Play',  image=self.play_icon, compound='left', command=self.on_play_button_clicked)
        self.play_button.grid(row=start_row, column=1, padx=2)
        Button(playbar_frame, text='Stop', command=self.on_stop_button_clicked).grid(
            row=start_row, column=3, padx=2)
        self.loopbutton = Checkbutton(
            playbar_frame, text='Loop', command=self.on_loop_button_toggled)
        self.loopbutton.grid(row=start_row, column=16, padx=5)
        Label(playbar_frame, text='Beats Per Minute').grid(
            row=start_row, column=25)
        self.beats_per_minute_widget = Spinbox(playbar_frame, from_=MIN_BEATS_PER_MINUTE, to=MAX_BEATS_PER_MINUTE, width=5,
                increment=5.0, command=self.on_beats_per_minute_changed)
        self.beats_per_minute_widget.grid(row=start_row, column=30)
        self.beats_per_minute_widget.delete(0,"end")
        self.beats_per_minute_widget.insert(0,INITIAL_BEATS_PER_MINUTE)
        photo = PhotoImage(file='images/signature.gif')
        label = Label(playbar_frame, image=photo)
        label.image = photo
        label.grid(row=start_row, column=50, padx=1, sticky='w')

    def create_right_button_matrix(self):
        right_frame = Frame(self.root)
        right_frame.grid(row=10, column=6, sticky=W +
                         E + N + S, padx=15, pady=4)
        self.buttons = [[None for x in range(
            self.find_number_of_columns())] for x in range(MAX_NUMBER_OF_DRUM_SAMPLES)]
        for row in range(MAX_NUMBER_OF_DRUM_SAMPLES):
            for col in range(self.find_number_of_columns()):
                self.buttons[row][col] = Button(
                    right_frame, command=self.on_button_clicked(row, col))
                self.buttons[row][col].grid(row=row, column=col)
                self.display_button_color(row, col)

    def create_left_drum_loader(self):
        left_frame = Frame(self.root)
        left_frame.grid(row=10, column=0, columnspan=6, sticky=W + E + N + S)
        open_file_icon = PhotoImage(file='images/openfile.gif')
        for i in range(MAX_NUMBER_OF_DRUM_SAMPLES):
            open_file_button = Button(left_frame, image=open_file_icon,
                                      command=self.on_open_file_button_clicked(i))
            open_file_button.image = open_file_icon
            open_file_button.grid(row=i, column=0,  padx=5, pady=4)
            self.drum_load_entry_widget[i] = Entry(left_frame)
            self.drum_load_entry_widget[i].grid(
                row=i, column=4, padx=7, pady=4)


    def create_top_bar(self):
        topbar_frame = Frame(self.root, height=25)
        topbar_frame.grid(row=0, columnspan=12, rowspan=10, padx=5, pady=5)

        Label(topbar_frame, text='Pattern Number:').grid(row=0, column=1)
        self.pattern_index_widget = Spinbox(topbar_frame, from_=0, to=MAX_NUMBER_OF_PATTERNS - 1, width=5,
                command=self.on_pattern_changed)
        self.pattern_index_widget.grid(row=0, column=2)
        self.current_pattern_name_widget = Entry(topbar_frame)
        self.current_pattern_name_widget.grid(row=0, column=3, padx=7, pady=2)

        Label(topbar_frame, text='Number of Units:').grid(row=0, column=4)
        self.number_of_units_widget = Spinbox(topbar_frame, from_=1, to=MAX_NUMBER_OF_UNITS, width=5,
                command=self.on_number_of_units_changed)
        self.number_of_units_widget.delete(0,"end")
        self.number_of_units_widget.insert(0,INITIAL_NUMBER_OF_UNITS)
        self.number_of_units_widget.grid(row=0, column=5)
        Label(topbar_frame, text='BPUs:').grid(row=0, column=6)
        self.bpu_widget = Spinbox(topbar_frame, from_=1, to=MAX_BPU, width=5,
                command=self.on_bpu_changed)
        self.bpu_widget.grid(row=0, column=7)
        self.bpu_widget.delete(0,"end")
        self.bpu_widget.insert(0,INITIAL_BPU)


    def create_top_menu(self):
        self.menu_bar = Menu(self.root)
        self.file_menu = Menu(self.menu_bar, tearoff=0)
        self.file_menu.add_command(label="Load Project")
        self.file_menu.add_command(label="Save Project")
        self.file_menu.add_separator()
        self.file_menu.add_command(label="Exit")
        self.menu_bar.add_cascade(label="File", menu=self.file_menu)
        self.about_menu = Menu(self.menu_bar, tearoff=0)
        self.about_menu.add_command(label="About")
        self.menu_bar.add_cascade(label="About", menu=self.about_menu)
        self.root.config(menu=self.menu_bar)

    def init_gui(self):
        self.create_top_menu()
        self.create_top_bar()
        self.create_left_drum_loader()
        self.create_right_button_matrix()
        self.create_play_bar()


if __name__ == '__main__':
    root = Tk()
    DrumMachine(root)
    root.mainloop()


================================================
FILE: Chapter 03/3.06.py
================================================
"""
               ****** Non reponsive warning ! ******
    - This program becomes non responsive on playback of audio files.
    - It is meant to be that way as a demonstration.
    - You can close the program by stopping the python script
                *************************************

Code illustration: 3.06

    Playing Audio
        New Modules Imported Here
            - import pygame
            - import time

        Attributes Added here:
            - self.loop
            - self.now_playing

        New Methods defined here:
            init_pygame()
            play_sound()
            start_play()
            stop_play()
            play_pattern()
            time_to_play_each_column()
            on_beats_per_minute_changed()
            get_column_from_matrix()

        Dummy Methods that existed earlier but modified here:
            on_loop_button_toggled()
            on_play_button_clicked()
            on_stop_button_clicked()


Chapter 3 : Programmable Drum Machine
Tkinter GUI Application Development Blueprints
"""
import os
import time
from tkinter import Tk, Entry, W, E, N, S, PhotoImage, Checkbutton, Button, \
        Menu, Frame, Label, Spinbox, END, BooleanVar
from tkinter import filedialog
import pygame


PROGRAM_NAME = ' Explosion Drum Machine '
MAX_NUMBER_OF_PATTERNS = 10
MAX_NUMBER_OF_DRUM_SAMPLES = 5
MAX_NUMBER_OF_UNITS = 5
MAX_BPU = 5
INITIAL_NUMBER_OF_UNITS = 4
INITIAL_BPU = 4
INITIAL_BEATS_PER_MINUTE = 240
MIN_BEATS_PER_MINUTE = 80
MAX_BEATS_PER_MINUTE = 360
COLOR_1 = 'grey55'
COLOR_2 = 'khaki'
BUTTON_CLICKED_COLOR = 'green'


class DrumMachine:

    def __init__(self, root):
        self.root = root
        self.root.title(PROGRAM_NAME)
        self.all_patterns = [None] * MAX_NUMBER_OF_PATTERNS
        self.beats_per_minute = INITIAL_BEATS_PER_MINUTE
        self.current_pattern_index = 0
        self.loop = True
        self.now_playing = False
        self.drum_load_entry_widget = [None] * MAX_NUMBER_OF_DRUM_SAMPLES
        self.init_all_patterns()
        self.init_gui()

    def on_open_file_button_clicked(self, drum_index):
        def event_handler():
            file_path = filedialog.askopenfilename(defaultextension=".wav",
                                                   filetypes=[("Wave Files", "*.wav"), ("OGG Files", "*.ogg")])
            if not file_path:
                return
            self.set_drum_file_path(drum_index, file_path)
            self.display_all_drum_file_names()
        return event_handler

    def display_all_drum_file_names(self):
        for i, drum_name in enumerate(self.get_list_of_drum_files()):
            self.display_drum_name(i, drum_name)

    def display_drum_name(self, text_widget_num, file_path):
        if file_path is None:
            return
        drum_name = os.path.basename(file_path)
        self.drum_load_entry_widget[text_widget_num].delete(0, END)
        self.drum_load_entry_widget[text_widget_num].insert(0, drum_name)



    #
    # getters and setters begins
    #

    def get_current_pattern_dict(self):
        return self.all_patterns[self.current_pattern_index]

    def get_bpu(self):
        return self.get_current_pattern_dict()['bpu']

    def set_bpu(self):
        self.get_current_pattern_dict()['bpu'] = int(self.bpu_widget.get())

    def get_number_of_units(self):
        return self.get_current_pattern_dict()['number_of_units']

    def set_number_of_units(self):
        self.get_current_pattern_dict(
        )['number_of_units'] = int(self.number_of_units_widget.get())

    def get_list_of_drum_files(self):
        return self.get_current_pattern_dict()['list_of_drum_files']

    def get_drum_file_path(self, drum_index):
        return self.get_list_of_drum_files()[drum_index]

    def set_drum_file_path(self, drum_index, file_path):
        self.get_list_of_drum_files()[drum_index] = file_path

    def get_is_button_clicked_list(self):
        return self.get_current_pattern_dict()['is_button_clicked_list']

    def set_is_button_clicked_list(self, num_of_rows, num_of_columns):
        self.get_current_pattern_dict()['is_button_clicked_list'] = [
            [False] * num_of_columns for x in range(num_of_rows)]


    def init_all_patterns(self):
        self.all_patterns = [
            {
                'list_of_drum_files': [None] * MAX_NUMBER_OF_DRUM_SAMPLES,
                'number_of_units': INITIAL_NUMBER_OF_UNITS,
                'bpu': INITIAL_BPU,
                'is_button_clicked_list':
                self.init_is_button_clicked_list(
                    MAX_NUMBER_OF_DRUM_SAMPLES,
                    INITIAL_NUMBER_OF_UNITS * INITIAL_BPU
                )
            }
            for k in range(MAX_NUMBER_OF_PATTERNS)]

    def on_pattern_changed(self):
        pass

    def on_number_of_units_changed(self):
        self.set_number_of_units()
        self.set_is_button_clicked_list(MAX_NUMBER_OF_DRUM_SAMPLES,
                                        self.find_number_of_columns())
        self.create_right_button_matrix()

    def on_bpu_changed(self):
        self.set_bpu()
        self.set_is_button_clicked_list(MAX_NUMBER_OF_DRUM_SAMPLES,
                                        self.find_number_of_columns())
        self.create_right_button_matrix()

    def on_play_button_clicked(self):
        self.start_play()

    def start_play(self):
        self.init_pygame()
        self.play_pattern()

    def on_stop_button_clicked(self):
        self.stop_play()

    def stop_play(self):
        self.now_playing = False

    def init_pygame(self):
        pygame.mixer.pre_init(44100, -16, 1, 512)
        pygame.init()

    def play_sound(self, sound_filename):
        if sound_filename is not None:
            pygame.mixer.Sound(sound_filename).play()

    def get_column_from_matrix(self, matrix, i):
        return [row[i] for row in matrix]


    def play_pattern(self):
        self.now_playing = True
        while self.now_playing:
            play_list = self.get_is_button_clicked_list()
            num_columns = len(play_list[0])
            for column_index in range(num_columns):
                column_to_play = self.get_column_from_matrix(
                      play_list, column_index)
                for i, item in enumerate(column_to_play):
                    if item:
                        sound_filename = self.get_drum_file_path(i)
                        self.play_sound(sound_filename)
                time.sleep(self.time_to_play_each_column())
                if not self.now_playing: break
            if not self.loop: break
        self.now_playing = False

    def time_to_play_each_column(self):
        beats_per_second = self.beats_per_minute / 60
        time_to_play_each_column = 1 / beats_per_second
        return time_to_play_each_column


    def on_loop_button_toggled(self):
        self.loop = self.loopbuttonvar.get()

    def on_beats_per_minute_changed(self):
        self.beats_per_minute = int(self.beats_per_minute_widget.get())

    def init_is_button_clicked_list(self, num_of_rows, num_of_columns):
        return [[False] * num_of_columns for x in range(num_of_rows)]

    def get_button_value(self, row, col):
        return self.all_patterns[self.current_pattern_index][
            'is_button_clicked_list'][row][col]

    def find_number_of_columns(self):
        return int(self.number_of_units_widget.get()) * int(self.bpu_widget.get())

    def process_button_clicked(self, row, col):
        self.set_button_value(row, col, not self.get_button_value(row, col))
        self.display_button_color(row, col)

    def set_button_value(self, row, col, bool_value):
        self.all_patterns[self.current_pattern_index][
            'is_button_clicked_list'][row][col] = bool_value

    def on_button_clicked(self, row, col):
        def event_handler():
            self.process_button_clicked(row, col)
        return event_handler

    def display_all_button_colors(self):
        number_of_columns = self.find_number_of_columns()
        for r in range(MAX_NUMBER_OF_DRUM_SAMPLES):
            for c in range(number_of_columns):
                self.display_button_color(r, c)

    def display_button_color(self, row, col):
        bpu = int(self.bpu_widget.get())
        original_color = COLOR_1 if ((col//bpu) % 2) else COLOR_2
        button_color = BUTTON_CLICKED_COLOR if self.get_button_value(
            row, col) else original_color
        self.buttons[row][col].config(background=button_color)

    def create_play_bar(self):
        playbar_frame = Frame(self.root, height=15)
        start_row = MAX_NUMBER_OF_DRUM_SAMPLES + 10
        playbar_frame.grid(row=start_row, columnspan=13,
                           sticky=W + E, padx=15, pady=10)
        self.play_icon = PhotoImage(file="images/play.gif")
        self.play_button = Button(
            playbar_frame, text='Play',  image=self.play_icon, compound='left', command=self.on_play_button_clicked)
        self.play_button.grid(row=start_row, column=1, padx=2)
        Button(playbar_frame, text='Stop', command=self.on_stop_button_clicked).grid(
            row=start_row, column=3, padx=2)
        self.loopbuttonvar = BooleanVar()
        self.loopbuttonvar.set(True)
        self.loopbutton = Checkbutton(
            playbar_frame, text='Loop', command=self.on_loop_button_toggled, variable=self.loopbuttonvar)
        self.loopbutton.grid(row=start_row, column=16, padx=5)
        Label(playbar_frame, text='Beats Per Minute').grid(
            row=start_row, column=25)
        self.beats_per_minute_widget = Spinbox(playbar_frame, from_=MIN_BEATS_PER_MINUTE, to=MAX_BEATS_PER_MINUTE, width=5,
                increment=5.0, command=self.on_beats_per_minute_changed)
        self.beats_per_minute_widget.grid(row=start_row, column=30)
        self.beats_per_minute_widget.delete(0,"end")
        self.beats_per_minute_widget.insert(0,INITIAL_BEATS_PER_MINUTE)
        photo = PhotoImage(file='images/signature.gif')
        label = Label(playbar_frame, image=photo)
        label.image = photo
        label.grid(row=start_row, column=50, padx=1, sticky='w')

    def create_right_button_matrix(self):
        right_frame = Frame(self.root)
        right_frame.grid(row=10, column=6, sticky=W +
                         E + N + S, padx=15, pady=4)
        self.buttons = [[None for x in range(
            self.find_number_of_columns())] for x in range(MAX_NUMBER_OF_DRUM_SAMPLES)]
        for row in range(MAX_NUMBER_OF_DRUM_SAMPLES):
            for col in range(self.find_number_of_columns()):
                self.buttons[row][col] = Button(
                    right_frame, command=self.on_button_clicked(row, col))
                self.buttons[row][col].grid(row=row, column=col)
                self.display_button_color(row, col)

    def create_left_drum_loader(self):
        left_frame = Frame(self.root)
        left_frame.grid(row=10, column=0, columnspan=6, sticky=W + E + N + S)
        open_file_icon = PhotoImage(file='images/openfile.gif')
        for i in range(MAX_NUMBER_OF_DRUM_SAMPLES):
            open_file_button = Button(left_frame, image=open_file_icon,
                                      command=self.on_open_file_button_clicked(i))
            open_file_button.image = open_file_icon
            open_file_button.grid(row=i, column=0,  padx=5, pady=4)
            self.drum_load_entry_widget[i] = Entry(left_frame)
            self.drum_load_entry_widget[i].grid(
                row=i, column=4, padx=7, pady=4)


    def create_top_bar(self):
        topbar_frame = Frame(self.root, height=25)
        topbar_frame.grid(row=0, columnspan=12, rowspan=10, padx=5, pady=5)

        Label(topbar_frame, text='Pattern Number:').grid(row=0, column=1)
        self.pattern_index_widget = Spinbox(topbar_frame, from_=0, to=MAX_NUMBER_OF_PATTERNS - 1, width=5,
                command=self.on_pattern_changed)
        self.pattern_index_widget.grid(row=0, column=2)
        self.current_pattern_name_widget = Entry(topbar_frame)
        self.current_pattern_name_widget.grid(row=0, column=3, padx=7, pady=2)

        Label(topbar_frame, text='Number of Units:').grid(row=0, column=4)
        self.number_of_units_widget = Spinbox(topbar_frame, from_=1, to=MAX_NUMBER_OF_UNITS, width=5,
                command=self.on_number_of_units_changed)
        self.number_of_units_widget.delete(0,"end")
        self.number_of_units_widget.insert(0,INITIAL_NUMBER_OF_UNITS)
        self.number_of_units_widget.grid(row=0, column=5)
        Label(topbar_frame, text='BPUs:').grid(row=0, column=6)
        self.bpu_widget = Spinbox(topbar_frame, from_=1, to=MAX_BPU, width=5,
                command=self.on_bpu_changed)
        self.bpu_widget.grid(row=0, column=7)
        self.bpu_widget.delete(0,"end")
        self.bpu_widget.insert(0,INITIAL_BPU)


    def create_top_menu(self):
        self.menu_bar = Menu(self.root)
        self.file_menu = Menu(self.menu_bar, tearoff=0)
        self.file_menu.add_command(label="Load Project")
        self.file_menu.add_command(label="Save Project")
        self.file_menu.add_separator()
        self.file_menu.add_command(label="Exit")
        self.menu_bar.add_cascade(label="File", menu=self.file_menu)
        self.about_menu = Menu(self.menu_bar, tearoff=0)
        self.about_menu.add_command(label="About")
        self.menu_bar.add_cascade(label="About", menu=self.about_menu)
        self.root.config(menu=self.menu_bar)

    def init_gui(self):
        self.create_top_menu()
        self.create_top_bar()
        self.create_left_drum_loader()
        self.create_right_button_matrix()
        self.create_play_bar()


if __name__ == '__main__':
    root = Tk()
    DrumMachine(root)
    root.mainloop()


================================================
FILE: Chapter 03/3.07.py
================================================
"""
Code illustration: 3.07

    Tkinter and Threading
    **********************
       New modules imported here:
            - threading

        New methods defined here:
            - play_in_thread()
            - toggle_play_button_state()

        Method modified here:
            - start_play()
            - __init__ method - to override the close button
            - on_play_button_clicked()
            - on_stop_button_clicked()
            - on_loop_button_toggled()
            - play_pattern() - added a call to toggle_play_button_state()

Chapter 3 : Programmable Drum Machine
Tkinter GUI Application Development Blueprints
"""
import os
import time
import threading
from tkinter import Tk, Entry, W, E, N, S, PhotoImage, Checkbutton, Button, \
        Menu, Frame, Label, Spinbox, END, BooleanVar
from tkinter import filedialog
import pygame


PROGRAM_NAME = ' Explosion Drum Machine '
MAX_NUMBER_OF_PATTERNS = 10
MAX_NUMBER_OF_DRUM_SAMPLES = 5
MAX_NUMBER_OF_UNITS = 5
MAX_BPU = 5
INITIAL_NUMBER_OF_UNITS = 4
INITIAL_BPU = 4
INITIAL_BEATS_PER_MINUTE = 240
MIN_BEATS_PER_MINUTE = 80
MAX_BEATS_PER_MINUTE = 360
COLOR_1 = 'grey55'
COLOR_2 = 'khaki'
BUTTON_CLICKED_COLOR = 'green'


class DrumMachine:

    def __init__(self, root):
        self.root = root
        self.root.title(PROGRAM_NAME)
        self.all_patterns = [None] * MAX_NUMBER_OF_PATTERNS
        self.beats_per_minute = INITIAL_BEATS_PER_MINUTE
        self.current_pattern_index = 0
        self.loop = True
        self.now_playing = False
        self.drum_load_entry_widget = [None] * MAX_NUMBER_OF_DRUM_SAMPLES
        self.init_all_patterns()
        self.init_gui()

    def on_open_file_button_clicked(self, drum_index):
        def event_handler():
            file_path = filedialog.askopenfilename(defaultextension=".wav",
                                                   filetypes=[("Wave Files", "*.wav"), ("OGG Files", "*.ogg")])
            if not file_path:
                return
            self.set_drum_file_path(drum_index, file_path)
            self.display_all_drum_file_names()
        return event_handler

    def display_all_drum_file_names(self):
        for i, drum_name in enumerate(self.get_list_of_drum_files()):
            self.display_drum_name(i, drum_name)

    def display_drum_name(self, text_widget_num, file_path):
        if file_path is None:
            return
        drum_name = os.path.basename(file_path)
        self.drum_load_entry_widget[text_widget_num].delete(0, END)
        self.drum_load_entry_widget[text_widget_num].insert(0, drum_name)



    #
    # getters and setters begins
    #

    def get_current_pattern_dict(self):
        return self.all_patterns[self.current_pattern_index]

    def get_bpu(self):
        return self.get_current_pattern_dict()['bpu']

    def set_bpu(self):
        self.get_current_pattern_dict()['bpu'] = int(self.bpu_widget.get())

    def get_number_of_units(self):
        return self.get_current_pattern_dict()['number_of_units']

    def set_number_of_units(self):
        self.get_current_pattern_dict(
        )['number_of_units'] = int(self.number_of_units_widget.get())

    def get_list_of_drum_files(self):
        return self.get_current_pattern_dict()['list_of_drum_files']

    def get_drum_file_path(self, drum_index):
        return self.get_list_of_drum_files()[drum_index]

    def set_drum_file_path(self, drum_index, file_path):
        self.get_list_of_drum_files()[drum_index] = file_path

    def get_is_button_clicked_list(self):
        return self.get_current_pattern_dict()['is_button_clicked_list']

    def set_is_button_clicked_list(self, num_of_rows, num_of_columns):
        self.get_current_pattern_dict()['is_button_clicked_list'] = [
            [False] * num_of_columns for x in range(num_of_rows)]


    def init_all_patterns(self):
        self.all_patterns = [
            {
                'list_of_drum_files': [None] * MAX_NUMBER_OF_DRUM_SAMPLES,
                'number_of_units': INITIAL_NUMBER_OF_UNITS,
                'bpu': INITIAL_BPU,
                'is_button_clicked_list':
                self.init_is_button_clicked_list(
                    MAX_NUMBER_OF_DRUM_SAMPLES,
                    INITIAL_NUMBER_OF_UNITS * INITIAL_BPU
                )
            }
            for k in range(MAX_NUMBER_OF_PATTERNS)]

    def on_pattern_changed(self):
        pass

    def on_number_of_units_changed(self):
        self.set_number_of_units()
        self.set_is_button_clicked_list(MAX_NUMBER_OF_DRUM_SAMPLES,
                                        self.find_number_of_columns())
        self.create_right_button_matrix()

    def on_bpu_changed(self):
        self.set_bpu()
        self.set_is_button_clicked_list(MAX_NUMBER_OF_DRUM_SAMPLES,
                                        self.find_number_of_columns())
        self.create_right_button_matrix()

    def play_in_thread(self):
        self.thread = threading.Thread(target = self.play_pattern)
        self.thread.start()


    def on_play_button_clicked(self):
        self.start_play()
        self.toggle_play_button_state()

    def start_play(self):
        self.init_pygame()
        self.play_in_thread()

    def on_stop_button_clicked(self):
        self.stop_play()
        self.toggle_play_button_state()


    def toggle_play_button_state(self):
        if self.now_playing:
            self.play_button.config(state="disabled")
        else:
            self.play_button.config(state="normal")

    def exit_app(self):
        self.now_playing = False
        if messagebox.askokcancel("Quit", "Really quit?"):
            self.root.destroy()

    def stop_play(self):
        self.now_playing = False

    def init_pygame(self):
        pygame.mixer.pre_init(44100, -16, 1, 512)
        pygame.init()

    def play_sound(self, sound_filename):
        if sound_filename is not None:
            pygame.mixer.Sound(sound_filename).play()

    def get_column_from_matrix(self, matrix, i):
        return [row[i] for row in matrix]


    def play_pattern(self):
        self.now_playing = True
        self.toggle_play_button_state()
        while self.now_playing:
            play_list = self.get_is_button_clicked_list()
            num_columns = len(play_list[0])
            for column_index in range(num_columns):
                column_to_play = self.get_column_from_matrix(
                      play_list, column_index)
                for i, item in enumerate(column_to_play):
                    if item:
                        sound_filename = self.get_drum_file_path(i)
                        self.play_sound(sound_filename)
                time.sleep(self.time_to_play_each_column())
                if not self.now_playing: break
            if not self.loop: break
        self.now_playing = False
        self.toggle_play_button_state()

    def time_to_play_each_column(self):
        beats_per_second = self.beats_per_minute / 60
        time_to_play_each_column = 1 / beats_per_second
        return time_to_play_each_column


    def on_loop_button_toggled(self):
        self.loop = self.loopbuttonvar.get()

    def on_beats_per_minute_changed(self):
        self.beats_per_minute = int(self.beats_per_minute_widget.get())

    def init_is_button_clicked_list(self, num_of_rows, num_of_columns):
        return [[False] * num_of_columns for x in range(num_of_rows)]

    def get_button_value(self, row, col):
        return self.all_patterns[self.current_pattern_index][
            'is_button_clicked_list'][row][col]

    def find_number_of_columns(self):
        return int(self.number_of_units_widget.get()) * int(self.bpu_widget.get())

    def process_button_clicked(self, row, col):
        self.set_button_value(row, col, not self.get_button_value(row, col))
        self.display_button_color(row, col)

    def set_button_value(self, row, col, bool_value):
        self.all_patterns[self.current_pattern_index][
            'is_button_clicked_list'][row][col] = bool_value

    def on_button_clicked(self, row, col):
        def event_handler():
            self.process_button_clicked(row, col)
        return event_handler

    def display_all_button_colors(self):
        number_of_columns = self.find_number_of_columns()
        for r in range(MAX_NUMBER_OF_DRUM_SAMPLES):
            for c in range(number_of_columns):
                self.display_button_color(r, c)

    def display_button_color(self, row, col):
        bpu = int(self.bpu_widget.get())
        original_color = COLOR_1 if ((col//bpu) % 2) else COLOR_2
        button_color = BUTTON_CLICKED_COLOR if self.get_button_value(
            row, col) else original_color
        self.buttons[row][col].config(background=button_color)

    def create_play_bar(self):
        playbar_frame = Frame(self.root, height=15)
        start_row = MAX_NUMBER_OF_DRUM_SAMPLES + 10
        playbar_frame.grid(row=start_row, columnspan=13,
                           sticky=W + E, padx=15, pady=10)
        self.play_icon = PhotoImage(file="images/play.gif")
        self.play_button = Button(
            playbar_frame, text='Play',  image=self.play_icon, compound='left', command=self.on_play_button_clicked)
        self.play_button.grid(row=start_row, column=1, padx=2)
        Button(playbar_frame, text='Stop', command=self.on_stop_button_clicked).grid(
            row=start_row, column=3, padx=2)
        self.loopbuttonvar = BooleanVar()
        self.loopbuttonvar.set(True)
        self.loopbutton = Checkbutton(
            playbar_frame, text='Loop', command=self.on_loop_button_toggled, variable=self.loopbuttonvar)
        self.loopbutton.grid(row=start_row, column=16, padx=5)
        Label(playbar_frame, text='Beats Per Minute').grid(
            row=start_row, column=25)
        self.beats_per_minute_widget = Spinbox(playbar_frame, from_=MIN_BEATS_PER_MINUTE, to=MAX_BEATS_PER_MINUTE, width=5,
                increment=5.0, command=self.on_beats_per_minute_changed)
        self.beats_per_minute_widget.grid(row=start_row, column=30)
        self.beats_per_minute_widget.delete(0,"end")
        self.beats_per_minute_widget.insert(0,INITIAL_BEATS_PER_MINUTE)
        photo = PhotoImage(file='images/signature.gif')
        label = Label(playbar_frame, image=photo)
        label.image = photo
        label.grid(row=start_row, column=50, padx=1, sticky='w')

    def create_right_button_matrix(self):
        right_frame = Frame(self.root)
        right_frame.grid(row=10, column=6, sticky=W +
                         E + N + S, padx=15, pady=4)
        self.buttons = [[None for x in range(
            self.find_number_of_columns())] for x in range(MAX_NUMBER_OF_DRUM_SAMPLES)]
        for row in range(MAX_NUMBER_OF_DRUM_SAMPLES):
            for col in range(self.find_number_of_columns()):
                self.buttons[row][col] = Button(
                    right_frame, command=self.on_button_clicked(row, col))
                self.buttons[row][col].grid(row=row, column=col)
                self.display_button_color(row, col)

    def create_left_drum_loader(self):
        left_frame = Frame(self.root)
        left_frame.grid(row=10, column=0, columnspan=6, sticky=W + E + N + S)
        open_file_icon = PhotoImage(file='images/openfile.gif')
        for i in range(MAX_NUMBER_OF_DRUM_SAMPLES):
            open_file_button = Button(left_frame, image=open_file_icon,
                                      command=self.on_open_file_button_clicked(i))
            open_file_button.image = open_file_icon
            open_file_button.grid(row=i, column=0,  padx=5, pady=4)
            self.drum_load_entry_widget[i] = Entry(left_frame)
            self.drum_load_entry_widget[i].grid(
                row=i, column=4, padx=7, pady=4)


    def create_top_bar(self):
        topbar_frame = Frame(self.root, height=25)
        topbar_frame.grid(row=0, columnspan=12, rowspan=10, padx=5, pady=5)

        Label(topbar_frame, text='Pattern Number:').grid(row=0, column=1)
        self.pattern_index_widget = Spinbox(topbar_frame, from_=0, to=MAX_NUMBER_OF_PATTERNS - 1, width=5,
                command=self.on_pattern_changed)
        self.pattern_index_widget.grid(row=0, column=2)
        self.current_pattern_name_widget = Entry(topbar_frame)
        self.current_pattern_name_widget.grid(row=0, column=3, padx=7, pady=2)

        Label(topbar_frame, text='Number of Units:').grid(row=0, column=4)
        self.number_of_units_widget = Spinbox(topbar_frame, from_=1, to=MAX_NUMBER_OF_UNITS, width=5,
                command=self.on_number_of_units_changed)
        self.number_of_units_widget.delete(0,"end")
        self.number_of_units_widget.insert(0,INITIAL_NUMBER_OF_UNITS)
        self.number_of_units_widget.grid(row=0, column=5)
        Label(topbar_frame, text='BPUs:').grid(row=0, column=6)
        self.bpu_widget = Spinbox(topbar_frame, from_=1, to=MAX_BPU, width=5,
                command=self.on_bpu_changed)
        self.bpu_widget.grid(row=0, column=7)
        self.bpu_widget.delete(0,"end")
        self.bpu_widget.insert(0,INITIAL_BPU)


    def create_top_menu(self):
        self.menu_bar = Menu(self.root)
        self.file_menu = Menu(self.menu_bar, tearoff=0)
        self.file_menu.add_command(label="Load Project")
        self.file_menu.add_command(label="Save Project")
        self.file_menu.add_separator()
        self.file_menu.add_command(label="Exit")
        self.menu_bar.add_cascade(label="File", menu=self.file_menu)
        self.about_menu = Menu(self.menu_bar, tearoff=0)
        self.about_menu.add_command(label="About")
        self.menu_bar.add_cascade(label="About", menu=self.about_menu)
        self.root.config(menu=self.menu_bar)

    def init_gui(self):
        self.create_top_menu()
        self.create_top_bar()
        self.create_left_drum_loader()
        self.create_right_button_matrix()
        self.create_play_bar()


if __name__ == '__main__':
    root = Tk()
    DrumMachine(root)
    root.mainloop()


================================================
FILE: Chapter 03/3.08.py
================================================
"""
Code illustration: 3.08

    Adding support for multiple beat patterns

        New methods added here:
            - display_pattern_name()
            - change_pattern()
            - restart_play_of_new_pattern

        Methods modified here:
            - create_top_bar() - added a call to display_pattern_name()
            - on_pattern_changed()

Chapter 3 : Programmable Drum Machine
Tkinter GUI Application Development Blueprints
"""
import os
import time
import threading
from tkinter import Tk, Entry, W, E, N, S, PhotoImage, Checkbutton, Button, \
        Menu, Frame, Label, Spinbox, END, BooleanVar
from tkinter import filedialog
import pygame


PROGRAM_NAME = ' Explosion Drum Machine '
MAX_NUMBER_OF_PATTERNS = 10
MAX_NUMBER_OF_DRUM_SAMPLES = 5
MAX_NUMBER_OF_UNITS = 5
MAX_BPU = 5
INITIAL_NUMBER_OF_UNITS = 4
INITIAL_BPU = 4
INITIAL_BEATS_PER_MINUTE = 240
MIN_BEATS_PER_MINUTE = 80
MAX_BEATS_PER_MINUTE = 360
COLOR_1 = 'grey55'
COLOR_2 = 'khaki'
BUTTON_CLICKED_COLOR = 'green'


class DrumMachine:

    def __init__(self, root):
        self.root = root
        self.root.title(PROGRAM_NAME)
        self.all_patterns = [None] * MAX_NUMBER_OF_PATTERNS
        self.beats_per_minute = INITIAL_BEATS_PER_MINUTE
        self.current_pattern_index = 
Download .txt
gitextract_ux_6jgor/

├── Chapter 01/
│   ├── 1.01.py
│   ├── 1.02.py
│   ├── 1.03.py
│   ├── 1.04.py
│   ├── 1.05.py
│   ├── 1.06.py
│   ├── 1.07.py
│   ├── 1.08.py
│   ├── 1.09.py
│   ├── 1.10.py
│   ├── 1.11.py
│   ├── 1.12.py
│   ├── gir.xbm
│   ├── optionDB.txt
│   ├── readme.txt
│   └── textcontent.txt
├── Chapter 02/
│   ├── 2.01.py
│   ├── 2.02.py
│   ├── 2.03.py
│   ├── 2.04.py
│   ├── 2.05.py
│   ├── 2.06.py
│   ├── 2.07.py
│   ├── 2.08.py
│   ├── 2.09.py
│   ├── 2.10.py
│   ├── 2.11.py
│   ├── 2.12.py
│   └── readme.txt
├── Chapter 03/
│   ├── 3.01.py
│   ├── 3.02.py
│   ├── 3.03.py
│   ├── 3.04.py
│   ├── 3.05.py
│   ├── 3.06.py
│   ├── 3.07.py
│   ├── 3.08.py
│   ├── 3.09.py
│   ├── 3.10.py
│   ├── 3.11.py
│   ├── 3.12.py
│   └── readme.txt
├── Chapter 04/
│   ├── 4.01/
│   │   ├── configurations.py
│   │   ├── controller.py
│   │   ├── exceptions.py
│   │   ├── model.py
│   │   └── view.py
│   ├── 4.02/
│   │   ├── configurations.py
│   │   ├── controller.py
│   │   ├── exceptions.py
│   │   ├── model.py
│   │   ├── piece.py
│   │   └── view.py
│   ├── 4.03/
│   │   ├── configurations.py
│   │   ├── controller.py
│   │   ├── exceptions.py
│   │   ├── model.py
│   │   ├── piece.py
│   │   └── view.py
│   ├── 4.04/
│   │   ├── configurations.py
│   │   ├── controller.py
│   │   ├── exceptions.py
│   │   ├── model.py
│   │   ├── piece.py
│   │   └── view.py
│   ├── 4.05/
│   │   ├── configurations.py
│   │   ├── controller.py
│   │   ├── exceptions.py
│   │   ├── model.py
│   │   ├── piece.py
│   │   └── view.py
│   ├── 4.06/
│   │   ├── configurations.py
│   │   ├── controller.py
│   │   ├── exceptions.py
│   │   ├── model.py
│   │   ├── piece.py
│   │   └── view.py
│   ├── 4.07/
│   │   ├── chess_options.ini
│   │   ├── configurations.py
│   │   ├── controller.py
│   │   ├── exceptions.py
│   │   ├── model.py
│   │   ├── piece.py
│   │   ├── preferenceswindow.py
│   │   └── view.py
│   └── readme.txt
├── Chapter 05/
│   ├── 5.01/
│   │   ├── model.py
│   │   ├── player.py
│   │   └── view.py
│   ├── 5.02/
│   │   ├── model.py
│   │   ├── player.py
│   │   └── view.py
│   ├── 5.03/
│   │   ├── model.py
│   │   ├── player.py
│   │   └── view.py
│   ├── 5.04/
│   │   ├── model.py
│   │   ├── player.py
│   │   └── view.py
│   ├── 5.05/
│   │   ├── model.py
│   │   ├── player.py
│   │   ├── seekbar.py
│   │   └── view.py
│   ├── 5.06/
│   │   ├── helpers.py
│   │   ├── model.py
│   │   ├── player.py
│   │   ├── seekbar.py
│   │   └── view.py
│   ├── 5.07/
│   │   ├── helpers.py
│   │   ├── model.py
│   │   ├── player.py
│   │   ├── seekbar.py
│   │   └── view.py
│   ├── 5.08/
│   │   ├── helpers.py
│   │   ├── model.py
│   │   ├── player.py
│   │   ├── seekbar.py
│   │   └── view.py
│   ├── 5.09/
│   │   ├── helpers.py
│   │   ├── model.py
│   │   ├── player.py
│   │   ├── pygleterror.py
│   │   ├── seekbar.py
│   │   └── view.py
│   └── readme.txt
├── Chapter 06/
│   ├── 6.01.py
│   ├── 6.02.py
│   ├── 6.03.py
│   ├── 6.04.py
│   ├── 6.05.py
│   ├── 6.06.py
│   ├── 6.07.py
│   ├── 6.08.py
│   ├── 6.09.py
│   ├── framework.py
│   └── supershapes.py
├── Chapter 07/
│   ├── 7.01/
│   │   ├── constants.py
│   │   └── view.py
│   ├── 7.02/
│   │   ├── constants.py
│   │   └── view.py
│   ├── 7.03/
│   │   ├── audio.py
│   │   ├── constants.py
│   │   └── view.py
│   ├── 7.04/
│   │   ├── audio.py
│   │   ├── constants.py
│   │   └── view.py
│   ├── 7.05/
│   │   ├── audio.py
│   │   ├── constants.py
│   │   └── view.py
│   ├── 7.06/
│   │   ├── audio.py
│   │   ├── constants.py
│   │   └── view.py
│   ├── 7.07/
│   │   ├── audio.py
│   │   ├── constants.py
│   │   ├── score_maker.py
│   │   └── view.py
│   ├── handle_widget_resize.py
│   ├── json/
│   │   ├── chords.json
│   │   ├── progressions.json
│   │   └── scales.json
│   ├── nonresponsive.py
│   └── responsive.py
├── Chapter 08/
│   ├── 8.01_screensaver.py
│   ├── 8.02_pie_chart.py
│   ├── 8.03_bar_graph.py
│   ├── 8.04_scatter_plot.py
│   ├── 8.05_matplotlib_embedding_graphs.py
│   ├── 8.06_polar_plot.py
│   ├── 8.07_gravity_simulation.py
│   ├── 8.08_Mandelbrot.py
│   ├── 8.09_vornoi_diagram.py
│   ├── 8.10_spring_pendulum.py
│   ├── 8.11_chaos_game.py
│   ├── 8.12_phyllotaxis.py
│   └── 8.13_3D_graphics.py
├── Chapter 09/
│   ├── 9.01_race_condition.py
│   ├── 9.02_lock_demo.py
│   ├── 9.03_threading_with queue.py
│   ├── 9.04_game_of_ snake.py
│   ├── 9.05_urllib_demo.py
│   ├── 9.06_weather_ reporter.py
│   ├── 9.07_socket_demo.py
│   ├── 9.08_port_scanner.py
│   ├── 9.09_chat_server.py
│   ├── 9.10_chat_client.py
│   ├── 9.11_phonebook.py
│   ├── 9.12_async_demo.py
│   ├── 9.13.arduino_sketch.ino
│   ├── 9.14_read_from_serial_port.py
│   └── readme.txt
├── Chapter 10/
│   ├── 10.01_trace_variable.py
│   ├── 10.02_widget_traversal.py
│   ├── 10.03_validation_mode_demo.py
│   ├── 10.04_percent _substitutions _demo.py
│   ├── 10.05_key_validation.py
│   ├── 10.06_focus_out _validation.py
│   ├── 10.07_formatting_entry_widget_to_display_date.py
│   ├── 10.08_font_demo.py
│   ├── 10.09_all_fonts_on_a_system.py
│   ├── 10.10_font_selector.py
│   ├── 10.11_reading_from_command_line.py
│   └── 10.12_tkinter_class_hierarchy.py
├── LICENSE
└── README.md
Download .txt
SYMBOL INDEX (2280 symbols across 145 files)

FILE: Chapter 01/1.09.py
  function callback (line 11) | def callback(event): ##(2)

FILE: Chapter 01/1.10.py
  function show_event_details (line 9) | def show_event_details(event):

FILE: Chapter 01/1.11.py
  function show (line 11) | def show():

FILE: Chapter 02/2.04.py
  function cut (line 26) | def cut():
  function copy (line 31) | def copy():
  function paste (line 36) | def paste():
  function undo (line 41) | def undo():
  function redo (line 46) | def redo(event=None):

FILE: Chapter 02/2.05.py
  function select_all (line 25) | def select_all(event=None):
  function find_text (line 30) | def find_text(event=None):
  function search_output (line 56) | def search_output(needle, if_ignore_case, content_text,
  function cut (line 77) | def cut():
  function copy (line 82) | def copy():
  function paste (line 87) | def paste():
  function undo (line 92) | def undo():
  function redo (line 97) | def redo(event=None):

FILE: Chapter 02/2.07.py
  function new_file (line 30) | def new_file(event=None):
  function open_file (line 37) | def open_file(event=None):
  function write_to_file (line 49) | def write_to_file(file_name):
  function save_as (line 59) | def save_as(event=None):
  function save (line 70) | def save(event=None):
  function select_all (line 81) | def select_all(event=None):
  function find_text (line 86) | def find_text(event=None):
  function search_output (line 112) | def search_output(needle, if_ignore_case, content_text,
  function cut (line 133) | def cut():
  function copy (line 138) | def copy():
  function paste (line 143) | def paste():
  function undo (line 148) | def undo():
  function redo (line 153) | def redo(event=None):

FILE: Chapter 02/2.09.py
  function display_about_messagebox (line 27) | def display_about_messagebox(event=None):
  function display_help_messagebox (line 32) | def display_help_messagebox(event=None):
  function exit_editor (line 38) | def exit_editor(event=None):
  function new_file (line 46) | def new_file(event=None):
  function open_file (line 53) | def open_file(event=None):
  function write_to_file (line 65) | def write_to_file(file_name):
  function save_as (line 74) | def save_as(event=None):
  function save (line 84) | def save(event=None):
  function select_all (line 93) | def select_all(event=None):
  function find_text (line 98) | def find_text(event=None):
  function search_output (line 124) | def search_output(needle, if_ignore_case, content_text,
  function cut (line 145) | def cut():
  function copy (line 150) | def copy():
  function paste (line 155) | def paste():
  function undo (line 160) | def undo():
  function redo (line 165) | def redo(event=None):

FILE: Chapter 02/2.10.py
  function update_line_numbers (line 26) | def update_line_numbers(event=None):
  function highlight_line (line 34) | def highlight_line(interval=100):
  function undo_highlight (line 41) | def undo_highlight():
  function toggle_highlight (line 45) | def toggle_highlight(event=None):
  function on_content_changed (line 52) | def on_content_changed(event=None):
  function get_line_numbers (line 56) | def get_line_numbers():
  function display_about_messagebox (line 65) | def display_about_messagebox(event=None):
  function display_help_messagebox (line 70) | def display_help_messagebox(event=None):
  function exit_editor (line 76) | def exit_editor(event=None):
  function new_file (line 81) | def new_file(event=None):
  function open_file (line 89) | def open_file(event=None):
  function write_to_file (line 102) | def write_to_file(file_name):
  function save_as (line 111) | def save_as(event=None):
  function save (line 121) | def save(event=None):
  function select_all (line 130) | def select_all(event=None):
  function find_text (line 135) | def find_text(event=None):
  function search_output (line 161) | def search_output(needle, if_ignore_case, content_text,
  function cut (line 182) | def cut():
  function copy (line 188) | def copy():
  function paste (line 193) | def paste():
  function undo (line 199) | def undo():
  function redo (line 205) | def redo(event=None):

FILE: Chapter 02/2.11.py
  function show_cursor_info_bar (line 25) | def show_cursor_info_bar():
  function update_cursor_info_bar (line 33) | def update_cursor_info_bar(event=None):
  function change_theme (line 41) | def change_theme(event=None):
  function update_line_numbers (line 49) | def update_line_numbers(event=None):
  function highlight_line (line 57) | def highlight_line(interval=100):
  function undo_highlight (line 64) | def undo_highlight():
  function toggle_highlight (line 67) | def toggle_highlight(event=None):
  function on_content_changed (line 73) | def on_content_changed(event=None):
  function get_line_numbers (line 78) | def get_line_numbers():
  function update_line_numbers (line 87) | def update_line_numbers(event=None):
  function display_about_messagebox (line 95) | def display_about_messagebox(event=None):
  function display_help_messagebox (line 100) | def display_help_messagebox(event=None):
  function exit_editor (line 106) | def exit_editor(event=None):
  function new_file (line 111) | def new_file(event=None):
  function open_file (line 119) | def open_file(event=None):
  function write_to_file (line 132) | def write_to_file(file_name):
  function save_as (line 141) | def save_as(event=None):
  function save (line 151) | def save(event=None):
  function select_all (line 160) | def select_all(event=None):
  function find_text (line 165) | def find_text(event=None):
  function search_output (line 191) | def search_output(needle, if_ignore_case, content_text,
  function cut (line 212) | def cut():
  function copy (line 218) | def copy():
  function paste (line 223) | def paste():
  function undo (line 229) | def undo():
  function redo (line 235) | def redo(event=None):

FILE: Chapter 02/2.12.py
  function show_popup_menu (line 26) | def show_popup_menu(event):
  function show_cursor_info_bar (line 30) | def show_cursor_info_bar():
  function update_cursor_info_bar (line 38) | def update_cursor_info_bar(event=None):
  function change_theme (line 45) | def change_theme(event=None):
  function update_line_numbers (line 53) | def update_line_numbers(event=None):
  function highlight_line (line 61) | def highlight_line(interval=100):
  function undo_highlight (line 68) | def undo_highlight():
  function toggle_highlight (line 72) | def toggle_highlight(event=None):
  function on_content_changed (line 79) | def on_content_changed(event=None):
  function get_line_numbers (line 84) | def get_line_numbers():
  function display_about_messagebox (line 93) | def display_about_messagebox(event=None):
  function display_help_messagebox (line 98) | def display_help_messagebox(event=None):
  function exit_editor (line 104) | def exit_editor(event=None):
  function new_file (line 109) | def new_file(event=None):
  function open_file (line 117) | def open_file(event=None):
  function write_to_file (line 130) | def write_to_file(file_name):
  function save_as (line 139) | def save_as(event=None):
  function save (line 150) | def save(event=None):
  function select_all (line 159) | def select_all(event=None):
  function find_text (line 164) | def find_text(event=None):
  function search_output (line 191) | def search_output(needle, if_ignore_case, content_text,
  function cut (line 212) | def cut():
  function copy (line 218) | def copy():
  function paste (line 223) | def paste():
  function undo (line 229) | def undo():
  function redo (line 235) | def redo(event=None):

FILE: Chapter 03/3.01.py
  class DrumMachine (line 13) | class DrumMachine:
    method __init__ (line 15) | def __init__(self, root):

FILE: Chapter 03/3.02.py
  class DrumMachine (line 19) | class DrumMachine:
    method __init__ (line 21) | def __init__(self, root):
    method init_all_patterns (line 28) | def init_all_patterns(self):
    method init_is_button_clicked_list (line 42) | def init_is_button_clicked_list(self, num_of_rows, num_of_columns):

FILE: Chapter 03/3.03.py
  class DrumMachine (line 65) | class DrumMachine:
    method __init__ (line 67) | def __init__(self, root):
    method init_all_patterns (line 77) | def init_all_patterns(self):
    method on_pattern_changed (line 91) | def on_pattern_changed(self):
    method on_number_of_units_changed (line 94) | def on_number_of_units_changed(self):
    method on_bpu_changed (line 97) | def on_bpu_changed(self):
    method on_open_file_button_clicked (line 100) | def on_open_file_button_clicked(self, drum_index):
    method on_play_button_clicked (line 103) | def on_play_button_clicked(self):
    method on_stop_button_clicked (line 106) | def on_stop_button_clicked(self):
    method on_loop_button_toggled (line 109) | def on_loop_button_toggled(self):
    method on_beats_per_minute_changed (line 112) | def on_beats_per_minute_changed(self):
    method init_is_button_clicked_list (line 115) | def init_is_button_clicked_list(self, num_of_rows, num_of_columns):
    method get_button_value (line 118) | def get_button_value(self, row, col):
    method find_number_of_columns (line 122) | def find_number_of_columns(self):
    method process_button_clicked (line 125) | def process_button_clicked(self, row, col):
    method set_button_value (line 129) | def set_button_value(self, row, col, bool_value):
    method on_button_clicked (line 133) | def on_button_clicked(self, row, col):
    method display_all_button_colors (line 138) | def display_all_button_colors(self):
    method display_button_color (line 144) | def display_button_color(self, row, col):
    method create_play_bar (line 151) | def create_play_bar(self):
    method create_right_button_matrix (line 177) | def create_right_button_matrix(self):
    method create_left_drum_loader (line 190) | def create_left_drum_loader(self):
    method create_top_bar (line 203) | def create_top_bar(self):
    method create_top_menu (line 228) | def create_top_menu(self):
    method init_gui (line 241) | def init_gui(self):

FILE: Chapter 03/3.04.py
  class DrumMachine (line 42) | class DrumMachine:
    method __init__ (line 44) | def __init__(self, root):
    method get_current_pattern_dict (line 58) | def get_current_pattern_dict(self):
    method get_bpu (line 61) | def get_bpu(self):
    method set_bpu (line 64) | def set_bpu(self):
    method get_number_of_units (line 67) | def get_number_of_units(self):
    method set_number_of_units (line 70) | def set_number_of_units(self):
    method get_list_of_drum_files (line 74) | def get_list_of_drum_files(self):
    method get_drum_file_path (line 77) | def get_drum_file_path(self, drum_index):
    method set_drum_file_path (line 80) | def set_drum_file_path(self, drum_index, file_path):
    method get_is_button_clicked_list (line 83) | def get_is_button_clicked_list(self):
    method set_is_button_clicked_list (line 86) | def set_is_button_clicked_list(self, num_of_rows, num_of_columns):
    method init_all_patterns (line 91) | def init_all_patterns(self):
    method on_pattern_changed (line 105) | def on_pattern_changed(self):
    method on_number_of_units_changed (line 108) | def on_number_of_units_changed(self):
    method on_bpu_changed (line 114) | def on_bpu_changed(self):
    method on_open_file_button_clicked (line 121) | def on_open_file_button_clicked(self, drum_index):
    method on_play_button_clicked (line 124) | def on_play_button_clicked(self):
    method on_stop_button_clicked (line 127) | def on_stop_button_clicked(self):
    method on_loop_button_toggled (line 130) | def on_loop_button_toggled(self):
    method on_beats_per_minute_changed (line 133) | def on_beats_per_minute_changed(self):
    method init_is_button_clicked_list (line 136) | def init_is_button_clicked_list(self, num_of_rows, num_of_columns):
    method get_button_value (line 139) | def get_button_value(self, row, col):
    method find_number_of_columns (line 143) | def find_number_of_columns(self):
    method process_button_clicked (line 146) | def process_button_clicked(self, row, col):
    method set_button_value (line 150) | def set_button_value(self, row, col, bool_value):
    method on_button_clicked (line 154) | def on_button_clicked(self, row, col):
    method display_all_button_colors (line 159) | def display_all_button_colors(self):
    method display_button_color (line 165) | def display_button_color(self, row, col):
    method create_play_bar (line 172) | def create_play_bar(self):
    method create_right_button_matrix (line 198) | def create_right_button_matrix(self):
    method create_left_drum_loader (line 211) | def create_left_drum_loader(self):
    method create_top_bar (line 224) | def create_top_bar(self):
    method create_top_menu (line 249) | def create_top_menu(self):
    method init_gui (line 262) | def init_gui(self):

FILE: Chapter 03/3.05.py
  class DrumMachine (line 38) | class DrumMachine:
    method __init__ (line 40) | def __init__(self, root):
    method on_open_file_button_clicked (line 50) | def on_open_file_button_clicked(self, drum_index):
    method display_all_drum_file_names (line 60) | def display_all_drum_file_names(self):
    method display_drum_name (line 64) | def display_drum_name(self, text_widget_num, file_path):
    method get_current_pattern_dict (line 77) | def get_current_pattern_dict(self):
    method get_bpu (line 80) | def get_bpu(self):
    method set_bpu (line 83) | def set_bpu(self):
    method get_number_of_units (line 86) | def get_number_of_units(self):
    method set_number_of_units (line 89) | def set_number_of_units(self):
    method get_list_of_drum_files (line 93) | def get_list_of_drum_files(self):
    method get_drum_file_path (line 96) | def get_drum_file_path(self, drum_index):
    method set_drum_file_path (line 99) | def set_drum_file_path(self, drum_index, file_path):
    method get_is_button_clicked_list (line 102) | def get_is_button_clicked_list(self):
    method set_is_button_clicked_list (line 105) | def set_is_button_clicked_list(self, num_of_rows, num_of_columns):
    method init_all_patterns (line 110) | def init_all_patterns(self):
    method on_pattern_changed (line 124) | def on_pattern_changed(self):
    method on_number_of_units_changed (line 127) | def on_number_of_units_changed(self):
    method on_bpu_changed (line 133) | def on_bpu_changed(self):
    method on_play_button_clicked (line 140) | def on_play_button_clicked(self):
    method on_stop_button_clicked (line 143) | def on_stop_button_clicked(self):
    method on_loop_button_toggled (line 146) | def on_loop_button_toggled(self):
    method on_beats_per_minute_changed (line 149) | def on_beats_per_minute_changed(self):
    method init_is_button_clicked_list (line 152) | def init_is_button_clicked_list(self, num_of_rows, num_of_columns):
    method get_button_value (line 155) | def get_button_value(self, row, col):
    method find_number_of_columns (line 159) | def find_number_of_columns(self):
    method process_button_clicked (line 162) | def process_button_clicked(self, row, col):
    method set_button_value (line 166) | def set_button_value(self, row, col, bool_value):
    method on_button_clicked (line 170) | def on_button_clicked(self, row, col):
    method display_all_button_colors (line 175) | def display_all_button_colors(self):
    method display_button_color (line 181) | def display_button_color(self, row, col):
    method create_play_bar (line 188) | def create_play_bar(self):
    method create_right_button_matrix (line 214) | def create_right_button_matrix(self):
    method create_left_drum_loader (line 227) | def create_left_drum_loader(self):
    method create_top_bar (line 241) | def create_top_bar(self):
    method create_top_menu (line 266) | def create_top_menu(self):
    method init_gui (line 279) | def init_gui(self):

FILE: Chapter 03/3.06.py
  class DrumMachine (line 61) | class DrumMachine:
    method __init__ (line 63) | def __init__(self, root):
    method on_open_file_button_clicked (line 75) | def on_open_file_button_clicked(self, drum_index):
    method display_all_drum_file_names (line 85) | def display_all_drum_file_names(self):
    method display_drum_name (line 89) | def display_drum_name(self, text_widget_num, file_path):
    method get_current_pattern_dict (line 102) | def get_current_pattern_dict(self):
    method get_bpu (line 105) | def get_bpu(self):
    method set_bpu (line 108) | def set_bpu(self):
    method get_number_of_units (line 111) | def get_number_of_units(self):
    method set_number_of_units (line 114) | def set_number_of_units(self):
    method get_list_of_drum_files (line 118) | def get_list_of_drum_files(self):
    method get_drum_file_path (line 121) | def get_drum_file_path(self, drum_index):
    method set_drum_file_path (line 124) | def set_drum_file_path(self, drum_index, file_path):
    method get_is_button_clicked_list (line 127) | def get_is_button_clicked_list(self):
    method set_is_button_clicked_list (line 130) | def set_is_button_clicked_list(self, num_of_rows, num_of_columns):
    method init_all_patterns (line 135) | def init_all_patterns(self):
    method on_pattern_changed (line 149) | def on_pattern_changed(self):
    method on_number_of_units_changed (line 152) | def on_number_of_units_changed(self):
    method on_bpu_changed (line 158) | def on_bpu_changed(self):
    method on_play_button_clicked (line 164) | def on_play_button_clicked(self):
    method start_play (line 167) | def start_play(self):
    method on_stop_button_clicked (line 171) | def on_stop_button_clicked(self):
    method stop_play (line 174) | def stop_play(self):
    method init_pygame (line 177) | def init_pygame(self):
    method play_sound (line 181) | def play_sound(self, sound_filename):
    method get_column_from_matrix (line 185) | def get_column_from_matrix(self, matrix, i):
    method play_pattern (line 189) | def play_pattern(self):
    method time_to_play_each_column (line 206) | def time_to_play_each_column(self):
    method on_loop_button_toggled (line 212) | def on_loop_button_toggled(self):
    method on_beats_per_minute_changed (line 215) | def on_beats_per_minute_changed(self):
    method init_is_button_clicked_list (line 218) | def init_is_button_clicked_list(self, num_of_rows, num_of_columns):
    method get_button_value (line 221) | def get_button_value(self, row, col):
    method find_number_of_columns (line 225) | def find_number_of_columns(self):
    method process_button_clicked (line 228) | def process_button_clicked(self, row, col):
    method set_button_value (line 232) | def set_button_value(self, row, col, bool_value):
    method on_button_clicked (line 236) | def on_button_clicked(self, row, col):
    method display_all_button_colors (line 241) | def display_all_button_colors(self):
    method display_button_color (line 247) | def display_button_color(self, row, col):
    method create_play_bar (line 254) | def create_play_bar(self):
    method create_right_button_matrix (line 282) | def create_right_button_matrix(self):
    method create_left_drum_loader (line 295) | def create_left_drum_loader(self):
    method create_top_bar (line 309) | def create_top_bar(self):
    method create_top_menu (line 334) | def create_top_menu(self):
    method init_gui (line 347) | def init_gui(self):

FILE: Chapter 03/3.07.py
  class DrumMachine (line 48) | class DrumMachine:
    method __init__ (line 50) | def __init__(self, root):
    method on_open_file_button_clicked (line 62) | def on_open_file_button_clicked(self, drum_index):
    method display_all_drum_file_names (line 72) | def display_all_drum_file_names(self):
    method display_drum_name (line 76) | def display_drum_name(self, text_widget_num, file_path):
    method get_current_pattern_dict (line 89) | def get_current_pattern_dict(self):
    method get_bpu (line 92) | def get_bpu(self):
    method set_bpu (line 95) | def set_bpu(self):
    method get_number_of_units (line 98) | def get_number_of_units(self):
    method set_number_of_units (line 101) | def set_number_of_units(self):
    method get_list_of_drum_files (line 105) | def get_list_of_drum_files(self):
    method get_drum_file_path (line 108) | def get_drum_file_path(self, drum_index):
    method set_drum_file_path (line 111) | def set_drum_file_path(self, drum_index, file_path):
    method get_is_button_clicked_list (line 114) | def get_is_button_clicked_list(self):
    method set_is_button_clicked_list (line 117) | def set_is_button_clicked_list(self, num_of_rows, num_of_columns):
    method init_all_patterns (line 122) | def init_all_patterns(self):
    method on_pattern_changed (line 136) | def on_pattern_changed(self):
    method on_number_of_units_changed (line 139) | def on_number_of_units_changed(self):
    method on_bpu_changed (line 145) | def on_bpu_changed(self):
    method play_in_thread (line 151) | def play_in_thread(self):
    method on_play_button_clicked (line 156) | def on_play_button_clicked(self):
    method start_play (line 160) | def start_play(self):
    method on_stop_button_clicked (line 164) | def on_stop_button_clicked(self):
    method toggle_play_button_state (line 169) | def toggle_play_button_state(self):
    method exit_app (line 175) | def exit_app(self):
    method stop_play (line 180) | def stop_play(self):
    method init_pygame (line 183) | def init_pygame(self):
    method play_sound (line 187) | def play_sound(self, sound_filename):
    method get_column_from_matrix (line 191) | def get_column_from_matrix(self, matrix, i):
    method play_pattern (line 195) | def play_pattern(self):
    method time_to_play_each_column (line 214) | def time_to_play_each_column(self):
    method on_loop_button_toggled (line 220) | def on_loop_button_toggled(self):
    method on_beats_per_minute_changed (line 223) | def on_beats_per_minute_changed(self):
    method init_is_button_clicked_list (line 226) | def init_is_button_clicked_list(self, num_of_rows, num_of_columns):
    method get_button_value (line 229) | def get_button_value(self, row, col):
    method find_number_of_columns (line 233) | def find_number_of_columns(self):
    method process_button_clicked (line 236) | def process_button_clicked(self, row, col):
    method set_button_value (line 240) | def set_button_value(self, row, col, bool_value):
    method on_button_clicked (line 244) | def on_button_clicked(self, row, col):
    method display_all_button_colors (line 249) | def display_all_button_colors(self):
    method display_button_color (line 255) | def display_button_color(self, row, col):
    method create_play_bar (line 262) | def create_play_bar(self):
    method create_right_button_matrix (line 290) | def create_right_button_matrix(self):
    method create_left_drum_loader (line 303) | def create_left_drum_loader(self):
    method create_top_bar (line 317) | def create_top_bar(self):
    method create_top_menu (line 342) | def create_top_menu(self):
    method init_gui (line 355) | def init_gui(self):

FILE: Chapter 03/3.08.py
  class DrumMachine (line 42) | class DrumMachine:
    method __init__ (line 44) | def __init__(self, root):
    method on_open_file_button_clicked (line 56) | def on_open_file_button_clicked(self, drum_index):
    method display_all_drum_file_names (line 66) | def display_all_drum_file_names(self):
    method display_drum_name (line 70) | def display_drum_name(self, text_widget_num, file_path):
    method get_current_pattern_dict (line 83) | def get_current_pattern_dict(self):
    method get_bpu (line 86) | def get_bpu(self):
    method set_bpu (line 89) | def set_bpu(self):
    method get_number_of_units (line 92) | def get_number_of_units(self):
    method set_number_of_units (line 95) | def set_number_of_units(self):
    method get_list_of_drum_files (line 99) | def get_list_of_drum_files(self):
    method get_drum_file_path (line 102) | def get_drum_file_path(self, drum_index):
    method set_drum_file_path (line 105) | def set_drum_file_path(self, drum_index, file_path):
    method get_is_button_clicked_list (line 108) | def get_is_button_clicked_list(self):
    method set_is_button_clicked_list (line 111) | def set_is_button_clicked_list(self, num_of_rows, num_of_columns):
    method init_all_patterns (line 116) | def init_all_patterns(self):
    method display_pattern_name (line 130) | def display_pattern_name(self):
    method on_pattern_changed (line 137) | def on_pattern_changed(self):
    method change_pattern (line 140) | def change_pattern(self):
    method on_number_of_units_changed (line 148) | def on_number_of_units_changed(self):
    method on_bpu_changed (line 154) | def on_bpu_changed(self):
    method play_in_thread (line 160) | def play_in_thread(self):
    method on_play_button_clicked (line 165) | def on_play_button_clicked(self):
    method start_play (line 169) | def start_play(self):
    method on_stop_button_clicked (line 173) | def on_stop_button_clicked(self):
    method toggle_play_button_state (line 178) | def toggle_play_button_state(self):
    method exit_app (line 184) | def exit_app(self):
    method stop_play (line 189) | def stop_play(self):
    method init_pygame (line 192) | def init_pygame(self):
    method play_sound (line 196) | def play_sound(self, sound_filename):
    method get_column_from_matrix (line 200) | def get_column_from_matrix(self, matrix, i):
    method play_pattern (line 204) | def play_pattern(self):
    method time_to_play_each_column (line 223) | def time_to_play_each_column(self):
    method on_loop_button_toggled (line 229) | def on_loop_button_toggled(self):
    method on_beats_per_minute_changed (line 232) | def on_beats_per_minute_changed(self):
    method init_is_button_clicked_list (line 235) | def init_is_button_clicked_list(self, num_of_rows, num_of_columns):
    method get_button_value (line 238) | def get_button_value(self, row, col):
    method find_number_of_columns (line 242) | def find_number_of_columns(self):
    method process_button_clicked (line 245) | def process_button_clicked(self, row, col):
    method set_button_value (line 249) | def set_button_value(self, row, col, bool_value):
    method on_button_clicked (line 253) | def on_button_clicked(self, row, col):
    method display_all_button_colors (line 258) | def display_all_button_colors(self):
    method display_button_color (line 264) | def display_button_color(self, row, col):
    method create_play_bar (line 271) | def create_play_bar(self):
    method create_right_button_matrix (line 299) | def create_right_button_matrix(self):
    method create_left_drum_loader (line 312) | def create_left_drum_loader(self):
    method create_top_bar (line 326) | def create_top_bar(self):
    method create_top_menu (line 352) | def create_top_menu(self):
    method init_gui (line 365) | def init_gui(self):

FILE: Chapter 03/3.09.py
  class DrumMachine (line 46) | class DrumMachine:
    method __init__ (line 48) | def __init__(self, root):
    method on_open_file_button_clicked (line 60) | def on_open_file_button_clicked(self, drum_index):
    method display_all_drum_file_names (line 70) | def display_all_drum_file_names(self):
    method display_drum_name (line 74) | def display_drum_name(self, text_widget_num, file_path):
    method get_current_pattern_dict (line 87) | def get_current_pattern_dict(self):
    method get_bpu (line 90) | def get_bpu(self):
    method set_bpu (line 93) | def set_bpu(self):
    method get_number_of_units (line 96) | def get_number_of_units(self):
    method set_number_of_units (line 99) | def set_number_of_units(self):
    method get_list_of_drum_files (line 103) | def get_list_of_drum_files(self):
    method get_drum_file_path (line 106) | def get_drum_file_path(self, drum_index):
    method set_drum_file_path (line 109) | def set_drum_file_path(self, drum_index, file_path):
    method get_is_button_clicked_list (line 112) | def get_is_button_clicked_list(self):
    method set_is_button_clicked_list (line 115) | def set_is_button_clicked_list(self, num_of_rows, num_of_columns):
    method init_all_patterns (line 120) | def init_all_patterns(self):
    method display_pattern_name (line 134) | def display_pattern_name(self):
    method on_pattern_changed (line 141) | def on_pattern_changed(self):
    method change_pattern (line 144) | def change_pattern(self):
    method on_number_of_units_changed (line 152) | def on_number_of_units_changed(self):
    method on_bpu_changed (line 158) | def on_bpu_changed(self):
    method play_in_thread (line 164) | def play_in_thread(self):
    method on_play_button_clicked (line 169) | def on_play_button_clicked(self):
    method start_play (line 173) | def start_play(self):
    method on_stop_button_clicked (line 177) | def on_stop_button_clicked(self):
    method toggle_play_button_state (line 182) | def toggle_play_button_state(self):
    method exit_app (line 188) | def exit_app(self):
    method stop_play (line 193) | def stop_play(self):
    method init_pygame (line 196) | def init_pygame(self):
    method play_sound (line 200) | def play_sound(self, sound_filename):
    method get_column_from_matrix (line 204) | def get_column_from_matrix(self, matrix, i):
    method play_pattern (line 208) | def play_pattern(self):
    method time_to_play_each_column (line 227) | def time_to_play_each_column(self):
    method on_loop_button_toggled (line 233) | def on_loop_button_toggled(self):
    method on_beats_per_minute_changed (line 236) | def on_beats_per_minute_changed(self):
    method init_is_button_clicked_list (line 239) | def init_is_button_clicked_list(self, num_of_rows, num_of_columns):
    method get_button_value (line 242) | def get_button_value(self, row, col):
    method find_number_of_columns (line 246) | def find_number_of_columns(self):
    method process_button_clicked (line 249) | def process_button_clicked(self, row, col):
    method set_button_value (line 253) | def set_button_value(self, row, col, bool_value):
    method on_button_clicked (line 257) | def on_button_clicked(self, row, col):
    method display_all_button_colors (line 262) | def display_all_button_colors(self):
    method display_button_color (line 268) | def display_button_color(self, row, col):
    method create_play_bar (line 275) | def create_play_bar(self):
    method create_right_button_matrix (line 303) | def create_right_button_matrix(self):
    method create_left_drum_loader (line 316) | def create_left_drum_loader(self):
    method create_top_bar (line 330) | def create_top_bar(self):
    method load_project (line 355) | def load_project(self):
    method save_project (line 374) | def save_project(self):
    method show_about (line 383) | def show_about(self):
    method create_top_menu (line 386) | def create_top_menu(self):
    method init_gui (line 402) | def init_gui(self):

FILE: Chapter 03/3.12.py
  class DrumMachine (line 41) | class DrumMachine:
    method __init__ (line 43) | def __init__(self, root):
    method get_current_pattern_dict (line 56) | def get_current_pattern_dict(self):
    method get_bpu (line 59) | def get_bpu(self):
    method set_bpu (line 62) | def set_bpu(self):
    method get_number_of_units (line 65) | def get_number_of_units(self):
    method set_number_of_units (line 68) | def set_number_of_units(self):
    method get_list_of_drum_files (line 72) | def get_list_of_drum_files(self):
    method get_drum_file_path (line 75) | def get_drum_file_path(self, drum_index):
    method set_drum_file_path (line 78) | def set_drum_file_path(self, drum_index, file_path):
    method get_is_button_clicked_list (line 81) | def get_is_button_clicked_list(self):
    method set_is_button_clicked_list (line 84) | def set_is_button_clicked_list(self, num_of_rows, num_of_columns):
    method set_beats_per_minute (line 89) | def set_beats_per_minute(self):
    method init_all_patterns (line 93) | def init_all_patterns(self):
    method init_is_button_clicked_list (line 107) | def init_is_button_clicked_list(self, num_of_rows, num_of_columns):
    method load_project (line 110) | def load_project(self):
    method save_project (line 129) | def save_project(self):
    method show_about (line 138) | def show_about(self):
    method exit_app (line 142) | def exit_app(self):
    method display_pattern_name (line 147) | def display_pattern_name(self):
    method on_pattern_changed (line 154) | def on_pattern_changed(self):
    method change_pattern (line 157) | def change_pattern(self):
    method on_number_of_units_changed (line 165) | def on_number_of_units_changed(self):
    method on_bpu_changed (line 171) | def on_bpu_changed(self):
    method on_open_file_button_clicked (line 177) | def on_open_file_button_clicked(self, drum_index):
    method display_all_drum_file_names (line 187) | def display_all_drum_file_names(self):
    method display_drum_name (line 191) | def display_drum_name(self, text_widget_num, file_path):
    method play_in_thread (line 198) | def play_in_thread(self):
    method on_play_button_clicked (line 202) | def on_play_button_clicked(self):
    method start_play (line 206) | def start_play(self):
    method on_stop_button_clicked (line 210) | def on_stop_button_clicked(self):
    method stop_play (line 214) | def stop_play(self):
    method init_pygame (line 218) | def init_pygame(self):
    method play_sound (line 222) | def play_sound(self, sound_filename):
    method get_column_from_matrix (line 226) | def get_column_from_matrix(self, matrix, i):
    method toggle_play_button_state (line 229) | def toggle_play_button_state(self):
    method play_pattern (line 235) | def play_pattern(self):
    method time_to_play_each_column (line 254) | def time_to_play_each_column(self):
    method on_loop_button_toggled (line 259) | def on_loop_button_toggled(self):
    method on_beats_per_minute_changed (line 262) | def on_beats_per_minute_changed(self):
    method get_button_value (line 265) | def get_button_value(self, row, col):
    method find_number_of_columns (line 269) | def find_number_of_columns(self):
    method process_button_clicked (line 272) | def process_button_clicked(self, row, col):
    method set_button_value (line 276) | def set_button_value(self, row, col, bool_value):
    method on_button_clicked (line 280) | def on_button_clicked(self, row, col):
    method display_all_button_colors (line 285) | def display_all_button_colors(self):
    method display_button_color (line 291) | def display_button_color(self, row, col):
    method create_play_bar (line 298) | def create_play_bar(self):
    method create_right_button_matrix (line 331) | def create_right_button_matrix(self):
    method create_left_drum_loader (line 344) | def create_left_drum_loader(self):
    method create_top_bar (line 357) | def create_top_bar(self):
    method create_top_menu (line 382) | def create_top_menu(self):
    method init_gui (line 397) | def init_gui(self):

FILE: Chapter 04/4.01/controller.py
  class Controller (line 10) | class Controller():
    method __init__ (line 12) | def __init__(self):
    method init_model (line 15) | def init_model(self):

FILE: Chapter 04/4.01/exceptions.py
  class ChessError (line 5) | class ChessError(Exception): pass

FILE: Chapter 04/4.01/model.py
  class Model (line 9) | class Model():
    method __init__ (line 11) | def __init__(self):

FILE: Chapter 04/4.01/view.py
  class View (line 12) | class View():
    method __init__ (line 17) | def __init__(self, parent, controller):
    method create_chess_base (line 23) | def create_chess_base(self):
    method create_top_menu (line 29) | def create_top_menu(self):
    method create_bottom_frame (line 35) | def create_bottom_frame(self):
    method on_about_menu_clicked (line 42) | def on_about_menu_clicked(self):
    method on_new_game_menu_clicked (line 46) | def on_new_game_menu_clicked(self):
    method on_preference_menu_clicked (line 49) | def on_preference_menu_clicked(self):
    method create_file_menu (line 52) | def create_file_menu(self):
    method create_edit_menu (line 59) | def create_edit_menu(self):
    method create_about_menu (line 66) | def create_about_menu(self):
    method create_canvas (line 73) | def create_canvas(self):
    method draw_board (line 80) | def draw_board(self):
    method get_alternate_color (line 91) | def get_alternate_color(self, current_color):
    method on_square_clicked (line 98) | def on_square_clicked(self, event):
    method get_clicked_row_column (line 102) | def get_clicked_row_column(self, event):
    method get_x_y_coordinate (line 108) | def get_x_y_coordinate(self, row, col):
  function main (line 114) | def main(controller):
  function init_new_game (line 121) | def init_new_game():

FILE: Chapter 04/4.02/controller.py
  class Controller (line 10) | class Controller():
    method __init__ (line 12) | def __init__(self):
    method init_model (line 15) | def init_model(self):

FILE: Chapter 04/4.02/exceptions.py
  class ChessError (line 5) | class ChessError(Exception): pass

FILE: Chapter 04/4.02/model.py
  class Model (line 10) | class Model(dict):
    method __init__ (line 18) | def __init__(self):
    method get_piece_at (line 21) | def get_piece_at(self, position):
    method get_alphanumeric_position (line 24) | def get_alphanumeric_position(self, rowcol):
    method is_on_board (line 29) | def is_on_board(self, rowcol):

FILE: Chapter 04/4.02/piece.py
  function create_piece (line 9) | def create_piece (piece, color='white'):
  class Piece (line 19) | class Piece():
    method __init__ (line 21) | def __init__(self, color):
    method keep_reference (line 29) | def keep_reference(self, model):
  class King (line 32) | class King(Piece):
  class Queen (line 35) | class Queen(Piece):
  class Rook (line 38) | class Rook(Piece):
  class Bishop (line 41) | class Bishop(Piece):
  class Knight (line 44) | class Knight(Piece):
  class Pawn (line 47) | class Pawn(Piece):

FILE: Chapter 04/4.02/view.py
  class View (line 12) | class View():
    method __init__ (line 17) | def __init__(self, parent, controller):
    method create_chess_base (line 23) | def create_chess_base(self):
    method create_top_menu (line 29) | def create_top_menu(self):
    method create_bottom_frame (line 35) | def create_bottom_frame(self):
    method on_about_menu_clicked (line 42) | def on_about_menu_clicked(self):
    method on_new_game_menu_clicked (line 46) | def on_new_game_menu_clicked(self):
    method on_preference_menu_clicked (line 49) | def on_preference_menu_clicked(self):
    method create_file_menu (line 52) | def create_file_menu(self):
    method create_edit_menu (line 59) | def create_edit_menu(self):
    method create_about_menu (line 66) | def create_about_menu(self):
    method create_canvas (line 73) | def create_canvas(self):
    method draw_board (line 80) | def draw_board(self):
    method on_square_clicked (line 91) | def on_square_clicked(self, event):
    method get_clicked_row_column (line 95) | def get_clicked_row_column(self, event):
    method get_x_y_coordinate (line 101) | def get_x_y_coordinate(self, row, col):
    method get_alternate_color (line 106) | def get_alternate_color(self, current_color):
  function main (line 114) | def main(controller):
  function init_new_game (line 121) | def init_new_game():

FILE: Chapter 04/4.03/controller.py
  class Controller (line 16) | class Controller():
    method __init__ (line 18) | def __init__(self):
    method init_model (line 21) | def init_model(self):
    method get_all_peices_on_chess_board (line 24) | def get_all_peices_on_chess_board(self):
    method reset_game_data (line 27) | def reset_game_data(self):
    method reset_to_initial_locations (line 30) | def reset_to_initial_locations(self):
    method get_numeric_notation (line 33) | def get_numeric_notation(self, position):

FILE: Chapter 04/4.03/exceptions.py
  class ChessError (line 5) | class ChessError(Exception): pass

FILE: Chapter 04/4.03/model.py
  class Model (line 18) | class Model(dict):
    method __init__ (line 26) | def __init__(self):
    method reset_game_data (line 29) | def reset_game_data(self):
    method reset_to_initial_locations (line 36) | def reset_to_initial_locations(self):
    method get_piece_at (line 43) | def get_piece_at(self, position):
    method get_alphanumeric_position (line 46) | def get_alphanumeric_position(self, rowcol):
    method is_on_board (line 51) | def is_on_board(self, rowcol):

FILE: Chapter 04/4.03/piece.py
  function create_piece (line 19) | def create_piece (piece, color='white'):
  function get_numeric_notation (line 29) | def get_numeric_notation(rowcol):
  class Piece (line 34) | class Piece():
    method __init__ (line 36) | def __init__(self, color):
    method keep_reference (line 44) | def keep_reference(self, model):
  class King (line 47) | class King(Piece):
  class Queen (line 50) | class Queen(Piece):
  class Rook (line 53) | class Rook(Piece):
  class Bishop (line 56) | class Bishop(Piece):
  class Knight (line 59) | class Knight(Piece):
  class Pawn (line 62) | class Pawn(Piece):

FILE: Chapter 04/4.03/view.py
  class View (line 22) | class View():
    method __init__ (line 28) | def __init__(self, parent, controller):
    method create_chess_base (line 35) | def create_chess_base(self):
    method create_top_menu (line 41) | def create_top_menu(self):
    method create_bottom_frame (line 47) | def create_bottom_frame(self):
    method on_about_menu_clicked (line 54) | def on_about_menu_clicked(self):
    method on_new_game_menu_clicked (line 58) | def on_new_game_menu_clicked(self):
    method on_preference_menu_clicked (line 61) | def on_preference_menu_clicked(self):
    method create_file_menu (line 64) | def create_file_menu(self):
    method create_edit_menu (line 71) | def create_edit_menu(self):
    method create_about_menu (line 78) | def create_about_menu(self):
    method create_canvas (line 85) | def create_canvas(self):
    method draw_board (line 92) | def draw_board(self):
    method on_square_clicked (line 103) | def on_square_clicked(self, event):
    method get_clicked_row_column (line 107) | def get_clicked_row_column(self, event):
    method get_x_y_coordinate (line 113) | def get_x_y_coordinate(self, row, col):
    method calculate_piece_coordinate (line 118) | def calculate_piece_coordinate(self, row, col):
    method draw_single_piece (line 125) | def draw_single_piece(self, position, piece):
    method draw_all_pieces (line 136) | def draw_all_pieces(self):
    method start_new_game (line 141) | def start_new_game(self):
    method get_alternate_color (line 147) | def get_alternate_color(self, current_color):
  function main (line 155) | def main(controller):
  function init_new_game (line 162) | def init_new_game():

FILE: Chapter 04/4.04/controller.py
  class Controller (line 11) | class Controller():
    method __init__ (line 13) | def __init__(self):
    method init_model (line 16) | def init_model(self):
    method get_all_peices_on_chess_board (line 19) | def get_all_peices_on_chess_board(self):
    method reset_game_data (line 22) | def reset_game_data(self):
    method reset_to_initial_locations (line 25) | def reset_to_initial_locations(self):
    method get_numeric_notation (line 28) | def get_numeric_notation(self, position):

FILE: Chapter 04/4.04/exceptions.py
  class ChessError (line 5) | class ChessError(Exception): pass

FILE: Chapter 04/4.04/model.py
  class Model (line 14) | class Model(dict):
    method __init__ (line 22) | def __init__(self):
    method all_positions_occupied_by_color (line 25) | def all_positions_occupied_by_color(self, color):
    method all_occupied_positions (line 33) | def all_occupied_positions(self):
    method reset_game_data (line 36) | def reset_game_data(self):
    method reset_to_initial_locations (line 43) | def reset_to_initial_locations(self):
    method get_piece_at (line 50) | def get_piece_at(self, position):
    method get_alphanumeric_position (line 53) | def get_alphanumeric_position(self, rowcol):
    method is_on_board (line 58) | def is_on_board(self, rowcol):

FILE: Chapter 04/4.04/piece.py
  function create_piece (line 17) | def create_piece(piece, color='white'):
  function get_numeric_notation (line 28) | def get_numeric_notation(rowcol):
  class Piece (line 33) | class Piece():
    method __init__ (line 35) | def __init__(self, color):
    method keep_reference (line 43) | def keep_reference(self, model):
    method moves_available (line 46) | def moves_available(self, current_position, directions, distance):
    method possible_position (line 67) | def possible_position(self, destination):
  class King (line 71) | class King(Piece):
    method moves_available (line 75) | def moves_available(self, current_position):
  class Queen (line 79) | class Queen(Piece):
    method moves_available (line 83) | def moves_available(self, current_position):
  class Rook (line 87) | class Rook(Piece):
    method moves_available (line 91) | def moves_available(self, current_position):
  class Bishop (line 95) | class Bishop(Piece):
    method moves_available (line 99) | def moves_available(self, current_position):
  class Knight (line 103) | class Knight(Piece):
    method moves_available (line 105) | def moves_available(self, current_position):
  class Pawn (line 118) | class Pawn(Piece):
    method moves_available (line 120) | def moves_available(self, current_position):

FILE: Chapter 04/4.04/view.py
  class View (line 22) | class View():
    method __init__ (line 28) | def __init__(self, parent, controller):
    method create_chess_base (line 35) | def create_chess_base(self):
    method create_top_menu (line 41) | def create_top_menu(self):
    method create_bottom_frame (line 47) | def create_bottom_frame(self):
    method on_about_menu_clicked (line 54) | def on_about_menu_clicked(self):
    method on_new_game_menu_clicked (line 58) | def on_new_game_menu_clicked(self):
    method on_preference_menu_clicked (line 61) | def on_preference_menu_clicked(self):
    method create_file_menu (line 64) | def create_file_menu(self):
    method create_edit_menu (line 71) | def create_edit_menu(self):
    method create_about_menu (line 78) | def create_about_menu(self):
    method create_canvas (line 85) | def create_canvas(self):
    method draw_board (line 92) | def draw_board(self):
    method on_square_clicked (line 103) | def on_square_clicked(self, event):
    method get_clicked_row_column (line 107) | def get_clicked_row_column(self, event):
    method get_x_y_coordinate (line 113) | def get_x_y_coordinate(self, row, col):
    method calculate_piece_coordinate (line 118) | def calculate_piece_coordinate(self, row, col):
    method draw_single_piece (line 125) | def draw_single_piece(self, position, piece):
    method draw_all_pieces (line 136) | def draw_all_pieces(self):
    method start_new_game (line 141) | def start_new_game(self):
    method get_alternate_color (line 147) | def get_alternate_color(self, current_color):
  function main (line 155) | def main(controller):
  function init_new_game (line 162) | def init_new_game():

FILE: Chapter 04/4.05/controller.py
  class Controller (line 11) | class Controller():
    method __init__ (line 13) | def __init__(self):
    method init_model (line 16) | def init_model(self):
    method get_all_peices_on_chess_board (line 19) | def get_all_peices_on_chess_board(self):
    method reset_game_data (line 22) | def reset_game_data(self):
    method reset_to_initial_locations (line 25) | def reset_to_initial_locations(self):
    method get_numeric_notation (line 28) | def get_numeric_notation(self, position):

FILE: Chapter 04/4.05/exceptions.py
  class ChessError (line 5) | class ChessError(Exception): pass

FILE: Chapter 04/4.05/model.py
  class Model (line 14) | class Model(dict):
    method __init__ (line 22) | def __init__(self):
    method get_all_available_moves (line 25) | def get_all_available_moves(self, color):
    method all_positions_occupied_by_color (line 35) | def all_positions_occupied_by_color(self, color):
    method all_occupied_positions (line 43) | def all_occupied_positions(self):
    method reset_game_data (line 46) | def reset_game_data(self):
    method reset_to_initial_locations (line 53) | def reset_to_initial_locations(self):
    method get_piece_at (line 60) | def get_piece_at(self, position):
    method get_alphanumeric_position (line 63) | def get_alphanumeric_position(self, rowcol):
    method is_on_board (line 68) | def is_on_board(self, rowcol):
    method get_alphanumeric_position_of_king (line 72) | def get_alphanumeric_position_of_king(self, color):
    method is_king_under_check (line 78) | def is_king_under_check(self, color):

FILE: Chapter 04/4.05/piece.py
  function create_piece (line 11) | def create_piece(piece, color='white'):
  function get_numeric_notation (line 22) | def get_numeric_notation(rowcol):
  class Piece (line 27) | class Piece():
    method __init__ (line 29) | def __init__(self, color):
    method keep_reference (line 37) | def keep_reference(self, model):
    method moves_available (line 40) | def moves_available(self, current_position, directions, distance):
    method possible_position (line 61) | def possible_position(self, destination):
  class King (line 65) | class King(Piece):
    method moves_available (line 69) | def moves_available(self, current_position):
  class Queen (line 73) | class Queen(Piece):
    method moves_available (line 77) | def moves_available(self, current_position):
  class Rook (line 81) | class Rook(Piece):
    method moves_available (line 85) | def moves_available(self, current_position):
  class Bishop (line 89) | class Bishop(Piece):
    method moves_available (line 93) | def moves_available(self, current_position):
  class Knight (line 97) | class Knight(Piece):
    method moves_available (line 99) | def moves_available(self, current_position):
  class Pawn (line 112) | class Pawn(Piece):
    method moves_available (line 114) | def moves_available(self, current_position):

FILE: Chapter 04/4.05/view.py
  class View (line 12) | class View():
    method __init__ (line 18) | def __init__(self, parent, controller):
    method create_chess_base (line 25) | def create_chess_base(self):
    method create_top_menu (line 31) | def create_top_menu(self):
    method create_bottom_frame (line 37) | def create_bottom_frame(self):
    method on_about_menu_clicked (line 44) | def on_about_menu_clicked(self):
    method on_new_game_menu_clicked (line 48) | def on_new_game_menu_clicked(self):
    method on_preference_menu_clicked (line 51) | def on_preference_menu_clicked(self):
    method create_file_menu (line 54) | def create_file_menu(self):
    method create_edit_menu (line 61) | def create_edit_menu(self):
    method create_about_menu (line 68) | def create_about_menu(self):
    method create_canvas (line 75) | def create_canvas(self):
    method draw_board (line 82) | def draw_board(self):
    method on_square_clicked (line 93) | def on_square_clicked(self, event):
    method get_clicked_row_column (line 97) | def get_clicked_row_column(self, event):
    method get_x_y_coordinate (line 103) | def get_x_y_coordinate(self, row, col):
    method calculate_piece_coordinate (line 108) | def calculate_piece_coordinate(self, row, col):
    method draw_single_piece (line 115) | def draw_single_piece(self, position, piece):
    method draw_all_pieces (line 126) | def draw_all_pieces(self):
    method start_new_game (line 131) | def start_new_game(self):
    method get_alternate_color (line 137) | def get_alternate_color(self, current_color):
  function main (line 145) | def main(controller):
  function init_new_game (line 152) | def init_new_game():

FILE: Chapter 04/4.06/controller.py
  class Controller (line 16) | class Controller():
    method __init__ (line 18) | def __init__(self):
    method init_model (line 21) | def init_model(self):
    method reset_game_data (line 24) | def reset_game_data(self):
    method reset_to_initial_locations (line 27) | def reset_to_initial_locations(self):
    method get_alphanumeric_position (line 30) | def get_alphanumeric_position(self, rowcolumntuple):
    method get_numeric_notation (line 33) | def get_numeric_notation(self, rowcol):
    method get_piece_at (line 36) | def get_piece_at(self, position_of_click):
    method pre_move_validation (line 39) | def pre_move_validation(self, start_pos, end_pos):
    method get_all_peices_on_chess_board (line 42) | def get_all_peices_on_chess_board(self):
    method player_turn (line 45) | def player_turn(self):
    method moves_available (line 48) | def moves_available(self, position):

FILE: Chapter 04/4.06/exceptions.py
  class ChessError (line 13) | class ChessError(Exception): pass
  class Check (line 14) | class Check(ChessError): pass
  class InvalidMove (line 15) | class InvalidMove(ChessError): pass
  class CheckMate (line 16) | class CheckMate(ChessError): pass
  class Draw (line 17) | class Draw(ChessError): pass
  class NotYourTurn (line 18) | class NotYourTurn(ChessError): pass
  class InvalidCoord (line 19) | class InvalidCoord(ChessError): pass

FILE: Chapter 04/4.06/model.py
  class Model (line 24) | class Model(dict):
    method __init__ (line 32) | def __init__(self):
    method update_game_statistics (line 35) | def update_game_statistics(self, piece, dest, start_pos, end_pos):
    method change_player_turn (line 50) | def change_player_turn(self, color):
    method pre_move_validation (line 54) | def pre_move_validation(self, initial_pos, final_pos):
    method move (line 80) | def move(self, start_pos, final_pos):
    method will_move_cause_check (line 83) | def will_move_cause_check(self, start_position, end_position):
    method get_all_available_moves (line 88) | def get_all_available_moves(self, color):
    method is_king_under_check (line 98) | def is_king_under_check(self, color):
    method get_alphanumeric_position_of_king (line 103) | def get_alphanumeric_position_of_king(self, color):
    method all_positions_occupied_by_color (line 109) | def all_positions_occupied_by_color(self, color):
    method all_occupied_positions (line 117) | def all_occupied_positions(self):
    method reset_game_data (line 120) | def reset_game_data(self):
    method reset_to_initial_locations (line 127) | def reset_to_initial_locations(self):
    method get_piece_at (line 134) | def get_piece_at(self, position):
    method get_alphanumeric_position (line 137) | def get_alphanumeric_position(self, rowcol):
    method is_on_board (line 142) | def is_on_board(self, rowcol):

FILE: Chapter 04/4.06/piece.py
  function create_piece (line 11) | def create_piece(piece, color='white'):
  function get_numeric_notation (line 22) | def get_numeric_notation(rowcol):
  class Piece (line 27) | class Piece():
    method __init__ (line 29) | def __init__(self, color):
    method keep_reference (line 37) | def keep_reference(self, model):
    method moves_available (line 40) | def moves_available(self, current_position, directions, distance):
    method possible_position (line 61) | def possible_position(self, destination):
  class King (line 65) | class King(Piece):
    method moves_available (line 69) | def moves_available(self, current_position):
  class Queen (line 73) | class Queen(Piece):
    method moves_available (line 77) | def moves_available(self, current_position):
  class Rook (line 81) | class Rook(Piece):
    method moves_available (line 85) | def moves_available(self, current_position):
  class Bishop (line 89) | class Bishop(Piece):
    method moves_available (line 93) | def moves_available(self, current_position):
  class Knight (line 97) | class Knight(Piece):
    method moves_available (line 99) | def moves_available(self, current_position):
  class Pawn (line 112) | class Pawn(Piece):
    method moves_available (line 114) | def moves_available(self, current_position):

FILE: Chapter 04/4.06/view.py
  class View (line 26) | class View():
    method __init__ (line 35) | def __init__(self, parent, controller):
    method create_bottom_frame (line 42) | def create_bottom_frame(self):
    method create_top_menu (line 49) | def create_top_menu(self):
    method create_file_menu (line 55) | def create_file_menu(self):
    method create_edit_menu (line 62) | def create_edit_menu(self):
    method create_about_menu (line 69) | def create_about_menu(self):
    method on_preference_menu_clicked (line 76) | def on_preference_menu_clicked(self):
    method show_prefereces_window (line 79) | def show_prefereces_window(self):
    method create_canvas (line 82) | def create_canvas(self):
    method create_chess_base (line 89) | def create_chess_base(self):
    method start_new_game (line 95) | def start_new_game(self):
    method reset_board_state (line 101) | def reset_board_state(self):
    method on_new_game_menu_clicked (line 106) | def on_new_game_menu_clicked(self):
    method get_clicked_row_column (line 109) | def get_clicked_row_column(self, event):
    method on_square_clicked (line 115) | def on_square_clicked(self, event):
    method shift (line 127) | def shift(self, start_pos, end_pos):
    method update_label (line 138) | def update_label(self, piece, start_pos, end_pos):
    method update_highlight_list (line 143) | def update_highlight_list(self, position):
    method get_x_y_coordinate (line 155) | def get_x_y_coordinate(self, row, col):
    method draw_board (line 160) | def draw_board(self):
    method calculate_piece_coordinate (line 175) | def calculate_piece_coordinate(self, row, col):
    method draw_single_piece (line 182) | def draw_single_piece(self, position, piece):
    method draw_all_pieces (line 193) | def draw_all_pieces(self):
    method on_about_menu_clicked (line 198) | def on_about_menu_clicked(self):
    method get_alternate_color (line 202) | def get_alternate_color(self, current_color):
  function main (line 210) | def main(model):
  function init_new_game (line 217) | def init_new_game():

FILE: Chapter 04/4.07/controller.py
  class Controller (line 10) | class Controller():
    method __init__ (line 12) | def __init__(self):
    method init_model (line 15) | def init_model(self):
    method reset_game_data (line 18) | def reset_game_data(self):
    method reset_to_initial_locations (line 21) | def reset_to_initial_locations(self):
    method get_alphanumeric_position (line 24) | def get_alphanumeric_position(self, rowcolumntuple):
    method get_numeric_notation (line 27) | def get_numeric_notation(self, rowcol):
    method get_piece_at (line 30) | def get_piece_at(self, position_of_click):
    method pre_move_validation (line 33) | def pre_move_validation(self, start_pos, end_pos):
    method get_all_peices_on_chess_board (line 36) | def get_all_peices_on_chess_board(self):
    method player_turn (line 39) | def player_turn(self):
    method moves_available (line 42) | def moves_available(self, position):

FILE: Chapter 04/4.07/exceptions.py
  class ChessError (line 6) | class ChessError(Exception): pass
  class Check (line 7) | class Check(ChessError): pass
  class InvalidMove (line 8) | class InvalidMove(ChessError): pass
  class CheckMate (line 9) | class CheckMate(ChessError): pass
  class Draw (line 10) | class Draw(ChessError): pass
  class NotYourTurn (line 11) | class NotYourTurn(ChessError): pass
  class InvalidCoord (line 12) | class InvalidCoord(ChessError): pass

FILE: Chapter 04/4.07/model.py
  class Model (line 12) | class Model(dict):
    method __init__ (line 20) | def __init__(self):
    method update_game_statistics (line 23) | def update_game_statistics(self, piece, dest, p1, p2):
    method change_player_turn (line 38) | def change_player_turn(self, color):
    method pre_move_validation (line 42) | def pre_move_validation(self, initial_pos, final_pos):
    method move (line 68) | def move(self, start_pos, final_pos):
    method will_move_cause_check (line 71) | def will_move_cause_check(self, start_position, end_position):
    method get_all_available_moves (line 76) | def get_all_available_moves(self, color):
    method is_king_under_check (line 86) | def is_king_under_check(self, color):
    method get_alphanumeric_position_of_king (line 91) | def get_alphanumeric_position_of_king(self, color):
    method all_positions_occupied_by_color (line 97) | def all_positions_occupied_by_color(self, color):
    method all_occupied_positions (line 105) | def all_occupied_positions(self):
    method reset_game_data (line 108) | def reset_game_data(self):
    method reset_to_initial_locations (line 115) | def reset_to_initial_locations(self):
    method get_piece_at (line 122) | def get_piece_at(self, position):
    method get_alphanumeric_position (line 125) | def get_alphanumeric_position(self, rowcol):
    method is_on_board (line 130) | def is_on_board(self, rowcol):

FILE: Chapter 04/4.07/piece.py
  function create_piece (line 12) | def create_piece(piece, color='white'):
  function get_numeric_notation (line 23) | def get_numeric_notation(rowcol):
  class Piece (line 28) | class Piece():
    method __init__ (line 30) | def __init__(self, color):
    method keep_reference (line 38) | def keep_reference(self, model):
    method moves_available (line 41) | def moves_available(self, current_position, directions, distance):
    method possible_position (line 62) | def possible_position(self, destination):
  class King (line 66) | class King(Piece):
    method moves_available (line 71) | def moves_available(self, current_position):
  class Queen (line 75) | class Queen(Piece):
    method moves_available (line 80) | def moves_available(self, current_position):
  class Rook (line 84) | class Rook(Piece):
    method moves_available (line 89) | def moves_available(self, current_position):
  class Bishop (line 93) | class Bishop(Piece):
    method moves_available (line 98) | def moves_available(self, current_position):
  class Knight (line 102) | class Knight(Piece):
    method moves_available (line 104) | def moves_available(self, current_position):
  class Pawn (line 117) | class Pawn(Piece):
    method moves_available (line 119) | def moves_available(self, current_position):

FILE: Chapter 04/4.07/preferenceswindow.py
  class PreferencesWindow (line 19) | class PreferencesWindow():
    method __init__ (line 21) | def __init__(self, view):
    method fill_preference_colors (line 27) | def fill_preference_colors(self):
    method set_color_1 (line 32) | def set_color_1(self):
    method set_color_2 (line 35) | def set_color_2(self):
    method set_highlight_color (line 38) | def set_highlight_color(self):
    method create_prefereces_window (line 41) | def create_prefereces_window(self):
    method create_prefereces_list (line 47) | def create_prefereces_list(self):
    method on_save_button_clicked (line 71) | def on_save_button_clicked(self):
    method set_new_values (line 77) | def set_new_values(self):
    method on_cancel_button_clicked (line 89) | def on_cancel_button_clicked(self):

FILE: Chapter 04/4.07/view.py
  class View (line 32) | class View():
    method __init__ (line 41) | def __init__(self, parent, controller):
    method reload_colors (line 48) | def reload_colors(self, color_1, color_2, highlight_color):
    method on_preference_menu_clicked (line 55) | def on_preference_menu_clicked(self):
    method show_preferences_window (line 58) | def show_preferences_window(self):
    method create_bottom_frame (line 61) | def create_bottom_frame(self):
    method create_top_menu (line 68) | def create_top_menu(self):
    method create_file_menu (line 74) | def create_file_menu(self):
    method create_edit_menu (line 81) | def create_edit_menu(self):
    method create_about_menu (line 88) | def create_about_menu(self):
    method create_canvas (line 95) | def create_canvas(self):
    method create_chess_base (line 102) | def create_chess_base(self):
    method start_new_game (line 108) | def start_new_game(self):
    method reset_board_state (line 114) | def reset_board_state(self):
    method on_new_game_menu_clicked (line 119) | def on_new_game_menu_clicked(self):
    method get_clicked_row_column (line 122) | def get_clicked_row_column(self, event):
    method on_square_clicked (line 128) | def on_square_clicked(self, event):
    method shift (line 140) | def shift(self, start_pos, end_pos):
    method update_label (line 151) | def update_label(self, piece, start_pos, end_pos):
    method update_highlight_list (line 156) | def update_highlight_list(self, position):
    method get_x_y_coordinate (line 168) | def get_x_y_coordinate(self, row, col):
    method draw_board (line 173) | def draw_board(self):
    method get_alternate_color (line 188) | def get_alternate_color(self, current_color):
    method calculate_piece_coordinate (line 195) | def calculate_piece_coordinate(self, row, col):
    method draw_single_piece (line 202) | def draw_single_piece(self, position, piece):
    method draw_all_pieces (line 213) | def draw_all_pieces(self):
    method on_about_menu_clicked (line 218) | def on_about_menu_clicked(self):
  function main (line 223) | def main(model):
  function init_new_game (line 230) | def init_new_game():

FILE: Chapter 05/5.01/model.py
  class Model (line 7) | class Model:
    method __init__ (line 9) | def __init__(self):

FILE: Chapter 05/5.01/player.py
  class Player (line 9) | class Player:
    method __init__ (line 11) | def __init__(self):

FILE: Chapter 05/5.01/view.py
  class View (line 18) | class View:
    method __init__ (line 22) | def __init__(self, root, model, player):
    method create_gui (line 28) | def create_gui(self):
    method create_top_display (line 36) | def create_top_display(self):
    method create_button_frame (line 52) | def create_button_frame(self):
    method create_list_box (line 105) | def create_list_box(self):
    method create_bottom_frame (line 119) | def create_bottom_frame(self):
    method create_context_menu (line 156) | def create_context_menu(self):
    method show_context_menu (line 161) | def show_context_menu(self, event):
    method on_previous_track_button_clicked (line 164) | def on_previous_track_button_clicked(self):
    method on_rewind_button_clicked (line 167) | def on_rewind_button_clicked(self):
    method on_play_stop_button_clicked (line 170) | def on_play_stop_button_clicked(self):
    method on_pause_unpause_button_clicked (line 173) | def on_pause_unpause_button_clicked(self):
    method on_mute_unmute_button_clicked (line 176) | def on_mute_unmute_button_clicked(self):
    method on_fast_forward_button_clicked (line 179) | def on_fast_forward_button_clicked(self):
    method on_next_track_button_clicked (line 182) | def on_next_track_button_clicked(self):
    method on_volume_scale_changed (line 185) | def on_volume_scale_changed(self, value):
    method on_add_file_button_clicked (line 188) | def on_add_file_button_clicked(self):
    method on_remove_selected_button_clicked (line 191) | def on_remove_selected_button_clicked(self):
    method on_add_directory_button_clicked (line 194) | def on_add_directory_button_clicked(self):
    method on_clear_play_list_button_clicked (line 197) | def on_clear_play_list_button_clicked(self):
    method on_remove_selected_context_menu_clicked (line 200) | def on_remove_selected_context_menu_clicked(self):
    method on_play_list_double_clicked (line 203) | def on_play_list_double_clicked(self, event=None):

FILE: Chapter 05/5.02/model.py
  class Model (line 8) | class Model:
    method __init__ (line 10) | def __init__(self):
    method play_list (line 14) | def play_list(self):
    method get_file_to_play (line 17) | def get_file_to_play(self, file_index):
    method clear_play_list (line 20) | def clear_play_list(self):
    method add_to_play_list (line 23) | def add_to_play_list(self, file_name):
    method remove_item_from_play_list_at_index (line 26) | def remove_item_from_play_list_at_index(self, index):

FILE: Chapter 05/5.02/player.py
  class Player (line 12) | class Player:
    method __init__ (line 14) | def __init__(self):
    method play_media (line 18) | def play_media(self, audio_file):
    method reset_player (line 25) | def reset_player(self):
    method is_playing (line 29) | def is_playing(self):
    method seek (line 37) | def seek(self, time):
    method track_length (line 44) | def track_length(self):
    method volume (line 51) | def volume(self):
    method elapsed_play_duration (line 55) | def elapsed_play_duration(self):
    method volume (line 59) | def volume(self, volume):
    method unpause (line 62) | def unpause(self):
    method pause (line 65) | def pause(self):
    method stop (line 68) | def stop(self):
    method mute (line 71) | def mute(self):
    method unmute (line 74) | def unmute(self, newvolume_level):
    method fast_forward (line 77) | def fast_forward(self):
    method rewind (line 87) | def rewind(self):

FILE: Chapter 05/5.02/view.py
  class View (line 18) | class View:
    method __init__ (line 22) | def __init__(self, root, model, player):
    method create_gui (line 28) | def create_gui(self):
    method create_top_display (line 36) | def create_top_display(self):
    method create_button_frame (line 52) | def create_button_frame(self):
    method create_list_box (line 105) | def create_list_box(self):
    method create_bottom_frame (line 119) | def create_bottom_frame(self):
    method create_context_menu (line 156) | def create_context_menu(self):
    method show_context_menu (line 161) | def show_context_menu(self, event):
    method on_previous_track_button_clicked (line 164) | def on_previous_track_button_clicked(self):
    method on_rewind_button_clicked (line 167) | def on_rewind_button_clicked(self):
    method on_play_stop_button_clicked (line 170) | def on_play_stop_button_clicked(self):
    method on_pause_unpause_button_clicked (line 173) | def on_pause_unpause_button_clicked(self):
    method on_mute_unmute_button_clicked (line 176) | def on_mute_unmute_button_clicked(self):
    method on_fast_forward_button_clicked (line 179) | def on_fast_forward_button_clicked(self):
    method on_next_track_button_clicked (line 182) | def on_next_track_button_clicked(self):
    method on_volume_scale_changed (line 185) | def on_volume_scale_changed(self, value):
    method on_add_file_button_clicked (line 188) | def on_add_file_button_clicked(self):
    method on_remove_selected_button_clicked (line 191) | def on_remove_selected_button_clicked(self):
    method on_add_directory_button_clicked (line 194) | def on_add_directory_button_clicked(self):
    method on_clear_play_list_button_clicked (line 197) | def on_clear_play_list_button_clicked(self):
    method on_remove_selected_context_menu_clicked (line 200) | def on_remove_selected_context_menu_clicked(self):
    method on_play_list_double_clicked (line 203) | def on_play_list_double_clicked(self, event=None):

FILE: Chapter 05/5.03/model.py
  class Model (line 8) | class Model:
    method __init__ (line 10) | def __init__(self):
    method play_list (line 14) | def play_list(self):
    method get_file_to_play (line 17) | def get_file_to_play(self, file_index):
    method clear_play_list (line 20) | def clear_play_list(self):
    method add_to_play_list (line 23) | def add_to_play_list(self, file_name):
    method remove_item_from_play_list_at_index (line 26) | def remove_item_from_play_list_at_index(self, index):

FILE: Chapter 05/5.03/player.py
  class Player (line 12) | class Player:
    method __init__ (line 14) | def __init__(self):
    method play_media (line 18) | def play_media(self, audio_file):
    method reset_player (line 25) | def reset_player(self):
    method is_playing (line 29) | def is_playing(self):
    method seek (line 37) | def seek(self, time):
    method track_length (line 44) | def track_length(self):
    method volume (line 51) | def volume(self):
    method elapsed_play_duration (line 55) | def elapsed_play_duration(self):
    method volume (line 59) | def volume(self, volume):
    method unpause (line 62) | def unpause(self):
    method pause (line 65) | def pause(self):
    method stop (line 68) | def stop(self):
    method mute (line 71) | def mute(self):
    method unmute (line 74) | def unmute(self, newvolume_level):
    method fast_forward (line 77) | def fast_forward(self):
    method rewind (line 87) | def rewind(self):

FILE: Chapter 05/5.03/view.py
  class View (line 34) | class View:
    method __init__ (line 38) | def __init__(self, root, model, player):
    method create_gui (line 44) | def create_gui(self):
    method create_top_display (line 52) | def create_top_display(self):
    method create_button_frame (line 68) | def create_button_frame(self):
    method create_list_box (line 121) | def create_list_box(self):
    method create_bottom_frame (line 135) | def create_bottom_frame(self):
    method create_context_menu (line 172) | def create_context_menu(self):
    method show_context_menu (line 177) | def show_context_menu(self, event):
    method on_add_file_button_clicked (line 180) | def on_add_file_button_clicked(self):
    method on_remove_selected_button_clicked (line 183) | def on_remove_selected_button_clicked(self):
    method on_add_directory_button_clicked (line 186) | def on_add_directory_button_clicked(self):
    method on_clear_play_list_button_clicked (line 189) | def on_clear_play_list_button_clicked(self):
    method on_remove_selected_context_menu_clicked (line 192) | def on_remove_selected_context_menu_clicked(self):
    method on_previous_track_button_clicked (line 195) | def on_previous_track_button_clicked(self):
    method on_rewind_button_clicked (line 198) | def on_rewind_button_clicked(self):
    method on_play_stop_button_clicked (line 201) | def on_play_stop_button_clicked(self):
    method on_pause_unpause_button_clicked (line 204) | def on_pause_unpause_button_clicked(self):
    method on_mute_unmute_button_clicked (line 207) | def on_mute_unmute_button_clicked(self):
    method on_fast_forward_button_clicked (line 210) | def on_fast_forward_button_clicked(self):
    method on_next_track_button_clicked (line 213) | def on_next_track_button_clicked(self):
    method on_volume_scale_changed (line 216) | def on_volume_scale_changed(self, value):
    method on_play_list_double_clicked (line 219) | def on_play_list_double_clicked(self, event=None):
    method add_audio_file (line 222) | def add_audio_file(self):
    method remove_selected_files (line 230) | def remove_selected_files(self):
    method add_all_audio_files_from_directory (line 239) | def add_all_audio_files_from_directory(self):
    method get_all_audio_file_from_directory (line 250) | def get_all_audio_file_from_directory(self, directory_path):
    method clear_play_list (line 258) | def clear_play_list(self):

FILE: Chapter 05/5.04/model.py
  class Model (line 8) | class Model:
    method __init__ (line 10) | def __init__(self):
    method play_list (line 14) | def play_list(self):
    method get_file_to_play (line 17) | def get_file_to_play(self, file_index):
    method clear_play_list (line 20) | def clear_play_list(self):
    method add_to_play_list (line 23) | def add_to_play_list(self, file_name):
    method remove_item_from_play_list_at_index (line 26) | def remove_item_from_play_list_at_index(self, index):

FILE: Chapter 05/5.04/player.py
  class Player (line 12) | class Player:
    method __init__ (line 14) | def __init__(self):
    method play_media (line 18) | def play_media(self, audio_file):
    method reset_player (line 25) | def reset_player(self):
    method is_playing (line 29) | def is_playing(self):
    method seek (line 37) | def seek(self, time):
    method track_length (line 44) | def track_length(self):
    method volume (line 51) | def volume(self):
    method elapsed_play_duration (line 55) | def elapsed_play_duration(self):
    method volume (line 59) | def volume(self, volume):
    method unpause (line 62) | def unpause(self):
    method pause (line 65) | def pause(self):
    method stop (line 68) | def stop(self):
    method mute (line 71) | def mute(self):
    method unmute (line 74) | def unmute(self, newvolume_level):
    method fast_forward (line 77) | def fast_forward(self):
    method rewind (line 87) | def rewind(self):

FILE: Chapter 05/5.04/view.py
  class View (line 44) | class View:
    method __init__ (line 52) | def __init__(self, root, model, player):
    method create_gui (line 58) | def create_gui(self):
    method create_top_display (line 66) | def create_top_display(self):
    method create_button_frame (line 82) | def create_button_frame(self):
    method create_list_box (line 135) | def create_list_box(self):
    method create_bottom_frame (line 149) | def create_bottom_frame(self):
    method create_context_menu (line 186) | def create_context_menu(self):
    method show_context_menu (line 191) | def show_context_menu(self, event):
    method on_add_file_button_clicked (line 194) | def on_add_file_button_clicked(self):
    method on_remove_selected_button_clicked (line 197) | def on_remove_selected_button_clicked(self):
    method on_add_directory_button_clicked (line 200) | def on_add_directory_button_clicked(self):
    method on_clear_play_list_button_clicked (line 203) | def on_clear_play_list_button_clicked(self):
    method on_remove_selected_context_menu_clicked (line 206) | def on_remove_selected_context_menu_clicked(self):
    method on_play_stop_button_clicked (line 209) | def on_play_stop_button_clicked(self):
    method on_pause_unpause_button_clicked (line 220) | def on_pause_unpause_button_clicked(self):
    method on_mute_unmute_button_clicked (line 227) | def on_mute_unmute_button_clicked(self):
    method on_previous_track_button_clicked (line 239) | def on_previous_track_button_clicked(self):
    method on_rewind_button_clicked (line 242) | def on_rewind_button_clicked(self):
    method on_fast_forward_button_clicked (line 245) | def on_fast_forward_button_clicked(self):
    method on_next_track_button_clicked (line 248) | def on_next_track_button_clicked(self):
    method on_volume_scale_changed (line 251) | def on_volume_scale_changed(self, value):
    method on_play_list_double_clicked (line 258) | def on_play_list_double_clicked(self, event=None):
    method play_previous_track (line 262) | def play_previous_track(self):
    method play_next_track (line 266) | def play_next_track(self):
    method start_play (line 271) | def start_play(self):
    method stop_play (line 279) | def stop_play(self):
    method add_audio_file (line 283) | def add_audio_file(self):
    method remove_selected_files (line 291) | def remove_selected_files(self):
    method add_all_audio_files_from_directory (line 300) | def add_all_audio_files_from_directory(self):
    method get_all_audio_file_from_directory (line 311) | def get_all_audio_file_from_directory(self, directory_path):
    method clear_play_list (line 319) | def clear_play_list(self):

FILE: Chapter 05/5.05/model.py
  class Model (line 8) | class Model:
    method __init__ (line 10) | def __init__(self):
    method play_list (line 14) | def play_list(self):
    method get_file_to_play (line 17) | def get_file_to_play(self, file_index):
    method clear_play_list (line 20) | def clear_play_list(self):
    method add_to_play_list (line 23) | def add_to_play_list(self, file_name):
    method remove_item_from_play_list_at_index (line 26) | def remove_item_from_play_list_at_index(self, index):

FILE: Chapter 05/5.05/player.py
  class Player (line 12) | class Player:
    method __init__ (line 14) | def __init__(self):
    method play_media (line 18) | def play_media(self, audio_file):
    method reset_player (line 25) | def reset_player(self):
    method is_playing (line 29) | def is_playing(self):
    method seek (line 37) | def seek(self, time):
    method track_length (line 44) | def track_length(self):
    method volume (line 51) | def volume(self):
    method elapsed_play_duration (line 55) | def elapsed_play_duration(self):
    method volume (line 59) | def volume(self, volume):
    method unpause (line 62) | def unpause(self):
    method pause (line 65) | def pause(self):
    method stop (line 68) | def stop(self):
    method mute (line 71) | def mute(self):
    method unmute (line 74) | def unmute(self, newvolume_level):
    method fast_forward (line 77) | def fast_forward(self):
    method rewind (line 87) | def rewind(self):

FILE: Chapter 05/5.05/seekbar.py
  class Seekbar (line 10) | class Seekbar(tk.Canvas):
    method __init__ (line 12) | def __init__(self, parent, **options):
    method bind_mouse_button (line 22) | def bind_mouse_button(self):
    method on_seekbar_clicked (line 30) | def on_seekbar_clicked(self, event=None):
    method slide_to_position (line 34) | def slide_to_position(self, new_position):
  class TestSeekBar (line 40) | class TestSeekBar():
    method __init__ (line 42) | def __init__(self):
    method seek_new_position (line 52) | def seek_new_position(self, event):

FILE: Chapter 05/5.05/view.py
  class View (line 29) | class View:
    method __init__ (line 37) | def __init__(self, root, model, player):
    method create_gui (line 43) | def create_gui(self):
    method create_top_display (line 51) | def create_top_display(self):
    method create_button_frame (line 70) | def create_button_frame(self):
    method create_list_box (line 123) | def create_list_box(self):
    method create_bottom_frame (line 137) | def create_bottom_frame(self):
    method create_context_menu (line 174) | def create_context_menu(self):
    method show_context_menu (line 179) | def show_context_menu(self, event):
    method on_add_file_button_clicked (line 182) | def on_add_file_button_clicked(self):
    method on_remove_selected_button_clicked (line 185) | def on_remove_selected_button_clicked(self):
    method on_add_directory_button_clicked (line 188) | def on_add_directory_button_clicked(self):
    method on_clear_play_list_button_clicked (line 191) | def on_clear_play_list_button_clicked(self):
    method on_remove_selected_context_menu_clicked (line 194) | def on_remove_selected_context_menu_clicked(self):
    method on_play_stop_button_clicked (line 197) | def on_play_stop_button_clicked(self):
    method on_pause_unpause_button_clicked (line 208) | def on_pause_unpause_button_clicked(self):
    method on_mute_unmute_button_clicked (line 215) | def on_mute_unmute_button_clicked(self):
    method on_previous_track_button_clicked (line 227) | def on_previous_track_button_clicked(self):
    method on_rewind_button_clicked (line 230) | def on_rewind_button_clicked(self):
    method on_fast_forward_button_clicked (line 233) | def on_fast_forward_button_clicked(self):
    method on_next_track_button_clicked (line 236) | def on_next_track_button_clicked(self):
    method on_volume_scale_changed (line 239) | def on_volume_scale_changed(self, value):
    method on_play_list_double_clicked (line 246) | def on_play_list_double_clicked(self, event=None):
    method play_previous_track (line 250) | def play_previous_track(self):
    method play_next_track (line 254) | def play_next_track(self):
    method start_play (line 259) | def start_play(self):
    method stop_play (line 267) | def stop_play(self):
    method add_audio_file (line 271) | def add_audio_file(self):
    method remove_selected_files (line 279) | def remove_selected_files(self):
    method add_all_audio_files_from_directory (line 288) | def add_all_audio_files_from_directory(self):
    method get_all_audio_file_from_directory (line 299) | def get_all_audio_file_from_directory(self, directory_path):
    method clear_play_list (line 307) | def clear_play_list(self):

FILE: Chapter 05/5.06/helpers.py
  function get_time_in_minute_seconds (line 8) | def get_time_in_minute_seconds(time_in_seconds):
  function truncate_text (line 14) | def truncate_text(text, truncate_length):

FILE: Chapter 05/5.06/model.py
  class Model (line 8) | class Model:
    method __init__ (line 10) | def __init__(self):
    method play_list (line 14) | def play_list(self):
    method get_file_to_play (line 17) | def get_file_to_play(self, file_index):
    method clear_play_list (line 20) | def clear_play_list(self):
    method add_to_play_list (line 23) | def add_to_play_list(self, file_name):
    method remove_item_from_play_list_at_index (line 26) | def remove_item_from_play_list_at_index(self, index):

FILE: Chapter 05/5.06/player.py
  class Player (line 12) | class Player:
    method __init__ (line 14) | def __init__(self):
    method play_media (line 18) | def play_media(self, audio_file):
    method reset_player (line 25) | def reset_player(self):
    method is_playing (line 29) | def is_playing(self):
    method seek (line 37) | def seek(self, time):
    method track_length (line 44) | def track_length(self):
    method volume (line 51) | def volume(self):
    method elapsed_play_duration (line 55) | def elapsed_play_duration(self):
    method volume (line 59) | def volume(self, volume):
    method unpause (line 62) | def unpause(self):
    method pause (line 65) | def pause(self):
    method stop (line 68) | def stop(self):
    method mute (line 71) | def mute(self):
    method unmute (line 74) | def unmute(self, newvolume_level):
    method fast_forward (line 77) | def fast_forward(self):
    method rewind (line 87) | def rewind(self):

FILE: Chapter 05/5.06/seekbar.py
  class Seekbar (line 9) | class Seekbar(tk.Canvas):
    method __init__ (line 11) | def __init__(self, parent, **options):
    method bind_mouse_button (line 21) | def bind_mouse_button(self):
    method on_seekbar_clicked (line 29) | def on_seekbar_clicked(self, event=None):
    method slide_to_position (line 33) | def slide_to_position(self, new_position):
  class TestSeekBar (line 39) | class TestSeekBar():
    method __init__ (line 41) | def __init__(self):
    method seek_new_position (line 51) | def seek_new_position(self, event):

FILE: Chapter 05/5.06/view.py
  class View (line 30) | class View:
    method __init__ (line 38) | def __init__(self, root, model, player):
    method create_gui (line 45) | def create_gui(self):
    method create_top_display (line 53) | def create_top_display(self):
    method create_button_frame (line 72) | def create_button_frame(self):
    method create_list_box (line 125) | def create_list_box(self):
    method create_bottom_frame (line 139) | def create_bottom_frame(self):
    method create_context_menu (line 176) | def create_context_menu(self):
    method show_context_menu (line 181) | def show_context_menu(self, event):
    method on_add_file_button_clicked (line 184) | def on_add_file_button_clicked(self):
    method on_remove_selected_button_clicked (line 187) | def on_remove_selected_button_clicked(self):
    method on_add_directory_button_clicked (line 190) | def on_add_directory_button_clicked(self):
    method on_clear_play_list_button_clicked (line 193) | def on_clear_play_list_button_clicked(self):
    method on_remove_selected_context_menu_clicked (line 196) | def on_remove_selected_context_menu_clicked(self):
    method on_play_stop_button_clicked (line 199) | def on_play_stop_button_clicked(self):
    method on_pause_unpause_button_clicked (line 210) | def on_pause_unpause_button_clicked(self):
    method on_mute_unmute_button_clicked (line 217) | def on_mute_unmute_button_clicked(self):
    method on_previous_track_button_clicked (line 229) | def on_previous_track_button_clicked(self):
    method on_rewind_button_clicked (line 232) | def on_rewind_button_clicked(self):
    method on_fast_forward_button_clicked (line 235) | def on_fast_forward_button_clicked(self):
    method on_next_track_button_clicked (line 238) | def on_next_track_button_clicked(self):
    method on_volume_scale_changed (line 241) | def on_volume_scale_changed(self, value):
    method on_play_list_double_clicked (line 248) | def on_play_list_double_clicked(self, event=None):
    method play_previous_track (line 252) | def play_previous_track(self):
    method play_next_track (line 256) | def play_next_track(self):
    method start_play (line 261) | def start_play(self):
    method stop_play (line 271) | def stop_play(self):
    method add_audio_file (line 275) | def add_audio_file(self):
    method remove_selected_files (line 283) | def remove_selected_files(self):
    method add_all_audio_files_from_directory (line 292) | def add_all_audio_files_from_directory(self):
    method get_all_audio_file_from_directory (line 303) | def get_all_audio_file_from_directory(self, directory_path):
    method clear_play_list (line 311) | def clear_play_list(self):
    method manage_one_time_track_updates_on_play_start (line 315) | def manage_one_time_track_updates_on_play_start(self):
    method update_now_playing_text (line 319) | def update_now_playing_text(self):
    method display_track_duration (line 325) | def display_track_duration(self):

FILE: Chapter 05/5.07/helpers.py
  function get_time_in_minute_seconds (line 8) | def get_time_in_minute_seconds(time_in_seconds):
  function truncate_text (line 14) | def truncate_text(text, truncate_length):

FILE: Chapter 05/5.07/model.py
  class Model (line 8) | class Model:
    method __init__ (line 10) | def __init__(self):
    method play_list (line 14) | def play_list(self):
    method get_file_to_play (line 17) | def get_file_to_play(self, file_index):
    method clear_play_list (line 20) | def clear_play_list(self):
    method add_to_play_list (line 23) | def add_to_play_list(self, file_name):
    method remove_item_from_play_list_at_index (line 26) | def remove_item_from_play_list_at_index(self, index):

FILE: Chapter 05/5.07/player.py
  class Player (line 12) | class Player:
    method __init__ (line 14) | def __init__(self):
    method play_media (line 18) | def play_media(self, audio_file):
    method reset_player (line 25) | def reset_player(self):
    method is_playing (line 29) | def is_playing(self):
    method seek (line 37) | def seek(self, time):
    method track_length (line 44) | def track_length(self):
    method volume (line 51) | def volume(self):
    method elapsed_play_duration (line 55) | def elapsed_play_duration(self):
    method volume (line 59) | def volume(self, volume):
    method unpause (line 62) | def unpause(self):
    method pause (line 65) | def pause(self):
    method stop (line 68) | def stop(self):
    method mute (line 71) | def mute(self):
    method unmute (line 74) | def unmute(self, newvolume_level):
    method fast_forward (line 77) | def fast_forward(self):
    method rewind (line 87) | def rewind(self):

FILE: Chapter 05/5.07/seekbar.py
  class Seekbar (line 12) | class Seekbar(tk.Canvas):
    method __init__ (line 14) | def __init__(self, parent, **options):
    method bind_mouse_button (line 24) | def bind_mouse_button(self):
    method on_seekbar_clicked (line 32) | def on_seekbar_clicked(self, event=None):
    method slide_to_position (line 35) | def slide_to_position(self, new_position):
  class TestSeekBar (line 42) | class TestSeekBar():
    method __init__ (line 44) | def __init__(self):
    method seek_new_position (line 54) | def seek_new_position(self, event):

FILE: Chapter 05/5.07/view.py
  class View (line 31) | class View:
    method __init__ (line 39) | def __init__(self, root, model, player):
    method create_gui (line 46) | def create_gui(self):
    method create_top_display (line 54) | def create_top_display(self):
    method create_button_frame (line 73) | def create_button_frame(self):
    method create_list_box (line 126) | def create_list_box(self):
    method create_bottom_frame (line 140) | def create_bottom_frame(self):
    method create_context_menu (line 177) | def create_context_menu(self):
    method show_context_menu (line 182) | def show_context_menu(self, event):
    method on_add_file_button_clicked (line 185) | def on_add_file_button_clicked(self):
    method on_remove_selected_button_clicked (line 188) | def on_remove_selected_button_clicked(self):
    method on_add_directory_button_clicked (line 191) | def on_add_directory_button_clicked(self):
    method on_clear_play_list_button_clicked (line 194) | def on_clear_play_list_button_clicked(self):
    method on_remove_selected_context_menu_clicked (line 197) | def on_remove_selected_context_menu_clicked(self):
    method on_play_stop_button_clicked (line 200) | def on_play_stop_button_clicked(self):
    method on_pause_unpause_button_clicked (line 211) | def on_pause_unpause_button_clicked(self):
    method on_mute_unmute_button_clicked (line 218) | def on_mute_unmute_button_clicked(self):
    method on_previous_track_button_clicked (line 230) | def on_previous_track_button_clicked(self):
    method on_rewind_button_clicked (line 233) | def on_rewind_button_clicked(self):
    method on_fast_forward_button_clicked (line 236) | def on_fast_forward_button_clicked(self):
    method on_next_track_button_clicked (line 239) | def on_next_track_button_clicked(self):
    method on_volume_scale_changed (line 242) | def on_volume_scale_changed(self, value):
    method on_play_list_double_clicked (line 249) | def on_play_list_double_clicked(self, event=None):
    method play_previous_track (line 253) | def play_previous_track(self):
    method play_next_track (line 257) | def play_next_track(self):
    method start_play (line 262) | def start_play(self):
    method stop_play (line 273) | def stop_play(self):
    method add_audio_file (line 277) | def add_audio_file(self):
    method remove_selected_files (line 285) | def remove_selected_files(self):
    method add_all_audio_files_from_directory (line 294) | def add_all_audio_files_from_directory(self):
    method get_all_audio_file_from_directory (line 305) | def get_all_audio_file_from_directory(self, directory_path):
    method clear_play_list (line 313) | def clear_play_list(self):
    method manage_one_time_track_updates_on_play_start (line 317) | def manage_one_time_track_updates_on_play_start(self):
    method update_now_playing_text (line 321) | def update_now_playing_text(self):
    method display_track_duration (line 327) | def display_track_duration(self):
    method manage_periodic_updates_during_play (line 334) | def manage_periodic_updates_during_play(self):
    method update_clock (line 339) | def update_clock(self):
    method update_seek_bar (line 346) | def update_seek_bar(self):
    method seek_new_position (line 351) | def seek_new_position(self, event=None):

FILE: Chapter 05/5.08/helpers.py
  function get_time_in_minute_seconds (line 8) | def get_time_in_minute_seconds(time_in_seconds):
  function truncate_text (line 14) | def truncate_text(text, truncate_length):

FILE: Chapter 05/5.08/model.py
  class Model (line 8) | class Model:
    method __init__ (line 10) | def __init__(self):
    method play_list (line 14) | def play_list(self):
    method get_file_to_play (line 17) | def get_file_to_play(self, file_index):
    method clear_play_list (line 20) | def clear_play_list(self):
    method add_to_play_list (line 23) | def add_to_play_list(self, file_name):
    method remove_item_from_play_list_at_index (line 26) | def remove_item_from_play_list_at_index(self, index):

FILE: Chapter 05/5.08/player.py
  class Player (line 12) | class Player:
    method __init__ (line 14) | def __init__(self):
    method play_media (line 18) | def play_media(self, audio_file):
    method reset_player (line 25) | def reset_player(self):
    method is_playing (line 29) | def is_playing(self):
    method seek (line 37) | def seek(self, time):
    method track_length (line 44) | def track_length(self):
    method volume (line 51) | def volume(self):
    method elapsed_play_duration (line 55) | def elapsed_play_duration(self):
    method volume (line 59) | def volume(self, volume):
    method unpause (line 62) | def unpause(self):
    method pause (line 65) | def pause(self):
    method stop (line 68) | def stop(self):
    method mute (line 71) | def mute(self):
    method unmute (line 74) | def unmute(self, newvolume_level):
    method fast_forward (line 77) | def fast_forward(self):
    method rewind (line 87) | def rewind(self):

FILE: Chapter 05/5.08/seekbar.py
  class Seekbar (line 9) | class Seekbar(tk.Canvas):
    method __init__ (line 11) | def __init__(self, parent, **options):
    method bind_mouse_button (line 21) | def bind_mouse_button(self):
    method on_seekbar_clicked (line 29) | def on_seekbar_clicked(self, event=None):
    method slide_to_position (line 33) | def slide_to_position(self, new_position):
  class TestSeekBar (line 39) | class TestSeekBar():
    method __init__ (line 41) | def __init__(self):
    method seek_new_position (line 51) | def seek_new_position(self, event):

FILE: Chapter 05/5.08/view.py
  class View (line 31) | class View:
    method __init__ (line 39) | def __init__(self, root, model, player):
    method create_gui (line 47) | def create_gui(self):
    method create_top_display (line 55) | def create_top_display(self):
    method create_button_frame (line 74) | def create_button_frame(self):
    method create_list_box (line 127) | def create_list_box(self):
    method create_bottom_frame (line 141) | def create_bottom_frame(self):
    method create_context_menu (line 178) | def create_context_menu(self):
    method show_context_menu (line 183) | def show_context_menu(self, event):
    method on_add_file_button_clicked (line 186) | def on_add_file_button_clicked(self):
    method on_remove_selected_button_clicked (line 189) | def on_remove_selected_button_clicked(self):
    method on_add_directory_button_clicked (line 192) | def on_add_directory_button_clicked(self):
    method on_clear_play_list_button_clicked (line 195) | def on_clear_play_list_button_clicked(self):
    method on_remove_selected_context_menu_clicked (line 198) | def on_remove_selected_context_menu_clicked(self):
    method on_play_stop_button_clicked (line 201) | def on_play_stop_button_clicked(self):
    method on_pause_unpause_button_clicked (line 212) | def on_pause_unpause_button_clicked(self):
    method on_mute_unmute_button_clicked (line 219) | def on_mute_unmute_button_clicked(self):
    method on_previous_track_button_clicked (line 231) | def on_previous_track_button_clicked(self):
    method on_rewind_button_clicked (line 234) | def on_rewind_button_clicked(self):
    method on_fast_forward_button_clicked (line 237) | def on_fast_forward_button_clicked(self):
    method on_next_track_button_clicked (line 240) | def on_next_track_button_clicked(self):
    method on_volume_scale_changed (line 243) | def on_volume_scale_changed(self, value):
    method play_previous_track (line 251) | def play_previous_track(self):
    method play_next_track (line 255) | def play_next_track(self):
    method start_play (line 260) | def start_play(self):
    method stop_play (line 271) | def stop_play(self):
    method on_play_list_double_clicked (line 275) | def on_play_list_double_clicked(self, event=None):
    method add_audio_file (line 279) | def add_audio_file(self):
    method remove_selected_files (line 287) | def remove_selected_files(self):
    method add_all_audio_files_from_directory (line 296) | def add_all_audio_files_from_directory(self):
    method get_all_audio_file_from_directory (line 307) | def get_all_audio_file_from_directory(self, directory_path):
    method clear_play_list (line 315) | def clear_play_list(self):
    method manage_one_time_track_updates_on_play_start (line 319) | def manage_one_time_track_updates_on_play_start(self):
    method update_now_playing_text (line 323) | def update_now_playing_text(self):
    method display_track_duration (line 329) | def display_track_duration(self):
    method update_clock (line 336) | def update_clock(self):
    method update_seek_bar (line 343) | def update_seek_bar(self):
    method seek_new_position (line 348) | def seek_new_position(self, event=None):
    method manage_periodic_updates_during_play (line 352) | def manage_periodic_updates_during_play(self):
    method not_to_loop (line 359) | def not_to_loop(self):
    method close_player (line 370) | def close_player(self):

FILE: Chapter 05/5.09/helpers.py
  function get_time_in_minute_seconds (line 8) | def get_time_in_minute_seconds(time_in_seconds):
  function truncate_text (line 14) | def truncate_text(text, truncate_length):

FILE: Chapter 05/5.09/model.py
  class Model (line 8) | class Model:
    method __init__ (line 10) | def __init__(self):
    method play_list (line 14) | def play_list(self):
    method get_file_to_play (line 17) | def get_file_to_play(self, file_index):
    method clear_play_list (line 20) | def clear_play_list(self):
    method add_to_play_list (line 23) | def add_to_play_list(self, file_name):
    method remove_item_from_play_list_at_index (line 26) | def remove_item_from_play_list_at_index(self, index):

FILE: Chapter 05/5.09/player.py
  class Player (line 12) | class Player:
    method __init__ (line 14) | def __init__(self):
    method play_media (line 18) | def play_media(self, audio_file):
    method reset_player (line 25) | def reset_player(self):
    method is_playing (line 29) | def is_playing(self):
    method seek (line 37) | def seek(self, time):
    method track_length (line 44) | def track_length(self):
    method volume (line 51) | def volume(self):
    method elapsed_play_duration (line 55) | def elapsed_play_duration(self):
    method volume (line 59) | def volume(self, volume):
    method unpause (line 62) | def unpause(self):
    method pause (line 65) | def pause(self):
    method stop (line 68) | def stop(self):
    method mute (line 71) | def mute(self):
    method unmute (line 74) | def unmute(self, new_volume_level):
    method fast_forward (line 77) | def fast_forward(self):
    method rewind (line 87) | def rewind(self):

FILE: Chapter 05/5.09/seekbar.py
  class Seekbar (line 9) | class Seekbar(tk.Canvas):
    method __init__ (line 11) | def __init__(self, parent, **options):
    method bind_mouse_button (line 21) | def bind_mouse_button(self):
    method on_seekbar_clicked (line 29) | def on_seekbar_clicked(self, event=None):
    method slide_to_position (line 33) | def slide_to_position(self, new_position):
  class TestSeekBar (line 39) | class TestSeekBar():
    method __init__ (line 41) | def __init__(self):
    method seek_new_position (line 51) | def seek_new_position(self, event):

FILE: Chapter 05/5.09/view.py
  class View (line 31) | class View:
    method __init__ (line 39) | def __init__(self, root, model, player):
    method create_gui (line 47) | def create_gui(self):
    method create_top_display (line 56) | def create_top_display(self):
    method create_button_frame (line 75) | def create_button_frame(self):
    method create_list_box (line 135) | def create_list_box(self):
    method create_bottom_frame (line 149) | def create_bottom_frame(self):
    method create_context_menu (line 190) | def create_context_menu(self):
    method show_context_menu (line 195) | def show_context_menu(self, event):
    method on_add_file_button_clicked (line 198) | def on_add_file_button_clicked(self):
    method on_remove_selected_button_clicked (line 201) | def on_remove_selected_button_clicked(self):
    method on_add_directory_button_clicked (line 204) | def on_add_directory_button_clicked(self):
    method on_clear_play_list_button_clicked (line 207) | def on_clear_play_list_button_clicked(self):
    method on_remove_selected_context_menu_clicked (line 210) | def on_remove_selected_context_menu_clicked(self):
    method on_play_stop_button_clicked (line 213) | def on_play_stop_button_clicked(self):
    method on_pause_unpause_button_clicked (line 224) | def on_pause_unpause_button_clicked(self):
    method on_mute_unmute_button_clicked (line 231) | def on_mute_unmute_button_clicked(self):
    method on_previous_track_button_clicked (line 243) | def on_previous_track_button_clicked(self):
    method on_rewind_button_clicked (line 246) | def on_rewind_button_clicked(self):
    method on_fast_forward_button_clicked (line 249) | def on_fast_forward_button_clicked(self):
    method on_next_track_button_clicked (line 252) | def on_next_track_button_clicked(self):
    method on_volume_scale_changed (line 255) | def on_volume_scale_changed(self, value):
    method play_previous_track (line 262) | def play_previous_track(self):
    method play_next_track (line 266) | def play_next_track(self):
    method start_play (line 271) | def start_play(self):
    method stop_play (line 282) | def stop_play(self):
    method on_play_list_double_clicked (line 286) | def on_play_list_double_clicked(self, event=None):
    method add_audio_file (line 290) | def add_audio_file(self):
    method remove_selected_files (line 298) | def remove_selected_files(self):
    method add_all_audio_files_from_directory (line 307) | def add_all_audio_files_from_directory(self):
    method get_all_audio_file_from_directory (line 318) | def get_all_audio_file_from_directory(self, directory_path):
    method clear_play_list (line 326) | def clear_play_list(self):
    method manage_one_time_track_updates_on_play_start (line 330) | def manage_one_time_track_updates_on_play_start(self):
    method update_now_playing_text (line 334) | def update_now_playing_text(self):
    method display_track_duration (line 340) | def display_track_duration(self):
    method update_clock (line 348) | def update_clock(self):
    method update_seek_bar (line 355) | def update_seek_bar(self):
    method seek_new_position (line 360) | def seek_new_position(self, event=None):
    method manage_periodic_updates_during_play (line 364) | def manage_periodic_updates_during_play(self):
    method not_to_loop (line 371) | def not_to_loop(self):
    method close_player (line 382) | def close_player(self):

FILE: Chapter 06/6.01.py
  class PaintApplication (line 11) | class PaintApplication(framework.Framework):
    method __init__ (line 13) | def __init__(self, root):
    method create_gui (line 17) | def create_gui(self):
    method create_menu (line 24) | def create_menu(self):
    method create_top_bar (line 34) | def create_top_bar(self):
    method create_tool_bar (line 38) | def create_tool_bar(self):
    method create_drawing_canvas (line 42) | def create_drawing_canvas(self):
    method create_scroll_bar (line 50) | def create_scroll_bar(self):
    method bind_menu_accelrator_keys (line 60) | def bind_menu_accelrator_keys(self):
    method on_new_file_menu_clicked (line 69) | def on_new_file_menu_clicked(self, event=None):
    method on_save_menu_clicked (line 72) | def on_save_menu_clicked(self, event=None):
    method on_save_as_menu_clicked (line 75) | def on_save_as_menu_clicked(self):
    method on_canvas_zoom_out_menu_clicked (line 78) | def on_canvas_zoom_out_menu_clicked(self):
    method on_canvas_zoom_in_menu_clicked (line 81) | def on_canvas_zoom_in_menu_clicked(self):
    method on_close_menu_clicked (line 84) | def on_close_menu_clicked(self):
    method on_undo_menu_clicked (line 87) | def on_undo_menu_clicked(self, event=None):
    method on_about_menu_clicked (line 90) | def on_about_menu_clicked(self, event=None):

FILE: Chapter 06/6.02.py
  class PaintApplication (line 25) | class PaintApplication(framework.Framework):
    method bind_mouse (line 30) | def bind_mouse(self):
    method on_mouse_button_pressed (line 38) | def on_mouse_button_pressed(self, event):
    method on_mouse_button_pressed_motion (line 43) | def on_mouse_button_pressed_motion(self, event):
    method on_mouse_button_released (line 47) | def on_mouse_button_released(self, event):
    method on_mouse_unpressed_motion (line 52) | def on_mouse_unpressed_motion(self, event):
    method __init__ (line 55) | def __init__(self, root):
    method create_gui (line 60) | def create_gui(self):
    method create_menu (line 67) | def create_menu(self):
    method create_top_bar (line 77) | def create_top_bar(self):
    method create_tool_bar (line 81) | def create_tool_bar(self):
    method create_drawing_canvas (line 85) | def create_drawing_canvas(self):
    method create_scroll_bar (line 93) | def create_scroll_bar(self):
    method bind_menu_accelrator_keys (line 103) | def bind_menu_accelrator_keys(self):
    method on_new_file_menu_clicked (line 112) | def on_new_file_menu_clicked(self, event=None):
    method on_save_menu_clicked (line 115) | def on_save_menu_clicked(self, event=None):
    method on_save_as_menu_clicked (line 118) | def on_save_as_menu_clicked(self):
    method on_canvas_zoom_out_menu_clicked (line 121) | def on_canvas_zoom_out_menu_clicked(self):
    method on_canvas_zoom_in_menu_clicked (line 124) | def on_canvas_zoom_in_menu_clicked(self):
    method on_close_menu_clicked (line 127) | def on_close_menu_clicked(self):
    method on_undo_menu_clicked (line 130) | def on_undo_menu_clicked(self, event=None):
    method on_about_menu_clicked (line 133) | def on_about_menu_clicked(self, event=None):

FILE: Chapter 06/6.03.py
  class PaintApplication (line 21) | class PaintApplication(framework.Framework):
    method create_tool_bar_buttons (line 32) | def create_tool_bar_buttons(self):
    method on_tool_bar_button_clicked (line 41) | def on_tool_bar_button_clicked(self, button_index):
    method display_options_in_the_top_bar (line 46) | def display_options_in_the_top_bar(self):
    method remove_options_from_top_bar (line 50) | def remove_options_from_top_bar(self):
    method show_selected_tool_icon_in_top_bar (line 54) | def show_selected_tool_icon_in_top_bar(self, function_name):
    method bind_mouse (line 63) | def bind_mouse(self):
    method on_mouse_button_pressed (line 71) | def on_mouse_button_pressed(self, event):
    method on_mouse_button_pressed_motion (line 75) | def on_mouse_button_pressed_motion(self, event):
    method on_mouse_button_released (line 79) | def on_mouse_button_released(self, event):
    method on_mouse_unpressed_motion (line 83) | def on_mouse_unpressed_motion(self, event):
    method __init__ (line 86) | def __init__(self, root):
    method create_gui (line 91) | def create_gui(self):
    method create_menu (line 99) | def create_menu(self):
    method create_top_bar (line 109) | def create_top_bar(self):
    method create_tool_bar (line 113) | def create_tool_bar(self):
    method create_drawing_canvas (line 117) | def create_drawing_canvas(self):
    method create_scroll_bar (line 125) | def create_scroll_bar(self):
    method bind_menu_accelrator_keys (line 135) | def bind_menu_accelrator_keys(self):
    method on_new_file_menu_clicked (line 144) | def on_new_file_menu_clicked(self, event=None):
    method on_save_menu_clicked (line 147) | def on_save_menu_clicked(self, event=None):
    method on_save_as_menu_clicked (line 150) | def on_save_as_menu_clicked(self):
    method on_canvas_zoom_out_menu_clicked (line 153) | def on_canvas_zoom_out_menu_clicked(self):
    method on_canvas_zoom_in_menu_clicked (line 156) | def on_canvas_zoom_in_menu_clicked(self):
    method on_close_menu_clicked (line 159) | def on_close_menu_clicked(self):
    method on_undo_menu_clicked (line 162) | def on_undo_menu_clicked(self, event=None):
    method on_about_menu_clicked (line 165) | def on_about_menu_clicked(self, event=None):

FILE: Chapter 06/6.04.py
  class PaintApplication (line 38) | class PaintApplication(framework.Framework):
    method function_not_defined (line 56) | def function_not_defined(self):
    method execute_selected_method (line 59) | def execute_selected_method(self):
    method draw_line (line 65) | def draw_line(self):
    method draw_oval (line 69) | def draw_oval(self):
    method draw_rectangle (line 73) | def draw_rectangle(self):
    method draw_arc (line 77) | def draw_arc(self):
    method draw_triangle (line 81) | def draw_triangle(self):
    method draw_star (line 97) | def draw_star(self):
    method create_tool_bar_buttons (line 121) | def create_tool_bar_buttons(self):
    method on_tool_bar_button_clicked (line 130) | def on_tool_bar_button_clicked(self, button_index):
    method display_options_in_the_top_bar (line 135) | def display_options_in_the_top_bar(self):
    method remove_options_from_top_bar (line 139) | def remove_options_from_top_bar(self):
    method show_selected_tool_icon_in_top_bar (line 143) | def show_selected_tool_icon_in_top_bar(self, function_name):
    method bind_mouse (line 152) | def bind_mouse(self):
    method on_mouse_button_pressed (line 160) | def on_mouse_button_pressed(self, event):
    method on_mouse_button_pressed_motion (line 165) | def on_mouse_button_pressed_motion(self, event):
    method on_mouse_button_released (line 171) | def on_mouse_button_released(self, event):
    method on_mouse_unpressed_motion (line 175) | def on_mouse_unpressed_motion(self, event):
    method __init__ (line 178) | def __init__(self, root):
    method create_gui (line 183) | def create_gui(self):
    method create_menu (line 191) | def create_menu(self):
    method create_top_bar (line 201) | def create_top_bar(self):
    method create_tool_bar (line 205) | def create_tool_bar(self):
    method create_drawing_canvas (line 209) | def create_drawing_canvas(self):
    method create_scroll_bar (line 217) | def create_scroll_bar(self):
    method bind_menu_accelrator_keys (line 227) | def bind_menu_accelrator_keys(self):
    method on_new_file_menu_clicked (line 236) | def on_new_file_menu_clicked(self, event=None):
    method on_save_menu_clicked (line 239) | def on_save_menu_clicked(self, event=None):
    method on_save_as_menu_clicked (line 242) | def on_save_as_menu_clicked(self):
    method on_canvas_zoom_out_menu_clicked (line 245) | def on_canvas_zoom_out_menu_clicked(self):
    method on_canvas_zoom_in_menu_clicked (line 248) | def on_canvas_zoom_in_menu_clicked(self):
    method on_close_menu_clicked (line 251) | def on_close_menu_clicked(self):
    method on_undo_menu_clicked (line 254) | def on_undo_menu_clicked(self, event=None):
    method on_about_menu_clicked (line 257) | def on_about_menu_clicked(self, event=None):

FILE: Chapter 06/6.05.py
  class PaintApplication (line 33) | class PaintApplication(framework.Framework):
    method create_color_palette (line 53) | def create_color_palette(self):
    method bind_color_palette (line 62) | def bind_color_palette(self):
    method set_foreground_color (line 68) | def set_foreground_color(self, event=None):
    method set_background_color (line 74) | def set_background_color(self, event=None):
    method create_current_coordinate_label (line 81) | def create_current_coordinate_label(self):
    method show_current_coordinates (line 87) | def show_current_coordinates(self, event=None):
    method function_not_defined (line 93) | def function_not_defined(self):
    method execute_selected_method (line 96) | def execute_selected_method(self):
    method draw_line (line 102) | def draw_line(self):
    method draw_oval (line 106) | def draw_oval(self):
    method draw_rectangle (line 110) | def draw_rectangle(self):
    method draw_arc (line 114) | def draw_arc(self):
    method draw_triangle (line 118) | def draw_triangle(self):
    method draw_star (line 133) | def draw_star(self):
    method create_tool_bar_buttons (line 151) | def create_tool_bar_buttons(self):
    method on_tool_bar_button_clicked (line 160) | def on_tool_bar_button_clicked(self, button_index):
    method display_options_in_the_top_bar (line 165) | def display_options_in_the_top_bar(self):
    method remove_options_from_top_bar (line 169) | def remove_options_from_top_bar(self):
    method show_selected_tool_icon_in_top_bar (line 173) | def show_selected_tool_icon_in_top_bar(self, function_name):
    method bind_mouse (line 182) | def bind_mouse(self):
    method on_mouse_button_pressed (line 190) | def on_mouse_button_pressed(self, event):
    method on_mouse_button_pressed_motion (line 195) | def on_mouse_button_pressed_motion(self, event):
    method on_mouse_button_released (line 201) | def on_mouse_button_released(self, event):
    method on_mouse_unpressed_motion (line 205) | def on_mouse_unpressed_motion(self, event):
    method __init__ (line 208) | def __init__(self, root):
    method create_gui (line 213) | def create_gui(self):
    method create_menu (line 223) | def create_menu(self):
    method create_top_bar (line 233) | def create_top_bar(self):
    method create_tool_bar (line 237) | def create_tool_bar(self):
    method create_drawing_canvas (line 241) | def create_drawing_canvas(self):
    method create_scroll_bar (line 249) | def create_scroll_bar(self):
    method bind_menu_accelrator_keys (line 259) | def bind_menu_accelrator_keys(self):
    method on_new_file_menu_clicked (line 268) | def on_new_file_menu_clicked(self, event=None):
    method on_save_menu_clicked (line 271) | def on_save_menu_clicked(self, event=None):
    method on_save_as_menu_clicked (line 274) | def on_save_as_menu_clicked(self):
    method on_canvas_zoom_out_menu_clicked (line 277) | def on_canvas_zoom_out_menu_clicked(self):
    method on_canvas_zoom_in_menu_clicked (line 280) | def on_canvas_zoom_in_menu_clicked(self):
    method on_close_menu_clicked (line 283) | def on_close_menu_clicked(self):
    method on_undo_menu_clicked (line 286) | def on_undo_menu_clicked(self, event=None):
    method on_about_menu_clicked (line 289) | def on_about_menu_clicked(self, event=None):

FILE: Chapter 06/6.06.py
  class PaintApplication (line 45) | class PaintApplication(framework.Framework):
    method set_foreground_color (line 65) | def set_foreground_color(self, event=None):
    method set_background_color (line 71) | def set_background_color(self, event=None):
    method get_color_from_chooser (line 77) | def get_color_from_chooser(self, initial_color, color_type="a"):
    method try_to_set_fill_after_palette_change (line 88) | def try_to_set_fill_after_palette_change(self):
    method try_to_set_outline_after_palette_change (line 94) | def try_to_set_outline_after_palette_change(self):
    method display_options_in_the_top_bar (line 100) | def display_options_in_the_top_bar(self):
    method draw_line_options (line 107) | def draw_line_options(self):
    method draw_oval_options (line 113) | def draw_oval_options(self):
    method draw_rectangle_options (line 118) | def draw_rectangle_options(self):
    method draw_arc_options (line 123) | def draw_arc_options(self):
    method draw_triangle_options (line 128) | def draw_triangle_options(self):
    method draw_star_options (line 133) | def draw_star_options(self):
    method create_fill_options_combobox (line 139) | def create_fill_options_combobox(self):
    method create_number_of_spokes_options_combobox (line 148) | def create_number_of_spokes_options_combobox(self):
    method create_outline_options_combobox (line 159) | def create_outline_options_combobox(self):
    method create_width_options_combobox (line 169) | def create_width_options_combobox(self):
    method create_dash_options_combobox (line 179) | def create_dash_options_combobox(self):
    method create_arrow_options_combobox (line 188) | def create_arrow_options_combobox(self):
    method set_fill (line 197) | def set_fill(self, event=None):
    method set_outline (line 208) | def set_outline(self, event=None):
    method set_width (line 219) | def set_width(self, event):
    method set_number_of_spokes (line 222) | def set_number_of_spokes(self, event):
    method set_arrow (line 225) | def set_arrow(self, event):
    method set_dash (line 228) | def set_dash(self, event):
    method create_color_palette (line 240) | def create_color_palette(self):
    method bind_color_palette (line 249) | def bind_color_palette(self):
    method create_current_coordinate_label (line 255) | def create_current_coordinate_label(self):
    method show_current_coordinates (line 261) | def show_current_coordinates(self, event=None):
    method function_not_defined (line 267) | def function_not_defined(self):
    method execute_selected_method (line 270) | def execute_selected_method(self):
    method draw_line (line 276) | def draw_line(self):
    method draw_oval (line 280) | def draw_oval(self):
    method draw_rectangle (line 284) | def draw_rectangle(self):
    method draw_arc (line 288) | def draw_arc(self):
    method draw_triangle (line 292) | def draw_triangle(self):
    method draw_star (line 307) | def draw_star(self):
    method create_tool_bar_buttons (line 325) | def create_tool_bar_buttons(self):
    method on_tool_bar_button_clicked (line 334) | def on_tool_bar_button_clicked(self, button_index):
    method remove_options_from_top_bar (line 339) | def remove_options_from_top_bar(self):
    method show_selected_tool_icon_in_top_bar (line 343) | def show_selected_tool_icon_in_top_bar(self, function_name):
    method bind_mouse (line 352) | def bind_mouse(self):
    method on_mouse_button_pressed (line 360) | def on_mouse_button_pressed(self, event):
    method on_mouse_button_pressed_motion (line 365) | def on_mouse_button_pressed_motion(self, event):
    method on_mouse_button_released (line 371) | def on_mouse_button_released(self, event):
    method on_mouse_unpressed_motion (line 375) | def on_mouse_unpressed_motion(self, event):
    method __init__ (line 378) | def __init__(self, root):
    method create_gui (line 383) | def create_gui(self):
    method create_menu (line 395) | def create_menu(self):
    method create_top_bar (line 405) | def create_top_bar(self):
    method create_tool_bar (line 409) | def create_tool_bar(self):
    method create_drawing_canvas (line 413) | def create_drawing_canvas(self):
    method create_scroll_bar (line 421) | def create_scroll_bar(self):
    method bind_menu_accelrator_keys (line 431) | def bind_menu_accelrator_keys(self):
    method on_new_file_menu_clicked (line 440) | def on_new_file_menu_clicked(self, event=None):
    method on_save_menu_clicked (line 443) | def on_save_menu_clicked(self, event=None):
    method on_save_as_menu_clicked (line 446) | def on_save_as_menu_clicked(self):
    method on_canvas_zoom_out_menu_clicked (line 449) | def on_canvas_zoom_out_menu_clicked(self):
    method on_canvas_zoom_in_menu_clicked (line 452) | def on_canvas_zoom_in_menu_clicked(self):
    method on_close_menu_clicked (line 455) | def on_close_menu_clicked(self):
    method on_undo_menu_clicked (line 458) | def on_undo_menu_clicked(self, event=None):
    method on_about_menu_clicked (line 461) | def on_about_menu_clicked(self, event=None):

FILE: Chapter 06/6.07.py
  class PaintApplication (line 36) | class PaintApplication(framework.Framework):
    method draw_irregular_line (line 57) | def draw_irregular_line(self):
    method draw_irregular_line_update_x_y (line 62) | def draw_irregular_line_update_x_y(self, event=None):
    method draw_irregular_line_options (line 67) | def draw_irregular_line_options(self):
    method on_tool_bar_button_clicked (line 71) | def on_tool_bar_button_clicked(self, button_index):
    method draw_super_shape (line 77) | def draw_super_shape(self):
    method draw_super_shape_options (line 83) | def draw_super_shape_options(self):
    method create_super_shapes_options_combobox (line 89) | def create_super_shapes_options_combobox(self):
    method set_selected_super_shape (line 100) | def set_selected_super_shape(self, event=None):
    method get_super_shape_points (line 103) | def get_super_shape_points(self, a, b, m, n1, n2, n3):
    method float_range (line 115) | def float_range(self, x, y, step):
    method set_foreground_color (line 120) | def set_foreground_color(self, event=None):
    method set_background_color (line 126) | def set_background_color(self, event=None):
    method get_color_from_chooser (line 132) | def get_color_from_chooser(self, initial_color, color_type="a"):
    method try_to_set_fill_after_palette_change (line 144) | def try_to_set_fill_after_palette_change(self):
    method try_to_set_outline_after_palette_change (line 150) | def try_to_set_outline_after_palette_change(self):
    method display_options_in_the_top_bar (line 156) | def display_options_in_the_top_bar(self):
    method draw_line_options (line 163) | def draw_line_options(self):
    method draw_oval_options (line 169) | def draw_oval_options(self):
    method draw_rectangle_options (line 174) | def draw_rectangle_options(self):
    method draw_arc_options (line 179) | def draw_arc_options(self):
    method draw_triangle_options (line 184) | def draw_triangle_options(self):
    method draw_star_options (line 189) | def draw_star_options(self):
    method create_fill_options_combobox (line 195) | def create_fill_options_combobox(self):
    method create_number_of_spokes_options_combobox (line 204) | def create_number_of_spokes_options_combobox(self):
    method create_outline_options_combobox (line 215) | def create_outline_options_combobox(self):
    method create_width_options_combobox (line 225) | def create_width_options_combobox(self):
    method create_dash_options_combobox (line 235) | def create_dash_options_combobox(self):
    method create_arrow_options_combobox (line 244) | def create_arrow_options_combobox(self):
    method set_fill (line 253) | def set_fill(self, event=None):
    method set_outline (line 264) | def set_outline(self, event=None):
    method set_width (line 275) | def set_width(self, event):
    method set_number_of_spokes (line 278) | def set_number_of_spokes(self, event):
    method set_arrow (line 281) | def set_arrow(self, event):
    method set_dash (line 284) | def set_dash(self, event):
    method create_color_palette (line 296) | def create_color_palette(self):
    method bind_color_palette (line 305) | def bind_color_palette(self):
    method create_current_coordinate_label (line 311) | def create_current_coordinate_label(self):
    method show_current_coordinates (line 317) | def show_current_coordinates(self, event=None):
    method function_not_defined (line 323) | def function_not_defined(self):
    method execute_selected_method (line 326) | def execute_selected_method(self):
    method draw_line (line 332) | def draw_line(self):
    method draw_oval (line 336) | def draw_oval(self):
    method draw_rectangle (line 340) | def draw_rectangle(self):
    method draw_arc (line 344) | def draw_arc(self):
    method draw_triangle (line 348) | def draw_triangle(self):
    method draw_star (line 363) | def draw_star(self):
    method create_tool_bar_buttons (line 381) | def create_tool_bar_buttons(self):
    method remove_options_from_top_bar (line 390) | def remove_options_from_top_bar(self):
    method show_selected_tool_icon_in_top_bar (line 394) | def show_selected_tool_icon_in_top_bar(self, function_name):
    method bind_mouse (line 403) | def bind_mouse(self):
    method on_mouse_button_pressed (line 411) | def on_mouse_button_pressed(self, event):
    method on_mouse_button_pressed_motion (line 416) | def on_mouse_button_pressed_motion(self, event):
    method on_mouse_button_released (line 422) | def on_mouse_button_released(self, event):
    method on_mouse_unpressed_motion (line 426) | def on_mouse_unpressed_motion(self, event):
    method __init__ (line 429) | def __init__(self, root):
    method create_gui (line 434) | def create_gui(self):
    method create_menu (line 446) | def create_menu(self):
    method create_top_bar (line 456) | def create_top_bar(self):
    method create_tool_bar (line 460) | def create_tool_bar(self):
    method create_drawing_canvas (line 464) | def create_drawing_canvas(self):
    method create_scroll_bar (line 472) | def create_scroll_bar(self):
    method bind_menu_accelrator_keys (line 482) | def bind_menu_accelrator_keys(self):
    method on_new_file_menu_clicked (line 491) | def on_new_file_menu_clicked(self, event=None):
    method on_save_menu_clicked (line 494) | def on_save_menu_clicked(self, event=None):
    method on_save_as_menu_clicked (line 497) | def on_save_as_menu_clicked(self):
    method on_canvas_zoom_out_menu_clicked (line 500) | def on_canvas_zoom_out_menu_clicked(self):
    method on_canvas_zoom_in_menu_clicked (line 503) | def on_canvas_zoom_in_menu_clicked(self):
    method on_close_menu_clicked (line 506) | def on_close_menu_clicked(self):
    method on_undo_menu_clicked (line 509) | def on_undo_menu_clicked(self, event=None):
    method on_about_menu_clicked (line 512) | def on_about_menu_clicked(self, event=None):

FILE: Chapter 06/6.08.py
  class PaintApplication (line 32) | class PaintApplication(framework.Framework):
    method draw_text (line 53) | def draw_text(self):
    method draw_text_options (line 56) | def draw_text_options(self):
    method on_create_text_button_clicked (line 69) | def on_create_text_button_clicked(self):
    method delete_item (line 77) | def delete_item(self):
    method fill_item (line 81) | def fill_item(self):
    method fill_item_options (line 88) | def fill_item_options(self):
    method duplicate_item (line 92) | def duplicate_item(self):
    method get_all_configurations_for_item (line 103) | def get_all_configurations_for_item(self):
    method canvas_function_wrapper (line 110) | def canvas_function_wrapper(self, function_name, *arg, **kwargs):
    method move_to_top (line 114) | def move_to_top(self):
    method drag_item (line 118) | def drag_item(self):
    method drag_item_update_x_y (line 123) | def drag_item_update_x_y(self, event):
    method enlarge_item_size (line 128) | def enlarge_item_size(self):
    method reduce_item_size (line 134) | def reduce_item_size(self):
    method draw_irregular_line (line 140) | def draw_irregular_line(self):
    method draw_irregular_line_update_x_y (line 145) | def draw_irregular_line_update_x_y(self, event=None):
    method draw_irregular_line_options (line 150) | def draw_irregular_line_options(self):
    method on_tool_bar_button_clicked (line 154) | def on_tool_bar_button_clicked(self, button_index):
    method draw_super_shape (line 160) | def draw_super_shape(self):
    method draw_super_shape_options (line 166) | def draw_super_shape_options(self):
    method create_super_shapes_options_combobox (line 172) | def create_super_shapes_options_combobox(self):
    method set_selected_super_shape (line 183) | def set_selected_super_shape(self, event=None):
    method get_super_shape_points (line 186) | def get_super_shape_points(self, a, b, m, n1, n2, n3):
    method float_range (line 198) | def float_range(self, x, y, step):
    method set_foreground_color (line 203) | def set_foreground_color(self, event=None):
    method set_background_color (line 209) | def set_background_color(self, event=None):
    method get_color_from_chooser (line 215) | def get_color_from_chooser(self, initial_color, color_type="a"):
    method try_to_set_fill_after_palette_change (line 226) | def try_to_set_fill_after_palette_change(self):
    method try_to_set_outline_after_palette_change (line 232) | def try_to_set_outline_after_palette_change(self):
    method display_options_in_the_top_bar (line 238) | def display_options_in_the_top_bar(self):
    method draw_line_options (line 246) | def draw_line_options(self):
    method draw_oval_options (line 252) | def draw_oval_options(self):
    method draw_rectangle_options (line 257) | def draw_rectangle_options(self):
    method draw_arc_options (line 262) | def draw_arc_options(self):
    method draw_triangle_options (line 267) | def draw_triangle_options(self):
    method draw_star_options (line 272) | def draw_star_options(self):
    method create_fill_options_combobox (line 278) | def create_fill_options_combobox(self):
    method create_number_of_spokes_options_combobox (line 287) | def create_number_of_spokes_options_combobox(self):
    method create_outline_options_combobox (line 298) | def create_outline_options_combobox(self):
    method create_width_options_combobox (line 308) | def create_width_options_combobox(self):
    method create_dash_options_combobox (line 318) | def create_dash_options_combobox(self):
    method create_arrow_options_combobox (line 327) | def create_arrow_options_combobox(self):
    method set_fill (line 336) | def set_fill(self, event=None):
    method set_outline (line 347) | def set_outline(self, event=None):
    method set_width (line 358) | def set_width(self, event):
    method set_number_of_spokes (line 361) | def set_number_of_spokes(self, event):
    method set_arrow (line 364) | def set_arrow(self, event):
    method set_dash (line 367) | def set_dash(self, event):
    method create_color_palette (line 379) | def create_color_palette(self):
    method bind_color_palette (line 388) | def bind_color_palette(self):
    method create_current_coordinate_label (line 394) | def create_current_coordinate_label(self):
    method show_current_coordinates (line 400) | def show_current_coordinates(self, event=None):
    method function_not_defined (line 406) | def function_not_defined(self):
    method execute_selected_method (line 409) | def execute_selected_method(self):
    method draw_line (line 415) | def draw_line(self):
    method draw_oval (line 419) | def draw_oval(self):
    method draw_rectangle (line 423) | def draw_rectangle(self):
    method draw_arc (line 427) | def draw_arc(self):
    method draw_triangle (line 431) | def draw_triangle(self):
    method draw_star (line 446) | def draw_star(self):
    method create_tool_bar_buttons (line 464) | def create_tool_bar_buttons(self):
    method remove_options_from_top_bar (line 473) | def remove_options_from_top_bar(self):
    method show_selected_tool_icon_in_top_bar (line 477) | def show_selected_tool_icon_in_top_bar(self, function_name):
    method bind_mouse (line 486) | def bind_mouse(self):
    method on_mouse_button_pressed (line 494) | def on_mouse_button_pressed(self, event):
    method on_mouse_button_pressed_motion (line 499) | def on_mouse_button_pressed_motion(self, event):
    method on_mouse_button_released (line 505) | def on_mouse_button_released(self, event):
    method on_mouse_unpressed_motion (line 509) | def on_mouse_unpressed_motion(self, event):
    method __init__ (line 512) | def __init__(self, root):
    method create_gui (line 517) | def create_gui(self):
    method create_menu (line 529) | def create_menu(self):
    method create_top_bar (line 539) | def create_top_bar(self):
    method create_tool_bar (line 543) | def create_tool_bar(self):
    method create_drawing_canvas (line 547) | def create_drawing_canvas(self):
    method create_scroll_bar (line 555) | def create_scroll_bar(self):
    method bind_menu_accelrator_keys (line 565) | def bind_menu_accelrator_keys(self):
    method on_new_file_menu_clicked (line 574) | def on_new_file_menu_clicked(self, event=None):
    method on_save_menu_clicked (line 577) | def on_save_menu_clicked(self, event=None):
    method on_save_as_menu_clicked (line 580) | def on_save_as_menu_clicked(self):
    method on_canvas_zoom_out_menu_clicked (line 583) | def on_canvas_zoom_out_menu_clicked(self):
    method on_canvas_zoom_in_menu_clicked (line 586) | def on_canvas_zoom_in_menu_clicked(self):
    method on_close_menu_clicked (line 589) | def on_close_menu_clicked(self):
    method on_undo_menu_clicked (line 592) | def on_undo_menu_clicked(self, event=None):
    method on_about_menu_clicked (line 595) | def on_about_menu_clicked(self, event=None):

FILE: Chapter 06/6.09.py
  class PaintApplication (line 42) | class PaintApplication(framework.Framework):
    method on_new_file_menu_clicked (line 63) | def on_new_file_menu_clicked(self, event=None):
    method start_new_project (line 66) | def start_new_project(self):
    method on_save_menu_clicked (line 71) | def on_save_menu_clicked(self, event=None):
    method on_save_as_menu_clicked (line 77) | def on_save_as_menu_clicked(self):
    method actual_save (line 85) | def actual_save(self):
    method on_close_menu_clicked (line 89) | def on_close_menu_clicked(self):
    method close_window (line 92) | def close_window(self):
    method on_undo_menu_clicked (line 96) | def on_undo_menu_clicked(self, event=None):
    method undo (line 99) | def undo(self):
    method on_canvas_zoom_in_menu_clicked (line 107) | def on_canvas_zoom_in_menu_clicked(self):
    method on_canvas_zoom_out_menu_clicked (line 110) | def on_canvas_zoom_out_menu_clicked(self):
    method canvas_zoom_in (line 113) | def canvas_zoom_in(self):
    method canvas_zoom_out (line 117) | def canvas_zoom_out(self):
    method on_about_menu_clicked (line 121) | def on_about_menu_clicked(self, event=None):
    method draw_text_options (line 125) | def draw_text_options(self):
    method on_create_text_button_clicked (line 138) | def on_create_text_button_clicked(self):
    method delete_item (line 146) | def delete_item(self):
    method fill_item (line 150) | def fill_item(self):
    method fill_item_options (line 156) | def fill_item_options(self):
    method duplicate_item (line 160) | def duplicate_item(self):
    method get_all_configurations_for_item (line 170) | def get_all_configurations_for_item(self):
    method canvas_function_wrapper (line 177) | def canvas_function_wrapper(self, function_name, *arg, **kwargs):
    method move_to_top (line 181) | def move_to_top(self):
    method drag_item (line 185) | def drag_item(self):
    method drag_item_update_x_y (line 190) | def drag_item_update_x_y(self, event):
    method enlarge_item_size (line 195) | def enlarge_item_size(self):
    method reduce_item_size (line 201) | def reduce_item_size(self):
    method draw_irregular_line (line 207) | def draw_irregular_line(self):
    method draw_irregular_line_update_x_y (line 212) | def draw_irregular_line_update_x_y(self, event=None):
    method draw_irregular_line_options (line 217) | def draw_irregular_line_options(self):
    method on_tool_bar_button_clicked (line 221) | def on_tool_bar_button_clicked(self, button_index):
    method draw_super_shape (line 227) | def draw_super_shape(self):
    method draw_super_shape_options (line 233) | def draw_super_shape_options(self):
    method create_super_shapes_options_combobox (line 239) | def create_super_shapes_options_combobox(self):
    method set_selected_super_shape (line 250) | def set_selected_super_shape(self, event=None):
    method get_super_shape_points (line 253) | def get_super_shape_points(self, a, b, m, n1, n2, n3):
    method float_range (line 265) | def float_range(self, x, y, step):
    method set_foreground_color (line 270) | def set_foreground_color(self, event=None):
    method set_background_color (line 276) | def set_background_color(self, event=None):
    method get_color_from_chooser (line 282) | def get_color_from_chooser(self, initial_color, color_type="a"):
    method try_to_set_fill_after_palette_change (line 293) | def try_to_set_fill_after_palette_change(self):
    method try_to_set_outline_after_palette_change (line 299) | def try_to_set_outline_after_palette_change(self):
    method display_options_in_the_top_bar (line 305) | def display_options_in_the_top_bar(self):
    method draw_line_options (line 312) | def draw_line_options(self):
    method draw_oval_options (line 318) | def draw_oval_options(self):
    method draw_rectangle_options (line 323) | def draw_rectangle_options(self):
    method draw_arc_options (line 328) | def draw_arc_options(self):
    method draw_triangle_options (line 333) | def draw_triangle_options(self):
    method draw_star_options (line 338) | def draw_star_options(self):
    method create_fill_options_combobox (line 344) | def create_fill_options_combobox(self):
    method create_outline_options_combobox (line 353) | def create_outline_options_combobox(self):
    method create_number_of_spokes_options_combobox (line 363) | def create_number_of_spokes_options_combobox(self):
    method create_width_options_combobox (line 374) | def create_width_options_combobox(self):
    method create_dash_options_combobox (line 384) | def create_dash_options_combobox(self):
    method create_arrow_options_combobox (line 393) | def create_arrow_options_combobox(self):
    method set_fill (line 402) | def set_fill(self, event=None):
    method set_outline (line 413) | def set_outline(self, event=None):
    method set_width (line 424) | def set_width(self, event):
    method set_number_of_spokes (line 427) | def set_number_of_spokes(self, event):
    method set_arrow (line 430) | def set_arrow(self, event):
    method set_dash (line 433) | def set_dash(self, event):
    method create_color_palette (line 445) | def create_color_palette(self):
    method bind_color_palette (line 454) | def bind_color_palette(self):
    method create_current_coordinate_label (line 460) | def create_current_coordinate_label(self):
    method show_current_coordinates (line 466) | def show_current_coordinates(self, event=None):
    method function_not_defined (line 472) | def function_not_defined(self):
    method execute_selected_method (line 475) | def execute_selected_method(self):
    method draw_line (line 481) | def draw_line(self):
    method draw_oval (line 485) | def draw_oval(self):
    method draw_rectangle (line 489) | def draw_rectangle(self):
    method draw_arc (line 493) | def draw_arc(self):
    method draw_triangle (line 497) | def draw_triangle(self):
    method draw_star (line 512) | def draw_star(self):
    method create_tool_bar_buttons (line 530) | def create_tool_bar_buttons(self):
    method remove_options_from_top_bar (line 539) | def remove_options_from_top_bar(self):
    method show_selected_tool_icon_in_top_bar (line 543) | def show_selected_tool_icon_in_top_bar(self, function_name):
    method bind_mouse (line 552) | def bind_mouse(self):
    method on_mouse_button_pressed (line 560) | def on_mouse_button_pressed(self, event):
    method on_mouse_button_pressed_motion (line 565) | def on_mouse_button_pressed_motion(self, event):
    method on_mouse_button_released (line 571) | def on_mouse_button_released(self, event):
    method on_mouse_unpressed_motion (line 575) | def on_mouse_unpressed_motion(self, event):
    method __init__ (line 578) | def __init__(self, root):
    method create_gui (line 583) | def create_gui(self):
    method create_menu (line 595) | def create_menu(self):
    method create_top_bar (line 605) | def create_top_bar(self):
    method create_tool_bar (line 609) | def create_tool_bar(self):
    method create_drawing_canvas (line 613) | def create_drawing_canvas(self):
    method create_scroll_bar (line 621) | def create_scroll_bar(self):
    method bind_menu_accelrator_keys (line 631) | def bind_menu_accelrator_keys(self):

FILE: Chapter 06/framework.py
  class Framework (line 10) | class Framework():
    method __init__ (line 39) | def __init__(self, root):
    method build_menu (line 42) | def build_menu(self, menu_definitions):
    method _add_menu_command (line 53) | def _add_menu_command(self, menu, item):
  class TestThisFramework (line 67) | class TestThisFramework(Framework):
    method new_file (line 69) | def new_file(self):
    method open_file (line 72) | def open_file(self):
    method undo (line 75) | def undo(self):
    method options (line 78) | def options(self):
    method about (line 81) | def about(self):

FILE: Chapter 07/7.01/view.py
  class PianoTutor (line 11) | class PianoTutor:
    method __init__ (line 13) | def __init__(self, root):
    method build_mode_selector_frame (line 25) | def build_mode_selector_frame(self):
    method build_score_sheet_frame (line 44) | def build_score_sheet_frame(self):
    method build_controls_frame (line 52) | def build_controls_frame(self):
    method build_keyboard_frame (line 59) | def build_keyboard_frame(self):
    method build_scales_frame (line 68) | def build_scales_frame(self):
    method build_chords_frame (line 77) | def build_chords_frame(self):
    method build_progressions_frame (line 87) | def build_progressions_frame(self):
    method on_mode_changed (line 97) | def on_mode_changed(self, event):
    method show_scales_frame (line 106) | def show_scales_frame(self):
    method show_chords_frame (line 111) | def show_chords_frame(self):
    method show_progressions_frame (line 116) | def show_progressions_frame(self):
  function run (line 122) | def run():

FILE: Chapter 07/7.02/view.py
  class PianoTutor (line 25) | class PianoTutor:
    method __init__ (line 27) | def __init__(self, root):
    method build_mode_selector_frame (line 40) | def build_mode_selector_frame(self):
    method build_score_sheet_frame (line 59) | def build_score_sheet_frame(self):
    method build_controls_frame (line 67) | def build_controls_frame(self):
    method build_keyboard_frame (line 74) | def build_keyboard_frame(self):
    method build_scales_frame (line 87) | def build_scales_frame(self):
    method build_chords_frame (line 96) | def build_chords_frame(self):
    method build_progressions_frame (line 106) | def build_progressions_frame(self):
    method on_mode_changed (line 116) | def on_mode_changed(self, event):
    method show_scales_frame (line 125) | def show_scales_frame(self):
    method show_chords_frame (line 130) | def show_chords_frame(self):
    method show_progressions_frame (line 135) | def show_progressions_frame(self):
    method create_key (line 140) | def create_key(self, img, key_name, x_coordinate):
    method change_image_to_pressed (line 151) | def change_image_to_pressed(self, event):
    method change_image_to_unpressed (line 160) | def change_image_to_unpressed(self, event):
    method on_key_pressed (line 169) | def on_key_pressed(self, event):
    method on_key_released (line 173) | def on_key_released(self, event):
  function run (line 178) | def run():

FILE: Chapter 07/7.03/audio.py
  function play_note (line 5) | def play_note(note_name):
  function play_scale (line 9) | def play_scale(scale):
  function play_scale_in_new_thread (line 14) | def play_scale_in_new_thread(scale):
  function play_chord (line 17) | def play_chord(scale):
  function play_chord_in_new_thread (line 21) | def play_chord_in_new_thread(chord):

FILE: Chapter 07/7.03/view.py
  class PianoTutor (line 21) | class PianoTutor:
    method __init__ (line 23) | def __init__(self, root):
    method build_mode_selector_frame (line 36) | def build_mode_selector_frame(self):
    method build_score_sheet_frame (line 55) | def build_score_sheet_frame(self):
    method build_controls_frame (line 63) | def build_controls_frame(self):
    method build_keyboard_frame (line 70) | def build_keyboard_frame(self):
    method build_scales_frame (line 83) | def build_scales_frame(self):
    method build_chords_frame (line 92) | def build_chords_frame(self):
    method build_progressions_frame (line 102) | def build_progressions_frame(self):
    method on_mode_changed (line 112) | def on_mode_changed(self, event):
    method show_scales_frame (line 121) | def show_scales_frame(self):
    method show_chords_frame (line 126) | def show_chords_frame(self):
    method show_progressions_frame (line 131) | def show_progressions_frame(self):
    method create_key (line 136) | def create_key(self, img, key_name, x_coordinate):
    method change_image_to_pressed (line 147) | def change_image_to_pressed(self, event):
    method change_image_to_unpressed (line 156) | def change_image_to_unpressed(self, event):
    method on_key_pressed (line 165) | def on_key_pressed(self, event):
    method on_key_released (line 169) | def on_key_released(self, event):
  function run (line 174) | def run():

FILE: Chapter 07/7.04/audio.py
  function play_note (line 5) | def play_note(note_name):
  function play_scale (line 9) | def play_scale(scale):
  function play_scale_in_new_thread (line 14) | def play_scale_in_new_thread(scale):
  function play_chord (line 17) | def play_chord(scale):
  function play_chord_in_new_thread (line 21) | def play_chord_in_new_thread(chord):

FILE: Chapter 07/7.04/view.py
  class PianoTutor (line 29) | class PianoTutor:
    method __init__ (line 31) | def __init__(self, root):
    method load_json_files (line 47) | def load_json_files(self):
    method on_scale_changed (line 52) | def on_scale_changed(self, event):
    method on_scale_key_changed (line 56) | def on_scale_key_changed(self, event):
    method find_scale (line 60) | def find_scale(self, event=None):
    method highlight_list_of_keys (line 69) | def highlight_list_of_keys(self, key_names):
    method highlight_key (line 73) | def highlight_key(self, key_name):
    method remove_key_highlight (line 84) | def remove_key_highlight(self, key_name):
    method remove_all_key_highlights (line 95) | def remove_all_key_highlights(self):
    method build_mode_selector_frame (line 103) | def build_mode_selector_frame(self):
    method build_score_sheet_frame (line 122) | def build_score_sheet_frame(self):
    method build_controls_frame (line 130) | def build_controls_frame(self):
    method build_keyboard_frame (line 136) | def build_keyboard_frame(self):
    method build_scales_frame (line 149) | def build_scales_frame(self):
    method build_chords_frame (line 177) | def build_chords_frame(self):
    method build_progressions_frame (line 187) | def build_progressions_frame(self):
    method on_mode_changed (line 196) | def on_mode_changed(self, event):
    method show_scales_frame (line 205) | def show_scales_frame(self):
    method show_chords_frame (line 210) | def show_chords_frame(self):
    method show_progressions_frame (line 215) | def show_progressions_frame(self):
    method create_key (line 220) | def create_key(self, img, key_name, x_coordinate):
    method change_image_to_pressed (line 231) | def change_image_to_pressed(self, event):
    method change_image_to_unpressed (line 240) | def change_image_to_unpressed(self, event):
    method on_key_pressed (line 249) | def on_key_pressed(self, event):
    method on_key_released (line 253) | def on_key_released(self, event):
  function run (line 258) | def run():

FILE: Chapter 07/7.05/audio.py
  function play_note (line 5) | def play_note(note_name):
  function play_scale (line 9) | def play_scale(scale):
  function play_scale_in_new_thread (line 14) | def play_scale_in_new_thread(scale):
  function play_chord (line 17) | def play_chord(scale):
  function play_chord_in_new_thread (line 21) | def play_chord_in_new_thread(chord):

FILE: Chapter 07/7.05/view.py
  class PianoTutor (line 31) | class PianoTutor:
    method __init__ (line 33) | def __init__(self, root):
    method load_json_files (line 49) | def load_json_files(self):
    method on_chord_changed (line 55) | def on_chord_changed(self, event):
    method on_chords_key_changed (line 59) | def on_chords_key_changed(self, event):
    method find_chord (line 63) | def find_chord(self, event=None):
    method on_scale_changed (line 74) | def on_scale_changed(self, event):
    method on_scale_key_changed (line 78) | def on_scale_key_changed(self, event):
    method find_scale (line 82) | def find_scale(self, event=None):
    method highlight_list_of_keys (line 91) | def highlight_list_of_keys(self, key_names):
    method highlight_key (line 95) | def highlight_key(self, key_name):
    method remove_key_highlight (line 106) | def remove_key_highlight(self, key_name):
    method remove_all_key_highlights (line 117) | def remove_all_key_highlights(self):
    method build_mode_selector_frame (line 125) | def build_mode_selector_frame(self):
    method build_score_sheet_frame (line 144) | def build_score_sheet_frame(self):
    method build_controls_frame (line 152) | def build_controls_frame(self):
    method build_keyboard_frame (line 158) | def build_keyboard_frame(self):
    method build_scales_frame (line 171) | def build_scales_frame(self):
    method build_chords_frame (line 199) | def build_chords_frame(self):
    method build_progressions_frame (line 226) | def build_progressions_frame(self):
    method on_mode_changed (line 235) | def on_mode_changed(self, event):
    method show_scales_frame (line 247) | def show_scales_frame(self):
    method show_chords_frame (line 252) | def show_chords_frame(self):
    method show_progressions_frame (line 257) | def show_progressions_frame(self):
    method create_key (line 262) | def create_key(self, img, key_name, x_coordinate):
    method change_image_to_pressed (line 273) | def change_image_to_pressed(self, event):
    method change_image_to_unpressed (line 282) | def change_image_to_unpressed(self, event):
    method on_key_pressed (line 291) | def on_key_pressed(self, event):
    method on_key_released (line 295) | def on_key_released(self, event):
  function run (line 300) | def run():

FILE: Chapter 07/7.06/audio.py
  function play_note (line 5) | def play_note(note_name):
  function play_scale (line 9) | def play_scale(scale):
  function play_scale_in_new_thread (line 14) | def play_scale_in_new_thread(scale):
  function play_chord (line 17) | def play_chord(scale):
  function play_chord_in_new_thread (line 21) | def play_chord_in_new_thread(chord):

FILE: Chapter 07/7.06/view.py
  class PianoTutor (line 40) | class PianoTutor:
    method __init__ (line 42) | def __init__(self, root):
    method load_json_files (line 59) | def load_json_files(self):
    method on_progression_scale_changed (line 68) | def on_progression_scale_changed(self, event):
    method on_progression_key_changed (line 77) | def on_progression_key_changed(self, event):
    method on_progression_changed (line 80) | def on_progression_changed(self, event):
    method destroy_current_progression_buttons (line 83) | def destroy_current_progression_buttons(self):
    method show_progression_buttons (line 87) | def show_progression_buttons(self):
    method on_progression_button_clicked (line 104) | def on_progression_button_clicked(self, i):
    method on_chord_changed (line 121) | def on_chord_changed(self, event):
    method on_chords_key_changed (line 125) | def on_chords_key_changed(self, event):
    method find_chord (line 129) | def find_chord(self, event=None):
    method on_scale_changed (line 139) | def on_scale_changed(self, event):
    method on_scale_key_changed (line 143) | def on_scale_key_changed(self, event):
    method find_scale (line 147) | def find_scale(self, event=None):
    method highlight_list_of_keys (line 157) | def highlight_list_of_keys(self, key_names):
    method highlight_key (line 161) | def highlight_key(self, key_name):
    method remove_key_highlight (line 172) | def remove_key_highlight(self, key_name):
    method remove_all_key_highlights (line 183) | def remove_all_key_highlights(self):
    method build_mode_selector_frame (line 188) | def build_mode_selector_frame(self):
    method build_score_sheet_frame (line 201) | def build_score_sheet_frame(self):
    method build_controls_frame (line 210) | def build_controls_frame(self):
    method build_keyboard_frame (line 216) | def build_keyboard_frame(self):
    method build_scales_frame (line 229) | def build_scales_frame(self):
    method build_chords_frame (line 253) | def build_chords_frame(self):
    method build_progressions_frame (line 278) | def build_progressions_frame(self):
    method on_mode_changed (line 316) | def on_mode_changed(self, event):
    method show_scales_frame (line 329) | def show_scales_frame(self):
    method show_chords_frame (line 334) | def show_chords_frame(self):
    method show_progressions_frame (line 339) | def show_progressions_frame(self):
    method create_key (line 344) | def create_key(self, img, key_name, x_coordinate):
    method change_image_to_pressed (line 355) | def change_image_to_pressed(self, event):
    method change_image_to_unpressed (line 364) | def change_image_to_unpressed(self, event):
    method on_key_pressed (line 373) | def on_key_pressed(self, event):
    method on_key_released (line 377) | def on_key_released(self, event):
  function run (line 381) | def run():

FILE: Chapter 07/7.07/audio.py
  function play_note (line 5) | def play_note(note_name):
  function play_scale (line 9) | def play_scale(scale):
  function play_scale_in_new_thread (line 14) | def play_scale_in_new_thread(scale):
  function play_chord (line 17) | def play_chord(scale):
  function play_chord_in_new_thread (line 21) | def play_chord_in_new_thread(chord):

FILE: Chapter 07/7.07/score_maker.py
  class ScoreMaker (line 4) | class ScoreMaker:
    method __init__ (line 9) | def __init__(self, container):
    method _clean_score_sheet (line 19) | def _clean_score_sheet(self):
    method _create_treble_staff (line 24) | def _create_treble_staff(self):
    method draw_chord (line 29) | def draw_chord(self, chord):
    method _draw_five_lines (line 36) | def _draw_five_lines(self):
    method draw_notes (line 45) | def draw_notes(self, notes):
    method _draw_single_note (line 51) | def _draw_single_note(self, note, is_in_chord=False):

FILE: Chapter 07/7.07/view.py
  class PianoTutor (line 28) | class PianoTutor:
    method __init__ (line 30) | def __init__(self, root):
    method load_json_files (line 47) | def load_json_files(self):
    method on_progression_scale_changed (line 56) | def on_progression_scale_changed(self, event):
    method on_progression_key_changed (line 65) | def on_progression_key_changed(self, event):
    method on_progression_changed (line 68) | def on_progression_changed(self, event):
    method destroy_current_progression_buttons (line 71) | def destroy_current_progression_buttons(self):
    method show_progression_buttons (line 75) | def show_progression_buttons(self):
    method on_progression_button_clicked (line 92) | def on_progression_button_clicked(self, i):
    method on_chord_changed (line 110) | def on_chord_changed(self, event):
    method on_chords_key_changed (line 114) | def on_chords_key_changed(self, event):
    method find_chord (line 118) | def find_chord(self, event=None):
    method on_scale_changed (line 129) | def on_scale_changed(self, event):
    method on_scale_key_changed (line 133) | def on_scale_key_changed(self, event):
    method find_scale (line 137) | def find_scale(self, event=None):
    method highlight_list_of_keys (line 148) | def highlight_list_of_keys(self, key_names):
    method highlight_key (line 152) | def highlight_key(self, key_name):
    method remove_key_highlight (line 163) | def remove_key_highlight(self, key_name):
    method remove_all_key_highlights (line 174) | def remove_all_key_highlights(self):
    method build_mode_selector_frame (line 179) | def build_mode_selector_frame(self):
    method build_score_sheet_frame (line 192) | def build_score_sheet_frame(self):
    method build_controls_frame (line 201) | def build_controls_frame(self):
    method build_keyboard_frame (line 207) | def build_keyboard_frame(self):
    method build_scales_frame (line 220) | def build_scales_frame(self):
    method build_chords_frame (line 244) | def build_chords_frame(self):
    method build_progressions_frame (line 269) | def build_progressions_frame(self):
    method on_mode_changed (line 307) | def on_mode_changed(self, event):
    method show_scales_frame (line 320) | def show_scales_frame(self):
    method show_chords_frame (line 325) | def show_chords_frame(self):
    method show_progressions_frame (line 330) | def show_progressions_frame(self):
    method create_key (line 335) | def create_key(self, img, key_name, x_coordinate):
    method change_image_to_pressed (line 346) | def change_image_to_pressed(self, event):
    method change_image_to_unpressed (line 355) | def change_image_to_unpressed(self, event):
    method on_key_pressed (line 364) | def on_key_pressed(self, event):
    method on_key_released (line 368) | def on_key_released(self, event):
  function run (line 372) | def run():

FILE: Chapter 07/handle_widget_resize.py
  function on_label_resized (line 19) | def on_label_resized(event):

FILE: Chapter 08/8.01_screensaver.py
  class RandomBall (line 12) | class RandomBall:
    method __init__ (line 14) | def __init__(self, canvas):
    method create_ball (line 20) | def create_ball(self):
    method generate_random_attributes (line 24) | def generate_random_attributes(self):
    method generate_random_color (line 32) | def generate_random_color(self):
    method create_oval (line 36) | def create_oval(self):
    method move_ball (line 44) | def move_ball(self):
    method check_screen_bounds (line 50) | def check_screen_bounds(self):
  class ScreenSaver (line 58) | class ScreenSaver:
    method __init__ (line 62) | def __init__(self, number_of_balls):
    method create_screensaver (line 72) | def create_screensaver(self):
    method create_canvas (line 77) | def create_canvas(self):
    method add_balls_to_canvas (line 81) | def add_balls_to_canvas(self):
    method quit_on_interaction (line 85) | def quit_on_interaction(self):
    method animate_balls (line 89) | def animate_balls(self):
    method quit_screensaver (line 94) | def quit_screensaver(self, event):

FILE: Chapter 08/8.02_pie_chart.py
  function angle (line 14) | def angle(n):

FILE: Chapter 08/8.04_scatter_plot.py
  function motion (line 13) | def motion(event):

FILE: Chapter 08/8.06_polar_plot.py
  function polar_to_cartesian (line 16) | def polar_to_cartesian(r, theta, scaling_factor, x_center, y_center):

FILE: Chapter 08/8.07_gravity_simulation.py
  class Planet (line 19) | class Planet:
    method __init__ (line 23) | def __init__(self, name, mass, distance, radius, color, canvas):
    method distance_scaler (line 36) | def distance_scaler(self, value):
    method radius_scaler (line 41) | def radius_scaler(self, value):
    method draw_initial_planet (line 45) | def draw_initial_planet(self):
    method gravitational_force (line 60) | def gravitational_force(self):
    method angular_position (line 64) | def angular_position(self, t):
    method coordinates (line 68) | def coordinates(self, theta):
    method update_location (line 74) | def update_location(self, t):
  class Moon (line 83) | class Moon(Planet):
    method __init__ (line 86) | def __init__(self, name, mass, distance, radius, color, canvas, earth):
    method gravitational_force (line 94) | def gravitational_force(self):
    method coordinates (line 98) | def coordinates(self, t):
    method update_location (line 106) | def update_location(self, t):
  function update_bodies_position (line 126) | def update_bodies_position():

FILE: Chapter 08/8.08_Mandelbrot.py
  function mandelbrot_set_check (line 19) | def mandelbrot_set_check(real, imaginary):
  function get_color (line 32) | def get_color(num_iterations):
  function map_pixels_to_real (line 55) | def map_pixels_to_real(x):
  function map_pixels_to_imaginary (line 60) | def map_pixels_to_imaginary(y):

FILE: Chapter 08/8.09_vornoi_diagram.py
  function create_voronoi_diagram (line 17) | def create_voronoi_diagram(canvas, w, h, number_of_attractor_points):

FILE: Chapter 08/8.10_spring_pendulum.py
  function differential_functions (line 21) | def differential_functions(state_vector, time):
  function update_graph (line 51) | def update_graph():

FILE: Chapter 08/8.11_chaos_game.py
  function midway_point (line 25) | def midway_point(p1, p2):
  function random_point_inside_triangle (line 31) | def random_point_inside_triangle(v1, v2, v3):
  function get_next_point (line 44) | def get_next_point():
  function update (line 57) | def update():

FILE: Chapter 08/8.12_phyllotaxis.py
  function update (line 41) | def update():

FILE: Chapter 08/8.13_3D_graphics.py
  class MatrixHelpers (line 11) | class MatrixHelpers:
    method transpose_matrix (line 12) | def transpose_matrix(self, matrix):
    method translate_vector (line 15) | def translate_vector(self, x, y, dx, dy):
    method matrix_multiply (line 18) | def matrix_multiply(self, matrix_a, matrix_b):
    method rotate_along_x (line 25) | def rotate_along_x(self, x, shape):
    method rotate_along_y (line 29) | def rotate_along_y(self, y, shape):
    method rotate_along_z (line 33) | def rotate_along_z(self, z, shape):
  class Cube (line 38) | class Cube(MatrixHelpers):
    method __init__ (line 45) | def __init__(self, root):
    method init_data (line 54) | def init_data(self):
    method create_canvas (line 60) | def create_canvas(self):
    method bind_mouse_buttons (line 65) | def bind_mouse_buttons(self):
    method draw_cube (line 69) | def draw_cube(self):
    method continually_rotate (line 82) | def continually_rotate(self):
    method on_mouse_clicked (line 89) | def on_mouse_clicked(self, event):
    method on_mouse_motion (line 93) | def on_mouse_motion(self, event):
  function main (line 102) | def main():

FILE: Chapter 09/9.01_race_condition.py
  class RaceConditionDemo (line 10) | class RaceConditionDemo:
    method __init__ (line 12) | def __init__(self):
    method increment (line 17) | def increment(self):
    method decrement (line 21) | def decrement(self):
    method demo_of_race_condition (line 25) | def demo_of_race_condition(self):

FILE: Chapter 09/9.02_lock_demo.py
  class LockDemo (line 10) | class LockDemo():
    method __init__ (line 12) | def __init__(self):
    method increment (line 18) | def increment(self):
    method decrement (line 24) | def decrement(self):
    method demo_of_lock_to_avoid_race_condition (line 30) | def demo_of_lock_to_avoid_race_condition(self):

FILE: Chapter 09/9.03_threading_with queue.py
  class Consumer (line 11) | class Consumer(threading.Thread):
    method __init__ (line 13) | def __init__(self, queue):
    method run (line 17) | def run(self):
    method do_task (line 22) | def do_task(self, task):
  function producer (line 27) | def producer(tasks):

FILE: Chapter 09/9.04_game_of_ snake.py
  class View (line 13) | class View(Tk):
    method __init__ (line 15) | def __init__(self, queue):
    method create_gui (line 21) | def create_gui(self):
    method queue_handler (line 31) | def queue_handler(self):
    method game_over (line 49) | def game_over(self):
  class Food (line 55) | class Food:
    method __init__ (line 57) | def __init__(self, queue):
    method generate_food (line 61) | def generate_food(self):
  class Snake (line 69) | class Snake(threading.Thread):
    method __init__ (line 72) | def __init__(self, queue):
    method run (line 83) | def run(self):
    method on_keypress (line 89) | def on_keypress(self, e):
    method move (line 92) | def move(self):
    method calculate_new_coordinates (line 103) | def calculate_new_coordinates(self):
    method check_game_over (line 115) | def check_game_over(self, snake_point):
  function main (line 122) | def main():

FILE: Chapter 09/9.06_weather_ reporter.py
  class WeatherReporter (line 16) | class WeatherReporter:
    method __init__ (line 21) | def __init__(self, root):
    method create_top_frame (line 26) | def create_top_frame(self):
    method create_weather_display_frame (line 35) | def create_weather_display_frame(self):
    method on_show_weather_button_clicked (line 41) | def on_show_weather_button_clicked(self):
    method get_weather_data (line 49) | def get_weather_data(self):
    method clear_canvas (line 53) | def clear_canvas(self):
    method format_data (line 57) | def format_data(self):
    method kelvin_to_celsius (line 78) | def kelvin_to_celsius(self, k):
    method kelvin_to_fahrenheit (line 81) | def kelvin_to_fahrenheit(self, k):
    method str2num (line 84) | def str2num(self, string, precision):
    method display_data (line 87) | def display_data(self):
    method time_stamp_to_time (line 137) | def time_stamp_to_time(self, ts):
    method time_stamp_to_data (line 140) | def time_stamp_to_data(self, ts):
    method get_data_from_url (line 143) | def get_data_from_url(self):
    method json_to_dict (line 159) | def json_to_dict(self, json_data):
  function main (line 176) | def main():

FILE: Chapter 09/9.08_port_scanner.py
  class PortScanner (line 12) | class PortScanner():
    method __init__ (line 19) | def __init__(self, root):
    method on_scan_button_clicked (line 23) | def on_scan_button_clicked(self):
    method empty_console (line 27) | def empty_console(self):
    method scan_in_a_new_thread (line 32) | def scan_in_a_new_thread(self):
    method start_scan (line 40) | def start_scan(self, url, start_port, end_port):
    method is_port_open (line 49) | def is_port_open(self, url, port):
    method on_stop_button_clicked (line 59) | def on_stop_button_clicked(self):
    method output_to_console (line 62) | def output_to_console(self, new_text):
    method create_gui (line 68) | def create_gui(self):

FILE: Chapter 09/9.09_chat_server.py
  class ChatServer (line 10) | class ChatServer:
    method __init__ (line 16) | def __init__(self):
    method create_listening_server (line 19) | def create_listening_server(self):
    method receive_messages (line 29) | def receive_messages(self, so):
    method broadcast_to_all_clients (line 38) | def broadcast_to_all_clients(self, senders_socket):
    method receive_messages_in_a_new_thread (line 44) | def receive_messages_in_a_new_thread(self):
    method add_to_clients_list (line 52) | def add_to_clients_list(self, client):

FILE: Chapter 09/9.10_chat_client.py
  class ChatClient (line 16) | class ChatClient:
    method __init__ (line 21) | def __init__(self, root):
    method initialize_socket (line 27) | def initialize_socket(self):
    method initialize_gui (line 33) | def initialize_gui(self):
    method listen_for_incoming_messages_in_a_thread (line 38) | def listen_for_incoming_messages_in_a_thread(self):
    method recieve_message_from_server (line 43) | def recieve_message_from_server(self, so):
    method display_name_section (line 52) | def display_name_section(self):
    method display_chat_transcript (line 59) | def display_chat_transcript(self):
    method display_chat_entrybox (line 71) | def display_chat_entrybox(self):
    method on_enter_key_pressed (line 83) | def on_enter_key_pressed(self, event):
    method clear_text (line 91) | def clear_text(self):
    method send_chat (line 94) | def send_chat(self):

FILE: Chapter 09/9.11_phonebook.py
  class PhoneBook (line 12) | class PhoneBook:
    method __init__ (line 16) | def __init__(self, root):
    method execute_db_query (line 20) | def execute_db_query(self, query, parameters=()):
    method create_gui (line 27) | def create_gui(self):
    method create_left_icon (line 35) | def create_left_icon(self):
    method create_label_frame (line 41) | def create_label_frame(self):
    method create_message_area (line 54) | def create_message_area(self):
    method create_tree_view (line 58) | def create_tree_view(self):
    method create_bottom_buttons (line 64) | def create_bottom_buttons(self):
    method on_add_record_button_clicked (line 70) | def on_add_record_button_clicked(self):
    method on_delete_selected_button_clicked (line 73) | def on_delete_selected_button_clicked(self):
    method on_modify_selected_button_clicked (line 82) | def on_modify_selected_button_clicked(self):
    method add_new_record (line 91) | def add_new_record(self):
    method new_records_validated (line 104) | def new_records_validated(self):
    method view_records (line 107) | def view_records(self):
    method delete_record (line 116) | def delete_record(self):
    method open_modify_window (line 124) | def open_modify_window(self):
    method update_record (line 142) | def update_record(self, newphone, old_phone_number, name):

FILE: Chapter 09/9.12_async_demo.py
  function asyncio_thread (line 7) | def asyncio_thread(event_loop):
  function execute_tasks_in_a_new_thread (line 12) | def execute_tasks_in_a_new_thread(event_loop):
  function simulate_fetch_one_url (line 17) | async def simulate_fetch_one_url(url):
  function simulate_fetch_all_urls (line 24) | async def simulate_fetch_all_urls():
  function check_if_button_freezed (line 32) | def check_if_button_freezed():
  function main (line 38) | def main(event_loop):

FILE: Chapter 09/9.14_read_from_serial_port.py
  function read_serial_data (line 18) | def read_serial_data():

FILE: Chapter 10/10.01_trace_variable.py
  function trace_when_my_variable_written (line 13) | def trace_when_my_variable_written(var, indx, mode):

FILE: Chapter 10/10.02_widget_traversal.py
  class TraversalDemo (line 10) | class TraversalDemo:
    method __init__ (line 12) | def __init__(self, root):

FILE: Chapter 10/10.03_validation_mode_demo.py
  class ValidateModeDemo (line 10) | class ValidateModeDemo():
    method __init__ (line 12) | def __init__(self):
    method validate_data (line 45) | def validate_data(self, v):

FILE: Chapter 10/10.04_percent _substitutions _demo.py
  class PercentSubstitutionsDemo (line 11) | class PercentSubstitutionsDemo():
    method __init__ (line 13) | def __init__(self):
    method validate (line 21) | def validate(self, d, i, P, s, S, v, V, W):

FILE: Chapter 10/10.05_key_validation.py
  class KeyValidationDemo (line 10) | class KeyValidationDemo():
    method __init__ (line 12) | def __init__(self):
    method validate_data (line 24) | def validate_data(self, S):
    method invalid_name (line 29) | def invalid_name(self, S):

FILE: Chapter 10/10.06_focus_out _validation.py
  class FocusOutValidationDemo (line 10) | class FocusOutValidationDemo():
    method __init__ (line 12) | def __init__(self):
    method validate_email (line 25) | def validate_email(self, P):
    method invalid_email (line 30) | def invalid_email(self, P):

FILE: Chapter 10/10.07_formatting_entry_widget_to_display_date.py
  class FormatEntryWidgetDemo (line 9) | class FormatEntryWidgetDemo:
    method __init__ (line 11) | def __init__(self, root):
    method format_date_entry_widget (line 20) | def format_date_entry_widget(self, event):

FILE: Chapter 10/10.10_font_selector.py
  class FontSelectorDemo (line 10) | class FontSelectorDemo():
    method __init__ (line 12) | def __init__(self):
    method gui_creator (line 23) | def gui_creator(self):
    method on_value_change (line 58) | def on_value_change(self, event=None):
Condensed preview — 203 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (822K chars).
[
  {
    "path": "Chapter 01/1.01.py",
    "chars": 182,
    "preview": "\"\"\"\nCode illustration: 1.01\nYour first GUI application - the top level window\nTkinter GUI Application Development Bluepr"
  },
  {
    "path": "Chapter 01/1.02.py",
    "chars": 312,
    "preview": "\"\"\"\nCode illustration: 1.02\nAdding some widgets\nTkinter GUI Application Development Blueprints\n\"\"\"\n\nimport tkinter as tk"
  },
  {
    "path": "Chapter 01/1.03.py",
    "chars": 5330,
    "preview": "\"\"\"\r\nCode illustration: 01.03\r\nA demonstration of all core tkinter widgets\r\nTkinter GUI Application Development Blueprin"
  },
  {
    "path": "Chapter 01/1.04.py",
    "chars": 975,
    "preview": "\"\"\"\nCode illustration: 1.04\nA demonstration of some of pack() options\nTkinter GUI Application Development Blueprints\n\"\"\""
  },
  {
    "path": "Chapter 01/1.05.py",
    "chars": 581,
    "preview": "\"\"\"\nCode illustration: 1.05\nWhere to use pack() options\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\n\nimport tki"
  },
  {
    "path": "Chapter 01/1.06.py",
    "chars": 452,
    "preview": "\"\"\"\nCode illustration: 1.06\nSimple example of grid Geometry Manager\n\n@Tkinter GUI Application Development Blueprints\n\"\"\""
  },
  {
    "path": "Chapter 01/1.07.py",
    "chars": 1406,
    "preview": "\"\"\"\nCode illustration: 1.07\nA demonstration of grid() geometry manager options\n@Tkinter GUI Application Development Blue"
  },
  {
    "path": "Chapter 01/1.08.py",
    "chars": 393,
    "preview": "\"\"\"\nCode illustration: 1.08\nA demonstration of common place() options\n\n@Tkinter GUI Application Development Blueprints\n\""
  },
  {
    "path": "Chapter 01/1.09.py",
    "chars": 520,
    "preview": "\"\"\"\nCode illustration: 1.09\nA demonstration of event binding with the bind() method\n\n@Tkinter GUI Application Developmen"
  },
  {
    "path": "Chapter 01/1.10.py",
    "chars": 2333,
    "preview": "\"\"\"\nCode illustration: 1.10\nA demonstration of events and the information available in it.\n\n@Tkinter GUI Application Dev"
  },
  {
    "path": "Chapter 01/1.11.py",
    "chars": 1166,
    "preview": "\"\"\"\nCode illustration: 1.11\nA demonstration of tkinter Variable Class\nIntVar, StringVar & BooleanVar\n\n@Tkinter GUI Appli"
  },
  {
    "path": "Chapter 01/1.12.py",
    "chars": 1390,
    "preview": "\"\"\"\nCode illustration: 1.12\nA demonstration of tkinter styling\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\n\nimp"
  },
  {
    "path": "Chapter 01/gir.xbm",
    "chars": 36173,
    "preview": "#define 1026234pirate_width 226\n#define 1026234pirate_height 199\nstatic char 1026234pirate_bits[] = {\n  0x00, 0x00, 0x00"
  },
  {
    "path": "Chapter 01/optionDB.txt",
    "chars": 95,
    "preview": "*Button*borderwidth:3\n*Button*relief: raised\n*Button*width: 3\n*Button*height: 1\n*Button*pady:3\n"
  },
  {
    "path": "Chapter 01/readme.txt",
    "chars": 923,
    "preview": "====================================================================\nCode Readme\nTkinter GUI Application Development Blu"
  },
  {
    "path": "Chapter 01/textcontent.txt",
    "chars": 600,
    "preview": "I am a text-widget.\nTkinter includes 21 core widgets. This program demonstrates all of them.\n\nSee if you can identify al"
  },
  {
    "path": "Chapter 02/2.01.py",
    "chars": 781,
    "preview": "\"\"\"\nCode illustration: 2.01\nText Editor Code\nStep 1: Adding Top-level\nStep 2: Add Menubuttons\n\n@Tkinter GUI Application "
  },
  {
    "path": "Chapter 02/2.02.py",
    "chars": 3454,
    "preview": "\"\"\"\nCode illustration: 2.02\nText Editor Code\nStep 3: Adding  Menu items to each menu\nStep 4: Adding labels to hold short"
  },
  {
    "path": "Chapter 02/2.03.py",
    "chars": 4466,
    "preview": "\"\"\"\nCode illustration: 2.03\n\nAdding View Menu Items to demonstrate\nother Types of Menu Items\n    1. Checkbutton menu-ite"
  },
  {
    "path": "Chapter 02/2.04.py",
    "chars": 4789,
    "preview": "\"\"\"\nCode illustration: 2.04\n\nleveraging Text widget built-in options for\n    1. Cut\n    2. Copy\n    3. Paste\n    4. Undo"
  },
  {
    "path": "Chapter 02/2.05.py",
    "chars": 7052,
    "preview": "\"\"\"\nCode illustration: 2.05\n\nText Widget Indexing and Tagging explained using\nimplementation of:\n    1. select_all\n    2"
  },
  {
    "path": "Chapter 02/2.06.py",
    "chars": 1184,
    "preview": "\"\"\"\nCode illustration: 2.06\nA demonstration of different types of top-level window\n\n@Tkinter GUI Application Development"
  },
  {
    "path": "Chapter 02/2.07.py",
    "chars": 9063,
    "preview": "\"\"\"\nCode illustration: 2.07\n\nAdding features:\n    File > New\n    File > Open\n    File > Save\n    File > Save As\n\n\n@Tkint"
  },
  {
    "path": "Chapter 02/2.08.py",
    "chars": 1421,
    "preview": "\"\"\"\nCode illustration: 2.08\nA demonstration of tkinter.messagebox\nshowinfo\nshowwarning\nshowerror\naskquestion\naskokcancel"
  },
  {
    "path": "Chapter 02/2.09.py",
    "chars": 9720,
    "preview": "\"\"\"\nCode illustration: 2.09\n\nAdding:\n    About, Help Message Box\n    'Really Quit ?' Prompt  to exit button\n\n@Tkinter GU"
  },
  {
    "path": "Chapter 02/2.10.py",
    "chars": 11301,
    "preview": "\"\"\"\nCode illustration: 2.10\n\nAdding Shortcut Icons toolbar\nDisplaying Line Numbers\nHighlighting Current Line\n\n\n@Tkinter "
  },
  {
    "path": "Chapter 02/2.11.py",
    "chars": 12578,
    "preview": "\"\"\"\nCode illustration: 2.11\n\nAdding cursor location info at bottom\nAdding Color Theme\n\n@Tkinter GUI Application Developm"
  },
  {
    "path": "Chapter 02/2.12.py",
    "chars": 12849,
    "preview": "\"\"\"\nCode illustration: 2.12.py\nFeatures Added:\n    Add context/ Pop-up Menu\n    Set focus on launch\n\n@Tkinter GUI Applic"
  },
  {
    "path": "Chapter 02/readme.txt",
    "chars": 1006,
    "preview": "====================================================================\nCode Readme\nTkinter GUI Application Development Blu"
  },
  {
    "path": "Chapter 03/3.01.py",
    "chars": 425,
    "preview": "\"\"\"\nCode illustration: 3.01\n    - Creating OOP Based GUI structure\n\nChapter 3 : Programmable Drum Machine\nTkinter GUI Ap"
  },
  {
    "path": "Chapter 03/3.02.py",
    "chars": 1394,
    "preview": "\"\"\"\nCode illustration: 3.02\n    - Defining & Initializing the Data Structure\n\nChapter 3 : Programmable Drum Machine\nTkin"
  },
  {
    "path": "Chapter 03/3.03.py",
    "chars": 9859,
    "preview": "\"\"\"\nCode illustration: 3.03\n    Displaying All Visual Elements:\n\n        Methods newly defined and implemented here:\n   "
  },
  {
    "path": "Chapter 03/3.04.py",
    "chars": 10832,
    "preview": "\"\"\"\nCode illustration: 3.04\n    - Adding all the getter & setter methods for our data structure.\n            - get_curre"
  },
  {
    "path": "Chapter 03/3.05.py",
    "chars": 11346,
    "preview": "\"\"\"\nCode illustration: 3.05\n    - Loading drum samples\n\n        New modules imported here:\n            - os, tkinter.fil"
  },
  {
    "path": "Chapter 03/3.06.py",
    "chars": 13754,
    "preview": "\"\"\"\n               ****** Non reponsive warning ! ******\n    - This program becomes non responsive on playback of audio "
  },
  {
    "path": "Chapter 03/3.07.py",
    "chars": 13987,
    "preview": "\"\"\"\nCode illustration: 3.07\n\n    Tkinter and Threading\n    **********************\n       New modules imported here:\n    "
  },
  {
    "path": "Chapter 03/3.08.py",
    "chars": 14519,
    "preview": "\"\"\"\nCode illustration: 3.08\n\n    Adding support for multiple beat patterns\n\n        New methods added here:\n            "
  },
  {
    "path": "Chapter 03/3.09.py",
    "chars": 16070,
    "preview": "\"\"\"\nCode illustration: 3.09\n    Saving Drum Patterns | Object Persistence: pickling and unpickling\n\n        New modules "
  },
  {
    "path": "Chapter 03/3.10.py",
    "chars": 2137,
    "preview": "\"\"\"\nCode illustration: 3.10.py\n\n    1. tkinter versus ttk Themed Widgets\n    2. new widgets introduced in ttk\n\nChapter 3"
  },
  {
    "path": "Chapter 03/3.11.py",
    "chars": 1467,
    "preview": "\"\"\"\nCode illustration: 3.11.py\n    ttk widgets styling and theming explained\n\nChapter 3 : Programmable Drum Machine\nTkin"
  },
  {
    "path": "Chapter 03/3.12.py",
    "chars": 16408,
    "preview": "\"\"\"\nCode illustration: 3.12\n    applying ttk themes to our play button, stop button, loopbutton\n    adding separators\n\n "
  },
  {
    "path": "Chapter 03/readme.txt",
    "chars": 848,
    "preview": "====================================================================\nCode Readme\nTkinter GUI Application Development Blu"
  },
  {
    "path": "Chapter 04/4.01/configurations.py",
    "chars": 234,
    "preview": "\"\"\"\nCode illustration: 4.01\n\n@ Tkinter GUI Application Development Blueprints\n\"\"\"\n\nNUMBER_OF_ROWS = 8\nNUMBER_OF_COLUMNS "
  },
  {
    "path": "Chapter 04/4.01/controller.py",
    "chars": 259,
    "preview": "\"\"\"\nCode illustration: 4.01\n\n@ Tkinter GUI Application Development Blueprints\n\"\"\"\nfrom configurations import *\nimport mo"
  },
  {
    "path": "Chapter 04/4.01/exceptions.py",
    "chars": 115,
    "preview": "\"\"\"\nCode illustration: 4.01\n@ Tkinter GUI Application Development Blueprints\n\"\"\"\nclass ChessError(Exception): pass\n"
  },
  {
    "path": "Chapter 04/4.01/model.py",
    "chars": 166,
    "preview": "\"\"\"\nCode illustration: 4.01\n\n@ Tkinter GUI Application Development Blueprints\n\"\"\"\nfrom configurations import *\n\n\nclass M"
  },
  {
    "path": "Chapter 04/4.01/view.py",
    "chars": 4260,
    "preview": "\"\"\"\nCode illustration: 4.01\n\n@ Tkinter GUI Application Development Blueprints\n\"\"\"\n\nfrom tkinter import Tk, Menu, Label, "
  },
  {
    "path": "Chapter 04/4.02/configurations.py",
    "chars": 885,
    "preview": "\"\"\"\nCode illustration: 4.01\n\n@ Tkinter GUI Application Development Blueprints\n\"\"\"\n\nNUMBER_OF_ROWS = 8\nNUMBER_OF_COLUMNS "
  },
  {
    "path": "Chapter 04/4.02/controller.py",
    "chars": 259,
    "preview": "\"\"\"\nCode illustration: 4.01\n\n@ Tkinter GUI Application Development Blueprints\n\"\"\"\nfrom configurations import *\nimport mo"
  },
  {
    "path": "Chapter 04/4.02/exceptions.py",
    "chars": 115,
    "preview": "\"\"\"\nCode illustration: 4.02\n@ Tkinter GUI Application Development Blueprints\n\"\"\"\nclass ChessError(Exception): pass\n"
  },
  {
    "path": "Chapter 04/4.02/model.py",
    "chars": 692,
    "preview": "\"\"\"\nCode illustration: 4.01\n\n@ Tkinter GUI Application Development Blueprints\n\"\"\"\nfrom configurations import *\nimport pi"
  },
  {
    "path": "Chapter 04/4.02/piece.py",
    "chars": 1121,
    "preview": "\"\"\"\nCode illustration: 4.02\n@ Tkinter GUI Application Development Blueprints\n\"\"\" \nfrom configurations import *\nimport ex"
  },
  {
    "path": "Chapter 04/4.02/view.py",
    "chars": 4239,
    "preview": "\"\"\"\nCode illustration: 4.01\n\n@ Tkinter GUI Application Development Blueprints\n\"\"\"\n\nfrom tkinter import Tk, Menu, Label, "
  },
  {
    "path": "Chapter 04/4.03/configurations.py",
    "chars": 885,
    "preview": "\"\"\"\nCode illustration: 4.03\n\n@ Tkinter GUI Application Development Blueprints\n\"\"\"\n\nNUMBER_OF_ROWS = 8\nNUMBER_OF_COLUMNS "
  },
  {
    "path": "Chapter 04/4.03/controller.py",
    "chars": 780,
    "preview": "\"\"\"\nCode illustration: 4.03\n    New method added here:\n        get_numeric_notation(position)\n        get_all_peices_on_"
  },
  {
    "path": "Chapter 04/4.03/exceptions.py",
    "chars": 115,
    "preview": "\"\"\"\nCode illustration: 4.03\n@ Tkinter GUI Application Development Blueprints\n\"\"\"\nclass ChessError(Exception): pass\n"
  },
  {
    "path": "Chapter 04/4.03/model.py",
    "chars": 1379,
    "preview": "\"\"\"\nCode illustration: 4.03\n\n    Methods modified here:\n        __init__ method (added a call to reset_to_initial_locati"
  },
  {
    "path": "Chapter 04/4.03/piece.py",
    "chars": 1335,
    "preview": "\"\"\"\nCode illustration: 4.03\n\n    New Imports\n        import sys\n    \n       \n    Methods Added\n        - all classes and"
  },
  {
    "path": "Chapter 04/4.03/view.py",
    "chars": 5785,
    "preview": "\"\"\"\nCode illustration: 4.03\n\n    New attributes added here:\n        images = {}\n\n    New methods defined here:\n        d"
  },
  {
    "path": "Chapter 04/4.04/configurations.py",
    "chars": 1052,
    "preview": "\"\"\"\nCode illustration: 4.04\n\n@ Tkinter GUI Application Development Blueprints\n\"\"\"\n\nNUMBER_OF_ROWS = 8\nNUMBER_OF_COLUMNS "
  },
  {
    "path": "Chapter 04/4.04/controller.py",
    "chars": 611,
    "preview": "\"\"\"\nCode illustration: 4.04\n\n@ Tkinter GUI Application Development Blueprints\n\"\"\"\nfrom configurations import *\nimport mo"
  },
  {
    "path": "Chapter 04/4.04/exceptions.py",
    "chars": 115,
    "preview": "\"\"\"\nCode illustration: 4.04\n@ Tkinter GUI Application Development Blueprints\n\"\"\"\nclass ChessError(Exception): pass\n"
  },
  {
    "path": "Chapter 04/4.04/model.py",
    "chars": 1697,
    "preview": "\"\"\"\nCode illustration: 4.04\n\n    New methods added here:\n        all_positions_occupied_by_color(color)\n        all_occu"
  },
  {
    "path": "Chapter 04/4.04/piece.py",
    "chars": 5278,
    "preview": "\"\"\"\nCode illustration: 4.04\n\n    Methods Added\n        - moves_available(current_position, directions, distance)\n\n    Cl"
  },
  {
    "path": "Chapter 04/4.04/view.py",
    "chars": 5785,
    "preview": "\"\"\"\nCode illustration: 4.04\n\n    New attributes added here:\n        images = {}\n\n    New methods defined here:\n        d"
  },
  {
    "path": "Chapter 04/4.05/configurations.py",
    "chars": 1115,
    "preview": "\"\"\"\nCode illustration: 4.05\n\n@ Tkinter GUI Application Development Blueprints\n\"\"\"\n\nNUMBER_OF_ROWS = 8\nNUMBER_OF_COLUMNS "
  },
  {
    "path": "Chapter 04/4.05/controller.py",
    "chars": 611,
    "preview": "\"\"\"\nCode illustration: 4.05\n\n@ Tkinter GUI Application Development Blueprints\n\"\"\"\nfrom configurations import *\nimport mo"
  },
  {
    "path": "Chapter 04/4.05/exceptions.py",
    "chars": 115,
    "preview": "\"\"\"\nCode illustration: 4.05\n@ Tkinter GUI Application Development Blueprints\n\"\"\"\nclass ChessError(Exception): pass\n"
  },
  {
    "path": "Chapter 04/4.05/model.py",
    "chars": 2505,
    "preview": "\"\"\"\nCode illustration: 4.05\n\n    New methods added here:\n        get_all_available_moves(color)\n\n\n@ Tkinter GUI Applicat"
  },
  {
    "path": "Chapter 04/4.05/piece.py",
    "chars": 5107,
    "preview": "\"\"\"\nCode illustration: 4.05\n\n@ Tkinter GUI Application Development Blueprints\n\"\"\"\nfrom configurations import *\nimport sy"
  },
  {
    "path": "Chapter 04/4.05/view.py",
    "chars": 5566,
    "preview": "\"\"\"\nCode illustration: 4.05\n\n@ Tkinter GUI Application Development Blueprints\n\"\"\"\n\nfrom tkinter import Tk, Menu, Label, "
  },
  {
    "path": "Chapter 04/4.06/configurations.py",
    "chars": 1194,
    "preview": "\"\"\"\nCode illustration: 4.06\n\n    added constant HIGHLIGHT_COLOR = \"#2EF70D\"\n    \n@ Tkinter GUI Application Development B"
  },
  {
    "path": "Chapter 04/4.06/controller.py",
    "chars": 1240,
    "preview": "\"\"\"\nCode illustration: 4.06\n\n    New methods added here:\n     shift( start_pos,end_pos)\n     get_all_peices_on_chess_boa"
  },
  {
    "path": "Chapter 04/4.06/exceptions.py",
    "chars": 499,
    "preview": "\"\"\"\nCode illustration: 4.06\n\n    New classes added here:\n        InvalidMove(ChessError)\n        CheckMate(ChessError)\n "
  },
  {
    "path": "Chapter 04/4.06/model.py",
    "chars": 5045,
    "preview": "\"\"\"\nCode illustration: 4.06\n        \n        New imports \n            from copy import deepcopy\n            import excep"
  },
  {
    "path": "Chapter 04/4.06/piece.py",
    "chars": 5112,
    "preview": "\"\"\"\nCode illustration: 4.06\n\n@ Tkinter GUI Application Development Blueprints\n\"\"\"\nfrom configurations import *\nimport sy"
  },
  {
    "path": "Chapter 04/4.06/view.py",
    "chars": 8245,
    "preview": "\"\"\"\nCode illustration: 4.06\n\n    Attributes added\n        selected_piece_position = None\n        all_squares_to_be_highl"
  },
  {
    "path": "Chapter 04/4.07/chess_options.ini",
    "chars": 90,
    "preview": "[chess_colors]\nboard_color_1 = #59a803\nboard_color_2 = #8b83d9\nhighlight_color = #b92129\n\n"
  },
  {
    "path": "Chapter 04/4.07/configurations.py",
    "chars": 1377,
    "preview": "\"\"\"\nCode illustration: 4.07\n    \n@ Tkinter GUI Application Development Blueprints\n\"\"\"\nfrom configparser import ConfigPar"
  },
  {
    "path": "Chapter 04/4.07/controller.py",
    "chars": 1092,
    "preview": "\"\"\"\nCode illustration: 4.07\n\n@ Tkinter GUI Application Development Blueprints\n\"\"\"\nimport model\nimport piece\n\n\nclass Cont"
  },
  {
    "path": "Chapter 04/4.07/exceptions.py",
    "chars": 318,
    "preview": "\"\"\"\nCode illustration: 4.07\n\n@ Tkinter GUI Application Development Blueprints\n\"\"\"\nclass ChessError(Exception): pass\nclas"
  },
  {
    "path": "Chapter 04/4.07/model.py",
    "chars": 4604,
    "preview": "\"\"\"\nCode illustration: 4.07\n        \n@ Tkinter GUI Application Development Blueprints\n\"\"\"\nfrom copy import deepcopy\nimpo"
  },
  {
    "path": "Chapter 04/4.07/piece.py",
    "chars": 5087,
    "preview": "\"\"\"\nCode illustration: 4.07\n\n@ Tkinter GUI Application Development Blueprints\n\"\"\"\n\nfrom configurations import *\nimport s"
  },
  {
    "path": "Chapter 04/4.07/preferenceswindow.py",
    "chars": 3536,
    "preview": "\"\"\"\nCode illustration: 4.07\n\n    this entire file added here\n    \n@ Tkinter GUI Application Development Blueprints\n\"\"\"\n\n"
  },
  {
    "path": "Chapter 04/4.07/view.py",
    "chars": 8673,
    "preview": "\"\"\"\nCode illustration: 4.07\n\n    new import\n        import preferenceswindow\n\n\n    new attributes added here:\n        bo"
  },
  {
    "path": "Chapter 04/readme.txt",
    "chars": 618,
    "preview": "====================================================================\nCode Readme\nTkinter GUI Application Development Blu"
  },
  {
    "path": "Chapter 05/5.01/model.py",
    "chars": 148,
    "preview": "\"\"\"\nCode illustration: 5.01\n\n@Tkinter GUI Application Development Blueprints\n\"\"\" \n\nclass Model:\n    \n    def __init__(se"
  },
  {
    "path": "Chapter 05/5.01/player.py",
    "chars": 171,
    "preview": "\"\"\"\nCode illustration: 5.01\n\n@Tkinter GUI Application Development Blueprints\n\"\"\" \n\nimport pyglet\n\nclass Player:\n    \n   "
  },
  {
    "path": "Chapter 05/5.01/view.py",
    "chars": 8436,
    "preview": "\"\"\"\nCode illustration: 5.01\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\nimport tkinter as tk\nimport tkinter.fil"
  },
  {
    "path": "Chapter 05/5.02/model.py",
    "chars": 559,
    "preview": "\"\"\"\nCode illustration: 5.02\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\n\n\nclass Model:\n\n    def __init__(self):"
  },
  {
    "path": "Chapter 05/5.02/player.py",
    "chars": 2050,
    "preview": "\"\"\"\nCode illustration: 5.02\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\n\nimport pyglet\n\nFORWARD_REWIND_JUMP_TIM"
  },
  {
    "path": "Chapter 05/5.02/view.py",
    "chars": 8436,
    "preview": "\"\"\"\nCode illustration: 5.02\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\nimport tkinter as tk\nimport tkinter.fil"
  },
  {
    "path": "Chapter 05/5.03/model.py",
    "chars": 559,
    "preview": "\"\"\"\nCode illustration: 5.03\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\n\n\nclass Model:\n\n    def __init__(self):"
  },
  {
    "path": "Chapter 05/5.03/player.py",
    "chars": 2050,
    "preview": "\"\"\"\nCode illustration: 5.03\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\n\nimport pyglet\n\nFORWARD_REWIND_JUMP_TIM"
  },
  {
    "path": "Chapter 05/5.03/view.py",
    "chars": 10747,
    "preview": "\"\"\"\nCode illustration: 5.03\n    \n    New imports here:\n        import os\n    \n    Methods modified here:\n        on_add_"
  },
  {
    "path": "Chapter 05/5.04/model.py",
    "chars": 559,
    "preview": "\"\"\"\nCode illustration: 5.04\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\n\n\nclass Model:\n\n    def __init__(self):"
  },
  {
    "path": "Chapter 05/5.04/player.py",
    "chars": 2050,
    "preview": "\"\"\"\nCode illustration: 5.04\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\n\nimport pyglet\n\nFORWARD_REWIND_JUMP_TIM"
  },
  {
    "path": "Chapter 05/5.04/view.py",
    "chars": 13269,
    "preview": "\"\"\"\nCode illustration: 5.04\n    \n    New modules imported here:\n        import itertools\n\n    New attributes added here:"
  },
  {
    "path": "Chapter 05/5.05/model.py",
    "chars": 559,
    "preview": "\"\"\"\nCode illustration: 5.05\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\n\n\nclass Model:\n\n    def __init__(self):"
  },
  {
    "path": "Chapter 05/5.05/player.py",
    "chars": 2050,
    "preview": "\"\"\"\nCode illustration: 5.05\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\n\nimport pyglet\n\nFORWARD_REWIND_JUMP_TIM"
  },
  {
    "path": "Chapter 05/5.05/seekbar.py",
    "chars": 1817,
    "preview": "\"\"\"\nCode illustration: 5.05\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\n\n\nimport tkinter as tk\n\nclass Seekbar(t"
  },
  {
    "path": "Chapter 05/5.05/view.py",
    "chars": 13012,
    "preview": "\"\"\"\nCode illustration: 5.05\n    \n    New modules imported here:\n        from seekbar import *\n    \n    New constants add"
  },
  {
    "path": "Chapter 05/5.06/helpers.py",
    "chars": 457,
    "preview": "\"\"\"\nCode illustration: 5.06\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\n\n\ndef get_time_in_minute_seconds(time_i"
  },
  {
    "path": "Chapter 05/5.06/model.py",
    "chars": 559,
    "preview": "\"\"\"\nCode illustration: 5.06\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\n\n\nclass Model:\n\n    def __init__(self):"
  },
  {
    "path": "Chapter 05/5.06/player.py",
    "chars": 2050,
    "preview": "\"\"\"\nCode illustration: 5.06\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\n\nimport pyglet\n\nFORWARD_REWIND_JUMP_TIM"
  },
  {
    "path": "Chapter 05/5.06/seekbar.py",
    "chars": 1815,
    "preview": "\"\"\"\nCode illustration: 5.06\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\n\nimport tkinter as tk\n\nclass Seekbar(tk"
  },
  {
    "path": "Chapter 05/5.06/view.py",
    "chars": 13908,
    "preview": "\"\"\"\nCode illustration: 5.06\n    \n    New modules imported here:\n        from helpers import *\n    \n\n    Methods added he"
  },
  {
    "path": "Chapter 05/5.07/helpers.py",
    "chars": 457,
    "preview": "\"\"\"\nCode illustration: 5.07\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\n\n\ndef get_time_in_minute_seconds(time_i"
  },
  {
    "path": "Chapter 05/5.07/model.py",
    "chars": 559,
    "preview": "\"\"\"\nCode illustration: 5.07\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\n\n\nclass Model:\n\n    def __init__(self):"
  },
  {
    "path": "Chapter 05/5.07/player.py",
    "chars": 2050,
    "preview": "\"\"\"\nCode illustration: 5.07\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\n\nimport pyglet\n\nFORWARD_REWIND_JUMP_TIM"
  },
  {
    "path": "Chapter 05/5.07/seekbar.py",
    "chars": 1933,
    "preview": "\"\"\"\nCode illustration: 5.07\n\n    Method modified here:\n        on_seekbar_knob_clicked() - added a call to seek_new_posi"
  },
  {
    "path": "Chapter 05/5.07/view.py",
    "chars": 14905,
    "preview": "\"\"\"\nCode illustration: 5.07\n\n    New methods added here:\n     manage_periodic_updates_during_play()\n     update_clock()\n"
  },
  {
    "path": "Chapter 05/5.08/helpers.py",
    "chars": 457,
    "preview": "\"\"\"\nCode illustration: 5.08\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\n\n\ndef get_time_in_minute_seconds(time_i"
  },
  {
    "path": "Chapter 05/5.08/model.py",
    "chars": 559,
    "preview": "\"\"\"\nCode illustration: 5.08\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\n\n\nclass Model:\n\n    def __init__(self):"
  },
  {
    "path": "Chapter 05/5.08/player.py",
    "chars": 2050,
    "preview": "\"\"\"\nCode illustration: 5.08\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\n\nimport pyglet\n\nFORWARD_REWIND_JUMP_TIM"
  },
  {
    "path": "Chapter 05/5.08/seekbar.py",
    "chars": 1816,
    "preview": "\"\"\"\nCode illustration: 5.08\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\n\nimport tkinter as tk\n\nclass Seekbar(tk"
  },
  {
    "path": "Chapter 05/5.08/view.py",
    "chars": 15437,
    "preview": "\"\"\"\nCode illustration: 5.08\n\n    methods modified\n        manage_periodic_updates_during_play()\n        __init__  method"
  },
  {
    "path": "Chapter 05/5.09/helpers.py",
    "chars": 457,
    "preview": "\"\"\"\nCode illustration: 5.09\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\n\n\ndef get_time_in_minute_seconds(time_i"
  },
  {
    "path": "Chapter 05/5.09/model.py",
    "chars": 559,
    "preview": "\"\"\"\nCode illustration: 5.09\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\n\n\nclass Model:\n\n    def __init__(self):"
  },
  {
    "path": "Chapter 05/5.09/player.py",
    "chars": 2052,
    "preview": "\"\"\"\nCode illustration: 5.09\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\n\nimport pyglet\n\nFORWARD_REWIND_JUMP_TIM"
  },
  {
    "path": "Chapter 05/5.09/pygleterror.py",
    "chars": 144,
    "preview": "import pyglet\n\naudio_file = 'test.mp3'\nplayer = pyglet.media.Player()\nsource = pyglet.media.load(audio_file)\nplayer.queu"
  },
  {
    "path": "Chapter 05/5.09/seekbar.py",
    "chars": 1816,
    "preview": "\"\"\"\nCode illustration: 5.09\n\n@Tkinter GUI Application Development Blueprints\n\"\"\"\n\nimport tkinter as tk\n\nclass Seekbar(tk"
  },
  {
    "path": "Chapter 05/5.09/view.py",
    "chars": 16224,
    "preview": "\"\"\"\nCode illustration: 5.09\n\n    new imports here:\n        import Pmw\n    \n    methods modifed here:\n        create_gui\n"
  },
  {
    "path": "Chapter 05/readme.txt",
    "chars": 732,
    "preview": "====================================================================\nReadme\nTkinter GUI Application Development Blueprin"
  },
  {
    "path": "Chapter 06/6.01.py",
    "chars": 3371,
    "preview": "\"\"\"\nCode illustration: 6.01\n  \n@ Tkinter GUI Application Development Blueprints\n\"\"\"\n\nimport tkinter as tk\nimport framewo"
  },
  {
    "path": "Chapter 06/6.02.py",
    "chars": 4789,
    "preview": "\"\"\"\nCode illustration: 6.02\n\n    New attributes defined here:\n        start_x, start_y\n        end_x, end_y\n\n    Methods"
  },
  {
    "path": "Chapter 06/6.03.py",
    "chars": 6355,
    "preview": "\"\"\"\nCode illustration: 6.03\n\n    New methods defined here:\n        create_tool_bar_buttons()\n        on_tool_bar_button_"
  },
  {
    "path": "Chapter 06/6.04.py",
    "chars": 9802,
    "preview": "\"\"\"\nCode illustration: 6.04\n    \n    New module import here:\n        math\n        cmath\n\n    New attributes added here:\n"
  },
  {
    "path": "Chapter 06/6.05.py",
    "chars": 11461,
    "preview": "\"\"\"\nCode illustration: 6.05\n\n    New imports here:\n        from tkinter import colorchooser\n        \n    New attributes "
  },
  {
    "path": "Chapter 06/6.06.py",
    "chars": 17936,
    "preview": "\"\"\"\nCode illustration: 6.06\n    \n    New imports here:\n        from tkinter import ttk\n       \n\n    New methods added he"
  },
  {
    "path": "Chapter 06/6.07.py",
    "chars": 20190,
    "preview": "\"\"\"\nCode illustration: 6.07\n    \n    New imports here:\n        from supershapes import *\n        \n    New attributes add"
  },
  {
    "path": "Chapter 06/6.08.py",
    "chars": 23426,
    "preview": "\"\"\"\nCode illustration: 6.08\n    \n    New methods added here:\n        draw_text()\n        draw_text_options()\n        on_"
  },
  {
    "path": "Chapter 06/6.09.py",
    "chars": 25081,
    "preview": "\"\"\"\nCode illustration: 6.09\n    \n    Modules imported here:\n        from tkinter import messagebox\n        from tkinter "
  },
  {
    "path": "Chapter 06/framework.py",
    "chars": 3099,
    "preview": "\"\"\"\n    Chapter 6: Paint Application\n        Developing a Tiny Framework\n\nTkinter GUI Application Development Blueprints"
  },
  {
    "path": "Chapter 06/supershapes.py",
    "chars": 488,
    "preview": "super_shapes = {\n    \"shape A\": (1.5, 1.5, 5, 2, 7, 7),\n    \"shape B\": (1.5, 1.5, 3, 5, 18, 18),\n    \"shape C\": (1.4, 1."
  },
  {
    "path": "Chapter 07/7.01/constants.py",
    "chars": 277,
    "preview": "WINDOW_WIDTH = 560\nMODE_SELECTOR_HEIGHT = 50\nCONTROLS_FRAME_HEIGHT = 80\nKEYBOARD_HEIGHT = 160\nSCORE_DISPLAY_HEIGHT = 110"
  },
  {
    "path": "Chapter 07/7.01/view.py",
    "chars": 5181,
    "preview": "'''\nChapter 7: Piano Tutor\nTkinter GUI Application Development Blueprints\n\n'''\nfrom tkinter import Tk, Frame, Button, BO"
  },
  {
    "path": "Chapter 07/7.02/constants.py",
    "chars": 976,
    "preview": "WINDOW_WIDTH = 560\nMODE_SELECTOR_HEIGHT = 50\nCONTROLS_FRAME_HEIGHT = 80\nKEYBOARD_HEIGHT = 160\nSCORE_DISPLAY_HEIGHT = 110"
  },
  {
    "path": "Chapter 07/7.02/view.py",
    "chars": 6909,
    "preview": "'''\nCode 7.02.py\n\n      Adding the piano keyboard\n\nattribute added here:\n\n   self.keys = []\n\nnew methods added here\n    "
  },
  {
    "path": "Chapter 07/7.03/audio.py",
    "chars": 502,
    "preview": "import simpleaudio as sa\nfrom _thread import start_new_thread\nimport time\n\ndef play_note(note_name):\n  wave_obj = sa.Wav"
  },
  {
    "path": "Chapter 07/7.03/constants.py",
    "chars": 976,
    "preview": "WINDOW_WIDTH = 560\nMODE_SELECTOR_HEIGHT = 50\nCONTROLS_FRAME_HEIGHT = 80\nKEYBOARD_HEIGHT = 160\nSCORE_DISPLAY_HEIGHT = 110"
  },
  {
    "path": "Chapter 07/7.03/view.py",
    "chars": 6840,
    "preview": "'''\nCode 7.03.py\n\n      Playing Audio\n\nnew import here:\nfrom audio import play_note    \n\nmethod modified here\n      on_k"
  },
  {
    "path": "Chapter 07/7.04/audio.py",
    "chars": 502,
    "preview": "import simpleaudio as sa\nfrom _thread import start_new_thread\nimport time\n\ndef play_note(note_name):\n  wave_obj = sa.Wav"
  },
  {
    "path": "Chapter 07/7.04/constants.py",
    "chars": 1254,
    "preview": "WINDOW_WIDTH = 560\nMODE_SELECTOR_HEIGHT = 50\nCONTROLS_FRAME_HEIGHT = 80\nKEYBOARD_HEIGHT = 160\nSCORE_DISPLAY_HEIGHT = 110"
  },
  {
    "path": "Chapter 07/7.04/view.py",
    "chars": 10033,
    "preview": "'''\n7.04\n\n    Implementing the Scales Tutor\n\nnew imports here:\n import json\n from collections import OrderedDict\n from a"
  },
  {
    "path": "Chapter 07/7.05/audio.py",
    "chars": 502,
    "preview": "import simpleaudio as sa\nfrom _thread import start_new_thread\nimport time\n\ndef play_note(note_name):\n  wave_obj = sa.Wav"
  },
  {
    "path": "Chapter 07/7.05/constants.py",
    "chars": 1295,
    "preview": "WINDOW_WIDTH = 560\nMODE_SELECTOR_HEIGHT = 50\nCONTROLS_FRAME_HEIGHT = 80\nKEYBOARD_HEIGHT = 160\nSCORE_DISPLAY_HEIGHT = 110"
  },
  {
    "path": "Chapter 07/7.05/view.py",
    "chars": 12121,
    "preview": "'''\n7.05\n\n    Implementing the Chords TUtor\n\nnew imports here:\n    from audio import play_chord_in_new_thread\n method mo"
  },
  {
    "path": "Chapter 07/7.06/audio.py",
    "chars": 502,
    "preview": "import simpleaudio as sa\nfrom _thread import start_new_thread\nimport time\n\ndef play_note(note_name):\n  wave_obj = sa.Wav"
  },
  {
    "path": "Chapter 07/7.06/constants.py",
    "chars": 1492,
    "preview": "WINDOW_WIDTH = 560\nMODE_SELECTOR_HEIGHT = 50\nCONTROLS_FRAME_HEIGHT = 100\nKEYBOARD_HEIGHT = 160\nSCORE_DISPLAY_HEIGHT = 11"
  },
  {
    "path": "Chapter 07/7.06/view.py",
    "chars": 16011,
    "preview": "'''\n7.06\n\n    Implementing the Chord Progression tutor\n\nnew imports here:\n    import math\n    from functools import part"
  },
  {
    "path": "Chapter 07/7.07/audio.py",
    "chars": 502,
    "preview": "import simpleaudio as sa\nfrom _thread import start_new_thread\nimport time\n\ndef play_note(note_name):\n  wave_obj = sa.Wav"
  },
  {
    "path": "Chapter 07/7.07/constants.py",
    "chars": 1492,
    "preview": "WINDOW_WIDTH = 560\nMODE_SELECTOR_HEIGHT = 50\nCONTROLS_FRAME_HEIGHT = 100\nKEYBOARD_HEIGHT = 160\nSCORE_DISPLAY_HEIGHT = 11"
  },
  {
    "path": "Chapter 07/7.07/score_maker.py",
    "chars": 2558,
    "preview": "from tkinter import *\nimport itertools\n\nclass ScoreMaker:\n\n  NOTES = ['C1','D1', 'E1', 'F1', 'G1','A1', 'B1', 'C2','D2',"
  },
  {
    "path": "Chapter 07/7.07/view.py",
    "chars": 15797,
    "preview": "'''\n7.07\n\n    Implementing the Score Maker\n\nnew imports here:\n    from score_maker import ScoreMaker\n    \n   \nmethods mo"
  },
  {
    "path": "Chapter 07/handle_widget_resize.py",
    "chars": 371,
    "preview": "'''\n\nChapter 7\n\nHandling Widget Resize\n\n\n'''\n\n\nfrom tkinter import Tk, Label, Pack\n\nroot= Tk()\n\nlabel  = Label(root, tex"
  },
  {
    "path": "Chapter 07/json/chords.json",
    "chars": 447,
    "preview": "{ \n\"Major\" \t: [0, 4, 7],\n\"Minor\"\t\t: [0, 3, 7],\n\"Sus4\"\t\t: [0, 5, 7],\n\"5\" \t\t: [0, 4, 6],\n\"Diminished\"\t: [0, 3, 6],\n\"Augmen"
  },
  {
    "path": "Chapter 07/json/progressions.json",
    "chars": 1079,
    "preview": "{\n  \"Major\": {\n    \"I-IV-V\": [ \"0\", \"5\", \"7\"  ],\n    \"ii-V-I\": [ \"2\", \"7\", \"0\"  ],\n    \"I-V-vi-IV\": [ \"0\", \"7\", \"9\", \"5\""
  },
  {
    "path": "Chapter 07/json/scales.json",
    "chars": 686,
    "preview": "{\n  \"Major\": [ 0, 2, 4, 5, 7, 9, 11 ],\n  \"Minor\": [ 0, 2, 3, 5, 7, 8, 10  ],\n  \"Harmonic minor\": [ 0, 2, 3, 5, 7, 8, 11 "
  },
  {
    "path": "Chapter 07/nonresponsive.py",
    "chars": 411,
    "preview": "'''\nChapter 7\nA note on responsiveness\n\nThis is an example of nonresponsive widgets\nRun this program and resize the wind"
  },
  {
    "path": "Chapter 07/responsive.py",
    "chars": 360,
    "preview": "'''\n\nChapter 7\n\nA demonstration of a responsive window\nusing Grid.rowconfigure and Grid.columnconfigure\n\n'''\nfrom tkinte"
  },
  {
    "path": "Chapter 08/8.01_screensaver.py",
    "chars": 2974,
    "preview": "\"\"\"\nCode illustration: 8.01\n    Screensaver\nTkinter GUI Application Development Blueprints\n\"\"\"\n\n\nfrom tkinter import Tk,"
  },
  {
    "path": "Chapter 08/8.02_pie_chart.py",
    "chars": 1009,
    "preview": "\"\"\"\nCode illustration: 8.02\n    Pie chart\nTkinter GUI Application Development Blueprints\n\"\"\"\n\n\nimport tkinter\n\nroot = tk"
  },
  {
    "path": "Chapter 08/8.03_bar_graph.py",
    "chars": 654,
    "preview": "\"\"\"\nCode illustration: 8.03 \n    Bar graph\nTkinter GUI Application Development Blueprints\n\"\"\"\n\nimport tkinter\nimport ran"
  },
  {
    "path": "Chapter 08/8.04_scatter_plot.py",
    "chars": 972,
    "preview": "\"\"\"\nCode illustration: 8.04\n    Scatter Plot\n\nTkinter GUI Application Development Blueprints\n\"\"\"\n\nimport tkinter\nimport "
  },
  {
    "path": "Chapter 08/8.05_matplotlib_embedding_graphs.py",
    "chars": 724,
    "preview": "\"\"\"\nCode illustration: 8.05\n    Embedding Matplotlib graph on tkinter\nTkinter GUI Application Development Blueprints\n\"\"\""
  },
  {
    "path": "Chapter 08/8.06_polar_plot.py",
    "chars": 1893,
    "preview": "\"\"\"\nCode illustration: 8.06\n    Polar Plot\nTkinter GUI Application Development Blueprints\n\"\"\"\n\nfrom tkinter import Tk, C"
  },
  {
    "path": "Chapter 08/8.07_gravity_simulation.py",
    "chars": 4436,
    "preview": "\"\"\"\nCode illustration: 8.07\n    Gravity Simulation\nTkinter GUI Application Development Blueprints\n\"\"\"\nimport math\nimport"
  },
  {
    "path": "Chapter 08/8.08_Mandelbrot.py",
    "chars": 2294,
    "preview": "\"\"\"\nCode illustration: 8.08\n    Mandelbrot Set\n    *** This may take some time to compute ***\nTkinter GUI Application De"
  },
  {
    "path": "Chapter 08/8.09_vornoi_diagram.py",
    "chars": 1523,
    "preview": "\"\"\"\nCode illustration: 8.09\n    Vornoi Diagrams\n     *** Warnig - this code takes up to a few minutes to compute ***\n\nTk"
  },
  {
    "path": "Chapter 08/8.10_spring_pendulum.py",
    "chars": 1978,
    "preview": "\"\"\"\nCode illustration: 8.10\n    Spring Pendulum Simulation\nTkinter GUI Application Development Blueprints\n\"\"\"\nfrom tkint"
  },
  {
    "path": "Chapter 08/8.11_chaos_game.py",
    "chars": 1360,
    "preview": "\"\"\"\nCode illustration: 8.11\n    Chaos Game\nTkinter GUI Application Development Blueprints\n\"\"\"\nimport random\nfrom tkinter"
  },
  {
    "path": "Chapter 08/8.12_phyllotaxis.py",
    "chars": 1160,
    "preview": "\"\"\"\nCode illustration: 8.12\n    Screensaver\nTkinter GUI Application Development Blueprints\n\"\"\"\nfrom tkinter import Tk, C"
  },
  {
    "path": "Chapter 08/8.13_3D_graphics.py",
    "chars": 3109,
    "preview": "\"\"\"\nCode illustration: 8.13_3D_graphics\n    3D Graphics\nTkinter GUI Application Development Blueprints\n\"\"\"\n\nfrom tkinter"
  },
  {
    "path": "Chapter 09/9.01_race_condition.py",
    "chars": 879,
    "preview": "\"\"\"\nCode illustration: 9.01\n    Race Condition Demo\nTkinter GUI Application Development Blueprints\n\"\"\"\n\nimport threading"
  },
  {
    "path": "Chapter 09/9.02_lock_demo.py",
    "chars": 1046,
    "preview": "\"\"\"\nCode illustration: 9.02\n    Lock Demo\nTkinter GUI Application Development Blueprints\n\"\"\"\n\nimport threading\n\n\nclass L"
  },
  {
    "path": "Chapter 09/9.03_threading_with queue.py",
    "chars": 980,
    "preview": "\"\"\"\nCode illustration: 9.03\n    Threading with Queue Simple Demo\nTkinter GUI Application Development Blueprints\n\"\"\"\n\nimp"
  },
  {
    "path": "Chapter 09/9.04_game_of_ snake.py",
    "chars": 4166,
    "preview": "\"\"\"\nCode illustration: 9.04\n    Game of Snake\nTkinter GUI Application Development Blueprints\n\"\"\"\nimport threading\nimport"
  },
  {
    "path": "Chapter 09/9.05_urllib_demo.py",
    "chars": 199,
    "preview": "\"\"\"\nCode illustration: 9.05\n    urllib demo\nTkinter GUI Application Development Blueprints\n\"\"\"\nimport urllib.request\nwit"
  },
  {
    "path": "Chapter 09/9.06_weather_ reporter.py",
    "chars": 7347,
    "preview": "\"\"\"\nCode illustration: 9.06\n    Weather reporter\nTkinter GUI Application Development Blueprints\n\"\"\"\nimport sys\nimport js"
  },
  {
    "path": "Chapter 09/9.07_socket_demo.py",
    "chars": 906,
    "preview": "\"\"\"\nCode illustration: 7.08\n    Socket Programming Demo\nTkinter GUI Application Development Blueprints\n\"\"\"\n\nimport socke"
  },
  {
    "path": "Chapter 09/9.08_port_scanner.py",
    "chars": 3675,
    "preview": "\"\"\"\nCode illustration: 7.09\n    Port Scanner\nTkinter GUI Application Development Blueprints\n\"\"\"\nimport socket\nfrom tkint"
  },
  {
    "path": "Chapter 09/9.09_chat_server.py",
    "chars": 1777,
    "preview": "\"\"\"\nCode illustration: 9.09\n    Chat server\nTkinter GUI Application Development Blueprints\n\"\"\"\nimport socket\nimport thre"
  },
  {
    "path": "Chapter 09/9.10_chat_client.py",
    "chars": 3742,
    "preview": "'''\nCode illustration: 9.10\n    Chat Client\n\n    *** NOTE  Run atleast 2 instances of this program to see chat in action"
  },
  {
    "path": "Chapter 09/9.11_phonebook.py",
    "chars": 6117,
    "preview": "'''\nCode illustration: 9.11\n    Phonebook Application\nTkinter GUI Application Development Blueprints\n'''\nfrom tkinter im"
  },
  {
    "path": "Chapter 09/9.12_async_demo.py",
    "chars": 1436,
    "preview": "from tkinter import Tk, Button\nimport asyncio\nimport threading\nimport random\n\n\ndef asyncio_thread(event_loop):\n  print('"
  },
  {
    "path": "Chapter 09/9.13.arduino_sketch.ino",
    "chars": 649,
    "preview": "const int triggerPin = 8;\nconst int echoBackPin = 7;\n\nvoid setup() {\n Serial.begin(9600);\n pinMode(triggerPin, OUTPUT);\n"
  },
  {
    "path": "Chapter 09/9.14_read_from_serial_port.py",
    "chars": 681,
    "preview": "from tkinter import Tk, Label\nimport serial\n\nser = serial.Serial()\nser.port = \"/dev/ttyUSB0\"\nser.baudrate = 9600\ntry:\n  "
  },
  {
    "path": "Chapter 09/readme.txt",
    "chars": 954,
    "preview": "====================================================================\nCode Readme\nTkinter GUI Application Development Blu"
  },
  {
    "path": "Chapter 10/10.01_trace_variable.py",
    "chars": 513,
    "preview": "\"\"\"\nCode illustration: 10.01\nTkinter Trace Variable Demo\nTkinter GUI Application Development Blueprints\n\"\"\"\n\nfrom tkinte"
  },
  {
    "path": "Chapter 10/10.02_widget_traversal.py",
    "chars": 1859,
    "preview": "\"\"\"\nCode illustration: 10.02\nWidget Traversal\nTkinter GUI Application Development Blueprints\n\"\"\"\nfrom tkinter import Tk,"
  },
  {
    "path": "Chapter 10/10.03_validation_mode_demo.py",
    "chars": 1863,
    "preview": "\"\"\"\nCode illustration: 10.03\nValidation Modes Demo\nTkinter GUI Application Development Blueprints\n\"\"\"\n\nimport tkinter as"
  },
  {
    "path": "Chapter 10/10.04_percent _substitutions _demo.py",
    "chars": 1083,
    "preview": "\"\"\"\nCode illustration: 10.04\n\nDemonstration of percent substitutions in data validation\nTkinter GUI Application Developm"
  },
  {
    "path": "Chapter 10/10.05_key_validation.py",
    "chars": 987,
    "preview": "\"\"\"\nCode illustration: 10.05\nvalidate='key' demo\nTkinter GUI Application Development Blueprints\n\"\"\"\n\nimport tkinter as t"
  },
  {
    "path": "Chapter 10/10.06_focus_out _validation.py",
    "chars": 1050,
    "preview": "\"\"\"\nCode illustration: 10.06\nvalidate='focusout' demo\nTkinter GUI Application Development Blueprints\n\"\"\"\nimport tkinter "
  },
  {
    "path": "Chapter 10/10.07_formatting_entry_widget_to_display_date.py",
    "chars": 1316,
    "preview": "\"\"\"\nCode illustration: 10.07\nFormatting Entry Widget\nTkinter GUI Application Development Blueprints\n\"\"\"\nfrom tkinter imp"
  },
  {
    "path": "Chapter 10/10.08_font_demo.py",
    "chars": 661,
    "preview": "\"\"\"\nCode illustration: 10.08\n        font Demo\nTkinter GUI Application Development Blueprints\n\"\"\"\n\nfrom tkinter import T"
  },
  {
    "path": "Chapter 10/10.09_all_fonts_on_a_system.py",
    "chars": 224,
    "preview": "\"\"\"\nCode illustration: 10.09\n        Fetching tuple of all fonts installed on a system\nTkinter GUI Application Developme"
  },
  {
    "path": "Chapter 10/10.10_font_selector.py",
    "chars": 3090,
    "preview": "\"\"\"\nCode illustration: 10.10\nFont Selector\nTkinter GUI Application Development Blueprints\n\"\"\"\nfrom tkinter import Tk, St"
  },
  {
    "path": "Chapter 10/10.11_reading_from_command_line.py",
    "chars": 436,
    "preview": "\"\"\"\nCode illustration: 10.11\n    Reading from the command line\nTkinter GUI Application Development Blueprints\n\"\"\"\nfrom "
  }
]

// ... and 3 more files (download for full content)

About this extraction

This page contains the full source code of the PacktPublishing/Tkinter-GUI-Application-Development-Blueprints-Second-Edition GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 203 files (765.5 KB), approximately 212.1k tokens, and a symbol index with 2280 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!