Lesson 1

Overview

What a function is

A function packages logic into a reusable unit. Instead of repeating the same code over and over, you give the logic a name and call it when needed.

def greet(name):
	return f"Hi {name}"

greet("Ali") -> "Hi Ali"

What you will learn

  • How `def`, calls, and `return` really behave
  • Parameters, arguments, defaults, and keywords
  • `*args`, `**kwargs`, positional-only, keyword-only
  • Local, global, and nonlocal scope
  • Functions as values, closures, lambda, docstrings

With functions vs without functions


							

Lesson 2

Define, Call, Return

The smallest useful function

def square(x):
	return x * x

result = square(4)

`def`

Defines a function object and binds it to a name. The body is not executed yet.

Call

Calling the function creates a fresh local scope, binds arguments to parameters, and runs the body.

`return`

Ends the function and sends a value back. If you return nothing, Python returns `None`.

Important rule

def make_message():
	text = "hello"
	print(text)

value = make_message()

print(value)  -> None

`print()` shows something on screen. `return` gives a value back to the caller. Beginners mix these up a lot.

Step through a function call


								

Lesson 3

Parameters and Arguments

Parameter names vs argument values

def greet(name, greeting="Hello"):
	return f"{greeting}, {name}"

greet("Ali")
greet("Ali", "Hi")
greet(name="Ali", greeting="Hey")

Parameters live in the function definition. Arguments are the actual values you pass during the call.

Argument binding lab

def greet(name, greeting="Hello"):
	return f"{greeting}, {name}"
Choose a call and I will show how Python matches values to parameters.

Common trap

Default values are evaluated once when the function is defined, not every time it is called. Mutable defaults such as `[]` often cause bugs.

Lesson 4

Advanced Parameters

`*args`

Collects extra positional arguments into a tuple.

def add_all(*args):
	return sum(args)

`**kwargs`

Collects extra keyword arguments into a dictionary.

def show(**kwargs):
	return kwargs

`/` and `*`

`/` marks positional-only parameters. `*` marks the start of keyword-only parameters.

def mix(a, /, b, *, c):
	return a, b, c

Signature explorer

Select a signature pattern to see what it means and why it exists.

Lesson 5

Scope Rules

How Python finds names

Python usually searches names in this order:

local -> enclosing -> global -> builtins

This is often called LEGB.

Most function confusion comes from not knowing which scope owns a name.

Scope simulator

spam = "global spam"

def outer():
	spam = "outer spam"

	def inner():
		...

	inner()
Choose a scope rule to see what changes.

Honest advice: avoid `global` unless you really need module state. `nonlocal` is more reasonable for closures, but still use it carefully.

Lesson 6

Functions as Values

Functions are objects too

def shout(text):
	return text.upper()

alias = shout
print(alias("hi"))

In Python, functions can be stored in variables, passed into other functions, returned from functions, and kept in data structures.

Patterns explorer

Select a pattern to see how function objects are used in real code.

Lambda

pairs = [(1, "b"), (2, "a")]
sorted_pairs = sorted(pairs, key=lambda pair: pair[1])

`lambda` creates a small anonymous function. It is best for tiny expressions, not for complex logic.

Opinionated rule: if the logic deserves a name or spans more than one small expression, write a normal `def`.

Lesson 7

Helpful Tools

Docstrings

The first string inside a function becomes its documentation string.

def add(a, b):
	"""Return the sum of two numbers."""
	return a + b

Annotations

Type annotations describe intended types, but they do not enforce types by themselves.

def add(a: int, b: int) -> int:
	return a + b

Decorators and `yield`

Decorators wrap or modify functions. `yield` turns a function into a generator.

@debug
def run():
	yield 1

Flip cards

Lesson 8

Practice and Quiz

Mini practice

1. Write a function `double(x)` that returns `x * 2`.

2. Write `describe(name, job="developer")`.

3. Write `make_multiplier(n)` that returns a function remembering `n`.

Quick quiz

Answer the quiz and check your score.

Reference

Cheat Sheet

Fast syntax

def greet(name, greeting="Hello"):
	return f"{greeting}, {name}"

def collect(*args, **kwargs):
	return args, kwargs

def mix(a, /, b, *, c):
	return a, b, c

Remember this

  • `def` creates a function object
  • `return` gives a value back; `print` only displays
  • Defaults are evaluated once at definition time
  • Scope usually follows local -> enclosing -> global -> builtins
  • Functions can be passed, returned, and stored

Authority

Sources