diff --git a/Week03/pyramid_vladyslav_senkiv.py b/Week03/pyramid_vladyslav_senkiv.py new file mode 100644 index 00000000..c1f013d7 --- /dev/null +++ b/Week03/pyramid_vladyslav_senkiv.py @@ -0,0 +1,10 @@ +def calculate_pyramid_height(number_of_blocks): + height = 0 + needed_blocks = 1 + + while number_of_blocks >= needed_blocks: + number_of_blocks -= needed_blocks + height += 1 + needed_blocks += 1 + + return height diff --git a/Week03/sequences_vladyslav_senkiv.py b/Week03/sequences_vladyslav_senkiv.py new file mode 100644 index 00000000..d10dbfbf --- /dev/null +++ b/Week03/sequences_vladyslav_senkiv.py @@ -0,0 +1,29 @@ +def remove_duplicates(seq: list) -> list: + result = [] + + for item in seq: + if item not in result: + result.append(item) + + return result + + +def list_counts(seq: list) -> dict: + result = {} + + for item in seq: + if item in result: + result[item] += 1 + else: + result[item] = 1 + + return result + + +def reverse_dict(d: dict) -> dict: + result = {} + + for key, value in d.items(): + result[value] = key + + return result diff --git a/Week04/decorators_vladyslav_senkiv.py b/Week04/decorators_vladyslav_senkiv.py new file mode 100644 index 00000000..ef16153c --- /dev/null +++ b/Week04/decorators_vladyslav_senkiv.py @@ -0,0 +1,32 @@ +import time +import sys +from functools import wraps + + +def performance(func): + @wraps(func) + def wrapper(*args, **kwargs): + start_time = time.perf_counter() + + result = func(*args, **kwargs) + + end_time = time.perf_counter() + + performance.counter += 1 + performance.total_time += end_time - start_time + performance.total_mem += sys.getsizeof(result) + + if isinstance(result, list): + performance.total_mem += sys.getsizeof(result) + + for item in result: + performance.total_mem += sys.getsizeof(item) + + return result + + return wrapper + + +performance.counter = 0 +performance.total_time = 0 +performance.total_mem = 0 diff --git a/Week04/functions_vladyslav_senkiv.py b/Week04/functions_vladyslav_senkiv.py new file mode 100644 index 00000000..e2fb6131 --- /dev/null +++ b/Week04/functions_vladyslav_senkiv.py @@ -0,0 +1,41 @@ +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 number + :param y: second number + :param a: additional parameter + :param b: power value + :param c: divisor + :return: result of custom equation + """ + + values = [x, y, a, b, c] + + for value in values: + if not isinstance(value, int): + raise TypeError("value must be int") + + return (x + y ** b) / c + + +counter = 0 + + +def fn_w_counter() -> (int, dict[str, int]): + global counter + + counter += 1 + + return counter, {__name__: counter} diff --git a/Week05/awaitme_vladyslav_senkiv.py b/Week05/awaitme_vladyslav_senkiv.py new file mode 100644 index 00000000..ce4d64a7 --- /dev/null +++ b/Week05/awaitme_vladyslav_senkiv.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 diff --git a/Week06/timer_vladyslav_senkiv.py b/Week06/timer_vladyslav_senkiv.py new file mode 100644 index 00000000..2867f8d4 --- /dev/null +++ b/Week06/timer_vladyslav_senkiv.py @@ -0,0 +1,15 @@ +from time import perf_counter + + +class Timer: + def __init__(self): + self.start_time = None + self.end_time = None + + def __enter__(self): + self.start_time = perf_counter() + return self + + def __exit__(self, exc_type, exc_value, traceback): + self.end_time = perf_counter() + return False diff --git a/Week07/threaded_vladyslav_senkiv.py b/Week07/threaded_vladyslav_senkiv.py new file mode 100644 index 00000000..3868ed07 --- /dev/null +++ b/Week07/threaded_vladyslav_senkiv.py @@ -0,0 +1,25 @@ +import threading +from functools import wraps + + +def threaded(number_of_threads): + def decorator(func): + @wraps(func) + def wrapper(*args, **kwargs): + threads = [] + + for _ in range(number_of_threads): + thread = threading.Thread( + target=func, + args=args, + kwargs=kwargs + ) + threads.append(thread) + thread.start() + + for thread in threads: + thread.join() + + return wrapper + + return decorator diff --git a/Week08/estimate_pi_w_threads_vladyslav_senkiv.py b/Week08/estimate_pi_w_threads_vladyslav_senkiv.py new file mode 100644 index 00000000..ffff4dad --- /dev/null +++ b/Week08/estimate_pi_w_threads_vladyslav_senkiv.py @@ -0,0 +1,47 @@ +import random +import threading +import math + + +class PiWorker(threading.Thread): + def __init__(self, points_count): + super().__init__() + self.points_count = points_count + self.inside_circle = 0 + + def run(self): + for _ in range(self.points_count): + x = random.random() + y = random.random() + + if x * x + y * y <= 1: + self.inside_circle += 1 + + +def estimate_pi(total_points=1000000, thread_count=4): + points_per_thread = total_points // thread_count + threads = [] + + for _ in range(thread_count): + thread = PiWorker(points_per_thread) + threads.append(thread) + thread.start() + + inside_circle = 0 + + for thread in threads: + thread.join() + inside_circle += thread.inside_circle + + used_points = points_per_thread * thread_count + pi_value = 4 * inside_circle / used_points + + return pi_value + + +if __name__ == "__main__": + pi = estimate_pi(total_points=1000000, thread_count=4) + + print("Estimated PI:", pi) + print("Real PI:", math.pi) + print("Difference:", abs(math.pi - pi))