Prerequisites: Complete Seminar 0a (Python Setup from Scratch) before this seminar.
Setup note: Environment setup is fully covered in Seminar 0a; this seminar starts directly with Python basics.
Learning Objectives¶
By the end of this seminar you will be able to:
Understand Python’s core data types:
int,float,str,bool,listanddictUse
print(),input(), and f-strings for I/OApply PEP-8 coding style conventions
Part 1: Theory¶
Note: This is not a Python course — we cover the minimum foundation needed before moving on to algorithmics. If you can already confidently tick all the boxes above, skip to Part 2.
Struggling with Python? That is completely fine. These first three seminars exist to give you that foundation. If you want a video walkthrough alongside this notebook, these free resources cover exactly the same material:
🎥 CS50P Lecture 0 — Functions & Variables (~1.5 hrs — covers
input, f-strings)🎥 CS50P Lecture 1 — Conditionals (~1 hr)
📖 Python official tutorial — introduction — concise written reference
How to use this notebook:
Read the short explanation in each section.
Run the code cell below it with
Shift + Enterand look at the output.Change a value and run it again — this is the fastest way to learn.
Then attempt the exercise for that section.
⚠️ Important — run cells in order, top to bottom. If you skip a cell and see a
NameError, go back and run the cells above first. Each cell can depend on variables defined in earlier cells.Resource: This course loosely follows the Python track on roadmap.sh and the Data Structures & Algorithms track. Feel free to go as deep as you want.
Quick reference: reading the code cells¶
Two things appear in almost every code cell:
Lines starting with
#are comments — Python ignores them completely. They exist only to explain the code to you and later on your code to others.To uncomment a line (make Python run it), simply remove the
#and the space at the start of that line.print(...)displays output below the cell when you run it.
1.1 Variables and Core Data Types¶
Python is dynamically typed: you do not declare a type explicitly — the interpreter infers it from the value.
However, being dynamically typed does not mean Python is permissive about types. Python is also strongly typed: it will never silently convert one type into another for you. If you try to mix incompatible types, Python raises an error immediately — there are no surprises.
Compare this to JavaScript, which is weakly typed and will silently coerce values in ways that often produce unexpected and hard-to-debug results:
// JavaScript (weakly typed) — all of these run without any error:
console.log("5" + 3); // → "53" (number silently converted to string!)
console.log("5" - 3); // → 2 (string silently converted to number!)
console.log(true + true); // → 2 (booleans silently treated as integers!)In Python, the equivalent operations raise a TypeError immediately, making bugs far easier to spot. Run the code cell directly below to see this in action.
Fundamental scalar types in Python¶
| Type | Example | Description |
|---|---|---|
int | 42, -7, 0 | Arbitrary-precision integer |
float | 3.14, -0.001, 1e6 | 64-bit IEEE 754 floating point |
str | 'hello', "world" | Immutable sequence of Unicode characters |
bool | True, False | Subclass of int (True == 1, False == 0) |
list | [1, 2, "hi"] | Mutable ordered sequence of any type |
dict | {"name": "Alex"} | Mutable mapping of key–value pairs |
⭐ Core for today:
int,float,str,bool. Lists (list) and dictionaries (dict) are introduced here for completeness — you will use them heavily from seminar 2 onwards. Don’t worry if they feel unfamiliar right now.
Type coercion and conversion¶
Python does not implicitly convert between types (unlike JavaScript). Use explicit constructors: int(), float(), str(), bool().
Run the second code cell below, then try changing a value (e.g. student_count = 100) and re-run it to see how the output changes.
# ============================================================
# ⭐ CORE — Python is strongly typed
# ============================================================
# These lines raise a TypeError — uncomment them one at a time to see.
# (To uncomment: remove the '#' and the space at the start of the line)
# "5" + 3 # → TypeError: can only concatenate str (not "int") to str
# "5" - 3 # → TypeError: unsupported operand type(s) for -: 'str' and 'int'
# What you must do instead — convert explicitly:
print("5" + str(3)) # → "53" (int converted to str explicitly)
print(int("5") - 3) # → 2 (str converted to int explicitly)
print(int("5") + 3) # → 8
# Python always tracks the type of every variable:
x = 42
y = "hello"
print(f"\ntype(x) = {type(x)}") # <class 'int'>
print(f"type(y) = {type(y)}") # <class 'str'>
# Mixing incompatible types always fails loudly — uncomment to see:
# print(x + y) # → TypeError: unsupported operand type(s) for +: 'int' and 'str'# ============================================================
# ⭐ CORE — run this cell, read the output, then modify values
# ============================================================
# --- Integers ---
student_count = 42 # whole number
negative_temp = -7 # negative integer
print("=== Integers ===")
print(f"student_count = {student_count}, type = {type(student_count)}")
print(f"negative_temp = {negative_temp}")
# --- Floats ---
pi = 3.14159
scientific = 6.022e23 # Avogadro's number (scientific notation)
print("\n=== Floats ===")
print(f"pi = {pi}")
print(f"scientific = {scientific:.3e}") # formatted as scientific notation
# ⚠️ Classic gotcha — float arithmetic is not always exact:
print(f"\n0.1 + 0.2 = {0.1 + 0.2}") # Not 0.3!
print(f"Round fix: {round(0.1 + 0.2, 10)}")
# --- Strings ---
name = "Alice"
city = 'Geneva' # single or double quotes both work
print("\n=== Strings ===")
print(f"name = '{name}', length = {len(name)}")
print(f"Uppercase: {name.upper()}")
print(f"Slicing name[1:3]: {name[1:3]}") # characters at index 1 and 2 → 'li'
# --- Booleans ---
is_enrolled = True
has_submitted = False
print("\n=== Booleans ===")
print(f"is_enrolled = {is_enrolled}")
print(f"bool(0) = {bool(0)}") # 0 is falsy
print(f"bool('') = {bool('')}") # empty string is falsy
print(f"bool('hello') = {bool('hello')}") # non-empty string is truthy
# --- Lists ---
grades = [85, 92, 78, 95]
names = ["Alice", "Bob", "Carol"]
print("\n=== Lists ===")
print(f"grades = {grades}")
print(f"grades[0] = {grades[0]}") # first element (index starts at 0)
print(f"grades[-1] = {grades[-1]}") # last element
grades.append(88)
print(f"after append = {grades}")
print(f"length = {len(grades)}")
# --- Dicts ---
student = {"name": "Alice", "age": 21, "enrolled": True}
print("\n=== Dicts ===")
print(f"student = {student}")
print(f"student['name'] = {student['name']}")
student["grade"] = 92
print(f"after adding key = {student}")
print(f"keys = {list(student.keys())}")
# ============================================================
# 💡 OPTIONAL — other integer formats and curiosities
# ============================================================
# big_number = 1_000_000 # underscores for readability (Python 3.6+)
# in_binary = 0b1010 # binary literal → 10
# in_hex = 0xFF # hexadecimal → 255
# multiline = """This string
# spans multiple lines."""
# Boolean quirk: True is literally the integer 1
# print(f"True + True = {True + True}") # = 2 (legal but unusual)
# print(f"int(True) = {int(True)}") # = 1# ============================================================
# ⭐ CORE — explicit type conversion
# ============================================================
age_str = "21" # This is a string — you cannot do arithmetic on it yet
age_int = int(age_str) # Convert to int
age_float = float(age_str) # Convert to float
print(f"'21' as int: {age_int + 1}") # 22 — now we can do arithmetic
print(f"'21' as float: {age_float}") # 21.0
# type() tells you what type a variable is
x = 42
print(f"\ntype(42): {type(x)}")
print(f"type('hello'): {type('hello')}")
# --- What happens with an invalid conversion? ---
try:
int("hello") # This raises a ValueError — "hello" is not a number
except ValueError as e:
print(f"\nValueError: {e}")
print("You cannot convert a non-numeric string to int!")
# isinstance() checks whether a value belongs to one or more types.
# It is preferred over type() in production code because it also handles
# subclasses (e.g. bool is a subclass of int, so isinstance(True, int) is True).
print(f"\nisinstance(42, (int, float)): {isinstance(x, (int, float))}")
# → True: 42 is an int, and int is one of the types listed1.2 Input and Output¶
print() — output¶
print() is Python’s built-in function for displaying output. It writes text to the console — the terminal window when running a .py file, or the output area below the cell in Jupyter. Every time you want your program to show something to the user, you use print().
print(*objects, sep=' ', end='\n', file=sys.stdout)You can pass multiple values separated by commas, and control how they are joined with
sepand how the line ends withend.
input() — input¶
input() is the counterpart to print(). It displays a prompt message in the console, then pauses the program and waits for the user to type something and press Enter. This is how you build interactive command-line programs where the user provides data at runtime — for example, asking someone for their name or a number to process.
Always returns a string, regardless of what the user types — remember to convert if you need a number.
In Jupyter notebooks,
input()opens an interactive text field below the cell.
f-strings (formatted string literals)¶
Introduced in Python 3.6, f-strings are the modern, readable way to embed expressions inside strings:
name = "Alice"
score = 95.7
print(f"Student {name} scored {score:.1f}%")
# → Student Alice scored 95.7%⭐ Core pattern: prefix a string with
f, then put any variable or expression inside{ }. Add:.2fafter a number to control decimal places. That’s all you need for the exercises.
Format specifiers after : control how values are displayed:
| Specifier | Meaning | Example output |
|---|---|---|
.2f | 2 decimal places (float) | 3.14 |
d | integer | 42 |
e | scientific notation | 6.02e+23 |
>10 | right-align in 10 chars | Alice |
<10 | left-align in 10 chars | Alice |
, | thousands separator | 1,000,000 |
💡 Optional: alignment specifiers (
>,<,^) and zero-padding (03d) are only needed for Exercise 4. Skip them for now and come back when you get there.
Run the code cells below. After the first one, change name and score and re-run.
# ============================================================
# ⭐ CORE — print() and basic f-strings
# ============================================================
# --- print() basics ---
print("Hello, World!")
print("Alice", "Bob", "Carol") # multiple args → joined with a space by default
print("Alice", "Bob", "Carol", sep=" | ") # sep= changes the character between each value
# '\n' is the newline character — it moves output to the next line.
# By default print() adds a '\n' at the end, so each print() starts on a fresh line.
print("Line 1", end=" ") # end="" replaces the default '\n' — no line break here
print("(still on the same line)") # this continues on the same line as "Line 1"
# --- f-strings: the essential pattern ---
name = "Alice"
score = 95.666
print(f"\nStudent: {name}") # \n at the start adds a blank line before the output
print(f"Score: {score:.2f}%") # :.2f = show exactly 2 decimal places
# Any Python expression works inside { }
a, b = 7, 3
print(f"\n{a} + {b} = {a + b}")
print(f"Name uppercase: {name.upper()}")
# Debug trick (Python 3.8+): add = after the variable name inside { }
# to print both the variable name and its value — very handy when debugging!
x = 42
print(f"{x=}") # prints: x=42
# ============================================================
# 💡 OPTIONAL — alignment and padding (useful for Exercise 4)
# ============================================================
rank = 1
population = 8_100_000_000
print(f"\nRank: {rank:03d}") # 03d: pad integer with zeros to width 3 → 001
print(f"World population: {population:,}") # , adds thousands separators → 8,100,000,000
print(f"Right-aligned: {'hello':>15}") # >15: right-align in a field of 15 characters
print(f"Left-aligned: {'hello':<15}|") # <15: left-align (the | shows where the field ends)
print(f"Centered: {'hello':^15}|") # ^15: center
print(f"Pi approx: {3.14159265:.4f}")⚠️ The cell below uses
input()and requires your interaction. Run it withShift + Enter, then type your answer in the text field that appears and press Enter to confirm. Do not use Run All — it will hang waiting for input that never comes.
# --- input() example ---
# Run this cell — a text field will appear below it in Jupyter.
# Type your name, press Enter, then type your age and press Enter again.
name = input("Enter your name: ")
age_str = input("Enter your age: ")
age = int(age_str) # input() always returns a string — convert to int for arithmetic
print(f"Hello, {name}! You are {age} years old.")
print(f"In 10 years you will be {age + 10}.")1.3 PEP-8: The Python Style Guide¶
PEP-8 is the official style guide for Python code. Following it makes code more readable and maintainable — especially important in team projects.
💡 You do not need to memorise all of these right now. Focus on just two rules today: 4-space indentation and snake_case variable names. Those are the ones you will encounter every single session. The rest will become familiar over time, and Ruff (below) will catch them automatically anyway.
Key rules at a glance¶
| Rule | Bad | Good |
|---|---|---|
| Indentation | 2 spaces or tabs | 4 spaces |
| Line length | >79 characters | ≤79 characters |
| Variable names | MyVar, myvar, MYVAR | my_var (snake_case) |
| Class names | my_class, myclass | MyClass (PascalCase) |
| Constants | maxSpeed | MAX_SPEED (UPPER_CASE) |
| Functions | CalcArea() | calc_area() (snake_case) |
| Spaces around operators | x=1+2 | x = 1 + 2 |
| Blank lines | None between functions | 2 blank lines between top-level defs |
| Imports | import os, sys | One import per line |
Automatic enforcement: linting and formatting¶
Linting is the process of automatically analysing your source code to detect style violations, potential bugs, and code-quality issues — without actually running the code. Formatting means automatically rewriting your code to conform to a consistent style (indentation, spacing, line length, etc.). Together, they save you from having to remember every PEP-8 rule by hand.
One tool that does both is Ruff — a fast Python linter and formatter.
Install Ruff in your virtual environment:
pip install ruffCheck your code (linting):
ruff check main.py # or . for all files in the current directoryAutomatically format your code:
ruff format main.py # or . for all files in the current directory# ============================================================
# PEP-8 VIOLATIONS vs. CORRECT CODE — side-by-side comparison
# ============================================================
# --- BAD: poor naming, no spaces, mixed style ---
# (This is commented out because it's intentionally bad style)
# def CalcArea(r):
# PI=3.14159
# return PI*r*r
# myResult=CalcArea(5)
# print(myResult)
# --- GOOD: PEP-8 compliant ---
import math # standard library imports at the top
def calculate_circle_area(radius: float) -> float:
"""Return the area of a circle given its radius."""
# Use math.pi for the most accurate value
return math.pi * radius ** 2
# Constants in UPPER_SNAKE_CASE
MAX_RADIUS = 1000
# Variable names in snake_case
test_radius = 5.0
area_result = calculate_circle_area(test_radius)
print(f"Area of circle with radius {test_radius}: {area_result:.4f}")
print(f"Maximum allowed radius: {MAX_RADIUS}")
# --- Spaces around operators ---
x = 10
y = 20
total = x + y # good: spaces around +
product = x * y # good
# Exception: no space around = in keyword arguments
print(f"Total: {total}", end="\n") # 'end' has no spaces around =
# --- Boolean comparisons ---
items = []
# BAD: if items == []: or if len(items) == 0:
# GOOD:
if not items:
print("The list is empty (Pythonic check)")
value = None
# BAD: if value == None:
# GOOD:
if value is None:
print("Value is None (use 'is', not '==', for None)")Part 2: Exercises¶
Work through these exercises individually or in pairs. Ask for help if you get stuck — that is what seminars are for!
Exercise 1: Greeting Script¶
Write a script that:
Asks the user for their name and age (using
input())Prints a personalised greeting that includes their name
Computes and prints the year they were born (assume current year is 2026)
Checks whether they are a minor (under 18) or an adult and prints an appropriate message
Expected output (example):
Enter your name: Alice
Enter your age: 21
Hello, Alice! Welcome to the Algorithmics course.
You were born in approximately 2005.
You are an adult.💡 Step 4 requires an
if/elsestatement — this is covered formally in seminar 2, but the structure is provided for you below. Your job is to fill in the condition and the two messages.
if age < 18:
print("...") # message for minors
else:
print("...") # message for adults# Exercise 1 — Your solution here
# Hint: use input(), int(), and f-strings.
Exercise 2: Fix the PEP-8 Violations¶
The code cell below contains intentional PEP-8 violations. Your task is to:
Identify every violation (there are 11)
Fix them in the cell below it
Verify the fixed version still produces the same output
Violations to look for: bad naming, wrong indentation, missing spaces, wrong import style, too-long lines, wrong comparison syntax.
# ================================================
# BROKEN CODE — do NOT run this cell as-is
# (it will run, but the style is terrible)
# ================================================
import math,os # violation 1: multiple imports on one line
def CalcRectArea(W,H): # violation 2: PascalCase for function; violation 3: no spaces after commas
area=W*H # violation 4: 2-space indent; violation 5: no spaces around =
return area
MyWidth=10 # violation 6: PascalCase for variable
MyHeight=5 # violation 7: same
Result=CalcRectArea(MyWidth,MyHeight) # violation 8: PascalCase; violation 9: no space after comma
if Result == None: # violation 10: use 'is None' not '== None'
print( "No result") # violation 11: extra space inside print()
else:
print("Area =",Result)# Exercise 2 — Fixed PEP-8-compliant version
# Write your corrected code here.Exercise 3: Type Conversions¶
Python’s built-in int(), float(), str(), and bool() let you convert between types. This matters whenever you read user input (which is always a string) or prepare data for display.
Part A — Explore conversions: run each line and record the result in a comment.
Part B — Practical: write a short script that:
Reads a number from the user with
input()(as a string)Converts it to a float
Prints its square and its square root (use
** 0.5)Prints whether it is positive, negative, or zero
Example run:
Enter a number: 9
Square: 81.0
Square root: 3.0
The number is positive.# Exercise 3 — Type Conversions
# ── Part A: explore conversions (fill in the expected results) ──
print(int("42")) # → ?
print(int(3.99)) # → ? (truncates, does not round)
print(float("3.14")) # → ?
print(str(100)) # → ?
print(bool(0)) # → ?
print(bool("")) # → ?
print(bool("hello")) # → ?
print(bool([])) # → ?
print(bool([0])) # → ? (non-empty list — truthy even if it holds 0)
# ── Part B: YOUR CODE HERE ──────────────────────────────────────
# 1. Read a number from the user
# 2. Convert to float
# 3. Print square and square root
# 4. Print positive / negative / zero
Exercise 4: f-string Formatting¶
f-strings (formatted string literals) let you embed expressions directly in strings and control their layout with format specifiers:
| Specifier | Meaning | Example |
|---|---|---|
{x:<12} | left-align in 12 chars | 'Alice ' |
{x:>5} | right-align in 5 chars | ' 21' |
{x:.1f} | float with 1 decimal place | '87.0' |
{x:,} | thousands separator | '1,000,000' |
Task: using the student list below, print a formatted table that looks exactly like this:
Name Age Grade
-----------------------------
Alice 21 87.0%
Bob 19 73.5%
Chiara 22 95.0%
Dmitri 20 61.3%Hint: print the header and separator first, then fill in the body of the loop.
💡 Loops (
for) are covered properly in seminar 2 — for now, the loop structure is provided for you. Your job is to write theprint(...)line inside it using f-string alignment specifiers.
# Exercise 4 — f-string Formatting
students = [
("Alice", 21, 87.0),
("Bob", 19, 73.5),
("Chiara", 22, 95.0),
("Dmitri", 20, 61.3),
]
# Step 1: print the header line and the separator
# YOUR CODE HERE
# Step 2: the loop unpacks each row into (name, age, grade) for you.
# Replace the 'pass' with a single print() using f-string specifiers.
for name, age, grade in students:
pass # ← replace with: print(f"...")Summary¶
In this seminar you covered:
| Topic | Key takeaway |
|---|---|
| Data types | int, float, str, bool, list, dict — convert explicitly |
| I/O | print() with f-strings; input() always returns str |
| PEP-8 | Consistent style = readable, maintainable code |
You are now ready to start developing in Python. In the next lecture, we will have a look at the basic Python commands.