Python Basics — Strings Practice Exercises

2 minute read

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 →

Updated: