{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Основы программирования в Python\n", "\n", "*Алла Тамбовцева, НИУ ВШЭ*\n", "\n", "## Семинар 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Задача 0 (разминка)\n", "\n", "Даны два списка `a` и `b` (см. ниже).\n", " \n", "1. Выведите на экран первый элемент списка `a`, третий элемент списка `a`, последний элемент списка `a`.\n", "2. Добавьте в список `b` элемент 7 (просто допишите в конец).\n", "3. Замените пятый элемент списка `a` на число 8.\n", "4. Создайте список `merged`, который включает в себя все элементы списка `a` и списка `b`.\n", "5. Создайте новый список `с`, который получается заменой последнего элемента списка `a` на число 100. Сам список `a` измениться не должен!" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "a = [1, 0, 9, 12, 18, 34, 89, 91, 33, 127]\n", "b = [2, 8, 9, 11, 76, 25, 44]" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1 9 127\n" ] } ], "source": [ "# 1\n", "print(a[0], a[2], a[-1])" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[2, 8, 9, 11, 76, 25, 44, 7]" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 2\n", "b.append(7)\n", "b" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 0, 9, 12, 8, 34, 89, 91, 33, 127]" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 3\n", "a[4] = 8\n", "a" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 0, 9, 12, 8, 34, 89, 91, 33, 127, 2, 8, 9, 11, 76, 25, 44, 7]" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 4\n", "merged = a + b\n", "merged" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 0, 9, 12, 8, 34, 89, 91, 33, 127] [1, 0, 9, 12, 8, 34, 89, 91, 33, 100]\n" ] } ], "source": [ "# 5\n", "c = a.copy()\n", "c[-1] = 100\n", "print(a, c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "*Примечание:* написать `c = a` вместо `a.copy()` нельзя, так как этот код создаст ссылку `c` на старый список `a`, а не новый список `c`, поэтому при изменении списка `c` список `a` также изменится." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Задача 1 (девочковая)\n", "\n", "Есть список имен:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "girls = [\"Иветта\", \"Виолетта\", \"Кассандра\", \"Вирджиния\", \"Амелия\", \"Розамунда\", \"Янина\", \"Беатриса\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Используя список `girls`, выведите на экран следующие списки:\n", "\n", " [\"Виолетта\", \"Кассандра\", \"Вирджиния\", \"Амелия\"]\n", " [\"Вирджиния\", \"Амелия\", \"Розамунда\", \"Янина\", \"Беатриса\"]\n", " [\"Иветта\", \"Виолетта\", \"Вирджиния\", \"Амелия\"]\n", " [\"Кассандра\", \"Амелия\", \"Розамунда\"]" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['Виолетта', 'Кассандра', 'Вирджиния', 'Амелия']\n", "['Вирджиния', 'Амелия', 'Розамунда', 'Янина', 'Беатриса']\n", "['Иветта', 'Виолетта', 'Вирджиния', 'Амелия']\n", "['Кассандра', 'Амелия', 'Розамунда']\n" ] } ], "source": [ "print(girls[1:5]) # 1\n", "print(girls[3:]) # 2\n", "print(girls[0:2] + girls[3:5]) # 3\n", "print(girls[2:3] + girls[4:6]) # 4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "В последнем пункте главное не вызвать имя Кассандра отдельно, без среза, так как в таком случае мы будем складывать строку и список, что даст ошибку:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "must be str, not list", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mgirls\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mgirls\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m4\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;36m6\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: must be str, not list" ] } ], "source": [ "print(girls[2] + girls[4:6])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Эту ошибку можно исправить, добавив квадратные скобки вокруг Кассандры, создав список из одного элемента (хотя, конечно, решение со срезами более элегантное):" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['Кассандра', 'Амелия', 'Розамунда']\n" ] } ], "source": [ "print([girls[2]] + girls[4:6])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Задача 2 (поэлементная) \n", "\n", "Дан список `L`. Выведите на экран (последовательно, с новой строчки): \n", "\n", "* все элементы списка `L`;\n", "* логарифмированные значения элементов списка `L`." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "L = [12, 3, 8, 125, 10, 98, 54, 199]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Замените пятый элемент списка `L` на 0. Проделайте те же операции, что и раньше. Объясните, почему получаются такие результаты." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "12\n", "3\n", "8\n", "125\n", "10\n", "98\n", "54\n", "199\n" ] } ], "source": [ "# до добавления 0 - все элементы\n", "for i in L:\n", " print(i)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2.4849066497880004\n", "1.0986122886681098\n", "2.0794415416798357\n", "4.8283137373023015\n", "2.302585092994046\n", "4.584967478670572\n", "3.9889840465642745\n", "5.293304824724492\n" ] } ], "source": [ "# до добавления 0 - натуральные логарифмы всех элементов\n", "import math\n", "for j in L:\n", " print(math.log(j))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Примечание: импортировать модули или библиотеки нужно вне циклов, так как их достаточно импортировать один раз. Многократный импорт библиотеки в цикле не вызовет ошибку, но замедлит исполнение кода (на таком простом примере мы это не заметим, но это так)." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2.4849066497880004\n", "1.0986122886681098\n", "2.0794415416798357\n", "4.8283137373023015\n" ] }, { "ename": "ValueError", "evalue": "math domain error", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mj\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mL\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlog\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mj\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mValueError\u001b[0m: math domain error" ] } ], "source": [ "# после добавления 0 – натуральные логарифмы всех элементов\n", "L[4] = 0\n", "L\n", "\n", "for j in L:\n", " print(math.log(j))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "На пятом элементе все сломалось, исполнение кода остановилось, Python вышел из цикла. Значит, проблема с нулем. Это объяснимо, логарифм не определен для неположительных чисел. Python выдает ошибку значения `ValueError` и пишет про *domain*, что по-английски область определения функции, то есть множество значений, которые может принимать аргумент функции." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Задача 3 (демографическая)\n", "\n", "В списке `age` сохранены значения возраста респондентов: \n", "\n", " age = [24, 35, 42, 27, 45, 48, 33]\n", " \n", "Создайте список `age2`, в котором будут храниться значения возраста, возведенные в квадрат.\n", "\n", "**Подсказка:** используйте цикл `for`." ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[576, 1225, 1764, 729, 2025, 2304, 1089]" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "age = [24, 35, 42, 27, 45, 48, 33]\n", "age2 = []\n", "for a in age:\n", " age2.append(a ** 2)\n", "age2" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[576, 1225, 1764, 729, 2025, 2304, 1089]" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# то же, но со списковыми включениями\n", "age2 = [a**2 for a in age]\n", "age2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Задача 4 (игровая)\n", "\n", "Питон просит пользователя загадать (ввести с клавиатуры) целое число $k$ от 1 до 10. Питон берет это число $k$ и выводит на экран $k$-тый элемент списка `numbers`, причем $k$-ый элемент в привычном понимании, в нумерации, которая начинается с единицы. \n", "\n", "Список `numbers`:" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "numbers = [1, 5, 6, 8, 10, 21, 25, 1, 0, -9, 9]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Пояснение:**\n", " \n", "*Входные данные:*\n", "\n", " Введите целое число от 1 до 10: 3\n", " \n", "*Выходные данные:*\n", "\n", " 6" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Enter a number: 6\n", "21\n" ] } ], "source": [ "k = int(input(\"Enter a number: \"))\n", "print(numbers[k-1])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Задача 5 (мыслительная)\n", "\n", "Объясните, что делает следующий код и почему он выдает такие результаты:" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5\n", "3\n", "5\n", "7\n" ] } ], "source": [ "l = [1,2,3,4]\n", "\n", "for i in range(len(l)):\n", " a = l[i] + l[i-1]\n", " print(a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Разберем код на части. Что такое `range(len(l))`?" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 1, 2, 3]" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list(range(len(l))) # индексы элементов списка l" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Значит, цикл `for` бегает по индексам списка `l`. Тогда `l[i]` ‒ это i-тый элемент списка `l`, а `l[i-1]` ‒ элемент, предшествующий i-тому элементу. Эти два элемента складываются, и результат сохраняется в `a`.\n", "\n", "Посмотрим. Если `i = 0`, то получаем `l[0]` и `l[-1]`. Значит, на первом шаге (на первой итерации) цикла мы складываем первый и последний элементы списка.\n", "\n", " 1 + 4 = 5\n", "\n", "Двигаемся дальше. Если `i = 1`, то получаем `l[1]` и `l[0]`. Значит, на втором шаге цикла мы складываем второй и первый элементы списка.\n", "\n", " 2 + 1 = 3\n", "\n", "И так далее.\n", "\n", "Почему этот код интересен? Потому, что он не ломается: Python не возражает против отрицательных индексов элементов, он просто начинает считать элементы с конца списка." ] } ], "metadata": { "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.6.8" } }, "nbformat": 4, "nbformat_minor": 2 }