OIM3640 - Problem Solving and Software Design

2026 Spring

Session 18 (3/31)

contain

Today's Agenda

  • Announcements/Updates
  • What We've Learned So Far
  • Review Questions
  • Error Handling
  • APIs and JSON

Announcements/Updates

  • Mini Project 2 - Text Analysis
    • Start coding if you haven't already!
  • 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

🙋 Review Questions

words = 'the cat sat on the mat'.split()
print(len(words))
print(len(set(words)))
  • What does each print output?
  • Why are the two numbers different?

🙋 Review Questions (continued)

def mystery(s):
    return len(set(s)) == len(s)

print(mystery('hello'))
print(mystery('world'))
  • What does each print output?
  • What does mystery check for?

🙋 Review Questions (continued)

freq = {'a': 3, 'b': 1, 'c': 2}
result = sorted(freq.items(), key=lambda x: x[1])
print(result)
  • What does result look like?
  • How would you get the item with the highest count?

Error Handling

What happens when something goes wrong in your code?

Errors You've Seen Before

print(name)          # NameError
'hello' + 5          # TypeError
my_list[99]          # IndexError
my_dict['missing']   # KeyError
open('nope.txt')     # FileNotFoundError

Python crashes at the first error. Can we do better?

try / except

try:
    age = int(input('Your age: '))
    print(f'You are {age} years old')
except ValueError:
    print('That is not a valid number!')
  • Code in try runs normally
  • If an error occurs, Python jumps to except
  • Program keeps running instead of crashing

Catching Specific Exceptions

scores = {'Alice': 95, 'Bob': 87}

try:
    name = input('Student name: ')
    print(f'{name}: {scores[name]}')
except KeyError:
    print(f'{name} not found')

Always catch specific exceptions, not bare except:.

Next up: we'll use this with APIs!

API (Application Programming Interface)

What is an API?

  • You (human): open browser, search "weather Boston", read a website
  • Your code: send a request, get structured data back
Your Python code  -->  HTTP request  -->  API server
                  <--  JSON response <--

Examples: current Bitcoin price, weather data, people in space...

JSON: Data for Computers

JSON looks just like Python dicts and lists:

{
  "name": "Boston",
  "temp": 72.5,
  "tags": ["sunny", "warm"],
  "wind": {"speed": 8, "dir": "NW"}
}

response.json() converts JSON to a Python dict. That's it!

Getting Started

Install the requests library:

pip install requests

Your first API call - just 3 lines:

import requests

response = requests.get('https://oim.108122.xyz/words/random')
print(response.json())   # a random word!

Try it now!

Parsing Rich API Data

response = requests.get('https://oim.108122.xyz/mass')
data = response.json()

print(data['name'])       # 'Massachusetts'
print(data['governor'])   # 'Maura Healey'

for town in data['data'][:5]:
    print(f"{town['name']}: pop {town['population']:,}")

Nested JSON: dicts inside lists inside dicts.

Error Handling + APIs

try:
    response = requests.get('https://oim.108122.xyz/mass')
    data = response.json()
    print(data['name'])
except requests.exceptions.ConnectionError:
    print('Cannot connect to the API')
except KeyError as e:
    print(f'Missing key: {e}')

APIs can fail: network down, server errors, missing data.

GET vs POST

# GET: read/fetch data
requests.get('https://oim.108122.xyz/words/random')

# POST: send/submit data
requests.post('https://oim.108122.xyz/echo',
              json={'name': 'Alice', 'course': 'OIM3640'})

Visit oim.108122.xyz/echo/view in your browser.
What happens? Why?

🔴 Live: Watch Each Other's Requests!

Open oim.108122.xyz/live on the projector.

import requests

response = requests.get(
    'https://oim.108122.xyz/words/random',
    headers={'X-Token': 'alicealice'},  # your first name x2
)
print(response.json())

Your name appears on the dashboard! (No token → "Anonymous")

API docs: oim.108122.xyz/docs

Public APIs: No Auth Needed

url = 'http://api.open-notify.org/astros.json'
data = requests.get(url).json()
print(f"{data['number']} people in space right now!")
for p in data['people']:
    print(f"  {p['name']} on {p['craft']}")

Also try: CoinDesk Bitcoin API - paste in browser!

API Keys: OpenWeather

Some APIs require an API key for access.

API_KEY = 'abc123...'  # Don't hardcode this!
url = (f'https://api.openweathermap.org/data/2.5/weather'
       f'?q=Boston&appid={API_KEY}&units=imperial')
data = requests.get(url).json()
print(f"Boston: {data['main']['temp']}°F")

How do we protect the key?

Protecting Your API Key

import os
from dotenv import load_dotenv

load_dotenv()
API_KEY = os.getenv('OPENWEATHER_API_KEY')
  1. pip install python-dotenv
  2. Create .env file: OPENWEATHER_API_KEY=abc123...
  3. Add .env to .gitignore - never commit secrets!
  4. Use os.getenv() to read the key in your code

OpenAI API

Same pattern, different API:

from openai import OpenAI

client = OpenAI()  # reads OPENAI_API_KEY from .env
response = client.chat.completions.create(
    model='gpt-4o-mini',
    messages=[{'role': 'user', 'content': 'Hello!'}]
)
print(response.choices[0].message.content)

OpenAI Quickstart

Recommendations on API

Your Turn

Option A: Weather for your hometown

  • Use your OpenWeather API key with .env
  • Print temperature, humidity, and description
  • Add try/except for error handling

Option B: Explore Massachusetts towns

  • Fetch data from oim.108122.xyz/mass
  • Find the town with the largest population
  • Find the oldest town (smallest founded year)
  • Find all towns in a specific county

Before You Leave

  • Any questions?
  • Start your Learning Log for this week (logs/wk10.md)
  • Read Ch 13: Files and Databases
  • Work on MP2 - start coding!
  • Push your work to GitHub

Next session: File I/O (reading, writing, CSV, JSON)

global styles