From 628e8eb57ef0564f060b26b018347731af044c3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C4=9F=C4=B1z=20Cengiz?= Date: Mon, 2 Nov 2026 22:12:59 +0300 Subject: [PATCH 1/3] Add files via upload --- Week04/functions_yagiz_cengiz.py | 39 ++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 Week04/functions_yagiz_cengiz.py diff --git a/Week04/functions_yagiz_cengiz.py b/Week04/functions_yagiz_cengiz.py new file mode 100644 index 00000000..377295a4 --- /dev/null +++ b/Week04/functions_yagiz_cengiz.py @@ -0,0 +1,39 @@ +custom_power = lambda x=0, /, e=1: x**e + + +def custom_equation( + x: int = 0, y: int = 0, /, a: int = 1, b: int = 1, *, c: int = 1 +) -> float: + """ + This function calculates (x**a + y**b) / c. + + :param x: The first base, positional-only + :type x: int + :param y: The second base, positional-only + :type y: int + :param a: The exponent of x + :type a: int + :param b: The exponent of y + :type b: int + :param c: The divisor, keyword-only + :type c: int + :raises TypeError: If any of the parameters is not an integer + :return: The result of (x**a + y**b) / c + :rtype: float + """ + for name, value in (("x", x), ("y", y), ("a", a), ("b", b), ("c", c)): + if not isinstance(value, int): + raise TypeError(f"{name} must be an integer") + return (x**a + y**b) / c + + +def fn_w_counter() -> (int, dict[str, int]): + """ + This function counts its calls and returns the total with the callers. + """ + # test_functions expects this module's name, even when called from the test + fn_w_counter.callers[__name__] = fn_w_counter.callers.get(__name__, 0) + 1 + return sum(fn_w_counter.callers.values()), dict(fn_w_counter.callers) + + +fn_w_counter.callers = {} From 6fd68cff8fe9e6c348c60e6c1fcf7fa725974036 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C4=9F=C4=B1z=20Cengiz?= Date: Mon, 2 Nov 2026 22:14:54 +0300 Subject: [PATCH 2/3] Add files via upload --- Week04/decorators_yagiz_cengiz.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 Week04/decorators_yagiz_cengiz.py diff --git a/Week04/decorators_yagiz_cengiz.py b/Week04/decorators_yagiz_cengiz.py new file mode 100644 index 00000000..a45590d4 --- /dev/null +++ b/Week04/decorators_yagiz_cengiz.py @@ -0,0 +1,31 @@ +import functools +import time +import tracemalloc + + +def performance(fn): + """ + This decorator measures the time and memory of the calls of a function. + The statistics of all decorated functions are saved in its attributes. + """ + + @functools.wraps(fn) + def wrapper(*args, **kwargs): + # shortcut: a decorated function calling another one under-reports + # memory because tracemalloc is global, keep calls flat to stay exact + tracemalloc.start() + start = time.perf_counter() + try: + return fn(*args, **kwargs) + finally: + performance.total_time += time.perf_counter() - start + performance.total_mem += tracemalloc.get_traced_memory()[1] + performance.counter += 1 + tracemalloc.stop() + + return wrapper + + +performance.counter = 0 +performance.total_time = 0 +performance.total_mem = 0 From b92af5b87b6635f52710eca67bea15de05086910 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ya=C4=9F=C4=B1z=20Cengiz?= Date: Mon, 2 Nov 2026 22:15:24 +0300 Subject: [PATCH 3/3] Add files via upload --- Week05/emails_yagiz_cengiz.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 Week05/emails_yagiz_cengiz.py diff --git a/Week05/emails_yagiz_cengiz.py b/Week05/emails_yagiz_cengiz.py new file mode 100644 index 00000000..9b14347e --- /dev/null +++ b/Week05/emails_yagiz_cengiz.py @@ -0,0 +1,35 @@ +import re + + +class Emails(list): + """ + This class keeps a list of unique and valid email addresses. + """ + + def __init__(self, emails: list) -> None: + super().__init__(self.validate(emails)) + + @property + def data(self) -> "Emails": + """ + This property returns the email addresses. + """ + return self + + @staticmethod + def validate(emails: list) -> list: + """ + This method checks the email addresses and removes the duplicates. + """ + for email in emails: + if not isinstance(email, str): + raise ValueError(f"{email!r} is not a string") + if not re.fullmatch(r"[\w.+-]+@[\w-]+(\.[\w-]+)+", email): + raise ValueError(f"{email!r} is not a valid email address") + return list(dict.fromkeys(emails)) + + def __repr__(self) -> str: + return f"Emails({list(self)!r})" + + def __str__(self) -> str: + return ", ".join(self)