Skip to content

Notes: M3: Functions, files, libraries & errors

M1 and M2 gave you the raw materials, values, decisions, loops, lists, dictionaries. This module gives you the four habits that turn a one-off script into software you can trust and reuse: functions (name and reuse a block of work), libraries (stand on other people's code), files (read data in, write results out, including JSON), and error handling (don't let one bad line take down the whole program). It's also where you leave the browser and run Python on your own machine for the first time. None of this is busywork: it's the exact toolkit you'll use to call an AI model, parse its JSON reply, and keep your app standing in Part B.

A note on difficulty: the install is the hardest part of this whole course for many people, > not because it's complex, but because every machine is a little different. If setup fights you, that's normal and it's not you. Go step by step with the install guide, lean on your partner, and remember you only have to do it once.

Running Python on your own machine

The terminal

The terminal is a text window where you type commands instead of clicking. python3 --version, pip install rich, python myfile.py, these are commands you type and run. It feels old-fashioned but it's how nearly all development tools are driven. (Course 01 covered this; if it's new, the terminal guide gets you opened up.)

Virtual environments: a clean box per project

When you pip install a library, where does it go? Without care, into one big shared pile, where Project A needs version 1 of something and Project B needs version 2, and they clash. A virtual environment (venv) is a private box of libraries that belongs to one project. You create it once (python -m venv .venv), activate it (your prompt shows (.venv)), and from then on every pip install lands in that box. It's standard professional practice, and it's why the very first thing you do in any Python project is make a venv.

flowchart TB
  subgraph Proj["Your project: ai-course/"]
    Code["your .py files"]
    subgraph Venv[".venv  (the private box)"]
      Rich["rich"]
      Future["…libraries you pip install"]
    end
  end
  Code -->|import| Venv

pip: installing other people's code

pip installs libraries (also called packages), reusable code published by others. One command, pip install rich, downloads the library and everything it depends on. Projects record what they need in a requirements.txt file so anyone can install it all at once with pip install -r requirements.txt. The standard library (like json, below) comes with Python and needs no install.

Functions: name a block of work, reuse it

A function is a named block of code you can run whenever you like, with different inputs:

def categorize(amount):     # 'amount' is a parameter, an input the function expects
    if amount < 5:
        return "small"      # 'return' hands a value back to whoever called it
    elif amount < 50:
        return "medium"
    else:
        return "big"

size = categorize(62.00)    # calling it; size is now "big"
- Define with def name(parameters):, then an indented body. - Parameters are the inputs; arguments are the actual values you pass in. - return sends a value back. (A function with no return hands back None.)

Why bother? Three reasons: you write the logic once and call it many times; you give it a name that explains intent; and you can change it in one place. In the lab you take M2's inline decision and lift it into categorize(), same logic, now reusable and testable.

Light touch on objects & classes: libraries often hand you objects: bundles of data with their own functions (called methods). In the lab, Console() and Table() from rich are objects; table.add_row(...) is calling a method on one. You'll happily use objects from libraries long before you write your own classes, that's normal and enough for this course.

Files: reading in, writing out

Programs become useful when they work with data that outlives them. You open a file with open(), and the safe pattern is with, which closes the file for you automatically:

with open("expenses.txt") as f:     # read mode by default
    for line in f:
        print(line.strip())          # .strip() removes the trailing newline

with open("out.txt", "w") as f:      # "w" = write (creates/overwrites the file)
    f.write("hello\n")
