Introduction to Python
davidbpython.com
Project Discussion, Session 6
6.1 | Notes typing assignment. Please write out this week's transcription notes. |
6.2 | Command Line Exercises. |
Please see last week's discussion. If you can't find the location of your python_data folder relative to your home directory, please get in touch with me. 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. m Note: please don't return to your home directory during the above journey - use '..' when you need to travel to a parent directory. |
|
6.3 | Trap one known exception and one undiscovered exception. Take two inputs using two calls to input(), asking for integer values. Convert to int, then divide one value by the other. |
Print the result, or if the user input raises an exception, trap the exception and print a suitable error message. Begin by completing the program's functionality without any consideration of errors. When the user types in two integer values, the program converts to int, divides the first by the second, and then prints the result. Once this program is complete, cause each of the two errors to occur, then use try/except to handle them. First, input a value that is not a number. When Python raises the exception that results, note the line number and type of exception. Wrap just this line in a try: block and use except with the exception type to print a suitable error message. (Make sure not to use except: by itself or except Exception:, as this is a bad practice in most situations.) Next, input two numbers, but make the second a 0. When Python raises the exception that results, note the line number and type of exception. Wrap just this line in a try: block and use except with the exception type to print a suitable error message. Lastly, see if you can combine the two error lines (the two lines you identified as raising the exception) into one try: block. Use an except block for the first exception followed by an except block for the second exception, each with its own error message. |
|
6.4 | Write a program that reads a config from a multidimensional structure and print out in a readable format. |
Start with this code: |
|
import json
fh = open('config.json')
conf = json.load(fh)
fh.close()
|
|
conf is a list of dicts containing the config data. Loop through each dict and print out the info as indicated. Use spaces and empty print statements to organize elements as shown. The purpose of this assignment is to help you disambiguate the nested braces and brackets that are found in a complex structure, and to use subscript syntax, and looping, to access "inner" structures. Another purpose is to help you learn to distinguish between situations where we want to loop, and ones where we want to subscript. This structure is a list of dicts, with one of the dict keys pointing to a string, another dict key pointing to an "inner" dict, and a dict key pointing to an "inner" list. All of the 3 dicts are uniform in structure, as is usually the case with config files -- they may be arbitrarily structured, but the structure is reliable. As discussed in the slides and with some of the exercises, an easy way to explore these structures is to travel from "out" to "in" by accessing an element of the outer structure, and seeing what you have. So considering conf, notice that it's a list of dicts. If you loop through this list, each element will be one of the 3 dicts, each in turn. In a small-step fashion, try learning things about this dict. You can print the len() of the dict. You can print the keys of the dict. For example, here's my attempt at printing the keys of the dict: |
|
for entry in conf:
print(list(entry.keys()))
|
|
You'll see a list of the keys in each dict. It becomes clear that entry is each dict, and you should be able to print out the 'domain' value very easily. The 'database' key points to another dict, however. Now you have to treat entry['database'] as a dictionary. You can call keys() on this dict as well: |
|
list(entry['database'].keys())
|
|
So it should be relatively clear how to print the values in the "inner" dict. The list associated with entry['plugins'] must also be treated as a list. You can loop through this list, take its len(); whatever you'd like to do with a list you can do it with entry['plugins']. Again, some of the exercises cover multidimensional structures, so if anything is unclear make sure to do those as well. * please don't subscript the outer list -- loop through it * please don't loop through any of the dictionaries -- use subscripts * please don't subscript the "plugins" list -- loop through it Special error note: if you get a JSONDecodeError this means that something is wrong with the json in the .json file, such as a missing quote or comma; this is similar to a SyntaxError in Python. This might happen if you open the .json file and then save it. To fix this problem, re-download the python_data_ipy folder and copy over the same .json file to replace the file in your project directory (i.e., your original copy of python_data_ipy) and try again - let me know if you can't resolve this issue. |
|
EXTRA CREDIT |
|
6.5 | Reading through FF_tiny.txt, build a dict of lists in which the key is the 4-digit year and the value is a list of Mkt-RF values (the 2nd values, or leftmost float values) for that year. |
This solution will be very similar to previous Fama-French assignments, in particular one in which you built the 'summing' dictionary. Consider that in that assignment you maintained and updated a float sum for each year. In this assignment you'll maintain a list of float values for each year. Your dictionary considerations will be the same (specifically, whether a key is new or already exists in the dict); this time instead of pairing a new key (i.e., a key not yet in the dict) to value 0, you'll pair the new key to an empty list. Instead of adding a new value to the float paired with an old key (i.e., a key already in the dict), you'll append a new value to the list paired with the old key. |
|
As you loop line by line, the operative code line is this:
mktrf_sum[year].append(mktrf_value_from_line)
|
|
where you are appending the Mkt-RF value (the 2nd value, or leftmost float value) to a list of values for a given year. However, as discussed, you will need to check the dict ahead of time to see if the ticker key is already there. If not, set the key and value in the dict for that line. |
|
ticker_prices[ticker] = []
|
|
Please avoid looping through the FILE more than once (you WILL NEED to loop through the dict keys once you've built it). Please avoid using a separate list or set to hold any of the values. A dictionary of lists is all you need! This exercise helps you see how you can build a multidimensional structure. |
|
Pseudocode:
initialize an empty dict loop through the file line-by-line split line into a list slice out the year if the year is not in the dict (i.e., is not a key): set the year as key, and value as empty list append the new float value to the list for this key loop through the dict keys, and print out the key and then value for that key (i.e., the list of values for that year) Note that if Python can't find your file, it may be because the relative path is incorrect. Please see "Filepaths for Locating Files" in Session 3 Slides. |
|
6.6 | Use the NOAA Weather API to access the current weather conditions in San Francisco, CA. |
import requests
import json
response = requests.get('https://api.weather.gov/gridpoints/'
'OKX/33,39/forecast')
obj = json.loads(response.text)
|
|
There are several forecasts in the data -- please select the earliest. Please note that sometimes the NOAA API is not available - if so, you must wait until it becomes available again. This assignment offers the experience of working with an unfamiliar JSON structure without supporting documentation. You should be able to see much of the structure by using json.dumps(obj, indent=4) to render the structure with indents. You should be able to read the structure with your eyes to determine the order of objects nested without the "outer" object. You should also be able to inspect any of the objects supported by JSON (lists and dicts; strings, ints and floats) by using type() to identify the object, and then standard object inspections (len() to get an object's length, subscripting to read an item, mydict.keys() to get a dict's keys, and for looping). Understanding that any container object may contain other containers, start from the initial variable, determine its type, then inspect that object. This will lead you to the objects contained within, then leading you further into the contents. Always think just in terms of the container that is in front of you - if a list, consider whether to loop or subscript a simple list - if a dict, consider whether to loop or subscript a simple dict. Doing so will lead you to the next innermost structure, etc. If you get an error mentioning SSL: CERTIFICATE_VERIFY_FAILED then please refer to discussion in the Session 3 slide deck involving requests -- the code needed to circumvent this error can be found there. |
|