Compare commits
10 Commits
f4a0576f3c
...
1121c6a171
Author | SHA1 | Date | |
---|---|---|---|
1121c6a171 | |||
9ea341183d | |||
801b641fb2 | |||
f3e49c96cd | |||
f89435117a | |||
56c0d4bec3 | |||
407389a5cb | |||
da878ec3e6 | |||
8ed82e01aa | |||
23f4c7be52 |
22
README.md
22
README.md
@@ -1,33 +1,33 @@
|
||||
# Übungsaufgaben zur EidP (WS2023) Klausur
|
||||
|
||||
Alle Aufgaben hier behandeln Konzepte aus der Vorlesung **Einführung in die Programmierung** von der Albert-Ludwig-Universität Freiburg. Hierbei handelt es sich um selbsterstellte Aufgaben der EidP-Tutoren [**Nils Pukropp**](mailto:nils@narl.io) und [**Daniel Mironow**](mailto:mail@danielmironov.dev) die bei der Vorbereitung auf die Klausur helfen sollen.
|
||||
Alle Aufgaben hier behandeln Konzepte aus der Vorlesung **Einführung in die Programmierung** von der Albert-Ludwig-Universität Freiburg. Hierbei handelt es sich um selbsterstellte Aufgaben der EidP-Tutoren [**Nils Pukropp**](mailto:nils@narl.io) und [**Daniel Mironow**](mailto:mail@danielmironov.dev) die bei der Vorbereitung auf die Klausur helfen sollen. :D
|
||||
|
||||
## Reihenfolge der Themen
|
||||
|
||||
Es gibt keine direkte Reihenfolge, lediglich Themen die sich teilweise überschneiden. Dennoch gibt es eine Reihenfolge nach Wichtigkeit der Themen:
|
||||
|
||||
- [Grundkonzept Schleifen (`for`, `while`, ...)](./loops)
|
||||
- [Grundkonzept Schleifen (`for`, `while`, ...)](src/branch/main/loops)
|
||||
- allgemeine Knobelaufgaben rund um Schleifen
|
||||
- Einfach mit ein paar schwierigeren Aufgaben zum Nachdenken
|
||||
- [Zeichenketten (Strings `str`)](./strings)
|
||||
- [Zeichenketten (Strings `str`)](src/branch/main/strings)
|
||||
- allgemeine Knobelaufgaben rund um `str`
|
||||
- Einfach mit ein paar schwierigeren Aufgaben zum Nachdenken
|
||||
- [Dataclasses (OOP `@dataclass`)](./dataclasses)
|
||||
- [Dataclasses (OOP `@dataclass`)](src/branch/main/dataclasses)
|
||||
- Objekt orientierte Programmierung mit `@dataclass`
|
||||
- Einfach (Auswendig lernen)
|
||||
- [Pattern Matching (`match`)](./pattern_matching)
|
||||
- [Pattern Matching (`match`)](src/branch/main/pattern_matching)
|
||||
- Intensive Übungen zu `match`
|
||||
- Mittel (Auswendig lernen, aber erfordert grundlegende Konzepte)
|
||||
- [Typvariabeln (Generics `[T]`)](./generics)
|
||||
- [Typvariabeln (Generics `[T]`)](src/branch/main/generics)
|
||||
- Platzhalter Variabeln um generische Typannotation umzusetzen
|
||||
- Mittel (Auswendig lernen, aber erfordert grundlegende Konzepte)
|
||||
- [Rekursion (Tree)](./recursion)
|
||||
- [Rekursion (Tree)](src/branch/main/recursion)
|
||||
- Sich selbst aufrufende Funktionen
|
||||
- Schwer, da das Konzept etwas verwirrend ist, aber gut für schnelle Punkte in der Klausur!
|
||||
- [Generator](./generator)
|
||||
- [Generator](src/branch/main/generator)
|
||||
- Erzeugen von Iteratoren auf die seltsame Python Art und Weise!
|
||||
- Mittel, da das Konzept etwas seltsam ist. Muss man einfach ein paar mal machen!
|
||||
- [Funktionale Programmierung](./functional_programming)
|
||||
- [Funktionale Programmierung](src/branch/main/functional_programming)
|
||||
- Programmieren-Paradigma bei dem der Programmfluss durch Funktionen bestimmt wird!
|
||||
- Schwer, da das Konzept etwas schwer zu verstehen ist und viele Grundlagen vorraussetzt
|
||||
|
||||
@@ -45,9 +45,11 @@ Es gibt keine direkte Reihenfolge, lediglich Themen die sich teilweise überschn
|
||||
- Könnt auch gerne nachfragen wenn was nicht funktioniert!
|
||||
- Dann könnt ihr einfach die Tests mit `pytest` in der Konsole aufrufen
|
||||
- Schlagen die Tests fehl sieht das so aus:
|
||||
|
||||

