CS 110X Feb 25 2014
Expected Readings: 279-288
Clicker: Assessment
The price of success is hard work, dedication to the job at hand, and the determination that whether we win or lose, we have applied the best of ourselves to the task at hand.
Vince Lombardi
1 Two Styles Of Software Development
There are, in general, two styles towards solving problems: "top-down" development, and "bottom-up" development.
In top-down, you start by defining the highest-level function and you understand that this will be broken down into sub-functions, but you start with the big picture first.
In bottom-up, you start by defining the most specific function first, and then increasingly work on "higher-level" functions until the whole problem is solved.
Neither approach is "the right one"; they each have their benefits and weaknesses. Let’s discuss.
Now let’s use these skills on solving a specific problem.
You want to know how many rolls of a single die does it take to get a 6. And you want to plot the results using a column format.
Let’s start with an in-class exercise that you will work on. Write a function, rollDiceUntilSize() that returns the number of times it takes to roll a die until a six appears. This is known as the "Chevalier" function in probability.
def rollDiceUntilSix():
"""
Count how long it takes for a die roll to produce a six.
Return an integer representing the number of rolls.
"""
Go...
1.1 Plotting columns using pylab
Aside from the Pylab graphs you have seen so far, there is one more that you need to know, Column Graphs.
11 Q1 – 16.2
11 Q2 – 14.9
11 Q3 – 13.7
11 Q4 – 15.7
12 Q1 – 22.8
12 Q2 – 25.1
12 Q3 – 31.3
12 Q4 – 41.2
import pylab import numpy def plotResults(): colValues = [ 16.2, 14.9, 13.7, 15.7, 22.8, 25.1, 31.3, 41.2] # compute moving average over three months avs = [] for idx in range(3,8): avs.append(numpy.average(colValues[idx-3:idx])) # plot column values pylab.bar(range(8), colValues) # plot this line in red pylab.plot(range(3,8), avs, ’r’) pylab.show()
Certainly we can improve this graph, but you can deal with this if you want.
1.2 Top-Down Development
So to solve the rolling die problem, how are we going to break this down?
def plotChevalier(numTrials): """ Plots using columns the results of chevalierReport """ counts = chevalierReport(numTrials) pylab.bar(range(1,len(counts)+1), counts) pylab.show()
Start with the above as a framework, and then realize that you can expand upon the chevalierReport function.
1.3 Bottom-Up Development
As an alternative, you might tackle the problem from a bottom up approach:
def rollDiceUntilSix(seed): """ Use given seed for random number generation and count how long it takes for a die roll to produce a six. """ random.seed(seed) iterations = 0 while True: die1 = random.randint(1,6) iterations = iterations + 1 if die1 == 6: return iterations
Let’s review this code. Observe that it will return, as long as the random number generator works the way it should.
Also this function, once written, can be easily tested and validated that it works.
1.4 Completing the problem
Whether you start this problem using a bottom-up approach, or a top-down approach, at some point you have to actually finish the program!
def chevalierReport(numTrials): """ Run a number of trials (with different seed numbers) and compute how long it takes until a die rolls a six. Assume you will never have to roll more than 150 times. """ # assume allways done within 150 rolls counts = [0] * 150 trials = 0 while trials < numTrials: ct = rollDiceUntilSix(trials) if ct > len(counts): print ("Too Many Rolls: " + str(ct)) else: counts[ct-1] = counts[ct-1] + 1 trials = trials + 1 return counts
1.5 Clicker Question
Takes place now.
1.6 Final skills for lists
You have seen how to manipulate lists by appending values to the end of list or by inserting them at arbitrary positions within the list.
You have also seen how to delete a value from an element by using the del keyword on a specific index location.
>>> values = [10, 20, 30, 40] >>> del values[2] >>> values [10, 20, 40] >>> values.append(50) >>> values [10, 20, 40, 50] >>> del values[1:3] >>> values [10, 50]
You might also want to remove a value that you know exists in the list. You can do this in two different ways:
>>> values = [10, 20, 30, 40, 30] >>> values.index(30) 2 >>> del values[2] >>> values [10, 20, 40, 30]
But a more convenient mechanism is:
>>> values = [10, 20, 30, 40, 30] >>> values.remove(30) >>> values [10, 20, 40, 30]
That is, you can remove the first occurrence of a value in a list. If the value does not exist in the list, then an error will occur, so you must make sure to check whether the value is in the list.
1.7 Version : 2014/02/27
(c) 2014, George Heineman