Compare commits

..

17 Commits

Author SHA1 Message Date
060362ec09 feat: json exercise 2026-03-19 13:28:20 +01:00
e28a2bdc67 feat: pathlib exercise 2026-03-19 11:58:22 +01:00
a455b46b72 refractor: added comment and removed infinite loop guardrail 2026-03-17 18:07:52 +01:00
9ff7d9161e feat: kata snail now has function, which rearanges list based on kata rules. Pre test commit, may still be incorrect 2026-03-17 18:03:24 +01:00
11f8bf5394 feat: list created, where endresult will be saved 2026-03-16 18:19:01 +01:00
f722614590 feat: initial commit for kata 'Snail'. test: initial commit for kata 'Snail' 2026-03-16 18:09:21 +01:00
fdcde7a855 chore: Kata description for Snail added to README 2026-03-16 17:50:23 +01:00
e867f69ad9 build: changed name of test/codewars to test/test_codewars 2026-03-13 17:49:29 +01:00
87eea6433e Merge branch 'tutorial' 2026-03-13 17:44:57 +01:00
60cf2dd6c6 feat: module and import exercises 2026-03-13 17:44:37 +01:00
03427a784f Merge pull request 'task2' (#1) from task2 into main
Reviewed-on: #1

Nein, von der Struktur sieht das sehr schön aus. Du hast sogar tests (z.B. für piracy-OOP) eingefügt, das ist natürlich sehr vorbildlich. Weil Du dort den Order tests/codewars/test___ nennst, bin ich nicht ganz sicher, ob dieser in jedem falle automatisch als Testordner erkannt wird (wegen dem codewars). Wenn Du viele Tests in einem Order tests/ hast und alle Files mit test_ beginnen, kannst Du alle zusammen automatisch ausführen mit pytest in der Konsole (oder auch einzeln unter Angabe des exakten Files).
2026-03-13 10:24:15 +01:00
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
51964de52c feat: tutorial analysis for modules and imports 2026-03-12 12:30:45 +01:00
f3d6554b1b build: matplotlib and pandas added to requirements 2026-03-12 12:04:30 +01:00
ce9a4029b7 refractor: removed print statement, that was ment for development 2026-03-11 23:57:28 +01:00
99e6d45790 Merge branch 'task2' of https://gitea.fhgr.ch/zimmersandro/ppe2 into task2 2026-03-06 18:36:52 +01:00
35f4b12c34 feat: finished kata building_blocks, thinkful_quarks and thinkful_vectors. test: finished test cases for katas 2026-03-06 18:32:13 +01:00
45 changed files with 640 additions and 4 deletions

View File

@ -29,3 +29,4 @@ Repository for CDS-2020 Programming and Promt Engineering II
|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)|
|Snail|kata_snail.py|test_snail.py|[521c2db8ddc89b9b7a0000c1](https://www.codewars.com/kata/521c2db8ddc89b9b7a0000c1)|

View File

@ -1,4 +1,6 @@
ruff == 0.15.1
black == 26.1.0
pytest == 9.0.2
pre-commit == 4.5.1
pre-commit == 4.5.1
matplotlib == 3.10.8
pandas == 3.0.1

View File

@ -0,0 +1,24 @@
class Block:
def __init__(self, dimensions: list):
self.width = dimensions[0]
self.length = dimensions[1]
self.height = dimensions[2]
def get_width(self):
return self.width
def get_length(self):
return self.length
def get_height(self):
return self.height
def get_volume(self):
return self.width * self.length * self.height
def get_surface_area(self):
return (
2 * self.length * self.height
+ 2 * self.width * self.height
+ 2 * self.width * self.length
)

View File

@ -29,6 +29,3 @@ def next_bigger(n):
# return number
return int("".join([str(x) for x in digits]))
print(next_bigger(5113455566888))

View File

@ -0,0 +1,86 @@
def snail(snail_map):
# first list in array is always first. So add it to new list snail and pop it from snail_map
snail = [x for x in snail_map[0]]
snail_map.pop(0)
# transpone list and append first list to snail. Then pop firt item of snail_map. Loop till snail_map is empty
while len(snail_map) > 0:
snail_map = [list(reversed(x)) for x in snail_map]
snail_map = [list(row) for row in zip(*snail_map)]
[snail.append(x) for x in snail_map[0]]
snail_map.pop(0)
return snail
array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
array = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]
print(snail(array))
"""
Konzept:
Ziel: 1 2 3 6 9 8 7 4 5
1 2 3
4 5 6
7 8 9
1 2 3
4 5 6
7 8 9
6 9
5 8
4 7
1 2 3 6 9
5 8
4 7
8 7
5 4
1 2 3 6 9 8 7
5 4
4
5
1 2 3 6 9 8 7 4
5
1 2 3 6 9 8 7 4 5
Ziel: 1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
8 12 16
7 11 15
6 10 14
5 9 13
1 2 3 4 8 12 16
7 11 15
6 10 14
5 9 13
...
"""

