{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Практические задания\n", "\n", "\n", "## Чет, нечет\n", "\n", "Пусть дан список `L` положительных целых чисел. С помощью спискового включения сгенерируйте другой список, где каждое четное заменится на строку `\"even\"`, а не четное на строку `\"odd\"`.\n", "\n", "```python\n", "def odd_even(L):\n", " return [\n", " # ваш код\n", " ]\n", "\n", "numbers = [1, 3, 2]\n", "odd_even([1, 3, 2]) # [odd, odd, even]\n", "```\n", "\n", "Сделайте это без применения функций (в том числе и лямбда) внутри спискового включения.\n", "\n", "## Сумма элементов \n", "\n", "С помощью списковых включений вычислите сумму всех нечетных элементов списка.\n", "\n", "```python\n", "def sum_odds(L):\n", " pass\n", "\n", "L = [1, 2, 3, 4] \n", "sum_odds(L) # 4\n", "```\n", "\n", "## Числа с цифрой 6\n", "\n", "Пусть дан список целых чисел `L`. С помощью спискового включения оставьте только те числа, в записи которых есть цифра 6.\n", "\n", "## Список нескрытых файлов\n", "\n", "В Unix-like операционных системах файлы и папки, названия которых начинаются с точки (`.`), считаются скрытыми. С помощью спискового включения отфильтруйте таковые из результата функции [os.listdir](https://docs.python.org/3/library/os.html#os.listdir). \n", "\n", "```python\n", "def nonhidden(path):\n", " return [\n", " # ваш код\n", " ]\n", "\n", "```\n", "\n", "## Попарные суммы элементов двух списков\n", "\n", "Пусть есть два списка чисел $L_1$ и $L_2$. Верните сумму $x_1 + x_2$ для каждой возможной пары элементов $(x_1, x_2)$, где $x_1\\in L_1$, а $x_2\\in L_2$. \n", "\n", "```python\n", "def outer_sum(L1, L2):\n", " return [\n", " # ваш код\n", " ]\n", "\n", "L1 = [0, 1, 2]\n", "L2 = [100, 200, 300]\n", "outer_sum(L1, L2) # [100, 200, 300, 101, 201, 301, 102, 202, 302]\n", "```\n", "\n", "## Попарные суммы элементов одного списка\n", "\n", "Пусть дан список $L$. Найдите сумму $x_1 + x_2$ для каждой возможной пары элементов $(x_1, x_2)$ из списка $L$.\n", "\n", "```python\n", "def choice2_sum(L):\n", " return [\n", " # ваш код\n", " ]\n", "\n", "L = [1, 7, 42]\n", "choice2_sum(L) # [2, 8, 43, 8, 14, 49, 43, 49, 84]\n", "```\n", "\n", "## Сумма по строкам \n", "\n", "Пусть дана прямоугольная матрица чисел `M` в виде списка списков. Верните список сумм каждой из строк этой матрицы (эквивалент `np.sum(M, axis=1)`). \n", "\n", "```python\n", "def row_wise_sum(M):\n", " return [\n", " # ваш код\n", " ]\n", "\n", "matrix = [[1, 2], [3, 4]]\n", "row_wise_sum(matrix) # [3, 7]\n", "```\n", "\n", "## Сумма по столбцам*\n", "\n", "Предыдущая задача, но сумма по столбцам.\n", "\n", "```python\n", "def column_wise_sum(M):\n", " return [\n", " # ваш код\n", " ]\n", "\n", "matrix = [[1, 2], [3, 4]]\n", "column_wise_sum(matrix) # [4, 6]\n", "```\n", "\n", "## Диагонали матрицы\n", "\n", "Пусть дана квадратная матрица чисел `M` в виде списка списков. Напишите два списковых включения, первое из которых возвращает главную диагональ матрицы, а второе побочную. \n", "\n", "```python\n", "def major_diagonal(M):\n", " return [ \n", " # ваш код \n", " ]\n", "\n", "def minor_diagonal(M):\n", " return [\n", " # ваш код\n", " ]\n", "\n", "\n", "matrix = [[1, 2], [3, 4]]\n", "major_diagonal(M) # [1, 4]\n", "minor_diagonal(M) # [2, 3]\n", "```\n", "\n", "## Скалярное произведение\n", "\n", "Пусть есть два списка чисел $L_1$ и $L_2$. Используя списковое включение, найдите их скалярное произведение.\n", "\n", "```python\n", "def dot_product(L1, L2):\n", " pass\n", "\n", "L1 = [1, 2]\n", "L2 = [3, 4]\n", "\n", "dot_product(L1, L2) # 11\n", "```\n", "\n", "## Логирующий декоратор\n", "\n", "В качестве примера реализуйте параметризованный декоратор `logged`, который при каждом вызове будет записывать данные для отладки в конец файла, переданного в декоратор в качестве параметра. Будет ли параметр именем файла или файловой переменной остаётся на ваше усмотрение. \n", "\n", "\n", "## Декоратор, проверяющий тип*\n", "\n", "Напишите параметризованный декоратор `typed` для функций одного аргумента, который бросает исключение [TypeError](https://docs.python.org/3/library/exceptions.html#TypeError), если функция вызвана с аргументом не того типа, который был указан в декораторе.\n", "\n", "```python\n", "def typed(type_):\n", " # ваш код здесь\n", "\n", "@typed(str)\n", "def paint_red(x):\n", " color_red = \"\\033[91m\"\n", " color_end = \"\\033[0m\"\n", " return \"\".join([color_red, x, color_end])\n", "```\n", "\n", "Если эта функция вызывается со строковым аргументом, то при печати в консоль результат должен отображаться красным цветом. " ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "tags": [ "remove-cell" ] }, "outputs": [], "source": [ "from functools import wraps\n", "\n", "def typed(type_):\n", " def decorate(func):\n", " wraps(func)\n", " def wrap(x):\n", " if not isinstance(x, type_):\n", " error_msg = \"Функция {} вызвана с неправильным типом аргумента {}. Ожидался тип {}.\"\n", " raise TypeError(error_msg.format(\n", " func.__name__,\n", " type(x).__name__,\n", " type_.__name__\n", " ))\n", " return func(x)\n", " return wrap\n", " return decorate\n", "\n", "@typed(str)\n", "def paint_red(x):\n", " color_red = \"\\033[91m\"\n", " color_end = \"\\033[0m\"\n", " return \"\".join([color_red, x, color_end])" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[91mТекст красным цветом\u001b[0m\n" ] } ], "source": [ "print(paint_red(\"Текст красным цветом\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{note}\n", "В IDE и на сайте текст останется исходного цвета.\n", "```\n", "\n", "А вызов этой функции с аргументом другого типа, должен приводить к ошибке." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Функция paint_red вызвана с неправильным типом аргумента int. Ожидался тип str.\n" ] } ], "source": [ "try:\n", " paint_red(42)\n", "except TypeError as msg:\n", " print(msg)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Если `func` --- имя декорируемой функции, `x` --- имя её аргумента, а `type_` --- параметр, задающий тип этого аргумента в декораторе, то бросить необходимое исключение можно инструкцией\n", "```python\n", "error_msg = \"Функция {} вызвана с неправильным типом аргумента {}. Ожидался тип {}.\"\n", "raise TypeError(error_msg.format(\n", " func.__name__,\n", " type(x).__name__,\n", " type_.__name__\n", "))\n", "```\n", "\n", "## Диапазон действительных чисел.\n", "\n", "Реализуйте генератор, который будет аналогичен `range`, но будет принимать и целые и действительные числа (аналог `np.arange`). Генератор должен работать для произвольной комбинации значений параметров, в том числе он должен уметь считать задом наперед. Использование этого генератора не должно приводить к бесконечным циклам.\n", "\n", "```python\n", "def frange():\n", " # сигнатуру придумайте сами\n", " # ваш код здесь\n", "\n", "print(list(frange(start=1.0, stop=0.0, step=-0.3))) # [1.0, 0.7, 0.4, 0.1]\n", "```\n", "\n", "\n", "## Счет вверх и вниз \n", "\n", "Напишите генератор, который считает от 0 до `n`, а затем в обратном порядке.\n", "\n", "```python\n", "def UpAndDown(n):\n", " # ваш код здесь\n", "\n", "print(list(UpAndDown(3))) # [0, 1, 2, 3, 2, 1, 0]\n", "```\n", "\n", "## Итератор по соседним элементам\n", "\n", "Реализуйте итератор/генератор, который позволит итерировать сразу парами соседних элементов, т.е. для списка `[1, 2, 3, 4]`:\n", "1. первая итерация `1` и `2`;\n", "2. вторая итерация `2` и `3`;\n", "3. третья и последняя итерация `3` и `4`.\n", "\n", "```python\n", "def prev_next(iterable):\n", " # ваш код здесь\n", "\n", "x = [1, 2, 3, 4]\n", "print(list(prev_next(x))) # [(1, 2), (2, 3), (3, 4)]\n", "```\n", "\n", "## Итератор по лог файлам \n", "\n", "Предположим, что вы пишите инструмент для анализа `log` файлов какого-то софта. Часто за время работы программы накапливается много таких файлов. Ниже приведен список файлов в папке лог файлов некого фаервола.\n", "```\n", "access_log-20210304.bz2 access_log-20210624.bz2 access_log-20211029.bz2 access_log-20211216.bz2\n", "access_log-20210320.bz2 access_log-20210717.bz2 access_log-20211105.bz2 access_log-20211219.bz2\n", "access_log-20210330.bz2 access_log-20210804.bz2 access_log-20211111.bz2 access_log-20211221.bz2\n", "access_log-20210412.bz2 access_log-20210817.bz2 access_log-20211114.bz2 access_log-20211223.bz2\n", "access_log-20210416.bz2 access_log-20210827.bz2 access_log-20211118.bz2 access_log-20211227.bz2\n", "access_log-20210427.bz2 access_log-20210914.bz2 access_log-20211123.bz2 access_log-20220103.bz2\n", "access_log-20210507.bz2 access_log-20210923.bz2 access_log-20211127.bz2 access_log-20220113.bz2\n", "access_log-20210517.bz2 access_log-20210929.bz2 access_log-20211201.bz2 access_log-20220125.bz2\n", "access_log-20210520.bz2 access_log-20211005.bz2 access_log-20211204.bz2 access_log-20220208.bz2\n", "access_log-20210524.bz2 access_log-20211015.bz2 access_log-20211209.bz2 access_log-20220217.bz2\n", "access_log-20210526.bz2 access_log-20211020.bz2 access_log-20211212.bz2\n", "access_log-20210603.bz2 access_log-20211024.bz2 access_log-20211214.bz2\n", "```\n", "\n", "Реализуйте итератор/генератор, который в качестве параметра будет принимать путь к папке и позволит пробежаться по строкам всех файлов в указанной папке так, будто бы это был один большой файл." ] } ], "metadata": { "celltoolbar": "Tags", "interpreter": { "hash": "cd49b4596bae9c980ff74fdf93e8fe80e447435ae307c062fad6c4f9ef2eb47f" }, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" } }, "nbformat": 4, "nbformat_minor": 2 }