Introduction to Programming

Written by Luke Chang This notebook runs in your browser. There is nothing to install: every cell below is live Python, and you are encouraged to change the code and see what happens. Breaking a cell costs nothing — reload the page and it comes back. If you want to run Python on your own machine, see Setting up Python first. A note on how to read this page. Many cells have a slider or a box above them. Those are not decoration — move one and every cell that depends on it re-runs immediately. That is what a reactive notebook means, and it is the fastest way to build intuition about what a piece of code actually does.

How a cell shows its output

Before anything else, the rule that catches everyone in marimo: a cell displays whatever its last expression evaluates to.
x = 2 + 2      # an assignment is a statement, not an expression -> shows nothing
x = 2 + 2
x              # the last line is an expression -> shows 4
print() is different: it writes text out as the cell runs, so you can show several things, or show something from inside a loop. The value it returns is None, which is why a cell ending in print(...) shows the printed text and nothing else. Use print() when you want a running commentary; end on a bare expression when you want marimo to render the thing itself — a table, a figure, a slider.
30

Variables and types

A variable is a name bound to a value. Python works out the type for you, and type() tells you what it decided. Type a Python value into the box — try 42, 3.14, 'hello', True, None, [1, 2, 3], {'a': 1} — and watch what Python makes of it.
x = 42
type(x)   # -> int
Python read that as a int, with the value 42.
The types you will meet constantly:
Type Example What it is
int 42 a whole number
float 3.14 a number with a decimal point
str 'hello' text
bool True true or false
NoneType None "no value" — not zero, not empty
You can convert between them when the conversion makes sense. str(1) gives '1', and int('1') gives 1 — but int('hello') raises a ValueError, because there is no sensible answer.

Arithmetic

The usual operators, plus two that surprise people. Change the numbers and the operator:
    ```python
    7 / 2
    ```
     `3.5`  (a `float`)
/ is true division and always gives a float, even when it divides evenly.

Strings

+ joins strings and * repeats them. The same symbols do different things depending on the type — adding numbers and adding strings are not the same operation.
word = 'ha'
word * 3        # -> 'hahaha'
word + "!"       # -> 'ha!'
len(word)        # -> 2
word.upper()     # -> 'HA'

Putting values into text

Nearly every print on this page uses an f-string: a string prefixed with f, in which anything inside {braces} is evaluated and dropped into the text.
name, n = "Luke", 3
f"{name} ran {n} subjects"    # -> 'Luke ran 3 subjects'
f"{n} squared is {n ** 2}"    # -> '3 squared is 9'
A colon introduces formatting, which is how you stop a float printing to seventeen decimal places:
f"{3.14159:.2f}"   # -> '3.14'     two decimal places
f"{42:>6}"         # -> '    42'   right-aligned in six columns
f"{0.87:.1%}"      # -> '87.0%'    as a percentage

Comparisons and logic

Comparisons produce a bool. and, or and not combine them.
5 < 10
True
Combining them: (5 < 10) and (5 != 0)True

Conditional logic

if runs a block when a condition is true, elif offers another condition, and else catches everything remaining. Python decides where a block begins and ends by indentation — there are no braces, and the indentation is not cosmetic. Drag the reaction time and watch which branch runs. A trial answered in under 150 ms was almost certainly anticipated rather than decided, and one past 2000 ms suggests attention lapsed — so a study usually labels the trial before analysing it.
rt = 450
if rt < 150:
label = "anticipation"
elif rt <= 2000:
label = "valid"
else:
label = "lapse"

The highlighted branch is the one that runs, so label is "valid".

Loops

A for loop walks over the items of something. A while loop keeps going until its condition stops being true. range(n) produces the numbers 0 to n-1 — note it stops before n, which is the same convention as slicing below.
for i in range(5):
    print(i, i ** 2)
```text i = 0 i2 = 0 i = 1 i2 = 1 i = 2 i2 = 4 i = 3 i2 = 9 i = 4 i**2 = 16
The same thing as a **list comprehension**, which is the idiomatic way to build a list
from a loop:
```python
[i ** 2 for i in range(5)]   # -> [0, 1, 4, 9, 16]

Functions

