Python INFO1-CE9990 Homework

Summer 2017 Section 2

  1. Thursday, June 15, 2017: up to the start of while in the in-class examples. Install Python 3 and IDLE on your Mac or PC. Try out everything we did in class and see if it actually works as advertised. (Please do this every week.) Don’t worry too much about try and except: we can go over them again next week.

    Read the course’s grading policy. Bookmark the Python documentation in your browser. Look at the documentation for the built-in functions we mentioned in class tonight: round, print, input len, int, etc.

    Create a GitHub account if you don’t already have one. To add a photo of yourself. log into your GitHib account, pull down the triangle in the upper right corner, select Settings, and upload a picture.

    Log into your GitHub account and create a repository named Python-INFO1-CE9990. (Be careful: the I and O are uppercase letters; the 1 and 0 are digits; and the two dashes are dashes, not underscores.) The Description of the repository should be
    NYU SPS, Summer 2017 Section 2
    Before you press the green “Create repository” button, make sure the Public radio button is pressed, and check the checkbox for “Initialize this repository with a README”. If the repository was created successfully, you’ll se a list of the files that belong to the repository. At this point, only one file (README.md) belongs to the repository. To the upper right of the README.md, there’s a button named “Create new file”. Don’t press it yet. If for some reason you want to delete this repository and make a fresh start, click on the Settings gear and scroll down to the Danger Zone.

    Here is the instructor’s GitHub account and his Python-INFO1-CE9990 repository. The repository contains a file named flag.py. This file is a Python script and we’ll talk about it here. Admire the other students’ repositories.

    Do exercise #8 here and upload it to your Python-INFO1-CE99990 repository in your GitHub account. Email me if you get into trouble:
    mark.meretzky@gmail.com

    Three differences between Python 2 and Python 3 we mentioned tonight (see Common Stumbling Blocks):


  2. Thursday, June 22, 2017: up to the end of if in the in-class examples. (If I were you, I’d study the nested loops in the factoring example.) We also took a peek at graphics with tkinter. Why did we see Adventures with Russian Books and the People who Read Them?

    Please email me at mark.meretzky@gmail.com if your name here is spelled wrong or not linked to your INFO-CE9990 repository.

    Do the graph paper homework. Name the script graphpaper.py and upload it to your Python-INFO1-CE9990 repository in GitHub. (Extra credit: also write a second script named graphpaper2.py that doesn’t leave the right and bottom edges of the graph paper open.) Also write an interesting script with if statements (maybe with if/else or if/elif/else, etc.), while loops, etc. It could do something with user input from input, stock prices downloaded from the web, etc. Name the script control.py (for “control structure”) and upload it to Python-INFO1-CE9990. In general from now on, upload all your homework scripts to Python-INFO1-CE9990. Don’t leave your homework till the last minute.

    Run the tkinter flag script but don’t hand it in. If it produces no picture on macOS, can you correct it by correcting the “unstable” warning in the installation instructions? Microsoft people: if you email me a link to Microsoft’s instructions for taking a screenshot (or a shot of just one window), I’ll paste it into the flag page.

    As usual, I’m happy to bring my iPod Touch (equipped with Facetime and Google Hangouts) to class. If you email me instructions for streaming, recording the lecture, etc., I’ll do it at 6:29 p.m. on the appointed date. A more reliable idea would be for one of you to be in charge of setup in the classroom.

    My Mac at home (MacBook Pro Retina, macOS Sierra 10.12.5) doesn’t have Excel. Is there a free lookalike I can downlaod that would do the same kind of Python stuff that the real Excel can do?

    A difference between Python 2 and Python 3 we mentioned tonight: In the flag page, you had to import Tkinter and call Tkinter.Tk() with uppercase T’s in Python 2.


  3. Thursday, June 29, 2017: up to the start of access_log in Lines in the in-class examples. Find someone who administers a computer that’s running an Apache web server and ask them about the web server’s access_log file.

    If I were you, I’d rewrite your graph paper script with for loops instead of while loops, but don’t hand it in. Is there a word (preferably in English) that starts with more than four leading consonants?

    Hand in a Python script that draws a picture using tkinter. (“Hand in” always means “upload to your Python-INFO1-CE9990 repository in your GitHub account.) The picture could be a flag, real or imaginary, but not the flag of France or any of the other European tricolors. Your script must have the user-defined drawPixel function we saw here. If you email me a link to the official Microsoft instructions for taking a screenshot or a shot of a window, I’ll paste them here. If you want, you can take a screenshot of your flag and upload it to your GitHub repository.

    Also hand in a Python script that does something interesting with for loops and if statements. (But not the same interesting thing as last week’s assignment.) We’ve seen lots of things that you can loop through with a for loop:

    1. The integers in a range of numbers.
    2. The characters of a string (with and without the index numbers too, using enumerate).
    3. The lines of an input file, at least if the input file is a text file. (If the input file is not a text file, it has no lines to loop through.)

    Some suggestions, but I’d rather have you surprise me. As usual, please look at each other’s homeworks.

    1. Exercise #6.
    2. Loop through the characters in a string.
    3. I’d like to avoid hardcoding the numbers 32 and 126 into the ASCII chart script. Can you avoid this by using the string string.printable and the ord function? Remember to import string.

    What is the value of the sys.platform string on your machine? Does it start with "darwin", "linux", or "win32"? Other than the Python scripts in the same directory as beer.py, is there any file that is present on both macOS and Microsoft Windows (and Linux)? See Lines.

    The function urllib.request.urlopen used to be urllib.urlopen in Python 2. I offer to be in the classroom at 6:15 p.m. on July 6 if anyone wants to set up Google Hangouts for me.


  4. Thursday, July 6, 2017: up to Sort a list in the in-class examples. Here’s the video of lecture 4 (July 6, 2017), with a guest appearance by Sam Sultan at 1:44:50. Should we do this again next week? Bring a head microphone. Now that you know how to read many lines from a file on the web, go back and look at the IBM example, which reads only one line.

    Zelda Salfati writes “Can you log in on Facebook and add me as a friend? I can add you to the
    Python INFO1-CE9990 Summer 2017 Section 2
    Facebook group only if I have you as a friend. Also if you can tell the other students to send their Fb name so that I can find them as well. Thanks!” Zelda’s Facebook name is
    Zelda Slt

    Write and upload a Python script that uses nested loops and a list of strings to output the lyrics of a song whose verses get longer and longer. Examples include The Twelve Days of Christmas (lyrics), Green Grow the Rushes, O (my favorite video of this song), There’s a Hole in the Bottom of the Sea, The Rattlin’ Bog, There Was an Old Lady Who Swallowed a Fly, etc. Foreign language is encouraged: אֶחָד מִי יוֹדֵעַ (Hebrew), חַד גַּדְיָא (the Wikipedia article comments dryly, “the composer’s grasp of Aramaic was limited”), etc. For the mathematical background, see Donad Knuth’s The Complexity of Songs. That’s the way, uh huh, uh huh, I like it!

    Also write and upload a Python script that inputs all the lines of a text file from your disk (it could be a web server’s access_log file) or from the web, and does something interesting with them (sort, search, convert them to numbers and add them up, find the maximum or minimum, print all or only some of them, etc). Pressed for time? You can combine the two assignments into a single script that reads the lines from a text file, stores them into a list of strings, and then uses the list of strings to output the lyrics that get longer and longer. Here’s how to use append to build up a list of the lines read from a text file, assuming that the file has already been opened (as in here) or urlopened (as in here). There’s an example of this append in the restaurant inspection results.

    listOfLines = []    #Start with an empty list.
    
    for line in lines:
        #If the line came from the web, use decode to
        #convert the line from a sequence of bytes into a string of characters.
        listOfLines.append(line)
    
    #Arrive here when all the lines have been stored in the listOfLines.
    #Close the input file.
    

    Of course, if you want to learn any language, you’ll have to write many more than two scripts per week. I’ll gladly improve (i.e., simplify) anything you want to post on GitHub.
    :)
    As usual, you can check this link to see who has posted recently.

    A difference between Python 2 and Python 3 we mentioned tonight: the Python 3 sort function takes a keyword argument named key that specifies a one-argument function. For example, see the one-argument function score in Sort a list. The Python 2 sort function took a keyword argument named cmp that specified a two-argument function. See the second paragraph of note (8).


  5. Thursday, July 13, 2017: up to Roman in the in-class examples. In CSV, you can specify a delimiter other than the default "," by using the delimiter argument of csv.reader. I wrote to Richard Czerwinski and asked him to install Tcl 8.5.18 on the Macs in room 1036 so we can use tkinter. I started posting to the Facebook group
    Python INFO1-CE9990 Summer 2017 Section 2.

    We saw three abbreviations tonight that will take some getting used to:

    1. Lambda functions (i.e., nameless functions).
    2. Conditional expressions.
    3. List comprehensions.
      1. without an if
      2. with an if

    Write a Python script that inputs information from one of the NYC Open Data databases and does something interesting with it. (New York City is unrivaled in its online databases; only San Francisco and its “Bay Area” begin to approach it.) It’s okay to use the restaurant inspection results that we already saw. Or you could pick another database. For example, I searched for “Parking Violations” and one of the databases I found was this one. (What is the most expensive fine?) Your script can read the CSV file from your hard disk or directly from the website, whichever you prefer.

    Also write a Python script that uses a list of lists to hold information in rows and columns. Examples we saw in class were the 5 rows and 4 columns of exercise 3 of Heterogeneous; the 13 rows and 3 columns of the final version of Christmas; and the 2 rows and 10 columns in count.py. You can create the list already loaded with information as in the above three examples, or you can start with an empty list([]) and append items to it as in CSV. Pressed for time? It’s okay to combine the two assignments into a single script that does both.

    A difference we mentioned tonight between the versions of Python: the sorted function appeared for the first time in verison 2.4 of Python (see the old documentation), while the sort function is aboriginal.


  6. Thursday, July 20, 2017: up to Popular in the in-class examples. Photographic evidence allowed me to correct the mileage to Montreal. Check out the Android course I’m teaching on Monday nights in Fall 2017 (November 6th to December 18th).

    Write an interesting script with a dictionary. It can have a GUI if you want. If any of the script’s lists are not supposed to change, let them be tuples.

    Equally important, study the exampes we saw tonight of lists that contain smaller lists in Roman, Plot Generator, and Manhattan. It would be really great of your script this week had a list that contains smaller lists and/or dictionaries, or a dictionary that contains smaller lists and/or dictionaries. How are your environment variables different from mine?

    Student code we looked at tonight:

    1. In csv.py, r is an int (line 31). Would z be a better name for it? What do lines 29, 35–36 do?
      r = some integer
      count = 0
      
      for i in str(r):
          count += 1
      
      #Simpler way to do the same thing.
      r = some integer
      count = len(str(r))
      
    2. sortandprint.py, line 42.
                  #Hardest to understand.
                  print(line[0]," ", line[1]," ",line[3]," ",line [4]," ",line [2]," ",line [5], sep="")
      
                  print(line[0], " ", line[1], " ", line[3], " ", line[4], " ", line[2], " ", line[5], sep = "")
      
                  #Easiest to understand.
                  print(line[0], line[1], line[3], line[4], line[2], line[5])
      
    3. A long chain of changes: per capita water consumption. Lines 37–46:
      index=0
      for line in hopLines:
          if index==0:
              print("Rank - {:4} - ".format(line[0]),line[3], sep="")
              index+=1
          else:
              print("{:4} - {:4} - {:4}".format(index,line[0],line[3]))
              index+=1
      

      No need to write index+=1 twice.

      index = 0
      for line in hopLines:
          if index == 0:
              print("Rank - {:4} - ".format(line[0]), line[3], sep = "")  #first line in file
          else:
              print("{:4} - {:4} - {:4}".format(index, line[0], line[3])) #all the remaining lines
      
          index += 1
      

      No need to write index += 1 once.

      for index, line in enumerate(hopLines):
          if index == 0:
              print("Rank - {:4} - ".format(line[0]), line[3], sep = "")  #first line in file
          else:
              print("{:4} - {:4} - {:4}".format(index, line[0], line[3])) #all the remaining lines
      
      Rank - Year - Per Capita(Gallons per person per day)
         1 - 1979 - 213
         2 - 1980 - 213
         3 - 1984 - 203
         4 - 1988 - 202
         5 - 1991 - 199
         6 - 1983 - 198
         7 - 1987 - 197
         8 - 1982 - 194
         9 - 1990 - 194
        10 - 1989 - 191
      

      The above output shows that the last {:4} failed. It failed because line[3] is a string. {:4} would right-justify a three-digit number, but {:4} left-justifies a three-character string.

      for index, line in enumerate(hopLines):
          if index == 0:
              print("Rank - {:4} - ".format(line[0]), line[3], sep = "")  #first line in file
          else:
              print("{:4} - {:4} - {:4}".format(index, line[0], int(line[3]))) #all the remaining lines
      

      The main bug is in line 35:

      hopLines= sorted(hopLines, key=lambda field: field[3], reverse=True)   # sort by per capita
      

      We’re sorting the numbers (the column of gallons) in alphabetical order, because the field[3] in line 35 is a string. When we try to fix it,

      hopLines = sorted(hopLines, key = lambda field: int(field[3]), reverse = True)
      

      the int function gives an error message: the field[3] on the first line of the file is a string that does not look like a number.

      firstline = hopLines[0]
      hopLines = sorted(hopLines[1:], key = lambda field: int(field[3]), reverse = True)
      
      print("Rank - {:4} - ".format(firstline[0]), firstline[3], sep = "")  #first line in file
      
      for index, line in enumerate(hopLines, start = 1):
          print("{:4} - {:4} - {:4}".format(index, line[0], int(line[3])))  #all the remaining lines
      

      Now the for loop no longer contains an if statement.

    4. After Roman, listless and listful.

  7. Thursday, July 27, 2017: up to Return tuple in the in-class examples. I added a simple XML example, and on August 3rd we’re going to have a brief oral report comparing JSON and XML. The instructor formally thanks the volunteer, and anticipates the usual circus-like atmosphere during the presentation. If you have a Twitter account, try to get Tweepy to work.

    We saw three websites in the JSON example from which we can download information in JSON format. Find another such website and write a Python script that will download information from it in JSON or XML format. If you’re downloading information in JSON format, change the sequence of bytes that you download into a string of characters, and then feed the string of characters to the function json.loads to convert the string into a Python list or dictionary.

    Also write a Python script that will call the os.popen function to launch another program on your Mac or PC. The Python script will then read input from the other program, and call close when it’s done reading. We did all of this in Set. Here’s a simple example: instead of "ps -A -o comm", the other program could be
    "/Library/Frameworks/Python.framework/Versions/3.6/bin/pip3 list"
    (Microsoft people will have to say py.exe -m pip instead of /Library/Frameworks/Python.framework/Versions/3.6/bin/pip3) which lists the installed Python packages, one per line. Your Python script could read these lines, count them, and then triumphantly print out the number of installed packages. Or you could do something more interesting with netstat -a -f inet -p TCP or ifconfig; after all, we live in a networked world.


  8. Thursday, August 3, 2017: up to the end of Class Date in the in-class examples. Study the three programs in the student code we looked at tonight. One of David Blaikie’s email addresses is here.

    Hand in the file classDate.py with exercises 2–8 of Class Date done to the definition of class Date in that file. On August 10th, we’ll test these changes to class Date using unit tests.


  9. Thursday, August 10, 2017: up to the start of Generator in the in-class examples. Study the List Comprehension examples. Install the latest version of SQLite on your Mac or PC. Please fill out and submit your NYU SPS course evaluations before 11:59 p.m. on August 17, 2017.

    I forgot how I videoed the July 6, 2017 lecture, so please email me instructions if you want me to video the August 17, 2017 lecture.

    Your final homework is to create the file location.py so that we can run uselocation.py and get the following output. The hexadecimal code number of the Unicode degree symbol ° is 00B0, so one way to print it is to print "\u00B0". See exercise 1 of Monte Carlo; line 37 of deblasio.py in Tweepy. A zero latitude should count as N, and a zero longitude should count as E, but I admit I’m being arbitrary here.

    The latitude of 40.7541476°N 73.9818586°W is 40.7541476.
    The longitude of 40.7541476°N 73.9818586°W is -73.9818586.
    The zipcode of 40.7541476°N 73.9818586°W is 10036.
    
    The latitude of 40.921787°N 73.905614°W is 40.921787.
    The longitude of 40.921787°N 73.905614°W is -73.905614.
    The zipcode of 40.921787°N 73.905614°W is 10705.
    
    The latitude of 90°N 73.905614°W is 90.
    The longitude of 90°N 73.905614°W is -73.905614.
    The zipcode of 90°N 73.905614°W is 00000.
    
    

    The file location.py will be similar in spirit to the file date.py you saw in Module. location.py will contain the class definition for a class named Location. Each object of the class will have instance attributes named latitude and longitude. The value of each of these instance attributes will be an int or a float.

    Class Location will have seven instance methods named __init__, __str__, getLatitude, setLatitude, getLongitude, setLongitude, and getZipcode.

    The getLatitude method will return the value of the latitude instance attribute of the Location object to which the getLatitude belongs. The getLongitude method will return the value of the longitude instance attribute of the Location to which the getLongitude belongs. But the setLatitude and setLongitude methods will not return anything, and will have no return statements. setLatitude will install a new value into the latitude instance variable of the Location object to which the setLatitude belongs, and setLongitude will install a new value into the longitude instance variable of the Location object to which the setLongitude belongs. (We are not using the @property function decorator in this assignment, because we never covered it in this course.)

    The methods that take numeric arguments should raise the TypeError exception if their numeric arguments are neither int nor float, and they should raise the ValueError exception if their arguments have illegal values. (A legal latitude is in the range –90 to 90 inclusive. A legal longitude is in the range –180 to 180 inclusive.) We saw methods that raise these exceptions in the date.py in Module.

    The most complicated instance method of class Location will be getZipcode, whch always returns a string of exactly five decimal digits. The string should be "00000" if the given location has no zipcode. Let’s assume that the location will always be in the United States. I’ll give you some help.

    There’s a convenient website that takes a latitude and longitude and gives you back the corresponding zipcode. To see a sample of the kind of JSON you receive from this site, point your browser at the following URL, which contains the latitude and longitude of our building at 11 West 42nd Street.
    https://maps.googleapis.com/maps/api/geocode/json?latlng=40.7541476,-73.9818586

    1. Observe that the whole JSON file is one big dictionary, enclosed in {curly braces}, containing keys named status (down at the bottom) and results (up at the top).
    2. The value corresponding to the status key is the string "OK".
    3. The value corresponding to the results key is a list of dictionaries.
    4. The first dictionary in this list contains a key named address_components.
    5. The value corresponding to this key is another list of dictionaries.
    6. One of the dictionaries in this list contains a key named types, whose corresponding value is a list of strings containing the string "postal_code". This dictionary also contains a key named long_name whose corresponding value is a string that is the zipcode you will return.

    The getZipcode method will create a URL containing the current latitude and longitude of the Location to which the getZipcode belongs. We saw in JSON how to get a dictionary containing all the information from a website that dispenses it in JSON format; the dictionary in that example arrived in line 41 of openweathermap.py. Here’s how getZipcode will use the dictionary that it receives from its file of JSON. Put in EAFP error checking to make sure that the dictionaries actually have the keys that we expect them to have, and to make sure that the list of results actually contains at least one item. (For EAFP vs. LBYL error checking, see Do and Attributes.)

            if dictionary["status"] != "OK":
                return "00000"                                     #The server couldn't find the zipcode.
    
            results = dictionary["results"]                        #results is a list of dictionaries
            firstResult = results[0]                               #firstResult is a dictionary
            address_components = firstResult["address_components"] #address_components is a list of dictionaries
    
            for component in address_components:                   #component is a dictionary
                if "postal_code" in component["types"]:            #component["types"] is a list of strings
                    return component["long_name"]                  #component["long_name"] is a five-digit string
    
            return "00000"
    

    At the bottom of the location.py file, write an if that does a little demo of class Location. For example, the demo could create and print one object of this class with a location in the United States, thus demonstrating that the __init__ and __str__ methods work correctly, and also print its zipcode.

    if __name__ == "__main__":
    

    Class trip to Mughlai and Oracle:



  10. Thursday, August 17, 2017: up to Inspection in the in-class examples.