What the code is supposed to do
The method printEvenNumbers takes an array nums and should print its even numbers, one per line. For Array(2, 1, 0, 4, 3) the expected output is 2, 0 and 4. The code you start with prints something else:
even
even
Here is the code:
class Solution {
def printEvenNumbers(nums: Array[Int]): Unit = {
for (num <- nums) {
if (num % 2 == 1) {
println("even")
}
}
}
// Do not change this code:
def mainFunction(): Unit = {
printEvenNumbers(Array(2, 1, 0, 4, 3))
}
}
What goes wrong
There are two separate mistakes, both inside the loop. Each one shows up in the output.
Mistake 1: the condition selects odd numbers
The operator % gives the remainder after division. An even number divides by 2 with remainder 0, and an odd number leaves remainder 1. So num % 2 == 1 is true for the odd numbers in the array, which are 1 and 3, and false for the even ones. That is why exactly two lines are printed: the array has two odd numbers.
The condition should select numbers whose remainder is 0.
Mistake 2: the text is printed instead of the number
println("even") prints the characters inside the quotes, and it does so every time it runs. A string in quotes is a fixed piece of text. It has nothing to do with the variable num. To print the value of a variable, pass the variable itself, without quotes: println(num).
Fixing it step by step
- Change the comparison. Replace
num % 2 == 1withnum % 2 == 0. Now theifbody runs for 2, 0 and 4. - Change what is printed. Replace
println("even")withprintln(num), so each even number is shown. - Leave the rest alone. The loop
for (num <- nums)already visits every element, andmainFunctionis marked as not to be changed.
How to find bugs like these
Compare the actual output with the expected output. Two lines of even instead of three numbers tells you two things: the printed text is wrong, and the number of lines is wrong. The count points at the condition, and the content points at the print statement. Walking through the array by hand with the original condition confirms it: 2 gives remainder 0 and is skipped, 1 gives remainder 1 and prints, and so on.
The fixed code in Scala
class Solution {
def printEvenNumbers(nums: Array[Int]): Unit = {
for (num <- nums) {
if (num % 2 == 0) {
println(num)
}
}
}
def mainFunction(): Unit = {
printEvenNumbers(Array(2, 1, 0, 4, 3))
}
}
For the sample array, this prints:
2
0
4
Some Scala details are worth knowing:
- Zero is even.
0 % 2is 0, so 0 is printed, as the expected output requires. - Negative numbers and
%. The result of%takes the sign of the left operand, so-3 % 2is-1, not 1. A test for odd numbers written asnum % 2 == 1therefore misses negative odd numbers. Comparing with 0 avoids the problem:-4 % 2 == 0is true, and-3 % 2 == 0is false. - The loop variable.
numis a value that the loop creates on each pass. It holds the current element and isn't an index.
Edge cases and common mistakes
- Arrays with no even numbers.
Array(1, 3)prints nothing, and that is correct. - Empty array. Nothing is printed.
- Fixing only one mistake. Changing just the condition still prints the word
eventhree times. Changing just the print line prints 1 and 3 instead. - Quotes around the variable.
println("num")prints the wordnum, not the value. - Printing instead of returning. The method's return type is
Unit, so it prints its results and returns nothing.
Testing
Array(2, 1, 0, 4, 3)prints 2, 0 and 4.Array(-4, -3, 7)prints -4.Array(5, 9)prints nothing.
