Day 5 – Functions, Scope, and Docstrings


 🧰 Day 5 – Functions, Scope, and Docstrings

1. Learning Objectives

By the end of Day 5, you will be able to:

  • Define reusable functions with def to encapsulate engineering calculations.
  • Understand the difference between local and global variable scope.
  • Write docstrings to document what a function does (its purpose, parameters, and return value).
  • Build a small library of AEC‑focused functions (moment of inertia, section modulus, U‑value check).
  • Call functions with arguments and use return values in larger scripts.

2. Concept Explanation

2.1 Why Functions?

Functions let you package a block of code that performs a specific task. You can then call it many times with different inputs. In AEC:

  • Instead of rewriting the same formula for every beam, you write a function once.
  • Functions make your code organised, testable, and reusable.
  • You can share your library of design functions with colleagues.

2.2 Defining and Calling Functions

def function_name(parameter1, parameter2, ...):
    """Optional docstring explaining the function."""
    # code block
    return result   # optional

Example – section modulus of a rectangular section:

def section_modulus_rect(b, h):
    """Calculate elastic section modulus S = b * h² / 6."""
    S = b * h**2 / 6
    return S

# Calling the function
S = section_modulus_rect(200, 400)   # b=200 mm, h=400 mm
print(f"S = {S:.0f} mm³")

2.3 Function Parameters and Return Values

  • Parameters are the variables listed in the function definition.
  • Arguments are the actual values passed when calling.
  • A function can have zero, one, or multiple parameters.
  • return sends a value back to the caller. If no return, the function returns None.

2.4 Scope – Local vs. Global Variables

  • Local variables – created inside a function; only accessible within that function.
  • Global variables – defined at the top level of the script; accessible everywhere (but modifying them inside a function requires the global keyword – avoid this unless necessary).
# Global scope
material = "Steel"           # global variable

def get_density():
    density = 7850           # local variable – only inside function
    return density

print(material)              # works
print(get_density())         # works
# print(density)             # ERROR – density is not defined globally

2.5 Docstrings

A docstring is a triple‑quoted string immediately after the function header. It should describe:

  • What the function does.
  • Parameters (type, meaning).
  • Return value (type, meaning).
  • Optionally, an example.

Tools like help() and Sphinx use docstrings to generate documentation.

def moment_simply_supported(load, span):
    """
    Calculate maximum bending moment for a simply supported beam
    under uniformly distributed load.

    Parameters:
        load (float): UDL in kN/m
        span (float): span length in metres

    Returns:
        float: maximum moment in kNm
    """
    M = load * span**2 / 8
    return M

3. Code Examples

Example 1: Function library for beam analysis

def moment_udl(load, span):
    """Maximum moment for simply supported beam with UDL (kNm)."""
    return load * span**2 / 8

def shear_udl(load, span):
    """Maximum shear force for simply supported beam with UDL (kN)."""
    return load * span / 2

def deflection_udl(load, span, E, I):
    """Maximum deflection (mm) for simply supported beam with UDL."""
    # Using formula: 5*w*L^4 / (384*E*I) – units consistent
    # Assume load in kN/m, span in m, E in MPa, I in mm^4
    # Convert to N and mm: w = load * 1000 N/m, L = span * 1000 mm
    w = load * 1000        # N/m
    L = span * 1000        # mm
    d = 5 * w * L**4 / (384 * E * I)
    return d

# Usage
L = 6.0      # m
w = 20.0      # kN/m
E = 200000    # MPa (steel)
I = 120e6     # mm^4 (say a UB section)

M = moment_udl(w, L)
V = shear_udl(w, L)
d = deflection_udl(w, L, E, I)

print(f"Max moment: {M:.2f} kNm")
print(f"Max shear: {V:.2f} kN")
print(f"Max deflection: {d:.2f} mm")

Example 2: U‑value check function

def u_value_check(actual_u, max_u=0.28):
    """
    Check if a building element meets U-value requirement.

    Parameters:
        actual_u (float): measured U-value (W/m²K)
        max_u (float): maximum allowed (default 0.28)

    Returns:
        bool: True if passes, False otherwise
        str: message
    """
    if actual_u <= max_u:
        return True, f"PASS: U={actual_u:.3f} ≤ {max_u:.3f}"
    else:
        return False, f"FAIL: U={actual_u:.3f} > {max_u:.3f}"

# Use it
pass_flag, msg = u_value_check(0.25)
print(msg)

pass_flag, msg = u_value_check(0.35)
print(msg)

Example 3: Geometry helper – moment of inertia for a rectangle

def i_rect(b, h):
    """
    Second moment of area (I) for a rectangular section.

    I = b * h³ / 12

    Parameters:
        b (float): width (mm)
        h (float): depth (mm)

    Returns:
        float: I in mm⁴
    """
    return b * h**3 / 12

