OIM3640 - Problem Solving and Software Design

2026 Spring

Session 20 (4/07)

contain

Today's Agenda

  • Announcements/Updates
  • What We've Learned So Far
  • Review Questions
  • I/O Programming (Files, CSV, JSON, YAML, SQLite)
  • Hands-on: API to File
  • Project 2 Sharing
  • Introduction to Flask

Announcements/Updates

  • Mini Project 2 - Text Analysis
    • We'll share your work today!
  • Mini Project 3 - Web App (details next session)
  • Elective Projects - now bonus opportunities (not required)
  • 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/finally
  • APIs: requests, JSON, GET/POST, API keys

🙋 Review Questions

# Code A
requests.get('https://oim.108122.xyz/mass')

# Code B
requests.post('https://oim.108122.xyz/echo',
              json={'name': 'Alice'})
  • What's the difference between GET and POST?
  • When would you use each one?
  • Where does the data go in each case?

🙋 Review Questions (continued)

from openai import OpenAI
client = OpenAI()  # reads OPENAI_API_KEY from .env

response = client.responses.create(
    model="gpt-5-nano",
    input="What is the capital of France?"
)
print(response.output_text)
  • What does this code do?
  • Why do we use .env instead of writing the key directly in code?
  • How would you change this to ask a different question?

I/O Programming

Saving and loading data from files.

Ch 13: Files and Databases

Reading and Writing Files

# Read entire file
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 \n

# Write to file ('w' = overwrite, 'a' = append)
with open('output.txt', 'w') as f:
    f.write('Hello, World!\n')

Always use with - it closes the file automatically.

CSV Files

import csv

# Read CSV (each row becomes a dict)
with open('students.csv') as f:
    for row in csv.DictReader(f):
        print(f"{row['name']}: {row['grade']}")

# Write 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)

JSON: File vs String

You already know response.json() from APIs. For files:

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.

API to File Round-Trip

import requests, json

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

# 2. Save to file (no API call needed next time!)
with open('mass.json', 'w') as f:
    json.dump(data, f, indent=2)

# 3. Load from file
with open('mass.json') as f:
    loaded = json.load(f)
print(loaded['governor'])  # 'Maura Healey'

Save API data locally so you don't hit the API every time.

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

Project 2: Share Your Work!

Pair up with a classmate and take turns (5 min each):

  1. Show your MP2 code and output
  2. Explain one design choice you made
  3. Ask your partner one question about their code

Switch partners after the first round if time allows.

Project 2: Discussion

After sharing, discuss with your partner:

  • What text source did you choose and what did you discover?
  • How did AI help you during the project?
    • What ideas or approaches did it suggest?
    • What did you learn from its suggestions vs. figure out yourself?
  • Did you learn any new libraries (e.g., matplotlib, pandas)?
  • What was the hardest part?
  • What would you do differently next time?

Introduction to Web Apps - Flask

So far: your Python scripts run in the terminal. What if anyone could use your program in a browser?

  • Flask turns your Python code into a website
    • You write Python, Flask handles the web part
  • Why Flask? Simple, beginner-friendly, used in production
    • Pinterest, Zillow, Twilio, Reddit, Netflix, ...
  • There's also Django (more powerful, more complex) - Flask is the right starting point

Flask - How URLs Work

Every website maps URLs to pages. Think about TikTok:

URL What you see
MyTiktok.com/ Home feed
MyTiktok.com/new Upload a new video
MyTiktok.com/1 Video #1
MyTiktok.com/1/edit Edit video #1

In Flask, you decide what each URL does:

@app.route('/new')       # when someone visits /new
def upload():            # run this function
    return 'Upload page'

Your First Flask App

Create a folder helloflask/, then create app.py:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello, World!'

if __name__ == '__main__':
    app.run(debug=True)
cd helloflask
pip install flask
python app.py     # visit http://127.0.0.1:5000

Flask Templates

Returning raw strings is limited. Use templates (HTML files):

app.py:

from flask import Flask, render_template

@app.route('/hello/<name>')
def greet(name):
    return render_template('hello.html', name=name)

templates/hello.html:

<h1>Hello, {{ name }}!</h1>
<p>Welcome to my Flask app.</p>

{{ name }} is replaced by the value passed from Python.

Your Turn

  1. Get your Flask "Hello World" running
  2. Add a route /greet/<name> that shows a greeting page using a template
  3. Challenge: Add a route /weather/<city> that fetches weather from the OpenWeather API and displays it in HTML

Flask Resources

Before You Leave

  • Any questions?
  • Start your Learning Log for this week (logs/wk11.md)
  • Get Flask running on your laptop
  • Explore Flask Quickstart
  • Push your work to GitHub

Next session: Flask forms, POST requests, and Mini Project 3!

global styles