Objects, methods, attributes, and dictionaries#

Use this notebook

Use Notebook 0: Python warm-up to practise the concepts in this chapter: open it in the book or download the notebook.

Most scientific Python APIs become easier once you can read this pattern:

result = object.method(arguments)
value = object.attribute

The object is the thing being acted on. The dot asks Python to look inside that object. Parentheses call a method and pass arguments; no parentheses means that you are only looking up the method or attribute.

Learn from Path#

from pathlib import Path

path = Path("data/trials.csv")  # create a Path object for one file

type(path)      # the class of the object
path.name       # an attribute: "trials.csv"
path.exists()   # a method call: True or False

Parentheses matter: path.exists refers to the method itself; path.exists() calls it.

Check with Python: compare an attribute, a method object, and the result of calling the method.

Output will appear here.

The same pattern appears everywhere#

epochs.mean(axis=0)
frame.groupby("participant")
model.fit(X, y)
model.predict(X_new)
model.coef_

Scientific libraries create objects for recordings, tables, models, and figures. Learn to recognise these objects and inspect the operations they provide.

type(model)
dir(model)
help(model.fit)

For example, a fitted model is still the same kind of object as before fitting, but it now has learned attributes such as coefficients. A Matplotlib Axes object stores the plotting area and provides methods such as .plot() and .set_xlabel(). A pandas DataFrame stores tabular data and provides methods such as .head() and .groupby(). This is why the same object-method-attribute pattern appears throughout the workshop.

Dictionaries for research metadata#

A dictionary stores named pieces of information together. This makes it useful for metadata: an ID, condition, age, and file locations can travel as one clearly labelled record. Nested dictionaries group related information such as the files for one participant.

participant = {
    "id": "P07",                    # participant label
    "condition": "control",         # experimental condition
    "age": 24,                       # participant metadata
    "files": {                       # related file paths
        "epochs": "P07_epochs.npy",
        "trials": "P07_trials.csv",
    },
}

Access and update values:

participant["condition"]                    # retrieve one value
participant["files"]["epochs"]             # retrieve a nested value
participant.get("handedness", "unknown")   # fallback if the key is absent
participant["excluded"] = False             # add or update a key

Check with Python: add another metadata field or inspect a missing key.

Output will appear here.

Mutable nested objects#

Exercise 7 (One object or two?)

Predict the result.

original = {"channels": ["Fz", "Cz"]}
copied = original.copy()
copied["channels"].append("Pz")

print(original)

Solution to Exercise 7 (One object or two?)

The outer dictionary is copied, but the nested list is shared. The result is {'channels': ['Fz', 'Cz', 'Pz']}. Use copy.deepcopy when independent nested objects are required.

Small class-reading exercise#

The workshop mostly asks you to use classes supplied by Python libraries. You can read an API without writing the class yourself. A class is a template for objects; an instance is one concrete object created from that template. In Cognitive Science code, examples include a Path for one data file, a DataFrame for one table, an Axes for one plot, and a fitted estimator for one modelling workflow.

Exercise 8 (Read an object-oriented API)

For each expression, identify the object, method, argument, or attribute:

fig, ax = plt.subplots()
ax.plot(times, signal, label="condition A")
ax.set_title("Evoked response")

Then explain why ax.plot and ax.plot(...) are not the same value.

Solution to Exercise 8 (Read an object-oriented API)

  • fig and ax are objects returned by plt.subplots().

  • ax.plot(...) calls the plot method on ax.

  • times and signal are positional arguments; label="condition A" is a keyword argument.

  • ax.set_title(...) calls another method, with the title string as its argument.

  • ax.plot refers to the method object itself; parentheses call it and return the plotted line objects.