Difference between revisions of "CSC111 Homework 6 2011"

From dftwiki3
Jump to: navigation, search
(Demo Program)
(Submission)
 
(20 intermediate revisions by the same user not shown)
Line 6: Line 6:
 
| <bluebox>
 
| <bluebox>
  
This homework assignment is due on April Fool's Day, 4/1/10, at midnight.
+
This homework assignment is due on Nov. 1st, in the evening, at midnight.
  
You can work on Problem #1 in pairs.   
+
You can work on Problem #1 and on Problem #2 in pairs.  You can submit both programs using '''rsubmit''' on beowulf, or by using the submit form at http://cs.smith.edu/~111a/submit6.htm
 
 
Problem #2 is optional and extra-credit, and if you work on it, you must work on it on your own.  
 
  
 
</bluebox>
 
</bluebox>
Line 18: Line 16:
 
<br />
 
<br />
 
<br />
 
<br />
 
+
<center>
 +
<font color="red">'''The due date has been pushed to 11/3/2011 due to the power outage.  Also, putting a white box in the graphics window against which the circles are going to bounce off is optional.  If you have already coded it, it will count as extra credit.''</font>
 +
</center>
 +
<br />
 +
<br />
 
==Problem #1==
 
==Problem #1==
  
Line 26: Line 28:
  
 
<source lang="python">
 
<source lang="python">
 +
# hw6a.py
 +
# D. Thiebaut
 
# This program shows two balls moving in the graphics window.
 
# This program shows two balls moving in the graphics window.
 
# One is yellow, one is magenta.  The magenta ball is not bound
 
# One is yellow, one is magenta.  The magenta ball is not bound
Line 40: Line 44:
 
   
 
   
 
def main():
 
def main():
     """Opens a graphics window 300x300 and draws a button on
+
     """Opens a graphics window 600x300 and draws two circles on it"""
    it.  Then wait for the user to click the mouse 10 times
 
    before exiting"""
 
 
     W = 600
 
     W = 600
 
     H = 300
 
     H = 300
Line 85: Line 87:
 
</source>
 
</source>
  
===Statement===
+
===Assignment===
Write a program called '''hw6a.py''' that moves two balls on the graphics screen.
+
# Modify the program hw6a.py so that the '''two''' balls bounce off the walls of the window, not just one.
# the two balls should bounce off the walls (border of the graphics window)
+
# Make the balls bounce when their side hits the walls, not their center.
# the two balls should bounce off each other.
+
# Make the two balls bounce off when they hit each other (the way pool-table balls would).  
# there should be three black boxes in the graphics window, and if any one of the two balls happens to move completely inside any one of the boxes, it should stop there.  
+
# There should be three black boxes in the graphics window, and if any one of the two balls happens to move '''completely inside''' any one of the boxes, it should stop there.  
# the program should stop and display ''click to End'' when the simulation has gone through 300 steps, or as soon as the two balls have been immobilized in boxes.
+
# the program should stop and display ''click me to quit'' when the simulation has gone through 1000 steps, '''or as soon as the two balls have been immobilized in boxes'''.
# there should be a fourth box, this one white, which should act as an obstacle.  Any time a ball hits the white box, it should bounce off the walls of the box, in a same way it bounces off the walls.
+
#<font color="red">'''Optional''': there should be a fourth box, this one white, which should act as an obstacle.  Any time a ball hits the white box, it should bounce off the walls of the box, in a same way it bounces off the walls.
 +
</font>
  
 
===Requirements===
 
===Requirements===
* Use boolean functions
+
* Use a list to hold the black boxes (defined by their coordinates).  The idea is too hold the boxes in a list rather than having 3 different variables to keep track of the thee boxes.  This way if we wanted to create a large window with, say, 100 boxes, your program could easily adapt: all we would have to do is just add more rectangles to the list.
* Use a list to hold the black boxes.
+
 
 +
* Below is an example of how you could keep track of 3 boxes in a list called ''boxes'':
 +
 
 +
<br />
 +
<br />
 +
<source lang="python">
 +
        # P1, P2, P3, P4, P5, and P6 are 6 points in the graphics window
 +
        boxes = []
 +
        r = Rectangle( P1, P2 )
 +
        boxes.append( r )
 +
        r = Rectangle( P3, P4 )
 +
        boxes.append( r )
 +
        r = Rectangle( P5, P6 )
 +
        boxes.append( r )
 +
 
 +
</source>
 +
<br />
 +
<br />
 +
 
 
* You are free to select the size of the white and black boxes, but make them big enough to allow balls to hit them regularly, but not too big so as to make the balls "fall" in a black box before having time to hit a few walls or the white box.
 
* You are free to select the size of the white and black boxes, but make them big enough to allow balls to hit them regularly, but not too big so as to make the balls "fall" in a black box before having time to hit a few walls or the white box.
 
* Include your account name(s) or your first name(s) in the title of the graphics window to make it easier to identify printed screen captures of your running program:
 
* Include your account name(s) or your first name(s) in the title of the graphics window to make it easier to identify printed screen captures of your running program:
  
       win = GraphWin( W, H, "111c-xx 111c-yy" )
+
       win = GraphWin( W, H, "111a-xx's billiard program" )
  
 
===Realism===
 
===Realism===
* It is not easy nor possible with our current knowledge of Python to make the bouncing of the balls off each other realistic.  When a ball hits a wall, the rule is very nice and clear: we change the sign of either dx or dy, depending on which is perpendicular to the wall.  When the balls hit each other, both dx and dy would normally change.  The real equation for how dx and dy change is too complicated for us.  Invent your own laws of physics and  implement them in python!
+
* It is not easy nor possible with our current knowledge of Python to make the balls bounce off each other in a  realistic way.  When a ball hits a wall, the rule is very nice and clear: we change the sign of either dirX or dirY, depending on which is perpendicular to the wall.  When the balls hit each other, both dirX and dirY would normally change.  The real equation for how dirX and dirY change is too complicated for us.  Invent your own laws of physics and  implement them in python!
  
 
===Submission===
 
===Submission===
  
 
* Make sure the header of your program contains your names and account numbers, if working in pairs, or just your name and account number if working individually.
 
* Make sure the header of your program contains your names and account numbers, if working in pairs, or just your name and account number if working individually.
 +
 
* Submit your program as follows:
 
* Submit your program as follows:
  
     submit hw8 hw8a.py
+
     rsubmit hw6 hw6a.py
  
 
===Additional Information===
 
===Additional Information===
Line 118: Line 140:
 
   
 
   
 
  def distance( P1, P2 ):
 
  def distance( P1, P2 ):
       """Computes the distance between Point P1 and Point P2. The returned value is a float"""
+
       """Computes the distance between Point P1 and Point P2.  
       return sqrt( pow( P1.getX() - P2.getX(), 2 ) + pow( P1.getY() - P2.getY(), 2 ) )
+
          The returned value is a float
 +
      """
 +
       d = sqrt( pow( P1.getX() - P2.getX(), 2 ) + pow( P1.getY() - P2.getY(), 2 ) )
 +
      return d
 +
 
 +
* Here is a way it could be used:
 +
 
 +
  P1 = Point( x1, y1 )
 +
  P2 = Point( x2, y2 )
 +
 
 +
  ...
 +
 +
  if distance( P1, P2 ) > 30:
 +
      # do something if the points are more than 30 pixels away from each other
 +
  else
 +
      # do something else if the points are closer than 30 pixels
 +
 
 +
=Problem #2=
 +
 
 +
[[Image:stateOfTheInternet.jpg | right | link=http://mashable.com/2010/02/26/state-of-internet/ ]]
 +
* This second program should be called '''hw6b.py''', but before you start on it, though, play with the following program and figure out how it works.  It will provide you with some good clues for how to code hw6b.py.
  
==Problem #2: Optional and Extra Credits==
+
<source lang="python">
 +
# people.py
 +
# D. Thiebaut
 +
# a demo program illustrating how to sort an array of pairs.
 +
# a pair is a list with 2 items.  Here each pair contains a string, and
 +
# an integer.  The string is the name of a person, the integer that person's
 +
# age.
  
<bluebox>
+
def main():
This part is extra credit and optional. You cannot work on it in pairs, but you must work on it on your own.  If you submit a program that is  
+
    people = [ ["Marie", 16], ["Joe", 33], ["Alex", 30], ["Fred", 5 ] ]
* well documented, and that
+
 
* runs flawlessly when tested,  
+
    # sort the list by alphabetical order
you will get an additional 1/3 point on your midterm grade. So, if you had gotten B+, this extra-credit part will bring you to A- total. 
+
    people.sort()
</bluebox>
+
 
 +
    # display the contents of the list in alphabetical order
 +
    for person, age in people:
 +
        print( "%30s: %4d" % ( person, age ) )
 +
 
 +
    print()
 +
 
 +
    # create a new list of people, this time the age is first in
 +
    # each pair.
 +
    newPeople = []
 +
    for person, age in people:
 +
        newPeople.append( [age, person] )
  
<!--center>[[File:UnderConstruction.jpg | 150px | Under Construction]]<br />Under Construction...</center-->
+
    # sort by age, in increasing order
 +
    newPeople.sort()
  
* Your assignment is to write a program that will read a long string of characters which represents the results of a computer experiment.
+
    # display the contents of the list, ordered by age
:In this experiment, many different computers (88) are asked to compute a number and return this result to a main computer.  The main computer outputs all the different answers in a long listing.  It is this listing that your program has to read, analyze, and process.
+
    for age, person in newPeople:
 +
        print( "%-30s: %4d" % ( person, age ) )
  
* To see what the list looks like, use getcopy to get two programs into your account:
+
    # find the oldest person
 +
    age, person = max( newPeople )
 +
    print( "\nThe oldest person is", person," who's", age, "years old.\n\n" )
 +
   
 +
main()
  
getcopy hw8b.py
+
     
getcopy montecarlo.pyc
 
  
:montecarlo.pyc is a module that is used by hw8b.py.
 
  
* Run the hw8b.py program and observe its output:
+
</source>
 +
<br />
 +
<br />
 +
 
 +
* Now that you have played with people.py, try this new program, called '''hw6b.py''':
 +
<br />
 +
<br />
 +
<source lang="python">
 +
# hw6b.py
 +
# your name
 +
#
 +
 +
statistics = [['Afghanistan', 28710000, -1, -1, 1], ['Albania', 3580000,
 +
12000, -1, 10], ['Algeria', 32810000, 180000, -1, 2],
 +
['Andorra', 69150, 24500, -1, 1], ['Angola', 10760000,
 +
60000, -1, 1], ['Anguilla', 12738, 919, -1, 16],
 +
['Antigua_and_Barbuda', 67897, 5000, -1, 16], ['Argentina',
 +
38740000, 4650000, -1, 33], ['Armenia', 3320000, 30000, -1,
 +
9], ['Aruba', 70844, 24000, -1, -1], ['Australia', 19730000,
 +
13010000, 9020000, 571], ['Austria', 8180000, 4650000,
 +
1300000, 37], ['Azerbaijan', 7830000, 25000, -1, 2],
 +
['Bahrain', 667238, 140200, -1, 1], ['Bangladesh',
 +
138440000, 150000, -1, 10], ['Barbados', 277264, 6000, -1,
 +
19], ['Belarus', 10330000, 422000, -1, 23], ['Belgium',
 +
10280000, 4870000, 1600000, 61], ['Belize', 266440, 18000,
 +
-1, 2], ['Benin', 7040000, 25000, -1, 4], ['Bhutan',
 +
2130000, 2500, -1, -1], ['Bolivia', 8580000, 78000, -1, 9],
 +
['Bosnia_and_Herzegovian', 3980000, 45000, -1, 3],
 +
['Botswana', 1570000, 33000, -1, 11], ['Brazil', 182030000,
 +
22320000, 10860000, 50], ['Brunei', 358098, 35000, -1, 2],
 +
['Bulgaria', 7530000, 1610000, -1, 200], ['Burkina_Faso',
 +
13220000, 25000, -1, 1], ['Burma', 42510000, 10000, -1, 1],
 +
['Burundi', 6090000, 6000, -1, 1], ['Cambodia', 13120000,
 +
10000, -1, 2], ['Cameroon', 15740000, 45000, -1, 1],
 +
['Canada', 32200000, 20450000, 8800000, 760], ['Cape_Verde',
 +
412137, 12000, -1, 1], ['Cayman_Islands', 41934, -1, -1,
 +
16], ['Central_African_Republic', 3680000, 2000, -1, 1],
 +
['Chad', 9250000, 4000, -1, 1], ['Chile', 15660000, 5040000,
 +
-1, 7], ['China', 1280000000, 99800000, -1, 3], ['Colombia',
 +
41660000, 1870000, -1, 18], ['Comoros', 632948, 2500, -1,
 +
1], ['Republic_of_the_Congo_Democratic', 56620000, 6000, -1,
 +
1], ['Congo_Republic', 2950000, 500, -1, 1],
 +
['Cook_Islands', 21008, -1, -1, 3], ['Costa_Rica', 3890000,
 +
384000, -1, 3], ['Cote_d_Ivoire', 16960000, 70000, -1, 5],
 +
['Croatia', 4420000, 480000, -1, 9], ['Cuba', 11260000,
 +
120000, -1, 5], ['Cyprus', 771657, 150000, -1, 6],
 +
['Czech_Republic', 10240000, 3530000, -1, 300], ['Denmark',
 +
5380000, 3720000, -1, 13], ['Djibouti', 457130, 3300, -1,
 +
1], ['Dominica', 69655, 2000, -1, 16],
 +
['Dominican_Republic', 8710000, 186000, -1, 24],
 +
['East_Timor', 977853, -1, -1, -1], ['Ecuador', 13710000,
 +
328000, -1, 31], ['Egypt', 74710000, 2420000, -1, 50],
 +
['El_Salvador', 6470000, 40000, -1, 4],
 +
['Equatorial_Guinea', 510473, 900, -1, 1], ['Eritrea',
 +
4360000, 10000, -1, 5], ['Estonia', 1400000, 620000, -1,
 +
38], ['Ethiopia', 66550000, 20000, -1, 1], ['Faroe_Islands',
 +
46345, 3000, -1, 2], ['Fiji', 856300, 15000, -1, 2],
 +
['Finland', 5190000, 3270000, -1, 3], ['France', 60180000,
 +
25470000, 15530000, 62], ['French_Guiana', 182917, 2000, -1,
 +
2], ['French_Polynesia', 262125, 16000, -1, 2], ['Gabon',
 +
1320000, 18000, -1, 1], ['Gambia', 1500000, 5000, -1, 2],
 +
['Georgia', 4930000, 25000, -1, 6], ['Germany', 82390000,
 +
41880000, 29520000, 200], ['Ghana', 20460000, 200000, -1,
 +
12], ['Gilbraltar', 27776, -1, -1, 2], ['Greece', 10660000,
 +
2710000, -1, 27], ['Greenland', 56385, 20000, -1, 1],
 +
['Grenada', 89258, 5200, -1, 14], ['Guadeloupe', 440189,
 +
4000, -1, 3], ['Guam', 163941, 5000, -1, 20], ['Guatemala',
 +
13900000, 200000, -1, 5], ['Guernsey', 64818, -1, -1, -1],
 +
['Guinea', 9030000, 15000, -1, 4], ['Guinea-Bissau',
 +
1360000, 4000, -1, 2], ['Guyana', 702100, 95000, -1, 3],
 +
['Haiti', 7520000, 30000, -1, 3], ['Honduras', 6660000,
 +
40000, -1, 8], ['Hong_Kong', 7390000, 4580000, 2630000, 17],
 +
['Hungary', 10040000, 2940000, -1, 16], ['Iceland', 200000,
 +
198000, -1, 20], ['India', 1040000000, 36970000, -1, 43],
 +
['Indonesia', 234890000, 12860000, -1, 24], ['Iran',
 +
68270000, 420000, -1, 8], ['Iraq', 24680000, 12500, -1, 1],
 +
['Ireland', 3920000, 1810000, -1, 22],
 +
['Islas_Malvinas_(Falkland_Islands)', 2967, -1, -1, 2],
 +
['Isle_of_Man', 74261, -1, -1, -1], ['Israel', 6110000,
 +
3130000, 976000, 21], ['Italy', 57990000, 25530000,
 +
15700000, 93], ['Jamaica', 2690000, 100000, -1, 21],
 +
['Japan', 127210000, 78050000, 36580000, 73], ['Jersey',
 +
90156, -1, -1, -1], ['Jordan', 5460000, 212000, -1, 5],
 +
['Kazakhstan', 16760000, 100000, -1, 10], ['Kenya',
 +
31630000, 500000, -1, 65], ['Kiribati', 98549, 1000, -1, 1],
 +
['Kuwait', 2180000, 200000, -1, 3], ['Kyrgyzstan', 4890000,
 +
51600, -1, -1], ['Laos', 5920000, 10000, -1, 1], ['Latvia',
 +
2340000, 455000, -1, 41], ['Lebanon', 3720000, 300000, -1,
 +
22], ['Lesotho', 1860000, 5000, -1, 1], ['Liberia', 3310000,
 +
500, -1, 2], ['Libya', 5490000, 20000, -1, 1],
 +
['Liechtenstein', 3314, -1, -1, -1], ['Lithuania', 3590000,
 +
480000, -1, 32], ['Luxembourg', 454157, 100000, -1, 8],
 +
['Macau', 469903, 101000, -1, 1], ['Macedonia', 2060000,
 +
100000, -1, 6], ['Madagascar', 16970000, 35000, -1, 2],
 +
['Malawi', 11650000, 35000, -1, 7], ['Malaysia', 23090000,
 +
10040000, -1, 7], ['Maldives', 329684, 6000, -1, 1],
 +
['Mali', 11620000, 30000, -1, 13], ['Malta', 400420, 59000,
 +
-1, 6], ['Marshall_Islands', 56429, 900, -1, 1],
 +
['Martinique', 425966, 5000, -1, 2], ['Mauritania', 2910000,
 +
7500, -1, 5], ['Mauritius', 1210000, 158000, -1, 2],
 +
['Mexico', 104900000, 13880000, -1, 51], ['Micronesia',
 +
108143, 2000, -1, 1], ['Moldova', 4430000, 15000, -1, 2],
 +
['Monaco', 32130, -1, -1, 2], ['Mongolia', 2710000, 40000,
 +
-1, 5], ['Montserrat', 8995, -1, -1, 17], ['Morocco',
 +
31680000, 400000, -1, 8], ['Mozambique', 17470000, 22500,
 +
-1, 11], ['Namibia', 1920000, 45000, -1, 2], ['Nauru',
 +
12570, -1, -1, 1], ['Nepal', 26460000, 60000, -1, 6],
 +
['Netherlands_Antilles', 216226, 2000, -1, 6],
 +
['New_Caledonia', 210798, 24000, -1, 1], ['New_Zealand',
 +
3950000, 2340000, -1, 36], ['Nicaragua', 5120000, 20000, -1,
 +
3], ['Niger', 10050000, 12000, -1, 1], ['Nigeria',
 +
133880000, 100000, -1, 11], ['Niue', 2145, -1, -1, 1],
 +
['Norfolk_Island', 1853, -1, -1, 2], ['North_Korea',
 +
22460000, -1, -1, 1], ['Northern_Mariana_Islar', 80006, -1,
 +
-1, 1], ['Norway', 4540000, 3030000, -1, 13], ['Oman',
 +
2800000, 120000, -1, 1], ['Pakistan', 150690000, 1200000,
 +
-1, 30], ['Palau', 19717, -1, -1, 1], ['Panama', 2960000,
 +
45000, -1, 6], ['Papua_New_Guinea', 5290000, 135000, -1, 3],
 +
['Paraguay', 6030000, 20000, -1, 4], ['Peru', 28400000,
 +
4570000, -1, 10], ['Philippines', 84610000, 5960000, -1,
 +
33], ['Pitcairn_Islands', 47, -1, -1, -1], ['Poland',
 +
38620000, 10400000, -1, 19], ['Portugal', 10100000, 6090000,
 +
-1, 16], ['Puerto_Rico', 3880000, 600000, -1, 76], ['Qatar',
 +
817052, 75000, -1, 1], ['Reunion', 755171, 10000, -1, 1],
 +
['Romania', 22270000, 4940000, -1, 38], ['Russia',
 +
144520000, 21230000, -1, 35], ['Rwanda', 7810000, 20000, -1,
 +
2], ['Samoa', 178173, 3000, -1, 2], ['San_Marino', 28119,
 +
-1, -1, 2], ['Sao_Tome_and_Principe', 175883, 9000, -1, 2],
 +
['Saudi_Arabia', 24290000, 2540000, -1, 42], ['Senegal',
 +
10580000, 100000, -1, 1], ['Seychelles', 80469, 9000, -1,
 +
1], ['Sierra_Leone', 5730000, 20000, -1, 1], ['Singapore',
 +
4600000, 2750000, 956000, 9], ['Slovakia', 5430000, 1610000,
 +
-1, 6], ['Slovenia', 1930000, 930000, -1, 11],
 +
['Solomon_Islands', 509190, 8400, -1, 1], ['Somalia',
 +
8020000, 200, -1, 3], ['South_Africa', 43600000, 4780000,
 +
-1, 150], ['South_Korea', 42760000, 31670000, -1, 11],
 +
['Spain', 40210000, 13440000, 8210000, 56], ['Sri_Lanka',
 +
19740000, 121500, -1, 5], ['St._Kitts_and_Nevis', 38763,
 +
2000, -1, 16], ['St._Lucia', 162157, 3000, -1, 15],
 +
['St._Vincent_and_the_Grenadines', 116812, 3500, -1, 15],
 +
['Sudan', 38110000, 56000, -1, 2], ['Suriname', 435449,
 +
14500, -1, 2], ['Svalbard', 2811, -1, -1, -1], ['Swaziland',
 +
1160000, 14000, -1, 6], ['Sweden', 8870000, 6120000,
 +
4640000, 29], ['Switzerland', 7310000, 4600000, 3310000,
 +
44], ['Syria', 17580000, 60000, -1, 1], ['Taiwan', 22600000,
 +
9520000, 5000000, 8], ['Tajilistan', 6860000, 5000, -1, 4],
 +
['Tanzania', 35920000, 300000, -1, 6], ['Thailand',
 +
64260000, 7570000, -1, 15], ['The_Bahamas', 297477, 16900,
 +
-1, 19], ['The_Netherlands', 16149999, 9790000, 7780000,
 +
52], ['Togo', 5420000, 50000, -1, 3], ['Tokelau', 1418, -1,
 +
-1, 1], ['Tonga', 108141, 1000, -1, 2],
 +
['Trinidad_and_Tobago', 1100000, 120000, -1, 17],
 +
['Tunisia', 9920000, 400000, -1, 1], ['Turkey', 68100000,
 +
7270000, -1, 50], ['Turkmenistan', 4770000, 2000, -1, -1],
 +
['Turks_and_Caicos', 19350, -1, -1, 14], ['Tuvalu', 11305,
 +
-1, -1, 1], ['Uganda', 25630000, 60000, -1, 2], ['Ukraine',
 +
48050000, 5278100, -1, 260], ['United_Arab_Emirates',
 +
2480000, 900000, -1, 1], ['United_Kingdom', 60090000,
 +
33110000, 22550000, 400], ['United_States', 290340000,
 +
185550000, 139520000, 7000], ['Uruguay', 3410000, 600000,
 +
-1, 14], ['Uzbekistan', 25980000, 100000, -1, 42],
 +
['Vanuatu', 199414, 3000, -1, 1], ['Venezuela', 24650000,
 +
2310000, -1, 16], ['Vietnam', 81620000, 400000, -1, 5],
 +
['Virgin_Islands', 124778, 12000, -1, 50],
 +
['Wallis_and_Futuna', 15734, -1, -1, 1], ['Western_Sahara',
 +
261794, -1, -1, 1], ['Yemen', 19340000, 17000, -1, 1],
 +
['Zambia', 10300000, 25000, -1, 5], ['Zimbabwe', 12570000,
 +
100000, -1, 6]]
 +
 +
def prettyPrint( stats ):
 +
    print( "%-40s %10s %10s %10s %10s" % ( " ",      " ",          " ",    "Active", " " ) )
 +
    print( "%-40s %10s %10s %10s %10s" % ( "Country", "Population", "Users", "Users",  "ISPs" ) )
 +
    for item in stats:
 +
        country, population, internetUsers, activeUsers, ISPs = item
 +
        print( "%-40s %10d %10d %10d %10d" % ( country, population, internetUsers, activeUsers, ISPs ) )
 +
 +
 +
def main():
 +
    prettyPrint( statistics )
 +
 +
 +
main()
 +
 
 +
 
 +
</source>
 +
<br />
 +
<br />
 +
 
 +
* Run the program, and observe its output:
  
'''python hw8b.py'''
 
 
<code><pre>
 
<code><pre>
------------------------------
+
                                                                  Active         
N= 10000000
+
Country                                  Population      Users      Users      ISPs
pi=3.16159265359
+
Afghanistan                                28710000        -1        -1          1
Job 1 stopped: Execution time:3.073 seconds
+
Albania                                    3580000      12000        -1         10
------------------------------
+
Algeria                                    32810000    180000        -1          2
N= 10000000
+
Andorra                                      69150      24500        -1          1
pi=3.15159265359
+
Angola                                    10760000      60000        -1          1
Job 2 stopped: Execution time:3.023 seconds
 
------------------------------
 
N= 10000000
 
pi=3.15159265359
 
Job 3 stopped: Execution time:3.029 seconds
 
------------------------------
 
N= 10000000
 
pi=3.14159265359
 
Job 4 stopped: Execution time:3.015 seconds
 
 
...
 
...
...
 
...
 
------------------------------
 
N= 10000000
 
pi=3.14159265359
 
Job 88 stopped: Execution time:3.021 seconds
 
 
</pre></code>
 
</pre></code>
 +
:This data is taken from http://www.clickz.com/ and represents statistics about the world population of Internet users, and the number of Internet Service Providers dating from a few years back.  (For a fun movie made very last year with interesting statistics about the Internet, go to http://mashable.com/2010/02/26/state-of-internet/ )
 +
 +
: The original data used "NA" to indicate when data was ''Not Available'', but I have replaced the NAs with -1 to simplify processing.
 +
 +
* Study the program and make sure you understand how the data is coded, and how the program works.  '''There are no new Python constructs in this code.  We have seen all the Python constructs used in this program in class or in a lab before!'''
  
* 88 different results are computed and reported in 88 groups of 4 lines.  Each group starts with a line of dashes.  The next line in a group, '''N= 10000000''', is not important for us.  It just indicates that 10,000,000 iterations were performed to estimate each value of Pi.  The third line of a group,  '''pi=3.14159265359''', shows the result of computing Pi on one of the computers.  This result is an ''estimation'' and is not exactly Pi.  The last line of each group, '''Job XX stopped: Execution time:n.nnn seconds''' indicates that the program ran on Computer #XX, and took ''n.nnn'' seconds to run.
+
===Your assignment===
 +
Your assignment is to add new functions to this program so that we get a finer quantitative view of the world in terms of its usage of the Internet.
  
* Your assignment is to modify hw8b.py so that it will process this collection of lines (stored in the variable '''output''' in the program hw8b.py), extract all the values of '''pi''' listed, average them out (i.e. sum them all, then divide by the number of values), and print the average.
+
;Question 1
 +
: Add a new function that will receive the ''statistics'' list as parameter and that will print the top 10 countries in the world by order of their population. This function should be called from the '''main()''' function and should use the same format as the one shown above, i.e. with the country name listed first, then the population, then the Active users, then the users, then the ISPs, but it should output a ranking on the left side, with 1 listed in the left margin of the first country, 2 listed in the left margin of the second country, until the 10th country.  Note that the number 10 has 2 digits, while 1 to 9 have only one digits.  However, the countries names and the various quantities should be listed one above the other without a jump to the right on the 10th line.
  
* Your program should also keep track of the smallest and largest execution times reported.
+
:Make sure your program does not output the complete list of the 225 countries!  This would use up too much paper when your program is graded.  All that we are interested in this assignment is a collection of short lists of "the most" countries, for various quantities.
  
* The output of your program should be something like this:
+
:Make sure your program prints a title before the list of the top 10 populated countries.  Something like "Top 10 Countries ranked by population" is fine.
  
  88 valid values read
+
:Make sure you are ''efficient'' and that if you do not replicate identical code in different functions. The purpose of a function is to encapsulate code that can be used many times in different areas.
  average value of pi: 3.14159257298131
 
  minimum execution time recorded: 3.000 seconds
 
  maximum execution time recorded: 3.311 seconds
 
  
===Complications===
+
;Question 2
 +
: Add a new function that will receive the ''statistics'' list as parameter and that will print the top 10 countries in terms of users and active users (i.e. add the number of users and the number of active users, and list the 10 countries with the largest such sums).
  
* The complications come from the fact that every so often one of the computers will crash, or will not return data.  If you run the hw8b.py program several times, you will observe these two cases from time to time.
+
: As with Question 1, make sure you print at title before the liste.
  
* In the first case, when computers crash, we will get results that will be messed up, as shown below:
+
; Question 3
 +
: Add a new function that will receive the ''statistics'' list as a parameter and that will print the top 10 countries in terms of the ratio of active Internet Users to population.  The first country listed should be the one with the highest percentage of active users to the total population.
  
------------------------------
+
: Use the same print format as explained in Question 2, including a title before the list.
N= 10000000
 
pi= Job 82 crashed
 
NA seconds
 
  
:Note that the number of seconds is not available any more, and that the string '''NA''' is reported instead.
+
;Question 4 -- Optional and Extra Credit
 +
: Add a function to your program that will receive ''statistics'' as a parameter and that will print out some global statistics.
 +
:* The total world population as recorded in the list ''statistics''
 +
:* The total number of Internet users (be careful not to count the -1 values.)
 +
:* The total number of active Internet users.
 +
:* The total number of ISPs.
 +
:* The percentage of active users relative to Internet users, for the whole world.
 +
:* The percentage of Internet users relative to the world population.
  
* In the second case, when computers do not return results, we simply get fewer than 88 results.  
+
: The percentages should be printed with 2 decimal digits, and with the % sign. For example:
  
===Requirements ===
+
        Active Internet users world-wide:  12.30%
  
* Make your program work regardless of the errors that might happenYour program should not crash when the list contains corrupted results as shown above, or when the number of results is less than 88.
+
:(Note, the % sign is a string operatorWhen it appears in a string, Python thinks it is going to be used as a substitution operator.  To print a regular %-sign, just write two of them next to each other and Python will understand!)
  
* Use the '''try/catch''' construct.
+
=A Note on Grading=
  
===Submission===
+
* Each programs counts for 50% of the grade.
 +
* '''Documentation is becoming more important with each assignment!'''  Make sure you document your code well.  Functions should have a header, the same way programs have headers.  Python programmers like to use ''doc-strings'' as function headers.  A doc-string is a """string""" that is inserted between the def part of the function, and the first python statement:
 +
 
 +
<br />
 +
<br />
 +
<br />
 +
<br />
 +
 
 +
<source lang="python">
 +
    def f1( a, b, c ):
 +
        """f1 receives 3 strings.
 +
        Splits the strings and ... blah-blah-blah...
 +
        """
 +
        wordsa = a.split()
 +
        wordsb = b.split()
 +
        wordsc = c.split()
 +
        ...
  
* Submit your program as follows:
+
</source>
 +
<br />
 +
<br />
 +
<br />
 +
<br />
  
  submit hw8 hw8b.py
+
* You know how to test for different conditions. If you know something is going to make your program crash, make sure you have a test for it.
 +
* If you know your program is not working properly for some quantities, or under certain conditions, explain this in your header.
 +
* Do not make your program output erroneous information.  Better no information rather than erroneous information!
  
:(You do not need to submit montecarlo.pyc)
 
 
<br />
 
<br />
 +
=Submission=
 +
 +
* either login into your 111a-xx account on beowulf and type in this:
 +
 +
  rsubmit hw6 hw6a.py
 +
  rsubmit hw6 hw6b.py
 +
 +
* or submit your program  [http://cs.smith.edu/~111a/submit6.htm here].
 +
 
<br /><br /><br /><br /><br /><br /><br /><br /><br />
 
<br /><br /><br /><br /><br /><br /><br /><br /><br />
 
<br /><br />
 
<br /><br />

Latest revision as of 14:15, 3 November 2011

--D. Thiebaut 13:21, 25 October 2011 (EDT)


This homework assignment is due on Nov. 1st, in the evening, at midnight.

You can work on Problem #1 and on Problem #2 in pairs. You can submit both programs using rsubmit on beowulf, or by using the submit form at http://cs.smith.edu/~111a/submit6.htm



'The due date has been pushed to 11/3/2011 due to the power outage. Also, putting a white box in the graphics window against which the circles are going to bounce off is optional. If you have already coded it, it will count as extra credit.



Problem #1

Demo Program

  • Create the following graphics program, either on beowulf, or on your own computer. Make sure the graphics.py library is in the same folder as your program.
# hw6a.py
# D. Thiebaut
# This program shows two balls moving in the graphics window.
# One is yellow, one is magenta.  The magenta ball is not bound
# by the dimensions of the window, while the yellow one is and
# bounces off the edges as it moves.
# The initial location and speed of the balls are random, but such
# that the balls appear in the window, and are visible.  It is possible
# for a ball to have a speed of 0, in which case it does not move.
 
from graphics import *
import random
 
 
 
def main():
    """Opens a graphics window 600x300 and draws two circles on it"""
    W = 600
    H = 300
    win = GraphWin( "Two Moving Balls", W, H )

    # draw a yellow ball, at a random place, with a random velocity
    c1 = Circle( Point( random.randrange( 100, W-100 ),  # random X
                        random.randrange( 100, H-100 ) ),# random Y
                 random.randrange( 10, 20 ) )            # random radius
    c1.setFill( "yellow" )
    dirX1 = random.randrange( -5, 5 )  # random horizontal displacement
    dirY1 = random.randrange( -5, 5 )  # random vertical displacement
    c1.draw( win )

    # draw a magenta ball, at a random place, with a random velocity
    c2 = Circle( Point( random.randrange( 100, W-100 ),  # random X
                        random.randrange( 100, H-100 ) ),# random Y
                 random.randrange( 10, 20 ) )            # random radius
    c2.setFill( "magenta" )
    dirX2 = random.randrange( -5, 5 )  # random horizontal displacement
    dirY2 = random.randrange( -5, 5 )  # random vertical displacement
    c2.draw( win )
    
    for i in range( 1000 ):

        c1.move( dirX1, dirY1 )
        c2.move( dirX2, dirY2 )

        if c1.getCenter().getX() < 0 or c1.getCenter().getX() > W:
            dirX1 = -dirX1
        if c1.getCenter().getY() < 0 or c1.getCenter().getY() > H:
            dirY1 = -dirY1

 
    #--- wait for  one more click and close up window---
    Text( Point( W//2, H//2 ), "Click me to quit" ).draw( win )
    win.getMouse()
    win.close()
 
main()

Assignment

  1. Modify the program hw6a.py so that the two balls bounce off the walls of the window, not just one.
  2. Make the balls bounce when their side hits the walls, not their center.
  3. Make the two balls bounce off when they hit each other (the way pool-table balls would).
  4. There should be three black boxes in the graphics window, and if any one of the two balls happens to move completely inside any one of the boxes, it should stop there.
  5. the program should stop and display click me to quit when the simulation has gone through 1000 steps, or as soon as the two balls have been immobilized in boxes.
  6. Optional: there should be a fourth box, this one white, which should act as an obstacle. Any time a ball hits the white box, it should bounce off the walls of the box, in a same way it bounces off the walls.

Requirements

  • Use a list to hold the black boxes (defined by their coordinates). The idea is too hold the boxes in a list rather than having 3 different variables to keep track of the thee boxes. This way if we wanted to create a large window with, say, 100 boxes, your program could easily adapt: all we would have to do is just add more rectangles to the list.
  • Below is an example of how you could keep track of 3 boxes in a list called boxes:



         # P1, P2, P3, P4, P5, and P6 are 6 points in the graphics window
         boxes = []
         r = Rectangle( P1, P2 )
         boxes.append( r )
         r = Rectangle( P3, P4 )
         boxes.append( r )
         r = Rectangle( P5, P6 )
         boxes.append( r )



  • You are free to select the size of the white and black boxes, but make them big enough to allow balls to hit them regularly, but not too big so as to make the balls "fall" in a black box before having time to hit a few walls or the white box.
  • Include your account name(s) or your first name(s) in the title of the graphics window to make it easier to identify printed screen captures of your running program:
      win = GraphWin( W, H, "111a-xx's billiard program" )

Realism

  • It is not easy nor possible with our current knowledge of Python to make the balls bounce off each other in a realistic way. When a ball hits a wall, the rule is very nice and clear: we change the sign of either dirX or dirY, depending on which is perpendicular to the wall. When the balls hit each other, both dirX and dirY would normally change. The real equation for how dirX and dirY change is too complicated for us. Invent your own laws of physics and implement them in python!

Submission

  • Make sure the header of your program contains your names and account numbers, if working in pairs, or just your name and account number if working individually.
  • Submit your program as follows:
   rsubmit hw6 hw6a.py

Additional Information

  • You may find the following function useful for computing the distance between two graphics points:
from math import *   # this should be at the beginning of the program

def distance( P1, P2 ):
     """Computes the distance between Point P1 and Point P2. 
         The returned value is a float
     """
     d = sqrt( pow( P1.getX() - P2.getX(), 2 ) + pow( P1.getY() - P2.getY(), 2 ) )
     return d
  • Here is a way it could be used:
 P1 = Point( x1, y1 )
 P2 = Point( x2, y2 )
 
 ...

 if distance( P1, P2 ) > 30:
      # do something if the points are more than 30 pixels away from each other
 else
      # do something else if the points are closer than 30 pixels

Problem #2

StateOfTheInternet.jpg
  • This second program should be called hw6b.py, but before you start on it, though, play with the following program and figure out how it works. It will provide you with some good clues for how to code hw6b.py.
# people.py
# D. Thiebaut
# a demo program illustrating how to sort an array of pairs.
# a pair is a list with 2 items.  Here each pair contains a string, and
# an integer.  The string is the name of a person, the integer that person's
# age.

def main():
    people = [ ["Marie", 16], ["Joe", 33], ["Alex", 30], ["Fred", 5 ] ]

    # sort the list by alphabetical order
    people.sort()

    # display the contents of the list in alphabetical order
    for person, age in people:
        print( "%30s: %4d" % ( person, age ) )

    print()

    # create a new list of people, this time the age is first in
    # each pair.
    newPeople = []
    for person, age in people:
        newPeople.append( [age, person] )

    # sort by age, in increasing order
    newPeople.sort()

    # display the contents of the list, ordered by age
    for age, person in newPeople:
        print( "%-30s: %4d" % ( person, age ) )

    # find the oldest person
    age, person = max( newPeople )
    print( "\nThe oldest person is", person," who's", age, "years old.\n\n" )
    
main()



  • Now that you have played with people.py, try this new program, called hw6b.py:



# hw6b.py
# your name 
#
 
statistics = [['Afghanistan', 28710000, -1, -1, 1], ['Albania', 3580000,
12000, -1, 10], ['Algeria', 32810000, 180000, -1, 2],
['Andorra', 69150, 24500, -1, 1], ['Angola', 10760000,
60000, -1, 1], ['Anguilla', 12738, 919, -1, 16],
['Antigua_and_Barbuda', 67897, 5000, -1, 16], ['Argentina',
38740000, 4650000, -1, 33], ['Armenia', 3320000, 30000, -1,
9], ['Aruba', 70844, 24000, -1, -1], ['Australia', 19730000,
13010000, 9020000, 571], ['Austria', 8180000, 4650000,
1300000, 37], ['Azerbaijan', 7830000, 25000, -1, 2],
['Bahrain', 667238, 140200, -1, 1], ['Bangladesh',
138440000, 150000, -1, 10], ['Barbados', 277264, 6000, -1,
19], ['Belarus', 10330000, 422000, -1, 23], ['Belgium',
10280000, 4870000, 1600000, 61], ['Belize', 266440, 18000,
-1, 2], ['Benin', 7040000, 25000, -1, 4], ['Bhutan',
2130000, 2500, -1, -1], ['Bolivia', 8580000, 78000, -1, 9],
['Bosnia_and_Herzegovian', 3980000, 45000, -1, 3],
['Botswana', 1570000, 33000, -1, 11], ['Brazil', 182030000,
22320000, 10860000, 50], ['Brunei', 358098, 35000, -1, 2],
['Bulgaria', 7530000, 1610000, -1, 200], ['Burkina_Faso',
13220000, 25000, -1, 1], ['Burma', 42510000, 10000, -1, 1],
['Burundi', 6090000, 6000, -1, 1], ['Cambodia', 13120000,
10000, -1, 2], ['Cameroon', 15740000, 45000, -1, 1],
['Canada', 32200000, 20450000, 8800000, 760], ['Cape_Verde',
412137, 12000, -1, 1], ['Cayman_Islands', 41934, -1, -1,
16], ['Central_African_Republic', 3680000, 2000, -1, 1],
['Chad', 9250000, 4000, -1, 1], ['Chile', 15660000, 5040000,
-1, 7], ['China', 1280000000, 99800000, -1, 3], ['Colombia',
41660000, 1870000, -1, 18], ['Comoros', 632948, 2500, -1,
1], ['Republic_of_the_Congo_Democratic', 56620000, 6000, -1,
1], ['Congo_Republic', 2950000, 500, -1, 1],
['Cook_Islands', 21008, -1, -1, 3], ['Costa_Rica', 3890000,
384000, -1, 3], ['Cote_d_Ivoire', 16960000, 70000, -1, 5],
['Croatia', 4420000, 480000, -1, 9], ['Cuba', 11260000,
120000, -1, 5], ['Cyprus', 771657, 150000, -1, 6],
['Czech_Republic', 10240000, 3530000, -1, 300], ['Denmark',
5380000, 3720000, -1, 13], ['Djibouti', 457130, 3300, -1,
1], ['Dominica', 69655, 2000, -1, 16],
['Dominican_Republic', 8710000, 186000, -1, 24],
['East_Timor', 977853, -1, -1, -1], ['Ecuador', 13710000,
328000, -1, 31], ['Egypt', 74710000, 2420000, -1, 50],
['El_Salvador', 6470000, 40000, -1, 4],
['Equatorial_Guinea', 510473, 900, -1, 1], ['Eritrea',
4360000, 10000, -1, 5], ['Estonia', 1400000, 620000, -1,
38], ['Ethiopia', 66550000, 20000, -1, 1], ['Faroe_Islands',
46345, 3000, -1, 2], ['Fiji', 856300, 15000, -1, 2],
['Finland', 5190000, 3270000, -1, 3], ['France', 60180000,
25470000, 15530000, 62], ['French_Guiana', 182917, 2000, -1,
2], ['French_Polynesia', 262125, 16000, -1, 2], ['Gabon',
1320000, 18000, -1, 1], ['Gambia', 1500000, 5000, -1, 2],
['Georgia', 4930000, 25000, -1, 6], ['Germany', 82390000,
41880000, 29520000, 200], ['Ghana', 20460000, 200000, -1,
12], ['Gilbraltar', 27776, -1, -1, 2], ['Greece', 10660000,
2710000, -1, 27], ['Greenland', 56385, 20000, -1, 1],
['Grenada', 89258, 5200, -1, 14], ['Guadeloupe', 440189,
4000, -1, 3], ['Guam', 163941, 5000, -1, 20], ['Guatemala',
13900000, 200000, -1, 5], ['Guernsey', 64818, -1, -1, -1],
['Guinea', 9030000, 15000, -1, 4], ['Guinea-Bissau',
1360000, 4000, -1, 2], ['Guyana', 702100, 95000, -1, 3],
['Haiti', 7520000, 30000, -1, 3], ['Honduras', 6660000,
40000, -1, 8], ['Hong_Kong', 7390000, 4580000, 2630000, 17],
['Hungary', 10040000, 2940000, -1, 16], ['Iceland', 200000,
198000, -1, 20], ['India', 1040000000, 36970000, -1, 43],
['Indonesia', 234890000, 12860000, -1, 24], ['Iran',
68270000, 420000, -1, 8], ['Iraq', 24680000, 12500, -1, 1],
['Ireland', 3920000, 1810000, -1, 22],
['Islas_Malvinas_(Falkland_Islands)', 2967, -1, -1, 2],
['Isle_of_Man', 74261, -1, -1, -1], ['Israel', 6110000,
3130000, 976000, 21], ['Italy', 57990000, 25530000,
15700000, 93], ['Jamaica', 2690000, 100000, -1, 21],
['Japan', 127210000, 78050000, 36580000, 73], ['Jersey',
90156, -1, -1, -1], ['Jordan', 5460000, 212000, -1, 5],
['Kazakhstan', 16760000, 100000, -1, 10], ['Kenya',
31630000, 500000, -1, 65], ['Kiribati', 98549, 1000, -1, 1],
['Kuwait', 2180000, 200000, -1, 3], ['Kyrgyzstan', 4890000,
51600, -1, -1], ['Laos', 5920000, 10000, -1, 1], ['Latvia',
2340000, 455000, -1, 41], ['Lebanon', 3720000, 300000, -1,
22], ['Lesotho', 1860000, 5000, -1, 1], ['Liberia', 3310000,
500, -1, 2], ['Libya', 5490000, 20000, -1, 1],
['Liechtenstein', 3314, -1, -1, -1], ['Lithuania', 3590000,
480000, -1, 32], ['Luxembourg', 454157, 100000, -1, 8],
['Macau', 469903, 101000, -1, 1], ['Macedonia', 2060000,
100000, -1, 6], ['Madagascar', 16970000, 35000, -1, 2],
['Malawi', 11650000, 35000, -1, 7], ['Malaysia', 23090000,
10040000, -1, 7], ['Maldives', 329684, 6000, -1, 1],
['Mali', 11620000, 30000, -1, 13], ['Malta', 400420, 59000,
-1, 6], ['Marshall_Islands', 56429, 900, -1, 1],
['Martinique', 425966, 5000, -1, 2], ['Mauritania', 2910000,
7500, -1, 5], ['Mauritius', 1210000, 158000, -1, 2],
['Mexico', 104900000, 13880000, -1, 51], ['Micronesia',
108143, 2000, -1, 1], ['Moldova', 4430000, 15000, -1, 2],
['Monaco', 32130, -1, -1, 2], ['Mongolia', 2710000, 40000,
-1, 5], ['Montserrat', 8995, -1, -1, 17], ['Morocco',
31680000, 400000, -1, 8], ['Mozambique', 17470000, 22500,
-1, 11], ['Namibia', 1920000, 45000, -1, 2], ['Nauru',
12570, -1, -1, 1], ['Nepal', 26460000, 60000, -1, 6],
['Netherlands_Antilles', 216226, 2000, -1, 6],
['New_Caledonia', 210798, 24000, -1, 1], ['New_Zealand',
3950000, 2340000, -1, 36], ['Nicaragua', 5120000, 20000, -1,
3], ['Niger', 10050000, 12000, -1, 1], ['Nigeria',
133880000, 100000, -1, 11], ['Niue', 2145, -1, -1, 1],
['Norfolk_Island', 1853, -1, -1, 2], ['North_Korea',
22460000, -1, -1, 1], ['Northern_Mariana_Islar', 80006, -1,
-1, 1], ['Norway', 4540000, 3030000, -1, 13], ['Oman',
2800000, 120000, -1, 1], ['Pakistan', 150690000, 1200000,
-1, 30], ['Palau', 19717, -1, -1, 1], ['Panama', 2960000,
45000, -1, 6], ['Papua_New_Guinea', 5290000, 135000, -1, 3],
['Paraguay', 6030000, 20000, -1, 4], ['Peru', 28400000,
4570000, -1, 10], ['Philippines', 84610000, 5960000, -1,
33], ['Pitcairn_Islands', 47, -1, -1, -1], ['Poland',
38620000, 10400000, -1, 19], ['Portugal', 10100000, 6090000,
-1, 16], ['Puerto_Rico', 3880000, 600000, -1, 76], ['Qatar',
817052, 75000, -1, 1], ['Reunion', 755171, 10000, -1, 1],
['Romania', 22270000, 4940000, -1, 38], ['Russia',
144520000, 21230000, -1, 35], ['Rwanda', 7810000, 20000, -1,
2], ['Samoa', 178173, 3000, -1, 2], ['San_Marino', 28119,
-1, -1, 2], ['Sao_Tome_and_Principe', 175883, 9000, -1, 2],
['Saudi_Arabia', 24290000, 2540000, -1, 42], ['Senegal',
10580000, 100000, -1, 1], ['Seychelles', 80469, 9000, -1,
1], ['Sierra_Leone', 5730000, 20000, -1, 1], ['Singapore',
4600000, 2750000, 956000, 9], ['Slovakia', 5430000, 1610000,
-1, 6], ['Slovenia', 1930000, 930000, -1, 11],
['Solomon_Islands', 509190, 8400, -1, 1], ['Somalia',
8020000, 200, -1, 3], ['South_Africa', 43600000, 4780000,
-1, 150], ['South_Korea', 42760000, 31670000, -1, 11],
['Spain', 40210000, 13440000, 8210000, 56], ['Sri_Lanka',
19740000, 121500, -1, 5], ['St._Kitts_and_Nevis', 38763,
2000, -1, 16], ['St._Lucia', 162157, 3000, -1, 15],
['St._Vincent_and_the_Grenadines', 116812, 3500, -1, 15],
['Sudan', 38110000, 56000, -1, 2], ['Suriname', 435449,
14500, -1, 2], ['Svalbard', 2811, -1, -1, -1], ['Swaziland',
1160000, 14000, -1, 6], ['Sweden', 8870000, 6120000,
4640000, 29], ['Switzerland', 7310000, 4600000, 3310000,
44], ['Syria', 17580000, 60000, -1, 1], ['Taiwan', 22600000,
9520000, 5000000, 8], ['Tajilistan', 6860000, 5000, -1, 4],
['Tanzania', 35920000, 300000, -1, 6], ['Thailand',
64260000, 7570000, -1, 15], ['The_Bahamas', 297477, 16900,
-1, 19], ['The_Netherlands', 16149999, 9790000, 7780000,
52], ['Togo', 5420000, 50000, -1, 3], ['Tokelau', 1418, -1,
-1, 1], ['Tonga', 108141, 1000, -1, 2],
['Trinidad_and_Tobago', 1100000, 120000, -1, 17],
['Tunisia', 9920000, 400000, -1, 1], ['Turkey', 68100000,
7270000, -1, 50], ['Turkmenistan', 4770000, 2000, -1, -1],
['Turks_and_Caicos', 19350, -1, -1, 14], ['Tuvalu', 11305,
-1, -1, 1], ['Uganda', 25630000, 60000, -1, 2], ['Ukraine',
48050000, 5278100, -1, 260], ['United_Arab_Emirates',
2480000, 900000, -1, 1], ['United_Kingdom', 60090000,
33110000, 22550000, 400], ['United_States', 290340000,
185550000, 139520000, 7000], ['Uruguay', 3410000, 600000,
-1, 14], ['Uzbekistan', 25980000, 100000, -1, 42],
['Vanuatu', 199414, 3000, -1, 1], ['Venezuela', 24650000,
2310000, -1, 16], ['Vietnam', 81620000, 400000, -1, 5],
['Virgin_Islands', 124778, 12000, -1, 50],
['Wallis_and_Futuna', 15734, -1, -1, 1], ['Western_Sahara',
261794, -1, -1, 1], ['Yemen', 19340000, 17000, -1, 1],
['Zambia', 10300000, 25000, -1, 5], ['Zimbabwe', 12570000,
100000, -1, 6]]
 
def prettyPrint( stats ):
    print( "%-40s %10s %10s %10s %10s" % ( " ",       " ",          " ",     "Active", " " ) )
    print( "%-40s %10s %10s %10s %10s" % ( "Country", "Population", "Users", "Users",  "ISPs" ) )
    for item in stats:
        country, population, internetUsers, activeUsers, ISPs = item
        print( "%-40s %10d %10d %10d %10d" % ( country, population, internetUsers, activeUsers, ISPs ) )
 
 
def main():
    prettyPrint( statistics )
 
 
main()



  • Run the program, and observe its output:
                                                                   Active           
Country                                  Population      Users      Users       ISPs
Afghanistan                                28710000         -1         -1          1
Albania                                     3580000      12000         -1         10
Algeria                                    32810000     180000         -1          2
Andorra                                       69150      24500         -1          1
Angola                                     10760000      60000         -1          1
...
This data is taken from http://www.clickz.com/ and represents statistics about the world population of Internet users, and the number of Internet Service Providers dating from a few years back. (For a fun movie made very last year with interesting statistics about the Internet, go to http://mashable.com/2010/02/26/state-of-internet/ )
The original data used "NA" to indicate when data was Not Available, but I have replaced the NAs with -1 to simplify processing.
  • Study the program and make sure you understand how the data is coded, and how the program works. There are no new Python constructs in this code. We have seen all the Python constructs used in this program in class or in a lab before!

Your assignment

Your assignment is to add new functions to this program so that we get a finer quantitative view of the world in terms of its usage of the Internet.

Question 1
Add a new function that will receive the statistics list as parameter and that will print the top 10 countries in the world by order of their population. This function should be called from the main() function and should use the same format as the one shown above, i.e. with the country name listed first, then the population, then the Active users, then the users, then the ISPs, but it should output a ranking on the left side, with 1 listed in the left margin of the first country, 2 listed in the left margin of the second country, until the 10th country. Note that the number 10 has 2 digits, while 1 to 9 have only one digits. However, the countries names and the various quantities should be listed one above the other without a jump to the right on the 10th line.
Make sure your program does not output the complete list of the 225 countries! This would use up too much paper when your program is graded. All that we are interested in this assignment is a collection of short lists of "the most" countries, for various quantities.
Make sure your program prints a title before the list of the top 10 populated countries. Something like "Top 10 Countries ranked by population" is fine.
Make sure you are efficient and that if you do not replicate identical code in different functions. The purpose of a function is to encapsulate code that can be used many times in different areas.
Question 2
Add a new function that will receive the statistics list as parameter and that will print the top 10 countries in terms of users and active users (i.e. add the number of users and the number of active users, and list the 10 countries with the largest such sums).
As with Question 1, make sure you print at title before the liste.
Question 3
Add a new function that will receive the statistics list as a parameter and that will print the top 10 countries in terms of the ratio of active Internet Users to population. The first country listed should be the one with the highest percentage of active users to the total population.
Use the same print format as explained in Question 2, including a title before the list.
Question 4 -- Optional and Extra Credit
Add a function to your program that will receive statistics as a parameter and that will print out some global statistics.
  • The total world population as recorded in the list statistics
  • The total number of Internet users (be careful not to count the -1 values.)
  • The total number of active Internet users.
  • The total number of ISPs.
  • The percentage of active users relative to Internet users, for the whole world.
  • The percentage of Internet users relative to the world population.
The percentages should be printed with 2 decimal digits, and with the % sign. For example:
       Active Internet users world-wide:  12.30%
(Note, the % sign is a string operator. When it appears in a string, Python thinks it is going to be used as a substitution operator. To print a regular %-sign, just write two of them next to each other and Python will understand!)

A Note on Grading

  • Each programs counts for 50% of the grade.
  • Documentation is becoming more important with each assignment! Make sure you document your code well. Functions should have a header, the same way programs have headers. Python programmers like to use doc-strings as function headers. A doc-string is a """string""" that is inserted between the def part of the function, and the first python statement:





    def f1( a, b, c ):
        """f1 receives 3 strings.
        Splits the strings and ... blah-blah-blah...
        """
        wordsa = a.split()
        wordsb = b.split()
        wordsc = c.split()
        ...





  • You know how to test for different conditions. If you know something is going to make your program crash, make sure you have a test for it.
  • If you know your program is not working properly for some quantities, or under certain conditions, explain this in your header.
  • Do not make your program output erroneous information. Better no information rather than erroneous information!


Submission

  • either login into your 111a-xx account on beowulf and type in this:
  rsubmit hw6 hw6a.py
  rsubmit hw6 hw6b.py
  • or submit your program here.