0% found this document useful (0 votes)
2 views52 pages

Read and Learn Python Chapter 8

Uploaded by

budak.j4h4t
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views52 pages

Read and Learn Python Chapter 8

Uploaded by

budak.j4h4t
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Read And Learn

Python
Chapter 8: Testing, Debugging & Code Quality

An In-Depth Comprehensive Guide for Beginners


1. The Importance of Testing

As your Python programs grow in complexity, the probability of introducing bugs


increases exponentially. Testing is the practice of writing code to verify that your
actual application code behaves as expected. Software testing is generally broken
down into several levels, with the most fundamental being Unit Testing.

Unit testing involves testing individual components of software, usually functions or


methods, in isolation. By writing unit tests, you can refactor your code with
confidence, knowing that if you break something, your tests will immediately notify
you.

2. Unit Testing with unittest

Python comes with a built-in testing framework called unittest . It requires you to
put your tests into classes as methods. To use it, you subclass
[Link] and write methods starting with the word test .
import unittest

# The function we want to test


def divide(a, b):
if b == 0:
raise ValueError("Cannot divide by zero")
return a / b

# The test case class


class TestMathFunctions([Link]):

def test_divide_normal(self):
# Assertions verify the expected outcome
[Link](divide(10, 2), 5)
[Link](divide(-10, 2), -5)

def test_divide_by_zero(self):
# Context managers can test for exceptions
with [Link](ValueError):
divide(10, 0)

if __name__ == '__main__':
[Link]()

Test Setup and Teardown

If your tests require a specific environment (like an open database connection


or a temporary file), you can use the setUp() and tearDown() methods.
setUp() runs immediately before every test method, and tearDown()
runs immediately after.
3. Professional Logging

Beginners often use the print() function to debug and track the flow of their
application. However, professional Python applications use the built-in logging
module. Logging allows you to categorize messages by severity (DEBUG, INFO,
WARNING, ERROR, CRITICAL) and direct them to different destinations (like a
console or a file).

import logging

# Configure the logging system


[Link](
level=[Link],
format='%(asctime)s - %(levelname)s - %(message)s',
filename='[Link]', # Saves to a file instead of the terminal
filemode='a'
)

[Link]("This is a debug message (ignored due to level).")


[Link]("System initialized successfully.")
[Link]("Memory usage is getting high.")
[Link]("Failed to connect to the database.")
[Link]("System crash imminent!")
4. Debugging with pdb

When you encounter a complex bug that logs and tests can't easily explain, you
need a debugger. Python includes a built-in interactive debugger called pdb
(Python Debugger). It allows you to pause the execution of your program, inspect
variables, and step through the code line by line.

def calculate_tax(total):
tax_rate = 0.05
# Insert a breakpoint. The script pauses here during execution.
import pdb; pdb.set_trace()
# In Python 3.7+, you can simply use the built-in: breakpoint()

final_amount = total + (total * tax_rate)


return final_amount

calculate_tax(100)

5. Type Hinting (PEP 484)

Python is dynamically typed, but modern Python supports Type Hints. Type hints do
not affect how the code runs, but they allow IDEs (like VSCode or PyCharm) and
static analysis tools (like mypy ) to catch type-related errors before you even run
the code.
from typing import List, Dict

# Specifying that 'name' must be a str, and the function returns a


str
def greet(name: str) -> str:
return f"Hello, {name}"

# Specifying complex data structures


def process_scores(scores: List[int]) -> Dict[str, float]:
average = sum(scores) / len(scores)
return {"average_score": average}

6. Practice Exercises

Writing robust, professional Python code requires mastering testing, logging, and
type hints. The following 45 exercises will guide you through practical scenarios.
Exercise 1: Unit Test Assertion

Problem Statement: Develop a Python script that implements unit test


assertion effectively.

Python Code Solution:

# Exercise 1: Unit Test Assertion


import unittest

def multiply(a, b): return a * b

class TestMath([Link]):
def test_mult(self):
[Link](multiply(1, 2), 2)

# [Link]()

Detailed Explanation: This exercise tests your mastery of unit test


assertion. We define a test case inheriting from [Link]. We use
[Link] to assert that our multiplication function correctly processes
the inputs and returns the exact expected mathematical output.
Exercise 2: Exception Testing

Problem Statement: Develop a Python script that implements exception


testing effectively.

Python Code Solution:

# Exercise 2: Exception Testing


import unittest

def get_item(lst, index):


return lst[index]

class TestList([Link]):
def test_bounds(self):
with [Link](IndexError):
get_item([1, 2], 7)

# [Link]()

Detailed Explanation: This exercise tests your mastery of exception testing.


Using the [Link] context manager, we instruct the test runner to
expect an IndexError. If the function successfully throws the error, the test
passes; otherwise, it fails.
Exercise 3: Logging Configuration

Problem Statement: Develop a Python script that implements logging


configuration effectively.

Python Code Solution:

# Exercise 3: Logging Configuration


import logging
[Link](level=[Link])

val = 30
[Link](f'Debugging variable state: val={val}')
[Link]('Operation finished safely.')

Detailed Explanation: This exercise tests your mastery of logging


configuration. Instead of using print(), we configure the built-in logging
module to display DEBUG level messages and above. This is the
professional standard for tracking application flow and internal states.
Exercise 4: Type Hinting

Problem Statement: Develop a Python script that implements type hinting


effectively.

Python Code Solution:

# Exercise 4: Type Hinting


from typing import List

def filter_evens(nums: List[int]) -> List[int]:


return [n for n in nums if n % 2 == 0]

res: List[int] = filter_evens([4, 5, 6])


print(res)

Detailed Explanation: This exercise tests your mastery of type hinting. We


apply PEP 484 type hints to the function arguments and return type. This
explicitly defines the expected data structures (Lists of integers), allowing
static analysis tools to catch type mismatch errors before execution.
Exercise 5: Test Setup Method

Problem Statement: Develop a Python script that implements test setup


method effectively.

Python Code Solution:

# Exercise 5: Test Setup Method


import unittest

class TestEnv([Link]):
def setUp(self):
self.test_data = [x for x in range(5)]

def test_data_length(self):
[Link](len(self.test_data), 5)

# [Link]()

Detailed Explanation: This exercise tests your mastery of test setup


method. The setUp() method is automatically called before every single test
method in the class. It is used to prepare the environment, such as opening
database connections or instantiating complex test data objects.
Exercise 6: Debugging Simulation

Problem Statement: Develop a Python script that implements debugging


simulation effectively.

Python Code Solution:

# Exercise 6: Debugging Simulation


def process_data(val):
modifier = 5
# breakpoint()
return val * modifier + 6

res = process_data(10)
print('Simulated debug output:', res)

Detailed Explanation: This exercise tests your mastery of debugging


simulation. In a live debugging scenario, inserting the built-in breakpoint()
function (or import pdb; pdb.set_trace()) pauses the script. This drops the
developer into an interactive console to manually inspect the values of
'modifier' and 'val'.
Exercise 7: Unit Test Assertion

Problem Statement: Develop a Python script that implements unit test


assertion effectively.

Python Code Solution:

# Exercise 7: Unit Test Assertion


import unittest

def multiply(a, b): return a * b

class TestMath([Link]):
def test_mult(self):
[Link](multiply(7, 2), 14)

# [Link]()

Detailed Explanation: This exercise tests your mastery of unit test


assertion. We define a test case inheriting from [Link]. We use
[Link] to assert that our multiplication function correctly processes
the inputs and returns the exact expected mathematical output.
Exercise 8: Exception Testing

Problem Statement: Develop a Python script that implements exception


testing effectively.

Python Code Solution:

# Exercise 8: Exception Testing


import unittest

def get_item(lst, index):


return lst[index]

class TestList([Link]):
def test_bounds(self):
with [Link](IndexError):
get_item([1, 2], 13)

# [Link]()

Detailed Explanation: This exercise tests your mastery of exception testing.


Using the [Link] context manager, we instruct the test runner to
expect an IndexError. If the function successfully throws the error, the test
passes; otherwise, it fails.
Exercise 9: Logging Configuration

Problem Statement: Develop a Python script that implements logging


configuration effectively.

Python Code Solution:

# Exercise 9: Logging Configuration


import logging
[Link](level=[Link])

