{"id":"return-values-shapes","slug":"drawing-shapes","title":"Drawing shapes with methods","text":"Text shapes are a good workout for loops and methods together. The trick is to look at a shape one row at a time, and write down what each row is made of. Here's a pyramid of height 3:\n\n```\n  ^\n ^^^\n^^^^^\n```\n\n| Row | Spaces | Symbols |\n|---|---|---|\n| 1 | 2 | 1 |\n| 2 | 1 | 3 |\n| 3 | 0 | 5 |\n\nThe spaces go down by one per row: for a height `h`, row `r` has `h - r` of them. The symbols go up by two: `2 * r - 1`. With a method that returns repeated text, each row is then one line of code:\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        printPyramid(3);\n    }\n\n    public static void printPyramid(int height) {\n        for (int row = 1; row <= height; row++) {\n            System.out.println(repeat(\" \", height - row) + repeat(\"^\", 2 * row - 1));\n        }\n    }\n\n    public static String repeat(String text, int times) {\n        String result = \"\";\n        for (int i = 0; i < times; i++) {\n            result += text;\n        }\n        return result;\n    }\n}\n```\n\n```output\n  ^\n ^^^\n^^^^^\n```\n\nSpaces at the start of a line count, so the checks compare them exactly. (Spaces at the end of a line are ignored.)\n\n### The end of part 2\n\nThis step ends the material of the MOOC's second part. Looking back, most of it was about two tools. A loop runs the same lines as often as needed, so a program never has to repeat itself. A method gives a piece of code a name, so a long program becomes a set of small parts that can each be read and checked on its own. The shapes above use both. The MOOC closes the part with [a short self-reflection questionnaire](https://java-programming.mooc.fi/part-2/5-end-questionnaire) on its own site.\n","task":"Write `printDiagonal(int size)`, which prints `size` rows with an `o` in each, every row one space further to the right. Use `repeat` for the spaces. The check runs `printDiagonal(3);` and expects:\n\n```\no\n o\n  o\n```\n","kind":"code","seed":"public class Main {\n    public static void main(String[] args) {\n        printDiagonal(3);\n    }\n\n    public static String repeat(String text, int times) {\n        String result = \"\";\n        for (int i = 0; i < times; i++) {\n            result += text;\n        }\n        return result;\n    }\n\n    // Write the printDiagonal method here.\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        printDiagonal(3);\n    }\n\n    public static String repeat(String text, int times) {\n        String result = \"\";\n        for (int i = 0; i < times; i++) {\n            result += text;\n        }\n        return result;\n    }\n\n    public static void printDiagonal(int size) {\n        for (int row = 1; row <= size; row++) {\n            System.out.println(repeat(\" \", row - 1) + \"o\");\n        }\n    }\n}\n","hints":["Row 1 has no spaces before the `o`, row 2 has one, row 3 has two: row `r` has `r - 1`.","`System.out.println(repeat(\" \", row - 1) + \"o\");` inside a loop over the rows."],"tests":[{"name":"printDiagonal(3);","stdin":"","call":"printDiagonal(3);\n","expect":"o\n o\n  o","hidden":false},{"name":"printDiagonal(1);","stdin":"","call":"printDiagonal(1);\n","expect":"o","hidden":true},{"name":"printDiagonal(5);","stdin":"","call":"printDiagonal(5);\n","expect":"o\n o\n  o\n   o\n    o","hidden":true}],"require":[{"pattern":"\\brepeat\\s*\\(","min":2,"message":"Make the spaces with `repeat`."}],"forbid":[],"more":[{"task":"Write `printStairs(int height)`, which prints stairs rising to the right. Each step is two `#` wide, and each row is one step longer than the one above: row `r` has `2 * r` symbols, pushed to the right edge with spaces. The check runs `printStairs(3);` and expects:\n\n```\n    ##\n  ####\n######\n```\n","kind":"code","seed":"public class Main {\n    public static void main(String[] args) {\n        printStairs(3);\n    }\n\n    public static String repeat(String text, int times) {\n        String result = \"\";\n        for (int i = 0; i < times; i++) {\n            result += text;\n        }\n        return result;\n    }\n\n    // Write the printStairs method here.\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        printStairs(3);\n    }\n\n    public static String repeat(String text, int times) {\n        String result = \"\";\n        for (int i = 0; i < times; i++) {\n            result += text;\n        }\n        return result;\n    }\n\n    public static void printStairs(int height) {\n        for (int row = 1; row <= height; row++) {\n            System.out.println(repeat(\" \", 2 * (height - row)) + repeat(\"#\", 2 * row));\n        }\n    }\n}\n","hints":["Make a table like the pyramid's: for a height of 3, the spaces go 4, 2, 0 and the symbols 2, 4, 6.","Row `r` has `2 * (height - r)` spaces and `2 * r` symbols."],"tests":[{"name":"printStairs(3);","stdin":"","call":"printStairs(3);\n","expect":"    ##\n  ####\n######","hidden":false},{"name":"printStairs(1);","stdin":"","call":"printStairs(1);\n","expect":"##","hidden":true},{"name":"printStairs(5);","stdin":"","call":"printStairs(5);\n","expect":"        ##\n      ####\n    ######\n  ########\n##########","hidden":true}],"require":[{"pattern":"\\brepeat\\s*\\(","min":2,"message":"Build the rows with `repeat`."}],"forbid":[]},{"task":"Write `printDiamond(int size)`: a pyramid of `o` with `size` rows, followed by the same pyramid upside down without its widest row, so the diamond has `2 * size - 1` rows. The check runs `printDiamond(3);` and expects:\n\n```\n  o\n ooo\nooooo\n ooo\n  o\n```\n","kind":"code","seed":"public class Main {\n    public static void main(String[] args) {\n        printDiamond(3);\n    }\n\n    public static String repeat(String text, int times) {\n        String result = \"\";\n        for (int i = 0; i < times; i++) {\n            result += text;\n        }\n        return result;\n    }\n\n    // Write the printDiamond method here.\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        printDiamond(3);\n    }\n\n    public static String repeat(String text, int times) {\n        String result = \"\";\n        for (int i = 0; i < times; i++) {\n            result += text;\n        }\n        return result;\n    }\n\n    public static void printDiamond(int size) {\n        for (int row = 1; row <= size; row++) {\n            printRow(size, row);\n        }\n        for (int row = size - 1; row >= 1; row--) {\n            printRow(size, row);\n        }\n    }\n\n    public static void printRow(int size, int row) {\n        System.out.println(repeat(\" \", size - row) + repeat(\"o\", 2 * row - 1));\n    }\n}\n","hints":["The top half is the pyramid from the lesson. The bottom half is the same rows again, from `size - 1` down to 1.","A helper `printRow(int size, int row)` that prints one pyramid row keeps both loops short."],"tests":[{"name":"printDiamond(3);","stdin":"","call":"printDiamond(3);\n","expect":"  o\n ooo\nooooo\n ooo\n  o","hidden":false},{"name":"printDiamond(1);","stdin":"","call":"printDiamond(1);\n","expect":"o","hidden":true},{"name":"printDiamond(4);","stdin":"","call":"printDiamond(4);\n","expect":"   o\n  ooo\n ooooo\nooooooo\n ooooo\n  ooo\n   o","hidden":true}],"require":[{"pattern":"\\brepeat\\s*\\(","min":2,"message":"Build the rows with `repeat`."}],"forbid":[]}]}