{"id":"debugging-reading-crashes","slug":"reading-a-crash","title":"Reading a crash","text":"Programs go wrong in two ways. You've met the first since module 1: **javac** finds a mistake, and the program doesn't run at all. The second kind happens while the program runs: it gets to a line it can't carry out, and it stops. This is a **crash**, and Java calls the problem an **exception**.\n\nThis program computes an average, but nothing has been added yet:\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        int total = 0;\n        int count = 0;\n        System.out.println(\"Scores added: \" + count);\n        int average = total / count;\n        System.out.println(\"Average: \" + average);\n    }\n}\n```\n\n```output\nScores added: 0\n```\n\n```crash\nException in thread \"main\" java.lang.ArithmeticException: / by zero\n\tat Main.main(Main.java:6)\n```\n\nA crash message has three parts worth reading:\n\n- **What happened**: the exception's name, here `ArithmeticException`, a calculation that can't be done.\n- **Why**: the message after the colon, `/ by zero`. A whole number can't be divided by zero.\n- **Where**: `at Main.main(Main.java:6)`, the method `main` on line 6.\n\nEverything printed before the crash still appears: `Scores added: 0` came out, and the lines after line 6 never ran.\n\nWhen the crash happens inside a method, Java lists every method that was running, the one that crashed first. This is the call stack from module 11:\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        printShare(12, 4);\n        printShare(12, 0);\n    }\n\n    public static void printShare(int total, int people) {\n        System.out.println(\"Each gets \" + share(total, people));\n    }\n\n    public static int share(int total, int people) {\n        return total / people;\n    }\n}\n```\n\n```output\nEach gets 3\n```\n\n```crash\nException in thread \"main\" java.lang.ArithmeticException: / by zero\n\tat Main.share(Main.java:12)\n\tat Main.printShare(Main.java:8)\n\tat Main.main(Main.java:4)\n```\n\nRead it from the top: the division on line 12 in `share` failed. `share` was called by `printShare` on line 8, and that call came from line 4 of `main`, the second `printShare`. The first call worked; only the call with 0 people crashed.\n\nJava Arena shows a crash the same way and explains it in plain words, with the line it happened on. The fix is often not on the crashing line itself: ask where the bad value came from.\n","task":"This program reads scores until the user types `0`, then prints their average. It crashes when the very first input is `0`. Make it print `No scores` in that case, and the average otherwise. With the input `0` it prints:\n\n```\nNo scores\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 total = 0;\n        int count = 0;\n        while (true) {\n            int score = Integer.valueOf(scanner.nextLine());\n            if (score == 0) {\n                break;\n            }\n            total += score;\n            count++;\n        }\n        System.out.println(\"Average: \" + (total / count));\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 total = 0;\n        int count = 0;\n        while (true) {\n            int score = Integer.valueOf(scanner.nextLine());\n            if (score == 0) {\n                break;\n            }\n            total += score;\n            count++;\n        }\n        if (count == 0) {\n            System.out.println(\"No scores\");\n        } else {\n            System.out.println(\"Average: \" + (total / count));\n        }\n    }\n}\n","hints":["Run it with the input `0` and read the crash: which line, and which value is zero there?","`count` is 0 when no score was added. Check `if (count == 0)` before dividing, and print `No scores` then."],"tests":[{"name":"Test 1","stdin":"0\n","expect":"No scores","hidden":false},{"name":"Test 2","stdin":"4\n6\n0\n","expect":"Average: 5","hidden":false},{"name":"Test 3","stdin":"10\n0\n","expect":"Average: 10","hidden":true}],"require":[],"forbid":[],"more":[{"task":"This program prints how many points each team member gets. It crashes when a team has no members. Change only the method `perMember`, so it returns 0 when `members` is 0. The check runs `printPoints(30, 0);` and expects:\n\n```\nEach member gets 0\n```\n","kind":"code","seed":"public class Main {\n    public static void main(String[] args) {\n        printPoints(30, 3);\n        printPoints(30, 0);\n    }\n\n    public static void printPoints(int points, int members) {\n        System.out.println(\"Each member gets \" + perMember(points, members));\n    }\n\n    public static int perMember(int points, int members) {\n        return points / members;\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        printPoints(30, 3);\n        printPoints(30, 0);\n    }\n\n    public static void printPoints(int points, int members) {\n        System.out.println(\"Each member gets \" + perMember(points, members));\n    }\n\n    public static int perMember(int points, int members) {\n        if (members == 0) {\n            return 0;\n        }\n        return points / members;\n    }\n}\n","hints":["The crash's first `at` line names the method where it happened: `perMember`.","Start `perMember` with `if (members == 0) { return 0; }`, before the division."],"tests":[{"name":"printPoints(30, 0);","stdin":"","call":"printPoints(30, 0);\n","expect":"Each member gets 0","hidden":false},{"name":"printPoints(30, 3);","stdin":"","call":"printPoints(30, 3);\n","expect":"Each member gets 10","hidden":true},{"name":"System.out.println(perMember(7, 2));","stdin":"","call":"System.out.println(perMember(7, 2));\n","expect":"3","hidden":true}],"require":[],"forbid":[]},{"task":"Here is a crash from a program you can't see:\n\n```crash\nException in thread \"main\" java.lang.ArithmeticException: / by zero\n\tat Main.average(Main.java:14)\n\tat Main.report(Main.java:9)\n\tat Main.main(Main.java:4)\n```\n\nFill in the blanks: the method the crash happened in, and the line of `main` that started the call.\n","kind":"fill","seed":"public class Main {\n    public static void main(String[] args) {\n        String crashedIn = \"[[average]]\";\n        int mainLine = [[4]];\n        System.out.println(crashedIn + \" was called from line \" + mainLine);\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        String crashedIn = \"average\";\n        int mainLine = 4;\n        System.out.println(crashedIn + \" was called from line \" + mainLine);\n    }\n}\n","hints":["The first `at` line is where the crash happened; the last one is in `main`.","The method is `average`, and `main` was on line 4."],"tests":[{"name":"Output","stdin":"","expect":"average was called from line 4","hidden":false}],"require":[],"forbid":[]}]}