From f4e72da83616e49e9aa0ff1c68bd92fe2219a4b7 Mon Sep 17 00:00:00 2001 From: AntonLodygin Date: Tue, 23 Sep 2025 18:29:45 +0300 Subject: [PATCH 01/24] =?UTF-8?q?=D1=80=D0=B5=D1=88=D0=B5=D0=BD=D0=BD?= =?UTF-8?q?=D1=8B=D0=B5=20=D0=B7=D0=B0=D0=B4=D0=B0=D1=87=D0=B8=20lesson02?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- solutions/lesson02/task1.py | 3 ++- solutions/lesson02/task2.py | 5 +++-- solutions/lesson02/task3.py | 4 +++- solutions/lesson02/task4.py | 9 ++++++++- solutions/lesson02/task5.py | 7 +++++-- solutions/lesson02/task6.py | 14 +++++++++++--- solutions/lesson02/task7.py | 5 ++--- 7 files changed, 34 insertions(+), 13 deletions(-) diff --git a/solutions/lesson02/task1.py b/solutions/lesson02/task1.py index c782dcd8..478c0588 100644 --- a/solutions/lesson02/task1.py +++ b/solutions/lesson02/task1.py @@ -1,4 +1,5 @@ def get_factorial(num: int) -> int: factorial = 1 - # ваш код + for i in range(2, num + 1): + factorial *= i return factorial diff --git a/solutions/lesson02/task2.py b/solutions/lesson02/task2.py index b91420c5..498a07c0 100644 --- a/solutions/lesson02/task2.py +++ b/solutions/lesson02/task2.py @@ -1,4 +1,5 @@ def get_doubled_factorial(num: int) -> int: factorial = 1 - # ваш код - return factorial + if num <= 1: + return 1 + return num * get_doubled_factorial(num - 2) diff --git a/solutions/lesson02/task3.py b/solutions/lesson02/task3.py index ee2a84ec..e6649c4c 100644 --- a/solutions/lesson02/task3.py +++ b/solutions/lesson02/task3.py @@ -1,4 +1,6 @@ def get_amount_of_ways_to_climb(stair_amount: int) -> int: step_prev, step_curr = 1, 1 - # ваш код + for i in range(1, stair_amount): + step_prev, step_curr = step_curr, step_prev + step_curr + return step_curr diff --git a/solutions/lesson02/task4.py b/solutions/lesson02/task4.py index 45ff4bb4..69e54d14 100644 --- a/solutions/lesson02/task4.py +++ b/solutions/lesson02/task4.py @@ -1,4 +1,11 @@ def get_multiplications_amount(num: int) -> int: multiplications_amount = 0 - # ваш код + while num != 1: + if num % 2 == 0: + multiplications_amount += 1 + num //= 2 + else: + multiplications_amount += 1 + num -= 1 + return multiplications_amount diff --git a/solutions/lesson02/task5.py b/solutions/lesson02/task5.py index 8fb9a048..b2896416 100644 --- a/solutions/lesson02/task5.py +++ b/solutions/lesson02/task5.py @@ -1,3 +1,6 @@ def get_gcd(num1: int, num2: int) -> int: - # ваш код - return num1 + d = max(num1, num2) % min(num1, num2) + while d != 0: + num1, num2 = min(num1, num2), d + d = num1 % d + return min(num1, num2) diff --git a/solutions/lesson02/task6.py b/solutions/lesson02/task6.py index bec4b6cd..68231035 100644 --- a/solutions/lesson02/task6.py +++ b/solutions/lesson02/task6.py @@ -1,4 +1,12 @@ def get_sum_of_prime_divisors(num: int) -> int: - sum_of_divisors = 0 - # ваш код - return sum_of_divisors + nums = set() + while num != 1: + for i in range(2, int(num ** 0.5) + 1): + if num % i == 0: + num //= i + nums.add(i) + break + else: + nums.add(num) + break + return sum(nums) diff --git a/solutions/lesson02/task7.py b/solutions/lesson02/task7.py index 4b2d73be..c080a86c 100644 --- a/solutions/lesson02/task7.py +++ b/solutions/lesson02/task7.py @@ -1,5 +1,4 @@ def is_palindrome(num: int) -> bool: - num_reversed = 0 - num_origin = num - # ваш код + num_reversed = str(num)[::-1] + num_origin = str(num) return num_origin == num_reversed From 517393508a1578643611e4d265a6c0da01521fdc Mon Sep 17 00:00:00 2001 From: AntonLodygin Date: Thu, 25 Sep 2025 16:30:47 +0300 Subject: [PATCH 02/24] remove unused variable --- solutions/lesson02/task2.py | 1 - 1 file changed, 1 deletion(-) diff --git a/solutions/lesson02/task2.py b/solutions/lesson02/task2.py index 498a07c0..0dec16d9 100644 --- a/solutions/lesson02/task2.py +++ b/solutions/lesson02/task2.py @@ -1,5 +1,4 @@ def get_doubled_factorial(num: int) -> int: - factorial = 1 if num <= 1: return 1 return num * get_doubled_factorial(num - 2) From 6fb47dba4ea3e1b0704b1c9a86941e45da96cf16 Mon Sep 17 00:00:00 2001 From: AntonLodygin Date: Sat, 27 Sep 2025 01:21:19 +0300 Subject: [PATCH 03/24] new solution --- solutions/lesson02/task2.py | 8 +++++--- solutions/lesson02/task5.py | 10 ++++++---- solutions/lesson02/task6.py | 15 ++++++++++----- solutions/lesson02/task7.py | 20 ++++++++++++++++++-- 4 files changed, 39 insertions(+), 14 deletions(-) diff --git a/solutions/lesson02/task2.py b/solutions/lesson02/task2.py index 0dec16d9..63b4b9be 100644 --- a/solutions/lesson02/task2.py +++ b/solutions/lesson02/task2.py @@ -1,4 +1,6 @@ def get_doubled_factorial(num: int) -> int: - if num <= 1: - return 1 - return num * get_doubled_factorial(num - 2) + factorial = 1 + while num > 1: + factorial *= num + num -= 2 + return factorial diff --git a/solutions/lesson02/task5.py b/solutions/lesson02/task5.py index b2896416..2712bd70 100644 --- a/solutions/lesson02/task5.py +++ b/solutions/lesson02/task5.py @@ -1,6 +1,8 @@ def get_gcd(num1: int, num2: int) -> int: - d = max(num1, num2) % min(num1, num2) + if num1 < num2: + num1, num2 = num2, num1 + d = num1 % num2 while d != 0: - num1, num2 = min(num1, num2), d - d = num1 % d - return min(num1, num2) + num1, num2 = num2, d + d = num1 % num2 + return num2 diff --git a/solutions/lesson02/task6.py b/solutions/lesson02/task6.py index 68231035..0b18c12e 100644 --- a/solutions/lesson02/task6.py +++ b/solutions/lesson02/task6.py @@ -1,12 +1,17 @@ def get_sum_of_prime_divisors(num: int) -> int: - nums = set() + sum_of_divisors = 0 + mult_of_divisors = 1 while num != 1: - for i in range(2, int(num ** 0.5) + 1): + for i in range(2, int(num**0.5) + 1): if num % i == 0: num //= i - nums.add(i) + if mult_of_divisors % i != 0: + sum_of_divisors += i + mult_of_divisors *= i break else: - nums.add(num) + if mult_of_divisors % num != 0: + sum_of_divisors += num break - return sum(nums) + + return sum_of_divisors diff --git a/solutions/lesson02/task7.py b/solutions/lesson02/task7.py index c080a86c..b58f5872 100644 --- a/solutions/lesson02/task7.py +++ b/solutions/lesson02/task7.py @@ -1,4 +1,20 @@ def is_palindrome(num: int) -> bool: - num_reversed = str(num)[::-1] - num_origin = str(num) + if num < 0: + return False + + num_reversed = 0 + num_origin = num + + smax = 0 + for i in range(1, 10): + if num // 10**i > 0: + smax += 1 + + s = smax + while s != -1: + n_s = num // 10**s + num -= n_s * 10**s + num_reversed += n_s * 10 ** (smax - s) + s -= 1 + return num_origin == num_reversed From 462565fe44114ed097ccadd7061f6961b060b7c1 Mon Sep 17 00:00:00 2001 From: AntonLodygin Date: Fri, 10 Oct 2025 16:02:33 +0300 Subject: [PATCH 04/24] lesson03 solution --- solutions/lesson03/task1.py | 30 ++++++++++++++++++++++++++++-- solutions/lesson03/task2.py | 21 +++++++++++++++++++-- solutions/lesson03/task3.py | 21 +++++++++++++++++++-- 3 files changed, 66 insertions(+), 6 deletions(-) diff --git a/solutions/lesson03/task1.py b/solutions/lesson03/task1.py index f1d8fe26..3f09fdab 100644 --- a/solutions/lesson03/task1.py +++ b/solutions/lesson03/task1.py @@ -1,3 +1,29 @@ def flip_bits_in_range(num: int, left_bit: int, right_bit: int) -> int: - # ваш код - return num \ No newline at end of file + n = num + s = 0 + while n: + s += 1 + n //= 2 + + t = s + new_num = 0 + + for i in range(left_bit - 1): + r = 0 if num % 2 == 0 else 1 + new_num += r * 2 ** (s - t) + num //= 2 + t -= 1 + + for j in range(right_bit - left_bit + 1): + r = 1 if num % 2 == 0 else 0 + new_num += r * 2 ** (s - t) + num //= 2 + t -= 1 + + for k in range(t): + r = 0 if num % 2 == 0 else 1 + new_num += r * 2 ** (s - t) + num //= 2 + t -= 1 + + return new_num diff --git a/solutions/lesson03/task2.py b/solutions/lesson03/task2.py index a3a738c2..61acffc2 100644 --- a/solutions/lesson03/task2.py +++ b/solutions/lesson03/task2.py @@ -1,3 +1,20 @@ def get_cube_root(n: float, eps: float) -> float: - # ваш код - return n \ No newline at end of file + if n == 0: + return 0 + + abs_n = abs(n) + + low = 0 + high = abs_n if abs_n >= 1 else 1 + mid = (low + high) / 2 + mid3 = mid * mid * mid + while abs(mid3 - abs_n) > eps: + if mid3 > abs_n: + high = mid + else: + low = mid + + mid = (low + high) / 2 + mid3 = mid * mid * mid + + return mid * abs_n / n diff --git a/solutions/lesson03/task3.py b/solutions/lesson03/task3.py index 5e91a6ac..22f94142 100644 --- a/solutions/lesson03/task3.py +++ b/solutions/lesson03/task3.py @@ -1,3 +1,20 @@ def get_nth_digit(num: int) -> int: - # ваш код - return 0 + if num <= 5: + return 2 * (num - 1) + + q = 5 + r = 1 + w = 0 + while q < num: + w = q + q += 45 * 10 ** (r - 1) * (r + 1) + r += 1 + d = num - w + count = (d + r - 1) // r + res = 10 ** (r - 1) + 2 * (count - 1) + last_num = count * r + while last_num - d: + res //= 10 + last_num -= 1 + + return res % 10 From 88935c59d401c6fd91b5994b51c72bbcba322c42 Mon Sep 17 00:00:00 2001 From: AntonLodygin Date: Wed, 15 Oct 2025 18:56:57 +0300 Subject: [PATCH 05/24] lesson04 solutions --- solutions/lesson04/task1.py | 9 ++++++--- solutions/lesson04/task2.py | 16 ++++++++++++++-- solutions/lesson04/task3.py | 6 ++++-- solutions/lesson04/task4.py | 18 +++++++++++++++--- solutions/lesson04/task5.py | 13 +++++++++++-- solutions/lesson04/task6.py | 16 +++++++++++++--- 6 files changed, 63 insertions(+), 15 deletions(-) diff --git a/solutions/lesson04/task1.py b/solutions/lesson04/task1.py index 47384423..78b5c42b 100644 --- a/solutions/lesson04/task1.py +++ b/solutions/lesson04/task1.py @@ -1,3 +1,6 @@ -def is_arithmetic_progression(lst: list[list[int]]) -> bool: - # ваш код - return False \ No newline at end of file +def is_arithmetic_progression(lst: list[int]) -> bool: + lst.sort() + for i in range(len(lst) - 2): + if lst[i] - lst[i + 1] != lst[i + 1] - lst[i + 2]: + return False + return True diff --git a/solutions/lesson04/task2.py b/solutions/lesson04/task2.py index 4591d0a3..aaaab8c0 100644 --- a/solutions/lesson04/task2.py +++ b/solutions/lesson04/task2.py @@ -1,3 +1,15 @@ def merge_intervals(intervals: list[list[int, int]]) -> list[list[int, int]]: - # ваш код - return [[0,0]] \ No newline at end of file + if not intervals: + return [] + + intervals.sort() + new_intervals = [intervals[0]] + for i in range(1, len(intervals)): + x1, y1 = new_intervals[-1] + x2, y2 = intervals[i] + if x2 <= y1: + new_intervals[-1] = [x1, max(y2, y1)] + else: + new_intervals.append(intervals[i]) + + return new_intervals diff --git a/solutions/lesson04/task3.py b/solutions/lesson04/task3.py index 7253f6cb..9db4c15b 100644 --- a/solutions/lesson04/task3.py +++ b/solutions/lesson04/task3.py @@ -1,3 +1,5 @@ def find_single_number(nums: list[int]) -> int: - # ваш код - return 0 + n = 0 + for i in nums: + n ^= i + return n diff --git a/solutions/lesson04/task4.py b/solutions/lesson04/task4.py index b21bc5a3..b97b52f4 100644 --- a/solutions/lesson04/task4.py +++ b/solutions/lesson04/task4.py @@ -1,3 +1,15 @@ -def move_zeros_to_end(nums: list[int]) -> list[int]: - # ваш код - return 0 \ No newline at end of file +def move_zeros_to_end(nums: list[int]) -> int: + if not nums.count(0): + return len(nums) + + n = len(nums) - nums.count(0) + i = 0 + while i != n: + elem = nums[i] + if elem == 0: + del nums[i] + nums.append(0) + else: + i += 1 + + return nums.index(0) diff --git a/solutions/lesson04/task5.py b/solutions/lesson04/task5.py index 02d7742b..a20636de 100644 --- a/solutions/lesson04/task5.py +++ b/solutions/lesson04/task5.py @@ -1,3 +1,12 @@ def find_row_with_most_ones(matrix: list[list[int]]) -> int: - # ваш код - return 0 \ No newline at end of file + if not matrix: + return 0 + + m = len(matrix[0]) + best_index = 0 + for i in range(len(matrix)): + while m > 0 and matrix[i][m - 1]: + m -= 1 + best_index = i + + return best_index diff --git a/solutions/lesson04/task6.py b/solutions/lesson04/task6.py index 16df27ca..1ac6656b 100644 --- a/solutions/lesson04/task6.py +++ b/solutions/lesson04/task6.py @@ -1,3 +1,13 @@ -def count_cycles(arr: list[int]) -> int: - # ваш код - return 0 \ No newline at end of file +def count_cycles(arr: list[int]) -> int: + used_indexes = [] + cycles_count = 0 + for i in range(len(arr)): + new_index = arr[i] + f = new_index in used_indexes + while new_index not in used_indexes: + used_indexes.append(new_index) + new_index = arr[new_index] + if not f: + cycles_count += 1 + + return cycles_count From 63a836f6ae994ff4c4af8aa67e5ba50053b4d381 Mon Sep 17 00:00:00 2001 From: AntonLodygin Date: Fri, 24 Oct 2025 00:49:45 +0300 Subject: [PATCH 06/24] lesson05 solutions --- solutions/lesson05/task1.py | 4 ++-- solutions/lesson05/task2.py | 30 ++++++++++++++++++++++++++-- solutions/lesson05/task3.py | 8 ++++++-- solutions/lesson05/task4.py | 10 ++++++++-- solutions/lesson05/task5.py | 40 ++++++++++++++++++++++++++++++++++--- solutions/lesson05/task6.py | 15 ++++++++++++-- 6 files changed, 94 insertions(+), 13 deletions(-) diff --git a/solutions/lesson05/task1.py b/solutions/lesson05/task1.py index 9a17211e..83cb2363 100644 --- a/solutions/lesson05/task1.py +++ b/solutions/lesson05/task1.py @@ -1,3 +1,3 @@ def is_palindrome(text: str) -> bool: - # ваш код - return False \ No newline at end of file + text = text.lower() + return text == text[::-1] \ No newline at end of file diff --git a/solutions/lesson05/task2.py b/solutions/lesson05/task2.py index 36750380..850722e4 100644 --- a/solutions/lesson05/task2.py +++ b/solutions/lesson05/task2.py @@ -1,3 +1,29 @@ def are_anagrams(word1: str, word2: str) -> bool: - # ваш код - return False \ No newline at end of file + low_letters = [0] * 26 + upper_letters = [0] * 26 + a_index = ord("a") + A_index = ord("A") + + for i in word1: + index = ord(i) + if index >= 97: + low_letters[index - a_index] += 1 + elif index >= 65: + upper_letters[index - A_index] += 1 + + for j in word2: + index = ord(j) + if index >= 97: + low_letters[index - a_index] -= 1 + elif index >= 65: + upper_letters[index - A_index] -= 1 + + # return not any(low_letters) and not any(upper_letters) + for k in low_letters: + if k: + return False + for p in upper_letters: + if p: + return False + + return True diff --git a/solutions/lesson05/task3.py b/solutions/lesson05/task3.py index e368e2f4..41331860 100644 --- a/solutions/lesson05/task3.py +++ b/solutions/lesson05/task3.py @@ -1,3 +1,7 @@ def is_punctuation(text: str) -> bool: - # ваш код - return False + if not text: + return False + for i in text: + if i not in r'!"#$%&\'()*+,-./:;<=>?@[]^_{|}~`': + return False + return True diff --git a/solutions/lesson05/task4.py b/solutions/lesson05/task4.py index 4c4e9086..0f6cce30 100644 --- a/solutions/lesson05/task4.py +++ b/solutions/lesson05/task4.py @@ -1,3 +1,9 @@ def unzip(compress_text: str) -> str: - # ваш код - return compress_text \ No newline at end of file + result = "" + for i in compress_text.split(): + if "*" in i: + s, count = i.split("*") + result += s * int(count) + else: + result += i + return result diff --git a/solutions/lesson05/task5.py b/solutions/lesson05/task5.py index 076c5bb6..1a128a4e 100644 --- a/solutions/lesson05/task5.py +++ b/solutions/lesson05/task5.py @@ -1,3 +1,37 @@ -def reg_validator(reg_expr: str, text: str) -> bool: - # ваш код - return False \ No newline at end of file +def reg_validator(reg_expr: str, text: str) -> bool: + index = 0 + text_len = len(text) + + for char in reg_expr: + if index == text_len: + return False + + if char == "d": + num_len = 0 + while index < text_len and text[index].isdigit(): + index += 1 + num_len += 1 + if not num_len: + return False + + elif char == "w": + word_len = 0 + while index < text_len and text[index].isalpha(): + index += 1 + word_len += 1 + if not word_len: + return False + + elif char == "s": + string_len = 0 + while index < text_len and text[index].isalnum(): + index += 1 + string_len += 1 + if not string_len: + return False + + else: + if char != text[index]: + return False + index += 1 + return index == text_len diff --git a/solutions/lesson05/task6.py b/solutions/lesson05/task6.py index 1b914ada..1a334083 100644 --- a/solutions/lesson05/task6.py +++ b/solutions/lesson05/task6.py @@ -1,3 +1,14 @@ def simplify_path(path: str) -> str: - # ваш код - return path \ No newline at end of file + catalogs = [] + for i in path.replace("//", "/").split("/"): + if i == ".." and not catalogs: + return "" + if i == "..": + del catalogs[-1] + continue + if i == ".": + continue + if i: + catalogs.append(i) + + return "/" + "/".join(catalogs) From 96e9f32805df4ebcaa0a1a4baa6db59928ce15cb Mon Sep 17 00:00:00 2001 From: AntonLodygin Date: Fri, 24 Oct 2025 00:59:43 +0300 Subject: [PATCH 07/24] code formatted --- solutions/lesson05/task1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/lesson05/task1.py b/solutions/lesson05/task1.py index 83cb2363..8d94d0ac 100644 --- a/solutions/lesson05/task1.py +++ b/solutions/lesson05/task1.py @@ -1,3 +1,3 @@ def is_palindrome(text: str) -> bool: text = text.lower() - return text == text[::-1] \ No newline at end of file + return text == text[::-1] From 17c0a660d9e8d4920e1f021ba9c4a87f8739dc31 Mon Sep 17 00:00:00 2001 From: AntonLodygin Date: Sun, 26 Oct 2025 22:39:40 +0300 Subject: [PATCH 08/24] solutions lesson06 --- solutions/lesson06/task1.py | 32 ++++++++++++++++++++++++++++++-- solutions/lesson06/task2.py | 24 ++++++++++++++++++++++-- solutions/lesson06/task3.py | 14 ++++++++------ solutions/lesson06/task4.py | 7 +++++-- 4 files changed, 65 insertions(+), 12 deletions(-) diff --git a/solutions/lesson06/task1.py b/solutions/lesson06/task1.py index 2d1e30e9..2d03a401 100644 --- a/solutions/lesson06/task1.py +++ b/solutions/lesson06/task1.py @@ -1,3 +1,31 @@ def int_to_roman(num: int) -> str: - # ваш код - return "" \ No newline at end of file + symbols = { + 1: "I", + 4: "IV", + 5: "V", + 9: "IX", + 10: "X", + 40: "XL", + 50: "L", + 90: "XC", + 100: "C", + 400: "CD", + 500: "D", + 900: "CM", + 1000: "M", + } + + res = "" + counter = 0 + while num: + n = (num % 10) * 10**counter + if n in symbols: + res = symbols[n] + res + elif n > 5 * 10**counter: + res = symbols[5 * 10**counter] + symbols[10**counter] * (n // 10**counter - 5) + res + else: + res = symbols[10**counter] * (n // 10**counter) + res + num //= 10 + counter += 1 + + return res diff --git a/solutions/lesson06/task2.py b/solutions/lesson06/task2.py index f535b5a0..74a8dc79 100644 --- a/solutions/lesson06/task2.py +++ b/solutions/lesson06/task2.py @@ -1,3 +1,23 @@ def get_len_of_longest_substring(text: str) -> int: - # ваш код - return 0 \ No newline at end of file + text_len = len(text) + max_len = 0 + symbols_count = len(set(text)) + + for i in range(text_len): + f = False + + for j in range(i + max_len, text_len): + substring_len = j + 1 - i + + if len(set(text[i : j + 1])) == substring_len: + max_len = substring_len + if max_len == symbols_count: + f = True + break + else: + break + + if f: + break + + return max_len diff --git a/solutions/lesson06/task3.py b/solutions/lesson06/task3.py index 7449a1e7..484cb985 100644 --- a/solutions/lesson06/task3.py +++ b/solutions/lesson06/task3.py @@ -1,7 +1,9 @@ -def is_there_any_good_subarray( - nums: list[int], - k: int, -) -> bool: - - # ваш код +def is_there_any_good_subarray(nums: list[int], k: int) -> bool: + nums_len = len(nums) + for i in range(nums_len - 1): + for j in range(i + 1, nums_len): + s = sum(nums[i : j + 1]) + if s % k == 0: + return True + return False diff --git a/solutions/lesson06/task4.py b/solutions/lesson06/task4.py index 5b75a110..95aaccbc 100644 --- a/solutions/lesson06/task4.py +++ b/solutions/lesson06/task4.py @@ -1,3 +1,6 @@ def count_unique_words(text: str) -> int: - # ваш код - return 0 \ No newline at end of file + for i in text: + if not i.isalnum() and i != " ": + text = text.replace(i, "") + + return len(set(text.lower().split())) From d6628d2baf704669acc12f7a576fbf84457dd4af Mon Sep 17 00:00:00 2001 From: AntonLodygin Date: Tue, 28 Oct 2025 18:03:15 +0300 Subject: [PATCH 09/24] optimize solution of task3 --- solutions/lesson06/task3.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/solutions/lesson06/task3.py b/solutions/lesson06/task3.py index 484cb985..ae08a11c 100644 --- a/solutions/lesson06/task3.py +++ b/solutions/lesson06/task3.py @@ -1,8 +1,9 @@ def is_there_any_good_subarray(nums: list[int], k: int) -> bool: nums_len = len(nums) for i in range(nums_len - 1): + s = nums[i] for j in range(i + 1, nums_len): - s = sum(nums[i : j + 1]) + s += nums[j] if s % k == 0: return True From 39749ea9e30a717232f24c1fb05af5e1b6266cbe Mon Sep 17 00:00:00 2001 From: AntonLodygin Date: Fri, 14 Nov 2025 18:21:31 +0300 Subject: [PATCH 10/24] solutions lesson08 --- solutions/lesson08/task1.py | 12 ++++++++++-- solutions/lesson08/task2.py | 30 ++++++++++++++++++++++++------ 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/solutions/lesson08/task1.py b/solutions/lesson08/task1.py index 4390f6c8..a6e93196 100644 --- a/solutions/lesson08/task1.py +++ b/solutions/lesson08/task1.py @@ -1,5 +1,13 @@ from typing import Callable + def make_averager(accumulation_period: int) -> Callable[[float], float]: - # ваш код - pass \ No newline at end of file + daily_profits = [] + + def get_avg(profit: float) -> float: + daily_profits.append(profit) + if len(daily_profits) < accumulation_period: + return sum(daily_profits) / len(daily_profits) + return sum(daily_profits[-accumulation_period:]) / accumulation_period + + return get_avg diff --git a/solutions/lesson08/task2.py b/solutions/lesson08/task2.py index 6e4af870..088fbacd 100644 --- a/solutions/lesson08/task2.py +++ b/solutions/lesson08/task2.py @@ -1,10 +1,28 @@ +import time +from functools import wraps from typing import Callable, TypeVar T = TypeVar("T") -def collect_statistic( - statistics: dict[str, list[float, int]] -) -> Callable[[T], T]: - - # ваш код - pass \ No newline at end of file + +def collect_statistic(statistics: dict[str, list[float, int]]) -> Callable[[T], T]: + def _collect_statistic(func) -> T: + @wraps(func) + def wrapper(*args, **kwargs): + func_name = func.__name__ + start_time = time.time() + res = func(*args, **kwargs) + delta_time = time.time() - start_time + if func_name not in statistics: + statistics[func_name] = [delta_time, 1] + else: + time_avg, counter = statistics[func_name] + statistics[func_name] = [ + (time_avg * counter + delta_time) / (counter + 1), + counter + 1, + ] + return res + + return wrapper + + return _collect_statistic From c9b4f266b83066dde8ba3d07cf07dbb3a92e899b Mon Sep 17 00:00:00 2001 From: AntonLodygin Date: Tue, 18 Nov 2025 19:53:11 +0300 Subject: [PATCH 11/24] solution homework task1 --- homeworks/hw1/aggregate_segmentation.py | 69 ++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/homeworks/hw1/aggregate_segmentation.py b/homeworks/hw1/aggregate_segmentation.py index 1cdc176a..77ebfa03 100644 --- a/homeworks/hw1/aggregate_segmentation.py +++ b/homeworks/hw1/aggregate_segmentation.py @@ -1,3 +1,5 @@ +from uuid import UUID + ALLOWED_TYPES = { "spotter_word", "voice_human", @@ -5,6 +7,33 @@ } +def is_valid_uuid(uuid): + try: + UUID(uuid) + return True + except ValueError: + return False + + +def is_valid_segment(segment): + if "segment_id" not in segment: + return False + + if not is_valid_uuid(segment["segment_id"]): + return False + + if segment["type"] is None and segment["segment_start"] is None and segment["segment_end"] is None: + pass + elif (not isinstance(segment["type"], str) or not isinstance(segment["segment_start"], float) or + not isinstance(segment["segment_end"], float)): + return False + + if segment["type"] not in ALLOWED_TYPES and segment["type"] is not None: + return False + + return True + + def aggregate_segmentation( segmentation_data: list[dict[str, str | float | None]], ) -> tuple[dict[str, dict[str, dict[str, str | float]]], list[str]]: @@ -24,5 +53,41 @@ def aggregate_segmentation( Список `audio_id` (str), которые требуют переразметки. """ - # ваш код - return {}, [] + audio = {} + not_valid_audio_id = set() + + for i in segmentation_data: + audio_id = i["audio_id"] + segment_id = i["segment_id"] + start = i["segment_start"] + end = i["segment_end"] + segment_type = i["type"] + + if is_valid_uuid(audio_id) and is_valid_segment(i): + if audio_id not in audio: + audio[audio_id] = { + segment_id: { + "end": end, + "start": start, + "type": segment_type + } + } + else: + if segment_id not in audio[audio_id]: + audio[audio_id][segment_id] = { + "end": end, + "start": start, + "type": segment_type + } + else: + segment = audio[audio_id][segment_id] + if segment["end"] != end or segment["start"] != start or segment["type"] != segment_type: + not_valid_audio_id.add(audio_id) + + else: + not_valid_audio_id.add(audio_id) + + audio = {a_id: segments if not any(not any(s.values()) for s_id, s in segments.items()) else {} for a_id, segments + in audio.items()} + + return audio, list(not_valid_audio_id) From fa93202effe466e4f5ba8f68240ef63a25bd1c26 Mon Sep 17 00:00:00 2001 From: AntonLodygin Date: Wed, 19 Nov 2025 00:38:03 +0300 Subject: [PATCH 12/24] solution homework task2 --- homeworks/hw1/convert_exception.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/homeworks/hw1/convert_exception.py b/homeworks/hw1/convert_exception.py index fe5c770f..2b2ab2fb 100644 --- a/homeworks/hw1/convert_exception.py +++ b/homeworks/hw1/convert_exception.py @@ -4,6 +4,8 @@ TypeVar, ) +from functools import wraps + P = ParamSpec("P") R = TypeVar("R") @@ -24,5 +26,14 @@ def convert_exceptions_to_api_compitable_ones( Декоратор для непосредственного использования. """ - # ваш код - pass + def decorator(func): + @wraps(func) + def wrapper(*args, **kwargs): + try: + func(*args, **kwargs) + except Exception as e: + raise exception_to_api_exception[type(e)] + + return wrapper + + return decorator From ec65c264a78b699cdc1079521e53d0635b6e8e5c Mon Sep 17 00:00:00 2001 From: AntonLodygin Date: Wed, 19 Nov 2025 12:02:20 +0300 Subject: [PATCH 13/24] modified solution task2 --- homeworks/hw1/convert_exception.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/homeworks/hw1/convert_exception.py b/homeworks/hw1/convert_exception.py index 2b2ab2fb..8aedfc5c 100644 --- a/homeworks/hw1/convert_exception.py +++ b/homeworks/hw1/convert_exception.py @@ -32,7 +32,9 @@ def wrapper(*args, **kwargs): try: func(*args, **kwargs) except Exception as e: - raise exception_to_api_exception[type(e)] + if type(e) in exception_to_api_exception: + raise exception_to_api_exception[type(e)] from None + raise e return wrapper From 099f7aedb3b5378e4976de5477fd529e524409a0 Mon Sep 17 00:00:00 2001 From: AntonLodygin Date: Thu, 20 Nov 2025 00:45:13 +0300 Subject: [PATCH 14/24] solution homework task3 --- homeworks/hw1/backoff.py | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/homeworks/hw1/backoff.py b/homeworks/hw1/backoff.py index 696ffa73..6e0ad475 100644 --- a/homeworks/hw1/backoff.py +++ b/homeworks/hw1/backoff.py @@ -5,6 +5,7 @@ ParamSpec, TypeVar, ) +from functools import wraps P = ParamSpec("P") R = TypeVar("R") @@ -34,5 +35,32 @@ def backoff( ValueError, если были переданы невозможные аргументы. """ - # ваш код - pass + if retry_amount < 1 or retry_amount > 100: + raise ValueError + if timeout_start <= 0 or timeout_start > 10: + raise ValueError + if timeout_max <= 0 or timeout_max > 10: + raise ValueError + if backoff_scale <= 0 or backoff_scale > 10: + raise ValueError + + def decorator(func): + @wraps(func) + def wrapper(*args, **kwargs): + nonlocal timeout_start + + last_error = None + for i in range(retry_amount): + try: + return func(*args, **kwargs) + except backoff_triggers as e: + sleep(timeout_start + uniform(0, 0.5)) + if timeout_start < timeout_max: + timeout_start *= backoff_scale + last_error = e + + raise last_error + + return wrapper + + return decorator From b413135e0c4df85de4a5484e97b6c7c0ca5182a7 Mon Sep 17 00:00:00 2001 From: AntonLodygin Date: Thu, 20 Nov 2025 15:43:55 +0300 Subject: [PATCH 15/24] solution homework task4 --- homeworks/hw1/cache.py | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/homeworks/hw1/cache.py b/homeworks/hw1/cache.py index 9eb1d5d2..d63f64a3 100644 --- a/homeworks/hw1/cache.py +++ b/homeworks/hw1/cache.py @@ -1,3 +1,4 @@ +from functools import wraps from typing import ( Callable, ParamSpec, @@ -23,5 +24,34 @@ def lru_cache(capacity: int) -> Callable[[Callable[P, R]], Callable[P, R]]: для получения целого числа. ValueError, если после округления capacity - число, меньшее 1. """ - # ваш код - pass + + try: + capacity = round(capacity) + except TypeError: + raise TypeError(f"{type(capacity).__name__} неверный тип для размера кэша") from None + if capacity < 1: + raise ValueError + + cache = {} + + def decorator(func): + @wraps(func) + def wrapper(*args, **kwargs): + func_args = args + tuple(sorted(kwargs.items())) + if func_args in cache: + cache[func_args][1] = 0 + return cache[func_args][0] + else: + for k in cache.keys(): + cache[k][1] += 1 + + if len(cache) == capacity: + least_used_key = sorted(cache.items(), key=lambda x: x[1][1])[-1][0] + cache.pop(least_used_key) + res = func(*args, **kwargs) + cache[func_args] = [res, 0] + return res + + return wrapper + + return decorator From ce43573603606c8a950f2f33b52a6f1d10bad7a0 Mon Sep 17 00:00:00 2001 From: AntonLodygin Date: Thu, 20 Nov 2025 19:33:33 +0300 Subject: [PATCH 16/24] modified solution homework task4 --- homeworks/hw1/cache.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/homeworks/hw1/cache.py b/homeworks/hw1/cache.py index d63f64a3..3da4fa3f 100644 --- a/homeworks/hw1/cache.py +++ b/homeworks/hw1/cache.py @@ -1,4 +1,5 @@ from functools import wraps +from collections import OrderedDict from typing import ( Callable, ParamSpec, @@ -32,24 +33,21 @@ def lru_cache(capacity: int) -> Callable[[Callable[P, R]], Callable[P, R]]: if capacity < 1: raise ValueError - cache = {} + cache = OrderedDict() def decorator(func): @wraps(func) def wrapper(*args, **kwargs): func_args = args + tuple(sorted(kwargs.items())) if func_args in cache: - cache[func_args][1] = 0 - return cache[func_args][0] - else: - for k in cache.keys(): - cache[k][1] += 1 + cache.move_to_end(func_args) + return cache[func_args] + else: if len(cache) == capacity: - least_used_key = sorted(cache.items(), key=lambda x: x[1][1])[-1][0] - cache.pop(least_used_key) + cache.popitem(last=False) res = func(*args, **kwargs) - cache[func_args] = [res, 0] + cache[func_args] = res return res return wrapper From 9c2879661e95768e99f5530f4148918bafc3be46 Mon Sep 17 00:00:00 2001 From: AntonLodygin Date: Thu, 20 Nov 2025 19:35:58 +0300 Subject: [PATCH 17/24] formatting code in homework tasks --- homeworks/hw1/aggregate_segmentation.py | 44 ++++++++++++++----------- homeworks/hw1/backoff.py | 2 +- homeworks/hw1/cache.py | 2 +- homeworks/hw1/convert_exception.py | 3 +- 4 files changed, 27 insertions(+), 24 deletions(-) diff --git a/homeworks/hw1/aggregate_segmentation.py b/homeworks/hw1/aggregate_segmentation.py index 77ebfa03..69ad77fa 100644 --- a/homeworks/hw1/aggregate_segmentation.py +++ b/homeworks/hw1/aggregate_segmentation.py @@ -22,10 +22,17 @@ def is_valid_segment(segment): if not is_valid_uuid(segment["segment_id"]): return False - if segment["type"] is None and segment["segment_start"] is None and segment["segment_end"] is None: + if ( + segment["type"] is None + and segment["segment_start"] is None + and segment["segment_end"] is None + ): pass - elif (not isinstance(segment["type"], str) or not isinstance(segment["segment_start"], float) or - not isinstance(segment["segment_end"], float)): + elif ( + not isinstance(segment["type"], str) + or not isinstance(segment["segment_start"], float) + or not isinstance(segment["segment_end"], float) + ): return False if segment["type"] not in ALLOWED_TYPES and segment["type"] is not None: @@ -65,29 +72,26 @@ def aggregate_segmentation( if is_valid_uuid(audio_id) and is_valid_segment(i): if audio_id not in audio: - audio[audio_id] = { - segment_id: { - "end": end, - "start": start, - "type": segment_type - } - } + audio[audio_id] = {segment_id: {"end": end, "start": start, "type": segment_type}} else: if segment_id not in audio[audio_id]: - audio[audio_id][segment_id] = { - "end": end, - "start": start, - "type": segment_type - } + audio[audio_id][segment_id] = {"end": end, "start": start, "type": segment_type} else: segment = audio[audio_id][segment_id] - if segment["end"] != end or segment["start"] != start or segment["type"] != segment_type: + if ( + segment["end"] != end + or segment["start"] != start + or segment["type"] != segment_type + ): not_valid_audio_id.add(audio_id) else: not_valid_audio_id.add(audio_id) - audio = {a_id: segments if not any(not any(s.values()) for s_id, s in segments.items()) else {} for a_id, segments - in audio.items()} - - return audio, list(not_valid_audio_id) + return ( + { + a_id: segments if not any(not any(s.values()) for s_id, s in segments.items()) else {} + for a_id, segments in audio.items() + }, + list(not_valid_audio_id), + ) diff --git a/homeworks/hw1/backoff.py b/homeworks/hw1/backoff.py index 6e0ad475..2a422417 100644 --- a/homeworks/hw1/backoff.py +++ b/homeworks/hw1/backoff.py @@ -1,3 +1,4 @@ +from functools import wraps from random import uniform from time import sleep from typing import ( @@ -5,7 +6,6 @@ ParamSpec, TypeVar, ) -from functools import wraps P = ParamSpec("P") R = TypeVar("R") diff --git a/homeworks/hw1/cache.py b/homeworks/hw1/cache.py index 3da4fa3f..0f74eb54 100644 --- a/homeworks/hw1/cache.py +++ b/homeworks/hw1/cache.py @@ -1,5 +1,5 @@ -from functools import wraps from collections import OrderedDict +from functools import wraps from typing import ( Callable, ParamSpec, diff --git a/homeworks/hw1/convert_exception.py b/homeworks/hw1/convert_exception.py index 8aedfc5c..3a94c5cf 100644 --- a/homeworks/hw1/convert_exception.py +++ b/homeworks/hw1/convert_exception.py @@ -1,11 +1,10 @@ +from functools import wraps from typing import ( Callable, ParamSpec, TypeVar, ) -from functools import wraps - P = ParamSpec("P") R = TypeVar("R") From 180bd61bebbcebc5eff5c6f5cb200ed2822a27a6 Mon Sep 17 00:00:00 2001 From: AntonLodygin Date: Sat, 22 Nov 2025 12:41:51 +0300 Subject: [PATCH 18/24] used default dict --- homeworks/hw1/cache.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/homeworks/hw1/cache.py b/homeworks/hw1/cache.py index 0f74eb54..7d8dc65a 100644 --- a/homeworks/hw1/cache.py +++ b/homeworks/hw1/cache.py @@ -1,4 +1,3 @@ -from collections import OrderedDict from functools import wraps from typing import ( Callable, @@ -33,19 +32,19 @@ def lru_cache(capacity: int) -> Callable[[Callable[P, R]], Callable[P, R]]: if capacity < 1: raise ValueError - cache = OrderedDict() + cache = {} def decorator(func): @wraps(func) def wrapper(*args, **kwargs): func_args = args + tuple(sorted(kwargs.items())) if func_args in cache: - cache.move_to_end(func_args) + cache[func_args] = cache.pop(func_args) return cache[func_args] else: if len(cache) == capacity: - cache.popitem(last=False) + cache.pop(next(iter(cache.keys()))) res = func(*args, **kwargs) cache[func_args] = res return res From ab61c375668795dd9aabad17e359609e3a3e54cb Mon Sep 17 00:00:00 2001 From: AntonLodygin Date: Sat, 22 Nov 2025 13:06:21 +0300 Subject: [PATCH 19/24] modified homework task1 --- homeworks/hw1/aggregate_segmentation.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/homeworks/hw1/aggregate_segmentation.py b/homeworks/hw1/aggregate_segmentation.py index 69ad77fa..8909bfb9 100644 --- a/homeworks/hw1/aggregate_segmentation.py +++ b/homeworks/hw1/aggregate_segmentation.py @@ -88,10 +88,12 @@ def aggregate_segmentation( else: not_valid_audio_id.add(audio_id) - return ( - { - a_id: segments if not any(not any(s.values()) for s_id, s in segments.items()) else {} - for a_id, segments in audio.items() - }, - list(not_valid_audio_id), - ) + audio_without_empty_segments = {} + for a_id, segments in audio.items(): + new_segments = {} + for s_id, s in segments.items(): + if any(s.values()): + new_segments[s_id] = s + audio_without_empty_segments[a_id] = new_segments + + return audio_without_empty_segments, list(not_valid_audio_id) From 92cbb23b94f53166df0ae9fe4a27b6b79daf44cd Mon Sep 17 00:00:00 2001 From: AntonLodygin Date: Sun, 30 Nov 2025 15:11:27 +0300 Subject: [PATCH 20/24] modified solution task1 --- homeworks/hw1/aggregate_segmentation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeworks/hw1/aggregate_segmentation.py b/homeworks/hw1/aggregate_segmentation.py index 8909bfb9..a9ba1a69 100644 --- a/homeworks/hw1/aggregate_segmentation.py +++ b/homeworks/hw1/aggregate_segmentation.py @@ -64,7 +64,7 @@ def aggregate_segmentation( not_valid_audio_id = set() for i in segmentation_data: - audio_id = i["audio_id"] + audio_id = i["audio_id"] if "audio_id" in i else None segment_id = i["segment_id"] start = i["segment_start"] end = i["segment_end"] From c57de7389271227ff91129ba15d33bc8ebb4c520 Mon Sep 17 00:00:00 2001 From: AntonLodygin Date: Tue, 2 Dec 2025 01:08:39 +0300 Subject: [PATCH 21/24] solution lesson11 --- solutions/lesson11/task1.py | 107 ++++++++++++++++++++++++++++++++++-- 1 file changed, 102 insertions(+), 5 deletions(-) diff --git a/solutions/lesson11/task1.py b/solutions/lesson11/task1.py index 6a15f31f..d71326c4 100644 --- a/solutions/lesson11/task1.py +++ b/solutions/lesson11/task1.py @@ -1,10 +1,107 @@ +from math import acos + + class Vector2D: + _abscissa = 0.0 + _ordinate = 0.0 + + def __init__(self, abscissa=0.0, ordinate=0.0): + self._abscissa = round(abscissa, 12) + self._ordinate = round(ordinate, 12) + + @property + def abscissa(self): + return self._abscissa + + @property + def ordinate(self): + return self._ordinate + + def __repr__(self): + return f"Vector2D(abscissa={self._abscissa}, ordinate={self._ordinate})" + + def __eq__(self, other): + if not isinstance(other, Vector2D): + return False + + return self._ordinate == other.ordinate and self._abscissa == other.abscissa + + def __ne__(self, other): + return not (self == other) + + def __gt__(self, other): + if not isinstance(other, Vector2D): + raise TypeError() + + return self._abscissa > other.abscissa or ( + self._abscissa == other.abscissa and self._ordinate > other.ordinate + ) + + def __lt__(self, other): + return not (self > other) and not (self == other) + + def __ge__(self, other): + return not (self < other) + + def __le__(self, other): + return not (self > other) + + def __abs__(self): + return (self._abscissa**2 + self._ordinate**2) ** 0.5 + + def __bool__(self): + return abs(self) != 0 + + def __mul__(self, num): + return Vector2D(self._abscissa * num, self._ordinate * num) + + def __rmul__(self, num): + return self * num + + def __truediv__(self, num): + return self * (1 / num) + + def __add__(self, other): + if isinstance(other, (float, int)): + return Vector2D(self._abscissa + other, self._ordinate + other) + if isinstance(other, Vector2D): + return Vector2D(self._abscissa + other.abscissa, self._ordinate + other.ordinate) + + raise TypeError() + + def __radd__(self, other): + return self + other + + def __sub__(self, other): + return self + -other + + def __neg__(self): + return Vector2D(-self._abscissa, -self._ordinate) + + def __int__(self): + return int(abs(self)) + + def __float__(self): + return abs(self) + + def __complex__(self): + return complex(self._abscissa, self._ordinate) + + def __matmul__(self, other): + if not isinstance(other, Vector2D): + raise TypeError() + + return self._abscissa * other.abscissa + self._ordinate * other.ordinate + def conj(self) -> "Vector2D": - # ваш код - return Vector2D() + return Vector2D(self._abscissa, -self._ordinate) def get_angle(self, other: "Vector2D") -> float: - # ваш код - return 0 + if not isinstance(other, Vector2D): + raise TypeError() - # ваш код + if (not self._abscissa and not self._ordinate) or ( + not other.abscissa and not other.ordinate + ): + raise ValueError("Нельзя рассчитать угол с нулевым вектором") + return acos((self @ other) / (abs(self) * abs(other))) From ffb669177bca4d0fc01b8840a107e569316e4ff1 Mon Sep 17 00:00:00 2001 From: AntonLodygin Date: Sat, 13 Dec 2025 01:20:50 +0300 Subject: [PATCH 22/24] solution lesson12 --- solutions/lesson12/task1.py | 13 +++++++++++-- solutions/lesson12/task2.py | 13 +++++++++++-- solutions/lesson12/task3.py | 31 +++++++++++++++++++++++-------- 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/solutions/lesson12/task1.py b/solutions/lesson12/task1.py index d1bb828c..f413bd85 100644 --- a/solutions/lesson12/task1.py +++ b/solutions/lesson12/task1.py @@ -2,5 +2,14 @@ def chunked(iterable: Iterable, size: int) -> Generator[tuple[Any], None, None]: - # ваш код - ... + arr = [] + arr_size = 0 + for i in iterable: + arr.append(i) + arr_size += 1 + if arr_size == size: + yield tuple(arr) + arr = [] + arr_size = 0 + if arr: + yield tuple(arr) diff --git a/solutions/lesson12/task2.py b/solutions/lesson12/task2.py index 3ad802ee..ef6bf1ac 100644 --- a/solutions/lesson12/task2.py +++ b/solutions/lesson12/task2.py @@ -2,5 +2,14 @@ def circle(iterable: Iterable) -> Generator[Any, None, None]: - # ваш код - ... + elems = [] + for i in iterable: + yield i + elems.append(i) + + if not elems: + return + + while True: + for i in elems: + yield i diff --git a/solutions/lesson12/task3.py b/solutions/lesson12/task3.py index 64c112cc..a11b8493 100644 --- a/solutions/lesson12/task3.py +++ b/solutions/lesson12/task3.py @@ -2,11 +2,26 @@ class FileOut: - def __init__( - self, - path_to_file: str, - ) -> None: - # ваш код - ... - - # ваш код + file = None + path_to_file = None + original_stdout = None + + def __init__(self, path_to_file: str) -> None: + self.path_to_file = path_to_file + + def __enter__(self): + self.file = open(self.path_to_file, "w") + self.original_stdout = sys.stdout + sys.stdout = self.file + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + if self.original_stdout is not None: + sys.stdout = self.original_stdout + self.original_stdout = None + + if self.file: + self.file.close() + self.file = None + + return False From be9b7fad0a5a851093a28d041daa4bba30d86d2f Mon Sep 17 00:00:00 2001 From: bermo0d Date: Fri, 10 Apr 2026 23:52:31 +0300 Subject: [PATCH 23/24] sotution task1 --- solutions/sem02/lesson07/task1.py | 51 +++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/solutions/sem02/lesson07/task1.py b/solutions/sem02/lesson07/task1.py index 3a505d89..05d2e88e 100644 --- a/solutions/sem02/lesson07/task1.py +++ b/solutions/sem02/lesson07/task1.py @@ -13,8 +13,55 @@ def visualize_diagrams( ordinates: np.ndarray, diagram_type: Any, ) -> None: - # ваш код - pass + if abscissa.shape[0] != ordinates.shape[0] or diagram_type not in ["hist", "box", "violin"]: + raise ShapeMismatchError + fig = plt.figure(figsize=(8, 8)) + grid = plt.GridSpec(4, 4, wspace=0.2, hspace=0.2) + scat_graph = fig.add_subplot(grid[0:-1, 1:]) + graph1 = fig.add_subplot(grid[0:-1, 0], sharey=scat_graph) + graph2 = fig.add_subplot(grid[-1, 1:], sharex=scat_graph) + scat_graph.scatter(abscissa, ordinates, color="#00FF00", alpha=0.3) + + if diagram_type == "box": + graph1.boxplot( + ordinates, + boxprops={"color": "#00FF00"}, + ) + graph2.boxplot( + abscissa, + vert=False, + boxprops={"color": "#00FF00"}, + ) + + if diagram_type == "violin": + viol_vertical = graph1.violinplot( + ordinates, + showmedians=True, + ) + for body in viol_vertical["bodies"]: + body.set_facecolor("#00FF00") + body.set_edgecolor("black") + for parts in viol_vertical: + if parts == "bodies": + continue + viol_vertical[parts].set_edgecolor("black") + + viol_horizontal = graph2.violinplot(abscissa, vert=False, showmedians=True) + for body in viol_horizontal["bodies"]: + body.set_facecolor("#00FF00") + body.set_edgecolor("black") + for parts in viol_horizontal: + if parts == "bodies": + continue + viol_horizontal[parts].set_edgecolor("black") + + if diagram_type == "hist": + graph1.hist( + ordinates, orientation="horizontal", bins=50, color="#00FF00", alpha=0.3, edgecolor="black" + ) + graph2.hist(abscissa, bins=50, color="#00FF00", alpha=0.3, edgecolor="black") + graph1.invert_xaxis() + graph2.invert_yaxis() if __name__ == "__main__": From b1a61598810a70b02394e2888258b191fd2ccbb8 Mon Sep 17 00:00:00 2001 From: bermo0d Date: Fri, 10 Apr 2026 23:59:50 +0300 Subject: [PATCH 24/24] sotution task2 --- solutions/sem02/lesson07/task2.py | 50 ++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/solutions/sem02/lesson07/task2.py b/solutions/sem02/lesson07/task2.py index decd607e..2cba87fb 100644 --- a/solutions/sem02/lesson07/task2.py +++ b/solutions/sem02/lesson07/task2.py @@ -1 +1,49 @@ -# ваш код (используйте функции или классы для решения данной задачи) +import json + +import matplotlib.pyplot as plt +import numpy as np + + +def mitrial_disiase_analyse(path_to_json): + with open(path_to_json, "r", encoding="utf-8") as f: + data_dict = json.load(f) + + before_data = np.array(data_dict["before"]) + after_data = np.array(data_dict["after"]) + + _, counts_before = np.unique(before_data, return_counts=True) + _, counts_after = np.unique(after_data, return_counts=True) + + fig, axis = plt.subplots(figsize=(9, 9)) + axis: plt.Axes + labels = np.array(["I", "II", "III", "IV"]) + + x = np.arange(labels.size) + width = 0.35 + + axis.set_title("анализ заболевания", fontsize=17,) + axis.set_ylabel("кол-во людей", fontsize=12) + + axis.bar( + x - width / 2, + counts_before, + width=width, + color="red", + edgecolor="red", + label="before", + ) + axis.bar( + x + width / 2, + counts_after, + width=width, + color="blue", + edgecolor="blue", + label="after", + ) + + axis.set_xticks(x, labels=labels, weight="bold") + axis.tick_params(axis="x", labelsize=14, labelcolor="dimgray") + axis.legend() + + plt.savefig("mitral_disease_analysis.png") +