{"id":"list-methods-sum-average","slug":"totals-flags-and-text","title":"Totals, flags and joined text","text":"In the last module you added up a list with an index loop. With a for-each loop it's shorter, because there's no index to keep track of:\n\n```java\nArrayList<Integer> pages = new ArrayList<>();\npages.add(12);\npages.add(30);\npages.add(18);\n\nint total = 0;\nfor (int count : pages) {\n    total += count;\n}\nSystem.out.println(\"Pages read: \" + total);\nSystem.out.println(\"Per day: \" + (double) total / pages.size());\n```\n\n```output\nPages read: 60\nPer day: 20.0\n```\n\nAverages and counts work just as before; only the loop is new. This step adds two more things a loop over a list often has to work out: a yes-or-no answer about all the values, and one line of text made from them.\n\n### Does every value pass? A flag\n\nSome questions are about the whole list: is every value valid? Is any value negative? A `boolean` variable answers them. It's called a **flag**: it starts with the answer that holds until some value proves otherwise, and the loop changes it when a value does.\n\n```java\nArrayList<Integer> ages = new ArrayList<>();\nages.add(19);\nages.add(23);\nages.add(17);\nages.add(30);\n\nboolean allAdults = true;\nfor (int age : ages) {\n    if (age < 18) {\n        allAdults = false;\n    }\n}\n\nif (allAdults) {\n    System.out.println(\"Everyone is 18 or over\");\n} else {\n    System.out.println(\"Someone is under 18\");\n}\n```\n\n```output\nSomeone is under 18\n```\n\nOne age under 18 is enough to make the flag `false`, and nothing sets it back to `true`. That's why the `if` in the loop has no `else`: with `else { allAdults = true; }`, only the last age would decide, and here the 30 would hide the 17.\n\nFor \"is there any ...?\", turn it around: start the flag at `false`, and set it to `true` when a value matches.\n\n### Joining values into one line\n\nText can be built in a loop, as in module 11: start from `\"\"` and add each value with `+=`. To put a separator between the values, but not in front of the first one, check whether the text is still empty:\n\n```java\nArrayList<String> stops = new ArrayList<>();\nstops.add(\"Home\");\nstops.add(\"Park\");\nstops.add(\"School\");\n\nString route = \"\";\nfor (String stop : stops) {\n    if (!route.equals(\"\")) {\n        route += \" > \";\n    }\n    route += stop;\n}\nSystem.out.println(route);\n```\n\n```output\nHome > Park > School\n```\n\nIn the first round `route` is still empty, so no separator goes in. From then on, each stop gets one in front of it.\n","task":"A delivery van takes parcels of at most 25 kg each, and at most 100 kg in all. The program reads parcel weights until `0`, into the list `parcels`. Add one for-each loop that adds up the weights and keeps a flag that says whether every parcel is 25 kg or less. Print the total, and then `Ready to go` when both rules hold, or `Repack the van` when either one is broken. For the input 20, 18, 25 and 9 the program prints:\n\n```\nTotal: 72 kg\nReady to go\n```\n","kind":"code","seed":"import java.util.ArrayList;\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        ArrayList<Integer> parcels = new ArrayList<>();\n        while (true) {\n            int weight = Integer.valueOf(scanner.nextLine());\n            if (weight == 0) {\n                break;\n            }\n            parcels.add(weight);\n        }\n\n        // Add up the weights and check every parcel here.\n    }\n}\n","solution":"import java.util.ArrayList;\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        ArrayList<Integer> parcels = new ArrayList<>();\n        while (true) {\n            int weight = Integer.valueOf(scanner.nextLine());\n            if (weight == 0) {\n                break;\n            }\n            parcels.add(weight);\n        }\n\n        int total = 0;\n        boolean allLight = true;\n        for (int weight : parcels) {\n            total += weight;\n            if (weight > 25) {\n                allLight = false;\n            }\n        }\n        System.out.println(\"Total: \" + total + \" kg\");\n        if (allLight && total <= 100) {\n            System.out.println(\"Ready to go\");\n        } else {\n            System.out.println(\"Repack the van\");\n        }\n    }\n}\n","hints":["Before the loop: `int total = 0;` and `boolean allLight = true;`. Inside it, add the weight, and set the flag to `false` when the weight is over 25.","After the loop, both rules at once: `if (allLight && total <= 100)`."],"tests":[{"name":"Test 1","stdin":"20\n18\n25\n9\n0\n","expect":"Total: 72 kg\nReady to go","hidden":false},{"name":"Test 2","stdin":"30\n5\n0\n","expect":"Total: 35 kg\nRepack the van","hidden":true},{"name":"Test 3","stdin":"25\n25\n25\n25\n1\n0\n","expect":"Total: 101 kg\nRepack the van","hidden":true},{"name":"Test 4","stdin":"10\n0\n","expect":"Total: 10 kg\nReady to go","hidden":true}],"require":[{"pattern":"for\\s*\\(\\s*\\w+\\s+\\w+\\s*:","message":"Go through the parcels with a for-each loop."},{"pattern":"\\bboolean\\b","message":"Keep the answer to \"is every parcel light enough?\" in a `boolean` flag."}],"forbid":[],"more":[{"task":"Read whole numbers until `0`, and print them as one addition with its result: the numbers with ` + ` between them, then ` = ` and the sum. Build the line with a for-each loop. There's always at least one number. For the input 4, 7 and 2 the program prints:\n\n```\n4 + 7 + 2 = 13\n```\n","kind":"code","seed":"import java.util.ArrayList;\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        ArrayList<Integer> numbers = new ArrayList<>();\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        Scanner scanner = new Scanner(System.in);\n        ArrayList<Integer> numbers = new ArrayList<>();\n        while (true) {\n            int number = Integer.valueOf(scanner.nextLine());\n            if (number == 0) {\n                break;\n            }\n            numbers.add(number);\n        }\n\n        String line = \"\";\n        int sum = 0;\n        for (int number : numbers) {\n            if (!line.equals(\"\")) {\n                line += \" + \";\n            }\n            line += number;\n            sum += number;\n        }\n        System.out.println(line + \" = \" + sum);\n    }\n}\n","hints":["Two things to keep while going through the list: the text so far (starting at `\"\"`) and the sum (starting at 0).","As with the route in the lesson: add `\" + \"` only when the text isn't empty any more, then add the number."],"tests":[{"name":"Test 1","stdin":"4\n7\n2\n0\n","expect":"4 + 7 + 2 = 13","hidden":false},{"name":"Test 2","stdin":"5\n0\n","expect":"5 = 5","hidden":true},{"name":"Test 3","stdin":"10\n-3\n8\n1\n0\n","expect":"10 + -3 + 8 + 1 = 16","hidden":true}],"require":[{"pattern":"for\\s*\\(\\s*\\w+\\s+\\w+\\s*:","message":"Build the line with a for-each loop."}],"forbid":[]},{"task":"Read the names of your dinner guests until the line `end` (there's at least one). Print them on one line the way you'd write them in a sentence: a comma between the names, but `and` before the last one. For the input `Ada`, `Ben`, `Cleo` and `Dev` the program prints:\n\n```\nGuests: Ada, Ben, Cleo and Dev\n```\n\nTwo guests are `Ada and Ben`, and a single guest is just the name.\n","kind":"code","seed":"import java.util.ArrayList;\nimport java.util.Scanner;\n\npublic class Main {\n    public static void main(String[] args) {\n        Scanner scanner = new Scanner(System.in);\n        ArrayList<String> guests = new ArrayList<>();\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        Scanner scanner = new Scanner(System.in);\n        ArrayList<String> guests = new ArrayList<>();\n        while (true) {\n            String name = scanner.nextLine();\n            if (name.equals(\"end\")) {\n                break;\n            }\n            guests.add(name);\n        }\n\n        String line = \"\";\n        for (int i = 0; i < guests.size(); i++) {\n            if (i == guests.size() - 1 && i > 0) {\n                line += \" and \";\n            } else if (i > 0) {\n                line += \", \";\n            }\n            line += guests.get(i);\n        }\n        System.out.println(\"Guests: \" + line);\n    }\n}\n","hints":["What goes in front of a name depends on where it is: nothing for the first, ` and ` for the last, `, ` for the others. That's a job for an index loop.","The last index is `guests.size() - 1`. Check for it first, and only when `i > 0`, so a single guest gets nothing in front."],"tests":[{"name":"Test 1","stdin":"Ada\nBen\nCleo\nDev\nend\n","expect":"Guests: Ada, Ben, Cleo and Dev","hidden":false},{"name":"Test 2","stdin":"Mo\nend\n","expect":"Guests: Mo","hidden":true},{"name":"Test 3","stdin":"Ada\nBen\nend\n","expect":"Guests: Ada and Ben","hidden":true},{"name":"Test 4","stdin":"Kai\nLin\nUma\nend\n","expect":"Guests: Kai, Lin and Uma","hidden":true}],"require":[],"forbid":[]}]}