DVP IBM AI Engineering
Reference

Primer 2 — Data & Shapes

Slicing, comprehensions, dicts, first NumPy — what the notebooks assume

Do this alongside Course 1, before the first lab. Goal: slicing, comprehensions and your first NumPy — the three things course notebooks assume without ever explaining.


Slicing — grabbing ranges

You know takes[0]. Slicing grabs a range:

takes = [12.5, 8.0, 22.1, 15.3, 9.9, 30.0]

print(takes[1:4])    # [8.0, 22.1, 15.3]   — from index 1 UP TO BUT NOT INCLUDING 4
print(takes[:3])     # [12.5, 8.0, 22.1]   — empty start = from the beginning
print(takes[3:])     # [15.3, 9.9, 30.0]   — empty end = to the end
print(takes[-2:])    # [9.9, 30.0]         — last two

The rule that prevents every confusion: start is included, end is not. [1:4] gives you indexes 1, 2, 3. That's also why [:3] + [3:] = the whole list with nothing doubled — which is exactly how train/test splits work.

In editing terms: a slice is an in/out point. The in point is on the cut; the out point is after the last frame you keep.

Self-check — answer without looking
  1. x = [10, 20, 30, 40, 50] — predict x[1:3], x[:2], x[-1:].
  2. Why does x[:2] + x[2:] reassemble the list perfectly?

Comprehensions — a loop squeezed into one line

You will meet this constantly and it looks like magic until someone shows you the unfolding:

# the one-liner…
doubled = [t * 2 for t in takes]

# …is EXACTLY this loop:
doubled = []
for t in takes:
    doubled.append(t * 2)

Read a comprehension inside-out: "for each t in takes, keep t * 2."

With a filter:

long_takes = [t for t in takes if t > 10]
# for each t in takes, keep t — but only if t > 10

That's it. Any comprehension you ever see can be unfolded into a for (+ optional if) exactly like this. When one confuses you, unfold it.

Self-check — answer without looking

Unfold this into a normal loop: names = [f.upper() for f in files if f.endswith(".mov")]


f-strings — putting values inside text

clip = "A014C022"
dur = 12.5
print(f"clip {clip} runs {dur} seconds")
# clip A014C022 runs 12.5 seconds

The f before the quote makes {...} slots live. {dur:.2f} formats to 2 decimals — you'll see f"loss: {loss:.4f}" in every training loop in this certificate.


Dictionaries — labelled values

Lists index by position; dicts index by name:

clip = {"name": "A014C022", "fps": 29.97, "frames": 375}

print(clip["fps"])          # 29.97
clip["codec"] = "ProRes"    # add a new key

Where you'll meet them: every model config, every API response, every {"prompt": ..., "chosen": ..., "rejected": ...} training example in course 11. A dict is a labelled bin; the label is the key, the contents the value.

for key, value in clip.items():
    print(key, "→", value)
Self-check — answer without looking
  1. params = {"lr": 0.001, "epochs": 10} — how do you read the learning rate?
  2. What happens if you ask for params["batch"]? (Run it. Read the error. Errors are information.)

NumPy — lists that know math

Python lists can't do arithmetic on all elements at once. NumPy arrays can — and that single idea is the foundation of everything from Course 1 to Course 13.

import numpy as np

x = np.array([12.5, 8.0, 22.1, 15.3])

print(x * 2)         # [25.  16.  44.2 30.6]  — EVERY element, no loop
print(x.mean())      # 14.475
print(x.max())       # 22.1
print(x > 10)        # [ True False  True  True]
print(x[x > 10])     # [12.5 22.1 15.3]  — filter by a condition!

x * 2 on a list would error (well — [list] * 2 duplicates it, worse). On an array it multiplies every element. This "do it to everything at once" is called vectorisation, and it's why ML code has so few loops.

2D — where shape starts to matter

X = np.array([[1.0, 2.0, 3.0],
              [4.0, 5.0, 6.0]])

print(X.shape)      # (2, 3)  ← 2 rows, 3 columns
print(X[0])         # [1. 2. 3.]        — row 0
print(X[0, 2])      # 3.0               — row 0, column 2
print(X[:, 0])      # [1. 4.]           — ALL rows, column 0

X[:, 0] is the one to burn in: the : means "everything" in that position. All rows, column 0. In this certificate, rows are samples and columns are features — so X[:, 0] is "the first feature of every sample" and X[0] is "everything about the first sample".

X.shape answers the question you should ask about every array you ever meet: what shape is this? When course code breaks, the answer is almost always a shape.

Self-check — answer without looking
  1. A dataset has 150 samples and 4 features. What is X.shape?
  2. What does X[:, 2] mean in dataset language? And X[10]?
  3. Predict: np.array([1,2,3]) + np.array([10,20,30]).

Read real course code, again

Course 1's split step, now fully decodable:

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

Primer 2 in one page