Skip to content

2.1.4 Input and Output

Python input processing output flowchart

This section is where your program starts interacting with the user. You’ll learn how to use input() to receive information, print() to display results, and f-string formatting to lay the foundation for command-line tools, API debugging, and result presentation later on.

  • Master different uses of print() and formatted output
  • Learn how to use input() to get user input
  • Understand advanced f-string formatting
  • Write simple interactive programs

When beginners learn Python, this is the one line to focus on first: the program gets input, does a bit of processing, and then outputs the result. CLI, API, RAG, and Agent later on all repeat this same pattern in essence.

service = input("Please enter the service name: ")
latency_ms = int(input("Please enter latency in ms: "))
print(f"Service: {service}")
print(f"Latency in seconds: {latency_ms / 1000:.2f}")
print(f"Alert threshold in 10 ms: {latency_ms + 10} ms")

Example output:

FieldValue
Service inputLogin API
Latency input185 ms
Printed seconds0.18
Printed threshold195 ms

This is the most basic input/output pattern: input() is responsible for receiving data, and print() is responsible for displaying the result.


print() is the function you will use most often, without question.

# Print a string
print("Hello, World!")
# Print numbers
print(42)
print(3.14)
# Print a variable
name = "Python"
print(name)
# Print the result of an expression
print(1 + 2 + 3) # 6
# Separate with commas; print will automatically join them with spaces
print("Service:", "Login API", "Latency:", 185, "ms")
# Output: Service: Login API Latency: 185 ms
# Custom separator
print("2026", "01", "15", sep="-")
# Output: 2026-01-15
print("lint", "test", "deploy", sep=" | ")
# Output: lint | test | deploy
# By default, every print ends with a newline
print("Line 1")
print("Line 2")
# Output:
# Line 1
# Line 2
# Use the end parameter to change the ending character
print("Hello", end=" ")
print("World")
# Output: Hello World (on the same line)
# Use end to create a simple progress display
print("Loading", end="")
print(".", end="")
print(".", end="")
print(".", end="")
print(" Done!")
# Output: Loading... Done!
# Newline character \n
print("Line 1\nLine 2\nLine 3")
# Output:
# Line 1
# Line 2
# Line 3
# Tab character \t (used for alignment)
print("Task\tOwner\tStatus")
print("Login API\tMina\tDone")
print("Dashboard UI\tKai\tIn progress")
# Output:
# Task Owner Status
# Login API Mina Done
# Dashboard UI Kai In progress
# Backslash itself \\
print("File path: C:\\Users\\Desktop")
# Raw string (does not process escape sequences)
print(r"File path: C:\Users\Desktop") # The r prefix means a raw string

f-string is the string formatting style introduced in Python 3.6, and it is also the most recommended method at present.

service = "Login API"
owner = "Mina"
latency_ms = 92.567
# Add f before the string, and put variable names inside curly braces
print(f"{service} is owned by {owner}")
# Output: Login API is owned by Mina
# You can put any expression inside the curly braces
print(f"The next retry number is {2 + 1}")
print(f"The service name has {len(service)} characters")
print(f"Within 100 ms target? {'Yes' if latency_ms < 100 else 'No'}")

This is one of the most powerful features of f-strings:

# Control decimal places
pi = 3.141592653589793
print(f"π = {pi:.2f}") # 3.14 (keep 2 decimal places)
print(f"π = {pi:.4f}") # 3.1416 (keep 4 decimal places)
# Percentage
accuracy = 0.8734
print(f"Accuracy: {accuracy:.1%}") # 87.3%
print(f"Accuracy: {accuracy:.2%}") # 87.34%
# Thousands separator
population = 1400000000
print(f"Population: {population:,}") # 1,400,000,000
print(f"Population: {population:_}") # 1_400_000_000
# Scientific notation
speed_of_light = 299792458
print(f"Speed of light: {speed_of_light:.2e} m/s") # 3.00e+08 m/s
# Pad integers with zeros
for i in range(1, 4):
print(f"Episode {i:03d}") # Episode 001, Episode 002, Episode 003
# Left align, right align, center
name = "Python"
print(f"|{name:<20}|") # |Python | left aligned
print(f"|{name:>20}|") # | Python| right aligned
print(f"|{name:^20}|") # | Python | centered
# Pad with a specific character
print(f"|{name:*<20}|") # |Python**************|
print(f"|{name:*>20}|") # |**************Python|
print(f"|{name:*^20}|") # |*******Python*******|
# Practical use: print a simple table
print(f"{'Service':<16}{'Latency':>10}")
print("-" * 20)
print(f"{'Login API':<16}{95:>10}")
print(f"{'Search API':<16}{187:>10}")
print(f"{'Worker':<16}{42:>10}")

Output:

Service Latency
--------------------
Login API 95
Search API 187
Worker 42
FormatMeaningExampleResult
:.2fKeep 2 decimal placesf"{3.14159:.2f}"3.14
:.1%Percentage (1 decimal place)f"{0.873:.1%}"87.3%
:,Thousands separatorf"{1000000:,}"1,000,000
:.2eScientific notationf"{12345:.2e}"1.23e+04
:03dPad with zeros to 3 digitsf"{5:03d}"005
:<10Left aligned, width 10f"{'hi':<10}"hi________
:>10Right aligned, width 10f"{'hi':>10}"________hi
:^10Centered, width 10f"{'hi':^10}"____hi____

input() pauses the program, waits for the user to type something, and then returns the input as a string.

