| t | class SubString(str): | t | class SubString(str): |
| | | |
| def __new__(cls, value=''): | | def __new__(cls, value=''): |
| return super().__new__(cls, str(value)) | | return super().__new__(cls, str(value)) |
| | | |
| def __sub__(self, other): | | def __sub__(self, other): |
| if not isinstance(other, str): | | if not isinstance(other, str): |
| return NotImplemented | | return NotImplemented |
| counts = {} | | counts = {} |
| for ch in other: | | for ch in other: |
| counts[ch] = counts.get(ch, 0) + 1 | | counts[ch] = counts.get(ch, 0) + 1 |
| res = [] | | res = [] |
| for ch in self: | | for ch in self: |
| if counts.get(ch, 0) > 0: | | if counts.get(ch, 0) > 0: |
| counts[ch] -= 1 | | counts[ch] -= 1 |
| else: | | else: |
| res.append(ch) | | res.append(ch) |
| return SubString(''.join(res)) | | return SubString(''.join(res)) |
| | | |
| def __rsub__(self, other): | | def __rsub__(self, other): |
| if not isinstance(other, str): | | if not isinstance(other, str): |
| return NotImplemented | | return NotImplemented |
| return SubString(other).__sub__(self) | | return SubString(other).__sub__(self) |
| | | |
| def __add__(self, other): | | def __add__(self, other): |
| if not isinstance(other, str): | | if not isinstance(other, str): |
| return NotImplemented | | return NotImplemented |
| return SubString(str.__add__(self, other)) | | return SubString(str.__add__(self, other)) |
| | | |
| def __radd__(self, other): | | def __radd__(self, other): |
| if not isinstance(other, str): | | if not isinstance(other, str): |
| return NotImplemented | | return NotImplemented |
| return SubString(str.__add__(other, self)) | | return SubString(str.__add__(other, self)) |
| | | |
| def __mul__(self, n): | | def __mul__(self, n): |
| return SubString(str.__mul__(self, n)) | | return SubString(str.__mul__(self, n)) |
| | | |
| def __rmul__(self, n): | | def __rmul__(self, n): |
| return SubString(str.__mul__(self, n)) | | return SubString(str.__mul__(self, n)) |
| | | |
| def __getitem__(self, key): | | def __getitem__(self, key): |
| res = str.__getitem__(self, key) | | res = str.__getitem__(self, key) |
| return SubString(res) if isinstance(res, str) else res | | return SubString(res) if isinstance(res, str) else res |
| | | |
| def __getattribute__(self, name): | | def __getattribute__(self, name): |
| attr = super().__getattribute__(name) | | attr = super().__getattribute__(name) |
| if callable(attr): | | if callable(attr): |
| | | |
| def wrapper(*args, **kwargs): | | def wrapper(*args, **kwargs): |
| res = attr(*args, **kwargs) | | res = attr(*args, **kwargs) |
| if isinstance(res, str): | | if isinstance(res, str): |
| return SubString(res) | | return SubString(res) |
| if isinstance(res, tuple): | | if isinstance(res, tuple): |
| return tuple((SubString(x) if isinstance(x, str) els | | return tuple((SubString(x) if isinstance(x, str) els |
| e x for x in res)) | | e x for x in res)) |
| return res | | return res |
| return wrapper | | return wrapper |
| return attr | | return attr |