Thesis

In the majority of cases an f-string is better than string concatenation because it allows for better readability and creates readable code.

Type Coercion

print(f"Your score is {score}") 

The f-string converts score automatically, therefore str() isn't needed.

Readability

If the code is written with concatenation it reads:

("Your score is" + str(score)) 

By writing it this way the code has four separate parts starting with a string. Followed by the + symbol to create the concatenation. Then there is a data type conversion from either integer or float to a string. The code ends with a variable within parentheses that needed to be converted. Written as an f-string the same line is a function followed by the f prefix. Then a string that held two curly braces to place the name of the variable being converted. It makes for quicker and cleaner read. It also allows you to complete the entire code in one string instead of two. For these reasons I recommend f-strings are used in these cases.

When Concatenation Still Wins

One situation where concatenation still makes sense is if the user is building a string piece by piece in a loop. When building this type of code each pass appends one line, so the message grows as the loop runs.