What the code is supposed to do
The function printOddNumbers takes an Int named n and prints the odd numbers that are smaller than n, one per line. Calling it with 8 should print 1, 3, 5 and 7. The code in the editor prints nothing at all:
def printOddNumbers(n: Int): Unit = {
for (i <- 0 until n) {
if (n % 2 == 1) {
println(n)
}
}
}
// Do not change this code:
def mainFunction(): Unit = {
printOddNumbers(8)
}
Your job is to find the mistake and fix the function. The part under "Do not change this code" stays as it is.
What goes wrong
The loop is fine. for (i <- 0 until n) gives i the values 0, 1, 2, up to n - 1, and the body runs once for each. The mistake is inside the body, where the two lines use n instead of i.
The parameter n is a fixed number for the whole call. In printOddNumbers(8) it is 8 on every pass of the loop. So n % 2 == 1 asks "is 8 odd?" eight times, gets false each time and never reaches println. The loop variable i is the only value that changes from one pass to the next, and the code never looks at it.
The same bug looks different with an odd argument. For n = 5, the check 5 % 2 == 1 is true on every pass, so the function prints 5 five times instead of printing 1 and 3. Both outputs come from the same mistake: the code tests and prints n where it should use i.
Fixing it step by step
- Keep the loop. It already visits every number from 0 to
n - 1, which is the range the task describes. The upper end is excluded becauseuntilstops beforen. - Test the loop variable. Change the condition to
i % 2 == 1. The remainder of an odd number divided by 2 is 1, so this is true exactly for the odd values ofi. - Print the loop variable. Change
println(n)toprintln(i), so the line shows the odd number that was just found. - Leave the rest alone.
mainFunctioncallsprintOddNumbers(8)and the function needs no other change.
The fixed code in Scala
def printOddNumbers(n: Int): Unit = {
for (i <- 0 until n) {
if (i % 2 == 1) {
println(i)
}
}
}
def mainFunction(): Unit = {
printOddNumbers(8)
}
With n = 8, the loop visits 0 to 7 and the output is:
1
3
5
7
A few Scala details are worth knowing here:
- Parameter versus loop variable. Both are immutable values inside the body, but only the loop variable gets a new value on each pass. A name like
nthat never changes inside the loop is a warning sign when the condition depends on it. untilversusto.0 until nstops beforen, while0 to nincludes it. Forn = 8the difference doesn't change the output, because 8 is even, but for an oddnsuch as 9 the version withtowould also print 9.- The compiler can't help. Both versions are valid Scala. The compiler accepts any
Intin the condition, so this kind of mistake only shows up when you run the code and read the output.
Common mistakes
- Fixing only one of the two lines. If only the condition is changed to
i, the function prints8four times. If only the print is changed, the function still prints nothing. - Starting the check at the wrong value. A condition such as
i % 2 == 0prints the even numbers 0, 2, 4 and 6 instead. - Printing in the wrong format. Each number goes on its own line, so use
println. The print function without thelnwould join the numbers into one line. - Editing the protected code. The lines below the comment call the function with 8, and the lesson expects them unchanged.
Checking your fix
Run the code in the editor above. The output should be the four lines 1, 3, 5 and 7. If you see nothing, the condition still uses n. If you see the right numbers repeated, the print still uses n.
