RizTech Academy logo
RizTech Academy
Variables and Data TypesLesson 3 of 525 min

Strings and f-strings

Text is most of what programs actually handle — names, addresses, messages, file contents, everything a user types. This is the longest lesson in the module, and the f-string section is the single most useful piece of syntax you will learn this week.

Making strings

Single and double quotes work identically:

name = "Priya"
city = 'Pune'

Pick one and stay consistent. The exception is when the text itself contains a quote:

message = "It's raining"
quote = 'She said "hello"'

Use the other kind, and you avoid escaping entirely.

For text spanning several lines, use triple quotes:

address = """42 MG Road
Koregaon Park
Pune 411001"""
print(address)

The line breaks are preserved exactly as typed.

Joining and repeating

first = "Priya"
last = "Sharma"
full = first + " " + last
print(full)
Priya Sharma

+ joins strings. Note the " " — without it you get PriyaSharma. Python adds nothing you did not ask for.

* repeats:

print("-" * 40)

A quick way to print a separator line.

Adding a string to a number fails:

age = 25
print("I am " + age)
TypeError: can only concatenate str (not "int") to str

This is Python refusing to guess. Did you mean the text "25", or something numeric? Rather than choose for you, it stops. The fix is the next section.

f-strings

This is the important part.

Put f before the opening quote, and anything inside { } is worked out and inserted:

name = "Priya"
age = 25
print(f"{name} is {age} years old")
Priya is 25 years old

No +, no converting the number by hand, and — crucially — you can read it. The sentence looks like the sentence.

Any expression works inside the braces, not just a name:

price = 250
quantity = 3
print(f"Total: {price * quantity} rupees")
print(f"Name in caps: {name.upper()}")
Total: 750 rupees
Name in caps: PRIYA

Formatting inside the braces

After a colon you can say how to display the value. These few are worth memorising:

pi = 3.14159265
print(f"{pi:.2f}")        # 3.14      — two decimal places
print(f"{1234567:,}")     # 1,234,567 — thousands separators
print(f"{0.856:.1%}")     # 85.6%     — as a percentage

Combine them for money:

total = 1234567.891
print(f"Total: {total:,.2f}")
Total: 1,234,567.89

That one line replaces a surprising amount of fiddly code.

Alignment, for lining up columns:

for item, cost in [("Tea", 40), ("Coffee", 120), ("Sandwich", 85)]:
    print(f"{item:<12}{cost:>6}")
Tea             40
Coffee         120
Sandwich        85

< left-aligns, > right-aligns, ^ centres, and the number is the width. You have not met for loops yet — they arrive in the next module — so take that example on trust for now.

A debugging trick

Put = after the expression and Python prints both the expression and its value:

count = 17
print(f"{count = }")
count = 17

When you are scattering print calls to find a bug, this saves typing the name twice and guarantees the label matches what is actually printed.

Older styles

You will meet these in existing code:

print("%s is %d years old" % (name, age))     # very old
print("{} is {} years old".format(name, age)) # older
print(f"{name} is {age} years old")           # use this

Recognise the first two. Write the third.

Useful methods

A method is a function belonging to a value, called with a dot.

text = "  Hello World  "

print(text.strip())        # "Hello World" — removes surrounding whitespace
print(text.upper())        # "  HELLO WORLD  "
print(text.lower())        # "  hello world  "
print(text.replace("World", "Pune"))

strip() matters more than it looks. Anything a user types or that comes from a file arrives with stray spaces and newlines, and a trailing space is invisible while breaking every comparison you make.

Searching and testing:

email = "priya@example.com"

print(email.startswith("priya"))   # True
print(email.endswith(".com"))      # True
print("@" in email)                # True
print(email.find("@"))             # 5
print(len(email))                  # 17

in is the readable way to ask whether text appears inside other text. Prefer it to find() unless you need the position.

Splitting and joining are a pair you will use constantly:

csv_line = "Priya,Sharma,Pune"
parts = csv_line.split(",")
print(parts)

rejoined = " | ".join(parts)
print(rejoined)
['Priya', 'Sharma', 'Pune']
Priya | Sharma | Pune

split turns a string into a list; join turns a list back into a string. Note that join is called on the separator, which reads backwards until you have done it twice.

Indexing and slicing

Positions start at zero:

word = "Python"
print(word[0])    # P
print(word[1])    # y
print(word[-1])   # n   — last character
print(word[-2])   # o   — second from last

Negative indexes count from the end, so [-1] is the last character without needing to know the length.

Slicing takes a range, [start:end], where end is not included:

word = "Python"
print(word[0:3])   # Pyt
print(word[:3])    # Pyt   — from the beginning
print(word[3:])    # hon   — to the end
print(word[::-1])  # nohtyP — reversed

That exclusive end is the single most common off-by-one confusion in Python. The way to hold it: word[0:3] gives you three characters, starting at zero. The length of the slice is end - start.

Strings cannot be changed

word = "Python"
word[0] = "J"
TypeError: 'str' object does not support item assignment

Strings are immutable. You cannot modify one in place. Every method that appears to change a string actually returns a new one:

text = "hello"
text.upper()
print(text)        # still "hello"

text = text.upper()
print(text)        # now "HELLO"

That first text.upper() computed "HELLO" and threw it away, because nothing caught the result. This catches everybody once. If a string method seems to have done nothing, check that you assigned its result.

Escape characters

print("Line one\nLine two")     # \n is a newline
print("Name:\tPriya")           # \t is a tab
print("She said \"hello\"")     # \" is a literal quote
print("C:\\Users\\priya")       # \\ is a literal backslash

For Windows paths, a raw string is easier — the r switches escaping off:

print(r"C:\Users\priya\new_file")

Without the r, that \n in \new_file would become a newline.

Practice

  1. Ask for a first and last name (hard-code them for now), and print a greeting using an f-string.
  2. Given price = 2499.5, print Price: ₹2,499.50 using f-string formatting only — no manual rounding.
  3. Take " PRIYA SHARMA " and produce "Priya Sharma" using string methods. You will need strip() and one more; find it with dir("").
  4. Given email = "priya.sharma@example.com", extract the username before the @ two ways: once with split(), once with slicing and find().
  5. Write a function-free "password strength" check: given password = "hello123", print its length, whether it contains a digit (try any(c.isdigit() for c in password)), and whether it is longer than 8 characters.
  6. Prove immutability to yourself: call .upper() on a string without assigning the result, print it, and confirm nothing changed.

Next: booleans, None, and the values Python quietly treats as false.

Stuck on this lesson?

Being stuck is part of it — but being stuck alone for three days is not. Our internship programme pairs this curriculum with code review and one-to-one help from working developers, and it is free.

About the internship