Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Tutorial 1: Python Programming Fundamentals

Authors
Affiliations
University of Oxford
University of Toronto / University of Cambridge

Goal

This notebook introduces the fundamental programming concepts that you’ll use throughout the Connectome 2026–2027 competition and beyond. We try to make it relevant for analyzing scientific datasets.

By the end of this notebook, you should be comfortable with:

1. Variables and print

A variable stores a value so that it can be used later in your program.

Variables can store many different types of data. Some of the most common include:

  • Numbers (e.g., 34, 3.14)

  • Strings (text, e.g., "Hippocampus" or "Hello")

In this example, participant_age stores a number, while region_name stores a piece of text (called a string).

The print() function displays information in the output. You can print variables individually or combine them to create more informative messages.

Finally, any text following # in your code is treated as a comment. Comments are ignored by Python and are useful for explaining what your code is doing.

# Comment code by adding `#`
participant_age = 21 # assigning number 21 to variable participant_age
region_name = "hippocampus"

print(participant_age)
print(region_name)
21
hippocampus
print("Age:", participant_age)
print("Region name:", region_name)
Age: 21
Region name: hippocampus

f-Strings

Often, you’ll want to combine text with the values stored in variables.

One convenient way to do this is using an f-string (formatted string).

Simply place an f before the quotation marks, and put any variable inside curly braces {}. Python will automatically replace the variable with its value.

print(f"The participant is {participant_age} years old.")
print(f"The brain region of interest is {region_name}.")
The participant is 21 years old.
The brain region of interest is hippocampus.

f-strings are one of the most common ways to display variables in Python because they are both readable and easy to write.

Try it yourself

  • Change region_name to a different brain region (e.g., "Amygdala" or "Prefrontal Cortex").

  • Create a new variable called region_function and assign it a function associated with that brain region (e.g., "emotion" or "decision making").

  • Write an f-string that prints something along the lines of “The (PUT YOUR REGION NAME HERE) is involved in (PUT THE REGION’S FUNCTION HERE)”.

# Edit and continue code here ...

region_name = "a brain region of your choice" 

2. Lists

A list stores multiple values together in a single variable. This is useful whenever you have a collection of related items, such as participant IDs, brain regions, or ages.

Each item in the list can be of any data types, including strings and numbers.

Every item in a list has an index (position). Python starts counting from 0, so the first item has index 0, the second item has index 1, and so on.

or example:

Index:          0                1                2                3
brain_regions = ["Frontal Lobe", "Parietal Lobe", "Temporal Lobe", "Occipital Lobe"]
brain_regions = ["Frontal Lobe", "Parietal Lobe", "Temporal Lobe", "Occipital Lobe"]

print(brain_regions)
['Frontal Lobe', 'Parietal Lobe', 'Temporal Lobe', 'Occipital Lobe']
participant_age = [20, 34, 45, 67]

print(participant_age)
[20, 34, 45, 67]

You can access individual items in a list using their index inside square brackets [].

For example, when Python sees:

brain_regions[0]

it looks inside the list, finds the item at index 0 (the first item), and replaces brain_regions[0] with its value.

print("The first item in the list is", brain_regions[0])
print("The third item in the list is", brain_regions[2])
The first item in the list is Frontal Lobe
The third item in the list is Temporal Lobe

Try it yourself

  • Change "Frontal Lobe" to another brain region (e.g., "Hippocampus") and rerun. What does brain_regions[0] print now?

  • Print the fourth brain region in the list.

  • What happens if you try to print brain_regions[10]? Read the error message carefully—can you explain why it occurs?

# Write your code here:

3. Dictionaries

A dictionary stores information as key–value pairs.

A key is the name (or label) used to describe a piece of information, while a value is the actual information stored.

For example, let’s look at an example dictionary (brain_region) below:

brain_region = {
    "name": "Hippocampus", 
    "function": "memory",
    "hemisphere": "left"
}

print(brain_region)
{'name': 'Hippocampus', 'function': 'memory', 'hemisphere': 'left'}
  • "name", "function", and "hemisphere" are the keys.

  • "Hippocampus", "memory", and "left" are the corresponding values.

