{"id":"formatting-sep-and-end","slug":"sep-and-end","title":"Joining values in print: sep and end","text":"A date is three numbers: day 15, month 3, year 2026. How do you print them as `15.3.2026`? Here are the tools you have so far:\n\n```python\nday = 15\nmonth = 3\nyear = 2026\nprint(str(day) + \".\" + str(month) + \".\" + str(year))\nprint(day, \".\", month, \".\", year)\nprint(f\"{day}.{month}.{year}\")\n```\n\n```output\n15.3.2026\n15 . 3 . 2026\n15.3.2026\n```\n\nJoining with `+` works, but only strings can be joined, so every number needs its own `str`. The commas version needs no `str`, but `print` puts a space between the values, and here the spaces are wrong. The f-string gets it right.\n\nThe `+` way has a trap: leave out one `str`, and the program stops.\n\n```python\nday = 15\nprint(\"Day \" + day)\n```\n\n```crash\nTraceback (most recent call last):\n  File \"main.py\", line 2, in <module>\n    print(\"Day \" + day)\n          ~~~~~~~^~~~~\nTypeError: can only concatenate str (not \"int\") to str\n```\n\n### The separator: sep\n\nWhen you give `print` several values with commas, it puts a space between them. That space isn't fixed: you can choose another separator with the **`sep`** argument, written after the values as `sep=` and a string. The first line here solves the date problem:\n\n```python\nprint(15, 3, 2026, sep=\".\")\nprint(\"a\", \"b\", \"c\", sep=\", \")\nprint(\"no\", \"spaces\", \"at\", \"all\", sep=\"\")\nprint(\"one\", \"line\", \"each\", sep=\"\\n\")\n```\n\n```output\n15.3.2026\na, b, c\nnospacesatall\none\nline\neach\n```\n\n`sep=\"\"` joins the values with nothing between them, and `\"\\n\"` is the line break character, so `sep=\"\\n\"` puts each value on a line of its own.\n\n`sep` is a **keyword argument**: it's given with its name, `sep=`, instead of by its position. That's how `print` can tell it from the values to print.\n\n### The end of the line: end\n\nEvery `print` ends its line with a line break, so the next `print` starts on a new line. The keyword argument **`end`** sets what comes at the end instead:\n\n```python\nprint(\"Loading\", end=\"\")\nprint(\"...\", end=\"\")\nprint(\"done\")\nfor i in range(1, 6):\n    print(i, end=\" \")\nprint()\nprint(\"Next line\")\n```\n\n```output\nLoading...done\n1 2 3 4 5\nNext line\n```\n\nWith `end=\"\"` the next `print` goes on in the same line. In the loop, `end=\" \"` keeps all the numbers in one line, with a space after each, and the empty `print()` at the end finishes that line. Without it, `Next line` would be printed right after the 5.\n\nYou can give both `sep` and `end` in one call: `print(1, 2, sep=\"+\", end=\"=3\\n\")` prints `1+2=3`.\n","task":"Fill in the blanks with the names of the keyword arguments, so the program prints:\n\n```\n15.3.2026\nLoading...done\n```\n","kind":"fill","seed":"day = 15\nmonth = 3\nyear = 2026\nprint(day, month, year, [[sep]]=\".\")\nprint(\"Loading...\", [[end]]=\"\")\nprint(\"done\")\n","solution":"day = 15\nmonth = 3\nyear = 2026\nprint(day, month, year, sep=\".\")\nprint(\"Loading...\", end=\"\")\nprint(\"done\")\n","hints":["One argument sets what goes between the values, the other what goes at the end of the line.","`sep` is the separator between values, and `end` replaces the line break at the end."],"tests":[{"name":"Output","stdin":"","expect":"15.3.2026\nLoading...done","hidden":false}],"require":[],"forbid":[],"more":[{"task":"Write the function `print_list(items: list)`, which prints the items of a list on one line, with a comma and a space between them but not after the last one. For example, `print_list([\"red\", \"green\", \"blue\"])` prints:\n\n```\nred, green, blue\n```\n\nYou can assume the list has at least one item.\n","kind":"code","seed":"def print_list(items: list):\n    pass\n\n\nif __name__ == \"__main__\":\n    print_list([\"red\", \"green\", \"blue\"])\n","solution":"def print_list(items: list):\n    for i in range(len(items)):\n        if i < len(items) - 1:\n            print(items[i], end=\", \")\n        else:\n            print(items[i])\n\n\nif __name__ == \"__main__\":\n    print_list([\"red\", \"green\", \"blue\"])\n","hints":["Print each item with `end=\", \"`, so the next item goes on in the same line.","The last item is different: it needs a line break, not a comma. Go through the indexes with `range(len(items))` so you know which item is the last.","For an index smaller than `len(items) - 1` use `end=\", \"`; for the last one, a plain `print(items[i])`."],"tests":[{"name":"print_list([\"red\", \"green\", \"blue\"])","stdin":"","call":"print_list([\"red\", \"green\", \"blue\"])\n","expect":"red, green, blue","hidden":false},{"name":"print_list([\"solo\"])","stdin":"","call":"print_list([\"solo\"])\n","expect":"solo","hidden":true},{"name":"print_list([1, 2, 3, 4])","stdin":"","call":"print_list([1, 2, 3, 4])\n","expect":"1, 2, 3, 4","hidden":true}],"require":[],"forbid":[]},{"task":"What does this program print? Type each line it prints.\n","kind":"predict","seed":"print(\"a\", \"b\", \"c\", sep=\"-\")\nprint(\"x\", end=\"\")\nprint(\"y\", end=\"!\")\nprint()\nprint(1, 2, sep=\"\")\nprint(\"one\", \"two\", sep=\"\\n\")\n","solution":"print(\"a\", \"b\", \"c\", sep=\"-\")\nprint(\"x\", end=\"\")\nprint(\"y\", end=\"!\")\nprint()\nprint(1, 2, sep=\"\")\nprint(\"one\", \"two\", sep=\"\\n\")\n","hints":["`sep` goes between the values: `\"-\"` between a, b and c.","`end=\"\"` and `end=\"!\"` keep the next `print` on the same line. The empty `print()` ends that line.","`sep=\"\\n\"` puts each value on a line of its own."],"tests":[{"name":"Output","stdin":"","expect":"a-b-c\nxy!\n12\none\ntwo","hidden":false}],"require":[],"forbid":[],"lines":["a-b-c","xy!","12","one","two"]}]}