Today's outcomes
- Distinguish literal characters from escape syntax.
- Explain raw strings and their limitations.
- Use f-string formatting without losing numeric precision.
Before you start: Complete Day 12 and its practical challenge.
Understand the concept
A literal's source spelling is not always its value
Escape sequences let source code represent characters that would otherwise be difficult to write in a quoted literal. \n represents a newline, \t a tab, \\ a backslash, and an escaped quote can appear inside a string delimited by that quote. The source contains backslashes, but the resulting string may contain a different character.
This distinction matters when inspecting a path, a report, or a pattern. print displays the string's value, while repr produces an inspection representation with escapes visible. Seeing \n in repr is not evidence that print will display a literal backslash and letter n. Inspect the value and its representation as two different views.
Triple-quoted literals allow several source lines within one string. They can be useful for a fixed message, but they also preserve unintended indentation and newlines. If an output contract requires exact lines, check the resulting value rather than assuming source layout is invisible.
Raw strings reduce escape interpretation
A raw string prefix such as r"..." treats backslashes differently when forming the literal. It is useful for many regular-expression patterns and illustrative Windows paths. It does not create a separate raw-string runtime type: the result is still a str.
A raw literal cannot end with an odd number of backslashes immediately before its closing quote, because the quote would be escaped at the lexical level. “Raw means every possible spelling is allowed” is therefore false. For actual file paths, pathlib on Day 16 is often clearer than manually managing path separators.
Raw strings also do not switch off interpretation by the library that later receives them. A regular-expression engine can still treat backslash sequences in the resulting pattern specially. Python string parsing and regex parsing are separate layers.
F-strings create presentation from values
F-strings insert evaluated expressions between braces. Format specifications can align text, control decimal places, or display percentages. A width is generally a minimum field width, not an automatic maximum. A long title can exceed a 12-character field unless you explicitly truncate it under a stated policy.
Keep the underlying values numeric and format at the display boundary. Use doubled braces to include literal braces in an f-string. An inspection conversion such as !r can reveal spaces and escapes while debugging. Avoid hiding complicated calculations inside a display expression when a named intermediate result would explain the report better.
Worked example
topic = "functions"
minutes = 75
target = 90
fraction = minutes / target
path_hint = r"C:\notes\day13.txt"
print("First line\nSecond line")
print("Literal inspection:", repr("First line\nSecond line"))
print("Path text:", path_hint)
print(f"{topic:<12} | {minutes:>4} minutes")
print(f"Target reached: {fraction:.1%}")
print(f"Literal braces: {{topic}}; value: {topic!r}")
assert isinstance(path_hint, str)
assert "\n" in "First line\nSecond line"
assert fraction == 75 / 90
| Feature | Example effect | What remains unchanged |
|---|---|---|
| Newline escape | First and second lines display separately | The program still holds one string |
| repr | Escapes become inspectable | Original string value |
| Raw path literal | Backslashes stay in path text | Result is still str |
| Width alignment | Topic left, minutes right | Topic and numeric minutes |
| Percentage format | About 83.3% displayed | Underlying ratio 75/90 |
The path is only illustrative text; this script does not access a Windows drive. The percentage is a ratio in this fictional session, not a claim about learning quality.
Guided practice
- Predict: compare the length and display of
"a\nb"withr"a\nb". One contains a newline; the other contains a backslash and n. Check with repr after making your prediction. - Modify: add a tab between two labels, then replace it with explicit field widths. Explain why tabs can display differently across terminals and why predictable report alignment may need a clearer contract.
- Reconstruct: format 7 recorded sessions out of 10 as 70.0%, but retain the numeric ratio for a later comparison. State that the denominator counts observed sessions, not just selected sessions.
Use formatting to clarify data, not to conceal it. Rounding two close results to the same displayed value does not make their underlying values equal. If a decision depends on precision, apply the decision to the numeric value under its own rule.
Daily challenge
Implement format_session(topic, minutes). The topic is text without line breaks; minutes is a nonnegative integer or None. Display at most the first 12 code points of the topic, left-aligned in a 12-character field. Display known minutes right-aligned in four characters, or -- for missing minutes. Separate fields with |.
| Input | Required interpretation |
|---|---|
| functions, 75 | Known duration 75, right-aligned |
| lists, 0 | Known zero remains 0 |
| strings, None | Missing duration becomes -- |
| a title longer than 12 code points, 60 | Title deliberately truncated |
This is a simple terminal display contract. Code-point width is not a universal visual-column width for Unicode text. Record that limitation rather than claiming the formatter perfectly aligns every script or emoji.
Reference solution
Compare after attempting the challenge
def format_session(topic, minutes):
title = topic[:12]
duration = "--" if minutes is None else str(minutes)
return f"{title:<12} | {duration:>4}"
assert format_session("functions", 75) == "functions | 75"
assert format_session("lists", 0) == "lists | 0"
assert format_session("strings", None) == "strings | --"
assert format_session("abcdefghijklmnop", 60) == "abcdefghijkl | 60"
print(format_session("functions", 75))
print(format_session("strings", None))
The known-zero and missing cases stay distinct. Truncation happens before formatting, so the width does not silently accept an overlong title. The function returns one string; the caller decides when to print it.
Debug and explain
If a path displays a newline unexpectedly, inspect whether a backslash-n sequence was interpreted in the literal. If braces appear in output, inspect the f prefix and doubled-brace rules. If long fields break alignment, inspect your width assumptions instead of adding arbitrary spaces to individual examples.
Explain the layers of source spelling, string value, and display. Then explain which part of the daily formatter loses information deliberately. Keeping original topic values outside the formatter lets the application retain the full title even when its report is shortened.
Review and next step
Save one value with escapes and its repr, plus the four formatting checks. Rebuild the missing-duration branch at your next review. Day 14 introduces concise list transformations while preserving the explicit policies you have been practicing.
Sources and verification
Original teaching examples checked with Python 3.12.14. Library behavior reviewed against these primary references on October 3, 2026. Day 26's examples also use Beautiful Soup 4.14.3.
Check your understanding
Five questions, 20 points each. Pass at 85% or above, which requires all five correct. Feedback explains each answer; revise the lesson and retry when needed.
Review your practical work
Check these statements after running your own challenge. This is your self-review; the website does not execute or assess your Python code.
Pass the knowledge check and finish the practical self-review to save completion.