Difference between revisions of "CSC111 Lab 12 2015b"

From dftwiki3
Jump to: navigation, search
(Created page with "--~~~~ ---- <center> <font size="+2">Page under construction!</font> </center> <br \> center|300px <!-- ====================================...")
 
 
(14 intermediate revisions by 2 users not shown)
Line 2: Line 2:
 
----
 
----
  
<center>
 
<font size="+2">Page under construction!</font>
 
</center>
 
<br \>
 
[[File:UnderConstruction.jpg|center|300px]]
 
  
 
<!-- ============================================================= -->
 
<!-- ============================================================= -->
Line 16: Line 11:
 
<br />
 
<br />
 
<br />
 
<br />
The deadline for the submission on Moodle is Friday 12/04 at 11:55 a.m.
+
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=
 
<br />
 
<br />
[[Image:MyRectClassLabel.png|right|200px]]
+
[[Image:MyRectClassLabel.png|right|250px]]
 
* Create a new program called '''Lab11_1.py''' and copy the code below into it.
 
* Create a new program called '''Lab11_1.py''' and copy the code below into it.
 
::<source lang="python">
 
::<source lang="python">
Line 96: Line 101:
 
<br />
 
<br />
 
<br />
 
<br />
 +
 
=<center>Discussion Time!</center>=
 
=<center>Discussion Time!</center>=
 
<br />
 
<br />
Line 102: Line 108:
 
* 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.
 
* 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.
 
<br />
 
<br />
 
<!--
 
* Ok, if you thought that the inherited '''move()''' method from the Rectangle class is not what we want to use, because the original Rectangle class does not know anything about the label, you are totally correct.  If, furthermore, you thought you needed to create a new '''move()''' method for '''MyRect()''' that will ''override'' the Rectangle '''move()''' method, then I'm really impressed!
 
* Create a new method called '''move()''' and base its design on the '''draw()''' method, so that it will call '''Rectangle.move()''' to make the yellow rectangle move, and it will activate the '''move()''' method of the label to make it move by the same dx, dy displacement.
 
* Verify that your new program makes the rectangle and the label move together (it's ok if you see some jitter in the motion).
 
-->
 
 
 
<br />
 
<br />
 
<!-- ================================================================ -->
 
<!-- ================================================================ -->
Line 115: Line 114:
 
* 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.
 
* 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.
 
<br />
 
<br />
* Modify the loop in your main program so that it makes both the '''MyRect''' object and the '''MyCirc''' object (that you will have created) move together.   
+
* 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).   
 
<br />
 
<br />
 
<!-- ================================================================ -->
 
<!-- ================================================================ -->
 
=Building a Car with MyRect=
 
=Building a Car with MyRect=
 +
[[File:Simple2WheelCar.png|right|150px]]
 
<br />
 
<br />
* Locate the program you wrote  a while back, that displays a car on the graphic window (with a body, two wheels and a top).
+
* 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.   
 
* 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.
 
* Copy the car class in your current program for today's lab.
Line 127: Line 127:
 
<br />
 
<br />
 
* 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.
 
