{"id":"paradigms-procedural","slug":"procedural","title":"Procedural programs","text":"You've written programs in two different styles already. Up to module 16, a program was `main` and a few static methods. From module 17 on, programs were made of objects too. This module gives the two styles their names, writes the same programs in both, and looks honestly at what each one makes easy.\n\n### What a paradigm is\n\nA **programming paradigm** is a style of programming: a set of ideas about what a program is made of and how its parts work together. Two programs can print exactly the same thing and still follow different paradigms. Many languages support more than one paradigm, and Java is one of them.\n\nModule 21 already named one paradigm, **object-oriented programming**: a program is built from objects, and each object looks after its own data. This step is about another one.\n\n### Procedural programming\n\nIn **procedural programming**, a program is a sequence of steps, run one after another. The data is kept in variables, and the work is split into **procedures**: named pieces of code that get the data they need as parameters and may hand back a result. In Java, a procedure is a method, usually a `static` method like the ones in module 10. The data and the methods stay apart: a method knows only what it's given, and the caller decides what to do with any answer it hands back. The C language, for example, is built around this style.\n\nHere's a program that keeps track of how far someone has read in a book, written procedurally:\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        String title = \"The Salt Road\";\n        int pages = 240;\n        int page = 0;\n\n        page = read(page, 60, pages);\n        page = read(page, 100, pages);\n        printProgress(title, page, pages);\n\n        page = read(page, 120, pages);\n        printProgress(title, page, pages);\n    }\n\n    public static int read(int page, int count, int pages) {\n        page = page + count;\n        if (page > pages) {\n            page = pages;\n        }\n        return page;\n    }\n\n    public static void printProgress(String title, int page, int pages) {\n        int percent = 100 * page / pages;\n        System.out.println(title + \": page \" + page + \" of \" + pages + \", \" + percent + \"% read\");\n    }\n}\n```\n\n```output\nThe Salt Road: page 160 of 240, 66% read\nThe Salt Road: page 240 of 240, 100% read\n```\n\n- `main` keeps the book's data in three local variables, and runs from top to bottom: read 60 pages, read 100 more, print, read 120 more, print.\n- `read` works out which page the reader is on after reading `count` more pages. It gets everything it needs as parameters, and it keeps a rule of the problem: nobody reads past the last page, so the third call stops at 240.\n- `read` can't change the variable `page` of `main`, because a parameter gets a copy of the value (module 22). So it returns the new page, and `main` stores it: `page = read(page, 60, pages);`.\n- `printProgress` gets everything it prints as parameters too. `100 * page / pages` divides whole numbers, so 160 of 240 pages is 66%, with the decimals dropped.\n\n### Strengths and weak spots\n\nFor a program this small, the procedural style is hard to beat. It all happens in `main`, in the order it's written, and each method is a small calculation that's easy to check on its own: `read(200, 60, 240)` returns 240, whatever the rest of the program does.\n\nThe weak spots show up as a program grows:\n\n- The title, the number of pages and the page reached belong together, but only their names say so. Every method that needs them has to be handed them one by one.\n- The rule \"not past the last page\" is in `read`, but nothing makes `main` use `read`. The line `page = page + 500;` compiles and runs, and then the reader is on page 660 of a 240-page book.\n- A call without `page =` in front of it, like `read(page, 60, pages);`, compiles too. It works out the new page and throws it away, and the program goes on as if nothing had been read.\n- A second book needs three more variables, and every call has to be given the right ones.\n\nThe next step writes the same program with an object, and comes back to these weak spots.\n","task":"In a board game, the pieces move along the squares 1 to 30. A piece can't go past square 30, and a card like \"go back 5\" can't take it below square 1. The program is procedural: `main` keeps the square in a variable, and `move` gets the square and a number of steps, and returns the new square. Fill in the blanks, so that the program prints:\n\n```\nSquare 6\nSquare 30\nSquare 1\n```\n","kind":"fill","seed":"public class Main {\n    public static void main(String[] args) {\n        int square = 1;\n        square = move(square, 5);\n        System.out.println(\"Square \" + square);\n        [[square]] = move(square, 28);\n        System.out.println(\"Square \" + square);\n        square = move(square, -40);\n        System.out.println(\"Square \" + square);\n    }\n\n    public static [[int]] move(int square, int steps) {\n        square = square + steps;\n        if (square > 30) {\n            square = 30;\n        }\n        if (square < 1) {\n            square = 1;\n        }\n        [[return]] square;\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        int square = 1;\n        square = move(square, 5);\n        System.out.println(\"Square \" + square);\n        square = move(square, 28);\n        System.out.println(\"Square \" + square);\n        square = move(square, -40);\n        System.out.println(\"Square \" + square);\n    }\n\n    public static int move(int square, int steps) {\n        square = square + steps;\n        if (square > 30) {\n            square = 30;\n        }\n        if (square < 1) {\n            square = 1;\n        }\n        return square;\n    }\n}\n","hints":["`move` gives back a whole number, so its return type is `int`, and its last line hands the square back with `return`.","`move` can't change the variable of `main`. `main` has to store what it returns, as the first call does: `square = move(square, 28);`."],"tests":[{"name":"The program","stdin":"","expect":"Square 6\nSquare 30\nSquare 1","hidden":false},{"name":"System.out.println(move(10, 4) + \" \" + move(27, 6) + \" \" + move(3, -5) + \" \" + move(30, 0));","stdin":"","call":"System.out.println(move(10, 4) + \" \" + move(27, 6) + \" \" + move(3, -5) + \" \" + move(30, 0));\n","expect":"14 30 1 30","hidden":true}],"require":[],"forbid":[],"more":[{"task":"A jigsaw puzzle has 500 pieces. `main` is ready, and it's procedural: it keeps the number of pieces already in place in a variable. Write the two methods it uses:\n\n- `place(int placed, int count, int total)` returns how many pieces are in place after `count` more are put in: `placed + count`, but never more than `total`, the number of pieces in the puzzle.\n- `piecesLeft(int placed, int total)` returns how many pieces are still to be put in place.\n\nThe program prints:\n\n```\nPlaced 120 pieces, 380 to go\nPlaced 370 pieces, 130 to go\nPlaced 500 pieces, 0 to go\n```\n","kind":"code","seed":"public class Main {\n    public static void main(String[] args) {\n        int total = 500;\n        int placed = 0;\n        placed = place(placed, 120, total);\n        System.out.println(\"Placed \" + placed + \" pieces, \" + piecesLeft(placed, total) + \" to go\");\n        placed = place(placed, 250, total);\n        System.out.println(\"Placed \" + placed + \" pieces, \" + piecesLeft(placed, total) + \" to go\");\n        placed = place(placed, 200, total);\n        System.out.println(\"Placed \" + placed + \" pieces, \" + piecesLeft(placed, total) + \" to go\");\n    }\n\n    // Write the methods place and piecesLeft here.\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        int total = 500;\n        int placed = 0;\n        placed = place(placed, 120, total);\n        System.out.println(\"Placed \" + placed + \" pieces, \" + piecesLeft(placed, total) + \" to go\");\n        placed = place(placed, 250, total);\n        System.out.println(\"Placed \" + placed + \" pieces, \" + piecesLeft(placed, total) + \" to go\");\n        placed = place(placed, 200, total);\n        System.out.println(\"Placed \" + placed + \" pieces, \" + piecesLeft(placed, total) + \" to go\");\n    }\n\n    // Write the methods place and piecesLeft here.\n    public static int place(int placed, int count, int total) {\n        placed = placed + count;\n        if (placed > total) {\n            placed = total;\n        }\n        return placed;\n    }\n\n    public static int piecesLeft(int placed, int total) {\n        return total - placed;\n    }\n}\n","hints":["Both methods are `public static int`, with the parameters in the order given. `place` works like `read` in the book program: add first, then check the limit.","In `place`, return `total` when `placed + count` is more than `total`, and `placed + count` otherwise. `piecesLeft` returns `total - placed`."],"tests":[{"name":"The program","stdin":"","expect":"Placed 120 pieces, 380 to go\nPlaced 370 pieces, 130 to go\nPlaced 500 pieces, 0 to go","hidden":false},{"name":"System.out.println(place(0, 3, 10) + \" \" + place(9, 3, 10) + \" \" + place(4, 0, 4) + \" \" + place(2, 8, 10));","stdin":"","call":"System.out.println(place(0, 3, 10) + \" \" + place(9, 3, 10) + \" \" + place(4, 0, 4) + \" \" + place(2, 8, 10));\n","expect":"3 10 4 10","hidden":true},{"name":"System.out.println(piecesLeft(3, 10) + \" \" + piecesLeft(10, 10) + \" \" + piecesLeft(0, 25));","stdin":"","call":"System.out.println(piecesLeft(3, 10) + \" \" + piecesLeft(10, 10) + \" \" + piecesLeft(0, 25));\n","expect":"7 0 25","hidden":true}],"require":[],"forbid":[]},{"task":"What does this program print? One of the calls doesn't store what `read` returns.\n","kind":"predict","seed":"public class Main {\n    public static void main(String[] args) {\n        int page = 0;\n        page = read(page, 50, 200);\n        read(page, 30, 200);\n        System.out.println(page);\n        int next = read(page, 170, 200);\n        System.out.println(next + \" \" + page);\n        page = read(next, 10, 200);\n        System.out.println(page);\n    }\n\n    public static int read(int page, int count, int pages) {\n        page = page + count;\n        if (page > pages) {\n            page = pages;\n        }\n        return page;\n    }\n}\n","solution":"public class Main {\n    public static void main(String[] args) {\n        int page = 0;\n        page = read(page, 50, 200);\n        read(page, 30, 200);\n        System.out.println(page);\n        int next = read(page, 170, 200);\n        System.out.println(next + \" \" + page);\n        page = read(next, 10, 200);\n        System.out.println(page);\n    }\n\n    public static int read(int page, int count, int pages) {\n        page = page + count;\n        if (page > pages) {\n            page = pages;\n        }\n        return page;\n    }\n}\n","hints":["`read(page, 30, 200);` works out 80 and returns it, but nothing stores the answer. The variable `page` of `main` is still 50.","`next` gets 50 + 170, which stops at 200. `page` doesn't change until the last line stores into it, and that call starts from `next`."],"tests":[{"name":"Output","stdin":"","expect":"50\n200 50\n200","hidden":false}],"require":[],"forbid":[],"lines":["50","200 50","200"]}]}