Compare commits

...

41 Commits

Author SHA1 Message Date
7d1e778902 Merge pull request 'task3' (#2) from task3 into main
Reviewed-on: #2

Wow, alle Beispiele gelöst, sehr schön. Wenn Du konkrete Feedbacks willst, müsstest Du diese einfach stellen.
Was mir gefällt ist die strukturierte Beschrifftung der commits (feat etc.) und dass Du alle Aufgaben modular commitest.
2026-03-13 10:11:17 +01:00
ce9a4029b7 refractor: removed print statement, that was ment for development 2026-03-11 23:57:28 +01:00
9df3b783fb feat: kata finished. Now correctly finds next bigger number. test: added test cases 2026-03-11 23:41:59 +01:00
fbe9f4bf02 function will now swamp pivot with lowest number right of pivot 2026-03-11 22:22:40 +01:00
c16bdad9b9 feat: function now finds pivot of number. Returns -1 if there is no pivot 2026-03-11 22:02:34 +01:00
5797eb8ef9 test: added a large number test case for kata 'Next bigger number with the same digits' 2026-03-11 21:44:56 +01:00
01a6ff1ead feat: kata next biggest number. Works but struggles with big numbers. test: test cases for kata 'Next bigger number with the same digits' 2026-03-11 17:45:04 +01:00
bc00bcf5f3 chore: added context for kata 'Next bigger number with the same digits' 2026-03-11 17:19:06 +01:00
d010de0fe5 test: test cases for kata 'Who has the most money' 2026-03-10 16:38:11 +01:00
c00cbd030b feat: kata 'Who has the most money' compleated. 2026-03-10 16:36:56 +01:00
a681ae4f2b chore: README updated for kata 'Who has the most money' 2026-03-10 15:24:22 +01:00
90ba3e1e60 chore: README updated for kata 'Who has the most money' 2026-03-10 15:24:00 +01:00
e521f037a4 refractor: removed unnecessary comment 2026-03-09 21:20:36 +01:00
00a42ea0fd fix: fixed function page_item_count. from calculating: constant * muliplicator * 2. to: constant * multiplicator + constant. first calculation returned wrong amount of items to return 2026-03-09 21:19:09 +01:00
fa8b2b21f9 fix: forgot to return len() of list in function page_item_count. Insted list itself was returned 2026-03-09 20:20:52 +01:00
7e43f0d42d feat: function page_count and page_item_count finished 2026-03-09 20:14:59 +01:00
fbf13b3f3f feat: function item_count() finished, working on page_count() 2026-03-09 18:36:38 +01:00
17de0e0f92 test: added test cases for kata 'PaginationHelper' 2026-03-09 18:20:09 +01:00
27c5087006 chore: README updated for kata content 'PaginationHelper' 2026-03-09 18:03:58 +01:00
95d79c84a8 feat: added inheritace and comparisond methods 2026-03-06 16:38:28 +01:00
8f3cd117ef feat: version manager kata done. test: testcase for version manager kata started 2026-03-06 10:22:31 +01:00
ec105d44be feat: kata version manager __init__ configured and methods created 2026-03-05 23:56:33 +01:00
e18a3f062f feat: animal.py tutorial for Interface and Inheritance 2026-03-05 12:26:46 +01:00
b67ebcdcca feat: mro tuorial 2026-03-05 12:00:34 +01:00
ffc1c06a2d feat: storage.py is a tutorial for Interface 2026-03-05 11:46:32 +01:00
16497f059c feat: robotpy is a tutorial for polymorphism 2026-03-05 11:17:10 +01:00
81dc543bf5 chore: nothing changen just needed to save file 2026-03-05 00:09:31 +01:00
4ed2cbe3f3 chore: README for katas descriptions feat: source file for katas test: test files for katas 2026-03-05 00:08:48 +01:00
be6d0997dc feat: finished ceasar cipher kata and test. refractor: vigenere cipher testfile, updated import after renameing filename of kata src 2026-03-04 23:55:54 +01:00
d1f40c422a chore: removed duplicate file in wrong directory 2026-03-04 23:12:15 +01:00
2a611bcc83 feat: new kata ceasar cipher helper 2026-03-04 23:10:38 +01:00
03d93a0b83 chore: added description for ceasar chiper helper codewars kata 2026-03-04 23:08:33 +01:00
d188900557 chore: renamed cipher_helper.py in vigenere_chpher_helper. Next kata will be ceasar_cipher_helper 2026-03-04 23:04:55 +01:00
252ff429d2 feat: key will repeat over every characters even if it isn't in alphabet 2026-03-04 22:59:39 +01:00
696c37396b feat: rehaul of encode function. Now will encode regardless of text length. Will ignore values not in alphabet. Decode works on same logic, but opposite 2026-03-04 22:08:22 +01:00
76e5f47d64 feat: encoding works but with only same length text and key and only alphabet values test: added asserts to test 2026-03-04 21:23:22 +01:00
ee9265d00c feat: kata vigenere cipher test: test for kata vigenere cipher 2026-03-04 18:07:27 +01:00
c6b4d8f3d9 chore: README updated codewars kata Vigenère Cipher Helper 2026-03-04 17:51:10 +01:00
da15c756d4 feat: codewars kata object oriented piracy. test: test codewars test object oriented piracy. chore: README updated for kata 2026-03-04 17:48:45 +01:00
515df4d452 chore: README updated with KATA description feat: added kata_the_lamp.py test: added test_the_lamp.py for testing kata 2026-03-02 18:45:55 +01:00
bc6f7e27aa chore: added Kata description to codewars table in README 2026-03-02 18:15:18 +01:00
28 changed files with 512 additions and 14 deletions

View File

@ -17,4 +17,15 @@ Repository for CDS-2020 Programming and Promt Engineering II
# Codewars # Codewars
|Title|Source (src/codewars/)|Test (test/codewars/)|URL| |Title|Source (src/codewars/)|Test (test/codewars/)|URL|
|-|-|-|-| |-|-|-|-|
|Find the force of gravity between two objects|kata_force_of_gravity.py|test_force_of_gravity.py|[URL](https://www.codewars.com/kata/5b609ebc8f47bd595e000627/)| |Find the force of gravity between two objects|kata_force_of_gravity.py|test_force_of_gravity.py|[5b609ebc8f47bd595e000627](https://www.codewars.com/kata/5b609ebc8f47bd595e000627)|
|The Lamp: Revisited|kata_the_lamp.py|test_the_lamp.py|[570e6e32de4dc8a8340016dd](https://www.codewars.com/kata/570e6e32de4dc8a8340016dd)|
|OOP: Object Oriented Piracy|kata_object_oriented_piracy.py|test_object_oriented_piracy.py|[54fe05c4762e2e3047000add](https://www.codewars.com/kata/54fe05c4762e2e3047000add)|
|Vigenère Cipher Helper|kata_vigenere_cipher_helper.py|test_vigenere_cipher_helper.py|[52d1bd3694d26f8d6e0000d3](https://www.codewars.com/kata/52d1bd3694d26f8d6e0000d3)|
|Caesar Cipher Helper|kata_ceasar_cipher_helper.py|test_ceasar_cipher_helper.py|[526d42b6526963598d0004db](https://www.codewars.com/kata/526d42b6526963598d0004db)|
|Versions manager|kata_version_mamanger.py|test_version_manager.py|[5bc7bb444be9774f100000c3](https://www.codewars.com/kata/5bc7bb444be9774f100000c3)|
|Thinkful - Object Drills: Quarks|kata_thinkful_quarks.py|test_thinkful_quarks.py|[5882b052bdeafec15e0000e6](https://www.codewars.com/kata/5882b052bdeafec15e0000e6)|
|Thinkful - Object Drills: Vectors|kata_thinkful_vectors.py|test_thinkful_vectors.py|[587f1e1f39d444cee6000ad4](https://www.codewars.com/kata/587f1e1f39d444cee6000ad4)|
|Building blocks|kata_building_blocks.py|test_building_blocks.py|[55b75fcf67e558d3750000a3](https://www.codewars.com/kata/55b75fcf67e558d3750000a3)|
|PaginationHelper|kata_pagination_helper.py|test_pagination_helper.py|[515bb423de843ea99400000a](https://www.codewars.com/kata/515bb423de843ea99400000a)|
|Who has the most money?|kata_who_the_most_money.py|test_who_the_most_money.py|[528d36d7cc451cd7e4000339](https://www.codewars.com/kata/528d36d7cc451cd7e4000339)|
|Next bigger number with the same digits|kata_next_bigger_number_same_digits.py|test_next_bigger_number_same_digits.py|[55983863da40caa2c900004e](https://www.codewars.com/kata/55983863da40caa2c900004e)|

View File

View File

@ -0,0 +1,28 @@
class CaesarCipher(object):
def __init__(self, shift):
self.shift = shift
self.alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def encode(self, text):
idx_alph = [
self.alphabet.index(x) if x in self.alphabet else x for x in text.upper()
]
idx_shift = [
(x + self.shift) % len(self.alphabet) if isinstance(x, (int)) else x
for x in idx_alph
]
return "".join(
[self.alphabet[x] if isinstance(x, (int)) else x for x in idx_shift]
)
def decode(self, text):
idx_alph = [
self.alphabet.index(x) if x in self.alphabet else x for x in text.upper()
]
idx_shift = [
(x - self.shift) % len(self.alphabet) if isinstance(x, (int)) else x
for x in idx_alph
]
return "".join(
[self.alphabet[x] if isinstance(x, (int)) else x for x in idx_shift]
)

View File

@ -0,0 +1,31 @@
def next_bigger(n):
# get number as digits in list
digits = [int(x) for x in list(str(n))]
# find index of pivot. return -1 if there is no pivot, meaning number is alreadig biggest
pivot = -1
for i in range(1, len(digits)):
if digits[-i] > digits[-i - 1]:
pivot = -i - 1
break
if pivot == -1:
return -1
# find the smallest digit to the right that is bigger than the pivot
right = digits[pivot + 1 :]
swap = right.index(min([x for x in right if x > digits[pivot]]))
# swap pivot with found digit
digits[pivot], digits[len(digits) - len(right) + swap] = (
right[swap],
digits[pivot],
)
# sort right side of new swapped pivot and replace it at the end
right = digits[pivot + 1 :]
right.sort()
digits[pivot + 1 :] = right
# return number
return int("".join([str(x) for x in digits]))

View File

@ -0,0 +1,7 @@
class Ship:
def __init__(self, draft, crew):
self.draft = draft
self.crew = crew
def is_worth_it(self):
return self.draft - self.crew * 1.5 > 20

View File

@ -0,0 +1,46 @@
class PaginationHelper:
# The constructor takes in an array of items and an integer indicating
# how many items fit within a single page
def __init__(self, collection, items_per_page):
self.collection = collection
self.items_per_page = items_per_page
# returns the number of items within the entire collection
def item_count(self):
return len(self.collection)
# returns the number of pages
def page_count(self):
return int(len(self.collection) / self.items_per_page) + (
len(self.collection) % self.items_per_page > 0
)
# returns the number of items on the given page. page_index is zero based
# this method should return -1 for page_index values that are out of range
def page_item_count(self, page_index):
if page_index < 0 or self.page_count() - 1 < page_index:
return -1
if page_index == 0:
return len(self.collection[: self.items_per_page])
return len(
self.collection[
self.items_per_page * page_index : self.items_per_page * page_index
+ self.items_per_page
]
)
# determines what page an item at the given index is on. Zero based indexes.
# this method should return -1 for item_index values that are out of range
def page_index(self, item_index):
try:
self.collection[item_index]
if item_index < 0:
raise IndexError
except IndexError:
return -1
return item_index // self.items_per_page

View File

@ -0,0 +1,13 @@
class Lamp:
def __init__(self, color: str):
self.color = color
self.on = False
def toggle_switch(self):
self.on = not self.on
def state(self):
if self.on:
return "The lamp is on."
return "The lamp is off."

View File

View File

View File

@ -0,0 +1,47 @@
class VersionManager:
def __init__(self, version=None):
if not version:
version = "0.0.1"
parts = version.split(".")[:3]
if not all(p.isdecimal() for p in parts):
raise ValueError("Error occured while parsing version!")
nums = [int(p) for p in parts]
while len(nums) < 3:
nums.append(0)
self.major_v, self.minor_v, self.patch_v = nums
self.history = []
def _save(self):
self.history.append((self.major_v, self.minor_v, self.patch_v))
def major(self):
self._save()
self.major_v += 1
self.minor_v = 0
self.patch_v = 0
return self
def minor(self):
self._save()
self.minor_v += 1
self.patch_v = 0
return self
def patch(self):
self._save()
self.patch_v += 1
return self
def rollback(self):
if not self.history:
raise Exception("Cannot rollback!")
self.major_v, self.minor_v, self.patch_v = self.history.pop()
return self
def release(self):
return f"{self.major_v}.{self.minor_v}.{self.patch_v}"

View File

@ -0,0 +1,40 @@
class VigenereCipher(object):
def __init__(self, key, alphabet):
self.key = key
self.alphabet = alphabet
def encode(self, text):
encoded = []
idx_key = 0
for char in text:
if char in self.alphabet:
text_pos = self.alphabet.index(char)
key_char = self.key[idx_key % len(self.key)]
key_pos = self.alphabet.index(key_char)
pos = (text_pos + key_pos) % len(self.alphabet)
encoded.append(self.alphabet[pos])
else:
encoded.append(char)
idx_key += 1
return "".join(encoded)
def decode(self, text):
decoded = []
idx_key = 0
for char in text:
if char in self.alphabet:
text_pos = self.alphabet.index(char)
key_char = self.key[idx_key % len(self.key)]
key_pos = self.alphabet.index(key_char)
pos = (text_pos - key_pos) % len(self.alphabet)
decoded.append(self.alphabet[pos])
else:
decoded.append(char)
idx_key += 1
return "".join(decoded)

View File

@ -0,0 +1,15 @@
class Student:
def __init__(self, name, fives, tens, twenties):
self.name = name
self.fives = fives
self.tens = tens
self.twenties = twenties
def most_money(students):
student_names = [x.name for x in students]
student_money = [x.fives * 5 + x.tens * 10 + x.twenties * 20 for x in students]
if len(set(student_money)) == 1 and len(student_money) > 1:
return "all"
return max(list(zip(student_names, student_money)), key=lambda x: x[1])[0]

View File

@ -0,0 +1,32 @@
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def speak(slef) -> str:
return "..."
def chorus(self, n: int) -> str:
# Wiederhole den Laut n-mal als eine Zeile"
if n <= 0:
raise ValueError("n muss positiv sein")
return " ".join(self.speak() for _ in range(n))
class Dog(Animal):
def speak(self) -> str:
return "wuff"
class Cat(Animal):
def speak(self) -> str:
return "miau"
class Cow(Animal):
def speak(self) -> str:
return "muh"
cow = Cow()
print(cow.chorus(3))

View File

@ -1,41 +1,88 @@
class Hund: from abc import ABC, abstractmethod
class Hund(ABC):
anzahl_hunde = 0 anzahl_hunde = 0
def __init__(self, name: str, rasse: str, alter: int, gewicht: float): def __init__(self, name: str, alter: int, gewicht: float, bellgeraeusch: str):
self.name = name self.name = name
self.rasse = rasse
self.alter = alter self.alter = alter
self.gewicht = gewicht self.gewicht = gewicht
self.bellgeraeusch = bellgeraeusch
Hund.anzahl_hunde += 1 Hund.anzahl_hunde += 1
def __repr__(self): def __repr__(self) -> str:
return f"Hund(name={self.name!r}, rasse={self.rasse}, alter={self.alter}, gewicht={self.gewicht}" return f"Hund(name={self.name!r}, rasse={self.__class__.__name__}, alter={self.alter}, gewicht={self.gewicht}"
def __str__(self): def __str__(self) -> str:
return f"{self.name} ist ein {self.alter}-jähriger {self.rasse}" return f"{self.name} ist ein {self.alter}-jähriger {self.__class__.__name__}"
def bellen(self, n=1) -> int: @abstractmethod
print(n * "Woof! ") def bellen(self, n: int = 1) -> None:
print(" ".join([self.bellgeraeusch] * n))
def geburtstag(self): def geburtstag(self) -> None:
self.alter += 1 self.alter += 1
print( print(
f"Alles Gute zum Geburtstag, {self.name}! Du bist jetzt {self.alter} Jahre alt." f"Alles Gute zum Geburtstag, {self.name}! Du bist jetzt {self.alter} Jahre alt."
) )
def ist_welpe(self): def ist_welpe(self) -> None:
if self.alter < 2: if self.alter < 2:
print(f"{self.name} ist ein {self.alter}-jähriger Welpe") print(f"{self.name} ist ein {self.alter}-jähriger Welpe")
else: else:
print(f"{self.name} ist ein {self.alter}-jähriger erwachsener Hund") print(f"{self.name} ist ein {self.alter}-jähriger erwachsener Hund")
def __lt__(self, other): # less than: self < other
return self.alter < other.alter
hund1 = Hund(name="Bello", rasse="Pudel", alter=99, gewicht=357) def __le__(self, other): # less equal: self <= other
hund2 = Hund(name="Dewy", rasse="Labrador", alter=-6, gewicht=1) return self.alter <= other.alter
def __gt__(self, other): # greater than: self > other
return self.alter > other.alter
def __ge__(self, other): # greater equal: self >= other
return self.alter >= other.alter
def __eq__(self, other): # equal: self == other
return self.alter == other.alter
class Pudel(Hund):
def __init__(self, name, alter, gewicht):
super().__init__(name, alter, gewicht, "wau")
def bellen(self, n=1):
super().bellen(n)
class Labrador(Hund):
def __init__(self, name, alter, gewicht):
super().__init__(name, alter, gewicht, "wuff")
def bellen(self, n=1):
super().bellen(n)
class Bulldog(Hund):
def __init__(self, name, alter, gewicht):
super().__init__(name, alter, gewicht, "woff")
def bellen(self, n=1):
super().bellen(n)
hund1 = Labrador(name="Bello", alter=33, gewicht=27)
hund2 = Pudel(name="Dewy", alter=6, gewicht=1)
hund3 = Bulldog(name="Stone", alter=15, gewicht=1000)
print(repr(hund1)) print(repr(hund1))
print(hund2) print(hund2)
hund2.bellen(3) hund2.bellen(3)
hund1.bellen(2)
hund1.geburtstag() hund1.geburtstag()
hund2.ist_welpe() hund2.ist_welpe()
hund1.ist_welpe() hund1.ist_welpe()
hund3.bellen(4)
print(hund3 > hund2)

View File

@ -0,0 +1,17 @@
class A:
pass
class B(A):
pass
class C(A):
pass
class D(B, C):
pass
print(D.mro())

View File

@ -0,0 +1,21 @@
class Dog:
def speak(self) -> str:
return "wuff"
class Cat:
def speak(self) -> str:
return "miau"
class Robot:
def speak(self) -> str:
return "bip bup"
def chorus(animals) -> list:
for a in animals:
print(a.speak())
chorus([Dog(), Cat(), Robot()])

View File

@ -0,0 +1,27 @@
from abc import ABC, abstractmethod
class Storage(ABC):
@abstractmethod
def save(self, key: str, value: str) -> None:
pass
@abstractmethod
def load(self, key: str) -> str:
pass
class MemoryStorage(Storage):
def __init__(self) -> None:
self.storage = {}
def save(self, key: str, value: str) -> None:
self.storage[key] = value
def load(self, key):
return self.storage[key]
s = MemoryStorage()
s.save("randomkey", "My Value")
print(s.load("randomkey"))

View File

View File

@ -0,0 +1,8 @@
from src.codewars.kata_ceasar_cipher_helper import CaesarCipher
def test_cipher_helper():
c = CaesarCipher(5)
assert c.encode("Codewars") == "HTIJBFWX"
assert c.decode("HTIJBFWX") == "CODEWARS"

View File

@ -0,0 +1,15 @@
from src.codewars.kata_next_bigger_number_same_digits import next_bigger
def test_next_bigger():
assert next_bigger(12) == 21
assert next_bigger(21) == -1
assert next_bigger(513) == 531
assert next_bigger(2017) == 2071
assert next_bigger(414) == 441
assert next_bigger(144) == 414
assert next_bigger(1234567890) == 1234567908
assert next_bigger(59884848459853) == 59884848483559
assert next_bigger(7600201336) == 7600201363
assert next_bigger(5113455566888) == 5113455568688
assert next_bigger(4769560370633) == 4769560373036

View File

@ -0,0 +1,15 @@
from src.codewars.kata_object_oriented_piracy import Ship
def test_piracy():
empty_ship = Ship(0, 0)
assert not empty_ship.is_worth_it()
boat = Ship(15, 20)
assert not boat.is_worth_it()
worthy_ship = Ship(100, 20)
assert worthy_ship.is_worth_it()
big_boat = Ship(35, 20)
assert not big_boat.is_worth_it()

View File

@ -0,0 +1,27 @@
from src.codewars.kata_pagination_helper import PaginationHelper
def test_pagination():
collection = ["a", "b", "c", "d", "e", "f"]
helper = PaginationHelper(collection, 4)
assert helper.page_count() == 2
assert helper.item_count() == 6
assert helper.page_item_count(0) == 4
assert helper.page_item_count(1) == 2
assert helper.page_item_count(2) == -1
assert helper.page_index(5) == 1
assert helper.page_index(2) == 0
assert helper.page_index(20) == -1
assert helper.page_index(-10) == -1
empty = PaginationHelper([], 10)
assert empty.item_count() == 0
assert empty.page_count() == 0
assert empty.page_index(0) == -1
assert empty.page_index(1) == -1
assert empty.page_index(-1) == -1
assert empty.page_item_count(0) == -1
assert empty.page_item_count(1) == -1
assert empty.page_item_count(-1) == -1

View File

@ -0,0 +1,13 @@
from src.codewars.kata_the_lamp import Lamp
def test_lamp():
my_lamp = Lamp("Blue")
assert my_lamp.color == "Blue"
assert not my_lamp.on
assert my_lamp.state() == "The lamp is off."
my_lamp.toggle_switch()
assert my_lamp.state() == "The lamp is on."
my_lamp.toggle_switch()
assert my_lamp.state() == "The lamp is off."

View File

View File

View File

@ -0,0 +1,7 @@
from src.codewars.kata_version_mamanger import VersionManager
def test_lamp():
v = VersionManager("1.1.1")
assert v.release() == "1.1.1"

View File

@ -0,0 +1,16 @@
from src.codewars.kata_vigenere_cipher_helper import VigenereCipher
def test_cipher_helper():
abc = "abcdefghijklmnopqrstuvwxyz"
key = "password"
c = VigenereCipher(key, abc)
assert c.encode("codewars") == "rovwsoiv"
assert c.decode("rovwsoiv") == "codewars"
assert c.encode("waffles") == "laxxhsj"
assert c.decode("laxxhsj") == "waffles"
assert c.encode("CODEWARS") == "CODEWARS"
assert c.decode("CODEWARS") == "CODEWARS"

View File

@ -0,0 +1,15 @@
from src.codewars.kata_who_the_most_money import Student, most_money
def test_most_money():
phil = Student("Phil", 2, 2, 1)
cam = Student("Cameron", 2, 2, 0)
geoff = Student("Geoff", 0, 3, 0)
assert most_money([cam, geoff, phil]) == "Phil"
phil = Student("Phil", 2, 2, 2)
cam = Student("Cameron", 2, 2, 2)
geoff = Student("Geoff", 2, 2, 2)
assert most_money([cam, geoff, phil]) == "all"