View File

@ -0,0 +1,8 @@
class Quark(object):
def __init__(self, color, flavor):
self.color = color
self.flavor = flavor
self.baryon_number = 1 / 3
def interact(self, other) -> None:
self.color, other.color = other.color, self.color

View File

@ -0,0 +1,7 @@
class Vector(object):
def __init__(self, x: int, y: int):
self.x = x
self.y = y
def add(self, other):
return Vector(self.x + other.x, self.y + other.y)

View File

@ -0,0 +1,6 @@
from pathlib import Path
base_dir = Path("data")
file_path = base_dir / "raw" / "processed.json"
file_path.mkdir(parents=True, exist_ok=True)

View File

@ -0,0 +1,8 @@
from analysis.io import read_csv
from analysis.metrics import revenue
if __name__ == "__main__":
df = read_csv("analysis/csv/sales.csv")
print(df)
df = revenue(df)
print(df)

View File

@ -0,0 +1,11 @@
day,product,quantity,unit_price,region
Mon,Notebook,3,899.0,West
Mon,Mouse,12,25.0,West
Tue,Notebook,2,899.0,Ost
Tue,Keyboard,5,70.0,Ost
Wed,Monitor,4,220.0,West
Wed,Mouse,10,25.0,Nord
Thu,Keyboard,6,70.0,Sued
Thu,Monitor,3,220.0,Ost
Fri,Notebook,1,899.0,Nord
Fri,Mouse,15,25.0,Sued
1 day product quantity unit_price region
2 Mon Notebook 3 899.0 West
3 Mon Mouse 12 25.0 West
4 Tue Notebook 2 899.0 Ost
5 Tue Keyboard 5 70.0 Ost
6 Wed Monitor 4 220.0 West
7 Wed Mouse 10 25.0 Nord
8 Thu Keyboard 6 70.0 Sued
9 Thu Monitor 3 220.0 Ost
10 Fri Notebook 1 899.0 Nord
11 Fri Mouse 15 25.0 Sued

View File

@ -0,0 +1,5 @@
import pandas as pd
def read_csv(file: str) -> pd.DataFrame:
return pd.read_csv(file)

View File

@ -0,0 +1,6 @@
import pandas as pd
def revenue(df: pd.DataFrame) -> pd.DataFrame:
revenue = df["quantity"] * df["unit_price"]
return revenue.groupby("day").sum()

View File

@ -0,0 +1,33 @@
# Ziel dieses Skripts:
#
# 1. Das Produkt von 6 * 7 berechnen → Erwartet: 42.0
# 2. Die Kreisfläche für Radius 5 berechnen → Erwartet: ~78.54
# 3. Den genauen Wert von PI ausgeben → Erwartet: 3.141592653589793
#
# ----------------------------------------------------------------------
# AUFGABE: Das Skript liefert falsche Ergebnisse. Finde den Fehler und
# korrigiere die Import-Anweisungen ohne den restlichen Code
# zu verändern!
# ----------------------------------------------------------------------
# from src.mathematik import berechne, PI # (1) Import aus mathematik
# from src.geometrie import berechne, PI # (2) Import aus geometrie
import src.geometrie as geo
import src.mathematik as mathe
def main():
# --- Aufgabe 1: Produkt berechnen (nutzt mathematik.berechne) ---
produkt = mathe.berechne(6, 7) # Erwartet: 42.0 — bekommt aber einen Fehler!
print(f"6 × 7 = {produkt}")
# --- Aufgabe 2: Kreisfläche (nutzt geometrie.berechne) ---
flaeche = geo.berechne(5) # Erwartet: ~78.54
print(f"Kreisfläche (r=5): {flaeche:.4f}")
# --- Aufgabe 3: PI-Wert ---
print(f"PI = {mathe.PI}") # Erwartet: 3.141592653589793
if __name__ == "__main__":
main()

