Introduction to Python

davidbpython.com




Projects, Session 7



PLEASE REMEMBER:

  1. re-read the assignment before submitting
  2. go through the checklist including the tests
  3. make sure your notations are as specified in the homework instructions

All requirements are detailed in the homework instructions document.

Careless omissions will result in reductions to your solution grade.

 
7.1 Notes typing assignment. Please write out this week's transcription notes. The notes are displayed as an image named transcription in each week's project files folder.

This does not need to be in a Python program - you can use a simple text file.

 
7.2 Command Line Exercises.

As usual, returned solutions will lose points. It is recommended to confirm (through testing) that your answer is correct before submitting to ensure that you will receive credit. As previously, reaffirm the location of your python_data folder relative to your home directory.

1. Open a Windows Explorer or Mac Finder window and find the python_data folder. As with previous sessions, this week's session_07_functions_power_tools folder contains the dir1 folder tree:
python_data
├── session_00_test_project
├── session_01_objects_types
├── session_02_funcs_condits_methods
├── session_03_strings_lists_files
├── session_04_containers_lists_sets
├── session_05_dictionaries
├── session_06_multis
└── session_07_functions_power_tools
    └── dir1
        ├── file1.txt
        ├── test1.py
        │
        ├── dir2a
        │   ├── file2a.txt
        │   ├── test2a.py
        │   │
        │   └── dir3a
        │       ├── file3a.txt
        │       ├── test3a.py
        │       │
        │       └── dir4
        │           ├── file4.txt
        │           └── test4.py
        └── dir2b
            ├── file2b.txt
            ├── test2b.py
            │
            └── dir3b
               ├── file3b.txt
               └── test3b.py

2. Please update the following files as specified:

test2a.py:  update the open('') function call so that it opens file file4.txt.

test3b.py:  update the open('') function call so that it opens file file3a.txt.

