Homework

8.4.3. Homework#

  • Use these questions after class to check your understanding of the chapter concepts and coding skills.

  • Sign in from the account menu before you start working on the homework.

  • Complete all true/false and coding questions before you submit the homework.

  • Launch Live Code (the rocket) to write and run code in the coding cells.

  • Multiple submissions are allowed. The highest score is kept.

1. String Immutability

A cleaning script should create a new cleaned string instead of expecting a string method to mutate the original text in place.

Hide code cell source

### Solution
# True
# Strings are immutable, so methods such as strip() and lower() return a new string and
# leave the original unchanged. You must assign the result, as in text = text.strip(), to
# keep the cleaned version.

2. Normalization

Lowercasing and stripping whitespace can help make text comparisons more consistent.

Hide code cell source

### Solution
# True
# strip() removes leading and trailing whitespace and lower() converts letters to
# lowercase. After both steps, " Data " and "data" compare as equal.

3. Splitting Text

split() always preserves punctuation as separate tokens without extra cleaning.

Hide code cell source

### Solution
# False
# split() with no argument splits only on whitespace, so punctuation stays attached to
# neighboring words, as in "data,". You need extra cleaning, such as replace() or a
# regular expression, to remove or separate punctuation.

4. Regular Expressions

A regular expression is useful when a script needs to find text that follows a pattern such as several digits.

Hide code cell source

### Solution
# True
# A regular expression describes a pattern rather than fixed text. For example,
# re.findall(r"\d+", text) finds every run of one or more digits.

5. Text Frequency

A word-frequency report should usually treat Data and data as different words when capitalization is not meaningful.

Hide code cell source

### Solution
# False
# When capitalization is not meaningful, Data and data are the same word and should be
# counted together. A frequency report should normalize case first, for example with
# lower(), so the counts are not split.
### 6. Normalize a label
# Strip extra spaces and title-case the label. Print exactly this line:
# # Label: Quarterly Revenue
label = "  quarterly revenue  "

### Your code starts here.



### Your code ends here.

Hide code cell source

### Solution
label = "  quarterly revenue  "
clean_label = label.strip().title()
print("Label:", clean_label)
Label: Quarterly Revenue
### 7. Split and clean words
# Create lowercase words without commas. Print exactly this line:
# # Words: ['data', 'science', 'data']
text = "Data, science, data"

### Your code starts here.



### Your code ends here.

Hide code cell source

### Solution
text = "Data, science, data"
words = text.replace(",", "").lower().split()
print("Words:", words)
Words: ['data', 'science', 'data']
### 8. Use a regex pattern
# Use `re.findall` to collect ticket numbers. Print exactly this line:
# # Ticket numbers: ['12', '105']
message = "Ticket 12 moved before ticket 105."

### Your code starts here.



### Your code ends here.

Hide code cell source

### Solution
import re

message = "Ticket 12 moved before ticket 105."
numbers = re.findall(r"\d+", message)
print("Ticket numbers:", numbers)
Ticket numbers: ['12', '105']
### 9. Count normalized words
# Build a word count dictionary. Print exactly this line:
# # Counts: {'python': 2, 'data': 1}
text = "Python data PYTHON"

### Your code starts here.



### Your code ends here.

Hide code cell source

### Solution
text = "Python data PYTHON"
counts = {}

for word in text.lower().split():
    counts[word] = counts.get(word, 0) + 1

print("Counts:", counts)
Counts: {'python': 2, 'data': 1}
### 10. Build a successor map
# Split sentence into words. Build successor_map, a dict that maps each
# word to the list of words that follow it in the sentence (use
# setdefault, or check whether the word is already a key).
# Write generate(word, length) that returns a list of words starting
# with word: while the list has fewer than length words and word has
# successors, move word to the first word in its successor list and
# append it. Stop early when word has no successors.
# Print the successors of "the", then the words generated from "the"
# and from "dog" with length 6, joined with spaces.
# Print exactly these lines:
# # Successors of 'the': ['cat', 'mat', 'dog']
# # From 'the': the cat sat on the cat
# # From 'dog': dog ran away
sentence = "the cat sat on the mat and the dog ran away"

### Your code starts here.



### Your code ends here.

Hide code cell source

### Solution
sentence = "the cat sat on the mat and the dog ran away"

words = sentence.split()
successor_map = {}
for i in range(len(words) - 1):
    successor_map.setdefault(words[i], []).append(words[i + 1])


def generate(word, length):
    result = [word]
    while len(result) < length and word in successor_map:
        word = successor_map[word][0]
        result.append(word)
    return result


print("Successors of 'the':", successor_map["the"])
print("From 'the':", " ".join(generate("the", 6)))
print("From 'dog':", " ".join(generate("dog", 6)))
Successors of 'the': ['cat', 'mat', 'dog']
From 'the': the cat sat on the cat
From 'dog': dog ran away