Loading

What Is a Function?

Imagine a vending machine in your college canteen. You put in Rs. 20 (the input), press the button for chai (the instruction), and out comes a cup of chai (the output). The machine does the same thing every time, for anyone who uses it. You do not need to understand the heating coil and the mixing mechanism — you just use it.

A function in Python is the same idea. You write the logic once, give it a name, and then call that name whenever you need the result. The rest of your code does not need to care about how it works internally.

Key Idea

Functions solve two major problems: (1) repetition — you write logic once instead of copying and pasting it everywhere, and (2) organisation — a 200-line program broken into named functions is far easier to read and fix than 200 lines in a single block.

Defining and Calling a Function

Use the def keyword. Everything indented below the def line is the function body. The function does nothing until you call it by name.

Python — defining and calling functions
# Function with no parameters (no input needed) def greet(): print("Hello from Quadratech Academy!") print("Welcome to Python 103.") # Calling the function: greet() # Output: Hello from Quadratech Academy! ... greet() # Call it again — runs the same code again greet() # And again

Functions with Parameters

Parameters are the inputs your function accepts — like pressing different buttons on the vending machine.

Python — function with parameters
# Function with one parameter def greet_student(name): print(f"Hello, {name}! Welcome to Python class.") greet_student("Arjun") # Hello, Arjun! Welcome to Python class. greet_student("Meera") # Hello, Meera! Welcome to Python class. # Function with multiple parameters and a return value def add(a, b): result = a + b return result # Send the answer back to whoever called us total = add(15, 27) print(total) # 42

A Real Example — Percentage Calculator

Python — calculate_percentage function
def calculate_percentage(obtained, total): if total == 0: return 0 # Avoid division by zero percentage = (obtained / total) * 100 return round(percentage, 2) # round to 2 decimal places # Use it for different students: print(calculate_percentage(427, 500)) # 85.4 print(calculate_percentage(312, 400)) # 78.0 print(calculate_percentage(180, 600)) # 30.0
Try This

Write a function called is_prime(n) that returns True if n is a prime number and False if it is not. Then use a for loop with range(2, 50) and call your function to print all prime numbers between 2 and 49.

Parameters and Return Values

Functions become much more powerful when you understand the different ways to pass inputs and get outputs back.

Keyword Arguments

Normally you pass arguments in order. With keyword arguments, you name them — so order doesn't matter and the code is self-documenting.

Python — positional vs keyword arguments
def display_student(name, branch, year): print(f"Name: {name} | Branch: {branch} | Year: {year}") # Positional — must be in the right order display_student("Ravi", "ECE", 3) # Keyword — order doesn't matter display_student(branch="CSE", year=2, name="Sneha")

Default Parameter Values

Set a default value for a parameter. If the caller doesn't provide it, the default is used. Like a photocopy shop — if you don't specify single-sided or double-sided, they default to single-sided.

Python — default parameters
def calculate_cgpa(marks_list, scale=10): # scale defaults to 10 if not provided total = sum(marks_list) out_of = len(marks_list) * scale return round((total / out_of) * scale, 2) # 10-point scale (uses default) print(calculate_cgpa([8, 7, 9, 8, 7])) # 7.8 # 4-point scale (overrides default) print(calculate_cgpa([3.5, 3.7, 4.0], scale=4)) # 3.73

Returning Multiple Values

Python functions can return multiple values as a tuple. Unpack them directly into separate variables.

Python — returning multiple values
def area_and_perimeter_rectangle(length, width): area = length * width perimeter = 2 * (length + width) return area, perimeter # Python packs these as a tuple # Unpack both return values at once: a, p = area_and_perimeter_rectangle(8, 5) print(f"Area: {a} sq units") # Area: 40 sq units print(f"Perimeter: {p} units") # Perimeter: 26 units

Area Calculators — A Complete Example

Python — area calculator for multiple shapes
import math # We'll cover this properly in the Modules section def area_circle(radius): return round(math.pi * radius ** 2, 4) def area_rectangle(length, width): return length * width def area_triangle(base, height): return 0.5 * base * height # Use them all: print("Circle (r=7):", area_circle(7)) # 153.9380 print("Rectangle (4x6):", area_rectangle(4, 6)) # 24 print("Triangle (b=10,h=8):", area_triangle(10, 8)) # 40.0
Common Mistake — Forgetting return

