Домашнее задание №6
Contents
Домашнее задание №6#
Warning
Данное домашнее задание нацелено на закрепление темы списковых включений, генераторов и декораторов. Убедитесь, что в каждой задаче вы используете хотя бы один из перечисленных элементов.
В рамках домашнего задания №6 от вас требуется решить 13 задач
Чет, нечет;
Сумма элементов;
Числа с цифрой 6;
Список нескрытых файлов;
Попарные суммы элементов двух списков;
Попарные суммы элементов одного списка;
Сумма по строкам;
Сумма по столбцам*;
Диагонали матрицы;
Скалярное произведение;
\(l_p\) норма;
Счет вверх и вниз;
Итератор по соседним элементам.
На усмотрение студента предлагается решить ещё и задачи из необязательной части.
1. Чет, нечет#
Пусть дан список v
положительных целых чисел. С помощью спискового включения сгенерируйте другой список, где каждое четное заменится на строку "even"
, а нечетное на строку "odd"
.
def odd_even(v: list[int]) -> list[str]:
return [
# ваш код
]
numbers = [1, 3, 2]
print(odd_even(numbers)) # ["odd", "odd", "even"]
Сделайте это без применения функций (в том числе и анонимных) внутри спискового включения.
2. Сумма нечетных элементов#
С помощью списковых включений вычислите сумму всех нечетных (по значению) элементов списка.
def sum_odds(v: list[int]) -> int:
pass
L = [3, 7, 2, 4, 5, 6]
print(sum_odds(L)) # 15
3. Числа с цифрой 6#
Пусть дан список целых чисел v
. С помощью спискового включения оставьте только те числа, в десятичной записи которых есть цифра 6.
def contains_digit_six(v: list[int]) -> list[int]:
return [
# ваш код
]
v = [5, 6, 15, 51, 16, 61, 66, -5, -6]
print(contains_digit_six(v)) # [6, 16, 61, 66, -6]
4. Список нескрытых файлов#
В Unix-like операционных системах файлы и папки, названия которых начинаются с точки (.
), считаются скрытыми. С помощью спискового включения отфильтруйте таковые из результата функции os.listdir.
def nonhidden(path):
return [
# ваш код
]
5. Попарные суммы элементов двух списков#
Пусть есть два списка чисел \(u\) и \(v\). Верните сумму \(x_1 + x_2\) для каждой возможной пары элементов \((x_1, x_2)\), где \(x_1\in u\), а \(x_2\in v\).
def outer_sum(u: list[float], v: list[float]) -> list[float]:
return [
# ваш код
]
u = [0, 1, 2]
v = [100, 200, 300]
print(outer_sum(u, v)) # [100, 200, 300, 101, 201, 301, 102, 202, 302]
6. Попарные суммы элементов одного списка#
Пусть дан список чисел \(v\). Найдите \(\{x + y| x, y \in v\}\).
def choice2_sum(v: list[float]) -> list[float]:
return [
# ваш код
]
L = [1, 7, 42]
print(choice2_sum(L)) # [2, 8, 43, 8, 14, 49, 43, 49, 84]
7. Сумма по строкам#
Пусть дана прямоугольная матрица чисел matrix
в виде списка списков. Верните список сумм каждой из строк этой матрицы (эквивалент np.sum(matrix, axis=1)
).
def rowwise_sum(matrix: list[list[float]]) -> list[float]:
return [
# ваш код
]
matrix = [[1, 2], [3, 4]]
print(rowwise_sum(matrix)) # [3, 7]
8. Сумма по столбцам#
Пусть дана прямоугольная матрица чисел matrix
в виде списка списков. Верните список сумм каждой из строк этой матрицы (эквивалент np.sum(matrix, axis=0)
).
def columnwise_sum(matrix: list[list[float]]) -> list[float]:
return [
# ваш код
]
matrix = [[1, 2], [3, 4]]
print(columnwise_sum(matrix)) # [4, 6]
9. Диагонали матрицы#
Пусть дана квадратная матрица чисел matrix
в виде списка списков. Напишите два списковых включения, первое из которых возвращает главную диагональ матрицы, а второе побочную.
def major_diagonal(matrix: list[list[float]]) -> list[float]:
return [
# ваш код
]
def minor_diagonal(matrix: list[list[float]]) -> list[float]:
return [
# ваш код
]
matrix = [[1, 2], [3, 4]]
print(major_diagonal(matrix)) # [1, 4]
print(minor_diagonal(matrix)) # [2, 3]
10. Скалярное произведение#
Пусть даны два списка чисел \(u\) и \(v\). Используя списковое включение, найдите их скалярное произведение.
def dot_product(u: list[float], v: list[float]) -> float:
pass
u = [1, 2]
v = [3, 4]
print(dot_product(u, v)) # 11
11. \(l_p\) норма#
В пространстве \(l_p\) (\(p\geq1\)) норма вектора \(\vec{v}=\bigl(v_1, \ldots, v_n \bigr)\) определяется формулой
Определите функцию norm
вычисляющую \(l_p\) норму.
def norm(v: list[float], p: float) -> float:
pass
v = [3, 4]
print(norm(v, 2)) # 5.0
12. Счет вверх и вниз#
Напишите генератор, который считает от 0 до n
, а затем в обратном порядке.
def UpAndDown(n: int):
# ваш код здесь
print(list(UpAndDown(3))) # [0, 1, 2, 3, 2, 1, 0]
13. Итератор по соседним элементам#
Реализуйте итератор/генератор, который позволит итерировать сразу парами соседних элементов, т.е. для списка [A, B, C, D]
:
первая итерация
A
иB
— первый и второй элементы списка;вторая итерация
B
иC
— второй и третий элементы списка;третья и последняя итерация
C
иD
— третий и четвертый элементы списка.
def prev_next(iterable):
# ваш код здесь
x = ["A", "B", "C", "D"]
print(list(prev_next(x))) # [("A", "B"), ("B", "C"), ("C", "D")]
Необязательная часть#
Логирующий декоратор#
В качестве примера реализуйте параметризованный декоратор logged
, который при каждом вызове будет записывать данные для отладки в конец файла, переданного в декоратор в качестве параметра. Будет ли параметр именем файла или файловой переменной остаётся на ваше усмотрение.
Декоратор, проверяющий тип#
Напишите параметризованный декоратор typed
для функций одного аргумента, который бросает исключение TypeError, если функция вызвана с аргументом не того типа, который был указан в декораторе.
def typed(type_):
# ваш код здесь
@typed(str)
def paint_red(x):
color_red = "\033[91m"
color_end = "\033[0m"
return "".join([color_red, x, color_end])
Если эта функция вызывается со строковым аргументом, то при печати в консоль результат должен отображаться красным цветом.
print(paint_red("Текст красным цветом"))
Текст красным цветом
Note
В IDE и на сайте текст останется исходного цвета.
А вызов этой функции с аргументом другого типа, должен приводить к ошибке.
try:
paint_red(42)
except TypeError as msg:
print(msg)
Функция paint_red вызвана с неправильным типом аргумента int. Ожидался тип str.
Если func
— имя декорируемой функции, x
— имя её аргумента, а type_
— параметр, задающий тип этого аргумента в декораторе, то бросить необходимое исключение можно инструкцией
error_msg = "Функция {} вызвана с неправильным типом аргумента {}. Ожидался тип {}."
raise TypeError(error_msg.format(
func.__name__,
type(x).__name__,
type_.__name__
))
Диапазон действительных чисел#
Реализуйте генератор, который будет аналогичен range
, но будет принимать и целые и действительные числа (аналог np.arange
). Генератор должен работать для произвольной комбинации значений параметров, в том числе он должен уметь считать задом наперед. Использование этого генератора не должно приводить к бесконечным циклам.
def frange(): # сигнатуру придумайте сами
# ваш код здесь
print(list(frange(start=1.0, stop=0.0, step=-0.3))) # [1.0, 0.7, 0.4, 0.1]
Итератор по лог файлам#
Предположим, что вы пишите инструмент для анализа log
файлов какого-то софта. Часто за время работы программы накапливается много таких файлов. Ниже приведен список файлов в папке лог файлов некого фаервола.
access_log-20210304.bz2 access_log-20210624.bz2 access_log-20211029.bz2 access_log-20211216.bz2
access_log-20210320.bz2 access_log-20210717.bz2 access_log-20211105.bz2 access_log-20211219.bz2
access_log-20210330.bz2 access_log-20210804.bz2 access_log-20211111.bz2 access_log-20211221.bz2
access_log-20210412.bz2 access_log-20210817.bz2 access_log-20211114.bz2 access_log-20211223.bz2
access_log-20210416.bz2 access_log-20210827.bz2 access_log-20211118.bz2 access_log-20211227.bz2
access_log-20210427.bz2 access_log-20210914.bz2 access_log-20211123.bz2 access_log-20220103.bz2
access_log-20210507.bz2 access_log-20210923.bz2 access_log-20211127.bz2 access_log-20220113.bz2
access_log-20210517.bz2 access_log-20210929.bz2 access_log-20211201.bz2 access_log-20220125.bz2
access_log-20210520.bz2 access_log-20211005.bz2 access_log-20211204.bz2 access_log-20220208.bz2
access_log-20210524.bz2 access_log-20211015.bz2 access_log-20211209.bz2 access_log-20220217.bz2
access_log-20210526.bz2 access_log-20211020.bz2 access_log-20211212.bz2
access_log-20210603.bz2 access_log-20211024.bz2 access_log-20211214.bz2
Реализуйте итератор/генератор, который в качестве параметра будет принимать путь к папке и позволит пробежаться по строкам всех файлов в указанной папке так, будто бы это был один большой файл.