Difference between revisions of "CSC111 Lab 11 2011"

From dftwiki3
Jump to: navigation, search
(Accessing Web Page)
Line 201: Line 201:
 
* Scroll down the source code and locate where the temperature is displayed.  Searching for the words "''Feels like''" is a good way to locate the place.  This should look something like this:
 
* Scroll down the source code and locate where the temperature is displayed.  Searching for the words "''Feels like''" is a good way to locate the place.  This should look something like this:
  
   <td class="twc-col-1 twc-forecast-temperature-info">Feels Like: <strong%gt;55°</strong>
+
   <td class="twc-col-1 twc-forecast-temperature-info">Feels Like: <strong>55°</strong>
  
 
* To get the temperature, then, if we can get the whole html page in a string (that should sound familiar after our last homework assignment), all we need to do is search for the strings "Feels Like: <strong>'' and ''°'' , and take whatever is in between, and we'll have the temperature for the area code '''01060'''.
 
* To get the temperature, then, if we can get the whole html page in a string (that should sound familiar after our last homework assignment), all we need to do is search for the strings "Feels Like: <strong>'' and ''°'' , and take whatever is in between, and we'll have the temperature for the area code '''01060'''.

Revision as of 16:34, 16 November 2011

--D. Thiebaut 13:03, 16 November 2011 (EST)


Kinect Demo

  • The first part of the lab takes place in FH343 (almost directly above the regular lab place) for a demo of Kinect. The demo will last about 10-15 minutes.



DFTPointCloudOnKinect.png



Exceptions

If you feel you have a good handle on exceptions, then move on to the next section. Otherwise do the exercises of this section.

TypeError Exceptions

The code section below should remind you of a recent homework assignment. Create a program called stats.py with this code:



statistics = [['Afghanistan', 28710000, 'NA', 'NA', 1], ['Albania', 3580000,
               12000, 'NA', 10], ['Algeria', 32810000, 180000, 'NA', 2],
               ['Andorra', 69150, 24500, 'NA', 1], ['Angola', 10760000,
               60000, 'NA', 1], ['Anguilla', 12738, 919, 'NA', 16],
               ['Antigua_and_Barbuda', 67897, 5000, 'NA', 16], ['Argentina',
               38740000, 4650000, 'NA', 33], ['Armenia', 3320000, 30000, 'NA',
               9], ['Aruba', 70844, 24000, 'NA', 'NA'], ['Australia', 19730000,
               13010000, 9020000, 571], ['Austria', 8180000, 4650000,
               1300000, 37], ['Azerbaijan', 7830000, 25000, 'NA', 2],
               ['Bahrain', 667238, 140200, 'NA', 1], ['Bangladesh',
               138440000, 150000, 'NA', 10], ['Barbados', 277264, 6000, 'NA',
               19], ['Belarus', 10330000, 422000, 'NA', 23], ['Belgium',
               10280000, 4870000, 1600000, 61], ['Belize', 266440, 18000,
               'NA', 2], ['Benin', 7040000, 25000, 'NA', 4], ['Bhutan',
               2130000, 2500, 'NA', 'NA'], ['Bolivia', 8580000, 78000, 'NA', 9],
               ['Bosnia_and_Herzegovian', 3980000, 45000, 'NA', 3],
               ['Botswana', 1570000, 33000, 'NA', 11], ['Brazil', 182030000,
               22320000, 10860000, 50], ['Brunei', 358098, 35000, 'NA', 2],
               ['Bulgaria', 7530000, 1610000, 'NA', 200], ['Burkina_Faso',
               13220000, 25000, 'NA', 1], ['Burma', 42510000, 10000, 'NA', 1],
               ['Burundi', 6090000, 6000, 'NA', 1], ['Cambodia', 13120000,
               10000, 'NA', 2], ['Cameroon', 15740000, 45000, 'NA', 1] ]

def main():
    for country, pop, users, active, isp in statistics:
        print( "%30s (%d habitants)" % (country, pop ), end="" )
        print( "Users=", users, " Active=", active, " ISP=", isp )


