A document from MCS 260 Fall 2021, instructor David Dumas. You can also get the notebook file.

MCS 260 Fall 2021 Homework 8 Solutions

  • Course instructor: David Dumas
  • Solutions prepared by: Johnny Joyce

Instructions:

  • Complete the problems below, which ask you to write Python scripts.
  • Upload your python code directly to gradescope, i.e. upload the .py files containing your work. (If you upload a screenshot or other file format, you won't get credit.)

Deadline

This homework assignment must be submitted in Gradescope by 10am CST on Tuesday, October 19, 2021.

Topic

This homework focuses on exceptions, the os module, and the function- and assignment-related concepts from Lecture 20 (multiple return values, tuples, tuple assignment, variadic functions, iterable unpacking).

Collaboration

Collaboration is prohibited, and you may only access resources (books, online, etc.) listed below.

Resources you may consult

The course materials you may refer to for this homework are:

Point distribution

This homework assignment has 2 problems, numbered 2 and 3. The grading breakdown is:

Points Item
2 Autograder
4 Problem 2
4 Problem 3
10 Total

What to do if you're stuck

Ask your instructor or TA a question by email, in office hours, or on discord.

( 1. There's no problem 1 )

Gradescope will show the results of the automated syntax check of all submitted files as the score for problem 1.

2. Robust chemical element CSV to JSON

In Homework 7, problem 3 (titled "Chemical element CSV to JSON"), you wrote a program to convert a CSV file containing data about chemical elements to a JSON file. The program used hard-coded filenames elements.csv and elements.json.

Modify this program (either start with one of the solutions posted to the course web site, or your own solution) so that it is robust to all of the following conditions:

  • elements.csv does not exist
  • elements.csv exists and is a CSV file, but it has fewer than 3 columns
  • elements.csv exists and is a CSV file with columns called number, abbreviation, and name, but some of the values in the column number are not integers

If any of these conditions arises, the program should print an error message describing the situation and then exit without creating elements.json nor writing anything to it.

Hint: You can detect these error conditions because they cause exceptions. I recommend forcing each of these things to happen and checking the type of exception that results.

Save the result as hwk8prob2.py.

Solution

The solution below is a direct modification of last week's solution 1 for homework 7 problem 3, and not all that much has actually changed. For the most part, we've just added try and except statements to catch various kinds of errors.

The solution for this week's problem could also be based on one of the other solutions to problem 3 from homework 7. We can use another try & except statement when opening the file, and a try & except statement when attempting to read the file's contents, with the latter needing to catch at least two different types of exceptions.

In [2]:
import csv
import json

# Open the CSV file and initialize the reader
try:
    infile = open("elements.csv", "r", encoding="UTF-8", newline="")
except FileNotFoundError:
    print("Error: elements.csv does not exist")
    exit()
reader = csv.reader(infile)

# Initialize a list to put our JSON data into
jsondata = []

# Is this the first iteration where we are looking at the header row?
on_header = True

# Iterate over each line in the CSV file
for element in reader:
    if on_header:
        # Record that we're done reading the header row
        on_header = False
    else:
        # This is a regular row, not the header
        # Make a dictionary for this row and add it to jsondata
        try:
            elementjson = {
                "number": int(element[0]),
                "abbreviation": element[1],
                "name": element[2]
            }
        except IndexError:
            print("Error: elements.csv exists and is a CSV file, but it has fewer than 3 columns")
            infile.close()
            exit()
        except ValueError:
            print("Error: Some of the values in the column `number` are not integers")
            infile.close()
            exit()
        # Read succeeded so add this dict to the list we'll write as JSON.
        jsondata.append(elementjson)
infile.close()
        
# Get the output JSON file ready
outfile = open("elements.json", "w", encoding="UTF-8")
        
# Write the JSON data to the output file
json.dump(jsondata, outfile)
    
# Close the files
outfile.close()

3. Listing Python files containing the word "Lecture"

Motivation

Most of the sample programs we've written in lecture contain a comment listing the lecture or lectures in which we worked on or discussed the program. Usually such a comment looks like this:

# Lecture 12

or this:

# MCS 260 Fall 2021 Lecture 9

This problem is motivated by the question: How could you write a Python script to find all such example programs that mention a specific lecture?

Your task

Write a program that prints a list of names of all files in the current directory that meet both of the following criteria:

  1. The filename ends with .py.
  2. The text inside the file contains the string Lecture somewhere.

To test this program, you should probably create another file in the current working directory that ends with .py and which contains the string Lecture somewhere!

You don't need to split a file into words for this problem; for example, if a file has first line asdfLecturefghil and its name ends in .py, this program should print its name.

Save the result as hwk8prob3.py.

Restricted methods note: For full credit your answer may only import these modules: os, json, and csv.

BE CAREFUL: This program should only open files for reading. It would be dangerous to open all files in the current directory for writing, because that would delete the current contents!

Example: When I run a program meeting the specifications of this problem with the current working directory set to the samplecode directory for MCS 260, the output is:

quadroots.py
wordlist.py
jsonreaddemo.py
wordstats3file.py
terminal.py
terminal_2pm.py
inputyesno.py
terminal2.py
collatz.py
csvwritedemo.py
rectangle.py
parentheses.py
csvdictreaddemo.py
greet.py
csvinfo.py
spillreport.py
quadsquare.py
csvreaddemo.py
wordstats3.py
terminal_10am.py
charactertype.py
parentheses2.py
collatz_nofunction.py

Solution

The solution below produces an output which only shows hwk8prob3.py (i.e. the name of the solution below). This is because the other files in the example above were not present when running this solution. The word "Lecture" appears in hwk8prob3.py inside the if statement to check whether the word "Lecture" appears in the first place!

In [4]:
import os

cwd = os.getcwd() # Get current working directory (cwd)

for filename in os.listdir(cwd): # Iterate over files in the cwd

    # Use the string slice [-3:] to check the last 3 letters
    if filename[-3:] == ".py":

        # Open the file, then read it. Note that we don't have to specify the entire
        # path because we are already looking inside the current working directory
        file = open(filename, "r", encoding="UTF-8")
        contents = file.read()

        if "Lecture" in contents:
            print(filename)

        file.close()
spillreport.py
csvdictreaddemo.py
collatz.py
csvwritedemo.py
collatz_nofunction.py
terminal_10am.py
inputyesno.py
greet.py
jsonreaddemo.py
parentheses.py
quadsquare.py
rectangle.py
terminal.py
wordlist.py
quadroots.py
parentheses2.py
charactertype.py
terminal_2pm.py
wordstats3.py
csvinfo.py
csvreaddemo.py
terminal2.py
wordstats3file.py

Revision history

  • 2021-10-21 Initial release of solutions