PYTHON LAB 2 – FUNCTIONS, VARIABLES, LOOPS and Structures
PART A — VARIABLES
A1) Variables ⭐
Definition: A variable is a named storage for a value. It allows reuse of values in
calculations.
Learning focus
• Creating variables to store numbers and text.
• Using print() to display values.
• Checking data types using type().
Problem description
We store basic mechanical values (RPM, torque, material name) in variables and
display both the values and their data types. This helps us see how Python treats
whole numbers, decimal numbers, and text.
Program A1: Store mechanical values and display types
python
# %% A1: Variables - store and display mechanical values
# CONFIG: values stored in variables (names)
rpm = 1500 # int (whole number)
torque_Nm = 120.5 # float (decimal number)
material = "Steel" # str (text inside quotes)
# print() displays information in the console
print("=== STORED VALUES ===")
print("RPM =", rpm)
print("Torque (N.m) =", torque_Nm)
print("Material =", material)
# type() tells the data type of each variable
print("\n=== DATA TYPES ===")
print("type(rpm) =", type(rpm))
print("type(torque_Nm) =", type(torque_Nm))
print("type(material) =", type(material))
Expected Outcome
• Stored values (rpm, torque, material) are printed clearly.
• Data types are displayed as:
– <class 'int'>, <class 'float'>, <class 'str'>.
A2) Reassignment (Updating a Variable) ⭐⭐
Definition: Reassignment means updating a variable by storing a new value into
the same variable name.
Learning focus
• Updating (reassigning) a variable using =.
• Repeating updates using a for loop.
• Understanding how values change step-by-step.
Problem description
We start with an initial RPM and increase it by a fixed step multiple times. This
mirrors real lab scenarios such as stepping RPM in a test (e.g., 1000 → 1250 →
1500 …).
Program A2: Update RPM step-by-step using a loop
python
# %% A2: Reassignment - updating RPM in steps
# CONFIG
rpm = 1000 # initial rpm
step = 250 # rpm increment each update
updates = 5 # number of updates
print("=== RPM UPDATES ===")
print("Initial RPM:", rpm)
# for loop repeats a block of code a fixed number of times
# range(updates) generates 0,1,2,3,4
for i in range(updates):
rpm = rpm + step # reassignment: rpm becomes rpm + step
print("Update", i + 1, "-> RPM:", rpm)
print("\nFinal RPM:", rpm)
Expected Outcome
• RPM increases by step for updates times.
• Final RPM equals 1000 + 5×250 = 2250 (with the given CONFIG).
A3) Scope (Global vs Local Variables) ⭐⭐⭐
Definition: Scope means where a variable exists and can be used.
• Global: defined outside functions.
• Local: defined inside a function.
Learning focus
• Defining functions using def.
• Understanding the difference between global and local variables.
• Seeing how function parameters behave (inputs to functions).
• Using return to send results back.
Problem description
We keep one RPM value globally and run functions that create and modify local
variables. This demonstrates that changes inside a function do not automatically
change global variables unless we explicitly reassign them.
Program A3: Show global vs local behaviour clearly
python
# %% A3: Scope - global vs local variables
rpm_global = 1500 # global variable (exists throughout the file)
# def defines a function (reusable code block)
def change_rpm_locally():
# rpm_local exists only inside this function
rpm_local = 900
rpm_local = rpm_local + 100
return rpm_local # return sends the value back to where we called
the function
def change_rpm_using_input(rpm_value):
# rpm_value is a parameter (local inside function)
rpm_value = rpm_value + 200
return rpm_value
print("=== SCOPE DEMO ===")
print("Global rpm before:", rpm_global)
new_local = change_rpm_locally() # function call
print("Returned local rpm:", new_local)
rpm_after = change_rpm_using_input(rpm_global) # passing global
value in
print("Result after passing global rpm:", rpm_after)
print("Global rpm after function calls:", rpm_global)
print("\nConclusion:")
print("Local variables change inside functions,")
print("but global variables remain unchanged unless reassigned
explicitly.")
Expected Outcome
• The returned local rpm prints as 1000.
• rpm_after prints as 1700.
• rpm_global remains 1500.
PART B — FUNCTIONS
B1) Functions (Basic form) ⭐
Definition: A function is a reusable block of code that performs a single task.
• def defines a function.
• return sends results back.
Learning focus
• Creating a function using def.
• Passing an input value (parameter) into a function.
• Returning a computed output using return.
• Calling the function inside a loop for multiple values.
Problem description
We convert multiple millimetre values into metres using a single conversion
function. This avoids repeating the same conversion formula many times.
Program B1: Convert mm → m using a function
python
# %% B1: Function - mm to m converter
# CONFIG
values_mm = [5, 10, 25, 50, 100]
def mm_to_m(mm):
"""Converts millimetres to metres."""
metres = mm / 1000
return metres
print("=== mm to m Conversion ===")
print("mm -> m")
print("-" * 18)
for mm in values_mm:
m = mm_to_m(mm) # function call
print(f"{mm:>3} -> {m:.4f}")
Expected Outcome
• A neat conversion table prints.
• Example: 100 -> 0.1000.
B2) Functions with Multiple Inputs ⭐⭐
Definition: Functions can take multiple parameters and return a computed result.
Learning focus
• Writing a function with two inputs (force and diameter).
• Performing unit conversion inside the function (mm → m).
• Returning a numeric result and printing it with formatting.
• Using import math and [Link].
Problem description
We compute axial stress for a circular rod using force and diameter. This is a
common mechanical calculation and is ideal for learning “inputs → formula →
output” using functions.
Program B2: Axial stress in MPa using a function
python
# %% B2: Axial stress function (MPa)
import math
# CONFIG
force_N = 12000
diameter_mm = 12
def axial_stress_mpa(F_N, d_mm):
"""
Computes axial stress in MPa for a circular rod:
A = pi*d^2/4 (d in metres)
stress = F/A (Pa) then convert to MPa
"""
d_m = d_mm / 1000
area_m2 = [Link] * (d_m ** 2) / 4
stress_pa = F_N / area_m2
stress_mpa = stress_pa / 1e6
return stress_mpa
sigma = axial_stress_mpa(force_N, diameter_mm)
print("=== AXIAL STRESS ===")
print("Force (N):", force_N)
print("Diameter (mm):", diameter_mm)
print(f"Stress = {sigma:.2f} MPa")
Expected Outcome
• Stress prints in MPa with 2 decimal places.
• Values change correctly when force/diameter change.
B3) Multiple Returns + raise (Validation) ⭐⭐⭐
Definition:
• A function can return more than one value.
• raise stops execution with a clear message when inputs are invalid.
Learning focus
• Returning multiple outputs from a function (volume and mass).
• Validating inputs before calculation.
• Understanding raise ValueError(...) as a safety stop for invalid inputs.
• Using tuples implicitly via return volume, mass.
Problem description
We compute the volume and mass of a rectangular plate. If any input is physically
invalid (zero/negative dimension or density), we stop the program with a clear
message to prevent incorrect calculations.
Program B3: Plate volume and mass with validation
python
# %% B3: Multiple returns + raise validation
# CONFIG
L = 0.2
W = 0.1
T = 0.01
density = 7850
def plate_properties(L, W, T, density):
"""
Returns two values: (volume_m3, mass_kg)
Validates inputs using raise.
"""
if L <= 0 or W <= 0 or T <= 0:
raise ValueError("Length, width, and thickness must be
positive.")
if density <= 0:
raise ValueError("Density must be positive.")
volume = L * W * T
mass = density * volume
return volume, mass
vol, mass = plate_properties(L, W, T, density)
print("=== PLATE PROPERTIES ===")
print("L, W, T =", L, W, T, "m")
print("Density =", density, "kg/m^3")
print(f"Volume = {vol:.6f} m^3")
print(f"Mass = {mass:.3f} kg")
Expected Outcome
• With valid inputs, volume and mass print normally.
• If any dimension is set to 0 or negative, the program stops and shows a clear
ValueError.
PART C — LOOPS
C1) for loop ⭐
Definition: for repeats a block a fixed number of times.
Learning focus
• Using range(n) to repeat a task n times.
• Understanding the loop variable (i) changing each time.
• Printing sequential results.
Problem description
We simulate taking five readings in a lab and print the reading number each time.
Program C1: Print five readings
python
# %% C1: for loop - repeat 5 times
print("=== FOR LOOP EXAMPLE ===")
for i in range(5): # i becomes 0,1,2,3,4
print("Reading number:", i + 1)
Expected Outcome
• The console prints Reading number 1 to 5.
C2) for loop over a list ⭐⭐
Definition: A list stores multiple values; looping processes each value.
Learning focus
• Storing readings in a list.
• Using a loop to sum values (accumulator pattern).
• Computing average using len().
Problem description
We take vibration readings stored in a list, compute total vibration, and then
compute the average vibration level.
Program C2: Compute average vibration
python
# %% C2: Loop over list - vibration average
# CONFIG
vib = [1.1, 1.4, 1.3, 1.8, 1.2]
total = 0
for value in vib:
total = total + value
avg = total / len(vib)
print("=== VIBRATION ANALYSIS ===")
print("Readings:", vib)
print("Total =", total)
print("Count =", len(vib))
print(f"Average = {avg:.2f} m/s^2")
Expected Outcome
• Total, count, and average print correctly.
• Average updates correctly when readings are changed.
C3) while loop ⭐⭐⭐
Definition: while repeats while a condition stays True. It needs:
• initial value,
• condition,
• update step (to avoid infinite loops).
Learning focus
• Initialising a loop variable before while.
• Updating the loop variable inside the loop.
• Calling a function repeatedly inside a loop.
• Printing a table of results.
Problem description
We sweep RPM from a start value to an end value using a step size, and compute
power at each RPM. This matches real test sweeps (RPM steps in a dynamometer
experiment).
Program C3: RPM sweep using while + function
python
# %% C3: while loop - rpm sweep using function
import math
# CONFIG
torque_Nm = 120.0
rpm_start = 1000
rpm_end = 2500
step = 250
def shaft_power_kW(torque, rpm):
omega = 2 * [Link] * rpm / 60 # rad/s
power_W = torque * omega # watts
return power_W / 1000 # kW
print("=== RPM SWEEP (WHILE LOOP) ===")
print("Torque =", torque_Nm, "N.m")
print("RPM | Power(kW)")
print("-" * 18)
rpm = rpm_start
while rpm <= rpm_end:
p = shaft_power_kW(torque_Nm, rpm)
print(f"{rpm:>4} | {p:>8.2f}")
rpm = rpm + step # update is essential
Expected Outcome
• A table prints from 1000 rpm to 2500 rpm with 250 rpm steps.
• Power values increase with rpm.
PART D — STRUCTURES (Control + Data Structures)
D1) Control structure: if/elif/else ⭐
Definition: Used to make decisions based on conditions.
Learning focus
• Using comparison operators (<, <=, >).
• Writing multiple decision paths using if/elif/else.
• Printing a classification result.
Problem description
We classify temperature into cold/safe, normal operating range, or high-
temperature warning. This is a simple example of decision-making in programs.
Program D1: Temperature classification
python
# %% D1: if/elif/else - temperature status
# CONFIG
temperature_C = 95
print("=== TEMPERATURE CHECK ===")
print("Temperature =", temperature_C, "C")
if temperature_C < 60:
print("Status: Cold / safe")
elif temperature_C <= 90:
print("Status: Normal operating range")
else:
print("Status: HIGH TEMPERATURE WARNING")
Expected Outcome
• For 95°C, “HIGH TEMPERATURE WARNING” prints.
• Changing temperature changes the status accordingly.
D2) List structure: find maximum value ⭐⭐
Definition: A list stores ordered values; indexing accesses values by position.
Learning focus
• Accessing list values using indices.
• Tracking maximum value using comparison in a loop.
• Tracking the position (index) of the maximum value.
Problem description
We find the maximum vibration reading and identify where it occurred. This is
common in lab data processing (finding peak value).
Program D2: Maximum vibration and its position
python
# %% D2: List structure - max value and its position
# CONFIG
vib = [1.1, 1.4, 1.3, 1.8, 1.2]
max_value = vib[0]
max_index = 0
for i in range(len(vib)):
if vib[i] > max_value:
max_value = vib[i]
max_index = i
print("=== MAX VIBRATION ===")
print("Readings:", vib)
print("Maximum value =", max_value, "m/s^2")
print("Index position =", max_index, "(index starts at 0)")
print("Reading number =", max_index + 1)
Expected Outcome
• Maximum value prints as 1.8.
• Index prints as 3 and reading number prints as 4 (with the given CONFIG).
D3) Dictionary structure ⭐⭐⭐
Definition: A dictionary stores key → value pairs (e.g., material → density).
Learning focus
• Creating a dictionary using {key: value} format.
• Looping through key–value pairs using .items().
• Storing computed outputs back into a dictionary.
• Finding the maximum result using max(..., key=...).
Problem description
We compare the mass of the same plate made from different materials using their
densities stored in a dictionary. This demonstrates how dictionaries help manage
“property tables” in code.
Program D3: Compare mass for different materials using a dictionary
python
# %% D3: Dictionary structure - material mass comparison
# CONFIG: densities stored as key:value pairs
densities = {
"Steel": 7850,
"Aluminium": 2700,
"CastIron": 7200
}
L = 0.2
W = 0.1
T = 0.01
def mass_kg(density, L, W, T):
volume = L * W * T
return density * volume
print("=== MATERIAL MASS COMPARISON ===")
print("Plate size:", L, "x", W, "x", T, "m\n")
print("Material Density(kg/m^3) Mass(kg)")
print("-" * 45)
masses = {} # store computed masses
for material, density in [Link](): # .items() gives key and
value
m = mass_kg(density, L, W, T)
masses[material] = m
print(f"{material:<10} {density:>14} {m:>12.3f}")
max_material = max(masses, key=[Link]) # key with the highest
mass
print("\nMaximum mass material:", max_material)
print(f"Mass = {masses[max_material]:.3f} kg")
Expected Outcome
• A table prints mass for each material.
• Steel becomes the maximum mass material (with the given densities).
PART E — INTEGRATED PROGRAMS ⭐⭐⭐
E1) Stress report table (Functions + Lists + Loops + if)
Learning focus
• Combining lists, functions, loops, and decisions in one program.
• Processing multiple cases using parallel lists (force list + diameter list).
• Producing a neat engineering-style report table.
• Using if/else to classify SAFE/UNSAFE.
Problem description
We generate a stress report for multiple rod specimens. For each specimen, we
compute axial stress from its force and diameter, then compare it against an
allowable stress to classify it as SAFE or UNSAFE.
python
# %% E1: Integrated Program - stress report table
import math
# CONFIG
forces_N = [8000, 12000, 15000, 20000] # list of forces (N)
diameters_mm = [10, 12, 14, 12] # list of diameters (mm)
allowable_MPa = 250 # allowable stress (MPa)
def axial_stress_mpa(F_N, d_mm):
"""Calculates axial stress (MPa) for a circular rod."""
d_m = d_mm / 1000 # convert mm to m
area = [Link] * (d_m ** 2) / 4
sigma_mpa = (F_N / area) / 1e6
return sigma_mpa
print("=== STRESS REPORT (MULTIPLE SPECIMENS) ===")
print("Allowable stress =", allowable_MPa, "MPa\n")
print("Case | Force(N) | Dia(mm) | Stress(MPa) | Status")
print("-" * 56)
for i in range(len(forces_N)):
F = forces_N[i]
d = diameters_mm[i]
sigma = axial_stress_mpa(F, d)
if sigma <= allowable_MPa:
status = "SAFE"
else:
status = "UNSAFE"
print(f"{i+1:>4} | {F:>8} | {d:>7} | {sigma:>10.2f} | {status}")
Expected Outcome
• A full report prints for multiple specimens.
• Each case is labelled SAFE/UNSAFE based on allowable stress.
E2) Pump daily energy and cost table (Functions + Validation + Loops +
Dictionary)
Learning focus
• Validating engineering inputs using raise ValueError(...).
• Performing unit conversions inside a function (L/min → m³/s, bar → Pa).
• Returning structured outputs using a dictionary.
• Looping over multiple operating points and generating a cost table.
Problem description
We compute hydraulic power, shaft power, daily energy, and daily electricity cost
for several pump operating points. Each operating point contains flow rate,
pressure rise, and hours of operation.
python
# %% E2: Integrated Program - pump power, energy and cost table
# CONFIG
price_inr_per_kWh = 8.0
eta = 0.72 # efficiency (0 to 1)
# Each operating point: (Q_Lmin, dP_bar, hours_per_day)
operating_points = [
(80, 2.5, 4),
(120, 3.5, 5),
(160, 4.0, 6),
]
def pump_calculations(Q_Lmin, dP_bar, eta, hours):
"""Returns a dictionary of pump calculations for one operating
point."""
if eta <= 0 or eta > 1:
raise ValueError("Efficiency eta must be in the range (0,
1].")
if Q_Lmin <= 0:
raise ValueError("Flow rate must be positive.")
if dP_bar <= 0:
raise ValueError("Pressure rise must be positive.")
if hours < 0:
raise ValueError("Hours must be zero or positive.")
Q_m3_s = (Q_Lmin / 1000) / 60 # L/min -> m^3/s
dP_Pa = dP_bar * 1e5 # bar -> Pa
hydraulic_power_kW = (dP_Pa * Q_m3_s) / 1000
shaft_power_kW = hydraulic_power_kW / eta
daily_energy_kWh = shaft_power_kW * hours
return {
"hydraulic_power_kW": hydraulic_power_kW,
"shaft_power_kW": shaft_power_kW,
"daily_energy_kWh": daily_energy_kWh,
}
print("=== PUMP ENERGY & COST REPORT ===")
print("Efficiency eta =", eta)
print("Price =", price_inr_per_kWh, "INR/kWh\n")
print("Case | Q(L/min) | dP(bar) | Hours | Ph(kW) | Ps(kW) |
Energy(kWh) | Cost(INR)")
print("-" * 85)
for i in range(len(operating_points)):
Q_Lmin, dP_bar, hours = operating_points[i]
result = pump_calculations(Q_Lmin, dP_bar, eta, hours)
Ph = result["hydraulic_power_kW"]
Ps = result["shaft_power_kW"]
E = result["daily_energy_kWh"]
cost = E * price_inr_per_kWh
print(f"{i+1:>4} | {Q_Lmin:>7} | {dP_bar:>6.2f} | {hours:>5} |
{Ph:>5.2f} | {Ps:>5.2f} |"
f" {E:>10.2f} | {cost:>8.2f}")
Expected Outcome
• A table prints one line per operating point.
• Invalid inputs stop execution with a clear ValueError.
E3) Vibration monitoring report (Functions + Lists + Loops + if + Summary)
Learning focus
• Storing grouped data using a dictionary (machine → readings list).
• Writing reusable functions (average, classify) and calling them repeatedly.
• Using max() and len() for summary information.
• Producing both a per-machine report and a final summary count.
Problem description
We monitor vibration from multiple machines, compute average vibration, classify
the condition as NORMAL or HIGH VIBRATION, and count how many machines
exceed the limit.
python
# %% E3: Integrated Program - vibration monitoring report
# CONFIG
vibration_limit = 1.50 # m/s^2 threshold (example)
machine_vibration = {
"Pump_A": [1.1, 1.4, 1.3, 1.8, 1.2],
"Motor_B": [0.9, 1.0, 1.2, 1.1, 1.0],
"Fan_C": [1.6, 1.7, 1.8, 1.5, 1.9],
}
def average(values):
"""Returns average of a list of numbers."""
if len(values) == 0:
raise ValueError("Average cannot be computed for an empty
list.")
return sum(values) / len(values)
def classify(avg_value, limit):
"""Classifies average vibration using if/else."""
if avg_value <= limit:
return "NORMAL"
else:
return "HIGH VIBRATION"
print("=== VIBRATION MONITORING REPORT ===")
print("Limit =", vibration_limit, "m/s^2\n")
print("Machine | Readings Count | Average (m/s^2) | Status | Max
Reading")
print("-" * 70)
for machine, readings in machine_vibration.items():
avg_v = average(readings)
status = classify(avg_v, vibration_limit)
max_reading = max(readings)
print(f"{machine:<7} | {len(readings):>13} | {avg_v:>14.2f} |
{status:<13} | {max_reading:>11.2f}")
high_count = 0
for machine in machine_vibration:
if classify(average(machine_vibration[machine]), vibration_limit)
== "HIGH VIBRATION":
high_count += 1
print("\nSummary:")
print("Machines monitored =", len(machine_vibration))
print("High vibration machines =", high_count)
Expected Outcome
• A report prints average and status for each machine.
• Summary prints total machines and count of high-vibration machines.
Common mistakes (quick reference)
• IndentationError: incorrect spacing after def, for, while, if.
• NameError: spelling mismatch in variable names.
• TypeError: mixing numbers and strings incorrectly.
• Infinite loop: missing update line in a while loop.
• ValueError (from raise): program stopped because inputs are physically
invalid (correct safety behaviour).
Quick Reference: Problem List, Description, and Python Commands
Code Program focus and classroom Python commands /
description concepts used (quick)
A1 Variables + printing + data types. We assignment =, print(),
store core mechanical values (RPM, type(), literals (int, float,
torque, material) in variables, print them str)
neatly, and use type() to identify int,
float, and str.
A2 Reassignment + for loop repetition. We for, range(),
start from an initial RPM and repeatedly reassignment, arithmetic +
update it using rpm = rpm + step inside a
for loop, showing how values change
step-by-step.
A3 Scope (global vs local) + function call + def, parameters,
return. We observe that local variables local/global scope, return,
inside functions do not change global function call
variables unless reassigned; parameters
and return control data flow.
B1 Function definition + single parameter def, parameter, return,
+ calling inside a loop. We define for, list, function call
mm_to_m() and convert many values
without repeating code.
B2 Function with multiple inputs + import, [Link], def,
formula + unit conversion. We compute parameters, return,
axial stress using [Link], returning MPa. arithmetic **, /
B3 Multiple returns + input validation def, return (multiple), if,
using raise. We compute volume and logical or, raise
mass, return two outputs, and stop invalid ValueError, tuple
inputs with raise ValueError. unpacking
C1 for loop with range() basics. We repeat for, range(), print()
an action five times (simulate readings).
C2 Loop over a list + accumulator + list, for (over list),
average. We sum list values and compute accumulator, len(),
average using len(). arithmetic +, /
C3 while loop sweep + repeated function while, loop variable
evaluation. We sweep RPM with a step init/update, def, function
and compute power at each RPM, call, import math,
emphasising loop update to avoid infinite formatted printing
loop.
D1 Decision making with if/elif/else. We if, elif, else,
classify temperature into comparisons <, <=, >
safe/normal/high.
D2 List indexing + peak value detection. list indexing [],
We find maximum vibration and its range(len()), if,
position by scanning indices. comparisons, variables
(max_value, max_index)
D3 Dictionary (key→value) + looping + dict {}, .items(), for,
storing results + max selection. We storing masses[key]=...,
compute mass per material and find the max(..., key=...)
maximum.
E1 Integrated stress report (lists + lists, def, return, for
function + loop + if). We compute stress range(len()), if/else,
for multiple specimens and classify import math, f-strings
SAFE/UNSAFE in a table.
E2 Integrated pump energy & cost report list of tuples, def, raise
(validation + unit conversions + dict ValueError, unit
outputs). We compute Ph, Ps, energy, cost conversions, dict return,
across operating points with safe for, f-strings
validation.
E3 Integrated condition monitoring (dict dict of lists, .items(), def,
of machines + functions + classification sum(), len(), max(),
+ summary). We compute average/max if/else, loop counting
per machine, classify status, and count
high-vibration machines.