For file test3b.py, don't forget that to execute a file in a directory at the same "level" as the one the script is in, the path must say "down, then up". "Down" of course means using .. and "up" means specifying the directory you'd like to travel to. 3. Open your computer's command line program (on Windows it is called Anaconda Prompt; on the Mac it is Terminal). Please do not use PyCharm's Terminal tab for this assignment. 4. Now, in the open command line session, please perform the following actions in this order: A. Travel to dir2a B. Execute file test2a.py (you should see this is file4.txt) C. Travel to dir3b D. Execute file test3b.py (you should see this is file3a.txt) 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. 5. If you made a lot of mistakes in performing the above, please make note of the correct commands that you needed, then click the small 'x' at the top left tab of the Terminal window to close the Terminal, and then reopen it and start fresh using the correct commands (it's OK to make a few mistakes; your commands do not have to be perfect!). 6. Finally, please copy and paste your entire Terminal session into the homework submisssion window and submit.

 
7.3 Write a function tipcalc(bill, party, pct) that takes 3 arguments: a total bill (a float), number in party (int) and tip percentage (int). The program calculates and returns the amount to be paid by each person.

The function should also raise a ValueError exception (use the raise statement) if either of the first two arguments are 0 or less (which would invalidate any results). THE FUNCTION MUST NOT USE ANY OUTSIDE VARIABLE NAMES. IT MUST WORK ONLY WITH THE 3 ARGUMENTS PASSED TO THE FUNCTION. (However, please give your function variable names meaning, not x, y, z, etc.) THE FUNCTION MUST NOT USE input(). IT MUST WOR ONLY WITH THE 3 ARGUMENTS PASSED TO THE FUNCTION. THE FUNCTION MUST NOT PRINT ANYTHING. IT MUST USE THE return STATEMENT TO SEND THE RETURN VALUE BACK FROM THE FUNCTION. THE FUNCTION MUST NOT exit(). IT MUST USE THE raise STATEMENT TO SIGNAL AN ERROR. After completing the function, please run the stub code below and verify that the function returned the indicated values. YOU MUST RUN THE BELOW CODE AND SEE THE OUTPUT AS SHOWN!

# your 'def' function here (PLEASE INCLUDE the below code with your function)

total = 100.0                         # DO NOT REFER TO THESE
num = 4                               # VARIABLES INSIDE
tip_pct = 20                          # THE FUNCTION!

share = tipcalc(total, num, tip_pct)  # total bill of 100, 4 in party, 20% tip
print(share)                          # 30.0

share = tipcalc(150, 3, 15)           # total bill of 150, 3 in party, 15% tip
print(share)                          # 57.5
Testing the raise of ValueError if first two args are not > 0:
share = tipcalc(0, 3, 5)              # should see ValueError:  'bill' and
                                      # 'number in party' must be greater than 0

share = tipcalc(150, -1, 5)           # should see ValueError:  'bill' and
                                      # 'number in party' must be greater than 0

Test each of the above two calls separately. Remember that the correct output from the last 2 calls is an exception. This will look like an error to you, but is not an error -- it is the result of your raise statement.
HOMEWORK CHECKLIST: all points are required


     The function returns the share value exactly as shown.
 
    The tests (with raise if they fail) are performed first, before any calculations.
 
     Blank lines are used to separate steps inside the function as well as outside of it.
 
     The function will not refer to outside variables (like 'bill', 'num' and 'pct')! Instead, use the function's arguments inside the function.
 
     The function will not print anything! Some students print from the function and think they've returned from the function. The function must return a float using the return statement.
 
     The function will not use input(). It simply expects the 3 numeric arguments, then uses the arguments to calculate and return a float value.
 
     The function will not exit(). If you want to signal an error (not required), use the raise statement, e.g. raise ValueError('arg must be a float') However, this is not required.
 
     Make sure your function variable names do not match those outside the function! The function must be self-contained and not refer to any outside variables. However, please do come up with descriptive names for your function variables - not 'var1', 'a', 'b', etc.
 
     If you see None printed, remember that any function that does not have a return statement will return None. Does your function return the float using the return statement, or does it just print it? (Remember, no printing inside the function!)
 
     Be sure to extend the use of blank lines to separate steps, to inside a function as well. The function should not be one solid block, otherwise it's challenging to read.

 
7.4 A function that can pull information from a file. Complete the function code below (see YOUR CODE HERE). The function expects a filename fname and student id stuid as arguments and returns the student's full name.

Please note this solution does not need to include a list comprehension. THE FUNCTION MUST NOT USE ANY OUTSIDE VARIABLE NAMES. IT MUST NOT USE THE NAMES sid OR name. IT MUST WORK ONLY WITH THE ARGUMENTS fname and stuid PASSED TO THE FUNCTION. (However, please use descriptive variable names always.) THE FUNCTION MUST NOT PRINT ANYTHING. IT MUST USE THE return STATEMENT TO SEND THE RETURN VALUE BACK FROM THE FUNCTION.

def get_student_name(fname, stuid):
    """ - expects a filename (str) and a student id (string)
        - opens the specified file
        - loops through the file and reads the first field
        - if the student id is found in the first field,
          returns the student's full name, built from the first
          name and last name in the line
        - if the student id is not found, returns None
        - (not required to include a list comprehension)

        Arguments:     a filename (string) and a student id (string)
        Return value:  the student's full name, or None if not found
    """
    # YOUR CODE HERE


sid = 'ap172'
fname = '../student_db_names.txt'

name = get_student_name(fname, sid)
print(name)                     # Anton Perillo

sid = 'jab44'
name = get_student_name(fname, sid)
print(name)                     # Janine Brillo

sid = 'ak9'
name = get_student_name(fname, sid)
print(name)                     # Axel Krumpet

sid = 'xxx'
name = get_student_name(fname, sid)
print(name)                     # None (please make sure this is the
                                # None value (no quotes), and not
                                # a string 'None'.  They print the same.)

if name is not None:
    print("error:  your code must return the value None (no quotes) and not a string 'None'")


HOMEWORK CHECKLIST: all points are required


     The test for the id focuses specifically on the 'id' field (first field). It does not look for the id anywhere in the line, because a) we want to be precise where possible, and b) we want to indicate to the reader exactly where we expect the id to be.
 
     The function returns the student name exactly as shown.
 
     Blank lines are used to separate steps inside the function as well as outside of it.
 
     The function will not print anything! Some students print from the function and think they've returned from the function. The function must return a string using the return statement.
 
     The function will not use input(). It simply expects the string argument, then uses that string argument to find and return a string from the file.
 
     The function will not exit(). If you want to signal an error (not required), use the raise statement, e.g. raise ValueError('arg must be an int')
 
     Make sure your function variable names do not match those outside the function! The function must be self-contained and not refer to any outside variables.
 
     If you see None printed, remember that any function that does not return anything will return None. Does your function return the string using the return statement, or does it just print it?
 
     If you see a name for the first id printed followed by None for the second id, there is a subtle truth about file objects to consider: any open file object will allow you to loop through the file only once. If you loop partially through the file and then ask the file object to loop through the file again, it will resume looping from the point at which it left off (using an internal "file pointer"). See discussion for more detail about this issue.

 
