{"id":"variables-f-strings","slug":"f-strings","title":"F-strings","text":"Joining with `+` and `str` works, but long lines get clumsy, and commas add spaces you don't always want. An **f-string** lets you write a line the way it should look and mark the places where values go. Write `f` right before the opening quote, and put a variable's name in curly brackets `{ }` inside the string. Python puts the variable's value in its place:\n\n```python\nitem = \"pencils\"\ncount = 12\nprint(f\"You ordered {count} {item}.\")\n```\n\n```output\nYou ordered 12 pencils.\n```\n\nThe f stands for \"formatted\". The values can be of any type, so no `str` is needed. Everything outside the brackets is printed exactly as it is written, so you decide where every space goes.\n\n### Several values, and calculations\n\nAn f-string can have as many brackets as you need, and a bracket can hold a calculation as well as a variable:\n\n```python\nname = \"Ada\"\nprice = 3\ncount = 12\nprint(f\"{name} buys {count} pencils at {price} each.\")\nprint(f\"That's {count * price} in all.\")\n```\n\n```output\nAda buys 12 pencils at 3 each.\nThat's 36 in all.\n```\n\n### Compared with commas\n\nHere is the first example with commas instead. The automatic spaces put a space before the full stop:\n\n```python\nitem = \"pencils\"\ncount = 12\nprint(\"You ordered\", count, item, \".\")\n```\n\n```output\nYou ordered 12 pencils .\n```\n\nTo get rid of that space, you'd have to mix the two ways: commas for the words and `+` for the full stop, `print(\"You ordered\", count, item + \".\")`. It works, but you have to think about every gap. The f-string says the whole line in one piece, exactly as it's printed.\n\nCommas are fine for a quick look at some values. When the output has to look exactly right, an f-string is usually the easiest choice.\n\n### The missing f\n\nWithout the `f`, the string is an ordinary string, and the brackets are printed as they are:\n\n```python\ncity = \"Oslo\"\nprint(\"Welcome to {city}!\")\nprint(f\"Welcome to {city}!\")\n```\n\n```output\nWelcome to {city}!\nWelcome to Oslo!\n```\n\nThere's no error message: Python can't know that you meant an f-string. If you see curly brackets in your output, check for the `f`.\n\nAn f-string makes a string like any other, so you can also store it in a variable: `label = f\"{count} {item}\"`.\n","task":"Fill in the blank so the program greets the user. If the user types `Ada`, the run looks like this:\n\n```\nName: Ada\nHello, Ada!\n```\n","kind":"fill","seed":"name = input(\"Name: \")\nprint([[f]]\"Hello, {name}!\")\n","solution":"name = input(\"Name: \")\nprint(f\"Hello, {name}!\")\n","hints":["Without anything in the blank, the program prints `{name}` as it is.","One letter right before the opening quote turns the string into an f-string: `f`."],"tests":[{"name":"Test 1","stdin":"Ada\n","expect":"Name: Ada\nHello, Ada!","hidden":false},{"name":"Test 2","stdin":"Grace\n","expect":"Name: Grace\nHello, Grace!","hidden":true}],"require":[],"forbid":[],"more":[{"task":"The last line prints extra spaces around the parentheses. Rewrite it with an f-string, so that a run looks like this:\n\n```\nName: Ada\nAge: 36\nAda (36 years)\n```\n","kind":"code","seed":"name = input(\"Name: \")\nage = input(\"Age: \")\nprint(name, \"(\", age, \"years )\")\n","solution":"name = input(\"Name: \")\nage = input(\"Age: \")\nprint(f\"{name} ({age} years)\")\n","hints":["Each comma in `print` adds a space. An f-string prints only the spaces you write.","Write the whole line as one f-string, with the two variables in curly brackets: `f\"{name} (...)\"`.","The round parentheses are just characters inside the string: `f\"{name} ({age} years)\"`."],"tests":[{"name":"Test 1","stdin":"Ada\n36\n","expect":"Name: Ada\nAge: 36\nAda (36 years)","hidden":false},{"name":"Test 2","stdin":"Linus\n57\n","expect":"Name: Linus\nAge: 57\nLinus (57 years)","hidden":true}],"require":[{"pattern":"\\bf[\"']","raw":true,"message":"Print the line with an f-string."}],"forbid":[]},{"task":"A notebook costs 4 and the customer buys 3 of them. The program asks for the product's name; the price and the amount are already in variables. Add one `print` with an f-string, so that a run looks like this:\n\n```\nProduct: notebook\n3 x notebook = 12 euros\n```\n\nCalculate the total inside the f-string, from the variables.\n","kind":"code","seed":"product = input(\"Product: \")\nprice = 4\namount = 3\n","solution":"product = input(\"Product: \")\nprice = 4\namount = 3\nprint(f\"{amount} x {product} = {amount * price} euros\")\n","hints":["The line has three values in it: the amount, the product and the total. Each one goes in curly brackets.","The total is a calculation in brackets: `{amount * price}`.","The `x` and the `=` are just characters of the text, outside the brackets."],"tests":[{"name":"Test 1","stdin":"notebook\n","expect":"Product: notebook\n3 x notebook = 12 euros","hidden":false},{"name":"Test 2","stdin":"pen\n","expect":"Product: pen\n3 x pen = 12 euros","hidden":true}],"require":[{"pattern":"\\bf[\"']","raw":true,"message":"Print the line with an f-string."}],"forbid":[{"pattern":"\\b12\\b","raw":true,"message":"Let Python calculate the total from the variables instead of typing 12."}]}]}