View File

@ -0,0 +1,14 @@
# geometrie.py
# Modul für geometrische Berechnungen (Kreisflächen, Umfang usw.)
PI = 3.14 # Vereinfachter Wert (nur 2 Nachkommastellen!)
def berechne(radius: float) -> float:
"""Berechnet die Fläche eines Kreises: A = PI * r²"""
return PI * radius**2
def umfang(radius: float) -> float:
"""Berechnet den Umfang eines Kreises: U = 2 * PI * r"""
return 2 * PI * radius

View File

@ -0,0 +1,14 @@
# mathematik.py
# Modul für allgemeine mathematische Berechnungen
PI = 3.141592653589793 # Hochpräziser Wert
def berechne(a: float, b: float) -> float:
"""Berechnet das Produkt zweier Zahlen."""
return a * b
def potenz(basis: float, exponent: int) -> float:
"""Berechnet basis hoch exponent."""
return basis**exponent

View File

@ -0,0 +1,59 @@
# Ziel dieses Skripts:
#
# Testergebnisse einer Klasse auswerten und formatiert ausgeben.
#
# Gegeben: Punkte von 5 Studierenden (von max. 100 Punkten)
# Erwartet:
# Mittelwert → 73.5 (kaufm. gerundet → 74 → "Gut")
# Max. Punkte → 100 (aus statistik.MAX_WERT)
#
# ----------------------------------------------------------------------
# AUFGABE: Das Skript gibt falsche Werte aus. Es gibt keine Fehlermeldung
# vom Interpreter. Finde heraus, warum die Ergebnisse falsch sind
# und korrigiere die Import-Anweisungen!
# ----------------------------------------------------------------------
from src.statistik import (
runde,
mittelwert,
bewerte,
MAX_WERT,
) # importiert: runde, mittelwert, bewerte, MAX_WERT, MIN_WERT
from src.formatierung import (
trennlinie,
) # importiert: runde, als_prozent, trennlinie, MAX_WERT, MIN_WERT
PUNKTE = [92, 85, 61, 48, 82]
def auswertung():
print(trennlinie("="))
print(" TESTERGEBNISSE")
print(trennlinie("="))
# --- Mittelwert berechnen und benoten ---
mw = mittelwert(PUNKTE)
mw_gerundet = runde(mw) # Soll kaufm. auf int runden → Erwartet: 74
note = bewerte(mw)
print(f" Mittelwert : {mw}")
print(f" Gerundet : {mw_gerundet} ← Erwartet: 74 (int)")
print(f" Durchschnittsnote: {note}")
print(trennlinie())
# --- Maximale Punktzahl aus dem Modul ---
print(f" Max. Punkte : {MAX_WERT} ← Erwartet: 100")
print(trennlinie())
# --- Einzelne Ergebnisse ---
print(" Einzelergebnisse:")
for p in PUNKTE:
print(f" {p:>3} Punkte → {bewerte(p)}")
print(trennlinie("="))
if __name__ == "__main__":
auswertung()

View File

@ -0,0 +1,21 @@
# formatierung.py
# Modul für Ausgabe-Formatierung und Darstellung
MAX_WERT = 255 # Maximaler RGB-Farbwert (0255)
MIN_WERT = 0 # Minimaler RGB-Farbwert
def runde(wert: float, stellen: int = 2) -> float:
"""Rundet auf 'stellen' Nachkommastellen (für Anzeige-Formatierung)."""
faktor = 10**stellen
return int(wert * faktor + 0.5) / faktor
def als_prozent(wert: float, gesamt: float) -> str:
"""Gibt einen Wert als formatierten Prozentstring zurück."""
return f"{runde(wert / gesamt * 100)} %"
def trennlinie(zeichen: str = "-", laenge: int = 40) -> str:
"""Erzeugt eine Trennlinie für die Konsolenausgabe."""
return zeichen * laenge

