Difference between revisions of "CSC111 Lab 12 2015b"
(9 intermediate revisions by 2 users not shown) | |||
Line 2: | Line 2: | ||
---- | ---- | ||
− | |||
− | |||
− | |||
− | |||
− | |||
<!-- ============================================================= --> | <!-- ============================================================= --> | ||
Line 16: | Line 11: | ||
<br /> | <br /> | ||
<br /> | <br /> | ||
− | The deadline for the submission on Moodle is Friday 12/04 at 11:55 | + | The deadline for the submission on Moodle is Friday 12/04 at 11:55 p.m. |
</bluebox> | </bluebox> | ||
+ | <br /> | ||
+ | <br /> | ||
+ | __TOC__ | ||
+ | <br /> | ||
+ | <br /> | ||
+ | |||
+ | <showafterdate after="20151202 12:00" before="20151231 00:00"> | ||
+ | <bluebox> | ||
+ | First please complete the survey by clicking on this link: http://goo.gl/forms/Bho0VvB3tP | ||
+ | </bluebox> | ||
=Problem 1: Class Inheritance: Rectangles with Labels Inside= | =Problem 1: Class Inheritance: Rectangles with Labels Inside= | ||
Line 163: | Line 168: | ||
<!-- ================================================================ --> | <!-- ================================================================ --> | ||
− | =Problem | + | =Problem 2: Animals= |
<br /> | <br /> | ||
− | The text below contains names of animals and their speed, expressed in miles per hour. Write a Python program called ''' | + | The text below contains names of animals and their speed, expressed in miles per hour. Write a Python program called '''lab12.py''' (no need to write classes for this problem) based on the preparation problem above. It should prompt the user for file (create your own file and use the animals listed below). Your program should read the animals from the file and should output the following quantities: |
# The list of '''all''' the animals ranked by speed. Fastest first. | # The list of '''all''' the animals ranked by speed. Fastest first. | ||
# The 10 fastest animals listed in order of decreasing speed | # The 10 fastest animals listed in order of decreasing speed | ||
# The 10 slowest animals listed in order of increasing speed | # The 10 slowest animals listed in order of increasing speed | ||
# The ratio of the speeds of the fastest animal versus that of the slowest animal. For example, if the speed of the fastest animal is 50 and the speed of the slowest is 2, then the program should output that the fastest animal is '''25 times''' faster than the slowest one. | # The ratio of the speeds of the fastest animal versus that of the slowest animal. For example, if the speed of the fastest animal is 50 and the speed of the slowest is 2, then the program should output that the fastest animal is '''25 times''' faster than the slowest one. | ||
− | # The list of all the animals (just their name, not their speed) that are faster than a human being ("human" is one of the species listed). Your program should not contain the number 27.9, which is the speed of a human. Instead it should find this number by looking up "human" in one of your lists and get the speed associated for the human. | + | # The list of all the animals (just their name, not their speed) that are faster than a human being ("human" is one of the species listed). Your program should not contain the number 27.9, which is the speed of a human. Instead it should find this number by looking up "human" in one of your lists and get the speed associated for the human. The animals should be presented in ascending alphabetical order. |
<br /> | <br /> | ||
::<source lang="text"> | ::<source lang="text"> | ||
− | Black Mamba Snake 20.0 mph | + | Pig (domestic) 11.0 mph |
+ | Pronghorn Antelope 61.0 mph | ||
+ | Quarter Horse 47.5 mph | ||
+ | Rabbit (domestic) 35.0 mph | ||
+ | Reindeer 32.0 mph | ||
+ | Six-Lined Racerunner 18.0 mph | ||
+ | Spider (Tegenaria atrica) 1.2 mph | ||
+ | Squirrel 12.0 mph | ||
+ | Thomson's Gazelle 50.0 mph | ||
+ | Three-Toed Sloth 0.1 mph | ||
+ | Warthog 30.0 mph | ||
+ | Whippet 35.5 mph | ||
+ | White-Tailed Deer 30.0 mph | ||
+ | Wild Turkey 15.0 mph | ||
+ | Wildebeest 50.0 mph | ||
+ | Zebra 40.0 mph | ||
+ | Human 27.9 mph | ||
+ | </source> | ||
+ | <br /> | ||
+ | Your output should look like: | ||
+ | Input file:short.txt | ||
+ | -*- | ||
+ | COMPLETE LIST, ORDERED BY DECREASING SPEED | ||
+ | Pronghorn Antelope 61.0 | ||
+ | Wildebeest 50.0 | ||
+ | ... | ||
+ | Three-Toed Sloth 0.1 | ||
+ | |||
+ | |||
+ | 10 FASTEST ANIMALS, ORDERED BY DECREASING SPEED | ||
+ | Pronghorn Antelope 61.0 | ||
+ | Wildebeest 50.0 | ||
+ | ... | ||
+ | Warthog 30.0 | ||
+ | |||
+ | |||
+ | 10 SLOWEST ANIMALS, ORDERED BY INCREASING SPEED | ||
+ | Three-Toed Sloth 0.1 | ||
+ | Spider (Tegenaria atrica) 1.2 | ||
+ | ... | ||
+ | Reindeer 32.0 | ||
+ | |||
+ | |||
+ | SPEED-RATIO OF FASTEST TO SLOWEST | ||
+ | The Pronghorn Antelope is 610 times faster than the Three-Toed Sloth. | ||
+ | |||
+ | |||
+ | ANIMALS FASTER THAN HUMAN BEINGS | ||
+ | Pronghorn Antelope | ||
+ | Quarter Horse | ||
+ | ... | ||
+ | Zebra | ||
+ | <br /> | ||
+ | Make sure your program puts the string -*- on a line just before you begin printing the output | ||
+ | |||
+ | Submit your program to Moodle as lab12.py | ||
+ | </showafterdate> | ||
+ | |||
+ | <!-- =========================================================== --> | ||
+ | <!-- SOLUTION PROGRAMS --> | ||
+ | <!-- =========================================================== --> | ||
+ | <br /> | ||
+ | <showafterdate after="20151205 00:00" before="20151231 00:00"> | ||
+ | =Solution Programs= | ||
+ | ==Animals == | ||
+ | <br /> | ||
+ | ::<source lang="python"> | ||
+ | # animals.py | ||
+ | # D. Thiebaut | ||
+ | # parses a list of lines containing | ||
+ | # animal information and outputs several | ||
+ | # interesting statistics about the quantities | ||
+ | # contained in the text. | ||
+ | |||
+ | text = """Black Mamba Snake 20.0 mph | ||
Cape Hunting Dog 45.0 mph | Cape Hunting Dog 45.0 mph | ||
Cat (domestic) 30.0 mph | Cat (domestic) 30.0 mph | ||
Line 208: | Line 287: | ||
Wild Turkey 15.0 mph | Wild Turkey 15.0 mph | ||
Wildebeest 50.0 mph | Wildebeest 50.0 mph | ||
− | Zebra 40.0 mph | + | Zebra 40.0 mph""" |
+ | |||
+ | def main(): | ||
+ | #---------------------------------------------------------- | ||
+ | # display the list sorted by decreasing speed | ||
+ | #---------------------------------------------------------- | ||
+ | print( "\n\nCOMPLETE LIST, ORDERED BY DECREASING SPEED" ) | ||
+ | list = [] | ||
+ | for line in text.split( "\n" ): | ||
+ | fields = line.split( ) | ||
+ | # skip lines that do not contain a valid count of fields | ||
+ | if len( fields ) < 3: | ||
+ | continue | ||
+ | |||
+ | # create a name and a speed | ||
+ | name = fields[0:-2] # all fields except last 2 | ||
+ | name = " ".join( name ) # join all fields with a space | ||
+ | speed = float( fields[-2] ) # one before last field | ||
+ | |||
+ | # create a tuple with speed listed first | ||
+ | tuple = (speed, name ) | ||
+ | |||
+ | # add it to the list | ||
+ | list.append( tuple ) | ||
+ | |||
+ | # sort the list in increasing order (smallest speed first) | ||
+ | list.sort() | ||
+ | |||
+ | # reverse the list | ||
+ | list.reverse() | ||
+ | |||
+ | # display the list | ||
+ | for speed, name in list: | ||
+ | print( "{0:30} {1:3.1f}".format( name, speed ) ) | ||
+ | |||
+ | |||
+ | #---------------------------------------------------------- | ||
+ | # display the 10 fastest in order of decreasing speed | ||
+ | #---------------------------------------------------------- | ||
+ | print( "\n\n10 FASTEST ANIMALS, ORDERED BY DECREASING SPEED" ) | ||
+ | for i in range( min( 10, len( list ) ) ): | ||
+ | speed, name = list[i] | ||
+ | print( "{0:30} {1:3.1f}".format( name, speed ) ) | ||
+ | |||
+ | #---------------------------------------------------------- | ||
+ | # display the 10 slowest in order of decreasing speed | ||
+ | #---------------------------------------------------------- | ||
+ | print( "\n\n10 SLOWEST ANIMALS, ORDERED BY INCREASING SPEED" ) | ||
+ | list.reverse() | ||
+ | for i in range( min( 10, len( list ) ) ): | ||
+ | speed, name = list[i] | ||
+ | print( "{0:30} {1:3.1f}".format( name, speed ) ) | ||
+ | |||
+ | #---------------------------------------------------------- | ||
+ | # display the ratio of fastest to slowest | ||
+ | #---------------------------------------------------------- | ||
+ | print( "\n\nSPEED-RATIO OF FASTEST TO SLOWEST" ) | ||
+ | fastestSpeed, fastestName = list[-1] | ||
+ | slowestSpeed, slowestName = list[0] | ||
+ | print( "The {0:1} is {1:1.0f} times faster than the {2:1}." | ||
+ | .format( fastestName, fastestSpeed/slowestSpeed, slowestName )) | ||
+ | |||
+ | #---------------------------------------------------------- | ||
+ | # display the animals faster than human beings | ||
+ | #---------------------------------------------------------- | ||
+ | print( "\n\nANIMALS FASTER THAN HUMAN BEINGS" ) | ||
+ | |||
+ | # find the speed of the human | ||
+ | speedHuman = 0 | ||
+ | for speed, name in list: | ||
+ | if name.strip().lower()=="human": | ||
+ | speedHuman = speed | ||
+ | break | ||
+ | |||
+ | # create a list of the animals faster than humans | ||
+ | list2 = [] | ||
+ | for speed, name in list: | ||
+ | if speed > speedHuman: | ||
+ | list2.append( name ) | ||
+ | |||
+ | # sort the list alphabetically | ||
+ | list2.sort() | ||
+ | |||
+ | # display the list | ||
+ | for name in list2: | ||
+ | print( "{0:30}".format( name, speed ) ) | ||
+ | |||
+ | |||
+ | if __name__=="__main__": | ||
+ | main() | ||
+ | |||
+ | |||
</source> | </source> | ||
<br /> | <br /> | ||
+ | ==Aquarium== | ||
+ | <br /> | ||
+ | <source lang="python"> | ||
+ | # aquariumLab11.py | ||
+ | # D. Thiebaut | ||
+ | # A graphics program based on Zelle's graphic library. | ||
+ | # Creates an application with the picture of an aquarium | ||
+ | # as the backdrop, then creates a school of fish, and animates | ||
+ | # them, having them move around the aquarium, in a somewhat | ||
+ | # random fashion. | ||
+ | from graphics import * | ||
+ | import random | ||
+ | |||
+ | WIDTH = 700 | ||
+ | HEIGHT = 517 | ||
+ | |||
+ | class Fish: | ||
+ | """A class for the fish. Supports randomly moving in the | ||
+ | right to left direction""" | ||
+ | |||
+ | def __init__(self, fileName ): | ||
+ | self.img = Image( Point( random.randrange( WIDTH//2, WIDTH), | ||
+ | random.randrange( HEIGHT) ), fileName ) | ||
+ | |||
+ | def draw( self, win ): | ||
+ | """shows the fish on the graphics window""" | ||
+ | self.img.draw( win ) | ||
+ | |||
+ | def moveRandom( self ): | ||
+ | """moves the fish to the right, randomly. Some random up/down motion""" | ||
+ | deltaX = random.randrange( -5, 0 ) | ||
+ | deltaY = random.randrange( -3, 4 ) | ||
+ | self.img.move( deltaX, deltaY ) | ||
+ | if self.img.getAnchor().getX() < -50: | ||
+ | self.img.move( WIDTH + 100, 0 ) | ||
+ | |||
+ | def main(): | ||
+ | # open the window | ||
+ | win = GraphWin( "CSC Aquarium", WIDTH, HEIGHT ) | ||
+ | |||
+ | # display background | ||
+ | background = Image( Point( WIDTH//2, HEIGHT//2 ), "tank2.gif" ) | ||
+ | background.draw( win ) | ||
+ | |||
+ | # create a school of fish | ||
+ | fishList = [] | ||
+ | for i in range( 10 ): | ||
+ | fish = Fish( "fish0.gif" ) | ||
+ | fish.draw( win ) | ||
+ | fishList.append( fish ) | ||
+ | |||
+ | # animation loop. | ||
+ | while win.checkMouse() == None: | ||
+ | for fish in fishList: | ||
+ | fish.moveRandom() | ||
+ | |||
+ | |||
+ | # one more click to close the window. | ||
+ | win.getMouse() | ||
+ | win.close() | ||
+ | |||
+ | main() | ||
+ | </source> | ||
+ | <br /> | ||
+ | == Presidents== | ||
+ | <br /> | ||
+ | ::<source lang="python"> | ||
+ | # presidents.py | ||
+ | # D. Thiebaut | ||
+ | |||
+ | text="""Presidency ,President, Took office ,Left office ,Party , Home State | ||
+ | 1, George Washington, 30/04/1789, 4/03/1797, Independent, Virginia | ||
+ | 2, John Adams, 4/03/1797, 4/03/1801, Federalist, Massachusetts | ||
+ | 3, Thomas Jefferson, 4/03/1801, 4/03/1809, Democratic-Republican, Virginia | ||
+ | 4, James Madison, 4/03/1809, 4/03/1817, Democratic-Republican, Virginia | ||
+ | 5, James Monroe, 4/03/1817, 4/03/1825, Democratic-Republican, Virginia | ||
+ | 6, John Quincy Adams, 4/03/1825, 4/03/1829, Democratic-Republican/National Republican, Massachusetts | ||
+ | 7, Andrew Jackson, 4/03/1829, 4/03/1837, Democratic, Tennessee | ||
+ | 8, Martin Van Buren, 4/03/1837, 4/03/1841, Democratic, New York | ||
+ | 9, William Henry Harrison, 4/03/1841, 4/04/1841, Whig, Ohio | ||
+ | 10, John Tyler, 4/04/1841, 4/03/1845, Whig, Virginia | ||
+ | 11, James K. Polk, 4/03/1845, 4/03/1849, Democratic, Tennessee | ||
+ | 12, Zachary Taylor, 4/03/1849, 9/07/1850, Whig, Louisiana | ||
+ | 13, Millard Fillmore, 9/07/1850, 4/03/1853, Whig, New York | ||
+ | 14, Franklin Pierce, 4/03/1853, 4/03/1857, Democratic, New Hampshire | ||
+ | 15, James Buchanan, 4/03/1857, 4/03/1861, Democratic, Pennsylvania | ||
+ | 16, Abraham Lincoln, 4/03/1861, 15/04/1865, Republican/National Union, Illinois | ||
+ | 17, Andrew Johnson, 15/04/1865, 4/03/1869, Democratic/National Union, Tennessee | ||
+ | 18, Ulysses S. Grant, 4/03/1869, 4/03/1877, Republican, Ohio | ||
+ | 19, Rutherford B. Hayes, 4/03/1877, 4/03/1881, Republican, Ohio | ||
+ | 20, James A. Garfield, 4/03/1881, 19/09/1881, Republican, Ohio | ||
+ | 21, Chester A. Arthur, 19/09/1881, 4/03/1885, Republican, New York | ||
+ | 22, Grover Cleveland, 4/03/1885, 4/03/1889, Democratic, New York | ||
+ | 23, Benjamin Harrison, 4/03/1889, 4/03/1893, Republican, Indiana | ||
+ | 24, Grover Cleveland, 4/03/1893, 4/03/1897, Democratic, New York | ||
+ | 25, William McKinley, 4/03/1897, 14/9/1901, Republican, Ohio | ||
+ | 26, Theodore Roosevelt, 14/9/1901, 4/3/1909, Republican, New York | ||
+ | 27, William Howard Taft, 4/3/1909, 4/03/1913, Republican, Ohio | ||
+ | 28, Woodrow Wilson, 4/03/1913, 4/03/1921, Democratic, New Jersey | ||
+ | 29, Warren G. Harding, 4/03/1921, 2/8/1923, Republican, Ohio | ||
+ | 30, Calvin Coolidge, 2/8/1923, 4/03/1929, Republican, Massachusetts | ||
+ | 31, Herbert Hoover, 4/03/1929, 4/03/1933, Republican, Iowa | ||
+ | 32, Franklin D. Roosevelt, 4/03/1933, 12/4/1945, Democratic, New York | ||
+ | 33, Harry S. Truman, 12/4/1945, 20/01/1953, Democratic, Missouri | ||
+ | 34, Dwight D. Eisenhower, 20/01/1953, 20/01/1961, Republican, Texas | ||
+ | 35, John F. Kennedy, 20/01/1961, 22/11/1963, Democratic, Massachusetts | ||
+ | 36, Lyndon B. Johnson, 22/11/1963, 20/1/1969, Democratic, Texas | ||
+ | 37, Richard Nixon, 20/1/1969, 9/8/1974, Republican, California | ||
+ | 38, Gerald Ford, 9/8/1974, 20/01/1977, Republican, Michigan | ||
+ | 39, Jimmy Carter, 20/01/1977, 20/01/1981, Democratic, Georgia | ||
+ | 40, Ronald Reagan, 20/01/1981, 20/01/1989, Republican, California | ||
+ | 41, George H. W. Bush, 20/01/1989, 20/01/1993, Republican, Texas | ||
+ | 42, Bill Clinton, 20/01/1993, 20/01/2001, Democratic, Arkansas | ||
+ | 43, George W. Bush, 20/01/2001, 20/01/2009, Republican, Texas""" | ||
+ | |||
+ | def main(): | ||
+ | # remove the first line from the list of lines | ||
+ | lines = text.split( "\n" ) | ||
+ | lines = lines[1:] | ||
+ | |||
+ | # create a list of tuples | ||
+ | list = [] | ||
+ | for line in lines: | ||
+ | fields = line.split( "," ) | ||
+ | |||
+ | # skip invalid lines | ||
+ | if len( fields ) != 6: | ||
+ | continue | ||
+ | |||
+ | # create tuple | ||
+ | name = fields[1].strip() | ||
+ | yearStart = int( fields[2].split( "/" )[2] ) | ||
+ | yearEnd = int( fields[3].split( "/" )[2] ) | ||
+ | party = fields[-2].strip() | ||
+ | state = fields[-1].strip() | ||
+ | tuple = ( name, yearStart, yearEnd, party, state ) | ||
+ | |||
+ | # add tuple to list | ||
+ | list.append( tuple ) | ||
+ | |||
+ | #========================================================= | ||
+ | # Display the list of presidents in alphabetical order | ||
+ | #========================================================= | ||
+ | print( "\n\nAlphabetical List".upper() ) | ||
+ | list.sort() | ||
+ | for name, y1, y2, party, s in list: | ||
+ | print( name ) | ||
+ | |||
+ | |||
+ | #========================================================= | ||
+ | # Display the list of presidents associated with the democratic | ||
+ | # party | ||
+ | #========================================================= | ||
+ | print( "\n\nAlphabetical List of Democrats".upper() ) | ||
+ | for name, y1, y2, party, s in list: | ||
+ | if party.lower().find( "democra" )!= -1: | ||
+ | print( name ) | ||
+ | |||
+ | #========================================================= | ||
+ | # Display the president in office in 1945 | ||
+ | #========================================================= | ||
+ | print( "\n\nPresident in office in 1945".upper() ) | ||
+ | for name, y1, y2, party, s in list: | ||
+ | if y1 <= 1945 <= y2: | ||
+ | print( name ) | ||
+ | |||
+ | |||
+ | #========================================================= | ||
+ | # Display the president whose home state was Massachusetts | ||
+ | #========================================================= | ||
+ | print( "\n\nPresident from Massachusetts".upper() ) | ||
+ | for name, y1, y2, party, s in list: | ||
+ | if s.capitalize().find( "Massa" ) != -1: | ||
+ | print( name ) | ||
+ | |||
+ | if __name__=="__main__": | ||
+ | main() | ||
+ | |||
+ | |||
+ | </source> | ||
+ | ==MyRect, MyCirc, Car == | ||
+ | <br /> | ||
+ | ::<source lang="python"> | ||
+ | # MyRect.py | ||
+ | # D. Thiebaut | ||
+ | # This program illustrates how to create and use derived classes. | ||
+ | # MyRect is derived from Rectangle, in graphics.py | ||
+ | # MyCirc is derived from Cirle, also in graphics.py | ||
+ | # Car uses a MyRect object for its body, and a Rectangle for its top. | ||
+ | |||
+ | from graphics import * | ||
+ | |||
+ | WIDTH = 600 | ||
+ | HEIGHT = 400 | ||
+ | |||
+ | class MyRect( Rectangle ): | ||
+ | def __init__( self, p1, p2, labl ): | ||
+ | Rectangle.__init__( self, p1, p2 ) | ||
+ | midPoint = Point( (p1.getX()+p2.getX())/2, | ||
+ | (p1.getY()+p2.getY())/2 ) | ||
+ | self.label = Text( midPoint, labl ) | ||
+ | |||
+ | def draw( self, win ): | ||
+ | Rectangle.draw( self, win ) | ||
+ | self.label.draw( win ) | ||
+ | |||
+ | def move( self, dx, dy ): | ||
+ | Rectangle.move( self, dx, dy ) | ||
+ | self.label.move( dx, dy ) | ||
+ | |||
+ | |||
+ | class MyCirc( Circle ): | ||
+ | def __init__( self, centr, rad, labl ): | ||
+ | Circle.__init__( self, centr, rad ) | ||
+ | self.label = Text( centr, labl ) | ||
+ | |||
+ | def draw( self, win ): | ||
+ | Circle.draw( self, win ) | ||
+ | self.label.draw( win ) | ||
+ | |||
+ | def move( self, dx, dy ): | ||
+ | Circle.move( self, dx, dy ) | ||
+ | self.label.move( dx, dy ) | ||
+ | |||
+ | 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: | ||
+ | def __init__( self, rp, labl ): | ||
+ | x = rp.getX() | ||
+ | y = rp.getY() | ||
+ | p2 = Point( x+180, y+60 ) | ||
+ | self.body = MyRect( rp, p2, labl ) | ||
+ | self.body.setFill( "yellow" ) | ||
+ | self.top = Rectangle( Point( x+10, y-20 ), Point(x+160, y ) ) | ||
+ | self.top.setFill( "yellow" ) | ||
+ | self.w1 = Wheel( Point( x+20, y+60 ), 20,10 ) | ||
+ | self.w2 = Wheel( Point( x+120, y+60 ), 20,10 ) | ||
+ | |||
+ | def draw( self, win ): | ||
+ | self.body.draw( win ) | ||
+ | self.w1.draw( win ) | ||
+ | self.w2.draw( win ) | ||
+ | self.top.draw( win ) | ||
+ | |||
+ | def move( self, dx, dy ): | ||
+ | self.body.move( dx, dy ) | ||
+ | self.top.move( dx, dy ) | ||
+ | self.w1.move( dx, dy ) | ||
+ | self.w2.move( dx, dy ) | ||
+ | |||
+ | def main(): | ||
+ | # open the window | ||
+ | win = GraphWin( "CSC111", WIDTH, HEIGHT ) | ||
+ | |||
+ | r1 = MyRect( Point( 100, 100 ), Point( 200, 200 ), "CSC111" ) | ||
+ | r1.setFill( "Yellow" ) | ||
+ | r1.draw( win ) | ||
+ | |||
+ | c1 = MyCirc( Point( 200, 200 ), 20, "BALL" ) | ||
+ | c1.setFill( "red" ) | ||
+ | c1.draw( win ) | ||
+ | |||
+ | car = Car( Point( 100,250 ), "TAXI" ) | ||
+ | car.draw( win ) | ||
+ | |||
+ | while win.checkMouse() == None: | ||
+ | for i in range( 20 ): | ||
+ | r1.move( 10,2 ) | ||
+ | c1.move( 5, 1 ) | ||
+ | car.move( 1, 0 ) | ||
+ | |||
+ | for i in range( 20 ): | ||
+ | r1.move( -10,-2 ) | ||
+ | c1.move( -5, 1 ) | ||
+ | |||
+ | win.getMouse() | ||
+ | win.close() | ||
+ | |||
+ | main() | ||
+ | |||
+ | </source> | ||
+ | </showafterdate> | ||
<br /> | <br /> | ||
<br /> | <br /> |
Latest revision as of 20:31, 2 December 2015
--D. Thiebaut (talk) 16:49, 20 November 2015 (EST)
The first part of the lab deals with classes in general and class inheritance in particular, and you will be building classes derived from other classes.
For the second part, you will be working with text-based information in the form of lists. We often have to deal with lists: they can be list of email addresses, list of contacts, list of courses, list of grad schools, list of historical facts, list of books, or authors, etc. And very often we need to extract just a few items from the list that are of interest to us. Once you know programming, such task can be done very simply. In this lab, you are going to process several lists and extract information from them.
The deadline for the submission on Moodle is Friday 12/04 at 11:55 p.m.
Contents
<showafterdate after="20151202 12:00" before="20151231 00:00">
First please complete the survey by clicking on this link: http://goo.gl/forms/Bho0VvB3tP
Problem 1: Class Inheritance: Rectangles with Labels Inside
- Create a new program called Lab11_1.py and copy the code below into it.
# lab11_1.py # ... # A graphic program with a new MyRect class that is derived from # the Rectangle class in the graphics.py library. from graphics import * # window geometry WIDTH = 600 HEIGHT = 400 class MyRect( Rectangle ): """MyRect: a class that inherits from Rectangle, in graphics.py""" def __init__( self, p1, p2, labl ): """constructor. Constructs a rectangle with a text label in its center""" # call the Rectangle constructor and pass it the 2 points Rectangle.__init__( self, p1, p2 ) # put a label at a point in-between p1 and p2. midPoint = Point( (p1.getX()+p2.getX())/2, (p1.getY()+p2.getY())/2 ) self.label = Text( midPoint, labl ) def draw( self, win ): """draw the rectangle and the label on the window.""" # call the draw() method of the rectangle class to draw the rectangle Rectangle.draw( self, win ) # then draw the label on top self.label.draw( win ) def main(): # open the window win = GraphWin( "CSC LAB", WIDTH, HEIGHT ) # create an object of type MyRect with the string "CSC111" in the middle r1 = MyRect( Point( 100, 100 ), Point( 200, 200 ), "CSC111" ) r1.setFill( "Yellow" ) r1.draw( win ) # close the window when the user clicks the mouse win.getMouse() win.close() main()
- Run the program. Verify that it displays a Yellow rectangle with a string in the middle.
- Add a loop to your main program, that will make the rectangle move to the right:
for i in range( 20 ): r1.move( 10,2 )
- Do you observe something strange? What is happening? Think...
- Think some more. Do not move on until you are sure you know what is going on...
Discussion Time!
- Discuss the various options as a class. Figure out what is going on. What is missing, what the problem is, and how to fix it.
Circles with Labels Inside
- Use the same approach to create a new class called MyCirc that is a subclass of Circle, and that displays a circle with a label inside. You can use the same program and add to it.
- Modify the loop in your main program so that it makes both the MyRect object and the MyCirc object move together (maybe not in the same direction).
Building a Car with MyRect
- Locate the program you wrote a while back, that displays a car on the graphic window (with a body, and two wheels).
- In case you had implemented a text label as part of your Car class, please remove it. Make sure your program displays only a car with 2 wheels and two rectangles, one for the body, one for the top.
- Copy the car class in your current program for today's lab.
Using MyRect to build the Body of the Car
- Organize your program so that the MyRect class is listed at the top of the program, along with MyCirc, and then followed by the Wheel and Car classes.
;header Class MyRect: ... Class Wheel: ... Class Car: ... def main(): ... main()
- Modify your Car class so that it uses MyRect instead of Rectangle for its body. Make the label inside the body be a label that is passed in the constructor of the Car.
- Verify that your program correctly displays the modified car.
- Make your car move some deltax, deltay in a loop, the same way you moved the MyRect and MyCirc objects in the previous problem. Verify that the car moves correctly, including its label.
List of Lists
Demonstration Example
- Create a new new program called Lab11_demo.py and copy the code from this program.
- Carefully read the program to see what it does, and how it does it.
- Run the program to verify that it works well.
- Edit the text variable, and make it contain only 5 lines of text (it doesn't matter what countries you pick).
- Run your program again and verify that the "top-10" and "last-10" sections still work and do not crash, even though the list contains fewer than 10 tuples.
- Using a similar approach, solve the next problem.
Problem 2: Animals
The text below contains names of animals and their speed, expressed in miles per hour. Write a Python program called lab12.py (no need to write classes for this problem) based on the preparation problem above. It should prompt the user for file (create your own file and use the animals listed below). Your program should read the animals from the file and should output the following quantities:
- The list of all the animals ranked by speed. Fastest first.
- The 10 fastest animals listed in order of decreasing speed
- The 10 slowest animals listed in order of increasing speed
- The ratio of the speeds of the fastest animal versus that of the slowest animal. For example, if the speed of the fastest animal is 50 and the speed of the slowest is 2, then the program should output that the fastest animal is 25 times faster than the slowest one.
- The list of all the animals (just their name, not their speed) that are faster than a human being ("human" is one of the species listed). Your program should not contain the number 27.9, which is the speed of a human. Instead it should find this number by looking up "human" in one of your lists and get the speed associated for the human. The animals should be presented in ascending alphabetical order.
Pig (domestic) 11.0 mph Pronghorn Antelope 61.0 mph Quarter Horse 47.5 mph Rabbit (domestic) 35.0 mph Reindeer 32.0 mph Six-Lined Racerunner 18.0 mph Spider (Tegenaria atrica) 1.2 mph Squirrel 12.0 mph Thomson's Gazelle 50.0 mph Three-Toed Sloth 0.1 mph Warthog 30.0 mph Whippet 35.5 mph White-Tailed Deer 30.0 mph Wild Turkey 15.0 mph Wildebeest 50.0 mph Zebra 40.0 mph Human 27.9 mph
Your output should look like: Input file:short.txt -*- COMPLETE LIST, ORDERED BY DECREASING SPEED Pronghorn Antelope 61.0 Wildebeest 50.0 ... Three-Toed Sloth 0.1 10 FASTEST ANIMALS, ORDERED BY DECREASING SPEED Pronghorn Antelope 61.0 Wildebeest 50.0 ... Warthog 30.0 10 SLOWEST ANIMALS, ORDERED BY INCREASING SPEED Three-Toed Sloth 0.1 Spider (Tegenaria atrica) 1.2 ... Reindeer 32.0 SPEED-RATIO OF FASTEST TO SLOWEST The Pronghorn Antelope is 610 times faster than the Three-Toed Sloth. ANIMALS FASTER THAN HUMAN BEINGS Pronghorn Antelope Quarter Horse ... Zebra
Make sure your program puts the string -*- on a line just before you begin printing the output
Submit your program to Moodle as lab12.py </showafterdate>
<showafterdate after="20151205 00:00" before="20151231 00:00">
Solution Programs
Animals
# animals.py # D. Thiebaut # parses a list of lines containing # animal information and outputs several # interesting statistics about the quantities # contained in the text. text = """Black Mamba Snake 20.0 mph Cape Hunting Dog 45.0 mph Cat (domestic) 30.0 mph Cheetah 70.0 mph Chicken 9.0 mph Coyote 43.0 mph Elephant 25.0 mph Elk 45.0 mph Giant Tortoise 0.2 mph Giraffe 32.0 mph Gray Fox 42.0 mph Greyhound 39.4 mph Grizzly Bear 30.0 mph Human 27.9 mph Hyena 40.0 mph Jackal 35.0 mph Lion 50.0 mph Mongolian Wild Ass 40.0 mph Mule Deer 35.0 mph Pig (domestic) 11.0 mph Pronghorn Antelope 61.0 mph Quarter Horse 47.5 mph Rabbit (domestic) 35.0 mph Reindeer 32.0 mph Six-Lined Racerunner 18.0 mph Spider (Tegenaria atrica) 1.2 mph Squirrel 12.0 mph Thomson's Gazelle 50.0 mph Three-Toed Sloth 0.1 mph Warthog 30.0 mph Whippet 35.5 mph White-Tailed Deer 30.0 mph Wild Turkey 15.0 mph Wildebeest 50.0 mph Zebra 40.0 mph""" def main(): #---------------------------------------------------------- # display the list sorted by decreasing speed #---------------------------------------------------------- print( "\n\nCOMPLETE LIST, ORDERED BY DECREASING SPEED" ) list = [] for line in text.split( "\n" ): fields = line.split( ) # skip lines that do not contain a valid count of fields if len( fields ) < 3: continue # create a name and a speed name = fields[0:-2] # all fields except last 2 name = " ".join( name ) # join all fields with a space speed = float( fields[-2] ) # one before last field # create a tuple with speed listed first tuple = (speed, name ) # add it to the list list.append( tuple ) # sort the list in increasing order (smallest speed first) list.sort() # reverse the list list.reverse() # display the list for speed, name in list: print( "{0:30} {1:3.1f}".format( name, speed ) ) #---------------------------------------------------------- # display the 10 fastest in order of decreasing speed #---------------------------------------------------------- print( "\n\n10 FASTEST ANIMALS, ORDERED BY DECREASING SPEED" ) for i in range( min( 10, len( list ) ) ): speed, name = list[i] print( "{0:30} {1:3.1f}".format( name, speed ) ) #---------------------------------------------------------- # display the 10 slowest in order of decreasing speed #---------------------------------------------------------- print( "\n\n10 SLOWEST ANIMALS, ORDERED BY INCREASING SPEED" ) list.reverse() for i in range( min( 10, len( list ) ) ): speed, name = list[i] print( "{0:30} {1:3.1f}".format( name, speed ) ) #---------------------------------------------------------- # display the ratio of fastest to slowest #---------------------------------------------------------- print( "\n\nSPEED-RATIO OF FASTEST TO SLOWEST" ) fastestSpeed, fastestName = list[-1] slowestSpeed, slowestName = list[0] print( "The {0:1} is {1:1.0f} times faster than the {2:1}." .format( fastestName, fastestSpeed/slowestSpeed, slowestName )) #---------------------------------------------------------- # display the animals faster than human beings #---------------------------------------------------------- print( "\n\nANIMALS FASTER THAN HUMAN BEINGS" ) # find the speed of the human speedHuman = 0 for speed, name in list: if name.strip().lower()=="human": speedHuman = speed break # create a list of the animals faster than humans list2 = [] for speed, name in list: if speed > speedHuman: list2.append( name ) # sort the list alphabetically list2.sort() # display the list for name in list2: print( "{0:30}".format( name, speed ) ) if __name__=="__main__": main()
Aquarium
# aquariumLab11.py
# D. Thiebaut
# A graphics program based on Zelle's graphic library.
# Creates an application with the picture of an aquarium
# as the backdrop, then creates a school of fish, and animates
# them, having them move around the aquarium, in a somewhat
# random fashion.
from graphics import *
import random
WIDTH = 700
HEIGHT = 517
class Fish:
"""A class for the fish. Supports randomly moving in the
right to left direction"""
def __init__(self, fileName ):
self.img = Image( Point( random.randrange( WIDTH//2, WIDTH),
random.randrange( HEIGHT) ), fileName )
def draw( self, win ):
"""shows the fish on the graphics window"""
self.img.draw( win )
def moveRandom( self ):
"""moves the fish to the right, randomly. Some random up/down motion"""
deltaX = random.randrange( -5, 0 )
deltaY = random.randrange( -3, 4 )
self.img.move( deltaX, deltaY )
if self.img.getAnchor().getX() < -50:
self.img.move( WIDTH + 100, 0 )
def main():
# open the window
win = GraphWin( "CSC Aquarium", WIDTH, HEIGHT )
# display background
background = Image( Point( WIDTH//2, HEIGHT//2 ), "tank2.gif" )
background.draw( win )
# create a school of fish
fishList = []
for i in range( 10 ):
fish = Fish( "fish0.gif" )
fish.draw( win )
fishList.append( fish )
# animation loop.
while win.checkMouse() == None:
for fish in fishList:
fish.moveRandom()
# one more click to close the window.
win.getMouse()
win.close()
main()
Presidents
# presidents.py # D. Thiebaut text="""Presidency ,President, Took office ,Left office ,Party , Home State 1, George Washington, 30/04/1789, 4/03/1797, Independent, Virginia 2, John Adams, 4/03/1797, 4/03/1801, Federalist, Massachusetts 3, Thomas Jefferson, 4/03/1801, 4/03/1809, Democratic-Republican, Virginia 4, James Madison, 4/03/1809, 4/03/1817, Democratic-Republican, Virginia 5, James Monroe, 4/03/1817, 4/03/1825, Democratic-Republican, Virginia 6, John Quincy Adams, 4/03/1825, 4/03/1829, Democratic-Republican/National Republican, Massachusetts 7, Andrew Jackson, 4/03/1829, 4/03/1837, Democratic, Tennessee 8, Martin Van Buren, 4/03/1837, 4/03/1841, Democratic, New York 9, William Henry Harrison, 4/03/1841, 4/04/1841, Whig, Ohio 10, John Tyler, 4/04/1841, 4/03/1845, Whig, Virginia 11, James K. Polk, 4/03/1845, 4/03/1849, Democratic, Tennessee 12, Zachary Taylor, 4/03/1849, 9/07/1850, Whig, Louisiana 13, Millard Fillmore, 9/07/1850, 4/03/1853, Whig, New York 14, Franklin Pierce, 4/03/1853, 4/03/1857, Democratic, New Hampshire 15, James Buchanan, 4/03/1857, 4/03/1861, Democratic, Pennsylvania 16, Abraham Lincoln, 4/03/1861, 15/04/1865, Republican/National Union, Illinois 17, Andrew Johnson, 15/04/1865, 4/03/1869, Democratic/National Union, Tennessee 18, Ulysses S. Grant, 4/03/1869, 4/03/1877, Republican, Ohio 19, Rutherford B. Hayes, 4/03/1877, 4/03/1881, Republican, Ohio 20, James A. Garfield, 4/03/1881, 19/09/1881, Republican, Ohio 21, Chester A. Arthur, 19/09/1881, 4/03/1885, Republican, New York 22, Grover Cleveland, 4/03/1885, 4/03/1889, Democratic, New York 23, Benjamin Harrison, 4/03/1889, 4/03/1893, Republican, Indiana 24, Grover Cleveland, 4/03/1893, 4/03/1897, Democratic, New York 25, William McKinley, 4/03/1897, 14/9/1901, Republican, Ohio 26, Theodore Roosevelt, 14/9/1901, 4/3/1909, Republican, New York 27, William Howard Taft, 4/3/1909, 4/03/1913, Republican, Ohio 28, Woodrow Wilson, 4/03/1913, 4/03/1921, Democratic, New Jersey 29, Warren G. Harding, 4/03/1921, 2/8/1923, Republican, Ohio 30, Calvin Coolidge, 2/8/1923, 4/03/1929, Republican, Massachusetts 31, Herbert Hoover, 4/03/1929, 4/03/1933, Republican, Iowa 32, Franklin D. Roosevelt, 4/03/1933, 12/4/1945, Democratic, New York 33, Harry S. Truman, 12/4/1945, 20/01/1953, Democratic, Missouri 34, Dwight D. Eisenhower, 20/01/1953, 20/01/1961, Republican, Texas 35, John F. Kennedy, 20/01/1961, 22/11/1963, Democratic, Massachusetts 36, Lyndon B. Johnson, 22/11/1963, 20/1/1969, Democratic, Texas 37, Richard Nixon, 20/1/1969, 9/8/1974, Republican, California 38, Gerald Ford, 9/8/1974, 20/01/1977, Republican, Michigan 39, Jimmy Carter, 20/01/1977, 20/01/1981, Democratic, Georgia 40, Ronald Reagan, 20/01/1981, 20/01/1989, Republican, California 41, George H. W. Bush, 20/01/1989, 20/01/1993, Republican, Texas 42, Bill Clinton, 20/01/1993, 20/01/2001, Democratic, Arkansas 43, George W. Bush, 20/01/2001, 20/01/2009, Republican, Texas""" def main(): # remove the first line from the list of lines lines = text.split( "\n" ) lines = lines[1:] # create a list of tuples list = [] for line in lines: fields = line.split( "," ) # skip invalid lines if len( fields ) != 6: continue # create tuple name = fields[1].strip() yearStart = int( fields[2].split( "/" )[2] ) yearEnd = int( fields[3].split( "/" )[2] ) party = fields[-2].strip() state = fields[-1].strip() tuple = ( name, yearStart, yearEnd, party, state ) # add tuple to list list.append( tuple ) #========================================================= # Display the list of presidents in alphabetical order #========================================================= print( "\n\nAlphabetical List".upper() ) list.sort() for name, y1, y2, party, s in list: print( name ) #========================================================= # Display the list of presidents associated with the democratic # party #========================================================= print( "\n\nAlphabetical List of Democrats".upper() ) for name, y1, y2, party, s in list: if party.lower().find( "democra" )!= -1: print( name ) #========================================================= # Display the president in office in 1945 #========================================================= print( "\n\nPresident in office in 1945".upper() ) for name, y1, y2, party, s in list: if y1 <= 1945 <= y2: print( name ) #========================================================= # Display the president whose home state was Massachusetts #========================================================= print( "\n\nPresident from Massachusetts".upper() ) for name, y1, y2, party, s in list: if s.capitalize().find( "Massa" ) != -1: print( name ) if __name__=="__main__": main()
MyRect, MyCirc, Car
# MyRect.py # D. Thiebaut # This program illustrates how to create and use derived classes. # MyRect is derived from Rectangle, in graphics.py # MyCirc is derived from Cirle, also in graphics.py # Car uses a MyRect object for its body, and a Rectangle for its top. from graphics import * WIDTH = 600 HEIGHT = 400 class MyRect( Rectangle ): def __init__( self, p1, p2, labl ): Rectangle.__init__( self, p1, p2 ) midPoint = Point( (p1.getX()+p2.getX())/2, (p1.getY()+p2.getY())/2 ) self.label = Text( midPoint, labl ) def draw( self, win ): Rectangle.draw( self, win ) self.label.draw( win ) def move( self, dx, dy ): Rectangle.move( self, dx, dy ) self.label.move( dx, dy ) class MyCirc( Circle ): def __init__( self, centr, rad, labl ): Circle.__init__( self, centr, rad ) self.label = Text( centr, labl ) def draw( self, win ): Circle.draw( self, win ) self.label.draw( win ) def move( self, dx, dy ): Circle.move( self, dx, dy ) self.label.move( dx, dy ) 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: def __init__( self, rp, labl ): x = rp.getX() y = rp.getY() p2 = Point( x+180, y+60 ) self.body = MyRect( rp, p2, labl ) self.body.setFill( "yellow" ) self.top = Rectangle( Point( x+10, y-20 ), Point(x+160, y ) ) self.top.setFill( "yellow" ) self.w1 = Wheel( Point( x+20, y+60 ), 20,10 ) self.w2 = Wheel( Point( x+120, y+60 ), 20,10 ) def draw( self, win ): self.body.draw( win ) self.w1.draw( win ) self.w2.draw( win ) self.top.draw( win ) def move( self, dx, dy ): self.body.move( dx, dy ) self.top.move( dx, dy ) self.w1.move( dx, dy ) self.w2.move( dx, dy ) def main(): # open the window win = GraphWin( "CSC111", WIDTH, HEIGHT ) r1 = MyRect( Point( 100, 100 ), Point( 200, 200 ), "CSC111" ) r1.setFill( "Yellow" ) r1.draw( win ) c1 = MyCirc( Point( 200, 200 ), 20, "BALL" ) c1.setFill( "red" ) c1.draw( win ) car = Car( Point( 100,250 ), "TAXI" ) car.draw( win ) while win.checkMouse() == None: for i in range( 20 ): r1.move( 10,2 ) c1.move( 5, 1 ) car.move( 1, 0 ) for i in range( 20 ): r1.move( -10,-2 ) c1.move( -5, 1 ) win.getMouse() win.close() main()
</showafterdate>