web-dev/hws/hw-2/README.md
2026-02-13 15:01:19 +03:00

354 lines
No EOL
22 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Решите задачи, приведённые ниже. Код каждой задачи разместите в отдельном файле, название которого соответствует указанному в условии задачи. В качестве ответа на это задание загрузите архив (ZIP) с решениями. Архив должен содержать только файлы с решениями, файл test.py и вспомогательные файлы, необходимые для отдельных задач (не должно быть папок).
Напишите тесты для решённых задач с использованием фреймворка pytest, разместите их в файле test.py. Для каждой задачи достаточно рассмотреть принципиально различные ситуации (входные данные). Всего должно быть написано не менее 60 тестов. В отличие от предыдущего домашнего задания, в данном задании предполагается, что решение каждой задачи будет представлено в виде функции (если не сказано иного), которую вам необходимо импортировать в файле test.py для последующего тестирования (т. е. в тестах должны непосредственно вызываться тестируемые функции). При импорте функций не должно выполняться ничего лишнего. При необходимости выполнить какие-либо действия при запуске файла с программой (например, запросить пользовательский ввод, осуществить замер времени выполнения функции т. д.) не забудьте заключить их в условие `if __name__ == '__main__':`.
При обнаружении ошибок или неточностей в формулировках задач свяжитесь с преподавателем.
## 1) Вычисление факториала
Реализуйте рекурсивную (fact_rec) и итерационную (fact_it) функции вычисления факториала целого положительного числа n. Сравните скорость работы реализованных функций, результат сравнения приведите в комментарии в файле с программой. Для измерения времени выполнения можно использовать модули `time` или `timeit`. Функцией math.factorial пользоваться нельзя.
**Ограничения:**
- 1 ⩽ n ⩽ 10⁵
**Название файла:** fact.py
## 2) Данные сотрудника
Реализуйте функцию show_employee, принимающую в качестве аргументов имя сотрудника (name) и величину его заработной платы (salary) и возвращающую строку с данными в следующем формате: "Иванов Иван Иванович: 30000 ₽". В случае, если значение заработной платы не было передано при вызове функции, установить его равным 100000.
**Название файла:** show_employee.py
## 3) Сумма и разность
Реализуйте функцию sum_and_sub, которая принимает в качестве аргументов два действительных числа (a и b) и возвращает их сумму и разность.
**Название файла:** sum_and_sub.py
## 4) Обработка списка
В файле process_list.py приведён код функции обработки данных списка (arr).
Перепишите приведённую функцию с использованием list comprehension. Реализуйте функцию-генератор с аналогичной функциональностью (process_list_gen). Сравните скорость работы реализованных функций, результат сравнения приведите в комментарии в файле с программой.
**Ограничения:**
- 1 ⩽ len(arr) ⩽ 10³
**Название файла:** process_list.py
## 5) Функция сложения с произвольным количеством аргументов
Реализуйте функцию my_sum, принимающую произвольное количество аргументов (действительных чисел) и возвращающую их сумму.
**Название файла:** my_sum.py
## 6) Аргументы командной строки
Перепишите программу из 5-й задачи таким образом, чтобы числа для сложения передавались при вызове программы как аргументы командной строки, а результат выводился на стандартный поток вывода.
**Название файла:** my_sum_argv.py
**Пример вызова:** python3 my_sum_argv.py 1 2 3 4 5
**Пример вывода:**
```
15
```
## 7) Сортировка файлов
Напишите программу, которая в качестве аргумента командной строки принимает путь до некоторой директории и выводит список всех файлов в этой директории, упорядоченных в лексикографическом порядке и сгруппированных по расширению. Имена вложенных подкаталогов выводить не нужно. Например, если в директории находятся файлы a.py, a.txt, b.py, b.txt, c.py, c.txt, они должны быть выведены в следующем порядке:
```
a.py
b.py
c.py
a.txt
b.txt
c.txt
```
**Подсказка:** для того, чтобы отличить строку с именем файла от строки с именем подкаталога можно использовать функции os.path.isfile или os.path.isdir.
**Название файла:** files_sort.py
## 8) Рекурсивный поиск файла
Напишите программу, которая в качестве аргумента командной строки принимает имя файла и осуществляет рекурсивный поиск указанного файла относительно директории, в которой находится файл с программой. Если файл найден -- вывести первые 5 строк, в противном случае -- вывести сообщение "Файл {названиеайла} не найден".
**Подсказка:** если вы пишете рекурсивную функцию, то после рекурсивного вызова нужно возвращаться в родительский каталог при помощи os.chdir(".."). Другой вариант решения задачи: воспользоваться функцией os.walk.
**Название файла:** file_search.py
## 9) Валидация адресов электронной почты
Вам дается целое число N, за которым следуют N адресов электронной почты. Ваша задача -- вывести список, содержащий только корректные адреса электронной почты в лексикографическом порядке.
Корректные адреса электронной почты должны соответствовать следующим правилам:
- Он должен иметь формат username@websitename.extension.
- Имя пользователя может содержать только цифры, латинские буквы, тире и подчеркивания.
- Название веб-сайта может содержать только цифры и латинские буквы.
- Расширение может содержать только латинские буквы.
- Максимальная длина расширения составляет 3.
Допишите функцию fun, которая прилагается к заданию, чтобы она возвращала True для корректных адресов, а для остальных -- False.
**Формат ввода:**
Первая строка ввода -- целое число, количество адресов электронной почты. Далее следуют N строк, каждая из которых содержит адрес электронной почты.
**Ограничения:**
Не может быть введено пустых значений.
**Пример ввода:**
```
3
lara@mospolytech.ru
brian-23@mospolytech.ru
britts_54@mospolytech.ru
```
**Пример вывода:**
```
['brian-23@mospolytech.ru', 'britts_54@mospolytech.ru', 'lara@mospolytech.ru']
```
**Название файла:** email_validation.py
## 10) Числа Фибоначчи
Дополните код, приведённый в файле fibonacci.py. Вы должны сгенерировать список первых n чисел Фибоначчи, начиная с 0. Затем примените функцию map и лямбда-выражение для возведения в куб каждого из полученных чисел Фибоначчи и выведите список на стандартный поток вывода.
**Формат ввода:**
Одна строка: целое число n.
**Формат вывода:**
Список в одной строке, содержащий кубы первых n чисел Фибоначчи.
**Ограничения:**
- 1 ⩽ n ⩽ 15
**Пример ввода:**
```
5
```
**Пример вывода:**
```
[0, 1, 1, 8, 27]
```
**Название файла:** fibonacci.py
## 11) Средние оценки
Университет проводит экзамен для N студентов по X предметам. Реализуйте функцию compute_average_scores, которая подсчитывает средние баллы каждого студента. Функция принимает один параметр scores -- список из X кортежей, каждый из которых содержит по N чисел в диапазоне от 0 до 100. Каждый кортеж соответствует оценкам по определённому предмету. Элементы с одинаковым индексом в каждом из кортежей соответствуют одному и тому же студенту. Возвращает функция кортеж из X элементов -- средние баллы каждого студента.
**Формат ввода:**
Первая строка содержит значения N и X, разделенные пробелом. Следующие X строк содержат оценки, разделенные пробелом, полученные учащимися по определенному предмету.
**Ограничения:**
- 0 < N 100
- 0 < X 100
**Формат вывода:**
Выведите средние значения по всем учащимся в отдельных строках. Средние значения должны быть корректными с точностью до 1 десятичного знака.
**Пример ввода:**
```
5 3
89 90 78 93 80
90 91 85 88 86
91 92 83 89 90.5
```
**Пример вывода:**
```
90.0
91.0
82.0
90.0
85.5
```
**Название файла:** average_scores.py
## 12) Угол между плоскостями
Вам даны четыре точки (A, B, C, D) в трехмерной декартовой системе координат. Вам нужно вычислить угол между плоскостями, образованными точками A, B, C и B, C, D в градусах (не в радианах). Обозначим этот угол как ϕ, тогда cos(ϕ) = (X, Y)/|X||Y|, где X = AB × BC и Y = BC × CD. (X, Y) -- скалярное произведение X и Y, AB × BC -- векторное произведение AB и BC, где AB = B A и BC = B C. Оформите решение в виде функции plane_angle, которая принимает четыре аргумента: точки A, B, C, D (экземпляры класса Point). В файле plane_angle.py приведена заготовка класса Point -- допишите недостающие методы, которые вам потребуются для решения задачи. Функция plane_angle должна возвращать одно число -- искомый угол в градусах.
**Название файла:** plane_angle.py
## 13) Форматирование номера телефона
Вам даны номера мобильных телефонов. Отсортируйте их в порядке возрастания, затем выведите в стандартном формате: +7 (xxx) xxx-xx-xx. Указанные мобильные номера могут начинаться с 8, +7 или 0, после чего следует десятизначный номер. Также префикс может отсутствовать вовсе. Вам дана заготовка кода в файле phone_number.py -- заполните недостающие фрагменты.
**Формат ввода:**
Первая строка ввода содержит целое число N, количество номеров мобильных телефонов. Далее следуют N строк, содержащие номера мобильных телефонов.
**Формат вывода:**
Выведите N номеров мобильных телефонов отдельными строками в требуемом формате.
**Пример ввода:**
```
3
07895462130
89875641230
9195969878
```
**Пример вывода:**
```
+7 (789) 546-21-30
+7 (919) 596-98-78
+7 (987) 564-12-30
```
**Название файла:** phone_number.py
## 14) Сортировка списка
Вам предоставляется некоторая информация о людях. Для каждого человека в вашем распоряжении есть имя, фамилия, возраст и пол. Выведите их имена в определенном формате (см. ниже), отсортируйте список по возрасту в порядке возрастания, т.е. имя самого младшего человека должно быть напечатано первым. Для двух человек одного возраста выведите их в порядке ввода. Вам дана заготовка кода в файле people_sort.py -- заполните недостающие фрагменты.
**Формат ввода:**
Первая строка содержит целое число N, количество человек. Следующие N строк содержат разделенные пробелом значения имени, фамилии, возраста и пола соответственно.
**Формат вывода:**
Выведите имена в отдельных строках в приведённом ниже формате в порядке возрастания возраста.
Пример формата вывода: для "Henry Davids" вывод должен быть "Mr. Henry Davids", для "Mary George" вывод должен быть "Ms. Mary George".
**Ограничения:**
- 1 N 10
**Пример ввода:**
```
3
Mike Thomson 20 M
Robert Bustle 32 M
Andria Bustle 30 F
```
**Пример вывода:**
```
Mr. Mike Thomson
Ms. Andria Bustle
Mr. Robert Bustle
```
**Название файла:** people_sort.py
## 15) Комплексные числа
Для этого задания вам даны два комплексных числа, и вы должны вывести результат их сложения, вычитания, умножения, деления и операции вычисления модуля. Действительная и мнимая части должны быть представлены с точностью до двух знаков после запятой. Вам дана заготовка кода в файле complex_numbers.py -- заполните недостающие фрагменты.
**Формат ввода:**
Одна строка ввода: действительная и мнимая части числа, разделенные пробелом.
**Формат вывода:**
Для двух комплексных чисел C и D выходные данные должны быть в следующей последовательности в отдельных строках:
- C + D,
- C - D,
- C * D,
- C/D,
- mod(C),
- mod(D).
Для комплексных чисел с ненулевой действительной (A) и комплексной (B) частью выходные данные должны быть в следующем формате: A + Bi. Знак "+" должен быть заменён на "-", если B < 0.
Для комплексных чисел с нулевой комплексной частью (B), т.е. действительных чисел, выходные данные должны быть в формате: A + 0.00i.
Для комплексных чисел, где действительная часть (A) равна нулю, а комплексная часть (B) ненулевая, выходные данные должны быть: 0.00 + Bi.
**Пример ввода:**
```
2 1
5 6
```
**Пример вывода:**
```
7.00+7.00i
-3.00-5.00i
4.00+17.00i
0.26-0.11i
2.24+0.00i
7.81+0.00i
```
**Название файла:** complex_numbers.py
## 16) Монте-Карло
Реализуйте вычисление площади окружности методом Монте-Карло. Оформите решение в виде функции circle_square_mk, которая принимает два параметра: r -- радиус окружности и n -- количество экспериментов в методе Монте-Карло, и возвращает действительное число -- полученную площадь. При тестировании функции сравните полученные результаты с площадью, вычисленной по формуле. Оцените получаемую погрешность расчёта в зависимости от количества экспериментов (n), результат укажите в комментарии.
**Название файла:** circle_square_mk.py
## 17) Декоратор для логирования
Напишите декоратор function_logger, который принимает в качестве аргумента путь к файлу. Если данный декоратор добавить к функции, то в указанный файл будет логироваться информация вида:
- Название функции,
- Время вызова функции (в формате yyyy-mm-dd HH:MM:SS),
- Входящие аргументы (при наличии: в виде кортежа -- позиционные, в виде словаря -- ключевые),
- Возвращаемое значение (если есть, если нет то логировать '-')
- Время завершения работы функции (в формате yyyy-mm-dd HH:MM:SS)
- Время работы функции (в секундах).
При отсутствии указанного файла он должен быть создан, в противном случае логи должны добавляться в конец файла.
**Пример использования:**
```python
@function_logger('test.log')
def greeting_format(name):
return f'Hello, {name}!'
greeting_format('John')
```
**Пример содержимого файла test.log:**
```
greeting_format
2024-02-19 16:00:12.670738
('John',)
Hello, John!
2024-02-19 16:00:12.670741
0:00:00.000003
```
**Название файла:** log_decorator.py
**Замечание:** При написании тестов вам может быть полезна библиотека FreezeGun.