Python Basics — Strings Practice Exercises
Strings Practice Exercises
Test your understanding of string creation, slicing, methods, formatting, and basic regex.
Exercise 1: Word Counter
Write a function that takes a sentence and returns a dictionary with word frequencies (case-insensitive). Remove punctuation before counting.
Expected Output:
count_words("Hello hello world! World hello.")
# {'hello': 3, 'world': 2}
Solution
import re
def count_words(sentence):
# Remove punctuation and lowercase
clean = re.sub(r"[^\w\s]", "", sentence.lower())
words = clean.split()
counts = {}
for word in words:
counts[word] = counts.get(word, 0) + 1
return counts
result = count_words("Hello hello world! World hello.")
print(result) # {'hello': 3, 'world': 2}
Exercise 2: String Reverser
Write a function that reverses each word in a sentence while keeping the word order intact.
Expected Output:
reverse_words("Hello World Python")
# "olleH dlroW nohtyP"
Solution
def reverse_words(sentence):
words = sentence.split()
reversed_words = [word[::-1] for word in words]
return " ".join(reversed_words)
print(reverse_words("Hello World Python"))
# olleH dlroW nohtyP
Exercise 3: Password Strength Checker
Write a function that checks password strength based on these rules:
- Weak: Less than 8 characters
- Medium: 8+ characters with at least one letter and one digit
- Strong: 8+ characters with uppercase, lowercase, digit, and special character
Expected Output:
check_strength("abc") → "Weak"
check_strength("hello123") → "Medium"
check_strength("Hello@123") → "Strong"
Solution
import re
def check_strength(password):
if len(password) < 8:
return "Weak"
has_upper = bool(re.search(r"[A-Z]", password))
has_lower = bool(re.search(r"[a-z]", password))
has_digit = bool(re.search(r"\d", password))
has_special = bool(re.search(r"[!@#$%^&*(),.?\":{}|<>]", password))
if has_upper and has_lower and has_digit and has_special:
return "Strong"
elif (has_upper or has_lower) and has_digit:
return "Medium"
else:
return "Weak"
print(check_strength("abc")) # Weak
print(check_strength("hello123")) # Medium
print(check_strength("Hello@123")) # Strong
Exercise 4: Title Case Converter
Write a function that converts a string to title case, but keeps small words (a, an, the, of, in, for, and, but, or) lowercase unless they are the first word.
Expected Output:
smart_title("the lord of the rings")
# "The Lord of the Rings"
smart_title("a tale of two cities")
# "A Tale of Two Cities"
Solution
def smart_title(text):
small_words = {"a", "an", "the", "of", "in", "for", "and", "but", "or", "to", "is"}
words = text.lower().split()
result = []
for i, word in enumerate(words):
if i == 0 or word not in small_words:
result.append(word.capitalize())
else:
result.append(word)
return " ".join(result)
print(smart_title("the lord of the rings")) # The Lord of the Rings
print(smart_title("a tale of two cities")) # A Tale of Two Cities
Exercise 5: Log Parser
Given log lines in the format [TIMESTAMP] LEVEL: Message, write a function that extracts and returns all ERROR-level messages with their timestamps.
Given data:
logs = """
[2025-03-15 10:23:45] INFO: Server started
[2025-03-15 10:24:01] ERROR: Database connection failed
[2025-03-15 10:24:15] INFO: Retrying connection
[2025-03-15 10:24:30] ERROR: Timeout after 30s
[2025-03-15 10:25:00] INFO: Connection restored
[2025-03-15 10:25:10] WARNING: High memory usage
[2025-03-15 10:26:00] ERROR: Disk space low
"""
Expected Output:
Error Log Report:
[10:24:01] Database connection failed
[10:24:30] Timeout after 30s
[10:26:00] Disk space low
Total errors: 3
Solution
import re
logs = """
[2025-03-15 10:23:45] INFO: Server started
[2025-03-15 10:24:01] ERROR: Database connection failed
[2025-03-15 10:24:15] INFO: Retrying connection
[2025-03-15 10:24:30] ERROR: Timeout after 30s
[2025-03-15 10:25:00] INFO: Connection restored
[2025-03-15 10:25:10] WARNING: High memory usage
[2025-03-15 10:26:00] ERROR: Disk space low
"""
pattern = r"\[\d{4}-\d{2}-\d{2} (\d{2}:\d{2}:\d{2})\] ERROR: (.+)"
matches = re.findall(pattern, logs)
print("Error Log Report:")
for time, message in matches:
print(f"[{time}] {message}")
print(f"\nTotal errors: {len(matches)}")
Scoring Guide
| Exercises Completed | Level |
|---|---|
| 5/5 | Expert — Strings mastered! |
| 4/5 | Advanced — Solid string skills |
| 3/5 | Intermediate — Good foundation |
| 1-2/5 | Beginner — Review string concepts |
Next Chapter: Lists →