This page provides links for programs used in The Great Courses course 9151, How to Program: Computer Science Concepts and Python Exercises, by John Keyser.

The larger examples used in the lectures are provided here. You can download a .zip file containing all the files by clicking THIS LINK.

To examine or download individual programs, find the corresponding link, below.

To jump to the lecture you are interested in, go here:


Spot an error or have a comment? Please send email to: tgccomments@keyseronline.net. Note: because of the volume of email I receive regularly, I will not be able to reply to most emails, but I appreciate any comments or suggestions you have.

Lecture 1:

1-1 – Introductory program demonstrating comments and multiple commands.

#Greeting
print ("Howdy!")

#Invitation
print ("Shall we play a game?")

1-2 – Preview program for next lecture. Demonstrates input and variables.

name=input ("Enter your name:")
print ("Hello,", name)

1-VideoExercise – Video exercise solution

print(10)
print(37/3) 
print(10 // 3) 
print(10 % 3)

Lecture 2:

2-1 – Shows assignment to variables

x = 3
y = x
x = 5

print(x)
print(y)

2-2 – Illustrates variable types

a = -5
b = 3.14
c = 'Hello'
d = "Howdy"


print(a)
print(b)
print(c)
print(d)

2-3 – Illustrates computations with variables

a = 2+5
b = a-4
c = a*b


print(a)
print(b)
print(c)

2-4 – Basic interest calculation

interest_rate = 0.03
principal = 1000
interest_earned = interest_rate * principal
total_amount = principal + interest_earned


print(interest_rate)
print(principal)
print(interest_earned)
print(total_amount)

2-5 – String concatenation

first_name = "John"
last_name = "Keyser"
full_name = first_name + ' ' + last_name


print(first_name)
print(last_name)
print(full_name)

2-6 – Calculation with integer variables – days in weeks

number_of_weeks = 26
number_of_days = number_of_weeks * 7

print(number_of_days)

2-7 – Calculation with string variables – concatenating strings to form an address

city_name = "Los Angeles"
state_name = "California"
zip_code = "90001-5151"
address = city_name + ', ' + state_name + ' ' + zip_code

print(address)

2-8 – Calculations for incrementing, decrementing, multiply-by, and divide-by

x = 3
x = x+1
y = 5
y += 1
z = 8
z -= 1
m = 10
n = 10
m *= 2
n /= 2


print(x)
print(y)
print(z)
print(m)
print(n)

2-9 – Solution – decreasing an account balance

balance = 1000.00
withdrawal_amount = 20.00

balance = balance - withdrawal_amount
# OR
balance -= withdrawal_amount

2-10 – Concatenations and the print statement

a = "John"
b = 3.14159
c = 100
print(a)
print(a, b, c)
print("Hello", "\n", 'World')
print("Hello"+"\n"+'World')
print(b+c)

2-11 – The input command

Question3 = input("What is your favorite color? ")
print(Question3)
b = input()
print("You entered", b)

2-12 – Illustrates that input is taken as strings

a = input("Enter a value for a:")
b = input("Enter a value for b:")
print("The sum of a and b is", a+b)

2-13 – Illustrates type conversion between different types, and problem with converting a float to an int

a = "1"
b = "3.14159"
c = float(a)
print(c)
d = int(b)
print (d)

2-14 – Converting input to ints

a = int(input("Enter a value for a:"))
b = int(input ("Enter a value for b:"))
print("The sum of a and b is", a+b)

2-15 – Solution – asking for a user’s name

name = input("What is your name?")
print("Hi,", name)
#OR
print("Hi, " + name)

2-VideoExercise – Video exercise solution

radius = float(input("Enter the radius:"))
Pi = 3.14159
area = Pi * radius * radius
print("The area is:", area)
#OR
print("The area is: " + str(area))

Lecture 3:

3-1 – Nested conditional

if False:
	print("It is cold.")
	if True:
		print("The heater is already on.")
	else:
		print("Turning the Heater on.")
else:
	print("It is warm enough.")

3-2 – Boolean variable

temp_is_low = False
if temp_is_low:
	print("Turning on the heater.")
else:
	print("Temperature is fine.")

3-3 – Assigning an expression to a Boolean variable

#Assume the variable age is already set
age = 11

x = (age <= 12)
if x:
    print("Your meal is free!")
else:
    print("Sorry, you have to pay.")

3-4 – Using an expression in a conditional

#Assume the variable age is already set
age = 11

if age <= 12:
    print("Your meal is free!")
else:
    print("Sorry, you have to pay.")

3-5 – Solution – defining conditions for nested conditionals

#currentTemp is current temperature
currentTemp = 65
#heaterIsOn is True if heater is on, False if not
heaterIsOn = False

if currentTemp < 68:
	print("It is cold.")
	if heaterIsOn:
		print("The heater is already on.")
	else:
		print("Turning the Heater on.")
else:
	print("It is warm enough.")

3-6 – Nested conditions – car maintenance

# Assume the variables currentMiles, lastOil, lastTires are already set
currentMiles = 15000
lastOil = 11000
lastTires = 5000

milesSinceOil = currentMiles - lastOil
milesSinceTires = currentMiles - lastTires

if milesSinceOil >= 3000:
	print("Time for an oil change.")
	if milesSinceTires >= 6000:
		print ("While here, better rotate your tires.")
else:
	print("You should get your car serviced in ", 3000-milesSinceOil, " miles")

3-7 – Range checking with nested conditions

a=7

if a>=1:
	if a<=10:
		print("It is in range")
	else:
		print("It is not in range")
else:
	print("It is not in range")

3-8 – Range checking with single Boolean expression

a=7

if (a>=1) and (a<=10):
	print("It is in range")
else:
	print("It is not in range")

3-9 – Checking many options using nested if statements

age = 7

if (age < 3):
	price = 0.00
else:
	if (age <= 12):
		price = 10.00
	else:
		if (age >= 65):
			price = 15.00
		else:
			price = 25.00

print(price)

3-10 – Checking many options with elif

age = 7

if (age < 3):
	price = 0.00
elif (age <= 12):
	price = 10.00
elif (age >= 65):
	price = 15.00
else:
	price = 25.00


print(price)

3-11 – Dice value comparison for game of craps, using elif statements

die1 = 4
die2 = 3

if (die1 + die2) == 2:
	win = False
elif (die1 + die2) == 3:
	win = False
elif (die1 + die2) == 4:
	point = 4
elif (die1 + die2) == 5:
	point = 5
elif (die1 + die2) == 6:
	point = 6
elif (die1 + die2) == 7:
	win = True
elif (die1 + die2) == 8:
	point = 8
elif (die1 + die2) == 9:
	point = 9
elif (die1 + die2) == 10:
	point = 10
elif (die1 + die2) == 11:
	win = True
elif (die1 + die2) == 12:
	win = False

3-12 – Dice value comparison for game of craps, using Boolean expression

die1 = 4
die2 = 3

if ((die1 + die2) == 2) or ((die1 + die2) == 3) or ((die1 + die2) == 12):
    win = False
elif ((die1 + die2) == 7) or ((die1 + die2) == 11):
    win = True
else:
    point = die1 + die2

3-VideoExercise – Video exercise solution

LDL = 80.0
HDL = 80.0
TRI = 180.0

total = LDL + HDL + (TRI/5.0)
if (LDL < 100) and (HDL > 60) and (TRI < 150) and (total < 200):
	print ("Cholesterol looks great!")
elif (LDL > 130) or (HDL < 50) or (TRI > 200) or (total > 240):
	print ("Warning: Cholesterol looks bad!")
else:
	print ("Borderline cholesterol problems.")

Lecture 4:

4 – Overall program developed

#Get information from user
print("I'll help you determine how long you will need to save.")
name = input("What's your name? ")
item = input("What is it you are saving up for? ")

balance = float(input("OK, "+name+".  Please enter the cost of the "+item+": "))
if (balance<0):
    print("Looks like you already saved enough!")
    balance = 0
    payment = 1
else:
    payment = float(input("Enter how much you will save each period: "))
    if (payment <= 0):
        payment = float(input("Savings must be positive.  Please enter a positive value:"))
        if (payment <=0):
            print(name+", you still didn't enter a positive number!  I am going to just assume you save 1 per period.")
            payment = 1

#Calculate number of payments that will be needed
num_remaining_payments = int(balance/payment)
if (num_remaining_payments < balance/payment):
    num_remaining_payments = num_remaining_payments + 1

#Present information to user
print(name+", you must make", num_remaining_payments, "more payments, and then you'll have your "+item+"!")

Lecture 5:

5-1 – Basic while loop

value = 0

#Get information from user
while value <= 0:
	value = int(input ("Enter a Positive value!"))
	print("You entered", value)

5-2 – Basic loop for counting to a limit

a = 0
while a < 3:
	print(a)
	a = a+1

5-3 – Basic loop for counting down to some limit

value = 10
while value > 0:
	print(value)
	value -= 1

5-4 – Loop for getting ages of those in a group

num_people = int(input("How many people are there? "))
i = 0 
total_age = 0.0
while (i < num_people):
	age = float(input("Enter the age of person " +str(i+1)+ ": "))
	total_age = total_age + age
	i = i+1
average_age = total_age / num_people
print("The average age was", average_age)

5-5 – Range examples

for i in range(4):
	print(i)


for i in range (0, 7, 1):
	print (i)


for i in range (1, 7, 2):
	print (i)


for i in range (5, 1, -1):
	print (i)

5-6 – While-else example

value = -1

while value <= 0:
    value = int(input ("Enter a Positive value!"))
else:
    print ("You entered", value)

5-7 – Solution – Times tables from 1 to 10

for i in range(1,11):
	for j in range(1,11):
		print(i, 'x', j, '=', i*j)

#OR

for i in range(10):
	for j in range(10):
		print(i+1, 'x', j+1, '=', (i+1)*(j+1))

5-8 – Solution – Printing pairs of people

numpeople = int(input("How many people are there?"))
for i in range(1, numpeople+1):
    for j in range(i+1, numpeople+1):
        print(i, j)

5-9 – Example of continue statement

day_to_skip = 4
hours_worked = 0
target_hours = 10
day = 0
while hours_worked < target_hours:
	day += 1
	target_hours += 8
	if day%day_to_skip == 0:
		continue
	if day < 10:
		hours_worked += 6
	elif day < 15:
		hours_worked += 8
	else:
		hours_worked += 14

print(hours_worked)

5-10 – Example of break statement

bad_number = 7

for i in range(1,10,2):
    if i == bad_number:
        print("Whoops!  We didn't want that number!")
        break
    print(i)
else:
    print("We got through all numbers")

5-VideoExercise – Video exercise solution

n = int(input("Enter a number: "))
print(n)

count = 0
while n != 1:
    count += 1
    if n % 2 == 0:
        n = n/2
    else:
        n = 3*n+1
    print(n)

print("We reached 1 in", count, "steps.")

Lecture 6:

6-1 – Opening and closing files

infile = open("MyDataFile.txt", "r")
outfile = open("results.txt", "w")
#Do stuff here
infile.close()
outfile.close()

#OR

with open("MyDataFile.txt", "r") as infile:
	with open("results.txt", "w") as outfile:
		#Do stuff here

6-2 – Writing a string to a file

myfile = open("Filename", "w")

outputstring = "This line is written to the file."
myfile.write(outputstring)

myfile.close()

6-3 – Writing numerical data to a file

#Assume the variables "volume1" and "volume2" have been computed
volume1 = 100.0
volume2 = 10

with open("results.txt", "w") as outfile:
	outfile.write("The first volume is " + str(volume1) + '\n')
	outfile.write("The second volume is " + str(volume2) + '\n')

6-4 – Reading from a file

myfile = open("Filename", "r")
outfile = open('output.txt', 'w')

linefromfile = myfile.readline()
secondline = myfile.readline()
outfile.write(linefromfile)
outfile.write(secondline)

outfile.close()
myfile.close()

6-5 – Solution: Reading numerical data from a file

infile = open("important.txt", "r")

linefromfile = infile.readline()
speed = float(linefromfile)

infile.close()

6-6 – Reading all lines from a file

myfile = open("Filename", "r")

linefromfile = myfile.readline()
while linefromfile != "":
	#do something
    linefromfile = myfile.readline()

myfile.close()

#OR

myfile = open("Filename", "r")

for linefromfile in myfile:
	#do something

myfile.close()

6-7 – Examples of escape characters

str1 = '"That\'s horrible," he said'
str2 = "\"That's horrible,\" he said"
str3 = '\"That\'s horrible,\" he said'
print(str1)
print(str2)
print(str3)

str4 = "This shows all \t sorts \t of \t options\n\\for \"escape\' characters"
print(str4)

6-8 – Examples of multi-line comments

a = """This is a
multi-line string that
contains three
new lines"""

b = '''This is another
multi-line string but this has
just two new lines'''


print(a)
print(b)

Lecture 7:

7-1 – Accessing elements of a list

daily_high_temps = [83, 80, 73, 75, 79, 83, 86]
print (daily_high_temps[0])
print (daily_high_temps[4])
i = 1
print (daily_high_temps[i])

daily_high_temps[3] = 100

print(daily_high_temps)

7-2 – Solutions: days in each month of the year, and handling leap year

days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
print(days_in_month[0])
print(days_in_month[8])

year = 2020
# use "%" to calculate the remainder from division
if (year%4 == 0):
    days_in_month[1]=29
    
print(days_in_month)

7-3 – Solution: Looping through all elements of a list

daily_high_temps = [83, 80, 73, 75, 79, 83, 86]
for i in range(len(daily_high_temps)):
	print(daily_high_temps[i])

#OR

daily_high_temps = [83, 80, 73, 75, 79, 83, 86]
for i in daily_high_temps:
	print(i)

# Changing the value of the iterator does not change the list
for i in daily_high_temps:
	i=0
print(daily_high_temps)

for i in range(7):
    daily_high_temps[i] = 0
print(daily_high_temps)

7-4 – Solution: Days in year from list of days in each month

days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
num_days = 0
for i in range(12):
	num_days += days_in_month[i]

print(num_days)

#OR

num_days = 0
for i in range(len(days_in_month)):
	num_days += days_in_month[i]

print(num_days)

#OR

days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
num_days = 0
for i in days_in_month:
	num_days += i

print(num_days)

#OR

num_days = sum(days_in_month)

print(num_days)

7-5 – Combining and appending lists

list1 = [3.1, 1.2, 5.9]
list2 = [3.0, 2.5]
list3 = list1 + list2
list1 += list2
list2.append(3.9)

print(list1)
print(list2)
print(list3)

7-6 – Building a list by appending

ages=[]
age = int(input("Enter an age of a group member.  Enter -1 when done"))
while (age != -1):
	ages.append(age)
	age = int(input("Enter an age of a group member.  Enter -1 when done"))

print (ages)

7-7 – Negative index and Slicing examples

daily_high_temps = [83, 80, 73, 75, 79, 83, 86]
print (daily_high_temps[-1])
print (daily_high_temps[-3])

weekday_temps = daily_high_temps[1:6]
print (weekday_temps)

daily_high_temps = [83, 80, 73, 75, 79, 83, 86]
daily_high_temps[1:6] = []
daily_high_temps[1:1] = [300, 100]
print(daily_high_temps)

daily_high_temps = [83, 80, 73, 75, 79, 83, 86]
daily_high_temps[1:6] = []
daily_high_temps[1:1] = [300, 100]
print(daily_high_temps)

daily_high_temps = [83, 80, 73, 75, 79, 83, 86]
daily_high_temps[1:6] = []
daily_high_temps[:0] = [300, 100]
print(daily_high_temps)

daily_high_temps = [83, 80, 73, 75, 79, 83, 86]
daily_high_temps[1:6] = []
daily_high_temps[2:2] = [300, 100]
print(daily_high_temps)

7-8 – Solution: slicing to get parts of a year

days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
days_in_summer = days_in_month[5:8]

days_at_beginning = days_in_month[:3]
days_at_end = days_in_month[-3:]
days_at_extremes1 = days_at_beginning + days_at_end

days_at_extremes2 = days_in_month[:]
days_at_extremes2[3:6] = []

print(days_in_summer)
print(days_at_beginning)
print(days_at_end)
print(days_at_extremes1)
print(days_at_extremes2)

7-9 – Slicing on strings

example = "Arthur, King of the Britons"
print (example[:6])
print (example[8:12])
print (example[-4:])

7-10 – String manipulation functions and List examples

teststr = "Testing String Commands"
lowstring = teststr.lower()
capstring = teststr.capitalize()

print(lowstring)
print(capstring)

list1 = [1, 2, 3, 4, 5]
list2 = [1.1, 2.2, 3.3, 4.4, 5.5]
list3 = ['a', "b", 'c', "d", 'e']

print(list1)
print(list2)
print(list3)

7-11 – Solution: working with lists of lists

list_of_lists = [ [4, 5, 6], [1, 2, 3], [7, 8, 9] ]
print (list_of_lists[0])
print (list_of_lists[2][0])

7-12 – Tuple example

credit_card = 'First National Bank Credit Card', 1357246898764321, 'January, 2023'

print(credit_card)


car_tuple = "Buick", "Century", 2007
make, model, year = car_tuple

print(make)
print(model)
print(year)
print(car_tuple[1:])

7-VideoExercise – Video exercise solution

names = []                                                    #start with empty lists
ages = []
name = input("Enter a person's name, or 'stop' to stop:" )    #Get the initial name
while (name != 'stop'):                                       #Keep going until "stop" is entered
    age = int(input("What is the age of "+name+"? "))         #Get the age
    names.append(name)                                        #Add names and ages to lists
    ages.append(age)
    name = input("Enter a person's name, or 'stop' to stop:" )

maxindex = 0                                                  #Start with the first person being oldest
for i in range(1,len(ages)):
    if ages[i] > ages[maxindex]:                              #See if this person is older, than oldest so far
        maxindex = i                                          # if so, set that person as the max

print("The oldest person is", names[maxindex])

Lecture 8:

8-1 – Examples of split command, including solution

phonenum = "888-345-9876"
areacode, prefix, suffix = phonenum.split('-')
print ('('+areacode+')'+prefix+'-'+suffix)

sentence = "Look, it's a bird! \n Very interesting."
words = sentence.split()
print (words)

greeting = "Howdy!How are you today?I'm great!"
lines = greeting.split('')
for line in lines:
    print(line)

8 – Final program developed

########## Read in Data ##########
#Open File
filename = input("Enter the name of the data file: ")
infile = open(filename, 'r')

#Read lines from File
datalist = []

for line in infile:
    #get data from line
    date, h, l, r = (line.split(','))
    lowtemp = int(l)
    hightemp = int(h)
    rainfall = float(r)
    m, d, y = date.split('/')
    month = int(m)
    day = int(d)
    year = int(y)
    #Put data into list
    datalist.append([day, month, year, lowtemp, hightemp, rainfall])

#Close File
infile.close()

########## Analyze Data ##########
# Get date of interest
month = int(input("For the date you care about, enter the month: "))
day = int(input("For the date you care about, enter the day: "))

# Find historical data for date
gooddata = []
for singleday in datalist:
    if (singleday[0] == day) and (singleday[1] == month):
        gooddata.append([singleday[2], singleday[3], singleday[4], singleday[5]])

# Perform analysis
minsofar = 120
maxsofar = -100
numgooddates = 0
sumofmin=0
sumofmax=0
raindays = 0
for singleday in gooddata:
    numgooddates += 1
    sumofmin += singleday[1]
    sumofmax += singleday[2]
    if singleday[1] < minsofar:
        minsofar = singleday[1]
    if singleday[2] > maxsofar:
        maxsofar = singleday[2]
    if singleday[3] > 0:
        raindays += 1
avglow = sumofmin / numgooddates
avghigh = sumofmax / numgooddates
rainpercent = raindays / numgooddates * 100


########## Present Results ##########
print("There were",numgooddates,"days")
print("The lowest temperature on record was", minsofar)
print("The highest temperature on record was", maxsofar)
print("The average low has been", avglow)
print("The average high has been", avghigh)
print("The chance of rain is", rainpercent, "%")

Datafile1 – Data file used in program

Lecture 9:

9-1 – Simple function definition and call

def warn():
	print("Warning! Use program at your own risk.")

a = 3
print (a)
warn()
print("Welcome!")

9-2 – Repeated function calls for one definition

########################### THIS IS OUR WARN FUNcTION #################
def warn():
	print("Warning! You are about to enter sensitive information.")
	ans = input("Do you want to continue? (Y/N)")
	if (ans == 'n') or (ans == 'N'):
		quit()

############################ THIS IS OUR "MAIN" CODE ##################
warn()
name = input("Enter your name:")

warn()
address = input("Enter your address:")

warn()
ccn = input("Type in your credit card number:")

warn()
expiration = input("Enter the expiration date for your card:")

9-3 – Functions to represent discrete ideas

def getClient():
    name = input("Enter the client's name:")
    address = input("Enter the client's address:")
    clientnames.append(name)
    clientaddresses.append(address)
    clientbalances.append(1)
    return

def printInvoice():
    print("To: "+clientnames[i])
    print("At: "+clientaddresses[i])
    print(clientnames[i]+", you owe a total of "+str(clientbalances[i]))
    print("Please pay your bill right away.")

clientnames = []
clientaddresses = []
clientbalances = []

have_client = True
while (have_client):
    getClient()
    response = input("Is there another client (y/n)?")
    if response == 'n':
        have_client = False

#More stuff here

for i in range(len(clientnames)):
    #Generate invoice
    if clientbalances[i] > 0:
        printInvoice()

9-4 – Returning values from functions

def getName():
	first = input("Enter your first name:")
	last = input("Enter your last name:")
	return last + ', ' + first

name = getName()

def getGuess():
	number = input("What number do you guess? ")
	return number

guess = getGuess()

print(name)
print(guess)

9-5 – Returning multiple values from functions

def getName():
	first = input("Enter your first name:")
	last = input("Enter your last name:")
	return first, last

name = getName()

userfirst, userlast = getName()

print(name)
print(userlast)
print(userfirst)

exampletuple = ("John", "Marwood", "Cleese")
first, middle, last= exampletuple

print(first)
print(exampletuple[2])

9-6 – More examples of returning multiple values from functions

def getBirthday():
    month = input("Enter your birth month: ")
    day = input("Enter your birth day: ")
    year = input("Enter your birth year: ")
    return month, day, year


bday = getBirthday()
m, d, y = getBirthday()
print(bday)
print(m)
print(d)
print(y)

9-7 – Passing a parameter to a function

def getSum(x):
	sum = 0
	for i in range(x+1):
		sum += i
	return sum


total = getSum(100)
print(total)

9-8 – Defining a function to hide inner workings from main code

def factorial(n):
    product = 1
    for i in range(1,n+1):
        product = product * i
    return product

print(factorial(20))

9-9 – Taking multiple parameters and building more complex functions by calling simpler ones

def getSum(x):
	return x * (x+1) / 2

def getRangeSum(a, b):
	return getSum(b) - getSum(a)


print ("The sum from 1 to 100 is:", getRangeSum(1, 100))
print ("The sum from 20 to 60 is:", getRangeSum(20, 60))

9-10 – Side effect – function changing list contents

def sumList(mylist):
    for i in range(1, len(mylist)):
        mylist[i] += mylist[i-1]
    return mylist[len(mylist)-1]

testlist = [5, 3, 2, 1, 4]

print(sumList(testlist))

print(testlist)

9-11 – Docstring example

def greet(name):
    """Print a greeting.
       Prints text "Hello, " for parameter ."""
    print("Hello, "+name)

help(greet)

9-VideoExercise – Video exercise solution

def countChar(ch, teststring):
    count = 0;
    for i in range(len(teststring)):
        if teststring[i] == ch:
            count += 1
    return count

print(countChar('e', "The quick brown fox jumped over the lazy dogs."))

Lecture 10:

10-1 – Parameter passing and return

def maxdemo(val1, val2):
	if (val1 > val2):
		return val1
	else:
		return val2

a = 1
b = 2
c = maxdemo(a,b)
print(c)

10-2 – Scope of local parameters

def testscore(numcorrect, total):
	numcorrect += 5
	temp_value = numcorrect / total
	return (temp_value * 100)

a = 12
b = 20
c = testscore(a,b)
print(c)

10-3 – Accessing data in main program from a function

a = 10

def testscore(numcorrect, total):
	numcorrect += a;
	temp_value = numcorrect / total
	return (temp_value * 100)

a = 12
b = 20
c = testscore(a,b)
print(c)

10-4 – Global variable declarations in functions

def initialize():
	global fuellevel
	fuellevel = 100.0

fuellevel = 0
initialize()
print(fuellevel)

10-5 – Mutable and immutable data types passed as parameters

def adder(val1, val2):
	val1 += val2

num1 = 3
num2 = 4
adder(num1, num2)
print (num1)

num1 = 3.1
num2 = 4.1
adder(num1, num2)
print(num1)

num1 = "Hi"
num2 = "There"
adder(num1, num2)
print(num1)

num1 = [1, 2]
num2 = [3, 4]
adder(num1, num2)
print(num1)

10-6 – Mutable data being modified or assigned to

def DoSomething(in1, in2):
	in1 += [7]
	in2 = [8]

a = [1, 2, 3]
b = [4, 5, 6]
DoSomething(a, b)
print (a)
print (b)

10-7 – Default parameters

def calc_miles(gallons, mpg=20.0):
	return gallons*mpg

print( calc_miles(10.0, 15.0) )
print( calc_miles(10.0) )

10-8 – Madlib showing default parameters and

def madlib(animal="Dinosaur", adjective="Green", city="Chicago", food="Spaghetti" ):
	return "You'll never believe what I saw in " + city + ".  It was a " + adjective + " " + animal + "!  And, it was eating "+food+"!"

print( madlib() )
print( madlib("kangaroo") )
print( madlib("parrot", "dead") )
print( madlib("dog", "happy", "New York") )
print( madlib("platypus", "tired", "Dallas", "pizza") )

print( madlib(food = "pizza") )
print( madlib("cat", food = "steak", city = "Denver") )

Lecture 11:

11-buggy – Buggy version of program that is debugged in the lesson

########## Read in Data ##########
#Open File
filename = input("Enter the name of the data file: ")
infile = open(filename, 'r')

#Read lines from File
datalist = []

for line in infile:
    #get data from line
    date, h, l, r = (line.split(','))
    lowtemp = int(l)
    hightemp = int(h)
    rainfall = float(r)
    m, d, y = date.split('/')
    month = int(m)
    day = int(d)
    year = int(y)
    #Put data into list
    datalist.append([day, month, year, lowtemp, hightemp, rainfall])

#Close File
infile.close()

########## Analyze Data ##########
# Get date of interest
month = int(input("For the date you care about, enter the month: "))
day = int(input("For the date you care about, enter the day: "))

# Find historical data for date
gooddata = []
for singleday in datalist:
    if (singleday[0] == month) and (singleday[1] == day):
        gooddata.append([singleday[2], singleday[3], singleday[4], singleday[5]])

# Perform analysis
minsofar = 120
maxsofar = -100
numgooddates = 0
sumofmin=0
sumofmax=0
raindays = 0
for singleday in gooddata:
    numgooddates += 1
    sumofmin += singleday[1]
    sumofmax += singleday[2]
    if singleday[1] < minsofar:
        minsofar = singleday[1]
    if singleday[2] > maxsofar:
        maxsofar = singleday[2]
    if singleday[3] > 0:
        raindays += 1
avglow = sumofmin / numgooddates
avghigh = sumofmax / numgooddates
rainpercent = raindays / numgooddates * 100


########## Present Results ##########
print("There were",numgooddates,"days")
print("The lowest temperature on record was", minsofar)
print("The highest temperature on record was", maxsofar)
print("The average low has been", avglow)
print("The average high has been", avghigh)
print("The chance of rain is", rainpercent, "%")


exit(0)

11-1 – Exception handling example

filename = input("Henter name of file:")
try:
    myfile = open(filename, 'r')
except OSError:
    print("That file could not be opeend.  Using default file.")
    myfile = open("Default.txt", "r")

11-2 – Multiple exception blocks

def computeDivision(first, second):
    try:
        division = first/second
    except TypeError:
        print("You didn't enter two floating point numbers!")
    except ZeroDivisionError:
        print("Don't give a zero for the second number!")
    except:
        print("There was some other exception.")
    else:
        print("Great - no exceptions were raised!")
    finally:
        print("The function is ending")
    return division

11-3 – Raising exceptions

def computeDate(month, day, year):
    try:
        if (month <= 0) or (month > 12):
            raise TypeError
    except TypeError:
        print("Invalid Date: Please reenter:")
        day = int(input("Enter the day: "))
        month = int(input("Enter the month: "))
        year = int(input("Enter the year: "))

def find_pattern(pattern, sequence):
    if len(pattern) != 5:
        #expected pattern of length 5
        raise TypeError

Datafile1 – Data file used in program

Lecture 12:

12-1 – using some basic modules from Python Standard Library

import math
print(math.sin(math.pi/2))

import webbrowser
webbrowser.open("http://www.thegreatcourses.com")

import turtle
turtle.forward(100)

import shutil
shutil.copy("File1.txt", "File2.txt")

12-ModuleA – Code to be saved separately as ModuleA.py for use in other modules

a = 5

#while(True):
#    st = input("Type something: ")
#    print("You typed:", st)

def SumOfSquares(n):
    sum = 0
    for i in range(1,n+1):
        sum += i*i
    return sum

def SumOfCubes(n):
    sum = 0
    for i in range(1,n+1):
        sum += i*i*i
    return sum

12-2 – importing and using a user-defined module

import math
print(math.cos(math.pi / 4.0))

from math import *
print(cos(pi / 4.0))

import webbrowser
webbrowser.open("http://www.thegreatcourses.com")

import calendar
calendar.setfirstweekday((calendar.SUNDAY))
print(calendar.month(2020, 1))

import time
print(time.ctime())

import statistics
a = [3, 10, 23, 5, 14, 83, 7, 1]
print(statistics.median(a))

import shutil
shutil.copy("temperature.dat", "weather.txt")

12-3 – many examples of modules from Python Standard Libraryy

import math
print(math.cos(math.pi / 4.0))

from math import *
print(cos(pi / 4.0))

import webbrowser
webbrowser.open("http://www.thegreatcourses.com")

import calendar
calendar.setfirstweekday((calendar.SUNDAY))
print(calendar.month(2020, 1))

import time
print(time.ctime())

import statistics
a = [3, 10, 23, 5, 14, 83, 7, 1]
print(statistics.median(a))

import shutil
shutil.copy("temperature.dat", "weather.txt")

12-4 – Picture renaming

import os

dirname = input("Enter the directory: ")
os.chdir(dirname)
dirlist = os.listdir()

lead = input("what label do you want for the pictures? ")
picture_number = 1
for filename in dirlist:
    if filename.endswith('.jpg'):
        newname = lead+str(picture_number)+".jpg"
        os.rename(filename,newname)
        picture_number += 1

12-VideoExercise – Video exercise solution

import random

while (True):
    secretnum = random.randint(1,100)
    numguesses = 0
    guessed = False
    while not guessed:
        guess = int(input("Enter a guess from 1 to 100: "))
        numguesses += 1
        if guess == secretnum:
            print("You guessed it!  It took you", numguesses, "tries!")
            guessed = True
        elif guess < secretnum:
            print("Too low!  Try again.")
        else:
            print("Too high! Try again.")

Lecture 13:

13 – Game program developed in lecture

from random import choice

def InitializeGrid(board):
    #Initialize Grid by reading in from file
    for i in range(8):
        for j in range(8):
            board[i][j] = choice(['Q', 'R', 'S', 'T', 'U'])

def Initialize(board):
    #Initialize game
    #Initialize grid
    InitializeGrid(board)
    #Initialize score
    global score
    score = 0
    #Initialize turn number
    global turn
    turn = 1

def ContinueGame(current_score, goal_score = 100):
    #Return false if game should end, true if game is not over
    if (current_score >= goal_score):
        return False
    else:
        return True

def DrawBoard(board):
    #Display the board to the screen
    #Draw some blank lines first
    print("\n\n\n")
    print("  ---------------------------------")
    #Now draw rows from 8 down to 1
    for i in range(7,-1,-1):
        #Draw each row
        linetodraw= str(i+1)
        for j in range(8):
            linetodraw += " | " + board[i][j]
        linetodraw+= " |"
        print(linetodraw)
        print("   ---------------------------------")
    print("    a   b   c   d   e   f   g   h")
    global score
    print("Current Sore: ", score)

def IsValid(move):
    #Returns true if the move is valid, false otherwise
    #Check length of move
    if len(move) != 3:
        return False

    #Check that the space and direction are valid
    if not (move[0] in ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']):
        return False
    if not (move[1] in ['1', '2', '3', '4', '5', '6', '7', '8']):
        return False
    if not (move[2] in ['u', 'd', 'l', 'r']):
        return False

    #Check that the direction is valid for the given row/column
    #check that first column moves are not left
    if (move[0] == 'a') and (move[2] == 'l'):
        return False
    #check that last column moves are not right
    if (move[0] == 'h') and (move[2] == 'r'):
        return False
    #check that bottom row moves are not down
    if (move[1] == '1') and (move[2] == 'd'):
        return False
    #check that top row moves are not up
    if (move[1] == '8') and (move[2] == 'u'):
        return False

    #no problems, so the move is valid!
    return True

def GetMove():
    #Get the move from the user
    #Print instructions
    print("Enter a move by specifying the space and the direction (u,d,l,r).  Spaces should list column then row).")
    print("For exmaple, e3u would swap position e3 with the one above, and f7r would swap f7 to the right.")

    #Get Move
    move = input("Enter move: ")

    #Loop until we get good move
    while not IsValid(move):
        move = input("That's not a valid move!  Enter another move:")

    return move

def ConvertLetterToCol(Col):
    if Col == 'a':
        return 0
    elif Col == 'b':
        return 1
    elif Col == 'c':
        return 2
    elif Col == 'd':
        return 3
    elif Col == 'e':
        return 4
    elif Col == 'f':
        return 5
    elif Col == 'g':
        return 6
    elif Col == 'h':
        return 7
    else:
        #not a valid column!
        return -1

def SwapPieces(board, move):
    #Swap pieces on board according to move
    #Get original position
    origrow = int(move[1])-1
    origcol = ConvertLetterToCol(move[0])

    #Get adjacent position
    if move[2] == 'u':
        newrow = origrow + 1
        newcol = origcol
    elif move[2] == 'd':
        newrow = origrow - 1
        newcol = origcol
    elif move[2] == 'l':
        newrow = origrow
        newcol = origcol - 1
    elif move[2] == 'r':
        newrow = origrow
        newcol = origcol + 1

    #Swap objects in two positions
    temp = board[origrow][origcol]
    board[origrow][origcol] = board[newrow][newcol]
    board[newrow][newcol] = temp

def RemovePieces(board):
    #Remove 3-in-a-row and 3-in-a-column pieces
    #Create board to store remove-or-not
    remove = [[0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0]]

    #Go through rows
    for i in range(8):
        for j in range(6):
            if (board[i][j] == board[i][j+1]) and (board[i][j] == board[i][j+2]):
                #three in a row are the same!
                remove[i][j] = 1;
                remove[i][j+1] = 1;
                remove[i][j+2] = 1;

    #Go through columns
    for j in range(8):
        for i in range(6):
            if (board[i][j] == board[i+1][j]) and (board[i][j] == board[i+2][j]):
                #three in a row are the same!
                remove[i][j] = 1;
                remove[i+1][j] = 1;
                remove[i+2][j] = 1;

    #Eliminate those marked
    global score
    removed_any = False
    for i in range(8):
        for j in range(8):
            if remove[i][j] == 1:
                board[i][j] = 0
                score += 1
                removed_any = True
    return removed_any

def DropPieces(board):
    #Drop pieces to fill in blanks
    for j in range(8):
        #make list of pieces in the column
        listofpieces = []
        for i in range(8):
            if board[i][j] != 0:
                listofpieces.append(board[i][j])
        #copy that list into colulmn
        for i in range(len(listofpieces)) :
            board[i][j] = listofpieces[i]
        #fill in remainder of column with 0s
        for i in range(len(listofpieces), 8):
            board[i][j] = 0

def FillBlanks(board):
    #Fill blanks with random pieces
    for i in range(8):
        for j in range(8):
            if (board[i][j] == 0):
                board[i][j] = choice(['Q', 'R', 'S', 'T', 'U'])

def Update(board, move):
    #Update the board according to move
    SwapPieces(board, move)
    pieces_eliminated = True
    while pieces_eliminated:
        pieces_eliminated = RemovePieces(board)
        DropPieces(board)
        FillBlanks(board)


def DoRound(board):
    #Perform one round of the game
    #Display current board
    DrawBoard(board)
    #Get move
    move = GetMove()
    #Update board
    Update(board, move)
    #Update turn number
    global turn
    turn += 1

#State main variables
score = 100
turn = 100
goalscore = 100
board = [[0, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0, 0]]

#Initialize game
Initialize(board)

#While game not over
while ContinueGame(score, goalscore):
    #Do a round of the game
    DoRound(board)

Lecture 14:

14-1 – Turtle graphics: square spiral

from turtle import forward, left
for i in range(1,100):
    forward(2*i)
    left(90)

input()

14-2 – Encapsulating turtle commands into a function

from turtle import forward, backward, left, right, penup, pendown

def drawSquare():
    forward(100)
    left(90)
    forward(100)
    left(90)
    forward(100)
    left(90)
    forward(100)
    left(90)

drawSquare()
drawSquare()

input()

14-3 – Creating and combining shape functions to draw a house shape

from turtle import forward, backward, left, right, penup, pendown

def drawRectangle(length = 100, height = 100):
    forward(length)
    left(90)
    forward(height)
    left(90)
    forward(length)
    left(90)
    forward(height)
    left(90)

def drawTriangle(size=100):
    forward(size)
    left(120)
    forward(size)
    left(120)
    forward(size)
    left(120)

def drawSquare(size=100):
    forward(size)
    left(90)
    forward(size)
    left(90)
    forward(size)
    left(90)
    forward(size)
    left(90)

def drawHouse(size = 100):
    #draw base
    drawSquare(size)

    #reposition turtle
    left(90)
    forward(size)
    right(90)

    #draw top
    drawTriangle(size)

    #move back to start
    right(90)
    forward(size)
    left(90)

drawHouse(80)

input()

14-4 – Generating tally marks

from turtle import forward, backward, left, right, penup, pendown, pos, goto

def shiftRight():
    penup()
    forward(5)
    pendown()

def drawTally():
    left(90)
    forward(20)
    backward(20)
    right(90)
    shiftRight()

def drawSlash():
    #move up
    left(90)
    penup()
    forward(3)
    pendown()

    # draw slash
    startposition = pos()
    goto(startposition[0] - 25, startposition[1] + 14)
    # Note: alternative would have been left(61) then forward( (28.7)

    # return to starting position
    penup()
    goto(startposition)
    # Note: alternative would have been backward(28.7) then right(61)
    backward(3)
    right(90)
    pendown()

    #shift over
    shiftRight()
    shiftRight()

def drawFive():
    drawTally()
    drawTally()
    drawTally()
    drawTally()
    drawSlash()

def drawTallies(n):
    while(n>=5):
        drawFive()
        n = n - 5
    while(n>=1):
        drawTally()
        n = n - 1

num_to_draw = int(input("Enter a number:"))
drawTallies(num_to_draw)

input()

14-5 – Robot path for room coverage

from turtle import *
import random

xmax = 250
xmin = -250
ymax = 250
ymin = -250
proximity = 10

def sensor():
    if xmax - position()[0] < proximity:
        #Too close to right wall
        return True
    if position()[0] - xmin < proximity:
        #Too clsoe to left wall
        return True
    if ymax - position()[1] < proximity:
        #Too close to top wall
        return True
    if position()[1] - ymin < proximity:
        #Too clsoe to bottom wall
        return True
    #Not too close to any
    return False

def straightline():
    '''Move in a random direction until sensor is triggered'''
    #Pick a random direction
    left(random.randrange(0,360))
    #Keep going forward until a wall is hit
    while not sensor():
        forward(1)

def spiral(gap = 20):
    '''Spiral with spacing gap'''
    #Determine starting radius of spiral based on the gap
    current_radius = gap
    while not sensor():
        #Determine how much of the circumference 1 unit is
        circumference = 2 * 3.14159*current_radius
        fraction = 1/circumference
        #Move as if in a circle of that radius
        left(fraction*360)
        forward(1)
        #Change radius so that we will be out by 2*proximity after 360 degrees
        current_radius += gap*fraction

def backupspiral(backup = 100, gap = 20):
    '''First move backward by amount backup, then in a spiral with spacing gap'''
    #first back up by backup amount
    while not sensor() and backup > 0:
        backward(1)
        backup -= 1
    #Now spiral out
    spiral(gap)

def followwall(amount = 500):
    '''Move turtle parallel to nearest wall for amount distance'''
    #find nearest wall and turn parallel to it
    min = xmax - position()[0]
    setheading(90)
    if position()[0] - xmin < min:
        min = position()[0] - xmin
        setheading(270)
    if ymax - position()[1] < min:
        min = ymax - position()[1]
        setheading(180)
    if position()[1] - ymin < min:
        setheading(0)

    #Keep going until hitting another wall
    while not sensor() and amount > 0:
        forward (1)
        amount -= 1

    #Keep going until hitting another wall
    while not sensor():
        forward (1)


speed(0)
#Start with a spriral
spiral(40)
while (True):
    #First back up so no longer colliding
    backward(1)
    #Pick one of the three behaviors at random
    which_function = random.choice(['a', 'b', 'c'])
    if which_function == 'a':
        straightline()
    if which_function == 'b':
        backupspiral(random.randrange(100,200), random.randrange(10,50))
    if which_function == 'c':
        followwall(random.randrange(100,500))

Lecture 15:

15-1 – Early Pyglet program – printing text labels in a window

import pyglet

window = pyglet.window.Window(width=400, height=300, caption="TestWindow")

label1 = pyglet.text.Label('Howdy',
                           font_name='Times New Roman',
                           font_size=18,
                           x=50, y = 250)
label2 = pyglet.text.Label('World',
                           font_name='Times New Roman',
                           font_size=18,
                           x=300, y = 50)

@window.event
def on_draw():
    window.clear()
    label1.draw()
    label2.draw()

pyglet.app.run()

15-2 – Pyglet program to demonstrate key press capture

import pyglet
from pyglet.window import key

window = pyglet.window.Window(width=400, height=300, caption="TestWindow")

label = pyglet.text.Label('Nothing pressed so far',
                          font_name='Times New Roman',
                          font_size=18,
                          x=50, y = 150)

@window.event
def on_key_press(symbol, modifiers):
    if symbol == key.A:
        key_pressed = "a"
    elif symbol == key.RETURN:
        key_pressed = "return"
    elif symbol == key.LEFT:
        key_pressed = "left arrow"
    else:
        key_pressed = 'unknown'
    global label
    label = pyglet.text.Label('You pressed the '+key_pressed+' key!',
                          font_name='Times New Roman',
                          font_size=18,
                          x=50, y = 150)

@window.event
def on_draw():
    window.clear()
    label.draw()

pyglet.app.run()

15-3 – Pyglet program to demonstrate mouse capture

import pyglet
from pyglet.window import key

window = pyglet.window.Window(width=400, height=300, caption="TestWindow")

label = pyglet.text.Label('Nothing pressed so far',
                          font_name='Times New Roman',
                          font_size=18,
                          x=50, y = 150)

@window.event
def on_key_press(symbol, modifiers):
    if symbol == key.A:
        key_pressed = "a"
    elif symbol == key.RETURN:
        key_pressed = "return"
    elif symbol == key.LEFT:
        key_pressed = "left arrow"
    else:
        key_pressed = 'unknown'
    global label
    label = pyglet.text.Label('You pressed the '+key_pressed+' key!',
                              font_name='Times New Roman',
                              font_size=18,
                              x=50, y = 150)

@window.event
def on_mouse_press(x, y, button, modifiers):
    global label
    label = pyglet.text.Label('Mouse click at position ('+str(x)+', '+str(y)+')',
                              font_name='Times New Roman',
                              font_size=18,
                              x=50, y = 150)

@window.event
def on_mouse_release(x, y, button, modifiers):
    global label
    label = pyglet.text.Label('Mouse released at position ('+str(x)+', '+str(y)+')',
                              font_name='Times New Roman',
                              font_size=18,
                              x=25, y = 150)

@window.event
def on_mouse_drag(x, y, dx, dy, button, modifiers):
    global label
    label = pyglet.text.Label('Mouse is dragging at position ('+str(x)+', '+str(y)+')',
                              font_name='Times New Roman',
                              font_size=18,
                              x=0, y = 150)


@window.event
def on_mouse_motion(x, y, dx, dy):
    global label
    label = pyglet.text.Label('Mouse is at position ('+str(x)+', '+str(y)+')',
                              font_name='Times New Roman',
                              font_size=18,
                              x=50, y = 150)

@window.event
def on_draw():
    window.clear()
    label.draw()

pyglet.app.run()

15-4 – Pyglet program to load and display images

import pyglet
window = pyglet.window.Window(width=400, height = 500, caption="GameWindow")

Im1 = pyglet.image.load('BlueTri.jpg')

@window.event
def on_draw():
    window.clear()
    Im1.blit(50, 50)

pyglet.app.run()

15-5 – Graphical interface to grid-based matching game

from random import choice
import pyglet

window = pyglet.window.Window(width=400, height = 450, caption="GameWindow")
Im1 = pyglet.image.load('BlueTri.jpg')
Im2 = pyglet.image.load('PurpleStar.jpg')
Im3 = pyglet.image.load('OrangeDiamond.jpg')
Im4 = pyglet.image.load('YellowCircle.jpg')
Im5 = pyglet.image.load('RedHex.jpg')

def InitializeGrid(board):
    #Initialize Grid by reading in from file
    for i in range(8):
        for j in range(8):
            board[i][j] = choice(['A', 'B', 'C', 'D', 'E'])

def Initialize(board):
    #Initialize game
    #Initialize grid
    InitializeGrid(board)
    #Initialize score
    global score
    score = 0
    #Initialize turn number
    global turn
    turn = 1
    #Set up graphical info


def ContinueGame(current_score, goal_score = 100):
    #Return false if game should end, true if game is not over
    if (current_score >= goal_score):
        return False
    else:
        return True

def SwapPieces(board, move):
    #Swap objects in two positions
    temp = board[move[0]][move[1]]
    board[move[0]][move[1]] = board[move[2]][move[3]]
    board[move[2]][move[3]] = temp

def RemovePieces(board):
    #Remove 3-in-a-row and 3-in-a-column pieces
    #Create board to store remove-or-not
    remove = [[0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0, 0]]

    #Go through rows
    for i in range(8):
        for j in range(6):
            if (board[i][j] == board[i][j+1]) and (board[i][j] == board[i][j+2]):
                #three in a row are the same!
                remove[i][j] = 1;
                remove[i][j+1] = 1;
                remove[i][j+2] = 1;

    #Go through columns
    for j in range(8):
        for i in range(6):
            if (board[i][j] == board[i+1][j]) and (board[i][j] == board[i+2][j]):
                #three in a row are the same!
                remove[i][j] = 1;
                remove[i+1][j] = 1;
                remove[i+2][j] = 1;

    #Eliminate those marked
    global score
    removed_any = False
    for i in range(8):
        for j in range(8):
            if remove[i][j] == 1:
                board[i][j] = 0
                score += 1
                removed_any = True
    return removed_any

def DropPieces(board):
    #Drop pieces to fill in blanks
    for j in range(8):
        #make list of pieces in the column
        listofpieces = []
        for i in range(8):
            if board[i][j] != 0:
                listofpieces.append(board[i][j])
        #copy that list into colulmn
        for i in range(len(listofpieces)) :
            board[i][j] = listofpieces[i]
        #fill in remainder of column with 0s
        for i in range(len(listofpieces), 8):
            board[i][j] = 0

def FillBlanks(board):
    #Fill blanks with random pieces
    for i in range(8):
        for j in range(8):
            if (board[i][j] == 0):
                board[i][j] = choice(['A', 'B', 'C', 'D', 'E'])

def Update(board, move):
    #Update the board according to move
    SwapPieces(board, move)
    pieces_eliminated = True
    while pieces_eliminated:
        pieces_eliminated = RemovePieces(board)
        DropPieces(board)
        FillBlanks(board)

@window.event
def on_draw():
    window.clear()
    for i in range(7,-1,-1):
        #Draw each row
        y = 50+50*i
        for j in range(8):
            #draw each piece, first getting position
            x = 50*j
            if board[i][j] == 'A':
                Im1.blit(x,y)
            elif board[i][j] == 'B':
                Im2.blit(x,y)
            elif board[i][j] == 'C':
                Im3.blit(x,y)
            elif board[i][j] == 'D':
                Im4.blit(x,y)
            elif board[i][j] == 'E':
                Im5.blit(x,y)
    label = pyglet.text.Label('Turn: '+str(turn)+'   Score: '+str(score),
                          font_name='Arial',
                          font_size=18,
                          x=20, y = 10)
    label.draw()

@window.event
def on_mouse_press(x, y, button, modifiers):
    #Get the starting cell
    global startx
    global starty
    startx = x
    starty = y

@window.event
def on_mouse_release(x, y, button, modifiers):
    #Get starting and ending cell and see if they are adjacent
    startcol = startx//50
    startrow = (starty-50)//50
    endcol = x//50
    endrow = (y-50)//50
    #Check whether ending is adjacent to starting and if so, make move.
    if ((startcol==endcol and startrow==endrow - 1) or (startcol==endcol and startrow==endrow+1) or
            (startrow==endrow and startcol==endcol-1) or (startrow==endrow and startcol==endcol+1)):
        Update(board,[startrow,startcol,endrow,endcol])
        global turn
        turn += 1
        #See if game is over
        if not ContinueGame(score):
            print("You won in", turn, "turns!")
            exit()

#State main variables
score = 100
turn = 100
goalscore = 100
board = [[0, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0, 0]]

#Initialize game
Initialize(board)

pyglet.app.run()

15-6 – Tkinter program showing button creation and operation

import tkinter

class Application(tkinter.Frame):
    def __init__(self, master=None):
        tkinter.Frame.__init__(self, master)
        self.pack()

        self.increase_button = tkinter.Button(self)
        self.increase_button["text"] = "Increase"
        self.increase_button["command"] = self.increase_value
        self.increase_button.pack(side="right")

        self.increase_button = tkinter.Button(self)
        self.increase_button["text"] = "Decrease"
        self.increase_button["command"] = self.decrease_value
        self.increase_button.pack(side="left")

    def increase_value(self):
        global mainval
        mainval *= 2
        print (mainval)
    def decrease_value(self):
        global mainval
        mainval /= 2
        print (mainval)

mainval = 1.0

root = tkinter.Tk()
app = Application(master=root)
app.mainloop()

BlueTri.jpg – Image used for pieces

GreenSquare.jpg – Image used for pieces

OrangeDiamond.jpg – Image used for pieces

PurpleStar.jpg – Image used for pieces

RedHex.jpg – Image used for pieces

YellowCircle.jpg – Image used for pieces

Lecture 16:

16-1 – Basic data plot

from matplotlib import pyplot

pyplot.plot([0,1,2,3,4,5], [0,1,4,9,16,25])

pyplot.axis([0,5,0,25])

pyplot.show()

exit(0)

16-2 – Plotting data formed automatically

from matplotlib.pyplot import plot, axis, show

xlist = range(0,6)
ylist = []
for i in xlist:
    ylist.append(i*i)
plot(xlist, ylist)

axis([0,5,0,25])

show()

16-3 – Plotting with color and symbols

from matplotlib.pyplot import plot, axis, show, legend

xlist = range(0,6)
ylist = []
for i in xlist:
    ylist.append(i*i)
plot(xlist, ylist, label="squares", marker='+', color = "red", markeredgecolor="blue")

axis([0,5,0,25])

legend()

show()

16-4 – Plotting two sets of data on same axes

from matplotlib.pyplot import plot, axis, show, legend

xlist = range(0,6)
ylist = []
ylist2 = []
for i in xlist:
    ylist.append(i*i)
    ylist2.append(i*i*i)
plot(xlist, ylist, label="squares", marker='+', color = "red", markeredgecolor="blue")
plot(xlist, ylist2, label="cubes", marker = "o", color ="green", markeredgecolor = "green")

axis([0,5,0,125])

legend()

show()

16-5 – Plotting 3 sets of data with 3 axes

from matplotlib.pyplot import subplots, show

fig, mainplot = subplots()
plot2 = mainplot.twinx()
plot3 = mainplot.twinx()
fig.subplots_adjust(right=0.75)

plot3.spines["right"].set_position(("axes", 1.15))

p1, = mainplot.plot([2000, 2004, 2006, 2010], [350, 550, 900, 700], "b", label="Fish")
p2, = plot2.plot([2000, 2009], [12, 17], "r", label="Bears")
p3, = plot3.plot([2000, 2002, 2004, 2006, 2008, 2010], [11, 13, 15, 18, 24, 29], "g", label="Eagles")

mainplot.set_xlim(2000, 2010)
mainplot.set_ylim(300, 1000)
plot2.set_ylim(0, 20)
plot3.set_ylim(0, 30)

mainplot.set_xlabel("Year")
mainplot.set_ylabel("Fish")
plot2.set_ylabel("Bears")
plot3.set_ylabel("Eagles")

mainplot.yaxis.label.set_color("b")
plot2.yaxis.label.set_color("r")
plot3.yaxis.label.set_color("g")

mainplot.tick_params(axis='y', colors = "b")
plot2.tick_params(axis='y', colors = "r")
plot3.tick_params(axis='y', colors = "g")


lines = [p1, p2, p3]
mainplot.legend(lines, [l.get_label() for l in lines])

show()

16-6 – Graphing a mortgage over time

from matplotlib.pyplot import plot, axis, show, legend

mortgage_amount = float(input("How much is the mortgage for?"))
interest_rate = float(input("What is the interest rate (as a percentage)?"))/100
payment = float(input("How much are you paying per month?"))

max_months = 1200 # don't figure for more than 10 years
month = 0
month_list = [0]
mortgage_list = [mortgage_amount]
principal_paid_list = [0]
interest_paid_list = [0]

while (mortgage_amount > 0.0) and (month < max_months):
    month += 1
    month_list.append(month)
    #determine new interest
    interest = mortgage_amount *(interest_rate/12)
    interest_paid_list.append(interest+interest_paid_list[month-1])
    #determine pricipal paid and remaining
    principal = payment - interest
    mortgage_amount -= principal
    mortgage_list.append(mortgage_amount)
    principal_paid_list.append(principal+principal_paid_list[month-1])


plot(month_list, mortgage_list, label="Remaining Mortgage", color = "red")
plot(month_list, principal_paid_list, label="Principal Paid", color = "blue")
plot(month_list, interest_paid_list, label="Interest Paid", color = "green")

axis([0,month,0,max(interest_paid_list[month], mortgage_list[0])])

legend()

show()

16-7 – Growth of a fixed investment over time

from matplotlib.pyplot import plot, show

#Set initial conditions
time = 0
balance = 1000
#Set list to store data
timelist=[time]
balancelist=[balance]

while (time < 100):
    #Increase balance and time
    balance += balance*0.03
    time += 1
    #Store time and balance in lists
    timelist.append(time)
    balancelist.append(balance)

#Output the simulation results
for i in range(len(timelist)):
    print("Year:", timelist[i], "  Balance:", balancelist[i])

plot(timelist, balancelist)
show()

16-8 – Monte Carlo simulation of growth in an investment with fluctuating interest

import random
from matplotlib.pyplot import hist, show

def ChangeInBalance(initial_balance):
    rate = random.uniform(0.0, 0.06)
    return initial_balance*rate

number_years = 10
number_sims = 10000
final_balances = []
for i in range(number_sims):
    #Set initial conditions
        time = 0
        balance = 1000

        while (time < number_years):
            #Increase balance and time
            balance += ChangeInBalance(balance)
            time += 1

        final_balances.append(balance)

#Output the simulation results
hist(final_balances, bins=20)
show()

16-9 – Simulation comparing many different investment options

import random
import statistics
from matplotlib.pyplot import hist, show

historical_stock_returns = [.1348, .3215, .1589, .0210, .1482, .2594, -.3655, .0548, .1561,
                            .0483, .1074, .2836, -.2197, -.1185, -.0903, .2089, .2834, .3310, .2268,
                            .3720, .0133, .0997, .0749, .3023, -.0306, .3148, .1654, .0581, .1849,
                            .3124, .0615, .2234, .2042, -.0470, .3174, .1852, .0651, -.0698, .2383,
                            .3700, -.2590, -.1431, .1876, .1422, .0356, -.0824, .1081, .2380, -.0997,
                            .1240, .1642, .2261, -.0881, .2664, .0034, .1206, .4372, -.1046, .0744,
                            .3260, .5256, -.0121, .1815, .2368, .3081, .1830, .0570, .0520, -.0843]

historical_bond_performance = [-.0202, .0422, .0784, .0654, .0593, .0524, .0697, .0433,
                               .0243, .0434, .0410, .1026, .0843, .1163 -.0082, .0870, .0964, .0364,
                              .1846, -.0292, .0975, .0740, .1600, .0896, .1453, .0789, .0275, .1530,
                               .2213, .1515, .0819, .3265, .0626, .271]

historical_bond_yields = [.0485, .051, .0494, .0566, .0604, .0729, .0744, .0648, .0648,
                          .0606, .0639, .0676, .078, .0795, .0837, .0788, .0722, .0787, .0805,
                          .082, .0863, .0793, .0898, .098, .1036, .1018, .1083, .1053, .1039,
                          .1272, .1419, .135, .1611, .1604, .1367, .1069, .0949, .0897, .0975]

historical_treasury_rates = [.0254, .0235, .018, .0278, .0322, .0326, .0366, .0463, .048,
                             .0429, .0427, .0401, .0461, .0502, .0603, .0565, .0526, .0635, .0644,
                             .0657, .0709, .0587, .0701, .0786, .0855, .0849, .0885, .0839, .0767,
                             .1062, .1246, .111, .1301, .1392, .1143, .0943, .0841, .0742, .0761,
                             .0799, .0756, .0685, .0621, .0616, .0735, .0667, .0564, .0507, .0493,
                             .0428, .0419, .0400, .0395]

historical_inflation = [.0, .016, .015, .021, .032, .016, -.004, .038, .028, .032,
                        .034, .027, .023, .016, .028, .034, .022, .016, .023, .030,
                        .028, .026, .030, .030, .042, .054, .048, .041, .036, .019,
                        .036, .043, .032, .062, .103, .135, .113, .076, .065, .058,
                        .091, .110, .062, .032, .044, .057, .055, .042, .031, .029,
                        .016, .013, .013, .010, .010, .017, .007, .028, .033, .015,
                        -.004, .007, .008, .019, .079, .013, -.012, .081, .144, .083]

def ChangeInBalanceStocks(initial_balance):
    rate = random.choice(historical_stock_returns)
    return initial_balance*rate

def ChangeInBalanceBonds(initial_balance):
    rate = random.choice(historical_bond_performance)
    return initial_balance*rate

def YearData():
    ''' Returns a rate of change for stocks, bonds, and inflation in a single tuple'''
    year = random.randrange(33)
    return (historical_stock_returns[year], historical_bond_performance[year])


number_years = 10
number_sims = 10000
final_balances_stocks = []
final_balances_bonds = []
final_balances_mixed = []
final_balances_mixed_norebalance = []
for i in range(number_sims):
    #Set initial conditions
    time = 0
    balance_stocks = 1000
    balance_bonds = 1000
    balance_mixed_stocks = 500
    balance_mixed_bonds = 500
    balance_mixed_stocks_norebalance = 500
    balance_mixed_bonds_norebalance = 500

    while (time < number_years):
        #Increase balance and time
        stock_perform, bond_perform = YearData()
        balance_stocks *= (1.0+stock_perform)
        balance_bonds *= (1.0+bond_perform)
        balance_mixed_stocks *= (1.0+stock_perform)
        balance_mixed_bonds *= (1.0+bond_perform)
        balance_mixed_stocks_norebalance *= (1.0+stock_perform)
        balance_mixed_bonds_norebalance *= (1.0+bond_perform)
        #Rebalance account
        balance_mixed = balance_mixed_stocks + balance_mixed_bonds
        target_stocks = balance_mixed * 0.5
        amount_to_move = balance_mixed_stocks - target_stocks
        balance_mixed_stocks -= amount_to_move
        balance_mixed_bonds += amount_to_move
        time += 1

    final_balances_stocks.append(balance_stocks)
    final_balances_bonds.append(balance_bonds)
    final_balances_mixed.append(balance_mixed)
    final_balances_mixed_norebalance.append(balance_mixed_stocks_norebalance + balance_mixed_bonds_norebalance)

final_balance_average = statistics.mean(final_balances_stocks)
final_balance_average = statistics.mean(final_balances_stocks)
final_balance_standard_deviation = statistics.stdev(final_balances_stocks)
print("The average final balance for a stock account was", final_balance_average)
print("The standard deviation in the final balance for a stock account was", final_balance_standard_deviation)
final_balance_average = statistics.mean(final_balances_bonds)
final_balance_standard_deviation = statistics.stdev(final_balances_bonds)
print("The average final balance for a bond account was", final_balance_average)
print("The standard deviation in the final balance for a bond account was", final_balance_standard_deviation)
final_balance_average = statistics.mean(final_balances_mixed)
final_balance_standard_deviation = statistics.stdev(final_balances_mixed)
print("The average final balance for a 50-50 mixed account with rebalancing was", final_balance_average)
print("The standard deviation in the final balance for a 50-50 mixed account with rebalancing was", final_balance_standard_deviation)
final_balance_average = statistics.mean(final_balances_mixed_norebalance)
final_balance_standard_deviation = statistics.stdev(final_balances_mixed_norebalance)
print("The average final balance for a 50-50 mixed account with NO Rebalancing was", final_balance_average)
print("The standard deviation in the final balance for a 50-50 mixed account with NO Rebalancing was", final_balance_standard_deviation)

#Output the simulation results
hist([final_balances_stocks, final_balances_bonds, final_balances_mixed, final_balances_mixed_norebalance], bins=40)
#hist(final_balances_bonds, bins=20)
show()

16-10 – Simulation looking at retirement funds

import random
import statistics
from matplotlib.pyplot import hist, show

historical_stock_returns = [.1348, .3215, .1589, .0210, .1482, .2594, -.3655, .0548, .1561,
                            .0483, .1074, .2836, -.2197, -.1185, -.0903, .2089, .2834, .3310, .2268,
                            .3720, .0133, .0997, .0749, .3023, -.0306, .3148, .1654, .0581, .1849,
                            .3124, .0615, .2234, .2042, -.0470, .3174, .1852, .0651, -.0698, .2383,
                            .3700, -.2590, -.1431, .1876, .1422, .0356, -.0824, .1081, .2380, -.0997,
                            .1240, .1642, .2261, -.0881, .2664, .0034, .1206, .4372, -.1046, .0744,
                            .3260, .5256, -.0121, .1815, .2368, .3081, .1830, .0570, .0520, -.0843]

historical_bond_performance = [-.0202, .0422, .0784, .0654, .0593, .0524, .0697, .0433,
                               .0243, .0434, .0410, .1026, .0843, .1163 -.0082, .0870, .0964, .0364,
                              .1846, -.0292, .0975, .0740, .1600, .0896, .1453, .0789, .0275, .1530,
                               .2213, .1515, .0819, .3265, .0626, .271]

historical_inflation = [.0, .016, .015, .021, .032, .016, -.004, .038, .028, .032,
                        .034, .027, .023, .016, .028, .034, .022, .016, .023, .030,
                        .028, .026, .030, .030, .042, .054, .048, .041, .036, .019,
                        .036, .043, .032, .062, .103, .135, .113, .076, .065, .058,
                        .091, .110, .062, .032, .044, .057, .055, .042, .031, .029,
                        .016, .013, .013, .010, .010, .017, .007, .028, .033, .015,
                        -.004, .007, .008, .019, .079, .013, -.012, .081, .144, .083]

def ChangeInBalanceStocks(initial_balance):
    rate = random.choice(historical_stock_returns)
    return initial_balance*rate

def ChangeInBalanceBonds(initial_balance):
    rate = random.choice(historical_bond_performance)
    return initial_balance*rate

def Inflation():
    return random.choice(historical_inflation)

def YearData():
    ''' Returns a rate of change for stocks, bonds, and inflation in a single tuple'''
    year = random.randrange(30)
    return (historical_stock_returns[year], historical_bond_performance[year], historical_inflation[year])

#Get information from user
initial_balance = float(input("What is your retirement account balance? "))
initial_expenses = float(input("What are your yearly expenses? "))
time_to_last = int(input("How many years does this need to last? "))

number_sims = 10000
final_balances = []
ran_out = 0             #Will count how many times the money ran out
stock_percentage = 0.5

for i in range(number_sims):
    #Set initial conditions
    time = 0
    balance_stocks = initial_balance * stock_percentage
    balance_bonds = initial_balance * (1.0-stock_percentage)
    expenses = initial_expenses

    while (time < time_to_last):
        time += 1
        #Increase balance and time
        stock_perform, bond_perform, inflation = YearData()
        balance_stocks *= (1.0+stock_perform)
        balance_bonds *= (1.0+bond_perform)
        #Rebalance account
        balance_mixed = balance_stocks + balance_bonds
        target_stocks = balance_mixed * stock_percentage
        amount_to_move = balance_stocks - target_stocks
        balance_stocks -= amount_to_move
        balance_bonds += amount_to_move

        #Remove this year's expenses, which increase by inflation
        expenses *= (1.0+inflation)
        balance_stocks -= expenses * stock_percentage
        balance_bonds -= expenses * (1.0-stock_percentage)

        if (balance_stocks < 0):
            #We ran out of money!  Increase ran_out count and set time to time_to_last to stop loop
            ran_out += 1
            time = time_to_last

    if (balance_stocks > 0):
        #The money lasted - save the final balance information
        final_balances.append(balance_stocks+balance_bonds)

percent_successful = (number_sims - ran_out)/number_sims * 100
final_balance_average = statistics.mean(final_balances)
final_balance_standard_deviation = statistics.stdev(final_balances)
print("The money lasted", percent_successful, "percent of the time")
print("The average final balance when the money lasted was", final_balance_average)
print("The standard deviation in the final balance when the money lasted was", final_balance_standard_deviation)

#Output the simulation results
hist(final_balances, bins=20)
show()

Lecture 17:

17-1 – Basic class with an attribute

class BankAccount:
	balance = 0.0

my_account = BankAccount()
your_account = BankAccount()
my_account.balance = 100.0
print(your_account.balance)

17-2 – Class with a mutable attribute

class BankAccount:
	balance = 0.0
	deposits = []

checking_account = BankAccount()
savings_account = BankAccount()
checking_account.deposits.append(100.0)
print(savings_account.deposits)

17-3 – The init constructor and instance attributes

class BankAccount:
	balance = 0.0

	def __init__(self):
		self.deposits = []

checking_account = BankAccount()
savings_account = BankAccount()
checking_account.deposits.append(100.0)
print(savings_account.deposits)

17-4 – Passing parameters to the init constructor

class BankAccount:
	def __init__(self, initial_amount=0.0):
		self.balance = initial_amount
		self.deposits = []

checking_account = BankAccount(200.00)
savings_account = BankAccount()
print(checking_account.balance)
print(savings_account.balance)

17-5 – Methods in classes

class BankAccount:
	def __init__(self, initial_amount=0.0):
		self.balance = initial_amount
		self.deposits = []

	def makeDeposit(self, amount):
		self.balance += amount
		self.deposits.append(amount)

	def makeWithdrawal(self, amount):
		self.balance -= amount

checking_account = BankAccount(100.00)
checking_account.makeDeposit(50.00)
checking_account.makeWithdrawal(70.00)
print(checking_account.balance)
print(checking_account.deposits)

17-6 – Accessor functions and private attributes

class BankAccount:
	def __init__(self, initial_amount=0.0):
		self._balance = initial_amount
		self._deposits = []

	def makeDeposit(self, amount):
		self._balance += amount
		self._deposits.append(amount)

	def makeWithdrawal(self, amount):
		self._balance -= amount

	def getBalance(self):
		return self._balance

	def getDeposits(self):
		return self._deposits

checking_account = BankAccount(100.00)
checking_account.makeDeposit(50.00)
print(checking_account.getBalance())
print(checking_account.getDeposits())

17-7 – Using a class as an attribute of a class

from datetime import date

class BankAccount:
    def __init__(self, amt=0.0):
        self._balance = amt
        self._deposits = []
        self.opendate = date(2011, 3, 15)

checking_account = BankAccount(100.0)
print(checking_account.opendate)

17-8 – Objects as mutable data types

class BankAccount:
    def __init__(self, amt=0.0):
        self._balance = amt
        self._deposits = []

    def makeDeposit(self, amt):
        self._balance += amt
        self._deposits.append(amt)

    def makeWithdrawal(self, amt):
        self._balance -= amt

    def getBalance(self):
        return self._balance

    def getDeposits(self):
        copied_list = self._deposits[:]
        return copied_list


def winLottery(account):
    account.makeDeposit(10000000.00)

checking_account = BankAccount()
winLottery(checking_account)
print(checking_account.getBalance())


checking_account = BankAccount(100.00)
checking_account.makeDeposit(50.0)
x = checking_account.getDeposits()
x.append(500.0)
print(checking_account.getBalance())
print(checking_account.getDeposits())


savings_account = BankAccount()
checking_account.makeDeposit(50.00)
checking_account.makeWithdrawal(75.00)
print(savings_account.getBalance())
print(savings_account.getDeposits())

17-VideoExercise – Video exercise solution

class BankAccount:
    def __init__(self, amt=0.0):
        self._balance = amt
        self._deposits = []

    def makeDeposit(self, amt):
        self._balance += amt
        self._deposits.append(amt)

    def makeWithdrawal(self, amt):
        self._balance -= amt

    def getBalance(self):
        return self._balance

    def getDeposits(self):
        copied_list = self._deposits[:]
        return copied_list

checking_account = BankAccount(100.00)
checking_account.name = "My Checking Account"
print(checking_account.name)

savings_account = BankAccount(1000.00)
print(savings_account.name)

Lecture 18:

18-1 – Basic class example for review

class Gift:
    def __init__(self, giver="", recipient = "", gift = "", occasion = "", date = "", value = 0):
        self._giver= giver
        self._recipient = recipient
        self._gift = gift
        self._occasion = occasion
        self._date = date
        self._value = value

    def setGiver(self, giver):
        self._giver = giver

    def getGiver(self):
        return self._giver

    def setRecipient(self, recipient):
        self._recipient = recipient

    def getRecipient(self):
        return self._recipient


my_birthday_gift = Gift("Mom", "me", "shirt", "birthday", "2015", 25.00)
my_birthday_gift.setGiver("Sister")
print(my_birthday_gift.getRecipient())

18-2 – Alternative implementation (could delete this example)

class Gift:
    giver = ""
    recipient = ""
    gift = ""
    occasion = ""
    date = ""
    value = 0

my_birthday_gift = Gift()
my_birthday_gift.giver = "Mom"
my_birthday_gift.recipient = "Me"
my_birthday_gift.gift = "shirt"
my_birthday_gift.occasion = "birthday"
my_birthday_gift.date = "2015"
my_birthday_gift.value = 25.00

my_birthday_gift.giver = "sister"
print(my_birthday_gift.recipient)

18-3 – Football player example (complete with inheritance and polymorphism)

class FootballPlayer:
    name = "John Doe"
    team = "None"
    years_in_league = 0
    def printPlayer(self):
        print(self.name+" playing for the "+self.team+":")
    def printGood(self):
        if (self.isGood()):
            print("  is a GOOD player")
        else:
            print("  is NOT a good player")

class Quarterback(FootballPlayer):
    pass_attempts = 0
    completions = 0
    pass_yards = 0
    def completionRate(self):
        return self.completions/self.pass_attempts
    def yardsPerAttempt(self):
        return self.pass_yards/self.pass_attempts
    def isGood(self):
        return (self.yardsPerAttempt() > 7)

class RunningBack(FootballPlayer):
    rushes = 0
    rush_yards = 0
    def yardsPerRush(self):
        return self.rush_yards/self.rushes
    def isGood(self):
        return (self.yardsPerRush() > 4)

player1 = Quarterback()
player1.name = "John"
player1.team = "Cowboys"
player1.pass_attempts = 10
player1.completions = 6
player1.pass_yards = 57

player2 = RunningBack()
player2.name = "Joe"
player2.team = "Eagles"
player2.rushes = 12
player2.rush_yards = 73

playerlist = []
playerlist.append(player1)
playerlist.append(player2)

for player in playerlist:
    player.printPlayer()
    player.printGood()

18-4 – Football player example (failure to define function)

class FootballPlayer:
    name = "John Doe"
    team = "None"
    years_in_league = 0
    def printPlayer(self):
        print(self.name+" playing for the "+self.team+":")
    def printGood(self):
        if (self.isGood()):
            print("  is a GOOD player")
        else:
            print("  is NOT a good player")

class Quarterback(FootballPlayer):
    pass_attempts = 0
    completions = 0
    pass_yards = 0
    def completionRate(self):
        return self.completions/self.pass_attempts
    def yardsPerAttempt(self):
        return self.pass_yards/self.pass_attempts
#    def isGood(self):
#       return (self.yardsPerAttempt() > 7)

class RunningBack(FootballPlayer):
    rushes = 0
    rush_yards = 0
    def yardsPerRush(self):
        return self.rush_yards/self.rushes
    def isGood(self):
        return (self.yardsPerRush() > 4)

player1 = Quarterback()
player1.name = "John"
player1.team = "Cowboys"
player1.pass_attempts = 10
player1.completions = 6
player1.pass_yards = 57

player2 = RunningBack()
player2.name = "Joe"
player2.team = "Eagles"
player2.rushes = 12
player2.rush_yards = 73

playerlist = []
playerlist.append(player1)
playerlist.append(player2)

for player in playerlist:
    player.printPlayer()
    if player.isGood():
        print ("  is a GOOD player.")
    else:
        print ("  is NOT a good player.")

18-5 – Creating, raising, and catching our own exceptions

class MissingChildMethodError(Exception):
    pass

class FootballPlayer:
    name = "John Doe"
    team = "None"
    years_in_league = 0
    def printPlayer(self):
        print(self.name+" playing for the "+self.team+":")
    def isGood(self):
        raise MissingChildMethodError("Error! isGood is not defined!")

player1 = FootballPlayer()
player1.name = "John"
player1.team = "Cowboys"
try:
    if player1.isGood():
        print(player1.name+" is a GOOD player")
    else:
        print(player1.name+" is NOT a good player.")
except MissingChildMethodError:
    print("Whoops - we forgot to define isGood!")

18-6 – Writing to a file with JSON

import json

length = 20.0
width = 15
outfile = open("datafile1.dat", "w")

json_string = json.dumps(length)
outfile.write(json_string+'\n')
json_string = json.dumps(width)
outfile.write(json_string+'\n')
json_string = json.dumps("Data for an example")
outfile.write(json_string+'\n')

outfile.close() 

18-7 – Reading from a file with JSON

import json

infile = open("datafile1.dat", "r")
json_string = infile.readline()
l = json.loads(json_string)
json_string = infile.readline()
w = json.loads(json_string)
json_string = infile.readline()
description = json.loads(json_string)
infile.close()

print(description)
print(l*w)

18-8 – Writing objects with JSON

import json

class FootballPlayer:
    name = "John Doe"
    team = "None"
    years_in_league = 0
    def printPlayer(self):
        print(self.name+" playing for the "+self.team+":")
    def printGood(self):
        if (self.isGood()):
            print("  is a GOOD player")
        else:
            print("  is NOT a good player")

class Quarterback(FootballPlayer):
    pass_attempts = 0
    completions = 0
    pass_yards = 0
    def completionRate(self):
        return self.completions/self.pass_attempts
    def yardsPerAttempt(self):
        return self.pass_yards/self.pass_attempts

class RunningBack(FootballPlayer):
    rushes = 0
    rush_yards = 0
    def yardsPerRush(self):
        return self.rush_yards/self.rushes
    def isGood(self):
        return (self.yardsPerRush() > 4)


player1 = Quarterback()

player1.name = "John"
player1.team = "Cowboys"
player1.pass_attempts = 10
player1.completions = 6
player1.pass_yards = 57

player2 = RunningBack()
player2.name = "Joe"
player2.team = "Eagles"
player2.rushes = 12
player2.rush_yards = 73

playerlist = []
playerlist.append(player1)
playerlist.append(player2)

outfile = open("datafile.dat", "w")

for player in playerlist:
    json_string = json.dumps(player.__dict__)+'\n'
    outfile.write(json_string)

outfile.close()

18-9 – Writing data with pickle

import pickle

account = 134218954
balance = 1783.45
owner = "John Smith"

outfile = open("BankAccount.dat", "wb")

pickle.dump(account, outfile)
pickle.dump(owner, outfile)
pickle.dump(balance, outfile)

outfile.close()

18-10 – Reading data with pickle

import pickle

infile = open("BankAccount.dat", "rb")

account = pickle.load(infile)
owner = pickle.load(infile)
balance = pickle.load(infile)

print(account, owner, balance)

infile.close()

18-11 – Writing objects with pickle

import pickle

class FootballPlayer:
    name = "John Doe"
    team = "None"
    years_in_league = 0
    def printPlayer(self):
        print(self.name+" playing for the "+self.team+":")
    def printGood(self):
        if (self.isGood()):
            print("  is a GOOD player")
        else:
            print("  is NOT a good player")

class Quarterback(FootballPlayer):
    pass_attempts = 0
    completions = 0
    pass_yards = 0
    def completionRate(self):
        return self.completions/self.pass_attempts
    def yardsPerAttempt(self):
        return self.pass_yards/self.pass_attempts

class RunningBack(FootballPlayer):
    rushes = 0
    rush_yards = 0
    def yardsPerRush(self):
        return self.rush_yards/self.rushes
    def isGood(self):
        return (self.yardsPerRush() > 4)


player1 = Quarterback()

player1.name = "John"
player1.team = "Cowboys"
player1.pass_attempts = 10
player1.completions = 6
player1.pass_yards = 57

player2 = RunningBack()
player2.name = "Joe"
player2.team = "Eagles"
player2.rushes = 12
player2.rush_yards = 73

playerlist = []
playerlist.append(player1)
playerlist.append(player2)

outfile = open("datafile2.dat", "wb")

pickle.dump(player1, outfile)
pickle.dump(player2, outfile)

outfile.close()

18-12 – Reading objects with pickle

import pickle

class FootballPlayer:
    name = "John Doe"
    team = "None"
    years_in_league = 0
    def printPlayer(self):
        print(self.name+" playing for the "+self.team+":")
    def printGood(self):
        if (self.isGood()):
            print("  is a GOOD player")
        else:
            print("  is NOT a good player")

class Quarterback(FootballPlayer):
    pass_attempts = 0
    completions = 0
    pass_yards = 0
    def completionRate(self):
        return self.completions/self.pass_attempts
    def yardsPerAttempt(self):
        return self.pass_yards/self.pass_attempts
    def isGood(self):
        return self.yardsPerAttempt() > 7

class RunningBack(FootballPlayer):
    rushes = 0
    rush_yards = 0
    def yardsPerRush(self):
        return self.rush_yards/self.rushes
    def isGood(self):
        return (self.yardsPerRush() > 4)


infile=open("datafile2.dat", "rb")
newplayer1 = pickle.load(infile)
newplayer2 = pickle.load(infile)
infile.close()

newplayer1.printPlayer()
if newplayer1.isGood():
    print ("  is a GOOD player.")
else:
    print ("  is NOT a good player.")
newplayer2.printPlayer()
if newplayer2.isGood():
    print ("  is a GOOD player.")
else:
    print ("  is NOT a good player.")

Lecture 19:

19-1 – Implementing a stack with a list

class Book:
	title = ""
	author = ""

long_book = Book()
long_book.title = "War and Peace"
long_book.author = "Tolstoy"

medium_book = Book()
medium_book.title = "Book of Armaments"
medium_book.author = "Maynard"

short_book = Book()
short_book.title = "Vegetables I Like"
short_book.author = "John Keyser"

book_stack = []

book_stack.append(medium_book)
book_stack.append(short_book)
book_stack.append(long_book)

next_book = book_stack.pop()
print(next_book.title+" by "+next_book.author)

19-2 – Implementing a stack class as part of a solitaire game (note: code is not complete – will not run without writing more)

class Stack:
    _stack = []
    def push(self, item):
        self._stack.append(item)
    def pop (self):
        return self._stack.pop()

waste_pile = Stack()

#Setting up solitaire game here

while not(noTurnsLeft()):
    #Get the player's move

    if move=="Draw":
        #Get next three cards and push them onto waste stack
        next_card1 = draw_next_card()
        next_card2 = draw_next_card()
        next_card3 = draw_next_card()
        waste_pile.push(next_card1)
        waste_pile.push(next_card2)
        waste_pile.push(next_card3)

    elif move=="PlayfromWaste":
        #Player wants to play the top card from the waste pile
        current_card = waste_pile.pop()

        #Have player play current_card

19-3 – Implementing a queue with a list

class Book:
	title = ""
	author = ""

long_book = Book()
long_book.title = "War and Peace"
long_book.author = "Tolstoy"

medium_book = Book()
medium_book.title = "Book of Armaments"
medium_book.author = "Maynard"

short_book = Book()
short_book.title = "Vegetables I Like"
short_book.author = "John Keyser"

book_queue = []

book_queue.append(medium_book)
book_queue.append(short_book)
book_queue.append(long_book)

next_book = book_queue.pop(0)
print(next_book.title+" by "+next_book.author)

19-4 – Implementing a queue class and using it for order fulfillment

from random import randint

class Queue:
    _queue = []
    def enqueue(self, item):
        self._queue.append(item)
    def dequeue(self):
        return self._queue.pop(0)
    def isEmpty(self):
        return (len(self._queue) == 0)

class Order:
    def __init__(self, customer = "", amt=0):
        self._customer = customer
        self._amount = amt
    def customer(self):
        return self._customer
    def numOrdered(self):
        return self._amount

orders = Queue()

for ordernum in range(20):
    amount = randint(1,200)
    customer = "Customer "+str(ordernum)
    neworder = Order(customer,amount)
    orders.enqueue(neworder)

inventory = 1000

while not orders.isEmpty():
    order = orders.dequeue()
    if order.numOrdered() < inventory:
        # We can fill the order
        print("Fill order for",order.numOrdered(),"shrubberies for customer",order.customer())
        inventory -= order.numOrdered()
    else:
        print("Notify",order.customer(),"that we cannot fulfill the order")

exit()

19-5 – Basic dictionary example

nicknames = {"Superstar" : "Sue Smith",
             "CowboysFan" : "Bill Brown",
             "JJwins" : "John James"}

print(nicknames["CowboysFan"])

19-6 – Deleting from a dictionary

nicknames = {}

nicknames["Superstar"] = "Sue Smith"
nicknames["CowboysFan"] = "Bill Brown"
nicknames["JJwins"] = "John James"

del nicknames["Superstar"]

print("CowboysFan" in nicknames)
print("SuperStar" in nicknames)

19-7 – Creating a dictionary incrementally

nicknames = {}

nicknames["Superstar"] = "Sue Smith"
nicknames["CowboysFan"] = "Bill Brown"
nicknames["JJwins"] = "John James"

for nickname in nicknames:
    print("The nickname for "+nicknames[nickname]+" is "+nickname)

19-8 – Dictionary example for storing passwords

passwords = {"John" : "123456", "Sue" : "PaSsWoRd", "Bill" : "G9.Kf-21.-fe8ilfb" }

failed_attempts = 0
verified = False

while (not verified):
    username = input("What is your username? ")
    password = input("What is your password? ")
    if (username in passwords) and (passwords[username] == password):
        print ("Welcome!")
        verified = True
    else:
        print ("Invalid username/password combination")
        failed_attempts += 1
        if failed_attempts > 2:
            print("Too many incorrect attempts.  Goodbye")
            exit()

19-9– Set operations

neighborhood_friends = set(['John', 'Sue', 'Bill'])
work_friends = {'Sue', 'Eric', 'Fred'}

print(neighborhood_friends - work_friends)
print(neighborhood_friends | work_friends)
print(neighborhood_friends & work_friends)
print(neighborhood_friends ^ work_friends)

19-10 – Shopping list generation using sets

class recipe:
    name=''
    ingredients = []
    def __init__(self, name, ingredients):
        self.name = name
        self.ingredients = ingredients

dish1 = recipe("Omlette", ['Eggs', 'Tomatoes', 'Onions', 'Peppers'])
dish2 = recipe("Bread", ['Flour', 'Yeast'])
dish3 = recipe("Cake", ['Eggs', 'Flour', 'Sugar', 'Butter'])
dishes_to_fix = [dish1, dish2, dish3]

shopping_list = set()
for dish in dishes_to_fix:
    ingredients = set(dish.ingredients)
    shopping_list = shopping_list | ingredients

ingredients_on_hand = {'Onions', 'Butter', 'Milk', 'Honey', 'Oatmeal', 'Sugar', 'Tomatoes'}
shopping_list -= ingredients_on_hand

print("Here is the set of items you need to buy:")
print(shopping_list)

Lecture 20:

20-1 – Searching an unordered list

def isIn(L, v):
    i = 0
    while (i < len(L)):
        if L[i] == v:
            return True
        else:
            i += 1
    return False

favorite_foods = ['pizza', 'barbeque', 'gumbo', 'chicken and dumplings', 'pecan pie', 'ice cream']
print(isIn(favorite_foods, 'gumbo'))
print(isIn(favorite_foods, 'coconut'))
print ('gumbo' in favorite_foods)
print ('coconut' in favorite_foods)

20-2 – Searching an ordered list

def binaryIn(L, v):
    if len(L) < 1:
        return False
    low = 0
    high = len(L)-1
    if L[low] == v or L[high] == v:
        return True
    while low < (high-1):
        midpoint = low + (high-low) // 2
        if L[midpoint] == v:
            return True
        elif L[midpoint] < v:
            low = midpoint
        else:
            high = midpoint
    return False

favorite_foods = ['barbeque', 'chicken and dumplings', 'gumbo', 'ice cream', 'pecan pie', 'pizza']
print(binaryIn(favorite_foods, 'gumbo'))
print(binaryIn(favorite_foods, 'coconut'))

20-3 – Searching and returning an index

def binaryIn(L, v):
    if len(L) < 1:
        return False
    low = 0
    high = len(L)-1
    if L[low] == v:
        return low
    if L[high] == v:
        return high
    while low < (high-1):
        midpoint = low + (high-low) // 2
        if L[midpoint] == v:
            return midpoint
        elif L[midpoint] < v:
            low = midpoint
        else:
            high = midpoint
    return -1

favorite_foods = ['barbeque', 'chicken and dumplings', 'gumbo', 'ice cream', 'pecan pie', 'pizza']
print(binaryIn(favorite_foods, 'gumbo'))
print(binaryIn(favorite_foods, 'coconut'))

20-4 – Selection sort

def selectionSort(L):
    maxindex = len(L) - 1
    for i in range(0,maxindex+1):
        #find the smallest remaining
        min_index = i
        for j in range(i+1,maxindex+1):
            if L[j] < L[min_index]:
                min_index = j
        #swap that item
        temp = L[i]
        L[i] = L[min_index]
        L[min_index] = temp

favorite_foods = ['pizza', 'barbeque', 'gumbo', 'chicken and dumplings', 'pecan pie', 'ice cream']
selectionSort(favorite_foods)
print(favorite_foods)

20-5 – Insertion sort

def insertionSort(L):
     for i in range(0,len(L)):
         temp = L[i]
         j = i-1
         while (j >= 0) and (L[j] > temp):
             L[j+1] = L[j]
             j -= 1
         L[j+1] = temp


favorite_foods = ['pizza', 'barbeque', 'gumbo', 'chicken and dumplings', 'pecan pie', 'ice cream']
insertionSort(favorite_foods)
print(favorite_foods)

20-6 – Using Python’s built-in sort command (in-place)

favorite_foods = ['pizza', 'barbeque', 'gumbo', 'chicken and dumplings', 'pecan pie', 'ice cream']
favorite_foods.sort()
print(favorite_foods)

20-7 – Using Python’s built-in sort command in reverse (out-of-place)

favorite_foods = ['pizza', 'barbeque', 'gumbo', 'chicken and dumplings', 'pecan pie', 'ice cream']
sorted_favorites = sorted(favorite_foods, reverse = True)
print(favorite_foods)
print(sorted_favorites)

Lecture 21:

21-1 – Basic recursive countdown program

def countdown(n):
    print (n)
    if n > 0:
        countdown(n-1)

countdown (5)

21-2 – Merge sort

def merge(L, L1, L2):
    i = 0
    j = 0
    k = 0
    while (j < len(L1)) or (k < len(L2)):
        if j < len(L1):
            if k < len(L2):
                # we are not at the end of L1 or L2, so pull the smaller value
                if L1[j] < L2[k]:
                    L[i] = L1[j]
                    j += 1
                else:
                    L[i] = L2[k]
                    k += 1
            else:
                # we are at the end of L2, so just pull from L1
                L[i] = L1[j]
                j += 1
        else:
            # we are at the end of L1, so just pull from L2
            L[i] = L2[k]
            k += 1
        i += 1
    return


def mergeSort(L):
    n = len(L)
    if n <= 1:
        return
    L1 = L[:n//2]
    L2 = L[n//2:]
    mergeSort(L1)
    mergeSort(L2)
    merge(L, L1, L2)
    return

favorite_foods = ['pizza', 'barbeque', 'gumbo', 'chicken and dumplings', 'pecan pie', 'ice cream']
mergeSort(favorite_foods)
print(favorite_foods)

21-3 – Quicksort

def quickSort(L):
    #handle base case
    if len(L) <= 1:
        return

    #pick pivot
    pivot = L[0]

    #form lists less/greater than pivot
    L1 = []
    L2 = []
    for element in L[1:]:
        if element < pivot:
            L1.append(element)
        else:
            L2.append(element)

    #sort sublists
    quickSort(L1)
    quickSort(L2)

    #join the sublists and pivot
    L[:] = []
    for element in L1:
        L.append(element)
    L.append(pivot)
    for element in L2:
        L.append(element)

    return

favorite_foods = ['pizza', 'barbeque', 'gumbo', 'chicken and dumplings', 'pecan pie', 'ice cream']
quickSort(favorite_foods)
print(favorite_foods)

21-4 – Recursive and iterative Fibonacci computations

def Fib2(n):
    F = [0,1]
    for i in range(2,n+1):
        #compute F[i]
        F.append(F[-2] + F[-1])
    return F[n]

def Fib(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return Fib(n-2) + Fib(n-1)


print(Fib2(100))

Lecture 22:

22-1 – Node and edge classes for cities: finding population along a road

class node:
    def __init__(self, name, population=0):
        self._name = name
        self._pop = population

    def getName(self):
        return self._name

    def getPopulation(self):
        return self._pop

class edge:
    def __init__(self, name1, name2, weight=0):
        self._city1 = name1
        self._city2 = name2
        self._distance = weight

    def getName1(self):
        return self._city1

    def getName2(self):
        return self._city2

    def getNames(self):
        return (self._city1, self._city2)

    def getWeight(self):
        return self._distance

cities = []
roads = []

city = node('Rivertown', 100)
cities.append(city)
city = node('Brookside', 1500)
cities.append(city)
city = node('Hillsview', 500)
cities.append(city)
city = node('Forrest City', 800)
cities.append(city)
city = node('Lakeside', 1100)
cities.append(city)

road = edge('Rivertown', 'Brookside', 100)
roads.append(road)
road = edge('Rivertown', 'Hillsview', 50)
roads.append(road)
road = edge('Hillsview', 'Brookside', 130)
roads.append(road)
road = edge('Hillsview', 'Forrest City', 40)
roads.append(road)
road = edge('Forrest City', 'Lakeside', 80)
roads.append(road)

road = roads[0]
pop1 = 0
pop2 = 0
for city in cities:
    if city.getName() == road.getName1():
        pop1 = city.getPopulation()
    if city.getName() == road.getName2():
        pop2 = city.getPopulation()

total_population = pop1 + pop2
print(total_population)

22-2 – Alternative edge formulation using indices rather than names (notice population of one city changed)

class node:
    def __init__(self, name, population=0):
        self._name = name
        self._pop = population

    def getName(self):
        return self._name

    def getPopulation(self):
        return self._pop

class edge:
    def __init__(self, index1, index2, weight=0):
        self._city1 = index1
        self._city2 = index2
        self._distance = weight

    def getIndex1(self):
        return self._city1

    def getIndex2(self):
        return self._city2

    def getIndices(self):
        return (self._city1, self._city2)

    def getWeight(self):
        return self._distance

cities = []
roads = []

city = node('Rivertown', 1000)
cities.append(city)
city = node('Brookside', 1500)
cities.append(city)
city = node('Hillsview', 500)
cities.append(city)
city = node('Forrest City', 800)
cities.append(city)
city = node('Lakeside', 1100)
cities.append(city)

road = edge(0, 1, 100)
roads.append(road)
road = edge(0, 2, 50)
roads.append(road)
road = edge(2, 1, 130)
roads.append(road)
road = edge(2, 3, 40)
roads.append(road)
road = edge(3, 4, 80)
roads.append(road)

road = roads[0]
pop1 = cities[road.getIndex1()].getPopulation()
pop2 = cities[road.getIndex2()].getPopulation()

total_population = pop1 + pop2
print(total_population)

22-3 – Finding neighbors of cities using adjacency lists

class node:
    def __init__(self, name, population=0):
        self._name = name
        self._pop = population
        self._roads = []

    def getName(self):
        return self._name

    def getPopulation(self):
        return self._pop

    def getRoads(self):
        return self._roads

    def addNeighborRoad(self, e):
        self._roads.append(e)

    def addNeighbor(self, city, weight=0):
        e = edge(city, weight)
        self._roads.append(e)


class edge:
    def __init__(self, city, weight=0):
        self._city = city
        self._weight = weight

    def getCity(self):
        return self._city

    def getWeight(self):
        return self._weight

def addRoad(name1, name2, weight=0):
    e1 = edge(name2, weight)
    e2 = edge(name1, weight)
    for city in cities:
        if city.getName() == name1:
            city.addNeighborRoad(e1)
        if city.getName() == name2:
            city.addNeighborRoad(e2)

def addRoad2(name1, name2, weight=0):
    for city in cities:
        if city.getName() == name1:
            city.addNeighbor(name2, weight)
        if city.getName() == name2:
            city.addNeighbor(name1, weight)

cities = []
city = node('Rivertown', 1000)
cities.append(city)
city = node('Brookside', 1500)
cities.append(city)
city = node('Hillsview', 500)
cities.append(city)
city = node('Forrest City', 800)
cities.append(city)
city = node('Lakeside', 1100)
cities.append(city)

addRoad('Rivertown', 'Brookside', 100)
addRoad('Rivertown', 'Hillsview', 50)
addRoad('Brookside', 'Hillsview', 130)
addRoad('Hillsview', 'Forrest City', 40)
addRoad('Forrest City', 'Lakeside', 80)

for city in cities:
    print('Neighbors of '+city.getName())
    roads = city.getRoads()
    for road in roads:
        print('     ', road.getCity(), 'at a distance', road.getWeight())

22-4 – Neighbor count using an adjacency matrix

class node:
    def __init__(self, name, population=0):
        self._name = name
        self._pop = population

    def getName(self):
        return self._name

    def getPopulation(self):
        return self._pop

class EdgeMatrix:
    def __init__(self, nodelist):
        self._matrix = []
        self._names = []
        for i in range(len(nodelist)):
            #store list of node names
            self._names.append(nodelist[i].getName())
            #initialize all elements of matrix to -1
            self._matrix.append([])
            for j in range(len(nodelist)):
                self._matrix[i].append(-1)

    def addRoad(self, city1, city2, length=0):
        i = self._names.index(city1)
        j = self._names.index(city2)
        self._matrix[i][j] = length
        self._matrix[j][i] = length

    def length(self, i, j):
        return self._matrix[i][j]

    def numConnected(self, city_name):
        i = self._names.index(city_name)
        count = 0;
        for j in range(len(self._names)):
            if self._matrix[i][j] != -1:
                count += 1
        return count

cities = []
city = node('Rivertown', 1000)
cities.append(city)
city = node('Brookside', 1500)
cities.append(city)
city = node('Hillsview', 500)
cities.append(city)
city = node('Forrest City', 800)
cities.append(city)
city = node('Lakeside', 1100)
cities.append(city)

roads = EdgeMatrix(cities)
roads.addRoad('Rivertown', 'Brookside', 100)
roads.addRoad('Rivertown', 'Hillsview', 50)
roads.addRoad('Brookside', 'Hillsview', 130)
roads.addRoad('Hillsview', 'Forrest City', 40)
roads.addRoad('Forrest City', 'Lakeside', 80)

print("Hillsview has", roads.numConnected('Hillsview'), "neighbors")

22-5 – Currency arbitrage using a directed graph


class Currency:
    def __init__(self, name):
        self._name = name
        self._rates = []

    def getName(self):
        return self._name

    def getRates(self):
        return self._rates

    def addRateEdge(self, e):
        self._rates.append(e)

    def addRate(self, currency, weight=0):
        e = edge(currency, weight)
        self._rates.append(e)

    def findRates(self, maincurrency, current_value, depth):
        if self._name == maincurrency:
            #We are back at the main currency - see if the value > 1
            if current_value > 1.0:
                #We found a way to make money!
                print("We found a way!  ")
                print(current_value, self._name)
                return True
        if depth > 3:
            #Base case for recursion: too many exchanges
            return False
        for rate in self._rates:
            conversion = current_value * rate.getExchange()
            for c in currencies:
                if c.getName() == rate.getCurrency():
                    if c.findRates(maincurrency, conversion, depth+1):
                        print("from", current_value, self._name)
                        return True
        return False

    def findArbitrage(self):
        for rate in self._rates:
            for c in currencies:
                if c.getName() == rate.getCurrency():
                    if c.findRates(self._name, rate.getExchange(), 1):
                        return True
        return False

class Edge:
    def __init__(self, currency, rate = 0):
        self._currency = currency
        self._exchange = rate

    def getCurrency(self):
        return self._currency

    def getExchange(self):
        return self._exchange

    def setExchange(self, exchange):
        self._exchange = exchange

def addExchange(name1, name2, exchange1):
    e1 = Edge(name2, exchange1)
    e2 =Edge(name1, 1.0/exchange1)
    for currency in currencies:
        if currency.getName() == name1:
            currency.addRateEdge(e1)
        if currency.getName() == name2:
            currency.addRateEdge(e2)

def addExchange2(name1, name2, weight=0):
    for currency in currencies:
        if currency.getName() == name1:
            currency.addNeighbor(name2, exchange1)
        if currency.getName() == name2:
            currency.addNeighbor(name1, 1.0/exchange1)

currencies = []
currency = Currency("Dollar")
currencies.append(currency)
currency = Currency("Pound")
currencies.append(currency)
currency = Currency("Euro")
currencies.append(currency)
currency = Currency("Yen")
currencies.append(currency)

addExchange("Dollar", "Pound", 0.7)
addExchange("Dollar", "Euro", 0.95)
addExchange("Yen", "Dollar", 0.0085)
addExchange("Euro", "Pound", 0.75)
addExchange("Pound", "Yen", 175.0)
addExchange("Euro", "Yen", 233.3)

currencies[0].findArbitrage()

22-6 – Node class for a tree

class node:
    def __init__(self, name, parent=-1):
        self._name = name
        self._parent = parent
        self._children = []

    def getName(self):
        return self._name

    def getParent(self):
        return self._parent

    def getChildren(self):
        return self._children

    def setParent(self, p):
        self._parent = p

    def addChild(self, c):
        self._children.append(c)

22-7 – Node class for a binary tree

class node:
    def __init__(self, name, parent=-1):
        self._name = name
        self._parent = parent
        self._left = -1
        self._right = -1

    def getName(self):
        return self._name

    def getParent(self):
        return self._parent

    def getLeft(self):
        return self._left

    def getRight(self):
        return self._right

    def setParent(self, p):
        self._parent = p

    def setLeft(self, l):
        self._left = l

    def setRight(self, r):
        self._right = r

22-8 – Binary search tree – insertion and sorting

class node:
    def __init__(self, value, parent=-1):
        self._val = value
        self._parent = parent
        self._left = -1
        self._right = -1

    def getValue(self):
        return self._val

    def getParent(self):
        return self._parent

    def getLeft(self):
        return self._left

    def getRight(self):
        return self._right

    def setParent(self, p):
        self._parent = p

    def setLeft(self, l):
        self._left = l

    def setRight(self, r):
        self._right = r

    def insert(self, insert_node):
        if nodelist[insert_node].getValue() < self._val:
            if self._left == -1:
                self._left = insert_node
            else:
                nodelist[self._left].insert(insert_node)
        else:
            if self._right == -1:
                self._right = insert_node
            else:
                nodelist[self._right].insert(insert_node)


    def printInOrder(self):
        if self._left != -1:
            nodelist[self._left].printInOrder()
        print(self._val)
        if self._right != -1:
            nodelist[self._right].printInOrder()

nodelist = []
n = node(15)
nodelist.append(n)
n = node(18)
nodelist.append(n)
n = node(8)
nodelist.append(n)
n = node(13)
nodelist.append(n)
n = node(23)
nodelist.append(n)
n = node(27)
nodelist.append(n)
n = node(3)
nodelist.append(n)
n = node(21)
nodelist.append(n)
n = node(11)
nodelist.append(n)
n = node(7)
nodelist.append(n)

root = 0
for i in range(1,9):
    nodelist[root].insert(i)
nodelist[root].printInOrder()

Lecture 23:

23-1 – Breadth First Search to find a chain of friends

class node:
    def __init__(self, name):
        self._name = name
        self._friends = []
        self._status = 0
        self._discoveredby = 0

    def getName(self):
        return self._name

    def getFriends(self):
        return self._friends

    def addFriend(self, friend_index):
        self._friends.append(friend_index)

    def isUnseen(self):
        if self._status == 0:
            return True
        else:
            return False

    def isSeen(self):
        if self._status == 1:
            return True
        else:
            return False

    def setUnseen(self):
        self._status = 0

    def setSeen(self):
        self._status = 1

    def discover(self, n):
        self._discoveredby = n

    def discovered(self):
        return self._discoveredby



def makeFriends(name1, name2):
    for i in range(len(people)):
        if people[i].getName() == name1:
            n1 = i
        if people[i].getName() == name2:
            n2 = i
    people[n1].addFriend(n2)
    people[n2].addFriend(n1)

class queue:
    def __init__(self):
        self._queue = []

    def enqueue(self, x):
        self._queue.append(x)

    def dequeue(self):
        return self._queue.pop(0)

    def isEmpty(self):
        return len(self._queue) == 0

def retrievePath(nodelist, start, goal):
    # Return the path from start to goal
    if start == goal:
        path = []
        path.append(start)
        return path
    else:
        previous = nodelist[goal].discovered()
        previous_path = retrievePath(nodelist, start, previous)
        previous_path.append(goal)
        return previous_path

def BFS(nodelist, start, goal):
    to_visit = queue()
    nodelist[start].setSeen()
    to_visit.enqueue(start)

    found = False
    while (not found) and (not to_visit.isEmpty()):
        current = to_visit.dequeue()
        neighbors = nodelist[current].getFriends()
        for neighbor in neighbors:
            if nodelist[neighbor].isUnseen():
                nodelist[neighbor].setSeen()
                nodelist[neighbor].discover(current)
                if neighbor == goal:
                    found = True
                else:
                    to_visit.enqueue(neighbor)
    return retrievePath(nodelist, start, goal)


people = []
person = node('John')
people.append(person)
person = node('Joe')
people.append(person)
person = node('Sue')
people.append(person)
person = node('Fred')
people.append(person)
person = node('Kathy')
people.append(person)

makeFriends('John', 'Joe')
makeFriends('John', 'Sue')
makeFriends('Joe', 'Sue')
makeFriends('Sue', 'Fred')
makeFriends('Fred', 'Kathy')

pathlist = BFS(people, 0, 4)
for index in pathlist:
    print(people[index].getName())

23-2 – Word game code

class node:
    def __init__(self, word):
        self._word = word
        self._neighbors = []
        self._status = 0
        self._discoveredby = 0

    def getWord(self):
        return self._word

    def getNeighbors(self):
        return self._neighbors

    def addNeighbor(self, neighbor_index):
        self._neighbors.append(neighbor_index)

    def isUnseen(self):
        if self._status == 0:
            return True
        else:
            return False

    def isSeen(self):
        if self._status == 1:
            return True
        else:
            return False

    def setUnseen(self):
        self._status = 0

    def setSeen(self):
        self._status = 1

    def discover(self, n):
        self._discoveredby = n

    def discovered(self):
        return self._discoveredby

def addWordLink(wordlist, word1, word2):
    for i in range(len(wordlist)):
        if wordlist[i].getWord() == word1:
            n1 = i
        if wordlist[i].getWord() == word2:
            n2 = i
    wordlist[n1].addNeighbor(n2)
    wordlist[n2].addNeighbor(n1)

def addLink(wordlist, index1, index2):
    wordlist[index1].addNeighbor(index2)
    wordlist[index2].addNeighbor(index1)

class queue:
    def __init__(self):
        self._queue = []

    def enqueue(self, x):
        self._queue.append(x)

    def dequeue(self):
        return self._queue.pop(0)

    def isEmpty(self):
        return len(self._queue) == 0

def retrievePath(nodelist, start, goal):
    # Return the path from start to goal
    if start == goal:
        path = []
        path.append(start)
        return path
    else:
        previous = nodelist[goal].discovered()
        previous_path = retrievePath(nodelist, start, previous)
        previous_path.append(goal)
        return previous_path

def BFS(nodelist, start, goal):
    to_visit = queue()
    nodelist[start].setSeen()
    to_visit.enqueue(start)

    found = False
    while (not found) and (not to_visit.isEmpty()):
        current = to_visit.dequeue()
        neighbors = nodelist[current].getNeighbors()
        for neighbor in neighbors:
            if nodelist[neighbor].isUnseen():
                nodelist[neighbor].setSeen()
                nodelist[neighbor].discover(current)
                if neighbor == goal:
                    found = True
                else:
                    to_visit.enqueue(neighbor)
    if found:
        return retrievePath(nodelist, start, goal)
    else:
        return []

def compareWords(word1, word2):
    if len(word1) != len(word2):
        return False
    numdifferent = 0
    for i in range(len(word1)):
        if word1[i] != word2[i]:
            numdifferent += 1
    if numdifferent == 1:
        return True
    else:
        return False

#Read in the words from a dictionary
words = []
dict = open("dictionary4letter.txt", 'r')
for line in dict:
    word = node(line.strip())
    words.append(word)

for i in range(len(words)):
    for j in range(i+1,len(words)):
        #compare word i and word j
        if compareWords(words[i].getWord(), words[j].getWord()):
            addLink(words, i, j)


#Get starting and ending word
word1 = input("What is the starting word? ")
word2 = input("What is the ending word? ")

index1 = -1
index2 = -1
for i in range(len(words)):
    if words[i].getWord() == word1:
        index1 = i
    if words[i].getWord() == word2:
        index2 = i
if index1 == -1:
    print(word1,"was not in the dictionary.  Exiting.")
    exit(0)
if index2 == -1:
    print(word2,"was not in the dictionary.  Exiting")
    exit(0)

#Find a chain of words
path = BFS(words, index1, index2)

#Report the chain
if path == []:
    print("There was no chain between those words, in my dictionary.")
else:
    for index in path:
        print(words[index].getWord())

dictionary.txt – file of dictionary words

dictionary4letter.txt – file of 4-letter dictionary words

Lecture 24:

24-1 – Basic process spawning

from multiprocessing import Process

def print_function(name):
    print("Hello,", name)

if __name__ == '__main__':
    p = Process(target=print_function, args=("John",))
    p.start()

24-2 – Spawning multiple processes with arguments

from multiprocessing import Process, Queue

def print_process(number):
    print("Printing from process", number)

if __name__ == '__main__':
    process_list = []
    process_list = []
    for i in range(20):
        p = Process(target=print_process, args=(i,))
        process_list.append(p)
    for p in process_list:
        p.start()

24-3 – Parallel version of word game

from multiprocessing import Process,  Queue

class node:
    def __init__(self, word):
        self._word = word
        self._neighbors = []
        self._status = 0
        self._discoveredby = 0

    def getWord(self):
        return self._word

    def getNeighbors(self):
        return self._neighbors

    def addNeighbor(self, neighbor_index):
        self._neighbors.append(neighbor_index)

    def isUnseen(self):
        if self._status == 0:
            return True
        else:
            return False

    def isSeen(self):
        if self._status == 1:
            return True
        else:
            return False

    def setUnseen(self):
        self._status = 0

    def setSeen(self):
        self._status = 1

    def discover(self, n):
        self._discoveredby = n

    def discovered(self):
        return self._discoveredby

def addWordLink(wordlist, word1, word2):
    for i in range(len(wordlist)):
        if wordlist[i].getWord() == word1:
            n1 = i
        if wordlist[i].getWord() == word2:
            n2 = i
    wordlist[n1].addNeighbor(n2)
    wordlist[n2].addNeighbor(n1)

def addLink(wordlist, index1, index2):
    wordlist[index1].addNeighbor(index2)
    wordlist[index2].addNeighbor(index1)

class queue:
    def __init__(self):
        self._queue = []

    def enqueue(self, x):
        self._queue.append(x)

    def dequeue(self):
        return self._queue.pop(0)

    def isEmpty(self):
        return len(self._queue) == 0

def retrievePath(nodelist, start, goal):
    # Return the path from start to goal
    if start == goal:
        path = []
        path.append(start)
        return path
    else:
        previous = nodelist[goal].discovered()
        previous_path = retrievePath(nodelist, start, previous)
        previous_path.append(goal)
        return previous_path

def BFS(nodelist, start, goal):
    to_visit = queue()
    nodelist[start].setSeen()
    to_visit.enqueue(start)

    found = False
    while (not found) and (not to_visit.isEmpty()):
        current = to_visit.dequeue()
        neighbors = nodelist[current].getNeighbors()
        for neighbor in neighbors:
            if nodelist[neighbor].isUnseen():
                nodelist[neighbor].setSeen()
                nodelist[neighbor].discover(current)
                if neighbor == goal:
                    found = True
                else:
                    to_visit.enqueue(neighbor)
    if found:
        return retrievePath(nodelist, start, goal)
    else:
        return []

def compareWords(word1, word2):
    if len(word1) != len(word2):
        return False
    numdifferent = 0
    for i in range(len(word1)):
        if word1[i] != word2[i]:
            numdifferent += 1
    if numdifferent == 1:
        return True
    else:
        return False

def findlinks(words, q, starti, endi):
    for i in range(starti, endi):
        for j in range(i+1,len(words)):
            #compare word i and word j
            if compareWords(words[i].getWord(), words[j].getWord()):
                q.put((i,j))  #addLink(words, i, j)

if __name__ == '__main__':
    #Read in the words from a dictionary
    words = []
    dict = open("dictionary4letter.txt", 'r')
    for line in dict:
        word = node(line.strip())
        words.append(word)

    q = Queue()
    process_list = []
    for i in range(0,len(words)-100,100):
        p = Process(target=findlinks, args=(words,q, i, i+100))
        process_list.append(p)
    p = Process(target=findlinks, args=(words, q, i+100, len(words)))
    process_list.append(p)
    for p in process_list:
        p.start()
    while not q.empty():
        i, j = q.get()
        addLink(words, i, j)
    for p in process_list:
        p.join()

    while not q.empty():
        i, j = q.get()
        addLink(words, i, j)


    #Get starting and ending word
    word1 = input("What is the starting word? ")
    word2 = input("What is the ending word? ")

    index1 = -1
    index2 = -1
    for i in range(len(words)):
        if words[i].getWord() == word1:
            index1 = i
        if words[i].getWord() == word2:
            index2 = i
    if index1 == -1:
        print(word1,"was not in the dictionary.  Exiting.")
        exit(0)
    if index2 == -1:
        print(word2,"was not in the dictionary.  Exiting")
        exit(0)

    #Find a chain of words
    path = BFS(words, index1, index2)

    #Report the chain
    if path == []:
        print("There was no chain between those words, in my dictionary.")
    else:
        for index in path:
            print(words[index].getWord())

24-4 – Subprocess example

import subprocess

subprocess.Popen("C:\\Windows\\notepad.exe ..\\TCGraph\\dictionary.txt")
subprocess.Popen("C:\\Program Files\\Microsoft Office\\Office15\\Excel.exe C:\\Users\\John\\Documents\\Grades.xlsx")

dictionary.txt – file of dictionary words

dictionary4letter.txt – file of 4-letter dictionary words