Dictionaries are useful whenever you want to describe an object using meaningful labels rather than positions.

For example, we might want to store information about a brain region by creating a dictionary called brain_region.

In neuroscience, we often work with data that naturally have descriptive labels. For example, each participant may have an ID, age, and diagnosis, while each brain region may have a name, function, hemisphere, or anatomical coordinates. A dictionary allows us to group all of this related information together in a single object.

To access a specific value, use its key inside square brackets.

For example, when python sees:

brain_region["name"]
'Hippocampus'

it looks for the key "name" and returns its corresponding value, "Hippocampus".

Unlike lists, dictionaries are accessed using descriptive keys rather than numerical positions.

Furthermore, you can also add more key/value pairs to the dictionary. For instance, we want to add the volume of the brain region in cm^3.

brain_region["volume"] = 3
brain_region
{'name': 'Hippocampus', 'function': 'memory', 'hemisphere': 'left', 'volume': 3}

Try it yourself

Imagine you’ve just recruited a new participant for your neuroscience study, and you want to store a little more information about them.

  • Create a dictionary called participant

  • Add a new key called "diagnosis" and assign it a value such as "Healthy Control" or "Parkinson's Disease".

  • Add another key called "handedness" and assign it a value such as "Right" or "Left".

  • Add another key called "age" and assign it a value such as 67.

  • Print the participant’s diagnosis using its key.

  • Write an f-string that introduces the participant using the information stored in the dictionary.

# Code below
participant = {
    # add key / values here
}


# Use f-string to print information about participant

4. if and elif

Sometimes we want our program to make decisions based on information that we already have.

This is where conditional statements come in.

Python evaluates each condition in order. If a condition is True, it executes the corresponding block of code. If it is False, Python moves on to the next condition.

The if statement checks the first condition, while elif (short for else if) allows us to check additional conditions if the previous ones were not met.

For example, we might classify participants into different age groups:

age = 67

if age < 18:
    print("Minor")
elif age < 65:
    print("Adult")
else:
    print("Older Adult")
Older Adult

In this example:

  • If age is less than 18, Python prints "Minor".

  • Otherwise, it checks whether age is less than 65. If so, it prints "Adult".

  • If neither condition is true, Python executes the else block and prints "Older Adult".

Only one of these blocks will be executed.

Boolean / if

In the previous example, we used a numerical comparison (age < 18) to decide which block of code to execute.

However, if statements are not limited to numbers. They can also be used with Boolean values.

A Boolean is a variable that can only have one of two values:

  • True

  • False

For example, suppose you’ve finished checking the quality of an MRI scan. You might store whether it passed quality control (QC) as a Boolean.

passed_qc = True # let's say this MRI scan passed quality control

if passed_qc:
    print("Proceed with analysis.")
else:
    print("Exclude participant.")
Proceed with analysis.

Since passed_qc is True, Python executes the first block and prints:

Proceed with analysis.

If you instead changed:

passed_qc = False

Python would skip the first block and execute the else block instead.

Finally, we can also compare text (strings) using if and elif.

For example, suppose participants belong to different groups:

diagnosis = "Parkinson's Disease"

if diagnosis == "Healthy Control":
    print("Control group")
elif diagnosis == "Parkinson's Disease":
    print("Patient group")
else:
    print("Unknown group")

Here, == means “is equal to.”

Python checks each condition one at a time until one of them is True, then executes the corresponding block of code.

Using in keyword to check if a value is present in a sequence

In the previous example, we checked whether diagnosis was equal to a single value.

However, in many neuroscience studies, we want to check whether a value belongs to a collection of values rather than comparing it with just one.

Python provides the keyword in for this purpose.

For example, imagine you’re conducting a study comparing healthy controls with individuals who have a substance use disorder. However, your study only recruits participants with nicotine, cocaine, or heroin addiction.

As participants are recruited (and let’s say their drug use data is stored in a dictionary), we want a quick way to determine whether each participant meets our inclusion criteria.

So below, we have data for two participants.

participant_1 = {
    "subject_id": "S045",
    "age": "34",
    "drug_use": "cocaine"
}

participant_2 = {
    "subject_id": "S049",
    "age": "34",
    "drug_use": "amphetamine"
}

