Start learning free

LESSON 129 OF 338 · LOOPS & CONDITIONALS

Print Positive / Negative in Go: Fixing the Buggy Loop

Practice Read the full explanation

Inside the code editor we've tried to write a function that takes an array nums as argument and for every number in the array:

  • prints "negative" if that number is less than zero

  • or prints the number itself, if the number is greater than or equal to zero

So when we called the function for [2, -12, 0, 4, -5, 3], we expected it to print:

2
negative
0
4
negative
3

but it seems like we made some mistakes because when we run our code, it produces this output:

positive
2
-12
0
positive
4
-5
positive
3

Assignment:

Your task is to fix our loop such that it will print the desired output.

STEP 1 OF 1
    Ctrl + Enter to check

    GO · LOOPS & CONDITIONALS

    Buggy Code Print Positive Negative in Go, explained

    What the code is supposed to do

    The function printPositiveAndNegative receives a slice of integers, nums, and prints one line per number. A number below zero prints the word negative. Any other number, zero included, prints as itself. For []int{2, -12, 0, 4, -5, 3} the expected output is:

    2
    negative
    0
    4
    negative
    3
    

    The code you start with prints nine lines instead of six:

    func printPositiveAndNegative(nums []int) {
        for _, num := range nums {
            if num > 0 {
                fmt.Println("positive")
            }
            fmt.Println(num)
        }
    }
    

    What goes wrong

    There are two separate mistakes, and both are visible in the loop body.

    1. The condition picks the wrong numbers. num > 0 is true for 2, 4 and 3, so those numbers get an extra positive line. The special word belongs to the numbers below zero, so the test must be num < 0 and the word must be negative.
    2. The last fmt.Println(num) is unconditional. It sits after the if block, so it runs for every number. Even when the word is printed, the number prints too, which is why -12 and -5 still appear. Each number must produce exactly one line, so the two prints need to be alternatives to each other.

    Tracing the first three numbers of the buggy version shows it. For 2, the if prints positive and then the number: two lines. For -12, the if is skipped and only -12 prints. For 0, the same: only 0 prints.

    Fixing it step by step

    1. Change the comparison from num > 0 to num < 0. Zero is not less than zero, so it falls to the other case, as the task requires.
    2. Change the message from "positive" to "negative".
    3. Add an else branch and move fmt.Println(num) into it. Now exactly one of the two prints runs for each number.
    4. Leave mainFunction alone. It already calls the function with the slice from the task.

    The fixed code in Go

    func printPositiveAndNegative(nums []int) {
        for _, num := range nums {
            if num < 0 {
                fmt.Println("negative")
            } else {
                fmt.Println(num)
            }
        }
    }
    
    
    func mainFunction() {
        printPositiveAndNegative([]int{2, -12, 0, 4, -5, 3})
    }
    

    A few Go details are worth knowing here:

    • range gives two values. For a slice it yields the index and the element. The loop writes _, num because Go refuses to compile a program with a declared but unused variable, so the unneeded index goes to the blank identifier _. Writing for i, num := range nums without using i is a compile error: i declared and not used.
    • else must follow the closing brace. Go requires } else { on one line. Putting else on a new line is a syntax error.
    • No parentheses around the condition. Go writes if num < 0 {, and the braces are mandatory even for one statement.
    • fmt.Println adds a newline and prints an int in plain decimal form, so -12 would print as -12. The word "negative" prints without its quotes.

    Why the original looked plausible

    The starting code has the right shape: a loop, a test, and a print. Bugs like this come from a branch that adds an extra action instead of choosing between two. An if without an else only adds work for some elements, while the code after it still runs for all of them. When the task says "either this or that", look for an else.

    Common mistakes

    • Using <=. That would turn 0 into negative. The task wants 0 printed as a number.
    • Fixing only the condition. With if num < 0 { fmt.Println("negative") } followed by the unconditional print, every negative number prints twice: first the word, then the number.
    • Using two separate if statements such as if num < 0 and if num >= 0. That works, but else says the same thing without a second test that could drift out of sync with the first.
    • Misspelling the word. The output is compared as text, so Negative or negetive fails.

    Checking your fix

    Run the code in the editor above. A correct fix prints six lines: 2, negative, 0, 4, negative, 3. For an empty slice the loop body never runs and nothing prints.

    Keep going with GoAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free