diff --git a/.coverage b/.coverage
new file mode 100644
index 00000000..d7376cf5
Binary files /dev/null and b/.coverage differ
diff --git a/.github/workflows/trying.ipynb b/.github/workflows/trying.ipynb
new file mode 100644
index 00000000..908a1b10
--- /dev/null
+++ b/.github/workflows/trying.ipynb
@@ -0,0 +1,1616 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "08c46c22",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "9999999999\n"
+ ]
+ }
+ ],
+ "source": [
+ "def get_sum_of_prime_divisors(num: int) -> int:\n",
+ " n = num\n",
+ " sum_of_divisors = 0\n",
+ " for i in range(2, int(num**0.5) + 1):\n",
+ " if num % i == 0:\n",
+ " sum_of_divisors += i\n",
+ " while num % i == 0:\n",
+ " num //= i\n",
+ " if sum_of_divisors == 0:\n",
+ " return n\n",
+ " return sum_of_divisors\n",
+ "\n",
+ "\n",
+ "print(get_sum_of_prime_divisors(10000000000 - 1))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "id": "9abf76e1",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[1, 2]\n",
+ "[1, 2, 3]\n",
+ "[2, 3]\n",
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "def is_there_any_good_subarray(nums: list[int], k: int) -> bool:\n",
+ " if len(nums) < 2:\n",
+ " return False\n",
+ " elif len(nums) == 2:\n",
+ " sum = 0\n",
+ " for subarr in nums:\n",
+ " sum+=subarr\n",
+ " if sum%k==0:\n",
+ " return True\n",
+ " else:\n",
+ " return False\n",
+ " for i in range(0,len(nums) - 1):\n",
+ " for j in range(i+2, len(nums)+1):\n",
+ " sum=0\n",
+ " print(nums[i:j])\n",
+ " for subarr in nums[i:j]:\n",
+ " sum += subarr\n",
+ " if sum % k == 0:\n",
+ " return True\n",
+ " return False\n",
+ "print(is_there_any_good_subarray([1, 2, 3], 5))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "fd7d5d7d",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "21\n"
+ ]
+ }
+ ],
+ "source": [
+ "def get_gcd(num1: int, num2: int) -> int:\n",
+ " while max(num1, num2) % min(num1, num2) != 0:\n",
+ " if num1 > num2:\n",
+ " num1 = num1 % num2\n",
+ " else:\n",
+ " num2 = num2 % num1\n",
+ " return min(num1, num2)\n",
+ "\n",
+ "\n",
+ "print(get_gcd(1071, 147))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "2a62ad6c",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "{2, 3}\n",
+ "5\n"
+ ]
+ }
+ ],
+ "source": [
+ "def IsPrime(num: int) -> bool:\n",
+ " d = 2\n",
+ " while num % d != 0:\n",
+ " d += 1\n",
+ " return d == num\n",
+ "\n",
+ "\n",
+ "def get_sum_of_prime_divisors(num: int) -> int:\n",
+ " sum_of_divisors = 0\n",
+ " divisors = []\n",
+ " i = 2\n",
+ " while num != 1:\n",
+ " if num % i == 0:\n",
+ " if IsPrime(i):\n",
+ " divisors.append(i)\n",
+ " num //= i\n",
+ " i = 2\n",
+ "\n",
+ " else:\n",
+ " i += 1\n",
+ " divisors = set(divisors)\n",
+ " for i in divisors:\n",
+ " sum_of_divisors += i\n",
+ " return sum_of_divisors\n",
+ "\n",
+ "\n",
+ "print(get_sum_of_prime_divisors(12))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "4fd42f4f",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "def is_palindrome(num: int) -> bool:\n",
+ " if num < 0:\n",
+ " return False\n",
+ " num_reversed = 0\n",
+ " num_reversed += num % 10\n",
+ " num_current = num\n",
+ " num_current //= 10\n",
+ " while num_current > 0:\n",
+ " num_reversed *= 10\n",
+ " num_reversed += num_current % 10\n",
+ " num_current //= 10\n",
+ " return num == num_reversed\n",
+ "\n",
+ "\n",
+ "print(is_palindrome(121))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "047df546",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1001\n"
+ ]
+ }
+ ],
+ "source": [
+ "num = 9\n",
+ "answer = 0\n",
+ "position = 1\n",
+ "while num > 0:\n",
+ " answer = answer + position * (num % 2)\n",
+ " position *= 10\n",
+ " num //= 2\n",
+ "print(answer)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "b8b93d7a",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1001\n",
+ "9\n"
+ ]
+ },
+ {
+ "ename": "",
+ "evalue": "",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[1;31mThe Kernel crashed while executing code in the current cell or a previous cell. \n",
+ "\u001b[1;31mPlease review the code in the cell(s) to identify a possible cause of the failure. \n",
+ "\u001b[1;31mClick here for more info. \n",
+ "\u001b[1;31mView Jupyter log for further details."
+ ]
+ }
+ ],
+ "source": [
+ "def flip_bits_in_range(num: int, left_bit: int, right_bit: int) -> int:\n",
+ " answer = 0\n",
+ " position = 1\n",
+ " curr_bit = 1\n",
+ " while num > 0:\n",
+ " if curr_bit >= left_bit and curr_bit <= right_bit:\n",
+ " if num % 2 == 1:\n",
+ " answer = answer + position * 0\n",
+ " else:\n",
+ " answer = answer + position * 1\n",
+ " else:\n",
+ " answer = answer + position * (num % 2)\n",
+ " position *= 10\n",
+ " num //= 2\n",
+ " curr_bit += 1\n",
+ " num = 0\n",
+ " power = 0\n",
+ " print(answer)\n",
+ " while answer > 0:\n",
+ " digit = answer % 10\n",
+ " num += digit * (2**power)\n",
+ " answer //= 10\n",
+ " power += 1\n",
+ " return num\n",
+ "\n",
+ "\n",
+ "print(flip_bits_in_range(0b1011, 2, 2))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 30,
+ "id": "693fdb92",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "0"
+ ]
+ },
+ "execution_count": 30,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "def get_nth_digit(num: int) -> int:\n",
+ " count_digit = 1\n",
+ " flag_finish = False\n",
+ " answer = 0\n",
+ " i = 0\n",
+ " while True:\n",
+ " k = i * 2\n",
+ " while k > 0:\n",
+ " if num == count_digit:\n",
+ " answer = k % 10\n",
+ " flag_finish = True\n",
+ " break\n",
+ " k //= 10\n",
+ " count_digit += 1\n",
+ " if flag_finish:\n",
+ " break\n",
+ " i += 1\n",
+ " return answer\n",
+ "\n",
+ "\n",
+ "get_nth_digit(5)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 57,
+ "id": "570f59c2",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "[[1, 4]]\n"
+ ]
+ }
+ ],
+ "source": [
+ "def merge_intervals(intervals: list[list[int, int]]) -> list[list[int, int]]:\n",
+ " intervals.sort(key=lambda x: x[0])\n",
+ " if len(intervals) == 0:\n",
+ " return []\n",
+ " newintervals = []\n",
+ " start, finish = intervals[0][0], intervals[0][1]\n",
+ " flag1 = True\n",
+ " for i in intervals:\n",
+ " if flag1:\n",
+ " flag1 = False\n",
+ " continue # скип первого элемента(костыль)\n",
+ " if start < i[0] and finish > i[1]:\n",
+ " continue\n",
+ " elif finish >= i[0] and start <= i[0]:\n",
+ " finish = i[1]\n",
+ " else:\n",
+ " newintervals.append([start, finish])\n",
+ " start = i[0]\n",
+ " finish = i[1]\n",
+ " newintervals.append([start, finish])\n",
+ " return newintervals\n",
+ "\n",
+ "\n",
+ "print(merge_intervals([[1, 4], [2, 3], [1, 4]]))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "fb839bd5",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "True\n"
+ ]
+ }
+ ],
+ "source": [
+ "def is_punctuation(text: str) -> bool:\n",
+ " for i in text:\n",
+ " numb_code = ord(i)\n",
+ " if not (\n",
+ " (numb_code >= 32 and numb_code <= 47)\n",
+ " or (numb_code >= 160 and numb_code <= 255)\n",
+ " or (numb_code >= 8192 and numb_code <= 8303)\n",
+ " or (numb_code >=ё 11776 and numb_code <= 11903)\n",
+ " or (numb_code >= 12288 and numb_code <= 12351)\n",
+ " )\n",
+ " return False\n",
+ " return True\n",
+ "\n",
+ "\n",
+ "print(is_punctuation(\"!!!!!;q';\"))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "c55fc9ef",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "def unzip(compress_text: str) -> str:\n",
+ " result = \"\"\n",
+ " compress_text = compress_text.split(\" \")\n",
+ " for i in compress_text:\n",
+ " if \"*\" not in i:\n",
+ " result += i\n",
+ " else:\n",
+ " result += i[:-2] * int(i[-1])\n",
+ " return result\n",
+ "\n",
+ "\n",
+ "print(unzip(\"a*10\"))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "66072e10",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "False\n"
+ ]
+ }
+ ],
+ "source": [
+ "def reg_validator(reg_expr: str, text: str) -> bool:\n",
+ " i, j = 0, 0\n",
+ " while i < len(reg_expr) and j < len(text):\n",
+ " symbol = reg_expr[i]\n",
+ " if symbol == \"d\":\n",
+ " if not text[j].isdigit():\n",
+ " print(i)\n",
+ " return False\n",
+ " while j < len(text) and text[j].isdigit():\n",
+ " j += 1\n",
+ " elif symbol == \"p\":\n",
+ " if not text[j].isalpha():\n",
+ " return False\n",
+ " while j < len(text) and text[j].isalpha():\n",
+ " j += 1\n",
+ " elif symbol == \"s\":\n",
+ " if not (text[j].isalpha() or text[j].isdigit()):\n",
+ " return False\n",
+ " while j < len(text) and (text[j].isalpha() or text[j].isdigit()):\n",
+ " j += 1\n",
+ " else:\n",
+ " if text[j] != symbol:\n",
+ " return False\n",
+ " j += 1\n",
+ " i += 1\n",
+ "\n",
+ " return i == len(reg_expr) and j == len(text)\n",
+ "\n",
+ "\n",
+ "print(reg_validator(\"w\", \"hello\"))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "7a1295ce",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "2\n"
+ ]
+ }
+ ],
+ "source": [
+ "def get_sum_of_prime_divisors(num: int) -> int:\n",
+ " n = num\n",
+ " if n == 1:\n",
+ " return 0\n",
+ " sum_of_divisors = 0\n",
+ " for i in range(2, int(num**0.5) + 1):\n",
+ " if num % i == 0:\n",
+ " sum_of_divisors += i\n",
+ " while num % i == 0:\n",
+ " num //= i\n",
+ " if sum_of_divisors == 0:\n",
+ " return n\n",
+ " return sum_of_divisors\n",
+ "print(get_sum_of_prime_divisors(26))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "id": "f34569a9",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "10\n",
+ "XL\n"
+ ]
+ }
+ ],
+ "source": [
+ "def int_to_roman(num: int) -> str:\n",
+ " roman_numbers = { 1000 : \"M\", 500 : \"D\", 100 : \"C\", \n",
+ " 50 : \"L\", 10 : \"X\", 5 : \"V\", 1 : \"I\"}\n",
+ " roman_digits = [1000, 500, 100, 50, 10, 5, 1]\n",
+ " index = 0\n",
+ " result = ''\n",
+ " flag_close = False\n",
+ " while index < len(roman_digits) and num > 0:\n",
+ " if not flag_close and (num - roman_digits[index]) < 0:\n",
+ " flag_close = True\n",
+ " elif not flag_close:\n",
+ " result += roman_numbers[roman_digits[index]]\n",
+ " num -= roman_digits[index]\n",
+ " elif flag_close:\n",
+ " if (index == 0 or index == 2 or index == 4) and (num - (roman_digits[index] - 10 ** ((str(roman_digits[index]).count('0')) - 1))) >= 0:\n",
+ " num -= (roman_digits[index] - 10 ** ((str(roman_digits[index]).count('0')) - 1))\n",
+ " result += roman_numbers[10 ** ((str(roman_digits[index]).count('0')) - 1)]+roman_numbers[roman_digits[index]]\n",
+ " flag_close = False\n",
+ " index+=1 \n",
+ " elif index != 2 and index!= 0 and index != 4 and (num - (roman_digits[index] - 10 ** str(roman_digits[index]).count('0'))) >= 0:\n",
+ " print( 10 ** str(roman_digits[index]).count('0'))\n",
+ " result += roman_numbers[10 ** str(roman_digits[index]).count('0')]+roman_numbers[roman_digits[index]]\n",
+ " num -= (roman_digits[index] - 10 ** str(roman_digits[index]).count('0'))\n",
+ " flag_close = False\n",
+ " index+=1\n",
+ " else:\n",
+ " flag_close = False\n",
+ " index+=1\n",
+ " return result\n",
+ "print(int_to_roman(40))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 24,
+ "id": "2ae168bc",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "4"
+ ]
+ },
+ "execution_count": 24,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "len(set('pwwwkew'))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "id": "fbde457b",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "18.329926258226045 0.06225318726752254\n"
+ ]
+ }
+ ],
+ "source": [
+ "rad = float(input())\n",
+ "i = 5.1*10**(-4)*(1453*2+576.02)*(rad**2) - 5.5\n",
+ "progri = i * (4*(0.005/rad)**2 + (1/(1453+1453+576.02))**2+0.002**2)**0.5\n",
+ "print(i, progri)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "114c276f",
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "ImportError",
+ "evalue": "cannot import name 'NoneType' from 'typing' (c:\\Users\\Shanechka\\AppData\\Local\\Programs\\Python\\Python313\\Lib\\typing.py)",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[1;31mImportError\u001b[0m Traceback (most recent call last)",
+ "Cell \u001b[1;32mIn[3], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21;01mtyping\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m NoneType\n\u001b[0;32m 2\u001b[0m test \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m 3\u001b[0m \u001b[38;5;28misinstance\u001b[39m(test, NoneType)\n",
+ "\u001b[1;31mImportError\u001b[0m: cannot import name 'NoneType' from 'typing' (c:\\Users\\Shanechka\\AppData\\Local\\Programs\\Python\\Python313\\Lib\\typing.py)"
+ ]
+ }
+ ],
+ "source": [
+ "test = None\n",
+ "isinstance(test, NoneType)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "id": "f6c933fd",
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "TypeError",
+ "evalue": "Vector2D.__init__() missing 2 required positional arguments: '_Vector2D__abscissa' and '_Vector2D__ordinate'",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)",
+ "Cell \u001b[1;32mIn[15], line 41\u001b[0m\n\u001b[0;32m 37\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;241m0\u001b[39m\n\u001b[0;32m 39\u001b[0m \u001b[38;5;66;03m# ваш код\u001b[39;00m\n\u001b[1;32m---> 41\u001b[0m vec\u001b[38;5;241m=\u001b[39m\u001b[43mVector2D\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 42\u001b[0m \u001b[38;5;28mprint\u001b[39m(vec)\n",
+ "\u001b[1;31mTypeError\u001b[0m: Vector2D.__init__() missing 2 required positional arguments: '_Vector2D__abscissa' and '_Vector2D__ordinate'"
+ ]
+ }
+ ],
+ "source": [
+ "class Vector2D:\n",
+ " __abscissa : float = 0.0\n",
+ " __ordinate : float = 0.0\n",
+ " def __init__(self, abscissa: float, ordinate: float):\n",
+ " self.abscissa = abscissa\n",
+ " self.ordinate = ordinate\n",
+ " def get_x(self):\n",
+ " return self.abscissa\n",
+ " def get_y(self):\n",
+ " return self.ordinate\n",
+ " property(get_x)\n",
+ " property(get_y)\n",
+ " def conj(self) -> \"Vector2D\":\n",
+ " # ваш код\n",
+ " return Vector2D()\n",
+ " def __repr__(self):\n",
+ " return f\"Vector2D(abscissa={self.abscissa}, ordinate={self.ordinate})\"\n",
+ " def __eq__(self, other: \"Vector2D\"):\n",
+ " return self.abscissa == other.abscissa and self.ordinate == other.ordinate\n",
+ " def __ne__(self, other: \"Vector2D\"):\n",
+ " return self.abscissa != other.abscissa or self.ordinate != other.ordinate\n",
+ " def __lt__(self, other: \"Vector2D\"):\n",
+ " return self.abscissa < other.abscissa or (self.ordinate < other.ordinate and self.abscissa == other.abscissa)\n",
+ " def __gt__(self, other: \"Vector2D\"):\n",
+ " return self.abscissa > other.abscissa or (self.ordinate > other.ordinate and self.abscissa == other.abscissa)\n",
+ " def __le__(self, other: \"Vector2D\"):\n",
+ " return not (self > other)\n",
+ " def __ge__(self, other: \"Vector2D\"):\n",
+ " return not (self < other)\n",
+ " def __abs__(self):\n",
+ " return (self.absciss**2 + self.ordinate**2) ** 0.5\n",
+ " def __bool__(self):\n",
+ " return abs(self) != 0\n",
+ " \n",
+ " def get_angle(self, other: \"Vector2D\") -> float:\n",
+ " # ваш код\n",
+ " return 0\n",
+ "\n",
+ "vec=Vector2D()\n",
+ "print(vec)\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 28,
+ "id": "750d5ad3",
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "AttributeError",
+ "evalue": "'function' object has no attribute '__mro__'",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[1;31mAttributeError\u001b[0m Traceback (most recent call last)",
+ "Cell \u001b[1;32mIn[28], line 2\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21;01mdataclasses\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m dataclass\n\u001b[1;32m----> 2\u001b[0m \u001b[38;5;28;43;01mclass\u001b[39;49;00m\u001b[38;5;250;43m \u001b[39;49m\u001b[38;5;21;43;01mVector2D\u001b[39;49;00m\u001b[43m:\u001b[49m\n\u001b[0;32m 3\u001b[0m \u001b[43m \u001b[49m\u001b[43m__abscissa\u001b[49m\u001b[43m \u001b[49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mfloat\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m0.0\u001b[39;49m\n\u001b[0;32m 4\u001b[0m \u001b[43m \u001b[49m\u001b[43m__ordinate\u001b[49m\u001b[43m \u001b[49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mfloat\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m0.0\u001b[39;49m\n",
+ "Cell \u001b[1;32mIn[28], line 5\u001b[0m, in \u001b[0;36mVector2D\u001b[1;34m()\u001b[0m\n\u001b[0;32m 3\u001b[0m __abscissa : \u001b[38;5;28mfloat\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m0.0\u001b[39m\n\u001b[0;32m 4\u001b[0m __ordinate : \u001b[38;5;28mfloat\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m0.0\u001b[39m\n\u001b[1;32m----> 5\u001b[0m \u001b[43m\u001b[49m\u001b[38;5;129;43m@dataclass\u001b[39;49m\n\u001b[0;32m 6\u001b[0m \u001b[43m\u001b[49m\u001b[38;5;28;43;01mdef\u001b[39;49;00m\u001b[38;5;250;43m \u001b[39;49m\u001b[38;5;21;43m__init__\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mabscissa\u001b[49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mfloat\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mordinate\u001b[49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mfloat\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m:\u001b[49m\n\u001b[0;32m 7\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m__abscissa\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mabscissa\u001b[49m\n\u001b[0;32m 8\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m__ordinate\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mordinate\u001b[49m\n",
+ "File \u001b[1;32mc:\\Users\\Shanechka\\AppData\\Local\\Programs\\Python\\Python313\\Lib\\dataclasses.py:1305\u001b[0m, in \u001b[0;36mdataclass\u001b[1;34m(cls, init, repr, eq, order, unsafe_hash, frozen, match_args, kw_only, slots, weakref_slot)\u001b[0m\n\u001b[0;32m 1302\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m wrap\n\u001b[0;32m 1304\u001b[0m \u001b[38;5;66;03m# We're called as @dataclass without parens.\u001b[39;00m\n\u001b[1;32m-> 1305\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mwrap\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mcls\u001b[39;49m\u001b[43m)\u001b[49m\n",
+ "File \u001b[1;32mc:\\Users\\Shanechka\\AppData\\Local\\Programs\\Python\\Python313\\Lib\\dataclasses.py:1295\u001b[0m, in \u001b[0;36mdataclass..wrap\u001b[1;34m(cls)\u001b[0m\n\u001b[0;32m 1294\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mwrap\u001b[39m(\u001b[38;5;28mcls\u001b[39m):\n\u001b[1;32m-> 1295\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_process_class\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mcls\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43minit\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mrepr\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43meq\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43morder\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43munsafe_hash\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1296\u001b[0m \u001b[43m \u001b[49m\u001b[43mfrozen\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmatch_args\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mkw_only\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mslots\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m 1297\u001b[0m \u001b[43m \u001b[49m\u001b[43mweakref_slot\u001b[49m\u001b[43m)\u001b[49m\n",
+ "File \u001b[1;32mc:\\Users\\Shanechka\\AppData\\Local\\Programs\\Python\\Python313\\Lib\\dataclasses.py:961\u001b[0m, in \u001b[0;36m_process_class\u001b[1;34m(cls, init, repr, eq, order, unsafe_hash, frozen, match_args, kw_only, slots, weakref_slot)\u001b[0m\n\u001b[0;32m 959\u001b[0m all_frozen_bases \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m 960\u001b[0m has_dataclass_bases \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mFalse\u001b[39;00m\n\u001b[1;32m--> 961\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m b \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28;43mcls\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[38;5;18;43m__mro__\u001b[39;49m[\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m:\u001b[38;5;241m0\u001b[39m:\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m]:\n\u001b[0;32m 962\u001b[0m \u001b[38;5;66;03m# Only process classes that have been processed by our\u001b[39;00m\n\u001b[0;32m 963\u001b[0m \u001b[38;5;66;03m# decorator. That is, they have a _FIELDS attribute.\u001b[39;00m\n\u001b[0;32m 964\u001b[0m base_fields \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mgetattr\u001b[39m(b, _FIELDS, \u001b[38;5;28;01mNone\u001b[39;00m)\n\u001b[0;32m 965\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m base_fields \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n",
+ "\u001b[1;31mAttributeError\u001b[0m: 'function' object has no attribute '__mro__'"
+ ]
+ }
+ ],
+ "source": [
+ "from dataclasses import dataclass\n",
+ "class Vector2D:\n",
+ " __abscissa : float = 0.0\n",
+ " __ordinate : float = 0.0\n",
+ " @dataclass\n",
+ " def __init__(self, abscissa: float, ordinate: float):\n",
+ " self.__abscissa = abscissa\n",
+ " self.__ordinate = ordinate\n",
+ " def get_x(self):\n",
+ " return self.__abscissa\n",
+ " def get_y(self):\n",
+ " return self.__ordinate\n",
+ " property(get_x)\n",
+ " property(get_y)\n",
+ " def conj(self) -> \"Vector2D\":\n",
+ " # ваш код\n",
+ " return Vector2D()\n",
+ " def __repr__(self):\n",
+ " return f\"Vector2D(__abscissa={self.__abscissa}, __ordinate={self.__ordinate})\"\n",
+ " def __eq__(self, other: \"Vector2D\"):\n",
+ " return self.__abscissa == other.__abscissa and self.__ordinate == other.__ordinate\n",
+ " def __ne__(self, other: \"Vector2D\"):\n",
+ " return self.__abscissa != other.__abscissa or self.__ordinate != other.__ordinate\n",
+ " def __lt__(self, other: \"Vector2D\"):\n",
+ " return self.__abscissa < other.__abscissa or (self.__ordinate < other.__ordinate and self.__abscissa == other.__abscissa)\n",
+ " def __gt__(self, other: \"Vector2D\"):\n",
+ " return self.__abscissa > other.__abscissa or (self.__ordinate > other.__ordinate and self.__abscissa == other.__abscissa)\n",
+ " def __le__(self, other: \"Vector2D\"):\n",
+ " return not (self > other)\n",
+ " def __ge__(self, other: \"Vector2D\"):\n",
+ " return not (self < other)\n",
+ " def __abs__(self):\n",
+ " return (self.__abscissa**2 + self.__ordinate**2) ** 0.5\n",
+ " def __bool__(self):\n",
+ " return abs(self) != 0\n",
+ " \n",
+ " def get_angle(self, other: \"Vector2D\") -> float:\n",
+ " # ваш код\n",
+ " return 0\n",
+ "\n",
+ " # ваш код\n",
+ "vec = Vector2D()\n",
+ "print(vec)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 40,
+ "id": "27573b31",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Vector2D(abscissa=5, ordinate=25)\n"
+ ]
+ }
+ ],
+ "source": [
+ "from dataclasses import dataclass\n",
+ "@dataclass\n",
+ "class Vector2D:\n",
+ " abscissa : float = 0.0\n",
+ " ordinate : float = 0.0\n",
+ " # def __init__(self, abscissa: float, ordinate: float):\n",
+ " # self.abscissa = abscissa\n",
+ " # self.ordinate = ordinate\n",
+ " # def __repr__(self):\n",
+ " # return f\"Vector2D(abscissa={self.abscissa}, ordinate={self.ordinate})\"\n",
+ " # def __eq__(self, other: \"Vector2D\"):\n",
+ " # return self.abscissa == other.abscissa and self.ordinate == other.ordinate\n",
+ " def get_x(self):\n",
+ " return self.abscissa\n",
+ " def get_y(self):\n",
+ " return self.ordinate\n",
+ " def conj(self) -> \"Vector2D\":\n",
+ " return Vector2D()\n",
+ "\n",
+ " property(get_x)\n",
+ " property(get_y)\n",
+ " def __ne__(self, other: \"Vector2D\"):\n",
+ " return self.abscissa != other.abscissa or self.ordinate != other.ordinate\n",
+ " def __lt__(self, other: \"Vector2D\"):\n",
+ " return self.abscissa < other.abscissa or (self.ordinate < other.ordinate and self.abscissa == other.abscissa)\n",
+ " def __gt__(self, other: \"Vector2D\"):\n",
+ " return self.abscissa > other.abscissa or (self.ordinate > other.ordinate and self.abscissa == other.abscissa)\n",
+ " def __le__(self, other: \"Vector2D\"):\n",
+ " return not (self > other)\n",
+ " def __ge__(self, other: \"Vector2D\"):\n",
+ " return not (self < other)\n",
+ " def __abs__(self):\n",
+ " return (self.abscissa**2 + self.ordinate**2) ** 0.5\n",
+ " def __bool__(self):\n",
+ " return abs(self) != 0\n",
+ " def __mul__ (self, mult_amount):\n",
+ " return Vector2D(self.abscissa * mult_amount, self.ordinate * mult_amount)\n",
+ " def __rmul__(self, mult_amount):\n",
+ " return self * mult_amount\n",
+ " \n",
+ " def get_angle(self, other: \"Vector2D\") -> float:\n",
+ " # ваш код\n",
+ " return 0\n",
+ " # ваш код\n",
+ "print( Vector2D(1,5) * 5)\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 42,
+ "id": "ca8141e7",
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "FrozenInstanceError",
+ "evalue": "cannot assign to field 'abscissa'",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[1;31mFrozenInstanceError\u001b[0m Traceback (most recent call last)",
+ "Cell \u001b[1;32mIn[42], line 74\u001b[0m\n\u001b[0;32m 72\u001b[0m \u001b[38;5;66;03m# ваш код\u001b[39;00m\n\u001b[0;32m 73\u001b[0m vec \u001b[38;5;241m=\u001b[39m Vector2D(\u001b[38;5;241m1\u001b[39m,\u001b[38;5;241m2\u001b[39m)\n\u001b[1;32m---> 74\u001b[0m \u001b[43mvec\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mabscissa\u001b[49m \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m2\u001b[39m\n",
+ "File \u001b[1;32m:11\u001b[0m, in \u001b[0;36m__setattr__\u001b[1;34m(self, name, value)\u001b[0m\n",
+ "\u001b[1;31mFrozenInstanceError\u001b[0m: cannot assign to field 'abscissa'"
+ ]
+ }
+ ],
+ "source": [
+ "from dataclasses import dataclass\n",
+ "from math import isclose, acos, degrees\n",
+ "@dataclass(eq = False, frozen = True)\n",
+ "class Vector2D:\n",
+ " abscissa : float = 0.0\n",
+ " ordinate : float = 0.0\n",
+ " # def __init__(self, abscissa: float, ordinate: float):\n",
+ " # self.abscissa = abscissa\n",
+ " # self.ordinate = ordinate\n",
+ " # def __repr__(self):\n",
+ " # return f\"Vector2D(abscissa={self.abscissa}, ordinate={self.ordinate})\"\n",
+ " def __post_init__(self):\n",
+ " object.__setattr__(self, \"abscissa\", float(self.abscissa))\n",
+ " object.__setattr__(self, \"ordinate\", float(self.ordinate))\n",
+ " @property\n",
+ " def get_x(self):\n",
+ " return self.abscissa\n",
+ " @property\n",
+ " def get_y(self):\n",
+ " return self.ordinate\n",
+ " def __eq__(self, other: \"Vector2D\"):\n",
+ " \"\"\"We use float numbers so we want to check equality by using isclose() while dataclass is using ==\"\"\"\n",
+ " return isclose(self.abscissa, other.abscissa) and isclose(self.ordinate, other.ordinate)\n",
+ " def __ne__(self, other: \"Vector2D\"):\n",
+ " return not (self == other)\n",
+ " def __lt__(self, other: \"Vector2D\"):\n",
+ " return self.abscissa < other.abscissa or (self.ordinate < other.ordinate and self.abscissa == other.abscissa)\n",
+ " def __gt__(self, other: \"Vector2D\"):\n",
+ " return self.abscissa > other.abscissa or (self.ordinate > other.ordinate and self.abscissa == other.abscissa)\n",
+ " def __le__(self, other: \"Vector2D\"):\n",
+ " return not (self > other)\n",
+ " def __ge__(self, other: \"Vector2D\"):\n",
+ " return not (self < other)\n",
+ " def __abs__(self):\n",
+ " return (self.abscissa**2 + self.ordinate**2) ** 0.5\n",
+ " def __bool__(self):\n",
+ " return abs(self) != 0\n",
+ " def __mul__ (self: \"Vector2D\", mult_amount):\n",
+ " return Vector2D(self.abscissa * mult_amount, self.ordinate * mult_amount)\n",
+ " def __rmul__ (self, mult_amount):\n",
+ " return self * mult_amount\n",
+ " def __truediv__ (self, mult_amount):\n",
+ " return Vector2D(self.abscissa / mult_amount, self.ordinate / mult_amount)\n",
+ " def __add__(self, other: \"Vector2D\"):\n",
+ " return Vector2D(self.abscissa + other.abscissa, self.ordinate + other.ordinate) \n",
+ " def __add__(self, add_amount):\n",
+ " return Vector2D(self.abscissa + add_amount, self.ordinate + add_amount)\n",
+ " def __radd__(self, add_amount):\n",
+ " return self + add_amount\n",
+ " def __sub__(self, sub_amount):\n",
+ " return Vector2D(self.abscissa - sub_amount, self.ordinate - sub_amount)\n",
+ " def __sub__(self, other: \"Vector2D\"):\n",
+ " return Vector2D(self.abscissa - other.abscissa, self.ordinate - other.ordinate)\n",
+ " def __neg__(self):\n",
+ " return self * -1\n",
+ " def __float__(self):\n",
+ " return abs(self)\n",
+ " def __int__(self):\n",
+ " return int(abs(self))\n",
+ " def __complex__(self):\n",
+ " return complex(self.abscissa, self.ordinate)\n",
+ " def __matmul__(self, other: \"Vector2D\"): #@ skalar mult\n",
+ " return self.abscissa * other.abscissa + self.ordinate * other.ordinate\n",
+ "\n",
+ " def get_angle(self, other: \"Vector2D\") -> float:\n",
+ " if isclose(abs(other), 0):\n",
+ " raise ValueError(\"You cannot get angle in between given vector and a zero vector\")\n",
+ " return degrees(acos((self @ other) / (abs(self) * abs(other))))\n",
+ " def conj(self):\n",
+ " return Vector2D(self.abscissa, self.ordinate * -1)\n",
+ "\n",
+ " # ваш код\n",
+ "vec = Vector2D(1,2)\n",
+ "vec.abscissa = 2"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "id": "134eb0ef",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Vector2D(abscissa=0.0, ordinate=0.0)\n"
+ ]
+ }
+ ],
+ "source": [
+ "from dataclasses import dataclass\n",
+ "from math import isclose, acos, degrees\n",
+ "@dataclass(eq = False, frozen = True)\n",
+ "class Vector2D:\n",
+ " abscissa : float = 0.\n",
+ " ordinate : float = 0.\n",
+ " # def __init__(self, abscissa: float, ordinate: float):\n",
+ " # self.abscissa = abscissa\n",
+ " # self.ordinate = ordinate\n",
+ " # def __repr__(self):\n",
+ " # return f\"Vector2D(abscissa={self.abscissa}, ordinate={self.ordinate})\"\n",
+ " def __post_init__(self):\n",
+ " object.__setattr__(self, \"abscissa\", float(self.abscissa))\n",
+ " object.__setattr__(self, \"ordinate\", float(self.ordinate))\n",
+ " @property\n",
+ " def get_x(self):\n",
+ " return self.abscissa\n",
+ " @property\n",
+ " def get_y(self):\n",
+ " return self.ordinate\n",
+ " def __eq__(self, other: \"Vector2D\"):\n",
+ " \"\"\"We use float numbers so we want to check equality by using isclose() while dataclass is using ==\"\"\"\n",
+ " return isclose(self.abscissa, other.abscissa) and isclose(self.ordinate, other.ordinate)\n",
+ " def __ne__(self, other: \"Vector2D\"):\n",
+ " return not (self == other)\n",
+ " def __lt__(self, other: \"Vector2D\"):\n",
+ " return self.abscissa < other.abscissa or (self.ordinate < other.ordinate and self.abscissa == other.abscissa)\n",
+ " def __gt__(self, other: \"Vector2D\"):\n",
+ " return self.abscissa > other.abscissa or (self.ordinate > other.ordinate and self.abscissa == other.abscissa)\n",
+ " def __le__(self, other: \"Vector2D\"):\n",
+ " return not (self > other)\n",
+ " def __ge__(self, other: \"Vector2D\"):\n",
+ " return not (self < other)\n",
+ " def __abs__(self):\n",
+ " return (self.abscissa**2 + self.ordinate**2) ** 0.5\n",
+ " def __bool__(self):\n",
+ " return abs(self) != 0\n",
+ " def __mul__ (self: \"Vector2D\", mult_amount):\n",
+ " return Vector2D(self.abscissa * mult_amount, self.ordinate * mult_amount)\n",
+ " def __rmul__ (self, mult_amount):\n",
+ " return self * mult_amount\n",
+ " def __truediv__ (self, mult_amount):\n",
+ " return Vector2D(self.abscissa / mult_amount, self.ordinate / mult_amount)\n",
+ " def __add__(self, other: \"Vector2D\"):\n",
+ " return Vector2D(self.abscissa + other.abscissa, self.ordinate + other.ordinate) \n",
+ " def __add__(self, add_amount):\n",
+ " return Vector2D(self.abscissa + add_amount, self.ordinate + add_amount)\n",
+ " def __radd__(self, add_amount):\n",
+ " return self + add_amount\n",
+ " def __sub__(self, sub_amount):\n",
+ " return Vector2D(self.abscissa - sub_amount, self.ordinate - sub_amount)\n",
+ " def __sub__(self, other: \"Vector2D\"):\n",
+ " return Vector2D(self.abscissa - other.abscissa, self.ordinate - other.ordinate)\n",
+ " def __neg__(self):\n",
+ " return self * -1\n",
+ " def __float__(self):\n",
+ " return abs(self)\n",
+ " def __int__(self):\n",
+ " return int(abs(self))\n",
+ " def __complex__(self):\n",
+ " return complex(self.abscissa, self.ordinate)\n",
+ " def __matmul__(self, other: \"Vector2D\"): #@ skalar mult\n",
+ " return self.abscissa * other.abscissa + self.ordinate * other.ordinate\n",
+ "\n",
+ " def get_angle(self, other: \"Vector2D\") -> float:\n",
+ " if isclose(abs(other), 0):\n",
+ " raise ValueError(\"You cannot get angle in between given vector and a zero vector\")\n",
+ " return degrees(acos((self @ other) / (abs(self) * abs(other))))\n",
+ " def conj(self):\n",
+ " return Vector2D(self.abscissa, self.ordinate * -1)\n",
+ "\n",
+ " # ваш код\n",
+ "print(Vector2D())"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "50ebd9a2",
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "RuntimeError",
+ "evalue": "'widget is not a recognised GUI loop or backend name",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[1;31mRuntimeError\u001b[0m Traceback (most recent call last)",
+ "File \u001b[1;32mc:\\Users\\Shanechka\\AppData\\Local\\Programs\\Python\\Python313\\Lib\\site-packages\\matplotlib\\backends\\registry.py:407\u001b[0m, in \u001b[0;36mBackendRegistry.resolve_gui_or_backend\u001b[1;34m(self, gui_or_backend)\u001b[0m\n\u001b[0;32m 406\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 407\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mresolve_backend\u001b[49m\u001b[43m(\u001b[49m\u001b[43mgui_or_backend\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 408\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m: \u001b[38;5;66;03m# KeyError ?\u001b[39;00m\n",
+ "File \u001b[1;32mc:\\Users\\Shanechka\\AppData\\Local\\Programs\\Python\\Python313\\Lib\\site-packages\\matplotlib\\backends\\registry.py:369\u001b[0m, in \u001b[0;36mBackendRegistry.resolve_backend\u001b[1;34m(self, backend)\u001b[0m\n\u001b[0;32m 368\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m gui \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m--> 369\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mRuntimeError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mbackend\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m is not a recognised backend name\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 371\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m backend, gui \u001b[38;5;28;01mif\u001b[39;00m gui \u001b[38;5;241m!=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mheadless\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n",
+ "\u001b[1;31mRuntimeError\u001b[0m: 'widget' is not a recognised backend name",
+ "\nDuring handling of the above exception, another exception occurred:\n",
+ "\u001b[1;31mRuntimeError\u001b[0m Traceback (most recent call last)",
+ "Cell \u001b[1;32mIn[21], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[43mget_ipython\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun_line_magic\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mmatplotlib\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mwidget\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m\n",
+ "File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python313\\site-packages\\IPython\\core\\interactiveshell.py:2482\u001b[0m, in \u001b[0;36mInteractiveShell.run_line_magic\u001b[1;34m(self, magic_name, line, _stack_depth)\u001b[0m\n\u001b[0;32m 2480\u001b[0m kwargs[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mlocal_ns\u001b[39m\u001b[38;5;124m'\u001b[39m] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mget_local_scope(stack_depth)\n\u001b[0;32m 2481\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mbuiltin_trap:\n\u001b[1;32m-> 2482\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[43mfn\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 2484\u001b[0m \u001b[38;5;66;03m# The code below prevents the output from being displayed\u001b[39;00m\n\u001b[0;32m 2485\u001b[0m \u001b[38;5;66;03m# when using magics with decorator @output_can_be_silenced\u001b[39;00m\n\u001b[0;32m 2486\u001b[0m \u001b[38;5;66;03m# when the last Python token in the expression is a ';'.\u001b[39;00m\n\u001b[0;32m 2487\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mgetattr\u001b[39m(fn, magic\u001b[38;5;241m.\u001b[39mMAGIC_OUTPUT_CAN_BE_SILENCED, \u001b[38;5;28;01mFalse\u001b[39;00m):\n",
+ "File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python313\\site-packages\\IPython\\core\\magics\\pylab.py:103\u001b[0m, in \u001b[0;36mPylabMagics.matplotlib\u001b[1;34m(self, line)\u001b[0m\n\u001b[0;32m 98\u001b[0m \u001b[38;5;28mprint\u001b[39m(\n\u001b[0;32m 99\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mAvailable matplotlib backends: \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 100\u001b[0m \u001b[38;5;241m%\u001b[39m _list_matplotlib_backends_and_gui_loops()\n\u001b[0;32m 101\u001b[0m )\n\u001b[0;32m 102\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m--> 103\u001b[0m gui, backend \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mshell\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43menable_matplotlib\u001b[49m\u001b[43m(\u001b[49m\u001b[43margs\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgui\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 104\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_show_matplotlib_backend(args\u001b[38;5;241m.\u001b[39mgui, backend)\n",
+ "File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python313\\site-packages\\IPython\\core\\interactiveshell.py:3667\u001b[0m, in \u001b[0;36mInteractiveShell.enable_matplotlib\u001b[1;34m(self, gui)\u001b[0m\n\u001b[0;32m 3664\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21;01mmatplotlib_inline\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mbackend_inline\u001b[39;00m\n\u001b[0;32m 3666\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21;01mIPython\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mcore\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;28;01mimport\u001b[39;00m pylabtools \u001b[38;5;28;01mas\u001b[39;00m pt\n\u001b[1;32m-> 3667\u001b[0m gui, backend \u001b[38;5;241m=\u001b[39m \u001b[43mpt\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfind_gui_and_backend\u001b[49m\u001b[43m(\u001b[49m\u001b[43mgui\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mpylab_gui_select\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 3669\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m gui \u001b[38;5;241m!=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 3670\u001b[0m \u001b[38;5;66;03m# If we have our first gui selection, store it\u001b[39;00m\n\u001b[0;32m 3671\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mpylab_gui_select \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n",
+ "File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python313\\site-packages\\IPython\\core\\pylabtools.py:349\u001b[0m, in \u001b[0;36mfind_gui_and_backend\u001b[1;34m(gui, gui_select)\u001b[0m\n\u001b[0;32m 347\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 348\u001b[0m gui \u001b[38;5;241m=\u001b[39m _convert_gui_to_matplotlib(gui)\n\u001b[1;32m--> 349\u001b[0m backend, gui \u001b[38;5;241m=\u001b[39m \u001b[43mbackend_registry\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mresolve_gui_or_backend\u001b[49m\u001b[43m(\u001b[49m\u001b[43mgui\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 351\u001b[0m gui \u001b[38;5;241m=\u001b[39m _convert_gui_from_matplotlib(gui)\n\u001b[0;32m 352\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m gui, backend\n",
+ "File \u001b[1;32mc:\\Users\\Shanechka\\AppData\\Local\\Programs\\Python\\Python313\\Lib\\site-packages\\matplotlib\\backends\\registry.py:409\u001b[0m, in \u001b[0;36mBackendRegistry.resolve_gui_or_backend\u001b[1;34m(self, gui_or_backend)\u001b[0m\n\u001b[0;32m 407\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mresolve_backend(gui_or_backend)\n\u001b[0;32m 408\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m: \u001b[38;5;66;03m# KeyError ?\u001b[39;00m\n\u001b[1;32m--> 409\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mRuntimeError\u001b[39;00m(\n\u001b[0;32m 410\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mgui_or_backend\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m is not a recognised GUI loop or backend name\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n",
+ "\u001b[1;31mRuntimeError\u001b[0m: 'widget is not a recognised GUI loop or backend name"
+ ]
+ }
+ ],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "id": "37da7d5e",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAg0AAAH5CAYAAAAC8w0GAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAGfhJREFUeJzt3QuMFeX9+OF3AVnEulADsqBUQazYqoBQEWJEIylWYjRprLcUJSrV1EaKrULTQrQ1tN5qtDRoGkubar0keKlaDEWNUSkoSESrRJQKKgtay1WFCvPPO8nuj1UuX/xzOLvL8yTj7pmdcd8z57D7Yc68h5qiKIoEALAL7Xa1AQBAJhoAgBDRAACEiAYAIEQ0AAAhogEACBENAEBIh9TGbN26Nb3//vvpwAMPTDU1NdUeDgC0aPntmtavX5969eqV2rVrt29FQw6G3r17V3sYANCqrFixIh166KH7VjTkMwyNd76urq7awwGAFm3dunXlX7Ybf3/uU9HQ+JJEDgbRAAAxkZf0XQgJAISIBgAgRDQAACGiAQAIEQ0AQIhoAABCRAMAECIaAIAQ0QAAhIgGACBENAAAIaIBAAgRDQBAiGgAAEJEAwAQIhoAgBDRAACEiAYAIEQ0AAAhogEACBENAECIaAAAQkQDABAiGgCAENEAAISIBgAgRDQAACGiAQAIEQ0AQIhoAABCRAMAECIaAIDqR8Ozzz6bzjzzzNSrV69UU1OTHn744V3u88wzz6Tjjz8+1dbWpn79+qUZM2ZUcogAQEuIho0bN6YBAwakadOmhbZftmxZGj16dDr11FPTokWL0vjx49Oll16annzyyUoOEwAI6JAq6Dvf+U65RE2fPj316dMn3XLLLeXto48+Oj333HPpt7/9bRo1alQFRwoAtKprGubOnZtGjhzZbF2Ohbx+RzZt2pTWrVvXbAEA2ng0NDQ0pB49ejRbl2/nEPjkk0+2u8/UqVNTly5dmpbevXvvpdECwL6lRUXDlzFp0qS0du3apmXFihXVHhIAtEkVvaZhd9XX16dVq1Y1W5dv19XVpf3333+7++RZFnkBAPahMw3Dhg1Lc+bMabZu9uzZ5XoAoA1Hw4YNG8qpk3lpnFKZP1++fHnTSwtjxoxp2v7yyy9Pb7/9drrmmmvSG2+8kX7/+9+nBx54IP34xz+u5DABgGpHw0svvZQGDRpULtmECRPKzydPnlzeXrlyZVNAZHm65eOPP16eXcjv75CnXv7hD38w3RIAWoCaoiiK1IbkmRZ5FkW+KDJfCwEA7Jnfmy3qmgYAoOUSDQBAiGgAAEJEAwAQIhoAgBDRAACEiAYAIEQ0AAAhogEACBENAECIaAAAQkQDABAiGgCAENEAAISIBgAgRDQAACGiAQAIEQ0AQIhoAABCRAMAECIaAIAQ0QAAhIgGACBENAAAIaIBAAgRDQBAiGgAAEJEAwAQIhoAgBDRAACEiAYAIEQ0AAAhogEACBENAECIaAAAQkQDABAiGgCAENEAAISIBgAgRDQAACGiAQAIEQ0AQIhoAABCRAMAECIaAIAQ0QAAhIgGACBENAAAIaIBAAgRDQBAiGgAAEJEAwAQIhoAgBDRAACEiAYAIEQ0AAAhogEACBENAECIaAAAQkQDABAiGgCAENEAAISIBgAgRDQAACGiAQAIEQ0AQIhoAABCRAMAECIaAIAQ0QAAhIgGACBENAAAIaIBAAgRDQBAiGgAAEJEAwAQIhoAgBDRAACEiAYAIEQ0AAAhogEACBENAECIaAAAQkQDABAiGgCAlhMN06ZNS4cffnjq1KlTGjp0aJo/f/4Ot50xY0aqqalptuT9AIA2Hg33339/mjBhQpoyZUpauHBhGjBgQBo1alRavXr1Dvepq6tLK1eubFreeeedSg8TAKh2NNx6663psssuS2PHjk3f+MY30vTp01Pnzp3T3XffvcN98tmF+vr6pqVHjx6VHiYAUM1o2Lx5c1qwYEEaOXLk/33Ddu3K23Pnzt3hfhs2bEiHHXZY6t27dzrrrLPSa6+9tsNtN23alNatW9dsAQBaWTR8+OGHacuWLV84U5BvNzQ0bHefo446qjwL8cgjj6S//OUvaevWrWn48OHp3Xff3e72U6dOTV26dGlacmgAAPvA7Ilhw4alMWPGpIEDB6YRI0akmTNnpu7du6c777xzu9tPmjQprV27tmlZsWLFXh8zAOwLOlTyf96tW7fUvn37tGrVqmbr8+18rULEfvvtlwYNGpSWLl263a/X1taWCwDQis80dOzYMQ0ePDjNmTOnaV1+uSHfzmcUIvLLG4sXL049e/as4EgBgKqeacjydMuLLrooDRkyJJ1wwgnptttuSxs3bixnU2T5pYhDDjmkvDYhu/7669OJJ56Y+vXrl9asWZNuuummcsrlpZdeWumhAgDVjIZzzz03ffDBB2ny5MnlxY/5WoVZs2Y1XRy5fPnyckZFo//+97/lFM287Ve/+tXyTMULL7xQTtcEAKqnpiiKIrUhecplnkWRL4rMbxIFAOyZ35stbvYEANAyiQYAIEQ0AAAhogEACBENAECIaAAAQkQDABAiGgCAENEAAISIBgAgRDQAACGiAQAIEQ0AQIhoAABCRAMAECIaAIAQ0QAAhIgGACBENAAAIaIBAAgRDQBAiGgAAEJEAwAQIhoAgBDRAACEiAYAIEQ0AAAhogEACBENAECIaAAAQkQDABAiGgCAENEAAISIBgAgRDQAACGiAQAIEQ0AQIhoAABCRAMAECIaAIAQ0QAAhIgGACBENAAAIaIBAAgRDQBAiGgAAEJEAwAQIhoAgBDRAACEiAYAIEQ0AAAhogEACBENAECIaAAAQkQDABAiGgCAENEAAISIBgAgRDQAACGiAQAIEQ0AQIhoAABCRAMAECIaAIAQ0QAAhIgGACBENAAAIaIBAAgRDQBAiGgAAEJEAwAQIhoAgBDRAACEiAYAIEQ0AAAhogEACBENAECIaAAAQkQDABAiGgCAENEAAISIBgAgRDQAACGiAQAIEQ0AQMuJhmnTpqXDDz88derUKQ0dOjTNnz9/p9s/+OCDqX///uX2xx57bHriiSf2xjABgGpGw/33358mTJiQpkyZkhYuXJgGDBiQRo0alVavXr3d7V944YV0/vnnp0suuSS9/PLL6eyzzy6XV199tdJDBQB2oqYoiiJVUD6z8K1vfSv97ne/K29v3bo19e7dO/3oRz9KEydO/ML25557btq4cWN67LHHmtadeOKJaeDAgWn69Om7/H7r1q1LXbp0SWvXrk11dXV7+N4AQNuyO783K3qmYfPmzWnBggVp5MiR//cN27Urb8+dO3e7++T1226f5TMTO9p+06ZN5R3edgEA9ryKRsOHH36YtmzZknr06NFsfb7d0NCw3X3y+t3ZfurUqWUhNS75LAYAsOe1+tkTkyZNKk+pNC4rVqyo9pAAoE3qUMn/ebdu3VL79u3TqlWrmq3Pt+vr67e7T16/O9vX1taWCwDQis80dOzYMQ0ePDjNmTOnaV2+EDLfHjZs2Hb3yeu33T6bPXv2DrcHANrAmYYsT7e86KKL0pAhQ9IJJ5yQbrvttnJ2xNixY8uvjxkzJh1yyCHltQnZVVddlUaMGJFuueWWNHr06HTfffell156Kd11112VHioAUM1oyFMoP/jggzR58uTyYsY8dXLWrFlNFzsuX768nFHRaPjw4enee+9NP//5z9PPfvazdOSRR6aHH344HXPMMZUeKgBQzfdp2Nu8TwMAtML3aQAA2g7RAACEiAYAIEQ0AAAhogEACBENAECIaAAAQkQDABAiGgCAENEAAISIBgAgRDQAACGiAQAIEQ0AQIhoAABCRAMAECIaAIAQ0QAAhIgGACBENAAAIaIBAAgRDQBAiGgAAEJEAwAQIhoAgBDRAACEiAYAIEQ0AAAhogEACBENAECIaAAAQkQDABAiGgCAENEAAISIBgAgRDQAACGiAQAIEQ0AQIhoAABCRAMAECIaAIAQ0QAAhIgGACBENAAAIaIBAAgRDQBAiGgAAEJEAwAQIhoAgBDRAACEiAYAIEQ0AAAhogEACBENAECIaAAAQkQDABAiGgCAENEAAISIBgAgRDQAACGiAQAIEQ0AQIhoAABCRAMAECIaAIAQ0QAAhIgGACBENAAAIaIBAAgRDQBAiGgAAEJEAwAQIhoAgBDRAACEiAYAIEQ0AAAhogEACBENAECIaAAAQkQDABAiGgCAENEAAISIBgAgRDQAACGiAQAIEQ0AQPWj4aOPPkoXXnhhqqurS127dk2XXHJJ2rBhw073OeWUU1JNTU2z5fLLL6/kMAGAgA6pgnIwrFy5Ms2ePTv973//S2PHjk3jxo1L99577073u+yyy9L111/fdLtz586VHCYAUM1oeP3119OsWbPSiy++mIYMGVKuu+OOO9IZZ5yRbr755tSrV68d7psjob6+vlJDAwBa0ssTc+fOLV+SaAyGbOTIkaldu3Zp3rx5O933nnvuSd26dUvHHHNMmjRpUvr44493uO2mTZvSunXrmi0AQCs609DQ0JAOPvjg5t+sQ4d00EEHlV/bkQsuuCAddthh5ZmIV155JV177bVpyZIlaebMmdvdfurUqem6667b4+MHAP4/o2HixInpN7/5zS5fmviy8jUPjY499tjUs2fPdNppp6W33norHXHEEV/YPp+JmDBhQtPtfKahd+/eX/r7AwB7KBquvvrqdPHFF+90m759+5bXJKxevbrZ+s8++6ycUbE71ysMHTq0/Lh06dLtRkNtbW25AAAtLBq6d+9eLrsybNiwtGbNmrRgwYI0ePDgct1TTz2Vtm7d2hQCEYsWLSo/5jMOAEAbvBDy6KOPTqeffno5fXL+/Pnp+eefT1deeWU677zzmmZOvPfee6l///7l17P8EsQvf/nLMjT+/e9/p0cffTSNGTMmnXzyyem4446r1FABgGq/uVOeBZGjIF+TkKdannTSSemuu+5q+np+74Z8kWPj7IiOHTumf/zjH+nb3/52uV9+KeS73/1u+tvf/lbJYQIAATVFURSpDckXQnbp0iWtXbu2fCdKAGDP/N70b08AACGiAQAIEQ0AQIhoAABCRAMAECIaAIAQ0QAAhIgGACBENAAAIaIBAAgRDQBAiGgAAEJEAwAQIhoAgBDRAACEiAYAIEQ0AAAhogEACBENAECIaAAAQkQDABAiGgCAENEAAISIBgAgRDQAACGiAQAIEQ0AQIhoAABCRAMAECIaAIAQ0QAAhIgGACBENAAAIaIBAAgRDQBAiGgAAEJEAwAQIhoAgBDRAACEiAYAIEQ0AAAhogEACBENAECIaAAAQkQDABAiGgCAENEAAISIBgAgRDQAACGiAQAIEQ0AQIhoAABCRAMAECIaAIAQ0QAAhIgGACBENAAAIaIBAAgRDQBAiGgAAEJEAwAQIhoAgBDRAACEiAYAIEQ0AAAhogEACBENAECIaAAAQkQDABAiGgCAENEAAISIBgAgRDQAACGiAQAIEQ0AQIhoAABCRAMAECIaAIAQ0QAAhIgGACBENAAAIaIBAAgRDQBAiGgAAEJEAwBQ3Wi44YYb0vDhw1Pnzp1T165dQ/sURZEmT56cevbsmfbff/80cuTI9Oabb1ZqiABAS4iGzZs3p3POOSddccUV4X1uvPHGdPvtt6fp06enefPmpQMOOCCNGjUqffrpp5UaJgAQVFPkv95X0IwZM9L48ePTmjVrdrpdHkavXr3S1VdfnX7yk5+U69auXZt69OhR/j/OO++80Pdbt25d6tKlS7lvXV3dHrkPANBW7c7vzRZzTcOyZctSQ0ND+ZJEo3wnhg4dmubOnbvD/TZt2lTe4W0XAGDPazHRkIMhy2cWtpVvN35te6ZOnVrGRePSu3fvio8VAPZFuxUNEydOTDU1NTtd3njjjbQ3TZo0qTyl0risWLFir35/ANhXdNidjfP1BhdffPFOt+nbt++XGkh9fX35cdWqVeXsiUb59sCBA3e4X21tbbkAAC0oGrp3714uldCnT58yHObMmdMUCfn6hDyLYndmYAAAreyahuXLl6dFixaVH7ds2VJ+npcNGzY0bdO/f//00EMPlZ/nlzbyLItf/epX6dFHH02LFy9OY8aMKWdUnH322ZUaJgBQiTMNuyO/SdOf/vSnptuDBg0qPz799NPplFNOKT9fsmRJeR1Co2uuuSZt3LgxjRs3rpyiedJJJ6VZs2alTp06VWqYAEBLeZ+Gvc37NABAG3+fBgCgZRMNAECIaAAAQkQDABAiGgCAENEAAISIBgAgRDQAACGiAQAIEQ0AQIhoAABCRAMAECIaAIAQ0QAAhIgGACBENAAAIaIBAAgRDQBAiGgAAEJEAwAQIhoAgBDRAACEiAYAIEQ0AAAhogEACBENAECIaAAAQkQDABAiGgCAENEAAIR0SG1MURTlx3Xr1lV7KADQ4jX+vmz8/blPRcP69evLj7179672UACgVf3+7NKly063qSkiadGKbN26Nb3//vvpwAMPTDU1Naml1VyOmRUrVqS6urpqD2ef4/hXl+NffR6D6lrXQo9/zoAcDL169Urt2rXbt8405Dt86KGHppYsP1la0hNmX+P4V5fjX30eg+qqa4HHf1dnGBq5EBIACBENAECIaNiLamtr05QpU8qP7H2Of3U5/tXnMaiu2jZw/NvchZAAQGU40wAAhIgGACBENAAAIaIBAAgRDQBAiGiosBtuuCENHz48de7cOXXt2jW0T57QMnny5NSzZ8+0//77p5EjR6Y333yz4mNtiz766KN04YUXlu++lo//JZdckjZs2LDTfU455ZTyLci3XS6//PK9NubWbNq0aenwww9PnTp1SkOHDk3z58/f6fYPPvhg6t+/f7n9sccem5544om9Nta2ancegxkzZnzhuZ73Y/c9++yz6cwzzyzfijkfx4cffniX+zzzzDPp+OOPL6dg9uvXr3w8WjrRUGGbN29O55xzTrriiivC+9x4443p9ttvT9OnT0/z5s1LBxxwQBo1alT69NNPKzrWtigHw2uvvZZmz56dHnvssfIP9rhx43a532WXXZZWrlzZtOTHhJ27//7704QJE8p56AsXLkwDBgwon7erV6/e7vYvvPBCOv/888uQe/nll9PZZ59dLq+++upeH/u++hhkOai3fa6/8847e3XMbcXGjRvL452jLWLZsmVp9OjR6dRTT02LFi1K48ePT5deeml68sknU4uW36eByvvjH/9YdOnSZZfbbd26taivry9uuummpnVr1qwpamtri7/+9a8VHmXb8q9//Su/B0nx4osvNq37+9//XtTU1BTvvffeDvcbMWJEcdVVV+2lUbYdJ5xwQvHDH/6w6faWLVuKXr16FVOnTt3u9t/73veK0aNHN1s3dOjQ4gc/+EHFx9pW7e5jEP25xO5JKRUPPfTQTre55pprim9+85vN1p177rnFqFGjipbMmYYWJtdnQ0ND+ZLEtv+QSD7NOHfu3KqOrbXJxyu/JDFkyJCmdfm45n/ULJ/B2Zl77rkndevWLR1zzDFp0qRJ6eOPP94LI27dZ9QWLFjQ7Hmbj3O+vaPnbV6/7fZZ/lux5/neewyy/HLdYYcdVv7ri2eddVZ5Zo7Km9tKn/9t7l+5bO1yMGQ9evRotj7fbvwaMfl4HXzwwc3WdejQIR100EE7PZYXXHBB+UM0vzb5yiuvpGuvvTYtWbIkzZw5cy+MunX68MMP05YtW7b7vH3jjTe2u09+DDzPq/sYHHXUUenuu+9Oxx13XFq7dm26+eaby2uwcji09H8tuLVr2MHzP//z2Z988kl5PVtL5EzDlzBx4sQvXDz0+WVHf0hp+cc/X/OQiz9fmJevifjzn/+cHnroofTWW2/t0fsB1TZs2LA0ZsyYNHDgwDRixIgyjLt3757uvPPOag+NFsqZhi/h6quvThdffPFOt+nbt++X+n/X19eXH1etWlXOnmiUb+c/2MSPfz6Wn78A7LPPPitnVDQe54j80lC2dOnSdMQRR3zJUbdt+aWc9u3bl8/TbeXbOzrWef3ubM+efww+b7/99kuDBg0qn+tUVv0Onv/5wtSWepYhEw1fQi7xvFRCnz59yifTnDlzmiIhn67Kr8HvzgyMtix6/PPfotasWVO+zjt48OBy3VNPPZW2bt3aFAIR+crmbNuIo7mOHTuWxzg/b/MMiCwf53z7yiuv3OHjk7+erxpvlGe55PXsncfg8/LLG4sXL05nnHFGhUfLsGHDvjDFuFU8/6t9JWZb98477xQvv/xycd111xVf+cpXys/zsn79+qZtjjrqqGLmzJlNt3/9618XXbt2LR555JHilVdeKc4666yiT58+xSeffFKle9F6nX766cWgQYOKefPmFc8991xx5JFHFueff37T1999993y+OevZ0uXLi2uv/764qWXXiqWLVtWPgZ9+/YtTj755Crei9bhvvvuK2f5zJgxo5y5Mm7cuPJ53NDQUH79+9//fjFx4sSm7Z9//vmiQ4cOxc0331y8/vrrxZQpU4r99tuvWLx4cRXvxb71GOSfS08++WTx1ltvFQsWLCjOO++8olOnTsVrr71WxXvROq1fv77p53v+1XrrrbeWn+ffAVk+7vn4N3r77beLzp07Fz/96U/L5/+0adOK9u3bF7NmzSpaMtFQYRdddFH5BPr88vTTTzdtk2/nqU/bTrv8xS9+UfTo0aP8AXDaaacVS5YsqdI9aN3+85//lJGQg62urq4YO3Zss2DLYbDt47F8+fIyEA466KDy2Pfr16/8Q7127doq3ovW44477ii+9rWvFR07diyn//3zn/9sNpU1/3nY1gMPPFB8/etfL7fP088ef/zxKox6330Mxo8f37Rt/nlzxhlnFAsXLqzSyFu3p59+ers/6xuPd/6Yj//n9xk4cGB5/PNfTrb9PdBS1eT/VPtsBwDQ8pk9AQCEiAYAIEQ0AAAhogEACBENAECIaAAAQkQDABAiGgCAENEAAISIBgAgRDQAACni/wG0ETR2GfNTBgAAAABJRU5ErkJggg==",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "import numpy as np\n",
+ "import matplotlib.pyplot as plt\n",
+ "from matplotlib.animation import FuncAnimation\n",
+ "\n",
+ "L = 10.0\n",
+ "g = 9.81\n",
+ "Omega = 7.292115e-5\n",
+ "phi = np.deg2rad(55)\n",
+ "\n",
+ "omega0 = np.sqrt(g / L)\n",
+ "omega_p = Omega * np.sin(phi)\n",
+ "\n",
+ "dt = 0.05\n",
+ "t = np.arange(0, 500, dt)\n",
+ "\n",
+ "A = 1.0\n",
+ "x = A * np.cos(omega0 * t) * np.cos(omega_p * t)\n",
+ "y = A * np.cos(omega0 * t) * np.sin(omega_p * t)\n",
+ "\n",
+ "fig, ax = plt.subplots(figsize=(6, 6))\n",
+ "ax.set_aspect('equal')\n",
+ "ax.set_xlim(-1.2*A, 1.2*A)\n",
+ "ax.set_ylim(-1.2*A, 1.2*A)\n",
+ "\n",
+ "line, = ax.plot([], [], lw=2)\n",
+ "point, = ax.plot([], [], 'ro')\n",
+ "\n",
+ "trail_x, trail_y = [], []\n",
+ "\n",
+ "def update(frame):\n",
+ " trail_x.append(x[frame])\n",
+ " trail_y.append(y[frame])\n",
+ " line.set_data(trail_x, trail_y)\n",
+ " point.set_data([x[frame]], [y[frame]])\n",
+ " return line, point\n",
+ "\n",
+ "ani = FuncAnimation(fig, update, frames=len(t), interval=30)\n",
+ "plt.show()\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "id": "b5f95296",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "ТЕСТ
"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 17,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "from IPython.display import HTML\n",
+ "HTML(\"ТЕСТ
\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ea929ebd",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Vector2D(abscissa=2, ordinate=1)\n"
+ ]
+ },
+ {
+ "ename": "TypeError",
+ "evalue": "__str__ returned non-string (type NoneType)",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)",
+ "Cell \u001b[1;32mIn[1], line 118\u001b[0m\n\u001b[0;32m 115\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21mconj\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n\u001b[0;32m 116\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m Vector2D(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mabscissa, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mordinate \u001b[38;5;241m*\u001b[39m \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m)\n\u001b[1;32m--> 118\u001b[0m \u001b[38;5;28;43mprint\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mVector2D\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m2\u001b[39;49m\u001b[43m,\u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n",
+ "\u001b[1;31mTypeError\u001b[0m: __str__ returned non-string (type NoneType)"
+ ]
+ }
+ ],
+ "source": [
+ "from dataclasses import dataclass\n",
+ "from math import acos, isclose\n",
+ "\n",
+ "\n",
+ "@dataclass(eq=False, init = False)\n",
+ "class Vector2D:\n",
+ " _abscissa: float\n",
+ " _ordinate: float \n",
+ "\n",
+ " def __init__(self, abscissa: float = 0., ordinate: float= 0.):\n",
+ " self._abscissa = abscissa\n",
+ " self._ordinate = ordinate\n",
+ " \n",
+ " \n",
+ " def __repr__(self):\n",
+ " return (f\"Vector2D(abscissa={self._abscissa}, ordinate={self._ordinate})\")\n",
+ "\n",
+ " @property\n",
+ " def abscissa(self):\n",
+ " return self._abscissa\n",
+ "\n",
+ " @property\n",
+ " def ordinate(self):\n",
+ " return self._ordinate\n",
+ "\n",
+ " def __ne__(self, other: \"Vector2D\"):\n",
+ " return not (self == other)\n",
+ "\n",
+ " def __eq__(self, other):\n",
+ " if not isinstance(other, Vector2D):\n",
+ " return NotImplemented\n",
+ " return isclose(self.abscissa, other.abscissa, rel_tol=1e-9, abs_tol=1e-10) and isclose(\n",
+ " self.ordinate, other.ordinate, rel_tol=1e-9, abs_tol=1e-10)\n",
+ "\n",
+ " def __lt__(self, other):\n",
+ " if not isinstance(other, Vector2D):\n",
+ " return NotImplemented\n",
+ " return (\n",
+ " self.abscissa < other.abscissa\n",
+ " and not (isclose(self.abscissa, other.abscissa, rel_tol=1e-9, abs_tol=1e-10))\n",
+ " ) or (\n",
+ " isclose(self.abscissa, other.abscissa, rel_tol=1e-9, abs_tol=1e-10)\n",
+ " and self.ordinate < other.ordinate\n",
+ " and not (isclose(self.ordinate, other.ordinate)))\n",
+ "\n",
+ " def __le__(self, other):\n",
+ " return self == other or self < other\n",
+ "\n",
+ " def __gt__(self, other):\n",
+ " return not (self <= other)\n",
+ "\n",
+ " def __ge__(self, other):\n",
+ " return not (self < other)\n",
+ "\n",
+ " def __abs__(self):\n",
+ " return (self.abscissa**2 + self.ordinate**2) ** 0.5\n",
+ "\n",
+ " def __bool__(self):\n",
+ " return not (isclose(abs(self), 0, abs_tol=1e-12))\n",
+ "\n",
+ " def __mul__(self, other):\n",
+ " if isinstance(other, (int, float)):\n",
+ " return Vector2D(self.abscissa * other, self.ordinate * other)\n",
+ " return NotImplemented\n",
+ "\n",
+ " def __rmul__(self, other):\n",
+ " return self * other\n",
+ "\n",
+ " def __truediv__(self, other):\n",
+ " if isinstance(other, (int, float)):\n",
+ " return Vector2D(self.abscissa / other, self.ordinate / other)\n",
+ " return NotImplemented\n",
+ "\n",
+ " def __add__(self, other):\n",
+ " if isinstance(other, Vector2D):\n",
+ " return Vector2D(self.abscissa + other.abscissa, self.ordinate + other.ordinate)\n",
+ " if isinstance(other, (int, float)):\n",
+ " return Vector2D(self.abscissa + other, self.ordinate + other)\n",
+ " return NotImplemented\n",
+ "\n",
+ " def __radd__(self, other):\n",
+ " return self + other\n",
+ "\n",
+ " def __sub__(self, other):\n",
+ " if isinstance(other, Vector2D):\n",
+ " return Vector2D(self.abscissa - other.abscissa, self.ordinate - other.ordinate)\n",
+ " if isinstance(other, (int, float)):\n",
+ " return Vector2D(self.abscissa - other, self.ordinate - other)\n",
+ " return NotImplemented\n",
+ "\n",
+ " def __neg__(self):\n",
+ " return self * -1\n",
+ "\n",
+ " def __float__(self):\n",
+ " return abs(self)\n",
+ "\n",
+ " def __int__(self):\n",
+ " return int(abs(self))\n",
+ "\n",
+ " def __complex__(self):\n",
+ " return complex(self.abscissa, self.ordinate)\n",
+ "\n",
+ " def __matmul__(self, other: \"Vector2D\"):\n",
+ " if not isinstance(other, Vector2D):\n",
+ " return NotImplemented\n",
+ " return self.abscissa * other.abscissa + self.ordinate * other.ordinate\n",
+ "\n",
+ " def get_angle(self, other: \"Vector2D\") -> float:\n",
+ " if not isinstance(other, Vector2D):\n",
+ " raise TypeError(\"Other must be Vector2D\")\n",
+ " if isclose(abs(other), 0) or isclose(abs(self), 0):\n",
+ " raise ValueError(\"You cannot get angle in between given vector and a zero vector\")\n",
+ " return acos((self @ other) / (abs(self) * abs(other)))\n",
+ "\n",
+ " def conj(self):\n",
+ " return Vector2D(self.abscissa, self.ordinate * -1)\n",
+ "\n",
+ "print(Vector2D(2,1))\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "393c431a",
+ "metadata": {},
+ "outputs": [
+ {
+ "ename": "TypeError",
+ "evalue": "unsupported operand type(s) for /: 'str' and 'int'",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)",
+ "Cell \u001b[1;32mIn[2], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mabcabcabc\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m/\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m3\u001b[39;49m\n",
+ "\u001b[1;31mTypeError\u001b[0m: unsupported operand type(s) for /: 'str' and 'int'"
+ ]
+ }
+ ],
+ "source": [
+ "\"abcabcabc\" / 3"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 41,
+ "id": "e10ab248",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'abc'"
+ ]
+ },
+ "execution_count": 41,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "\n",
+ "class Strdel(str):\n",
+ "\n",
+ " def __truediv__(self, other):\n",
+ " if not (isinstance(other, int)):\n",
+ " return NotImplemented\n",
+ " \n",
+ " if other <=0:\n",
+ " raise ValueError\n",
+ " \n",
+ " if not ((len(self)/ other).is_integer) or (len(self) // other) == 0:\n",
+ " return NotImplemented\n",
+ " \n",
+ " part = self[:len(self) // other]\n",
+ " if part * other == self:\n",
+ " return Strdel(part)\n",
+ " \n",
+ " return NotImplemented\n",
+ "stroka = Strdel(\"abcabc\")\n",
+ "stroka / 2"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 43,
+ "id": "6f5aede6",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "'abcabcabcabc'"
+ ]
+ },
+ "execution_count": 43,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "stroka * 2"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 37,
+ "id": "044780de",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "0 1\n",
+ "1 2\n",
+ "2 3\n",
+ "3 4\n"
+ ]
+ }
+ ],
+ "source": [
+ "def ar(arrr):\n",
+ " arrr.append(4)\n",
+ "arr = [1,2,3]\n",
+ "ar(arr)\n",
+ "for i, j in enumerate(arr):\n",
+ " print(i,j)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "id": "f4e7c72e",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "10\n"
+ ]
+ }
+ ],
+ "source": [
+ "x = 10\n",
+ "\n",
+ "def func():\n",
+ " global x\n",
+ "\n",
+ " print(x) # Казалось бы, должна взяться глобальная x\n",
+ " x = 5 # НО: наличие этой строки делает x локальной во всей функции\n",
+ "func()\n",
+ "# Ошибка: UnboundLocalError: local variable 'x' referenced before assignment"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "3e7f0e78",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "enumerate"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 40,
+ "id": "e5ee788d",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "4: Алексей\n",
+ "5: Мария\n",
+ "6: Иван\n"
+ ]
+ }
+ ],
+ "source": [
+ "class MyEnumerate:\n",
+ " def __init__(self, iterable, start=0):\n",
+ " # Сохраняем итератор из переданного объекта\n",
+ " self.iterator = iter(iterable)\n",
+ " self.count = start\n",
+ "\n",
+ " def __iter__(self):\n",
+ " # Итератор должен возвращать самого себя\n",
+ " return self\n",
+ "\n",
+ " def __next__(self):\n",
+ " # 1. Получаем следующее значение из вложенного итератора\n",
+ " # Если элементы закончатся, iter() сам выбросит StopIteration,\n",
+ " # и наш генератор тоже остановится.\n",
+ " value = next(self.iterator)\n",
+ " \n",
+ " # 2. Формируем текущий результат\n",
+ " result = (self.count, value)\n",
+ " \n",
+ " # 3. Увеличиваем счетчик для следующего шага\n",
+ " self.count += 1\n",
+ " \n",
+ " return result\n",
+ "\n",
+ "# Проверка:\n",
+ "names = [\"Алексей\", \"Мария\", \"Иван\"]\n",
+ "for idx, name in MyEnumerate(names, start=4):\n",
+ " print(f\"{idx}: {name}\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "d7d8d1a8",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1\n"
+ ]
+ }
+ ],
+ "source": [
+ "def giga_any(iterable):\n",
+ " iterable = iter(iterable)\n",
+ " count = 0\n",
+ " for item in iterable:\n",
+ " count+=1\n",
+ " if item:\n",
+ " return item\n",
+ " if count == 0:\n",
+ " return False\n",
+ " return item\n",
+ "print(giga_any([0,1]))\n",
+ " "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 53,
+ "id": "8e5dbb01",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "1"
+ ]
+ },
+ "execution_count": 53,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "range(6)[1]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "487e59ab",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "3\n",
+ "5\n"
+ ]
+ },
+ {
+ "data": {
+ "text/plain": [
+ "array([[[0., 0., 0., 0., 0.],\n",
+ " [0., 0., 0., 0., 0.],\n",
+ " [0., 0., 0., 0., 0.],\n",
+ " [0., 0., 0., 0., 0.],\n",
+ " [0., 0., 0., 0., 0.]],\n",
+ "\n",
+ " [[0., 0., 0., 0., 0.],\n",
+ " [0., 0., 0., 0., 0.],\n",
+ " [0., 0., 0., 0., 0.],\n",
+ " [0., 0., 0., 0., 0.],\n",
+ " [0., 0., 0., 0., 0.]],\n",
+ "\n",
+ " [[0., 0., 0., 0., 0.],\n",
+ " [0., 0., 0., 0., 0.],\n",
+ " [0., 0., 0., 0., 0.],\n",
+ " [0., 0., 0., 0., 0.],\n",
+ " [0., 0., 0., 0., 0.]]])"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import numpy as np\n",
+ "\n",
+ "# Создаем матрицу 3x5 (3 строки, 5 столбцов)\n",
+ "matrix = np.zeros((3, 5,5))\n",
+ "\n",
+ "print(matrix.shape[0]) # Выведет: 3 (строки)\n",
+ "print(matrix.shape[1]) \n",
+ "matrix # Выведет: 5 (столбцы)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 27,
+ "id": "241b61a0",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "np.True_"
+ ]
+ },
+ "execution_count": 27,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "import numpy as np\n",
+ "diagram_type = np.array([\"hist\",\"violin\",\"box\"])\n",
+ "arr2 = arr.copy()\n",
+ "diagram_type.sort()\n",
+ "(diagram_type == [\"hist\", \"box\", \"violin\"]).any()\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "id": "22c6a436",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "''"
+ ]
+ },
+ "execution_count": 26,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "\"\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "4beb7c3d",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bc903181",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "a4cdde85",
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.13.2"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/.gitignore b/.gitignore
index cececc15..bd573544 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,4 @@ __pycache__
# Python Files
*solved.ipynb
+.github\workflows\trying.ipynb.github\workflows\trying.ipynb
\ No newline at end of file
diff --git a/conditions/sem01/lesson05/tasks.md b/conditions/sem01/lesson05/tasks.md
index a608c0dd..a3593355 100644
--- a/conditions/sem01/lesson05/tasks.md
+++ b/conditions/sem01/lesson05/tasks.md
@@ -5,7 +5,11 @@
Ваша задача — определить, является ли заданная строка палиндромом.
+<<<<<<< HEAD:conditions/lesson05/tasks.md
+Допишите код в файле [task1](https://github.com/EvgrafovMichail/python_mipt_dafe_tasks/blob/main/solutions/lesson05/task1.py)
+=======
Допишите код в файле [task1](https://github.com/EvgrafovMichail/python_mipt_dafe_tasks/blob/main/solutions/sem01/lesson05/task1.py).
+>>>>>>> 7ba22f9a471a0b84a580183fed2466942f0104d2:conditions/sem01/lesson05/tasks.md
**Входные данные:**
- `text` — строка, состоящая из букв английского алфавита в верхнем и нижнем регистре длиной от 0 до 1000.
diff --git a/conditions/sem01/lesson11/task.md b/conditions/sem01/lesson11/task.md
index c783b137..d2a268ae 100644
--- a/conditions/sem01/lesson11/task.md
+++ b/conditions/sem01/lesson11/task.md
@@ -21,7 +21,7 @@
```
- При использовании объекта типа `Vector2D` в качестве аргумента функции `print()` в консоль должна печататься строка, представляющая собой команду создания данного объекта. Пример:
- ```python
+ ```pythonV
vector = Vector2D(1, 3)
print(vector)
# Vector2D(abscissa=1, ordinate=3)
diff --git a/deprecated_tests/sem01/tests/test_lesson02_tasks.py b/deprecated_tests/sem01/tests/test_lesson02_tasks.py
index f11403f4..b7febe4b 100644
--- a/deprecated_tests/sem01/tests/test_lesson02_tasks.py
+++ b/deprecated_tests/sem01/tests/test_lesson02_tasks.py
@@ -10,7 +10,7 @@
@pytest.mark.parametrize(
- "num, result_expected",
+ "num, result_expected",
(
pytest.param(
0,
@@ -44,7 +44,7 @@ def test_get_factorial(num: int, result_expected: int) -> None:
@pytest.mark.parametrize(
- "num, result_expected",
+ "num, result_expected",
(
pytest.param(
0,
@@ -83,7 +83,7 @@ def test_get_doubled_factorial(num: int, result_expected: int) -> None:
@pytest.mark.parametrize(
- "num, result_expected",
+ "num, result_expected",
(
pytest.param(
1,
@@ -125,7 +125,7 @@ def test_get_amount_of_ways_to_climb(
@pytest.mark.parametrize(
- "num, result_expected",
+ "num, result_expected",
(
pytest.param(
1,
@@ -162,7 +162,7 @@ def test_get_multiplications_amount(
@pytest.mark.parametrize(
- "num1, num2, result_expected",
+ "num1, num2, result_expected",
(
pytest.param(
1,
@@ -229,7 +229,7 @@ def test_get_gcd(
@pytest.mark.parametrize(
- "num, result_expected",
+ "num, result_expected",
(
pytest.param(
1,
@@ -273,10 +273,10 @@ def test_get_sum_of_prime_divisors(num: int, result_expected: int) -> None:
@pytest.mark.parametrize(
- "num, result_expected",
+ "num, result_expected",
(
pytest.param(
- -10**10,
+ -(10**10),
False,
id="negative-ten-billion",
),
diff --git a/deprecated_tests/sem01/tests/test_lesson04_tasks.py b/deprecated_tests/sem01/tests/test_lesson04_tasks.py
index 4110bdcc..c98b6f22 100644
--- a/deprecated_tests/sem01/tests/test_lesson04_tasks.py
+++ b/deprecated_tests/sem01/tests/test_lesson04_tasks.py
@@ -1,6 +1,7 @@
-import pytest
import random
+import pytest
+
from solutions.sem01.lesson04.task1 import is_arithmetic_progression
from solutions.sem01.lesson04.task2 import merge_intervals
from solutions.sem01.lesson04.task3 import find_single_number
@@ -8,62 +9,89 @@
from solutions.sem01.lesson04.task5 import find_row_with_most_ones
from solutions.sem01.lesson04.task6 import count_cycles
-@pytest.mark.parametrize("lst, expected", [
- pytest.param([], True, id="empty_list"),
- pytest.param([5], True, id="single_element"),
- pytest.param([1, 3], True, id="two_elements"),
- pytest.param([3, 1], True, id="two_elements_unsorted"),
- pytest.param([1, 3, 5, 7], True, id="already_sorted_ap"),
- pytest.param([3, 1, 5, 7], True, id="unsorted_ap"),
- pytest.param([1, 2, 4], False, id="not_ap"),
- pytest.param([10, 5, 0, -5], True, id="negative_difference"),
- pytest.param([1, 1, 1, 1], True, id="constant_sequence"),
- pytest.param([1, 2, 3, 5], False, id="almost_ap_but_not"),
- pytest.param([0, 0, 1], False, id="two_same_one_different"),
- pytest.param([10**5 + i*10**2 for i in range(1000)], True, id="long_list_true"),
- pytest.param([10**5 + i*10**2 for i in range(999)] + [1], False, id="long_list_false"),
-])
+
+@pytest.mark.parametrize(
+ "lst, expected",
+ [
+ pytest.param([], True, id="empty_list"),
+ pytest.param([5], True, id="single_element"),
+ pytest.param([1, 3], True, id="two_elements"),
+ pytest.param([3, 1], True, id="two_elements_unsorted"),
+ pytest.param([1, 3, 5, 7], True, id="already_sorted_ap"),
+ pytest.param([3, 1, 5, 7], True, id="unsorted_ap"),
+ pytest.param([1, 2, 4], False, id="not_ap"),
+ pytest.param([10, 5, 0, -5], True, id="negative_difference"),
+ pytest.param([1, 1, 1, 1], True, id="constant_sequence"),
+ pytest.param([1, 2, 3, 5], False, id="almost_ap_but_not"),
+ pytest.param([0, 0, 1], False, id="two_same_one_different"),
+ pytest.param([10**5 + i * 10**2 for i in range(1000)], True, id="long_list_true"),
+ pytest.param([10**5 + i * 10**2 for i in range(999)] + [1], False, id="long_list_false"),
+ ],
+)
def test_is_arithmetic_progression_parametrized(lst, expected):
if len(lst) > 500:
random.shuffle(lst)
assert is_arithmetic_progression(lst) == expected
-@pytest.mark.parametrize("intervals, expected", [
- pytest.param([], [], id="empty"),
- pytest.param([[1, 3]], [[1, 3]], id="single_interval"),
- pytest.param([[10, 13], [1, 3], [2, 6], [8, 10], [15, 18]], [[1, 6], [8, 13], [15, 18]], id="classic_merge"),
- pytest.param([[1, 4], [4, 5]], [[1, 5]], id="touching_intervals"),
- pytest.param([[1, 4], [2, 3]], [[1, 4]], id="nested_interval"),
- pytest.param([[5, 7], [1, 3], [15, 20], [0, 0], [2, 4], [6, 10], [0, 2]], [[0, 4], [5, 10], [15, 20]], id="unsorted_input"),
- pytest.param([[1, 2], [3, 4], [5, 6]], [[1, 2], [3, 4], [5, 6]], id="no_overlap"),
- pytest.param([[1, 10], [2, 3], [4, 5], [6, 7]], [[1, 10]], id="all_merged"),
-])
+@pytest.mark.parametrize(
+ "intervals, expected",
+ [
+ pytest.param([], [], id="empty"),
+ pytest.param([[1, 3]], [[1, 3]], id="single_interval"),
+ pytest.param(
+ [[10, 13], [1, 3], [2, 6], [8, 10], [15, 18]],
+ [[1, 6], [8, 13], [15, 18]],
+ id="classic_merge",
+ ),
+ pytest.param([[1, 4], [4, 5]], [[1, 5]], id="touching_intervals"),
+ pytest.param([[1, 4], [2, 3]], [[1, 4]], id="nested_interval"),
+ pytest.param(
+ [[5, 7], [1, 3], [15, 20], [0, 0], [2, 4], [6, 10], [0, 2]],
+ [[0, 4], [5, 10], [15, 20]],
+ id="unsorted_input",
+ ),
+ pytest.param([[1, 2], [3, 4], [5, 6]], [[1, 2], [3, 4], [5, 6]], id="no_overlap"),
+ pytest.param([[1, 10], [2, 3], [4, 5], [6, 7]], [[1, 10]], id="all_merged"),
+ ],
+)
def test_merge_intervals(intervals, expected):
assert merge_intervals(intervals) == expected
-@pytest.mark.parametrize("nums, expected", [
- pytest.param([2, 2, 1], 1, id="simple_case"),
- pytest.param([4, 1, 2, 1, 2], 4, id="middle_single"),
- pytest.param([1], 1, id="single_element"),
- pytest.param([100, 200, 300, 200, 100], 300, id="large_numbers"),
- pytest.param([0, 1, 0], 1, id="with_zero"),
- pytest.param([7, 8, 9, 8, 7], 9, id="unsorted"),
- pytest.param([i + 10**5 for i in range(500)] + [i + 10**5 for i in range(500)] + [69], 69, id="long_list"),
-])
+
+@pytest.mark.parametrize(
+ "nums, expected",
+ [
+ pytest.param([2, 2, 1], 1, id="simple_case"),
+ pytest.param([4, 1, 2, 1, 2], 4, id="middle_single"),
+ pytest.param([1], 1, id="single_element"),
+ pytest.param([100, 200, 300, 200, 100], 300, id="large_numbers"),
+ pytest.param([0, 1, 0], 1, id="with_zero"),
+ pytest.param([7, 8, 9, 8, 7], 9, id="unsorted"),
+ pytest.param(
+ [i + 10**5 for i in range(500)] + [i + 10**5 for i in range(500)] + [69],
+ 69,
+ id="long_list",
+ ),
+ ],
+)
def test_find_single_number(nums, expected):
assert find_single_number(nums) == expected
-@pytest.mark.parametrize("input_list, expected_list, expected_index", [
- pytest.param([0, 1, 0, 3, 12], [1, 3, 12, 0, 0], 3, id="basic"),
- pytest.param([0, 0, 1], [1, 0, 0], 1, id="zeros_first"),
- pytest.param([1, 2, 3], [1, 2, 3], 3, id="no_zeros"),
- pytest.param([0, 0, 0], [0, 0, 0], 0, id="all_zeros"),
- pytest.param([1, 0, 2, 0, 3, 0], [1, 2, 3, 0, 0, 0], 3, id="interleaved"),
- pytest.param([], [], 0, id="empty"),
- pytest.param([0], [0], 0, id="single_zero"),
- pytest.param([42], [42], 1, id="single_nonzero"),
-])
+
+@pytest.mark.parametrize(
+ "input_list, expected_list, expected_index",
+ [
+ pytest.param([0, 1, 0, 3, 12], [1, 3, 12, 0, 0], 3, id="basic"),
+ pytest.param([0, 0, 1], [1, 0, 0], 1, id="zeros_first"),
+ pytest.param([1, 2, 3], [1, 2, 3], 3, id="no_zeros"),
+ pytest.param([0, 0, 0], [0, 0, 0], 0, id="all_zeros"),
+ pytest.param([1, 0, 2, 0, 3, 0], [1, 2, 3, 0, 0, 0], 3, id="interleaved"),
+ pytest.param([], [], 0, id="empty"),
+ pytest.param([0], [0], 0, id="single_zero"),
+ pytest.param([42], [42], 1, id="single_nonzero"),
+ ],
+)
def test_move_zeros_to_end_parametrized(input_list, expected_list, expected_index):
arr = input_list[:]
result_index = move_zeros_to_end(arr)
@@ -71,89 +99,54 @@ def test_move_zeros_to_end_parametrized(input_list, expected_list, expected_inde
assert result_index == expected_index
-@pytest.mark.parametrize("matrix, expected_row", [
- pytest.param(
- [[0, 0, 1, 1],
- [0, 1, 1, 1],
- [0, 0, 0, 1],
- [1, 1, 1, 1],
- [0, 1, 1, 1]],
- 3,
- id="classic"
- ),
- pytest.param(
- [[0, 0, 0],
- [0, 0, 0],
- [0, 0, 0]],
- 0,
- id="all_zeros"
- ),
- pytest.param(
- [[1, 1, 1],
- [1, 1, 1],
- [1, 1, 1]],
- 0,
- id="all_ones_first"
- ),
- pytest.param(
- [[0, 1],
- [1, 1]],
- 1,
- id="two_rows"
- ),
- pytest.param(
- [[0]],
- 0,
- id="single_zero"
- ),
- pytest.param(
- [[1]],
- 0,
- id="single_one"
- ),
- pytest.param(
- [],
- 0,
- id="empty_matrix"
- ),
- pytest.param(
- [[0, 0, 1],
- [0, 1, 1],
- [0, 1, 1]],
- 1,
- id="tie"
- ),
-])
+@pytest.mark.parametrize(
+ "matrix, expected_row",
+ [
+ pytest.param(
+ [[0, 0, 1, 1], [0, 1, 1, 1], [0, 0, 0, 1], [1, 1, 1, 1], [0, 1, 1, 1]], 3, id="classic"
+ ),
+ pytest.param([[0, 0, 0], [0, 0, 0], [0, 0, 0]], 0, id="all_zeros"),
+ pytest.param([[1, 1, 1], [1, 1, 1], [1, 1, 1]], 0, id="all_ones_first"),
+ pytest.param([[0, 1], [1, 1]], 1, id="two_rows"),
+ pytest.param([[0]], 0, id="single_zero"),
+ pytest.param([[1]], 0, id="single_one"),
+ pytest.param([], 0, id="empty_matrix"),
+ pytest.param([[0, 0, 1], [0, 1, 1], [0, 1, 1]], 1, id="tie"),
+ ],
+)
def test_find_row_with_most_ones(matrix, expected_row):
assert find_row_with_most_ones(matrix) == expected_row
def test_find_row_with_most_ones_big_data():
size = 10000
- matrix = [[0]*size for i in range(size)]
- matrix[size-1][size-1] = 1
+ matrix = [[0] * size for i in range(size)]
+ matrix[size - 1][size - 1] = 1
for i in range(50):
assert find_row_with_most_ones(matrix) == 9999
size = 10000
- matrix = [[1]*size for i in range(size)]
+ matrix = [[1] * size for i in range(size)]
matrix[0][0] = 0
for i in range(50):
assert find_row_with_most_ones(matrix) == 1
-@pytest.mark.parametrize("input_arr, expected", [
- pytest.param([0], 1, id="self_loop"),
- pytest.param([1, 0], 1, id="two_cycle"),
- pytest.param([1, 2, 0], 1, id="three_cycle"),
- pytest.param([0, 1, 2], 3, id="three_self_loops"),
- pytest.param([1, 0, 3, 2], 2, id="two_2_cycles"),
- pytest.param([2, 0, 1, 4, 3], 2, id="mixed_cycles"),
- pytest.param([10, 6, 2, 9, 4, 0, 3, 8, 7, 1, 5], 5, id="mixed_cycles"),
- pytest.param([], 0, id="empty"),
-])
+@pytest.mark.parametrize(
+ "input_arr, expected",
+ [
+ pytest.param([0], 1, id="self_loop"),
+ pytest.param([1, 0], 1, id="two_cycle"),
+ pytest.param([1, 2, 0], 1, id="three_cycle"),
+ pytest.param([0, 1, 2], 3, id="three_self_loops"),
+ pytest.param([1, 0, 3, 2], 2, id="two_2_cycles"),
+ pytest.param([2, 0, 1, 4, 3], 2, id="mixed_cycles"),
+ pytest.param([10, 6, 2, 9, 4, 0, 3, 8, 7, 1, 5], 5, id="mixed_cycles"),
+ pytest.param([], 0, id="empty"),
+ ],
+)
def test_count_cycles(input_arr, expected):
arr = input_arr[:]
assert count_cycles(arr) == expected
diff --git a/deprecated_tests/sem01/tests/test_lesson05_tasks.py b/deprecated_tests/sem01/tests/test_lesson05_tasks.py
index 72ad6bc8..a43a2a45 100644
--- a/deprecated_tests/sem01/tests/test_lesson05_tasks.py
+++ b/deprecated_tests/sem01/tests/test_lesson05_tasks.py
@@ -1,4 +1,4 @@
-import pytest
+import pytest
from solutions.sem01.lesson05.task1 import is_palindrome
from solutions.sem01.lesson05.task2 import are_anagrams
@@ -7,145 +7,166 @@
from solutions.sem01.lesson05.task5 import reg_validator
from solutions.sem01.lesson05.task6 import simplify_path
-@pytest.mark.parametrize("s, expected", [
- pytest.param("", True, id="empty_string"),
- pytest.param("a", True, id="single_char"),
- pytest.param("aa", True, id="two_same"),
- pytest.param("ab", False, id="two_different"),
- pytest.param("aba", True, id="odd_palindrome"),
- pytest.param("abba", True, id="even_palindrome"),
- pytest.param("abcba", True, id="long_odd_palindrome"),
- pytest.param("abccba", True, id="long_even_palindrome"),
- pytest.param("abc", False, id="not_palindrome"),
- pytest.param("Aa", True, id="case_sensitive_mismatch"),
- pytest.param("Racecar", True, id="real_word_case_sensitive"),
- pytest.param("aA", True, id="reverse_case"),
- pytest.param("abcdefedcba", True, id="long_true"),
- pytest.param("abcdefedcbx", False, id="long_false"),
-])
+
+@pytest.mark.parametrize(
+ "s, expected",
+ [
+ pytest.param("", True, id="empty_string"),
+ pytest.param("a", True, id="single_char"),
+ pytest.param("aa", True, id="two_same"),
+ pytest.param("ab", False, id="two_different"),
+ pytest.param("aba", True, id="odd_palindrome"),
+ pytest.param("abba", True, id="even_palindrome"),
+ pytest.param("abcba", True, id="long_odd_palindrome"),
+ pytest.param("abccba", True, id="long_even_palindrome"),
+ pytest.param("abc", False, id="not_palindrome"),
+ pytest.param("Aa", True, id="case_sensitive_mismatch"),
+ pytest.param("Racecar", True, id="real_word_case_sensitive"),
+ pytest.param("aA", True, id="reverse_case"),
+ pytest.param("abcdefedcba", True, id="long_true"),
+ pytest.param("abcdefedcbx", False, id="long_false"),
+ ],
+)
def test_is_palindrome(s, expected):
assert is_palindrome(s) == expected
-@pytest.mark.parametrize("w1, w2, expected", [
- pytest.param("listen", "silent", True, id="classic_anagram"),
- pytest.param("evil", "vile", True, id="another_anagram"),
- pytest.param("a", "a", True, id="single_char_same"),
- pytest.param("A", "A", True, id="single_upper_same"),
- pytest.param("A", "a", False, id="case_sensitive_diff"),
- pytest.param("Listen", "Silent", False, id="mixed_case_not_anagram"),
- pytest.param("Aa", "aA", True, id="same_chars_permuted"),
- pytest.param("Ab", "ab", False, id="one_letter_case_diff"),
- pytest.param("abc", "cba", True, id="permuted_same_case"),
- pytest.param("abc", "Cba", False, id="case_breaks_anagram"),
- pytest.param("aabbcc", "abcabc", True, id="repeated_letters"),
- pytest.param("aabbcc", "aabbcd", False, id="extra_different_char"),
-])
+@pytest.mark.parametrize(
+ "w1, w2, expected",
+ [
+ pytest.param("listen", "silent", True, id="classic_anagram"),
+ pytest.param("evil", "vile", True, id="another_anagram"),
+ pytest.param("a", "a", True, id="single_char_same"),
+ pytest.param("A", "A", True, id="single_upper_same"),
+ pytest.param("A", "a", False, id="case_sensitive_diff"),
+ pytest.param("Listen", "Silent", False, id="mixed_case_not_anagram"),
+ pytest.param("Aa", "aA", True, id="same_chars_permuted"),
+ pytest.param("Ab", "ab", False, id="one_letter_case_diff"),
+ pytest.param("abc", "cba", True, id="permuted_same_case"),
+ pytest.param("abc", "Cba", False, id="case_breaks_anagram"),
+ pytest.param("aabbcc", "abcabc", True, id="repeated_letters"),
+ pytest.param("aabbcc", "aabbcd", False, id="extra_different_char"),
+ ],
+)
def test_are_anagrams_linear(w1, w2, expected):
assert are_anagrams(w1, w2) == expected
-@pytest.mark.parametrize("s, expected", [
- pytest.param("!!!", True, id="only_exclamations"),
- pytest.param("...?", True, id="dots_and_question"),
- pytest.param("", False, id="empty_string"),
- pytest.param("a", False, id="letter"),
- pytest.param("1", False, id="digit"),
- pytest.param(" ! ", False, id="space_inside"),
- pytest.param("!?.", True, id="symbols_only"),
- pytest.param("!a!", False, id="letter_in_middle"),
- pytest.param(" ", False, id="only_space"),
- pytest.param(".,;", True, id="commas_dots_semicolons"),
- pytest.param("", False, id="commas_dots_semicolons"),
-])
+@pytest.mark.parametrize(
+ "s, expected",
+ [
+ pytest.param("!!!", True, id="only_exclamations"),
+ pytest.param("...?", True, id="dots_and_question"),
+ pytest.param("", False, id="empty_string"),
+ pytest.param("a", False, id="letter"),
+ pytest.param("1", False, id="digit"),
+ pytest.param(" ! ", False, id="space_inside"),
+ pytest.param("!?.", True, id="symbols_only"),
+ pytest.param("!a!", False, id="letter_in_middle"),
+ pytest.param(" ", False, id="only_space"),
+ pytest.param(".,;", True, id="commas_dots_semicolons"),
+ pytest.param("", False, id="commas_dots_semicolons"),
+ ],
+)
def test_is_only_punctuation(s, expected):
assert is_punctuation(s) == expected
-@pytest.mark.parametrize("compressed, expected", [
- pytest.param("AbcD*4 ef GhI*2", "AbcDAbcDAbcDAbcDefGhIGhI", id="example"),
- pytest.param("a*3 b*2", "aaabb", id="simple_letters"),
- pytest.param("Hello", "Hello", id="star_one"),
- pytest.param("xyz", "xyz", id="no_compression"),
- pytest.param("", "", id="empty_input"),
- pytest.param("Test*2 Space", "TestTestSpace", id="mixed"),
- pytest.param("a*10", "aaaaaaaaaa", id="ten_a"),
- pytest.param("x y z", "xyz", id="three_plain"),
- pytest.param("Word word", "Wordword", id="case_sensitive"),
-])
+
+@pytest.mark.parametrize(
+ "compressed, expected",
+ [
+ pytest.param("AbcD*4 ef GhI*2", "AbcDAbcDAbcDAbcDefGhIGhI", id="example"),
+ pytest.param("a*3 b*2", "aaabb", id="simple_letters"),
+ pytest.param("Hello", "Hello", id="star_one"),
+ pytest.param("xyz", "xyz", id="no_compression"),
+ pytest.param("", "", id="empty_input"),
+ pytest.param("Test*2 Space", "TestTestSpace", id="mixed"),
+ pytest.param("a*10", "aaaaaaaaaa", id="ten_a"),
+ pytest.param("x y z", "xyz", id="three_plain"),
+ pytest.param("Word word", "Wordword", id="case_sensitive"),
+ ],
+)
def test_decompress(compressed, expected):
assert unzip(compressed) == expected
-@pytest.mark.parametrize("regexp, s, expected", [
- pytest.param("d", "123", True, id="d_valid_number"),
- pytest.param("d", "0", True, id="d_zero"),
- pytest.param("d", "abc", False, id="d_letters_instead_of_digits"),
- pytest.param("d", "", False, id="d_empty_string"),
- pytest.param("w", "hello", True, id="w_lowercase_word"),
- pytest.param("w", "HelloWorld", True, id="w_mixed_case_word"),
- pytest.param("w", "hello123", False, id="w_word_with_digits"),
- pytest.param("w", "", False, id="w_empty_string"),
- pytest.param("s", "abc123", True, id="s_alphanum"),
- pytest.param("s", "ABC99", True, id="s_uppercase_and_digits"),
- pytest.param("s", "abc_123", False, id="s_contains_underscore"),
- pytest.param("s", "", False, id="s_empty_string"),
- pytest.param("d-d", "12-34", True, id="d_dash_d_valid"),
- pytest.param("d-d", "12--34", False, id="d_dash_d_double_dash"),
- pytest.param("d-d", "12-abc", False, id="d_dash_d_letters_after_dash"),
- pytest.param("d-d", "1234", False, id="d_dash_d_missing_dash"),
- pytest.param("w.w", "hi.there", True, id="w_dot_w_valid"),
- pytest.param("w.w", "hi..there", False, id="w_dot_w_double_dot"),
- pytest.param("w.w", "hi1.there", False, id="w_dot_w_digit_in_first_word"),
- pytest.param("s.s", "h1i.th32ere", True, id="s_dot_s_valid"),
- pytest.param("s.s", "hi4..t2here", False, id="s_dot_s_double_dot"),
- pytest.param("d-dw", "12-45abc", True, id="example_valid"),
- pytest.param("d-dw", "1-abs", False, id="example_second_part_not_digit"),
- pytest.param("d-dw", "1-b123r", False, id="example_letter_after_dash"),
- pytest.param("d-dw", "1--123vdg", False, id="example_double_dash"),
- pytest.param("d-dw", "123-456XYZ", True, id="d-dw_all_caps"),
- pytest.param("d-dw", "0-0a", True, id="d-dw_minimal_valid"),
- pytest.param("d@d", "5@7", True, id="d_at_d_valid"),
- pytest.param("d@d", "5@@7", False, id="d_at_d_double_at"),
- pytest.param("w s", "hi 123", True, id="w_space_s_valid"),
- pytest.param("w s", "hi123", False, id="w_space_s_missing_space"),
- pytest.param("w s", "hi 123!", False, id="w_space_s_extra_char_in_s"),
- pytest.param("", "", True, id="empty_regexp_empty_string"),
- pytest.param("", "a", False, id="empty_regexp_non_empty_string"),
- pytest.param("d", "", False, id="non_empty_regexp_empty_string"),
- pytest.param("d!", "5!", True, id="d_exclam_valid"),
- pytest.param("d!", "5", False, id="d_exclam_missing_exclam"),
- pytest.param("d!", "5!!", False, id="d_exclam_extra_exclam"),
- pytest.param("s", "a1", True, id="s_letter_digit"),
- pytest.param("s", "1a", True, id="s_digit_letter"),
- pytest.param("s", "a!1", False, id="s_contains_exclamation"),
- pytest.param("d-w-s", "123-abc-XY1Z23", True, id="d_w_s_valid"),
- pytest.param("d-w-s", "123-abc-XYZ_123", False, id="d_w_s_underscore_in_s"),
-])
+
+@pytest.mark.parametrize(
+ "regexp, s, expected",
+ [
+ pytest.param("d", "123", True, id="d_valid_number"),
+ pytest.param("d", "0", True, id="d_zero"),
+ pytest.param("d", "abc", False, id="d_letters_instead_of_digits"),
+ pytest.param("d", "", False, id="d_empty_string"),
+ pytest.param("w", "hello", True, id="w_lowercase_word"),
+ pytest.param("w", "HelloWorld", True, id="w_mixed_case_word"),
+ pytest.param("w", "hello123", False, id="w_word_with_digits"),
+ pytest.param("w", "", False, id="w_empty_string"),
+ pytest.param("s", "abc123", True, id="s_alphanum"),
+ pytest.param("s", "ABC99", True, id="s_uppercase_and_digits"),
+ pytest.param("s", "abc_123", False, id="s_contains_underscore"),
+ pytest.param("s", "", False, id="s_empty_string"),
+ pytest.param("d-d", "12-34", True, id="d_dash_d_valid"),
+ pytest.param("d-d", "12--34", False, id="d_dash_d_double_dash"),
+ pytest.param("d-d", "12-abc", False, id="d_dash_d_letters_after_dash"),
+ pytest.param("d-d", "1234", False, id="d_dash_d_missing_dash"),
+ pytest.param("w.w", "hi.there", True, id="w_dot_w_valid"),
+ pytest.param("w.w", "hi..there", False, id="w_dot_w_double_dot"),
+ pytest.param("w.w", "hi1.there", False, id="w_dot_w_digit_in_first_word"),
+ pytest.param("s.s", "h1i.th32ere", True, id="s_dot_s_valid"),
+ pytest.param("s.s", "hi4..t2here", False, id="s_dot_s_double_dot"),
+ pytest.param("d-dw", "12-45abc", True, id="example_valid"),
+ pytest.param("d-dw", "1-abs", False, id="example_second_part_not_digit"),
+ pytest.param("d-dw", "1-b123r", False, id="example_letter_after_dash"),
+ pytest.param("d-dw", "1--123vdg", False, id="example_double_dash"),
+ pytest.param("d-dw", "123-456XYZ", True, id="d-dw_all_caps"),
+ pytest.param("d-dw", "0-0a", True, id="d-dw_minimal_valid"),
+ pytest.param("d@d", "5@7", True, id="d_at_d_valid"),
+ pytest.param("d@d", "5@@7", False, id="d_at_d_double_at"),
+ pytest.param("w s", "hi 123", True, id="w_space_s_valid"),
+ pytest.param("w s", "hi123", False, id="w_space_s_missing_space"),
+ pytest.param("w s", "hi 123!", False, id="w_space_s_extra_char_in_s"),
+ pytest.param("", "", True, id="empty_regexp_empty_string"),
+ pytest.param("", "a", False, id="empty_regexp_non_empty_string"),
+ pytest.param("d", "", False, id="non_empty_regexp_empty_string"),
+ pytest.param("d!", "5!", True, id="d_exclam_valid"),
+ pytest.param("d!", "5", False, id="d_exclam_missing_exclam"),
+ pytest.param("d!", "5!!", False, id="d_exclam_extra_exclam"),
+ pytest.param("s", "a1", True, id="s_letter_digit"),
+ pytest.param("s", "1a", True, id="s_digit_letter"),
+ pytest.param("s", "a!1", False, id="s_contains_exclamation"),
+ pytest.param("d-w-s", "123-abc-XY1Z23", True, id="d_w_s_valid"),
+ pytest.param("d-w-s", "123-abc-XYZ_123", False, id="d_w_s_underscore_in_s"),
+ ],
+)
def test_match_pattern(regexp, s, expected):
assert reg_validator(regexp, s) == expected
-@pytest.mark.parametrize("path, expected", [
- pytest.param("/home/", "/home", id="trailing_slash"),
- pytest.param("/../", "", id="go_above_root"),
- pytest.param("/home//foo/", "/home/foo", id="double_slash"),
- pytest.param("/home/./foo/", "/home/foo", id="current_dir_dot"),
- pytest.param("/./././", "/", id="only_dots_and_slashes"),
- pytest.param("/a/./b/../../c/", "/c", id="complex_up_and_down"),
- pytest.param("/a/b/c/../../../", "/", id="back_to_root"),
- pytest.param("/", "/", id="root_only"),
- pytest.param("/.", "/", id="root_with_dot"),
- pytest.param("/..", "", id="root_with_double_dot"),
- pytest.param("/...", "/...", id="triple_dot_as_name"),
- pytest.param("/..a", "/..a", id="dot_dot_a_as_name"),
- pytest.param("/a.b/c.d", "/a.b/c.d", id="names_with_dots"),
- pytest.param("/a//b////c/d//././/..", "/a/b/c", id="messy_path"),
- pytest.param("/a/./b/./c/./d", "/a/b/c/d", id="dots_everywhere"),
- pytest.param("/a/./b/../../c/./d/", "/c/d", id="up_down_with_dots"),
- pytest.param("/../foo", "", id="up_then_valid"),
- pytest.param("/../../foo", "", id="multiple_up_then_valid"),
- pytest.param("/../../../", "", id="three_up_from_root"),
- pytest.param("/home/foo/./../../../", "", id="too_many_up"),
- pytest.param("/_a.b/c__1/..", "/_a.b", id="names_with_underscores_and_dots"),
-])
+@pytest.mark.parametrize(
+ "path, expected",
+ [
+ pytest.param("/home/", "/home", id="trailing_slash"),
+ pytest.param("/../", "", id="go_above_root"),
+ pytest.param("/home//foo/", "/home/foo", id="double_slash"),
+ pytest.param("/home/./foo/", "/home/foo", id="current_dir_dot"),
+ pytest.param("/./././", "/", id="only_dots_and_slashes"),
+ pytest.param("/a/./b/../../c/", "/c", id="complex_up_and_down"),
+ pytest.param("/a/b/c/../../../", "/", id="back_to_root"),
+ pytest.param("/", "/", id="root_only"),
+ pytest.param("/.", "/", id="root_with_dot"),
+ pytest.param("/..", "", id="root_with_double_dot"),
+ pytest.param("/...", "/...", id="triple_dot_as_name"),
+ pytest.param("/..a", "/..a", id="dot_dot_a_as_name"),
+ pytest.param("/a.b/c.d", "/a.b/c.d", id="names_with_dots"),
+ pytest.param("/a//b////c/d//././/..", "/a/b/c", id="messy_path"),
+ pytest.param("/a/./b/./c/./d", "/a/b/c/d", id="dots_everywhere"),
+ pytest.param("/a/./b/../../c/./d/", "/c/d", id="up_down_with_dots"),
+ pytest.param("/../foo", "", id="up_then_valid"),
+ pytest.param("/../../foo", "", id="multiple_up_then_valid"),
+ pytest.param("/../../../", "", id="three_up_from_root"),
+ pytest.param("/home/foo/./../../../", "", id="too_many_up"),
+ pytest.param("/_a.b/c__1/..", "/_a.b", id="names_with_underscores_and_dots"),
+ ],
+)
def test_simplify_path(path, expected):
- assert simplify_path(path) == expected
\ No newline at end of file
+ assert simplify_path(path) == expected
diff --git a/deprecated_tests/sem01/tests/test_lesson06_tasks.py b/deprecated_tests/sem01/tests/test_lesson06_tasks.py
index 707d6609..f2f6a282 100644
--- a/deprecated_tests/sem01/tests/test_lesson06_tasks.py
+++ b/deprecated_tests/sem01/tests/test_lesson06_tasks.py
@@ -1,4 +1,4 @@
-import pytest
+import pytest
from solutions.sem01.lesson06.task1 import int_to_roman
from solutions.sem01.lesson06.task2 import get_len_of_longest_substring
@@ -6,103 +6,122 @@
from solutions.sem01.lesson06.task4 import count_unique_words
-@pytest.mark.parametrize("num, expected", [
- pytest.param(1, "I", id="one"),
- pytest.param(2, "II", id="two"),
- pytest.param(3, "III", id="three"),
- pytest.param(4, "IV", id="four"),
- pytest.param(5, "V", id="five"),
- pytest.param(6, "VI", id="six"),
- pytest.param(9, "IX", id="nine"),
- pytest.param(10, "X", id="ten"),
- pytest.param(11, "XI", id="eleven"),
- pytest.param(14, "XIV", id="fourteen"),
- pytest.param(19, "XIX", id="nineteen"),
- pytest.param(27, "XXVII", id="twenty_seven"),
- pytest.param(40, "XL", id="forty"),
- pytest.param(44, "XLIV", id="forty_four"),
- pytest.param(50, "L", id="fifty"),
- pytest.param(58, "LVIII", id="fifty_eight"),
- pytest.param(90, "XC", id="ninety"),
- pytest.param(99, "XCIX", id="ninety_nine"),
- pytest.param(100, "C", id="hundred"),
- pytest.param(400, "CD", id="four_hundred"),
- pytest.param(500, "D", id="five_hundred"),
- pytest.param(900, "CM", id="nine_hundred"),
- pytest.param(1000, "M", id="thousand"),
- pytest.param(1994, "MCMXCIV", id="mcmxciv"),
- pytest.param(3999, "MMMCMXCIX", id="max_value"),
- pytest.param(2023, "MMXXIII", id="current_year"),
- pytest.param(1984, "MCMLXXXIV", id="classic"),
-])
+@pytest.mark.parametrize(
+ "num, expected",
+ [
+ pytest.param(1, "I", id="one"),
+ pytest.param(2, "II", id="two"),
+ pytest.param(3, "III", id="three"),
+ pytest.param(4, "IV", id="four"),
+ pytest.param(5, "V", id="five"),
+ pytest.param(6, "VI", id="six"),
+ pytest.param(9, "IX", id="nine"),
+ pytest.param(10, "X", id="ten"),
+ pytest.param(11, "XI", id="eleven"),
+ pytest.param(14, "XIV", id="fourteen"),
+ pytest.param(19, "XIX", id="nineteen"),
+ pytest.param(27, "XXVII", id="twenty_seven"),
+ pytest.param(40, "XL", id="forty"),
+ pytest.param(44, "XLIV", id="forty_four"),
+ pytest.param(50, "L", id="fifty"),
+ pytest.param(58, "LVIII", id="fifty_eight"),
+ pytest.param(90, "XC", id="ninety"),
+ pytest.param(99, "XCIX", id="ninety_nine"),
+ pytest.param(100, "C", id="hundred"),
+ pytest.param(400, "CD", id="four_hundred"),
+ pytest.param(500, "D", id="five_hundred"),
+ pytest.param(900, "CM", id="nine_hundred"),
+ pytest.param(1000, "M", id="thousand"),
+ pytest.param(1994, "MCMXCIV", id="mcmxciv"),
+ pytest.param(3999, "MMMCMXCIX", id="max_value"),
+ pytest.param(2023, "MMXXIII", id="current_year"),
+ pytest.param(1984, "MCMLXXXIV", id="classic"),
+ ],
+)
def test_int_to_roman(num, expected):
assert int_to_roman(num) == expected
-@pytest.mark.parametrize("s, expected", [
- pytest.param("", 0, id="empty_string"),
- pytest.param("a", 1, id="single_char"),
- pytest.param("aa", 1, id="two_same_chars"),
- pytest.param("ab", 2, id="two_different_chars"),
- pytest.param("abcabcbb", 3, id="classic_example_abc"),
- pytest.param("bbbbb", 1, id="all_same"),
- pytest.param("pwwkew", 3, id="pwwkew_example"),
- pytest.param("abcdef", 6, id="all_unique"),
- pytest.param("abcabcbbxyz", 4, id="long_tail_unique"),
- pytest.param("aab", 2, id="aab"),
- pytest.param("dvdf", 3, id="dvdf"),
- pytest.param(" ", 1, id="single_space"),
- pytest.param("a b c", 3, id="letters_and_spaces_unique"),
- pytest.param("a b a", 3, id="space_in_middle_with_repeat"),
- pytest.param("1234567890", 10, id="digits_all_unique"),
- pytest.param("112233", 2, id="repeating_digits"),
- pytest.param("abcdefghijklmnopqrstuvwxyz", 26, id="all_lowercase_letters"),
- pytest.param("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ", 63, id="max_unique_set"),
- pytest.param("a" * 10000, 1, id="ten_thousand_same"),
- pytest.param("abc" * 3333 + "d", 4, id="long_repeating_with_new_char"),
-])
+
+@pytest.mark.parametrize(
+ "s, expected",
+ [
+ pytest.param("", 0, id="empty_string"),
+ pytest.param("a", 1, id="single_char"),
+ pytest.param("aa", 1, id="two_same_chars"),
+ pytest.param("ab", 2, id="two_different_chars"),
+ pytest.param("abcabcbb", 3, id="classic_example_abc"),
+ pytest.param("bbbbb", 1, id="all_same"),
+ pytest.param("pwwkew", 3, id="pwwkew_example"),
+ pytest.param("abcdef", 6, id="all_unique"),
+ pytest.param("abcabcbbxyz", 4, id="long_tail_unique"),
+ pytest.param("aab", 2, id="aab"),
+ pytest.param("dvdf", 3, id="dvdf"),
+ pytest.param(" ", 1, id="single_space"),
+ pytest.param("a b c", 3, id="letters_and_spaces_unique"),
+ pytest.param("a b a", 3, id="space_in_middle_with_repeat"),
+ pytest.param("1234567890", 10, id="digits_all_unique"),
+ pytest.param("112233", 2, id="repeating_digits"),
+ pytest.param("abcdefghijklmnopqrstuvwxyz", 26, id="all_lowercase_letters"),
+ pytest.param(
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ",
+ 63,
+ id="max_unique_set",
+ ),
+ pytest.param("a" * 10000, 1, id="ten_thousand_same"),
+ pytest.param("abc" * 3333 + "d", 4, id="long_repeating_with_new_char"),
+ ],
+)
def test_get_len_of_longest_substring(s, expected):
assert get_len_of_longest_substring(s) == expected
-@pytest.mark.parametrize("nums, k, expected", [
- pytest.param([23, 2, 4, 6, 7], 6, True, id="subarray_2_4_sum_6"),
- pytest.param([23, 2, 6, 4, 7], 6, True, id="total_sum_42_div_by_6"),
- pytest.param([23, 2, 6, 4, 7], 13, False, id="no_valid_subarray"),
- pytest.param([0, 0], 1, True, id="two_zeros_any_k"),
- pytest.param([1, 0], 2, False, id="length_2_sum_1_not_div_by_2"),
- pytest.param([1, 2, 3], 5, True, id="subarray_2_3_sum_5"),
- pytest.param([1], 1, False, id="single_element_too_short"),
- pytest.param([5, 0, 0], 3, True, id="zeros_after_nonzero"),
- pytest.param([1, 2], 3, True, id="exact_sum_equals_k"),
- pytest.param([1, 2], 4, False, id="sum_not_divisible_by_k"),
- pytest.param([0], 1, False, id="single_zero_too_short"),
- pytest.param([1, 0, 2], 2, True, id="subarray_0_2_sum_2"),
- pytest.param([4, 2, 4], 6, True, id="first_two_sum_6"),
- pytest.param([1, 1, 1], 2, True, id="first_two_ones_sum_2"),
- pytest.param([1, 2, 4, 8], 8, False, id="no_subarray_divisible_by_8"),
- pytest.param([0, 1, 0], 2, False, id="zeros_with_one_sum_1"),
- pytest.param([0, 1, 0, 0], 2, True, id="last_two_zeros_sum_0_div_by_any"),
-])
+
+@pytest.mark.parametrize(
+ "nums, k, expected",
+ [
+ pytest.param([23, 2, 4, 6, 7], 6, True, id="subarray_2_4_sum_6"),
+ pytest.param([23, 2, 6, 4, 7], 6, True, id="total_sum_42_div_by_6"),
+ pytest.param([23, 2, 6, 4, 7], 13, False, id="no_valid_subarray"),
+ pytest.param([0, 0], 1, True, id="two_zeros_any_k"),
+ pytest.param([1, 0], 2, False, id="length_2_sum_1_not_div_by_2"),
+ pytest.param([1, 2, 3], 5, True, id="subarray_2_3_sum_5"),
+ pytest.param([1], 1, False, id="single_element_too_short"),
+ pytest.param([5, 0, 0], 3, True, id="zeros_after_nonzero"),
+ pytest.param([1, 2], 3, True, id="exact_sum_equals_k"),
+ pytest.param([1, 2], 4, False, id="sum_not_divisible_by_k"),
+ pytest.param([0], 1, False, id="single_zero_too_short"),
+ pytest.param([1, 0, 2], 2, True, id="subarray_0_2_sum_2"),
+ pytest.param([4, 2, 4], 6, True, id="first_two_sum_6"),
+ pytest.param([1, 1, 1], 2, True, id="first_two_ones_sum_2"),
+ pytest.param([1, 2, 4, 8], 8, False, id="no_subarray_divisible_by_8"),
+ pytest.param([0, 1, 0], 2, False, id="zeros_with_one_sum_1"),
+ pytest.param([0, 1, 0, 0], 2, True, id="last_two_zeros_sum_0_div_by_any"),
+ ],
+)
def test_is_there_any_good_subarray(nums, k, expected):
assert is_there_any_good_subarray(nums, k) == expected
import pytest
-@pytest.mark.parametrize("text, expected", [
- pytest.param("", 0, id="empty_string"),
- pytest.param(" ", 0, id="only_spaces"),
- pytest.param("hello", 1, id="single_word"),
- pytest.param("Hello hello", 1, id="case_insensitive"),
- pytest.param("Hello, world!", 2, id="punctuation_around"),
- pytest.param("Hello, hello, world!", 2, id="duplicates_with_punct"),
- pytest.param("The quick brown fox jumps over the lazy dog.", 8, id="classic_pangram"),
- pytest.param("!!! ???", 0, id="only_punctuation"),
- pytest.param("word1 word2 word1", 2, id="digits_in_words"),
- pytest.param("Don't stop believing!", 3, id="apostrophe_inside"),
- pytest.param(" Hello , World ! ", 2, id="extra_whitespace"),
- pytest.param("A a A a", 1, id="repeated_case_variants"),
- pytest.param("word... word!!!", 1, id="multiple_punct_at_end"),
- pytest.param("123 456 123", 2, id="numbers_as_words"),
-])
+
+@pytest.mark.parametrize(
+ "text, expected",
+ [
+ pytest.param("", 0, id="empty_string"),
+ pytest.param(" ", 0, id="only_spaces"),
+ pytest.param("hello", 1, id="single_word"),
+ pytest.param("Hello hello", 1, id="case_insensitive"),
+ pytest.param("Hello, world!", 2, id="punctuation_around"),
+ pytest.param("Hello, hello, world!", 2, id="duplicates_with_punct"),
+ pytest.param("The quick brown fox jumps over the lazy dog.", 8, id="classic_pangram"),
+ pytest.param("!!! ???", 0, id="only_punctuation"),
+ pytest.param("word1 word2 word1", 2, id="digits_in_words"),
+ pytest.param("Don't stop believing!", 3, id="apostrophe_inside"),
+ pytest.param(" Hello , World ! ", 2, id="extra_whitespace"),
+ pytest.param("A a A a", 1, id="repeated_case_variants"),
+ pytest.param("word... word!!!", 1, id="multiple_punct_at_end"),
+ pytest.param("123 456 123", 2, id="numbers_as_words"),
+ ],
+)
def test_count_unique_words(text, expected):
- assert count_unique_words(text) == expected
\ No newline at end of file
+ assert count_unique_words(text) == expected
diff --git a/deprecated_tests/sem01/tests/test_lesson08_tasks.py b/deprecated_tests/sem01/tests/test_lesson08_tasks.py
index 962ba4bd..06f04319 100644
--- a/deprecated_tests/sem01/tests/test_lesson08_tasks.py
+++ b/deprecated_tests/sem01/tests/test_lesson08_tasks.py
@@ -1,10 +1,10 @@
-import pytest
import math
import time
from solutions.sem01.lesson08.task1 import make_averager
from solutions.sem01.lesson08.task2 import collect_statistic
+
def test_make_averager():
get_avg = make_averager(2)
@@ -15,6 +15,7 @@ def test_make_averager():
assert math.isclose(get_avg(5), 1)
assert math.isclose(get_avg(5), 5)
+
def test_make_averager2():
get_avg = make_averager(5)
@@ -27,6 +28,7 @@ def test_make_averager2():
assert math.isclose(get_avg(-7), 0)
assert math.isclose(get_avg(-2), -1)
+
def test_collect_statistic():
statistics: list[str, list[float, int]] = {}
@@ -37,7 +39,7 @@ def func1() -> None:
@collect_statistic(statistics)
def func2() -> None:
time.sleep(0.1)
-
+
for _ in range(3):
func1()
@@ -58,10 +60,11 @@ def test_collect_statistic_inout():
@collect_statistic(statistics)
def func(a, b, *, c, d):
return a + b + c + d
-
+
assert func(1, 2, c=3, d=4) == 10
assert statistics[func.__name__][1] == 1
+
def test_collect_statistic_count_call():
statistics: list[str, list[float, int]] = {}
@@ -76,7 +79,7 @@ def func():
count_call += 1
return func
-
+
func = func_fab()
func()
- assert statistics[func.__name__][1] == 1
\ No newline at end of file
+ assert statistics[func.__name__][1] == 1
diff --git a/deprecated_tests/sem01/tests/test_lesson11_tasks.py b/deprecated_tests/sem01/tests/test_lesson11_tasks.py
index d0cd02ef..16f3d70f 100644
--- a/deprecated_tests/sem01/tests/test_lesson11_tasks.py
+++ b/deprecated_tests/sem01/tests/test_lesson11_tasks.py
@@ -84,13 +84,12 @@ def test_print():
sys.stdout = old_stdout
output = captured_output.getvalue()
assert (
- output == "Vector2D(abscissa=1, ordinate=-2)"
+ output == "Vector2D(abscissa=1, ordinate=-2)"
or output == "Vector2D(abscissa=1., ordinate=-2.)"
- or output == "Vector2D(abscissa=1.0, ordinate=-2.0)"
+ or output == "Vector2D(abscissa=1.0, ordinate=-2.0)"
)
-
@pytest.mark.parametrize(
"abscissa1, ordinate1, abscissa2, ordinate2, expected",
[
diff --git a/deprecated_tests/sem01/tests_hw/test_hw1.py b/deprecated_tests/sem01/tests_hw/test_hw1.py
new file mode 100644
index 00000000..9819410b
--- /dev/null
+++ b/deprecated_tests/sem01/tests_hw/test_hw1.py
@@ -0,0 +1,49 @@
+from typing import Any
+
+import pytest
+
+# Импортируем тестируемую функцию и константу
+from homeworks.hw1.aggregate_segmentation import ALLOWED_TYPES, aggregate_segmentation
+
+# сюда тупа скопировать свой файл с 1 заданием
+# и потом запустить счерез pytest
+
+
+def test_aggregate_segmentation_with_invalid_type_after_valid_detailed():
+ """Тест с дополнительными проверками состояния до и после невалидного сегмента"""
+ segmentation_data = [
+ {
+ "audio_id": "audio_1",
+ "segment_id": "segment_1",
+ "segment_start": 0.0,
+ "segment_end": 1.0,
+ "type": "voice_human",
+ },
+ {
+ "audio_id": "audio_2", # Другой валидный audio_id
+ "segment_id": "segment_3",
+ "segment_start": 0.0,
+ "segment_end": 1.0,
+ "type": "voice_bot",
+ },
+ {
+ "audio_id": "audio_1", # Невалидный сегмент
+ "segment_id": "segment_2",
+ "segment_start": 1.0,
+ "segment_end": 2.0,
+ "type": "invalid_type",
+ },
+ ]
+
+ valid_result, invalid_result = aggregate_segmentation(segmentation_data)
+
+ # audio_1 должен быть в невалидных
+ assert "audio_1" in invalid_result
+ # audio_1 не должно быть в валидных
+ assert "audio_1" not in valid_result
+ # audio_2 должен остаться валидным
+ assert "audio_2" in valid_result
+ # В audio_2 должен быть один сегмент
+ assert len(valid_result["audio_2"]) == 1
+ # Проверяем содержимое сегмента audio_2
+ assert valid_result["audio_2"]["segment_3"] == {"start": 0.0, "end": 1.0, "type": "voice_bot"}
diff --git a/deprecated_tests/sem01/tests_hw/test_hw1_task1.py b/deprecated_tests/sem01/tests_hw/test_hw1_task1.py
new file mode 100644
index 00000000..348ec6f8
--- /dev/null
+++ b/deprecated_tests/sem01/tests_hw/test_hw1_task1.py
@@ -0,0 +1,387 @@
+from typing import Any
+
+import pytest
+
+# Импортируем тестируемую функцию и константу
+from homeworks.hw1.aggregate_segmentation import ALLOWED_TYPES, aggregate_segmentation
+
+
+class TestAggregateSegmentation:
+ """Тесты для функции агрегации сегментации аудио данных."""
+
+ def test_valid_segments_different_audio_ids(self):
+ """Тест валидных сегментов с разными audio_id."""
+ data = [
+ {
+ "audio_id": "audio-123",
+ "segment_id": "seg-1",
+ "segment_start": 0.5,
+ "segment_end": 2.5,
+ "type": "voice_human",
+ },
+ {
+ "audio_id": "audio-456",
+ "segment_id": "seg-2",
+ "segment_start": 1.0,
+ "segment_end": 3.0,
+ "type": "voice_bot",
+ },
+ ]
+ valid, invalid = aggregate_segmentation(data)
+
+ assert len(invalid) == 0
+ assert "audio-123" in valid
+ assert "audio-456" in valid
+ assert valid["audio-123"]["seg-1"]["type"] == "voice_human"
+ assert valid["audio-456"]["seg-2"]["type"] == "voice_bot"
+
+ def test_valid_segments_same_audio_id(self):
+ """Тест валидных сегментов с одинаковым audio_id."""
+ data = [
+ {
+ "audio_id": "audio-123",
+ "segment_id": "seg-1",
+ "segment_start": 0.5,
+ "segment_end": 2.5,
+ "type": "voice_human",
+ },
+ {
+ "audio_id": "audio-123",
+ "segment_id": "seg-2",
+ "segment_start": 3.0,
+ "segment_end": 5.0,
+ "type": "spotter_word",
+ },
+ ]
+ valid, invalid = aggregate_segmentation(data)
+
+ assert len(invalid) == 0
+ assert len(valid["audio-123"]) == 2
+ assert "seg-1" in valid["audio-123"]
+ assert "seg-2" in valid["audio-123"]
+
+ def test_segments_without_voice_all_none(self):
+ """Тест сегментов без голоса (все поля None) - должен создать пустой словарь."""
+ data = [
+ {
+ "audio_id": "audio-123",
+ "segment_id": "seg-1",
+ "segment_start": None,
+ "segment_end": None,
+ "type": None,
+ },
+ {
+ "audio_id": "audio-123",
+ "segment_id": "seg-2",
+ "segment_start": None,
+ "segment_end": None,
+ "type": None,
+ },
+ ]
+ valid, invalid = aggregate_segmentation(data)
+
+ assert len(invalid) == 0
+ assert valid["audio-123"] == {}
+
+ def test_mixed_voice_and_no_voice_segments(self):
+ """Тест смешанных сегментов (с голосом и без) для одного audio_id."""
+ data = [
+ {
+ "audio_id": "audio-123",
+ "segment_id": "seg-1",
+ "segment_start": 0.5,
+ "segment_end": 2.5,
+ "type": "voice_human",
+ },
+ {
+ "audio_id": "audio-123",
+ "segment_id": "seg-2",
+ "segment_start": None,
+ "segment_end": None,
+ "type": None,
+ },
+ ]
+ valid, invalid = aggregate_segmentation(data)
+
+ assert len(invalid) == 0
+ assert len(valid["audio-123"]) == 1 # Только сегмент с голосом
+ assert "seg-1" in valid["audio-123"]
+ assert "seg-2" not in valid["audio-123"]
+
+ def test_duplicate_segments_same_data(self):
+ """Тест дубликатов сегментов с одинаковыми данными (должны игнорироваться)."""
+ data = [
+ {
+ "audio_id": "audio-123",
+ "segment_id": "seg-1",
+ "segment_start": 0.5,
+ "segment_end": 2.5,
+ "type": "voice_human",
+ },
+ {
+ "audio_id": "audio-123",
+ "segment_id": "seg-1",
+ "segment_start": 0.5,
+ "segment_end": 2.5,
+ "type": "voice_human",
+ },
+ ]
+ valid, invalid = aggregate_segmentation(data)
+
+ assert len(invalid) == 0
+ assert len(valid["audio-123"]) == 1
+
+ @pytest.mark.parametrize(
+ "field,value",
+ [
+ ("type", 123), # type не строка
+ ("segment_start", "not_float"), # start не float
+ ("segment_end", "not_float"), # end не float
+ ],
+ )
+ def test_invalid_field_types(self, field: str, value: Any):
+ """Тест невалидных типов полей."""
+ base_segment = {
+ "audio_id": "audio-123",
+ "segment_id": "seg-1",
+ "segment_start": 0.5,
+ "segment_end": 2.5,
+ "type": "voice_human",
+ }
+ base_segment[field] = value
+ data = [base_segment]
+
+ valid, invalid = aggregate_segmentation(data)
+
+ assert "audio-123" in invalid
+ assert len(valid) == 0
+
+ @pytest.mark.parametrize(
+ "segment_start,segment_end,type_val",
+ [
+ (None, 2.5, "voice_human"), # Только start None
+ (0.5, None, "voice_human"), # Только end None
+ (0.5, 2.5, None), # Только type None
+ (None, None, "voice_human"), # Только type не None
+ (0.5, None, None), # Только start не None
+ ],
+ )
+ def test_partial_none_values(self, segment_start: Any, segment_end: Any, type_val: Any):
+ """Тест частичных None значений (должны быть невалидными)."""
+ data = [
+ {
+ "audio_id": "audio-123",
+ "segment_id": "seg-1",
+ "segment_start": segment_start,
+ "segment_end": segment_end,
+ "type": type_val,
+ }
+ ]
+ valid, invalid = aggregate_segmentation(data)
+
+ assert "audio-123" in invalid
+ assert len(valid) == 0
+
+ def test_type_not_in_allowed_types(self):
+ """Тест type не из ALLOWED_TYPES."""
+ data = [
+ {
+ "audio_id": "audio-123",
+ "segment_id": "seg-1",
+ "segment_start": 0.5,
+ "segment_end": 2.5,
+ "type": "invalid_type",
+ }
+ ]
+ valid, invalid = aggregate_segmentation(data)
+
+ assert "audio-123" in invalid
+ assert len(valid) == 0
+
+ def test_duplicate_segments_different_data(self):
+ """Тест дубликатов сегментов с разными данными (должно быть невалидно)."""
+ data = [
+ {
+ "audio_id": "audio-123",
+ "segment_id": "seg-1",
+ "segment_start": 0.5,
+ "segment_end": 2.5,
+ "type": "voice_human",
+ },
+ {
+ "audio_id": "audio-123",
+ "segment_id": "seg-1",
+ "segment_start": 1.0, # Другой start
+ "segment_end": 3.0,
+ "type": "voice_human",
+ },
+ ]
+ valid, invalid = aggregate_segmentation(data)
+
+ assert "audio-123" in invalid
+ # Проверяем, что валидные сегменты не добавлены
+ assert len(valid.get("audio-123", {})) == 0
+
+ def test_missing_audio_id(self):
+ """Тест отсутствующего audio_id (должен игнорироваться)."""
+ data = [
+ {
+ "audio_id": "", # Пустой ID
+ "segment_id": "seg-1",
+ "segment_start": 0.5,
+ "segment_end": 2.5,
+ "type": "voice_human",
+ },
+ {
+ "audio_id": "audio-123",
+ "segment_id": "seg-2",
+ "segment_start": 1.0,
+ "segment_end": 3.0,
+ "type": "voice_bot",
+ },
+ ]
+ valid, invalid = aggregate_segmentation(data)
+
+ assert len(invalid) == 0
+ assert "audio-123" in valid
+ assert len(valid["audio-123"]) == 1
+
+ def test_empty_input(self):
+ """Тест пустого входного списка."""
+ valid, invalid = aggregate_segmentation([])
+
+ assert len(valid) == 0
+ assert len(invalid) == 0
+
+ def test_multiple_invalid_segments_same_audio_id(self):
+ """Тест нескольких невалидных сегментов для одного audio_id (в списке должен быть один раз)."""
+ data = [
+ {
+ "audio_id": "audio-123",
+ "segment_id": "", # Невалидный
+ "segment_start": 0.5,
+ "segment_end": 2.5,
+ "type": "voice_human",
+ },
+ {
+ "audio_id": "audio-123",
+ "segment_id": "seg-2",
+ "segment_start": None, # Невалидный (частичный None)
+ "segment_end": 3.0,
+ "type": "voice_bot",
+ },
+ {
+ "audio_id": "audio-456",
+ "segment_id": "seg-3",
+ "segment_start": 1.0,
+ "segment_end": 2.0,
+ "type": "voice_human",
+ },
+ ]
+ valid, invalid = aggregate_segmentation(data)
+
+ assert "audio-123" in invalid
+ assert "audio-456" not in invalid
+ assert invalid.count("audio-123") == 1 # Только один раз
+ assert len(valid) == 1
+ assert "audio-456" in valid
+
+ def test_time_validation_edge_cases(self):
+ """Тест краевых случаев времени."""
+ data = [
+ {
+ "audio_id": "audio-123",
+ "segment_id": "seg-1",
+ "segment_start": 0.0, # Ноль
+ "segment_end": 10.0, # Максимум
+ "type": "voice_human",
+ },
+ {
+ "audio_id": "audio-456",
+ "segment_id": "seg-2",
+ "segment_start": 5.0,
+ "segment_end": 5.0, # Нулевая длительность
+ "type": "spotter_word",
+ },
+ ]
+ valid, invalid = aggregate_segmentation(data)
+
+ assert len(invalid) == 0
+ assert len(valid) == 2
+
+ @pytest.mark.performance
+ def test_large_dataset(self):
+ """Производственный тест на большом наборе данных."""
+ data = []
+ # 100 разных audio_id, каждый с 10 сегментами
+ for i in range(100):
+ audio_id = f"audio-{i}"
+ for j in range(10):
+ data.append(
+ {
+ "audio_id": audio_id,
+ "segment_id": f"seg-{i}-{j}",
+ "segment_start": float(j),
+ "segment_end": float(j + 1),
+ "type": "voice_human" if j % 2 == 0 else "voice_bot",
+ }
+ )
+
+ valid, invalid = aggregate_segmentation(data)
+
+ assert len(valid) == 100
+ assert len(invalid) == 0
+ assert all(len(segments) == 10 for segments in valid.values())
+
+ def test_mixed_allowed_types(self):
+ """Тест всех разрешенных типов."""
+ data = [
+ {
+ "audio_id": f"audio-{i}",
+ "segment_id": f"seg-{i}",
+ "segment_start": 0.5,
+ "segment_end": 2.5,
+ "type": voice_type,
+ }
+ for i, voice_type in enumerate(ALLOWED_TYPES)
+ ]
+ valid, invalid = aggregate_segmentation(data)
+
+ assert len(invalid) == 0
+ assert len(valid) == len(ALLOWED_TYPES)
+
+ def test_negative_time_values(self):
+ """Тест отрицательных значений времени (должны быть валидны, так как не проверяются)."""
+ data = [
+ {
+ "audio_id": "audio-123",
+ "segment_id": "seg-1",
+ "segment_start": -1.0,
+ "segment_end": -0.5,
+ "type": "voice_human",
+ }
+ ]
+ valid, invalid = aggregate_segmentation(data)
+
+ # В текущей реализации это считается валидным
+ assert "audio-123" not in invalid
+ assert "audio-123" in valid
+
+ def test_start_greater_than_end(self):
+ """Тест когда start > end (должно быть валидно, так как не проверяется)."""
+ data = [
+ {
+ "audio_id": "audio-123",
+ "segment_id": "seg-1",
+ "segment_start": 5.0,
+ "segment_end": 2.0,
+ "type": "voice_human",
+ }
+ ]
+ valid, invalid = aggregate_segmentation(data)
+
+ # В текущей реализации это считается валидным
+ assert "audio-123" not in invalid
+ assert "audio-123" in valid
+ assert valid["audio-123"]["seg-1"]["start"] == 5.0
+ assert valid["audio-123"]["seg-1"]["end"] == 2.0
diff --git a/deprecated_tests/sem01/tests_hw/test_hw1_task4.py b/deprecated_tests/sem01/tests_hw/test_hw1_task4.py
new file mode 100644
index 00000000..b48652af
--- /dev/null
+++ b/deprecated_tests/sem01/tests_hw/test_hw1_task4.py
@@ -0,0 +1,131 @@
+from unittest.mock import Mock
+
+import pytest
+
+# Импортируем тестируемую функцию
+from homeworks.hw1.cache import lru_cache
+
+"""
+
+ Списки с аргументами:
+
+ * первый параметр - количество аргументов
+ * второй параметр - возможные типы
+ * третий параметр - повторение аргументов
+ * четвертый параметр - размер
+
+"""
+
+ARGS_DICT: dict[str, list[tuple[object]]] = {
+ "one_int_without_repeating_args_small": [
+ (2),
+ (1),
+ ],
+ "one_int_with_repeating_args_small": [
+ (2),
+ (1),
+ (2),
+ (1),
+ (1),
+ ],
+ "one_int_with_repeating_args_huge": [
+ (1), # c
+ (2), # c
+ (2),
+ (1),
+ (2),
+ (1),
+ (1),
+ (2),
+ (1),
+ (1),
+ (3), # c
+ (1),
+ (1),
+ (3),
+ (2), # c
+ (1), # c
+ (1),
+ (1),
+ (1),
+ (3), # c
+ (1),
+ (3),
+ (2), # c
+ (1), # c
+ (3), # c
+ (2), # c
+ (1), # c
+ (1),
+ ],
+ "three_str_with_repeating_args_small": [
+ ("first", "second", "third"), # 1 o
+ ("first", "third", "second"), # 2 o
+ ("third", "first", "third"), # 3 o
+ ("first", "second", "third"), # 1 o
+ ("first", "third", "second"), # 2 o
+ ("first", "second", "first"), # 4 o
+ ("third", "first", "third"), # 3 o
+ ("first", "second", "third"), # 1 o
+ ],
+ "two_multi_with_repeating_args_small": [
+ (42, "str"), # o #o
+ (5.6, TypeError), # o #o
+ (7 + 7j, None), # o #o
+ (5.6, TypeError),
+ (7 + 7j, None),
+ (5.6, TypeError),
+ (42, "str"), # o
+ (5.6, TypeError),
+ (True, False), # o #o
+ (42, "str"), # o
+ (7 + 7j, None), # o #o
+ (True, False), # o
+ (5.6, TypeError), # o #o
+ (42, "str"), # o #o
+ (42, "str"),
+ (7 + 7j, None), # o #o
+ (7 + 7j, None),
+ (42, "str"),
+ (True, False), # o #o
+ ],
+}
+
+"""Тесты для декоратора LRU-cache"""
+
+
+@pytest.mark.parametrize(
+ "capacity, call_count_expected, call_args",
+ [
+ (2, 2, ARGS_DICT["one_int_without_repeating_args_small"]),
+ (2, 2, ARGS_DICT["one_int_with_repeating_args_small"]),
+ (2, 11, ARGS_DICT["one_int_with_repeating_args_huge"]),
+ (2, 8, ARGS_DICT["three_str_with_repeating_args_small"]),
+ (2, 12, ARGS_DICT["two_multi_with_repeating_args_small"]),
+ (5, 3, ARGS_DICT["one_int_with_repeating_args_huge"]),
+ (3, 6, ARGS_DICT["three_str_with_repeating_args_small"]),
+ (3, 9, ARGS_DICT["two_multi_with_repeating_args_small"]),
+ ],
+)
+def test_cache(capacity: int, call_count_expected: int, call_args: list[tuple[object]]) -> None:
+ mock_func = Mock()
+ func_cached = lru_cache(capacity=capacity)(mock_func)
+
+ for args in call_args:
+ func_cached(args)
+
+ assert mock_func.call_count == call_count_expected
+
+
+def test_exception_value_error() -> None:
+ capacity: float = 0.4
+ mock_func = Mock()
+ with pytest.raises(ValueError):
+ lru_cache(capacity=capacity)(mock_func)
+
+
+def test_exception_type_error() -> None:
+ capacity = None
+ mock_func = Mock()
+ with pytest.raises(TypeError):
+ lru_cache(capacity=capacity)(mock_func)
diff --git a/deprecated_tests/sem01/tests_hw/test_hw1_tasks.py b/deprecated_tests/sem01/tests_hw/test_hw1_tasks.py
index 0ecf8a10..9b250729 100644
--- a/deprecated_tests/sem01/tests_hw/test_hw1_tasks.py
+++ b/deprecated_tests/sem01/tests_hw/test_hw1_tasks.py
@@ -1,6 +1,5 @@
-import pytest
import uuid
-from unittest.mock import MagicMock, patch, Mock
+from unittest.mock import MagicMock, Mock, patch
from homeworks.sem01.hw1.aggregate_segmentation import aggregate_segmentation, ALLOWED_TYPES
from homeworks.sem01.hw1.backoff import backoff
@@ -11,7 +10,8 @@
TESTCASE_IDS,
)
-NAME_BACKOFF_MODULE = "homeworks.hw1.backoff" # название модуля с backoff
+NAME_BACKOFF_MODULE = "homeworks.hw1.backoff" # название модуля с backoff
+
def test_valid_segments() -> None:
"""Тест: валидные сегменты."""
@@ -32,53 +32,53 @@ def test_valid_segments() -> None:
"segment_id": segment_id_1,
"segment_start": 0.0,
"segment_end": 1.0,
- "type": list_allow_types[0]
+ "type": list_allow_types[0],
},
{
"audio_id": audio_id_1,
"segment_id": segment_id_2,
"segment_start": 2.5,
"segment_end": 3.5,
- "type": list_allow_types[1]
+ "type": list_allow_types[1],
},
{
"audio_id": audio_id_2,
"segment_id": segment_id_3,
"segment_start": 4.5,
"segment_end": 4.6,
- "type": list_allow_types[0]
+ "type": list_allow_types[0],
},
{
"audio_id": audio_id_2,
"segment_id": segment_id_4,
"segment_start": 5.5,
"segment_end": 6.5,
- "type": list_allow_types[1]
+ "type": list_allow_types[1],
},
{
"audio_id": audio_id_3,
"segment_id": segment_id_5,
"segment_start": None,
"segment_end": None,
- "type": None
+ "type": None,
},
{
"audio_id": "audio3",
"segment_id": "seg5",
"segment_start": 0.0,
"segment_end": 1.0,
- "type": "invalid_type"
+ "type": "invalid_type",
},
]
expected_valid = {
audio_id_1: {
segment_id_1: {"start": 0.0, "end": 1.0, "type": list_allow_types[0]},
- segment_id_2: {"start": 2.5, "end": 3.5, "type": list_allow_types[1]}
+ segment_id_2: {"start": 2.5, "end": 3.5, "type": list_allow_types[1]},
},
audio_id_2: {
segment_id_3: {"start": 4.5, "end": 4.6, "type": list_allow_types[0]},
- segment_id_4: {"start": 5.5, "end": 6.5, "type": list_allow_types[1]}
+ segment_id_4: {"start": 5.5, "end": 6.5, "type": list_allow_types[1]},
},
audio_id_3: {},
}
@@ -88,6 +88,7 @@ def test_valid_segments() -> None:
assert result_valid == expected_valid
assert result_forbidden == expected_forbidden
+
def test_convert_matching_exception() -> None:
"""Тест: исключение заменяется на API-совместимое."""
@@ -97,7 +98,7 @@ class ApiValueError(Exception):
@convert_exceptions_to_api_compitable_ones({ValueError: ApiValueError})
def func():
raise ValueError("Внутренняя ошибка")
-
+
@convert_exceptions_to_api_compitable_ones({ValueError: ApiValueError})
def func2():
raise KeyError("Внутренняя ошибка")
@@ -108,7 +109,8 @@ def func2():
with pytest.raises(KeyError):
func2()
-@patch(NAME_BACKOFF_MODULE + '.sleep')
+
+@patch(NAME_BACKOFF_MODULE + ".sleep")
def test_exponential_backoff_and_jitter(mock_sleep: MagicMock) -> None:
"""Тест: задержки увеличиваются, но не выше timeout_max и к ним добавляется дрожь."""
attempts = 0
@@ -116,12 +118,7 @@ def test_exponential_backoff_and_jitter(mock_sleep: MagicMock) -> None:
retry_amount = 4
timeouts = [1, 2, 4, 4]
- @backoff(
- retry_amount=retry_amount,
- timeout_start=1,
- timeout_max=timeout_max,
- backoff_scale=2.0
- )
+ @backoff(retry_amount=retry_amount, timeout_start=1, timeout_max=timeout_max, backoff_scale=2.0)
def func():
nonlocal attempts
attempts += 1
@@ -138,22 +135,23 @@ def func():
for av_time, args in zip(timeouts, args_list):
count_more_av_time += args > av_time
assert av_time <= args <= av_time + 0.5
-
- assert count_more_av_time # есть добавление "дрожи"
+
+ assert count_more_av_time # есть добавление "дрожи"
+
def test_success() -> None:
capacity = 2
- call_args = [
+ call_args = [
(1, 2),
(1, 2),
(2, 2),
]
call_count_expected = 2
-
+
mock_func = Mock()
func_cached = lru_cache(capacity=capacity)(mock_func)
for args in call_args:
func_cached(args)
- assert mock_func.call_count == call_count_expected
\ No newline at end of file
+ assert mock_func.call_count == call_count_expected
diff --git a/deprecated_tests/sem02/tests/task4/test_lesson04_tasks.py b/deprecated_tests/sem02/tests/task4/test_lesson04_tasks.py
index 37d249b7..81312dea 100644
--- a/deprecated_tests/sem02/tests/task4/test_lesson04_tasks.py
+++ b/deprecated_tests/sem02/tests/task4/test_lesson04_tasks.py
@@ -333,12 +333,8 @@ class TestTask2:
),
],
)
- def test_get_dominant_color_info(
- self, image, threshold, expected_color, expected_ratio
- ):
- color, ratio_percent = get_dominant_color_info(
- image.astype(np.uint8), threshold
- )
+ def test_get_dominant_color_info(self, image, threshold, expected_color, expected_ratio):
+ color, ratio_percent = get_dominant_color_info(image.astype(np.uint8), threshold)
assert color in expected_color
assert (abs(ratio_percent - expected_ratio * 100) < 1e-6) or (
diff --git a/deprecated_tests/sem02/tests/task5/test_lesson05_tasks.py b/deprecated_tests/sem02/tests/task5/test_lesson05_tasks.py
index aeb37ebc..4cc9188d 100644
--- a/deprecated_tests/sem02/tests/task5/test_lesson05_tasks.py
+++ b/deprecated_tests/sem02/tests/task5/test_lesson05_tasks.py
@@ -89,9 +89,7 @@ class TestTask1:
),
],
)
- def test_can_satisfy_demand(
- self, costs, resource_amounts, demand_expected, expected
- ):
+ def test_can_satisfy_demand(self, costs, resource_amounts, demand_expected, expected):
assert can_satisfy_demand(costs, resource_amounts, demand_expected) == expected
def test_can_satisfy_demand_validate(self):
@@ -172,9 +170,7 @@ class TestTask2:
),
],
)
- def test_get_projections_components(
- self, matrix, vector, proj_expected, orth_expected
- ):
+ def test_get_projections_components(self, matrix, vector, proj_expected, orth_expected):
projections, orthogonals = get_projections_components(matrix, vector)
if proj_expected is None:
diff --git a/homeworks/sem01/hw1/aggregate_segmentation.py b/homeworks/sem01/hw1/aggregate_segmentation.py
index 1cdc176a..839fc120 100644
--- a/homeworks/sem01/hw1/aggregate_segmentation.py
+++ b/homeworks/sem01/hw1/aggregate_segmentation.py
@@ -5,6 +5,53 @@
}
+def check_validation(audio_segment: dict, used_id: list[list[str, str]]) -> list[bool, int]:
+ """Проверка данных на валидность
+ Args:
+ audio_segment: словарь, в котором хранится сегемент который в данный момент находится \
+ на проверкеимеет те же поля, что и segmentation_data
+ used_id : cписок сегментов прошедших проверку хранит внутри массивы в каждом\
+ из которых первыйм идет audio_id вторым segment_id
+ Return:
+ [True,0] если значение валидно и на всех полях не None
+ [True,1] если значение валидно и на во всех полях None
+ [False,0] если значение невалидно
+
+ """
+
+ required_keys: tuple = ("segment_id", "segment_start", "segment_end", "type")
+
+ if not all(k in audio_segment for k in required_keys):
+ return [False, 0]
+
+ if not isinstance(audio_segment["segment_id"], str):
+ return [False, 0]
+
+ start: float = audio_segment["segment_start"]
+ end: float = audio_segment["segment_end"]
+ audio_type: str = audio_segment["type"]
+
+ if all(v is None for v in (start, end, audio_type)):
+ return [True, 1]
+
+ if any(v is None for v in (start, end, audio_type)):
+ return [False, 0]
+
+ if (
+ not isinstance(start, float)
+ or not isinstance(end, float)
+ or not isinstance(audio_type, str)
+ ):
+ return [False, 0]
+
+ if audio_segment["type"] not in ALLOWED_TYPES:
+ return [False, 0]
+
+ id_check = [audio_segment["audio_id"], audio_segment["segment_id"]]
+
+ return [id_check not in used_id, 0]
+
+
def aggregate_segmentation(
segmentation_data: list[dict[str, str | float | None]],
) -> tuple[dict[str, dict[str, dict[str, str | float]]], list[str]]:
@@ -23,6 +70,41 @@ def aggregate_segmentation(
Словарь с валидными сегментами, объединёнными по `audio_id`;
Список `audio_id` (str), которые требуют переразметки.
"""
+ result: list[dict[str, dict[str, dict[str, str | float]]], list[str]] = [{}, []]
+ audio_id_set = set(i["audio_id"] for i in segmentation_data)
+ redo_set: set = set()
+ used_id: list[list] = []
+
+ unique_segments: list = [] # удаляем прям одинаковые элементы чтобы потом не проверять
+ unique_segments_checked: set = set()
+ for segment in segmentation_data:
+ key = tuple(
+ sorted(segment.items())
+ ) # делаем tuple чтобы добавлять в множество тк массив нельзя(чтобы не забыть на сдаче)
+ if key not in unique_segments_checked:
+ unique_segments_checked.add(key)
+ unique_segments.append(segment)
+ segmentation_data = unique_segments
- # ваш код
- return {}, []
+ for audio in audio_id_set:
+ audio_rn: dict = {}
+ for segment in segmentation_data:
+ if segment["audio_id"] == audio:
+ checker = check_validation(segment, used_id)
+ if checker[0] and checker[1] == 0:
+ audio_rn[segment["segment_id"]] = {
+ "start": segment["segment_start"],
+ "end": segment["segment_end"],
+ "type": segment["type"],
+ }
+ used_id.append([segment["audio_id"], segment["segment_id"]])
+ elif checker[0] and checker[1] == 1:
+ used_id.append([segment["audio_id"], segment["segment_id"]])
+ else:
+ redo_set.add(audio)
+ break
+ if audio in redo_set:
+ continue
+ result[0][audio] = audio_rn
+ result[1] = list(redo_set)
+ return tuple(result)
diff --git a/homeworks/sem01/hw1/backoff.py b/homeworks/sem01/hw1/backoff.py
index 696ffa73..0a5194eb 100644
--- a/homeworks/sem01/hw1/backoff.py
+++ b/homeworks/sem01/hw1/backoff.py
@@ -1,3 +1,4 @@
+from functools import wraps
from random import uniform
from time import sleep
from typing import (
@@ -33,6 +34,25 @@ def backoff(
Raises:
ValueError, если были переданы невозможные аргументы.
"""
+ if retry_amount <= 0 or timeout_max <= 0 or timeout_start <= 0 or backoff_scale <= 0:
+ raise ValueError("Detected negative number, use positive numbers for decorator")
- # ваш код
- pass
+ def decorator(func: Callable):
+ @wraps(func)
+ def wrapper(*args, **kargs):
+ delay = timeout_start
+ for i in range(retry_amount + 1):
+ try:
+ return func(*args, **kargs)
+ except backoff_triggers:
+ if i == retry_amount + 1:
+ raise
+ delay_amount = min(timeout_max, delay) + uniform(0, 0.5)
+ sleep(delay_amount)
+ delay *= backoff_scale
+ except Exception:
+ raise
+
+ return wrapper
+
+ return decorator
diff --git a/homeworks/sem01/hw1/cache.py b/homeworks/sem01/hw1/cache.py
index 9eb1d5d2..ef50b060 100644
--- a/homeworks/sem01/hw1/cache.py
+++ b/homeworks/sem01/hw1/cache.py
@@ -1,3 +1,5 @@
+from collections import OrderedDict
+from functools import wraps
from typing import (
Callable,
ParamSpec,
@@ -23,5 +25,29 @@ def lru_cache(capacity: int) -> Callable[[Callable[P, R]], Callable[P, R]]:
для получения целого числа.
ValueError, если после округления capacity - число, меньшее 1.
"""
- # ваш код
- pass
+ try:
+ capacity = round(capacity)
+ except Exception:
+ raise TypeError
+ if capacity < 1:
+ raise ValueError
+
+ def decorator(func: Callable) -> Callable:
+ cashe = OrderedDict()
+
+ @wraps(func)
+ def wrapper(*args, **kargs):
+ key = (args, tuple(sorted(kargs.items())))
+ if key in cashe:
+ cashe.move_to_end(key)
+ return cashe[key]
+ res = func(*args, **kargs)
+ cashe[key] = res
+ cashe.move_to_end(key)
+ if len(cashe) > capacity:
+ cashe.popitem(last=False)
+ return res
+
+ return wrapper
+
+ return decorator
diff --git a/homeworks/sem01/hw1/convert_exception.py b/homeworks/sem01/hw1/convert_exception.py
index fe5c770f..68dc0bf2 100644
--- a/homeworks/sem01/hw1/convert_exception.py
+++ b/homeworks/sem01/hw1/convert_exception.py
@@ -1,3 +1,4 @@
+from functools import wraps
from typing import (
Callable,
ParamSpec,
@@ -24,5 +25,19 @@ def convert_exceptions_to_api_compitable_ones(
Декоратор для непосредственного использования.
"""
- # ваш код
- pass
+ def decorator(func: Callable):
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ try:
+ return func(*args, **kwargs)
+ except Exception as exc:
+ exc_type = type(exc)
+ if exc_type in exception_to_api_exception:
+ if isinstance(exception_to_api_exception[exc_type], type):
+ raise exception_to_api_exception[exc_type]()
+ raise exception_to_api_exception[exc_type]
+ raise
+
+ return wrapper
+
+ return decorator
diff --git a/result.png b/result.png
new file mode 100644
index 00000000..556c6f78
Binary files /dev/null and b/result.png differ
diff --git a/solutions/sem01/lesson02/task1.py b/solutions/sem01/lesson02/task1.py
index c782dcd8..f344e470 100644
--- a/solutions/sem01/lesson02/task1.py
+++ b/solutions/sem01/lesson02/task1.py
@@ -1,4 +1,5 @@
def get_factorial(num: int) -> int:
factorial = 1
- # ваш код
+ for i in range(num, 1, -1):
+ factorial *= i
return factorial
diff --git a/solutions/sem01/lesson02/task2.py b/solutions/sem01/lesson02/task2.py
index b91420c5..e96073ee 100644
--- a/solutions/sem01/lesson02/task2.py
+++ b/solutions/sem01/lesson02/task2.py
@@ -1,4 +1,7 @@
def get_doubled_factorial(num: int) -> int:
factorial = 1
- # ваш код
+ for i in range(num, 0, -2):
+ if i == 0 or i == 1:
+ break
+ factorial *= i
return factorial
diff --git a/solutions/sem01/lesson02/task3.py b/solutions/sem01/lesson02/task3.py
index ee2a84ec..280a3be3 100644
--- a/solutions/sem01/lesson02/task3.py
+++ b/solutions/sem01/lesson02/task3.py
@@ -1,4 +1,11 @@
def get_amount_of_ways_to_climb(stair_amount: int) -> int:
step_prev, step_curr = 1, 1
- # ваш код
+ if stair_amount == 1:
+ return step_curr
+ else:
+ for i in range(2, stair_amount + 1):
+ temp = step_curr
+ step_curr = step_curr + step_prev
+ step_prev = temp
+ # Stair amount equals to element with index n+1 of fibonacci sequence
return step_curr
diff --git a/solutions/sem01/lesson02/task4.py b/solutions/sem01/lesson02/task4.py
index 45ff4bb4..7bbe6132 100644
--- a/solutions/sem01/lesson02/task4.py
+++ b/solutions/sem01/lesson02/task4.py
@@ -1,4 +1,12 @@
def get_multiplications_amount(num: int) -> int:
multiplications_amount = 0
- # ваш код
+ if num == 1:
+ return 0
+ while num > 1:
+ if num % 2 != 0:
+ multiplications_amount += 1
+ num -= 1
+ continue
+ multiplications_amount += 1
+ num //= 2
return multiplications_amount
diff --git a/solutions/sem01/lesson02/task5.py b/solutions/sem01/lesson02/task5.py
index 8fb9a048..f4cb43c6 100644
--- a/solutions/sem01/lesson02/task5.py
+++ b/solutions/sem01/lesson02/task5.py
@@ -1,3 +1,7 @@
def get_gcd(num1: int, num2: int) -> int:
- # ваш код
- return num1
+ while max(num1, num2) % min(num1, num2) != 0:
+ if num1 > num2:
+ num1 = num1 % num2
+ else:
+ num2 = num2 % num1
+ return min(num1, num2)
diff --git a/solutions/sem01/lesson02/task6.py b/solutions/sem01/lesson02/task6.py
index bec4b6cd..1896ca12 100644
--- a/solutions/sem01/lesson02/task6.py
+++ b/solutions/sem01/lesson02/task6.py
@@ -1,4 +1,13 @@
def get_sum_of_prime_divisors(num: int) -> int:
+ n = num
+ if n == 1:
+ return 0
sum_of_divisors = 0
- # ваш код
+ for i in range(2, int(num**0.5) + 1):
+ if num % i == 0:
+ sum_of_divisors += i
+ while num % i == 0:
+ num //= i
+ if sum_of_divisors == 0:
+ return n
return sum_of_divisors
diff --git a/solutions/sem01/lesson02/task7.py b/solutions/sem01/lesson02/task7.py
index 4b2d73be..d97d936d 100644
--- a/solutions/sem01/lesson02/task7.py
+++ b/solutions/sem01/lesson02/task7.py
@@ -1,5 +1,12 @@
def is_palindrome(num: int) -> bool:
+ if num < 0:
+ return False
num_reversed = 0
- num_origin = num
- # ваш код
- return num_origin == num_reversed
+ num_reversed += num % 10
+ num_current = num
+ num_current //= 10
+ while num_current > 0:
+ num_reversed *= 10
+ num_reversed += num_current % 10
+ num_current //= 10
+ return num == num_reversed
diff --git a/solutions/sem01/lesson03/task1.py b/solutions/sem01/lesson03/task1.py
index f1d8fe26..a403cb56 100644
--- a/solutions/sem01/lesson03/task1.py
+++ b/solutions/sem01/lesson03/task1.py
@@ -1,3 +1,27 @@
def flip_bits_in_range(num: int, left_bit: int, right_bit: int) -> int:
- # ваш код
- return num
\ No newline at end of file
+ answer = 0
+ position = 1
+ curr_bit = 1
+ while num > 0:
+ if curr_bit >= left_bit and curr_bit <= right_bit:
+ if num % 2 == 1:
+ answer = answer + position * 0
+ else:
+ answer = answer + position * 1
+ else:
+ answer = answer + position * (num % 2)
+ position *= 10
+ num //= 2
+ curr_bit += 1
+ while curr_bit <= right_bit:
+ answer = answer + position * 1
+ position *= 10
+ curr_bit += 1
+ num = 0
+ power = 0
+ while answer > 0:
+ digit = answer % 10
+ num += digit * (2**power)
+ answer //= 10
+ power += 1
+ return num
diff --git a/solutions/sem01/lesson03/task2.py b/solutions/sem01/lesson03/task2.py
index a3a738c2..b9d835d5 100644
--- a/solutions/sem01/lesson03/task2.py
+++ b/solutions/sem01/lesson03/task2.py
@@ -1,3 +1,23 @@
def get_cube_root(n: float, eps: float) -> float:
- # ваш код
- return n
\ No newline at end of file
+ if n < 0:
+ return -get_cube_root(-n, eps)
+ if n >= 1:
+ low_border, high_border = 0, n
+ else:
+ low_border, high_border = 0, 1
+ while (
+ abs(
+ ((low_border + high_border) / 2)
+ * ((low_border + high_border) / 2)
+ * ((low_border + high_border) / 2)
+ - n
+ )
+ >= eps
+ ):
+ mid = (low_border + high_border) / 2
+ mid_cube = mid * mid * mid
+ if mid_cube < n:
+ low_border = mid
+ else:
+ high_border = mid
+ return (low_border + high_border) / 2
diff --git a/solutions/sem01/lesson03/task3.py b/solutions/sem01/lesson03/task3.py
index 5e91a6ac..95f70473 100644
--- a/solutions/sem01/lesson03/task3.py
+++ b/solutions/sem01/lesson03/task3.py
@@ -1,3 +1,12 @@
def get_nth_digit(num: int) -> int:
- # ваш код
- return 0
+ kolv_cifr = 0
+ digit_sum = 5
+ if num <= digit_sum:
+ return (num - 1) * 2
+ while num > digit_sum:
+ digit_sum += 45 * (10**kolv_cifr) * (kolv_cifr + 2)
+ kolv_cifr += 1
+ k = num - (digit_sum - 45 * (10 ** (kolv_cifr - 1)) * (kolv_cifr + 1)) - 1
+ k1 = k // (kolv_cifr + 1)
+ finall_humber = 10**kolv_cifr + k1 * 2
+ return (finall_humber // (10 ** ((kolv_cifr) - (k % (kolv_cifr + 1))))) % 10
diff --git a/solutions/sem01/lesson04/task1.py b/solutions/sem01/lesson04/task1.py
index 47384423..075af3a5 100644
--- a/solutions/sem01/lesson04/task1.py
+++ b/solutions/sem01/lesson04/task1.py
@@ -1,3 +1,12 @@
def is_arithmetic_progression(lst: list[list[int]]) -> bool:
- # ваш код
- return False
\ No newline at end of file
+ lst.sort()
+ if len(lst) in [0, 1]:
+ return True
+ flag = True
+ change = lst[1] - lst[0]
+ i = 1
+ while flag and i < len(lst):
+ if lst[i] - lst[i - 1] != change:
+ flag = False
+ i += 1
+ return flag
diff --git a/solutions/sem01/lesson04/task2.py b/solutions/sem01/lesson04/task2.py
index 4591d0a3..0a552647 100644
--- a/solutions/sem01/lesson04/task2.py
+++ b/solutions/sem01/lesson04/task2.py
@@ -1,3 +1,21 @@
def merge_intervals(intervals: list[list[int, int]]) -> list[list[int, int]]:
- # ваш код
- return [[0,0]]
\ No newline at end of file
+ intervals.sort(key=lambda x: x[0])
+ if len(intervals) == 0:
+ return []
+ newintervals = []
+ start, finish = intervals[0][0], intervals[0][1]
+ flag1 = True
+ for i in intervals:
+ if flag1:
+ flag1 = False
+ continue # скип первого элемента(костыль)
+ if start < i[0] and finish > i[1]:
+ continue
+ elif finish >= i[0] and start <= i[0]:
+ finish = i[1]
+ else:
+ newintervals.append([start, finish])
+ start = i[0]
+ finish = i[1]
+ newintervals.append([start, finish])
+ return newintervals
diff --git a/solutions/sem01/lesson04/task3.py b/solutions/sem01/lesson04/task3.py
index 7253f6cb..68802acc 100644
--- a/solutions/sem01/lesson04/task3.py
+++ b/solutions/sem01/lesson04/task3.py
@@ -1,3 +1,5 @@
def find_single_number(nums: list[int]) -> int:
- # ваш код
- return 0
+ result = 0
+ for num in nums:
+ result ^= num
+ return result
diff --git a/solutions/sem01/lesson04/task4.py b/solutions/sem01/lesson04/task4.py
index b21bc5a3..d22c3694 100644
--- a/solutions/sem01/lesson04/task4.py
+++ b/solutions/sem01/lesson04/task4.py
@@ -1,3 +1,9 @@
def move_zeros_to_end(nums: list[int]) -> list[int]:
- # ваш код
- return 0
\ No newline at end of file
+ index = 0
+ for i in range(len(nums)):
+ if nums[i] != 0:
+ nums[index] = nums[i]
+ index += 1
+ for i in range(index, len(nums)):
+ nums[i] = 0
+ return index
diff --git a/solutions/sem01/lesson04/task5.py b/solutions/sem01/lesson04/task5.py
index 02d7742b..85c40eec 100644
--- a/solutions/sem01/lesson04/task5.py
+++ b/solutions/sem01/lesson04/task5.py
@@ -1,3 +1,13 @@
def find_row_with_most_ones(matrix: list[list[int]]) -> int:
- # ваш код
- return 0
\ No newline at end of file
+ if not matrix or not matrix[0]:
+ return 0
+ row = 0
+ col = len(matrix[0]) - 1
+ result_index = 0
+ while row < len(matrix) and col >= 0:
+ if matrix[row][col] == 1:
+ result_index = row
+ col -= 1
+ else:
+ row += 1
+ return result_index
diff --git a/solutions/sem01/lesson04/task6.py b/solutions/sem01/lesson04/task6.py
index 16df27ca..00c5d5ad 100644
--- a/solutions/sem01/lesson04/task6.py
+++ b/solutions/sem01/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:
+ if not arr:
+ return 0
+ visited = [False] * len(arr)
+ cycle_count = 0
+ for i in range(len(arr)):
+ if not visited[i]:
+ cycle_count += 1
+ current = i
+ while not visited[current]:
+ visited[current] = True
+ current = arr[current]
+ return cycle_count
diff --git a/solutions/sem01/lesson05/task1.py b/solutions/sem01/lesson05/task1.py
index 9a17211e..8d94d0ac 100644
--- a/solutions/sem01/lesson05/task1.py
+++ b/solutions/sem01/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]
diff --git a/solutions/sem01/lesson05/task2.py b/solutions/sem01/lesson05/task2.py
index 36750380..eded933a 100644
--- a/solutions/sem01/lesson05/task2.py
+++ b/solutions/sem01/lesson05/task2.py
@@ -1,3 +1,11 @@
def are_anagrams(word1: str, word2: str) -> bool:
- # ваш код
- return False
\ No newline at end of file
+ if len(word1) != len(word2):
+ return False
+ char_index = [0] * 128
+ for i in word1:
+ char_index[ord(i)] += 1
+ for i in word2:
+ char_index[ord(i)] -= 1
+ if char_index[ord(i)] < 0:
+ return False
+ return True
diff --git a/solutions/sem01/lesson05/task3.py b/solutions/sem01/lesson05/task3.py
index e368e2f4..8352c22d 100644
--- a/solutions/sem01/lesson05/task3.py
+++ b/solutions/sem01/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 "!#$%&'()*+,-./:;<=>?@[\]^_{|}`\"~":
+ return False
+ return True
diff --git a/solutions/sem01/lesson05/task4.py b/solutions/sem01/lesson05/task4.py
index 4c4e9086..fd1c8bd7 100644
--- a/solutions/sem01/lesson05/task4.py
+++ b/solutions/sem01/lesson05/task4.py
@@ -1,3 +1,9 @@
def unzip(compress_text: str) -> str:
- # ваш код
- return compress_text
\ No newline at end of file
+ result = ""
+ compress_text = compress_text.split(" ")
+ for i in compress_text:
+ if "*" not in i:
+ result += i
+ else:
+ result += i[: i.find("*")] * int(i[i.find("*") + 1 :])
+ return result
diff --git a/solutions/sem01/lesson05/task5.py b/solutions/sem01/lesson05/task5.py
index 076c5bb6..44b40704 100644
--- a/solutions/sem01/lesson05/task5.py
+++ b/solutions/sem01/lesson05/task5.py
@@ -1,3 +1,27 @@
-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:
+ i, j = 0, 0
+ text = text.lower()
+ while i < len(reg_expr) and j < len(text):
+ symbol = reg_expr[i]
+ if symbol == "d":
+ if not text[j].isdigit():
+ return False
+ while j < len(text) and text[j].isdigit():
+ j += 1
+ elif symbol == "w":
+ if not text[j].isalpha():
+ return False
+ while j < len(text) and text[j].isalpha():
+ j += 1
+ elif symbol == "s":
+ if not (text[j].isalpha() or text[j].isdigit()):
+ return False
+ while j < len(text) and (text[j].isalpha() or text[j].isdigit()):
+ j += 1
+ else:
+ if text[j] != symbol:
+ return False
+ j += 1
+ i += 1
+
+ return i == len(reg_expr) and j == len(text)
diff --git a/solutions/sem01/lesson05/task6.py b/solutions/sem01/lesson05/task6.py
index 1b914ada..6513d768 100644
--- a/solutions/sem01/lesson05/task6.py
+++ b/solutions/sem01/lesson05/task6.py
@@ -1,3 +1,16 @@
def simplify_path(path: str) -> str:
- # ваш код
- return path
\ No newline at end of file
+ path = path.split("/")
+ queue = []
+ for dir in path:
+ if dir == "" or dir == ".":
+ continue
+ elif dir == "..":
+ if queue:
+ queue.pop()
+ else:
+ return ""
+ else:
+ queue.append(dir)
+ final_path = "/" + "/".join(queue)
+
+ return final_path
diff --git a/solutions/sem01/lesson06/task1.py b/solutions/sem01/lesson06/task1.py
index 2d1e30e9..af4c66fb 100644
--- a/solutions/sem01/lesson06/task1.py
+++ b/solutions/sem01/lesson06/task1.py
@@ -1,3 +1,41 @@
def int_to_roman(num: int) -> str:
- # ваш код
- return ""
\ No newline at end of file
+ roman_numbers = {1000: "M", 500: "D", 100: "C", 50: "L", 10: "X", 5: "V", 1: "I"}
+ roman_digits = [1000, 500, 100, 50, 10, 5, 1]
+ index = 0
+ result = ""
+ flag_close = False
+ while index < len(roman_digits) and num > 0:
+ if not flag_close and (num - roman_digits[index]) < 0:
+ flag_close = True
+ elif not flag_close:
+ result += roman_numbers[roman_digits[index]]
+ num -= roman_digits[index]
+ elif flag_close:
+ if (index == 0 or index == 2 or index == 4) and (
+ num - (roman_digits[index] - 10 ** ((str(roman_digits[index]).count("0")) - 1))
+ ) >= 0:
+ num -= roman_digits[index] - 10 ** ((str(roman_digits[index]).count("0")) - 1)
+ result += (
+ roman_numbers[10 ** ((str(roman_digits[index]).count("0")) - 1)]
+ + roman_numbers[roman_digits[index]]
+ )
+ flag_close = False
+ index += 1
+ elif (
+ index != 2
+ and index != 0
+ and index != 4
+ and (num - (roman_digits[index] - 10 ** str(roman_digits[index]).count("0"))) >= 0
+ ):
+ print(10 ** str(roman_digits[index]).count("0"))
+ result += (
+ roman_numbers[10 ** str(roman_digits[index]).count("0")]
+ + roman_numbers[roman_digits[index]]
+ )
+ num -= roman_digits[index] - 10 ** str(roman_digits[index]).count("0")
+ flag_close = False
+ index += 1
+ else:
+ flag_close = False
+ index += 1
+ return result
diff --git a/solutions/sem01/lesson06/task2.py b/solutions/sem01/lesson06/task2.py
index f535b5a0..be64a537 100644
--- a/solutions/sem01/lesson06/task2.py
+++ b/solutions/sem01/lesson06/task2.py
@@ -1,3 +1,13 @@
def get_len_of_longest_substring(text: str) -> int:
- # ваш код
- return 0
\ No newline at end of file
+ start = 0
+ maxlen = 0
+ while start < len(text):
+ substr = ""
+ for i in range(start, len(text)):
+ if text[i] not in substr:
+ substr += text[i]
+ else:
+ break
+ maxlen = max(maxlen, len(substr))
+ start += 1
+ return maxlen
diff --git a/solutions/sem01/lesson06/task3.py b/solutions/sem01/lesson06/task3.py
index 7449a1e7..1451f188 100644
--- a/solutions/sem01/lesson06/task3.py
+++ b/solutions/sem01/lesson06/task3.py
@@ -1,7 +1,19 @@
-def is_there_any_good_subarray(
- nums: list[int],
- k: int,
-) -> bool:
-
- # ваш код
+def is_there_any_good_subarray(nums: list[int], k: int) -> bool:
+ if len(nums) < 2:
+ return False
+ elif len(nums) == 2:
+ sum = 0
+ for subarr in nums:
+ sum += subarr
+ if sum % k == 0:
+ return True
+ else:
+ return False
+ for i in range(0, len(nums) - 1):
+ for j in range(i + 2, len(nums) + 1):
+ sum = 0
+ for subarr in nums[i:j]:
+ sum += subarr
+ if sum % k == 0:
+ return True
return False
diff --git a/solutions/sem01/lesson06/task4.py b/solutions/sem01/lesson06/task4.py
index 5b75a110..161c4b44 100644
--- a/solutions/sem01/lesson06/task4.py
+++ b/solutions/sem01/lesson06/task4.py
@@ -1,3 +1,12 @@
+import string
+
+
def count_unique_words(text: str) -> int:
- # ваш код
- return 0
\ No newline at end of file
+ text = text.lower()
+ words = text.split(" ")
+ unique_words = set()
+ for i in range(len(words)):
+ word = words[i].strip(string.punctuation)
+ if word or any(letter.isalnum() for letter in word):
+ unique_words.add(word)
+ return len(unique_words)
diff --git a/solutions/sem01/lesson08/task1.py b/solutions/sem01/lesson08/task1.py
index 4390f6c8..5dffe2c5 100644
--- a/solutions/sem01/lesson08/task1.py
+++ b/solutions/sem01/lesson08/task1.py
@@ -1,5 +1,15 @@
-from typing import Callable
+import typing
-def make_averager(accumulation_period: int) -> Callable[[float], float]:
- # ваш код
- pass
\ No newline at end of file
+
+def make_averager(accumulation_period: int) -> typing.Callable[[float], float]:
+ sum_change = []
+
+ def get_avg(value: float):
+ nonlocal sum_change
+ sum_change.append(value)
+ if len(sum_change) > accumulation_period:
+ sum_change.pop(0)
+ avg = sum(sum_change) / len(sum_change)
+ return avg
+
+ return get_avg
diff --git a/solutions/sem01/lesson08/task2.py b/solutions/sem01/lesson08/task2.py
index 6e4af870..86367abe 100644
--- a/solutions/sem01/lesson08/task2.py
+++ b/solutions/sem01/lesson08/task2.py
@@ -1,10 +1,25 @@
+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 checker(func: Callable):
+ @wraps(func)
+ def wrapper(*args, **kwargs):
+ start = time.time()
+ result = func(*args, **kwargs)
+ end = time.time()
+ time_length = end - start
+ if func.__name__ not in statistics:
+ statistics[func.__name__] = [0.0, 0]
+ old_avg, old_count = statistics[func.__name__]
+ new_avg = (old_avg * old_count + time_length) / (old_count + 1)
+ statistics[func.__name__] = [new_avg, old_count + 1]
+ return result
+
+ return wrapper
+
+ return checker
diff --git a/solutions/sem01/lesson11/task1.py b/solutions/sem01/lesson11/task1.py
index 6a15f31f..a59737a3 100644
--- a/solutions/sem01/lesson11/task1.py
+++ b/solutions/sem01/lesson11/task1.py
@@ -1,10 +1,114 @@
+from math import acos, isclose
+
+
class Vector2D:
- def conj(self) -> "Vector2D":
- # ваш код
- return Vector2D()
+ _abscissa: float
+ _ordinate: float
+
+ def __init__(self, abscissa: float = 0.0, ordinate: float = 0.0):
+ self._abscissa = abscissa
+ self._ordinate = ordinate
+
+ def __repr__(self):
+ return f"Vector2D(abscissa={self._abscissa}, ordinate={self._ordinate})"
+
+ @property
+ def abscissa(self):
+ return self._abscissa
+
+ @property
+ def ordinate(self):
+ return self._ordinate
+
+ def __ne__(self, other: "Vector2D"):
+ return not (self == other)
+
+ def __eq__(self, other):
+ if not isinstance(other, Vector2D):
+ return NotImplemented
+ return isclose(self.abscissa, other.abscissa) and isclose(self.ordinate, other.ordinate)
+
+ def __lt__(self, other):
+ if not isinstance(other, Vector2D):
+ return NotImplemented
+ return (
+ self.abscissa < other.abscissa and not (isclose(self.abscissa, other.abscissa))
+ ) or (
+ isclose(self.abscissa, other.abscissa)
+ and self.ordinate < other.ordinate
+ and not (isclose(self.ordinate, other.ordinate))
+ )
+
+ def __le__(self, other):
+ return self == other or self < other
+
+ def __gt__(self, other):
+ return not (self <= other)
+
+ def __ge__(self, other):
+ return not (self < other)
+
+ def __abs__(self):
+ return (self.abscissa**2 + self.ordinate**2) ** 0.5
+
+ def __bool__(self):
+ return not (isclose(abs(self), 0, abs_tol=1e-12))
+
+ def __mul__(self, other):
+ if isinstance(other, (int, float)):
+ return Vector2D(self.abscissa * other, self.ordinate * other)
+ return NotImplemented
+
+ def __rmul__(self, other):
+ return self * other
+
+ def __truediv__(self, other):
+ if isinstance(other, (int, float)):
+ return Vector2D(self.abscissa / other, self.ordinate / other)
+ return NotImplemented
+
+ def __add__(self, other):
+ if isinstance(other, Vector2D):
+ return Vector2D(self.abscissa + other.abscissa, self.ordinate + other.ordinate)
+ if isinstance(other, (int, float)):
+ return Vector2D(self.abscissa + other, self.ordinate + other)
+ return NotImplemented
+
+ def __radd__(self, other):
+ return self + other
+
+ def __sub__(self, other):
+ if isinstance(other, Vector2D):
+ return Vector2D(self.abscissa - other.abscissa, self.ordinate - other.ordinate)
+ if isinstance(other, (int, float)):
+ return Vector2D(self.abscissa - other, self.ordinate - other)
+ return NotImplemented
+
+ def __neg__(self):
+ return self * -1
+
+ def __float__(self):
+ return abs(self)
+
+ def __int__(self):
+ return int(abs(self))
+
+ def __complex__(self):
+ return complex(self.abscissa, self.ordinate)
+
+ def __matmul__(self, other: "Vector2D"):
+ if not isinstance(other, Vector2D):
+ return NotImplemented
+ return self.abscissa * other.abscissa + self.ordinate * other.ordinate
def get_angle(self, other: "Vector2D") -> float:
- # ваш код
- return 0
+ if not isinstance(other, Vector2D):
+ raise TypeError("Other must be Vector2D")
+ if isclose(abs(other), 0) or isclose(abs(self), 0):
+ raise ValueError("You cannot get angle in between given vector and a zero vector")
+ return acos((self @ other) / (abs(self) * abs(other)))
+
+ def conj(self):
+ return Vector2D(self.abscissa, self.ordinate * -1)
# ваш код
diff --git a/solutions/sem01/lesson12/task1.py b/solutions/sem01/lesson12/task1.py
index d1bb828c..15c0f22f 100644
--- a/solutions/sem01/lesson12/task1.py
+++ b/solutions/sem01/lesson12/task1.py
@@ -2,5 +2,11 @@
def chunked(iterable: Iterable, size: int) -> Generator[tuple[Any], None, None]:
- # ваш код
- ...
+ chunk = []
+ for i in iterable:
+ chunk.append(i)
+ if len(chunk) == size:
+ yield tuple(chunk)
+ chunk = []
+ if len(chunk) != 0:
+ yield tuple(chunk)
diff --git a/solutions/sem01/lesson12/task2.py b/solutions/sem01/lesson12/task2.py
index 3ad802ee..d9977ad5 100644
--- a/solutions/sem01/lesson12/task2.py
+++ b/solutions/sem01/lesson12/task2.py
@@ -2,5 +2,10 @@
def circle(iterable: Iterable) -> Generator[Any, None, None]:
- # ваш код
- ...
+ saved = []
+ for item in iterable:
+ yield item
+ saved.append(item)
+ while saved:
+ for item in saved:
+ yield item
diff --git a/solutions/sem01/lesson12/task3.py b/solutions/sem01/lesson12/task3.py
index 64c112cc..b3bf3342 100644
--- a/solutions/sem01/lesson12/task3.py
+++ b/solutions/sem01/lesson12/task3.py
@@ -1,12 +1,25 @@
import sys
+from typing import Any
class FileOut:
+ old_std_out: str = ""
+
def __init__(
self,
path_to_file: str,
) -> None:
- # ваш код
- ...
+ self.path_to_file = path_to_file
+
+ def __enter__(self):
+ self.old_std_out = sys.stdout
+ self.file = open(self.path_to_file, "w")
+ sys.stdout = self.file
+ return self
+
+ def __exit__(self, *_: Any):
+ sys.stdout = self.old_std_out
+ self.file.close()
+ return False
# ваш код
diff --git a/solutions/sem02/lesson03/task1.py b/solutions/sem02/lesson03/task1.py
index 2c3fc0b5..0c6d3738 100644
--- a/solutions/sem02/lesson03/task1.py
+++ b/solutions/sem02/lesson03/task1.py
@@ -8,13 +8,21 @@ class ShapeMismatchError(Exception):
def sum_arrays_vectorized(
lhs: np.ndarray,
rhs: np.ndarray,
-) -> np.ndarray: ...
+) -> np.ndarray:
+ if np.size(lhs) != np.size(rhs):
+ raise ShapeMismatchError
+ return lhs + rhs
-def compute_poly_vectorized(abscissa: np.ndarray) -> np.ndarray: ...
+def compute_poly_vectorized(abscissa: np.ndarray) -> np.ndarray:
+ return 3 * (abscissa**2) + 2 * abscissa + 1
def get_mutual_l2_distances_vectorized(
lhs: np.ndarray,
rhs: np.ndarray,
-) -> np.ndarray: ...
+) -> np.ndarray:
+ if np.size(lhs, 1) != np.size(rhs, 1):
+ raise ShapeMismatchError
+ dist = lhs[:, np.newaxis, :] - rhs[np.newaxis, :, :]
+ return np.sqrt(np.sum(dist**2, 2))
diff --git a/solutions/sem02/lesson03/task2.py b/solutions/sem02/lesson03/task2.py
index fc823c1d..ad523136 100644
--- a/solutions/sem02/lesson03/task2.py
+++ b/solutions/sem02/lesson03/task2.py
@@ -9,11 +9,26 @@ def convert_from_sphere(
distances: np.ndarray,
azimuth: np.ndarray,
inclination: np.ndarray,
-) -> tuple[np.ndarray, np.ndarray, np.ndarray]: ...
+) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
+ if not (np.shape(distances) == np.shape(azimuth) == np.shape(inclination)):
+ raise ShapeMismatchError
+ x = distances * np.cos(azimuth) * np.sin(inclination)
+ y = distances * np.sin(azimuth) * np.sin(inclination)
+ z = distances * np.cos(inclination)
+ return x, y, z
def convert_to_sphere(
abscissa: np.ndarray,
ordinates: np.ndarray,
applicates: np.ndarray,
-) -> tuple[np.ndarray, np.ndarray, np.ndarray]: ...
+) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
+ if not (np.shape(abscissa) == np.shape(ordinates) == np.shape(applicates)):
+ raise ShapeMismatchError
+ distance = np.sqrt(abscissa**2 + ordinates**2 + applicates**2)
+ azimuth = np.arctan2(ordinates, abscissa)
+ inciclination = np.zeros_like(distance)
+ compare_mask = distance != 0.0
+
+ inciclination[compare_mask] = np.arccos(applicates[compare_mask] / distance[compare_mask])
+ return distance, azimuth, inciclination
diff --git a/solutions/sem02/lesson03/task3.py b/solutions/sem02/lesson03/task3.py
index 477acd0c..a39234c4 100644
--- a/solutions/sem02/lesson03/task3.py
+++ b/solutions/sem02/lesson03/task3.py
@@ -3,4 +3,15 @@
def get_extremum_indices(
ordinates: np.ndarray,
-) -> tuple[np.ndarray, np.ndarray]: ...
+) -> tuple[np.ndarray, np.ndarray]:
+ if (np.size(ordinates)) < 3:
+ raise ValueError
+
+ all_numbers = np.arange(1, len(ordinates) - 1)
+
+ moved_left = ordinates[:-2]
+ moved_right = ordinates[2:]
+ check_area = ordinates[1:-1]
+ max_mask = (check_area > moved_left) & (check_area > moved_right)
+ min_mask = (check_area < moved_left) & (check_area < moved_right)
+ return (all_numbers[min_mask], all_numbers[max_mask])
diff --git a/solutions/sem02/lesson04/task1.py b/solutions/sem02/lesson04/task1.py
index 1b5526c1..06a1f3cd 100644
--- a/solutions/sem02/lesson04/task1.py
+++ b/solutions/sem02/lesson04/task1.py
@@ -2,16 +2,40 @@
def pad_image(image: np.ndarray, pad_size: int) -> np.ndarray:
- # ваш код
- return image
+ if pad_size < 1:
+ raise ValueError
+ if np.ndim(image) == 2:
+ hieght, length = image.shape
+ new_height, new_length = hieght + pad_size * 2, length + pad_size * 2
+ padded_image = np.zeros((new_height, new_length), dtype=image.dtype)
+ padded_image[pad_size : pad_size + hieght, pad_size : pad_size + length] = image
+ else:
+ hieght, length, depth = image.shape
+ new_height, new_length = hieght + pad_size * 2, length + pad_size * 2
+ padded_image = np.zeros((new_height, new_length, depth), dtype=image.dtype)
+ padded_image[pad_size : pad_size + hieght, pad_size : pad_size + length, ...] = image
+ return padded_image
def blur_image(
image: np.ndarray,
kernel_size: int,
) -> np.ndarray:
- # ваш код
- return image
+ if kernel_size < 1 or kernel_size % 2 == 0:
+ raise ValueError
+ if kernel_size == 1:
+ return image
+ pad = kernel_size // 2
+ padded_image = pad_image(image, pad)
+ shifted = [
+ padded_image[i : i + image.shape[0], j : j + image.shape[1], ...]
+ for i in range(kernel_size)
+ for j in range(kernel_size)
+ ]
+ # сверху сам массив а в глубину уходят элементы вокруг и потом мы просто ищем среднее вглубь
+ blurred = np.mean(shifted, axis=0)
+
+ return blurred.astype(image.dtype)
if __name__ == "__main__":
diff --git a/solutions/sem02/lesson04/task2.py b/solutions/sem02/lesson04/task2.py
index be9a2288..6e5599dd 100644
--- a/solutions/sem02/lesson04/task2.py
+++ b/solutions/sem02/lesson04/task2.py
@@ -5,6 +5,26 @@ def get_dominant_color_info(
image: np.ndarray[np.uint8],
threshold: int = 5,
) -> tuple[np.uint8, float]:
- # ваш код
+ if threshold < 1:
+ raise ValueError("threshold must be positive")
- return 0, 0
+ pixels = image.flatten()
+ counts = np.zeros(256, dtype=np.int64)
+ for color in range(256):
+ mask = pixels == color
+ counts[color] = np.sum(mask)
+
+ max_pixels = 0
+ best_color = 0
+ for current_color in range(256):
+ if counts[current_color] != 0:
+ low = max(0, current_color - (threshold - 1))
+ high = min(255, current_color + (threshold - 1))
+ current_sum = np.sum(counts[low : high + 1])
+
+ if current_sum > max_pixels:
+ max_pixels = current_sum
+ best_color = current_color
+
+ percentage = (max_pixels / pixels.size) * 100
+ return np.uint8(best_color), float(percentage)
diff --git a/solutions/sem02/lesson04/utils/__init__.py b/solutions/sem02/lesson04/utils/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/solutions/sem02/lesson05/task1.py b/solutions/sem02/lesson05/task1.py
index e9c7c3c5..413da76b 100644
--- a/solutions/sem02/lesson05/task1.py
+++ b/solutions/sem02/lesson05/task1.py
@@ -9,4 +9,9 @@ def can_satisfy_demand(
costs: np.ndarray,
resource_amounts: np.ndarray,
demand_expected: np.ndarray,
-) -> bool: ...
+) -> bool:
+ if resource_amounts.shape[0] != costs.shape[0] or demand_expected.shape[0] != costs.shape[1]:
+ raise ShapeMismatchError
+ total = costs @ demand_expected
+ check = total <= resource_amounts
+ return all(check)
diff --git a/solutions/sem02/lesson05/task2.py b/solutions/sem02/lesson05/task2.py
index be1fb9d2..cedbded6 100644
--- a/solutions/sem02/lesson05/task2.py
+++ b/solutions/sem02/lesson05/task2.py
@@ -8,4 +8,18 @@ class ShapeMismatchError(Exception):
def get_projections_components(
matrix: np.ndarray,
vector: np.ndarray,
-) -> tuple[np.ndarray | None, np.ndarray | None]: ...
+) -> tuple[np.ndarray | None, np.ndarray | None]:
+ if matrix.shape[0] != matrix.shape[1] or matrix.shape[1] != vector.size:
+ raise ShapeMismatchError
+ if np.linalg.det(matrix) == 0:
+ return (None, None)
+
+ scalar_mult = matrix @ vector
+
+ length = np.sum(matrix**2, axis=1)
+
+ keff = (scalar_mult / length)[:, np.newaxis]
+
+ projections = keff * matrix
+
+ return (projections, vector - projections)
diff --git a/solutions/sem02/lesson05/task3.py b/solutions/sem02/lesson05/task3.py
index 0c66906c..8ee68bf5 100644
--- a/solutions/sem02/lesson05/task3.py
+++ b/solutions/sem02/lesson05/task3.py
@@ -9,4 +9,12 @@ def adaptive_filter(
Vs: np.ndarray,
Vj: np.ndarray,
diag_A: np.ndarray,
-) -> np.ndarray: ...
+) -> np.ndarray:
+ if Vs.shape[0] != Vj.shape[0] or Vj.shape[1] != diag_A.size:
+ raise ShapeMismatchError
+
+ Vj_h = Vj.real - 1j * Vj.imag
+ Vj_h = np.moveaxis(Vj_h, 0, 1)
+ A = np.diag(diag_A)
+ R = Vs - Vj @ np.linalg.inv(np.eye(Vj.shape[1]) + Vj_h @ Vj @ A) @ (Vj_h @ Vs)
+ return R
diff --git a/solutions/sem02/lesson07/task1.py b/solutions/sem02/lesson07/task1.py
index 3a505d89..1d68b3d1 100644
--- a/solutions/sem02/lesson07/task1.py
+++ b/solutions/sem02/lesson07/task1.py
@@ -13,8 +13,56 @@ 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
+ figure = plt.figure(figsize=(8, 8))
+ grid = plt.GridSpec(4, 4, wspace=0.2, hspace=0.2)
+ scat_graph = figure.add_subplot(grid[0:-1, 1:])
+ ord_vert_graph = figure.add_subplot(grid[0:-1, 0], sharey=scat_graph)
+ abs_hor_graph = figure.add_subplot(grid[-1, 1:], sharex=scat_graph)
+ scat_graph.scatter(abscissa, ordinates, color="red", alpha=0.5)
+ if diagram_type == "box":
+ ord_vert_graph.boxplot(
+ ordinates,
+ patch_artist=True,
+ boxprops={"facecolor": "red", "linewidth": 2},
+ medianprops={"color": "black"},
+ )
+ abs_hor_graph.boxplot(
+ abscissa,
+ vert=False,
+ patch_artist=True,
+ boxprops={"facecolor": "red", "linewidth": 2},
+ medianprops={"color": "black"},
+ )
+ if diagram_type == "hist":
+ ord_vert_graph.hist(
+ ordinates, orientation="horizontal", bins=50, color="red", alpha=0.5, edgecolor="black"
+ )
+ abs_hor_graph.hist(abscissa, bins=50, color="red", alpha=0.5, edgecolor="black")
+ ord_vert_graph.invert_xaxis()
+ abs_hor_graph.invert_yaxis()
+
+ if diagram_type == "violin":
+ viol_vert = ord_vert_graph.violinplot(
+ ordinates,
+ showmedians=True,
+ )
+ for body in viol_vert["bodies"]:
+ body.set_facecolor("red")
+ body.set_edgecolor("black")
+ for parts in viol_vert:
+ if parts == "bodies":
+ continue
+ viol_vert[parts].set_edgecolor("black")
+ viol_hor = abs_hor_graph.violinplot(abscissa, vert=False, showmedians=True)
+ for body in viol_hor["bodies"]:
+ body.set_facecolor("red")
+ body.set_edgecolor("black")
+ for parts in viol_hor:
+ if parts == "bodies":
+ continue
+ viol_hor[parts].set_edgecolor("black")
if __name__ == "__main__":
diff --git a/solutions/sem02/lesson07/task2.py b/solutions/sem02/lesson07/task2.py
index decd607e..9c29919a 100644
--- a/solutions/sem02/lesson07/task2.py
+++ b/solutions/sem02/lesson07/task2.py
@@ -1 +1,43 @@
# ваш код (используйте функции или классы для решения данной задачи)
+import json
+
+import matplotlib.pyplot as plt
+import numpy as np
+
+
+def get_counts(tier_list, stages_order):
+ arr = np.array(tier_list)
+ return np.array([np.sum(arr == stage) for stage in stages_order])
+
+
+def solution():
+ plt.style.use("ggplot")
+ with open("solutions\sem02\lesson07\data\medic_data.json") as f:
+ data = json.load(f)
+
+ stages_order = ["I", "II", "III", "IV"]
+
+ before_count = get_counts(data["before"], stages_order)
+ after_count = get_counts(data["after"], stages_order)
+
+ fig, ax = plt.subplots(figsize=(12, 7))
+ x = np.arange(len(stages_order))
+ width = 0.35
+
+ ax.bar(x - width / 2, before_count, width, label="До установки", color="red", edgecolor="black")
+ ax.bar(
+ x + width / 2, after_count, width, label="После установки", color="green", edgecolor="black"
+ )
+ ax.set_title("Стадии митральной недостаточности")
+ ax.set_ylabel("Кол-во людей")
+ ax.set_xticks(x)
+ ax.set_xticklabels(stages_order)
+ ax.legend()
+ fig.tight_layout()
+
+ plt.savefig("result.png")
+ plt.show()
+
+
+if __name__ == "__main__":
+ solution()