7.5 Given a 4-digit year, use a list comprehension (do not use a conventional 'for' loop) 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.

  • Read the 4-digit year from input().
  • Open the FF_tiny.txt file, returning a file object.
  • Now, write a list comprehension that uses the file object as its "source" data.
  • Have the "filtering" part of the list comprehension select only those lines that match the 4-digit year.
  • Have the "transforming" part of the list comprehension .rstrip() the line so it has no newline character.
  • Make sure to use only one list comprehension, and don't attempt to do any pre- or post-processing - the list comprehension has to handle everything except the above
  • Print the resulting list.

Sample program runs:
please enter a year:  1926
['19260701    0.09    0.22    0.30   0.009', '19260702
0.44    0.35    0.08   0.003']
please enter a year:  1927
['19270103    0.97    0.21    0.24   0.015', '19270104
 0.30    0.15    0.73   0.011', '19270201    0.00    0.56
 1.09   0.022', '19270202    0.72    0.23    0.18   0.018' ]
please enter a year:  1928
['19280103    0.43    0.90    0.20   0.001', '19280104
 0.14    0.47    0.01   0.003', '19280105    0.71    0.14
 0.15   0.004']


HOMEWORK CHECKLIST: all points are required


    testing: you have run the program with the sample inputs as shown and are seeing the output exactly as shown (contact me if your output is different and you're unable to adjust to match)

    the program does NOT use a conventional 'for' loop. If you aren't sure what a list comprehension is, please see slide deck or videos

    there is only one list comprehension (keep in mind you can do filtering and transforming in the same list comprehension)

    the list comprehension is able to do everything except taking the input, opening the file and printing output

    the list comprehension iterates over the file object line by line and compares the first four digits of the line to the user's year in order to filter out other years.

    there are no extraneous comments or "testing" code lines

    program follows all recommendations in the "Code Quality" handout

 

EXTRA CREDIT

 
7.6 (Extra Credit.) Extend your list comprehension to produce a list of all Mkt-RF values (the 2nd column, or leftmost float values) as floats from FF_tiny.txt that are found for a selected year.
please enter a year:  1926
[0.09, 0.44]
please enter a year:  1927
[0.97, 0.30, 0.00, 0.72]
please enter a year:  1928
[0.43, 0.14, 0.71]

  • Read the 4-digit year from input().
  • Open the FF_tiny.txt file, returning a file object.
  • Attempt to use a list comprehension to do all of the work of isolating the Mkt-RF values and converting to float. You'll need to split, subscript and convert to float all in one combined statement inside the list comprehension (example of this kind of technique can be found in the slides).


Checklist (for extra credit only):

    the list comprehension is able to do everything except taking the input and printing output

    the result is a list of floats, not a list of strings.

    the list comprehension can iterate over the file line by line, isolate the float value and convert it to float, as well as slice the line and compare the first four digits to the user's year in order to filter out other years.

    there are no extraneous comments or "testing" code lines

    program follows all recommendations in the "Code Quality" handout

 
[pr]