Python 3.04: Strings HW
Popcorn Hack 1: Extract the Hidden Message
Only indexing and slicing, no string methods. The real words sit at fixed positions between decoy characters.
Code Runner Challenge
Popcorn Hack 1 - Extract the hidden message using indexing and slicing
View IPYNB Source
# CODE_RUNNER: Popcorn Hack 1 - Extract the hidden message using indexing and slicing
transmission = "xxSIGNALxxxCONFIRMEDxx77xxDELTA"
# "SIGNAL" starts at index 2 and is 6 characters long, so the stop index is 2 + 6 = 8 (excluded).
word_1 = transmission[2:8]
print("Word 1:", word_1)
# "SIGNAL" ends at index 7, then "xxx" fills 8-10, so "CONFIRMED" (9 letters) is 11 up to 20.
word_2 = transmission[11:20]
print("Word 2:", word_2)
# Negative slicing: -5 starts 5 characters from the end, and leaving out stop means "to the end".
word_3 = transmission[-5:]
print("Word 3:", word_3)
# len() counts every character, including the decoys.
print("Total length:", len(transmission))
# A step of 2 keeps every other character. The words get chopped up, so this pattern does NOT
# reveal the message; fixed-position slicing is what finds it.
print("Every other character:", transmission[::2])
Popcorn Hack 2: Scrub and Search a Noisy Transmission
Only string methods. Each method returns a new string, so every result is saved into a new variable.
Code Runner Challenge
Popcorn Hack 2 - Clean and search a noisy transmission using string methods
View IPYNB Source
# CODE_RUNNER: Popcorn Hack 2 - Clean and search a noisy transmission using string methods
noisy = " ...AGENT>>>Falcon---reports: the PACKAGE has ARRIVED!!! "
# .strip() returns a NEW string without the outer whitespace; noisy itself never changes.
trimmed = noisy.strip()
print("Trimmed:", repr(trimmed))
# Methods can be chained because each .replace() hands back a new string for the next one.
# ">" and "-" become spaces so the words don't run together; "!" is removed completely.
cleaned = trimmed.replace(">", " ").replace("-", " ").replace("!", "")
print("Cleaned:", cleaned)
# .lower() makes an all-lowercase COPY so the search below ignores capitalization.
lowered = cleaned.lower()
print("Lowered:", lowered)
# `in` returns True or False, so it works directly as a search.
has_arrived = "arrived" in lowered
print("Contains 'arrived':", has_arrived)
# .split() with no argument splits on ANY run of whitespace, so the extra spaces don't create empty words.
words = cleaned.split()
print("Words:", words)
print("Word count:", len(words))
Popcorn Hack 3: Build a Decoded Report
Concatenation, str(), f-strings, and .join().
Code Runner Challenge
Popcorn Hack 3 - Build a decoded report using concatenation and formatting
View IPYNB Source
# CODE_RUNNER: Popcorn Hack 3 - Build a decoded report using concatenation and formatting
agent_name = "Falcon"
target_word = "MIDNIGHT"
confidence = 87 # a percentage, stored as an int
fragments = ["ALPHA", "SEVEN", "DELTA"]
# + only joins strings to strings, so every piece here is already a str.
headline = "Agent " + agent_name + " intercepted: " + target_word
print(headline)
# confidence is an int, so it needs str() first; "Confidence: " + 87 would raise a TypeError.
confidence_line = "Confidence: " + str(confidence) + "%"
print(confidence_line)
# The f-string converts confidence automatically, with no + or str() needed.
confidence_line_fstring = f"Confidence: {confidence}%"
print(confidence_line_fstring)
# .join() is the reverse of .split(): it glues a list into one string with "-" between pieces.
joined_fragments = "-".join(fragments)
print("Joined fragments:", joined_fragments)
final_report = f"REPORT: {headline} | {confidence_line} | Fragments: {joined_fragments}"
print(final_report)
Homework Hack: Crack the Final Transmission
All three skills together: methods to clean and split the CSV row, indexing to pull out fields, slicing to check the year, and f-strings to rebuild it as a Markdown table row and a JSON line.
Code Runner Challenge
Homework - Crack the Final Transmission using slicing, methods, and formatting
View IPYNB Source
# CODE_RUNNER: Homework - Crack the Final Transmission using slicing, methods, and formatting
raw_transmission = " 2026-09-15,GHOST,THE-EAGLE-LANDS-AT-DAWN,87 "
# 1. Clean and split: .strip() removes the outer spaces, then .split(",") breaks the CSV row into a LIST.
# Stripping first matters: otherwise the first and last fields would keep stray spaces.
segments = raw_transmission.strip().split(",")
print("Segments:", segments)
# 2. Extract by index: the list keeps the CSV's field order, so each index is one column.
date = segments[0]
agent = segments[1]
message_code = segments[2]
confidence_str = segments[3]
print("Date:", date, "| Agent:", agent, "| Message code:", message_code, "| Confidence:", confidence_str)
# 3. Slice-check the year: date[0:4] is the first 4 characters. This is slicing, not a method.
year_check = date[0:4] == "2026"
print("Year check:", year_check)
# 4. Clean the message: .replace() returns a NEW string, so the result must be saved.
message = message_code.replace("-", " ")
print("Message:", message)
# 5. Case-insensitive search: lowercase a copy first, so "DAWN" matches "dawn".
found_dawn = "dawn" in message.lower()
print("Found 'dawn':", found_dawn)
# 6. Markdown table row: "|" separates the columns, just like a real Markdown table.
markdown_row = f"| {date} | {agent} | {message} | {confidence_str}% |"
print("Markdown row:", markdown_row)
# 7. JSON line: braces wrap the object, ":" separates keys from values, and "," separates pairs.
# The braces are stored in variables so they print as plain characters instead of being read
# as f-string placeholders. Strings get quotes, the number doesn't, and str(found_dawn).lower()
# turns Python's True into JSON's lowercase true.
open_brace = "{"
close_brace = "}"
json_line = f'{open_brace}"date": "{date}", "agent": "{agent}", "message": "{message}", "confidence": {confidence_str}, "contains_dawn": {str(found_dawn).lower()}{close_brace}'
print("JSON line:", json_line)
How It Works
Strings are ordered and immutable (AAP-1.C.4): every slice and method above returned a new string, and the original transmissions never changed, which is why each result had to be saved into a new variable. Slicing pulled out substrings by position (AAP-2.D.2), the methods cleaned and searched the text, and concatenation, f-strings, and .join() rebuilt the decoded data into new strings (AAP-2.D.1). The homework uses real separators: commas to split a CSV row, pipes to build a Markdown table row, and braces, colons, and commas to build a JSON line.