1214 lines
36 KiB
Plaintext
1214 lines
36 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Условные конструкции, циклы, функции"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Проверка условий"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Начнем с известных всем операторов. Проверим, \n",
|
||
"\n",
|
||
"* правда ли, что 8 меньше 9; \n",
|
||
"* правда ли, что 9 больше 10."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"True"
|
||
]
|
||
},
|
||
"execution_count": 1,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"8 < 9 # правда"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 2,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"False"
|
||
]
|
||
},
|
||
"execution_count": 2,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"9 > 10 # неправда"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Результат такой проверки имеет логический тип (*boolean*). "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 3,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"True"
|
||
]
|
||
},
|
||
"execution_count": 3,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"res = 8 < 9\n",
|
||
"res"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Как мы уже обсуждали, переменные такого типа могут принимать два значения True или False. Обратите внимание, что True и False не заключены в кавычки ‒ добавив кавычки, мы получим строки \"True\" и \"False\"."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"При проверке равенства двух частей (переменных, списков и так далее) используется двойной знак \"равно\"."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 5,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"True"
|
||
]
|
||
},
|
||
"execution_count": 5,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"6 == 6"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Одинарный знак \"равно\" используется для присваивания значений. Так ничего не сравним, но сохраним в переменную `a` число 6:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 6,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"6"
|
||
]
|
||
},
|
||
"execution_count": 6,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"a = 6 \n",
|
||
"a "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"А так уже проверим условия:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 7,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"True\n",
|
||
"False\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"print(a == 6) \n",
|
||
"print(a == 9) "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Неравенство, то есть отрицание равенства, в Python обозначается с помощью оператора `!=` (вообще `!` в программировании используется для отрицания). "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 8,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"True"
|
||
]
|
||
},
|
||
"execution_count": 8,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"6 != 7"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Стоит отметить, что Python достаточно лояльно относится к разделению между типам данных. Например, если мы сравним целое число и то же число, но с плавающей точкой (с дробной частью равной 0), Python сообщит, что эти числа совпадают."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 9,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"True"
|
||
]
|
||
},
|
||
"execution_count": 9,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"6 == 6.0 # верно"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Условные конструкции"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Условные конструкции ‒ конструкции с операторами условия. Условная конструкция обычно предполагает \"развилку\": если условие выполняется, то должен выполняться один набор действий, если нет ‒ другой набор действий. Давайте напишем программу, которая будет просить пользователя ввести целое число, и если это число менее 10, на экран будет выводиться сообщение \"Мало\", иначе ‒ \"Много\". И заодно познакомимся с конструкцией *if-else*."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 8,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Введите число: 10\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"x = int(input(\"Введите число: \"))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 9,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Много\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"if x < 10:\n",
|
||
" print(\"Мало\")\n",
|
||
"else:\n",
|
||
" print(\"Много\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"В части с `if` мы прописываем условие, в зависимости от которого Python будет делать выбор, что выводить на экран, а после двоеточия перечисляем действия, которые будут выполняться в случае, если `x` удовлетворяет условию. В части с `else` мы уже не пишем никакого условия ‒ оператор `else` сам по себе означает \"в случае, если условие в выражении с `if` не выполнено\".\n",
|
||
"\n",
|
||
"Часть с `else` является необязательной: программа может существовать только с условием `if`. Тогда в случае невыполнения условия ничего происходить не будет, Python просто перейдет к следующим строкам кода."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Как быть, если условий несколько? Например, мы просим пользователя ввести оценку, и если оценка больше 10, на экране должно быть сообщение \"Много\", если ровно 10 ‒ \"В самый раз\", если меньше ‒ \"Мало\". Можно воспользоваться оператором `elif`, который по смыслу является сочетанием `else + if`: если предыдущее условие невыполнено, то, нужно проверить следующее условие, и если оно тоже не выполнено, то уже перейти к ветке с `else`."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 10,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Введите оценку: 3\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"mark = int(input(\"Введите оценку: \"))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 11,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Мало\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"if mark > 10:\n",
|
||
" print(\"Много\")\n",
|
||
"elif mark == 10:\n",
|
||
" print(\"В самый раз\")\n",
|
||
"else:\n",
|
||
" print(\"Мало\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Ответвлений с `elif` может быть несколько: сколько условий, столько и выражений с `elif`. Добавим еще одно условие:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 12,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Плохо\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"if mark > 10:\n",
|
||
" print(\"Много\")\n",
|
||
"elif mark > 6:\n",
|
||
" print(\"Хорошо\")\n",
|
||
"elif mark > 4:\n",
|
||
" print(\"Неплохо\")\n",
|
||
"else:\n",
|
||
" print(\"Плохо\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Законный вопрос: а можно ли обойтись совсем без `elif`, просто записав несколько выражений с `if`? Тут все зависит от ситуации. Иногда решения использовать `elif` и `if` будут равнозначными. Если мы перепишем код в примере выше, заменив `elif` на `if`, ничего не изменится, так как условия будут проверяться последовательно в любом случае: если оценка больше 10, будет выведено слово \"Много\", если нет ‒ программа перейдет к следующему условию, и так далее. "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 13,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Плохо\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"if mark > 10:\n",
|
||
" print(\"Много\")\n",
|
||
"if mark > 6:\n",
|
||
" print(\"Хорошо\")\n",
|
||
"if mark > 4:\n",
|
||
" print(\"Неплохо\")\n",
|
||
"else:\n",
|
||
" print(\"Плохо\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"В случае, когда условия как-то связаны между собой, нужно быть более внимательными. Рассмотрим такой пример. \n",
|
||
"\n",
|
||
"**Случай 1.** "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 26,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Это нормально\n",
|
||
"Плохо\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"if mark < 10:\n",
|
||
" print(\"Это нормально\")\n",
|
||
"elif mark == 10:\n",
|
||
" print(\"Отлично\")\n",
|
||
"if mark < 6:\n",
|
||
" print(\"Плохо\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Если оценка меньше 10, мы выводим на экран сообщение \"Это нормально\", если нет, то проверяем, равна ли она 10: если да, то выводим \"Отлично\", если нет ‒ ничего не делаем. При этом, *после* всех этих действий делаем дополнительную проверку: если оценка меньше 6, выводим \"Плохо\". "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"**Случай 2.** "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 20,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Это нормально\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"if mark < 10:\n",
|
||
" print(\"Это нормально\")\n",
|
||
"elif mark == 10:\n",
|
||
" print(\"Отлично\")\n",
|
||
"elif mark < 6:\n",
|
||
" print(\"Плохо\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Если оценка меньше 10, мы выводим на экран сообщение \"Это нормально\", если нет, то проверяем, равна ли она 10: если да, то выводим \"Отлично\", если нет ‒ сравниваем ее с 6. Если оценка меньше 6, выводим \"Плохо\". "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Почему во втором случае мы не увидели сообщение \"Плохо\"? Потому что из-за второго `elif` мы попросту до него не дошли! На ветку со вторым `elif` мы попадаем в случае, если предыдущее условие не выполняется, то есть если оценка не равна 10. А на ветку с первым `elif` мы попадем, в случае, если оценка не менее 10. Получается, что мы должны выводить слово \"Плохо\" в случае, когда оценка более 10 и при этом менее 6, чего в природе не бывает. Использовав `elif` необдуманно, мы добавили лишнее условие, которое никогда не будет выполняться! Тут будет полезно вспомнить схемы, которые многие, наверное, видели на уроках информатики в школе. Запоминать их необязательно, просто они хорошо иллюстрируют различия между двумя случаями."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"**Случай 1**\n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"**Случай 2**\n",
|
||
"\n",
|
||
""
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Возможно, предыдущее обсуждение `if` и `elif` могло вас чуть-чуть запутать, но это не повод расстраиваться. Важно просто помнить, что разница между этими операторами есть. Остальное можно проверить экспериментально на конкретном примере :) "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Сложные условия"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Пусть у нас есть три целочисленные переменные `a`, `b` и `c`, и мы планируем составлять сложные, составные уcловия, касающиеся этих переменных."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 13,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"a = 3\n",
|
||
"b = 7\n",
|
||
"c = 1"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Помогут операторы `and` и `or`. Оператор `and` соответствует одновременному выполнению условий, оператор `or` соответствует ситуации, когда хотя бы одно из условий выполняется. Оператор `or` в Python ‒ обычное \"или\", не исключающее: либо верно первое условие, либо второе, либо оба."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 14,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"True"
|
||
]
|
||
},
|
||
"execution_count": 14,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"(a < b) and (b > c) # оба верны"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 15,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"False"
|
||
]
|
||
},
|
||
"execution_count": 15,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"(a < b) and (c > b) # второе неверно -> все неверно"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 16,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"True"
|
||
]
|
||
},
|
||
"execution_count": 16,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"(a < b) or (a > c) # первое верное -> хотя бы одно верно"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 17,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"True"
|
||
]
|
||
},
|
||
"execution_count": 17,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"(a < b) or (c > b) # первое верное -> хотя бы одно верно"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Можем работать с элементами списков:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 18,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"l1 = [1, 3, 6, 8]\n",
|
||
"l2 = [0, 9, 6, 8]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 19,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"True"
|
||
]
|
||
},
|
||
"execution_count": 19,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"l1[0] > l2[0] # 1 больше 0"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 20,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"True"
|
||
]
|
||
},
|
||
"execution_count": 20,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"(l1[0] > l2[0]) and (l1[2] == l2[2]) # оба верны"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 22,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"True"
|
||
]
|
||
},
|
||
"execution_count": 22,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"(l1[0] > l2[0]) or (l1[2] == l2[2]) # оба верны"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Давайте пройдемся по парам элементов в списках `l1` и `l2`, и если значения элементов, которые стоят на одном и том же месте, просто в разных списках, совпадают, мы будем выводить сообщение \"It's true! They are equal!\", а если нет ‒ сообщение \"It's false! They are not equal!\".\n",
|
||
"\n",
|
||
"Сначала посмотрим на длину списков:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 23,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"4\n",
|
||
"4\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"print(len(l1))\n",
|
||
"print(len(l2))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Списки одинаковой длины, это хорошо! Напишем цикл."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 24,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"It's false! They are not equal!\n",
|
||
"It's false! They are not equal!\n",
|
||
"It's true! They are equal!\n",
|
||
"It's true! They are equal!\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"for i in range(0, len(l1)):\n",
|
||
" if l1[i] == l2[i]:\n",
|
||
" print(\"It's true! They are equal!\")\n",
|
||
" else:\n",
|
||
" print(\"It's false! They are not equal!\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"А теперь предлагаю вам такую задачу. Есть список оценок `marks`, и для каждой оценки нужно вывести комментарий (Отлично, Хорошо, Удовлетворительно, Плохо) с новой строки. "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 26,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"marks = [2, 7, 8, 10, 5, 8, 1, 6]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"**Решение:**"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 27,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Плохо!\n",
|
||
"Хорошо!\n",
|
||
"Отлично!\n",
|
||
"Отлично!\n",
|
||
"Удовлетворительно!\n",
|
||
"Отлично!\n",
|
||
"Плохо!\n",
|
||
"Хорошо!\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"for mark in marks:\n",
|
||
" if mark >= 8:\n",
|
||
" print(\"Отлично!\")\n",
|
||
" elif (mark >= 6) and (mark < 8):\n",
|
||
" print(\"Хорошо!\")\n",
|
||
" elif (mark >= 4) and (mark < 6):\n",
|
||
" print(\"Удовлетворительно!\")\n",
|
||
" else:\n",
|
||
" print(\"Плохо!\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Можно написать аналогичный код, но оценку теперь будет вводить пользователь с клавиатуры. "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 28,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Введите оценку: 6\n",
|
||
"Хорошо!\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"mark = int(input(\"Введите оценку: \"))\n",
|
||
"if mark >= 8:\n",
|
||
" print(\"Отлично!\")\n",
|
||
"elif (mark >= 6) and (mark < 8):\n",
|
||
" print(\"Хорошо!\")\n",
|
||
"elif (mark >= 4) and (mark < 6):\n",
|
||
" print(\"Удовлетворительно!\")\n",
|
||
"else:\n",
|
||
" print(\"Плохо!\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Цикл `while`"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"С циклом `for` мы уже знакомы. Сейчас мы познакомимся с циклом `while`, логика которого отличается от `for`. Конструкции с циклом `while` устроены следующим образом: действия, которые указаны в теле цикла, должны выполняться до тех пор, пока верно условие, прописанное после `while` (отсюда и название). Если в цикле `for` мы указывали некоторый промежуток, по которому в ходе цикла мы будем \"пробегаться\", то в случае с циклом `while` мы просто фиксируем стартовую точку, а конечную точку никак не указываем: программа сама остановится, когда условие в цикле перестанет выполняться."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 50,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"nums = [1, 0, 9, 10, -1, 8]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Давайте, используя цикл `while`, будем выводить на экран элементы списка `nums` до тех пор, пока не столкнемся с отрицательным значением."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 51,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"1\n",
|
||
"0\n",
|
||
"9\n",
|
||
"10\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"i = 0 # начинаем с индекса i=0\n",
|
||
"\n",
|
||
"while nums[i] >= 0: # пока элемент nums[i] >= 0\n",
|
||
" print(nums[i]) # выводим элемент на экран\n",
|
||
" i = i + 1 # переходим к следующему элементу"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"На значении 10 мы остановились: за ним идет значение -1, для которого условие `nums[i] > = 0` не выполняется. \n",
|
||
"\n",
|
||
"Давайте теперь попробуем переписать код так, чтобы он работал точно так же, но только чтобы в нем использовался цикл `for`, а не `while`. Вообще почти любой код с `while` можно переписать через `for`, и иногда это полезно: код с циклом `while` обычно более медленный, плюс, склонен к зацикливанию."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 72,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"1\n",
|
||
"0\n",
|
||
"9\n",
|
||
"10\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"for n in nums:\n",
|
||
" if n >= 0:\n",
|
||
" print(n)\n",
|
||
" else:\n",
|
||
" break # выходим из цикла"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"В коде выше мы использовали оператор `break`, который позволяет выйти из цикла, то есть закончить исполнение строк кода в теле цикла и перейти к коду дальше. "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"### Функции"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Чтобы выполнять аналогичные действия много раз, помимо циклов используются функции. Со встроеными в Python функциями мы уже сталкивались: например, функция `round()` принимала на вход некоторое число и округляла его до целого. При этом, если мы дописывали внутри `round()` еще один аргумент (параметр) – число, отвечающее за количество знаков после запятой, то число округлялось соответствующим образом. Итак, мы приходим к следующему: у функции есть три основных части: *аргументы* (то, что подается на вход, те объекты, над которыми мы хотим произвести какие-то действия), *тело функции* (набор предполагаемых действий) и *результат* (то, что функция возвращает на выходе, измененные объекты, которые были поданы на вход или созданные на их основе новые). \n",
|
||
"\n",
|
||
"Для иллюстрации напишем функцию `my_square()`, которая будет возводить число в квадрат. Начнем с задания функции – строки, которая называется сигнатурой:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
" def my_square(x):"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"`def` здесь – специальное слово, которое декларирует начало функции. После него следует название функции, а далее – аргумент, тот объект, с которым функция будет работать."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"По-хорошему у любой функции должна быть документация с пояснениями, что это функция принимает на вход и что возвращает. Такое описание вносится в специальную строку *docstring*, которая добавляется сразу после сигнатуры:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def my_square(x):\n",
|
||
" \"\"\"\n",
|
||
" Returns a square of a number.\n",
|
||
" Parameters: x is an integer or a float.\n",
|
||
" \"\"\""
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Теперь опишем, что эта функция должна делать – какие действия выполнять:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 2,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def my_square(x):\n",
|
||
" \"\"\"\n",
|
||
" Returns a square of a number.\n",
|
||
" Parameters: x is an integer or a float.\n",
|
||
" \"\"\"\n",
|
||
" res = x ** 2\n",
|
||
" return res"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Последняя строка с `return` означает, что наша функция должна возращать некоторый результат – число, возведенное в квадрат. Применим функцию:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 3,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"49"
|
||
]
|
||
},
|
||
"execution_count": 3,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"my_square(7)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Все работает! Осталось только подумать вот над чем: что будет, если убрать строку с `return` и заменить ее, скажем, на `print()`? Попробуем применить и сравним результаты. "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 4,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"49"
|
||
]
|
||
},
|
||
"execution_count": 4,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"a = my_square(7) # c return\n",
|
||
"a "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 5,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def my_square2(x):\n",
|
||
" res = x ** 2\n",
|
||
" print(res)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 6,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"49\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"my_square2(7)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Кажется, что пока никакой разницы нет: в обоих случаях на экран выведено число 49. Теперь попробуем сохранить полученный выше результат в переменную `b`:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 8,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"49\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"b = my_square2(7)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 9,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"b"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"При вызове переменной `b` на экран ничего не выводится! Если мы выведем `b` на экран, это также ни к чему не приведет:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 10,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"None\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"print(b)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Результат `None` – пустота! Переменная `b` пуста. Почему это произошло? А потому, что функция `my_square2()` не сохраняет результат, только выводит его на экран! Тут можно привести такую «школьную» аналогию. Если преподаватель читает лекцию, а студент ее никаким образом не фиксирует, это ситуация соответствует случаю с `print()` и без `return()`. Преподаватель честно читает лекцию («выводит ее на экран»), но результат этих действий никак не сохраняется. Если студент что-то забудет, ему некуда будет обратиться – он не сможет залезть в несуществующий конспект или аудиозапись («посмотреть на значение переменной»). Функции, которые ничего не возвращают, могут быть полезны, но чаще всего мы сталкиваемся с необходимостью возвращать какие-либо объекты явно, и поэтому за устройством функции нужно внимательно следить. При этом, если хочется, чтобы результат выполнения функции и сохранялся, и выводился на экран, можно использовать `print()` и `return()` одновременно:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 11,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"def my_square(x):\n",
|
||
" \"\"\"\n",
|
||
" Returns a square of a number.\n",
|
||
" Parameters: x is an integer or a float.\n",
|
||
" \"\"\"\n",
|
||
" res = x ** 2\n",
|
||
" print(res)\n",
|
||
" return res"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 12,
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"100\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"y = my_square(10)"
|
||
]
|
||
}
|
||
],
|
||
"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.5"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 2
|
||
}
|