Rather than writing separate if statements for every diagnosis, we can store all eligible diagnoses in a list and simply check whether the participant’s diagnosis appears in that list.

We can store the diagnoses we want to include in a list:

included_drugs = [
    "nicotine",
    "cocaine",
    "heroin"
]

Now, let’s see whether we should include or excluce participant_1 and participant_2 based on their data.

# Participant 1

participant_drug_use = participant_1["drug_use"]
participant_drug_use
'cocaine'
if participant_drug_use in included_drugs:
    print("Include participant")
else:
    print("Exclude participant")
Include participant
# Participant 2

participant_drug_use = participant_2["drug_use"]
participant_drug_use
'amphetamine'
if participant_drug_use in included_drugs:
    print("Include participant")
else:
    print("Exclude participant")
Exclude participant

Note, there’re more efficient to do this, but we hope to demonstrate how we can combine the use of dictionary, list, and conditional statements.

5. for loops

Suppose we have the following list of participant IDs:

subjects = ["S045", "S049", "S052"]

Here, our variable subjects is a collection (i.e, the entire list), while "S045", "S049", and "S052" are the individual items stored inside that collection.

A for loop works by taking one item at a time from the collection and storing it in a variable.

The general syntax of a for loop is:

for item in collection:
    do something with item

Here:

  • collection is the sequence you want to loop through (for example, a list).

  • item is a variable that you choose. During the loop, Python stores one item from the collection in this variable before executing the code inside the loop.

For example, if we write:

for subject_id in subjects:
    print(subject_id)
S045
S049
S052

Python automatically uses subject_id to store one participant ID at a time.

Internally, the loop is doing something similar to this:

# First iteration
subject_id = "S045"    # Assign the first item in the list to subject_id
print(subject_id)      # Executes the indented code

# Second iteration
subject_id = "S049"    # Assign the next item in the list to subject_id
print(subject_id)      # Executes the indented code

# Third iteration
subject_id = "S052"    # Assign the next item in the list to subject_id
print(subject_id)      # Executes the indented code

Each time the loop goes through the code once is called an iteration.

In the example above:

  • The first iteration processes "S045".

  • The second iteration processes "S049".

  • The third iteration processes "S052".

The loop keeps repeating (iterating) until there are no more items left in the subjects list.

In other words, during each iteration, Python:

  1. Takes the next item from subjects.

  2. Assigns it to the variable subject_id.

  3. Executes the indented code.

  4. Repeats until there are no more items left.

Notice that subject_id is just a variable name—we could have called it almost anything (see below):

for participant in subjects:
    print(participant)
S045
S049
S052
# or

for x in subjects:
    print(x)
S045
S049
S052

These would all work exactly the same way. However, choosing descriptive names such as subject_id or participant makes the code much easier to read.

The important idea is that Python repeatedly assigns each item in the list to the variable (subject_id) and then executes the code inside the loop.

Looping through participant dictionaries

Earlier, we learned that a dictionary can store information about a single object using key–value pairs. That object could be almost anything really! It could be a participant, a brain region, a neuron, a file, or any other entity that has descriptive information associated with it.

In neuroscience, we don’t usually have just one participant—we might have hundreds or even thousands. One simple way to organize this information is to store multiple dictionaries inside a list, where each dictionary represents one participant.

Remember that a list can contain many different types of objects, including:

  • numbers,

  • strings,

  • dictionaries,

  • and even other lists.

In the example below, participants is a list containing three dictionaries. Each dictionary stores information about one participant.

participants = [
    {"subject_id": "S045", "age": 34, "drug_use": "cocaine"}, # a dictionary
    {"subject_id": "S049", "age": 36, "drug_use": "amphetamine"}, # a different dictionary
    {"subject_id": "S051", "age": 29, "drug_use": "nicotine"} # another dictionary
]
S045 cocaine
S049 amphetamine
S051 nicotine

Now suppose we want to print the subject ID and drug use for every participant.

We can loop through the list one dictionary at a time:

for participant in participants:
    print(participant["subject_id"], participant["drug_use"])

