Free access week – every resource, tutorial and practice application on this site is open to everyone until 10 November. No membership needed.
Home / AI Tutorials / Module 2
Module 2 of 10 · 8 lessons · about 70 min

Python for AI

The Python you actually need before any AI work: the language, the data libraries and the habits that stop a notebook turning into a mess.

Python installation, VS Code and Jupyter

Get a working setup once and stop fighting it. Every example in this course runs on Python 3.11 or newer.

  • Install Python from python.org, or brew install python on a Mac. On Windows tick “Add python.exe to PATH” in the installer – skipping it causes most of the “python is not recognised” problems.
  • Check it: python --version and pip --version.
  • VS Code plus the Python extension is enough for everything here. Jupyter notebooks are useful while you are exploring data; anything that has to run twice belongs in a .py file.
  • Never install packages into the system Python – the virtual environment section below is not optional.
▶ Try it yourself
Real-time example

On a locked-down office laptop you may not get an installer approved. The Python compiler on this site runs in the browser with no installation at all, so you can still follow every lesson here while you wait for IT.

Variables, data types, operators and control statements

The bedrock. If you have written Java for Selenium, the ideas transfer – the syntax is shorter and indentation replaces braces.

  • Indentation is the block. Four spaces, consistently – a stray tab is a real error, not a style opinion.
  • f-strings (f"{name}") are the readable way to build text.
  • == compares values, is compares identity. Use == unless you are checking None.
  • Integer division is //, true division is /; 7 / 2 gives 3.5.
python
risk_score = 0.87          # float
customer = "Priya"         # str
is_blocked = False         # bool
attempts = 3               # int

if risk_score > 0.9:
    decision = "block"
elif risk_score > 0.6:
    decision = "review"
else:
    decision = "allow"

for attempt in range(attempts):
    print(f"{customer}: attempt {attempt + 1} -> {decision}")

while attempts > 0:
    attempts -= 1
print("done", attempts)
▶ Try it yourself
Real-time example

The threshold ladder above is exactly how a fraud or claim model is wired into an application. The model gives the score; code like this turns it into allow / review / block. Your test cases live on the boundaries – 0.6 and 0.9 – not in the model.

Lists, tuples, dictionaries and sets

Four containers that cover nearly everything. Picking the right one makes later code shorter.

  • list when order matters and the contents change; tuple when they must not.
  • dict is the workhorse – every JSON response you get back from an API arrives as one.
  • set removes duplicates for free and makes “is it in there?” fast.
  • List comprehensions replace most small loops and read better once you are used to them.
python
cases = ["login", "logout", "reset"]        # list   - ordered, changeable
limits = (200, 5000)                        # tuple  - ordered, fixed
user = {"name": "Priya", "role": "member"}  # dict   - key -> value
seen = {"TC-01", "TC-02"}                   # set    - unique, unordered

cases.append("register")
user["role"] = "admin"
seen.add("TC-01")                 # already there, set stays the same size

print(len(cases), user["name"], len(seen))
print([c.upper() for c in cases if c.startswith("l")])   # list comprehension
▶ Try it yourself
Real-time example

Reading an API response in a test: response["data"]["orders"][0]["status"] is dict, dict, list, dict. Knowing which container you are in at each step is most of what makes JSON assertions feel easy or painful.

Functions, modules, packages and exception handling

Where scripts turn into something you can reuse and test.

  • Type hints (age: int) are optional but make an editor catch mistakes before you run.
  • Raise an error for a broken input; return a value for a valid one. Do not return None to mean failure.
  • try / except / finally – catch the specific exception, never a bare except:.
  • A module is one .py file; a package is a folder of them with an __init__.py.
python
def premium(age: int, cover: int, smoker: bool = False) -> float:
    """Published formula - the same one our InsureHub practice app uses."""
    if age < 18 or cover <= 0:
        raise ValueError("age must be 18+ and cover positive")
    base = cover * 0.0022
    loading = 1.6 if smoker else 1.0
    return round(base * (1 + (age - 18) * 0.012) * loading, 2)

try:
    print(premium(31, 500000))
    print(premium(16, 500000))
except ValueError as err:
    print("rejected:", err)
finally:
    print("checked")
▶ Try it yourself
Real-time example

This is a published formula, so a tester can compute the expected premium independently and assert on it. That is the difference between a rule and a model: here you can say “this number is wrong”. Keep that distinction – it decides whether you write an assertion or a range check.

Object-oriented programming

Enough OOP to read the AI libraries and to structure your own tools. If you have used page objects, you already think this way.

  • __init__ builds the object; self is the instance.
  • @property exposes a computed value as if it were an attribute.
  • __repr__ is what you see when you print the object – worth writing for anything you debug.
  • Inheritance exists, but prefer small classes that hold data and a few methods over deep hierarchies.