val = 90
[Link](f'Debugging variable state: val={val}')
[Link]('Operation finished safely.')

Detailed Explanation: This exercise tests your mastery of logging


configuration. Instead of using print(), we configure the built-in logging
module to display DEBUG level messages and above. This is the
professional standard for tracking application flow and internal states.
Exercise 10: Type Hinting

Problem Statement: Develop a Python script that implements type hinting


effectively.

Python Code Solution:

# Exercise 10: Type Hinting


from typing import List

def filter_evens(nums: List[int]) -> List[int]:


return [n for n in nums if n % 2 == 0]

res: List[int] = filter_evens([10, 11, 12])


print(res)

Detailed Explanation: This exercise tests your mastery of type hinting. We


apply PEP 484 type hints to the function arguments and return type. This
explicitly defines the expected data structures (Lists of integers), allowing
static analysis tools to catch type mismatch errors before execution.
Exercise 11: Test Setup Method

Problem Statement: Develop a Python script that implements test setup


method effectively.

Python Code Solution:

# Exercise 11: Test Setup Method


import unittest

class TestEnv([Link]):
def setUp(self):
self.test_data = [x for x in range(11)]

def test_data_length(self):
[Link](len(self.test_data), 11)

# [Link]()

Detailed Explanation: This exercise tests your mastery of test setup


method. The setUp() method is automatically called before every single test
method in the class. It is used to prepare the environment, such as opening
database connections or instantiating complex test data objects.
Exercise 12: Debugging Simulation

Problem Statement: Develop a Python script that implements debugging


simulation effectively.

Python Code Solution:

# Exercise 12: Debugging Simulation


def process_data(val):
modifier = 5
# breakpoint()
return val * modifier + 12

res = process_data(10)
print('Simulated debug output:', res)

Detailed Explanation: This exercise tests your mastery of debugging


simulation. In a live debugging scenario, inserting the built-in breakpoint()
function (or import pdb; pdb.set_trace()) pauses the script. This drops the
developer into an interactive console to manually inspect the values of
'modifier' and 'val'.
Exercise 13: Unit Test Assertion

Problem Statement: Develop a Python script that implements unit test


assertion effectively.

Python Code Solution:

# Exercise 13: Unit Test Assertion


import unittest

def multiply(a, b): return a * b

class TestMath([Link]):
def test_mult(self):
[Link](multiply(13, 2), 26)

# [Link]()

Detailed Explanation: This exercise tests your mastery of unit test


assertion. We define a test case inheriting from [Link]. We use
[Link] to assert that our multiplication function correctly processes
the inputs and returns the exact expected mathematical output.
Exercise 14: Exception Testing

Problem Statement: Develop a Python script that implements exception


testing effectively.

Python Code Solution:

# Exercise 14: Exception Testing


import unittest

def get_item(lst, index):


return lst[index]

class TestList([Link]):
def test_bounds(self):
with [Link](IndexError):
get_item([1, 2], 19)

# [Link]()

Detailed Explanation: This exercise tests your mastery of exception testing.


Using the [Link] context manager, we instruct the test runner to
expect an IndexError. If the function successfully throws the error, the test
passes; otherwise, it fails.
Exercise 15: Logging Configuration

Problem Statement: Develop a Python script that implements logging


configuration effectively.

Python Code Solution:

# Exercise 15: Logging Configuration


import logging
[Link](level=[Link])

val = 150
[Link](f'Debugging variable state: val={val}')
[Link]('Operation finished safely.')

Detailed Explanation: This exercise tests your mastery of logging


configuration. Instead of using print(), we configure the built-in logging
module to display DEBUG level messages and above. This is the
professional standard for tracking application flow and internal states.
Exercise 16: Type Hinting

Problem Statement: Develop a Python script that implements type hinting


effectively.

Python Code Solution:

# Exercise 16: Type Hinting


from typing import List

def filter_evens(nums: List[int]) -> List[int]:


return [n for n in nums if n % 2 == 0]

res: List[int] = filter_evens([16, 17, 18])


print(res)

Detailed Explanation: This exercise tests your mastery of type hinting. We


