Start learning free

LESSON 137 OF 414 · LOOPS & CONDITIONALS

Print Odd Numbers in Rust: Fixing the Buggy Code

Practice Read the full explanation

Inside the code editor we've tried to write a function that takes a number n as argument and prints to the console the odd numbers from 0 up to (but not including) n.

So when we called printOddNumbers(8), we expected our code to print:

1
3
5
7

but it seems like we made some mistakes because when we run our code, it prints nothing.


Assignment:

Your task is to fix our function such that it prints the odd numbers from 0 up to (but not including) n.

STEP 1 OF 1
    Ctrl + Enter to check

    RUST · LOOPS & CONDITIONALS

    Buggy Code Print Odd Numbers in Rust, explained

    What the code is supposed to do

    The function printOddNumbers takes a number n and should print the odd numbers below it, one per line. Called with 8, it should print 1, 3, 5 and 7. The code you start with prints nothing at all:

    fn printOddNumbers(n: i32) {
        for i in 0..n {
            if n % 2 == 1 {
                println!("{}", n);
            }
        }
    }
    
    // Do not change this code:
    fn mainFunction() {
        printOddNumbers(8);
    }
    

    The code compiles and runs without a crash. It just never reaches the println!.

    What goes wrong

    The loop for i in 0..n produces a new value of i on every pass: 0, 1, 2, up to 7. But the two lines inside the loop never look at i. They use n, the parameter, which is 8 on every pass and never changes.

    So the test n % 2 == 1 asks the same question eight times: is 8 odd? The remainder of 8 divided by 2 is 0, so the answer is no each time, and nothing is printed.

    The bug has a second face. If the function were called with an odd number, such as 9, the test would be true on every pass, and the function would print the number 9 nine times instead of the odd numbers below 9. The loop variable is the one that carries the changing value, and the code ignores it.

    The compiler hints at the problem. It warns that the variable i is unused, because nothing in the loop body reads it. A loop variable that is never used is a strong sign that the loop body is checking the wrong variable.

    Fixing it step by step

    1. Change the test from n % 2 == 1 to i % 2 == 1, so each pass checks the current number.
    2. Change the print from n to i, so the odd number found is the one that gets printed.
    3. Keep the loop range. 0..n covers 0 to n - 1, which matches the expected output for 8: the numbers 1, 3, 5 and 7.

    The fixed code in Rust

    fn printOddNumbers(n: i32) {
        for i in 0..n {
            if i % 2 == 1 {
                println!("{}", i);
            }
        }
    }
    fn mainFunction() {
        printOddNumbers(8);
    }
    

    Now the loop goes through 0 to 7. The remainder of i divided by 2 is 1 for 1, 3, 5 and 7, so those four are printed, each on its own line.

    Rust details

    • Naming. Rust's style is snake case, print_odd_numbers, and the compiler warns about a name like printOddNumbers. It is only a warning, so the program still builds. This lesson keeps the given names because the code around them depends on them.
    • The range excludes the end. 0..n stops before n. If the task asked for the odd numbers up to and including n, the range would be 0..=n. For n = 8 the result is the same, because 8 is even.
    • Warnings are hints. The unused variable warning points straight at the bug here, so read warnings before hunting through the code.
    • Parameters are values. n is an i32 copied into the function. Nothing in the loop changes it, which is why it keeps the value 8.

    Common mistakes

    • Fixing only one of the two lines. If only the test uses i, the function prints 8 four times. If only the print uses i, nothing is printed.
    • Changing the loop instead. The range is already right. Starting at 1 or stepping by 2 would change the structure for no reason.
    • Negative numbers. This is not a concern here, but note that -3 % 2 is -1 in Rust, so == 1 would miss negative odd numbers. The range here starts at 0.

    Testing

    • printOddNumbers(8) prints 1, 3, 5 and 7.
    • printOddNumbers(9) prints 1, 3, 5 and 7, because 9 itself is excluded.
    • printOddNumbers(1) and printOddNumbers(0) print nothing.
    Keep going with RustAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free