python
class Claim:
    def __init__(self, claim_id: str, amount: float, documents: list):
        self.claim_id = claim_id
        self.amount = amount
        self.documents = documents

    @property
    def is_complete(self) -> bool:
        return len(self.documents) >= 3

    def decide(self) -> str:
        if not self.is_complete:
            return "pending documents"
        return "approved" if self.amount < 50000 else "manual review"

    def __repr__(self):
        return f"Claim({self.claim_id}, {self.amount})"


c = Claim("CL-1001", 42000, ["bill", "report", "id"])
print(c, c.is_complete, c.decide())
Real-time example

The decision rule above is the one in our InsureHub practice app: under 50,000 with all three documents is auto-approved. Writing the business object this way means the same rules can be unit tested without a browser.

File handling, JSON, CSV and REST APIs

Getting data in and out. Most AI work is 20% model and 80% moving data around.

  • Always use with open(...) – it closes the file even when something throws.
  • Always pass encoding="utf-8". Windows defaults to something else and breaks on Indian names and the rupee sign.
  • requests is friendlier than urllib for real work: pip install requests.
  • Set a timeout on every network call. A test that hangs forever is worse than one that fails.
python
import csv, json, urllib.request

# JSON file in and out
with open("cases.json", "w", encoding="utf-8") as fh:
    json.dump([{"id": "TC-01", "title": "valid login"}], fh, indent=2)

with open("cases.json", encoding="utf-8") as fh:
    cases = json.load(fh)

# CSV, one row at a time
with open("cases.csv", "w", newline="", encoding="utf-8") as fh:
    writer = csv.DictWriter(fh, fieldnames=["id", "title"])
    writer.writeheader()
    writer.writerows(cases)

# a REST call with nothing but the standard library
req = urllib.request.Request("https://httpbin.org/json", headers={"Accept": "application/json"})
with urllib.request.urlopen(req, timeout=10) as resp:
    data = json.loads(resp.read())
print(type(data), list(data)[:3])
Real-time example

Module 7 calls an LLM API with this exact shape – a POST with a JSON body and a bearer token. If you can read and write JSON confidently, the “AI” part of calling a model is ten lines.

NumPy, Pandas and Matplotlib

The three libraries every dataset passes through. Pandas is the one you will use daily.

  • NumPy is fast numeric arrays – the layer Pandas and every ML library sit on.
  • Pandas gives you a DataFrame: a table with named columns, filters, grouping and joins.
  • df.head(), df.info(), df.describe() and df.isna().sum() are the first four things to run on any new dataset.
  • Matplotlib draws the chart. One df.plot() is usually enough to spot a problem that a table hides.
python
import pandas as pd

df = pd.DataFrame({
    "policy": ["P1", "P2", "P3", "P4"],
    "age":    [24, 38, 51, 29],
    "cover":  [300000, 500000, 250000, 800000],
    "claimed": [0, 1, 1, 0],
})

print(df.shape, list(df.columns))
print(df.describe())                      # count, mean, min, max per column
print(df[df["cover"] > 400000])           # filter
print(df.groupby("claimed")["age"].mean())  # average age of claimers vs not
df["premium"] = (df["cover"] * 0.0022).round(2)   # new column
print(df.head())
Real-time example

Pandas is immediately useful to a tester even without AI: load a CSV export from the application and one from the database, join them on the id and print the rows that differ. That is a data-migration test that would take a day by hand.

Virtual environments, pip and Git basics

The habits that keep a project reproducible on someone else’s machine.

  • One virtual environment per project. It is a folder you can delete and rebuild from requirements.txt.
  • Commit requirements.txt, never the .venv folder.
  • .env holds API keys and goes straight into .gitignore. A leaked key in Git history is a real incident, and rewriting history later is painful.
  • Commit small and often with a message that says why, not what.
bash
python -m venv .venv            # create an isolated environment
source .venv/bin/activate       # Windows: .venv\Scripts\activate
pip install pandas requests
pip freeze > requirements.txt   # exact versions, committed to the repo

git init
echo ".venv/" >> .gitignore
echo ".env"   >> .gitignore     # never commit API keys
git add . && git commit -m "AI course: module 2"
Real-time example

When we cleaned the client’s three AI project ZIPs for this site, the work was exactly this: drop __pycache__, drop the local database that held personal history, keep requirements.txt. Anyone could then run them from a clean folder.

If an AI assistant gives you code that works on its machine and not yours, nine times out of ten the difference is the environment, not the code.

Project: analyse a dataset and generate a report

  1. Export any table from an application you test – orders, claims, tickets – as CSV. Twenty rows is enough to start.
  2. Load it with Pandas and print shape, info(), describe() and isna().sum(). Write down three things that look wrong.
  3. Group by one column and compute a mean or a count. State one sentence you could tell the business.
  4. Write the summary to a CSV and a chart to a PNG, then wrap the whole thing in a function so it runs on next month’s export too.
Keep this script. In Module 9 you will run it as a scheduled job with tests around it.