# input() always returns a string!
service = input("Please enter the service name: ")
print(f"Checking {service}!")
print(type(service)) # <class 'str'>
# Common pitfall
latency = input("Please enter latency in ms: ") # User enters 185
print(type(latency)) # <class 'str'>, not int!
# If you do math directly, there will be a problem
# print(latency + 10) # Error! You can't add a number to a string
# Correct approach: convert the type first
latency = int(input("Please enter latency in ms: ")) # Convert to int while reading input
print(f"Alert threshold: {latency + 10} ms")
# If you need a floating-point number
timeout = float(input("Please enter timeout seconds: "))
print(f"Timeout is {timeout} seconds")

Users may enter something other than what you expected:

# The user entered "abc" instead of a number
# latency_ms = int(input("Please enter latency in ms: ")) # This will raise a ValueError!
# Safer approach (we will cover exception handling later, which is more elegant)
user_input = input("Please enter a number: ")
if user_input.isdigit():
number = int(user_input)
print(f"The number you entered is: {number}")
else:
print("This is not a valid number!")

print("=== Simple Calculator ===")
num1 = float(input("Please enter the first number: "))
num2 = float(input("Please enter the second number: "))
print(f"\nResults:")
print(f"{num1} + {num2} = {num1 + num2}")
print(f"{num1} - {num2} = {num1 - num2}")
print(f"{num1} × {num2} = {num1 * num2}")
if num2 != 0:
print(f"{num1} ÷ {num2} = {num1 / num2:.2f}")
else:
print("The divisor cannot be 0!")
# Simulated training result data
model_name = "ResNet-50"
total_epochs = 100
train_accuracy = 0.9534
val_accuracy = 0.9187
train_loss = 0.1245
val_loss = 0.2891
training_hours = 2.5
# Generate a formatted report
print("=" * 40)
print(f"{'Model Training Report':^40}")
print("=" * 40)
print(f"Model name: {model_name}")
print(f"Training epochs:{total_epochs}")
print(f"Training accuracy:{train_accuracy:.2%}")
print(f"Validation accuracy:{val_accuracy:.2%}")
print(f"Training loss: {train_loss:.4f}")
print(f"Validation loss: {val_loss:.4f}")
print(f"Training time: {training_hours:.1f} hours")
print("-" * 40)
# Judge model status
gap = train_accuracy - val_accuracy
if gap > 0.05:
print(f"⚠️ Overfitting risk: training/validation gap {gap:.2%}")
else:
print(f"✅ Model looks good: training/validation gap {gap:.2%}")
print("=" * 40)

Output summary:

FieldValue
ModelResNet-50
Epochs100
Accuracytrain 95.34%, validation 91.87%
Losstrain 0.1245, validation 0.2891
Training time2.5 hours
WarningOverfitting risk: gap 3.47%

Write a program that asks for a feature name, owner, completed tasks, and total tasks, then generates a formatted project status card:

feature = input("Feature name: ")
owner = input("Owner: ")
completed_tasks = int(input("Completed tasks: "))
total_tasks = int(input("Total tasks: "))
progress = completed_tasks / total_tasks
# Generate the project status card below
print("=" * 34)
print(f"Feature: {feature}")
print(f"Owner: {owner}")
print(f"Progress: {progress:.1%}")
print(f"Remaining: {total_tasks - completed_tasks}")
print("=" * 34)
# Input task information
task1 = "API endpoint"
hours1 = 5.0
rate1 = 40
task2 = "UI polish"
hours2 = 3.5
rate2 = 40
# Print a project estimate, with these requirements:
# 1. Task names left aligned, numbers right aligned
# 2. Show the cost for each task
# 3. Show the total at the end
# Hint: use f-string alignment features
subtotal1 = hours1 * rate1
subtotal2 = hours2 * rate2
total = subtotal1 + subtotal2
print("=" * 46)
print(f"{'Task':<18}{'Hours':>8}{'Rate':>6}{'Cost':>12}")
print("-" * 46)
print(f"{task1:<18}{hours1:>8.1f}{rate1:>6}{subtotal1:>12.2f}")
print(f"{task2:<18}{hours2:>8.1f}{rate2:>6}{subtotal2:>12.2f}")
print("-" * 46)
print(f"{'Total':<32}{total:>14.2f}")

Write a program that lets the user enter latency in milliseconds, then outputs the corresponding seconds and minutes:

latency_ms = float(input("Please enter latency in ms: "))
# 1000 milliseconds = 1 second
# 60 seconds = 1 minute
seconds = latency_ms / 1000
minutes = seconds / 60
print(f"{latency_ms:.2f} ms = {seconds:.2f} seconds")
print(f"{latency_ms:.2f} ms = {minutes:.2f} minutes")
Reference implementation and walkthrough
  1. input() returns strings. Convert completed/total task counts with int() and latency with float() before doing arithmetic.
  2. The status card should have top and bottom separators and should reflect the values typed by the user.
  3. The estimate table should align columns and show costs 200.00, 140.00, and total 340.00 for the given data.
  4. For latency_ms = 2500, seconds are 2.50 and minutes are about 0.04.
  5. If conversion fails, check for empty input, non-numeric input, full-width digits, or units typed into the number field.

Keep this page’s proof of learning as a small evidence card:

Concept
variable, type, operator, input/output, branch, loop, structure, function, or module
Code
smallest runnable Python snippet for the concept
Output
printed value, type, branch result, loop trace, or returned value
Failure Check
type mismatch, indentation, off-by-one, mutable data, or import path issue
Expected Output
code plus printed result that proves the concept works
Function/SyntaxPurposeKey point
print()Output informationsep changes the separator, end changes the ending
input()Get user inputThe return value is always a string
f"..."Format strings{variable:format} controls how values are displayed
int() / float()Type conversionYou usually need to convert after input()