This commit is contained in:
2024-02-14 01:14:52 +01:00
parent 14cd9fe8b0
commit 36b6a78833
4 changed files with 171 additions and 37 deletions

View File

@ -2,3 +2,91 @@
Diese Teilaufgaben sind teilweise sehr einfach zu implementieren und sollen veranschaulichen was man alles mit Strings machen kann. Hierbei könnt ihr euch es natürlich einfach machen und die Buildins von `str` verwenden oder die Funktionen komplett selber implementieren. Diese Teilaufgaben sind teilweise sehr einfach zu implementieren und sollen veranschaulichen was man alles mit Strings machen kann. Hierbei könnt ihr euch es natürlich einfach machen und die Buildins von `str` verwenden oder die Funktionen komplett selber implementieren.
## String-Class
Zunächst möchten wir eine *dataclass* *String* erstellen die genau einen *str* als Argument nimmt und in eimem privaten Attribut *__s* speichert. Dieses Attribut soll auch von Typ *str* sein und unsere *String* klasse intern representieren.
## Operatoren, Str, Len, und Iterator
Nun möchten wir alle standard Operatoren und Funktionen für unseren *String* überschreiben
### `__str__`
Diese Methode soll einfach die *str* Representation unserer *String* Klasse sein
### `__add__`, `__radd__`
Diese Methode soll unseren *String* nicht verändern, aber zwei *Str* konkatenieren. Hierbei kann ein *Str* sowohl ein *String* als auch ein *str* sein! Hierbei wird `self` mit `other` konkateniert.
`__radd__` hat genau das selbe verhalten, nur dass `other` mit `self` konkateniert wird.
```python
my_string = String("hello")
assert str(my_string + " world") == "hello world"
assert str("world " + my_str) == "world hello"
```
### `__len__`
Diese Methode soll uns die Länge unseres Strings zurückgeben
```python
assert len(String("hello world")) == 11
```
### `__eq__`
Diese Methode soll die Vergleichbarkeit zwischen *str* und *String* implementieren, also
```python
my_string = String("hello")
assert my_string == "hello"
assert my_string == String("hello")
```
### `__iter__`
Diese Methode soll einen Iterator aus unserem *String* machen damit wir über die einzelnen Characters iterieren können
```python
my_string = String("hello world")
my_it = iter(my_string)
for c in my_it:
print(c, end="") # hello world
```
## `concat`
Hierbei soll *self* nicht verändert werden, wir möchten *self* mit *other* konkatenieren und einen neuen konkatenierten *String* zurückgeben
## `contains`
Wir möchten schauen ob *other* in *self* enthalten ist
## `substring`
Wir möchten einen neuen *String* zurückgeben der alle Stellen von `start` bis `end`enthält. Hierbei sollten man von ausgehen dass `start` und `end` nicht negativ oder größer als der String sind.
## `strip`
Wir möchten am Anfang und Ende des Strings alle Stellen entfernen, solang diese in `chars` enthalten sind. Also
```python
assert String(" hello ").strip() == "hello"
```
## `replace`
Diese Methode soll überall `old` mit `new` genau `count`-Mal ersetzen. Wenn `count` negativ ist soll einfach jedes `old` ersetzt werden.
## `add_prefix`, `add_suffix`
`add_prefix` soll einen Prefix zu unserem String konkatenieren und analog dazu soll `add_suffix` einen Suffix zu unserem String konkatenieren
## `join`
Diese soll eine iterierbare Datenstruktur nehmen und zwischen jedes Element unseren *String* konkatenieren. Wir können davon ausgehen dass `T` zu einem *str* konvertiert werden kann (also `str(T)` anwendbar ist)
```python
assert String(", ").join([1, 2, 3, 4, 5]) == "1, 2, 3, 4, 5"
```

View File

