# CS2/examples/objects/OhMaybe.py David MacQuigg 8-Sept-07 '''Our new package of Coins has just arrived from the Coin Factory. Let's see if they followed our orders, and built every one to the correct interface.''' import Coins #** def testCoin(coin, bias=0.75, numTrials=500): '''Toss a coin "numTrials" times. Save all data (bias, numTrials, totalHeads, resultList) as attributes attached to each coin, and return just the most important result, the percentage of heads (a float). >>> Coins.random.seed(1234) >>> coin = Coins.BiasedCoin() # an instance of BiasedCoin >>> testCoin(coin, bias=0.2, numTrials=200) 22.5 ''' coin.bias = bias # Data will be saved until this coin coin.numTrials = numTrials # goes to the garbage collector. totalHeads = 0; resultList = [] for trial in range(numTrials): result = coin.toss() # Each coin has its own toss method if result == True: # Result is Heads resultList.append('H') totalHeads += 1 elif result == False: # Result is Tails resultList.append('-') else: # Result is something else resultList.append('*') percentHeads = 100.0 * totalHeads/numTrials # 100.0 forces a float coin.resultList = resultList coin.totalHeads = totalHeads coin.percentHeads = percentHeads return percentHeads #** if __name__ == '__main__': ''' ''' classList = Coins.__all__ # All public classes print classList # ['BiasedCoin', 'FairCoin'] for name in classList: coin = eval('Coins.%s()' % name) # eval('Coins.BiasedCoin()') percentHeads = testCoin(coin, numTrials=200) print '%s: percentHeads = %s' % (name, percentHeads) print ' '.join(coin.resultList) from doctest import testmod testmod() #** '''So what is wrong with this? We can now handle any object that follows the interface of class Coin. Coin is just a metaphor. A 'coin' could represent results of an experiment in biology, whatever. The internals of a 'coin' are now fully isolated from their environment. We still have a lot of stuff at global scope, however. If this module is to be useful in a larger program, we might want to encapsulate testCoin() along with some of the display stuff we see in the __main__ section above. Let's make a class call TestRunner with three different display methods, depending on how much detail you want. ~''' #**~