apply PEP 484 type hints to the function arguments and return type. This
explicitly defines the expected data structures (Lists of integers), allowing
static analysis tools to catch type mismatch errors before execution.
Exercise 17: Test Setup Method

Problem Statement: Develop a Python script that implements test setup


method effectively.

Python Code Solution:

# Exercise 17: Test Setup Method


import unittest

class TestEnv([Link]):
def setUp(self):
self.test_data = [x for x in range(17)]

def test_data_length(self):
[Link](len(self.test_data), 17)

# [Link]()

Detailed Explanation: This exercise tests your mastery of test setup


method. The setUp() method is automatically called before every single test
method in the class. It is used to prepare the environment, such as opening
database connections or instantiating complex test data objects.
Exercise 18: Debugging Simulation

Problem Statement: Develop a Python script that implements debugging


simulation effectively.

Python Code Solution:

# Exercise 18: Debugging Simulation


def process_data(val):
modifier = 5
# breakpoint()
return val * modifier + 18

res = process_data(10)
print('Simulated debug output:', res)

Detailed Explanation: This exercise tests your mastery of debugging


simulation. In a live debugging scenario, inserting the built-in breakpoint()
function (or import pdb; pdb.set_trace()) pauses the script. This drops the
developer into an interactive console to manually inspect the values of
'modifier' and 'val'.
Exercise 19: Unit Test Assertion

Problem Statement: Develop a Python script that implements unit test


assertion effectively.

Python Code Solution:

# Exercise 19: Unit Test Assertion


import unittest

def multiply(a, b): return a * b

class TestMath([Link]):
def test_mult(self):
[Link](multiply(19, 2), 38)

# [Link]()

Detailed Explanation: This exercise tests your mastery of unit test


assertion. We define a test case inheriting from [Link]. We use
[Link] to assert that our multiplication function correctly processes
the inputs and returns the exact expected mathematical output.
Exercise 20: Exception Testing

Problem Statement: Develop a Python script that implements exception


testing effectively.

Python Code Solution:

# Exercise 20: Exception Testing


import unittest

def get_item(lst, index):


return lst[index]

class TestList([Link]):
def test_bounds(self):
with [Link](IndexError):
get_item([1, 2], 25)

# [Link]()

Detailed Explanation: This exercise tests your mastery of exception testing.


Using the [Link] context manager, we instruct the test runner to
expect an IndexError. If the function successfully throws the error, the test
passes; otherwise, it fails.
Exercise 21: Logging Configuration

Problem Statement: Develop a Python script that implements logging


configuration effectively.

Python Code Solution:

# Exercise 21: Logging Configuration


import logging
[Link](level=[Link])

val = 210
[Link](f'Debugging variable state: val={val}')
[Link]('Operation finished safely.')

Detailed Explanation: This exercise tests your mastery of logging


configuration. Instead of using print(), we configure the built-in logging
module to display DEBUG level messages and above. This is the
professional standard for tracking application flow and internal states.
Exercise 22: Type Hinting

Problem Statement: Develop a Python script that implements type hinting


effectively.

Python Code Solution:

# Exercise 22: Type Hinting


from typing import List

def filter_evens(nums: List[int]) -> List[int]:


return [n for n in nums if n % 2 == 0]

res: List[int] = filter_evens([22, 23, 24])


print(res)

Detailed Explanation: This exercise tests your mastery of type hinting. We


apply PEP 484 type hints to the function arguments and return type. This
explicitly defines the expected data structures (Lists of integers), allowing
static analysis tools to catch type mismatch errors before execution.
Exercise 23: Test Setup Method

Problem Statement: Develop a Python script that implements test setup


method effectively.

Python Code Solution:

# Exercise 23: Test Setup Method


import unittest

class TestEnv([Link]):
def setUp(self):
self.test_data = [x for x in range(23)]

def test_data_length(self):
[Link](len(self.test_data), 23)

# [Link]()

Detailed Explanation: This exercise tests your mastery of test setup


method. The setUp() method is automatically called before every single test
method in the class. It is used to prepare the environment, such as opening
database connections or instantiating complex test data objects.
Exercise 24: Debugging Simulation

Problem Statement: Develop a Python script that implements debugging


simulation effectively.

Python Code Solution:

# Exercise 24: Debugging Simulation


def process_data(val):
modifier = 5
# breakpoint()
return val * modifier + 24

res = process_data(10)
print('Simulated debug output:', res)

Detailed Explanation: This exercise tests your mastery of debugging


simulation. In a live debugging scenario, inserting the built-in breakpoint()
function (or import pdb; pdb.set_trace()) pauses the script. This drops the
developer into an interactive console to manually inspect the values of
'modifier' and 'val'.
Exercise 25: Unit Test Assertion

Problem Statement: Develop a Python script that implements unit test


assertion effectively.

Python Code Solution:

# Exercise 25: Unit Test Assertion


import unittest

def multiply(a, b): return a * b

class TestMath([Link]):
def test_mult(self):
[Link](multiply(25, 2), 50)

# [Link]()

Detailed Explanation: This exercise tests your mastery of unit test


assertion. We define a test case inheriting from [Link]. We use
[Link] to assert that our multiplication function correctly processes
the inputs and returns the exact expected mathematical output.
Exercise 26: Exception Testing

Problem Statement: Develop a Python script that implements exception


testing effectively.

Python Code Solution:

# Exercise 26: Exception Testing


import unittest

def get_item(lst, index):


return lst[index]

class TestList([Link]):
def test_bounds(self):
with [Link](IndexError):
get_item([1, 2], 31)

# [Link]()

Detailed Explanation: This exercise tests your mastery of exception testing.


Using the [Link] context manager, we instruct the test runner to
expect an IndexError. If the function successfully throws the error, the test
passes; otherwise, it fails.
Exercise 27: Logging Configuration

Problem Statement: Develop a Python script that implements logging


configuration effectively.

Python Code Solution:

# Exercise 27: Logging Configuration


import logging
[Link](level=[Link])

val = 270
[Link](f'Debugging variable state: val={val}')
[Link]('Operation finished safely.')

Detailed Explanation: This exercise tests your mastery of logging


configuration. Instead of using print(), we configure the built-in logging
module to display DEBUG level messages and above. This is the
professional standard for tracking application flow and internal states.
Exercise 28: Type Hinting

Problem Statement: Develop a Python script that implements type hinting


effectively.

Python Code Solution:

# Exercise 28: Type Hinting


from typing import List

def filter_evens(nums: List[int]) -> List[int]:


return [n for n in nums if n % 2 == 0]

res: List[int] = filter_evens([28, 29, 30])


print(res)

Detailed Explanation: This exercise tests your mastery of type hinting. We


apply PEP 484 type hints to the function arguments and return type. This
explicitly defines the expected data structures (Lists of integers), allowing
static analysis tools to catch type mismatch errors before execution.
Exercise 29: Test Setup Method

Problem Statement: Develop a Python script that implements test setup


method effectively.

Python Code Solution:

# Exercise 29: Test Setup Method


import unittest

class TestEnv([Link]):
def setUp(self):
self.test_data = [x for x in range(29)]

def test_data_length(self):
[Link](len(self.test_data), 29)

# [Link]()

Detailed Explanation: This exercise tests your mastery of test setup


method. The setUp() method is automatically called before every single test
method in the class. It is used to prepare the environment, such as opening
database connections or instantiating complex test data objects.
Exercise 30: Debugging Simulation

Problem Statement: Develop a Python script that implements debugging


simulation effectively.

Python Code Solution:

# Exercise 30: Debugging Simulation


def process_data(val):
modifier = 5
# breakpoint()
return val * modifier + 30

res = process_data(10)
print('Simulated debug output:', res)

Detailed Explanation: This exercise tests your mastery of debugging


simulation. In a live debugging scenario, inserting the built-in breakpoint()
function (or import pdb; pdb.set_trace()) pauses the script. This drops the
developer into an interactive console to manually inspect the values of
'modifier' and 'val'.
Exercise 31: Unit Test Assertion

Problem Statement: Develop a Python script that implements unit test


assertion effectively.

Python Code Solution:

# Exercise 31: Unit Test Assertion


import unittest

def multiply(a, b): return a * b

class TestMath([Link]):
def test_mult(self):
[Link](multiply(31, 2), 62)

# [Link]()