Reading gives you text; turning "4.50" into a number still needs float(...) (the M1 lesson that text isn't a number applies here too).

JSON: your dictionaries, as text

JSON (JavaScript Object Notation) is a text format for data that looks almost exactly like a Python dictionary/list. It is the language APIs speak, including AI APIs. Python's built-in json library converts both ways:

You have You want Use
a dict/list → a file save it json.dump(data, f)
a file → a dict/list load it json.load(f)
a dict/list → a string (e.g. to send) json.dumps(data)
a string → a dict/list (e.g. a reply) json.loads(text)

import json
expenses = [{"item": "Coffee", "amount": 4.50}]
with open("expenses.json", "w") as f:
    json.dump(expenses, f, indent=2)     # writes nicely-indented JSON text
This is the direct bridge to M2 and M4: the dictionary you met in M2, written to disk or sent over the network as JSON, is exactly what an AI API receives and returns. Master this and the API in M6 will feel familiar.

Errors: try / except

Real input is messy: a missing file, a blank line, a word where a number should be. By default any of these crashes your program with a red traceback. try/except lets you attempt something risky and handle the failure instead of dying:

try:
    amount = float(text)       # might fail if text isn't a number
except ValueError:
    print("That wasn't a number, skipping.")
Catch the specific error you expect (ValueError for bad numbers, FileNotFoundError for a missing file). In the lab, one deliberately broken line in expenses.txt gets caught and skipped, the program reports it and keeps going. That resilience is the difference between a demo and something you'd actually run.

Optional tooling box, PyTorch (you do not need this for the course) **PyTorch** is the library used to *train and run AI models on your own hardware*. This course uses **hosted APIs** (you call a model over the internet), so **you do not need PyTorch**: skip this unless you specifically want to run or fine-tune models locally. If you do want it, install it from the **official selector**, which gives you the exact command for your system: ****. Two paths: - **CPU-only** (works on any laptop, no graphics card needed): the selector's "CPU" option, e.g. `pip install torch` (with the CPU index URL it shows). Slower, but fine for learning and small models. - **GPU / CUDA** (much faster, needs an NVIDIA GPU): the selector picks the right **CUDA** version for you. Don't hand-install CUDA blindly, let the selector give you the matching command. > **Beginner guidance:** do **not** install CUDA just to keep up with this course, you won't need > it. If you're curious later, start with the **CPU-only** build inside a fresh venv. Apple Silicon > Macs use a backend called **MPS** instead of CUDA; the selector handles that too.

Check yourself

Lock in today's win, answer each in your head, then reveal.

1. What problem does a virtual environment solve?

Show answer

It keeps each project's installed libraries in their own private box, so different projects can use different versions without clashing. You make one per project (python -m venv .venv), activate it (prompt shows (.venv)), and pip install then lands in that box.

2. What does return do in a function, and what happens if there isn't one?

Show answer

return hands a value back to whoever called the function, so you can store or use it (size = categorize(62)). A function with no return hands back None, which is why the starter showed -> None before you added the categorize logic.

3. You have a Python dictionary and you want to save it to a file. Which json function, and what kind of data is in the file afterwards?

Show answer

Use json.dump(data, f) (writing to an open file f). The file then contains JSON text: a string that looks almost identical to your dictionary. To read it back into a dict, use json.load(f).

4. Why wrap float(text) in try / except ValueError?

Show answer

Because if text isn't a valid number (a blank line, a word, a typo), float() raises a ValueError and crashes the program. try/except lets you catch that one case, handle it (skip or warn), and keep running. Catch the specific error you expect.

5. Do you need PyTorch and a CUDA GPU for this course?

Show answer

No. This course calls hosted AI models over an API, so there's nothing to run locally. PyTorch (and CUDA) only matter if you choose to run or fine-tune models on your own hardware, an optional path, best started with the CPU-only build via the official selector.


New words (also in resources/glossary.md): terminal, virtual environment (venv), activate, pip, package/library, requirements.txt, standard library, function, def, parameter, argument, return, object, method, class, file, open, with, JSON, json.dump/ load/dumps/loads, try/except, exception, ValueError, FileNotFoundError, PyTorch, CUDA.

Source: original, written for this course. Concepts and worked examples (functions, conditionals, loops, files) are informed by the instructor's own Python_continuation.pdf notes in Material_AI_Engineering/; the file→JSON budget refactor and the rich/PyTorch guidance are original. No third-party text or figures; diagrams are original. PyTorch install paths point to the official selector rather than reproducing commands that change over time.