To program, whatever the language we use, we need to be able to:
Those concepts are fundamental and universal!
A programming language relies on three essential elements:
From Structure and Interpretation of Computer Programs, see bibliography
We can use the Python interpreter in interactive mode, called a REPL (Read Eval Print Loop)
In the terminal, type python to open
the REPL or open the
Python Console directly on PyCharm:
python
Python 3.11.2 (main, May 12 2026, 05:17:27) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 2
2
>>> helpUse Ctr+d to close the REPL.
The REPL is a powerful development tool to quickly test some code and ideas!
Python provides ways to manipulate values of different types. We speak of data types.
You can inspect the type of a value using the
type(<value>) function:
# Type in the Python Console:
42 # Integer
1.5 # Floating-point number (decimal)
-50.05
"a" # String
"The quick brown fox jumps over the lazy dog" # String
True #Boolean
False
# Inspect data types
type('a') # str
type("The quick brown fox jumps over the lazy dog") # str
type(1.5) # float
type(42) # int
type(True) # bool#: a comment is text
ignored by the interpreter#This is a one line comment. Comments are ignored by the interpreter!
x=2
#We can use 'one line comment' syntax
#to write comments on several lines.
42 # The rest of this line is a comment now
"""
This
is
a
block comment
spanning several lines
"""See the shortcut to comment and uncomment multiple lines of code easily in PyCharm (really useful!)
Python provides primitive procedures called operators such as addition(+), subtraction(-), multiplication(*), division (/), integer division (//), modulo(%), power(**), etc.
# Type in the console
1.5 + 42
+42
42 * 42
5+-21
1 / 5
1 // 5
13 // 3
1e6 + 1
5E2
(1+2)*3
2**8 # power operator
(0+1j)**2 # Complex numbersHere, the addition operation is encoded by the
+character. I don’t need to know how the addition is performed (low level details). This primitive (built-in) procedure called+is provided by Python; I only need to know what it does (adds two numbers) and how to use it.
An expression is a combination of values, variables, constants, operators, and functions that is evaluated to produce a new value.
For example, a + b * 2 * math.sqrt(5),
7 % (5 / 2) and n > 0 ? a : b are
expressions.
Variables are a necessary mean of abstraction at our disposal.
Natural language is itself a form of abstraction: naming things enables us to discuss and reason about them, without having to specify every single detail.
A variable allows you to:
In Python, you do not need to declare a variable. A
variable is created the moment you first assign
a value to it, with the assignment operator
=:
x = 5
player1 = "John"
#Variable names are case-sensitive!
Player1 = "Jane"
print(player1, Player1)You can reassign a value to an existing variable, of a completely different type, at any point in its lifecycle (end of the program for a global variable) :
x = 5
x = 12.5
x = "some text"
x = [1, 2, 3] # a list of valuesSimilar to erasing what we wrote on our piece of paper to write a new thing
const keyword (unlike C).ALL_CAPS_WITH_UNDERSCORES),#We declare constants with uppercase letters
PI = 3.14
MAX_TEMPERATURE_CELSIUS=100There are ways to enforce constant values at runtime or during static analysis in Python, but they require more advanced concepts that we will explore later.
A variable name is an expression and can be evaluated.
>>> a=42
>>> a
42
>>> a + 5 # a is evaluated to 42, 42 + 5 is then evaluated
47In the REPL, you can evaluate a variable by typing its name directly
Assignment operators (==,
+=, -=, etc.) are special
because they perform an action: they change the
memory.
In most programming languages (including Python), the assignment
operator (=) does not have the same meaning as in
mathematics.
When we write x = 2, we say that we assign the
value 2 to x. In mathematics, x = 2 means that
x is identical to 2. In programming, you will often
encounter the statement x = x + 1, which does not exists
and has no meaning in mathematics! It means that we assign a
new value to x equal to its previous value plus
one.
x = 1
x = x + 1
print(x)x = 1
y = x # x is evaluated to 1, 1 is assigned to y
print(x, y)
x = 2
print(x, y)
x += 2 # short to x = x + 2, x stores the value 4
y *= x # short to y = y * x
print(y)A-z,
0-9, and _ )age, Age and AGE are three
different variables!)if, not, None, etc.)myvar = "Jane"
my_var = "Jane"
_my_var = "Jane"
myVar = "Jane"
MYVAR = "Jane"
myvar4 = "Jane"1myvar = "Jane"
my-var = "Jane"
my var = "Jane"
myv$r = "Jane"Variable names with more than one word can be difficult to read. There are several techniques you can use to make them more readable (camelCase, PascalCase, kebab-case, snake_case, etc.).
We will use snake_case format (see naming conventions section):
my_variable_name = "John"Values (and thus variables holding values) has types.
Why do we need a type system?
42 + 'a' # Can I add a string and an integer?
12 * 'a' # Can I multiply strings?
'aaa' / 3 # What does it mean to divide a string? Is it meaningful?For every expression, what should happen?
The type of an object (i.e, a piece of data manipulated in the program) determines:
In lower-level languages like C, types define how much memory to allocate and how to interpret the binary data
In Python, the built-in data types fall into these primary families:
int) and
Booleans (bool, which are a subtype of
int)float) and
Complex numbers (complex)str)#integers
12
16//3
#float
0.52
1/3
#complex numbers
1+5j
(1+1j)*(1-1j)
#Strings
"hello, world"
'some text'1/2
1//2
1 % 2
4 % 2//): Keeps only the integer part of
the division. The result is an integer. (2//3 is
asking how many times there is 3 in 2? 0)%): The modulus (i.e. the
result of the modulo operation) is the remainder of integer
division
(,
is the modulus)You spend your time comparing things in life!
1 == 1 # is equal to
2 > 3 # is greater than
1 + 5 < 9 # is lower than
2 != 3 # is not equal to, is different from
1.5 > 2
100 + 100 >= 200 # is greater or equal to
True == True
1 == True
2 == True
0 == False
8 % 2 == 0 # this is the definition of even number
9 % 2 == 1Expressions evaluated to
TrueorFalseare special expressions, also called predicates.
price_euros = 1000
my_budget = 1200
is_affordable = my_budget > price_euros
print(is_affordable)A statement (instruction) in Python is a line that executes an action or specifies an operation to perform:
price_euros = 1000 # statement: assign 1000 to price_euros
my_budget = 1200 # statement: assign 1200 to price_euros
is_affordable = my_budget > price_euros # statement: comparison and assignment
print(is_affordable) # statement: print on the outputprice_euros = 1000 # 1 |
my_budget = 1200 # 2 |
is_affordable = my_budget > price_euros # 3 |
# |
print(is_affordable) # 4 v timeprice_euros = 1000
my_budget = 1200
# Compare
is_affordable = my_budget > price_euros
# Decision (branching)
if(is_affordable):
# Executed only if is_affordable is 'True'
print("I can afford that!")
print("Let's buy it!")
print("End of the shopping")Change my_budget to 500. What happens?
Why?
price_euros = 1000
my_budget = 500
# Compare
is_affordable = my_budget > price_euros
# Decision (branching)
if(is_affordable):
print("I can afford that!")
print("Let's buy it!")
else:
# Executed only if is_affordable is False
print("Maybe another time...")
print("End of the shopping")We have seen previously that Python is a dynamically typed language.
That means Python infers the type of objects based on the value assigned to them at runtime.
#my_variable stores an int
my_variable = 5
my_variable = "my_variable stores now some random text"
#my_variable stores a float
my_variable = 1/10Unlike statically typed languages like C, C++, or Java, you do not need to explicitly declare variable types before using them.
You can cast (convert) the data type of a
value from one type to another using built-in
conversion functions: int(), str(),
float()
# Python will NOT automatically convert '5' to an int or 10 to a string.
result = "5" + 10 # Raises TypeError: can only concatenate str (not "int") to str
# You must perform explicit type conversion or casting with built-in functions:
result = int("5") + 10 # 15
result = "5" + str(10) # "510"Being strongly typed is helpful to reduce the risk of undesired behaviors and hard to catch bugs!
Use the input(prompt)
function to ask the user for input:
# Prompt and store the user input in the variable 'answer'
answer = input("What is your budget?")
print(answer)What is the type of answer? How to convert it to
integer?
String variables can be declared either by using single or double quotes:
x = "John"
# is the same as
x = 'John'
# Double quotes allow single quotes inside, and single quotes allow double quotes inside.
x = "He is called 'Johnny'"
x = 'He is called "Johnny"'Escape sequences in string literals are interpreted according to rules similar to those used by Standard C (and typewriters!)
#\n for newline feed (useful!)
print("A\nB\nC")
#\t for horizontal tabulation
print("A\tB\tC")
#\r carriage return
print("AB\rC")multiline_str="""This is a
multiline
string"""
another_multiline_str='''this is
also
a multiline
string'''
print(multiline_str)Wait…But this is a multiline comment? Python will ignore string literals that are not assigned to a variable, that’s why you can add a multiline string (triple quotes) in your code, and place your comment inside it
a = "And now, "
b = "for something completely "
msg = a + " "+ b + 'different'
print(msg)F-String was introduced in Python 3.6, and is now the preferred way of formatting strings.
To specify a string as an f-string, simply put an
f in front of the string literal (prefix), and add
curly brackets {} as placeholders
for variables and other operations.
char="A"
formatted_string=f"Your are looking for the letter {char}"
print(formatted_string)
a=2
b=3
print(f"a+b={a+b}")
price = 42
txt = f"The price is {price:.2f} dollars" #format the price with 2 decimal digits
print(txt)There are several prefixes available to influence the content of the string
The escape character (\) allows you to use
“escape” special characters in strings (suppressing
their standard interpretation):
quote = "He said, \"Python is great!\""
print(quote)
txt = "We are the so-called \"Vikings\" from the north. Isn\'t it amazing?"
print(txt)
path="\\Some\\Path\\On\\Windows"
print(path)Note: in the REPL, evaluating a variable show you the complete structure of the variable (debug), similar to use the function repr(). It does not give you the same result as using the print() function
None, the absence of
value #None is a built-in literal representing the
intentional absence of a value.
data = None
print(data)
print(type(data))Useful to indicate missing data, uninitialized state, or search failure.
Every language has an equivalent to
None: void*, null, nil, etc.
Operators specify what can be done with variables and values.
We already have seen a few of them (=, +,
*, ==, !=, >,
etc.)
Python features a wide variety of operators. They can be categorized by their nature:
and, or,
notis, is not, in,
not inBecause the assignment operator is special (it modifies memory), its left operand is subject to certain restrictions. We use the term lvalue (“left” value) to designate this special operand.
obj.attr), item
lookup (x[0])n = 5 # n IS a lvalue
n = b + 3; # n IS a lvalue
5 = x # 5 IS NOT a lvalue. SyntaxError: cannot assign to literal here
n + 1 = b + 3 # n + 1 IS NOT a lvalueand |
True | False |
|---|---|---|
| True | True | False |
| False | False | False |
or |
True | False |
|---|---|---|
| True | True | True |
| False | True | False |
not |
|
|---|---|
| True | False |
| False | True |
# Gives the value of each expression
True and True
True and False
False or False
False or True
False or False
True or (not False)
True and (True and not True)# What is the value of a?
a = 5 / 2 + 3 * 3;
# What are the value of a and b?
b = a = 5 * 2;
# What is the value of c?
c = True or False and False
# What is the value of d?
d = not 1 == 2
# What is the value of e?
e = (not 1) == 2How to read and use precedence table:
Priority
^
| Arithmetic
| Relational(Comparison)
| Logical
| Assignment
True for (almost) all programming languages !
Solve:
from the Problem Sheet
Python offers 4 different built-in data types to store collection or combination of data, called data structures:
Each data type has its own usage and properties. Let see some basic properties of each one.
Values can be organized into collections called lists in Python.
A list of values is declared using square brackets
([]), with each element separated by a
comma(,):
#A 'list'
numbers = [1, 2, 3, 4, 5]
#A 'list' can contain values of different types (heterogenous)
items = [-1, 42, "Jane Doe", ['A', 'B', 'C'], 12 / 5 ]Lists look like arrays in other programming languages (JavaScript, C, etc.)
#index: 0 1 2
names = ["john", "jane", "charlie"]You can access any element by specifying its position using square brackets:
items = [-1, "Jane Doe", ['A', 'B', 'C'], 12/5]
# Each item is indexed and accessible by its index (from 0 to length-1)
print(items[0])
print(items[1])
print(items[2])
print(items[3])
print(items[4]) # What happens ? IndexError: list index out of range
print(items[-1]) # -1 refers to the last item
print(items[-2]) # -2 refers to the second last itemYou can count how many elements are in a list with the
built-in len() function:
items = [-1, "Jane Doe", ['A', 'B', 'C'], 12/5]
nb_items = len(items)
print(f"There are {nb_items} in the collection")
msg="Does it work on a string?"
print(len(msg))strings share properties with lists, they are iterable data structures!
An iterable data structure (or simply an iterable) is any data collection that allows you to step through its items one by one, typically inside a for loop.
A for loop allows you to go through a list and process each item, one by one:
numbers = [0, 1, 2, 3, 4]
# In each pass, the variable 'n' holds the current number from the list
for n in numbers:
print(n)
# Output:
# 0
# 1
# 2
# 3
# 4Because strings are iterable, we can do the same thing with strings and visit each character, one by one:
message = "hello, world!"
for char in message:
print(char)
# Output:
# h
# e
# l
# l
# o
# ,
#
# w
# o
# r
# l
# d
# !colors = ['orange', 'blue', 'green', 'orange']
# Change the first item
colors[0] = 'red'
# Change the second item
colors[1] = 'yellow'
print(colors)
colors[10] = 'black' # Will this work ?Strings share many properties with lists: they are a collection of unicode characters, they are iterable but, unlike lists, strings are immutable! (you can not change the content of a string!)
print(len('été')) # 3
name="John"
print(name[0]) # J
print(name[1]) # o
name[0]="j" #TypeError: 'str' object does not support item assignmentprint(), a
method belongs to a specific data type and is
called directly on the variable using the dot operator
(.):colors = ['orange', 'blue', 'green', 'orange']
# Lists offer a method 'append(value)' to add an item at the end
colors.append('yellow')
print(colors)Each datatype offer several methods to perform some common and useful operations on the data! Check the string methods
list.insert(index, value) add an element at a desired
index (position)list.extend(list) append elements from another list to
the current list# Insert an element at some desired index/position:
colors.insert(1, 'red')
# Append elements from another list to the current list
my_favorite_colors = ['cyan', 'gray']
colors.extend(my_favorite_colors)
print(colors)list.remove(value) removes the first item from
the list whose value is equal to value.
numbers = [1, 2, 3, 2]
numbers.remove(2)
print(numbers)list.reverse() reverse the elements of the list in
place.
numbers = [1, 2, 3, 4]
numbers.reverse()
print(numbers)Lean more on methods available for lists by scheming the documentation. When programming, you spend much more time reading (documentation, code) than writing
Consider this list:
names = ["Lamport", "Von Neumann", "Abelson", "Van Rossum", "Ritchie", "Thompson"]last_itemnames with its original
list of names.names = ["Lamport", "Von Neumann", "Abelson", "Van Rossum", "Ritchie", "Thompson"]
# 1.
for name in names:
print(name)
# 2. Discover and test list methods
idx = names.index("Van Rossum") # 1. Find index
names.sort() # 2. Sort items
last_item = names.pop() # 3. Remove last item
names.clear() # 4. Remove all items
# 3. Reset
names = ["Lamport", "Von Neumann", "Abelson", "Van Rossum", "Ritchie", "Thompson"]
# 4. Loop with Index
for i in range(len(names)):
print(f"{i}: {names[i]}")
# OR
for name in names:
print(f"{names.index(name)}: {name}")Make a list of the numbers from one to one
million (excluded), and then use min() and
max() to make sure your list actually starts at one and
ends at one million. Also, use the sum() function to see
how quickly Python can add a million numbers.
Use the third argument of the range() function to
make a list of the odd numbers, from 1 to 20
(excluded). Use a for loop to print each
number.
Make a list of the multiples of 3 from 3 to 30 (included). Use a for loop to print the numbers in your list.
From
# 1.
numbers = list(range(1, int(1E6)))
print(min(numbers))
print(max(numbers))
print(sum(numbers))
# 2.
odds = list(range(1, 20, 2))
for odd in odds:
print(odd)
# 3.
threes = list(range(3, 31, 3))
for t in threes:
print(t)You can create a new list by slicing an existing one. To slice a list, specify a start index (included) and an end index (excluded).
The result will be a new list with the specified items.
# Syntax
list_name[start: end: step][start:end): Python follows the “closed open interval” principle. If omitted,
startdefaults to 0,enddefaults to the length of the list (one past the last item)
Slicing works also on strings!
colors = ['red', 'blue', 'green', 'yellow']
# Slice 'all' (start and end omitted)
print(colors[:]) # ['red', 'blue', 'green', 'yellow']
print(colors[1:]) # ['blue', 'green', 'yellow']
print(colors[:2]) # ['red', 'blue']
print(colors[1:3]) # ['blue', 'green']
print(colors[-2:]) # ['blue', 'green', 'yellow']
print(colors[-3:-1]) # ['blue', 'green']
# Reverse the list (negative step)
print(colors[::-1]) # ['yellow', 'green', 'blue', 'red']Positive step (1, 2, etc.) steps forward (left to right). Negative step (-1, -2, etc.) steps backward (right to left)
When slicing with a negative step, the reading direction reverses (from right to left)
Which result gives the following slice:
items[-3:-5:-1]?
items = [0, 10, 20, 30, 40, 50]
# index : 0 1 2 3 4 5
print(items[::-1]) # [50, 40, 30, 20, 10, 0], reversed list!
print(items[:2:-1]) # [50, 40, 30]
print(items[4:2:-1]) # [40, 30]
print(items[1::-1]) # [10, 0]
print(items[3:1:-1]) # [30, 20]Note: You can’t get circular wrapping with slicing only, e.g
[10, 0, 50, 40]fromitems
Consider the following list representing temperature readings (in celsius) throughout a week:
temperatures = [18, 21, 19, 24, 22, 20, 25]
# Index: 0 1 2 3 4 5 6
# Days: Mon Tue Wed Thu Fri Sat SunUse list slicing, to create the following lists:
[18, 21, 19, 24, 22])[20, 25]).[19, 24]).Consider this list representing daily sales amounts (in dollars) over a 10-day period:
sales = [120, 85, 200, 150, 90, 300, 400, 110, 95, 250]
# Days: 1 2 3 4 5 6 7 8 9 10[300, 400, 110]).[250, 95, 110, 400]).temperatures = [18, 21, 19, 24, 22, 20, 25]
weekdays = temperatures[0:5] # Output: [18, 21, 19, 24, 22]
weekend = temperatures[5:7] # Output: [20, 25]
mid_week = temperatures[2:4] # Output: [19, 24]sales = [120, 85, 200, 150, 90, 300, 400, 110, 95, 250]
# 1. Total sales for the first 5 days
first_half = sales[:5]
# 2.
total_first_half = 0
for amount in first_half:
total_first_half += amount
print(f"Total sales (Days 1-5): ${total_first_half}")
# 3. High sales in days 6 to 8
peak_days = sales[5:8]
# 4.
for amount in peak_days:
if amount > 150:
print(f"High sales amount: ${amount}")
# Output:
# High sales amount: $300
# High sales amount: $400
# 5. Average amount sales
average_sales=0
for amount in first_half:
average_sales += amount
average_sales /= len(sales)
print(f"Average sales: ${average_sales:.2f}")
#6. Reversed list of the last 4 days
print(sales[9:5:-1])
# OR
print(sales[:5:-1]) #we start at the end, until 5th position
# OR
print(sales[-1:-5:-1])A tuple is an immutable collection. Once defined, you can not change a tuple. It is defined with parenthesis:
# A tuple
vowels = ('a','e','i','o','u','y')
# Alternative syntax
some_tuple = "apple", "banana", "cherry"
# Tuple are ordered collections like lists, each element can be accessed via its index
print(some_tuple, some_tuple[0], some_tuple[1])Tuple unpacking allows you to extract elements from a tuple directly into individual variables in a single line.
# We want to extract data in x and y variables
point = (10, 20)
# With manual indexing
x = point[0]
y = point[1]
# Withe tuple unpacking
x, y = point # or (x, y) = point
print(x, y)Given the following two coordinate pairs represented as tuples:
# Format: (latitude, longitude)
paris = (48.8566, 2.3522)
lyon = (45.7640, 4.8357)[]), then
print them.48.9000. Observe what happens when you run
the code.paris = (48.8566, 2.3522)
lyon = (45.7640, 4.8357)
# 1. Accessing elements by index
lat_paris = paris[0]
lon_paris = paris[1]
print(f"Paris -> Latitude: {lat_paris}, Longitude: {lon_paris}")
# 2. Tuple Unpacking
lat_lyon, lon_lyon = lyon
print(f"Lyon -> Latitude: {lat_lyon}, Longitude: {lon_lyon}")
# 3. Immutability Check
# Try attempting to reassign a tuple element:
# paris[0] = 48.9000
# Raises TypeError: 'tuple' object does not support item assignmentDictionaries are used to store data values in key:value pairs.
Dictionaries are among Python’s most common and versatile data structures:
Dictionaries are written with curly brackets({}), and
have keys/values, separated by commas:
car = {
#key #value
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
print(car)Dictionaries are iterable, mutable and do not allow duplicates (can’t have two identical keys in a dictionary!).
Dictionary items are ordered.
Similar to struct in C, Object in JavaScript, Arrays in PHP, etc.
Any data type that is immutable can be used as a dictionary key: strings, numbers, booleans, tuples
# Valid dictionary with mixed key types:
data = {
"name": "Jane", # String key
101: "Admin User", # Integer key
(48.85, 2.35): "Paris" # Tuple key (coordinates)
}
print(data[101]) # Output: Admin User
print(data[(48.85, 2.35)]) # Output: ParisString keys are by far the most common
car = {
#key #value
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
# Access a value by key
print(car['brand'])
# Change a value under a key
car['brand'] = 'Peugeot'
# Add a key/value
car['color'] = 'Black'
print(car)
# Add a key/value using the method update()
car.update({"color": "red"})
print(car)Removing a key from a dictionary removes the associated value.
car = {
#key #value
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
# Remove the 'model' key with the pop() method
car.pop('model')
print(car)Like lists or strings, you can loop through a dictionary by using a for loop: dictionaries are iterable!
When looping through a dictionary, the return value are the keys of the dictionary, but there are methods to return the values as well.
car = {
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
for x in car:
print(x) # will print brand, model and year
# Or with keys() method
for x in car.keys():
print(x) # With square bracket notation
for x in car:
print(car[x])
# With values() method
for x in car.values():
print(x) #items() return a collection of each key/value represented as a tuple
for key, value in car.items():
print(key, value)
# OR, with parenthesis (tuple notation)
for (key, value) in car.items():
print(key, value) Create a dictionary and stores in
customer_a to model a customer. A customer is
defined by four keys or fields:
first_name (“Jane”)last_name (“Doe”)email (“j.doe@email.com”)total_purchases: (150.00)Jane made another purchase of $50.00. Update
total_purchases to 200.00.
Add a new key-value pair “is_vip” with
the boolean value True
Print the customer’s full name using string formatting (“Jane Doe”).
Remove the “email” key from
customer_a
# 1. Creation
customer_a = {
"first_name": "Jane",
"last_name": "Doe",
"email": "jane.doe@example.com",
"total_purchases": 150.00
}
# 2. Updates
customer_a["total_purchases"] = 200.00 # Modify existing key
# 3. Add key/value pair
customer_a["is_vip"] = True # Add new key
# 4. Access
full_name = f"{customer_a['first_name']} {customer_a['last_name']}"
print(f"Customer Name: {full_name}")
# 5. Remove
customer_a.pop("email")
print(customer_a)Given the following list of daily temperature recordings (celsius):
temperatures = [
{"date": "2026-03-01", "temperature": 12.5},
{"date": "2026-03-02", "temperature": 14.0},
{"date": "2026-03-03", "temperature": 9.8},
{"date": "2026-03-04", "temperature": 20.2},
{"date": "2026-03-05", "temperature": 15.1},
{"date": "2026-03-06", "temperature": 11.4},
]from datetime import datetime
temperatures = [
{"date": "2026-03-01", "temperature": 12.5},
{"date": "2026-03-02", "temperature": 14.0},
{"date": "2026-03-03", "temperature": 9.8},
{"date": "2026-03-04", "temperature": 20.2},
{"date": "2026-03-05", "temperature": 15.1},
{"date": "2026-03-06", "temperature": 11.4},
]
total_temp = 0
for item in temperatures:
total_temp += item["temperature"]
avg_temp = total_temp / len(temperatures)
print(f"Average temperature: {avg_temp:.2f}°C")
max_temp = temperatures[0]["temperature"]
hottest_date = temperatures[0]["date"]
for item in temperatures:
if item["temperature"] > max_temp:
max_temp = item["temperature"]
hottest_date = item["date"]
print(f"Max temperature: {max_temp}°C")
print(f"Hottest day: {hottest_date}")
date_obj = datetime.strptime(hottest_date, "%Y-%m-%d")
formatted_date = date_obj.strftime("%A, %B %d, %Y")
print(f"Max temperature: {max_temp}°C")
print(f"Hottest day: {formatted_date}")A set is a collection which is unordered (you can’t access values by index!), mutable (add/remove elements) and do not authorize duplicates.
my_set = {1, 2, 2, 3, 4, 5}
print(my_set)
print(len(my_set))It’s the equivalent of a set in the mathematical sense: a collection of different things.
my_set = {1, 2, 2, 3, 4, 5}
my_set.remove(2)
my_set.add(6)
print(my_set)Sets are useful to make… set operations: union, intersection, difference, symmetric difference, etc.
setA={'a','b','c'}
setB={'b','c', 'd'}
# Union
print(setA.union(setB))
print(setA | setB) # union short notation with '|' operator
# Intersection
print(setA.intersection(setB))
print(setA & setB) # intersection short notation with '|' operator
# Difference
print(setA.difference(setB))
print(setB.difference(setA))Each operation returns a new set! Lean more about sets
To write (any interesting!) program you need:
With these two ingredients you can write any program
For example, “this sentence contains six words” is a predicate that evaluates to false. “I think you are wrong” is a statement, but it is not a predicate.
if <condition>:
<instructions>
[else:
<instructions>][…] means it’s optional. else block is optional
number = 15
if number > 0:
print(f"{number} is positive")
else:
print(f"{number} is negative")
# Using 'falsy' values as predicat
if number:
print(f"{number} is not equal to zero")number = 15 # <= 1
if number > 0: # <= 2
print(f"{number} is positive") # <= 3
#Jump to <= 5 <= 4
else:
print(f"{number} is negative") #this is not executed!
x = 5 # <= 5
#...rest of the program <= 6We “jump” from one instruction (or a block) to another one, based on a condition. This is how we control the flow of execution. One program, several execution flows (or paths)
Python relies on indentation (whitespace at the beginning of a line) to define scope in the code (if/else block, function, loop block, etc.)
Other programming languages often use curly-brackets for this purpose.
a = 33
b = 200
# WRONG !
if b > a:
print("b is greater than a") # you will get an error!
print("Next instruction...")
# CORRECT !
if b > a:
print("b is greater than a")
print("Next instruction...")You can use spaces or tabs for indentation, but you must use the same amount of indentation for all statements within the same code block. By convention we will use one tab or 4 spaces.
if
statement).True are called
truthy, values that evaluate to False are called
falsy.Truthy values:
TrueFalsy values:
None, FalsePython will check each condition in order and execute the
first one that is true. You can have as many
elif statements as you need.
score = 75
if score >= 90:
print("Grade: A")
elif score >= 80:
print("Grade: B")
elif score >= 70:
print("Grade: C")
elif score >= 60:
print("Grade: D")
print("End of the program")As you can see,
elsestatement is not mandatory
Multiple if/else statements can be
nested to create an else if structure:
if condition1:
instruction1
elif condition2:
instruction2
else:
instruction3is equivalent to:
if condition1:
instruction1
else:
if condition2:
instruction2
else:
instruction3Notice how the indentation stays at the first level with
elif. Prefer theelifform (easier to read)!
if..else
notation #a = 5
b = 2
# One-line if statement
if a > b: print("a is greater than b")
# One-line if/else statement
print("A") if a > b else print("B") Pattern:
value_if_true if (condition) else value_if_false
a = 5
b = 2
# Assign a value to 'bigger' based on a condition
bigger = a if a > b else b
print(bigger)Shorthand if statements and ternary operators should be used when:
Don’t be “smart”! Be readable!
Remember, be careful to use the == operator to
compare and = to assign !
# Assignment
x = 1
# Comparison
x == 1
if(x = 1): #Error!
print("Oups!")for and while loops are the
fundamental loops in every programming language, including
Python.We use range([start,] stop[,step]) function to generate an iterable sequence of numbers (a ‘range’):
# From 0 (by default) to 5, step defaults to 1
for i in range(5):
#Body of the for loop
print(f'i={i}')
print("Next value please")
# Use the list() function to convert a range to a list
type(range(1:5)
numbers = list(range(1:5))
type(numbers)i is a variable, local to the for
loop, that sequentially takes all the values generated by
range(). The print() statements are,
the body of the loop (indented), repeated for each
value`.
# From 2 to 5, step = 1
for j in range(2, 5):
print(f'j={j}')
# From 2 to 8, step = 2
for k in range(2, 8, 2):
print(f'k={k}')
# From 0 to 10, step = -1
for l in range(0, -10, -1):
print(f'l={l}')Write for loops to produce the following sequences:
2, 3, 4, 50, 2, 4, 60, -1, -2, -3-10, -8, -6, -4, -2, 0Each number will be printed on its own line with the
print()function (no formating is required)
# 1. `2, 3, 4, 5`
for i in range(2,6):
print(i)
# 2. `0, 2, 4, 6`
for i in range(0, 8, 2):
print(i)
# 3. `0, -1, -2, -3`
for i in range(0, -4, -1):
print(i)
# 4. `-10, -8, -6, -4, -2, 0`
for i in range(-10, 1, 2):
print(i)A for loop, as we have already seen, is often used for going through iterables: list, tuple, dictionary, set or string:
# List
colors = ['orange', 'blue', 'green', 'orange']
for color in colors:
print(f'{color}')
# String
word='hello'
for letter in word
print(letter)
# Dictionary
my_animals = {"dog":['Medor', 'Max'], "cat":['Moustique', 'Plume']}
for (key, value) in my_animals.items():
print(key, '=>', value)break and continue ## What will be the result of this program ?
for x in range(6):
if x == 1: continue
if x == 3: break
print(x)
else:
print("Finally finished!")
print("The rest of the program")break: stop and quit the loopcontinue: stop the current iteration and jump to next
iterationelse: block: always executed at the end of the loop
(optional)With the while loop, we can execute a set of statements as long as a condition is true.
while (condition):
body of the loopExample:
i = 1
while i < 6:
print(i)
i+=1Any loop can be written as a for loop or as a while loop: they are functionally equivalent!
i=1
while i<12:
print(i)
i+=1
# Is equivalent to the for loop
for i in range(1, 12):
print(i)While loops are often used when we do not know in advance when the loop will end (e.g. reading bytes from a file), whereas for loops are used when we know beforehand when it will end (e.g. iterating over a finite collection of items).
To manipulate dates and datetimes easily, we need to use a package.
A package (or library) is a reusable and coherent unit of code, created and maintained by other developers, giving some specialized functionality. It contains custom data types, functions, etc.
To use a package, we need to import it in our code. To have
the datetime data type, we have to import the
corresponding package with the keyword import:
# From the 'datetime' package, import the datetime and timedelta data types
from datetime import datetime, timedelta
# Get current date and time
now = datetime.now()
# Format as a string
print("Today:", now.strftime("%Y-%m-%d %H:%M"))
# Date manipulation (add 7 days with timedelta() function)
next_week = now + timedelta(days=7)
print("In 7 days:", next_week.strftime("%Y-%m-%d"))The package
datetimehas already been installed on your machine with the Python interpreter!
import math
import random
print(math.sqrt(2), math.pi)
print(random.randint(1, 10))
datetime,mathandrandomare packages that are part of the Python Standard Library (PSL). They are pre-installed and shipped automatically whenever you install the Python interpreter on your machine. You can see where they are installed on your machine withprint(random.__file__). There is no magic here! We will see code modularity (and how to make our own packages) in details later!
Naming things well is hard in programming (in real projects). It requires practice.
In this course, we will follow PEP 8, the style guide for Python Code:
snake_case)MAX_OVERFLOW and
TOTAL.print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)time.sleep(n_seconds), from time package, to pause
execution for a given amount of secondsimport time
n = input('Enter a positive number: ')
for i in range(0, n)
print(i)
print(1, 2, 3, 4, sep='*', end='=')
vowels=['a','e','i','o','u','y']
'--'.join(vowels)
print("Start waiting...")
time.sleep(1) # Pauses execution for 1 second
print("Done!")See all Python built-in functions and start to learn how to use (navigate) documentation
Now, you should understand every line of this program!
from datetime import datetime
group = {
"Alice": "1995-04-12",
"Bob": "2002-11-23",
"Charlie": "1988-08-05",
}
youngest_name = None
youngest_date = None
for name, date_str in group.items():
# Convert string to datetime object
birth_date = datetime.strptime(date_str, "%Y-%m-%d")
if youngest_date is None or birth_date > youngest_date:
youngest_name = name
youngest_date = birth_date
print(
f"The youngest person is {youngest_name}, born on {youngest_date.strftime('%Y-%m-%d')}."
)poem.my to
print the following string in a specific format (see the output below).
Sample String : “Twinkle, twinkle, little star, How I wonder what you
are! Up above the world so high, Like a diamond in the sky. Twinkle,
twinkle, little star, How I wonder what you are”Twinkle, twinkle, little star,
How I wonder what you are!
Up above the world so high,
Like a diamond in the sky. Twinkle, twinkle, little star,
How I wonder what you arecurrent_datetime.py to display the current date and time.
Output Example:Current date and time:
2026-09-07 14:09:12Hint: use the strftime() method.
From Prof. Karim ZKIK, PhD Materials
geometry.py
that calculates and print the area of a circle based on a given radius.
Sample output:radius=1.1
Area= 3.8013271108436504input_to_datastructures.py that accepts a sequence of
comma-separated integers from the user and generates a
list and a tuple of those numbers. We suppose that the input is
valid (valid format). Sample output:Enter a sequence of comma-separated numbers: 1,2,3,4
List: ['1', '2', '3', '4']
Tuple: ('1', '2', '3', '4')Enter a sequence of comma-separated numbers: 1,-2.3,3,4.5
List: ['1', '-2.3', '3', '4.5']
Tuple: ('1', '-2.3', '3', '4.5')Hint: use str.split() method, tuple() and list() functions.
Start to organize your sources properly on your machine! (directories, naming convention, comments, etc.)
x = 2
y = 3
#Equivalent to
x = 2; y = 3In Python, == is the comparison
operator. It returns True if operands are the same
value, False otherwise.
0.2 == 0.2
True # So far so good!
0.1 + 0.2 == 0.3
False # ... Wait... What?! Why?! Computers are broken!0.1 is
finite. But, in base 2 (binary format), 0.1 is an
infinite sequence of digits!
>>> 0.1 + 0.2
0.30000000000000004Similarly, in base 10 (decimal notation), can not be represented with a finite sequence of numbers (0.33333333333…)!
A raw string is a string literal
prefixed with an r or R
(e.g., r”text”). It tells the Python interpreter to treat backslashes
(\) as literal characters rather than as escape
characters.
# Standard string: \n creates a new line
standard_str = "Line 1\nLine 2"
print(standard_str)
# Raw string: \n is treated as two literal characters '\' and 'n'
raw_str = r"Line 1\nLine 2"
print(raw_str)
# No need to escape every backslash like before
path = r"C:\Users\Name\Documents\notes.txt"
print(path)n = 5 does one thing:
stores the value 5 in the variable n’s
memory location. This assignment is NOT an
expression.n := 5 (with
Walrus Operator :=) does two things:
n’s
memory location;1 == (n=1) #SyntaxError: invalid syntax.
1 == (n:=1) #True: 'n:=1' affects 1 to n AND evaluates to 1