diff --git a/10/ex2/scope_mysteries.py b/10/ex2/scope_mysteries.py new file mode 100644 index 0000000..4388e68 --- /dev/null +++ b/10/ex2/scope_mysteries.py @@ -0,0 +1,79 @@ +from typing import Callable + + +def mage_counter() -> Callable: + i = 0 + + def count_call() -> int: + nonlocal i + i += 1 + return i + + return count_call + + +def spell_accumulator(initial_power: int) -> Callable: + power = initial_power + + def add_power(power_to_add: int) -> int: + nonlocal power + power += power_to_add + return power + + return add_power + + +def enchantment_factory(enchantment_type: str) -> Callable: + def apply_enchantment(item: str) -> str: + return f"{enchantment_type} {item}" + + return apply_enchantment + + +def memory_vault() -> dict[str, Callable]: + storage = {} + + def store(to_store: dict[str, str]) -> None: + nonlocal storage + for data in to_store: + storage[data] = to_store[data] + + def recall(key: str) -> str: + try: + return storage[key] + except KeyError: + return "Memory not found" + + return {"store": store, "recall": recall} + + +def main(): + print("===mage_counter===\n") + count = mage_counter() + print(f"1 : {count()}") + print(f"2 : {count()}") + print(f"3 : {count()}") + print(f"4 : {count()}") + + print("\n===spell_accumulator===\n") + accumulator = spell_accumulator(30) + print(f"initial_power: {accumulator(0)}") + print(f"add 10: {accumulator(10)}") + print(f"add 15: {accumulator(15)}") + print(f"add 5: {accumulator(5)}") + + print("\n===enchantment_factory===\n") + flaming = enchantment_factory("Flaming") + frozen = enchantment_factory("Frozen") + print(f"Flaming factory: {flaming('Sword')}") + print(f"Frozen factory: {frozen('Shield')}") + + print("\n===memory_vault===\n") + vault = memory_vault() + vault["store"]({"name": "Jean", "surname": "Dupont"}) + print(f"Access to name: {vault['recall']('name')}") + print(f"Access to age: {vault['recall']('age')}") + + +if __name__ == "__main__": + main() diff --git a/10/ex3/functools_artifacts.py b/10/ex3/functools_artifacts.py new file mode 100644 index 0000000..f818d1e --- /dev/null +++ b/10/ex3/functools_artifacts.py @@ -0,0 +1,91 @@ +from functools import lru_cache, reduce, partial, singledispatch +import operator as op +import re +from typing import Callable, Any + + +def spell_reducer(spells: list[int], operation: str) -> int: + if operation == "add": + return reduce(lambda x, y: op.add(x, y), spells) + if operation == "multiply": + return reduce(lambda x, y: op.mul(x, y), spells) + if operation == "max": + return reduce(lambda x, y: x if x > y else y, spells) + if operation == "min": + return reduce(lambda x, y: x if x < y else y, spells) + + return 0 + + +def partial_enchanter(base_enchantment: Callable) -> dict[str, Callable]: + return { + "fire_enchant": partial(base_enchantment, power=50, element="fire"), + "ice_enchant": partial(base_enchantment, power=50, element="ice"), + "lightning_enchant": partial( + base_enchantment, power=50, element="lightning" + ), + } + + +def memoized_fibonacci(n: int) -> int: + if n < 2: + return n + return memoized_fibonacci(n - 1) + memoized_fibonacci(n - 2) + + +def spell_dispatcher() -> Callable: + @singledispatch + def basic(arg: Any) -> str: + return arg + + @basic.register(int) + def basic_int(arg: int) -> str: + return f"{arg} damage take" + + @basic.register(str) + def basic_str(arg: str) -> str: + return f"apply {arg}" + + @basic.register(list) + def basic_list(arg: list) -> str: + res = "" + for cast in arg: + res += f"cast {cast}\n" + return res + + return basic + + +def attack(target: str, power: int, element: str) -> str: + return f"{target}: take {power} damage, {element} is applied" + + +@lru_cache(maxsize=128) +def main() -> None: + print("===spell_reducer===\n") + print(f"sum of [4, 5, 6]: {spell_reducer([4, 5, 6], 'add')}") + print(f"multiply [4, 5, 6]: {spell_reducer([4, 5, 6], 'multiply')}") + print(f"max of [4, 5, 6]: {spell_reducer([4, 5, 6], 'max')}") + print(f"min of [4, 5, 6]: {spell_reducer([4, 5, 6], 'min')}") + + print("\n===partial_enchanter===\n") + attacks = partial_enchanter(attack) + for x in attacks: + print(f"{x}: {attacks[x]('goblin')}") + + print("\n===memoized_fibonacci===\n") + print(f"fib(0): {memoized_fibonacci(0)}") + print(f"fib(1): {memoized_fibonacci(1)}") + print(f"fib(5): {memoized_fibonacci(5)}") + print(f"fib(30): {memoized_fibonacci(30)}") + + print("\n===spell_dispatcher===\n") + dispatcher = spell_dispatcher() + print(f"int: {dispatcher(3)}") + print(f"str: {dispatcher('fire')}") + print(f"list: {dispatcher(['test', 'hello', 'world', '!'])}") + print(f"dict: {dispatcher({1: 3})}") + + +if __name__ == "__main__": + main()