A function is a reusable named block of code. You define it once, call it many times.
Parameters vs Arguments: Parameters are the variable names in the def line. Arguments are the actual values you pass when calling the function. They're often used interchangeably in conversation.
A function can send a value back to the caller using return. Without it, the function returns None.
Variables created inside a function are local - they only exist while the function runs. Variables outside functions are global.
Avoid globals: Passing values via parameters and return values makes code easier to test and reason about. Using global keyword to modify globals from inside functions is a sign of poor design.
Default arguments make parameters optional. Keyword arguments let you specify them by name in any order.
Write a function that returns True if a string reads the same forwards and backwards.
s[::-1] reverses a string using slice notation (start:stop:step, with step -1 going backwards). Lowercasing and removing spaces handles "A man a plan a canal Panama".
Write a function that converts Celsius to Fahrenheit, with an optional decimals parameter (default 1) controlling how many decimal places to return.
Write a recursive function that computes n! (n factorial). Recall: 5! = 5 * 4 * 3 * 2 * 1 = 120. Base case: 0! = 1.
factorial(5) calls factorial(4) which calls factorial(3)... down to factorial(0) which returns 1. Then each call multiplies back up: 1 * 1 = 1, 2*1=2, 3*2=6, 4*6=24, 5*24=120.
What does a function return if it has no return statement?
In Python, a function with no return statement (or just return) implicitly returns None, not 0.
None is Python's null value. An empty string '' has type str. Functions with no return give None.
None is Python's way of saying 'no value'. It's distinct from False, 0, or ''.
Where does a local variable exist?
Local variables only live inside the function that created them. They're destroyed when the function returns.
Unlike some languages, Python if/for/while blocks do NOT create a new scope. Only functions (and classes/modules) create scope boundaries.
Local variables belong to the function's scope. Multiple functions can each have their own local variable named 'x' without conflict.
Which call uses a keyword argument?
Positional arguments are matched by position. Keyword arguments explicitly name the parameter: greet(name='Alice').
greet() with empty parens passes nothing. A keyword argument names the parameter explicitly.
*args unpacks a sequence as positional arguments. Keyword arguments use name=value syntax.
What is the output? def f(x, y=2): return x * y then print(f(3))
y has a default value of 2. Calling f(3) means x=3, y=2. Result: 3*2=6.
Default arguments make parameters optional. y=2 means you don't have to pass y.
The function returns x*y = 3*2 = 6, not just y's value.
A recursive function must have:
Recursion works through the call stack. No global variable is needed.
Recursion replaces loops - you don't need both. Recursion calls itself instead of using a loop.
Recursive functions can have any number of parameters. The essential requirement is a base case.