|
||||
- Hier sagt euch Pytest auch was alles nicht an eurem Code funktioniert
|
||||
- Funktioniert euer Code sieht das so aus:
|
||||
|
||||

|
||||
|
||||
## Kontakt
|
||||
@@ -59,4 +61,4 @@ Es gibt keine direkte Reihenfolge, lediglich Themen die sich teilweise überschn
|
||||
- Daniel Mironow (Tutor)
|
||||
- [E-Mail](mailto:mail@danielmironov.dev)
|
||||
- [Discord](https://discord.com/users/236939658301407243)
|
||||
- [Discord-Server](https://discord.gg/naeprrX7hB)
|
||||
- [Discord-Server](https://discord.gg/naeprrX7hB)
|
||||
|
1
generator/primes/README.md
Normal file
1
generator/primes/README.md
Normal file
@@ -0,0 +1 @@
|
||||
# primes generator
|
0
generator/primes/primes.py
Normal file
0
generator/primes/primes.py
Normal file
29
generator/primes/solution/primes.py
Normal file
29
generator/primes/solution/primes.py
Normal file
@@ -0,0 +1,29 @@
|
||||
from typing import Iterator
|
||||
|
||||
|
||||
def is_prime(n: int) -> bool:
|
||||
if n < 2:
|
||||
return False
|
||||
for d in range(2, n // 2 + 1):
|
||||
if n % d == 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def primes() -> Iterator[int]:
|
||||
num = 2
|
||||
while True:
|
||||
if is_prime(num):
|
||||
yield num
|
||||
num += 1
|
||||
|
||||
|
||||
def prime_factorize(n: int) -> Iterator[int]:
|
||||
it = primes()
|
||||
num = n
|
||||
while num > 1:
|
||||
if num % (prime := next(it)) != 0:
|
||||
continue
|
||||
num //= prime
|
||||
it = primes()
|
||||
yield prime
|
51
generator/primes/solution/test_primes.py
Normal file
51
generator/primes/solution/test_primes.py
Normal file
File diff suppressed because one or more lines are too long
1
list_comprehensions/README.md
Normal file
1
list_comprehensions/README.md
Normal file
@@ -0,0 +1 @@
|
||||
# List Comprehensions
|
36
list_comprehensions/comprehensions.py
Normal file
36
list_comprehensions/comprehensions.py
Normal file
@@ -0,0 +1,36 @@
|
||||
def divisible_by_7(n: int) -> list[int]:
|
||||
"""
|
||||
Returns a list of all numbers till 'n' that are divisible by '7'
|
||||
"""
|
||||
|
||||
|
||||
def contains_3(n: int) -> list[int]:
|
||||
"""
|
||||
Returns a list of all numbers that contain the digit '3' in them
|
||||
"""
|
||||
|
||||
|
||||
def count_spaces(string: str) -> int:
|
||||
"""
|
||||
Count the spaces in a string
|
||||
"""
|
||||
|
||||
|
||||
def remove_vowels(string: str) -> str:
|
||||
"""
|
||||
Remove all vowels from the string
|
||||
"""
|
||||
|
||||
|
||||
def word_lengths(string: str) -> dict[str, int]:
|
||||
"""
|
||||
Create a dictionary of all words with their lengths
|
||||
"""
|
||||
|
||||
|
||||
def prime_numbers(n: int) -> list[int]:
|
||||
"""
|
||||
Returns a list of all prime numbers till 'n' (HARD)
|
||||
"""
|
||||
|
||||
|
0
list_comprehensions/solution/README.md
Normal file
0
list_comprehensions/solution/README.md
Normal file
41
list_comprehensions/solution/comprehensions.py
Normal file
41
list_comprehensions/solution/comprehensions.py
Normal file
@@ -0,0 +1,41 @@
|
||||
def divisible_by_7(n: int) -> list[int]:
|
||||
"""
|
||||
Returns a list of all numbers till 'n' that are divisible by '7'
|
||||
"""
|
||||
return [x for x in range(1, n) if x % 7 == 0]
|
||||
|
||||
|
||||
def contains_3(n: int) -> list[int]:
|
||||
"""
|
||||
Returns a list of all numbers that contain the digit '3' in them
|
||||
"""
|
||||
return [x for x in range(1, n) if '3' in str(x)]
|
||||
|
||||
|
||||
def count_spaces(string: str) -> int:
|
||||
"""
|
||||
Count the spaces in a string
|
||||
"""
|
||||
return len([ch for ch in string if ' ' == ch])
|
||||
|
||||
|
||||
def remove_vowels(string: str) -> str:
|
||||
"""
|
||||
Remove all vowels from the string
|
||||
"""
|
||||
return ''.join([ch for ch in string if ch.lower() not in 'aeiou'])
|
||||
|
||||
|
||||
def word_lengths(string: str) -> dict[str, int]:
|
||||
"""
|
||||
Create a dictionary of all words with their lengths
|
||||
"""
|
||||
return {word: len(word) for word in string.split(' ') if len(word) > 0}
|
||||
|
||||
|
||||
def prime_numbers(n: int) -> list[int]:
|
||||
"""
|
||||
Returns a list of all prime numbers till 'n' (HARD)
|
||||
"""
|
||||
return [x for x in range(2, n) if all(x % y != 0 for y in range(2, x))]
|
||||
|
77
list_comprehensions/test_comprehensions.py
Normal file
77
list_comprehensions/test_comprehensions.py
Normal file
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
||||
# [Primzahlen](./primes.py)
|
||||
# [Primzahlen](src/branch/main/loops/primes/primes.py)
|
||||
|
||||
## `is_prime`
|
||||
|
||||
@@ -28,4 +28,4 @@ Schreiben Sie nun folgende Funktion `prime_factorize(n: int) -> list[int]` welch
|
||||
|
||||
Tipp: Sie können hierfür die Funktionen `is_prime` und `next_prime` verwenden
|
||||
|
||||
## [Hier gehts zu den Lösungen](./solution/primes.py)
|
||||
## [Hier gehts zu den Lösungen](src/branch/main/loops/primes/solution)
|
||||
|
84
loops/sort/README.md
Normal file
84
loops/sort/README.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# [Sortierte Datenstrukturen](src/branch/main/loops/sort/sort.py)
|
||||
|
||||
## `selection_sort`
|
||||
|
||||
**Selection Sort** basiert auf dem Konzept durch jedes Element in einer Liste zu gehen um dann das kleineste Element in den übrigen zu suchen und mit dem aktuellen Element zu tauschen.
|
||||
|
||||
- Wichtig ist dass dabei die übergebene Liste nicht verändert wird und eine neue sortierte erstellt wird
|
||||
- Manuell erstellen mit loop oder `deepcopy`
|
||||
|
||||
Beispiel:
|
||||
```
|
||||
arr[] = 64 25 12 22 11
|
||||
|
||||
// Find the minimum element in arr[0...4]
|
||||
// and place it at beginning
|
||||
11 25 12 22 64
|
||||
|
||||
// Find the minimum element in arr[1...4]
|
||||
// and place it at beginning of arr[1...4]
|
||||
11 12 25 22 64
|
||||
|
||||
// Find the minimum element in arr[2...4]
|
||||
// and place it at beginning of arr[2...4]
|
||||
11 12 22 25 64
|
||||
|
||||
// Find the minimum element in arr[3...4]
|
||||
// and place it at beginning of arr[3...4]
|
||||
11 12 22 25 64
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Hilfe 1: Pseudocode</summary>
|
||||
|
||||
```
|
||||
for e_i in xs
|
||||
kleinstes_e = e_i
|
||||
for e_j in xs mit: j = i + 1
|
||||
if kleinstes_e > e_j
|
||||
kleinstes_e = e_j
|
||||
vertausche e_i und kleinstes_e
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## `binary_search`
|
||||
|
||||
Hierbei handelt es sich um einen Algorithmus welcher die Position von einem Wert in einem sortierten Array schnell findet.
|
||||
|
||||
Beispiele:
|
||||
```python
|
||||
binary_search([1, 2, 3, 4, 5], 4) # 3, was der index von 4 ist
|
||||
binary_search(["a", "b", "c", "d"], "b") # 1, was der index von "b" ist
|
||||
```
|
||||
|
||||
- Dazu definieren wir eine linke Grenze `left` mit dem Anfangswert `0` und eine rechte Grenze `right` mit dem Anfangswert `len(xs) - 1`, damit können wir unser gesuchtes Element immer weiter eingrenzen.
|
||||
- Jetzt wissen wir durch die Sortierung dass `left <= right` sein muss.
|
||||
- Also gehen wir jetzt durch unsere Liste und berechnen die Mitte `middle` von `left` und `right` aus und vergleichen diese mit unserem gesuchten Wert.
|
||||
- Ist `middle` kleiner als unser Wert dann können wir `left = middle + 1` setzen
|
||||
- Ist `middle` größer als unser Wert dann können wir `right = middle - 1` setzen
|
||||
- Sonst haben wir unseren Wert, nämlich `middle`, gefunden und können diesen zurückgeben
|
||||
- Wenn der Wert nicht existiert wird `None` zurückgegeben
|
||||
- Für leere Listen soll auch `None` zurückgegeben werden
|
||||
|
||||
|
||||
<details>
|
||||
<summary>Hilfe 1: Pseudocode</summary>
|
||||
|
||||
```
|
||||
linker_index = 0
|
||||
rechter_index = länge - 1
|
||||
solange linker_index <= rechter_index dann
|
||||
mitte = (linker_index + rechter_index) / 2
|
||||
Wenn Liste[mitte] < gesuchter Wert dann
|
||||
linker_index = mitte + 1
|
||||
Wenn Liste[mitte] > gesuchter Wert dann
|
||||
rechter_index = mitte - 1
|
||||
Sonst
|
||||
return Liste[mitte]
|
||||
return Nichts
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## [Hier gehts zur Lösung](src/branch/main/loops/sort/solution)
|
87
loops/sort/solution/README.md
Normal file
87
loops/sort/solution/README.md
Normal file
@@ -0,0 +1,87 @@
|
||||
# Solution
|
||||
|
||||
## `selection_sort`
|
||||
|
||||
Zunächst müssen wir eine neue Liste mit den selben Elementen erstellen, am schnellsten geht das mit `copy.deepcopy` welche eine vollständige Copie erstellt.
|
||||
|
||||
```python
|
||||
from copy import deepcopy
|
||||
|
||||
xss = deepcopy(xs)
|
||||
```
|
||||
|
||||
Wir müssen durch jedes Element gehen, also
|
||||
|
||||
```python
|
||||
for i in range(len(xss)):
|
||||
# ...
|
||||
```
|
||||
Nun wollen wir in den übrigen Elementen ($j = i + 1$) das kleinste finden
|
||||
|
||||
```python
|
||||
for i in range(len(xss)):
|
||||
min_i = i # index vom kleinsten Element,
|
||||
# das aktuelle i falls dieses schon das kleinste ist
|
||||
for j in range(i + 1, len(xss)):
|
||||
# ...
|
||||
```
|
||||
|
||||
Jetzt vergleichen wir nur noch jedes j-te Element mit dem aktuellen kleinsten
|
||||
|
||||
```python
|
||||
for i in range(len(xss)):
|
||||
min_i = i # index vom kleinsten Element,
|
||||
# das aktuelle i falls dieses schon das kleinste ist
|
||||
for j in range(i + 1, len(xss)):
|
||||
if xss[j] < xss[min_i]:
|
||||
min_i = j # kleineres element gefunden
|
||||
```
|
||||
|
||||
Nun können wir einfach das i-te mit dem min_i vertauschen (entweder ist es i oder wir haben ein kleineres gefunden)
|
||||
|
||||
```python
|
||||
xss[i], xss[min_i] = xss[min_i], xss[i] # tauschen i mit min_i
|
||||
```
|
||||
|
||||
und am Ende können wir `xss` zurückgeben
|
||||
|
||||
```python
|
||||
return xss
|
||||
```
|
||||
|
||||
## `binary_search`
|
||||
|
||||
Hierfür definieren wir zunächst `left = 0` und `right = len(xs) - 1`, dann können wir die Schleifenbedingung definieren als
|
||||
|
||||
```python
|
||||
while left <= right:
|
||||
# ...
|
||||
```
|
||||
|
||||
weil sobald diese nicht mehr gilt konnten wir den Wert nicht finden. (Links und Rechts tauschen) und wir können `None` zurückgeben.
|
||||
|
||||
Nun berechnen wir den mittleren Index mit dem integer division (oder auch floor weil es die Zahl hinterm Komma verwirft).
|
||||
|
||||
```python
|
||||
middle = (left + right) // 2
|
||||
```
|
||||
|
||||
Nun müssen wir nur noch `xs[middle]` mit `value` vergleichen
|
||||
|
||||
```python
|
||||
if xs[middle] < value:
|
||||
left = middle + 1
|
||||
elif xs[middle] > value:
|
||||
right = middle - 1
|
||||
```
|
||||
|
||||
Und wenn `xs[middle] == value` ist haben wir unseren Index `middle` gefunden.
|
||||
|
||||
```python
|
||||
if xs[middle] < value:
|
||||
left = middle + 1
|
||||
elif xs[middle] > value:
|
||||
right = middle - 1
|
||||
else:
|
||||
return middle
|
||||
```
|
27
loops/sort/solution/sort.py
Normal file
27
loops/sort/solution/sort.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from copy import deepcopy
|
||||
from typing import Iterator, Optional
|
||||
|
||||
|
||||
def selection_sort[T](xs: Iterator[T]) -> Iterator[T]:
|
||||
length = len(xs)
|
||||
xss = deepcopy(xs)
|
||||
for i in range(length):
|
||||
min_i = i
|
||||
for j in range(i + 1, length):
|
||||
if xss[j] < xss[min_i]:
|
||||
min_i = j
|
||||
xss[i], xss[min_i] = xss[min_i], xss[i]
|
||||
return xss
|
||||
|
||||
def binary_search[T](xs: list[T], value: T) -> Optional[int]:
|
||||
left = 0
|
||||
right = len(xs) - 1
|
||||
while left <= right:
|
||||
middle = (left + right) // 2
|
||||
if xs[middle] < value:
|
||||
left = middle + 1
|
||||
elif xs[middle] > value:
|
||||
right = middle - 1
|
||||
else:
|
||||
return middle
|
||||
return None
|
9
loops/sort/sort.py
Normal file
9
loops/sort/sort.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from typing import Iterator, Optional
|
||||
|
||||
|
||||
def selection_sort[T](xs: Iterator[T]) -> Iterator[T]:
|
||||
return []
|
||||
|
||||
|
||||
def binary_search[T](xs: list[T], value: T) -> Optional[int]:
|
||||
return None
|
22
loops/sort/test_sort.py
Normal file
22
loops/sort/test_sort.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from random import randint
|
||||
from typing import Iterator
|
||||
from sort import selection_sort, binary_search
|
||||
|
||||
def get_random_collection(min: int, max: int, size: int) -> Iterator[int]:
|
||||
return [randint(min, max) for _ in range(size)]
|
||||
|
||||
def test_selection_sort():
|
||||
xs = [5, 4, 3, 2, 1, 0]
|
||||
assert list(selection_sort(xs)) == sorted(xs)
|
||||
assert xs == [5, 4, 3, 2, 1, 0], "list was modified in `selection_sort` return a copy instead"
|
||||
xs = get_random_collection(0, 100, 100)
|
||||
print(xs)
|
||||
assert list(selection_sort(xs)) == sorted(xs)
|
||||
|
||||
def test_binary_search():
|
||||
xs = sorted(set(get_random_collection(0, 10000, 100)))
|
||||
for i, e in enumerate(xs):
|
||||
assert binary_search(xs, e) == i
|
||||
assert binary_search([], 1) == None
|
||||
assert binary_search([2], 1) == None
|
||||
assert binary_search([2, 3], 1) == None
|
4
strings/string_manipulation/README.md
Normal file
4
strings/string_manipulation/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# Mit Zeichenketten arbeiten und manipulieren
|
||||
|
||||
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.
|
||||
|
93
strings/string_manipulation/solution/strings.py
Normal file
93
strings/string_manipulation/solution/strings.py
Normal file
@@ -0,0 +1,93 @@
|
||||
from dataclasses import dataclass, InitVar
|
||||
from typing import Iterator
|
||||
|
||||
type Str = 'String' | str
|
||||
|
||||
@dataclass
|
||||
class String:
|
||||
_s: InitVar[str]
|
||||
|
||||
def __post_init__(self, s: str) -> None:
|
||||
self.__s = s
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.__s
|
||||
|
||||
def __add__(self, other: Str) -> 'String':
|
||||
return String(self.__s + str(other))
|
||||
|
||||
def __iadd__(self, other: Str) -> 'String':
|
||||
return self + other
|
||||
|
||||
def __len__(self) -> int:
|
||||
return len(self.__s)
|
||||
|
||||
def __eq__(self, other: Str) -> bool:
|
||||
return str(self) == str(other)
|
||||
|
||||
def concat(self, other: Str) -> None:
|
||||
self + other
|
||||
|
||||
def contains(self, other: Str) -> bool:
|
||||
s = str(other)
|
||||
for c in str(self):
|
||||
if len(s) <= 0:
|
||||
break
|
||||
elif c == s[0]:
|
||||
s: str = s[1:]
|
||||
else:
|
||||
s = str(other)
|
||||
return len(s) == 0
|
||||
|
||||
def concat(self, other: Str) -> None:
|
||||
self.__s += str(other)
|
||||
|
||||
def substring(self, start: int, end: int) -> 'String':
|
||||
substr: str = ""
|
||||
for i, c in enumerate(self.__s):
|
||||
if i >= start and i <= end:
|
||||
substr += c
|
||||
return substr
|
||||
|
||||
def strip(self, chars: Str = ' ' + '\n' + '\t' + '\r') -> None:
|
||||
i = 0
|
||||
while i < len(self) and self.__s[i] in chars:
|
||||
i += 1
|
||||
j: int = len(self) - 1
|
||||
while i <= j and self.__s[j] in chars:
|
||||
j -= 1
|
||||
self.__s: str = str(self)[i:j + 1]
|
||||
|
||||
def replace(self, old: Str, new: Str, count = -1) -> None:
|
||||
o = str(old)
|
||||
n = str(new)
|
||||
j = 0
|
||||
while count > 0 or (count < 0 and j < len(self)):
|
||||
i: int = j
|
||||
while len(o) > 0 and j < len(self):
|
||||
if o[0] == self.__s[j]:
|
||||
o: str = o[1:]
|
||||
j += 1
|
||||
else:
|
||||
j += 1
|
||||
break
|
||||
if len(o) <= 0:
|
||||
self.__s = self.__s[:i] + n + self.__s[j:]
|
||||
j += len(new) - len(old)
|
||||
count -= 1
|
||||
o = str(old)
|
||||
|
||||
def add_prefix(self, prefix: Str) -> None:
|
||||
self.__s = str(prefix) + self.__s
|
||||
|
||||
def add_suffix(self, suffix: Str) -> None:
|
||||
self.__s += str(suffix)
|
||||
|
||||
def join[T](self, xs: Iterator[T]) -> 'String':
|
||||
output = String("")
|
||||
length: int = len(xs)
|
||||
for i, e in enumerate(xs):
|
||||
output += str(e)
|
||||
if i < length - 1:
|
||||
output += self
|
||||
return output
|
9
strings/string_manipulation/strings.py
Normal file
9
strings/string_manipulation/strings.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from dataclasses import dataclass
|
||||
|
||||
# kleine Hilfestellung mit `Str` kann man sowohl `str` als auch `String` meinen
|
||||
type Str = 'String' | str
|
||||
|
||||
@dataclass
|
||||
class String:
|
||||
# Implement!
|
||||
pass
|
49
strings/string_manipulation/test_strings.py
Normal file
49
strings/string_manipulation/test_strings.py
Normal file
@@ -0,0 +1,49 @@
|
||||
from strings import String
|
||||
|
||||
def test_eq_for_str():
|
||||
test_str = String("this is a test string!")
|
||||
assert test_str == "this is a test string!", "__eq__ wasn't implemented correctly for `String` and `str`"
|
||||
|
||||
def test_strings_contains():
|
||||
test_str = String("this is a test")
|
||||
assert test_str.contains("this")
|
||||
assert not test_str.contains("release")
|
||||
|
||||
def test_strings_concat():
|
||||
test_str = String("")
|
||||
test_str += "test succesful!"
|
||||
assert test_str == "test succesful!"
|
||||
test_str.concat(" Or is it?")
|
||||
assert test_str == "test succesful! Or is it?"
|
||||
|
||||
def test_strings_strip():
|
||||
test_str = String(" halo? \n")
|
||||
test_str.strip()
|
||||
assert test_str == "halo?"
|
||||
test_str = String(" \n ")
|
||||
test_str.strip()
|
||||
assert test_str == ""
|
||||
|
||||
|
||||
def test_strings_replace():
|
||||
test_str = String("har har har, try replacing thhis")
|
||||
test_str.replace('har ', 'ha')
|
||||
assert test_str == "hahahar, try replacing thhis"
|
||||
test_str.replace('r', '', 1)
|
||||
assert test_str == "hahaha, try replacing thhis"
|
||||
test_str.replace('hh', 'h')
|
||||
assert test_str == "hahaha, try replacing this"
|
||||
test_str.replace('try replacing this', "replaced")
|
||||
assert test_str == "hahaha, replaced"
|
||||
|
||||
|
||||
def test_add_pre_suf():
|
||||
test_str = String(" ")
|
||||
test_str.add_suffix("suff")
|
||||
assert test_str == " suff"
|
||||
test_str.add_prefix("pref")
|
||||
assert test_str == "pref suff"
|
||||
|
||||
def test_join():
|
||||
assert String(", ").join([1, 2, 3, 4]) == "1, 2, 3, 4"
|
||||
assert String(", ").join([]) == ""
|
Reference in New Issue
Block a user