View File

@ -0,0 +1,30 @@
# statistik.py
# Modul für statistische Berechnungen
MAX_WERT = 100 # Maximale Punktzahl in einem Test (0100)
MIN_WERT = 0 # Minimale Punktzahl
def runde(wert: float) -> int:
"""Rundet kaufmännisch auf ganze Zahlen (für Testergebnisse)."""
return int(wert + 0.5)
def mittelwert(werte: list[float]) -> float:
"""Berechnet den arithmetischen Mittelwert einer Liste."""
return sum(werte) / len(werte)
def bewerte(punkte: float) -> str:
"""Gibt eine Note zurück basierend auf Punktzahl (0100)."""
p = runde(punkte)
if p >= 90:
return "Sehr gut"
elif p >= 75:
return "Gut"
elif p >= 60:
return "Befriedigend"
elif p >= 45:
return "Ausreichend"
else:
return "Ungenügend"

View File

@ -0,0 +1,27 @@
# random.py
#
# Dieses Modul wurde angelegt, um eigene Hilfsfunktionen für
# "Zufallsentscheidungen" in der Lotterie-Logik bereitzustellen.
#
# Es definiert einige der gleichen Funktionen wie das Standardmodul
# aber mit vereinfachter (fehlerhafter) Implementierung.
def randint(a: int, b: int) -> int:
"""Gibt eine 'zufällige' Ganzzahl zwischen a und b zurück."""
return a # ← gibt IMMER den kleinsten Wert zurück!
def shuffle(lst: list) -> None:
"""Mischt eine Liste in-place."""
pass # ← tut gar nichts!
def sample(population: list, k: int) -> list:
"""Gibt k zufällige Elemente aus population zurück."""
return list(population)[:k] # ← gibt IMMER die ersten k Elemente zurück!
def seed(a=None):
"""Setzt den Zufallsgenerator-Seed."""
pass # ← keine Wirkung

View File

@ -0,0 +1,51 @@
# Lotterie-Simulation: Zieht 6 aus 45 Zahlen, dazu eine Zusatzzahl.
#
# Wiederholt die Ziehung 5× und gibt die Ergebnisse aus.
# Anschließend wird die Gewinnerliste zufällig gemischt.
#
# Erwartetes Verhalten:
# • Jede Ziehung liefert 6 VERSCHIEDENE, ZUFÄLLIGE Zahlen aus 145
# • Wiederholte Aufrufe liefern UNTERSCHIEDLICHE Ergebnisse
# • Die Teilnehmerliste ist nach dem Mischen in ZUFÄLLIGER Reihenfolge
#
# ----------------------------------------------------------------------
# AUFGABE: Das Programm läuft ohne Fehlermeldung, aber die Ergebnisse
# sind offensichtlich nicht zufällig. Finde die Ursache und
# behebe den Fehler ohne ziehung.py oder statistik.py zu ändern!
#
# REMARK: Möglicherweise ist das Problem sogar abhängig von der verwendeten
# IDE... Lasst das main.py mal aus eurer IDE laufen sowie aus dem
# Terminal. Sind die Resultate gleich?
# ----------------------------------------------------------------------
from ziehung import ziehe_zahlen, ziehe_zusatzzahl
from statistik import simuliere_ziehungen, mische_teilnehmer
TEILNEHMER = ["Alice", "Bob", "Carol", "Dave", "Eve"]
def main():
print("=" * 45)
print(" LOTTO-SIMULATION (6 aus 45)")
print("=" * 45)
print("\n--- 5 unabhängige Ziehungen ---")
for i, ziehung in enumerate(simuliere_ziehungen(5), 1):
print(f" Ziehung {i}: {ziehung}")
print("\n--- Einzelziehung mit Zusatzzahl ---")
haupt = ziehe_zahlen()
zusatz = ziehe_zusatzzahl(haupt)
print(f" Hauptzahlen : {haupt}")
print(f" Zusatzzahl : {zusatz}")
print("\n--- Gewinnerliste (zufällig gemischt) ---")
gemischt = mische_teilnehmer(TEILNEHMER)
for rang, name in enumerate(gemischt, 1):
print(f" Rang {rang}: {name}")
print("=" * 45)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,20 @@
# Wertet mehrere Lottoziehungen statistisch aus
import custom_random
from ziehung import ziehe_zahlen
def simuliere_ziehungen(anzahl: int = 10) -> list[list[int]]:
"""Führt 'anzahl' unabhängige Lottoziehungen durch."""
ergebnisse = []
for _ in range(anzahl):
zahlen = ziehe_zahlen()
ergebnisse.append(zahlen)
return ergebnisse
def mische_teilnehmer(teilnehmer: list[str]) -> list[str]:
"""Mischt die Teilnehmerliste zufällig (z. B. für Gewinner-Reihenfolge)."""
kopie = teilnehmer[:]
custom_random.shuffle(kopie)
return kopie

