From db2bb52187dea91677fd3b98308380a07fef055b Mon Sep 17 00:00:00 2001 From: AlexVenem <130144087+AlexVenem@users.noreply.github.com> Date: Mon, 17 Jun 2024 00:54:06 +0300 Subject: [PATCH 1/4] Submitting my work --- tasks/practice1/employee.py | 112 ++++++++++++++++++++++++++++++ tasks/practice1/practice1.py | 4 +- tasks/practice1/practice2.py | 121 +++++++++++++++++++++++++++++++++ tasks/practice1/practice3.py | 127 +++++++++++++++++++++++++++++++++++ tasks/practice1/practice4.py | 54 +++++++++++++++ tasks/practice1/team.py | 80 ++++++++++++++++++++++ 6 files changed, 496 insertions(+), 2 deletions(-) create mode 100644 tasks/practice1/employee.py create mode 100644 tasks/practice1/practice2.py create mode 100644 tasks/practice1/practice3.py create mode 100644 tasks/practice1/practice4.py create mode 100644 tasks/practice1/team.py diff --git a/tasks/practice1/employee.py b/tasks/practice1/employee.py new file mode 100644 index 0000000..0a8dea8 --- /dev/null +++ b/tasks/practice1/employee.py @@ -0,0 +1,112 @@ +from typing import Dict +from .exception import NoSuchPositionError + +POSITIONS: Dict[str, int] = { + 'CEO': 0, + 'manager': 1, + 'developer': 2, + 'tester': 3, +} + + +def get_position_level(position_name: str) -> int: + """ + Функция возвращает уровень позиции по ее названию. + Если должности нет в базе поднимается исключение `NoSuchPositionError(position_name)` + """ + + try: + return POSITIONS[position_name] + except KeyError as exp: + raise NoSuchPositionError(position_name) from exp + + +class Employee: + """ + Класс - сотрудник + + Возможности: + 1. Реализована возможность сравнения двух сотрудников в зависимости от занимаемой должности - метод __eq__ + 2. Возможность получить зарплату через метод get_salary + """ + name: str + position: str + _salary: int + + def __init__(self, name: str, position: str, salary: int): + """ + Задача: реализовать конструктор класса, чтобы все тесты проходили + """ + + if isinstance(salary, int): + self.name = name + self.position = position + self._salary = salary + else: + raise ValueError + + + def get_salary(self) -> int: + """ + Метод возвращает зарплату сотрудника. + """ + + return self._salary + + def __eq__(self, other: object) -> bool: + """ + Задача: реализовать метод сравнение двух сотрудников, чтобы все тесты проходили. + + Сравнение происходит по уровню позиции см. `get_position_level`. + Если что-то идет не так - бросаются исключения. Смотрим что происходит в тестах. + """ + + if not isinstance(other, Employee): + raise TypeError + try: + return get_position_level(self.position) == get_position_level(other.position) + except NoSuchPositionError: + raise ValueError + + def __str__(self): + """ + Задача: реализовать строковое представление объекта. + Пример вывода: 'name: Ivan position manager' + """ + + return f'name: {self.name} position: {self.position}' + + def __hash__(self): + return id(self) + + +class Developer(Employee): + """ + Сотрудник - разработчик + """ + + language: str + position: str = 'developer' + + def __init__(self, name: str, salary: int, language: str): + """ + Задача: реализовать конструктор класса, используя конструктор родителя + """ + + super().__init__(name, self.position, salary) + self.language = language + + +class Manager(Employee): + """ + Сотрудник - менеджер + """ + + position: str = 'manager' + + def __init__(self, name: str, salary: int): + """ + Задача: реализовать конструктор класса, используя конструктор родителя + """ + + super().__init__(name, self.position, salary) diff --git a/tasks/practice1/practice1.py b/tasks/practice1/practice1.py index 030da70..e2da9fe 100644 --- a/tasks/practice1/practice1.py +++ b/tasks/practice1/practice1.py @@ -8,7 +8,7 @@ def concatenate_strings(a: str, b: str) -> str: :return: результат сложения """ - # пиши свой код здесь + result = a + b return result @@ -22,6 +22,6 @@ def calculate_salary(total_compensation: int) -> float: :return: сумма заплаты после вычета налога """ - # пиши свой код здесь + result = total_compensation * 0.87 return result diff --git a/tasks/practice1/practice2.py b/tasks/practice1/practice2.py new file mode 100644 index 0000000..651d4e1 --- /dev/null +++ b/tasks/practice1/practice2.py @@ -0,0 +1,121 @@ +from typing import Iterable +import random + + +UNCULTURED_WORDS = ('kotleta', 'pirog') + + +def greet_user(name: str) -> str: + """ + Генерирует приветственную фразу. + Приветствие не может состоять только из одного имени пользователя. + + :param name: имя пользователя + :return: приветствие + """ + + greeting = 'Zdarovstvuyte, дорогой ' + name + + return greeting + + +def get_amount() -> float: + """ + Генерируем случайную сумму на счете. + + Сумма: + - в диапазоне от 100 до 1000000 + - float + - не больше 2-х знаков после запятой + + :return: случайную сумму на счете + """ + + amount = round(random.uniform(100, 1000000), 2) + + return amount + + +def is_phone_correct(phone_number: str) -> bool: + """ + Функция проверяет, что номер телефона соответствует следующему формату: + +7xxxxxxxxxx, где x - цифра от 0 до 9 + + :param phone_number: предполагаемый номер телефона + :return: буленовское значение - bool: True - если номер корректны, + False - если номер некорректный + """ + + if phone_number[:2] == "+7" and phone_number[2:].isnumeric(): + result = True + else: + result = False + + return result + + +def is_amount_correct(current_amount: float, transfer_amount: str) -> bool: + """ + Проверяет возможность осуществления перевода. + Перевод возможен если выполняется условие: + - текущий счет (current_amount) больше или равен сумме перевода (transfer_amount) + + :param current_amount: текущий счет + :param transfer_amount: сумма перевода + :return: буленовское значение - bool: True - если перевод возможен, + False - если денег недостаточно + """ + + result = current_amount >= float(transfer_amount) + return result + + +def moderate_text(text: str, uncultured_words: Iterable[str]) -> str: + """ + Модерирует текст по следующим правилам. + + Требования к тексту: + - Первая буква заглавная, остальные буквы только в нижнем регистре + - отсутствую лишние пробелы + - фильтруются 'опасные' символы: " ' (двойные и одинарные кавычки) + - слова, перечисленные в переменной uncultured_words заменяются на аналогичное количество знаков # + + :param text: исходный текст + :param uncultured_words: список запрещенных слов + :return: текст, соответсвующий правилам + """ + + dangerous_characters = ['"', "'"] + result = text.strip() + result = result.capitalize() + + for char in dangerous_characters: + result = result.replace(char, '') + for i in uncultured_words: + result = result.replace(i, '#' * len(i)) + + return result + + +def create_request_for_loan(user_info: str) -> str: + """ + Генерирует заявку на кредит на основе входящей строки. + Формат входящий строки: + + Иванов,Петр,Сергеевич,01.01.1991,10000 + + Что должны вернуть на ее основе: + + Фамилия: Иванов + Имя: Петр + Отчество: Сергеевич + Дата рождения: 01.01.1991 + Запрошенная сумма: 10000 + + :param user_info: строка с информацией о клиенте + :return: текст кредитной заявки + """ + + info = user_info.split(',') + result = f'Фамилия: {info[0]}\n Имя: {info[1]}\n Отчество: {info[2]}\n Дата рождения: {info[3]}\n Запрошенная сумма: {info[4]}' + return result diff --git a/tasks/practice1/practice3.py b/tasks/practice1/practice3.py new file mode 100644 index 0000000..deceaa5 --- /dev/null +++ b/tasks/practice1/practice3.py @@ -0,0 +1,127 @@ +from pathlib import Path +from typing import Dict, Any, List, Optional +import csv + + +def count_words(text: str) -> Dict[str, int]: + """ + Функция для подсчета слов в тексте. + + При подсчете слов - все знаки препинания игнорируются. + Словом считается непрерывная последовательность длиной больше одного + символа, состоящая из букв в диапазоне A-Z и a-z. + Если в последовательности присутствует цифра - это не слово. + + Hello - слово + Hello7 - не слово + + При подсчете слов регистр букв не имеет значения. + + Результат выполнения функции словарь, в котором: + ключ - слово в нижнем регистре + значение - количество вхождений слов в текст + + :param text: текст, для подсчета символов + :return: словарь, в котором: + ключ - слово в нижнем регистре + значение - количество вхождений слов в текст + """ + + dictionary = dict() + text = text.split() + for i in text: + if not any(j.isdigit() for j in i): + i = ''.join([j.lower() for j in i if j.isalpha()]) + if len(i) > 1: + if i in dictionary.keys(): + dictionary[i] += 1 + else: + dictionary[i] = 1 + + return dictionary + + +def exp_list(numbers: List[int], exp: int) -> List[int]: + """ + Функция, которая возводит каждый элемент списка в заданную степень + + :param numbers: список, состоящий из натуральных чисел + :param exp: в какую степень возвести числа в списке + :return: список натуральных чисел + """ + + result = [x ** exp for x in numbers] + + return result + + +def get_cashback(operations: List[Dict[str, Any]], special_category: List[str]) -> float: + """ + Функция для расчета кешбека по операциям. + За покупки в обычных категориях возвращается 1% от стоимости покупки + За покупки в special_category начисляют 5% от стоимости покупки + + :param operations: список словарей, содержащих поля + amount - сумма операции + category - категория покупки + :param special_category: список категорий повышенного кешбека + :return: размер кешбека + """ + + result = 0.0 + for i in operations: + if i['category'] in special_category: + result += i['amount'] * 0.05 + else: + result += i['amount'] * 0.01 + + return result + + +def get_path_to_file() -> Optional[Path]: + """ + Находит корректный путь до тестового файла. + + Если запускать тесты из pycharm - начальная папка - tests + Если запускать файлы через make tests - начальная папка - корень проекта + + :return: путь до тестового файла tasks.csv + """ + if Path().resolve().name == 'tests': + base_path = Path().resolve().parent + else: + base_path = Path().resolve() + return base_path / 'tasks' / 'practice3' / 'tasks.csv' + + +def csv_reader(header: str) -> int: + """ + Функция считывает csv файл и подсчитывает количество + уникальных элементов в столбце. + Столбец выбирается на основе имени заголовка, + переданного в переменной header. + + Обратите внимание на структуру файла! + Первая строка - строка с заголовками. + Остальные строки - строки с данными. + + Файл для анализа: tasks.csv + Для того чтобы файл корректно открывался в тестах: + для получения пути до файла - используйте функцию get_path_to_file + которая определена перед функцией. + + CSV анализируем с помощью встроенной библиотеки csv + + :param header: название заголовка + :return: количество уникальных элементов в столбце + """ + + path = get_path_to_file() + unique_elements = set() + with open(path, newline='') as csvfile: + reader = csv.DictReader(csvfile) + for row in reader: + unique_elements.add(row[header]) + result = len(unique_elements) + + return result diff --git a/tasks/practice1/practice4.py b/tasks/practice1/practice4.py new file mode 100644 index 0000000..b85e6ab --- /dev/null +++ b/tasks/practice1/practice4.py @@ -0,0 +1,54 @@ +from typing import Any, Optional + + +def search_phone(content: Any, name: str) -> Optional[str]: + """ + Функция поиска номера телефона пользователя в структуре данных. + + Алгоритм работы следующий: + 1) принимаем на вход структуру content, состоящую из словарей, + списков и строковых ключей в списке + 2) внутри структуры может быть запись следующего формата: + { + 'name': 'user_name', + 'phone': 'user_phone', + } + + 3) необходимо пройтись по всей структуре + 4) если встречаем словарь, в котором ключ name совпадает с + аргументом функции name - берем из этого словаря поле phone + и возвращаем этот телефон из функции + 5) если поле name с таким значением не найдено - возвращаем из + функции None + + Может пригодиться: + + 1) Чтобы проверить, является ли объект списком используйте функцию: + isinstance(some_object, list) + если some_object список - результат будет True + если some_object не список - False + + 2) Чтобы проверить, является ли объект словарем используйте функцию: + isinstance(some_object, dict) + + + :param content: словарь или список, внутрь которого вложены объекты. Внутри + может скрываться номер телефона пользователя + :param name: имя пользователя, у которого будем искать номер телефона + :return: номер телефона пользователя или None + """ + + if isinstance(content, dict): + if content.get('name') == name: + return content.get('phone') + for value in content.values(): + result = search_phone(value, name) + if result is not None: + return result + elif isinstance(content, list): + for item in content: + result = search_phone(item, name) + if result is not None: + return result + + return None diff --git a/tasks/practice1/team.py b/tasks/practice1/team.py new file mode 100644 index 0000000..1fca240 --- /dev/null +++ b/tasks/practice1/team.py @@ -0,0 +1,80 @@ +from typing import Set +from .employee import Employee, Manager +from .exception import NoSuchMemberError + + +class Team: + """ + Класс - команда. + У каждой команды есть менеджер, название и участники. + + Возможности: + - добавление участников + - удаление участника из команды + - просмотр базовой информации об участниках + - получение списка участников + """ + + name: str + manager: Manager + __members: Set[Employee] + + def __init__(self, name: str, manager: Manager): + """ + Задача: + Реализовать конструктор класса. + Конструктор должен присвоить значения публичным атрибутам + и инициализировать контейнер `__members` + """ + + self.name = name + self.manager = manager + self.__members = set() + + def add_member(self, member: Employee) -> None: + """ + Задача: реализовать метод добавления участника в команду. + Добавить можно только работника. + """ + + if not isinstance(member, Employee): + raise TypeError + self.__members.add(member) + + def remove_member(self, member: Employee) -> None: + """ + Задача: реализовать метод удаления участника из команды. + Если в команде нет такого участника поднимается исключение `NoSuchMemberError` + """ + + if not isinstance(member, Employee): + raise TypeError + if member not in self.__members: + raise NoSuchMemberError(self.name, member) + self.__members.remove(member) + + + def get_members(self) -> Set[Employee]: + """ + Задача: реализовать метод возвращения списка участков команды та, + чтобы из вне нельзя было поменять список участников внутри класса + """ + + return self.__members.copy() + + def __str__(self): + return 'team: ' + self.name + ' manager: ' + self.manager.name + ' number of members: ' + str(len(self.get_members())) + + def show(self) -> None: + """ + DO NOT EDIT! + Данный метод нельзя редактировать! + + Метод показывает информацию о команде в формате: + `'team: {team_name} manager: {manager_name} number of members: {members_count)}'` + + Задача: доработать класс таким образом, чтобы метод выполнял свою функцию, не меняя содержимое + этого метода + """ + + print(self) From 4b08559e466c56bacd0bedb076c2926e3a07c63b Mon Sep 17 00:00:00 2001 From: AlexVenem Date: Mon, 17 Jun 2024 01:04:40 +0300 Subject: [PATCH 2/4] Revert "Submitting my work" This reverts commit db2bb52187dea91677fd3b98308380a07fef055b. --- tasks/practice1/employee.py | 112 ------------------------------ tasks/practice1/practice1.py | 4 +- tasks/practice1/practice2.py | 121 --------------------------------- tasks/practice1/practice3.py | 127 ----------------------------------- tasks/practice1/practice4.py | 54 --------------- tasks/practice1/team.py | 80 ---------------------- 6 files changed, 2 insertions(+), 496 deletions(-) delete mode 100644 tasks/practice1/employee.py delete mode 100644 tasks/practice1/practice2.py delete mode 100644 tasks/practice1/practice3.py delete mode 100644 tasks/practice1/practice4.py delete mode 100644 tasks/practice1/team.py diff --git a/tasks/practice1/employee.py b/tasks/practice1/employee.py deleted file mode 100644 index 0a8dea8..0000000 --- a/tasks/practice1/employee.py +++ /dev/null @@ -1,112 +0,0 @@ -from typing import Dict -from .exception import NoSuchPositionError - -POSITIONS: Dict[str, int] = { - 'CEO': 0, - 'manager': 1, - 'developer': 2, - 'tester': 3, -} - - -def get_position_level(position_name: str) -> int: - """ - Функция возвращает уровень позиции по ее названию. - Если должности нет в базе поднимается исключение `NoSuchPositionError(position_name)` - """ - - try: - return POSITIONS[position_name] - except KeyError as exp: - raise NoSuchPositionError(position_name) from exp - - -class Employee: - """ - Класс - сотрудник - - Возможности: - 1. Реализована возможность сравнения двух сотрудников в зависимости от занимаемой должности - метод __eq__ - 2. Возможность получить зарплату через метод get_salary - """ - name: str - position: str - _salary: int - - def __init__(self, name: str, position: str, salary: int): - """ - Задача: реализовать конструктор класса, чтобы все тесты проходили - """ - - if isinstance(salary, int): - self.name = name - self.position = position - self._salary = salary - else: - raise ValueError - - - def get_salary(self) -> int: - """ - Метод возвращает зарплату сотрудника. - """ - - return self._salary - - def __eq__(self, other: object) -> bool: - """ - Задача: реализовать метод сравнение двух сотрудников, чтобы все тесты проходили. - - Сравнение происходит по уровню позиции см. `get_position_level`. - Если что-то идет не так - бросаются исключения. Смотрим что происходит в тестах. - """ - - if not isinstance(other, Employee): - raise TypeError - try: - return get_position_level(self.position) == get_position_level(other.position) - except NoSuchPositionError: - raise ValueError - - def __str__(self): - """ - Задача: реализовать строковое представление объекта. - Пример вывода: 'name: Ivan position manager' - """ - - return f'name: {self.name} position: {self.position}' - - def __hash__(self): - return id(self) - - -class Developer(Employee): - """ - Сотрудник - разработчик - """ - - language: str - position: str = 'developer' - - def __init__(self, name: str, salary: int, language: str): - """ - Задача: реализовать конструктор класса, используя конструктор родителя - """ - - super().__init__(name, self.position, salary) - self.language = language - - -class Manager(Employee): - """ - Сотрудник - менеджер - """ - - position: str = 'manager' - - def __init__(self, name: str, salary: int): - """ - Задача: реализовать конструктор класса, используя конструктор родителя - """ - - super().__init__(name, self.position, salary) diff --git a/tasks/practice1/practice1.py b/tasks/practice1/practice1.py index e2da9fe..030da70 100644 --- a/tasks/practice1/practice1.py +++ b/tasks/practice1/practice1.py @@ -8,7 +8,7 @@ def concatenate_strings(a: str, b: str) -> str: :return: результат сложения """ - result = a + b + # пиши свой код здесь return result @@ -22,6 +22,6 @@ def calculate_salary(total_compensation: int) -> float: :return: сумма заплаты после вычета налога """ - result = total_compensation * 0.87 + # пиши свой код здесь return result diff --git a/tasks/practice1/practice2.py b/tasks/practice1/practice2.py deleted file mode 100644 index 651d4e1..0000000 --- a/tasks/practice1/practice2.py +++ /dev/null @@ -1,121 +0,0 @@ -from typing import Iterable -import random - - -UNCULTURED_WORDS = ('kotleta', 'pirog') - - -def greet_user(name: str) -> str: - """ - Генерирует приветственную фразу. - Приветствие не может состоять только из одного имени пользователя. - - :param name: имя пользователя - :return: приветствие - """ - - greeting = 'Zdarovstvuyte, дорогой ' + name - - return greeting - - -def get_amount() -> float: - """ - Генерируем случайную сумму на счете. - - Сумма: - - в диапазоне от 100 до 1000000 - - float - - не больше 2-х знаков после запятой - - :return: случайную сумму на счете - """ - - amount = round(random.uniform(100, 1000000), 2) - - return amount - - -def is_phone_correct(phone_number: str) -> bool: - """ - Функция проверяет, что номер телефона соответствует следующему формату: - +7xxxxxxxxxx, где x - цифра от 0 до 9 - - :param phone_number: предполагаемый номер телефона - :return: буленовское значение - bool: True - если номер корректны, - False - если номер некорректный - """ - - if phone_number[:2] == "+7" and phone_number[2:].isnumeric(): - result = True - else: - result = False - - return result - - -def is_amount_correct(current_amount: float, transfer_amount: str) -> bool: - """ - Проверяет возможность осуществления перевода. - Перевод возможен если выполняется условие: - - текущий счет (current_amount) больше или равен сумме перевода (transfer_amount) - - :param current_amount: текущий счет - :param transfer_amount: сумма перевода - :return: буленовское значение - bool: True - если перевод возможен, - False - если денег недостаточно - """ - - result = current_amount >= float(transfer_amount) - return result - - -def moderate_text(text: str, uncultured_words: Iterable[str]) -> str: - """ - Модерирует текст по следующим правилам. - - Требования к тексту: - - Первая буква заглавная, остальные буквы только в нижнем регистре - - отсутствую лишние пробелы - - фильтруются 'опасные' символы: " ' (двойные и одинарные кавычки) - - слова, перечисленные в переменной uncultured_words заменяются на аналогичное количество знаков # - - :param text: исходный текст - :param uncultured_words: список запрещенных слов - :return: текст, соответсвующий правилам - """ - - dangerous_characters = ['"', "'"] - result = text.strip() - result = result.capitalize() - - for char in dangerous_characters: - result = result.replace(char, '') - for i in uncultured_words: - result = result.replace(i, '#' * len(i)) - - return result - - -def create_request_for_loan(user_info: str) -> str: - """ - Генерирует заявку на кредит на основе входящей строки. - Формат входящий строки: - - Иванов,Петр,Сергеевич,01.01.1991,10000 - - Что должны вернуть на ее основе: - - Фамилия: Иванов - Имя: Петр - Отчество: Сергеевич - Дата рождения: 01.01.1991 - Запрошенная сумма: 10000 - - :param user_info: строка с информацией о клиенте - :return: текст кредитной заявки - """ - - info = user_info.split(',') - result = f'Фамилия: {info[0]}\n Имя: {info[1]}\n Отчество: {info[2]}\n Дата рождения: {info[3]}\n Запрошенная сумма: {info[4]}' - return result diff --git a/tasks/practice1/practice3.py b/tasks/practice1/practice3.py deleted file mode 100644 index deceaa5..0000000 --- a/tasks/practice1/practice3.py +++ /dev/null @@ -1,127 +0,0 @@ -from pathlib import Path -from typing import Dict, Any, List, Optional -import csv - - -def count_words(text: str) -> Dict[str, int]: - """ - Функция для подсчета слов в тексте. - - При подсчете слов - все знаки препинания игнорируются. - Словом считается непрерывная последовательность длиной больше одного - символа, состоящая из букв в диапазоне A-Z и a-z. - Если в последовательности присутствует цифра - это не слово. - - Hello - слово - Hello7 - не слово - - При подсчете слов регистр букв не имеет значения. - - Результат выполнения функции словарь, в котором: - ключ - слово в нижнем регистре - значение - количество вхождений слов в текст - - :param text: текст, для подсчета символов - :return: словарь, в котором: - ключ - слово в нижнем регистре - значение - количество вхождений слов в текст - """ - - dictionary = dict() - text = text.split() - for i in text: - if not any(j.isdigit() for j in i): - i = ''.join([j.lower() for j in i if j.isalpha()]) - if len(i) > 1: - if i in dictionary.keys(): - dictionary[i] += 1 - else: - dictionary[i] = 1 - - return dictionary - - -def exp_list(numbers: List[int], exp: int) -> List[int]: - """ - Функция, которая возводит каждый элемент списка в заданную степень - - :param numbers: список, состоящий из натуральных чисел - :param exp: в какую степень возвести числа в списке - :return: список натуральных чисел - """ - - result = [x ** exp for x in numbers] - - return result - - -def get_cashback(operations: List[Dict[str, Any]], special_category: List[str]) -> float: - """ - Функция для расчета кешбека по операциям. - За покупки в обычных категориях возвращается 1% от стоимости покупки - За покупки в special_category начисляют 5% от стоимости покупки - - :param operations: список словарей, содержащих поля - amount - сумма операции - category - категория покупки - :param special_category: список категорий повышенного кешбека - :return: размер кешбека - """ - - result = 0.0 - for i in operations: - if i['category'] in special_category: - result += i['amount'] * 0.05 - else: - result += i['amount'] * 0.01 - - return result - - -def get_path_to_file() -> Optional[Path]: - """ - Находит корректный путь до тестового файла. - - Если запускать тесты из pycharm - начальная папка - tests - Если запускать файлы через make tests - начальная папка - корень проекта - - :return: путь до тестового файла tasks.csv - """ - if Path().resolve().name == 'tests': - base_path = Path().resolve().parent - else: - base_path = Path().resolve() - return base_path / 'tasks' / 'practice3' / 'tasks.csv' - - -def csv_reader(header: str) -> int: - """ - Функция считывает csv файл и подсчитывает количество - уникальных элементов в столбце. - Столбец выбирается на основе имени заголовка, - переданного в переменной header. - - Обратите внимание на структуру файла! - Первая строка - строка с заголовками. - Остальные строки - строки с данными. - - Файл для анализа: tasks.csv - Для того чтобы файл корректно открывался в тестах: - для получения пути до файла - используйте функцию get_path_to_file - которая определена перед функцией. - - CSV анализируем с помощью встроенной библиотеки csv - - :param header: название заголовка - :return: количество уникальных элементов в столбце - """ - - path = get_path_to_file() - unique_elements = set() - with open(path, newline='') as csvfile: - reader = csv.DictReader(csvfile) - for row in reader: - unique_elements.add(row[header]) - result = len(unique_elements) - - return result diff --git a/tasks/practice1/practice4.py b/tasks/practice1/practice4.py deleted file mode 100644 index b85e6ab..0000000 --- a/tasks/practice1/practice4.py +++ /dev/null @@ -1,54 +0,0 @@ -from typing import Any, Optional - - -def search_phone(content: Any, name: str) -> Optional[str]: - """ - Функция поиска номера телефона пользователя в структуре данных. - - Алгоритм работы следующий: - 1) принимаем на вход структуру content, состоящую из словарей, - списков и строковых ключей в списке - 2) внутри структуры может быть запись следующего формата: - { - 'name': 'user_name', - 'phone': 'user_phone', - } - - 3) необходимо пройтись по всей структуре - 4) если встречаем словарь, в котором ключ name совпадает с - аргументом функции name - берем из этого словаря поле phone - и возвращаем этот телефон из функции - 5) если поле name с таким значением не найдено - возвращаем из - функции None - - Может пригодиться: - - 1) Чтобы проверить, является ли объект списком используйте функцию: - isinstance(some_object, list) - если some_object список - результат будет True - если some_object не список - False - - 2) Чтобы проверить, является ли объект словарем используйте функцию: - isinstance(some_object, dict) - - - :param content: словарь или список, внутрь которого вложены объекты. Внутри - может скрываться номер телефона пользователя - :param name: имя пользователя, у которого будем искать номер телефона - :return: номер телефона пользователя или None - """ - - if isinstance(content, dict): - if content.get('name') == name: - return content.get('phone') - for value in content.values(): - result = search_phone(value, name) - if result is not None: - return result - elif isinstance(content, list): - for item in content: - result = search_phone(item, name) - if result is not None: - return result - - return None diff --git a/tasks/practice1/team.py b/tasks/practice1/team.py deleted file mode 100644 index 1fca240..0000000 --- a/tasks/practice1/team.py +++ /dev/null @@ -1,80 +0,0 @@ -from typing import Set -from .employee import Employee, Manager -from .exception import NoSuchMemberError - - -class Team: - """ - Класс - команда. - У каждой команды есть менеджер, название и участники. - - Возможности: - - добавление участников - - удаление участника из команды - - просмотр базовой информации об участниках - - получение списка участников - """ - - name: str - manager: Manager - __members: Set[Employee] - - def __init__(self, name: str, manager: Manager): - """ - Задача: - Реализовать конструктор класса. - Конструктор должен присвоить значения публичным атрибутам - и инициализировать контейнер `__members` - """ - - self.name = name - self.manager = manager - self.__members = set() - - def add_member(self, member: Employee) -> None: - """ - Задача: реализовать метод добавления участника в команду. - Добавить можно только работника. - """ - - if not isinstance(member, Employee): - raise TypeError - self.__members.add(member) - - def remove_member(self, member: Employee) -> None: - """ - Задача: реализовать метод удаления участника из команды. - Если в команде нет такого участника поднимается исключение `NoSuchMemberError` - """ - - if not isinstance(member, Employee): - raise TypeError - if member not in self.__members: - raise NoSuchMemberError(self.name, member) - self.__members.remove(member) - - - def get_members(self) -> Set[Employee]: - """ - Задача: реализовать метод возвращения списка участков команды та, - чтобы из вне нельзя было поменять список участников внутри класса - """ - - return self.__members.copy() - - def __str__(self): - return 'team: ' + self.name + ' manager: ' + self.manager.name + ' number of members: ' + str(len(self.get_members())) - - def show(self) -> None: - """ - DO NOT EDIT! - Данный метод нельзя редактировать! - - Метод показывает информацию о команде в формате: - `'team: {team_name} manager: {manager_name} number of members: {members_count)}'` - - Задача: доработать класс таким образом, чтобы метод выполнял свою функцию, не меняя содержимое - этого метода - """ - - print(self) From c4d379b022df703bcff9b47ec379db35db5b6945 Mon Sep 17 00:00:00 2001 From: AlexVenem Date: Mon, 17 Jun 2024 01:18:44 +0300 Subject: [PATCH 3/4] Submitting my work correctly --- tasks/practice1/practice1.py | 4 ++-- tasks/practice2/practice2.py | 31 +++++++++++++++++++++++++------ tasks/practice3/practice3.py | 35 +++++++++++++++++++++++++++++------ tasks/practice4/practice4.py | 13 ++++++++++++- tasks/practice5/employee.py | 24 ++++++++++++++++++------ tasks/practice5/team.py | 20 ++++++++++++++++---- 6 files changed, 102 insertions(+), 25 deletions(-) diff --git a/tasks/practice1/practice1.py b/tasks/practice1/practice1.py index 030da70..e2da9fe 100644 --- a/tasks/practice1/practice1.py +++ b/tasks/practice1/practice1.py @@ -8,7 +8,7 @@ def concatenate_strings(a: str, b: str) -> str: :return: результат сложения """ - # пиши свой код здесь + result = a + b return result @@ -22,6 +22,6 @@ def calculate_salary(total_compensation: int) -> float: :return: сумма заплаты после вычета налога """ - # пиши свой код здесь + result = total_compensation * 0.87 return result diff --git a/tasks/practice2/practice2.py b/tasks/practice2/practice2.py index 008f6d1..c411470 100644 --- a/tasks/practice2/practice2.py +++ b/tasks/practice2/practice2.py @@ -1,4 +1,6 @@ from typing import Iterable +import random + UNCULTURED_WORDS = ('kotleta', 'pirog') @@ -12,7 +14,8 @@ def greet_user(name: str) -> str: :return: приветствие """ - # пиши код здесь + greeting = 'Zdarovstvuyte, дорогой ' + name + return greeting @@ -28,7 +31,8 @@ def get_amount() -> float: :return: случайную сумму на счете """ - # пиши код здесь + amount = round(random.uniform(100, 1000000), 2) + return amount @@ -42,7 +46,11 @@ def is_phone_correct(phone_number: str) -> bool: False - если номер некорректный """ - # пиши код здесь + if phone_number[:2] == "+7" and phone_number[2:].isnumeric(): + result = True + else: + result = False + return result @@ -58,7 +66,8 @@ def is_amount_correct(current_amount: float, transfer_amount: str) -> bool: False - если денег недостаточно """ - # пиши код здесь + result = current_amount >= float(transfer_amount) + return result @@ -77,7 +86,15 @@ def moderate_text(text: str, uncultured_words: Iterable[str]) -> str: :return: текст, соответсвующий правилам """ - # пиши код здесь + dangerous_characters = ['"', "'"] + result = text.strip() + result = result.capitalize() + + for char in dangerous_characters: + result = result.replace(char, '') + for i in uncultured_words: + result = result.replace(i, '#' * len(i)) + return result @@ -100,5 +117,7 @@ def create_request_for_loan(user_info: str) -> str: :return: текст кредитной заявки """ - # пиши код здесь + info = user_info.split(',') + result = f'Фамилия: {info[0]}\n Имя: {info[1]}\n Отчество: {info[2]}\n Дата рождения: {info[3]}\n Запрошенная сумма: {info[4]}' + return result diff --git a/tasks/practice3/practice3.py b/tasks/practice3/practice3.py index 9115c9c..deceaa5 100644 --- a/tasks/practice3/practice3.py +++ b/tasks/practice3/practice3.py @@ -1,5 +1,6 @@ from pathlib import Path from typing import Dict, Any, List, Optional +import csv def count_words(text: str) -> Dict[str, int]: @@ -26,9 +27,18 @@ def count_words(text: str) -> Dict[str, int]: значение - количество вхождений слов в текст """ - # пиши свой код здесь + dictionary = dict() + text = text.split() + for i in text: + if not any(j.isdigit() for j in i): + i = ''.join([j.lower() for j in i if j.isalpha()]) + if len(i) > 1: + if i in dictionary.keys(): + dictionary[i] += 1 + else: + dictionary[i] = 1 - return {} + return dictionary def exp_list(numbers: List[int], exp: int) -> List[int]: @@ -40,9 +50,9 @@ def exp_list(numbers: List[int], exp: int) -> List[int]: :return: список натуральных чисел """ - # пиши свой код здесь + result = [x ** exp for x in numbers] - return [] + return result def get_cashback(operations: List[Dict[str, Any]], special_category: List[str]) -> float: @@ -58,6 +68,13 @@ def get_cashback(operations: List[Dict[str, Any]], special_category: List[str]) :return: размер кешбека """ + result = 0.0 + for i in operations: + if i['category'] in special_category: + result += i['amount'] * 0.05 + else: + result += i['amount'] * 0.01 + return result @@ -99,6 +116,12 @@ def csv_reader(header: str) -> int: :return: количество уникальных элементов в столбце """ - # пиши свой код здесь + path = get_path_to_file() + unique_elements = set() + with open(path, newline='') as csvfile: + reader = csv.DictReader(csvfile) + for row in reader: + unique_elements.add(row[header]) + result = len(unique_elements) - return 0 + return result diff --git a/tasks/practice4/practice4.py b/tasks/practice4/practice4.py index a7d6b8d..b85e6ab 100644 --- a/tasks/practice4/practice4.py +++ b/tasks/practice4/practice4.py @@ -38,6 +38,17 @@ def search_phone(content: Any, name: str) -> Optional[str]: :return: номер телефона пользователя или None """ - # пиши свой код здесь + if isinstance(content, dict): + if content.get('name') == name: + return content.get('phone') + for value in content.values(): + result = search_phone(value, name) + if result is not None: + return result + elif isinstance(content, list): + for item in content: + result = search_phone(item, name) + if result is not None: + return result return None diff --git a/tasks/practice5/employee.py b/tasks/practice5/employee.py index 1d7bad8..173c741 100644 --- a/tasks/practice5/employee.py +++ b/tasks/practice5/employee.py @@ -38,14 +38,20 @@ def __init__(self, name: str, position: str, salary: int): Задача: реализовать конструктор класса, чтобы все тесты проходили """ - # пиши свой код здесь + if isinstance(salary, int): + self.name = name + self.position = position + self._salary = salary + else: + raise ValueError + def get_salary(self) -> int: """ Метод возвращает зарплату сотрудника. """ - # пиши свой код здесь + return self._salary def __eq__(self, other: object) -> bool: """ @@ -55,7 +61,12 @@ def __eq__(self, other: object) -> bool: Если что-то идет не так - бросаются исключения. Смотрим что происходит в тестах. """ - # пиши свой код здесь + if not isinstance(other, Employee): + raise TypeError + try: + return get_position_level(self.position) == get_position_level(other.position) + except NoSuchPositionError: + raise ValueError def __str__(self): """ @@ -63,7 +74,7 @@ def __str__(self): Пример вывода: 'name: Ivan position manager' """ - # пиши свой код здесь + return f'name: {self.name} position: {self.position}' def __hash__(self): return id(self) @@ -82,7 +93,8 @@ def __init__(self, name: str, salary: int, language: str): Задача: реализовать конструктор класса, используя конструктор родителя """ - # пиши свой код здесь + super().__init__(name, self.position, salary) + self.language = language class Manager(Employee): @@ -97,4 +109,4 @@ def __init__(self, name: str, salary: int): Задача: реализовать конструктор класса, используя конструктор родителя """ - # пиши свой код здесь + super().__init__(name, self.position, salary) diff --git a/tasks/practice5/team.py b/tasks/practice5/team.py index 934796c..1d7cb62 100644 --- a/tasks/practice5/team.py +++ b/tasks/practice5/team.py @@ -27,7 +27,9 @@ def __init__(self, name: str, manager: Manager): и инициализировать контейнер `__members` """ - # пиши свой код здесь + self.name = name + self.manager = manager + self.__members = set() def add_member(self, member: Employee) -> None: """ @@ -35,7 +37,9 @@ def add_member(self, member: Employee) -> None: Добавить можно только работника. """ - # пиши свой код здесь + if not isinstance(member, Employee): + raise TypeError + self.__members.add(member) def remove_member(self, member: Employee) -> None: """ @@ -43,7 +47,11 @@ def remove_member(self, member: Employee) -> None: Если в команде нет такого участника поднимается исключение `NoSuchMemberError` """ - # пиши свой код здесь + if not isinstance(member, Employee): + raise TypeError + if member not in self.__members: + raise NoSuchMemberError(self.name, member) + self.__members.remove(member) def get_members(self) -> Set[Employee]: """ @@ -51,7 +59,11 @@ def get_members(self) -> Set[Employee]: чтобы из вне нельзя было поменять список участников внутри класса """ - # пиши свой код здесь + return self.__members.copy() + + def __str__(self): + return 'team: ' + self.name + ' manager: ' + self.manager.name + ' number of members: ' + str(len(self.get_members())) + def show(self) -> None: """ From b82cec5a7ba8ead64907ca52c22dfa04d6149403 Mon Sep 17 00:00:00 2001 From: AlexVenem Date: Mon, 17 Jun 2024 01:27:11 +0300 Subject: [PATCH 4/4] Submitting my work correctly --- tasks/practice2/practice2.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tasks/practice2/practice2.py b/tasks/practice2/practice2.py index c411470..7197f8d 100644 --- a/tasks/practice2/practice2.py +++ b/tasks/practice2/practice2.py @@ -118,6 +118,10 @@ def create_request_for_loan(user_info: str) -> str: """ info = user_info.split(',') - result = f'Фамилия: {info[0]}\n Имя: {info[1]}\n Отчество: {info[2]}\n Дата рождения: {info[3]}\n Запрошенная сумма: {info[4]}' + result = f'Фамилия: {info[0]}\n' + \ + f'Имя: {info[1]}\n' +\ + f'Отчество: {info[2]}\n' +\ + f'Дата рождения: {info[3]}\n' +\ + f'Запрошенная сумма: {info[4]}' return result