A decorator does not have to change the data at all. It can add invisible behavior like logging, metrics or caching while passing the payload straight through. This is how you slot instrumentation into a stream pipeline without touching the source or the caller.
Implement Counting. Its constructor (already provided) sets self.calls to 0. Its read() must increment self.calls by one and then return the wrapped text completely unchanged. To the pipeline it is transparent; on the side it records how many times read() was invoked. Because it keeps the same interface, it can sit anywhere in a stack of decorators and the output is unchanged.
class Source:
def __init__(self, text):
self.text = text
def read(self):
return self.text
class Decorator:
def __init__(self, wrapped):
self.wrapped = wrapped
def read(self):
return self.wrapped.read()
class UpperCase(Decorator):
def read(self):
return self.wrapped.read().upper()
class Reverse(Decorator):
def read(self):
return self.wrapped.read()[::-1]
class Repeat(Decorator):
def __init__(self, wrapped, times):
super().__init__(wrapped)
self.times = times
def read(self):
return self.wrapped.read() * self.times
class Counting(Decorator):
def __init__(self, wrapped):
super().__init__(wrapped)
self.calls = 0
def read(self):
"""Count this call, then delegate unchanged to the wrapped source."""
# TODO:
# self.calls += 1
# return self.wrapped.read()
pass
The editor and the test runner need a wide screen. Open this page on a desktop browser and your progress will be waiting.
A decorator does not have to change the data at all. It can add invisible behavior like logging, metrics or caching while passing the payload straight through. This is how you slot instrumentation into a stream pipeline without touching the source or the caller.
Implement Counting. Its constructor (already provided) sets self.calls to 0. Its read() must increment self.calls by one and then return the wrapped text completely unchanged. To the pipeline it is transparent; on the side it records how many times read() was invoked. Because it keeps the same interface, it can sit anywhere in a stack of decorators and the output is unchanged.
Press Run Tests or ββ© to check your solution.