A function packages a piece of work under a name so you can use it more than once. def names it, the parameters are its inputs, and return hands a value back. Edit this one — move the cutoffs, add a branch — and the cells below re-run.
| rt (ms) | label |
|---|---|
| 120 | anticipation |
| 150 | valid | | 450 | valid | | 2000 | valid | | 2400 | lapse |
Because the notebook is reactive, editing `trial_label` above rewrites this table
immediately  you never re-run anything by hand.

Lists

A list is an ordered, changeable sequence. Python counts from 0, so the first item is a[0]. Slicing is a[start:stop:step], and it includes start but excludes stop. That off-by-one is the single most common source of confusion for beginners, so rather than explain it again, move the sliders and watch which items survive.
a = [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
a[0:10:1]
0 1 4 9 16 25 36 49 64 81
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Dictionaries

A dictionary maps keys to values. Where a list answers "what is at position 3?", a dictionary answers "what is stored under 'age'?" — which is usually the question you actually have.

Tuples and sets

A tuple is an ordered sequence like a list, but it cannot be changed after it is made. Use one when the fixedness is the point — coordinates, or a function returning several values at once. A set is an unordered collection with no duplicates, and it does the membership-and-overlap questions quickly.
A = {1, 2, 3, 4, 5, 6}
B = {4, 5, 6, 7, 8}

A | B    # union         -> {1, 2, 3, 4, 5, 6, 7, 8}
A & B    # intersection  -> {4, 5, 6}
A - B    # difference    -> {1, 2, 3}
A ^ B    # in one, not both -> {1, 2, 3, 7, 8}

Modules

Most of Python's usefulness lives in modules you import rather than in the language itself. The standard library ships with the interpreter; everything else you install.
import math                     # the whole module
import numpy as np              # under a shorter name
from math import sqrt, pi       # just the names you want
Prefer import numpy as np to from numpy import *. With the second form you cannot tell where a name came from, and two modules can silently overwrite each other's.

When something breaks

You will spend more time reading errors than writing code, so it is worth learning to read them properly rather than skimming for red. A traceback is printed oldest call first. The last line is the one that matters: it names the error and says what went wrong. Everything above it is the path the interpreter took to get there, which only matters once the last line is not enough. Pick an error and read what Python says about it:
subtotal + 10
NameError: name 'subtotal' is not defined
NameError — Python has never seen that name. Nearly always a typo, or a cell that defines it has not run yet.

Exercises

Add a cell under each one and write your answer. Everything you need is above, and there is more than one right way to do each.

1. Find the even numbers

Given a = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100], make a new list containing only the even elements. Hint: % from the arithmetic section.

2. Find the range

Given a list of integers with at least one element, return the difference between the largest and smallest values. Hint: max() and min() are built in.

3. Numbers in both lists

Find the numbers that appear in both lists:
a = [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361]
b = [0, 4, 16, 36, 64, 100, 144, 196, 256, 324]
Hint: a list comprehension with in works. So does one line using sets — try both and compare.

4. Speeding ticket

Write a function that takes a speed and returns the fine: $0 at 60 or below, $100 from 61 to 80 inclusive, $500 at 81 or above. Hint: if / elif / else. The thresholds are inclusive at both ends, so decide carefully whether each comparison is < or <= — 60, 61, 80 and 81 are where a wrong choice shows up.

Graded version

The graded version of these four questions, plus one on reading an error message, is the Programming assignment at the end of this page. Open it with the Assignment button in the header — it runs in a drawer at the bottom of the page, so you can keep this chapter open while you work. Sign in with your Dartmouth account inside it and submit each question when you are ready. The cells below are for practice and are not collected.
  • 0: 1
  • 1: 4
  • 2: 9
  • 3: 16
  • 4: 25
  • 5: 36
  • 6: 49
  • 7: 64
  • 8: 81
  • 9: 100
  • 0: 17
  • 1: 4
  • 2: 9
  • 3: 42
  • 4: 25
  • 5: 3
  • 0: 20
  • 1: 10
  • 0: list · 2 items
    • 0: 55
    • 1: None
  • 1: list · 2 items
    • 0: 70
    • 1: None
  • 2: list · 2 items
    • 0: 95
    • 1: None

Assignment: Introduction to Programming

programming · v3

  1. Q1. The even numbers
  2. Q2. The range of a list
  3. Q3. In both lists
  4. Q4. The speeding fine
  5. Q5. Reading an error
Open in molab Opens in a drawer at the bottom of the page, so you can keep reading while you work. Autosaves in this browser.