From bba9da2d3cffa3aa79dba0a02fa5065158316a88 Mon Sep 17 00:00:00 2001 From: Shefler Date: Wed, 29 Apr 2026 01:21:41 +0300 Subject: [PATCH 1/6] Initial empty commit for develop From 46f7607ba75c58b42a5b5e9d953dd0ec3f327076 Mon Sep 17 00:00:00 2001 From: Shefler Date: Wed, 29 Apr 2026 02:00:16 +0300 Subject: [PATCH 2/6] Add task 1: Paiindrome --- task1_palindrome/palindrome_shefler.py | 30 ++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 task1_palindrome/palindrome_shefler.py diff --git a/task1_palindrome/palindrome_shefler.py b/task1_palindrome/palindrome_shefler.py new file mode 100644 index 0000000..be23541 --- /dev/null +++ b/task1_palindrome/palindrome_shefler.py @@ -0,0 +1,30 @@ +# Задача 1: Проверка является ли строка палиндромом +def is_palindrome(s: str) -> bool: + # входной параметр s - строка + # возвращаем true или false (палиндром или нет) + + # приводим к нижнему регистру и оставляем только буквы и цифры + cleaned = ''.join(char.lower() for char in s if char.isalnum()) + + # сравниваем строку с её перевёрнутой версией + return cleaned == cleaned[::-1] + +def main(): + # тестируем + test_cases = [ + "Hello, world!", + "И темен город. Мороз, узором дорог не мети.", + "12321", + "A man, a plan, a canal, Panama!", + "Не палиндром", + "", + "m", + ] + + print("Тест:") + for test in test_cases: + result = is_palindrome(test) + print(f"'{test}' - {result}") + +if __name__ == "__main__": + main() \ No newline at end of file From 36042b07dac077243f41a42b6323a714778a354b Mon Sep 17 00:00:00 2001 From: Shefler Date: Wed, 29 Apr 2026 02:45:25 +0300 Subject: [PATCH 3/6] Add task 2: string filtering with lambda functions --- task2_filter/filter_shefler.py | 71 ++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 task2_filter/filter_shefler.py diff --git a/task2_filter/filter_shefler.py b/task2_filter/filter_shefler.py new file mode 100644 index 0000000..5310028 --- /dev/null +++ b/task2_filter/filter_shefler.py @@ -0,0 +1,71 @@ +# Задача 2: Фильтрация массива строк с помощью лямбда-функций +from typing import Callable, List +import re + +def filter_strings(filter_func: Callable[[str], bool], strings: List[str]) -> List[str]: + # фильтрует массив строк согласно лямбда-функции + # входные параметры: strings - строки для фильтрации + # filter_func - функция фильтрации, возвращает значение типа bool + # возвращаем отфильтрованные строки + + return [s for s in strings if filter_func(s)] + + +def main(): + # тестируем + test_strings = [ + "hello world", + "dog", + "cat", + "amazing", + "awful", + "python", + "c++" + "a", + " ", + "long string with spaces", + "long_string_without_spaces", + "кит", + "12345", + "a good person" + ] + + print("Исходный массив строк:") + for i, s in enumerate(test_strings, 1): + print(f" {i}. '{s}'") + + # Фильтр 1: Исключить строки с пробелами + print("\n" + "="*60) + print("1. Исключены строки с пробелами:") + no_spaces_filter = lambda s: ' ' not in s + result1 = filter_strings(no_spaces_filter, test_strings) + for s in result1: + print(f" '{s}'") + + # Фильтр 2: Исключить строки, начинающиеся с буквы "a" (не зависит от регистра и алфавита) + print("\n" + "="*60) + print("2. Исключены строки, начинающиеся с буквы 'a':") + not_start_with_a = lambda s: not s.lower().startswith('a') or s.lower().startswith('а') + result2 = filter_strings(not_start_with_a, test_strings) + for s in result2: + print(f" '{s}'") + + # Фильтр 3: Исключить строки, длина которых меньше 5 + print("\n" + "="*60) + print("3. Исключены строки, длина которых меньше 5:") + length_ge_5 = lambda s: len(s) >= 5 + result3 = filter_strings(length_ge_5, test_strings) + for s in result3: + print(f" '{s}'") + + # Комбинация фильтров + print("\n" + "="*60) + print("Исключены строки короче 5 И начинающиеся не с 'a':") + combined_filter = lambda s: len(s) >= 5 and not s.lower().startswith('a') + result4 = filter_strings(combined_filter, test_strings) + for s in result4: + print(f" '{s}'") + + +if __name__ == "__main__": + main() \ No newline at end of file From 60d4ef2c3d6d085ad5a4e087714570a2b780653e Mon Sep 17 00:00:00 2001 From: Shefler Date: Wed, 29 Apr 2026 03:11:51 +0300 Subject: [PATCH 4/6] Add task 3: shapes hierarchy with area, perimeter and comparison methods --- task3_shapes/shapes_shefler.py | 180 +++++++++++++++++++++++++++++++++ 1 file changed, 180 insertions(+) create mode 100644 task3_shapes/shapes_shefler.py diff --git a/task3_shapes/shapes_shefler.py b/task3_shapes/shapes_shefler.py new file mode 100644 index 0000000..be4f3b6 --- /dev/null +++ b/task3_shapes/shapes_shefler.py @@ -0,0 +1,180 @@ +#Задача 3: Иерархия классов геометрических фигур +from abc import ABC, abstractmethod +from math import pi +from typing import Union + +class Shape(ABC): + #базовый класс для всех фигур + + @abstractmethod + #вычисление площади + def area(self) -> float: + pass + + @abstractmethod + #вычисление периметра + def perimeter(self) -> float: + pass + + def compare_area(self, other: 'Shape') -> str: + #сравнение площадей фигуры self (текушей) с other (другой) + # возвращает строку с пояснением + if self.area() > other.area(): + return f"Площадь {self.__class__.__name__} ({self.area():.2f}) > площади {other.__class__.__name__} ({other.area():.2f})" + elif self.area() < other.area(): + return f"Площадь {self.__class__.__name__} ({self.area():.2f}) < площади {other.__class__.__name__} ({other.area():.2f})" + else: + return f"Площади равны: {self.area():.2f}" + + def compare_perimeter(self, other: 'Shape') -> str: + #сравнение перметра фигуры self (текушей) с other (другой) + # возвращает строку с пояснением + if self.perimeter() > other.perimeter(): + return f"Периметр {self.__class__.__name__} ({self.perimeter():.2f}) > периметра {other.__class__.__name__} ({other.perimeter():.2f})" + elif self.perimeter() < other.perimeter(): + return f"Периметр {self.__class__.__name__} ({self.perimeter():.2f}) < периметра {other.__class__.__name__} ({other.perimeter():.2f})" + else: + return f"Периметры равны: {self.perimeter():.2f}" + + +class Square(Shape): + + def __init__(self, side: float): + #инициализация квадрата по длине стороны + #обработка при ошбке + if side <= 0: + raise ValueError("Сторона должна быть положительным числом") + self.side = side + + def area(self) -> float: + # вычисление площади квадрата + return self.side ** 2 + + def perimeter(self) -> float: + # вычисление периметра квадрата + return 4 * self.side + + # пояснение касательно конкретного квадрата + def __str__(self) -> str: + return f"Квадрат (сторона={self.side})" + + +class Rectangle(Shape): + + def __init__(self, width: float, height: float): + #инициализация прямоугольника по длине сторон + #обработка при ошбке + if width <= 0 or height <= 0: + raise ValueError("Ширина и высота должны быть положительными числами") + self.width = width + self.height = height + + def area(self) -> float: + # площадь + return self.width * self.height + + def perimeter(self) -> float: + #периметр + return 2 * (self.width + self.height) + + def __str__(self) -> str: + return f"Прямоугольник (ширина={self.width}, высота={self.height})" + + +class Triangle(Shape): + + def __init__(self, side_a: float, side_b: float, side_c: float): + # инициализация трегуольник апо трем сторонам + #обработк апри ошибке (в том числе на неравенство, чтобы треугольник существовал) + if side_a <= 0 or side_b <= 0 or side_c <= 0: + raise ValueError("Все стороны должны быть положительными числами") + if (side_a + side_b <= side_c) or (side_a + side_c <= side_b) or (side_b + side_c <= side_a): + raise ValueError("Стороны не образуют треугольник") + + self.side_a = side_a + self.side_b = side_b + self.side_c = side_c + + def area(self) -> float: + #площадь треугольника (формула Герона) + p = self.perimeter() / 2 + return (p * (p - self.side_a) * (p - self.side_b) * (p - self.side_c)) ** 0.5 + + def perimeter(self) -> float: + # периметр + return self.side_a + self.side_b + self.side_c + + def __str__(self) -> str: + return f"Треугольник (стороны={self.side_a}, {self.side_b}, {self.side_c})" + + +class Circle(Shape): + + def __init__(self, radius: float): + #инициализация круга по радиусу и обработка ошибок + if radius <= 0: + raise ValueError("Радиус должен быть положительным числом") + self.radius = radius + + def area(self) -> float: + #площадь круга + return pi * self.radius ** 2 + + def perimeter(self) -> float: + #периметр круга + return 2 * pi * self.radius + + def __str__(self) -> str: + return f"Круг (радиус={self.radius})" + + +def main(): + # Тестирование + + # Создаем фигуры + square = Square(6) + rectangle = Rectangle(3, 7) + triangle = Triangle(2, 4, 4) + circle = Circle(7) + + shapes = [square, rectangle, triangle, circle] + + print("=" * 60) + print("Информация о фигурах:") + print("=" * 60) + + for shape in shapes: + print(f"\n{shape}") + print(f" Площадь: {shape.area():.2f}") + print(f" Периметр: {shape.perimeter():.2f}") + + # Сравнение площадей + print("\n" + "=" * 60) + print("Сравнение площадей:") + print("=" * 60) + print(square.compare_area(rectangle)) + print(square.compare_area(circle)) + print(triangle.compare_area(square)) + print(circle.compare_area(rectangle)) + + # Сравнение периметров + print("\n" + "=" * 60) + print("Сравнение периметров:") + print("=" * 60) + print(square.compare_perimeter(rectangle)) + print(rectangle.compare_perimeter(circle)) + print(triangle.compare_perimeter(square)) + print(circle.compare_perimeter(triangle)) + + # сравнение одинаковых по площади и периметру квадрата и прямоугольника + print("\n" + "=" * 60) + print("Сравнение одинаковых по площади и периметру квадрата и прямоугольника (3 на 3):") + print("=" * 60) + square2 = Square(3) + rectangle2 = Rectangle(3, 3) + print(square2.compare_area(rectangle2)) + print(square2.compare_perimeter(rectangle2)) + + +if __name__ == "__main__": + main() \ No newline at end of file From 6f097ae817f206cc317bedad85645b841630d5bb Mon Sep 17 00:00:00 2001 From: Shefler Date: Wed, 29 Apr 2026 03:37:15 +0300 Subject: [PATCH 5/6] Add task 4: Student and GraduateStudent classes with scholarship calculation --- task4_students/students_shefler.py | 104 +++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 task4_students/students_shefler.py diff --git a/task4_students/students_shefler.py b/task4_students/students_shefler.py new file mode 100644 index 0000000..9ffaead --- /dev/null +++ b/task4_students/students_shefler.py @@ -0,0 +1,104 @@ +# Задача 4: Студенты и аспиранты +# Создаем классы, которые будут связаны друг с другом (аспирант - особый вид студента) + +class Student: + # базовый класс студент + + def __init__(self, full_name: str, age: int, group_number: str, average_grade: float): + # у студента есть ФИО, возраст, номер группы и средний балл + self.full_name = full_name + self.age = age + self.group_number = group_number + self.average_grade = average_grade + + def get_info(self) -> str: + #возвращает информацию о человеке + return f"ФИО: {self.full_name}, Возраст: {self.age} лет, Номер группы: {self.group_number}, Средний балл: {self.average_grade}" + + def get_scholarship(self) -> int: + #буду считать, что без стипендии студент остается, если средний балл 4 и больше + if self.average_grade == 5.0: + return 6000 + elif self.average_grade < 5.0 and self.average_grade >= 4.0: + return 4000 + else: + # Если балл ниже 3.0 или например отрицательный + return 0 + + def compare_scholarship(self, other) -> str: + # сравниваем стипендии студентов как это делали с параметрами фигур + my_scholarship = self.get_scholarship() + other_scholarship = other.get_scholarship() + + if my_scholarship > other_scholarship: + return f"Стипендия {self.full_name} ({my_scholarship}р) > стипендии {other.full_name} ({other_scholarship}р)" + elif my_scholarship < other_scholarship: + return f"Стипендия {self.full_name} ({my_scholarship}р) < стипендии {other.full_name} ({other_scholarship}р)" + else: + return f"Стипендии равны: {my_scholarship}р у {self.full_name} и {other.full_name}" + + +class GraduateStudent(Student): + # класс аспирант с научной работой + + def __init__(self, full_name: str, age: int, group_number: str, average_grade: float, research_topic: str): + #вызываем метод родителя через super() чтобы задать параметры студента, а затем добавляем науч работу + super().__init__(full_name, age, group_number, average_grade) + self.research_topic = research_topic # добавляем новое свойство - тему научной работы + + def get_info(self) -> str: + #дополняем также метод вывода научной работой + base_info = super().get_info() # берем родительскую инфу (ФИО и возраст) + return f"{base_info}, Научная работа: '{self.research_topic}'" + + def get_scholarship(self) -> int: + #переопределяем метод расчета стипендии, потому что у аспирантов она больше + if self.average_grade == 5.0: + return 8000 + elif self.average_grade < 5.0 and self.average_grade >= 4.0: + return 6000 + else: + return 0 + +def main(): + #Тестируем + print("=" * 60) + print("СОЗДАНИЕ СТУДЕНТОВ И АСПИРАНТОВ") + print("=" * 60) + + # Создаем обычных студентов + student1 = Student("Сычева Лина Игоревна", 20, "5142704/50801", 5.0) + student2 = Student("Петров Иван Иванович", 20, "5142704/50701", 3.2) + student3 = Student("Шефлер Валерия Александровна", 22, "5142704/50801", 4.8) # плохая успеваемость + + # Создаем аспирантов + grad1 = GraduateStudent("Иванов Петр Петрович", 24, "5144704/53301", 5.0, "Искусственный интеллект и промышленные вентиляторы") + grad2 = GraduateStudent("Викторов Виктор Викторович", 24, "5174704/53321", 4.5, "Интернет вещей как инновация") + + print("\nИНФОРМАЦИЯ О ЛЮДЯХ:") + print("-" * 40) + print(student1.get_info()) + print(student2.get_info()) + print(grad1.get_info()) + print(grad2.get_info()) + + print("\n" + "=" * 60) + print("СТИПЕНДИИ:") + print("=" * 60) + print(f"{student1.full_name}: {student1.get_scholarship()}р (средний балл {student1.average_grade})") + print(f"{student2.full_name}: {student2.get_scholarship()}р (средний балл {student2.average_grade})") + print(f"{student3.full_name}: {student3.get_scholarship()}р (средний балл {student3.average_grade})") + print(f"{grad1.full_name}: {grad1.get_scholarship()}р (средний балл {grad1.average_grade})") + print(f"{grad2.full_name}: {grad2.get_scholarship()}р (средний балл {grad2.average_grade})") + + print("\n" + "=" * 60) + print("СРАВНЕНИЕ СТИПЕНДИЙ:") + print("=" * 60) + print(student1.compare_scholarship(student2)) + print(student2.compare_scholarship(grad1)) + print(grad1.compare_scholarship(grad2)) + print(student3.compare_scholarship(student1)) + print(grad2.compare_scholarship(student2)) + +if __name__ == "__main__": + main() \ No newline at end of file From 96dc5dc108987e1748f8003bf021d386ca40f1cb Mon Sep 17 00:00:00 2001 From: Shefler Date: Wed, 29 Apr 2026 04:09:57 +0300 Subject: [PATCH 6/6] Add task 5: timer decorator with sum prog --- task5_decorator/decorator_shefler.py | 114 +++++++++++++++++++++++++++ task5_decorator/input.txt | 1 + task5_decorator/output.txt | 1 + 3 files changed, 116 insertions(+) create mode 100644 task5_decorator/decorator_shefler.py create mode 100644 task5_decorator/input.txt create mode 100644 task5_decorator/output.txt diff --git a/task5_decorator/decorator_shefler.py b/task5_decorator/decorator_shefler.py new file mode 100644 index 0000000..af22142 --- /dev/null +++ b/task5_decorator/decorator_shefler.py @@ -0,0 +1,114 @@ +# Задача 5: Декоратор для замера времени выполнения функции +# Как я поняла екоратор - это функция, которая оборачивает другую функцию и делает что-то до/после её выполнения, иными словами можно добавлять функционал не меняя основную функцию +import time +import os +from typing import Any, Callable + +def timer_decorator(func: Callable) -> Callable: + #Вызывается не исходная функция, а обертка + #Запоминается время до вызова функции + #Вызов исходной функции + #Вычисление разницы и возврат ее как результата + + def wrapper(*args, **kwargs): + start_time = time.time() + result = func(*args, **kwargs) + end_time = time.time() + elapsed_time = end_time - start_time + + print(f"[ДЕКОРАТОР] Функция '{func.__name__}' выполнялась: {elapsed_time:.6f} секунд") + + return result + + return wrapper + +@timer_decorator +def sum_and_print(a: float, b: float) -> None: + # суммируем числа из консоли, выводим в консоль + result = a + b + print(f"Сумма {a} + {b} = {result}") + # чтобы было более наглядно делаем time.sleep + time.sleep(0.1) + + +@timer_decorator # применяем тот же декоратор +def process_file() -> None: + #суммируем числа из файла и выводим в файл + # определяем текущую папку, а от нее пути + current_dir = os.path.dirname(os.path.abspath(__file__)) + input_path = os.path.join(current_dir, "input.txt") + output_path = os.path.join(current_dir, "output.txt") + + # Читаем числа из файла + print(f"Читаем файл: {input_path}") + + with open(input_path, 'r', encoding='utf-8') as file: + content = file.read().strip() + + # реализуем считывание вне зависимости от того, как отделены числа + # если в строке есть пробел - разделяем по пробелу + if ' ' in content: + parts = content.split() + else: + # если его нет разделим по переводу строки + parts = content.split() + + # если строк больше двух, берем первые две + if len(parts) >= 2: + a = float(parts[0]) + b = float(parts[1]) + else: + # при ошибке + raise ValueError(f"Не удалось прочитать два числа из файла: '{content}'") + + # считаем сумму + result = a + b + + # записываем результат + with open(output_path, 'w', encoding='utf-8') as file: + file.write(f'{result}') + + print(f"Записали результат в файл: {output_path}") + +@timer_decorator +def slow_function() -> None: + # это специальная функция, которая спит дольше, чтобы посмотреть, что декоратор работает + print("Долгая функция старт") + time.sleep(0.3) + print("Долгая функция стоп") + + +def main(): + # тестируем + + print("=" * 60) + print("ТЕСТИРОВАНИЕ ДЕКОРАТОРА ЗАМЕРА ВРЕМЕНИ") + print("=" * 60) + + print("\nТест 1: Функция сложения двух чисел") + sum_and_print(10, 25) + sum_and_print(3.14, 2.86) + + print("\nТест 2: Функция работы с файлами") + # сначала создадим input.txt, если его нет + current_dir = os.path.dirname(os.path.abspath(__file__)) + input_path = os.path.join(current_dir, "input.txt") + + if not os.path.exists(input_path): + # Создаем файл с примером данных + with open(input_path, 'w', encoding='utf-8') as f: + f.write("67 89") + print(f"Создан файл input.txt с числами 67 и 89") + + process_file() + + print("\nТест 3: Долгая функция") + slow_function() + + print("\n" + "=" * 60) + print("конец тестов") + print("=" * 60) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/task5_decorator/input.txt b/task5_decorator/input.txt new file mode 100644 index 0000000..7a7b635 --- /dev/null +++ b/task5_decorator/input.txt @@ -0,0 +1 @@ +45 77 \ No newline at end of file diff --git a/task5_decorator/output.txt b/task5_decorator/output.txt new file mode 100644 index 0000000..6c8fb5c --- /dev/null +++ b/task5_decorator/output.txt @@ -0,0 +1 @@ +122.0 \ No newline at end of file