@ -16,8 +16,8 @@ class String:
def __add__(self, other: Str) -> 'String': def __add__(self, other: Str) -> 'String':
return String(self.__s + str(other)) return String(self.__s + str(other))
def __iadd__(self, other: Str) -> 'String': def __radd__(self, other: Str) -> 'String':
return self + other return String(str(other) + self.__s)
def __len__(self) -> int: def __len__(self) -> int:
return len(self.__s) return len(self.__s)
@ -25,8 +25,14 @@ class String:
def __eq__(self, other: Str) -> bool: def __eq__(self, other: Str) -> bool:
return str(self) == str(other) return str(self) == str(other)
def concat(self, other: Str) -> None: def __iter__(self) -> Iterator[chr]:
self + other pass
for i in range(0, len(self)):
yield chr(self.__s[i])
raise StopIteration
def concat(self, other: Str) -> 'String':
return self + other
def contains(self, other: Str) -> bool: def contains(self, other: Str) -> bool:
s = str(other) s = str(other)
@ -39,9 +45,6 @@ class String:
s = str(other) s = str(other)
return len(s) == 0 return len(s) == 0
def concat(self, other: Str) -> None:
self.__s += str(other)
def substring(self, start: int, end: int) -> 'String': def substring(self, start: int, end: int) -> 'String':
substr: str = "" substr: str = ""
for i, c in enumerate(self.__s): for i, c in enumerate(self.__s):
@ -49,39 +52,41 @@ class String:
substr += c substr += c
return substr return substr
def strip(self, chars: Str = ' ' + '\n' + '\t' + '\r') -> None: def strip(self, chars: Str = ' ' + '\n' + '\t' + '\r') -> 'String':
i = 0 i = 0
while i < len(self) and self.__s[i] in chars: while i < len(self) and self.__s[i] in chars:
i += 1 i += 1
j: int = len(self) - 1 j: int = len(self) - 1
while i <= j and self.__s[j] in chars: while i <= j and self.__s[j] in chars:
j -= 1 j -= 1
self.__s: str = str(self)[i:j + 1] return String(str(self)[i:j + 1])
def replace(self, old: Str, new: Str, count = -1) -> None: def replace(self, old: Str, new: Str, count = -1) -> 'String':
o = str(old) o = str(old)
n = str(new) n = str(new)
new_str = self.__s
j = 0 j = 0
while count > 0 or (count < 0 and j < len(self)): while count > 0 or (count < 0 and j < len(new_str)):
i: int = j i: int = j
while len(o) > 0 and j < len(self): while len(o) > 0 and j < len(new_str):
if o[0] == self.__s[j]: if o[0] == new_str[j]:
o: str = o[1:] o: str = o[1:]
j += 1 j += 1
else: else:
j += 1 j += 1
break break
if len(o) <= 0: if len(o) <= 0:
self.__s = self.__s[:i] + n + self.__s[j:] new_str = new_str[:i] + n + new_str[j:]
j += len(new) - len(old) j += len(new) - len(old)
count -= 1 count -= 1
o = str(old) o = str(old)
return new_str
def add_prefix(self, prefix: Str) -> None: def add_prefix(self, prefix: Str) -> 'String':
self.__s = str(prefix) + self.__s return prefix + self
def add_suffix(self, suffix: Str) -> None: def add_suffix(self, suffix: Str) -> 'String':
self.__s += str(suffix) return self + suffix
def join[T](self, xs: Iterator[T]) -> 'String': def join[T](self, xs: Iterator[T]) -> 'String':
output = String("") output = String("")

View File

@ -1,9 +1,53 @@
from dataclasses import dataclass from dataclasses import dataclass
from typing import Iterator
# kleine Hilfestellung mit `Str` kann man sowohl `str` als auch `String` meinen # kleine Hilfestellung mit `Str` kann man sowohl `str` als auch `String` meinen
type Str = 'String' | str type Str = 'String' | str
@dataclass @dataclass
class String: class String:
# Implement!
pass def __post_init__(self, s: str) -> None:
pass
def __str__(self) -> str:
pass
def __add__(self, other: Str) -> 'String':
pass
def __radd__(self, other: Str) -> 'String':
pass
def __len__(self, other: Str) -> int:
pass
def __eq__(self, other: Str) -> bool:
pass
def __iter__(self) -> Iterator[chr]:
pass
def concat(self, other: Str) -> 'String':
pass
def contains(self, other: Str) -> bool:
pass
def substring(self, start: int, end: int) -> 'String':
pass
def strip(self, chars: Str = ' ' + '\n' + '\t' + '\r') -> 'String':
pass
def replace(self, old: Str, new: Str, count = -1) -> 'String':
pass
def add_prefix(self, prefix: Str) -> 'String':
pass
def add_suffix(self, suffix: Str) -> 'String':
pass
def join[T](self, xs: Iterator[T]) -> 'String':
pass

View File

@ -13,36 +13,33 @@ def test_strings_concat():
test_str = String("") test_str = String("")
test_str += "test succesful!" test_str += "test succesful!"
assert test_str == "test succesful!" assert test_str == "test succesful!"
test_str.concat(" Or is it?") assert test_str.concat(" Or is it?") == "test succesful! Or is it?"
assert test_str == "test succesful! Or is it?"
def test_strings_strip(): def test_strings_strip():
test_str = String(" halo? \n") test_str = String(" halo? \n")
test_str.strip() test_str = test_str.strip()
assert test_str == "halo?" assert test_str == "halo?"
test_str = String(" \n ") test_str = String(" \n ")
test_str.strip() test_str = test_str.strip()
assert test_str == "" assert test_str == ""
def test_strings_replace(): def test_strings_replace():
test_str = String("har har har, try replacing thhis") test_str = String("har har har, try replacing thhis")
test_str.replace('har ', 'ha') assert test_str.replace('har ', 'ha') == "hahahar, try replacing thhis"
assert test_str == "hahahar, try replacing thhis" test_str = test_str.replace('har ', 'ha')
test_str.replace('r', '', 1) assert test_str.replace('r', '', 1) == "hahaha, try replacing thhis"
assert test_str == "hahaha, try replacing thhis" test_str = test_str.replace('r', '', 1)
test_str.replace('hh', 'h') assert test_str.replace('hh', 'h') == "hahaha, try replacing this"
assert test_str == "hahaha, try replacing this" test_str = test_str.replace('hh', 'h')
test_str.replace('try replacing this', "replaced") assert test_str.replace('try replacing this', "replaced") == "hahaha, replaced"
assert test_str == "hahaha, replaced"
def test_add_pre_suf(): def test_add_pre_suf():
test_str = String(" ") test_str = String(" ")
test_str.add_suffix("suff") assert test_str.add_suffix("suff") == " suff"
assert test_str == " suff" assert test_str.add_prefix("pref") == "pref "
test_str.add_prefix("pref") assert test_str.add_suffix("suff").add_prefix("pref") == "pref suff"
assert test_str == "pref suff"
def test_join(): def test_join():
assert String(", ").join([1, 2, 3, 4]) == "1, 2, 3, 4" assert String(", ").join([1, 2, 3, 4]) == "1, 2, 3, 4"