{"id":"debugging-testing","slug":"testing-with-inputs","title":"Testing with different inputs","text":"A program that gives the right answer for one input can still be wrong. Bugs like to hide in the inputs nobody tried. So test with a few kinds of input on purpose:\n\n- **A typical case**, like the example in the task.\n- **The edges**: the smallest and largest values that are allowed, 0, 1, an empty input or a single value, and the values right at a limit (if something changes at 18, try 17 and 18).\n- **The unusual**: negative numbers, all values the same, the largest value first or last.\n\nThis program finds the largest number typed. It works for the example `3`, `9`, `4`:\n\n```java\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        int count = Integer.valueOf(scanner.nextLine());\n        int largest = 0;\n        for (int i = 0; i < count; i++) {\n            int number = Integer.valueOf(scanner.nextLine());\n            if (number > largest) {\n                largest = number;\n            }\n        }\n        System.out.println(\"Largest: \" + largest);\n    }\n}\n```\n\n```input\n3\n3\n9\n4\n```\n\n```output\nLargest: 9\n```\n\nNow try numbers that are all negative, `-5`, `-2`, `-8`: it prints `Largest: 0`, a number that wasn't even typed. Starting from 0 only works when some number is bigger than 0. The fix is to start from the first number itself, and compare the rest with it.\n\n### Tracing by hand\n\nFor a short loop, you can also play the computer: write the variables in a table and fill in one row per round, without running anything. With the numbers `-5`, `-2`, `-8`:\n\n| round | number | largest after the round |\n|---|---|---|\n| before the loop | | 0 |\n| 1 | -5 | 0 |\n| 2 | -2 | 0 |\n| 3 | -8 | 0 |\n\nThe table shows the problem at once: `largest` never changes, because no number beats 0. Next to each row you can also write what the value *should* be: the first row where the two differ is where the bug is.\n","task":"Fix the program above so it works for every input, negative numbers too. It reads how many numbers follow, then the numbers (at least one). With the input `3`, `-5`, `-2`, `-8` it prints:\n\n```\nLargest: -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 count = Integer.valueOf(scanner.nextLine());\n        int largest = 0;\n        for (int i = 0; i < count; i++) {\n            int number = Integer.valueOf(scanner.nextLine());\n            if (number > largest) {\n                largest = number;\n            }\n        }\n        System.out.println(\"Largest: \" + largest);\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 count = Integer.valueOf(scanner.nextLine());\n        int largest = Integer.valueOf(scanner.nextLine());\n        for (int i = 1; i < count; i++) {\n            int number = Integer.valueOf(scanner.nextLine());\n            if (number > largest) {\n                largest = number;\n            }\n        }\n        System.out.println(\"Largest: \" + largest);\n    }\n}\n","hints":["Read the first number before the loop and start `largest` from it. The loop then reads the remaining numbers.","If the first number is read before the loop, the loop runs one round fewer: start the counter at 1."],"tests":[{"name":"Test 1","stdin":"3\n-5\n-2\n-8\n","expect":"Largest: -2","hidden":false},{"name":"Test 2","stdin":"3\n3\n9\n4\n","expect":"Largest: 9","hidden":true},{"name":"Test 3","stdin":"1\n-7\n","expect":"Largest: -7","hidden":true}],"require":[],"forbid":[],"more":[{"task":"A swimming pool charges by age: under 7 swim free, 7 to 17 pay 3 euros, and 18 or older pay 6 euros. This program gets some ages wrong. Test it with the ages at the edges (6, 7, 17 and 18), then fix it. With the input `17` it prints:\n\n```\nPrice: 3 euros\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 age = Integer.valueOf(scanner.nextLine());\n        int price;\n        if (age <= 7) {\n            price = 0;\n        } else if (age < 17) {\n            price = 3;\n        } else {\n            price = 6;\n        }\n        System.out.println(\"Price: \" + price + \" euros\");\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 age = Integer.valueOf(scanner.nextLine());\n        int price;\n        if (age < 7) {\n            price = 0;\n        } else if (age <= 17) {\n            price = 3;\n        } else {\n            price = 6;\n        }\n        System.out.println(\"Price: \" + price + \" euros\");\n    }\n}\n","hints":["Work out by hand what the program does for 7 and for 17, and compare with the rules.","\"Under 7\" is `age < 7`, and \"7 to 17\" includes 17: `age <= 17`."],"tests":[{"name":"Test 1","stdin":"17\n","expect":"Price: 3 euros","hidden":false},{"name":"Test 2","stdin":"7\n","expect":"Price: 3 euros","hidden":true},{"name":"Test 3","stdin":"6\n","expect":"Price: 0 euros","hidden":true},{"name":"Test 4","stdin":"18\n","expect":"Price: 6 euros","hidden":true},{"name":"Test 5","stdin":"40\n","expect":"Price: 6 euros","hidden":true}],"require":[],"forbid":[]},{"task":"Trace this program by hand, with a table for `a` and `b`, then write down what it prints.\n","kind":"predict","seed":"public class Main {\n    public static void main(String[] args) {\n        int a = 1;\n        int b = 1;\n        for (int round = 1; round <= 4; round++) {\n            int next = a + b;\n            a = b;\n            b = next;\n        }\n        System.out.println(a);\n        System.out.println(b);\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        int a = 1;\n        int b = 1;\n        for (int round = 1; round <= 4; round++) {\n            int next = a + b;\n            a = b;\n            b = next;\n        }\n        System.out.println(a);\n        System.out.println(b);\n    }\n}\n","hints":["Each round, `next` is the sum of the two, `a` takes the old `b`, and `b` takes `next`.","After the rounds, the pairs are (1, 2), (2, 3), (3, 5) and (5, 8)."],"tests":[{"name":"Output","stdin":"","expect":"5\n8","hidden":false}],"require":[],"forbid":[],"lines":["5","8"]}]}