Detailed Explanation: This exercise tests your mastery of unit test


assertion. We define a test case inheriting from [Link]. We use
[Link] to assert that our multiplication function correctly processes
the inputs and returns the exact expected mathematical output.
Exercise 32: Exception Testing

Problem Statement: Develop a Python script that implements exception


testing effectively.

Python Code Solution:

# Exercise 32: Exception Testing


import unittest

def get_item(lst, index):


return lst[index]

class TestList([Link]):
def test_bounds(self):
with [Link](IndexError):
get_item([1, 2], 37)

# [Link]()

Detailed Explanation: This exercise tests your mastery of exception testing.


Using the [Link] context manager, we instruct the test runner to
expect an IndexError. If the function successfully throws the error, the test
passes; otherwise, it fails.
Exercise 33: Logging Configuration

Problem Statement: Develop a Python script that implements logging


configuration effectively.

Python Code Solution:

# Exercise 33: Logging Configuration


import logging
[Link](level=[Link])

val = 330
[Link](f'Debugging variable state: val={val}')
[Link]('Operation finished safely.')

Detailed Explanation: This exercise tests your mastery of logging


configuration. Instead of using print(), we configure the built-in logging
module to display DEBUG level messages and above. This is the
professional standard for tracking application flow and internal states.
Exercise 34: Type Hinting

Problem Statement: Develop a Python script that implements type hinting


effectively.

Python Code Solution:

# Exercise 34: Type Hinting


from typing import List

def filter_evens(nums: List[int]) -> List[int]:


return [n for n in nums if n % 2 == 0]

res: List[int] = filter_evens([34, 35, 36])


print(res)

Detailed Explanation: This exercise tests your mastery of type hinting. We


apply PEP 484 type hints to the function arguments and return type. This
explicitly defines the expected data structures (Lists of integers), allowing
static analysis tools to catch type mismatch errors before execution.
Exercise 35: Test Setup Method

Problem Statement: Develop a Python script that implements test setup


method effectively.

Python Code Solution:

# Exercise 35: Test Setup Method


import unittest

class TestEnv([Link]):
def setUp(self):
self.test_data = [x for x in range(35)]

def test_data_length(self):
[Link](len(self.test_data), 35)

# [Link]()

Detailed Explanation: This exercise tests your mastery of test setup


method. The setUp() method is automatically called before every single test
method in the class. It is used to prepare the environment, such as opening
database connections or instantiating complex test data objects.
Exercise 36: Debugging Simulation

Problem Statement: Develop a Python script that implements debugging


simulation effectively.

Python Code Solution:

# Exercise 36: Debugging Simulation


def process_data(val):
modifier = 5
# breakpoint()
return val * modifier + 36

res = process_data(10)
print('Simulated debug output:', res)

Detailed Explanation: This exercise tests your mastery of debugging


simulation. In a live debugging scenario, inserting the built-in breakpoint()
function (or import pdb; pdb.set_trace()) pauses the script. This drops the
developer into an interactive console to manually inspect the values of
'modifier' and 'val'.
Exercise 37: Unit Test Assertion

Problem Statement: Develop a Python script that implements unit test


assertion effectively.

Python Code Solution:

# Exercise 37: Unit Test Assertion


import unittest

def multiply(a, b): return a * b

class TestMath([Link]):
def test_mult(self):
[Link](multiply(37, 2), 74)

# [Link]()

Detailed Explanation: This exercise tests your mastery of unit test


assertion. We define a test case inheriting from [Link]. We use
[Link] to assert that our multiplication function correctly processes
the inputs and returns the exact expected mathematical output.
Exercise 38: Exception Testing

Problem Statement: Develop a Python script that implements exception


testing effectively.

Python Code Solution:

# Exercise 38: Exception Testing


import unittest

def get_item(lst, index):


return lst[index]

class TestList([Link]):
def test_bounds(self):
with [Link](IndexError):
get_item([1, 2], 43)

# [Link]()

Detailed Explanation: This exercise tests your mastery of exception testing.


Using the [Link] context manager, we instruct the test runner to
expect an IndexError. If the function successfully throws the error, the test
passes; otherwise, it fails.
Exercise 39: Logging Configuration

