DATE: 26/06/2026
PYTHON FUNDAMENTALS
Python is one of the go-to languages when it comes to working with data, and it's a good starting point for
anyone getting into data science.
PRINTING
The most basic thing you can get a computer to do is display a message on the screen. In Python this is
done with the print() function — the message goes inside the parentheses, wrapped in quotation marks.
print("Hello World!")
Output - Hello World!
ARITHMETIC
print() isn't just for text — it can also display the result of a calculation (addition, subtraction, multiplication,
division, and so on).
print(2+1)
Output - 3
Here Python adds 2 and 1 together and displays 3. Unlike text, numbers used in a calculation are not
wrapped in quotation marks.
print(9-5)
Output - 4
Python can handle a wide range of calculations:
• Addition ( + ) e.g. 1+2 = 3
• Subtraction ( - ) e.g. 6-4 = 2
• Multiplication ( * ) e.g. 2*3 = 6
• Division ( / ) e.g. 6/3 = 2
• Exponent ( ** ) e.g. 3**2 = 9
Parentheses let you control the order in which a long calculation is evaluated:
print(((1+3) * (9-2) / 2) ** 2)
Output - 196.0
NOTE — Python evaluates expressions using the PEMDAS order: Parentheses, Exponents, Multiplication,
Division, Addition, Subtraction.
COMMENTS
Comments are notes you leave inside your code to explain what it's doing — useful both for other people
reading your code and for future-you, who might not remember the logic behind it months later. Comments
become increasingly valuable as a codebase grows.
A line is turned into a comment by placing a pound sign (#) as its very first character. Python skips over
anything on a line that starts with #.
# Multiply 3 by 2
print(3 * 2)
Output - 6
Here, the comment (# Multiply 3 by 2) simply describes what the line below it does.
Multiply 3 by 2
print(3 * 2)
Output - SyntaxError: invalid syntax
Without the # symbol, Python tries to interpret "Multiply 3 by 2" as actual code — and since it isn't valid
Python, it throws a syntax error.
VARIABLES
Up to now, every calculation we've run has printed a result without saving it anywhere. If we want to reuse
that value later, we need to store it — that's what variables are for.
Creating Variables
The example below creates a variable named test_var and stores the result of 4+5 inside it. Printing
test_var afterward shows the stored value, 9.
# Create a variable called test_var and give it a value of 4+5
test_var = 4+5
# Print the value of test_var
print(test_var)
Output - 9
To create a variable, first pick a name that is short and describes what it holds. Variable names must follow
a few rules:
• No spaces are allowed (test var is invalid).
• Only letters, numbers, and underscores are allowed (test_var! is invalid).
• The name must start with a letter or an underscore (1_var is invalid).
The = sign assigns a value to the variable name. You can check what's stored in a variable at any time by
passing its name to print().
Manipulating Variables
A variable's value isn't fixed — you can overwrite it whenever you like. Below, my_var starts at 3 and is
later reassigned to 100.
# Set the value of a new variable to 3
my_var = 3
# Print the value assigned to my_var
print(my_var)
Output - 3
# Change the value of the variable to 100
my_var = 100
# Print the new value assigned to my_var
print(my_var)
Output - 100
You can also update a variable relative to its current value. Below, my_var is increased by 3, using its own
existing value on the right-hand side of the =.
# Increase the value by 3
my_var = my_var + 3
print(my_var)
Output - 103
NOTE — Once a variable is defined, every line of code that comes after it can use it.
Using Multiple Variables
Real calculations often rely on more than one variable at a time. Here's an example that works out how
many seconds are in four years, using five separate variables as inputs.
# Create variables
num_years = 4
days_per_year = 365
hours_per_day = 24
mins_per_hour = 60
secs_per_min = 60
# Calculate the number of seconds in four years
total_secs = secs_per_min * mins_per_hour * hours_per_day * days_per_year * num_years
print(total_secs)
Output - 126144000
NOTE — (i) The same result could be found with raw numbers, but splitting it into variables makes each
part of the calculation easy to inspect and debug. (ii) Variables really pay off once an input might change
— e.g. adjusting days_per_year to account for a leap year only requires updating that one variable, and
everything downstream recalculates correctly.
Debugging
A common mistake with variables is a simple typo. If hours_per_day is accidentally typed as
hours_per_dy, Python won't recognize it and will raise a NameError.
print(hours_per_dy)
Output - NameError: name 'hours_per_dy' is not defined
A NameError means Python doesn't recognize a name you've referenced — check your spelling against
how the variable was originally defined and correct it.
CHALLENGE SET 1
Working out the cost of a road trip. Comments are included with each answer to keep the code readable.
• Print the text: "Road Trip Cost Calculator"
# Prints the text "Road Trip Cost Calculator"
print("Road Trip Cost Calculator")
• Print the result of: total_km = 450 + 320 + 215 (three legs of the trip)
# Prints the total distance covered in the road trip
total_km = 450+320+215
print(total_km)
• Create these variables: total_km, fuel_efficiency, price_per_litre, num_passengers.
# Creates the mentioned variables
total_km = 985
fuel_efficiency = 12
price_per_litre = 1.85
num_passengers = 4
• Using only the variables (no raw numbers), calculate and print: (i) total_litres = total_km / fuel_efficiency
# Prints the total litres of fuel used
total_litres = total_km/fuel_efficiency
print(total_litres)
• (ii) total_cost = total_litres x price_per_litre
# Prints the total cost of fuel
total_cost = total_litres*price_per_litre
print(total_cost)
• (iii) cost_per_person = total_cost / num_passengers
# Prints cost per person
cost_per_person = total_cost/num_passengers
print(cost_per_person)
• Fuel prices went up. Increase price_per_litre by 0.20 and recalculate total_cost. Print the new value.
# Calculates and prints the new total cost
price_per_litre = price_per_litre + 0.20
total_cost = total_litres*price_per_litre
print(total_cost)
• In a single print() statement, calculate the cost if the trip were twice as long and fuel efficiency dropped
by 2 km/litre. Use parentheses to control the order.
# Calculates and prints the cost of the trip in a single line
print(((total_km*2)/(fuel_efficiency-2))*price_per_litre)
FUNCTIONS
A function is a reusable, named block of code built to do one specific job.
Here's a simple function called add_three() — it takes any number, adds 3 to it, and hands back the result.
# Define the function
def add_three(input_var):
output_var = input_var + 3
return output_var
Every function has two parts: a header and a body.
Function Header
The header names the function and lists what input(s) it expects.
• It always starts with def, telling Python a function definition is coming.
• The argument is the name given to the input value; it sits inside parentheses right after the function
name.
• A colon ( : ) always follows the closing parenthesis.
NOTE — A function can take zero arguments, one argument, or several.
Function Body
The body is where the actual work happens.
• Every line inside the function body must be indented.
• Python executes the indented lines in order, top to bottom.
• The return statement hands the final value back out of the function as its output.
How to Run a Function
Running a function is usually called "calling" it.
# Run the function with 10 as input
new_number = add_three(10)
# Check that the value is 13, as expected
print(new_number)
Output - 13
Naming Functions
Function names should stick to lowercase letters, with underscores in place of spaces.
# Example of a good function name
def my_function():
Variable Scope
A variable created inside a function body only exists inside that function — it can't be reached from outside
it. This is called the variable's scope. Variables created inside a function have local scope (limited to that
function), while variables created outside every function have global scope and can be used anywhere in
the code.
# Example to understand variable scope
def hat_color(input_var):
paint_hat = input_var
default_color = 'White'
return paint_hat
print(default_color)
Output - NameError: name 'default_color' is not defined
Functions With Multiple Arguments
To accept more than one input, just list the extra arguments in the header, separated by commas. When
calling the function, supply one value per argument, again separated by commas.
# Example to understand a function with multiple arguments
def function_with_multiple_arguments(input_var_1, input_var_2):
total = input_var_1 + input_var_2
return total
new_total = function_with_multiple_arguments(3,4)
print(new_total)
Output - 7
NOTE — How many arguments a function needs really depends on how flexible you want it to be for your
particular use case.
Functions With No Arguments
A function doesn't have to take any input, and it doesn't have to return anything either.
# Example to understand functions with no arguments
def print_hello():
print('Hello There!')
print_hello()
Output - Hello There!
CHALLENGE SET 2
• Write a function called add_tax that takes a price as input, adds 20% tax to it, and returns the result.
Call it with a price of 50 and print the output.
# Function that takes price as input and adds 20% tax to it
def add_tax(input_price):
new_price = input_price + (input_price*0.2)
return new_price
added_tax_price = add_tax(50)
print(added_tax_price)
• Write a function called calc_cost that takes distance, fuel efficiency, and price per litre as arguments
and returns the total fuel cost. Call it with values of your choice and print the result.
# Function that calculates total fuel cost
def calc_cost(dist, fuel_efficiency, price_per_litre):
total_cost = (dist/fuel_efficiency)*price_per_litre
return total_cost
my_fuel_cost = calc_cost(100,10,90)
print(my_fuel_cost)
• Write a function called print_greeting that prints "Welcome to the Python Calculator!" and takes no
arguments. Call it.
# A function with no arguments
def print_greeting():
print("Welcome to the Python Calculator!")
print_greeting()
• Define a function called double_it that takes a number, doubles it, and stores the result in a variable
called doubled. Try printing doubled outside the function. What happens and why?
# A function to show the local scope of a variable
def double_it(input_var):
doubled = input_var*2
return doubled
print(doubled)
This raises a NameError, because doubled only has local scope inside the function body — it simply
doesn't exist outside of it.
• Write a function called trip_summary that takes total_km and num_passengers as arguments, assumes
fuel_efficiency = 12 and price_per_litre = 2.05 inside the function, and returns the cost per person. Call
it and print the result.
# A function that calculates the cost per person for the trip
def trip_summary(total_km, num_passengers):
fuel_efficiency = 12
price_per_litre = 2.05
cost_per_person = ((total_km/fuel_efficiency)*price_per_litre)/num_passengers
return cost_per_person
my_cost = trip_summary(150, 6)
print(my_cost)
DATE: 29/06/2026
DATA TYPES
Every variable in Python holds a value that belongs to a particular data type — integers, floats, booleans,
and strings are common ones, and there are more advanced types too, like dictionaries, sets, lists, and
tuples.
The data type matters because it decides what operations are valid — for example, two floats can be
divided, but two strings cannot. Knowing your data types helps you avoid mismatched operations that lead
to errors.
INTEGERS
Integers are whole numbers with no decimal part. They can be positive (1, 2, 3, ...), negative (-1, -2, -3, ...),
or zero (0).
# Checking the type of variable x
x = 14
print(x)
print(type(x))
Output - 14 <class 'int'>
NOTE — type() reports a variable's data type; just pass the variable's name inside the parentheses.
FLOATS
Floats are numbers that include a decimal portion, and they can hold many digits after the decimal point.
# Checking the type of variable pi
nearly_pi = 3.141592653589793238462643383279502884197169399375105820974944
print(nearly_pi)
print(type(nearly_pi))
Output - 3.141592653589793 <class 'float'>
Dividing two numbers to get a fraction also produces a float:
# Checking the type of variable almost_pi
almost_pi = 22/7
print(almost_pi)
print(type(almost_pi))
Output - 3.142857142857143 <class 'float'>
NOTE — round() is handy for trimming a number down to a fixed number of decimal places.
# Round to 5 decimal places
rounded_pi = round(almost_pi, 5)
print(rounded_pi)
print(type(rounded_pi))
Output - 3.14286 <class 'float'>
NOTE — Any number written with a decimal point (1., 1.0, 1.00, etc.) is treated as a float by Python, even
if there's technically nothing after the point.
BOOLEANS
Booleans can only ever be one of two values: True or False.
z_one = True
print(z_one)
print(type(z_one))
Output - True <class 'bool'>
NOTE — (i) Booleans represent whether an expression is true or false.
# Checking the type of variable z_three
z_three = (1 < 2)
print(z_three)
print(type(z_three))
Output - True <class 'bool'>
(ii) The not keyword flips a boolean's value — not True becomes False, and not False becomes True.
# Switching value of boolean using not
z_five = not False
print(z_five)
print(type(z_five))
Output - True <class 'bool'>
STRINGS
A string is a sequence of characters — letters, punctuation, digits, or symbols — wrapped in quotation
marks. Strings are how Python represents text.
# Checking the type of variable w
w = "Hello, Python!"
print(w)
print(type(w))
Output - Hello, Python! <class 'str'>
NOTE — (i) len() gives you the number of characters in a string. The surrounding quotation marks aren't
counted.
# Printing length of string
print(len(w))
Output - 14
(ii) An empty string ("") is a valid string too — it just has a length of zero.
# Printing length of empty string
shortest_string = ""
print(type(shortest_string))
print(len(shortest_string))
Output - <class 'str'> 0
(iii) Wrapping a number in quotation marks makes it a string, not a number.
# Number as string
my_number = "1.12321"
print(my_number)
print(type(my_number))
Output - 1.12321 <class 'str'>
(iv) A string that looks like a number can be converted into an actual float using float().
# String to float
my_number = "1.12321"
also_my_number = float(my_number)
print(also_my_number)
print(type(also_my_number))
Output - 1.12321 <class 'float'>
(v) Just like numbers, strings can be added together with + — this joins (concatenates) them into one
longer string.
# Adding strings
new_string = "abc" + "def"
print(new_string)
print(type(new_string))
Output - abcdef <class 'str'>
(vi) You can't subtract, divide, or multiply two strings together — but you can multiply a string by an integer,
which repeats the string that many times.
# Multiplying string with integer
newest_string = "abc" * 3
print(newest_string)
print(type(newest_string))
Output - abcabcabc <class 'str'>
(vii) Multiplying a string by a float, however, is not allowed and raises an error.
# Multiplying string with a float — not allowed
will_not_work = "abc" * 3.0
Output - TypeError: can't multiply sequence by non-int of type 'float'
CONDITIONS
A condition is simply a statement that evaluates to either True or False. The most common conditions
compare two values against each other — for instance, checking whether 2 is greater than 3.
# Checking a condition
print(2 > 3)
Output - False
Common comparison operators used to build conditions:
• == equals
• != does not equal
• < less than
• <= less than or equal to
• > greater than
• >= greater than or equal to
NOTE — To check whether two values are equal, remember to use ==, not a single =. A single = is for
assignment, not comparison.
CONDITIONAL STATEMENTS
Conditional statements use a condition to decide which block of code should run. If the condition is True,
the associated block runs; if it's False, that block is skipped.
"if" Statements
The simplest kind of conditional is a plain if statement.
# Checking a condition using an if statement
season = "summer"
if season == "summer":
print("mango")
Output - mango
"if ... else" Statements
Pairing if with else lets you run one block when the condition is True and a different block when it's False.
# Checking a condition using an if...else statement
season = "winter"
if season == "summer":
print("mango")
else:
print("guava")
Output - guava
"if ... elif ... else" Statements
elif ("else if") lets you check several conditions in sequence, one after another, until one of them is True.
# Checking a condition using an if...elif...else statement
season = "monsoon"
if season == "summer":
print("mango")
elif season == "monsoon":
print("corn")
else:
print("guava")
Output - corn
LOOPS
Loops let you repeat a block of code multiple times instead of writing the same lines over and over. Python
has two main kinds: for loops and while loops.
For Loops
A for loop runs a block of code once for every item in a sequence (like a list, a string, or a range of
numbers).
# Printing each fruit in a list
fruits = ["mango", "guava", "corn"]
for fruit in fruits:
print(fruit)
Output -
mango
guava
corn
range() is often used with for loops to repeat something a fixed number of times.
# Printing numbers 0 to 4
for i in range(5):
print(i)
Output -
0
1
2
3
4
While Loops
A while loop keeps running its block of code for as long as a condition stays True. It's useful when you
don't know in advance exactly how many times you'll need to repeat something.
# Counting up to 3
count = 1
while count <= 3:
print(count)
count = count + 1
Output -
1
2
3
NOTE — Be careful with while loops: if the condition never becomes False, the loop will run forever (an
infinite loop).
Loop Control: break and continue
break exits a loop immediately, even if the loop's condition is still True. continue skips the rest of the
current iteration and moves on to the next one.
# Stop the loop once we hit "corn"
for fruit in fruits:
if fruit == "corn":
break
print(fruit)
Output -
mango
guava
LISTS
A list is an ordered, changeable collection of items, written inside square brackets and separated by
commas. Lists can hold any data type, and even a mix of types.
# Creating a list
seasons = ["summer", "monsoon", "winter"]
print(seasons)
print(type(seasons))
Output - ['summer', 'monsoon', 'winter'] <class 'list'>
List Indexing and Slicing
Each item in a list has a position, or index, starting at 0 for the first item. Negative indexes count backward
from the end of the list, with -1 being the last item.
# Accessing items by index
print(seasons[0])
Output - summer
print(seasons[-1])
Output - winter
Slicing lets you grab a range of items using start:stop, where the stop index is not included.
# Slicing a list
print(seasons[0:2])
Output - ['summer', 'monsoon']
List Methods
Lists come with several built-in methods for adding, removing, and reordering items.
• append(item) — adds an item to the end of the list.
• remove(item) — removes the first matching item from the list.
• sort() — arranges the list's items in order.
• len(list) — returns how many items are in the list.
# Adding an item to the list
[Link]("spring")
print(seasons)
Output - ['summer', 'monsoon', 'winter', 'spring']
TUPLES
A tuple is very similar to a list — an ordered collection of items — except that once created, it cannot be
changed (it's immutable). Tuples are written with parentheses instead of square brackets.
# Creating a tuple
coordinates = (10, 20)
print(coordinates)
print(type(coordinates))
Output - (10, 20) <class 'tuple'>
NOTE — Tuples are a good choice when you want to make sure the data can't accidentally be modified
later in the code.
DICTIONARIES
A dictionary stores data as key-value pairs, written inside curly braces. Instead of accessing items by
numeric position like a list, you access them by their key.
# Creating a dictionary
fruit_prices = {"mango": 60, "guava": 40, "corn": 25}
print(fruit_prices["mango"])
Output - 60
Dictionaries are useful whenever you need to look up a value using a meaningful label rather than a
numeric position.
# Adding a new key-value pair
fruit_prices["apple"] = 120
print(fruit_prices)
Output - {'mango': 60, 'guava': 40, 'corn': 25, 'apple': 120}
SETS
A set is an unordered collection of unique items — duplicate values are automatically dropped. Sets are
written with curly braces, like dictionaries, but without keys.
# Creating a set
unique_seasons = {"summer", "monsoon", "summer", "winter"}
print(unique_seasons)
Output - {'summer', 'monsoon', 'winter'}
NOTE — Sets are handy when you need to remove duplicates from a collection or quickly check whether a
value exists in it.
STRING METHODS
Strings come with a range of built-in methods that make it easy to clean up or transform text.
• upper() / lower() — converts a string to all uppercase or all lowercase.
• strip() — removes leading and trailing whitespace from a string.
• replace(old, new) — swaps out one substring for another.
• split(separator) — breaks a string into a list of pieces based on a separator.
# Using string methods
greeting = " Hello Python "
print([Link]().upper())
Output - HELLO PYTHON
TYPE CONVERSION
Sometimes a value needs to be converted from one data type to another before it can be used the way you
want. Python provides simple functions for this.
• int() — converts a value to an integer.
• float() — converts a value to a float.
• str() — converts a value to a string.
# Converting between types
age_text = "25"
age_number = int(age_text)
print(age_number + 5)
Output - 30
NOTE — Trying to convert a non-numeric string, like int("twenty"), will raise a ValueError, since Python
has no way to interpret it as a number.
THE input() FUNCTION
input() lets a program pause and take text typed in by the user. Whatever is typed is always returned as a
string, so it may need to be converted with int() or float() before it can be used in a calculation.
# Taking input from the user
name = input("What is your name? ")
print("Hello, " + name + "!")
F-STRINGS
f-strings are a clean way to build strings that include the value of a variable directly, without needing to use
+ to join pieces together. An f-string starts with an f before the opening quotation mark, and variables are
placed inside curly braces.
# Using an f-string
name = "Chandrachud"
print(f"Hello, {name}!")
Output - Hello, Chandrachud!