Python Exercises#
Beginner#
Variables and Data Types#
Exercise 1: String Manipulation#
# Create a variable 'name' with your name and 'age' with your age.
# Then print a message: "Hello, [name]! You are [age] years old."
# Your code here
# Assertions
assert isinstance(name, str), "name should be a string"
assert isinstance(age, int), "age should be an integer"
assert f"Hello, {name}! You are {age} years old." in globals()['__builtins__'].output
Solution
name = "Alice"
age = 25
print(f"Hello, {name}! You are {age} years old.")
Exercise 2: String Reversal#
# Write a function 'reverse_string' that takes a string as input and returns the reversed string.
# Your code here
# Assertions
assert reverse_string("hello") == "olleh", "String reversal is incorrect"
assert reverse_string("Python") == "nohtyP", "String reversal is incorrect"
assert reverse_string("") == "", "Should handle empty string"
Solution
def reverse_string(s):
return s[::-1]
Exercise 3: Palindrome Check#
# Write a function 'is_palindrome' that takes a string as input and returns True if it's a palindrome, False otherwise.
# Ignore spaces and consider the string case-insensitive.
# Your code here
# Assertions
assert is_palindrome("A man a plan a canal Panama") == True, "Should be a palindrome"
assert is_palindrome("race a car") == False, "Should not be a palindrome"
assert is_palindrome("") == True, "Empty string should be considered a palindrome"
Solution
def is_palindrome(s):
s = ''.join(char.lower() for char in s if char.isalnum())
return s == s[::-1]
Exercise 4: Basic Arithmetic#
# Calculate the area of a rectangle with length 7 and width 5.
# Store the result in a variable called 'area'.
# Your code here
# Assertions
assert isinstance(area, (int, float)), "area should be a number"
assert area == 35, "The area should be 35"
Solution
length = 7
width = 5
area = length * width
Control Flow#
Exercise 5: If-Else Statement#
# Write a function 'is_even' that takes a number as input and returns True if it's even, False otherwise.
# Your code here
# Assertions
assert is_even(4) == True, "4 should be even"
assert is_even(7) == False, "7 should be odd"
assert is_even(0) == True, "0 should be even"
Solution
def is_even(number):
return number % 2 == 0
Exercise 6: For Loop#
# Create a list of numbers from 1 to 10 and use a for loop to sum all the numbers.
# Store the result in a variable called 'total'.
# Your code here
# Assertions
assert isinstance(total, int), "total should be an integer"
assert total == 55, "The sum of numbers from 1 to 10 should be 55"
Exercise 7: FizzBuzz#
# Implement the classic FizzBuzz problem. Write a function 'fizzbuzz' that takes a number n
# and returns a list of strings for numbers from 1 to n:
# - For multiples of 3, use "Fizz" instead of the number
# - For multiples of 5, use "Buzz" instead of the number
# - For multiples of both 3 and 5, use "FizzBuzz"
# - For other numbers, use the number itself as a string
# Your code here
# Assertions
assert fizzbuzz(15) == ["1", "2", "Fizz", "4", "Buzz", "Fizz", "7", "8", "Fizz", "Buzz", "11", "Fizz", "13", "14", "FizzBuzz"]
assert fizzbuzz(5) == ["1", "2", "Fizz", "4", "Buzz"]
assert fizzbuzz(3) == ["1", "2", "Fizz"]
Solution
def fizzbuzz(n):
result = []
for i in range(1, n + 1):
if i % 3 == 0 and i % 5 == 0:
result.append("FizzBuzz")
elif i % 3 == 0:
result.append("Fizz")
elif i % 5 == 0:
result.append("Buzz")
else:
result.append(str(i))
return result
Functions#
Exercise 8: Basic Function#
# Write a function 'greet' that takes a name as input and returns a greeting message.
# For example, greet("Alice") should return "Hello, Alice!".
# Your code here
# Assertions
assert greet("Bob") == "Hello, Bob!", "Greeting message is incorrect"
assert greet("") == "Hello, !", "Function should work with empty string"
Solution
def greet(name):
return f"Hello, {name}!"
Lists#
Exercise 9: List Operations#
# Create a list of fruits and perform the following operations:
# 1. Add "apple" to the end of the list
# 2. Insert "banana" at the beginning of the list
# 3. Remove the second item from the list
# Store the final list in a variable called 'fruits'.
# Your code here
# Assertions
assert isinstance(fruits, list), "fruits should be a list"
assert fruits[0] == "banana", "First item should be 'banana'"
assert "apple" in fruits, "'apple' should be in the list"
assert len(fruits) == len(set(fruits)), "All items should be unique"
Solution
fruits = ["orange", "grape", "kiwi"]
fruits.append("apple")
fruits.insert(0, "banana")
fruits.pop(1)
Exercise 10: List Flattening#
# Write a function 'flatten_list' that takes a list of lists and returns a flattened list.
# Your code here
# Assertions
assert flatten_list([[1, 2], [3, 4]]) == [1, 2, 3, 4], "List flattening is incorrect"
assert flatten_list([[1], [2], [3]]) == [1, 2, 3], "List flattening is incorrect"
assert flatten_list([]) == [], "Should handle empty list"
Solution
def flatten_list(nested_list):
return [item for sublist in nested_list for item in sublist]
Exercise 11: Tuple Unpacking#
# Create a function 'swap_first_last' that takes a tuple as input and returns a new tuple
# with the first and last elements swapped.
# Your code here
# Assertions
assert swap_first_last((1, 2, 3, 4)) == (4, 2, 3, 1), "Tuple swap is incorrect"
assert swap_first_last((1,)) == (1,), "Should handle single-element tuple"
assert swap_first_last(()) == (), "Should handle empty tuple"
Solution
def swap_first_last(tup):
if len(tup) < 2:
return tup
return (tup[-1],) + tup[1:-1] + (tup[0],)
Dictionaries and Sets#
Exercise 12: Dictionary Merge#
# Write a function 'merge_dicts' that takes two dictionaries as input and returns a new dictionary
# containing all key-value pairs from both dictionaries. If a key exists in both dictionaries,
# the value from the second dictionary should be used.
# Your code here
# Assertions
dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}
assert merge_dicts(dict1, dict2) == {'a': 1, 'b': 3, 'c': 4}, "Dictionary merge is incorrect"
assert merge_dicts({}, {'x': 10}) == {'x': 10}, "Should handle empty dictionary"
assert merge_dicts({'y': 20}, {}) == {'y': 20}, "Should handle empty dictionary"
Solution
def merge_dicts(dict1, dict2):
return {**dict1, **dict2}
Exercise 13: Set Operations#
# Implement a function 'set_operations' that takes two sets as input and returns a dictionary
# containing the result of union, intersection, and difference operations.
# Your code here
# Assertions
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}
result = set_operations(set1, set2)
assert result['union'] == {1, 2, 3, 4, 5, 6}, "Union operation is incorrect"
assert result['intersection'] == {3, 4}, "Intersection operation is incorrect"
assert result['difference'] == {1, 2}, "Difference operation is incorrect"
Solution
def set_operations(set1, set2):
return {
'union': set1 | set2,
'intersection': set1 & set2,
'difference': set1 - set2
}
Basic File I/O#
Exercise 14: File Reading and Writing#
# Write a function 'word_frequency' that reads a text file, counts the frequency of each word,
# and writes the results to a new file. Ignore case and punctuation.
# Your code here
# Test the function (assuming you have a file named 'sample.txt')
word_frequency('sample.txt', 'word_counts.txt')
# Assertions
with open('word_counts.txt', 'r') as f:
content = f.read()
assert 'the' in content.lower(), "Common word 'the' should be in the frequency list"
assert len(content.split('\n')) > 1, "There should be multiple words in the frequency list"
Solution
import re
from collections import Counter
def word_frequency(input_file, output_file):
with open(input_file, 'r') as f:
text = f.read().lower()
words = re.findall(r'\w+', text)
frequency = Counter(words)
with open(output_file, 'w') as f:
for word, count in frequency.most_common():
f.write(f"{word}: {count}\n")
Intermediate#
List Comprehensions#
Exercise 15: Even Numbers#
# Use a list comprehension to create a list of even numbers from 0 to 20 (inclusive).
# Store the result in a variable called 'even_numbers'.
# Your code here
# Assertions
assert isinstance(even_numbers, list), "even_numbers should be a list"
assert all(num % 2 == 0 for num in even_numbers), "All numbers should be even"
assert len(even_numbers) == 11, "There should be 11 even numbers"
Solution
even_numbers = [num for num in range(21) if num % 2 == 0]
Exercise 16: Nested List Comprehension#
# Use a nested list comprehension to create a list of all possible coordinate pairs (x, y)
# where x and y are integers between 0 and 4 (inclusive), excluding pairs where x equals y.
# Your code here
# Assertions
assert len(coordinates) == 20, "There should be 20 coordinate pairs"
assert (0, 0) not in coordinates, "Pairs where x equals y should be excluded"
assert (0, 4) in coordinates, "Pair (0, 4) should be included"
assert all(0 <= x <= 4 and 0 <= y <= 4 for x, y in coordinates), "All coordinates should be between 0 and 4"
Solution
coordinates = [(x, y) for x in range(5) for y in range(5) if x != y]
Dictionaries#
Exercise 17: Dictionary Manipulation#
# Create a dictionary of book titles and their authors.
# Then write a function 'get_author' that takes a book title and returns the author.
# If the book is not in the dictionary, it should return "Unknown".
# Your code here
# Assertions
assert get_author("To Kill a Mockingbird") == "Harper Lee", "Incorrect author for 'To Kill a Mockingbird'"
assert get_author("1984") == "George Orwell", "Incorrect author for '1984'"
assert get_author("Nonexistent Book") == "Unknown", "Should return 'Unknown' for nonexistent books"
Solution
books = {
"To Kill a Mockingbird": "Harper Lee",
"1984": "George Orwell",
"Pride and Prejudice": "Jane Austen"
}
def get_author(title):
return books.get(title, "Unknown")
Lambda Functions#
Exercise 18: Sorting with Lambda#
# Use a lambda function to sort a list of tuples based on the second element of each tuple.
# Your code here
data = [(1, 5), (3, 2), (2, 8), (4, 1)]
sorted_data = # Your sorting code here
# Assertions
assert sorted_data == [(4, 1), (3, 2), (1, 5), (2, 8)], "Sorting is incorrect"
Solution
data = [(1, 5), (3, 2), (2, 8), (4, 1)]
sorted_data = sorted(data, key=lambda x: x[1])
Map, Filter, and Reduce#
Exercise 19: Map and Filter#
# Use map() and filter() to create a list of squares of even numbers from a given list of integers.
# Your code here
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
result = # Your code here
# Assertions
assert result == [4, 16, 36, 64, 100], "Map and filter result is incorrect"
Solution
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
result = list(map(lambda x: x**2, filter(lambda x: x % 2 == 0, numbers)))
Data Structures#
Exercise 20: Implement a Stack#
# Implement a Stack class with push, pop, and is_empty methods using a Python list.
# Your code here
# Assertions
stack = Stack()
assert stack.is_empty() == True, "New stack should be empty"
stack.push(1)
stack.push(2)
assert stack.pop() == 2, "Pop should return the last item pushed"
assert stack.is_empty() == False, "Stack should not be empty"
assert stack.pop() == 1, "Pop should return the remaining item"
assert stack.is_empty() == True, "Stack should be empty after popping all items"
Solution
class Stack:
def __init__(self):
self.items = []
def push(self, item):
self.items.append(item)
def pop(self):
if not self.is_empty():
return self.items.pop()
raise IndexError("pop from empty stack")
def is_empty(self):
return len(self.items) == 0
Exercise 21: Implement a Queue#
# Implement a Queue class with enqueue, dequeue, and is_empty methods using a Python list.
# Your code here
# Assertions
queue = Queue()
assert queue.is_empty() == True, "New queue should be empty"
queue.enqueue(1)
queue.enqueue(2)
assert queue.dequeue() == 1, "Dequeue should return the first item enqueued"
assert queue.is_empty() == False, "Queue should not be empty"
assert queue.dequeue() == 2, "Dequeue should return the remaining item"
assert queue.is_empty() == True, "Queue should be empty after dequeuing all items"
Solution
class Queue:
def __init__(self):
self.items = []
def enqueue(self, item):
self.items.append(item)
def dequeue(self):
if not self.is_empty():
return self.items.pop(0)
raise IndexError("dequeue from empty queue")
def is_empty(self):
return len(self.items) == 0
Algorithms#
Exercise 22: Binary Search#
# Implement a binary search function that takes a sorted list and a target value,
# and returns the index of the target value if found, or -1 if not found.
# Your code here
# Assertions
sorted_list = [1, 3, 5, 7, 9, 11, 13, 15, 17]
assert binary_search(sorted_list, 7) == 3, "Should find 7 at index 3"
assert binary_search(sorted_list, 15) == 7, "Should find 15 at index 7"
assert binary_search(sorted_list, 4) == -1, "Should return -1 for value not in list"
assert binary_search(sorted_list, 1) == 0, "Should find 1 at index 0"
assert binary_search(sorted_list, 17) == 8, "Should find 17 at index 8"
Solution
def binary_search(arr, target):
low, high = 0, len(arr) - 1
while low <= high:
mid = (low + high) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
low = mid + 1
else:
high = mid - 1
return -1
Object-Oriented Programming#
Exercise 23: Simple Class#
# Create a class 'Rectangle' with attributes 'width' and 'height'.
# Implement methods to calculate the area and perimeter of the rectangle.
# Your code here
# Assertions
rect = Rectangle(5, 3)
assert rect.area() == 15, "Area calculation is incorrect"
assert rect.perimeter() == 16, "Perimeter calculation is incorrect"
Solution
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
Exercise 24: Bank Account Class#
# Create a class 'BankAccount' with methods for deposit, withdraw, and check balance.
# Implement a 'MinimumBalanceAccount' that inherits from 'BankAccount' and requires a minimum balance.
# Your code here
# Assertions
account = BankAccount(1000)
account.deposit(500)
assert account.balance == 1500, "Deposit not handled correctly"
account.withdraw(200)
assert account.balance == 1300, "Withdrawal not handled correctly"
min_account = MinimumBalanceAccount(1000, minimum_balance=500)
min_account.withdraw(600)
assert min_account.balance == 1000, "Minimum balance rule not enforced"
Solution
class BankAccount:
def __init__(self, initial_balance=0):
self.balance = initial_balance
def deposit(self, amount):
self.balance += amount
def withdraw(self, amount):
if amount <= self.balance:
self.balance -= amount
else:
raise ValueError("Insufficient funds")
def check_balance(self):
return self.balance
class MinimumBalanceAccount(BankAccount):
def __init__(self, initial_balance, minimum_balance):
super().__init__(initial_balance)
self.minimum_balance = minimum_balance
def withdraw(self, amount):
if self.balance - amount >= self.minimum_balance:
super().withdraw(amount)
else:
raise ValueError("Withdrawal would breach minimum balance")
Inheritance and Polymorphism#
Exercise 25: Shape Hierarchy#
# Create a base class 'Shape' with a method 'area'.
# Create two derived classes 'Circle' and 'Square' that inherit from 'Shape' and implement the 'area' method.
# Your code here
# Assertions
circle = Circle(radius=5)
square = Square(side=4)
assert round(circle.area(), 2) == 78.54, "Circle area calculation is incorrect"
assert square.area() == 16, "Square area calculation is incorrect"
Solution
import math
class Shape:
def area(self):
pass
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return math.pi * self.radius ** 2
class Square(Shape):
def __init__(self, side):
self.side = side
def area(self):
return self.side ** 2
Regular Expressions#
Exercise 26: Email Validation#
# Write a function 'is_valid_email' that uses a regular expression to check if a given string is a valid email address.
import re
# Your code here
# Assertions
assert is_valid_email("user@example.com") == True, "Should be a valid email"
assert is_valid_email("invalid.email@com") == False, "Should be an invalid email"
assert is_valid_email("user@.com") == False, "Should be an invalid email"
Solution
import re
def is_valid_email(email):
pattern = r'^[\w\.-]+@[\w\.-]+\.\w+$'
return bool(re.match(pattern, email))
Modules and Packages#
Exercise 27: Custom Module#
# Create a custom module 'geometry' with functions to calculate area and perimeter of different shapes.
# Then, in a separate file, import and use these functions.
# File: geometry.py
# Your code here for the geometry module
# File: main.py
# Your code here to import and use the geometry module
# Assertions (in main.py)
assert abs(geometry.circle_area(5) - 78.54) < 0.01, "Circle area calculation is incorrect"
assert geometry.rectangle_perimeter(4, 5) == 18, "Rectangle perimeter calculation is incorrect"
assert geometry.triangle_area(3, 4, 5) == 6, "Triangle area calculation is incorrect"
Solution
# File: geometry.py
import math
def circle_area(radius):
return math.pi * radius ** 2
def rectangle_perimeter(length, width):
return 2 * (length + width)
def triangle_area(a, b, c):
s = (a + b + c) / 2
return math.sqrt(s * (s - a) * (s - b) * (s - c))
# File: main.py
import geometry
print(geometry.circle_area(5))
print(geometry.rectangle_perimeter(4, 5))
print(geometry.triangle_area(3, 4, 5))
Error Handling#
Exercise 28: Try-Except#
# Write a function 'safe_divide' that takes two numbers as input and returns their division.
# If the second number is zero, catch the ZeroDivisionError and return "Cannot divide by zero".
# Your code here
# Assertions
assert safe_divide(10, 2) == 5, "10 divided by 2 should be 5"
assert safe_divide(5, 0) == "Cannot divide by zero", "Should handle division by zero"
assert safe_divide(-1, 4) == -0.25, "Should handle negative numbers"
Solution
def safe_divide(a, b):
try:
return a / b
except ZeroDivisionError:
return "Cannot divide by zero"
File I/O#
Exercise 29: Reading and Writing Files#
# Write a function 'word_count' that reads a text file and returns a dictionary
# with the count of each word in the file. Ignore case and punctuation.
# Your code here
# Assertions
# Assuming a file named 'sample.txt' with content: "Hello world! Hello Python."
assert isinstance(word_count('sample.txt'), dict), "Should return a dictionary"
assert word_count('sample.txt')['hello'] == 2, "Should count 'hello' twice"
assert word_count('sample.txt')['world'] == 1, "Should count 'world' once"
assert word_count('sample.txt')['python'] == 1, "Should count 'python' once"
Solution
import re
from collections import defaultdict
def word_count(filename):
counts = defaultdict(int)
with open(filename, 'r') as file:
text = file.read().lower()
words = re.findall(r'\w+', text)
for word in words:
counts[word] += 1
return dict(counts)
Advanced#
Decorators#
Exercise 30: Timing Decorator#
# Create a decorator 'timer' that measures the time a function takes to execute.
# The decorator should print: "Function {func_name} took {time} seconds to run."
# Your code here
@timer
def slow_function():
import time
time.sleep(2)
# Run the function
slow_function()
# Assertions
# Note: We can't assert exact time, but we can check if the output is printed
assert "Function slow_function took" in globals()['__builtins__'].output
assert "seconds to run" in globals()['__builtins__'].output
Solution
import time
from functools import wraps
def timer(func):
@wraps(func)
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"Function {func.__name__} took {end_time - start_time:.2f} seconds to run.")
return result
return wrapper
Exercise 31: Retry Decorator#
# Create a decorator 'retry' that retries the decorated function a specified number of times if it raises an exception.
# Your code here
@retry(max_attempts=3)
def might_fail():
import random
if random.random() < 0.7:
raise ValueError("Random failure")
return "Success"
# Assertions
result = might_fail()
assert result == "Success", "Function should eventually succeed"
Solution
import functools
def retry(max_attempts):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
for _ in range(max_attempts):
try:
return func(*args, **kwargs)
except Exception as e:
last_exception = e
raise last_exception
return wrapper
return decorator
Generators and Iterators#
Exercise 32: Fibonacci Generator#
# Create a generator function 'fibonacci' that yields the Fibonacci sequence.
# The function should take a parameter 'n' for the number of Fibonacci numbers to generate.
# Your code here
# Assertions
fib = fibonacci(10)
assert list(fib) == [0, 1, 1, 2, 3, 5, 8, 13, 21, 34], "Incorrect Fibonacci sequence"
Solution
def fibonacci(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
Web Scraping#
Exercise 33: Web Scraping with BeautifulSoup#
# Implement a function 'scrape_headlines' that uses BeautifulSoup to scrape the top headlines
# from a news website (e.g., https://news.ycombinator.com/).
import requests
from bs4 import BeautifulSoup
# Your code here
# Assertions
headlines = scrape_headlines()
assert len(headlines) > 0, "Should have scraped at least one headline"
assert all(isinstance(h, str) for h in headlines), "All headlines should be strings"
Solution
import requests
from bs4 import BeautifulSoup
def scrape_headlines():
url = "https://news.ycombinator.com/"
response = requests.get(url)
soup = BeautifulSoup(response.text, 'html.parser')
headlines = soup.find_all('a', class_='storylink')
return [headline.text for headline in headlines]
Dynamic Programming#
Exercise 34: Longest Common Subsequence#
# Implement a function to find the length of the Longest Common Subsequence (LCS)
# between two strings using dynamic programming.
# Your code here
# Assertions
assert lcs_length("ABCDGH", "AEDFHR") == 3, "LCS should be 'ADH' with length 3"
assert lcs_length("AGGTAB", "GXTXAYB") == 4, "LCS should be 'GTAB' with length 4"
assert lcs_length("ABCBDAB", "BDCABA") == 4, "LCS should be 'BCBA' with length 4"
assert lcs_length("", "ABC") == 0, "LCS with empty string should be 0"
assert lcs_length("ABC", "ABC") == 3, "LCS of identical strings should be their length"
Solution
def lcs_length(X, Y):
m, n = len(X), len(Y)
L = [[0] * (n + 1) for _ in range(m + 1)]
for i in range(1, m + 1):
for j in range(1, n + 1):
if X[i-1] == Y[j-1]:
L[i][j] = L[i-1][j-1] + 1
else:
L[i][j] = max(L[i-1][j], L[i][j-1])
return L[m][n]
Graph Algorithms#
Exercise 35: Depth-First Search#
# Implement a depth-first search algorithm for a graph represented as an adjacency list.
# The function should return the list of nodes in the order they were visited.
# Your code here
# Assertions
graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E']
}
assert set(dfs(graph, 'A')) == set(['A', 'B', 'C', 'D', 'E', 'F']), "DFS should visit all nodes"
assert dfs(graph, 'A')[0] == 'A', "DFS should start with the given node"
Solution
def dfs(graph, start):
visited = set()
result = []
def dfs_recursive(node):
visited.add(node)
result.append(node)
for neighbor in graph[node]:
if neighbor not in visited:
dfs_recursive(neighbor)
dfs_recursive(start)
return result
Logical Problems#
Exercise 36: Tower of Hanoi#
# Implement a function to solve the Tower of Hanoi puzzle.
# The function should print the steps to move n disks from the source peg to the destination peg.
# Your code here
# Test the function (no assertions, as it prints the steps)
tower_of_hanoi(3, 'A', 'C', 'B')
Solution
def tower_of_hanoi(n, source, destination, auxiliary):
if n == 1:
print(f"Move disk 1 from {source} to {destination}")
return
tower_of_hanoi(n-1, source, auxiliary, destination)
print(f"Move disk {n} from {source} to {destination}")
tower_of_hanoi(n-1, auxiliary, destination, source)
Exercise 37: N-Queens Problem#
# Implement a function to solve the N-Queens problem.
# The function should return a list of all possible solutions for placing N queens on an NxN chessboard.
# Your code here
# Assertions
solutions_4 = solve_n_queens(4)
assert len(solutions_4) == 2, "There should be 2 solutions for 4-Queens"
assert len(solve_n_queens(1)) == 1, "There should be 1 solution for 1-Queen"
assert len(solve_n_queens(0)) == 0, "There should be no solutions for 0-Queens"
Solution
def solve_n_queens(n):
def is_safe(board, row, col):
for i in range(col):
if board[row][i] == 'Q':
return False
for i, j in zip(range(row, -1, -1), range(col, -1, -1)):
if board[i][j] == 'Q':
return False
for i, j in zip(range(row, n, 1), range(col, -1, -1)):
if board[i][j] == 'Q':
return False
return True
def solve(board, col):
if col >= n:
solutions.append([''.join(row) for row in board])
return
for i in range(n):
if is_safe(board, i, col):
board[i][col] = 'Q'
solve(board, col + 1)
board[i][col] = '.'
solutions = []
board = [['.' for _ in range(n)] for _ in range(n)]
solve(board, 0)
return solutions
Exercise 38: Custom Iterator for Prime Numbers#
# Implement a custom iterator class that generates prime numbers up to a specified limit.
# Your code here
# Assertions
primes = PrimeIterator(20)
assert list(primes) == [2, 3, 5, 7, 11, 13, 17, 19], "Should generate correct prime numbers up to 20"
primes = PrimeIterator(10)
assert list(primes) == [2, 3, 5, 7], "Should generate correct prime numbers up to 10"
primes = PrimeIterator(2)
assert list(primes) == [2], "Should generate only 2 for limit 2"
Solution
class PrimeIterator:
def __init__(self, limit):
self.limit = limit
self.current = 2
def __iter__(self):
return self
def __next__(self):
while self.current < self.limit:
if self.is_prime(self.current):
prime = self.current
self.current += 1
return prime
self.current += 1
raise StopIteration
def is_prime(self, n):
if n < 2:
return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True
Exercise 39: Asynchronous Web Crawler#
# Implement an asynchronous web crawler that fetches the content of multiple URLs concurrently.
# The crawler should respect a maximum number of concurrent requests.
import aiohttp
import asyncio
# Your code here
# Assertions
urls = [
"http://example.com",
"http://example.org",
"http://example.net",
"http://example.edu",
"http://example.io"
]
async def test_crawler():
results = await async_crawl(urls, max_concurrent=3)
assert len(results) == len(urls), "Should fetch all URLs"
assert all(isinstance(content, str) for content in results.values()), "All results should be strings"
asyncio.run(test_crawler())
Solution
import aiohttp
import asyncio
async def fetch(session, url):
async with session.get(url) as response:
return await response.text()
async def async_crawl(urls, max_concurrent):
semaphore = asyncio.Semaphore(max_concurrent)
async with aiohttp.ClientSession() as session:
async def bounded_fetch(url):
async with semaphore:
return url, await fetch(session, url)
tasks = [asyncio.create_task(bounded_fetch(url)) for url in urls]
results = await asyncio.gather(*tasks)
return dict(results)