A program is a set of instructions you write for the computer to follow. The simplest useful instruction is: show me a value. In Python, that is the job of print().
You hand print() a value, and Python writes that value to the console — the output area under a code cell. The console is where you see the results of your code, and it is the first place you look when something is wrong.
print("Hello, world!")
The text in quotes is a string. You can also pass numbers, or an expression — Python works out the value first, then prints it:
print(2 + 3) # prints 5
Even this tiny building block is the foundation of debugging. When your program behaves strangely, the first thing you do is add print() calls to see what the values actually are. Every experienced programmer debugs this way, so learning print() well is not beginner stuff — it is a professional habit you will use for your entire career.
flowchart LR P["print(value)"] --> S["Python turns value into text"] S --> O["appears in the console"] style P fill:#3776ab,color:#fff
Multiple arguments and automatic spacing
Give print() more than one argument, separated by commas, and it joins them with a single space:
print("Score:", 10 + 5) # Score: 15
This is the pattern you will use constantly: a label (a string), a comma, then a value Python computes. The comma is not part of the string — it is a separator between arguments. Each argument is evaluated first, then they are all printed in order with a space between them. This works with any number of arguments, so print('a', 'b', 'c') joins all three with spaces automatically.
You can override the separator with the sep argument. sep="" removes the space entirely; sep=", " adds a comma and space. This is handy when you need tight control over formatting, such as building a CSV-style line or joining path segments.
print("Hello, world!")
print("2 + 3 =", 2 + 3)
print("The answer is", 42)
Controlling the end of each line
After its output, print() adds a new line by default. That is why each print() above lands on its own line. You can change this with the end argument:
print("Loading", end="")
print("...")
This prints both parts on the same line. The default is end="\n" — a newline character. Other common choices are end=" " to stay on the same line with a space, or end="" to append nothing at all.
Together, sep and end give you precise control over how output is built. Most of the time the defaults are exactly what you want, but knowing they exist saves you from awkward string-joining workarounds. A good rule is: if you find yourself building a string with + just to print it, you probably should be using sep or end instead. Experiment with different combinations until the output looks exactly the way you want.
print("a", "b", "c", sep="-")
print("First", end=" ")
print("Second")
print("Done!")
flowchart LR
A["print('a', 'b', sep='-', end='!')"] --> E["evaluate args"]
E --> J["join with sep"]
J --> N["append end"]
N --> O["a-b!"]
style A fill:#3776ab,color:#fff
style O fill:#16a34a,color:#fff
f-strings: a cleaner way to mix text and values
The trap above has a cure most Python programmers reach for first. An f-string is an ordinary string with an f written in front of it, and inside it you can drop any expression between curly braces. Python runs each expression and tucks the result straight into the surrounding text, so there are no + signs to manage, no str() calls to forget, and no way to crash by joining a string with a number.
Read a placeholder as fill in the gap: the expression between the braces runs, and its answer is stitched into the sentence. f-strings are the modern, readable answer whenever a label and a value must sit together, and once they feel natural you will rarely reach for + again.
flowchart LR F["an f-string with placeholders"] --> E["each placeholder is evaluated"] E --> S["its value is dropped into the text"] S --> O["one finished string"] style F fill:#3776ab,color:#fff style O fill:#16a34a,color:#fff
name = "Ada"
score = 42
print(f"Player {name} scored {score} points.")
print(f"That is {score * 10} in arcade mode.")
Printing lists and other collections
Print a list directly and its items do not scatter across the page — you get the list's representation, brackets and all. print([1, 2, 3]) shows [1, 2, 3], because print() asks the value how it would like to appear as text, and a list answers with square brackets around its members.
This is worth knowing because the representation is built for programmers, not for readers. A list of names prints with quotes around each string and commas between them, which is perfect for debugging but ugly in a report. When the output is for a human rather than for you, reach for a loop or an f-string so you control exactly how each item appears.
Comments: notes to your future self
As programs grow, you will want to leave reminders in the code itself — what a tricky line does, why a number is what it is, a question you have not resolved yet. A comment is text the interpreter ignores, and in Python it starts with a hash: #. Everything from the # to the end of that line is for humans only.
Good comments explain why, not what — the code already shows what it does. A line like # discounts only apply above $50 earns its place; a line like # add tax restates the obvious total = total + tax below it and adds nothing. Used well, comments are a message to the reader who inherits your code, who is very often your future self.
Write price_line(item, price) that returns a single string like Coffee: $4 — the item name, then : $, then the price. (You can print the result yourself afterwards.)
def price_line(item, price):
# build and return "item: $price"
pass
Join strings together with +.
price is an int. Convert it to text with str(price) before joining.
def price_line(item, price):
return item + ": $" + str(price)
What does this print? Remember: print evaluates each expression, and commas become spaces.
print("Score:", 10 + 5)
print("Level", 2)
print works out 10 + 5 first, which is 15.
The comma between arguments becomes one space in the output.
Write print_receipt(items) that takes a list of (name, price) tuples and prints each one on its own line as name: $price. Use a loop and string concatenation.
def print_receipt(items):
# print each item as "name: $price"
pass
Loop over
itemswithfor name, price in items:.Build each line with string concatenation and
str(price).
def print_receipt(items):
for name, price in items:
print(name + ": $" + str(price))
This function tries to print a greeting with an age, but it crashes. Fix it without changing the message format.
def greet(name, age):
print("Hi, I'm " + name + " and I'm " + age + " years old.")
age is an int. Convert it with str(age) before joining.
Or use commas: print("Hi, I'm", name, ...).
def greet(name, age):
print("Hi, I'm " + name + " and I'm " + str(age) + " years old.")
Write countdown(start) that prints numbers from start down to 1 on a single line, separated by ... and ending with ...blastoff!. Use sep and end arguments.
def countdown(start):
# print countdown on one line: 3...2...1...blastoff!
pass
Build a list with range(start, 0, -1).
Unpack it with *nums and use sep='...', end='...blastoff!'.
def countdown(start):
nums = list(range(start, 0, -1))
print(*nums, sep="...", end="...blastoff!")
print()
Recap
print()sends values to the console so you can see what your program is doing.- It evaluates every argument first, then joins them with a space.
sepcontrols the gap between arguments;endcontrols what comes after the last one.- You cannot use
+between a string and a number — convert the number withstr()first, or pass them as separate arguments. - Expressions inside
print()are evaluated before printing, soprint(2 + 3)shows5, not2 + 3. - Mastering
print()early pays off: it is the first tool you reach for when debugging any program.
Next you'll learn about variables, the named storage places that let you keep a value around and use it more than once.