{"id":"larger-programs-bad-input","slug":"commands-and-bad-input","title":"Commands, and input that doesn't fit","text":"The command programs of module 25 trusted their users. Real users mistype a command, ask for something that isn't there, or type `five` where a number should be. A program shouldn't crash then, and it shouldn't quietly do something wrong either: it should say what's wrong and wait for the next command. Three kinds of bad input come up in almost every command program:\n\n| Bad input | Example | The answer |\n| --- | --- | --- |\n| An unknown command | `lend` | `Unknown command: lend` |\n| A name that isn't there | `log`, then `Cleo`, who isn't a volunteer | `No volunteer called Cleo` |\n| A number that isn't valid | `five`, or `40` hours in one shift | `Hours must be a whole number from 1 to 12` |\n\nA food bank's volunteers log the hours they help out. The plan is step 1's: `Volunteer` for the data, `FoodBank` for the logic, and `UserInterface` for the commands, as in module 25. The volunteers are added in `main`, and the commands are:\n\n- `log`, then a name and a number of hours: adds the hours to that volunteer. A shift is 1 to 12 hours.\n- `total`: prints the hours of all the volunteers added up.\n- `quit`: ends the program.\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        FoodBank bank = new FoodBank();\n        bank.add(new Volunteer(\"Ada\"));\n        bank.add(new Volunteer(\"Ben\"));\n        UserInterface ui = new UserInterface(scanner, bank);\n        ui.start();\n    }\n}\n// ==== Volunteer.java ====\npublic class Volunteer {\n    private String name;\n    private int hours;\n\n    public Volunteer(String name) {\n        this.name = name;\n        this.hours = 0;\n    }\n\n    public String getName() {\n        return this.name;\n    }\n\n    public int getHours() {\n        return this.hours;\n    }\n\n    public void addHours(int hours) {\n        this.hours += hours;\n    }\n\n    public String toString() {\n        return this.name + \": \" + this.hours + \" hours\";\n    }\n}\n// ==== FoodBank.java ====\nimport java.util.ArrayList;\n\npublic class FoodBank {\n    private ArrayList<Volunteer> volunteers;\n\n    public FoodBank() {\n        this.volunteers = new ArrayList<>();\n    }\n\n    public void add(Volunteer volunteer) {\n        this.volunteers.add(volunteer);\n    }\n\n    public Volunteer find(String name) {\n        for (Volunteer volunteer : this.volunteers) {\n            if (volunteer.getName().equals(name)) {\n                return volunteer;\n            }\n        }\n        return null;\n    }\n\n    public int totalHours() {\n        int total = 0;\n        for (Volunteer volunteer : this.volunteers) {\n            total += volunteer.getHours();\n        }\n        return total;\n    }\n}\n// ==== UserInterface.java ====\nimport java.util.Scanner;\n\npublic class UserInterface {\n    private Scanner scanner;\n    private FoodBank bank;\n\n    public UserInterface(Scanner scanner, FoodBank bank) {\n        this.scanner = scanner;\n        this.bank = bank;\n    }\n\n    public void start() {\n        while (true) {\n            System.out.print(\"> \");\n            String command = this.scanner.nextLine();\n            if (command.equals(\"quit\")) {\n                System.out.println(\"Thank you!\");\n                break;\n            }\n            if (command.equals(\"log\")) {\n                String name = this.scanner.nextLine();\n                int hours = this.toNumber(this.scanner.nextLine());\n                Volunteer volunteer = this.bank.find(name);\n                if (volunteer == null) {\n                    System.out.println(\"No volunteer called \" + name);\n                } else if (hours < 1 || hours > 12) {\n                    System.out.println(\"Hours must be a whole number from 1 to 12\");\n                } else {\n                    volunteer.addHours(hours);\n                    System.out.println(volunteer);\n                }\n            } else if (command.equals(\"total\")) {\n                System.out.println(\"Total: \" + this.bank.totalHours() + \" hours\");\n            } else {\n                System.out.println(\"Unknown command: \" + command);\n            }\n        }\n    }\n\n    private int toNumber(String text) {\n        try {\n            return Integer.valueOf(text);\n        } catch (Exception e) {\n            return -1;\n        }\n    }\n}\n```\n\n```input\nlog\nAda\n4\nlog\nCleo\n3\nlog\nBen\nfive\nlog\nBen\n5\nlend\ntotal\nquit\n```\n\n```output\n> Ada: 4 hours\n> No volunteer called Cleo\n> Hours must be a whole number from 1 to 12\n> Ben: 5 hours\n> Unknown command: lend\n> Total: 9 hours\n> Thank you!\n```\n\nEach kind of bad input has its own place:\n\n- **An unknown command** falls through every `if` and `else if` to the last `else`. Without that `else`, a typo gets no answer at all.\n- **A name that isn't there:** the logic class says so with its return value. `find` returns `null`, and the user interface turns that into a message. FoodBank still doesn't print anything.\n- **A number that isn't valid:** turning typed text into a number is the user interface's job, so it checks the number too, before the logic gets it.\n\n### Read the whole command first\n\n`log` takes three lines: the command, the name and the hours. The user interface reads all of them **before** it checks anything. Suppose it checked the name first and skipped the rest of the command when the name was wrong. The hours, `3`, would still be waiting in the input, and the next round would read them as a command: `Unknown command: 3`. Every command reads the same number of lines, whatever is wrong with them.\n\n### Is it a number?\n\n`Integer.valueOf(\"five\")` throws a NumberFormatException, and without a `catch` the program would crash. Module 20's `try` and `catch` turn the crash into an answer. The helper method `toNumber` returns the number, or `-1` when the text isn't a whole number:\n\n```java\nprivate int toNumber(String text) {\n    try {\n        return Integer.valueOf(text);\n    } catch (Exception e) {\n        return -1;\n    }\n}\n```\n\n- When `Integer.valueOf` succeeds, `return` hands the number back right away. When it throws, Java jumps to the `catch` block, and that returns `-1`.\n- `-1` works as a signal because no valid number of hours is negative. The range check after it catches `-1` together with `0`, `40` and every other number outside 1 to 12, so one message covers them all.\n- The method is `private` (module 18): it's a helper for the user interface itself, and no other class needs it.\n","task":"Neighbors share tools through a tool library. `Tool.java`, `ToolLibrary.java` and `Main.java` are ready: the library has a drill, a ladder and a saw, `find` returns the tool with the given name or `null`, and `isAvailable()` tells whether a tool is on the shelf. In `UserInterface.java`, `return` already checks its tool. `borrow` reads two lines, the tool and the person, but it has no checks yet, and unknown commands get no answer. Add:\n\n- in `borrow`, when there's no tool by that name: `No tool called ` and the name,\n- in `borrow`, when the tool is lent out: `The `, the name and ` is lent out`,\n- otherwise lend it, as now,\n- an answer to unknown commands: `Unknown command: ` and the command.\n\nFor the input shown, the program prints:\n\n```\n> Ana borrowed the ladder\n> The ladder is lent out\n> No tool called hammer\n> The ladder is back on the shelf\n> Ben borrowed the ladder\n> Unknown command: fix\n> drill: on the shelf\nladder: lent to Ben\nsaw: on the shelf\n> Bye\n```\n","kind":"code","seed":"// ==== UserInterface.java ====\nimport java.util.Scanner;\n\npublic class UserInterface {\n    private Scanner scanner;\n    private ToolLibrary library;\n\n    public UserInterface(Scanner scanner, ToolLibrary library) {\n        this.scanner = scanner;\n        this.library = library;\n    }\n\n    public void start() {\n        while (true) {\n            System.out.print(\"> \");\n            String command = this.scanner.nextLine();\n            if (command.equals(\"quit\")) {\n                System.out.println(\"Bye\");\n                break;\n            }\n            if (command.equals(\"borrow\")) {\n                String name = this.scanner.nextLine();\n                String person = this.scanner.nextLine();\n                Tool tool = this.library.find(name);\n                // Add the checks here.\n                tool.lendTo(person);\n                System.out.println(person + \" borrowed the \" + name);\n            } else if (command.equals(\"return\")) {\n                String name = this.scanner.nextLine();\n                Tool tool = this.library.find(name);\n                if (tool == null) {\n                    System.out.println(\"No tool called \" + name);\n                } else {\n                    tool.giveBack();\n                    System.out.println(\"The \" + name + \" is back on the shelf\");\n                }\n            } else if (command.equals(\"tools\")) {\n                for (Tool tool : this.library.tools()) {\n                    System.out.println(tool);\n                }\n            }\n            // Answer unknown commands here.\n        }\n    }\n}\n\n// ==== Tool.java ====\npublic class Tool {\n    private String name;\n    private String borrower;\n\n    public Tool(String name) {\n        this.name = name;\n        this.borrower = null;\n    }\n\n    public String getName() {\n        return this.name;\n    }\n\n    public boolean isAvailable() {\n        return this.borrower == null;\n    }\n\n    public void lendTo(String person) {\n        this.borrower = person;\n    }\n\n    public void giveBack() {\n        this.borrower = null;\n    }\n\n    public String toString() {\n        if (this.borrower == null) {\n            return this.name + \": on the shelf\";\n        }\n        return this.name + \": lent to \" + this.borrower;\n    }\n}\n\n// ==== ToolLibrary.java ====\nimport java.util.ArrayList;\n\npublic class ToolLibrary {\n    private ArrayList<Tool> tools;\n\n    public ToolLibrary() {\n        this.tools = new ArrayList<>();\n    }\n\n    public void add(Tool tool) {\n        this.tools.add(tool);\n    }\n\n    public Tool find(String name) {\n        for (Tool tool : this.tools) {\n            if (tool.getName().equals(name)) {\n                return tool;\n            }\n        }\n        return null;\n    }\n\n    public ArrayList<Tool> tools() {\n        return this.tools;\n    }\n}\n\n// ==== Main.java ====\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        ToolLibrary library = new ToolLibrary();\n        library.add(new Tool(\"drill\"));\n        library.add(new Tool(\"ladder\"));\n        library.add(new Tool(\"saw\"));\n        UserInterface ui = new UserInterface(scanner, library);\n        ui.start();\n    }\n}\n","solution":"// ==== UserInterface.java ====\nimport java.util.Scanner;\n\npublic class UserInterface {\n    private Scanner scanner;\n    private ToolLibrary library;\n\n    public UserInterface(Scanner scanner, ToolLibrary library) {\n        this.scanner = scanner;\n        this.library = library;\n    }\n\n    public void start() {\n        while (true) {\n            System.out.print(\"> \");\n            String command = this.scanner.nextLine();\n            if (command.equals(\"quit\")) {\n                System.out.println(\"Bye\");\n                break;\n            }\n            if (command.equals(\"borrow\")) {\n                String name = this.scanner.nextLine();\n                String person = this.scanner.nextLine();\n                Tool tool = this.library.find(name);\n                // Add the checks here.\n                if (tool == null) {\n                    System.out.println(\"No tool called \" + name);\n                } else if (!tool.isAvailable()) {\n                    System.out.println(\"The \" + name + \" is lent out\");\n                } else {\n                    tool.lendTo(person);\n                    System.out.println(person + \" borrowed the \" + name);\n                }\n            } else if (command.equals(\"return\")) {\n                String name = this.scanner.nextLine();\n                Tool tool = this.library.find(name);\n                if (tool == null) {\n                    System.out.println(\"No tool called \" + name);\n                } else {\n                    tool.giveBack();\n                    System.out.println(\"The \" + name + \" is back on the shelf\");\n                }\n            } else if (command.equals(\"tools\")) {\n                for (Tool tool : this.library.tools()) {\n                    System.out.println(tool);\n                }\n            } else {\n                System.out.println(\"Unknown command: \" + command);\n            }\n            // Answer unknown commands here.\n        }\n    }\n}\n\n// ==== Tool.java ====\npublic class Tool {\n    private String name;\n    private String borrower;\n\n    public Tool(String name) {\n        this.name = name;\n        this.borrower = null;\n    }\n\n    public String getName() {\n        return this.name;\n    }\n\n    public boolean isAvailable() {\n        return this.borrower == null;\n    }\n\n    public void lendTo(String person) {\n        this.borrower = person;\n    }\n\n    public void giveBack() {\n        this.borrower = null;\n    }\n\n    public String toString() {\n        if (this.borrower == null) {\n            return this.name + \": on the shelf\";\n        }\n        return this.name + \": lent to \" + this.borrower;\n    }\n}\n\n// ==== ToolLibrary.java ====\nimport java.util.ArrayList;\n\npublic class ToolLibrary {\n    private ArrayList<Tool> tools;\n\n    public ToolLibrary() {\n        this.tools = new ArrayList<>();\n    }\n\n    public void add(Tool tool) {\n        this.tools.add(tool);\n    }\n\n    public Tool find(String name) {\n        for (Tool tool : this.tools) {\n            if (tool.getName().equals(name)) {\n                return tool;\n            }\n        }\n        return null;\n    }\n\n    public ArrayList<Tool> tools() {\n        return this.tools;\n    }\n}\n\n// ==== Main.java ====\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        ToolLibrary library = new ToolLibrary();\n        library.add(new Tool(\"drill\"));\n        library.add(new Tool(\"ladder\"));\n        library.add(new Tool(\"saw\"));\n        UserInterface ui = new UserInterface(scanner, library);\n        ui.start();\n    }\n}\n","hints":["Follow the model of `return`: `if (tool == null)` comes first, since calling a method of `null` crashes. Then `else if (!tool.isAvailable())`, and the lending goes in the last `else`.","The answer to unknown commands is one more `else` at the end of the chain, after the `tools` branch: `else { System.out.println(\"Unknown command: \" + command); }`."],"tests":[{"name":"Test 1","stdin":"borrow\nladder\nAna\nborrow\nladder\nBen\nborrow\nhammer\nBen\nreturn\nladder\nborrow\nladder\nBen\nfix\ntools\nquit\n","expect":"> Ana borrowed the ladder\n> The ladder is lent out\n> No tool called hammer\n> The ladder is back on the shelf\n> Ben borrowed the ladder\n> Unknown command: fix\n> drill: on the shelf\nladder: lent to Ben\nsaw: on the shelf\n> Bye","hidden":false},{"name":"Test 2","stdin":"borrow\nsaw\nEli\nborrow\ndrill\nEli\nborrow\nsaw\nFay\nBorrow\ntools\nquit\n","expect":"> Eli borrowed the saw\n> Eli borrowed the drill\n> The saw is lent out\n> Unknown command: Borrow\n> drill: lent to Eli\nladder: on the shelf\nsaw: lent to Eli\n> Bye","hidden":true},{"name":"Test 3","stdin":"lend\nborrow\nSaw\nGus\nborrow\ndrill\nGus\ntools\nquit\n","expect":"> Unknown command: lend\n> No tool called Saw\n> Gus borrowed the drill\n> drill: lent to Gus\nladder: on the shelf\nsaw: on the shelf\n> Bye","hidden":true}],"require":[],"forbid":[],"more":[{"task":"A café's cake counter sells cakes by the slice. `Cake.java`, `CakeCounter.java` and `Main.java` are ready: the counter has a carrot cake of 8 slices and a lemon tart of 4, `find` returns the cake with the given name or `null`, and a cake has `getName()`, `getSlices()` and `sell(int slices)`. In `UserInterface.java`, write the `sell` command. It reads two lines: the cake's name, and how many slices. Read both lines first, and then check, in this order:\n\n1. No cake by that name: print `No cake called ` and the name.\n2. The slices aren't a whole number of at least 1 (such as `two`, `0` or `-3`): print `Slices must be a whole number, 1 or more`.\n3. The cake has fewer slices left: print `Not enough `, the name, `: ` and the slices left, like `Not enough lemon tart: 4 left`.\n4. Otherwise, sell them and print `Sold `, the slices, ` of `, the name, `, ` and the slices left, like `Sold 2 of carrot cake, 6 left`.\n\nTurn the text into a number with `try` and `catch`, as in the lesson, so that text that isn't a whole number counts as not valid. For the input shown, the program prints:\n\n```\n> Sold 2 of carrot cake, 6 left\n> No cake called banana bread\n> Slices must be a whole number, 1 or more\n> Slices must be a whole number, 1 or more\n> Not enough lemon tart: 4 left\n> Sold 4 of lemon tart, 0 left\n> carrot cake: 6 slices\nlemon tart: 0 slices\n> Closed\n```\n","kind":"code","seed":"// ==== UserInterface.java ====\nimport java.util.Scanner;\n\npublic class UserInterface {\n    private Scanner scanner;\n    private CakeCounter counter;\n\n    public UserInterface(Scanner scanner, CakeCounter counter) {\n        this.scanner = scanner;\n        this.counter = counter;\n    }\n\n    public void start() {\n        while (true) {\n            System.out.print(\"> \");\n            String command = this.scanner.nextLine();\n            if (command.equals(\"close\")) {\n                System.out.println(\"Closed\");\n                break;\n            }\n            if (command.equals(\"sell\")) {\n                // Write the sell command here.\n            } else if (command.equals(\"cakes\")) {\n                for (Cake cake : this.counter.cakes()) {\n                    System.out.println(cake);\n                }\n            } else {\n                System.out.println(\"Unknown command: \" + command);\n            }\n        }\n    }\n}\n\n// ==== Cake.java ====\npublic class Cake {\n    private String name;\n    private int slices;\n\n    public Cake(String name, int slices) {\n        this.name = name;\n        this.slices = slices;\n    }\n\n    public String getName() {\n        return this.name;\n    }\n\n    public int getSlices() {\n        return this.slices;\n    }\n\n    public void sell(int slices) {\n        this.slices -= slices;\n    }\n\n    public String toString() {\n        return this.name + \": \" + this.slices + \" slices\";\n    }\n}\n\n// ==== CakeCounter.java ====\nimport java.util.ArrayList;\n\npublic class CakeCounter {\n    private ArrayList<Cake> cakes;\n\n    public CakeCounter() {\n        this.cakes = new ArrayList<>();\n    }\n\n    public void add(Cake cake) {\n        this.cakes.add(cake);\n    }\n\n    public Cake find(String name) {\n        for (Cake cake : this.cakes) {\n            if (cake.getName().equals(name)) {\n                return cake;\n            }\n        }\n        return null;\n    }\n\n    public ArrayList<Cake> cakes() {\n        return this.cakes;\n    }\n}\n\n// ==== Main.java ====\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        CakeCounter counter = new CakeCounter();\n        counter.add(new Cake(\"carrot cake\", 8));\n        counter.add(new Cake(\"lemon tart\", 4));\n        UserInterface ui = new UserInterface(scanner, counter);\n        ui.start();\n    }\n}\n","solution":"// ==== UserInterface.java ====\nimport java.util.Scanner;\n\npublic class UserInterface {\n    private Scanner scanner;\n    private CakeCounter counter;\n\n    public UserInterface(Scanner scanner, CakeCounter counter) {\n        this.scanner = scanner;\n        this.counter = counter;\n    }\n\n    public void start() {\n        while (true) {\n            System.out.print(\"> \");\n            String command = this.scanner.nextLine();\n            if (command.equals(\"close\")) {\n                System.out.println(\"Closed\");\n                break;\n            }\n            if (command.equals(\"sell\")) {\n                // Write the sell command here.\n                String name = this.scanner.nextLine();\n                int slices = this.toNumber(this.scanner.nextLine());\n                Cake cake = this.counter.find(name);\n                if (cake == null) {\n                    System.out.println(\"No cake called \" + name);\n                } else if (slices < 1) {\n                    System.out.println(\"Slices must be a whole number, 1 or more\");\n                } else if (cake.getSlices() < slices) {\n                    System.out.println(\"Not enough \" + name + \": \" + cake.getSlices() + \" left\");\n                } else {\n                    cake.sell(slices);\n                    System.out.println(\"Sold \" + slices + \" of \" + name + \", \" + cake.getSlices() + \" left\");\n                }\n            } else if (command.equals(\"cakes\")) {\n                for (Cake cake : this.counter.cakes()) {\n                    System.out.println(cake);\n                }\n            } else {\n                System.out.println(\"Unknown command: \" + command);\n            }\n        }\n    }\n\n    private int toNumber(String text) {\n        try {\n            return Integer.valueOf(text);\n        } catch (Exception e) {\n            return -1;\n        }\n    }\n}\n\n// ==== Cake.java ====\npublic class Cake {\n    private String name;\n    private int slices;\n\n    public Cake(String name, int slices) {\n        this.name = name;\n        this.slices = slices;\n    }\n\n    public String getName() {\n        return this.name;\n    }\n\n    public int getSlices() {\n        return this.slices;\n    }\n\n    public void sell(int slices) {\n        this.slices -= slices;\n    }\n\n    public String toString() {\n        return this.name + \": \" + this.slices + \" slices\";\n    }\n}\n\n// ==== CakeCounter.java ====\nimport java.util.ArrayList;\n\npublic class CakeCounter {\n    private ArrayList<Cake> cakes;\n\n    public CakeCounter() {\n        this.cakes = new ArrayList<>();\n    }\n\n    public void add(Cake cake) {\n        this.cakes.add(cake);\n    }\n\n    public Cake find(String name) {\n        for (Cake cake : this.cakes) {\n            if (cake.getName().equals(name)) {\n                return cake;\n            }\n        }\n        return null;\n    }\n\n    public ArrayList<Cake> cakes() {\n        return this.cakes;\n    }\n}\n\n// ==== Main.java ====\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        CakeCounter counter = new CakeCounter();\n        counter.add(new Cake(\"carrot cake\", 8));\n        counter.add(new Cake(\"lemon tart\", 4));\n        UserInterface ui = new UserInterface(scanner, counter);\n        ui.start();\n    }\n}\n","hints":["Read the name and the number's line right at the start of the branch, before any `if`. Then `find` the cake, and check `cake == null` first.","Copy the lesson's `toNumber` method into the class, and call `this.toNumber(this.scanner.nextLine())`. It returns `-1` for text that isn't a number, so `slices < 1` catches that too. Compare `cake.getSlices() < slices` before selling."],"tests":[{"name":"Test 1","stdin":"sell\ncarrot cake\n2\nsell\nbanana bread\n1\nsell\nlemon tart\ntwo\nsell\nlemon tart\n0\nsell\nlemon tart\n5\nsell\nlemon tart\n4\ncakes\nclose\n","expect":"> Sold 2 of carrot cake, 6 left\n> No cake called banana bread\n> Slices must be a whole number, 1 or more\n> Slices must be a whole number, 1 or more\n> Not enough lemon tart: 4 left\n> Sold 4 of lemon tart, 0 left\n> carrot cake: 6 slices\nlemon tart: 0 slices\n> Closed","hidden":false},{"name":"Test 2","stdin":"sell\nbanana bread\nabc\nsell\ncarrot cake\n-3\nsell\ncarrot cake\n8\nsell\ncarrot cake\n1\ncakes\nclose\n","expect":"> No cake called banana bread\n> Slices must be a whole number, 1 or more\n> Sold 8 of carrot cake, 0 left\n> Not enough carrot cake: 0 left\n> carrot cake: 0 slices\nlemon tart: 4 slices\n> Closed","hidden":true},{"name":"Test 3","stdin":"sell\nlemon tart\n2.5\nsell\nLemon tart\n1\nsell\nlemon tart\n1\nsell\nlemon tart\n3\nbuy\ncakes\nclose\n","expect":"> Slices must be a whole number, 1 or more\n> No cake called Lemon tart\n> Sold 1 of lemon tart, 3 left\n> Sold 3 of lemon tart, 0 left\n> Unknown command: buy\n> carrot cake: 8 slices\nlemon tart: 0 slices\n> Closed","hidden":true}],"require":[{"pattern":"\\bcatch\\s*\\(","message":"Turn the slices into a number inside a `try`, with a `catch` for text that isn't a whole number."}],"forbid":[]},{"task":"A music school books its practice rooms with commands. `book` should read a room's name and then a number of hours. What does this program print? Follow each line of input: which part of the program reads it?\n","kind":"predict","seed":"import java.util.ArrayList;\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        ArrayList<String> rooms = new ArrayList<>();\n        rooms.add(\"studio\");\n        rooms.add(\"attic\");\n        Scanner scanner = new Scanner(\"book\\ncellar\\n3\\nbook\\nattic\\n2\\nquit\\n\");\n        while (true) {\n            String command = scanner.nextLine();\n            if (command.equals(\"quit\")) {\n                break;\n            }\n            if (command.equals(\"book\")) {\n                String room = scanner.nextLine();\n                if (!rooms.contains(room)) {\n                    System.out.println(\"No room called \" + room);\n                    continue;\n                }\n                int hours = Integer.valueOf(scanner.nextLine());\n                System.out.println(room + \" booked for \" + hours + \" hours\");\n            } else {\n                System.out.println(\"Unknown command: \" + command);\n            }\n        }\n    }\n}\n","solution":"import java.util.ArrayList;\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        ArrayList<String> rooms = new ArrayList<>();\n        rooms.add(\"studio\");\n        rooms.add(\"attic\");\n        Scanner scanner = new Scanner(\"book\\ncellar\\n3\\nbook\\nattic\\n2\\nquit\\n\");\n        while (true) {\n            String command = scanner.nextLine();\n            if (command.equals(\"quit\")) {\n                break;\n            }\n            if (command.equals(\"book\")) {\n                String room = scanner.nextLine();\n                if (!rooms.contains(room)) {\n                    System.out.println(\"No room called \" + room);\n                    continue;\n                }\n                int hours = Integer.valueOf(scanner.nextLine());\n                System.out.println(room + \" booked for \" + hours + \" hours\");\n            } else {\n                System.out.println(\"Unknown command: \" + command);\n            }\n        }\n    }\n}\n","hints":["There's no room called `cellar`, so `continue` starts the next round before the hours are read. What's the next line in the input then?","The next round reads `3` as a command. That's why a command should read all of its lines before checking any of them."],"tests":[{"name":"Output","stdin":"","expect":"No room called cellar\nUnknown command: 3\nattic booked for 2 hours","hidden":false}],"require":[],"forbid":[],"lines":["No room called cellar","Unknown command: 3","attic booked for 2 hours"]}]}