main()



  • Run the program.
  • Notice that the data are in their original form. When a quantity is not known, the creators of the list use "NA" to indicate that it was Not Available.
  • Let's compute the total population of the (partial) list of countries in the list statistics.
    count = 0
    for country, pop, users, active, isp in statistics:
         count += pop
Go ahead and see if your get a total population of 618039669.

Challenge #1

QuestionMark1.jpg
  • Modify your program so that it also computes the total number of Users. Make it use the very same construct as shown above, but now for the quantity users.
  • Run your program.
  • Did you get an error of this type?
Traceback (most recent call last):
  File "stats.py", line 36, in <module>
    main()
  File "stats.py", line 31, in main
    userCount += users
TypeError: unsupported operand type(s) for +=: 'int' and 'str'
If so, why? What made the program crash?
Think hard!
Harder!







FrogThinking.jpg







Do not move on until you know for sure why this error was generated.







  • I trust that if you are reading this, it is because you know what caused your program to crash. The clue is unsupported operand type(s) for +=: 'int' and 'str' , indicating that we are trying to add 'NA' which is a string to count, which is an integer.
We could use an if statement to test whether users contains 'NA' or not, but we'll use another approach. We will tell python to try adding users to the counting variable, and if there is an error of type TypeError (see the last ligne of the error message when the program crashed), then we won't add anything to the count variable; we'll just pass.
The main program becomes:
def main():
    popCount = 0
    userCount = 0
    for country, pop, users, active, isp in statistics:
        print "%30s (%d habitants)" % (country, pop ),
        print "Users=", users, " Active=", active, " ISP=", isp
        popCount += pop
        try:
            userCount += users
        except TypeError:
            # don't do anything
            pass 
        
    print "total population = ", popCount
    print "total users      = ", userCount
  • Try it!
  • Use the same method to compute the total number of ISPs.

Other Exceptions

  • Imagine that now the list statistics is defined as shown below, and that for some countries the ISP value (the last one) is missing:
.
statistics = [['Afghanistan', 28710000, 'NA', 'NA', 1], ['Albania', 3580000,
                12000, 'NA', 10], ['Algeria', 32810000, 180000, 'NA'],
                ['Andorra', 69150, 24500, 'NA', 1], ['Angola', 10760000,
                60000, 'NA', 1], ['Anguilla', 12738, 919, 'NA', 16],
                ['Antigua_and_Barbuda', 67897, 5000, 'NA', 16], ['Argentina',
                38740000, 4650000, 'NA', 33], ['Armenia', 3320000, 30000, 'NA',
                9], ['Aruba', 70844, 24000, 'NA' ], ['Australia', 19730000,
                13010000, 9020000, 571], ['Austria', 8180000, 4650000,
                1300000, 37], ['Azerbaijan', 7830000, 25000, 'NA'],
                ['Bahrain', 667238, 140200, 'NA', 1], ['Bangladesh',
                138440000, 150000, 'NA', 10], ['Barbados', 277264, 6000, 'NA',
                19], ['Belarus', 10330000, 422000, 'NA', 23], ['Belgium',
                10280000, 4870000, 1600000, 61], ['Belize', 266440, 18000,
                'NA', 2], ['Benin', 7040000, 25000, 'NA', 4], ['Bhutan',
                2130000, 2500, 'NA', 'NA'], ['Bolivia', 8580000, 78000, 'NA', 9],
                ['Bosnia_and_Herzegovian', 3980000, 45000, 'NA', 3],
                ['Botswana', 1570000, 33000, 'NA', 11], ['Brazil', 182030000,
                22320000, 10860000, 50], ['Brunei', 358098, 35000, 'NA', 2],
                ['Bulgaria', 7530000, 1610000, 'NA', 200], ['Burkina_Faso', 
                13220000, 25000, 'NA'], ['Burma', 42510000, 10000, 'NA', 1],
                ['Burundi', 6090000, 6000, 'NA', 1], ['Cambodia', 13120000,
               10000, 'NA', 2], ['Cameroon', 15740000, 45000, 'NA', 1] ]

