Overview Read this overview.
Video Watch the video for this class from the demo playlist.
Demonstration Look through these sample problems.
Challenges
Submission When you have completed the entire set of code challenges and all tests pass, create a pull request from your current branch to the main branch and merge it into main.
You will be able to see a test coverage report in GitHub on the Actions tab of your data-structures-and-algorithms repository. It should match what you saw on your terminal in the above steps. Your graders will be looking at this as well.
Submit a link to your pull request.
Bookmark and Review
Statement on why this topic matter as it relates to what I’m studying in this module:
Dunder methods, iterators, generators, and decorators, allows for customizing and enhancing the behavior of classes and functions.
What are dunder methods in Python, and how do they allow for the customization of built-in behavior in classes? Provide an example of a common dunder method and its purpose.
__init__, __str__, __add__). These methods allow classes to define and customize various built-in behaviors.Example:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return f"({self.x}, {self.y})"
def __add__(self, other):
return Point(self.x + other.x, self.y + other.y)
__init__(self, x, y): This is the constructor method, called when an object is created. It initializes the object’s attributes.__str__(self): This method defines the string representation of the object when str() is called on it.__add__(self, other): This method allows objects of the class to use the + operator, defining how two objects should be added together.Explain the concept of an iterator in Python. How do you create a custom iterator using the iter() and next() methods, and why are they important for enabling iteration in a class?
__iter__() and __next__() methods.__iter__() returns the iterator object itself and is used in initializing the iteration.__next__() returns the next item in the sequence. When there are no more items, it raises the StopIteration exception.
Creating a Custom Iterator:
class Squares:
def __init__(self, n):
self.n = n
self.i = 0
def __iter__(self):
return self
def __next__(self):
if self.i >= self.n:
raise StopIteration
result = self.i ** 2
self.i += 1
return result
# Using the custom iterator
sq = Squares(5)
it = iter(sq)
print(next(it)) # 0
print(next(it)) # 1
print(next(it)) # 4
Squares is a class that implements the iterator protocol.__iter__ returns the iterator object itself.__next__ computes and returns the next square value until n.What is a generator in Python, and how does it differ from a regular function? Illustrate your answer with an example of a generator function using the ‘yield’ keyword.
Generators are functions that use the yield keyword to return values one at a time, pausing and resuming execution as needed. They differ from regular functions in that they don’t return a single value and then exit; instead, they can yield multiple values over time.
Example of a Generator Function:
def fibonacci_generator(n):
a, b = 0, 1
count = 0
while count < n:
yield a
a, b = b, a + b
count += 1
# Using the generator
fib = fibonacci_generator(5)
for num in fib:
print(num)
fibonacci_generator is a generator function that yields Fibonacci numbers up to n.yield keyword pauses the function, saving its state, and returns the value. It then resumes execution from where it left off when called again.Define decorators in Python and explain their primary use case. How can you create and apply a custom decorator to a function or method? Provide a simple example to demonstrate this concept.
Decorators are functions that modify the behavior of another function or method. They are commonly used for adding functionality to existing functions without modifying their structure.
Creating and Applying a Custom Decorator:
def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func()
print("Something is happening after the function is called.")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
# Using the decorated function
say_hello()
my_decorator is a custom decorator that defines a wrapper function around the original func.@my_decorator syntax is used to apply the decorator to the say_hello function.say_hello is called, it executes the wrapper function, which adds extra behavior before and after calling say_hello.Retrospectives are a critical part of Agile, and typically take the form of meetings held by a team at the end of a sprint cycle. To get us acclimated to that process, we will use the format of a retrospectives to guide today’s reflection.
This article gives a nice overview to the role of retrospectives.