Skip to content

Commit afe5152

Browse files
author
Shehab Abdel-Salam
committed
Fix test suite
1 parent b8f3d7c commit afe5152

File tree

11 files changed

+239
-28
lines changed

11 files changed

+239
-28
lines changed

chapters/chapter02_variables/exercises/exercise_04.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@
88
def compute_length_difference(word1, word2):
99
# Your code should go here.
1010

11-
return ...
11+
return -1

chapters/chapter02_variables/tests/test_ch02.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ def test_e03():
2929

3030

3131
def test_e04():
32-
compute_length_difference("", "") == 0
33-
compute_length_difference("Hello", "World") == 0
34-
compute_length_difference("Python", "Java") == 2
35-
compute_length_difference("Python", "Programming") == 5
32+
assert compute_length_difference("", "") == 0
33+
assert compute_length_difference("Hello", "World") == 0
34+
assert compute_length_difference("Python", "Java") == 2
35+
assert compute_length_difference("Python", "Programming") == 5
3636

3737

3838
def test_e05():
Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
1-
# Exercise 63 - File Handler
2-
# Write a custom context manager using a class FileHandler that opens
3-
# and closes a file. Use it to read from data.txt.
1+
# Exercise 63 - How Many emails?
2+
# Write a function that reads a file and returns the number of emails in the file.
3+
#
4+
# Example: emails.txt
5+
# test1@abc.com
6+
# test2@abc.com
7+
# fullname1
8+
# fullname2
9+
# test3@abc.com
410

11+
# The function should return 3.
12+
# A valid email address contains a single @ symbol.
513

6-
class FileHandler: ...
14+
15+
def count_emails(file_name: str) -> int:
16+
# Your code should go here.
17+
18+
...

chapters/chapter08_files/tests/test_ch08.py

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77
from ..exercises.exercise_60 import course_grades_summary
88
from ..exercises.exercise_61 import inventory_management
99
from ..exercises.exercise_62 import is_file_sorted
10-
11-
# from ..exercises.exercise_63 import
10+
from ..exercises.exercise_63 import count_emails
1211

1312

1413
@pytest.mark.parametrize(
@@ -287,3 +286,44 @@ def test_e61(source, restock_threshold, expected):
287286
)
288287
def test_e62(source, expected):
289288
assert is_file_sorted(source) is expected
289+
290+
291+
@pytest.mark.parametrize(
292+
"file_content, expected",
293+
[
294+
(
295+
textwrap.dedent(
296+
"""
297+
username1
298+
username2
299+
"""
300+
),
301+
0,
302+
),
303+
(
304+
textwrap.dedent(
305+
"""
306+
username1
307+
test1@abc.com
308+
username2
309+
"""
310+
),
311+
1,
312+
),
313+
(
314+
textwrap.dedent(
315+
"""
316+
username1
317+
username2
318+
user1@abc.com
319+
user2@abc.com
320+
username3
321+
user3@abc.com
322+
"""
323+
),
324+
3,
325+
),
326+
],
327+
)
328+
def test_e63(source, expected):
329+
assert count_emails(source) == expected

chapters/chapter09_error_handling/exercises/exercise_65.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
class NegativeValueError: ...
88

99

10-
def check_positive(number):
10+
def check_positive(number: int):
1111
# Your code should go here.
1212