Problem Statement: Develop a Python script that implements logging


configuration effectively.

Python Code Solution:

# Exercise 39: Logging Configuration


import logging
[Link](level=[Link])

val = 390
[Link](f'Debugging variable state: val={val}')
[Link]('Operation finished safely.')

Detailed Explanation: This exercise tests your mastery of logging


configuration. Instead of using print(), we configure the built-in logging
module to display DEBUG level messages and above. This is the
professional standard for tracking application flow and internal states.
Exercise 40: Type Hinting

Problem Statement: Develop a Python script that implements type hinting


effectively.

Python Code Solution:

# Exercise 40: Type Hinting


from typing import List

def filter_evens(nums: List[int]) -> List[int]:


return [n for n in nums if n % 2 == 0]

res: List[int] = filter_evens([40, 41, 42])


print(res)

Detailed Explanation: This exercise tests your mastery of type hinting. We


apply PEP 484 type hints to the function arguments and return type. This
explicitly defines the expected data structures (Lists of integers), allowing
static analysis tools to catch type mismatch errors before execution.
Exercise 41: Test Setup Method

Problem Statement: Develop a Python script that implements test setup


method effectively.

Python Code Solution:

# Exercise 41: Test Setup Method


import unittest

class TestEnv([Link]):
def setUp(self):
self.test_data = [x for x in range(41)]

def test_data_length(self):
[Link](len(self.test_data), 41)

# [Link]()

Detailed Explanation: This exercise tests your mastery of test setup


method. The setUp() method is automatically called before every single test
method in the class. It is used to prepare the environment, such as opening
database connections or instantiating complex test data objects.
Exercise 42: Debugging Simulation

Problem Statement: Develop a Python script that implements debugging


simulation effectively.

Python Code Solution:

# Exercise 42: Debugging Simulation


def process_data(val):
modifier = 5
# breakpoint()
return val * modifier + 42

res = process_data(10)
print('Simulated debug output:', res)

Detailed Explanation: This exercise tests your mastery of debugging


simulation. In a live debugging scenario, inserting the built-in breakpoint()
function (or import pdb; pdb.set_trace()) pauses the script. This drops the
developer into an interactive console to manually inspect the values of
'modifier' and 'val'.
Exercise 43: Unit Test Assertion

Problem Statement: Develop a Python script that implements unit test


assertion effectively.

Python Code Solution:

# Exercise 43: Unit Test Assertion


import unittest

def multiply(a, b): return a * b

class TestMath([Link]):
def test_mult(self):
[Link](multiply(43, 2), 86)

# [Link]()

Detailed Explanation: This exercise tests your mastery of unit test


assertion. We define a test case inheriting from [Link]. We use
[Link] to assert that our multiplication function correctly processes
the inputs and returns the exact expected mathematical output.
Exercise 44: Exception Testing

Problem Statement: Develop a Python script that implements exception


testing effectively.

Python Code Solution:

# Exercise 44: Exception Testing


import unittest

def get_item(lst, index):


return lst[index]

class TestList([Link]):
def test_bounds(self):
with [Link](IndexError):
get_item([1, 2], 49)

# [Link]()

Detailed Explanation: This exercise tests your mastery of exception testing.


Using the [Link] context manager, we instruct the test runner to
expect an IndexError. If the function successfully throws the error, the test
passes; otherwise, it fails.
Exercise 45: Logging Configuration

Problem Statement: Develop a Python script that implements logging


configuration effectively.

Python Code Solution:

# Exercise 45: Logging Configuration


import logging
[Link](level=[Link])

val = 450
[Link](f'Debugging variable state: val={val}')
[Link]('Operation finished safely.')

Detailed Explanation: This exercise tests your mastery of logging


configuration. Instead of using print(), we configure the built-in logging
module to display DEBUG level messages and above. This is the
professional standard for tracking application flow and internal states.
Conclusion

Congratulations on completing Chapter 8! You are no longer just writing scripts; you
are writing professional, production-ready software. You have learned how to
proactively prevent bugs using the unittest framework, track application health
using the logging module, inspect complex logic using pdb , and enforce
structure using Type Hinting. These are the hallmarks of a senior Python developer.

You might also like