Lesson 4.6
Functions that call your functions
Part 4: FunctionsReading, about 6 min3 exercises in this lesson
Java answers can't run on Spine yet. You can still read Java, trace it, and put an answer's lines in order.
Functions that call your functions
By the end of this you will be able to write a small helper function, call it from inside another function you wrote, and follow a program as it goes from one call to the next.
So far, your functions were called from the main code. A function can also call another function that you wrote. This lets you solve a small job once, in a helper function, and then use that helper wherever a bigger job needs it.
A function that calls a helper
def square(n):
return n * n
def sum_of_squares(a, b):
return square(a) + square(b)
print(sum_of_squares(3, 4))public static void main(String[] args) {
System.out.println(sumOfSquares(3, 4));
}
static int square(int n) {
return n * n;
}
static int sumOfSquares(int a, int b) {
return square(a) + square(b);
}This prints 25. Here is what happens, in order, after the main code calls the function that adds the squares, with 3 and 4.
- That function starts, with
aholding 3 andbholding 4. - It reaches the first call to
square. It waits there whilesquareruns withnholding 3.squarereturns 9. - It reaches the second call.
squareruns again, this time withnholding 4, and returns 16. - It adds 9 and 16 and returns 25 to the main code, which prints it.
Each function waits for the call it made to finish, then carries on from the same place, with the returned value standing where the call was. A call to your own function works the same way whether it comes from the main code or from inside another function.
In Python, the helper may be defined above or below the function that calls it. What matters is that both def lines have run before the first call runs, which is why the call from the main code comes last. In Java, the methods can be in any order.
A helper inside a loop
A helper can also be called on every turn of a loop. This program counts how many whole numbers divide 12 with no remainder.
def divides(d, n):
return n % d == 0
def count_divisors(n):
count = 0
for d in range(1, n + 1):
if divides(d, n):
count = count + 1
return count
print(count_divisors(12))public static void main(String[] args) {
System.out.println(countDivisors(12));
}
static boolean divides(int d, int n) {
return n % d == 0;
}
static int countDivisors(int n) {
int count = 0;
for (int d = 1; d <= n; d++) {
if (divides(d, n)) {
count = count + 1;
}
}
return count;
}The helper returns true or false, so a call to it can be the condition of an if. The loop tries every d from 1 to 12, and the helper says yes for 1, 2, 3, 4, 6 and 12. So this prints 6.
The order of the values matters here as well. Asking the helper about 3 and 12, in that order, asks whether 3 divides 12, which is true. Asking about 12 and 3 asks whether 12 divides 3, which is false.
Why build from helpers
- Each helper can be checked on its own. Call
squarewith 3 and see 9 before you use it anywhere else. If the bigger function goes wrong later, you already know the helper is not the cause. - The bigger function reads like its plan. A line that adds the square of
ato the square ofbsays what it does. - A helper written once can be used many times:
squareis called twice above, anddividesonce on every turn of the loop. A fix to the helper fixes every place that uses it.
Two common slips
- Calling a helper and dropping its value. A line with only a call to
squareon it, such assquare(a), runs the helper, but the value it returns is thrown away. This gives no error in either language, and nothing is kept. Store the value, use it in a bigger expression, or return it. - Giving a helper its values in the wrong order. If the loop asked the helper about
nanddinstead ofdandn, it would check whetherndivides eachd. Withnas 12, that is true only whendis 12, so the count would be 1. Both values are whole numbers, so no error points to the slip.
Now try it yourself on the questions below.
Exercise 4.6.14.6.1 · Write itLargest of three
Write a function that returns the largest of three whole numbers.
a,bandcare whole numbers that can be negative.- Two or all three may be equal. If the largest value appears more than once, return it.
Write a helper function that returns the larger of two numbers, and use it.
Only the number your function returns is checked.
def max_of_three(a: int, b: int, c: int) -> int
You cannot use these in this question:
- max()
- min()
- sorted()
This question is about writing the comparison yourself, so built-in max functions are not allowed.
Examples
Your function is tested on 7 cases: the 3 examples below, and 4 hidden ones that check the rules above.
- max_of_three(1, 2, 3) should return 3: the third is largest (rule 1)
- max_of_three(5, 5, 5) should return 5: all three equal (rule 2)
- max_of_three(9, 3, 7) should return 9: the first is largest (rule 1)
public static int maxOfThree(int a, int b, int c)
Running Java here comes later. You can put this answer's lines in order instead. You can still write your Java answer (it stays while this page is open) and compare it with our worked solution. Or try this exercise in Python.Checking whether Java answers can run here.
You cannot use these in this question:
- Math.max()
- Math.min()
- Collections.max()
- Collections.min()
This question is about writing the comparison yourself, so built-in max functions are not allowed.
Examples
Your function is tested on 7 cases: the 3 examples below, and 4 hidden ones that check the rules above.
- maxOfThree(1, 2, 3) should return 3: the third is largest (rule 1)
- maxOfThree(5, 5, 5) should return 5: all three equal (rule 2)
- maxOfThree(9, 3, 7) should return 9: the first is largest (rule 1)
Exercise 4.6.24.6.2 · Write itSum of digits
Write a function that returns the sum of the digits of a whole number.
nis a whole number from 0 to 999999999.- The sum of the digits of 0 is 0.
Write helper functions for "last digit" (the remainder when dividing by 10) and "remove last digit" (whole-number division by 10), and use them. Do not convert the number to text.
Only the number your function returns is checked.
def sum_of_digits(n: int) -> int
You cannot use these in this question:
- str()
- len()
- repr()
- format()
- list()
- import math
This question is about using arithmetic to extract digits, so converting to text is not allowed.
Examples
Your function is tested on 7 cases: the 3 examples below, and 4 hidden ones that check the rules above.
- sum_of_digits(123) should return 6: 1 + 2 + 3 = 6 (rule 1)
- sum_of_digits(0) should return 0: zero has a digit sum of 0 (rule 2)
- sum_of_digits(9) should return 9: a single digit (rule 1)
public static int sumOfDigits(int n)
Running Java here comes later. You can put this answer's lines in order instead. You can still write your Java answer (it stays while this page is open) and compare it with our worked solution. Or try this exercise in Python.Checking whether Java answers can run here.
You cannot use these in this question:
- String.valueOf()
- Integer.toString()
- .length()
- .toCharArray()
- .charAt()
- .chars()
This question is about using arithmetic to extract digits, so converting to text is not allowed.
Examples
Your function is tested on 7 cases: the 3 examples below, and 4 hidden ones that check the rules above.
- sumOfDigits(123) should return 6: 1 + 2 + 3 = 6 (rule 1)
- sumOfDigits(0) should return 0: zero has a digit sum of 0 (rule 2)
- sumOfDigits(9) should return 9: a single digit (rule 1)
Exercise 4.6.34.6.3 · Answer itWhy decompose
A student writes one 40-line function. It reads three test marks typed by the user, works out their average, decides a grade letter from the average, and prints a short report.
(a) Explain one problem with keeping all of this in a single function. [1]
(b) Name two smaller functions you would split it into, saying what each one does. [1]
(c) Explain how one of your two functions could be tested on its own, without running the rest of the program. [1]
[3]