1313
return ...
Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,18 @@
1-
# Exercise 66 - Custom Exception
1+
# Exercise 66 - ProductSalesCalculator
2+
# Given the following class, fix the code so that it raises a custom exception called `InvalidQuantityError`
3+
# instead of the print message.
4+
5+
6+
class InvalidQuantityError(Exception):
7+
pass
8+
9+
10+
class ProductSalesCalculator:
11+
def __init__(self, price: float, quantity: int):
12+
if quantity <= 0:
13+
print("Quantity must be greater than zero")
14+
self.price = price
15+
self.quantity = quantity
16+
17+
def calculate_total(self) -> float:
18+
return self.price * self.quantity
Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,24 @@
1-
# Exercise 67 - Custom Exception
1+
# Exercise 67 - Exception Group
2+
# Given the following function, we want to raise an exception called `ExceptionGroup` if multiple errors occur during processing.
3+
# Fix this function so that it appends the exceptions to a list and raises an `ExceptionGroup` if multiple errors occur.
4+
5+
6+
def process_strings(strings: list[str]):
7+
exceptions = []
8+
9+
for string in strings:
10+
try:
11+
# Operation 1: Convert to Integer
12+
print(f"Converting '{string}' to integer: {int(string)}")
13+
14+
# Operation 2: Access First Character
15+
print(f"First character of '{string}' is '{string[0]}'")
16+
17+
except ValueError as e:
18+
print("TODO: Cannot convert to integer")
19+
20+
except IndexError as e:
21+
print("TODO: Cannot access first character")
22+
23+
if exceptions:
24+
raise ExceptionGroup("Multiple errors occurred during processing", exceptions)

chapters/chapter09_error_handling/tests/test_ch09.py

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import pytest
22
from ..exercises.exercise_64 import divide
33
from ..exercises.exercise_65 import check_positive, NegativeValueError
4-
5-
# from ..exercises.exercise_66 import
6-
# from ..exercises.exercise_67 import
4+
from ..exercises.exercise_66 import ProductSalesCalculator, InvalidQuantityError
5+
from ..exercises.exercise_67 import process_strings
76

87

98
def test_e64():
@@ -21,3 +20,33 @@ def test_e65():
2120
check_positive(-1)
2221
with pytest.raises(NegativeValueError):
2322
check_positive(-10)
23+
24+
25+
def test_e66():
26+
with pytest.raises(InvalidQuantityError):
27+
ProductSalesCalculator(10, 0)
28+
with pytest.raises(InvalidQuantityError):
29+
ProductSalesCalculator(10, -1)
30+
31+
psc = ProductSalesCalculator(10, 1)
32+
assert psc.calculate_total() == 10
33+
psc = ProductSalesCalculator(10, 2)
34+
assert psc.calculate_total() == 20
35+
36+
37+
def test_e67():
38+
test_strings = ["123", "", "abc", "456", "789", ""]
39+
40+
with pytest.raises(ExceptionGroup) as exc_info:
41+
process_strings(test_strings)
42+
43+
exceptions = exc_info.value.exceptions
44+
assert len(exceptions) == 3
45+
46+
value_error_raised = any(isinstance(e, ValueError) for e in exceptions)
47+
assert value_error_raised, "ValueError was not raised as expected"
48+
49+
index_error_count = sum(isinstance(e, IndexError) for e in exceptions)
50+
assert (
51+
index_error_count == 2
52+
), "IndexError was not raised the correct number of times"

chapters/chapter10_oop/tests/test_ch10.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ def test_e74():
117117
def test_e75():
118118
customer = Customer("John", "Doe")
119119
assert isinstance(customer, Customer)
120+
assert customer.add_account(Account("1234", "User A", 1000, [])) is None
121+
assert customer.add_card(Card("1234", "User A", "2024-12-31", "1234")) is None
122+
assert customer.get_total_balance() == 1000
123+
assert customer.withdraw(1234, 500, 1234, 1234) is None
120124

121125

122126
def test_e76():
Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
# Exercise 85 - Parse transaction files
2-
# Given this "RateInterestCalculator" class with two methods,
3-
# we need to replace the print() messages with log statements instead with
4-
# the appropriate Log Level.
5-
6-
# Can you fix this?
2+
# Given the following class and function, implement the `parse_transactions` function that reads a file
3+
# and returns a list of transactions. Each line in the file contains a timestamp and a description separated by a comma.
4+
# The timestamp should be converted to a `datetime` object.
5+
#
6+
from dataclasses import dataclass
77

88

9+
@dataclass
910
class Transaction:
1011
timestamp: str # Replace with `datetime`
1112
description: str
1213

1314

14-
def parse_transactions(filename): ...
15+
def parse_transactions(filename: str) -> list[Transaction]:
16+
# Your code should go here.
17+
18+
...

0 commit comments

Comments
 (0)