Introduction to Python
davidbpython.com
Project Discussion, Session 7
7.1 | Notes typing assignment. Please write out this week's transcription notes. |
7.2 | Command Line Exercises. |
Please see prior weeks' discussion. Please remember that executing (i.e., running) a file is not done using the open command; instead it is done with the python (Windows) or python3 (Mac) command. Note: please don't return to your home directory during the above journey - use '..' when you need to travel to a parent directory. |
|
7.3 | tipcalc(). You already completed this calculation in Week 1. This program is simply asking you to convert part of that program (the calculation) to a function. |
|
|
7.4 | Complete the get_student_name() function. The function expects a filename and student id as arguments and returns the student's full name. |
Step 1: we will begin by building the functionality without the function, then add it to the function later. Please create a brand new program that does not include the sample code. This program will start with a student id and will open the student_db_names.txt file:
student_id = 'jk43'
fh = open('student_db_names.txt')
|
|
Step 2: add the statement next(fh) to progress past the first line in the file (the headers). This will cause the for loop to start on the 2nd line of the file, after the headers. Step 3: loop through the file, split each line, and compare the id on each line to the student_id variable, above set to 'jk43'. If the line has this id, print the line. This is very similar to what we did in past weeks' assignments. Step 4: continue the above program so that instead of printing the entire line, you print the first and last name together. Then build the first and last name as a single string and print the string. Step 5: once you have tested this code with more than one id and see that it is working properly, place your entire program, including all the code you have written to open and read the file, inside a function, and make changes to make it into a reusable function: remove the student_id = 'jk43' line and the fname = '../student_db_names.txt' lines. Have the function accept two arguments, which will be the student id and the filename. Make sure that the filename and id used by the function HAS BEEN PASSED TO THE FUNCTION -- THE FUNCTION MUST NOT USE ANY 'OUTSIDE' VARIABLES! You also must take care not to open the file outside the function - this would produce an outside variable which you must not refer to inside the function. Step 6: instead of printing the student's full name, use a return statement to return the student's full name from the function. MAKE SURE YOUR FUNCTION DOES NOT PRINT ANYTHING. Step 7: use the stub program provided in the assignment with your completed function and make sure that it works as shown in the example calls -- it must take 2 arguments and return 1 value. MAKE SURE YOU ARE RUNNING THE ENTIRE STUB CODE PROVIDED! Special note on None appearing for the 2nd id: you may find that when you run the sample program that the first id (ap172)returns a name, but the second (valid) id (jab44) returns None. Experimenting, you may try different ids and get differing results. For example, if you reverse the ids in the test, and look for jab44 first followed by ap172, you'll find that both names are returned correctly. This last experimental result should indicate that something more is at play besides faulty logic - in fact it does appear that the logic works - but why for an id based on the order in which we request them? The operative knowledge needed to understand the root of this problem is the nature of a "file" object. Note the result below: |
|
fh = open('student_db_names.txt')
for row in fh: # starts at the 1st line
print(row) # id:fname:lname:address:city:state:zip
break # takes us out of the loop after the first iteration
for row in fh: # starts at the 2nd line
print(row) # jk43:John:Kane:23 Marfield Lane:Plainview:NY:10024
break
# now pointing at the 3rd line
line = next(fh) # axe99:Alfred:Everbooty:315 W. 115th Street, Apt. 11B:New York:NY:10027
|
|
Note above that when we start looping through a file, we get the |
|
7.5 | Given a 4-digit year, use a list comprehension to produce a list of only those lines from a selected year, stripped of the newline. |
Note: please do not use a function for this solution. The basic form of a list comprehension is this: |
|
endlist = [ transformed item for item in iterable if test ] |
|
File object iterator. Recall that a list comprehension reads from an iterable -- that is, an object you can loop over with for (file object is an iterable). The list comprehension iterates over the iterable object and returns a list of values (modified and/or selected) from the iterable. The object types we've been able to iterate over are file (literally called a "TextIOWrapper"), a list, a dict, a set, and a tuple. So your file object is the iterable, and one item from the iterable is a file line. |
|
user_year = '1928'
fh = open('FF_tiny.txt')
endlist = [ line for line in fh ]
fh.close()
|
|
Or better, you can be even more succinct and say:
endlist = [ line for line in open('FF_tiny.txt') ]
|
|
Test this step by printing endlist -- you should see all the lines in FF_tiny.txt from start to end, each in a list. Filtering test: does the line start with 4-digit year? Add an 'if' test after the iterator (see examples, and look at the form at the top of this discussion for proper placement) to filter the list. The test asks whether the year in the line is the same as the user's year. You may be able to replicate the "year test" you used in some of the prior Fama-French solutions (i.e., if this is the user's year...). Keep in mind you can slice the line (a string); you don't need to split off the date in order to slice it. Test this step by again printing endlist -- you should see all the lines in FF_tiny.txt that start with your year (in the above example, 1928). Modify the line to strip the line. Remember that the first part of the list comprehension (the "transform") determines what will go into the result list. You simply need to replace the first line with the call that strips the line of its newline. |
|
7.6 | Given a 4-digit year, use a list comprehension to produce a list of all Mkt-RF values (the 2nd values, or leftmost float values) as floats from FF_tiny.txt that belong under a selected year. |
The basic form of a list comprehension is this: |
|
endlist = [ transformed item for item in iterable if test ] |
|
This solution can be extended from the for-credit list comprehension. To derive just the float value from the line, you'll add this step: Modify the stripped line to return just the Mkt-RF value (the 2nd value, or leftmost float value) from the line. This is tricky because you must do this work in one statement: split the line and subscript the resulting list in one statement. |
|
How to do it? For this, you must combine the two expressions. Here are the two expressions:
line = '19270701 0.09 3.35 1.12 0.01'
items = line.split()
value = items[1] # 0.09
|
|
The idea in combining these two expressions is that the variable items is not needed if you can subscript the split() directly. You should test your combined expression in the separate code snippet above. Once you can see that it is working, then you can put it into your list comprehension at the transformed item portion of the "basic form" at the top of this discussion. You can find examples of this kind of expression combining in the slides on list comprehensions. |
|