{"id":"debugging-print","slug":"print-debugging","title":"Print debugging","text":"A crash tells you where to look. A wrong answer doesn't: the program runs to the end and prints something, just not the right thing. Then you need to see what the program actually does, step by step.\n\nThe simplest tool is a temporary print that shows the values of variables at an interesting point. This program should add up the numbers from 1 to 5, which is 15:\n\n```java\nint sum = 0;\nfor (int i = 1; i < 5; i++) {\n    sum += i;\n}\nSystem.out.println(\"Sum: \" + sum);\n```\n\n```output\nSum: 10\n```\n\n10 is wrong, but why? Add a print inside the loop:\n\n```java\nint sum = 0;\nfor (int i = 1; i < 5; i++) {\n    sum += i;\n    System.out.println(\"debug: i = \" + i + \", sum = \" + sum);\n}\nSystem.out.println(\"Sum: \" + sum);\n```\n\n```output\ndebug: i = 1, sum = 1\ndebug: i = 2, sum = 3\ndebug: i = 3, sum = 6\ndebug: i = 4, sum = 10\nSum: 10\n```\n\nNow it's plain to see: the loop stops after 4, so 5 is never added. The condition should be `i <= 5`. Fix it, run it again, and remove the debug print (or comment it out) once the answer is right.\n\nSome tips:\n\n- Print a label with each value (`\"debug: i = \" + i`), so you know which print you're looking at.\n- Print in the places where the program decides something: inside loops, before and after an `if`, at the start of a method (its parameters) and just before it returns.\n- Start with one or two prints. If the values are right there, move them later in the program; if they're already wrong, move them earlier.\n","task":"This program should count how many of the numbers typed are even, until the user types `-1`. It gives the wrong count. Find the bug (a debug print inside the loop helps), fix it, and make sure no debug prints are left. With the input `4`, `7`, `10`, `-1` it prints:\n\n```\nEven numbers: 2\n```\n","kind":"code","seed":"import java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        int evens = 0;\n        while (true) {\n            int number = Integer.valueOf(scanner.nextLine());\n            if (number == -1) {\n                break;\n            }\n            if (number % 2 == 1) {\n                evens++;\n            }\n        }\n        System.out.println(\"Even numbers: \" + evens);\n    }\n}\n","solution":"import java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        int evens = 0;\n        while (true) {\n            int number = Integer.valueOf(scanner.nextLine());\n            if (number == -1) {\n                break;\n            }\n            if (number % 2 == 0) {\n                evens++;\n            }\n        }\n        System.out.println(\"Even numbers: \" + evens);\n    }\n}\n","hints":["Print `number` and `evens` inside the loop, after the `if`. Which numbers make `evens` go up?","An even number leaves no remainder when divided by 2: `number % 2 == 0`."],"tests":[{"name":"Test 1","stdin":"4\n7\n10\n-1\n","expect":"Even numbers: 2","hidden":false},{"name":"Test 2","stdin":"-1\n","expect":"Even numbers: 0","hidden":true},{"name":"Test 3","stdin":"2\n4\n6\n9\n-1\n","expect":"Even numbers: 3","hidden":true}],"require":[],"forbid":[],"more":[{"task":"The method `sumBetween(int from, int to)` should add up every whole number from `from` to `to`, both included. For 3 and 6 that's 3 + 4 + 5 + 6 = 18, but it returns 12. Find the bug and fix it. The check runs `System.out.println(sumBetween(3, 6));` and expects:\n\n```\n18\n```\n","kind":"code","seed":"public class Main {\n    public static void main(String[] args) {\n        System.out.println(sumBetween(3, 6));\n    }\n\n    public static int sumBetween(int from, int to) {\n        int sum = 0;\n        for (int n = from; n < to; n++) {\n            sum += n;\n        }\n        return sum;\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        System.out.println(sumBetween(3, 6));\n    }\n\n    public static int sumBetween(int from, int to) {\n        int sum = 0;\n        for (int n = from; n <= to; n++) {\n            sum += n;\n        }\n        return sum;\n    }\n}\n","hints":["Print `n` inside the loop. Which numbers are added, and which one is missing?","`to` itself must be added too: the condition should be `n <= to`."],"tests":[{"name":"System.out.println(sumBetween(3, 6));","stdin":"","call":"System.out.println(sumBetween(3, 6));\n","expect":"18","hidden":false},{"name":"System.out.println(sumBetween(5, 5));","stdin":"","call":"System.out.println(sumBetween(5, 5));\n","expect":"5","hidden":true},{"name":"System.out.println(sumBetween(1, 10));","stdin":"","call":"System.out.println(sumBetween(1, 10));\n","expect":"55","hidden":true}],"require":[],"forbid":[]},{"task":"This program reads two exam scores and should print their average with decimals. For 3 and 4 it prints `Average: 3.0` instead of `Average: 3.5`. Print the values along the way to see where the half goes missing, then fix it. With the input `3` and `4` it prints:\n\n```\nAverage: 3.5\n```\n","kind":"code","seed":"import java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        int first = Integer.valueOf(scanner.nextLine());\n        int second = Integer.valueOf(scanner.nextLine());\n        int sum = first + second;\n        double average = sum / 2;\n        System.out.println(\"Average: \" + average);\n    }\n}\n","solution":"import java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        int first = Integer.valueOf(scanner.nextLine());\n        int second = Integer.valueOf(scanner.nextLine());\n        int sum = first + second;\n        double average = sum / 2.0;\n        System.out.println(\"Average: \" + average);\n    }\n}\n","hints":["`sum` is 7, which is right. The half is lost in the division: `sum / 2` divides two `int` values.","Divide by `2.0`, or cast first: `(double) sum / 2`."],"tests":[{"name":"Test 1","stdin":"3\n4\n","expect":"Average: 3.5","hidden":false},{"name":"Test 2","stdin":"10\n10\n","expect":"Average: 10.0","hidden":true},{"name":"Test 3","stdin":"0\n1\n","expect":"Average: 0.5","hidden":true}],"require":[],"forbid":[]}]}