Difference between revisions of "CSC111 Python Programs Fall 2015"
(→Nov. 30, 2015) |
(→Fractal Tree) |
||
(21 intermediate revisions by the same user not shown) | |||
Line 2,546: | Line 2,546: | ||
<br /> | <br /> | ||
<br /> | <br /> | ||
− | + | ||
==rainyCambridge.py== | ==rainyCambridge.py== | ||
<br /> | <br /> | ||
Line 2,552: | Line 2,552: | ||
# rainyCambridge.py | # rainyCambridge.py | ||
# D. Thiebaut | # D. Thiebaut | ||
− | # finds the rainiest month in | + | # This program finds the rainiest month and year |
− | # for Cambridge. | + | # in Cambridge, UK. The file is fetched from a |
+ | # Web site (http://cs.smith.edu/~dthiebaut/UKTemperatures/) | ||
+ | # where several text files are stored, including one | ||
+ | # for Cambridge, called cambridgedata.txt. | ||
# Information on how to retrieve URLs found at | # Information on how to retrieve URLs found at | ||
# https://docs.python.org/3.0/library/urllib.request.html | # https://docs.python.org/3.0/library/urllib.request.html | ||
# and http://stackoverflow.com/questions/606191/convert-bytes-to-a-python-string | # and http://stackoverflow.com/questions/606191/convert-bytes-to-a-python-string | ||
− | import urllib.request | + | i |
+ | |||
+ | import urllib.request # library for accessing Web pages | ||
#--- some constants used by the program --- | #--- some constants used by the program --- | ||
Line 2,565: | Line 2,570: | ||
def getTemperatureData( fileName ): | def getTemperatureData( fileName ): | ||
− | + | # fetches the file from the Website and returns it as | |
− | + | # a long string. | |
+ | # format of the file, with a sample of the lines: | ||
"""Cambridge NIAB | """Cambridge NIAB | ||
Location: 5435E 2606N, 26 metres amsl | Location: 5435E 2606N, 26 metres amsl | ||
Line 2,575: | Line 2,581: | ||
degC degC days mm hours | degC degC days mm hours | ||
1959 1 4.4 -1.4 20 --- 78.1 | 1959 1 4.4 -1.4 20 --- 78.1 | ||
+ | 1961 1 6.2 1.0 5 55.9 50.5 | ||
1961 2 10.3 4.3 0 50.4 65.9 | 1961 2 10.3 4.3 0 50.4 65.9 | ||
− | |||
− | |||
− | |||
2011 7 21.2 10.9 0 38.4* --- | 2011 7 21.2 10.9 0 38.4* --- | ||
2015 1 8.0 1.3 12 48.4* --- Provisional | 2015 1 8.0 1.3 12 48.4* --- Provisional | ||
− | |||
+ | |||
+ | """ | ||
url = BASEURL + fileName | url = BASEURL + fileName | ||
print( "Retrieving data from", url ) | print( "Retrieving data from", url ) | ||
Line 2,589: | Line 2,594: | ||
return data | return data | ||
− | def | + | def main(): |
− | # | + | # get the string |
− | # | + | data = getTemperatureData( "cambridgedata.txt" ) |
− | + | ||
− | + | # split string into lines | |
− | line = line.strip() | + | lines = data.split( "\n" ) |
− | # | + | |
− | if len( line )<=1: | + | |
+ | # create empty list | ||
+ | L = [] | ||
+ | |||
+ | # loop through all the lines | ||
+ | for line in lines: | ||
+ | |||
+ | # strip extra space and remove the * characters | ||
+ | line = line.strip().replace( '*', ' ' ) | ||
+ | |||
+ | # get rid of blank lines | ||
+ | if len( line ) <= 1: | ||
continue | continue | ||
− | if not line[0] in [' | + | |
+ | # get preamble | ||
+ | if not line[0] in ['1', '2']: | ||
continue | continue | ||
− | + | ||
− | fields = line.split() | + | # extract rain, year, month |
− | + | fields = line.split( ) | |
+ | year = fields[0] | ||
+ | month = fields[1] | ||
+ | rain = fields[5] | ||
+ | |||
+ | # it is possible that the rain data is a string | ||
+ | # of the form "---", in which case taking the float | ||
+ | # equivalent will result in an exception. We catch this | ||
+ | # exception with a try/except clause. | ||
+ | try: | ||
+ | tuple = ( float( rain ), month, year ) | ||
+ | except ValueError: | ||
continue | continue | ||
− | # | + | |
− | tuple | + | # if we're here, the rain data is correct. Put it as |
− | + | # the first item in a tuple, and record the tuple in a | |
+ | # list. | ||
+ | L.append( tuple ) | ||
+ | |||
− | + | # sort the list and reverse it | |
− | + | L.sort() | |
− | + | L.reverse() | |
− | + | ||
− | |||
− | + | # display rainiest month/year | |
− | + | rain, month, year = L[0] | |
− | + | print( "rain = ", rain, "year = ", year, "month = ", month ) | |
− | |||
− | rain = | ||
− | |||
− | |||
− | |||
− | |||
main() | main() | ||
− | |||
</source> | </source> | ||
Line 2,678: | Line 2,702: | ||
</source> | </source> | ||
<br /> | <br /> | ||
− | ==Presidents. | + | ==Presidents.py== |
<br /> | <br /> | ||
::<source lang="python"> | ::<source lang="python"> | ||
Line 2,708: | Line 2,732: | ||
</source> | </source> | ||
+ | <br /> | ||
+ | |||
+ | =Tue, 12/1/15= | ||
+ | <br /> | ||
+ | * Programs developed during office hours on 12/1/15 with a group of students | ||
+ | <br /> | ||
+ | ==hw11a.py== | ||
+ | <br /> | ||
+ | ::<source lang="python"> | ||
+ | lines = """building, Outdoor Track, Purple, Anna BD & Bailey Bogan, 108, 151, 103, 98, 202, 92, 209, 102, 214, 132, 206, 144 | ||
+ | Building, The Pitch, Purple, Anna BD & Bailey Bogan, 172, 249, 173, 193, 266, 190, 270, 244 | ||
+ | field, Outdoor Track, red, Anisha Tyagi and Sara Kacmoli, 1, 91, 98, 115, 91, 143, 87, 164, 86, 204, 87, | ||
+ | """ | ||
+ | |||
+ | def main(): | ||
+ | # create a dictionary of buildings | ||
+ | dict = {} | ||
+ | |||
+ | # process each line | ||
+ | for line in lines.split( "\n" ): | ||
+ | fields = line.lower().split( "," ) | ||
+ | |||
+ | # get rid of invalid lines | ||
+ | if len( fields ) < 8: | ||
+ | continue | ||
+ | |||
+ | if fields[0].startswith( "building" ) == False: | ||
+ | continue | ||
+ | |||
+ | # valid fields | ||
+ | #print( "fields = ", fields ) | ||
+ | |||
+ | |||
+ | # add line to dictionary, key is building name, | ||
+ | # value is list of coordinates | ||
+ | name = fields[1].strip() | ||
+ | coordinates = fields[4: ] | ||
+ | |||
+ | dict[ name ] = coordinates | ||
+ | |||
+ | |||
+ | # display contents of dictionary | ||
+ | for key in dict.keys(): | ||
+ | print( key, "-->", dict[ key ] ) | ||
+ | |||
+ | |||
+ | |||
+ | main() | ||
+ | </source> | ||
+ | <br /> | ||
+ | ==hw11b.py== | ||
+ | <br /> | ||
+ | ::<source lang="python"> | ||
+ | L = [ 1, 2, 3, 4, 5, 6, 10, 11, 14, 20] | ||
+ | |||
+ | for i in range( 0, len( L ), 2 ): | ||
+ | first = L[i] | ||
+ | second = L[i+1] | ||
+ | print( "(", first, ",", second, ")" ) | ||
+ | |||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | ==hw11c.py== | ||
+ | <br /> | ||
+ | ::<source lang="python"> | ||
+ | dateDict = {} | ||
+ | |||
+ | dateDict[ "Ford Hall" ] = 2005 | ||
+ | dateDict[ "Burton Hall" ] = 1905 | ||
+ | dateDict[ "Bass Hall" ] = 1998 | ||
+ | |||
+ | |||
+ | |||
+ | for name in [ "Ford", "Ford Hall", "Art", "Bass Hall", "Bass" ]: | ||
+ | #if name in dateDict.keys(): | ||
+ | # print( name ) | ||
+ | for key in dateDict.keys(): | ||
+ | if key.find( name ) != -1: | ||
+ | print( name ) | ||
+ | |||
+ | |||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | |||
+ | =Wed. 12/2/15= | ||
<br /> | <br /> | ||
==Inheritance0.py== | ==Inheritance0.py== | ||
Line 2,714: | Line 2,825: | ||
<br /> | <br /> | ||
::<source lang="python"> | ::<source lang="python"> | ||
− | + | # inheritance0.py | |
+ | # A simple car class to start with. | ||
+ | # To do: add a truck class, which is a car | ||
+ | # with a top. | ||
+ | |||
from graphics import * | from graphics import * | ||
Line 2,767: | Line 2,882: | ||
self.w2.move( dx, dy ) | self.w2.move( dx, dy ) | ||
− | + | ||
− | + | def main(): | |
− | + | # open the window | |
+ | win = GraphWin( "CSC111 Inheritance Demo", WIDTH, HEIGHT ) | ||
+ | |||
+ | car = Car( Point( 100,250 ) ) | ||
+ | car.draw( win ) | ||
+ | |||
+ | # animation loop | ||
+ | while win.checkMouse()==None: | ||
+ | car.move( 2, 0 ) | ||
+ | |||
+ | win.close() | ||
+ | |||
+ | main() | ||
+ | </source> | ||
+ | <br /> | ||
+ | ==Inheritance4.py== | ||
+ | <br /> | ||
+ | ::<source lang="python"> | ||
+ | # inheritance4.py | ||
+ | # a graphic demo program for creating a circle | ||
+ | # with a label in the middle. | ||
+ | # | ||
+ | |||
+ | from graphics import * | ||
+ | WIDTH = 800 | ||
+ | HEIGHT = 600 | ||
− | class | + | class MyCircle( Circle ): |
− | def __init__( self, rp ): | + | def __init__( self, rp, rad, text ): |
− | super().__init__( rp ) | + | super().__init__( rp, rad ) |
− | + | self.label= Text( rp, text ) | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | self. | ||
− | |||
def draw( self, win ): | def draw( self, win ): | ||
super().draw( win ) | super().draw( win ) | ||
− | self. | + | self.label.draw( win ) |
def move( self, dx, dy ): | def move( self, dx, dy ): | ||
super().move( dx, dy ) | super().move( dx, dy ) | ||
− | self. | + | self.label.move( dx, dy ) |
− | + | ||
+ | def setText( self, newText ): | ||
+ | self.label.setText( newText ) | ||
+ | |||
+ | def main(): | ||
+ | win = GraphWin( "MyCircle Demo", WIDTH, HEIGHT ) | ||
+ | |||
+ | labCirc = MyCircle( Point( 100, 100 ), 50, "Hello!" ) | ||
+ | labCirc.draw( win ) | ||
+ | |||
+ | count = 0 | ||
+ | while win.checkMouse() == None: | ||
+ | labCirc.move( 2, 1 ) | ||
+ | count += 1 | ||
+ | |||
+ | #if count % 30 == 0: | ||
+ | labCirc.setText( "{0:1} steps!".format( count ) ) | ||
+ | |||
+ | |||
+ | |||
+ | win.close() | ||
+ | |||
+ | main() | ||
+ | |||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | =Fri. 12/4/14= | ||
+ | <br /> | ||
+ | ==Inheritance5.py== | ||
+ | <br /> | ||
+ | ::<source lang="python"> | ||
+ | # inheritance5.py | ||
+ | # Animal class to be used as super class | ||
+ | # for Cow and Dog classes. | ||
+ | # Cow class contains milk member variable | ||
+ | # Dog class contains attribute: trained, hospital, | ||
+ | # seeing-eye dog, rescue. | ||
+ | |||
+ | class Animal: | ||
+ | def __init__( self, name, birth, vacc, tattd ): | ||
+ | self.name = name | ||
+ | self.dob = birth | ||
+ | self.vaccinated = vacc | ||
+ | self.tattooed = tattd | ||
+ | |||
+ | def __str__( self ): | ||
+ | vaccString = "vaccinated" | ||
+ | if self.vaccinated == False: | ||
+ | vaccString = "not vaccinated" | ||
+ | tattString = "tattooed" | ||
+ | if self.tattooed == False: | ||
+ | tattString = "not tattooed" | ||
+ | |||
+ | return "{0:1}: {1:1}, {2:1}, {3:1}".format( | ||
+ | self.name, self.dob, vaccString, tattString ) | ||
+ | |||
+ | def isVaccinated( self ): | ||
+ | return self.vaccinated | ||
+ | |||
+ | def isTattooed( self ): | ||
+ | return self.tattooed | ||
+ | |||
+ | def getDOB( self ): | ||
+ | return self.dob | ||
+ | |||
+ | def getName( self ): | ||
+ | return self.name | ||
+ | |||
+ | class Cow( Animal ): | ||
+ | def __init__( self, name, birth, vacc, tattd, milk ): | ||
+ | super().__init__( name, birth, vacc, tattd ) | ||
+ | self.milk = milk | ||
+ | |||
+ | def getMilk( self ): | ||
+ | return self.milk | ||
+ | |||
+ | def __str__( self ): | ||
+ | s = super().__str__() | ||
+ | return s + ", {0:1}".format( self.milk ) | ||
+ | |||
+ | |||
+ | def main(): | ||
+ | pet1 = Animal( "Rex", "12/02/2015", True, True ) | ||
+ | pet2 = Animal( "Garfield", "01/01/1978", True, False ) | ||
+ | print( "pet #1 = ", pet1 ) | ||
+ | print( "pet #2 = ", pet2 ) | ||
+ | |||
+ | cow1 = Cow( "Rosie", "12/1/14", True, False, 20 ) | ||
+ | print( "cow #1 = ", cow1 ) | ||
+ | |||
+ | main() | ||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | |||
+ | ==Polymorphism.py== | ||
+ | <br /> | ||
+ | ::<source lang="python"> | ||
+ | class Animal: | ||
+ | def name(self): | ||
+ | return | ||
+ | def sleep(self): | ||
+ | print( "sleeping now" ) | ||
+ | def speak(self): | ||
+ | return | ||
+ | |||
+ | class Dog( Animal ): | ||
+ | def name(self): | ||
+ | print( "I am a dog!" ) | ||
+ | def speak(self): | ||
+ | print( "Woof!" ) | ||
+ | |||
+ | class Cat( Animal ): | ||
+ | def name(self): | ||
+ | print( "I am a cat!" ) | ||
+ | def speak(self): | ||
+ | print( "Meow!" ) | ||
+ | |||
+ | class Duck( Animal ): | ||
+ | def name(self): | ||
+ | print( "I am a duck!" ) | ||
+ | def speak(self): | ||
+ | print( "Quack!" ) | ||
+ | |||
+ | |||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | ==Bananas.py== | ||
+ | [[Image:MinionBanana.jpg|right|200px]] | ||
+ | <br /> | ||
+ | ::<source lang="python"> | ||
+ | |||
+ | def minion( bunch ): | ||
+ | """this minion is given a bunch of bananas. | ||
+ | if there's only 1 banana in the bunch, it will | ||
+ | return that banana as the largest in the bunch. | ||
+ | |||
+ | If there's more than 1 banana in the bunch, this | ||
+ | minion will keep one banana (the first one it finds) | ||
+ | and pass the remainder of the bananas to another | ||
+ | minion. That new minion will follow the *exact* | ||
+ | same script in order to find the largest banana. | ||
+ | At some point that second minion will return the | ||
+ | largest of the bananas in the remainder. Our first | ||
+ | minion will compare that to the one it kept, and | ||
+ | return the largest of the two. | ||
+ | """ | ||
+ | |||
+ | # if minion gets a bunch of 1 banana, that banana | ||
+ | # is the largest of what it got. | ||
+ | if len( bunch ) == 1: | ||
+ | banana = bunch[0] | ||
+ | return banana | ||
+ | |||
+ | # if we're here, it's because the bunch has more | ||
+ | # than 1 banana. | ||
+ | # keep the first one: | ||
+ | kept = bunch[0] | ||
+ | |||
+ | # create a smaller bunch: the remaining bananas | ||
+ | remainingBananas = bunch[1: ] | ||
+ | |||
+ | # pass that to another minion | ||
+ | largestOfRemainingBananas = minion( remainingBananas ) | ||
+ | |||
+ | # figure out which of the 2 bananas is largest: the | ||
+ | # one kept, or the one just returned | ||
+ | if kept > largestOfRemainingBananas: | ||
+ | return kept | ||
+ | else: | ||
+ | return largestOfRemainingBananas | ||
+ | |||
+ | def main(): | ||
+ | bananas = [10, 2, 3, 20, -1, 5, 7, 0, 3, 6] | ||
+ | largest = minion( bananas ) | ||
+ | |||
+ | print( "bunch = ", bananas ) | ||
+ | print( "largest banana found = ", largest ) | ||
+ | |||
+ | main() | ||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | =Mon. 12/07/15= | ||
+ | <br /> | ||
+ | ==LookForBanana.py== | ||
+ | <br /> | ||
+ | ::<source lang="python"> | ||
+ | # this program is based on the program that finds the heaviest banana | ||
+ | # in a bunch of bananas, using minions to do the work. This time we | ||
+ | # are interested if there is a banana of a given weight in the bunch. | ||
+ | # The algorithm in this case will have a minion work this way: | ||
+ | # 1) it gets a bunch of bananas, along with a weight, and its job is | ||
+ | # to figure out if there is a banana with this weight in the bunch. | ||
+ | # 2) the minion then checks to see if it has gotten a bunch with just | ||
+ | # one banana. If so, it checks to see if that banana has the weight | ||
+ | # that is being sought. If it is, the minion returns True, meaning that | ||
+ | # a banana was found with that weight. Otherwise it returns False. | ||
+ | # 3) the minion takes 1 banana out of the bunch. Before passing the | ||
+ | # remaining bananas to another minion, it checks to see if the banana | ||
+ | # it has just picked has the weight that is being sought. If so, then | ||
+ | # the minion can stop the recursion and return True. | ||
+ | # 4) otherwise the minion passes the remaining bananas to another | ||
+ | # minion and asks that new minion to go through the same 5 steps | ||
+ | # explained here. | ||
+ | # 5) whatever is returned by the minion that was just called, this minion | ||
+ | # will also return. | ||
+ | |||
+ | def minion( bunch, look ): | ||
+ | print( "I'm a minion, and I got", bunch, "and am looking for", look ) | ||
+ | |||
+ | # stopping condition #1 | ||
+ | if len( bunch )==1: | ||
+ | if bunch[0] == look: | ||
+ | return True | ||
+ | else: | ||
+ | return False | ||
+ | |||
+ | kept = bunch[0] | ||
+ | |||
+ | # stopping condition #2 | ||
+ | if kept == look: | ||
+ | return True | ||
+ | |||
+ | # recursive step. Call another minion to see | ||
+ | # if look is in remaining bananas | ||
+ | remaining = bunch[1 : ] | ||
+ | |||
+ | # return whatever that minion returns to us... | ||
+ | return minion( remaining, look ) | ||
+ | |||
+ | |||
+ | def main(): | ||
+ | bananas = [ 100, 120, 107, 97, 105 ] | ||
+ | |||
+ | for item in bananas: | ||
+ | look = item | ||
+ | |||
+ | if minion( bananas, look ) == True: | ||
+ | print( look," found!" ) | ||
+ | else: | ||
+ | print( look, "not found!" ) | ||
+ | |||
+ | main() | ||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | ==Factorial.py== | ||
+ | <br /> | ||
+ | ::<source lang="python"> | ||
+ | def factorial( n ): | ||
+ | # stopping condition | ||
+ | if n==1: | ||
+ | return 1 | ||
+ | |||
+ | # recursive step | ||
+ | result = n * factorial( n-1 ) | ||
+ | |||
+ | return result | ||
+ | |||
+ | |||
def main(): | def main(): | ||
− | # open the | + | while True: |
− | win = | + | n = int( input( "> " ) ) |
+ | if n<=0: | ||
+ | break | ||
+ | |||
+ | print( "{0:1}! = {1:1}".format( n, factorial( n ) ) ) | ||
+ | |||
+ | main() | ||
+ | </source> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | =Wed. 12/09/15= | ||
+ | <br /> | ||
+ | ==Recursively Visiting a Maze== | ||
+ | <br /> | ||
+ | |||
+ | ::<source lang="python"> | ||
+ | # graphicsVisitMaze.py | ||
+ | # D. Thiebaut | ||
+ | # Generates a maze and displays it in a graphics window. | ||
+ | # The maze is defined as a collection of lines of text. | ||
+ | # MazeText is the variable containing the raw definition. | ||
+ | # MazeText is split into lines and the list of lines is kept | ||
+ | # in the variable maze. | ||
+ | # Each line in mazeText contains # or . characters. A #-character | ||
+ | # indicates a wall, while a . indicates an empty space. | ||
+ | # MazeText is cleaned up and all the dots are replaced by spaces. | ||
+ | # Then the maze is displayed in the graphic window. | ||
+ | # The program maintains the status of the visit in the variable | ||
+ | # maze. A '.' will represent a breadcrumb, i.e. a place that has | ||
+ | # been visited and that is potentially on the path to the exit. A | ||
+ | # 'v' character indicates a visited place that leads to an impass. | ||
+ | # The program starts by visiting location STARTi (line number) | ||
+ | # and STARTj (column number). | ||
+ | # | ||
+ | import time | ||
+ | import os | ||
+ | from graphics import * | ||
+ | |||
+ | |||
+ | # Dimensions of the graphics window | ||
+ | WIDTH = 600 | ||
+ | HEIGHT = 600 | ||
+ | |||
+ | mazeText = """ | ||
+ | ######################### | ||
+ | ........................# | ||
+ | ##############.########## | ||
+ | #.#.#........#.#........# | ||
+ | #.#.#.########.########.# | ||
+ | #.#.#.................#.# | ||
+ | #.#.###.#####.#####.#...# | ||
+ | #...........#.#.#.#.##### | ||
+ | #.#########.#.#.#.#...#.# | ||
+ | #.#.#.#.#.#.#.#.#######.# | ||
+ | #.#.........#.#.......#.. | ||
+ | #.###############.#####.# | ||
+ | #...............#.......# | ||
+ | #.###########.#########.# | ||
+ | #........#..............# | ||
+ | ######################### | ||
+ | """ | ||
+ | |||
+ | mazeText1 = """ | ||
+ | ######################### | ||
+ | ........................# | ||
+ | #.......................# | ||
+ | #.......................# | ||
+ | #.......................# | ||
+ | #.......................# | ||
+ | #.......................# | ||
+ | #.......................# | ||
+ | #.......................# | ||
+ | #.......................# | ||
+ | #.......................# | ||
+ | #.......................# | ||
+ | #.......................# | ||
+ | #.......................# | ||
+ | #........................ | ||
+ | ######################### | ||
+ | """ | ||
+ | |||
+ | mazeText2 = """ | ||
+ | ######################### | ||
+ | ........................# | ||
+ | #.......................# | ||
+ | #.......................# | ||
+ | #.......................# | ||
+ | #######################.# | ||
+ | #.......................# | ||
+ | #.......................# | ||
+ | #.......................# | ||
+ | #.......................# | ||
+ | #.####################### | ||
+ | #.......................# | ||
+ | #.......................# | ||
+ | #.......................# | ||
+ | #........................ | ||
+ | ######################### | ||
+ | """ | ||
+ | |||
+ | # | ||
+ | STARTi = 1 # line number | ||
+ | STARTj = 0 # column number | ||
+ | |||
+ | NOLINES = len( mazeText.strip().split("\n") ) | ||
+ | NOCHARS = len( mazeText.strip().split("\n")[1] ) | ||
+ | BLOCKWIDTH = WIDTH // NOCHARS # width in pixels of block on graphics window | ||
+ | BLOCKHEIGHT = HEIGHT / NOLINES # height in pixels of block on graphics window | ||
+ | |||
+ | |||
+ | def getMazeFromFile( fileName ): | ||
+ | """reads the definition of the maze from a file""" | ||
+ | |||
+ | try: | ||
+ | lines = open( fileName, 'r' ).read() | ||
+ | except: | ||
+ | print( "I/O Error: could not open", fileName ) | ||
+ | return None | ||
+ | |||
+ | return getMaze( lines ) | ||
+ | |||
+ | def getMaze( mazeText ): | ||
+ | """take the string representing the maze and | ||
+ | break it down into an array of lines""" | ||
+ | maze=[] | ||
+ | for i, line in enumerate( mazeText.split( '\n' ) ): | ||
+ | line = line.strip() | ||
+ | #print( "%d [%s]" % (i, line ) ) | ||
+ | if len( line ) < 2: | ||
+ | continue | ||
+ | line = line.replace( '.', ' ' ) | ||
+ | maze.append( line ) | ||
+ | return maze | ||
+ | |||
+ | def setBreakCrumb( i, j, win ): | ||
+ | """draw a circle where the walker has just landed, in | ||
+ | the maze.""" | ||
+ | global BLOCKWIDTH | ||
+ | global BLOCKHEIGHT | ||
+ | radius = BLOCKWIDTH // 4 | ||
+ | brd = Circle( Point( (j+0.5)*BLOCKWIDTH, (i+0.5)*BLOCKHEIGHT ), radius ) | ||
+ | brd.setFill( "red" ) | ||
+ | brd.draw( win ) | ||
+ | |||
+ | # rest a tiny bit to slow down the program | ||
+ | time.sleep( 0.1 ) | ||
+ | |||
+ | def setImpass( i, j, win ): | ||
+ | """mark a block as not leading to an exit. Set its color | ||
+ | to grey""" | ||
+ | global BLOCKWIDTH | ||
+ | global BLOCKHEIGHT | ||
+ | radius = BLOCKWIDTH // 4 | ||
+ | blk = Rectangle( Point( j*BLOCKWIDTH, i*BLOCKHEIGHT ), | ||
+ | Point( (j+1)*BLOCKWIDTH, (i+1)*BLOCKHEIGHT ) ) | ||
+ | blk.setFill( "lightgrey" ) | ||
+ | blk.setOutline( "lightgrey" ) | ||
+ | blk.draw( win ) | ||
+ | |||
+ | # rest a tiny bit to slow down the program | ||
+ | time.sleep( 0.1 ) | ||
+ | |||
+ | |||
+ | def displayMaze( maze, win ): | ||
+ | """ display the maze and wait for some amount of time""" | ||
+ | global BLOCKWIDTH | ||
+ | global BLOCKHEIGHT | ||
+ | global NOLINES | ||
+ | global NOCHARS | ||
+ | |||
+ | blocks = [] | ||
+ | for i in range (NOLINES ): | ||
+ | for j in range( NOCHARS ): | ||
+ | if maze[i][j]=="#": | ||
+ | r = Rectangle( Point( j*BLOCKWIDTH, i*BLOCKHEIGHT ), | ||
+ | Point( (j+1)*BLOCKWIDTH, (i+1)*BLOCKHEIGHT ) ) | ||
+ | r.setFill( "blue" ) | ||
+ | r.setOutline( "blue" ) | ||
+ | r.draw( win ) | ||
+ | blocks.append( r ) | ||
+ | |||
+ | return blocks | ||
+ | |||
+ | def setChar( maze, i, j, char ): | ||
+ | """puts the character char at position i, j in the maze""" | ||
+ | line = maze[i] | ||
+ | letters = [] | ||
+ | for letter in line: | ||
+ | letters.append( letter ) | ||
+ | letters[j] = char | ||
+ | maze[i] = ''.join( letters ) | ||
+ | |||
+ | def visitMaze( maze, i, j, win ): | ||
+ | """recursive visit of the maze. Returns True when it | ||
+ | has found the exit, False otherwise""" | ||
+ | |||
+ | # put a breadcrumb where we just landed. | ||
+ | setBreakCrumb( i, j, win ) | ||
+ | setChar( maze, i, j, '.' ) | ||
+ | |||
+ | # stopping condition: we landed on the Exit... | ||
+ | if ( i != STARTi or j != STARTj ) \ | ||
+ | and ( (i==0 or i==len( maze )-1 ) or (j==0 or j==len( maze[0] )-1 ) ): | ||
+ | return True | ||
+ | |||
+ | #--- try the four directions around where we are --- | ||
+ | #--- to the right? --- | ||
+ | if j+1< len( maze[0] ) and maze[i][j+1]==' ': | ||
+ | if visitMaze( maze, i, j+1, win ) == True: | ||
+ | return True # found an exit by going right! | ||
+ | |||
+ | #--- down? --- | ||
+ | if i+1< len( maze ) and maze[i+1][j]==' ': | ||
+ | if visitMaze( maze, i+1, j, win ) == True: | ||
+ | return True # found an exit by going down! | ||
+ | |||
+ | #--- up? --- | ||
+ | if i-1>=0 and maze[i-1][j]==' ': | ||
+ | if visitMaze( maze, i-1, j, win ) == True: | ||
+ | return True # found an exit by going up! | ||
+ | |||
+ | #--- to the left? --- | ||
+ | if j-1>=0 and maze[i][j-1]==' ': | ||
+ | if visitMaze( maze, i, j-1, win ) == True: | ||
+ | return True # found an exit by going left! | ||
+ | |||
+ | #--- if we're here, none of the 4 directions was successful --- | ||
+ | #--- in bringing us to an exit, we have to mark our cell with-- | ||
+ | #--- a v, and return false to our caller, indicating that we--- | ||
+ | #--- couldn't find a path --- | ||
− | + | setImpass( i, j, win ) | |
− | + | setChar( maze, i, j, 'v' ) | |
+ | #printMaze( maze ) | ||
+ | return False | ||
+ | |||
+ | |||
+ | def main(): | ||
+ | """gets the maze, visit and display it""" | ||
+ | #maze = getMazeFromFile( 'largemaze.txt' ) | ||
+ | win = GraphWin("Maze", WIDTH, HEIGHT ) | ||
+ | win.getMouse() | ||
+ | |||
+ | maze = getMaze( mazeText2 ) | ||
− | + | #printMaze( maze ) | |
− | + | blocks = displayMaze( maze, win ) | |
− | + | ||
+ | success = visitMaze( maze, STARTi, STARTj, win ) | ||
+ | |||
+ | #--- print the maze without the v-characters --- | ||
+ | #printMazeNoVs( maze ) | ||
+ | |||
+ | if success: | ||
+ | print( "A path was found!" ) | ||
+ | else: | ||
+ | print( "No path to an exit found..." ) | ||
− | + | win.getMouse() | |
− | + | win.close() | |
− | + | main() | |
− | + | ||
− | + | ||
− | + | ||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | ==Fractal Tree== | ||
+ | <br /> | ||
+ | ::<source lang="python"> | ||
+ | # fractalTree.py | ||
+ | # D. Thiebaut | ||
+ | # Code taken from http://openbookproject.net/thinkcs/python/english3e/recursion.html | ||
+ | # and adapted to work with graphics111.py. | ||
+ | # | ||
+ | # Draws a fractal tree on the graphic window. | ||
+ | # | ||
+ | from graphics import * | ||
+ | import math | ||
+ | import time | ||
+ | import random | ||
+ | |||
+ | # dimensions of the window | ||
+ | MAXWIDTH = 800 | ||
+ | MAXHEIGHT = 800 | ||
+ | |||
+ | # recursive tree-drawing function | ||
+ | # | ||
+ | def draw_tree(win , # the canvas | ||
+ | order, # the level of recursion. Starts positive. | ||
+ | theta, # angle of new branch leaving this trunk | ||
+ | sz, # size of this branch | ||
+ | x, y, # coordinates of base of this branch | ||
+ | heading, # angle of direction of this branch | ||
+ | color # color | ||
+ | ): | ||
+ | |||
+ | trunk_ratio = 0.29 # How big is the trunk relative to whole tree? | ||
+ | trunk = sz * trunk_ratio # length of trunk | ||
+ | |||
+ | # compute x, y of end of the current branch | ||
+ | delta_x = trunk * math.cos(heading) | ||
+ | delta_y = trunk * math.sin(heading) | ||
+ | x2, y2 = x + delta_x, y + delta_y | ||
+ | |||
+ | |||
+ | # draw current branch | ||
+ | branch = Line( Point( x, y), Point( x2, y2 ) ) | ||
+ | branch.setFill( color ) | ||
+ | branch.setWidth( 2 ) | ||
+ | branch.setOutline( color ) | ||
+ | branch.draw( win ) | ||
+ | |||
+ | # if this branch has sub-branches, then recurse | ||
+ | if order > 0: | ||
+ | |||
+ | # make the recursive calls to draw the two subtrees | ||
+ | newsz = sz*(1 - trunk_ratio) | ||
+ | draw_tree(win, | ||
+ | order-1, theta, newsz, x2, y2, heading-theta, | ||
+ | color ) | ||
+ | draw_tree(win, | ||
+ | order-1, theta, newsz, x2, y2, heading+theta, | ||
+ | color ) | ||
+ | |||
+ | |||
+ | # draw 1 tree in the middle of the screen, shooting straight up. | ||
+ | def main(): | ||
+ | win = GraphWin("Fractal Tree", MAXWIDTH, MAXHEIGHT ) | ||
+ | theta = 0.65 # use 0.02 for tall skinny trees, 0.7 for fat trees | ||
+ | draw_tree(win, | ||
+ | 9, | ||
+ | theta, | ||
+ | MAXWIDTH*0.9, MAXWIDTH//2, | ||
+ | MAXHEIGHT-50, | ||
+ | -math.pi/2, | ||
+ | "brown" ) | ||
win.getMouse() | win.getMouse() | ||
Line 2,815: | Line 3,532: | ||
main() | main() | ||
− | + | ||
− | + | ||
</source> | </source> | ||
+ | <br /> | ||
+ | ==Hanoi.py== | ||
+ | <br /> | ||
+ | The program can be found [[CSC231_hanoi.py| here]]. | ||
<br /> | <br /> | ||
<br /> | <br /> | ||
− | |||
<br /> | <br /> | ||
<br /> | <br /> | ||
Line 2,832: | Line 3,552: | ||
<br /> | <br /> | ||
<br /> | <br /> | ||
− | |||
[[Category:CSC111]][[Category:Python]] | [[Category:CSC111]][[Category:Python]] |
Latest revision as of 13:17, 9 December 2015
--D. Thiebaut (talk) 10:34, 18 September 2015 (EDT)
Contents
- 1 Wed., 9/16/15
- 2 Friday, 9/18/15
- 3 Monday, 9/21/15
- 4 Wednesday, 9/23/15
- 5 Friday, 9/25/15
- 6 Wed., 9/30/15
- 7 Fri., 10/2/15
- 8 Mon. 10/5/15
- 9 Fri. 10/9/15
- 10 Wed 10/14/15
- 11 Wed. 10/21/15
- 12 Mon. 11/2/15
- 13 Wed. 11/04/15
- 14 Fri. 11/06/15
- 15 Mon. 11/9/15
- 16 Wed. 11/11/15
- 17 Mon, 11/16/15
- 18 Wed. 11/18/15
- 19 Fri. 11/20/15
- 20 Mon. 11/23/15
- 21 Nov. 30, 2015
- 22 Tue, 12/1/15
- 23 Wed. 12/2/15
- 24 Fri. 12/4/14
- 25 Mon. 12/07/15
- 26 Wed. 12/09/15
Wed., 9/16/15
# displayWeek.py # D. Thiebaut # displays a schedule for the five days of the week length = eval( input( "Length of bar? " ) ) print( "-" * length ) for day in [ "Mo:", "Tu:", "We:", "Th:", "Fr:" ]: print( day ) #print( " :" * 2) print( " :" ) print( "-" * length )
Friday, 9/18/15
# displayGrade.py # D. Thiebaut # # prompts user for information and # grade. # display user's grade in graph, along with # class average (constant) # constant information classAvg = 80 # user input. Get info from user fName = "Al" lName = "K" Id = "990123456" final = 90 #--- Format information and display --- # create the bar bar = "+" + 48*"-" + "+" lenBar = len( bar ) # compute the number of dashes noSpaces = lenBar - len( fName ) -len(lName )-len(Id) - 6 spaces = " " * noSpaces # create the scale scale = " 00...10...20...30...40...50...60...70...80...90...100" # display the information print( bar ) print( "|" + fName, lName, spaces, Id, "|" ) print( bar ) print() print( scale ) # the length of the bar for the bar-graph, in number of characters # is 1/2 the actual grade. So divide the grade by half to get the # number of chars. We use // to get the integer part of the result print( "grade:", (final//2) * "#" ) print( "class:", (classAvg//2) * "#" )
Monday, 9/21/15
Version 1 of Teller Machine program
# tellerMachine.py # D. Thiebaut # A program that simulates a teller machine, where user enters an amount of # dollars, and program figures out the number of bills to return. # get the amount amount = eval( input( "Please enter amount: " ) ) amount = int( amount ) print() # break down into bills no20s = amount // 20 # how many 20s go into amount amount = amount % 20 # what is left over after giving out 20s go back into amount no10s = amount // 10 amount = amount % 10 no5s = amount //5 no1s = amount % 5 # display the results print( "Amount withdrawn = ", amount ) print( "Please lift your keyboard and find: " ) print( no20s, "$20-bill(s)" ) print( no10s, "$10-bill(s)" ) print( no5s, "$5-bill(s)" ) print( no1s, "$1-bill(s)" )
Version 2, submitted by Shirui Cheng, who figured out that it was a perfect opportunity to use a loop!
# Teller machine simulator # Shirui Cheng # get the input amount = eval(input ("How much money do you want to withdraw? ")) # break down in $20-, $10-, $5-, and $1-bills # and print the result at every step for bill in (20, 10, 5, 1): no = amount // bill amount = amount % bill print (no, "$", bill, "bill(s)")
Wednesday, 9/23/15
# averageAge.py # D. Thiebaut # # Example of how one would go about computing # the average value of a list of numbers. # def main(): # initialize variables sum = 0 count = 0 # loop through a list of ages and compute the total sum # of the ages, and the number of values in the list. for age in [20, 19, 21, 20, 21, 29, 17]: sum = sum + age count = count + 1 # compute the average, displays quantities of interest print( "-" * 30 ) print( "average = ", sum/count ) main()
Accumulating Strings
# stringPatterns.py # D. Thiebaut # print a string of 5 alternating patterns. def main(): # define 2 different patterns pat1 = "**" pat2 = "++" # create an empty string result = "" # loop 5 times (we want a string of 5 alternating patterns) for i in range( 5 ): # add a new pattern to the string result = result + pat1 # switch the patterns around pat1, pat2 = pat2, pat1 # done with the loop! Print string of patterns print( result ) main()
Friday, 9/25/15
# averageAge.py # D. Thiebaut # # Example of how one would go about debugging a simple # program and reveal how the loop works. # def main(): # initialize variables sum = 0 count = 0 print( "sum = {0:1} count = {1:1}".format( sum, count ) ) input() # loop through a list of ages and compute the total sum # of the ages, and the number of values in the list. for age in [20, 19, 21, 20, 21, 29, 17]: sum = sum + age count = count + 1 print( "age = {0:5} sum = {1:5} count = {2:5}".format( age, sum, count ) ) input() # compute the average, displays quantities of interest print( "-" * 30 ) print( "sum = ", sum ) print( "count = ", count ) print( "average = ", sum/count ) main()
Wed., 9/30/15
# exercises 9/30/15 def main(): # Exercise #1 fName = "SOPHIA" lName = "smith" fullName = fName + " " + lName print( fullName.title().center( 60 ) ) print( "\n", "-"*60, "\n\n", sep="" ) # Exercise #2 # Define the string with multiple lines book = """Ulysses James Joyce Stately, plump Buck Mulligan came from the stairhead, bearing a bowl of lather on which a mirror and a razor lay crossed. """ # split the book into a list of lines lines = book.splitlines() # assign different lines to variables bookTitle = lines[0] author = lines[1] sentence = lines[2] + lines[3] + lines[4] # this next statement is too sophisticated for now #sentence = " ".join( lines[2: ] ) # display the result print( bookTitle.upper().center( 60 ) ) print( author.title().center( 60 ) ) print( ) print( sentence ) main()
Fri., 10/2/15
# Using split() # ------------------------- poem = """Chocolate Chocolate is the first luxury. It has so many things wrapped up in it: Deliciousness in the moment, childhood memories, and that grin-inducing feeling of getting a reward for being good. --Mariska Hargitay""" # display each line centered in 60 spaces. # first line all uppercase. # last line right justified in 60 spaces. lines = poem.split( "\n" ) #print( lines ) # ----------------------------------------------------------------------- # (remove the triple double-quotes to energize the code section) print( lines[0].upper().center(60) ) for line in lines[1: ]: print( line.center( 60 ) ) # ----------------------------------------------------------------------- print( "-" * 60 ) lines[0] = lines[0].upper() for line in lines[0:3]+lines[4:]: print( line.center(60) )
Another Example
# ------------------------- # Another Example # ------------------------- def printBar(): print( 60 * '-' ) def sayHello(): print( ) print( "Hello, and welcome!" ) print( ) def main(): for i in range( 10 ): printBar() sayHello() printBar() main()
Happy Birthday
# ------------------------------------------ # Sing Happy Birthday to some Minions # ------------------------------------------ def singHappyBirthday( minion ): print( "Happy birthday to you\n" * 2, end="" ) print( "Happy birthday, dear", minion ) print( "Happy birthday to you" ) print() def main(): #singHappyBirthday( "Dave" ) #singHappyBirthday( "Stuart" ) minions = "Dave, Stuart, Jerry, Jorge, Tim, Mark, Phil, Kevin, Jon" minions = minions.split( ", " ) #print( minions ) for minion in minions: singHappyBirthday( minion.strip() ) main()
Mon. 10/5/15
Converting Temperatures
# F = C * 9 / 5 + 32
def convert( c ):
return int( c * 9/5 + 32 )
def main():
for C in [ 0, 32, 100 ] :
fahr = convert( C )
print( fahr )
main()
Transforming dates
def singHappyBirthday( minion ):
print( "minion = ", minion )
#print( "Happy birthday to you\n" * 2, end="" )
#print( "Happy birthday, dear", minion )
#print( "Happy birthday to you" )
#print()
def worker0( ):
return "clap " * 10
def worker1( num1 ):
return num1 * 2 + 1
def worker2( n ):
return n % 10
def worker3( p ):
p = worker1( p )
p = worker2( p )
return p
def dateConvert( date ):
"""converts a date in the form "2 Jan 2010" into
a date of the form 01022010"
"""
# split the string into day, month, and year
fields = date.split()
day = fields[0]
month = fields[1]
year = fields[2]
#print( day, month, year )
# if the day is less than 10, add a 0 in front of it
day = ( '0' + day )[-2: ]
#print( day, month, year )
# find where the month is located in a string of 3-letter
# months. If the string is "Jan", then the location will
# be 0. If the string is "Feb", then the location will be 3,
# etc.
months = "janfebmaraprmayjunjulaugsepoctnovdec"
index = months.find( month.lower() )
# divide by 3 to find the index in the form 0, 1, 2,... 11.
# and add 1 to make this 1, 2,... 12
monthDigit = index//3 + 1
# transform this digit into a string, with a 0 in front
# in case the digit is less than 10.
monthDigit = "{0:02}".format( monthDigit )
#print( day, month, year, monthDigit )
# return the formatted string
return "{0:1}{1:1}{2:1}".format( monthDigit, day, year )
def main():
for date in [ "1 Jan 2010", "2 Mar 1900", "31 Dec 2015" ]:
print( dateConvert( date ) )
main()
- Output:
01012010 03021900 12312015
Fri. 10/9/15
Once More: the Teller Machine program
def getAmount():
amount = eval( input( "Amount? " ) )
return abs( amount )
def breakDown( amount ):
no20s, amount = amount // 20, amount % 20
no10s, amount = amount // 10, amount % 10
no5s, amount = amount // 5, amount % 5
no1s = amount
return no20s, no10s, no5s, no1s
def display(orgAmount, No20s, No10s, No5s, No1s ):
print( orgAmount, No20s, No10s, No5s, No1s )
return
def main():
# get amount from user
amount = getAmount( )
orgAmount = amount # keep value of original amount
# get Number of $20-, $10, $5-, and $1-bills
No20s, No10s, No5s, No1s = breakDown( amount )
# display result
display( orgAmount, No20s, No10s, No5s, No1s )
main()
Flipping DNA
def getSentence( ):
sentence = input( "Enter a list of words: " )
words = sentence.split( )
for i in range( len( words ) ):
#print( "i = ", i, "words = ", words )
#print( "words[i] = ", words[i] )
#print( "words[i].capitalize() = ", words[i].capitalize() )
words[i] = words[i].capitalize()
#print( "i = ", i, "words = ", words )
#print()
return words
def flip( DNA ):
newDNA = DNA.replace( "A", "t" ).replace( "T", "a" )
newDNA = newDNA.replace( "G", 'c' ).replace( "C", 'g' )
return newDNA.upper()
def main():
listWords = getSentence( )
print( "list = ", listWords )
print( "AAACGTTTAG", flip( "AAACGTTTAG" ), sep="\n" )
main()
Wed 10/14/15
dempolls.raw
<html>
<head>
<title>
Democratic Polls
</title>
</head>
<body>
<h1>Results</h1>
<data />
</body>
</html>
dempolls.data
Biden 19.1 Chafee 0.6 Clinton 44.4 Lessig 0.0 O'Malley 1.0 Sanders 25.1 Webb 1.2
createDynamicWebPage.py
# createDynamicWebPage.py # D. Thiebaut # create dynamic Web page import datetime # get a library that will allow # us to print today's date. # getTextFrom(): given a file name, opens the # file, gets its contents as a string, and return # it. def getTextFrom( fileName ): file = open( fileName, "r" ) text = file.read() file.close() return text def main(): # get the raw html file html = getTextFrom( "dempolls.raw" ) # get the raw data file candidates = getTextFrom( "dempolls.data" ) # replace <data /> tag with the data just # read in the raw html file. today = datetime.datetime.today().strftime("%m/%d/%Y") newString = today + "<br />" + candidates html = html.replace( "<data />", newString ) # store new html to file file = open( "dempolls.html", "w" ) file.write( html ) file.close() # tell the user that process is over print( "File dempolls.html created, and in your directory!" ) main()
Wed. 10/21/15
graphicsDemo.py
# graphicsDemo.py # D. thiebaut # A demo program using the graphics library to make a ball # move on the graphic window. from graphics import * from random import * def main(): # open the graphic window win = GraphWin("My Circle", 600, 600) # put some text in the middle of the window label = Text( Point( 300, 300 ), "CSC111 Graphics Demo" ) label.draw( win ) # draw a circle x = 50 y = 50 r = 20 c = Circle( Point( x, y ), r ) red = randint( 0, 255 ) green = randint( 0, 255 ) blue = randint( 0, 255 ) color = color_rgb( red, green, blue ) c.setFill( color ) c.draw( win ) dx = 3 dy = 0 for i in range( 1000 ): # pick random color red = randint( 0, 255 ) green = randint( 0, 255 ) blue = randint( 0, 255 ) color = color_rgb( red, green, blue ) c.setFill( color ) # move c.move( dx, dy ) # see if bounce off walls center = c.getCenter() x = center.getX() if x > 600-r or x < 0+r: dx = -dx #win.getMouse() # move label label.move( 1, -1 ) # wait for user to click in window win.getMouse() # close the window win.close() main()
Mon. 11/2/15
Exception, Version 1
# getInput: returns an integer larger # than 0. Expected to be robust… def getInput(): while True: x = int( input( "Enter a positive int: " ) ) if x >= 0: return x print( "invalid input. Please reenter" ) def main(): num = getInput() print( "you entered", num ) main()
Exception, Version 2
# getInput: returns an integer larger # than 0. Expected to be robust… def getInput(): while True: try: x = int( input( "Enter a positive int: " ) ) except ValueError: print( "Invalid number. Please reenter" ) continue if x >= 0: return x print( "invalid input. Please reenter" ) def main(): num = getInput() print( "you entered", num ) main()
Quadratic Equation with Exceptions
import math def ZelleExample(): print( "solution to quadratic equation" ) try: a, b, c = eval( input( "Enter 3 coefficients (a, b, c): " ) ) disc = math.sqrt( b*b - 4*a*c ) root1 = (-b + disc )/ (2*a) root2 = (-b - disc )/ (2*a) print( "solutions: ", root1, roo2 ) except NameError: print( "You didn't enter 3 numbers!" ) except TypeError: print( "Your input contained invalid numbers" ) except SyntaxError: print( "Forgot a comma between the numbers? " ) except ValueError: print( "No real roots, negative discriminant" ) except: print( "Something went wrong..." ) def main(): ZelleExample() main()
Dice: Definining Classes
# DiceExample.py # D. Thiebaut # our first program where we define a class. # # The class implement a die, with some number # of sides, and a way to "roll" and show a new # number (value) up top. # libraries import random # a class for a die class Die: def __init__( self, n ): self.noSides = n self.value = 1 def roll( self ): self.value = random.randrange( 1, self.noSides+1 ) def getValue( self ): return self.value def main(): # Create 2 dice, one with 6 sides, one with 8 d1 = Die( 6 ) d2 = Die( 8 ) # Roll both dice d1.roll( ) d2.roll( ) # display their value print( "Die 1: ", d1.getValue() ) print( "Die 2: ", d2.getValue() ) main()
A program with a class to implement Cat objects
# cats1.py # D. Thiebaut # Our first built-from scratch program involving # classes and objects. # In this program we read a CSV file containing # the definitions of cats, one cat per line. # We extract the name, vaccinated status, breed, # and age of the cat, and save them in a cat # object. the Cat class is used to define how # a cat object behaves. class Cat: def __init__( self, na, vac, bre, ag ): self.name= na self.vaccinated = vac self.breed = bre self.age = ag def isVaccinated( self ): #if self.vaccinated == True: # return True #else: # return False return self.vaccinated def getName( self ): return self.name def main(): # Minou, 3, vac, stray text = """Minou, 3, vac, stray Max, 1, not-vac, Burmese Gizmo, 2, vac, Bengal Garfield, 4, not-vac, Orange Tabby""" catList = [] for line in text.split( "\n" ): words = line.split( "," ) if words[2].find( "not" ) != -1: vac = False else: vac = True age = int( words[1].strip() ) cat = Cat( words[0], vac, words[3], age ) catList.append( cat ) #cat1 = Cat( "Minou", True, "stray", 3 ) for cat in catList: if cat.isVaccinated(): print( cat.name, "is vaccinated" ) else: print( cat.getName(), "is not vaccinated" ) main()
Cats1.csv File
Max, 1, vaccinated, not tattooed, stray Black, 3, not vaccinated, tattooed, stray Gizmo, 2, vaccinated, not tattooed, Bengal Winston, 2, vaccinated, tattooed, Bengal Garfield, 3, vaccinated, not tattooed, Burmese Bob, 4, not vaccinated, tattooed, Orange Tabby Minou, 1, vaccinated, tattooed, stray Silky, 3, not vaccinated, tattooed, Siamese
Wed. 11/04/15
cats1.py
# cats1.py # D. Thiebaut # Our first built-from scratch program involving # classes and objects. # In this program we read a CSV file containing # the definitions of cats, one cat per line. # We extract the name, vaccinated status, breed, # and age of the cat, and save them in a cat # object. the Cat class is used to define how # a cat object behaves. class Cat: def __init__( self, na, vac, bre, ag ): self.name= na self.vaccinated = vac self.breed = bre self.age = ag def isVaccinated( self ): #if self.vaccinated == True: # return True #else: # return False return self.vaccinated def getBreed( self ): return self.breed def getName( self ): return self.name def __str__( self ): if self.vaccinated == True: vacc = "vaccinated" else: vacc = "not vaccinated" return "{0:1}: {1:1} {2:1} {3:1} yrs old".format( self.name, vacc, self.breed, self.age ) def getCatList( fileName ): """parses a collection of lines and creates a list of cat objects.""" file = open( fileName, "r" ) text = file.read() file.close() catList = [] for line in text.split( "\n" ): words = line.split( "," ) if len( words ) != 4: continue if words[2].find( "not" ) != -1: vac = False else: vac = True age = int( words[1].strip() ) cat = Cat( words[0].strip(), vac, words[3].strip(), age ) catList.append( cat ) return catList def main(): fileName = input( "File name? " ) catList = getCatList( fileName ) for cat in catList: print( cat ) for cat in catList: if not cat.isVaccinated() and cat.getBreed()=="stray": print( cat ) return main()
cats2.csv
Minou, 3, vac, stray Max, 1, not-vac, Burmese Gizmo, 2, vac, Bengal Garfield, 4, not-vac, Orange Tabby Smudges, 10, not-vac, stray Minique, 5, vac, French Tabby
Fri. 11/06/15
Wheel1.py
The beginning of a car...
# Graphics with Objects. # Demo program illustrating how we are going to # build a car. # from graphics import * #define global geometry of window WIDTH = 800 HEIGHT = 600 def main(): global WIDTH, HEIGHT win = GraphWin( "Wheel Demo", WIDTH, HEIGHT ) c1 = Circle( Point( WIDTH//2, HEIGHT//2 ), 30 ) c1.draw( win ) win.getMouse() win.close() main()
Car1.py
# Graphics with Objects. # Demo program illustrating how we are going to # build a car. # from graphics import * #define global geometry of window WIDTH = 800 HEIGHT = 600 class Wheel: def __init__( self, center, radius ): self.c1 = Circle( center, radius ) self.c2 = Circle( center, radius//2 ) self.c1.setFill( "black" ) self.c2.setFill( "white" ) def draw( self, win ): self.c1.draw( win ) self.c2.draw( win ) def move( self, dx, dy ): self.c1.move( dx, dy ) self.c2.move( dx, dy ) class Car: def __init__( self, refPoint ): x1 = refPoint.getX() y1 = refPoint.getY() x2 = x1 + 180 y2 = y1 + 60 self.body = Rectangle( Point( x1 , y1 ), Point( x2 , y2 ) ) self.w1 = Wheel( Point( x1+40, y1+60 ), 20 ) self.w2 = Wheel( Point( x1+140, y1+60 ), 20 ) self.body.setFill( "yellow" ) def draw( self, win ): self.body.draw( win ) self.w1.draw( win ) self.w2.draw( win ) def move( self, dx, dy ): self.body.move( dx, dy ) self.w1.move( dx, dy ) self.w2.move( dx, dy ) def main(): """Open a graphic window and puts graphic object(s) on it. Wait for user to click mouse to close. """ global WIDTH, HEIGHT # open window win = GraphWin( "Wheel Demo", WIDTH, HEIGHT ) # Create a list of 10 cars cars = [] # empty list for i in range( 10 ): # create a new car c1 = Car( Point( i*10, i*90 ) ) # draw the car just created c1.draw( win ) # add car just created to the list cars.append( c1 ) dx = 3 # x-direction for movement of cars dy = 0 # y-direction for movement of cars # animation loop while True: # move all the cars in the list for c1 in cars: c1.move( dx, dy ) # if user clicks the mouse, change the # direction of movement. if win.checkMouse() != None: dx = -dx # wait for user to click the mouse to close window win.getMouse() win.close() main()
Mon. 11/9/15
Images to Play With
catGlasses.gif
imageProcessing.py
# imageProcessingSkel.py # D. Thiebaut # A skeleton program to start doing image processing # in Python from graphics import * # image geometry = 424x18 # make the window the same geometry WIDTH = 424 HEIGHT = 418 def main(): # open the window win = GraphWin( "CSC111 Image Viewer", WIDTH, HEIGHT ) # get the file name from the user fileName = "catGlasses.gif" #input( "Image name? " ) print() # open the cat image cat = Image( Point(WIDTH//2, HEIGHT//2), fileName ) cat.draw( win ) # wait for user to click the mouse... win.getMouse() # and close the window win.close() main()
pixelProcessing.py
# pixelProcessingSkel.py # D. Thiebaut # Simple skeleton program for processing # the pixels of an image from graphics import * WIDTH = 424 HEIGHT = 418 IMAGEFILENAME = "catGlasses.gif" def makeRed( img, win ): """ set the red component of all the pixels to 255, the maximum value. """ global WIDTH, HEIGHT for y in range( HEIGHT ): win.update() # refresh the window after each inner loop for x in range( WIDTH ): red, green, blue = img.getPixel( x, y ) green, blue, red = red, green, blue red = 255 img.setPixel( x, y, color_rgb(red, green, blue ) ) def main(): win = GraphWin( "CSC111 Image Viewer", WIDTH, HEIGHT ) img = Image( Point(WIDTH//2, HEIGHT//2), IMAGEFILENAME ) img.draw( win ) makeRed( img, win ) win.getMouse() win.close() main()
Wed. 11/11/15
chessboard0.py
# chessboard0,py # D. Thiebaut # Displays an 8x8 chessboard. from graphics import * WIDTH = 600 HEIGHT = 600 def displayBoard( win ): """display an 8x8 chessboard in the square window defined by WIDTH and HEIGHT""" global WIDTH, HEIGHT # compute size of square side = WIDTH//8 # display 8 columns and 8 rows of squares for i in range( 0, 8 ): for j in range( 0, 8 ): # create a rectangle r = Rectangle( Point( i*side, j*side ), Point( i*side+side, j*side+side ) ) # figure out if it should be black or white if (i+j) % 2 != 0: r.setFill( "grey" ) else: r.setFill( "white" ) # draw it r.draw( win ) def main(): global WIDTH, HEIGHT # open a graphics window. win = GraphWin( "Chessboard", WIDTH, HEIGHT ) # display the board. displayBoard( win ) # wait for use to click window, and close up. win.getMouse() win.close() main()
Gifs for the game of Checkers
- piece.gif
- piece2.gif
Interactive Checkers
# Interactive game of checkers. # This program creates an 8x8 board, with # alternating white and dark cells. It then positions # 3 rows of white pieces, and 3 rows of black pieces at # the top and bottom of the board, respectively. # It then allows the user to click on various pieces to make them # disappear. from graphics import * WIDTH = 600 HEIGHT = 600 class CheckersPiece: """ a class defining a checkers piece. It uses gif images for each piece.""" def __init__(self, color, i, j ): global WIDTH, HEIGHT side = WIDTH // 8 x = i * side y = j * side centerPoint = Point( x+side//2, y+side//2 ) if color=="white": self.img = Image( centerPoint, "piece2.gif" ) else: self.img = Image( centerPoint, "piece.gif" ) def draw( self, win ): self.img.draw( win ) def undraw( self ): self.img.undraw() def getCoords( self ): global WIDTH, HEIGHT side = WIDTH // 8 x = self.img.getAnchor().getX() y = self.img.getAnchor().getY() return x-side//2, y-side//2, x+side//2, y+side//2 def isWhite( i, j ): if (i+j)%2==0: return True return False def displayBoard( win ): """this function displays the 8x8 board, with alternating colors.""" global WIDTH, HEIGHT side = WIDTH//8 for i in range( 0, 8 ): for j in range( 0, 8 ): r = Rectangle( Point( i*side, j*side ), Point( i*side+side, j*side+side ) ) if not isWhite( i, j ): r.setFill( "grey" ) else: r.setFill( "white" ) r.draw( win ) def createDisplayPieces( win ): """create 3 rows of white pieces at the top, and 3 rows of black pieces at the bottom. Put them only on dark squares.""" whites = [] blacks = [] for i in range( 8 ): for j in range( 3 ): if isWhite( i, j ): continue c = CheckersPiece( "white", i, j ) c.draw( win ) whites.append( c ) for j in range( 5, 8 ): if isWhite( i, j ): continue c = CheckersPiece( "black", i, j ) c.draw( win ) blacks.append( c ) return whites, blacks def findClickedPiece( p, whites, blacks ): """loop through all the pieces and see if the point that the user clicked (p) is inside the square that corresponds to where the piece is.""" for c in whites + blacks: x1, y1, x2, y2 = c.getCoords() if x1 <= p.getX() <= x2 and y1 <= p.getY() <= y2: return c return None def main(): global WIDTH, HEIGHT win = GraphWin( "Chessboard", WIDTH, HEIGHT ) displayBoard( win ) whites, blacks = createDisplayPieces( win ) # animation loop while True: p = win.getMouse() c = findClickedPiece( p, whites, blacks ) if c != None: c.undraw( ) win.getMouse() win.close() main()
Mon, 11/16/15
Button Demo
# buttonDemo.py # D. Thiebaut from graphics import * WIDTH = 600 HEIGHT = 600 class Button: """Implements a button, which contains a label (text), is rectangular (frame), and can be clicked (True) or not clicked.""" def __init__(self, x1, y1, w, h, text ): """constructor: pass (x,y) of top left corner, and width and height. Pass the text displayed in button.""" p1 = Point( x1, y1 ) p2 = Point( x1+w, y1+h ) self.frame = Rectangle( p1, p2 ) self.frame.setFill( "white" ) self.label = Text(Point( x1+w//2, y1+h//2 ), text ) self.clicked = False def draw( self, win ): """display button on window.""" self.frame.draw( win ) self.label.draw( win ) def isClicked( self, p ): """Checks if p is inside the frame of the button. Returns True if p inside frame, False otherwise. If p inside, button changes state and color.""" x1, y1 = self.frame.getP1().getX(), self.frame.getP1().getY() x2, y2 = self.frame.getP2().getX(), self.frame.getP2().getY() if x1 <= p.getX() <= x2 and y1 <= p.getY() <= y2: self.clicked = not self.clicked if self.clicked: self.frame.setFill( "yellow" ) else: self.frame.setFill( "white" ) return True else: return False def main(): global WIDTH, HEIGHT win = GraphWin( "Pushbutton Demo", WIDTH, HEIGHT ) button1 = Button( 10, 10, 60, 30, "OK" ) button1.draw( win ) while True: clickPoint = win.getMouse() if button1.isClicked( clickPoint ): print( "button clicked!" ) win.close() main()
Random Circles Demo
# randomDotDemo.py # D. Thiebaut from graphics import * from random import * WIDTH = 600 HEIGHT = 600 class Button: """Implements a button, which contains a label (text), is rectangular (frame), and can be clicked (True) or not clicked.""" def __init__(self, x1, y1, w, h, text ): """constructor: pass (x,y) of top left corner, and width and height. Pass the text displayed in button.""" p1 = Point( x1, y1 ) p2 = Point( x1+w, y1+h ) self.frame = Rectangle( p1, p2 ) self.frame.setFill( "white" ) self.label = Text(Point( x1+w//2, y1+h//2 ), text ) self.clicked = False def draw( self, win ): """display button on window.""" self.frame.draw( win ) self.label.draw( win ) def undraw( self ): self.frame.undraw( ) self.label.undraw( ) def isClicked( self, p ): """Checks if p is inside the frame of the button. Returns True if p inside frame, False otherwise. If p inside, button changes state and color.""" x1, y1 = self.frame.getP1().getX(), self.frame.getP1().getY() x2, y2 = self.frame.getP2().getX(), self.frame.getP2().getY() if x1 <= p.getX() <= x2 and y1 <= p.getY() <= y2: self.clicked = not self.clicked if self.clicked: self.frame.setFill( "yellow" ) else: self.frame.setFill( "white" ) return True else: return False def addDot( win ): x = randint( 100, 500 ) y = randint( 100, 500 ) center = Point( x, y ) radius = randint( 10, 600 ) c = Circle( center, radius ) r = randint( 0, 255 ) g = randint( 0, 255 ) b = randint( 0, 255 ) c.setFill( color_rgb( r, g, b ) ) c.draw( win ) def main(): global WIDTH, HEIGHT win = GraphWin( "Pushbutton Demo", WIDTH, HEIGHT ) # create UI OkButton = Button( 10, 10, 60, 30, "Ok" ) OkButton.draw( win ) quitButton = Button( 80, 10, 60, 30, "Quit" ) quitButton.draw( win ) addDotButton = Button( 150, 10, 60, 30, "Add Dot" ) addDotButton.draw( win ) # animation loop while True: clickedPoint = win.getMouse() if quitButton.isClicked( clickedPoint ): break if OkButton.isClicked( clickedPoint ): print( "button clicked!" ) continue if addDotButton.isClicked( clickedPoint ): addDot( win ) # redraw the buttons, just in case a circle covers them. OkButton.undraw() OkButton.draw( win ) quitButton.undraw() quitButton.draw( win ) addDotButton.undraw() addDotButton.draw( win ) # go back to top of loop and wait for another click from user... continue # if we're here, it's because user # clicked on window, but not on buttons print( "clicked on window" ) win.close() main()
Polygon Demo
# buttonDemo.py # polygon demo. A triangle # and a start are drawn # D. Thiebaut from graphics import * from random import * WIDTH = 300 HEIGHT = 300 def main(): global WIDTH, HEIGHT win = GraphWin( "Pushbutton Demo", WIDTH, HEIGHT ) # draw a triangle points = [ Point( 100, 100 ), Point( 150, 100 ), Point( 175, 150 ) ] poly1 = Polygon( points ) poly1.setFill( "orange" ) poly1.draw( win ) # draw a star points = [ Point( 35, 120 ), Point( 37.9,129.1), Point( 46.9,129.1), Point( 39.7,134.5), Point( 42.3, 143.1 ), Point( 35, 139 ), Point( 27.7, 143.1 ), Point( 30.3, 134.5 ), Point( 23.1, 129.1 ), Point( 32.1, 129.1 ) ] poly2 = Polygon( points ) poly2.setFill( "lightgreen" ) poly2.draw( win ) # wait for user to click mouse to close window win.getMouse() win.close() main()
Create Polygon With Mouse Demo: Skeleton Program
# recordShapeIntoPolygon.py # D. Thiebaut # Brings up a gif image in the window # and creates 2 buttons. # User can click on buttons to 1) start # Recording a shape, and 2) stop recording # it and displaying it as light-blue polygon. # WARNING: the program, as is, is not safe and will crash # if the user start the program and clicks on a point that is not # inside a button... The problem is with pointList... from graphics import * WIDTH = 400 HEIGHT = 400 class Button: """Implements a button, which contains a label (text), is rectangular (frame), and can be clicked (True) or not clicked.""" def __init__(self, x1, y1, w, h, text ): """constructor: pass (x,y) of top left corner, and width and height. Pass the text displayed in button.""" p1 = Point( x1, y1 ) p2 = Point( x1+w, y1+h ) self.frame = Rectangle( p1, p2 ) self.frame.setFill( "white" ) self.label = Text(Point( x1+w//2, y1+h//2 ), text ) self.clicked = False def draw( self, win ): """display button on window.""" self.frame.draw( win ) self.label.draw( win ) def isClicked( self, p ): """Checks if p is inside the frame of the button. Returns True if p inside frame, False otherwise. If p inside, button changes state and color.""" x1, y1 = self.frame.getP1().getX(), self.frame.getP1().getY() x2, y2 = self.frame.getP2().getX(), self.frame.getP2().getY() if x1 <= p.getX() <= x2 and y1 <= p.getY() <= y2: self.clicked = not self.clicked if self.clicked: self.frame.setFill( "yellow" ) else: self.frame.setFill( "white" ) return True else: return False def main(): global WIDTH, HEIGHT # create a graphic window win = GraphWin( "Record Polygon", WIDTH, HEIGHT ) # put a logo of Smith in the middle of the window img = Image( Point(WIDTH//2, HEIGHT//2), "smithLogo.gif" ) img.draw( win ) # create 2 buttons startB = Button( 10, 10, 60, 30, "Start" ) startB.draw( win ) stopB = Button( 80, 10, 60, 30, "Stop" ) stopB.draw( win ) # animation loop while True: clickedPoint = win.getMouse() # quit? if exitB.isClicked( clickedPoint ): break # start recording polygon? if startB.isClicked( clickedPoint ): pointList = [] continue # stop recording polygon? if stopB.isClicked( clickedPoint): poly = Polygon( pointList ) poly.setFill( "cyan" ) poly.draw( win ) continue # if we're here, it's because # the user clicked somewhere outside # the buttons pointList.append( clickedPoint ) win.getMouse() win.close() main()
Wed. 11/18/15
SavePolyToFile.py
# recordShapeIntoPolygon.py # D. Thiebaut # Brings up a gif image in the window # and creates 2 buttons. # User can click on buttons to 1) start # Recording a shape, and 2) stop recording # it and displaying it as light-blue polygon. from graphics import * WIDTH = 400 HEIGHT = 400 CSVFILE = "map.csv" class Button: """Implements a button, which contains a label (text), is rectangular (frame), and can be clicked (True) or not clicked.""" def __init__(self, x1, y1, w, h, text ): """constructor: pass (x,y) of top left corner, and width and height. Pass the text displayed in button.""" p1 = Point( x1, y1 ) p2 = Point( x1+w, y1+h ) self.frame = Rectangle( p1, p2 ) self.frame.setFill( "white" ) self.label = Text(Point( x1+w//2, y1+h//2 ), text ) self.clicked = False def draw( self, win ): """display button on window.""" self.frame.draw( win ) self.label.draw( win ) def isClicked( self, p ): """Checks if p is inside the frame of the button. Returns True if p inside frame, False otherwise. If p inside, button changes state and color.""" x1, y1 = self.frame.getP1().getX(), self.frame.getP1().getY() x2, y2 = self.frame.getP2().getX(), self.frame.getP2().getY() if x1 <= p.getX() <= x2 and y1 <= p.getY() <= y2: self.clicked = not self.clicked if self.clicked: self.frame.setFill( "yellow" ) else: self.frame.setFill( "white" ) return True else: return False def savePolyToFile( pointList, fileName ): file = open( fileName, "a" ) L = [] for point in pointList: x = point.getX() y = point.getY() #print( x, y ) L.append( str( x ) ) # "{0:1}".format( x ) L.append( str( y ) ) #print( ", ".join( L ) ) file.write( ", ".join( L ) ) file.close() def main(): global WIDTH, HEIGHT, CSVFILE # create a graphic window win = GraphWin( "Record Polygon", WIDTH, HEIGHT ) # put a logo of Smith in the middle of the window img = Image( Point(WIDTH//2, HEIGHT//2), "smithLogo.gif" ) img.draw( win ) # create 2 buttons startB = Button( 10, 10, 60, 30, "Start" ) startB.draw( win ) stopB = Button( 80, 10, 60, 30, "Stop" ) stopB.draw( win ) exitB = Button( 150, 10, 60, 30, "Quit" ) exitB.draw( win ) # create empty list of points pointList = [] # animation loop while True: clickedPoint = win.getMouse() # quit? if exitB.isClicked( clickedPoint ): break # start recording polygon? if startB.isClicked( clickedPoint ): pointList = [] continue # stop recording polygon? if stopB.isClicked( clickedPoint): poly = Polygon( pointList ) poly.setFill( "cyan" ) poly.draw( win ) savePolyToFile( pointList, CSVFILE ) continue # if we're here, it's because # the user clicked somewhere outside # the buttons pointList.append( clickedPoint ) win.getMouse() win.close() main()
Different Button Class
class Button: """Implements a button, which contains a label (text), is rectangular (frame), and can be clicked (True) or not clicked.""" def __init__(self, x1, y1, w, h, text ): """constructor: pass (x,y) of top left corner, and width and height. Pass the text displayed in button.""" p1 = Point( x1, y1 ) p2 = Point( x1+w, y1+h ) self.frame = Rectangle( p1, p2 ) self.frame.setFill( "white" ) self.label = Text(Point( x1+w//2, y1+h//2 ), text ) self.clicked = False def draw( self, win ): """display button on window.""" self.frame.draw( win ) self.label.draw( win ) def isClicked( self, p ): """Checks if p is inside the frame of the button. Returns True if p inside frame, False otherwise. If p inside, button changes state and color.""" x1, y1 = self.frame.getP1().getX(), self.frame.getP1().getY() x2, y2 = self.frame.getP2().getX(), self.frame.getP2().getY() if x1 <= p.getX() <= x2 and y1 <= p.getY() <= y2: self.clicked = not self.clicked # toggle #if self.clicked: # self.frame.setFill( "yellow" ) #else: # self.frame.setFill( "white" ) self.frame.setFill( "red" ) sleep( 0.1 ) # 0.1 sec self.frame.setFill( "white" ) return True else: return False
Fri. 11/20/15
Merge 2 Lists
# merging.py # D. Thiebaut # given 2 lists (in the form of stings), one a list # of Disney characters, one a fictitious list of # characters and their phone number, merge the # two lists and print the name of the Disney characters # and the area code they live in. # master list master = """Mickey Mouse, Mickey Mouse Clubhouse Pluto, The Chain Gang Minnie Mouse, Plane Crazy Donald Duck, The Wise Little Hen bambi, bambi Pluto The Chain Gang """ # secondary list phones = """Sue Green, (413) 585 1122, single Alex Marquis, (617) 512 1234, married Bambi, single Mickey Mouse, (212) 123 5598, married Pluto, (212) 123 5598, single Minnie Mouse, (212) 123 5598, married Donald Duck, (617) 525 1212, single Bambi, (209) 713 1139, single """ def findPhone( name ): """given name, a stripped name of a Disney character, locate line in phone list, and return line that contains phone associated with name. """ # split the string into lines phoneList = phones.split( "\n" ) # look at each line and see if we find the # character with the given name for line in phoneList: # is it valid? Does it contain commas? if len( line.split( "," ) ) != 3: # no continue # if we're here, we know the phone line is valid # make it lower case, and see if our name is included in it if line.lower().find( name ) != -1: # look for the position of the left parenthesis index = line.find( "(" ) # return a slice of the string, containing the 3 area code digits return line[index+1:index+4] # if we didn't find the name in any of the lines, # return None, indicating "not found" return None def main(): # split the master list into lines disneyList = master.split( "\n" ) # for each line in the master list... for character in disneyList: # clean up the line character = character.strip() # if not a blank line, process it if len( character ) > 1: # get rid of lines not containing commas fields = character.split(",") if len( fields ) <= 1: continue # get the name name = fields[0].lower().strip() # look in secondary list, and fine # the line associated with name phoneLine = findPhone( name ) # if we found a phone number, list it, otherwise # skip that Disney character... if phoneLine != None: print( name.title(), phoneLine ) main()
ColorOf
def colorOf( year ): # assume year is an int if year <= 1799: return 215, 97, 1 # if we're here... year is # above 1800 elif year <= 1899: return 241, 163, 64 elif year <= 1999: return 253, 184, 99 else: return 254, 224, 144
Aquarium Skeleton Program
# Aquarium.py # D. Thiebaut # A program with fish swimming in an aquarium # Two buttons control the creation of new fish, and how to # quit the program. from graphics import * from time import sleep from random import * # Global variables WIDTH = 700 HEIGHT = 517 AQUARIUM = "Tank2.gif" FISH = "Fish10.gif" class Button: """Implements a button, which contains a label (text), is rectangular (frame), and can be clicked (True) or not clicked.""" def __init__(self, x1, y1, w, h, text ): """constructor: pass (x,y) of top left corner, and width and height. Pass the text displayed in button.""" p1 = Point( x1, y1 ) p2 = Point( x1+w, y1+h ) self.frame = Rectangle( p1, p2 ) self.frame.setFill( "white" ) self.label = Text(Point( x1+w//2, y1+h//2 ), text ) self.clicked = False def draw( self, win ): """display button on window.""" self.frame.draw( win ) self.label.draw( win ) def isClicked( self, p ): """Checks if p is inside the frame of the button. Returns True if p inside frame, False otherwise. If p inside, button changes state and color.""" x1, y1 = self.frame.getP1().getX(), self.frame.getP1().getY() x2, y2 = self.frame.getP2().getX(), self.frame.getP2().getY() if x1 <= p.getX() <= x2 and y1 <= p.getY() <= y2: self.clicked = not self.clicked self.frame.setFill( "red" ) sleep(0.1) self.frame.setFill( "white" ) return True else: return False class Fish: """A class for a fish, which is an image """ def __init__( self, p ): self.img = Image( p, FISH ) def draw( self, win ): self.img.draw( win ) def autoMove( self ): """makes the fish move. If the fish disappears from the right, it automatically reappears on the left.""" dy = randint( -3, 3 ) # random vertical drift dx = randint( 0, 3 ) # random move forward self.img.move( dx, dy ) # has it disappeared on the right? x = self.img.getAnchor().getX() if x > WIDTH + 50: # yes, move it to the left of the aquarium self.img.move( -WIDTH-50, 0 ) #--------------------------------------------------------------- # Functions #--------------------------------------------------------------- def main(): """The main interactive function. Declare the graphic window, populate it with a map and 2 buttons, and allows the user to enter different polygons.""" global WIDTH, HEIGHT, AQUARIUM # create graphic window. make it the size of the map. win = GraphWin( "Aquarium", WIDTH, HEIGHT ) # display background image map = Image( Point( WIDTH//2, HEIGHT//2 ), AQUARIUM ) map.draw( win ) # create 2 buttons to start recording and record points to # csv addFish = Button( 10, 10, 60, 30, "Add Fish" ) addFish.draw( win ) quitButton = Button( 80, 10, 60, 30, "Quit" ) quitButton.draw( win ) fishList = [] # animation loop while True: # has user clicked on a point? clickedPoint = win.checkMouse() # yes, mouse clicked. if clickedPoint != None and quitButton.isClicked( clickedPoint ): break # was it on add-fish button? if clickedPoint != None and addFish.isClicked( clickedPoint ): clickedPoint = win.getMouse() fish = Fish( clickedPoint ) fish.draw( win ) fishList.append( fish ) continue for fish in fishList: fish.autoMove() # We currently will not reach this point, as there is # no way to escape the while loop. A good idear would be # to add an exit button. win.close() main()
Aquarium.py (Fully functional)
# Aquarium.py # D. Thiebaut # A program with fish swimming in an aquarium # Two buttons control the creation of new fish, and how to # quit the program. from graphics import * from time import sleep from random import * # Global variables WIDTH = 700 HEIGHT = 517 AQUARIUM = "Tank.gif" FISH = "Fish10.gif" class Button: """Implements a button, which contains a label (text), is rectangular (frame), and can be clicked (True) or not clicked.""" def __init__(self, x1, y1, w, h, text ): """constructor: pass (x,y) of top left corner, and width and height. Pass the text displayed in button.""" p1 = Point( x1, y1 ) p2 = Point( x1+w, y1+h ) self.frame = Rectangle( p1, p2 ) self.frame.setFill( "white" ) self.label = Text(Point( x1+w//2, y1+h//2 ), text ) self.clicked = False def draw( self, win ): """display button on window.""" self.frame.draw( win ) self.label.draw( win ) def isClicked( self, p ): """Checks if p is inside the frame of the button. Returns True if p inside frame, False otherwise. If p inside, button changes state and color.""" x1, y1 = self.frame.getP1().getX(), self.frame.getP1().getY() x2, y2 = self.frame.getP2().getX(), self.frame.getP2().getY() if x1 <= p.getX() <= x2 and y1 <= p.getY() <= y2: self.clicked = not self.clicked self.frame.setFill( "red" ) sleep(0.1) self.frame.setFill( "white" ) return True else: return False class Fish: """A class for a fish, which is an image """ def __init__( self, p ): self.img = Image( p, FISH ) def draw( self, win ): self.img.draw( win ) def autoMove( self ): """makes the fish move. If the fish disappears from the right, it automatically reappears on the left.""" dy = randint( -3, 3 ) # random vertical drift dx = randint( 0, 3 ) # random move forward self.img.move( dx, dy ) # has it disappeared on the right? x = self.img.getAnchor().getX() if x > WIDTH + 50: # yes, move it to the left of the aquarium self.img.move( -WIDTH-50, 0 ) #--------------------------------------------------------------- # Functions #--------------------------------------------------------------- def main(): """The main interactive function. Declare the graphic window, populate it with a map and 2 buttons, and allows the user to enter different polygons.""" global WIDTH, HEIGHT, AQUARIUM # create graphic window. make it the size of the map. win = GraphWin( "Aquarium", WIDTH, HEIGHT ) # display background image map = Image( Point( WIDTH//2, HEIGHT//2 ), AQUARIUM ) map.draw( win ) # create 2 buttons to start recording and record points to # csv addFish = Button( 10, 10, 60, 30, "Add Fish" ) addFish.draw( win ) quitButton = Button( 80, 10, 60, 30, "Quit" ) quitButton.draw( win ) fishList = [] # animation loop while True: # has user clicked on a point? clickedPoint = win.checkMouse() # yes, mouse clicked. if clickedPoint != None and quitButton.isClicked( clickedPoint ): break # was it on add-fish button? if clickedPoint != None and addFish.isClicked( clickedPoint ): clickedPoint = win.getMouse() fish = Fish( clickedPoint ) fish.draw( win ) fishList.append( fish ) continue for fish in fishList: fish.autoMove() # We currently will not reach this point, as there is # no way to escape the while loop. A good idear would be # to add an exit button. win.close() main()
Mon. 11/23/15
CountUniqueDogsWithLists.py
# countingUniqueDogsWithList.py # D. Thiebaut # Use a list to figure out how many unique # dogs are in the text variable. # a text string with many dogs. Some are repeats. text = """Fido 0 Fido 10 Rex 0 Milou 9 Ralph 3 Fido 8 """ # MAIN: def main(): dogsFound = [] # look at each line of text for line in text.split( "\n" ): # split the line on white space fields = line.capitalize().strip().split() # if invalid, skip if len( fields ) != 2: continue # get dog name name = fields[0] # have we seen it yet? if not name in dogsFound: dogsFound.append( name ) print( "We have found", len( dogsFound ), "dog(s)" ) print( "The dogs found are", ", ".join( dogsFound ) ) main()
CountingDogsWithDictionary.py
# countingUniqueDogsWithDictionary.py # D. Thiebaut # Demonstration program of the use of a dictionary # to keep track of unique elements found in a collection # of lines. # the list of dogs, and some value associated with each one. text = """Fido 0 Fido 10 Rex 0 Milou 9 Ralph 3 Fido 8 """ def main(): # create an empty dictionary dogsFound = {} # look at each line of text for line in text.split( "\n" ): # split the line on white space fields = line.capitalize().strip().split() # if invalid, skip if len( fields ) != 2: continue # get dog name name = fields[0] age = int( fields[1] ) # have we seen it yet? dogsFound[ name ] = age print( "We have found", len( dogsFound ), "dog(s)" ) print( "The dogs found are:" ) for name in dogsFound.keys(): print( name, dogsFound[ name ] ) main()
Keeping track of the first, last, and dogs with largest key found
# countingUniqueDogsWithDictionary.py # D. Thiebaut # Demonstration program of the use of a dictionary # to keep track of unique elements found in a collection # of lines. # the list of dogs, and some value associated with each one. text = """Fido 0 Fido 10 Rex 0 Milou 9 Ralph 3 Fido 8 """ def main(): dogsFoundFirst = {} dogsFoundLast = {} dogsFoundLargest = {} # look at each line of text for line in text.split( "\n" ): # split the line on white space fields = line.capitalize().strip().split() # if invalid, skip if len( fields ) != 2: continue # get dog name name = fields[0] age = int( fields[1] ) # Keep the first dog we see if not name in dogsFoundFirst.keys(): dogsFoundFirst[ name ] = age # Keep the last dog we see dogsFoundLast[ name ] = age # Keep the dog with the largest associated value if not name in dogsFoundLargest.keys(): dogsFoundLargest[ name ] = age else: # is the new dog found with an age larger than # what we have recorded so far, for this dog? if dogsFoundLargest[ name ] < age: # no, update and keep the new larger age dogsFoundLargest[ name ] = age print( "We have found", len( dogsFoundFirst ), "unique dog(s)" ) print( "The first dogs found are:" ) for name in dogsFoundFirst.keys(): print( " -", name, dogsFoundFirst[ name ] ) print( "\nThe last dogs found are:" ) for name in dogsFoundLast.keys(): print( " -", name, dogsFoundLast[ name ] ) print( "\nThe dogs with the largest age found are:" ) for name in dogsFoundLargest.keys(): print( " -", name, dogsFoundLargest[ name ] ) main()
Nov. 30, 2015
Cambridge.data
- You can get the data from this URL: http://cs.smith.edu/~dthiebaut/UKTemperatures/cambridgedata.txt
Email Addresses
- These are fake addresses of students registered for different classes. The goal is to create a list of unique addresses for Smith students present in the list, as well as unique addresses for 5-College students.
Ammie@hampshire.edu Bessie@smith.edu Carylon@smith.edu Cheryll@smith.edu Cordelia@smith.edu Illa@smith.edu Lisbeth@smith.edu Mackenzie@smith.edu Maryellen@smith.edu Matha@smith.edu Patrica@hampshire.edu Sanjuana@smith.edu Sharie@smith.edu Sonya@smith.edu Yuko@smith.edu Cheryll@smith.edu Codi@smith.edu Cordelia@smith.edu Elenore@smith.edu Emelia@smith.edu Josie@smith.edu Lina@smith.edu Lisbeth@smith.edu Mackenzie@smith.edu Margaretta@smith.edu Rosalina@smith.edu Sade@smith.edu Sanjuana@smith.edu Shelli@smith.edu Sonya@smith.edu Aja@hampshire.edu Alesia@hampshire.edu Bessie@smith.edu Carylon@smith.edu Chun@smith.edu Codi@smith.edu Constance@smith.edu Felisa@smith.edu Illa@smith.edu Karena@hampshire.edu Kortney@hampshire.edu Lina@smith.edu Mallie@smith.edu Patrica@hampshire.edu Zofia@smith.edu Anna@hampshire.edu Bessie@smith.edu Candyce@smith.edu Clorinda@smith.edu Elenore@smith.edu Karine@hampshire.edu Kaylee@hampshire.edu Kortney@hampshire.edu Lisbeth@smith.edu Marline@smith.edu Matha@smith.edu Porsha@hampshire.edu Renata@smith.edu Sanjuana@smith.edu Sonya@smith.edu Ammie@hampshire.edu Anna@hampshire.edu Birdie@smith.edu Codi@smith.edu Constance@smith.edu Edelmira@smith.edu Kaylee@hampshire.edu Kristel@hampshire.edu Margaretta@smith.edu Moira@smith.edu Patrica@hampshire.edu Phuong@hampshire.edu Sade@smith.edu Tamela@smith.edu Yuko@smith.edu
Presidents.txt
- The content of the file with all the presidents, up to G. W. Bush, can be found here.
rainyCambridge.py
# rainyCambridge.py # D. Thiebaut # This program finds the rainiest month and year # in Cambridge, UK. The file is fetched from a # Web site (http://cs.smith.edu/~dthiebaut/UKTemperatures/) # where several text files are stored, including one # for Cambridge, called cambridgedata.txt. # Information on how to retrieve URLs found at # https://docs.python.org/3.0/library/urllib.request.html # and http://stackoverflow.com/questions/606191/convert-bytes-to-a-python-string i import urllib.request # library for accessing Web pages #--- some constants used by the program --- BASEURL = "http://cs.smith.edu/~dthiebaut/UKTemperatures/" def getTemperatureData( fileName ): # fetches the file from the Website and returns it as # a long string. # format of the file, with a sample of the lines: """Cambridge NIAB Location: 5435E 2606N, 26 metres amsl Estimated data is marked with a * after the value. Missing data (more than 2 days missing in month) is marked by ---. Sunshine data taken from an automatic Kipp & Zonen sensor marked with a #, otherwise sunshine data taken from a Campbell Stokes recorder. yyyy mm tmax tmin af rain sun degC degC days mm hours 1959 1 4.4 -1.4 20 --- 78.1 1961 1 6.2 1.0 5 55.9 50.5 1961 2 10.3 4.3 0 50.4 65.9 2011 7 21.2 10.9 0 38.4* --- 2015 1 8.0 1.3 12 48.4* --- Provisional """ url = BASEURL + fileName print( "Retrieving data from", url ) f = urllib.request.urlopen( url ) data = f.read().decode("utf-8") return data def main(): # get the string data = getTemperatureData( "cambridgedata.txt" ) # split string into lines lines = data.split( "\n" ) # create empty list L = [] # loop through all the lines for line in lines: # strip extra space and remove the * characters line = line.strip().replace( '*', ' ' ) # get rid of blank lines if len( line ) <= 1: continue # get preamble if not line[0] in ['1', '2']: continue # extract rain, year, month fields = line.split( ) year = fields[0] month = fields[1] rain = fields[5] # it is possible that the rain data is a string # of the form "---", in which case taking the float # equivalent will result in an exception. We catch this # exception with a try/except clause. try: tuple = ( float( rain ), month, year ) except ValueError: continue # if we're here, the rain data is correct. Put it as # the first item in a tuple, and record the tuple in a # list. L.append( tuple ) # sort the list and reverse it L.sort() L.reverse() # display rainiest month/year rain, month, year = L[0] print( "rain = ", rain, "year = ", year, "month = ", month ) main()
processEmails.py
# processEmail.py # D. Thiebaut # Takes a list containing several (fake) email addresses and # splits them into two lists of unique addresses, one for Smith # and one for 5-college students. emails = """Ammie@hampshire.edu Bessie@smith.edu Carylon@smith.edu Bessie@smith.edu Ammie@hampshire.edu """ def main(): # create an empty list for Smith, and # an empty list for 5-col smith = [] fiveCol = [] # process each line and add to appropriate # list. for line in emails.split( "\n" ): line = line.strip() if len( line ) <= 1: continue if line.find( "@smith" ) != -1: if not line in smith: smith.append( line ) else: if not line in fiveCol: fiveCol.append( line ) print( "Smith = ", smith ) print( "5-col = ", fiveCol ) main()
Presidents.py
# presidents.py # D. Thiebaut text = """ copy paste the list of presidents here... """ def main(): # split into individual lines lines = text.split( "\n" ) # display header print( lines[0] ) # process all but first line for line in lines[1:]: fields = line.split( "," ) # remove Fields 2, 6, and 7 fields = fields[0:2] + fields[3:6] + fields[8:] # display the newly formed lines print( ", ".join( fields ) ) main()
Tue, 12/1/15
- Programs developed during office hours on 12/1/15 with a group of students
hw11a.py
lines = """building, Outdoor Track, Purple, Anna BD & Bailey Bogan, 108, 151, 103, 98, 202, 92, 209, 102, 214, 132, 206, 144 Building, The Pitch, Purple, Anna BD & Bailey Bogan, 172, 249, 173, 193, 266, 190, 270, 244 field, Outdoor Track, red, Anisha Tyagi and Sara Kacmoli, 1, 91, 98, 115, 91, 143, 87, 164, 86, 204, 87, """ def main(): # create a dictionary of buildings dict = {} # process each line for line in lines.split( "\n" ): fields = line.lower().split( "," ) # get rid of invalid lines if len( fields ) < 8: continue if fields[0].startswith( "building" ) == False: continue # valid fields #print( "fields = ", fields ) # add line to dictionary, key is building name, # value is list of coordinates name = fields[1].strip() coordinates = fields[4: ] dict[ name ] = coordinates # display contents of dictionary for key in dict.keys(): print( key, "-->", dict[ key ] ) main()
hw11b.py
L = [ 1, 2, 3, 4, 5, 6, 10, 11, 14, 20] for i in range( 0, len( L ), 2 ): first = L[i] second = L[i+1] print( "(", first, ",", second, ")" )
hw11c.py
dateDict = {} dateDict[ "Ford Hall" ] = 2005 dateDict[ "Burton Hall" ] = 1905 dateDict[ "Bass Hall" ] = 1998 for name in [ "Ford", "Ford Hall", "Art", "Bass Hall", "Bass" ]: #if name in dateDict.keys(): # print( name ) for key in dateDict.keys(): if key.find( name ) != -1: print( name )
Wed. 12/2/15
Inheritance0.py
- A program that displays a moving car. Need to add a Truck class...
# inheritance0.py # A simple car class to start with. # To do: add a truck class, which is a car # with a top. from graphics import * WIDTH = 600 HEIGHT = 400 class Wheel: """a Wheel is 2 concentric circles, the larger one black, the smaller one grey.""" def __init__(self, centr, rad1, rad2 ): # make circ1 the smaller of the 2 circles self.circ1 = Circle( centr, min( rad1, rad2 ) ) self.circ2 = Circle( centr, max( rad1, rad2 ) ) self.circ1.setFill( "grey" ) self.circ2.setFill( "black" ) def draw( self, win ): self.circ2.draw( win ) self.circ1.draw( win ) def move( self, dx, dy ): self.circ2.move( dx, dy ) self.circ1.move( dx, dy ) class Car: """A default simple car class. Sets the color to "Yellow" """ def __init__( self, rp ): """builds a car 180 pixels long on a reference point""" x = rp.getX() y = rp.getY() length = 180 # geometry of the car height = length // 3 firstQuarter = length//4 thirdQuarter = length * 3 // 4 p2 = Point( x+length, y+height ) self.body = Rectangle( rp, p2 ) self.body.setFill( "yellow" ) self.w1 = Wheel( Point( x+firstQuarter, y+height ), 20,10 ) self.w2 = Wheel( Point( x+thirdQuarter, y+height ), 20,10 ) def draw( self, win ): """ draws the body and wheels on the window""" self.body.draw( win ) self.w1.draw( win ) self.w2.draw( win ) def move( self, dx, dy ): """ moves the body and wheels some delta x and y""" self.body.move( dx, dy ) self.w1.move( dx, dy ) self.w2.move( dx, dy ) def main(): # open the window win = GraphWin( "CSC111 Inheritance Demo", WIDTH, HEIGHT ) car = Car( Point( 100,250 ) ) car.draw( win ) # animation loop while win.checkMouse()==None: car.move( 2, 0 ) win.close() main()
Inheritance4.py
# inheritance4.py # a graphic demo program for creating a circle # with a label in the middle. # from graphics import * WIDTH = 800 HEIGHT = 600 class MyCircle( Circle ): def __init__( self, rp, rad, text ): super().__init__( rp, rad ) self.label= Text( rp, text ) def draw( self, win ): super().draw( win ) self.label.draw( win ) def move( self, dx, dy ): super().move( dx, dy ) self.label.move( dx, dy ) def setText( self, newText ): self.label.setText( newText ) def main(): win = GraphWin( "MyCircle Demo", WIDTH, HEIGHT ) labCirc = MyCircle( Point( 100, 100 ), 50, "Hello!" ) labCirc.draw( win ) count = 0 while win.checkMouse() == None: labCirc.move( 2, 1 ) count += 1 #if count % 30 == 0: labCirc.setText( "{0:1} steps!".format( count ) ) win.close() main()
Fri. 12/4/14
Inheritance5.py
# inheritance5.py # Animal class to be used as super class # for Cow and Dog classes. # Cow class contains milk member variable # Dog class contains attribute: trained, hospital, # seeing-eye dog, rescue. class Animal: def __init__( self, name, birth, vacc, tattd ): self.name = name self.dob = birth self.vaccinated = vacc self.tattooed = tattd def __str__( self ): vaccString = "vaccinated" if self.vaccinated == False: vaccString = "not vaccinated" tattString = "tattooed" if self.tattooed == False: tattString = "not tattooed" return "{0:1}: {1:1}, {2:1}, {3:1}".format( self.name, self.dob, vaccString, tattString ) def isVaccinated( self ): return self.vaccinated def isTattooed( self ): return self.tattooed def getDOB( self ): return self.dob def getName( self ): return self.name class Cow( Animal ): def __init__( self, name, birth, vacc, tattd, milk ): super().__init__( name, birth, vacc, tattd ) self.milk = milk def getMilk( self ): return self.milk def __str__( self ): s = super().__str__() return s + ", {0:1}".format( self.milk ) def main(): pet1 = Animal( "Rex", "12/02/2015", True, True ) pet2 = Animal( "Garfield", "01/01/1978", True, False ) print( "pet #1 = ", pet1 ) print( "pet #2 = ", pet2 ) cow1 = Cow( "Rosie", "12/1/14", True, False, 20 ) print( "cow #1 = ", cow1 ) main()
Polymorphism.py
class Animal: def name(self): return def sleep(self): print( "sleeping now" ) def speak(self): return class Dog( Animal ): def name(self): print( "I am a dog!" ) def speak(self): print( "Woof!" ) class Cat( Animal ): def name(self): print( "I am a cat!" ) def speak(self): print( "Meow!" ) class Duck( Animal ): def name(self): print( "I am a duck!" ) def speak(self): print( "Quack!" )
Bananas.py
def minion( bunch ): """this minion is given a bunch of bananas. if there's only 1 banana in the bunch, it will return that banana as the largest in the bunch. If there's more than 1 banana in the bunch, this minion will keep one banana (the first one it finds) and pass the remainder of the bananas to another minion. That new minion will follow the *exact* same script in order to find the largest banana. At some point that second minion will return the largest of the bananas in the remainder. Our first minion will compare that to the one it kept, and return the largest of the two. """ # if minion gets a bunch of 1 banana, that banana # is the largest of what it got. if len( bunch ) == 1: banana = bunch[0] return banana # if we're here, it's because the bunch has more # than 1 banana. # keep the first one: kept = bunch[0] # create a smaller bunch: the remaining bananas remainingBananas = bunch[1: ] # pass that to another minion largestOfRemainingBananas = minion( remainingBananas ) # figure out which of the 2 bananas is largest: the # one kept, or the one just returned if kept > largestOfRemainingBananas: return kept else: return largestOfRemainingBananas def main(): bananas = [10, 2, 3, 20, -1, 5, 7, 0, 3, 6] largest = minion( bananas ) print( "bunch = ", bananas ) print( "largest banana found = ", largest ) main()
Mon. 12/07/15
LookForBanana.py
# this program is based on the program that finds the heaviest banana # in a bunch of bananas, using minions to do the work. This time we # are interested if there is a banana of a given weight in the bunch. # The algorithm in this case will have a minion work this way: # 1) it gets a bunch of bananas, along with a weight, and its job is # to figure out if there is a banana with this weight in the bunch. # 2) the minion then checks to see if it has gotten a bunch with just # one banana. If so, it checks to see if that banana has the weight # that is being sought. If it is, the minion returns True, meaning that # a banana was found with that weight. Otherwise it returns False. # 3) the minion takes 1 banana out of the bunch. Before passing the # remaining bananas to another minion, it checks to see if the banana # it has just picked has the weight that is being sought. If so, then # the minion can stop the recursion and return True. # 4) otherwise the minion passes the remaining bananas to another # minion and asks that new minion to go through the same 5 steps # explained here. # 5) whatever is returned by the minion that was just called, this minion # will also return. def minion( bunch, look ): print( "I'm a minion, and I got", bunch, "and am looking for", look ) # stopping condition #1 if len( bunch )==1: if bunch[0] == look: return True else: return False kept = bunch[0] # stopping condition #2 if kept == look: return True # recursive step. Call another minion to see # if look is in remaining bananas remaining = bunch[1 : ] # return whatever that minion returns to us... return minion( remaining, look ) def main(): bananas = [ 100, 120, 107, 97, 105 ] for item in bananas: look = item if minion( bananas, look ) == True: print( look," found!" ) else: print( look, "not found!" ) main()
Factorial.py
def factorial( n ): # stopping condition if n==1: return 1 # recursive step result = n * factorial( n-1 ) return result def main(): while True: n = int( input( "> " ) ) if n<=0: break print( "{0:1}! = {1:1}".format( n, factorial( n ) ) ) main()
Wed. 12/09/15
Recursively Visiting a Maze
# graphicsVisitMaze.py # D. Thiebaut # Generates a maze and displays it in a graphics window. # The maze is defined as a collection of lines of text. # MazeText is the variable containing the raw definition. # MazeText is split into lines and the list of lines is kept # in the variable maze. # Each line in mazeText contains # or . characters. A #-character # indicates a wall, while a . indicates an empty space. # MazeText is cleaned up and all the dots are replaced by spaces. # Then the maze is displayed in the graphic window. # The program maintains the status of the visit in the variable # maze. A '.' will represent a breadcrumb, i.e. a place that has # been visited and that is potentially on the path to the exit. A # 'v' character indicates a visited place that leads to an impass. # The program starts by visiting location STARTi (line number) # and STARTj (column number). # import time import os from graphics import * # Dimensions of the graphics window WIDTH = 600 HEIGHT = 600 mazeText = """ ######################### ........................# ##############.########## #.#.#........#.#........# #.#.#.########.########.# #.#.#.................#.# #.#.###.#####.#####.#...# #...........#.#.#.#.##### #.#########.#.#.#.#...#.# #.#.#.#.#.#.#.#.#######.# #.#.........#.#.......#.. #.###############.#####.# #...............#.......# #.###########.#########.# #........#..............# ######################### """ mazeText1 = """ ######################### ........................# #.......................# #.......................# #.......................# #.......................# #.......................# #.......................# #.......................# #.......................# #.......................# #.......................# #.......................# #.......................# #........................ ######################### """ mazeText2 = """ ######################### ........................# #.......................# #.......................# #.......................# #######################.# #.......................# #.......................# #.......................# #.......................# #.####################### #.......................# #.......................# #.......................# #........................ ######################### """ # STARTi = 1 # line number STARTj = 0 # column number NOLINES = len( mazeText.strip().split("\n") ) NOCHARS = len( mazeText.strip().split("\n")[1] ) BLOCKWIDTH = WIDTH // NOCHARS # width in pixels of block on graphics window BLOCKHEIGHT = HEIGHT / NOLINES # height in pixels of block on graphics window def getMazeFromFile( fileName ): """reads the definition of the maze from a file""" try: lines = open( fileName, 'r' ).read() except: print( "I/O Error: could not open", fileName ) return None return getMaze( lines ) def getMaze( mazeText ): """take the string representing the maze and break it down into an array of lines""" maze=[] for i, line in enumerate( mazeText.split( '\n' ) ): line = line.strip() #print( "%d [%s]" % (i, line ) ) if len( line ) < 2: continue line = line.replace( '.', ' ' ) maze.append( line ) return maze def setBreakCrumb( i, j, win ): """draw a circle where the walker has just landed, in the maze.""" global BLOCKWIDTH global BLOCKHEIGHT radius = BLOCKWIDTH // 4 brd = Circle( Point( (j+0.5)*BLOCKWIDTH, (i+0.5)*BLOCKHEIGHT ), radius ) brd.setFill( "red" ) brd.draw( win ) # rest a tiny bit to slow down the program time.sleep( 0.1 ) def setImpass( i, j, win ): """mark a block as not leading to an exit. Set its color to grey""" global BLOCKWIDTH global BLOCKHEIGHT radius = BLOCKWIDTH // 4 blk = Rectangle( Point( j*BLOCKWIDTH, i*BLOCKHEIGHT ), Point( (j+1)*BLOCKWIDTH, (i+1)*BLOCKHEIGHT ) ) blk.setFill( "lightgrey" ) blk.setOutline( "lightgrey" ) blk.draw( win ) # rest a tiny bit to slow down the program time.sleep( 0.1 ) def displayMaze( maze, win ): """ display the maze and wait for some amount of time""" global BLOCKWIDTH global BLOCKHEIGHT global NOLINES global NOCHARS blocks = [] for i in range (NOLINES ): for j in range( NOCHARS ): if maze[i][j]=="#": r = Rectangle( Point( j*BLOCKWIDTH, i*BLOCKHEIGHT ), Point( (j+1)*BLOCKWIDTH, (i+1)*BLOCKHEIGHT ) ) r.setFill( "blue" ) r.setOutline( "blue" ) r.draw( win ) blocks.append( r ) return blocks def setChar( maze, i, j, char ): """puts the character char at position i, j in the maze""" line = maze[i] letters = [] for letter in line: letters.append( letter ) letters[j] = char maze[i] = ''.join( letters ) def visitMaze( maze, i, j, win ): """recursive visit of the maze. Returns True when it has found the exit, False otherwise""" # put a breadcrumb where we just landed. setBreakCrumb( i, j, win ) setChar( maze, i, j, '.' ) # stopping condition: we landed on the Exit... if ( i != STARTi or j != STARTj ) \ and ( (i==0 or i==len( maze )-1 ) or (j==0 or j==len( maze[0] )-1 ) ): return True #--- try the four directions around where we are --- #--- to the right? --- if j+1< len( maze[0] ) and maze[i][j+1]==' ': if visitMaze( maze, i, j+1, win ) == True: return True # found an exit by going right! #--- down? --- if i+1< len( maze ) and maze[i+1][j]==' ': if visitMaze( maze, i+1, j, win ) == True: return True # found an exit by going down! #--- up? --- if i-1>=0 and maze[i-1][j]==' ': if visitMaze( maze, i-1, j, win ) == True: return True # found an exit by going up! #--- to the left? --- if j-1>=0 and maze[i][j-1]==' ': if visitMaze( maze, i, j-1, win ) == True: return True # found an exit by going left! #--- if we're here, none of the 4 directions was successful --- #--- in bringing us to an exit, we have to mark our cell with-- #--- a v, and return false to our caller, indicating that we--- #--- couldn't find a path --- setImpass( i, j, win ) setChar( maze, i, j, 'v' ) #printMaze( maze ) return False def main(): """gets the maze, visit and display it""" #maze = getMazeFromFile( 'largemaze.txt' ) win = GraphWin("Maze", WIDTH, HEIGHT ) win.getMouse() maze = getMaze( mazeText2 ) #printMaze( maze ) blocks = displayMaze( maze, win ) success = visitMaze( maze, STARTi, STARTj, win ) #--- print the maze without the v-characters --- #printMazeNoVs( maze ) if success: print( "A path was found!" ) else: print( "No path to an exit found..." ) win.getMouse() win.close() main()
Fractal Tree
# fractalTree.py # D. Thiebaut # Code taken from http://openbookproject.net/thinkcs/python/english3e/recursion.html # and adapted to work with graphics111.py. # # Draws a fractal tree on the graphic window. # from graphics import * import math import time import random # dimensions of the window MAXWIDTH = 800 MAXHEIGHT = 800 # recursive tree-drawing function # def draw_tree(win , # the canvas order, # the level of recursion. Starts positive. theta, # angle of new branch leaving this trunk sz, # size of this branch x, y, # coordinates of base of this branch heading, # angle of direction of this branch color # color ): trunk_ratio = 0.29 # How big is the trunk relative to whole tree? trunk = sz * trunk_ratio # length of trunk # compute x, y of end of the current branch delta_x = trunk * math.cos(heading) delta_y = trunk * math.sin(heading) x2, y2 = x + delta_x, y + delta_y # draw current branch branch = Line( Point( x, y), Point( x2, y2 ) ) branch.setFill( color ) branch.setWidth( 2 ) branch.setOutline( color ) branch.draw( win ) # if this branch has sub-branches, then recurse if order > 0: # make the recursive calls to draw the two subtrees newsz = sz*(1 - trunk_ratio) draw_tree(win, order-1, theta, newsz, x2, y2, heading-theta, color ) draw_tree(win, order-1, theta, newsz, x2, y2, heading+theta, color ) # draw 1 tree in the middle of the screen, shooting straight up. def main(): win = GraphWin("Fractal Tree", MAXWIDTH, MAXHEIGHT ) theta = 0.65 # use 0.02 for tall skinny trees, 0.7 for fat trees draw_tree(win, 9, theta, MAXWIDTH*0.9, MAXWIDTH//2, MAXHEIGHT-50, -math.pi/2, "brown" ) win.getMouse() win.close() main()
Hanoi.py
The program can be found here.