Here:

  • participants is the collection (a list of dictionaries).

  • participant is a variable that stores one dictionary at a time.

  • participant["subject_id"] retrieves the subject ID from the current participant (as we have previously used)

  • participant["drug_use"] retrieves the drug use from the current participant.

Internally, Python is doing something similar to:

# First iteration
participant = {"subject_id": "S045", "age": 34, "drug_use": "cocaine"}
print(participant["subject_id"], participant["drug_use"])

# Second iteration
participant = {"subject_id": "S049", "age": 34, "drug_use": "amphetamine"}
print(participant["subject_id"], participant["drug_use"])

# Third iteration
participant = {"subject_id": "S051", "age": 29, "drug_use": "nicotine"}
print(participant["subject_id"], participant["drug_use"])

The loop repeats until it has processed every dictionary in the participants list.

Practice: Classifying Participants

Imagine you’re helping analyze data from a neuroscience study investigating substance use disorders.

Suppose you’ve already collected data from five participants. For each participant, you know:

  • their subject ID,

  • their age,

  • and the drug they primarily use.

We’ll represent this information as a list of dictionaries, where each dictionary stores information about one participant.

Your goal is to examine each participant’s drug_use and add a new key called "group" to their dictionary.

Specifically:

  • If the participant reports using nicotine, cocaine, or heroin, assign:

"group" = "patient group"
  • Otherwise, assign:

"group" = "exclude"

In other words, by the end of this exercise, every participant dictionary should contain four pieces of information instead of three:

  • subject_id

  • age

  • drug_use

  • group

# Our data
participants = [
    {"subject_id": "S045", "age": 34, "drug_use": "cocaine"},
    {"subject_id": "S049", "age": 34, "drug_use": "amphetamine"},
    {"subject_id": "S051", "age": 29, "drug_use": "nicotine"},
    {"subject_id": "S063", "age": 41, "drug_use": "heroin"},
    {"subject_id": "S071", "age": 37, "drug_use": "alcohol"}
]

# Inclusion criteria
included_drugs = [
    "nicotine",
    "cocaine",
    "heroin"
]

Step 1: Think Before You Code

Before writing any Python, try describing the solution in plain English.

One possible solution is:

For every participant in the participants' list:

    Look at their drug use.

    If the drug is one of the included drugs:
        Add "group" = "patient group"

    Otherwise:
        Add "group" = "exclude"

Notice how this already resembles a for loop. Programming often begins by describing the algorithm in plain English before translating it into code.

Step 2: Ingredients

Think about the concepts you’ve learned so far.

You’ll need to use:

  • a for loop to visit every participant,

  • an if/else statement,

  • the in keyword to check whether the participant’s drug appears in included_drugs,

  • and a dictionary to add a new key called "group".

For every participant's dictionary in the participants' list:

    Look at their drug use by extracting the value of the "drug_use" key for that participant.

    If the drug is one of the included drugs:
        Add "group" = "patient group"

    Otherwise:
        Add "group" = "exclude"

Step 3: Write Your Code

# Your code
# Fill in the blanks below

for ... in ...:
    if ... in ... :
        participant["group"] = "patient group" # Adds a new key called "group" to the current participant.
    else:
        participant["group"] = "exclude" # Adds a new key called "group" to the current participant.

print(participants)













Step 4: Check Your Answers




for participant in participants:
    if participant["drug_use"] in included_drugs:
        participant["group"] = "patient group"
    else:
        participant["group"] = "exclude"

print(participants)
[{'subject_id': 'S045', 'age': 34, 'drug_use': 'cocaine', 'group': 'patient group'}, {'subject_id': 'S049', 'age': 36, 'drug_use': 'amphetamine', 'group': 'exclude'}, {'subject_id': 'S051', 'age': 29, 'drug_use': 'nicotine', 'group': 'patient group'}]

6. zip()

Sometimes, information is stored across multiple lists. For example, one list might contain participant IDs, while another contains their ages.

This often happens because the data come from different sources. For example, participant IDs may be stored in one file, while demographic information such as age or diagnosis is stored in another. As long as the two lists are in the same order, zip() allows us to process them together.

If the two lists correspond to one another, we can use zip() to loop through them together.

subject_ids = ["S045", "S049", "S051"]
ages = [34, 36, 29]