.
  • Write a program (or copy/paste part of the previous one) that will read the list above, and output the total population (which should be the same as before).
    • For this you should write your program as if all the country lists contained 5 quantities.
    • Then you run your program.
    • You observe that it crashes when it tries to extract the 5th quantity from a country list.
    • You note the name of the error generated (which is on the last line, and usually of the form XxxxError, such as IndexError, TypeError, NameError, ValueError, etc.)
    • Add a try/except statement around the code that generates the error (Python refers to a run-time error that creates a crash as an exception):
     try:
         country, pop, users, active, isp = someVariableOfYours
     except XxxxError:
         country, pop, users, active = someVariableOfYours
Run your program again and observe that it doesn't crash and that it reports the correct information.



Accessing Web Page

In this Lab section we are going to write a Python program that will access this page, read this contents and extract the number representing the current temperature, and print it on the screen.


CurrentTemperatureNoho.png
  • Observe that it displays the current temperature for Northampton
  • Make a note of the temperature that is being currently reported (the picture on the right hand-side is not current, and was taken another day).
  • Depending on the browser you are using, figure out a way to see the source code of the page, i.e. the html contents of the page. With Firefox, this is done by right-clicking on the page and selecting View Page Source. Wight Safari, you also right-click and select View Source. With Chrome, you control-click on the page and select View Page Source.
  • Scroll down the source code and locate where the temperature is displayed. Searching for the words "Feels like" is a good way to locate the place. This should look something like this:
 <td class="twc-col-1 twc-forecast-temperature-info">Feels Like: <strong>55&deg;</strong>
  • To get the temperature, then, if we can get the whole html page in a string (that should sound familiar after our last homework assignment), all we need to do is search for the strings "Feels Like: <strong> and &deg; , and take whatever is in between, and we'll have the temperature for the area code 01060.
  • Let's start:
    Step 1
Create a program called getTemperature.py with the following code:


 import urllib.request
 import sys
  
 #--- some constants used by the program ---
 BASEURL = "http://www.weather.com/weather/today/01060"
 
 def getTemperature( ):
  url = BASEURL
  print( url )
  f = urllib.request.urlopen( url )
  bytes = f.read()
  htmlText  = bytes.decode( "utf8" )
  print( htmlText )


 def main():
   getTemperature()
 
 main()


  • Step 2
Run the program


  • Step 3
Observe that it prints out a lot of text, which, if you check carefully, should match exactly the source page in your browser.


  • Step 4
If you have skip the last homework assignment, read again how the string method find() works in the http://python.org pages (use Google to search for "python string methods" and open the page at python.org with title String Methods.)


  • Step 5
Use the find() string method to get two indices that will allow you to slice away the temperature number from the html text.


  • Step 6
Make your program print this number on the screen.


  • Step 7
Modify your program so that it prompts the user for a zip-code, then reports the temperature at that zip-code.


Challenge #2: Applying this to other Urls

QuestionMark2.jpg


Adapt this method to the astrology pages of Cafe Astrology, at http://www.cafeastrology.com/. Locate the section Signs of the Zodiac in the middle of the page, and try a few of them (Aries Taurus Gemini Cancer Leo Virgo Libra Scorpio Sagittarius Capricorn Aquarius Pisces). Check the URL for each one. You will notice that the Url for Aries is http://www.cafeastrology.com/zodiacaries.html, the Url for Gemini is http://www.cafeastrology.com/zodiacgemini.html, etc.

So, by just inserting the lowercase version of the sign in the Url, between "zodiac" and ".html", you can access the page of interest.

Write a program that prompts the user for a zodiac sign, goes to the appropriate Web page at Cafe Astrology and reports some information found on that page, for example the first paragraph following "Comparison with its symbol...".

LeoSign.jpg