From b8286f0c1b154312433ed64c794dd9ab18833290 Mon Sep 17 00:00:00 2001 From: Irina Rueegg Date: Fri, 10 Apr 2026 15:30:28 +0200 Subject: [PATCH] master 10.04 --- requirements.txt | 1 + src/u6_tests/U6_Freitag_testing/__init__.py | 0 src/u6_tests/U6_Freitag_testing/bmi.py | 16 +++++++ .../U6_Freitag_testing/catching_exeptions.py | 29 ++++++++++++ .../U6_Freitag_testing/kata_list_filtering.py | 14 ++++++ .../U6_Freitag_testing/pandas_filter_rows.py | 37 +++++++++++++++ .../U6_Freitag_testing/vowel_count.py | 18 +++++++ src/u6_tests/pricing.py | 5 ++ tests/test_pricing.py | 8 ++++ tests/test_u6_catching_exceptions.py | 18 +++++++ tests/test_u6_kata_list_filtering.py | 47 +++++++++++++++++++ 11 files changed, 193 insertions(+) create mode 100644 src/u6_tests/U6_Freitag_testing/__init__.py create mode 100644 src/u6_tests/U6_Freitag_testing/bmi.py create mode 100644 src/u6_tests/U6_Freitag_testing/catching_exeptions.py create mode 100644 src/u6_tests/U6_Freitag_testing/kata_list_filtering.py create mode 100644 src/u6_tests/U6_Freitag_testing/pandas_filter_rows.py create mode 100644 src/u6_tests/U6_Freitag_testing/vowel_count.py create mode 100644 tests/test_u6_catching_exceptions.py create mode 100644 tests/test_u6_kata_list_filtering.py diff --git a/requirements.txt b/requirements.txt index 3cb1b9f..593feee 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,4 @@ black == 26.1.0 pytest == 9.0.2 pre-commit == 4.5.1 +pandas diff --git a/src/u6_tests/U6_Freitag_testing/__init__.py b/src/u6_tests/U6_Freitag_testing/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/u6_tests/U6_Freitag_testing/bmi.py b/src/u6_tests/U6_Freitag_testing/bmi.py new file mode 100644 index 0000000..51086c9 --- /dev/null +++ b/src/u6_tests/U6_Freitag_testing/bmi.py @@ -0,0 +1,16 @@ +# Task: Schreibt für die folgende Aufgabe einige Unit-Test. Nutzt dazu für den Happy-Path einen parametrisierten Test für +# einige valide Inputs und Outputs + + +def calculate_bmi(weight_kg: float, height_m: float) -> float: + """ + Berechnet den Body Mass Index (BMI). + BMI = Gewicht (kg) / Grösse (m)^2 + """ + if weight_kg <= 0 or height_m <= 0: + raise ValueError("Gewicht und Grösse müssen positiv sein.") + return weight_kg / (height_m**2) + + +if __name__ == "__main__": + print(calculate_bmi(weight_kg=72, height_m=1.84)) diff --git a/src/u6_tests/U6_Freitag_testing/catching_exeptions.py b/src/u6_tests/U6_Freitag_testing/catching_exeptions.py new file mode 100644 index 0000000..b040155 --- /dev/null +++ b/src/u6_tests/U6_Freitag_testing/catching_exeptions.py @@ -0,0 +1,29 @@ +# TASK: Schreibe sinnvolle Tests für die folgende Funktion +# Schreibe Tests für die korrekte Struktur des Outputs der Funktion +# Teste, ob bei Übergabe von 'falschem' Parameter data eine Exception geworfen wird + +# https://docs.python.org/3/library/exceptions.html +# Passing arguments of the wrong type (e.g. passing a list when an int is expected) should result in a TypeError, +# but passing arguments with the wrong value (e.g. a number outside expected boundaries) should result in a ValueError. + + +def double_integers(data: list[int]) -> list[int]: + """Doubles a list of given integers + + :param data: list of integers + :return: list of doubled integers + """ + + if not isinstance(data, list): + raise TypeError("data must be a list") + if not all([isinstance(i, int) for i in data]): + raise TypeError("data may contain only integers") + + return [i * 2 for i in data] + + +if __name__ == "__main__": + + data = [1, 2, 3] + result = double_integers(data) + print(result) diff --git a/src/u6_tests/U6_Freitag_testing/kata_list_filtering.py b/src/u6_tests/U6_Freitag_testing/kata_list_filtering.py new file mode 100644 index 0000000..39bf9ae --- /dev/null +++ b/src/u6_tests/U6_Freitag_testing/kata_list_filtering.py @@ -0,0 +1,14 @@ +# https://www.codewars.com/kata/53dbd5315a3c69eed20002dd +# level: 7 kyu + +# In this kata you will create a function that takes a list of non-negative integers and strings and returns a new +# list with the strings filtered out. +# +# Example +# filter_list([1,2,'a','b']) == [1,2] +# filter_list([1,'a','b',0,15]) == [1,0,15] +# filter_list([1,2,'aasf','1','123',123]) == [1,2,123] + + +def filter_list(list): + return [i for i in list if isinstance(i, int)] diff --git a/src/u6_tests/U6_Freitag_testing/pandas_filter_rows.py b/src/u6_tests/U6_Freitag_testing/pandas_filter_rows.py new file mode 100644 index 0000000..baa6a14 --- /dev/null +++ b/src/u6_tests/U6_Freitag_testing/pandas_filter_rows.py @@ -0,0 +1,37 @@ +# https://www.codewars.com/kata/5ea2baed9345eb001e8ce394 +# 7 kyu + +# Input parameters + +# dataframe: pandas.DataFrame object +# col: target column +# func: filter function + +# Task +# Your function must return a new pandas.DataFrame object with the same columns as the original input. However, +# include only the rows whose cell values in the designated column evaluate to False by func. +# +# Input DataFrame will never be empty. The target column will always be one of the dataframe columns. Filter function +# will be a valid one. Index value must remain the same. + +# REMARK: leichte Modifikation -> es wird ausgegeben, was in der Funktion definiert wurde (True) und nicht umgekehrt. + +import pandas as pd + + +def filter_dataframe(df, col, func): + if col not in df.columns: + raise ValueError(f"Column '{col}' is not present in the DataFrame.") + mask = df[col].apply(func) + return df[mask] + + +if __name__ == "__main__": + + df = pd.DataFrame( + { + "A": [1, 2, 3, 4, 5], + } + ) + + print(filter_dataframe(df, "A", lambda x: x >= 4)) diff --git a/src/u6_tests/U6_Freitag_testing/vowel_count.py b/src/u6_tests/U6_Freitag_testing/vowel_count.py new file mode 100644 index 0000000..0cbbe2b --- /dev/null +++ b/src/u6_tests/U6_Freitag_testing/vowel_count.py @@ -0,0 +1,18 @@ +# https://www.codewars.com/kata/54ff3102c1bad923760001f3 +# level: 7 kyu + +# Return the number (count) of vowels in the given string. +# We will consider a, e, i, o, u as vowels for this Kata (but not y). +# The input string will only consist of lower case letters and/or spaces. + + +def get_count(inputStr): + num_vowels = 0 + for char in inputStr: + if char in "aeiouAEIOU": + num_vowels = num_vowels + 1 + return num_vowels + + +if __name__ == "__main__": + print(get_count("Hello World")) diff --git a/src/u6_tests/pricing.py b/src/u6_tests/pricing.py index 6d3fdf7..a63acd6 100644 --- a/src/u6_tests/pricing.py +++ b/src/u6_tests/pricing.py @@ -1,4 +1,9 @@ def discount_price(price: float, percent: float) -> float: + if percent < 0: + raise ValueError("Discount percent cannot be negative") + if percent >= 100: + raise ValueError("Percent must be between 0% and 100%") + return price - price * percent / 100 diff --git a/tests/test_pricing.py b/tests/test_pricing.py index 4fb207d..6122f23 100644 --- a/tests/test_pricing.py +++ b/tests/test_pricing.py @@ -4,3 +4,11 @@ from src.u6_tests.pricing import discount_price def test_discount_price_reduces_price(): result = discount_price(100.0, 20.0) assert result == 80.0 + + +def test_discount_price_negative_discount(): + try: + discount_price(100.0, -20.0) + assert False, "Expected ValueError" + except ValueError as e: + assert str(e) == "Discount percent cannot be negative" diff --git a/tests/test_u6_catching_exceptions.py b/tests/test_u6_catching_exceptions.py new file mode 100644 index 0000000..e33108b --- /dev/null +++ b/tests/test_u6_catching_exceptions.py @@ -0,0 +1,18 @@ +from src.u6_tests.U6_Freitag_testing.catching_exeptions import double_integers +import pytest + + +def test_double_integers_with_invalid_input(): + with pytest.raises(TypeError): + double_integers("not a list") + + with pytest.raises(TypeError): + double_integers([1, 2, "not an int"]) + + +@pytest.mark.parametrize( + "input_data, expected_output", + [([1, 2, 3], [2, 4, 6]), ([0, -1, -2], [0, -2, -4]), ([], [])], +) +def test_double_integers(input_data, expected_output): + assert double_integers(input_data) == expected_output diff --git a/tests/test_u6_kata_list_filtering.py b/tests/test_u6_kata_list_filtering.py new file mode 100644 index 0000000..af57222 --- /dev/null +++ b/tests/test_u6_kata_list_filtering.py @@ -0,0 +1,47 @@ +import pytest + +from src.u6_tests.U6_Freitag_testing.kata_list_filtering import filter_list + + +def test_filter_list_with_mixed_types(): + result = filter_list([1, 2, "a", "b"]) + assert result == [1, 2] + + +def test_filter_list_with_only_strings(): + result = filter_list(["a", "b", "c"]) + assert result == [] + + +def test_filter_list_with_only_integers(): + result = filter_list([1, 2, 3]) + assert result == [1, 2, 3] + + +def test_filter_list_output_is_list(): + result = filter_list([1, "a", 2]) + assert isinstance(result, list) + + +def test_filter_list_assert_length(): + + l1 = [1, "a", 2, "b", 3] + l2 = [1, 2, 3] + l3 = [1 / 2, "a", 2.5, "b", 3] + + result1 = filter_list(l1) + result2 = filter_list(l2) + result3 = filter_list(l3) + + assert len(result1) == 3 + assert len(result2) == 3 + assert len(result3) == 1 + + +@pytest.mark.parametrize( + "input_list, expected_length", + [([1, "a", 2, "b", 3], 3), ([1, 2, 3], 3), ([1 / 2, "a", 2.5, "b", 3], 1)], +) +def test_filter_list_parametrized(input_list, expected_length): + result = filter_list(input_list) + assert len(result) == expected_length