029. String Slicing
Extract sub-sequences with start:stop:step
029. String Slicing
RAM Manager — Parsing Log Lines
Aryan’s RAM manager writes events to a structured log file. Each line has a fixed format:
2024-03-15 ERROR: disk full
0123456789- Characters 0–9 (10 chars): the date
"2024-03-15" - Characters 11–15 (5 chars): the level
"ERROR" - Characters 18 onwards: the message
"disk full"
His get_date() uses log[0:9] — that is 9 characters (indices 0–8), cutting off the last digit of the date. He gets "2024-03-1" instead of "2024-03-15".
Also, get_message() starts at index 17 instead of 18, so it includes the leading space from ": ", returning " disk full" instead of "disk full".
The lesson:
s[start:stop]includesstartbut excludesstop. To get 10 characters starting at 0, uses[0:10]— nots[0:9].
💡 Fun fact: Python’s exclusive-stop slicing convention (s[0:10] gives 10 items, not 11) was chosen by Guido van Rossum because it makes several properties elegant: len(s[a:b]) == b - a, slices can be concatenated as s[:n] + s[n:] == s, and an empty slice s[n:n] is always valid. Edsger Dijkstra wrote a famous argument for this convention in 1982.
⚠️ Watch out: The most common slicing mistake is using s[0:9] when you want the first 10 characters, forgetting that stop is exclusive. To get n characters starting at index i, the stop must be i + n, not i + n - 1.
🤔 Think about it: s[::-1] reverses a string in one expression, but s[1::-1] only reverses the first two characters. The step -1 means “go backwards” — so what does the start and stop represent when stepping backwards, and why does omitting them ([::-1]) give you the full reversed string?
Learning objectives
- Extract substrings with s[start:stop]
- Use negative indices in slices
- Reverse strings with s[::-1]
Key concepts
- string slicing
- start stop step
- substring
Try it
Concept detail
Slicing syntax: s[start:stop:step]. Stop is EXCLUSIVE (not included). Defaults: start=0, stop=len(s), step=1. Omit any: s[:5] == s[0:5], s[2:] == s[2:len(s)]. Step: s[::2] every other char, s[::-1] reversed. Slicing never raises IndexError — out-of-range just gives fewer characters. s[1:100] on a 5-char string gives s[1:5] without error. Slicing creates a new string (strings are immutable).
Solution
def get_date(log):
return log[0:10]
def get_level(log):
return log[11:16]
def get_message(log):
return log[18:]
def reverse_string(s):
return s[::-1]Tests
LOG = "2024-03-15 ERROR: disk full"
def test_get_date():
assert get_date(LOG) == "2024-03-15"
def test_get_level():
assert get_level(LOG) == "ERROR"
def test_get_message():
assert get_message(LOG) == "disk full"
def test_reverse_hello():
assert reverse_string("hello") == "olleh"
def test_reverse_empty():
assert reverse_string("") == ""