{"id":"recap-input-loops","slug":"input-and-loops","title":"Reading input in a loop","text":"This module opens Java Programming II, the second half of the course. It has nothing new in it: it's a warm-up. Module 29 ended with a list of everything parts 1 to 7 covered, and this module puts that list to work. Each step reminds you of one group of tools and names the module that taught them, works through an example or two, and then gives you three challenges. If a tool feels rusty, the module named next to it has the full story.\n\n### The tools\n\n| Tool | What it does | Taught in |\n| --- | --- | --- |\n| `scanner.nextLine()` | reads one line of input as a String | module 2, Reading input and strings |\n| `Integer.valueOf(line)` | turns text such as `\"42\"` into the int 42 | module 3, Variables and types |\n| `/` between two ints | whole-number division: the decimals are dropped | module 4, Calculating with numbers |\n| `%` | the remainder: what's left over after the division | module 6, Conditions and logic |\n| `if`, `else if`, `else` | picks one branch | module 5, Making decisions |\n| `while (true)` and `break` | repeats until something inside the loop ends it | module 8, Repeating with while |\n| `continue` | skips the rest of this round, and goes on with the next one | module 8, Repeating with while |\n| `for (int i = 0; i < n; i++)` | repeats a known number of times | module 9, Loop conditions and for |\n\n### A worked example\n\nA small car ferry crosses a lake. Its deck holds 4 cars, and bikes ride along in a rack of their own. Before the first crossing, the ferry worker counts the waiting vehicles: the first line of input is how many there are, and each line after it is one vehicle, `car` or `bike`. A car's fare is 12 euros, and a bike's 3.\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 vehicles = Integer.valueOf(scanner.nextLine());\n        int cars = 0;\n        int bikes = 0;\n        for (int i = 0; i < vehicles; i++) {\n            String vehicle = scanner.nextLine();\n            if (vehicle.equals(\"car\")) {\n                cars++;\n            } else {\n                bikes++;\n            }\n        }\n        int fullTrips = cars / 4;\n        int lastTrip = cars % 4;\n        System.out.println(\"Cars: \" + cars + \", bikes: \" + bikes);\n        System.out.println(\"Fares: \" + (cars * 12 + bikes * 3) + \" euros\");\n        if (lastTrip == 0) {\n            System.out.println(\"Trips: \" + fullTrips);\n        } else {\n            System.out.println(\"Trips: \" + (fullTrips + 1) + \", the last one with \" + lastTrip + \" cars\");\n        }\n    }\n}\n```\n\n```input\n8\ncar\ncar\nbike\ncar\ncar\nbike\ncar\ncar\n```\n\n```output\nCars: 6, bikes: 2\nFares: 78 euros\nTrips: 2, the last one with 2 cars\n```\n\n- The first line says how many lines follow, so a `for` loop reads exactly that many, and no stop word is needed. The loop variable `i` only counts the rounds.\n- `cars / 4` is the number of full trips: with two ints, the division drops the decimals, so 6 cars make 1 full trip, not 1.5. `cars % 4` is what's left over, the cars on a last trip that isn't full. When it's 0, every trip is full.\n- `(cars * 12 + bikes * 3)` needs its parentheses. Without them, `+` would join each number to the text in turn instead of adding them up (module 4).\n\nThe other common way to read input, until a stop word, with a rule that skips values and counts that grow as the loop goes, is module 29's step \"Statistics from input\". The first challenge below practices it.\n","task":"At a school play, the ticket seller types each ticket sold at the door, one per line: `adult` or `child`. The word `curtain` ends the input when the play begins. An adult ticket costs 10 euros, and a child's ticket 6. Any other line is a typing mistake: it's only counted as a mistake. Fill in the blanks. For the input shown, the program prints:\n\n```\nTickets: 4\nMistakes: 1\nSales: 32 euros\n```\n","kind":"fill","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 tickets = 0;\n        int mistakes = 0;\n        int sales = 0;\n        while (true) {\n            String line = scanner.nextLine();\n            if (line.equals(\"curtain\")) {\n                [[break]];\n            }\n            if (line.equals(\"adult\")) {\n                tickets++;\n                sales += 10;\n            } else if (line.[[equals]](\"child\")) {\n                tickets++;\n                sales += 6;\n            } [[else]] {\n                mistakes++;\n            }\n        }\n        System.out.println(\"Tickets: \" + tickets);\n        System.out.println(\"Mistakes: \" + mistakes);\n        System.out.println(\"Sales: \" + sales + \" 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 tickets = 0;\n        int mistakes = 0;\n        int sales = 0;\n        while (true) {\n            String line = scanner.nextLine();\n            if (line.equals(\"curtain\")) {\n                break;\n            }\n            if (line.equals(\"adult\")) {\n                tickets++;\n                sales += 10;\n            } else if (line.equals(\"child\")) {\n                tickets++;\n                sales += 6;\n            } else {\n                mistakes++;\n            }\n        }\n        System.out.println(\"Tickets: \" + tickets);\n        System.out.println(\"Mistakes: \" + mistakes);\n        System.out.println(\"Sales: \" + sales + \" euros\");\n    }\n}\n","hints":["`curtain` ends the loop, and the statement that leaves a loop is `break`. Text is compared with `equals`, never with `==`.","A line that's neither `adult` nor `child` falls through both conditions to the last branch of the chain, the one without a condition: `else`."],"tests":[{"name":"Test 1","stdin":"adult\nchild\nchild\nadlt\nadult\ncurtain\n","expect":"Tickets: 4\nMistakes: 1\nSales: 32 euros","hidden":false},{"name":"Test 2","stdin":"curtain\n","expect":"Tickets: 0\nMistakes: 0\nSales: 0 euros","hidden":true},{"name":"Test 3","stdin":"Adult\nchild\nkid\nchild\ncurtain\nadult\n","expect":"Tickets: 2\nMistakes: 2\nSales: 12 euros","hidden":true}],"require":[],"forbid":[],"more":[{"task":"A climber works through the gym's walls, numbered 1 to 6, in order. What does this program print?\n","kind":"predict","seed":"public class Main {\n    public static void main(String[] args) {\n        int walls = 0;\n        int meters = 0;\n        for (int wall = 1; wall <= 6; wall++) {\n            if (wall % 2 == 0) {\n                continue;\n            }\n            if (wall == 5) {\n                break;\n            }\n            walls++;\n            meters += wall * 4;\n            System.out.println(\"Wall \" + wall + \": \" + meters + \" m\");\n        }\n        System.out.println(walls + \" walls, \" + meters + \" m\");\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        int walls = 0;\n        int meters = 0;\n        for (int wall = 1; wall <= 6; wall++) {\n            if (wall % 2 == 0) {\n                continue;\n            }\n            if (wall == 5) {\n                break;\n            }\n            walls++;\n            meters += wall * 4;\n            System.out.println(\"Wall \" + wall + \": \" + meters + \" m\");\n        }\n        System.out.println(walls + \" walls, \" + meters + \" m\");\n    }\n}\n","hints":["`continue` in a `for` loop still runs `wall++`, so the even walls are skipped and the loop goes on with the next wall. `meters` is a running total: it prints the meters so far, not only this wall's.","`break` at wall 5 ends the loop at once, before wall 5 is counted. The last line prints the totals after walls 1 and 3."],"tests":[{"name":"Output","stdin":"","expect":"Wall 1: 4 m\nWall 3: 16 m\n2 walls, 16 m","hidden":false}],"require":[],"forbid":[],"lines":["Wall 1: 4 m","Wall 3: 16 m","2 walls, 16 m"]},{"task":"In a woodworking class, the students cut shelves of 45 cm from boards. The boards' lengths, in whole centimeters, are typed in one per line, until an empty line. From each board, the students cut as many whole shelves as fit, and what's left of the board is waste. Print:\n\n- `Boards: ` and the number of boards,\n- `Shelves: ` and the number of shelves cut from all the boards,\n- `Waste: `, the waste of all the boards added up, and ` cm`.\n\nFor the input shown, the program prints:\n\n```\nBoards: 4\nShelves: 8\nWaste: 90 cm\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\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 boards = 0;\n        int shelves = 0;\n        int waste = 0;\n        while (true) {\n            String line = scanner.nextLine();\n            if (line.isEmpty()) {\n                break;\n            }\n            int length = Integer.valueOf(line);\n            boards++;\n            shelves += length / 45;\n            waste += length % 45;\n        }\n        System.out.println(\"Boards: \" + boards);\n        System.out.println(\"Shelves: \" + shelves);\n        System.out.println(\"Waste: \" + waste + \" cm\");\n    }\n}\n","hints":["Read in a `while (true)` loop, and `break` when the line `isEmpty()`. Keep three variables before the loop: the boards, the shelves and the waste.","For a board of `length` centimeters, `length / 45` is how many whole shelves fit, and `length % 45` is the piece that's left over."],"tests":[{"name":"Test 1","stdin":"120\n90\n200\n40\n\n","expect":"Boards: 4\nShelves: 8\nWaste: 90 cm","hidden":false},{"name":"Test 2","stdin":"\n","expect":"Boards: 0\nShelves: 0\nWaste: 0 cm","hidden":true},{"name":"Test 3","stdin":"45\n\n","expect":"Boards: 1\nShelves: 1\nWaste: 0 cm","hidden":true},{"name":"Test 4","stdin":"44\n46\n135\n89\n\n","expect":"Boards: 4\nShelves: 5\nWaste: 89 cm","hidden":true}],"require":[],"forbid":[]}]}