1.2. Python Basic Syntax#

Hide code cell source

import sys
from pathlib import Path

current = Path.cwd()
for parent in [current, *current.parents]:
    if (parent / '_config.yml').exists():
        project_root = parent  # ← Add project root, not chapters
        break
else:
    project_root = Path.cwd().parent.parent

sys.path.insert(0, str(project_root))

from shared import thinkpython, diagram, jupyturtle, download

# # Register as top-level modules so direct imports work in subsequent cells
sys.modules['thinkpython'] = thinkpython
sys.modules['diagram'] = diagram
sys.modules['jupyturtle'] = jupyturtle
sys.modules['download'] = download
../../_images/python-syntax.webp

Fig. 1.5 Python Syntax Overview [dataflair Team, 2017]#

1.2.1. Indentation and Block Structure#

In Python, indentation defines code blocks instead of braces ({}), which many other languages use. Any line ending with a colon (:), such as if, for, while, def, or class, starts a new block, and the indented lines that follow belong to that block. Python expects consistent indentation (commonly 4 spaces per level), and mixing tabs and spaces or misaligning lines can raise IndentationError. When indentation changes, Python treats that as entering or leaving a block, so correct spacing controls program structure and execution flow.

for i in range(5):
print(i)                ### This line is not indented, so it will cause an error

Output

Cell In[2], line 2
    print(i)                ### This line is not indented, so it will cause an error
    ^
IndentationError: expected an indented block after 'for' statement on line 1
for i in range(5):
    print(i)            ### This line is indented, so it will work correctly
0
1
2
3
4

1.2.2. Statement Formatting#

In Python, a statement usually ends at a newline, so each line is typically one statement. You can place multiple simple statements on one line using semicolons (;), but this is generally discouraged because it reduces readability. For long statements, Python allows implicit line continuation inside parentheses (), brackets [], or braces {}, which is the preferred way to split expressions across lines. Explicit continuation with a backslash (\) also works, but it is fragile because a trailing space after the backslash will cause an error. In practice, write one statement per line and use parentheses for multi-line expressions.

### 1) Newlines: one statement per line (preferred)
x = 10
y = 20
total = x + y
print(total)
30
### 2) Semicolons: multiple statements on one line (valid, but less readable)
x = 10; y = 20; print(x + y)
30
### 3) Multi-line with parentheses (preferred)
total = (
    100
    + 200
    + 300
)
print(total)
600
### 4) Multi-line with backslash (works, but less preferred)
total = 100 + 200 + \
        300
print(total)
600
### 5) Multi-line function call with parentheses
print(
    "Name:", "Alice",
    "Age:", 25
)
Name: Alice Age: 25

1.2.3. Input and Output#

1.2.3.2. Keyboard Input#

Python provides a built-in function called input that stops the program and waits for the user to type something. When the user presses Return or Enter, the program resumes, and input returns what the user typed as a string. Before getting user input, you might want to display a prompt that explains what to type. The input syntax is:

variable = input("Prompt message: ")
name = input("Enter your name: ")
print("Hello, " + name + "!")

Output:

Enter your name: Alice
Hello, Alice!
  • Type Conversion with Input

age = input("Enter your age: ")   

print(type(age))                      ### age is of string type

age = int(age)                        ### convert input string to integer

print(type(age))
print(f"You are {age} years old.")

Output:

Enter your age: 35
<class 'str'>
<class 'int'>
You are 35 years old.
  • Type Conversion: Early

age = int(input("Enter your age: "))      ### Directly convert input to integer

print(type(age))

print(f"You are {age} years old.")

Output:

Enter your age: 35
<class 'int'>
You are 35 years old.

1.2.4. Comments#

Comments are explanatory notes in your code that are ignored by the Python interpreter. Comments are used to:

  1. Explain complex logic: help others (and your future self) understand what the code does.

  2. Document assumptions: note why certain decisions were made.

  3. Mark TODO items: indicate areas that need improvement or completion.

  4. Disable code temporarily: comment out code for testing without deleting it.

Single-line comments start with the hash symbol #. Everything after # on that line is ignored by Python. For multi-line comments, we use multiple hashes.

### single-line comments
# This is a comment explaining the code below
price = 100
tax_rate = 0.08  # 8% sales tax

### multiple-line comments
# Calculate total price including tax
# total = price * (1 + tax_rate)
# print(f"Total price: ${total}")

Ideally, good variable names can reduce the need for comments, but long names can make complex expressions hard to read, so there is a tradeoff. For example, velocity_mph = 8 might be clear without a comment, but v = 8 # velocity in miles per hour might be more readable in a mathematical formula.

1.2.4.1. Docstring#

Unlike comments, which are ignored by the Python interpreter at runtime, docstrings are string literals used for documentation. They are processed by the interpreter and can be accessed with __doc__ or help() as part of the program.

Usually, a docstring is a string literal written as the first statement inside a module, function, class, or method to describe what it does, its inputs, outputs, or behavior. By convention it uses triple quotes ("""...""") so it can span multiple lines.

def area_circle(radius):
    """Return the area of a circle given its radius."""
    import math
    return math.pi * radius**2

print(area_circle(3))      # 28.274333882308138
print(area_circle.__doc__) # Return the area of a circle given its radius.
28.274333882308138
Return the area of a circle given its radius.

1.2.5. Object#

In Python, everything is an object, and every object has:

  • identity (unique ID) (id())

  • value

  • type (type())

1.2.5.1. Object ID#

