{"id":"simple-loops-building-strings","slug":"building-strings","title":"Building strings in a loop","text":"A helper variable doesn't have to hold a number. A string can grow in a loop too: start with the **empty string** `\"\"` and add to it with `+=`, which joins strings just as `+` does:\n\n```python\nstars = \"\"\ncount = 0\nwhile True:\n    stars += \"*\"\n    count += 1\n    if count == 5:\n        break\nprint(stars)\n```\n\n```output\n*****\n```\n\nEach iteration adds one `*` to the end of `stars`, and the whole string is printed once, after the loop.\n\n### Collecting input\n\nIn the same way, a program can collect what the user types:\n\n```python\nguests = \"\"\nwhile True:\n    name = input(\"Guest (done to finish): \")\n    if name == \"done\":\n        break\n    guests += name\nprint(\"Guests: \" + guests)\n```\n\n```input\nAda\nAlan\nGrace\ndone\n```\n\n```output\nGuest (done to finish): Ada\nGuest (done to finish): Alan\nGuest (done to finish): Grace\nGuest (done to finish): done\nGuests: AdaAlanGrace\n```\n\nAlmost: `+=` joins the strings exactly as they are, so the names run together. They need a comma and a space between them, but not before the first name, and not after the last one either. So add the separator in front of each name, except the first:\n\n```python\nguests = \"\"\nwhile True:\n    name = input(\"Guest (done to finish): \")\n    if name == \"done\":\n        break\n    if guests == \"\":\n        guests = name\n    else:\n        guests += \", \" + name\nprint(\"Guests: \" + guests)\n```\n\n```input\nAda\nAlan\nGrace\ndone\n```\n\n```output\nGuest (done to finish): Ada\nGuest (done to finish): Alan\nGuest (done to finish): Grace\nGuest (done to finish): done\nGuests: Ada, Alan, Grace\n```\n\n`guests == \"\"` is true only for the first name, while nothing has been added yet.\n\n### Numbers into the string\n\n`+` joins only strings, so a number must be converted with `str` before it's added:\n\n```pycon\n>>> row = \"\"\n>>> row += str(1) + \" \"\n>>> row += str(2) + \" \"\n>>> row\n'1 2 '\n```\n\nWithout `str`, Python stops with the `TypeError` you saw earlier: `can only concatenate str (not \"int\") to str`.\n","task":"Write a program that asks for a number and prints a countdown from it on one line, followed by `Liftoff!`:\n\n```\nCount down from: 5\n5 4 3 2 1 Liftoff!\n```\n","kind":"code","seed":"number = int(input(\"Count down from: \"))\n","solution":"number = int(input(\"Count down from: \"))\nline = \"\"\nwhile True:\n    if number == 0:\n        break\n    line += str(number) + \" \"\n    number -= 1\nprint(line + \"Liftoff!\")\n","hints":["Start with an empty string, `line = \"\"`, before the loop, and print it only once, after the loop.","Each iteration adds the number and a space: `line += str(number) + \" \"`. Then `number -= 1` counts down.","Stop with `break` when the number reaches 0, and print `line + \"Liftoff!\"` at the end."],"tests":[{"name":"Test 1","stdin":"5\n","expect":"Count down from: 5\n5 4 3 2 1 Liftoff!","hidden":false},{"name":"Test 2","stdin":"1\n","expect":"Count down from: 1\n1 Liftoff!","hidden":true},{"name":"Test 3","stdin":"12\n","expect":"Count down from: 12\n12 11 10 9 8 7 6 5 4 3 2 1 Liftoff!","hidden":true}],"require":[{"pattern":"\\bwhile\\s+True\\b","message":"Use a `while True` loop."},{"pattern":"\\bprint\\s*\\(","max":1,"message":"Build the whole line in a string and print it once, after the loop."}],"forbid":[],"more":[{"task":"Write a program that asks for items for a shopping list until the user types `done`, and then prints them on one line, separated by commas. There's no comma after the last item. If the user typed no items at all, it prints `The list is empty.`\n\n```\nItem: milk\nItem: bread\nItem: eggs\nItem: done\nShopping list: milk, bread, eggs\n```\n","kind":"code","seed":"# Write your program below this line.\n","solution":"# Write your program below this line.\nitems = \"\"\nwhile True:\n    item = input(\"Item: \")\n    if item == \"done\":\n        break\n    if items == \"\":\n        items = item\n    else:\n        items += \", \" + item\nif items == \"\":\n    print(\"The list is empty.\")\nelse:\n    print(\"Shopping list: \" + items)\n","hints":["Collect the items in a string that starts as `\"\"` before the loop.","Add the first item as it is, and every later one with `\", \"` in front of it. `items == \"\"` tells you whether it's the first.","After the loop, the string is still empty only if no items were typed."],"tests":[{"name":"Test 1","stdin":"milk\nbread\neggs\ndone\n","expect":"Item: milk\nItem: bread\nItem: eggs\nItem: done\nShopping list: milk, bread, eggs","hidden":false},{"name":"Test 2","stdin":"done\n","expect":"Item: done\nThe list is empty.","hidden":true},{"name":"Test 3","stdin":"apples\ndone\n","expect":"Item: apples\nItem: done\nShopping list: apples","hidden":true},{"name":"Test 4","stdin":"tea\nhoney\nlemons\nginger\ndone\n","expect":"Item: tea\nItem: honey\nItem: lemons\nItem: ginger\nItem: done\nShopping list: tea, honey, lemons, ginger","hidden":true}],"require":[],"forbid":[]},{"task":"Write a program that asks for a height and draws a staircase of `#` characters: the first row has one, and each row has one more than the row before.\n\n```\nHeight: 4\n#\n##\n###\n####\n```\n","kind":"code","seed":"height = int(input(\"Height: \"))\n","solution":"height = int(input(\"Height: \"))\nrow = \"\"\nwhile True:\n    if len(row) == height:\n        break\n    row += \"#\"\n    print(row)\n","hints":["Each row is the row before it with one more `#`. So keep the current row in a string, and add one character per iteration.","Start with `row = \"\"`, then on each iteration add a `#` and print the row.","The loop is done when the row is as long as the height: `len(row) == height`. Check that before adding."],"tests":[{"name":"Test 1","stdin":"4\n","expect":"Height: 4\n#\n##\n###\n####","hidden":false},{"name":"Test 2","stdin":"1\n","expect":"Height: 1\n#","hidden":true},{"name":"Test 3","stdin":"7\n","expect":"Height: 7\n#\n##\n###\n####\n#####\n######\n#######","hidden":true}],"require":[{"pattern":"\\bwhile\\s+True\\b","message":"Use a `while True` loop."}],"forbid":[]}]}