[МУЗЫКА] [МУЗЫКА] Перейдем к практическому использованию функций и начнем с реализации функции подсчета факториала. Как считать факториал, мы уже более-менее представляем и просто запишем это в виде отдельной функции. Итак, def (define — определить), название функции и в скобочках параметры, которые она будет получать. Что нам нужно сделать? Нам нужно перемножить все числа до переданного параметра n. n мы можем считать переменной, у которой уже есть в данный момент какое-то значение. Заведем переменную для хранения результата, вначале она равна единице. И пока n > 1, в принципе, мы могли и ноль написать, тогда бы мы просто умножали на единицу, мы будем результат умножать (сокращенная запись — умножить, равно) на очередное число n. И затем return — вернуть значение, собственно, наш подсчитанный результат. Проверим, напечатаем факториал какого-нибудь небольшого числа, посмотрим, все ли у нас работает правильно. Например, факториал числа 5. Запускаем. У нас ушло в вечный цикл. Почему? Потому что я забыл уменьшать n на каждом шаге. Но ничего страшного. Останавливаем программу, останавливаем все программы, которые у нас запущены, если их вдруг несколько, вот можно сделать это проще. Вот она, наша программа. Итак, ничего страшного не происходит, как видите, все если вдруг зациклилось навечно, все исправимо, все выключается. Да, теперь стало работать. Факториал 5 — это 120. 2 * 3 = 6, 6 * 4 = 24, 24 * 5 = 120. Как раз все получилось правильно. То есть теперь мы можем каждый раз, когда нам понадобится факториал, не писать заново этот цикл, в котором, как видно, легко ошибиться, а просто вызывать эту функцию. В комбинаторике существует такое понятие, как биномиальный коэффициент C_n^k, треугольник Паскаля, может быть, что-то из этого вы слышали. Его суть заключается в том, что необходимо посчитать, сколькими способами можно выбрать k элементов из n-элементного множества. Мы не будем углубляться в комбинаторику, а просто научимся это считать, как C_n^k. Назовем функцию c из n по k, или можно было ей дать какое-нибудь другое название. Эта функция будет принимать уже два параметра: собственно n и k. Сколько элементов всего и сколько из них нужно выбрать? Мы знаем функцию, математическую формулу, которая говорит нам о том, что c из n по k равно факториал числа n, деленный на произведение факториалов, то есть в числителе дроби факториал n, а в знаменателе произведение факториала из k * (n − k). Теперь мы это описали один раз в виде функции и каждый раз опять же можем не писать заново вот такое длинное выражение, а просто писать cnk, и сколько у нас всего чисел, и подмножество какого размера мы хотим перебрать, посчитать, сколько их. Например, нам интересно, сколько двухэлементных подмножеств в четырехэлементном множестве — c из n по k с параметрами 4 и 2. Вот выяснилось, что их шесть. Наверное, это правда. То есть в принципе, как вы видите, мы вызвали одну свою функцию из другой своей функции, и абсолютно ничего страшного не произошло. Немного подробнее об отладке. Мы уже научились отлаживать функции по шагам, но здесь у нас есть некоторые особенности. Давайте посмотрим. Во-первых, чтобы отлаживать программу, если у нас где-то есть ошибка, нужно запускать ее в режиме debug. Не просто run, а debug — отладочный запуск. Выбираем, что именно мы хотим запустить, и вот оно, наше выражение. Получился результат 6, то есть на debugger она отработала, но допустим, мы хотим посмотреть, как этот процесс происходит. Ставим breakpoint на интересное место — просто нажимаем мышкой рядом с номером строки. Теперь при выполнении программы вот ровно на этой строке у нас выполнение и остановится. Давайте нажмем debug, со временем можно запомнить, как он вызывается, здесь подписаны кнопки, какие нужно нажимать. И вот у нас выполнение остановилось на этой строке, и открылась вкладка debugger вместо консоли ввода и вывода. Во вкладке debugger у нас отображаются все переменные с их текущими значениями. Чтобы делать шаги в программе, теперь у нас есть несколько способов, которые теперь, кстати, будут отличаться. Как вы видите, здесь есть достаточно много разных step (step — совершить один шаг выполнения программы). Есть step into, step into my code и step out. Чем они отличаются? Step into входит в функции, которые вызываются в этой строке. Step out, или иногда в некоторых называется step over, в других средах программирования, это не входя в функцию. Просто сразу функция берется и выполняется. Если вы уверены, что ваша функция работает правильно, можете пользоваться step over, который просто перейдет через эту функцию, подставив ее значение, не заходя внутрь. Если же вы хотите посмотреть, что у вас происходит внутри функции, пользуйтесь step into my code лучше. Почему? Потому что просто step into будет проваливаться в стандартные функции и тоже выполнять их по шагам. В стандартных функциях вы можете быть уверены, что все работает правильно, но может быть единственная проблема, что вы какие-то не те данные им сунули, и тогда это поможет вам разобраться. Вообще говоря, нажимая просто step into, вы можете попасть куда-то не совсем туда, куда вы ожидали. Например, если у вас есть чтение данных или print, то вы провалитесь в стандартную функцию. Сейчас у нас там, где мы находимся, никаких вызовов функции нет, и поэтому абсолютно все равно, мы будем пользоваться step into или step over. Давайте попробуем step over. Смотрите, что происходит. У нас, во-первых, когда мы сделали один шаг, появилась новая переменная Variables. Вот ее текущее значение. И здесь же напечатался нам результат ее вычисления, просто это не текст, вы не можете его взять и поменять. Это просто такие вам подсказки. Продолжаем выполнять по шагам программу, опять же, сейчас без разницы, как она выполняется: step into или step over. И смотрим, как меняются значения. Итак, на первом шаге у нас result стал равен четырем. Мы перемножаем числа от большего к меньшему, просто потому, что так написали код. От порядка выполнения умножения ничего не зависит. И текущие значения n также меняются. В общем-то, всё как пока что в обычной отладке. Как только мы доходим до строки с return, выполнение сейчас у нас провалится в то место, откуда была вызвана функция. То есть мы сейчас посчитали факториал от 4. Если мы сейчас сделаем step over, перешагнем, то мы не попадем внутрь этого экземпляра функции factorial и этого экземпляра функции factorial, а просто выйдем в нашу основную программу, где вызывается функция c из n по k. Вот я делаю step over, давайте я нажму в меню, чтобы было видно. Мы не попали туда, потому что у нас breakpoint стоит. На breakpoint она останавливается в любом случае. Вот теперь мы сняли breakpoint, посмотрим, что мы умеем делать. Вот у нас есть step out, step out выходит из функции. И делаем, наконец, step over уже без всяких breakpoint, и просто у нас выполняется эта строка. Давайте еще совсем немножко посмотрим, как делается отладка именно со входом или без входа в функцию. Сейчас этот отладочный процесс у нас завершился. breakpoint мы поставили на интересные наши функции и запускаем debug. Вот он остановился на нашей функции: n = 4, k = 2. Если мы сейчас будем делать step into, то мы три раза попадем в функцию factorial, она три раза вызывается в одной и той же строке. Если же мы сделаем step over, то мы просто вывалимся, выполним эту строку за одно действие. Давайте посмотрим step into, убедимся, что мы попадаем в функцию, это F7 кнопка. Да, вот мы попали в нашу функцию. Да, ровно то, что мы ожидали. Если мы еще раз сделаем step into, то мы попадем в другой экземпляр функции, в следующий, какой следующий по порядку вычисляется, уже с параметром 2. Вот он. И здесь нам написала, что n = 2. И вот третий тоже выполнился. Когда нужно использовать step into, когда нужно использовать step over? step into — если вы хотите попасть внутрь функции, посмотреть, как она работает; step over — если вы уверены, что функция работает, и никуда не хотите проваливаться, а просто выполнить эту одну строку и перейти к следующей строке. И наконец, еще раз напоминаю, что если вы проваливаетесь в какой-то не в ваш код, а например, в код стандартной библиотеки и каких-нибудь библиотек, которые вы используете, используете step into my code, то есть только в моем коде входить внутрь моих функций и не входить в не мои функции, в какие-то подключенные или в стандартные. Эти три способа позволят вам эффективно отлаживать программы, содержащие в себе функции, заходить или не заходить в них по вашему желанию. [МУЗЫКА] [МУЗЫКА]