Starter Notebook — Week 1

Six guided exercises. Open in Jupyter or VS Code. Complete before Friday.

Download Notebook (.ipynb)

How to open the notebook

Once downloaded, open a terminal (Mac) or Anaconda Prompt (Windows), activate your environment, and run:

conda activate compliancegpt
jupyter notebook week1_python.ipynb

A browser tab will open. Run each cell with Shift + Enter. Read each markdown cell before running the code below it.

1 — Variables and Types

A variable is a named container. Python figures out the type automatically — you never write int x = 5 like in Java.

The four types you will use

TypeExampleWhat it is
str"hospital"Text
int137Whole number
float0.942Decimal number
boolTrue / FalseYes or No

Live example

hospital_name = "Stony Brook Medicine"
num_cases     = 137
best_accuracy = 0.942
is_permitted  = True

print(hospital_name)      # Stony Brook Medicine
print(type(num_cases))    # <class 'int'>
print(is_permitted)       # True

Key rule: strings need quotes, numbers do not

"137" is text — you cannot do math with it. 137 is a number — you can. This is the most common beginner mistake. If you see a TypeError when adding or comparing, check for accidental strings.

2 — Lists and Dictionaries

These are the two data structures you will use constantly. Lists are ordered sequences. Dictionaries map keys to values.

Lists — ordered, indexed from 0

models = ["gemma3:4b", "llama3.1:8b", "qwen2.5:72b"]

print(models[0])      # gemma3:4b
print(models[-1])     # qwen2.5:72b  (last)
print(len(models))    # 3

models.append("claude-sonnet")
print(len(models))    # 4

Dictionaries — key → value pairs

result = {
    "scenario_id": "HHS-001",
    "verdict":     "PERMITTED",
    "correct":     True,
    "accuracy":    0.942
}

print(result["verdict"])   # PERMITTED
print(result["correct"])   # True

result["model"] = "gemma3:4b"  # add a key

Why this matters for ComplianceGPT

Every row the pipeline processes becomes a Python dictionary. The scenario text, the extracted facts, and the verdict are all keys in that dict. When you analyze results, you read rows as dicts and columns as keys.

3 — Conditionals (if / elif / else)

Conditionals let your program make decisions. Indentation is not optional in Python — it defines what is inside the block.

verdict = "DENIED"
ground_truth = "PERMITTED"

if verdict == ground_truth:
    print("Correct prediction")
elif verdict == "DENIED" and ground_truth == "PERMITTED":
    print("False negative — system wrongly denied a permitted disclosure")
else:
    print("False positive — system wrongly permitted a denied disclosure")

Comparison operators

  • ==   equal to
  • !=   not equal to
  • >   greater than
  • <=   less than or equal
  • in   membership: "cat" in ["cat","dog"]

Boolean logic

  • and — both must be True
  • or — at least one must be True
  • not — flips True/False
  • not TrueFalse
  • True and FalseFalse

4 — For Loops

A for loop runs the same block of code once for each item in a collection. You will use this to process rows of results.

verdicts = ["PERMITTED", "DENIED", "PERMITTED", "DENIED", "PERMITTED"]
correct_gt = ["PERMITTED", "PERMITTED", "PERMITTED", "DENIED", "PERMITTED"]

correct_count = 0

for i in range(len(verdicts)):
    if verdicts[i] == correct_gt[i]:
        correct_count += 1

accuracy = correct_count / len(verdicts)
print(f"Accuracy: {accuracy:.1%}")   # Accuracy: 80.0%

f-strings — the clean way to print

Put an f before the quote, then use { } to embed variables. :.1% formats a decimal as a percentage with 1 decimal place.

name = "Gemma3"
acc  = 0.942
print(f"{name} accuracy: {acc:.1%}")   # Gemma3 accuracy: 94.2%

5 — Functions

A function packages reusable logic under a name. You define it once with def, then call it as many times as you need.

def compute_accuracy(predicted, ground_truth):
    """Return the fraction of predictions that match ground truth."""
    correct = sum(p == g for p, g in zip(predicted, ground_truth))
    return correct / len(predicted)


# Use it:
preds = ["PERMITTED", "DENIED", "PERMITTED", "DENIED", "PERMITTED"]
gts   = ["PERMITTED", "PERMITTED", "PERMITTED", "DENIED", "PERMITTED"]

