Functions: Beginner
GitHub's entire pull request diff engine is built from composable functions that transform raw text into highlighted, reviewable code viewed by 100 million developers. Every feature at GitHub - from code review to Actions workflows to Dependabot alerts - is composed of small functions that each do one thing well and pass results to the next. The power of that architecture starts with exactly what this lesson teaches: how to define a function, give it inputs, and get a result back.
Defining with def
Create reusable code blocks with def
A function is a named block of code that performs a specific task. Think of it as a mini-program within your program that you can run whenever you need it. You create a function using the def keyword, which is short for "define." After def, you write the function name, followed by parentheses and a colon. All the code that belongs to the function must be indented beneath the definition line. This indented block is called the function body.
Pay close attention to the execution order in the output above. The code inside greet() only runs when you explicitly call the function with parentheses. Defining a function is like writing a recipe and putting it in a cookbook. Calling the function is like actually following that recipe to cook the dish. You can define a function once and call it as many times as you need throughout your program.
Why Use Functions?
Function Naming Conventions
Function names follow the same rules as variable names in Python. They must start with a letter or underscore, can contain only letters, numbers, and underscores, and cannot be reserved Python keywords like if, for, or class. Beyond these technical requirements, there are strong community conventions that make code more readable and professional.
- calculate_total_revenue
- validate_email_address
- format_user_record
- parse_json_response
- clean_transaction_data
- doStuff
- func1
- myFunction
- process
- x
Good function names use lowercase letters with words separated by underscores, a style called snake_case. They use verbs or verb phrases that describe what the function does. A developer reading calculate_total_revenue immediately understands the purpose without examining the code inside. Poor names like doStuff or func1 force readers to study the implementation to understand what the function does, wasting time and causing confusion.
Indentation: Function Body
> Define a simple function and call it twice. Pick the keyword that starts a function definition, and the built-in that displays text to the console.
greet(): ("Hello, World!") greet() greet()
Reusing Functions
Notice how we defined print_separator once but called it six times through announce_section. If we want to change the separator character from equals signs to dashes, we modify one line in print_separator, and all six uses update automatically. This is the fundamental value of functions: change once, benefit everywhere.
Parameters and Arguments
Pass data into functions flexibly
- Parameters are the variable names in the function definition
- Arguments are the actual values you pass when calling the function
- Each argument value gets assigned to its corresponding parameter
When you call greet_user("Alice"), Python creates a local variable named name and assigns the value "Alice" to it. Inside the function body, name behaves like any other variable, holding that value for the duration of this particular call. When the function finishes, that local variable is destroyed. The next call creates a fresh variable with whatever new value you pass.
Multiple Parameters
Data Engineering Example
- Wrap repeated logic in a named function
- Use consistent formatting via a single function
- Change behavior by editing one function definition
- Copy and paste the same code in multiple places
- Format output differently in every location
- Hunt down every copy when fixing a bug
Wrong Number of Arguments
Named Arguments
> Build a function that joins a name and age into a descriptive string. Pick the function that converts a number to text for concatenation, and the parameter that holds the person's name.
def describe(name, age): return + " is " + (age) print(describe("Alice", 28))
Return Values
Send computed results back to callers
Functions become truly powerful when they can send data back to the caller. The return statement lets a function produce a result that you can store in a variable, use in calculations, pass to other functions, or include in expressions. Return values transform functions from actions that just do things into calculators that compute and deliver usable results.
The return statement immediately exits the function and sends the specified value back to where the function was called. That returned value effectively replaces the function call in your code. In the expression calculate_area(20, 15) * cost_per_sqft, Python first calls the function to get 300, then multiplies 300 by 25 to get 7500.
Return vs Print: Key Diff
One of the most common sources of confusion for beginners is the difference between print() and return. They seem similar because both involve outputting information, but they serve completely different purposes. Understanding this distinction is essential for writing useful functions that work correctly in larger programs.
- Displays text on the screen
- For human eyes only
- Function still returns None
- Cannot use the output in code
- Side effect for debugging or UI
- Sends value back to caller
- For program consumption
- Value can be stored and reused
- Enables further calculations
- Produces actual function result
Look carefully at the output. add_with_print displays 15 on the screen, but when we store the result, we get None. We cannot do math with None. Meanwhile, add_with_return does not display anything itself, but the returned value 15 can be stored, multiplied, added, or used in any way we need.
- Use return to produce values your program needs
- Store returned values in variables for later use
- Use print() only for debugging or user-facing output
- Use print() when you need to use the result in code
- Forget that print() makes the function return None
- Mix up displaying data with computing data
Return Exits Immediately
When Python executes a return statement, it immediately exits the function. Any code after the return statement never runs. This behavior is useful for early exits when you have already determined the result and do not need to continue processing.
Try changing the return keyword below to see how it affects function behavior. What happens when you use print instead of return?
> A double function computes n * 2, and the caller stores the result. Pick whether to use return or print inside the function and see what the caller actually receives.
def double(n): n * 2 result = double(5) print(result)
Functions Without Return
If a function has no return statement, or uses return without a value, Python automatically returns None. None is a special Python value that represents "nothing" or "no value." Functions that return None are used for their side effects, like printing output, writing files, or modifying data structures.
Calling and Storing
Chain function calls into pipelines
Function calls can appear anywhere Python expects a value: on the right side of an assignment, inside print(), as an argument to another function, or as part of an arithmetic expression. Python evaluates the function call first, gets the returned value, and then uses that value in the surrounding expression.
Functions Calling Functions
Real Data Pipeline Pattern
Function Reference vs Call
There is an important distinction between a function reference and a function call. Writing my_func without parentheses gives you the function object itself, which you can pass around or inspect. Writing my_func() with parentheses actually executes the function and gives you its return value.
Docstrings
Document functions for team clarity
The docstring appears immediately after the function definition, enclosed in triple quotes. Python stores it in the __doc__ attribute. IDEs show docstrings when you hover over function names, and tools like help() display them. This makes docstrings a powerful form of inline documentation that stays with the code.
Docstring Conventions
Simple One-Line Docstrings
Why Docstrings Matter
Common Mistakes
Forgetting to Call Function
- def process_data():
- print("Processing...")
- clean_records()
- # Function defined but never called
- # Nothing happens when you run this!
- def process_data():
- print("Processing...")
- clean_records()
- process_data() # Call the function!
- # Now it actually runs
Forgetting return Statement
- def calculate_total(a, b):
- result = a + b
- # Forgot to return!
- total = calculate_total(5, 3)
- # total is None, not 8
- def calculate_total(a, b):
- result = a + b
- return result
- total = calculate_total(5, 3)
- # total is 8
Calling Before Defining
print vs return Mistake
> This add function computes the sum correctly but has an unnecessary print statement that uses invalid syntax. Remove it so the function cleanly returns the result.
The function prints AND returns. Remove the unnecessary print tile.
Object vs Call Confusion
- result = calculate_tax(100)
- greeting = get_greeting("Alice")
- print(format_record(data))
- result = calculate_tax # Function object!
- greeting = get_greeting # Missing parens!
- print(format_record) # Reference only!
> You are a junior data engineer at Stripe refactoring a 200-line data processing script into named functions so your team can reuse individual transformation steps across multiple payment pipelines.
def packages each transformation step into a named unit so it can be called from any pipeline without copy-pasting logic.return sends the transformed result back to the caller for storage, further processing, or downstream pipeline stages.def to define functions that package reusable code blocksreturn sends a value back to the caller; without it, the function returns Nonereturn for computed values programs needWrite once, use everywhere
- Category
- Python
- Difficulty
- beginner
- Duration
- 38 minutes
- Challenges
- 0 hands-on challenges
Topics covered: Defining with def, Parameters and Arguments, Return Values, Calling and Storing, Docstrings
Lesson Sections
- Defining with def (concepts: pyFuncDef)
Why Use Functions? Before diving deeper into function syntax, it is important to understand why functions matter so much in professional software development. Consider a data pipeline that processes customer orders. Without functions, you might write the same validation logic in dozens of places: check if the order ID is valid, verify the customer exists, confirm the product is in stock, calculate taxes, and format the receipt. Each copy is an opportunity for bugs and inconsistencies. Function N
- Parameters and Arguments (concepts: pyArgs)
Most useful functions need input data to work with. A function that calculates tax needs to know the price. A function that formats a name needs to know the name. A function that validates an email needs the email address to check. Parameters are variables that you define in the function signature to receive these input values. When you call the function, you provide arguments, which are the actual values that get assigned to those parameters. Multiple Parameters Functions frequently need multip
- Return Values (concepts: pyFuncDef)
Return vs Print: Key Diff Return Exits Immediately Each condition checks the score and returns immediately when it matches. For a score of 82, Python checks if it is invalid (no), then checks if it is 90 or above (no), then checks if it is 80 or above (yes), and immediately returns "B - Good". It never checks the remaining conditions. This pattern is efficient and easy to read. Functions Without Return
- Calling and Storing (concepts: pyFuncDef)
Defining a function creates it but does not execute it. The function body only runs when you explicitly call the function by writing its name followed by parentheses containing any required arguments. You can call a function as many times as needed, and each call is independent. The results can be used directly, stored in variables, or passed to other functions. Functions Calling Functions Functions can call other functions. This is how you build complex programs from simple, well-tested pieces.
- Docstrings (concepts: pyFuncDef)
When you work on a team or return to your own code after weeks or months, documentation becomes essential. Python provides docstrings, which are special strings that describe what a function does, what parameters it expects, and what it returns. Docstrings are written as the first statement in a function body using triple quotes, and Python stores them for tools and developers to access. Docstring Conventions While Python does not enforce a specific docstring format, several conventions are wide