In Python, every object has a unique identity, which can be obtained using the built-in id() function. An identity is a unique integer that remains constant for an object throughout its lifetime. This is useful for understanding how Python manages objects in memory and for distinguishing between objects that have the same value. Notice that these objects have different IDs.

num1 = 42
num2 = 3.14
greeting = "hello"
fruits = ["apple", "banana", "cherry"]

print(id(num1))
print(id(num2))
print(id(greeting))
print(id(fruits))
4317504800
4547728144
4431035536
4544369280

1.2.6. Python Keywords#

Reserved words, or keywords, are special words reserved by the programming language to be used to specify the structure of a program. Keywords of the language cannot be used as ordinary identifiers (such as variable names).

For example, if you try to assign a string to a variable named class, you will receive a syntax error because class is a keyword.

class = 'Assigning a string to a keyword to be a variable name...'

Running this raises SyntaxError because class is a reserved keyword in Python.

Here’s a complete list of 35 Python keywords as shown in the Python Language Reference :

False      await      else       import     pass
None       break      except     in         raise
True       class      finally    is         return
and        continue   for        lambda     try
as         def        from       nonlocal   while
assert     del        global     not        with
async      elif       if         or         yield

Keywords are part of Python’s syntax. Instead of memorizing all 35 at once, it helps to group some common ones by the jobs they do:

Category

Examples

Flow control

if, elif, else, for, while, break, continue, pass

Definitions

def, class, lambda

Boolean logic and identity

and, or, not, is, in, True, False, None

Imports and scope

import, from, global, nonlocal

Exceptions and context

try, except, finally, raise, assert, with, as

Async and generators

async, await, yield

In most development environments, keywords are displayed in a different color; if you try to use one as a variable name, the editor or interpreter will warn you.

To show all the Python keywords, you can do:

from keyword import kwlist
print("Number of Python keywords:", len(kwlist))
print("All Python keywords:", kwlist)

The output would look like:

Number of Python keywords: 35
All Python keywords: ['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']

As stated earlier, keywords form the program structure. The examples below show how keywords act like the grammatical parts of a program.

For example, if is a keyword in Python and is highlighted in most code editors.

### example of the "if" keyword in Python
num = 5
if num > 0:
    print("Positive number")
Positive number

And for and in are also keywords.

### example of the "for" keyword in Python
for i in range(5):
    print(i)
0
1
2
3
4

1.2.6.1. Soft keywords#

Python’s soft keywords are special words that act as keywords only in specific contexts, but can be used as regular identifiers (such as variable or function names) in other contexts. As of Python 3.12, there are four soft keywords : match, case, _, and type.

1.2.7. Modules and Packages#

In Python, functions, classes, modules, packages, and libraries are essential tools for organizing and reusing code:

Term

What It Is

Typical Use

Function

A named, reusable block of code that performs one specific task and can be called multiple times.

Break problems into smaller steps and avoid repeating logic.

Class

A blueprint for creating objects that bundle data (attributes) and behavior (methods).

Model real-world entities and organize related state + behavior.

Module

A single Python file (.py) containing code such as functions, classes, and variables.

Split code into files and import what you need.

Package

A directory of related modules (and often subpackages) that forms a larger namespace.

Organize multi-file projects into clear components.

Library

A broader collection of packages/modules built to solve common domains or tasks.

Reuse mature tools (e.g., data analysis, web, scientific computing) instead of building from scratch.

Together, these components help make Python code more organized, efficient, and maintainable. The most important distinction for now is:

  • Module: a single Python file (e.g., mymodule.py).

  • Package: a directory of modules (optionally with __init__.py).

1.2.7.1. Importing Modules#

Python ships with about 300 built-in and standard-library modules. For those modules, you can import them directly and use them (for example, import math). There are different ways of importing:

Import Pattern

Example Code

Usage Example

Description

Standard import

import math

math.sqrt(25)

Clear, namespaced imports

Aliased import

import math as m

m.pi

Alias for brevity (common with large libs)

Selective import

from math import sqrt

sqrt(25)

Convenient, but use sparingly for readability

Import all (not recommended)

from math import *

sqrt(25)

Imports all names; can cause name conflicts and is discouraged

Style notes: Prefer absolute imports in top-level scripts; reserve relative imports for package internals. Follow PEP 8 import order: standard library → third-party → local.

To use methods or attributes from a module, use the dot operator (.) between the module name and the attribute name. For example, the Python math module provides a variable called pi that contains the mathematical constant denoted \(\pi\). We can access it as math.pi:

import math
math.sqrt(25)     ### dot operator
5.0

1.2.7.2. Installing Packages#

External, third-party modules are created by the Python community. You must use pip to install them first (for example, notebook, NumPy, or pandas), then import them before using them. Most software on the Python Package Index (PyPI; https://pypi.org , where pip finds software packages) is referred to as “packages” in this context.

To install the packages in the CLI, you would go into your project directory, activate your virtual environment, and then use the pip installation syntax to install the package into your .venv folder (site-packages) for dependency integrity:

pip install [package_name]

If you are in Jupyter Notebook, use the Jupyter Notebook magic command %pip (instead of the older !pip) to install the package into the active kernel:

%pip install [package_name]

For example, NumPy (numeric Python) is a popular package for data science. From inside Jupyter Notebook, you can install it with:

%pip install numpy
Requirement already satisfied: numpy in /Users/tychen/workspace/py/.venv/lib/python3.13/site-packages (2.3.4)
[notice] A new release of pip is available: 25.2 -> 26.1.1
[notice] To update, run: pip install --upgrade pip
Note: you may need to restart the kernel to use updated packages.

You probably want to comment the %pip install line out after installation as you only need to install it once in the virtual environment.