[МУЗЫКА] [МУЗЫКА] Посмотрим еще несколько примеров функций, которые откроют нам новые возможности. Например, функция выбора максимума из двух чисел. Достаточно простая функция принимает два параметра, назовем ее max2, чтобы было понятно, что эта функция ровно для двух параметров. Допустим, у нас есть два числа a и b, и нам нужно, в зависимости от того, какое из чисел больше, вернуть одно из них. Если a больше b, то возвращаем a. А иначе возвращаем b. Ну и давайте поставим маленький эксперимент, вызовем эту функцию для каких-нибудь трех случаев, как мы тестируем тщательно, когда первое число меньше, когда второе число меньше и когда они равны, чтобы уже наверняка убедиться, что все хорошо, что всегда функция у нас работает. Ну и мы, понятно, что ожидаем увидеть. Запустим эту программу, и действительно, она нашла максимумы для каждой из этих пар чисел. Посмотрим внимательно теперь на код функций. У нас теперь содержится впервые несколько return-ов, то есть несколько мест, где функция возвращает в значение и прекращает свою работу. Поскольку она прекращает работу, то мы могли бы убрать этот else, он здесь необязателен. Почему? Потому что если у нас a было больше b, то есть выполнилось условие, то уже произойдет return, то есть вернется значение и дальше функция просто выключится. Это в некотором смысле похоже на break в цикле. То, что написано после него, выполняться не будет. Посмотрим, что ничего не сломалось. Да, действительно, все ok. То есть у нас функции, как только выполнился return, дальнейшее выполнение прекращается. Ну и поэтому можно в данном случае не писать else, хотя с else она выглядит логичнее в общем-то. Но тем не менее, в некоторых ситуациях, действительно у функции может быть несколько return-ов, и в самом конце, если ни один из случаев не сработал, возвращается какое-то конкретное значение. Иногда, кстати, функции используют для нескольких вложенных циклов, и допустим, в какой-то момент вам захотелось, с помощью break, выйти из нескольких циклов. Просто так на Python вы этого не сделаете, нет такой конструкции. Вам придется городить какой-то огород, писать: if, делать какую-то логическую переменную — признак того, что нужно выходить из цикла. Но иногда что делают? Оборачивают эти несколько циклов в функцию, и как только вам нужно выйти из вложенного цикла, делают просто return из этой функции. Ну и это замечательным образом выходит из всех вложенных циклов. Вот такое довольно нестандартное применение, но тоже случается. Теперь посмотрим, а как мы можем использовать эту функцию max2. Опять же, как в прошлый раз, мы можем вызывать функцию из функции. Например, мы хотим посчитать максимум теперь из трех чисел. Для этого достаточно написать: return max2 — уже готовая функция, из max2 от двух параметров, то есть у нас выберется максимум из чисел a и b, и числа c — третьего оставшегося числа. Ну и давайте на одном каком-нибудь примере проверим, выбрать максимум теперь из трех чисел. Да, ну еще раз убедились в том, что из одной нашей функции можно вызывать другую нашу функцию, а также, что в качестве параметра функции, которая туда передается, может выступать не только какая-то переменная, не только какое-то арифметическое значение, но и результат подсчета нашей функции. В принципе, они ничем не отличаются, но на всякий случай убедились, что так оно и есть. Посмотрим теперь на более хитрый пример, а именно, как возвращать несколько значений из функции. Вообще говоря, такое иногда случается, что из функции нужно вернуть не одно какое-то число или строку, или какой-то объект произвольный, а набор таких объектов. Вообще говоря, для этого используются кортежи. Подробнее мы будем изучать на следующем занятии, а пока что очень частный случай, как вернуть несколько значений с помощью кортежа, про который мы ничего не знаем. Посмотрим на примере задачи о сортировке двух чисел. То есть упорядочить два числа, так чтобы сначала шло меньшее, а затем большее, ну или, если они равны, то шли как угодно. Назовем эту функцию sort2 — посортировать два числа a и b. Если a меньше чем b, то сначала нужно, чтобы возвращалось число a, а затем, чтобы число b. Тогда мы просто пишем через запятую: return a, b. Ну и как мы уже только что смотрели в случае максимума, мы можем не писать else, а писать отдельный return. До него дойдет только, если условие было неверно и возвращать числа в другом порядке. Как теперь ловить значения этой функции? Мы можем сделать две переменные, например минимум и максимум, записать их через запятую и написать: = sort2, ну и от каких-нибудь чисел, например, 5 и 4. И давайте напечатаем эти минимумы и максимумы. Запускаем, смотрим — все работает. То есть пока что очень частный случай без глубокого понимания, что такое кортеж, без знания вообще слова кортеж. Просто, если вы хотите возвращать несколько значений, вы перечисляете их через запятую. Когда вы принимаете эти значения в программе, как у нас минимум и максимум, вы опять же перечисляете их через запятую, равно и функция со своими параметрами. И наконец, еще одно применение функции — это функции, возвращающие логическое значение. В принципе, логические значения мы уже научились раскладывать по переменным с говорящими именами, но иногда, если очень часто проверяется какое-то достаточно сложное логическое выражение, удобно обернуть его в функцию и пользоваться ее названием, говорящим вместо какой-то горы каких-то непонятных вычислений. Посмотрим простой пример: проверить, является ли число четным. Функции проверки логично называть, начиная со слова is — является ли, есть ли число четным. isEven — четное ли число? И некоторые параметры — собственно наше число, которое нужно проверить. Вот здесь достаточно написать return и результат вычисления логического выражения. Когда число четное? Когда остаток от деления на два равен 0. Кстати, возвращаясь к остаткам от деления. Если бы вы писали функцию: является ли число нечетным, то вам нужно было бы писать, что остаток от деления на два не равен 0, потому что он может быть 1, а может быть, в принципе, и −1. Ну конечно, для двойки он быть не может такой, но если в какой-то момент вы хотите написать универсальную функцию проверки делимости одного числа на другое, то нужно не забывать, что второе число может быть отрицательным, и проверять конечно же нужно на равенство/ неравенство 0. Никаких конкретных значений, кроме 0 лучше не использовать, потому что может оказаться, что число отрицательное. Но для двойки они всегда будут положительные, потому что двойка сама положительная. Так что, в принципе, можно было написать: равно 1 или не равно 0. Но лучше писать: не равно 0 на всякий случай. Итак, как теперь использовать это? Например, мы хотим считать число, которое вводит нам пользователь. Обратите внимание на названия переменных. Подробнее мы об этом поговорим чуть позже, но пока что вы можете заметить, что если вы будете называть переменные одинаково, то есть, здесь в основной программе у нас переменная называется n и в функции переменная тоже называется n. Это две разные переменные, ничего страшного. В принципе, могло называться как угодно. Итак, если у нас введенное число четное, то напечатаем, например, слово, что оно четное. И иначе — напечатаем, что оно нечетное. Посмотрим. Запустили, вводим число, ну вот четное число действительно четное, а нечетное число действительно нечетное. На что здесь нужно обратить внимание? Я в if написал просто название функции с параметром. Почему? Потому что она уже возвращает значение «истина» или «ложь». Собственно то, что нам нужно в if. Если вы будете писать вот так — сравнивать возвращенное значение с true, будет легко понять, что вы, например, школьник. В некоторых школах, к сожалению, так учат, не объясняют, почему это плохо. Ну вот здесь нам даже JetBrains, наша среда PyCharm подчеркнула это, наверное хочет на нас поругаться. Можно взять и почитать. Вот она прямо говорит: не делайте так. Почему? Ну потому что это бессмысленно. Вы сравниваете возвращенное значение «истина» или «ложь» с «истиной». Очевидно, что это выражение будет истинно, только если вам была возвращена функция «истина», а если была «ложь», то выражение будет ложным. То есть так писать не нужно. Если, например, пойдете на собеседование и там напишете такой код, возможно, над вами будут смеяться, ну и урежут вашу потенциальную зарплату. Так что, если у вас есть логическое выражение, то не надо сравнивать результат вычисления этого логического выражения с истиной. Никогда. Особенно это заметно на функциях. Ну хотя работать оно будет, но это лишние и достаточно глупые действия. Теперь мы знаем, как писать правильно, и дальше перейдем к достаточно сложной теме в понимании — рекурсии. Сначала у нас будет некоторое теоретическое объяснение, как оно работает, что это такое вообще и как оно устроено внутри. А потом вернемся к практике и посмотрим, как отлаживать рекурсивные функции. [МУЗЫКА] [МУЗЫКА]