From d8cbee030da8c83b60205f67a13e11d3ae97e492 Mon Sep 17 00:00:00 2001 From: Ilya Date: Thu, 4 Jun 2026 18:05:37 +0300 Subject: [PATCH 1/7] Create functions_illia_bredikhin.py --- Week04/functions_illia_bredikhin.py | 44 +++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 Week04/functions_illia_bredikhin.py diff --git a/Week04/functions_illia_bredikhin.py b/Week04/functions_illia_bredikhin.py new file mode 100644 index 00000000..f763d0a8 --- /dev/null +++ b/Week04/functions_illia_bredikhin.py @@ -0,0 +1,44 @@ +import inspect + + +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: + """ + Calculates custom equation. + + :param x: First positional-only value. + :param y: Second positional-only value. + :param a: Exponent of x. + :param b: Exponent of y. + :param c: Divisor. + :return: Result of equation. + """ + return (x ** a + y ** b) / c + + +_counter = 0 +_callers = {} + + +def fn_w_counter() -> (int, dict[str, int]): + global _counter + global _callers + + _counter += 1 + + caller = inspect.stack()[1].filename + caller = caller.split("/")[-1].replace(".py", "") + + _callers[caller] = _callers.get(caller, 0) + 1 + + return _counter, _callers.copy() From d11af7ab746a25658f5a75e08f6d715744943e9e Mon Sep 17 00:00:00 2001 From: Ilya Date: Thu, 4 Jun 2026 18:06:31 +0300 Subject: [PATCH 2/7] Create awaitme_illia_bredikhin.py --- Week05/awaitme_illia_bredikhin.py | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 Week05/awaitme_illia_bredikhin.py diff --git a/Week05/awaitme_illia_bredikhin.py b/Week05/awaitme_illia_bredikhin.py new file mode 100644 index 00000000..ce4d64a7 --- /dev/null +++ b/Week05/awaitme_illia_bredikhin.py @@ -0,0 +1,9 @@ +from functools import wraps + + +def awaitme(func): + @wraps(func) + async def wrapper(*args, **kwargs): + return func(*args, **kwargs) + + return wrapper From 7340806683115186f324e00e92c76f8e15070bc4 Mon Sep 17 00:00:00 2001 From: Ilya Date: Fri, 5 Jun 2026 12:35:32 +0300 Subject: [PATCH 3/7] Update functions_illia_bredikhin.py Refactor custom_equation docstring and type checks. Simplify fn_w_counter to track calls by module name. --- Week04/functions_illia_bredikhin.py | 33 ++++++++++++----------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/Week04/functions_illia_bredikhin.py b/Week04/functions_illia_bredikhin.py index f763d0a8..6c9659fc 100644 --- a/Week04/functions_illia_bredikhin.py +++ b/Week04/functions_illia_bredikhin.py @@ -1,6 +1,3 @@ -import inspect - - custom_power = lambda x=0, /, e=1: x ** e @@ -14,31 +11,27 @@ def custom_equation( c: int = 1 ) -> float: """ - Calculates custom equation. - - :param x: First positional-only value. - :param y: Second positional-only value. - :param a: Exponent of x. - :param b: Exponent of y. - :param c: Divisor. - :return: Result of equation. + Custom equation. + + :param x: first integer + :param y: second integer + :param a: power of x + :param b: power of y + :param c: divisor + :return: calculated result """ + for value in (x, y, a, b, c): + if not isinstance(value, int): + raise TypeError("All values must be integers") + return (x ** a + y ** b) / c _counter = 0 -_callers = {} def fn_w_counter() -> (int, dict[str, int]): global _counter - global _callers _counter += 1 - - caller = inspect.stack()[1].filename - caller = caller.split("/")[-1].replace(".py", "") - - _callers[caller] = _callers.get(caller, 0) + 1 - - return _counter, _callers.copy() + return _counter, {__name__: _counter} From 8f36c8888ca6c29259b3e934a95b449225226b46 Mon Sep 17 00:00:00 2001 From: Ilya Date: Fri, 5 Jun 2026 12:53:02 +0300 Subject: [PATCH 4/7] Create timer_illia_bredikhin.py --- Week06/timer_illia_bredikhin.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 Week06/timer_illia_bredikhin.py diff --git a/Week06/timer_illia_bredikhin.py b/Week06/timer_illia_bredikhin.py new file mode 100644 index 00000000..8d854b0d --- /dev/null +++ b/Week06/timer_illia_bredikhin.py @@ -0,0 +1,14 @@ +import time + + +class Timer: + def __init__(self): + self.start_time = None + self.end_time = None + + def __enter__(self): + self.start_time = time.perf_counter() + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.end_time = time.perf_counter() From 63d50f3ddb2182f6b1acabb0fc625b2fa885d05a Mon Sep 17 00:00:00 2001 From: Ilya Date: Fri, 5 Jun 2026 12:54:50 +0300 Subject: [PATCH 5/7] Create threaded_illia_bredikhin.py Implement a decorator to run functions in multiple threads. --- Week07/threaded_illia_bredikhin.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 Week07/threaded_illia_bredikhin.py diff --git a/Week07/threaded_illia_bredikhin.py b/Week07/threaded_illia_bredikhin.py new file mode 100644 index 00000000..c3df67f9 --- /dev/null +++ b/Week07/threaded_illia_bredikhin.py @@ -0,0 +1,26 @@ +import threading +from functools import wraps + + +def threaded(n: int): + def decorator(func): + @wraps(func) + def wrapper(*args, **kwargs): + threads = [] + + for _ in range(n): + thread = threading.Thread( + target=func, + args=args, + kwargs=kwargs + ) + + threads.append(thread) + thread.start() + + for thread in threads: + thread.join() + + return wrapper + + return decorator From 63b2e006a0d9b90785e3812eecc0f3b56f21429c Mon Sep 17 00:00:00 2001 From: Ilya Date: Fri, 5 Jun 2026 13:49:49 +0300 Subject: [PATCH 6/7] Create atomic_bredikhin_illia.py --- Week08/atomic_bredikhin_illia.py | 80 ++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 Week08/atomic_bredikhin_illia.py diff --git a/Week08/atomic_bredikhin_illia.py b/Week08/atomic_bredikhin_illia.py new file mode 100644 index 00000000..76c79b71 --- /dev/null +++ b/Week08/atomic_bredikhin_illia.py @@ -0,0 +1,80 @@ +import threading +import random + + +class AtomicOperation(threading.Thread): + def __init__(self, number_of_points: int = 100000): + super().__init__() + self.number_of_points = number_of_points + self.inner_points = 0 + self.total_points = 0 + + def run(self): + inner = 0 + + for _ in range(self.number_of_points): + x = random.random() + y = random.random() + + if x * x + y * y <= 1: + inner += 1 + + self.inner_points = inner + self.total_points = self.number_of_points + + +class AtomicPiEstimator(threading.Thread): + def __init__( + self, + desired_accuracy: float = 1.0e-4, + number_of_threads: int = 4, + chunk_size: int = 100000 + ): + super().__init__() + + self.desired_accuracy = desired_accuracy + self.number_of_threads = number_of_threads + self.chunk_size = chunk_size + + self.inner_points = 0 + self.total_points = 0 + + def pi(self) -> float: + if self.total_points == 0: + return 0.0 + + return 4 * self.inner_points / self.total_points + + def accuracy(self) -> float: + import math + return abs(math.pi - self.pi()) + + def run(self): + while self.accuracy() > self.desired_accuracy: + workers = [] + + for _ in range(self.number_of_threads): + worker = AtomicOperation(self.chunk_size) + workers.append(worker) + worker.start() + + for worker in workers: + worker.join() + + for worker in workers: + self.inner_points += worker.inner_points + self.total_points += worker.total_points + + +if __name__ == "__main__": + estimator = AtomicPiEstimator( + desired_accuracy=1e-5, + number_of_threads=8, + chunk_size=100000 + ) + + estimator.start() + estimator.join() + + print(f"PI = {estimator.pi()}") + print(f"Accuracy = {estimator.accuracy()}") From fb05cf64b82bbfee47306bfb577cc20dd2faebcf Mon Sep 17 00:00:00 2001 From: Bora Canbula Date: Fri, 5 Jun 2026 15:59:39 +0300 Subject: [PATCH 7/7] Delete Week08/atomic_bredikhin_illia.py --- Week08/atomic_bredikhin_illia.py | 80 -------------------------------- 1 file changed, 80 deletions(-) delete mode 100644 Week08/atomic_bredikhin_illia.py diff --git a/Week08/atomic_bredikhin_illia.py b/Week08/atomic_bredikhin_illia.py deleted file mode 100644 index 76c79b71..00000000 --- a/Week08/atomic_bredikhin_illia.py +++ /dev/null @@ -1,80 +0,0 @@ -import threading -import random - - -class AtomicOperation(threading.Thread): - def __init__(self, number_of_points: int = 100000): - super().__init__() - self.number_of_points = number_of_points - self.inner_points = 0 - self.total_points = 0 - - def run(self): - inner = 0 - - for _ in range(self.number_of_points): - x = random.random() - y = random.random() - - if x * x + y * y <= 1: - inner += 1 - - self.inner_points = inner - self.total_points = self.number_of_points - - -class AtomicPiEstimator(threading.Thread): - def __init__( - self, - desired_accuracy: float = 1.0e-4, - number_of_threads: int = 4, - chunk_size: int = 100000 - ): - super().__init__() - - self.desired_accuracy = desired_accuracy - self.number_of_threads = number_of_threads - self.chunk_size = chunk_size - - self.inner_points = 0 - self.total_points = 0 - - def pi(self) -> float: - if self.total_points == 0: - return 0.0 - - return 4 * self.inner_points / self.total_points - - def accuracy(self) -> float: - import math - return abs(math.pi - self.pi()) - - def run(self): - while self.accuracy() > self.desired_accuracy: - workers = [] - - for _ in range(self.number_of_threads): - worker = AtomicOperation(self.chunk_size) - workers.append(worker) - worker.start() - - for worker in workers: - worker.join() - - for worker in workers: - self.inner_points += worker.inner_points - self.total_points += worker.total_points - - -if __name__ == "__main__": - estimator = AtomicPiEstimator( - desired_accuracy=1e-5, - number_of_threads=8, - chunk_size=100000 - ) - - estimator.start() - estimator.join() - - print(f"PI = {estimator.pi()}") - print(f"Accuracy = {estimator.accuracy()}")