A function without a return statement returns None by default. If you write result = my_function() and the function only prints the answer instead of returning it, result will be None. Always decide: should this function print the answer, or return it so the caller can use it?

Scope — Who Can See What?

Think about your college. Some information is private to your classroom — the attendance register only your class teacher has. Some information the whole college can see — the notice board. Variables in Python work the same way. Where you create a variable determines who can access it.

Local Scope — Inside the Classroom

A variable created inside a function exists only while that function is running. Once the function finishes, the variable is gone. Other functions cannot see it.

Python — local scope
def calculate_tax(income): tax_rate = 0.20 # local variable — only visible inside this function tax = income * tax_rate return tax result = calculate_tax(50000) print(result) # 10000.0 # This would cause an error: # print(tax_rate) # NameError: name 'tax_rate' is not defined

Global Scope — The Notice Board

A variable created outside all functions is global — every function can read it. But to modify it inside a function, you need to declare it with the global keyword.

Python — global scope and the global keyword
passing_marks = 40 # global variable — everyone can read this def check_result(marks): if marks >= passing_marks: # reading global variable — fine return "PASS" return "FAIL" print(check_result(55)) # PASS print(check_result(32)) # FAIL # Modifying a global variable: student_count = 0 def register_student(): global student_count # tell Python we mean the global one student_count += 1 register_student() register_student() register_student() print("Students registered:", student_count) # 3
Key Idea — Why Scope Matters

Scope prevents functions from accidentally overwriting each other's variables. If every variable were global, a bug in one function could corrupt data used by another function — and tracking down such bugs is a nightmare. Keep variables as local as possible. Only use global when you genuinely need shared state across multiple functions.

Common Mistake — Shadowing

If you create a local variable with the same name as a global one, Python uses the local version inside the function. The global is untouched. This is called "shadowing" and can cause confusing behaviour. Example: if marks = 90 globally and you write marks = 50 inside a function (without global), the global stays 90. Use distinct names to avoid confusion.

Modules — Borrowing Other People's Work

When an electrician comes to fix wiring in your house, they don't manufacture their own screwdrivers and wire cutters from scratch. They go to the hardware shop and pick up the tools they need. Python has a massive hardware shop called its standard library — hundreds of modules (collections of pre-written functions) ready for you to import and use.

import math — Mathematics Done Right

Python — math module
import math print(math.pi) # 3.141592653589793 print(math.e) # 2.718281828459045 (Euler's number) print(math.sqrt(144)) # 12.0 — square root print(math.pow(2, 10)) # 1024.0 — 2 to the power 10 print(math.floor(9.7)) # 9 — round down print(math.ceil(9.2)) # 10 — round up print(math.factorial(5)) # 120 — 5! = 5×4×3×2×1 print(math.log(100, 10)) # 2.0 — log base 10 of 100 # Trigonometry (angles in radians): angle_degrees = 30 angle_radians = math.radians(angle_degrees) print(math.sin(angle_radians)) # 0.5 print(math.cos(angle_radians)) # 0.866...

import random — Randomness for Simulations and Games

Python — random module
import random # Random integer between 1 and 6 (like a dice roll): dice = random.randint(1, 6) print("Dice:", dice) # Random float between 0 and 1: probability = random.random() print("Probability:", probability) # Pick a random item from a list: students = ["Arjun", "Meera", "Ravi", "Sneha", "Kiran"] selected = random.choice(students) print("Today's presenter:", selected) # Shuffle a list in place (like shuffling a deck of cards): random.shuffle(students) print("New order:", students)

import datetime — Working with Dates and Times

Python — datetime module
import datetime now = datetime.datetime.now() print("Current date and time:", now) print("Year:", now.year) print("Month:", now.month) print("Day:", now.day) print("Hour:", now.hour) # Format date as a readable string: formatted = now.strftime("%d %B %Y, %I:%M %p") print("Formatted:", formatted) # e.g. 08 May 2026, 10:30 AM # Calculate how many days until an event: exam_date = datetime.date(2026, 6, 15) today = datetime.date.today() days_left = (exam_date - today).days print(f"Days until exam: {days_left}")

from module import function — Import Specific Things