* 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.
* 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'''.
 
 
<br />
 
<br />
<!-- ================================================================ -->
+
::<source lang="text">
=Problem 2: Aquarium=
+
      ;header
<br />
+
     
* Point your browser to [[Fish_for_an_Aquarium|this page]] and drag the tank image and a couple fish images to your desktop.
+
      Class MyRect:
 
+
          ...
* Write a new program called '''lab11_2.py''' and copy/paste the following code in it:
 
<br />
 
::<source lang="python">
 
# lab11_2.py
 
# Displays fish in an aquarium
 
 
 
from graphics import *
 
import random
 
 
 
WIDTH  = 700  # geometry of the tank2.gif file
 
HEIGHT = 517
 
 
 
 
          
 
          
def main():
+
      Class Wheel:
    # open the window
+
          ...
    win = GraphWin( "CSC Aquarium", WIDTH, HEIGHT )
 
 
 
    # display background image
 
    background = Image( Point( WIDTH//2, HEIGHT//2 ), "tank2.gif" )
 
    background.draw( win )
 
 
 
    # display the image of a fish at a random location
 
    fish = Image( Point( random.randrange( WIDTH),
 
                        random.randrange( HEIGHT) ),
 
                  "fish0.gif" )
 
    fish.draw( win )
 
 
 
    # close window when user clicks it
 
    win.getMouse()
 
    win.close()
 
   
 
main()
 
  
 +
      Class Car:
 +
          ...
  
 +
      def main():
 +
          ...
  
 +
      main()
 +
 
 
</source>
 
</source>
  
* Create a new class called '''Fish'''.
+
* 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.
* Include a '''constructor''' that received the name of the gif file for the fish.
+
* Verify that your program correctly displays the modified car.
* Include a '''member variable''' in the class to hold the image (Image class in graphics.py) of the fish.
+
* Make your car move some deltax, deltay in a loop, the same way you moved the MyRect and MyCirc objects in the previous problemVerify that the car moves correctly, '''including its label'''.
* Add a '''draw()''' method to the class, that will allow the main program to have the fish draw itself on the graphic window (win).
 
* Add a '''moveRandom()''' method to the class, that will move the image of the fish some random deltaX and deltaY on the graphic windowReminder: user <tt>random.randrange( 10 )</tt> to generate a random number between 0 and 10, and use <tt>random.randrange( -10, 0 )</tt> to generate a random number between -10 and 0 (not included).
 
* Modify the main program so that it simply creates and displays a fish object, as shown below:
 
<br />
 
::<source lang="python">
 
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 )
 
 
 
    # display a fish
 
    fish = Fish( "fish0.gif" )
 
    fish.draw( win )
 
 
 
    win.getMouse()
 
    win.close()
 
 
 
</source>
 
 
<br />
 
<br />
* When your code works, and only then, add a loop to make the fish move:
 
<br />
 
::<source lang="python">
 
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 )
 
 
    # display a fish
 
    fish = Fish( "fish0.gif" )
 
    fish.draw( win )
 
 
    # animation loop
 
    while win.checkMouse() == None:
 
        fish.moveRandom()
 
 
    win.getMouse()
 
    win.close()
 
 
</source>
 
 
<br />
 
* Modify the moveRandom() method so that the fish disappears from the graphics window, it is moved back on the other side of the aquarium.
 
* Create a list of 10 fish with the "fish0.gif" image, and add 10 fish with the "fish20.gif" image (or some fish that is headed in the opposite direction).
 
* Modify the Fish class so that you can define the direction a fish goes into when you create it. 
 
* Verify that the fish swim in the correct direction.
 
* Demonstrate your program to the lab instructor or a TA when you're done.
 
 
<br />
 
<br />
 
<br />
 
<br />
Line 241: Line 164:
 
* Edit the text variable, and make it contain only 5 lines of text (it doesn't matter what countries you pick).
 
* 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.
 
* 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 two problems.
+
* Using a similar approach, solve the next problem.
 
<br />
 
<br />
  
 
<!-- ================================================================ -->
 
<!-- ================================================================ -->
=Problem 3: Animals=
+
=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 '''Lab11_3.py''' (no need to write classes for this problem) based on the preparation problem above, and make your program output the following quantities:
+
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
 
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  
 
Pig (domestic) 11.0 mph  
 
Pronghorn Antelope 61.0 mph  
 
Pronghorn Antelope 61.0 mph  
Line 290: Line 194:
 
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
 +
Human 27.9 mph
 
</source>
 
</source>
 
<br />
 
<br />
<!-- ================================================================ -->
+
Your output should look like:
=Problem 4: Presidents=
+
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 />
 
<br />
Below is a CSV list (coma-separated values) of past presidents.  Using similar Python code as you have used for the previous problem, write a program ('''Lab11_4.py''') that will process this list and output:
+
Make sure your program puts the string -*- on a line just before you begin printing the output
<br />
+
 
# the list of presidents sorted alphabetically.  Your program should simply print the names, one per line.  No additional information is required.
+
Submit your program to Moodle as lab12.py
# the list of all the presidents who were associated with the democratic party.
+
</showafterdate>
# the person who was president in 1945.
 
# the presidents whose home state was Massachusetts.
 
::<source lang="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
 
  
</source>
+
<!-- =========================================================== -->
<br />
+
<!--  SOLUTION PROGRAMS -->
 +
<!-- =========================================================== -->
 
<br />
 
<br />
=Moodle Submission=
+
<showafterdate after="20151205 00:00" before="20151231 00:00">
<br />
 
Demonstrate the correct behavior of your aquarium to your lab instructor.  Submit your solution program for the presidents problem on Moodle, in the Lab11 PB4 section. 
 
<br />
 
 
 
 
 
<showafterdate after="20150417 11:00" before="20150601 00:00">
 
 
=Solution Programs=
 
=Solution Programs=
 
==Animals ==
 
==Animals ==
Line 795: Line 679:
  
 
</source>
 
</source>
= =
 
<br />
 
::<source lang="python">
 
 
</source>
 
= =
 
<br />
 
::<source lang="python">
 
 
</source>
 
= =
 
<br />
 
::<source lang="python">
 
 
</source>
 
= =
 
<br />
 
::<source lang="python">
 
 
</source>
 
= =
 
<br />
 
::<source lang="python">
 
 
</source>
 
= =
 
<br />
 
::<source lang="python">
 
 
</source>
 
= =
 
<br />
 
::<source lang="python">
 
 
</source>
 
 
 
</showafterdate>
 
</showafterdate>
<br />
 
<onlydft>
 
=VPL=
 
 
==vpl_run.sh==
 
<br />
 
<source lang="bash">
 
#! /bin/bash
 
 
cat > vpl_execution <<EOF
 
#! /bin/bash
 
 
# --- Python ----
 
if [[ `hostname -s` = "beowulf2" ]]; then
 
  python=/usr/bin/python3.3
 
else
 
  python=/usr/local/bin/python3.4
 
fi
 
 
prog=lab11_4.py
 
 
\$python \$prog
 
 
 
 
EOF
 
 
chmod +x vpl_execution
 
 
 
</source>
 
<br />
 
==vpl_debug.sh==
 
<br />
 
<source lang="bash">
 
</source>
 
<br />
 
==vpl_evaluate.sh==
 
<br />
 
<source lang="bash">
 
#! /bin/bash
 
 
cat  > vpl_execution <<EOF
 
#! /bin/bash
 
 
# --- Python ----
 
if [[ `hostname -s` = "beowulf2" ]]; then
 
  python=/usr/bin/python3.3
 
else
 
  python=/usr/local/bin/python3.4
 
fi
 
 
 
\$python evaluate.py
 
 
EOF
 
 
chmod +x vpl_execution
 
 
 
</source>
 
<br />
 
==vpl_evaluate.cases==
 
<br />
 
<source lang="text">
 
</source>
 
<br />
 
==evaluate.py==
 
<br />
 
<source lang="python">
 
# evaluate.py
 
 
listPres="""Clinton 2
 
Ford 1
 
Jefferson 2
 
Arthur 1
 
Taylor 1
 
Roosevelt 4
 
Taft 1
 
Nixon 1
 
Tyler 1
 
Jackson 2
 
Wilson 2
 
Monroe 2
 
Harding 1
 
Eisenhower 1
 
Adams 5
 
Madison 2
 
Buren 2
 
Garfield 1
 
Kennedy 3
 
McKinley 1
 
Hayes 1
 
Bush 2
 
Washington 1
 
Reagan 1
 
Cleveland 4
 
Johnson 4
 
Harrison 2
 
Hoover 1
 
Lincoln 1
 
Grant 1
 
Pierce 2
 
Truman 3
 
Coolidge 2
 
Buchanan 2
 
Fillmore 1
 
Polk 2
 
Carter 2"""
 
 
expectedOutputText = """ALPHABETICAL LIST
 
Abraham Lincoln
 
Andrew Jackson
 
Andrew Johnson
 
Benjamin Harrison
 
Bill Clinton
 
Calvin Coolidge
 
Chester A. Arthur
 
Dwight D. Eisenhower
 
Franklin D. Roosevelt
 
Franklin Pierce
 
George H. W. Bush
 
George W. Bush
 
George Washington
 
Gerald Ford
 
Grover Cleveland
 
Grover Cleveland
 
Harry S. Truman
 
Herbert Hoover
 
James A. Garfield
 
James Buchanan
 
James K. Polk
 
James Madison
 
James Monroe
 
Jimmy Carter
 
John Adams
 
John F. Kennedy
 
John Quincy Adams
 
John Tyler
 
Lyndon B. Johnson
 
Martin Van Buren
 
Millard Fillmore
 
Richard Nixon
 
Ronald Reagan
 
Rutherford B. Hayes
 
Theodore Roosevelt
 
Thomas Jefferson
 
Ulysses S. Grant
 
Warren G. Harding
 
William Henry Harrison
 
William Howard Taft
 
William McKinley
 
Woodrow Wilson
 
Zachary Taylor
 
 
ALPHABETICAL LIST OF DEMOCRATS
 
Andrew Jackson
 
Andrew Johnson
 
Bill Clinton
 
Franklin D. Roosevelt
 
Franklin Pierce
 
Grover Cleveland
 
Grover Cleveland
 
Harry S. Truman
 
James Buchanan
 
James K. Polk
 
James Madison
 
James Monroe
 
Jimmy Carter
 
John F. Kennedy
 
John Quincy Adams
 
Lyndon B. Johnson
 
Martin Van Buren
 
Thomas Jefferson
 
Woodrow Wilson
 
 
PRESIDENT IN OFFICE IN 1945
 
Franklin D. Roosevelt
 
Harry S. Truman
 
 
PRESIDENT FROM MASSACHUSETTS
 
Calvin Coolidge
 
John Adams
 
John F. Kennedy
 
John Quincy Adams
 
 
"""
 
# evaluate.py
 
# D. Thiebaut
 
# This program is used to test a student's python program on Moodle.
 
 
import sys
 
import random
 
import subprocess
 
 
#--- GLOBALS ---
 
#--- define what the student program is called, and what the solution
 
#--- program name is.
 
 
 
module = "lab11_4"
 
solutionModule = module + "sol"
 
userOutSplitPattern = ""      # pattern used to start recording the user
 
                              # output.  Useful when program does several
 
                              # input() statements, and user output starts
 
                              # after that.
 
stripOutputsBeforeCompare = True
 
                              # set to True if extra spaces at beginning or
 
                              # end of user output is ok
 
stripDoubleSpaceBeforeCompare = True
 
                              # set to True if double spaces must be removed in
 
                              # outputs
 
interpreter = sys.executable
 
 
def commentLong( line ):
 
    print( "<|--\n" + line  + "\n --|>" )
 
 
def commentShort( text ):
 
    print( "Comment :=>> " + text )
 
 
def printGrade( grade ):
 
    print( "Grade :=>> ", grade )
 
 
# generateInputFileWithRandomInputs
 
# generate a file with name "inputFileName" with some random input
 
# for the program.
 
# MAKE SURE TO EDIT THIS TO MATCH THE PROGRAM BEING TESTED
 
def generateInputFileWithRandomInputs( inputFileName ):
 
    #--- we don't need an input file for stdin, but we'll generate a
 
    #--- dummy one nonetheless
 
    #--- generate random inputs ---
 
    return ""
 
 
# removeIf__name__: re
 
def removeIf__name__( moduleName  ):
 
 
    file = open( moduleName + ".py", "r" )
 
    lines = file.readlines()
 
    file.close()
 
 
    newLines = []
 
    for line in lines:
 
        if line.find( "if __name__" ) != -1:
 
            line = "if True:\n"
 
        newLines.append( line.rstrip() )
 
 
    file = open( moduleName + ".py", "w" )
 
    file.write( "\n".join( newLines ) )
 
    file.close()
 
 
# checkForFunctionPresence
 
# checks that "functionName" is defined and called in the program.
 
# MAKE SURE TO EDIT TO MATCH PROGRAM BEING TESTED
 
def checkForFunctionPresence( module, functionName ):
 
    foundDef = False
 
    foundCall = False
 
 
    for line in open( module+".py", "r" ).readlines():
 
        # remove comments
 
        idx = line.find( "#" )
 
        if ( idx >=0 ): line = line[0:idx]
 
 
        if line.startswith( "def " + functionName + "(" ):
 
            foundDef = True
 
            continue
 
        if line.startswith( "def " + functionName + " (" ):
 
            foundDef = True
 
            continue
 
        if line.find( functionName+"(" ) != -1:
 
            foundCall = True
 
            continue
 
 
    return (foundDef, foundCall)
 
 
 
 
# ==================================================================
 
# NO EDITS NEEDED BELOW!
 
# ==================================================================
 
 
def clearLog():
 
    open( "log.txt", "w" ).write( "" )
 
 
def log( message ):
 
    file = open( "log.txt", "a" )
 
    file.write( message + "\n" )
 
    file.flush()
 
    file.close()
 
 
 
# checkModuleRunsOK: runs the module as a shell subprocess and
 
# look for errors in the output.  This is required, because otherwise
 
# importing the module in this program will make this program crash.
 
# It's not possible (as far as I can tell0 to catch exceptions from
 
# the import or __module__ statements.
 
# returns True, none if no errors, otherwise False, string if there's
 
# an exception, and the error message (string) is in the returned 2nd
 
# arg.
 
# The module name is assumed to not include ".py"
 
def checkModuleRunsOk( module, inputFileName ):
 
    global interpreter
 
    p = subprocess.Popen( [ interpreter, module+".py" ],
 
                          stdout=subprocess.PIPE,
 
                          stderr=subprocess.PIPE,
 
                          stdin=subprocess.PIPE)
 
 
    #print( "inputFileName = ", inputFileName )
 
    #print( "open( inputFileName, r).read() = ", open( inputFileName, "r" ).read() )
 
 
    p.stdin.write( bytes( "\n\n\n\n", 'UTF-8' ) )
 
    data = p.communicate( )
 
    p.stdin.close()
 
 
    error = data[1].decode( 'UTF-8' )
 
    if len( error ) > 1:
 
        return False, error
 
    return True, None
 
 
 
# extractTextFromErrorMessage( sys_exc_info ):
 
def extractTextFromErrorMessage( sys_exc_info ):
 
    print( "sys_exec_info = ", sys_exc_info )
 
    text = ""
 
    for field in sys_exc_info:
 
        if type( field )==type( " " ):
 
            text += field + "\n"
 
    return text
 
 
# runModule:
 
# runs the module, passes it data from the input file on its stdin
 
# and get its output on stdout captured in outputFileName.
 
# We assume the module will not crash, because we already tested
 
# it with checkModuleRunsOk().
 
def runModule( module, inputFileName, outputFileName ):
 
    global userOutSplitPattern
 
 
    # remove the if __name__=="__main__": statement
 
    removeIf__name__( module )
 
 
    error = False
 
 
    #--- make stdin read information from the text file
 
    #sys.stdin = open( inputFileName, "r" )
 
 
    #--- capture the stdout of the program to test into a file
 
    saveStdOut = sys.stdout
 
    saveStdErr = sys.stderr
 
 
    sys.stdout = open( outputFileName, "w" )
 
    sys.stderr = open( "errorOut", "w" )
 
 
    #--- run the student program ---
 
    try:
 
        _module = __import__(  module  )
 
    except:
 
        error = True
 
        sys.stderr.close()
 
        sys.stderr = saveStdErr
 
        sys.stdout.close()
 
        sys.stdout = saveStdOut
 
        text = sys.exc_info()[0]
 
        text = extractTextFromErrorMessage( text )
 
        print( "*** sys.exc_info() = ", text )
 
        text = open( outputFileName, "r" ).read() + "\n" + text
 
        return text
 
 
    #--- filter out junk from output of program ---
 
    sys.stdout.close()
 
    sys.stdout = saveStdOut
 
    sys.stderr.close()
 
    sys.stderr = saveStdErr
 
 
    file = open( outputFileName, "r" )
 
    text = file.read()
 
    #print( "output = ", text )
 
    file.close()
 
    return text
 
 
def removeBlankLines( lines ):
 
    newLines = []
 
    log( "removeBlankLines: lines = " + str( lines ) )
 
    for line in lines.split( "\n" ):
 
        if len( line )==0:
 
            continue
 
        newLines.append( line )
 
 
    return ( "\n".join( newLines ) ) + "\n"
 
 
def compareUserExpectedGrep( inputLines, userOutText, expectedOutText ):
 
    list = []
 
    for line in listPres.split( "\n" ):
 
        fields = line.split( )
 
        if len( fields ) != 2: continue
 
        pres = fields[0].strip().lower()
 
        count = int( fields[1].strip() )
 
        list.append( (pres, count) )
 
 
    input = userOutText.lower()
 
    #print( "input = ", input )
 
 
    sumUser    = 0
 
    sumExpected = 0
 
    for pres, count in list:
 
        c = input.count( pres )
 
        sumUser += c
 
        sumExpected += count
 
        #print( "pres=%s count=%d c=%d sumuser=%d sumExpected=%d"
 
        #      % ( pres, count, c, sumUser, sumExpected ) )
 
    return (sumUser * 100.0 )/sumExpected
 
 
 
 
def compareUserExpected( inputLines, userOutText, expectedOutText ):
 
    import re
 
    global stripOutputsBeforeCompare
 
 
    userOutText = removeBlankLines( userOutText )
 
    expectedOutText = removeBlankLines( expectedOutText )
 
    misMatchLineNumbers = []
 
    userTextOutLines = userOutText.split( "\n" )
 
    expectedOutTextLines = expectedOutText.split( "\n" )
 
 
 
    for i in range( len( userTextOutLines ) ):
 
        lineNo = i+1
 
        userLine = userTextOutLines[i]
 
        if i >= len( expectedOutTextLines ):
 
            misMatchLineNumbers.append( lineNo )
 
            break
 
        expectedLine = expectedOutTextLines[i]
 
        log( "comparing:\n  "+userLine+"\n  "+expectedLine )
 
 
        if stripOutputsBeforeCompare:
 
            userLine = userLine.strip()
 
            expectedLine = expectedLine.strip()
 
 
        if stripDoubleSpaceBeforeCompare:
 
            userLine = re.sub(' +',' ', userLine )
 
            expectedLine = re.sub( ' +', ' ', expectedLine )
 
 
        if userLine != expectedLine:
 
            log( "\ndifference: user    >" + userTextOutLines[i] + "<" )
 
            log( "expected >" + expectedOutTextLines[i] + "<" )
 
            misMatchLineNumbers.append( lineNo )
 
 
    return misMatchLineNumbers
 
 
 
 
def main():
 
    global module
 
    global solutionModule
 
 
    #--- clear debug log ---
 
    clearLog()
 
 
    #--- check that the main module uses a main() function
 
    """
 
    foundDef, foundCall = checkForFunctionPresence( module, "main" )
 
 
    if (not foundDef) or (not foundCall):
 
        commentShort( "-Missing main() program" )
 
        commentShort( "Your program must use a main() function." )
 
        commentShort( "(make sure you spell it exactly \"main()\"!" )
 
        printGrade( 40 )
 
        return
 
    """
 
    inputFileName = "cats.csv"
 
 
    #--- generate input file with random data ---
 
    inputLines = generateInputFileWithRandomInputs( inputFileName )
 
 
 
    Ok, errorMessage = checkModuleRunsOk( module, inputFileName )
 
    if not Ok:
 
        commentLong( "- Your program crashed...\n"
 
                    + "Error message:\n"
 
                    + errorMessage + "\n" )
 
        printGrade( 50 )
 
        return
 
 
    expectedOutText = runModule( solutionModule, inputFileName, "expectedOut" )
 
    userOutText = runModule( module, inputFileName, "userOut" )
 
 
    #print( "expectedOutText = ", expectedOutText )
 
    #print( "userOutText = ", userOutText )
 
 
    #missMatches = compareUserExpected( inputLines, userOutText, expectedOutText )
 
    percentMatches = compareUserExpectedGrep( inputLines, userOutText, expectedOutText )
 
 
 
    if abs(100-percentMatches) < 10: printGrade( 100 )
 
    elif abs(100-percentMatches) <20: printGrade( 90 )
 
    elif abs(100-percentMatches) <30: printGrade( 80 )
 
    elif abs(100-percentMatches) <40: printGrade( 65 )
 
    elif abs(100-percentMatches) <50: printGrade( 50 )
 
    else: printGrade( 10 )
 
 
    if abs( 100 - percentMatches ) >= 10:
 
        commentLong( "Your output does not match the expected output:\n"+expectedOutputText )
 
    else:
 
        commentLong( "Congrats, your output is correct." )
 
 
 
    #if len( missMatches ) != 0:
 
    #    commentLong( "- Incorrect output...\n"
 
    #                +"Expected output:\n"
 
    #                +expectedOutText + "\n"
 
    #                +"Your output:\n"
 
    #                +userOutText + "\n" )
 
    #    printGrade( 75 )
 
    #else:
 
    #    commentLong( "- Your program passes the test\n" )
 
    #    printGrade( 100 )
 
 
 
main()
 
 
 
 
</source>
 
<br />
 
==lab11_4sol.py==
 
<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 )
 
 
    allPres = {}
 
    #=========================================================
 
    # 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 )
 
        lastName = name.split()[-1].strip()
 
        try:
 
            allPres[lastName] += 1
 
        except:
 
            allPres[lastName] = 1
 
 
    print()
 
 
    #=========================================================
 
    # 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 )
 
            lastName = name.split()[-1].strip()
 
            try:
 
                allPres[lastName] += 1
 
            except:
 
                allPres[lastName] = 1
 
 
    print()
 
    #=========================================================
 
    # 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 )
 
            lastName = name.split()[-1].strip()
 
            try:
 
                allPres[lastName] += 1
 
            except:
 
                allPres[lastName] = 1
 
 
    print()
 
    #=========================================================
 
    # 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 )
 
            lastName = name.split()[-1].strip()
 
            try:
 
                allPres[lastName] += 1
 
            except:
 
                allPres[lastName] = 1
 
 
    #print()
 
    #for name in allPres.keys():
 
    #    print( name, allPres[name ] )
 
 
if True:
 
    main()
 
 
</source>
 
<br />
 
\
 
</onlydft>
 
 
<br />
 
<br />
 
<br />
 
<br />

Latest revision as of 21: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.





<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


MyRectClassLabel.png
  • 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...



ThinkThinkThink.jpg



  • Think some more. Do not move on until you are sure you know what is going on...



ThinkThinkThink.jpg



Discussion Time!


Discussion.jpg


  • 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

Simple2WheelCar.png


  • 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:

  1. The list of all the animals ranked by speed. Fastest first.
  2. The 10 fastest animals listed in order of decreasing speed
  3. The 10 slowest animals listed in order of increasing speed
  4. 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.
  5. 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>