Практические задания

Чет, нечет

Пусть дан список L положительных целых чисел. С помощью спискового включения сгенерируйте другой список, где каждое четное заменится на строку "even", а не четное на строку "odd".

def odd_even(L):
    return [
        # ваш код
    ]

numbers = [1, 3, 2]
odd_even([1, 3, 2]) # [odd, odd, even]

Сделайте это без применения функций (в том числе и лямбда) внутри спискового включения.

Сумма элементов

С помощью списковых включений вычислите сумму всех нечетных элементов списка.

def sum_odds(L):
    pass

L = [1, 2, 3, 4] 
sum_odds(L) # 4

Числа с цифрой 6

Пусть дан список целых чисел L. С помощью спискового включения оставьте только те числа, в записи которых есть цифра 6.

Список нескрытых файлов

В Unix-like операционных системах файлы и папки, названия которых начинаются с точки (.), считаются скрытыми. С помощью спискового включения отфильтруйте таковые из результата функции os.listdir.

def nonhidden(path):
    return [
        # ваш код
    ]

Попарные суммы элементов двух списков

Пусть есть два списка чисел \(L_1\) и \(L_2\). Верните сумму \(x_1 + x_2\) для каждой возможной пары элементов \((x_1, x_2)\), где \(x_1\in L_1\), а \(x_2\in L_2\).

def outer_sum(L1, L2):
    return [
        # ваш код
    ]

L1 = [0, 1, 2]
L2 = [100, 200, 300]
outer_sum(L1, L2) # [100, 200, 300, 101, 201, 301, 102, 202, 302]

Попарные суммы элементов одного списка

Пусть дан список \(L\). Найдите сумму \(x_1 + x_2\) для каждой возможной пары элементов \((x_1, x_2)\) из списка \(L\).

def choice2_sum(L):
    return [
        # ваш код
    ]

L = [1, 7, 42]
choice2_sum(L) # [2, 8, 43, 8, 14, 49, 43, 49, 84]

Сумма по строкам

Пусть дана прямоугольная матрица чисел M в виде списка списков. Верните список сумм каждой из строк этой матрицы (эквивалент np.sum(M, axis=1)).

def row_wise_sum(M):
    return [
        # ваш код
    ]

matrix = [[1, 2], [3, 4]]
row_wise_sum(matrix) # [3, 7]

Сумма по столбцам*

Предыдущая задача, но сумма по столбцам.

def column_wise_sum(M):
    return [
        # ваш код
    ]

matrix = [[1, 2], [3, 4]]
column_wise_sum(matrix) # [4, 6]

Диагонали матрицы

Пусть дана квадратная матрица чисел M в виде списка списков. Напишите два списковых включения, первое из которых возвращает главную диагональ матрицы, а второе побочную.

def major_diagonal(M):
    return [ 
        # ваш код 
    ]

def minor_diagonal(M):
    return [
        # ваш код
    ]


matrix = [[1, 2], [3, 4]]
major_diagonal(M) # [1, 4]
minor_diagonal(M) # [2, 3]

Скалярное произведение

Пусть есть два списка чисел \(L_1\) и \(L_2\). Используя списковое включение, найдите их скалярное произведение.

def dot_product(L1, L2):
    pass

L1 = [1, 2]
L2 = [3, 4]

dot_product(L1, L2) # 11

Логирующий декоратор

В качестве примера реализуйте параметризованный декоратор 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]

Счет вверх и вниз

Напишите генератор, который считает от 0 до n, а затем в обратном порядке.

def UpAndDown(n):
    # ваш код здесь

print(list(UpAndDown(3))) # [0, 1, 2, 3, 2, 1, 0]

Итератор по соседним элементам

Реализуйте итератор/генератор, который позволит итерировать сразу парами соседних элементов, т.е. для списка [1, 2, 3, 4]:

  1. первая итерация 1 и 2;

  2. вторая итерация 2 и 3;

  3. третья и последняя итерация 3 и 4.

def prev_next(iterable):
    # ваш код здесь

x = [1, 2, 3, 4]
print(list(prev_next(x))) # [(1, 2), (2, 3), (3, 4)]

Итератор по лог файлам

Предположим, что вы пишите инструмент для анализа 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

Реализуйте итератор/генератор, который в качестве параметра будет принимать путь к папке и позволит пробежаться по строкам всех файлов в указанной папке так, будто бы это был один большой файл.