2.1. Python Syntax#
Learning is all about connecting the dots – you need to collect enough dots first. To achieve expertise, you need to do two things:
Repeat: Keep collecting (learning) more dots.
Associate: Keep connecting the dots to make sense.
Fig. 2.2 Experience, Knowledge, and Creativity (*Nikolaos Arvanitis says that the original graph (knowledge & experience) is done by cartoonist Hugh McLeod. I personally would frame the constructs as information => knowledge => Expertise)#
2.1.1. Input and Output#
2.1.1.1. print() and F-Strings#
In Python, the print() function is used to display output to the screen. It’s one of the most commonly used functions for debugging, showing results, and interacting with users. When printing multiple values, a , can be used; or you may choose to concatenate the strings using the + operator.
The print() function displays values to the console/command line:
print("hello, world!") ### print a string
hello, world!
To print multiple values in one statement, you either comma-separate your values or concatenate the strings.
print("Name:", "Alice", "Age:", 25) ### commas-separated
print("Name:" + " Alice" + " Age:", 25) ### + concatenated
Name: Alice Age: 25
Name: Alice Age: 25
%%expect TypeError
print("I am " + 25 + " years old") ### Error: can only concatenate string
TypeError: can only concatenate str (not "int") to str
2.1.1.1.1. F-Strings#
F-strings (formatted string literals) are more readable and efficient for formatting strings in Python (available since Python 3.6). F-string is the preferred output method because it is clean and allows expressions between {}, so you don’t need to worry about data types:
name = "Alice"
age = 25
print(f"My name is {name} and I am {age} years old.") ### f-string with variables
x = 10
y = 20
print(f"The sum of {x} and {y} is {x + y}") ### f-string with expressions
My name is Alice and I am 25 years old.
The sum of 10 and 20 is 30
2.1.1.1.2. sep and end Params#
The print() function has useful parameters:
sepfor changing separator string in between print() arguments (default is space)endfor changing what comes at the end (default is newline)
print("A", "B", "C", " (separator is space by default)") ### Output: A B C (separator is space by default)
print("A", "B", "C", " (separator is now \"-\")", sep="-") ### Output: A-B-C (separator changed to '-')
A B C (separator is space by default)
A-B-C- (separator is now "-")
for num in range(1,4):
print(num) ### print list with default end character (\n, new line)
for num in range(1,4):
print(num, end=" ") ### Print list space as end character
1
2
3
1 2 3
print(2026, 2, 7, sep="/") ### Output: 2026/2/7
fruits = "apple, banana, cherry"
print(fruits, sep=", ") ### Output: apple, banana, cherry
2026/2/7
apple, banana, cherry
### Exercise: Print "hello, world"
### The output should look the same as the cell below
### Your code begins here
### Your code ends here
hello, world
2.1.1.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: ")
We usually save the user input value to a variable like this:
user_name = input("Enter your username: ")
print(user_name)
After entering the user name in the prompt box and hit Enter, we get
Enter your username: tychen
tychen
Or, to print richer information using f-string,
age = input("Enter your age: ")
print(f"You are {age} years old next year.")
After entering age in the prompt box and hit Enter:
Enter your age: 35
You are 35 years old next year.
2.1.3. Variables#
A variable is a named location in computer memory that stores a value. Think of it as a name/label that is associated with some data. Variables allow us to store, retrieve, and manipulate data throughout the program.
Unlike some other programming languages, Python doesn’t require you to declare the data type when creating a variable. The type is automatically determined based on the value you assign (this is called dynamic typing) at runtime (execution).
2.1.3.1. Creating Variables#
In Python, you create a variable by using an assignment statement with the assignment operator =.
name = "Alice"
age = 25
print(f"{name} is {age} years old.")
Alice is 25 years old.
Note that:
Variables can be reassigned.
You can assign multiple values/expressions to multiple variables in one line.
### reassignment
x = 10 # x is 10
x = 20.5 # now x is 20.5
x = "hello" # now x is a string (type can change!)
print(x)
hello
### multiple assignment in a single line:
x = y = z = 0 # x, y, and z are all 0
a, b, c = 10, 20, 30 # assign different values to variables
a, b = b, a # Swap values using tuple unpacking ==> sorting
print(f"After swap: a = {a}, b = {b}")
After swap: a = 20, b = 10
### Exercise: Create a variable called "name" and use f-string to print it
### The output should be the same as the cell below
### Your code starts here
### Your code ends here
Hello, Dr. Chen
2.1.3.2. Updating variables#
As you may have discovered, it is legal to make more than one assignment to the same variable. A new assignment makes an existing variable refer to a new value (and stop referring to the old value).
For example, here is an initial assignment that creates a variable.
x = 5
x
5
And here is an assignment that changes the value of a variable.
x = 7
x
7
The following figure shows what these assignments looks like in a state diagram.
from diagram import make_rebind, draw_bindings
bindings = make_rebind('x', [5, 7])
from diagram import diagram, adjust
width, height, x, y = [0.54, 0.61, 0.07, 0.45]
ax = diagram(width, height)
bbox = draw_bindings(bindings, ax, x, y)
# adjust(x, y, bbox)
The dotted arrow indicates that x no longer refers to 5.
The solid arrow indicates that it now refers to 7.
A common kind of assignment is an update, where the new value of the variable depends on the old.
x = 7
x = x + 1
x
8
This statement means “get the current value of x, add one, and assign the result back to x.”
Increasing the value of a variable is called an increment; decreasing the value is called a decrement.
Because these operations are so common, Python provides augmented assignment operators that update a variable more concisely.
For example, the += operator increments a variable by the given amount.
z += 2
z
2
There are augmented assignment operators for the other arithmetic operators, including -= and *=.
2.1.3.3. Naming Rules & Conventions#
Variable names must follow these rules (from PEP8):
Must start with a letter (a-z, A-Z) or underscore (
_)Can contain letters, digits (0-9), and underscores (
_)Can NOT contain spaces or special characters (@, #, $, %, etc.)
Cannot be a Python keyword (like
if,for,class, etc.)Case-sensitive:
Name,name, andNAMEare different variables
Python programmers follow these conventions (recommended but not required):
Convention |
Use Case |
Example |
|---|---|---|
snake_case |
Variable and function names |
|
UPPER_CASE |
Constants |
|
PascalCase (not camelCase) |
Class names |
|
Descriptive names |
Make code readable |
|
2.1.3.4. Object#
In Python, everything is an object, and every object has:
identity (unique ID) (
id())value
type (
type())
2.1.3.4.1. Type checking#
The built-in function type() returns the data type of the object; in this case, variables.
num1 = 10 ### integer
num2 = 10.1 ### floating-point number
greeting = "hello, world" ### text/string
fruits = ['Apple', 'Banana', 'Cherry'] ### lists are enclosed with square brackets
print(type(num1))
print(type(num2))
print(type(greeting))
print(type(fruits))
<class 'int'>
<class 'float'>
<class 'str'>
<class 'list'>
2.1.3.4.2. 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.
print(id(num1))
print(id(num2))
print(id(greeting))
print(id(fruits))
139755302601232
139754409263760
139754408146288
139754407786240
2.1.3.5. Type conversion#
Type conversion is the general process of converting a value from one data type to another. There are two ways of type conversion to change type:
Type Casting: Explicit conversion performed by the programmer (e.g., using
int("42")).Type Coercion: Implicit conversion performed automatically by the programming language (e.g.,
3 + 4.5results in7.5, where the integer3is coerced to a float to match the other operand).
### casting vs. coercion
### type casting
num = 5
print("num's type:", type(num))
print("num's new type", str(num)) ### casting (explicit conversion) by programmer
### type coercion
x = 3 ### integer
y = 0.14 ### float
print(f"{x} + {y} is {x+y} and has the type: {type(x + y)}")
### int + float = float done automatically by Python interpreter
### coercion (implicit conversion)
num's type: <class 'int'>
num's new type 5
3 + 0.14 is 3.14 and has the type: <class 'float'>
### Exercise: Type Conversion
### Print the data type of variable 'num' after the addition
### The result should be as the cell below
### Your code begins here
num = "100.1"
num = float(num) + 1.0
### Your code ends here
<class 'float'>
2.1.3.6. Type Hinting#
Type hinting/annotation in Python allows you to specify the expected data types of variables, function parameters, and return values, making your code more readable and easier to debug. Introduced in Python 3.5, type hints are optional and do not affect program execution, but they help tools like linters and IDEs catch type-related errors early. For example, you can annotate a function as def add(a: int, b: int) -> int: to indicate that both parameters and the return value should be integers.
num: int = 10 ### type hinting for integer
name: str = "Alice" ### type hinting for string
is_active: bool = True ### type hinting for boolean
height: float = 5.9 ### type hinting for float
2.1.4. 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. For example, if you try to assign a string to a variable name class, since class is a keyword, you will receive a syntax error because the Python interpreter will detect that.
%%expect SyntaxError
class = 'Self-Defense Against Fresh Fruit'
Cell In[30], line 1
class = 'Self-Defense Against Fresh Fruit'
^
SyntaxError: invalid syntax
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 serve as the grammar glue for you to express structure and can be group as such:
Structure |
Keywords |
|---|---|
1. control flow |
if, else, for, while |
2. logic/conditions |
and, or, not |
3. definitions |
def, class |
4. scoping/module structure |
import, from |
5. special behaviors |
return, break, continue, try, except, etc. |
You don’t have to memorize this list, but you can already see how these keywords play critical role in formulating code. In most development environments, keywords are displayed in a different color; if you try to use one as a variable name, you’ll be alarmed not to.
### example of the "if" keyword in Python
num = 5
if num > 0:
print("Positive number")
Positive number
### example of the "for" keyword in Python
for i in range(5):
print(i)
0
1
2
3
4
2.1.4.1. Soft keywords#
Python’s soft keywords are special words that act as keywords only within specific contexts, but can be used as regular identifiers (like variable or function names) in other contexts. As of Python 3.12, there are 4 soft keywords: match, case, _, and type
2.1.5. Operators#
In programming languages, operators are special symbols that perform computations or logical comparisons between values. They form the backbone of most expressions — whether you’re performing arithmetic, comparing data, assigning values, or testing relationships between objects. (For a detailed discussion of Expressions and Operators, see Python Reference/Expressions)
Category |
Operators |
Description |
Example |
|---|---|---|---|
Arithmetic |
|
Mathematical operations |
|
Comparison |
|
Compare values, return bool |
|
Logical |
|
Boolean logic |
|
Assignment |
|
Assign and update values |
|
Identity |
|
Test object identity |
|
Membership |
|
Test membership in sequence |
|
Bitwise |
|
Bit-level operations |
|
As an example for operators, we’ll cover some operators here.
2.1.5.1. Arithmetic Operators#
An arithmetic operator is a symbol that represents an arithmetic computation. For example:
The plus sign,
+, performs addition.The minus sign,
-, is the operator that performs subtraction.The asterisk,
*, performs multiplication.The forward slash,
/, performs division. Note that in modern Python (Python 3+), the division operator/always returns a floating-point number, even if the result is a whole number.The integer/floor division operator,
//, is called floor division because it always rounds down (toward the “floor”).The modulus operator
%returns the remainder after division.The operator
**performs exponentiation; that is, it raises a number to a power. In other languages, such as R, MATLAB, Julia, and Excel, the caret^is used for exponentiation.
a = 10 + 3
b = 10 - 3
c = 10 * 3
d = 10 / 3
e = 10 // 3
f = 10 % 3
g = 10 ** 3
print(a, b, c, d, e, f, g, sep="\n")
13
7
30
3.3333333333333335
3
1
1000
2.1.5.2. Integer division and modulus#
Recall that the integer division operator, //, divides two numbers and rounds down to an integer. For example, suppose the run time of a movie is 105 minutes. You might want to know how long that is in hours.
Conventional division returns a floating-point number:
minutes = 105
minutes / 60
1.75
But we don’t normally write hours with decimal points. Integer division returns the integer number of hours, rounding down:
minutes = 105
hours = minutes // 60
hours
1
To get the remainder, you could subtract off one hour in minutes:
remainder = minutes - hours * 60
remainder
45
Or you could use the modulus operator, %, which divides two numbers and returns the remainder.
remainder = minutes % 60
remainder
45
The modulus operator is more useful than it might seem.
For example, it can check whether one number is divisible by another – if x % y is zero, then x is divisible by y.
Also, it can extract the right-most digit or digits from a number.
For example, x % 10 yields the right-most digit of x (in base 10).
Similarly, x % 100 yields the last two digits.
x = 123
x % 10
3
x % 100
23
Finally, the modulus operator can do “clock arithmetic”. For example, if an event starts at 11 AM and lasts three hours, we can use the modulus operator to figure out what time it ends.
start = 11
duration = 3
end = (start + duration) % 12
end
2
The event would end at 2 PM.
2.1.5.3. Operator Precedence#
Operator precedence determines the order in which operations are evaluated in an expression. Operations with higher precedence are performed before those with lower precedence. When in doubt, use the parentheses () to ensure you have the preferred precedence.
Notice that exponentiation happens before addition because exponentiation is the 2nd highest precedence. This actually follows the order of operations you might have learned in a math class: exponentiation happens before multiplication and division, which happen before addition and subtraction.
In the following example, multiplication happens before addition, and exponentiation happens before multiplication.
num1 = 12 + 5 * 6
num2 = (12 + 5) * 6
x, y, z = 1, 2, 3
result = x + y * z ** 2
print(result) ### output: 13
19
2.1.6. Built-in Data Types#
Python has standard types built into the interpreter. The principal built-in types are: numerics, sequences, mappings, classes, instances, and exceptions. The commonly used data types can be organized as Fig. 2.3.
Fig. 2.3 Python Built-In Data Types#
These types can be grouped into simple/primitive data types and collections types; namely, among the often-used built-in types, some are for storing single values (Literals), while others are for storing multiple values.
Group |
No. |
Category |
Types |
Remarks |
|---|---|---|---|---|
Literals |
1 |
Numeric |
|
Represent numbers (whole numbers, decimals, complex numbers) |
2 |
String |
|
Represent text (immutable) |
|
3 |
Boolean |
|
Represent True/False |
|
4 |
Null |
|
Represent “nothing” |
|
Collections |
5 |
Sequence |
|
Ordered collections (list is mutable, tuple is immutable) |
6 |
Binary |
|
Store binary data |
|
7 |
Set |
|
Unordered unique values (set is mutable, frozenset is immutable) |
|
8 |
Mapping |
|
Key-value pairs for flexible data structure |
In the examples below, we look at some examples of data types.
2.1.6.1. Numbers#
Python has three numeric types:
integer = 42 # integer (natural number)
floating = 3.14 # floating-point number (real number)
complex_num = 3 + 4j # complex number
print(f"Integer: {integer}")
print(f"Floating-point number: {floating}")
print(f"Complex number: {complex_num}")
Integer: 42
Floating-point number: 3.14
Complex number: (3+4j)
2.1.6.2. Strings (Text Data)#
Strings represent text (character sequences) and are created using quotes. Strings can be created using single or double quotes. You can also wrap a single quote in double quotes if you need to include a quote within the string.
name1 = "Alice"
name2 = 'Alice'
name3 = """Alice"""
print(name1, name2, name3)
Alice Alice Alice
Common string operations include:
Concatenation:
"Hello" + " " + "World"→"Hello World"Repetition:
"Ha" * 3→"HaHaHa". The multiplication (*) operator also works with strings; it makes multiple copies of a string and concatenates them.Length:
len("Python")→6. Python provides a useful function calledlenthat computes the length of a string. Notice thatlencounts the letters between the quotes, but not the quotes. In collection types,lencounts the number of elements in the collection.Indexing:
"Python"[0]→"P"Slicing:
"Python"[0:3]→"Pyt"
name = "Alice"
greeting = "Hello, " + name + "!" ### 1. concatenation
print("1.", greeting)
print("2.", greeting * 3) ### 2. repetition
print(f"3. Length: {len(name)}") ### 3. length + f-string
print(f"4. First letter: {name[0]}") ### 4. indexing + f-string
print(f"5. First three letters: {name[0:3]}") ### 5. slicing + f-string
1. Hello, Alice!
2. Hello, Alice!Hello, Alice!Hello, Alice!
3. Length: 5
4. First letter: A
5. First three letters: Ali
2.1.6.3. Boolean Values#
Booleans represent truth values and are used extensively in conditional comparisons and logical expressions, which involve comparison/relational operators and logical operators.
3 > 5 ### relational
False
2 > 1 and 3 > 2 ### logical
True
num1, num2, num3, num4 = 1, 2, 3, 4
if (num1 > num2): ### comparison operator ">"
print("num1 is greater than num2.")
else:
print("num1 is not greator than num2.")
num1 is not greator than num2.
num1 > num2 and num3 > num4 ### logical opeartor "and"
False
2.1.6.3.1. Truthy and Falsy#
In Python, every object has a truth value in Boolean contexts like if and while. “Truthy” values behave like True, while “falsy” values behave like False — empty containers and zero are falsy; most non-empty values are truthy.
Falsy:
False,None,0,0.0,'',[],{},set()Truthy: most other values (e.g.,
'0',[0]).Quick check:
bool(value); idiom:if not items:checks emptiness.
### truthy/falsy examples
print(bool(0)) # False
print(bool('')) # False
print(bool('0')) # True
print(bool([0])) # True
False
False
True
True
2.1.7. Data Structures#
Python’s data structure are the built‑in container types you use to store, organize, and operate on groups of items/values. The four main data structure types are: list, tuple, dictionary, and set.
The commonly used built-in/standard data structures can be grouped as:
Sequence Types
Set Types
Mapping Types
Collections (broad category)
├── Sequence Types (ordered, indexed)
│ ├── list
│ ├── tuple
│ ├── str (string)
│ ├── range
│ └── bytes/bytearray
│
├── Set Types (unordered, no duplicates)
│ ├── set
│ └── frozenset
│
└── Mapping Types (key-value pairs)
└── dict
Among them, list, tuple, and range are sequence types. Also, strings are considered a sequence type (a kind of collection) because they behave like collections of characters, although conceptually, in many languages other than Python, strings are considered primitives, not collections.
range is debatable as a “collection”; it’s really a lazy sequence generator, not a traditional data structure. It does like a sequence, so Python treats it as one. Note that range stores a formula, not data; it computes values on demand. Therefore, range is a sequence protocol implementer, not a data container.
A set object is an “unordered collection of distinct hashable objects. Common uses include membership testing, removing duplicates from a sequence, and computing mathematical operations such as intersection, union, difference, and symmetric difference” [cite:pPython Standard Library_2026].
Mapping in Python refers to data types that store key-value pairs, where each key is associated with a corresponding value. The most common mapping type is the dictionary (dict).
Mutability and order are two important characteristics of Python data structures, summarized in the table below.
Type |
Literal |
|
Ordered |
Usage |
|---|---|---|---|---|
Sequence Types |
||||
list |
|
Yes |
Yes |
General purpose; dynamic arrays; index/slice access. |
tuple |
|
No |
Yes |
Fixed records; function returns; hashable if elements are.* |
range |
|
No |
Yes |
Memory-efficient integer sequences; iteration. |
str |
|
No |
Yes |
Text; immutable character sequences. |
Set Types |
||||
set |
|
Yes |
No |
Unique items; membership testing; set operations. |
frozenset |
|
No |
No |
Immutable set; dict keys; set elements. |
Mapping Types |
||||
dict |
|
Yes |
Yes** |
Key-value lookups; counting; grouping; configuration. |
Notes:
* Tuples are hashable only if all elements are hashable.
** Dict ordering guaranteed in Python 3.7+.
Python data collections let you:
model data naturally (ordered records, lookup tables, unique elements),
support iteration and common algorithms,
use methods for adding, removing, searching, and
transforming data.
2.1.7.1. Lists (Ordered Collections)#
Lists store multiple items in order and are mutable (can be changed):
numbers = [1, 2, 3, 4, 5]
fruits = ["Apple", "Banana", "Cherry"]
mixed = [1, "hello", 3.14, True]
empty_list = []
print(f"Numbers: {numbers}")
print(f"Fruits: {fruits}")
print(f"Mixed: {mixed}")
print(f"Empty list: {empty_list}")
Numbers: [1, 2, 3, 4, 5]
Fruits: ['Apple', 'Banana', 'Cherry']
Mixed: [1, 'hello', 3.14, True]
Empty list: []
Common list operations:
Append:
numbers.append(6)→[1, 2, 3, 4, 5, 6]Access/Indexing:
numbers[0]→1Slicing:
numbers[1:3]→[2, 3]Length:
len(numbers)→5
fruits = ["apple", "banana", "cherry"] ### create a list by assignment
print(f"\nOriginal list: {fruits}")
fruits.append("date") ### mutable: update/change the list
print(f"After append: {fruits}")
print(f"First fruit: {fruits[0]}") ### indexing
print(f"Number of fruits: {len(fruits)}") ### length
Original list: ['apple', 'banana', 'cherry']
After append: ['apple', 'banana', 'cherry', 'date']
First fruit: apple
Number of fruits: 4
fruits[2] = "cranberry" ### lists are mutable: modify an element
print(f"After modification: {fruits}")
After modification: ['apple', 'banana', 'cranberry', 'date']
2.1.7.2. Tuples (Immutable Sequences)#
Tuples are similar to lists, but they cannot be changed after creation (immutable). So, use tuples when you want to ensure data won’t change:
rgb_color = (255, 128, 0) single = (42,) # Note the comma for single-item tuple
fruits = tuple(fruits)
print(f"\nConverted to tuple: {fruits}") ### ( )
print("first element in coordinate: ", fruits[0]) ### indexing
Converted to tuple: ('apple', 'banana', 'cranberry', 'date')
first element in coordinate: apple
Since tuples are immutable, the following operation would generate an error:
%%expect TypeError
fruits[2] = "cherry" # This would cause an error because tuples are immutable!
TypeError: 'tuple' object does not support item assignment
2.1.7.3. Dictionaries (Key-Value Pairs)#
In Python, a mapping type is a collection that stores data as key–value pairs, where each key is unique and maps to a corresponding value. The most common mapping type is the dictionary (dict), which allows flexible data organization and fast lookup, insertion, and modification of values by key rather than numerical index. An example of a Python dictionary:
student = {
"name": "Alice",
"age": 20,
"major": "IST"
}
student
{'name': 'Alice', 'age': 20, 'major': 'IST'}
Common dictionary operations:
Access:
student["name"]→"Alice"Add/Update:
student["gpa"] = 3.8Keys:
student.keys()→dict_keys(['name', 'age', 'major'])Values:
student.values()→dict_values(['Alice', 20, 'Computer Science'])
print(f"Student Name: {student['name']}") ### 1. access value by key
student["major"] = "CS" ### 2. update: MUTABLE
student["GPA"] = 3.5 ### 2. add new key-value pair: MUTABLE
print(f"student: {student}")
print(student.keys()) ### 3. keys
print(student.values()) ### 4. values
Student Name: Alice
student: {'name': 'Alice', 'age': 20, 'major': 'CS', 'GPA': 3.5}
dict_keys(['name', 'age', 'major', 'GPA'])
dict_values(['Alice', 20, 'CS', 3.5])
2.1.8. Modules and Packages#
In Python, functions, classes, modules, packages, and libraries are essential tools for organizing and reusing code:
A function is a named block of code that performs a specific task and can be called whenever needed.
A class is a blueprint for creating objects that encapsulate data and behavior (methods/functions) together, supporting object-oriented programming.
Modules are files containing Python code—such as functions, classes, or variables—that can be imported into other programs.
Packages are collections of modules organized in directories, making it easier to structure larger projects.
Libraries are collections of related modules and packages that provide ready-to-use solutions for common programming tasks, such as data analysis, web development, or scientific computing.
Together, these components help make Python code more organized, efficient, and maintainable.
Note that a module is a single Python file (e.g., calc.py) and a Package: a directory/folder containing modules (optionally with __init__.py). So:
Module: a single Python file (e.g.,
mymodule.py).Package: a directory of modules (optionally with
__init__.py).
Import patterns (when to use):
import math→ usemath.sqrt(25); clear, namespaced imports.from math import sqrt→ usesqrt(25); convenient but use sparingly for readability.import math as m→ usem.pi; alias for brevity (common with large libs).
Installing external packages (Notebooks):
Use
%pip install package_nameto install into the active kernel; if imports fail, restart the kernel.For projects, prefer a virtual environment (e.g.,
python -m venv .venv) activated.
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.
Common data-science aliases (for later chapters): numpy as np, pandas as pd, matplotlib.pyplot as plt.
Python has about 300 built-in modules as part of the standard library that are shipped with Python. For those modules, you just import and use them (e.g., import math). There are different ways of importing:
Import Pattern |
Example Code |
Usage Example |
Description |
|---|---|---|---|
Standard import |
|
|
Clear, namespaced imports |
Selective import |
|
|
Convenient, but use sparingly for readability |
Import all (not recommended) |
|
|
Imports all names; can cause name conflicts and is discouraged |
Aliased import |
|
|
Alias for brevity (common with large libs) |
To use a variable/attribute in a module, you have to use the dot operator (.) between the name of the module and the name of the variable. For example, the Python math module provides a variable called pi that contains the value of the mathematical constant denoted \(\pi\). We can display its value like math.pi:
import math
math.sqrt(25) ### dot operator
5.0
External Package Notes
Python external (third-party) modules created by the community. You must use pip to install them first (e.g., notebook, NumPy, pandas, …), then import them to use. Most software on the Python Package Index (PyPI; https://pypi.org, where pip accesses 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 achieve the same:
%pip install [package_name]
For example, NumPy (numeric Python) is a popular package for data science and we can install it from inside Jupyter Notebook:
%pip install numpy
Requirement already satisfied: numpy in /home/tychen/workspace/dsm/.venv/lib/python3.10/site-packages (2.2.6)
Note: you may need to restart the kernel to use updated packages.
If you have installed the package already, you would want to comment it out:
# %pip install numpy
2.1.2. 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; and 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.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 = 8might be clear without a comment, butv = 8 # velocity in miles per hourmight be more readable in a mathematical formula.