for subject_id, age in zip(subject_ids, ages):
    print(f"{subject_id} is {age} years old.")
S045 is 34 years old.
S049 is 36 years old.
S051 is 29 years old.

Here, zip() pairs the first subject ID with the first age, the second subject ID with the second age, and so on.

Internally, Python is doing something similar to:

# First iteration
subject_id = subject_ids[0]    # Take the first subject ID
age = ages[0]                  # Take the first age
print(...)                     # Execute code

# Second iteration
subject_id = subject_ids[1]    # Take the second subject ID
age = ages[1]                  # Take the second age
print(...)                     # Execute code

# Third iteration
subject_id = subject_ids[2]    # Take the third subject ID
age = ages[2]                  # Take the third age
print(...)                     # Execute code

Zip Exercise: Pairing Participant IDs with Brain Volumes

Imagine you’ve measured the hippocampal volume (in mm³) for several participants.

For this exercise, the participant IDs and brain volumes are stored in two separate lists (see below). Your task is to pair them together and print a summary for each participant.

subject_ids = [
    "S045",
    "S049",
    "S051",
    "S063",
    "S071"
]

hippocampal_volumes = [
    3820,
    4015,
    3650,
    3895,
    3540
]

Step 1: Think Before You Code

Before writing any Python, describe the algorithm in plain English.

One possible solution is:

For each participant ID and hippocampal volume:

    Pair them together.

    Print a sentence showing the participant ID and hippocampal volume.

Notice that we’re processing two lists at the same time, which is exactly what zip() is designed for.


Step 2: Hint

Think about the tools you’ve already learned.

  • You’ll need a for loop.

  • You’ll need zip() to combine the two lists.

  • Inside the loop, use an f-string to print the information.

The general structure is:

for ..., ... in zip(..., ...):
    print(...)

Step 3: Write Your Solution

# Write your code here:

















Step 4: Check Your Answers

## ----- ANSWERS ----- ##

for subject_id, volume in zip(subject_ids, hippocampal_volumes):
    print(f"{subject_id} has a hippocampal volume of {volume} mm³.")

Challenge

Modify the loop so that participants with a hippocampal volume less than 3700 mm³ print:

S051: Below threshold

while those with normal range or >= 3700 mm³ print:

S045: Within normal range

Hint: Combine zip() with an if statement.

7. Functions

So far, we’ve learned how to:

  • store information using variables,

  • organize data using lists and dictionaries,

  • make decisions using if statements,

  • repeat actions using for loops.

However, sometimes we find ourselves writing the same block of code multiple times.

Rather than copying and pasting that code repeatedly, we can group it together into a function.

A function is simply a named collection of instructions that performs a specific task.

Think of a function as creating your own command. Instead of repeatedly writing every individual instruction, you can give that collection of instructions a name and reuse it whenever you need it.

Example 1: A Simple Function

Suppose we frequently want to greet participants.

Instead of writing:

print("Welcome to the study!")

multiple times, we can write:

def welcome():
    print("Welcome to the study!")


welcome()
welcome()
welcome()
Welcome to the study!
Welcome to the study!
Welcome to the study!

Here:

  • def tells Python that we are defining a function.

  • welcome is the function’s name.

  • Everything indented underneath belongs to the function.

  • The parentheses () are used to call (run) the function.

Example 2: Functions Can Accept Information

Functions become much more useful when we allow them to accept information.

Suppose we want to greet different participants.

def welcome(subject_id):
    print(f"Welcome, {subject_id}!")

welcome("S045")
welcome("S049")
welcome("S051")
Welcome, S045!
Welcome, S049!
Welcome, S051!

Here, subject_id is called a parameter.

Each time we call the function, Python temporarily stores the value we provide inside subject_id.

For example,

welcome("S045")

is similar to Python doing:

subject_id = "S045"
print(f"Welcome, {subject_id}!")

Example 3: Calling a Function Inside a Loop

Functions and loops work very well together.

Suppose we have several participants.

subjects = ["S045", "S049", "S051"]

# defining function
def welcome(subject_id):
    print(f"Welcome, {subject_id}!")

# for loop
for subject in subjects:
    # call our welcome function
    welcome(subject)