# Example: 200 x 400 beam
b = 200
h = 400
I = i_rect(b, h)
print(f"I = {I:.0f} mm⁴")

4. Hands‑on Exercises (3–5 Problems)

Problem 1 – Area and perimeter of a rectangle
Define a function rect_props(length, width) that returns both area and perimeter.
Call it for a room 8 m × 5 m and print the results.

Problem 2 – Concrete volume in a slab
Write a function slab_volume(length, width, thickness) that returns the volume.
Then create a second function slab_cost(volume, rate_per_m3) that returns cost.
Ask the user for inputs, call both functions, and print the total cost.

Problem 3 – Beam classification function
Write a function classify_beam(depth) that returns a string:

  • depth < 200 → "Light beam"
  • 200 ≤ depth < 400 → "Medium beam"
  • depth ≥ 400 → "Heavy beam"

Test it with several depths.

Problem 4 – Maximum of three values (reusable)
Write a function max_three(a, b, c) that returns the largest of three numbers.
Test with loads 45, 78, 62 (kN).
Do not use the built-in max() – implement your own logic using if.

Solutions (attempt first):

# P1
def rect_props(L, W):
    area = L * W
    perimeter = 2 * (L + W)
    return area, perimeter

a, p = rect_props(8, 5)
print(f"Area: {a} m², Perimeter: {p} m")

# P2
def slab_vol(L, W, t):
    return L * W * t

def slab_cost(vol, rate):
    return vol * rate

L = float(input("Length (m): "))
W = float(input("Width (m): "))
t = float(input("Thickness (m): "))
rate = float(input("Rate ($/m³): "))
vol = slab_vol(L, W, t)
cost = slab_cost(vol, rate)
print(f"Volume: {vol:.2f} m³, Cost: ${cost:.2f}")

# P3
def classify_beam(d):
    if d < 200:
        return "Light beam"
    elif d < 400:
        return "Medium beam"
    else:
        return "Heavy beam"

for d in [150, 250, 450]:
    print(f"Depth {d}mm: {classify_beam(d)}")

# P4
def max_three(a, b, c):
    if a >= b and a >= c:
        return a
    elif b >= a and b >= c:
        return b
    else:
        return c

print(max_three(45, 78, 62))   # 78

5. Applied Challenge Task

Task: Build a Beam Design Functions Module

Create a script that contains the following functions (all well‑documented with docstrings):

  1. section_modulus_rect(b, h) – returns elastic section modulus S (mm³).

  2. moment_udl(load, span) – returns max bending moment (kNm).

  3. shear_udl(load, span) – returns max shear force (kN).

  4. required_section_modulus(M, fy) – returns required S (mm³) given moment in kNm and yield stress in MPa (use allowable stress = 0.6 * fy).

  5. check_beam(depth, span, load, fy) – main orchestrator that:

    • Calls moment_udl, required_section_modulus.
    • Assuming a rectangular section with width = depth/2, computes the actual S.
    • Prints whether the section is adequate.

Then write the main part of the script that asks the user for depth, span, load, and fy, calls check_beam(), and prints a summary.

Why this matters:
You are building a small but realistic design‑aid tool. The functions can later be imported into other scripts or expanded with a GUI. This is the foundation of professional‑grade AEC automation.


6. Brief Review Summary

  • Functions encapsulate logic for reuse – def name(params):.
  • Local variables exist only inside the function; global variables are accessible everywhere.
  • return sends a result back; functions can return multiple values (as a tuple).
  • Docstrings ("""...""") document what a function does – essential for professional code.
  • Modular functions make AEC calculations easier to test, share, and maintain.

Key takeaway:
Functions transform your scripts from linear procedures into organised, reusable tools. This is how professional AEC software libraries are built – one well‑defined function at a time.


7. Preview of Next Topic (Day 6)

Tomorrow we’ll explore Lists, Tuples, and Basic Operations.
You’ll learn:

  • How to store ordered collections of data (e.g., list of column loads, coordinates of a polyline).
  • Indexing, slicing, and common list methods.
  • Tuples as immutable sequences (e.g., storing a point (x, y, z)).
  • Practical AEC examples: storing material properties in a list, iterating over a nested list of coordinates.

Lists are the foundation of handling datasets in Python – from structural members to room coordinates.

 

*** If you want to continue please hit the Subscribe page , and leave a comment below with the title Continue. 

 

Comments

EARN AT THE COMFORT OF YOUR HOME

Sponsored content

Popular posts from this blog

Day 10 – Exception Handling and Debugging

Day 1 – Python Foundations for AEC Professionals