UpperCase transformer

Step 2: UpperCase transformer

Now that the base decorator forwards transparently, we can subclass it to add behavior. A concrete decorator overrides read: it still calls self.wrapped.read() to get the underlying data, but transforms the result before handing it back.

Implement UpperCase, whose read() returns the wrapped text uppercased. Notice it does not care whether it is wrapping a plain Source or another decorator. It only relies on the shared read() interface. That is what makes decorators composable.

Hints
Starter code
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 the wrapped text uppercased."""
        # TODO:
        #   return self.wrapped.read().upper()
        pass
Write it on a laptop

The editor and the test runner need a wide screen. Open this page on a desktop browser and your progress will be waiting.