Welcome, S045!
Welcome, S049!
Welcome, S051!

Notice what happens.

During each iteration:

  1. The loop stores one participant ID in subject.

  2. That participant ID is passed into the function.

  3. The function prints the message.

Example 4: Reusing Code with Functions

Earlier, we wrote code to determine whether a participant should be included in our study based on their reported drug use.

That worked well for one analysis. However, imagine that later in your project you need to perform the same classification again. For example:

  • before preprocessing the data,

  • before calculating summary statistics,

  • before creating figures.

One option would be to copy and paste the same block of code into each part of your program.

However, copying and pasting code is generally not recommended.

If you later decide to change your inclusion criteria (for example, by including "amphetamine" as well), you would need to find every copy of the code and update it. This becomes difficult as programs grow larger.

Instead, we can place the classification code inside a function. Then, whenever we need to classify a participant, we simply call that function.

# define our function classify_participants
def classify_participant(participant):
    # same code as before
    if participant["drug_use"] in included_drugs:
        participant["group"] = "patient group"
    else:
        participant["group"] = "exclude"

Let’s look at the function more closely.

  • classify_participant is the name of the function.

  • participant is the parameter. When we call the function, Python temporarily stores the participant dictionary inside this variable.

  • Everything indented underneath belongs to the function.

  • Notice that the function doesn’t print anything. Instead, it updates the participant dictionary by adding a new key called "group".

Now that we have defined our function, let’s prepare our data similar to our previous code.

included_drugs = ["nicotine", "cocaine", "heroin"]

participants = [
    {"subject_id": "S045", "age": 34, "drug_use": "cocaine"},
    {"subject_id": "S049", "age": 36, "drug_use": "amphetamine"},
    {"subject_id": "S051", "age": 29, "drug_use": "nicotine"}
]

By loop through the participants and call our function, making our code very concise.

for participant in participants:
    classify_participant(participant)
    print(participant)
{'subject_id': 'S045', 'age': 34, 'drug_use': 'cocaine', 'group': 'patient group'}
{'subject_id': 'S049', 'age': 36, 'drug_use': 'amphetamine', 'group': 'exclude'}
{'subject_id': 'S051', 'age': 29, 'drug_use': 'nicotine', 'group': 'patient group'}

During the first iteration, Python is effectively doing something similar to:

participant = participants[0]

classify_participant(participant)

The function updates the first participant by adding a "group" key.

During the second iteration, Python repeats exactly the same function using the second participant.

This process continues until every participant has been classified.

By placing the classification code inside a function, we only need to write it once. If we later decide to change our inclusion criteria (e.g., how our if loop works), we only need to update the function rather than searching through our entire program for duplicated code.

Without our function, our code would have been a bit more wordy:

for participant in participants:

    # This if loop could have been replaced by a function
    if participant["drug_use"] in included_drugs:
        participant["group"] = "patient group"
    else:
        participant["group"] = "exclude"

    print(participant)

Altogether, we have combined many concepts at once: variables, dictionaries, lists, the in keyword, if statements, for loops, and functions. Although each concept is simple on its own, combining them allows us to solve realistic neuroscience problems with surprisingly little code.

Try it yourself: Part 1

Earlier, we used an f-string to print information about participants. Suppose each participant’s data is stored as a dictionary.

participant = {
    "subject_id": "S045",
    "age": 34,
    "drug_use": "cocaine"
}

Write a function called introduce_participant() that accepts one participant dictionary consisting of subject id, age, and drug use.

After calling the function, it should print something like this:

Participant S045 is 34 years old and reports cocaine use.

Hint: You’ll need to retrieve values from the dictionary using their keys.

# Write your code here

def introduce_participant():
    # print something


# call your function here ...

Try it yourself (Part 2)

Use the function introduce_participant() that accepts one participant dictionary.

Then use a for loop to call the function for every participant in the list below.

participants = [
    {"subject_id": "S045", "age": 34, "drug_use": "cocaine"},
    {"subject_id": "S049", "age": 36, "drug_use": "amphetamine"},
    {"subject_id": "S051", "age": 29, "drug_use": "nicotine"}
]
# Write your for loop here ...