Start Here

Defining, Calling & Blocks

Defining, Calling And Blocks

Two ideas cause more early confusion than anything else, and both came up live in the first class.

Defining something is not running it. And indentation is what marks a block, where other languages use braces.

Get these two and most beginner bewilderment disappears. There is more on blocks in No Braces: Indentation Is The Syntax.

Defining a function does not run it

Someone in the first class typed this, ran it, and got nothing at all:

def add(a, b):
    return a + b

They assumed something was broken. Nothing was.

Those two lines define the function. They tell Python that the name add now refers to this block. They do not execute it.

To run it, call it:

def add(a, b):
    return a + b

print(add(4, 5))
9

Defining and calling are separate events, often far apart in your file. Holding that distinction is what later makes decorators, callbacks and graph nodes make sense — in all three you hand over a function now that something else calls later.

The parts

def add(a, b):
    return a + b
  • def — define
  • add — the name
  • a, b — the arguments, the inputs
  • return — sends back one value

Several inputs, a single return value. Same shape as every language you know.

The same thing in Java

int add(int a, int b) {
    return a + b;
}

What Python drops: the return type, the parameter types, the braces, the semicolons.

What it adds: def and a colon.

That is the entire difference.

Indentation is the block

In Java, C# or JavaScript a block is what sits between { and }. Python has no braces. The block is whatever is indented under the colon.

for student in students:
    if student.startswith("A"):
        print(student)
    print("checked", student)

Read it by column:

  • print(student) runs only for names starting with A
  • print("checked", ...) runs for everyone

That is brace-inside-brace, expressed as spacing.

The stray space

The error people hit on their first function:

def add(a, b):
    return a + b

 print(add(4, 5))
IndentationError: unexpected indent

One space before print and Python thinks the line belongs to a block. Outer-level lines start at column zero.

The editor indents correctly for you after a colon. It goes wrong when you add or delete a space by hand.

Case matters

Print("hello")
NameError: name 'Print' is not defined

print and Print are different names, exactly as name and Name are different variables. This catches several people in every first class.

In a notebook, order is what you ran

A notebook does not run top to bottom unless you make it. It runs cells in the order you pressed Shift + Enter.

So a variable can exist because of a cell you have since deleted, and code that works for you can fail for someone opening it fresh.

When a notebook behaves strangely: Runtime → Restart and run all. Do this before sharing one.

Practise this

  • Define a function and run the cell. Confirm you get nothing. Then call it.
  • Write a function returning the product of two numbers, and call it with 6 and 7.
  • Add a single space before an outer-level line and read the error.
  • Type Print with a capital P on purpose, then fix it.

Try It Yourself

Copy this into a new Colab notebook and run it. Nothing to install.

example.py
1# Defining is not running. Indentation is the block. Case matters.
2
3# ---------------------------------------------------------------
4# 1. DEFINING a function does nothing on its own
5# ---------------------------------------------------------------
6
7def add(a, b):
8 return a + b
9
10print("The cell above produced no output. Nothing is broken.")
11print("Those two lines DEFINED add. They did not run it.")
12print()
13
14# To run it, you have to CALL it:
15print("add(4, 5) =", add(4, 5))
16print()
17
18# The parts:
19# def - define
20# add - the name
21# a, b - the arguments (inputs). There can be several.
22# return - sends back ONE value
23
24
25# ---------------------------------------------------------------
26# 2. The same function in Java, for comparison
27# ---------------------------------------------------------------
28print("""Java:
29 int add(int a, int b) {
30 return a + b;
31 }
32
33Python:
34 def add(a, b):
35 return a + b
36
37Python drops: the return type, the parameter types, the braces,
38the semicolons. It adds: `def` and a colon. That is the difference.
39""")
40
41
42# ---------------------------------------------------------------
43# 3. Indentation is the block - braces, expressed as spacing
44# ---------------------------------------------------------------
45students = ["Amit", "Sara", "Akhil"]
46
47for student in students:
48 if student.startswith("A"):
49 print(student, "starts with A")
50 print("checked", student)
51
52# Read it by column:
53# the first print runs only for names starting with A
54# the second runs for everyone
55print()
56
57
58# ---------------------------------------------------------------
59# 4. The stray space - the classic first-function error
60# ---------------------------------------------------------------
61try:
62 exec("def f():\n return 1\n\n print(f())")
63except IndentationError as e:
64 print("IndentationError:", e)
65 print(" -> one space before `print` and Python thinks it is inside a block")
66print()
67
68
69# ---------------------------------------------------------------
70# 5. Case matters
71# ---------------------------------------------------------------
72try:
73 exec('Print("hello")')
74except NameError as e:
75 print("NameError:", e)
76 print(" -> it is print, not Print. Same for every name you use.")
77print()
78
79
80# ---------------------------------------------------------------
81# 6. A program runs top to bottom, and an error stops it
82# ---------------------------------------------------------------
83print("this runs")
84try:
85 print(10 / 0)
86except ZeroDivisionError:
87 print("caught it - without the try, nothing below would run")
88print("this runs too, because we caught it")