acc = compute_accuracy(preds, gts)
print(f"Accuracy: {acc:.1%}")   # 80.0%

Anatomy of a function

  • def — starts the definition
  • name — what you call it
  • parameters — inputs in parentheses
  • return — what it hands back
  • Indentation — everything inside must be indented

zip() — pairing two lists

zip(list1, list2) pairs up items by position. Use it whenever you need to compare two lists element by element.

for p, g in zip(preds, gts):
    print(p, "vs", g)

6 — Pandas: Loading and Analyzing Data

Pandas is the Python library for working with tabular data (like a CSV file or Excel sheet). A DataFrame is a table — rows are observations, columns are fields. This is what you will use for every analysis this summer.

import pandas as pd

# Load the results file
df = pd.read_csv("results/final_vast_gemma3_4b.csv")

print(df.shape)          # (137, 12)  — 137 rows, 12 columns
print(df.columns.tolist())
print(df.head(3))        # first 3 rows

The 5 patterns you will use every day

import pandas as pd, json

# ── 1. Load results ──────────────────────────────────────────────
df = pd.read_csv("results/final_vast_gemma3_4b.csv")

# ── 2. Find wrong predictions ────────────────────────────────────
wrong = df[df["match"] != "Y"]
print(f"{len(wrong)} wrong out of {len(df)}")

# ── 3. Inspect a single row ──────────────────────────────────────
row = wrong.iloc[0]          # first wrong row
print(row["verdict"])        # what the model said
print(row["ground_truth"])   # what it should have said

# ── 4. Compute accuracy ──────────────────────────────────────────
accuracy = (df["match"] == "Y").mean()
print(f"Accuracy: {accuracy:.1%}")

# ── 5. Save annotated output ──────────────────────────────────────
df["is_correct"] = df["match"] == "Y"
df.to_csv("results/annotated.csv", index=False)

Filtering rows

Use a condition inside [ ] to keep only matching rows:

# Only permitted predictions
permitted = df[df["verdict"] == "PERMITTED"]

# Wrong AND model is gemma
wrong_gemma = df[(df["match"] != "Y") &
                 (df["model"] == "gemma3:4b")]

Summary statistics

# Count each verdict
df["verdict"].value_counts()

# Mean of a numeric column
df["e2e_s"].mean()

# Group by model, compute accuracy
df.groupby("model")["match"].apply(
    lambda x: (x == "Y").mean()
)

Notebook Exercises — Week 1

The downloadable notebook has 6 guided exercises. Here is what each one covers:

#ExerciseConcepts practicedExpected output
1 Hello Python Variables, print(), type() Print your name and today's date
2 Patient record Dictionaries, accessing keys, adding keys Build a dict representing one HIPAA scenario
3 Verdict check if / elif / else, string comparison Classify a prediction as correct / false positive / false negative
4 Count errors for loops, counters, f-strings Loop over 10 predictions and count wrong ones
5 Write accuracy() Functions, zip(), return Function that returns accuracy given two lists
6 Load real results Pandas read_csv(), filtering, .mean() Compute accuracy from an actual experiment CSV

Stuck? Try this order

  1. Read the markdown cell above the exercise — it explains what to do
  2. Look at the examples on this page for the same concept
  3. Run what you have and read the error message carefully — the last line tells you what went wrong
  4. Post in Slack #python-help with your code and the full error message

Common Errors and What They Mean

ErrorMost likely causeFix
IndentationError Mixed tabs and spaces, or missing indent inside def / if / for Use 4 spaces consistently. VS Code can fix this: Format Document (Shift+Alt+F)
NameError: name 'x' is not defined You used a variable before assigning it, or spelled it differently Check spelling. Make sure the cell that creates the variable was run.
KeyError: 'verdict' That column name doesn't exist in your DataFrame or dict Run print(df.columns.tolist()) to see actual column names
TypeError: can only concatenate str Adding a string to a number without converting Use f-string: f"Accuracy: {acc}" instead of "Accuracy: " + acc
FileNotFoundError The CSV path is wrong or Jupyter is running from a different folder Run import os; print(os.getcwd()) to see where you are, then adjust path
ModuleNotFoundError: pandas Your conda environment is not activated, or pandas not installed In terminal: conda activate compliancegpt then restart Jupyter