Strings and f-strings
Work with text: join it, slice it, clean it, and format it.
Why it matters
A prompt is a string. A model's reply is a string. Most of the data you'll feed an AI system starts as messy text: subject lines with stray spaces, tags in mixed capitals, product names pasted from three different tools. Cleaning text, and building it from pieces, are skills you'll use in nearly every AI project. The first big use is building prompts from data.
What you'll be able to do
- Pull out characters and slices of text with indexes
- Clean and reshape text with string methods
- Build text from variables with f-strings, including formatted numbers
- Write multi-line text and special characters
What it covers
- Text in quotes
- Indexing and slicing
- String methods
- Splitting and joining
- f-strings: text built from values
- Special characters and multi-line text
- Worked example: tidy a subject line and report on it
- Methods give you a new string
- Check before you slice
Text in quotes
A string is a piece of text. Picture a row of letter tiles: each tile is one character, and the row is the string. Single and double quotes work the same way, so pick the one that doesn't clash with the text inside:
headline = "It's our biggest sale" quote = 'She said "worth every penny"' print(headline) print(quote)
Three handy tools:
+joins strings end to end,*repeats them,len()counts the characters, spaces and punctuation included.
first = "Spring" second = "Sale" print(first + " " + second) print("-" * 20) print(len("Spring Sale"))
Indexing and slicing
Every character in a string has a position, called its index. Counting starts at 0, not
- Negative indexes count from the end:
-1is the last character.
code[0]is the first character.code[-1]is the last.code[2:6]is a slice: from index 2 up to, but not including, index 6.- Leave out a side to go to the edge:
code[:8]is the first 8 characters,code[9:]is everything from index 9 on.
Drag the handles below and watch the expression and its result change.
The stop position is never included, which is why code[0:8] gives exactly 8 characters. Try negative positions too.
Campaign codes, SKUs and UTM values often pack several facts into one string. Slicing pulls them apart:
code = "SUMMER25-EMAIL" season = code[:8] channel = code[-5:] print(season) print(channel) print(code[0], code[-1])
Asking for an index past the end, like code[50], raises an IndexError. Slices are more forgiving: code[:50] gives you the whole string.
word = "Newsletter" print(word[1:4])
Show the answer
ews
Index 1 is the 'e'. The slice stops before index 4, so you get indexes 1, 2 and 3: 'ews'.
String methods
A method is a function that belongs to a value. You call it with a dot after the value: subject.lower(). Strings come with dozens of methods. These are the ones you'll use most:
| Method | What it does | " Spring SALE " becomes |
|---|---|---|
.strip() | removes spaces (and newlines) from both ends | "Spring SALE" |
.lower() / .upper() | changes case | " spring sale " / " SPRING SALE " |
.title() | capitalizes each word | " Spring Sale " |
.replace(old, new) | swaps every occurrence | .replace("SALE", "Event") gives " Spring Event " |
.startswith(x) / .endswith(x) | True or False | |
.count(x) | how many times x appears |
Strings can't be changed in place. A method gives you back a new string, so store the result if you want to keep it. You can also chain methods. They run left to right:
raw = " Spring SALE Launch " clean = raw.strip().lower() print(clean) print(raw) # the original is unchanged print(clean.replace("sale", "event"))
The in operator asks whether one string appears inside another. It's case-sensitive, so change everything to lowercase first when that matters:
subject = "Last chance: FREE shipping ends tonight" print("free" in subject) print("free" in subject.lower())
If you've done the numbers lesson, here's the fix it promised for numbers with commas: int("1,200".replace(",", "")) gives 1200.
tag = " Email " tag.strip() print(len(tag))
Show the answer
9
strip() gives back a new string, but this code never stores it. tag still has its spaces: 2 + 5 + 2 = 9 characters. Write tag = tag.strip() to keep the result.
Splitting and joining
.split() breaks a string into pieces wherever a separator appears. It gives you back a list of strings: the values inside square brackets. Lists get their own lesson next. For now, read ['seo', 'email', 'ads'] as "three strings, in order".
.join() does the reverse. It's called on the separator you want between the pieces:
tags = "seo, email, ads".split(", ") print(tags) print(" | ".join(tags)) words = "write three short headlines".split() # no separator: split on any whitespace print(words)
f-strings: text built from values
Joining text with + gets clumsy fast, and it fails if one of the pieces is a number. Think of a form letter with blanks to fill in. An f-string is a string with an f before the opening quote. Anything inside curly brackets { } is worked out and dropped into the text:
product = "Midweight Hoodie" audience = "college students" count = 3 prompt = f"Write {count} ad headlines for the {product}, aimed at {audience}." print(prompt)
That's exactly how you'll build prompts from data later: a template with blanks, filled in from variables.
After the value you can add a colon and a format spec to control how numbers look:
| You write | Shows | Use for |
|---|---|---|
{cpc:.2f} | 2.50 | fixed decimal places |
{impressions:,} | 182,340 | thousands separators |
{spend:,.2f} | 3,120.50 | money |
{ctr:.1%} | 3.0% | a rate shown as a percentage (multiplies by 100 for you) |
spend = 3120.5 impressions = 182340 clicks = 5470 ctr = clicks / impressions print(f"Spend: ${spend:,.2f}") print(f"{impressions:,} impressions, {clicks:,} clicks, CTR {ctr:.1%}") print(f"Cost per click: {spend / clicks:.2f}")
The braces can hold any expression, such as the division in the last line.
Special characters and multi-line text
A backslash inside a string starts an escape sequence, a way to type characters that are otherwise awkward:
| Write | Means |
|---|---|
\n | a new line |
\t | a tab |
\" or \' | a quote mark that doesn't end the string |
\\ | a single backslash |
print("Subject: Spring sale\nPreview: 30% off everything") print("Name:\tDana")
For longer text, such as a prompt template, use triple quotes. The string can span several lines, and the line breaks are kept:
product = "Canvas Tote" prompt = f"""You are a copywriter for an online store. Write one Instagram caption for the {product}. Keep it under 20 words.""" print(prompt)
Worked example: tidy a subject line and report on it
A subject line came out of a spreadsheet with extra spaces and all-caps shouting. Clean it, then print a short report about it.
raw_subject = " LAST CHANCE: 30% off ends tonight! " subject = raw_subject.strip() softer = subject.capitalize() preview = subject[:20] print(f"Cleaned: {softer}") print(f"Length: {len(subject)} characters") print(f"Preview: {preview}...") print(f"Discount? {'%' in subject}")
.strip() removes the stray spaces first, so len() counts only real characters. .capitalize() makes the first letter a capital and the rest lowercase, which tones down the shouting. The slice [:20] copies the snippet an inbox shows before cutting text off. In the last f-string, '%' in subject uses single quotes so it doesn't end the double-quoted f-string. It works out to True.
spend = 1250.5. Which line prints Spend: 1,250.50?Show the answer
print(f"Spend: {spend:,.2f}")
, adds the thousands separator and .2f shows two decimals. Without the f prefix the braces are printed literally, and .2% would show it as a percentage.
Methods give you a new string
.upper(), .strip() and .replace() don't change the original text. They hand back a new string, and if you don't keep it, it's gone.
name = " ada " name.strip() print(repr(name)) name = name.strip() print(repr(name))
Text can't be changed in place in Python, so the only way to "update" a string is to save the result. Note too that in and == care about capitals: "Sale" in "summer sale" is False. Comparing cleaned-up text, such as text.lower(), avoids that surprise.
Check before you slice
A slice stops before its end index, so text[0:3] gives three characters. And an f-string needs its f, or the braces print as they are.
Practice what you just read
- 12 code examples you can edit and run
- a practice exercise that checks your code
- a 6-question quiz
- 6 review cards for spaced repetition
Try a quiz question
What does this print?
subject = "hello"
subject.upper()
print(subject)