View File

@ -0,0 +1,19 @@
# lotterie/ziehung.py
# Modul für die eigentliche Lottoziehung
import custom_random
ZAHLEN_POOL = list(range(1, 46)) # Zahlen 145
def ziehe_zahlen(anzahl: int = 6) -> list[int]:
"""Zieht 'anzahl' verschiedene Lottozahlen aus dem Pool."""
gezogen = custom_random.sample(ZAHLEN_POOL, anzahl)
gezogen.sort()
return gezogen
def ziehe_zusatzzahl(ausgeschlossen: list[int]) -> int:
"""Zieht eine Zusatzzahl, die nicht in der Hauptziehung vorkommt."""
pool = [z for z in ZAHLEN_POOL if z not in ausgeschlossen]
return custom_random.randint(1, len(pool) - 1) # ← Index in pool, dann Lookup

View File

@ -0,0 +1,53 @@
# Schulverwaltungs-Simulation:
# • Drei Schüler werden angelegt (mit Noten in zwei Kursen)
# • Zwei Kurse werden erstellt, Schüler werden eingeschrieben
# • Notenspiegel je Schüler und Kursbericht je Kurs wird ausgegeben
#
# ----------------------------------------------------------------------
# AUFGABE: Das Programm lässt sich gar nicht erst starten es gibt
# sofort einen ImportError.
#
# 1. Lies die Fehlermeldung sorgfältig und zeichne den
# Importgraphen auf: Welches Modul importiert welches?
#
# 2. Versuche durch eine geeignete Gegenmassnahme den Fehler zu
# beheben.
# ----------------------------------------------------------------------
from src.kurs import Kurs
from src.schueler import Schueler
def main():
# --- Schüler anlegen ---
anna = Schueler("Anna Meier", {"Mathematik": 2.5, "Deutsch": 3.0})
ben = Schueler("Ben Keller", {"Mathematik": 5.0, "Deutsch": 2.0})
clara = Schueler("Clara Huber", {"Mathematik": 3.5, "Deutsch": 4.5})
# --- Kurse anlegen und Schüler einschreiben ---
mathe = Kurs("Mathematik")
deutsch = Kurs("Deutsch")
for s in [anna, ben, clara]:
mathe.einschreiben(s)
deutsch.einschreiben(s)
# --- Ausgabe Notenspiegel ---
print("=" * 45)
print(" NOTENSPIEGEL")
print("=" * 45)
for s in [anna, ben, clara]:
print(s.notenspiegel())
print()
# --- Ausgabe Kursberichte ---
print("=" * 45)
print(" KURSBERICHTE")
print("=" * 45)
print(mathe.kursbericht())
print(deutsch.kursbericht())
print("=" * 45)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,16 @@
# ---------------------------------------------------------------
# Gemeinsam genutzte Hilfsfunktion wird auch in schueler.py
# über den Import von oben verwendet.
# ---------------------------------------------------------------
def ist_bestanden(note: float) -> bool:
"""Gibt True zurück, wenn die Note ≤ 4.0 (bestanden) ist."""
return note <= 4.0
def berechne_klassendurchschnitt(noten: list[float]) -> float:
"""Berechnet den Notendurchschnitt einer Gruppe."""
if not noten:
return 0.0
return round(sum(noten) / len(noten), 2)

View File

