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)
Hint
.copy() creates a new outer dictionary. Ask whether it also creates a new list for
the value stored under "channels".
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.
Hint
Read each expression from left to right: object, dot, attribute name. Parentheses turn a method attribute into a call and may contain positional and keyword arguments.
Solution to Exercise 8 (Read an object-oriented API)
figandaxare objects returned byplt.subplots().ax.plot(...)calls theplotmethod onax.timesandsignalare positional arguments;label="condition A"is a keyword argument.ax.set_title(...)calls another method, with the title string as its argument.ax.plotrefers to the method object itself; parentheses call it and return the plotted line objects.