OIM3640 - Problem Solving and Software Design

2026 Spring

Session 19 (4/02)

contain

Today's Agenda

  • Announcements/Updates
  • What We've Learned So Far
  • Review Questions
  • I/O Programming: Files, CSV, JSON

Announcements/Updates

  • Mini Project 2 - Text Analysis
    • Finish your code!
  • Mini Project - keep working on elective projects
  • Communication
    • Office Hours: Walk-in or by appointment
    • Email: Specify course # in subject, e.g., "OIM3640: GitHub settings"
    • You are required to meet with me at least once this semester
  • Questions?

What We've Learned So Far

  • Python Fundamentals: variables, types, functions, conditionals
  • Iteration: for, while, break, continue
  • Strings: indexing, slicing, methods
  • Data Structures: lists, dicts, tuples, sets
  • Text Analysis: word counting, frequency sorting
  • Error Handling: try/except
  • APIs: requests, JSON, API keys

🙋 Review Questions

try:
    x = int('hello')
    print('success')
except ValueError:
    print('oops')
print('done')
  • What gets printed?
  • What if you change 'hello' to '42'?

🙋 Review Questions (continued)

import requests
data = requests.get('https://oim.108122.xyz/mass').json()
print(type(data))
print(type(data['data']))
print(type(data['data'][0]))
  • What type does each print show?
  • How is this JSON structured?

APIs (continued)

Continue from last session

I/O Programming

Ch 13: Files and Databases

The with Statement

# Must remember to close the file
f = open('data.txt')
content = f.read()
f.close()  # easy to forget!

# Better: with auto-closes the file
with open('data.txt') as f:
    content = f.read()
# file closed automatically, even if error occurs

Always use with when working with files.

Reading Files

# Read entire file as one string
with open('data.txt') as f:
    text = f.read()

# Read line by line (best for large files)
with open('data.txt') as f:
    for line in f:
        print(line.strip())

strip() removes the newline character at the end of each line.

Writing Files

# 'w' = write (creates new or overwrites!)
with open('output.txt', 'w') as f:
    f.write('Hello, World!\n')
    f.write('Second line\n')

# 'a' = append (adds to end of file)
with open('log.txt', 'a') as f:
    f.write('New log entry\n')

Be careful with 'w' - it erases the file first!

Reading CSV Files

import csv

with open('students.csv') as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(f"{row['name']}: {row['grade']}")

csv.DictReader treats the first row as column headers.
Each row becomes a dict: {'name': 'Alice', 'grade': '95'}.

Writing CSV Files

import csv

data = [{'name': 'Alice', 'grade': 95},
        {'name': 'Bob', 'grade': 87}]

with open('output.csv', 'w', newline='') as f:
    writer = csv.DictWriter(f, fieldnames=['name', 'grade'])
    writer.writeheader()
    writer.writerows(data)

newline='' prevents extra blank lines on Windows.

JSON: File vs String

import json

data = {'name': 'Alice', 'age': 20}
Function What it does
json.load(f) Read JSON from file
json.dump(data, f) Write JSON to file
json.loads(s) Parse JSON string
json.dumps(data) Create JSON string

The s in loads/dumps stands for string.

Saving and Loading JSON

import json

data = {'course': 'OIM3640', 'students': 30}

# Save to file
with open('course.json', 'w') as f:
    json.dump(data, f, indent=2)

# Load from file
with open('course.json') as f:
    loaded = json.load(f)
print(loaded['course'])  # 'OIM3640'

indent=2 makes the file human-readable.

API to File Round-Trip

import requests, json

# Fetch from API
data = requests.get('https://oim.108122.xyz/mass').json()

# Save to JSON file
with open('mass.json', 'w') as f:
    json.dump(data, f, indent=2)

# Later: read it back (no API call needed!)
with open('mass.json') as f:
    data = json.load(f)
print(data['governor'])  # 'Maura Healey'

Quick Look: YAML

YAML - another human-readable format, great for config files:

import yaml

config = {'photo_dir': 'photos', 'extensions': ['.jpg', '.png']}

# Save
with open('config.yaml', 'w') as f:
    yaml.dump(config, f)

# Load
with open('config.yaml') as f:
    loaded = yaml.safe_load(f)

pip install pyyaml - JSON for data, YAML for config.

Quick Look: SQLite

import sqlite3

conn = sqlite3.connect('towns.db')
conn.execute('''CREATE TABLE IF NOT EXISTS towns
                (name TEXT, county TEXT, pop INTEGER)''')
conn.execute('INSERT INTO towns VALUES (?, ?, ?)',
             ('Boston', 'Suffolk', 675647))
conn.commit()

for row in conn.execute('SELECT * FROM towns'):
    print(row)  # ('Boston', 'Suffolk', 675647)

We won't go deep here - just know it exists! Demo code

Your Turn

Combine what you learned in S18 (APIs) and today (I/O):

  1. Fetch MA town data from oim.108122.xyz/mass
  2. Save the response as mass.json
  3. Read it back, print the governor and total number of towns
  4. Convert town data to CSV (mass.csv) with name, county, population, founded
  5. Challenge: find the most populated town and the oldest town

Before You Leave

  • Any questions?
  • Continue your Learning Log for this week (logs/wk10.md)
  • Finish MP2
  • Push your work to GitHub

Next session: Web Apps with Flask! See you then!

global styles