@ -0,0 +1,35 @@
# schulverwaltung/kurs.py
#
# Verwaltet Kurse und eingeschriebene Schüler.
# Benötigt die Schueler-Klasse aus schueler.py für die Einschreibung
# und Notenauswertung.
from notenrechner import ist_bestanden, berechne_klassendurchschnitt
from .schueler import Schueler
class Kurs:
def __init__(self, name: str):
self.name = name
self.schueler: list[Schueler] = []
def einschreiben(self, schueler: Schueler) -> None:
"""Schreibt einen Schüler in diesen Kurs ein."""
self.schueler.append(schueler)
def kursbericht(self) -> str:
"""Gibt eine Übersicht über alle Schüler und den Kursdurchschnitt aus."""
zeilen = [f"\n Kurs: {self.name} ({len(self.schueler)} Schüler)"]
noten_im_kurs = []
for s in self.schueler:
note = s.noten.get(self.name)
if note is not None:
status = "" if ist_bestanden(note) else ""
zeilen.append(f" {status} {s.name:<20} {note:.1f}")
noten_im_kurs.append(note)
if noten_im_kurs:
schnitt = berechne_klassendurchschnitt(noten_im_kurs)
zeilen.append(f" → Klassendurchschnitt: {schnitt:.2f}")
return "\n".join(zeilen)

View File

@ -0,0 +1,28 @@
# Verwaltet Schüler-Daten und prüft den Abschlussstatus.
# Benötigt ist_bestanden() aus kurs.py, um festzustellen ob
# ein Schüler alle Kurse bestanden hat.
from notenrechner import ist_bestanden
class Schueler:
def __init__(self, name: str, noten: dict[str, float]):
"""
name : Vollständiger Name des Schülers
noten : {Kursname: Note} z. B. {'Mathematik': 4.5, 'Deutsch': 3.0}
"""
self.name = name
self.noten = noten
def kann_abschliessen(self) -> bool:
"""Gibt True zurück, wenn alle Kursnoten bestanden sind (Note ≤ 4.0)."""
return all(ist_bestanden(note) for note in self.noten.values())
def notenspiegel(self) -> str:
"""Gibt eine formatierte Übersicht aller Noten zurück."""
zeilen = [f" Schüler: {self.name}"]
for kurs, note in self.noten.items():
status = "" if ist_bestanden(note) else ""
zeilen.append(f" {status} {kurs:<18} Note: {note:.1f}")
zeilen.append(f" → Abschluss möglich: {self.kann_abschliessen()}")
return "\n".join(zeilen)

View File

@ -0,0 +1,17 @@
from src.codewars.kata_building_blocks import Block
def test_block():
b1 = Block([2, 2, 2])
b2 = Block([41, 87, 67])
assert b1.get_width() == 2
assert b1.get_length() == 2
assert b1.get_height() == 2
assert b1.get_volume() == 8
assert b1.get_surface_area() == 24
assert b2.get_width() == 41
assert b2.get_length() == 87
assert b2.get_height() == 67
assert b2.get_volume() == 238989
assert b2.get_surface_area() == 24286

View File

@ -0,0 +1,10 @@
from src.codewars.kata_snail import snail
def test_snail():
array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
assert snail(array) == [1, 2, 3, 6, 9, 8, 7, 4, 5]
array = [[1, 2, 3], [8, 9, 4], [7, 6, 5]]
assert snail(array) == [1, 2, 3, 4, 5, 6, 7, 8, 9]

View File

@ -0,0 +1,15 @@
from src.codewars.kata_thinkful_quarks import Quark
def test_quark():
q1 = Quark("red", "up")
q2 = Quark("blue", "strange")
assert q1.color == "red"
assert q2.flavor == "strange"
assert q2.baryon_number == 1 / 3
q1.interact(q2)
assert q1.color == "blue"
assert q2.color == "red"

View File

@ -0,0 +1,13 @@
from src.codewars.kata_thinkful_vectors import Vector
def test_vector():
v1 = Vector(3, 4)
v2 = Vector(1, 2)
assert v1.x == 3
assert v2.y == 2
assert hasattr(v1, "add")
assert isinstance(v1.add(v2), Vector)
assert (v1.add(v2)).x == 4
assert (v1.add(v2)).y == 6