diff --git a/src/ex2_dictionary.py b/src/ex2_dictionary.py index a133a77..4e4bac0 100644 --- a/src/ex2_dictionary.py +++ b/src/ex2_dictionary.py @@ -21,9 +21,13 @@ def by_amount(articles: dict[str, int], cart: dict[str, int]) -> dict[int, list[ if __name__ == "__main__": - articles_dict = {"apples": 100, "oranges": 100, "lemons": 200, "avocado": 500} + articles_dict = {"apples": 100, "oranges": 100, + "lemons": 200, "avocado": 500} cart_dict = {"apples": 2, "oranges": 2, "lemons": 1, "bananas": 5} assert calculate_price(articles_dict, cart_dict) == 6.0 - assert by_amount(articles_dict, cart_dict) == {2: ['apples', 'oranges'], 1: ['lemons']} + assert by_amount(articles_dict, cart_dict) == { + 2: ['apples', 'oranges'], 1: ['lemons']} + + diff --git a/src/test_dictionary.py b/src/test_dictionary.py index 5bcacf1..81d2e25 100644 --- a/src/test_dictionary.py +++ b/src/test_dictionary.py @@ -1,10 +1,13 @@ +import argparse +import math +import sys +from copy import deepcopy +from enum import Enum + +import pytest + from ex2_dictionary import calculate_price from util import * -import pytest -import sys -import argparse -from enum import Enum -from copy import deepcopy class Task(Enum): @@ -16,7 +19,7 @@ EPS = 0.001 @pytest.mark.dependency(name=Task.MODULES) @pytest.mark.timeout(10) -@eidp_test("unerlaubte Module importiert", -10) +@eidp_test("unerlaubte Module importiert", -10, Task.MODULES) def test_imported_modules(): import ex2_dictionary assert len(list(imported_modules_of(ex2_dictionary))) == 0 @@ -25,7 +28,7 @@ def test_imported_modules(): @pytest.mark.dependency(depends=[Task.MODULES]) @pytest.mark.dependency(name=Task.A) @pytest.mark.timeout(10) -@eidp_test("`calculate_price` nicht implementiert", -10) +@eidp_test("`calculate_price` nicht implementiert", -10, Task.A) def test_calculate_price_implemented(): from ex2_dictionary import calculate_price as _ @@ -33,14 +36,14 @@ def test_calculate_price_implemented(): @pytest.mark.dependency(depends=[Task.MODULES]) @pytest.mark.dependency(name=Task.B) @pytest.mark.timeout(10) -@eidp_test("`by_amount` nicht implementiert", -10) +@eidp_test("`by_amount` nicht implementiert", -10, Task.B) def test_by_amount_implemented(): from ex2_dictionary import by_amount as _ @pytest.mark.dependency(depends=[Task.A]) @pytest.mark.timeout(10) -@eidp_test("`calculate_price` hat keine Typannotationen", -1) +@eidp_test("`calculate_price` hat keine Typannotationen", -1, Task.A) def test_no_typeannotation_calculate_price(): from ex2_dictionary import calculate_price assert not has_no_annotations(calculate_price) @@ -48,7 +51,7 @@ def test_no_typeannotation_calculate_price(): @pytest.mark.dependency(depends=[Task.A]) @pytest.mark.timeout(10) -@eidp_test("`calculate_price` hat inkorrekte Typannotationen", -0.5) +@eidp_test("`calculate_price` hat inkorrekte Typannotationen", -0.5, Task.A) def test_typeannotation_calculate_price(): from ex2_dictionary import calculate_price assert has_annotations( @@ -57,7 +60,7 @@ def test_typeannotation_calculate_price(): @pytest.mark.dependency(depends=[Task.B]) @pytest.mark.timeout(10) -@eidp_test("`by_amount` hat keine Typannotationen", -1) +@eidp_test("`by_amount` hat keine Typannotationen", -1, Task.B) def test_no_typeannotation_by_amount(): from ex2_dictionary import by_amount assert not has_no_annotations(by_amount) @@ -65,7 +68,7 @@ def test_no_typeannotation_by_amount(): @pytest.mark.dependency(depends=[Task.B]) @pytest.mark.timeout(10) -@eidp_test("`by_amount` hat inkorrekte Typannotationen", -0.5) +@eidp_test("`by_amount` hat inkorrekte Typannotationen", -0.5, Task.B) def test_typeannotation_by_amount(): from ex2_dictionary import by_amount assert has_annotations( @@ -74,7 +77,7 @@ def test_typeannotation_by_amount(): @pytest.mark.dependency(depends=[Task.A]) @pytest.mark.timeout(10) -@eidp_test("nicht überprüft ob Produkte in `articles` enthalten", -2) +@eidp_test("nicht überprüft ob Produkte in `articles` enthalten", -2, Task.A) def test_article_not_in_articles(): articles = {'Coke': 200} basket = {'Vitamine R': 1} @@ -83,7 +86,7 @@ def test_article_not_in_articles(): @pytest.mark.dependency(depends=[Task.A]) @pytest.mark.timeout(10) -@eidp_test("Preis wird nicht in Euro (float) ausgegeben", -2) +@eidp_test("Preis wird nicht in Euro (float) ausgegeben", -2, Task.A) def test_price_in_euro(): articles = {'Coke': 200} basket = {'Vitamine R': 1, 'Coke': 2} @@ -92,7 +95,7 @@ def test_price_in_euro(): @pytest.mark.dependency(depends=[Task.A]) @pytest.mark.timeout(10) -@eidp_test("Preis wird nicht korrekt berechnet", -2) +@eidp_test("Preis wird nicht korrekt berechnet", -2, Task.A) def test_price_calc(): articles = {'Coke': 200, 'Eis': 350} basket = {'Coke': 0} @@ -109,7 +112,7 @@ def test_price_calc(): @pytest.mark.dependency(depends=[Task.A]) @pytest.mark.timeout(10) -@eidp_test("`articles`/`cart` wird verwendet", -2) +@eidp_test("`articles`/`cart` wird verwendet", -2, Task.A) def test_sideeffectss(): a = {'Coke': 200, 'Eis': 350} b = {'Coke': 2, 'Eis': 3} @@ -119,7 +122,7 @@ def test_sideeffectss(): @pytest.mark.dependency(depends=[Task.B]) @pytest.mark.timeout(10) -@eidp_test("nicht überprüft ob Produkte in `articles` enthalten", -2) +@eidp_test("nicht überprüft ob Produkte in `articles` enthalten", -2, Task.B) def test_article_not_in_articles_by_amount(): from ex2_dictionary import by_amount articles_dict = {"apples_ex": 100, "oranges_ex": 100, @@ -131,7 +134,7 @@ def test_article_not_in_articles_by_amount(): @pytest.mark.dependency(depends=[Task.B]) @pytest.mark.timeout(10) -@eidp_test("`by_amount` wird nicht korrekt berechnet", -2) +@eidp_test("`by_amount` wird nicht korrekt berechnet", -2, Task.B) def test_by_amount(): from ex2_dictionary import by_amount articles_dict = {"apples": 100, "oranges": 100, @@ -144,7 +147,7 @@ def test_by_amount(): @pytest.mark.dependency(depends=[Task.B]) @pytest.mark.timeout(10) -@eidp_test("es wird kein neues Dictionary erstellt", -4) +@eidp_test("es wird kein neues Dictionary erstellt", -4, Task.B) def test_sideeffects_by_amount(): from ex2_dictionary import by_amount a = {"apples": 100, "oranges": 100, @@ -168,9 +171,6 @@ if __name__ == '__main__': '-t', '--test_only', help='only test without writing readme', action="store_true") args = parser.parse_args() - # print(options) - # print(f'verbose := {verbose}, backup := {backup}') - collector = ResultsCollector() pytest.main(['test_dictionary.py', '-vv', '-s'], plugins=[collector]) @@ -183,8 +183,29 @@ if __name__ == '__main__': print(f"skipped := {skipped}") if not args.test_only: - tests = dict([(name, f) for name, f in vars() if callable( - f) and hasattr(f, "is_test")]) - passed_tests = list(map(lambda m: m[1], filter( - lambda m: m[0] in passed, tests))) - print(passed_tests) + vals = dict(vars()) + tests = dict([(name, f) + for name, f in vals.items() if callable(f) and hasattr(f, "is_test")]) + failed = list(map(lambda m: m[1], filter( + lambda m: m[0] in failed, tests.items()))) + points_a = max(10 + sum(map(lambda f: f.minus_points, + filter(lambda f: f.task == Task.A, failed))), 0) + points_b = max(10 + sum(map(lambda f: f.minus_points, + filter(lambda f: f.task == Task.B, failed))), 0) + msg_a = "\n".join(map( + lambda f: f"- {f.msg} [`{f.minus_points}`]", filter(lambda f: f.task == Task.A, failed))) + msg_b = "\n".join(map( + lambda f: f"- {f.msg} [`{f.minus_points}`]", filter(lambda f: f.task == Task.B, failed))) + content = f"""\ +!!!autogeneriert!!! +## exercise 2 - dictionary - ({points_a + points_b}/20) + +### a) calculate_price ({points_a}/10) +{msg_a} + +### b) by_amount ({points_b}/10) +{msg_b}""" + with open("ex2_dictionary.md", 'w') as file: + file.seek(0) + file.truncate() + file.write(content) diff --git a/src/util.py b/src/util.py index ff018db..dbd7615 100644 --- a/src/util.py +++ b/src/util.py @@ -27,11 +27,12 @@ def imported_modules_of(module: ModuleType) -> Iterator[ModuleType]: return map(lambda m: m[1], filter(lambda m: inspect.ismodule(m[1]), inspect.getmembers(module))) -def eidp_test(message: str, minus_points: float) -> Callable[[Callable[..., Any]], Callable[..., Any]]: +def eidp_test(message: str, minus_points: float, task: Any) -> Callable[[Callable[..., Any]], Callable[..., Any]]: def wrapper(test: Callable[..., Any]) -> Callable[..., Any]: - test.message = message + test.msg = message test.minus_points = minus_points test.is_test = True + test.task = task return test return wrapper