{"id":"more-loops-helper-variables","slug":"helper-variables","title":"Helper variables in nested loops","text":"Nested loops often print a pattern, a little piece at a time. For that, `print` has an option you met in part 1: `print(..., end=\"\")`. Normally `print` ends its line, so the next `print` starts a new one. With `end=\"\"`, it ends with nothing instead, and the next `print` carries on where this one stopped. Any other text works as the ending too, such as a space. A `print()` with nothing in it then just ends the line:\n\n```python\nprint(\"one\", end=\"\")\nprint(\"two\", end=\" \")\nprint(\"three\")\nprint(\"four\")\n```\n\n```output\nonetwo three\nfour\n```\n\n### One helper variable per loop\n\nIn nested loops, each loop needs a helper variable of its own, and the inner one must start again in every round of the outer loop. This program prints a multiplication square:\n\n```python\nsize = 4\nrow = 1\nwhile row <= size:\n    column = 1\n    while column <= size:\n        print(row * column, end=\" \")\n        column += 1\n    print()\n    row += 1\n```\n\n```output\n1 2 3 4\n2 4 6 8\n3 6 9 12\n4 8 12 16\n```\n\n`row` counts the rows, and `column` counts the numbers on one row. `column = 1` is inside the outer loop, just before the inner loop, so every row starts again from column 1. After the inner loop, `print()` ends the row.\n\n### The start value in the wrong place\n\nThis is the most common mistake with nested loops: the inner helper variable gets its start value only once, before the outer loop.\n\n```python\nrow = 1\ncolumn = 1\nwhile row <= 3:\n    while column <= 3:\n        print(row * column, end=\" \")\n        column += 1\n    print()\n    row += 1\n```\n\n```output\n1 2 3\n```\n\nThe first row is fine. But after it, `column` is 4, and nothing sets it back to 1. In every later round of the outer loop, `column <= 3` is false from the start, so the inner loop doesn't run, and the other rows are empty.\n\n### Rows of different lengths\n\nThe inner loop's condition can use the outer loop's variable. Then each row can have a length of its own:\n\n```python\nheight = 4\nrow = 1\nwhile row <= height:\n    column = 1\n    while column <= row:\n        print(column, end=\" \")\n        column += 1\n    print()\n    row += 1\n```\n\n```output\n1\n1 2\n1 2 3\n1 2 3 4\n```\n\nRow 1 has one number, row 2 two numbers, and so on, because the inner loop runs while `column <= row`.\n","task":"This program should print a rectangle of `#` characters, but it prints only the first row. Fix it.\n\n```\nHeight: 3\nWidth: 5\n#####\n#####\n#####\n```\n","kind":"code","seed":"height = int(input(\"Height: \"))\nwidth = int(input(\"Width: \"))\nrow = 0\ncolumn = 0\nwhile row < height:\n    while column < width:\n        print(\"#\", end=\"\")\n        column += 1\n    print()\n    row += 1\n","solution":"height = int(input(\"Height: \"))\nwidth = int(input(\"Width: \"))\nrow = 0\nwhile row < height:\n    column = 0\n    while column < width:\n        print(\"#\", end=\"\")\n        column += 1\n    print()\n    row += 1\n","hints":["After the first row, what is the value of `column`? Does anything set it back to 0?","`column` has to start again from 0 for every row. Move `column = 0` into the outer loop, just before the inner loop."],"tests":[{"name":"Test 1","stdin":"3\n5\n","expect":"Height: 3\nWidth: 5\n#####\n#####\n#####","hidden":false},{"name":"Test 2","stdin":"1\n1\n","expect":"Height: 1\nWidth: 1\n#","hidden":true},{"name":"Test 3","stdin":"4\n2\n","expect":"Height: 4\nWidth: 2\n##\n##\n##\n##","hidden":true}],"require":[],"forbid":[],"more":[{"task":"Write a program that asks for a size and prints a hollow square: `#` characters on the edges and spaces inside.\n\n```\nSize: 4\n####\n#  #\n#  #\n####\n```\n","kind":"code","seed":"size = int(input(\"Size: \"))\n","solution":"size = int(input(\"Size: \"))\nrow = 1\nwhile row <= size:\n    column = 1\n    while column <= size:\n        if row == 1 or row == size or column == 1 or column == size:\n            print(\"#\", end=\"\")\n        else:\n            print(\" \", end=\"\")\n        column += 1\n    print()\n    row += 1\n","hints":["Use two nested loops, `row` and `column`, both from 1 to the size, and print one character in each round of the inner loop with `end=\"\"`.","A place is on the edge when it's in the first or the last row, or in the first or the last column.","`if row == 1 or row == size or column == 1 or column == size:` prints `#`, and `else` prints a space. After the inner loop, `print()` ends the row."],"tests":[{"name":"Test 1","stdin":"4\n","expect":"Size: 4\n####\n#  #\n#  #\n####","hidden":false},{"name":"Test 2","stdin":"1\n","expect":"Size: 1\n#","hidden":true},{"name":"Test 3","stdin":"2\n","expect":"Size: 2\n##\n##","hidden":true},{"name":"Test 4","stdin":"6\n","expect":"Size: 6\n######\n#    #\n#    #\n#    #\n#    #\n######","hidden":true}],"require":[],"forbid":[]},{"task":"Write a program that asks for a number of rows and prints a triangle of numbers that keep counting up from one row to the next: row 1 has one number, row 2 has two, and so on.\n\n```\nRows: 4\n1\n2 3\n4 5 6\n7 8 9 10\n```\n","kind":"code","seed":"rows = int(input(\"Rows: \"))\n","solution":"rows = int(input(\"Rows: \"))\nnumber = 1\nrow = 1\nwhile row <= rows:\n    column = 1\n    while column <= row:\n        print(number, end=\" \")\n        number += 1\n        column += 1\n    print()\n    row += 1\n","hints":["Start from the triangle in the lesson: the inner loop runs while `column <= row`, so each row is one number longer.","You need a third helper variable for the number to print. It must not start again for each row, so give it its start value 1 before the outer loop.","In the inner loop, print the number with `end=\" \"` and add 1 to it."],"tests":[{"name":"Test 1","stdin":"4\n","expect":"Rows: 4\n1\n2 3\n4 5 6\n7 8 9 10","hidden":false},{"name":"Test 2","stdin":"1\n","expect":"Rows: 1\n1","hidden":true},{"name":"Test 3","stdin":"6\n","expect":"Rows: 6\n1\n2 3\n4 5 6\n7 8 9 10\n11 12 13 14 15\n16 17 18 19 20 21","hidden":true}],"require":[],"forbid":[]}]}