Make small, interchangeable text operations. Inputs are strings.
Prototype: implement Lowercase.apply(text), returning lowercase text. Construction takes no arguments.
Final: implement TextOperation.apply(text) as a base method that raises NotImplementedError; Strip(TextOperation) and Replace(TextOperation) override it. Strip() removes surrounding whitespace. Replace(old, new) stores two strings and replaces every occurrence using normal str.replace behavior (including its behavior for an empty old). Implement Pipeline(operations).apply(text) to apply operations in order, returning the final string. Copy the provided operations sequence at construction so later appends to it have no effect. An empty pipeline returns its input unchanged. Accept any object with apply(text), including Lowercase; do not require inheritance. Callback exceptions propagate.
Complete the starter code, then run the checks.
Results and errors will appear here.