Instead of importing the whole module and typing math.sqrt(), you can import just the function you need and call it directly.

Python — selective imports
from math import sqrt, pi, sin, cos, radians # Now use them directly without the "math." prefix: print(sqrt(256)) # 16.0 print(pi) # 3.141592653589793 print(sin(radians(90))) # 1.0 # You can also give imports an alias: from datetime import datetime as dt print(dt.now().strftime("%H:%M")) # Current time like "14:35"
Try This — Scientific Calculator

Build a function called scientific_calc() that asks the user to choose an operation (sqrt, power, sin, cos, log) and the required input(s), then prints the result using the math module. Wrap the whole thing in a while True loop with an "Exit" option.

Creating Your Own Module

Here is where it all comes together. Instead of copying your useful functions into every new project, you can save them in a separate .py file and import them exactly like you import math or random.

Step 1 — Create the Module File

Save this as quadratech_utils.py in the same folder as your main program.

quadratech_utils.py — your personal utility module
# quadratech_utils.py # A collection of useful academic helper functions def calculate_percentage(obtained, total): """Calculate percentage from marks obtained and total marks.""" if total == 0: return 0.0 return round((obtained / total) * 100, 2) def grade_from_marks(percentage): """Return letter grade from a percentage score.""" if percentage >= 90: return "A+" elif percentage >= 80: return "A" elif percentage >= 70: return "B" elif percentage >= 60: return "C" elif percentage >= 40: return "D" else: return "F" def cgpa_to_percentage(cgpa, scale=10): """Convert CGPA on a given scale to percentage. Common formula used by many Indian universities: percentage = (CGPA / scale) * 100 For some universities: percentage = CGPA * 9.5 """ return round((cgpa / scale) * 100, 2) def is_passed(percentage, passing_percentage=40): """Check if a student has passed based on their percentage.""" return percentage >= passing_percentage # This block only runs when you execute THIS file directly, # not when you import it from somewhere else: if __name__ == "__main__": print("Testing quadratech_utils module...") print(calculate_percentage(427, 500)) # 85.4 print(grade_from_marks(85.4)) # A print(cgpa_to_percentage(8.5)) # 85.0 print(is_passed(85.4)) # True print(is_passed(35.0)) # False print("All tests passed.")

Step 2 — Import and Use Your Module

Now in your main program file (in the same folder), import it:

main_program.py — using your custom module
import quadratech_utils as qt # import with a short alias # Process results for a class of students: class_results = [ {"name": "Arjun", "obtained": 427, "total": 500}, {"name": "Meera", "obtained": 312, "total": 500}, {"name": "Ravi", "obtained": 189, "total": 500}, {"name": "Sneha", "obtained": 461, "total": 500}, ] print("=" * 50) print(f"{'Name':<12} {'%':>6} {'Grade':>6} {'Status':>8}") print("=" * 50) for student in class_results: pct = qt.calculate_percentage(student["obtained"], student["total"]) grade = qt.grade_from_marks(pct) status = "PASS" if qt.is_passed(pct) else "FAIL" print(f"{student['name']:<12} {pct:>6.1f} {grade:>6} {status:>8}") print("=" * 50)

The __name__ == "__main__" Pattern Explained

When Python runs a file directly, it sets a special variable __name__ to the string "__main__". When Python imports that file as a module, __name__ is set to the file's name instead.

Key Idea

The if __name__ == "__main__": guard lets you write test code inside your module file that only runs when you execute the file directly. When someone imports your module, the guard code is skipped — which is the correct behaviour. Every module you create should have this guard.

Try This — Extend Your Module

Add a function called cgpa_to_percentage_anna(cgpa) to quadratech_utils.py that uses Anna University's formula: percentage = cgpa * 10 - 0.75 * (10 - cgpa). Then add a function sgpa_to_cgpa(sgpa_list) that takes a list of semester GPAs and returns the overall CGPA as their average. Test both in the if __name__ == "__main__" block.

Series Complete
You've finished Python Basics 101–103

You now know variables, data types, operators, if/else, loops, lists, functions, scope, and modules. That is the complete foundation. You can write real, useful programs. The next step is to apply it in a real engineering context — Python for data analysis, sensor processing, or automation.

← Previous
Python 102: Control Flow & Loops
Up Next →
Explore More Study Materials