A science club receives temperatures in Celsius, but its display needs Fahrenheit. Your challenge is to build one converter tool, call it with several temperatures, and trust it to give a usable result every time.
By Lesson 3, you will package calculations and even a turtle polygon into tools with their own inputs and local names.
-
Define and call a reusable function with
def. -
Give a function inputs through parameters and send a value back with
return. -
Use built-in number tools for common calculations.
-
Tell which names belong inside a function and which result the caller receives.
-
Lesson 1: Define & Call
A science club receives Celsius readings and needs one reusable Fahrenheit tool. First, see how a function is defined and called.
Functions that only print
Define
greetwith no parameters. Its indented body runs only when you call it.def greet(): print("Hello!") greet()Scroll the code for more ↓
Output
Hello!Defining the function displays nothing. The call displays
Hello!. This function prints but returns no useful value.Now give
greetone parameter. The caller supplies a name for that local value.def greet(name): print("Hello, " + name + "!") greet("Maya")Scroll the code for more ↓
Output
Hello, Maya!The call displays
Hello, Maya!.namereceives the argument for this call; the function still only prints.Build the temperature-converter tool
A function is a named tool. This time it sends a result back with
return. The input is a Celsius temperature, and the returned result is Fahrenheit.def celsius_to_f(c): fahrenheit = c * 9 / 5 + 32 return fahrenheit print(celsius_to_f(-10)) print(celsius_to_f(0)) print(celsius_to_f(25))Scroll the code for more ↓
Output
14.0 32.0 77.0Visible payoff: one tool handles several inputs. The three calls return
14.0,32.0, and77.0. The/calculation makes each result a float.Read the definition from top to bottom:
-
deftells Python that a function definition starts. -
celsius_to_fis the function's meaningful name. -
cis a parameter, a local name that receives one call's input. -
The indented lines are the function body.
-
return fahrenheitsends the computed value back to the caller.
The definition stores the tool. A call such as
celsius_to_f(25)uses it.-
Small tools with one clear job
A function can return an integer or a boolean just as it can return a float. These two tools name their jobs and their inputs.
def square(n): result = n * n return result def is_even(n): return n % 2 == 0 print(square(5)) print(is_even(14)) print(is_even(9))Scroll the code for more ↓
Output
25 True Falsesquare(5)returns the integer25.is_even(14)returnsTrue, whileis_even(9)returnsFalse. The caller decides whether to print, save, compare, or calculate with a returned value.Notice: printing is not returning
This function displays a number, but it does not return that number. Predict what happens when the caller tries to add 1 to the missing result.
Error demo: this code stops with an error def f(n): print(n * n) total = f(3) + 1 print(total)Scroll the code for more ↓
Python first prints
9, then reports:TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'Read the last line first. The
+operation received aNoneTypevalue and an integer. A function with noreturngives backNone, which means no useful value was returned. The caller cannot add 1 to that missing value.Fix the boundary: let the function return its result, then let the caller choose to print or calculate with it.
def f(n): return n * n total = f(3) + 1 print(total)Scroll the code for more ↓
Output
10The fixed call produces
10.printsends text to the screen;returnsends a value to the caller. Exercise 2 is the one practice item pinned to this trap. In your other functions, focus on the value promised by the specification.Try a real temperature
This interactive version reads one Celsius value, calls the converter, and displays its result.
Try it celsius = float(input("Celsius: ")) print(celsius_to_f(celsius))Scroll the code for more ↓
Lesson 2: Functions that Compute
A number-puzzle table needs four reusable tools: test a prime, find a shared divisor, produce a Fibonacci number, and total the integers through a chosen endpoint. Each tool hides a loop behind a name and returns one answer.
Leave early with
returnfirst_multiple(start, k)searches fromstartupward. The first matching number is returned immediately; the loop does not keep searching.def first_multiple(start, k): number = start while True: if number % k == 0: return number number = number + 1 print(first_multiple(10, 4))Scroll the code for more ↓
Output
12The result is
12. Oncereturnruns, the function is finished; later loop trips do not happen.Test whether a number is prime
For
n >= 2, try possible divisors from 2 throughn - 1. The loop counterdivisornames the number currently being tested. A divisor that leaves remainder 0 proves the answer isFalse; otherwise the function reachesreturn True.def is_prime(n): for divisor in range(2, n): if n % divisor == 0: return False return True print(is_prime(29)) print(is_prime(35))Scroll the code for more ↓
Output
True Falseis_prime(29)returnsTrue;is_prime(35)returnsFalseas soon as divisor 5 is found. Forn == 2,range(2, 2)supplies no values, so the finalTrueis correct.Try a real prime test
Read one integer and let
is_primetest it.Try it n = int(input("Number: ")) print(is_prime(n))Scroll the code for more ↓
Greatest common divisor with
whileEuclid's algorithm repeatedly replaces a pair with the second number and the remainder. When the second number becomes 0, the first number is the greatest common divisor. The changing
bcontrols the loop.def gcd(a, b): while b != 0: remainder = a % b a = b b = remainder return a print(gcd(48, 18)) print(gcd(77, 28))Scroll the code for more ↓
Output
6 7Trace
gcd(48, 18): the pairs become 48 and 18, then 18 and 12, then 12 and 6, then 6 and 0. The returned answer is 6. This is the least intuitive Lesson 2 tool, so it is the first item to defer when time is short.Carry two Fibonacci values
The Fibonacci sequence starts 0, 1, 1, 2, 3, 5, 8, and so on. Two variables carry the current pair. A temporary variable named
nxtprotects the newly calculated value whileaandbmove forward.def fib(n): a = 0 b = 1 for step in range(n): nxt = a + b a = b b = nxt return a print(fib(0)) print(fib(1)) print(fib(7))Scroll the code for more ↓
Output
0 1 13The calls return
0,1, and13. The pair is updated in three clear steps:nxt = a + b, thena = b, thenb = nxt. Each name holds one value at a time.A hand-written running total
sum_to_n(n)adds every integer from 1 throughn. The nametotalremembers the running result across loop trips.def sum_to_n(n): total = 0 for number in range(1, n + 1): total = total + number return total print(sum_to_n(6)) print(sum_to_n(10))Scroll the code for more ↓
Output
21 55The calls return
21and55. Writing the loop exposes the running-total pattern.One function can call another
sum_of_squaresuses thesquarehelper defined in Lesson 1. This is composition: small tools work together.def sum_of_squares(n): total = 0 for number in range(1, n + 1): total = total + square(number) return total print(sum_of_squares(3))Scroll the code for more ↓
Output
14The result is
14becausesquaresupplies 1, 4, and 9. The caller sees one result fromsum_of_squares.Python also provides small, already-built functions for common number jobs.
Built-in number tools
A built-in function is ready to call without defining it first. In this unit, use these number tools:
-
max(a, b)returns the larger of two numbers. -
min(a, b, c)returns the smallest of three numbers. -
sum(range(1, n + 1))totals the integers supplied by a range. -
abs(number)returns distance from zero. -
round(number)returns a nearby whole number. -
range(...)is the callable that supplies integers to aforloop.
-
The two-argument form
round(number, 1)keeps one digit after the decimal point.lencounts characters in a string today and items in a list in Unit 10.print(max(7, 12)) print(min(9, 4, 15)) print(sum(range(1, 6))) print(abs(-17)) print(round(3.6)) print(round(2.5))Scroll the code for more ↓
Output
12 4 15 17 4 2sum(range(1, 6))returns 15, the same result a hand-written running-total loop would make for 1 through 5.maxandminreplace repeated comparisons when you only need an extreme number.abs(-17)returns 17.Rounding has a tie rule worth noticing:
round(2.5) == 2. Python sends an exact half toward the nearby even integer. Do not assume every.5rounds upward.Count characters in a string
Call the built-in
lenon a string to count its characters.print(len("banner"))Scroll the code for more ↓
Output
6"banner"has 6 characters, solen("banner")returns6.A default parameter
A parameter can have a default value. If the caller omits that argument, Python uses the value in the definition.
def rule(n, symbol="-"): return symbol * n print(rule(4)) print(rule(3, "="))Scroll the code for more ↓
Output
---- ===rule(4)returns----;rule(3, "=")returns===. The second call replaces the default symbol.Lesson 3: Scope
Imagine several teams calling the same scoring tool. Each call needs its own input names so one team's calculation cannot overwrite another's. Scope describes where a name can be used.
Parameters and body names are local
A parameter is a local name. A name first assigned in the function body is local too. Each call gets fresh local values.
score = 10 def add_bonus(score): bonus = 3 score = score + bonus return score new_score = add_bonus(score) print(score) print(new_score)Scroll the code for more ↓
Output
10 13The caller's
scorestays 10, andnew_scorebecomes 13. Insideadd_bonus, the parameter namedscoreis local. Changing that local name does not leak out and replace the caller's name.A function should take what it needs through parameters and return its result, rather than relying on outside names. This makes the tool honest about what it needs and what it provides.
Scope application: a polygon tool
Unit 06 drew polygons with repeated turtle commands. Now package that drawing rule as
draw_polygon(n, side). The parametersnandside, the calculatedangle, and the loop countercornerare local names inside this function.The real program (
assets/l3_draw_polygon.py)# Bring in Python's turtle drawing tools. import turtle # Draw one closed regular polygon. def draw_polygon(n, side): angle = 360 / n turtle.pendown() for corner in range(n): turtle.forward(side) turtle.left(angle) turtle.pencolor("darkviolet") draw_polygon(6, 56) turtle.done()Program # Bring in Python's turtle drawing tools. import turtle # Draw one closed regular polygon. def draw_polygon(n, side): angle = 360 / n turtle.pendown() for corner in range(n): turtle.forward(side) turtle.left(angle) turtle.pencolor("darkviolet") draw_polygon(6, 56) turtle.done()Scroll the code for more ↓
Program # In the real program (assets/l3_draw_polygon.py), draw_polygon is defined above. # Adding these two lines at the very end would show that `angle` is local to the function: draw_polygon(6, 56) print(angle)Scroll the code for more ↓
The call can use
anglewhiledraw_polygonis running, but the next line cannot use that local name. Python reportsNameError: name 'angle' is not defined. Read the error from the end:angleis not defined whereprint(angle)tried to use it.Run the matching real program from this unit directory:
assets/l3_draw_polygon.pyThe call supplies 6 and 56. Inside that one call,
nis 6,sideis 56, andangleis360 / 6. The loop makes six pen-down moves and closes the hexagon.turtle.done()remains once at the end of the file, outside the function.Return the result across the boundary
Local work stays protected inside a function, but a returned value crosses back to the caller on purpose.
def safe_temperature(c): fahrenheit = c * 9 / 5 + 32 bounded = max(fahrenheit, 32) return round(bounded) display_temperature = safe_temperature(-8) print(display_temperature)Scroll the code for more ↓
Output
32Put it together: the caller provides an argument, the parameter receives it as a local name, the body computes with other local names, and
returnsends one result back. Meaningful names and short purpose comments make the boundary readable.Try a real Celsius reading
The real program reads a value and passes it through
safe_temperature.Try it celsius = float(input("Celsius: ")) print(safe_temperature(celsius))Scroll the code for more ↓
-
defgives a reusable set of instructions a name. -
Parameters receive arguments when you call the function.
-
returnsends a value back;print()only displays one. -
Built-in tools such as
max()andround()handle common number jobs. -
Names made inside a function are local to that call.
You can now build a Celsius-to-Fahrenheit converter you can call with many readings.
-