Сборник. Сборник упражнений
Скачать 1.68 Mb.
|
Глава 4 Функции С ростом программ, которые мы пишем, возрастает необходимость в их максимальном упрощении и облегчении их поддержки и сопровождения. Одним из способов добиться этого является дробление программ на от- дельные блоки, именуемые функциями (function). Функции в программах служат сразу нескольким целям. Они позволяют написать код лишь раз и впоследствии обращаться к нему из разных мест. Кроме того, с их помощью можно легко тестировать различные решения. Также функции помогают скрыть (или, по крайней мере, отложить в сто- рону) детали реализации программного кода после окончания разработки части программного комплекса. С помощью функций программист имеет возможность написать необходимое количество строк кода, запрятать их в единый блок, именуемый функцией, и отложить для использования в будущем. К этому коду в дальнейшем можно будет обращаться из дру- гих блоков и программ. При этом сам блок функции со всеми входящи- ми в него инструкциями именуется определением (defining), а обращение к нему извне – вызовом (calling) функции. После вызова и выполнения функции управление возвращается в основную программу, и она про- должается с первой после вызова функции инструкции. Программы, которые вы писали до этого, изобиловали вызовами функ- ций вроде print, input, int и float. Все эти функции были заранее написаны разработчиками языка Python и могут быть вызваны в любой програм- ме на этом языке. В данной главе вы научитесь объявлять и вызывать собственные функции в дополнение к уже написанным и помещенным в стандартные библиотеки Python. Определение функции начинается с ключевого слова def, следом за которым идет имя функции, открывающая и закрывающая скобки и знак двоеточия. Далее следует набор инструкций с отступами (как в случае с циклами и условными выражениями), которые и составляют тело функ- ции. Функция завершается тогда, когда отступы в строках восстанавли- ваются до уровня, на котором стоит определение функции с ключевым словом def. Например, в следующем программном коде представлена функция, рисующая прямоугольник из звездочек. 72 Упражнения def drawBox(): print("**********") print("* *") print("* *") print("**********") Сами по себе эти строки кода, появившись в программе, не ведут к ри- сованию прямоугольника из звездочек на экране, поскольку мы не вызы- вали функцию, а только объявили ее. Объявление функции откладывает на будущее заключенные в ней строки кода, ассоциируя их с выбранным именем функции – в нашем случае это drawBox, – но не выполняет их не- медленно. Программа на языке Python, состоящая исключительно из объ- явлений функций, имеет право на существование, но при запуске не будет генерировать никакого выхода. Функцию drawBox можно вызвать в программе, обратившись к ней по име- ни со скобками. Добавление следующей строки к коду (без отступов) позво- лит осуществить вызов функции drawBox и вывести на экран прямоугольник. drawBox() Если следом вставить еще одну такую строку кода, на экран будет выве- дено два прямоугольника, а если три, то три. Функции могут быть вызваны в программе столько раз, сколько необходимо для решения той или иной задачи, и из самых разных мест. При каждом очередном вызове функции выполняется ее тело. По окончании выполнения функции программа про- должается с инструкции, следующей за строкой вызова функции. 4.1. ф ункции с параметрами Функция drawBox работает отменно. При вызове она исправно выводит на экран прямоугольник, что от нее и требуется. Но вы не находите, что наша функция обладает недостаточной гибкостью, а значит, и пользы от нее не так много? Было бы интереснее, если бы у нас была возможность выводить на экран прямоугольники разной формы. Для большей гибкости функции могут принимать аргументы (argument) посредством передачи им значений в круглых скобках. На входе в функ- цию значениями этих аргументов инициализируются переменные пара- метров (parameter variables), прописанные в круглых скобках при объ- явлении функции. Количество параметров, прописанное при объявлении функции, определяет число аргументов, которые должны быть переданы при вызове функции. Нашу функцию drawBox можно сделать куда более полезной, если снаб- дить ее двумя входными параметрами. Пусть это будут ширина и высота Функции 73 прямоугольника соответственно. В теле функции переменные, переданные в качестве параметров, будут использованы для определения характерис- тик выводимого на экран прямоугольника, как показано ниже. Выражение if и функцию quit мы используем для немедленного выхода из функции, если ей переданы неправильные значения в качестве пара метров. ## Рисуем прямоугольник из звездочек, заполненный пробелами # @param width – ширина прямоугольника # @param height – высота прямоугольника def drawBox(width, height): # Слишком маленькие прямоугольники не могут быть нарисованы при помощи этой функции if width < 2 or height < 2: print("Ошибка: ширина или высота прямоугольника слишком малы.") quit() # Рисуем верхнюю линию прямоугольника print("*" * width) # Рисуем стороны прямоугольника for i in range(height – 2): print("*" + " " * (width – 2) + "*") # Рисуем нижнюю линию прямоугольника print("*" * width) Теперь при вызове функции drawBox ей должны быть переданы два аргу- мента, обозначенные в виде параметров при ее объявлении. В момент вы- зова функции значение первого аргумента будет записано в переменную первого параметра (width), а значение второго – в переменную второго па- раметра (height). К примеру, следующий вызов функции приведет к отобра- жению прямоугольника шириной 15 единиц и высотой четыре единицы. Чтобы нарисовать прямоугольник с другими характеристиками, нужно вы- звать нашу функцию еще раз и передать в нее уже другие аргументы. drawBox(15, 4) Сейчас наша функция drawBox рисует границы прямоугольника исклю- чительно звездочками, а внутренняя его часть заполнена пробелами. И хотя выглядит он неплохо, иногда может возникнуть необходимость в рисовании сторон прямоугольника и его заполнении другими симво- лами. С этой целью мы добавим к объявлению функции drawBox еще два параметра, как показано в обновленной версии программы ниже. Пример вызова функции с альтернативными символами для сторон и заполнения прямоугольника показан в конце фрагмента кода. ## Рисуем прямоугольник # @param width – ширина прямоугольника 74 Упражнения # @param height – высота прямоугольника # @param outline – символ для рисования сторон прямоугольника # @param fill – символ для заливки прямоугольника def drawBox(width, height, outline, fill): # Слишком маленькие прямоугольники не могут быть нарисованы при помощи этой функции if width < 2 or height < 2: print("Ошибка: ширина или высота прямоугольника слишком малы.") quit() # Рисуем верхнюю линию прямоугольника print(outline * width) # Рисуем стороны прямоугольника for i in range(height – 2): print(outline + fill * (width – 2) + outline) # Рисуем нижнюю линию прямоугольника print(outline * width) # Демонстрируем работу обновленной функции drawBox(14, 5, "@", ".") При вызове новой версии функции drawBox программист обязательно должен передавать третий и четвертый параметры в дополнение к пер- вым двум. Это может быть приемлемо, если значения параметров по- стоянно меняются, но если, к примеру, звездочка и пробел используются в большинстве случаев для рисования прямоугольников, можно приме- нить иной подход, добавив к некоторым параметрам функции значения по умолчанию (default value) при ее объявлении. Для этого используется оператор присваивания, как показано в примере ниже. def drawBox(width, height, outline="*", fill=" "): В таком виде функция drawBox может вызываться с двумя, тремя или четырьмя аргументами. В первом случае значения первого и второго переданных аргументов будут присвоены переменным ширины и высо- ты будущего прямоугольника, тогда как переменным outline и fill будут присвоены значения по умолчанию, а именно звездочка и пробел соот- ветственно. Переменные параметров получают значения по умолчанию только тогда, когда для них не переданы соответствующие аргументы при вызове функции. Теперь давайте рассмотрим следующий вызов функции. drawBox(14, 5, "@", ".") В вызов функции включены четыре аргумента. Первые два соответству- ют ширине и высоте прямоугольника и присваиваются соответствующим переменным в теле функции. Третий аргумент характеризует символ для Функции 75 линий фигуры. Поскольку в этом случае мы передали на вход функции фактическое желаемое значение для параметра, отвечающего за тип ли- ний прямоугольника, значение переменной по умолчанию будет замене- но на знак @. То же самое произойдет и с четвертым аргументом – соответ- ствующая ему переменная параметра будет инициализирована точкой. В результате фигура, которая будет построена при помощи подобного вызова функции, обретет следующий вид. @@@@@@@@@@@@@@ @............@ @............@ @............@ @@@@@@@@@@@@@@ 4.2. п еременные в функцияХ Переменные, объявляемые внутри функции, называются локальными (lo- cal). Это означает, что область действия этих переменных ограничивается данной функцией, и к ним можно обратиться только в теле этой функции. После завершения работы функции локальные переменные очищаются из памяти, а значит, и обратиться к ним больше не получится. В функции drawBox задействовано сразу несколько локальных переменных. В их число входят и переменные параметров вроде width и fill, и даже внутренняя переменная i из цикла for внутри функции. Ко всем этим переменным можно обращаться только внутри тела функции. Переменные, создавае- мые и инициализируемые внутри функции при помощи оператора при- сваивания, также классифицируются как локальные. 4.3. в озвращаемые значения Наша функция выводит прямоугольник на экран. И хотя она принимает на вход целых четыре аргумента, никаких вычислений, результат кото- рых стоило бы сохранить в переменной и использовать позже, внутри функции не производится. Но многие функции пишутся именно для этого. Например, функция sqrt из модуля math вычисляет квадратный корень из переданного в нее аргумента и возвращает его для дальнейшего ис- пользования. Так же точно функция input считывает ввод с клавиатуры и возвращает введенное значение для дальнейшей его обработки. Многие функции, которые вы будете писать сами, тоже будут возвращать значения. Для возврата значения из функции существует ключевое слово return, после которого идет само значение. Дойдя до инструкции с return, функ- 76 Упражнения ция мгновенно прекращает свое выполнение, и управление передается инструкции, следующей сразу за вызовом функции. Например, следую- щее выражение прекращает выполнение функции, возвращая при этом значение 5. return 5 Функции, возвращающие значение, обычно появляются в выражени- ях справа от оператора присваивания, но могут быть вызваны и в других контекстах, когда необходимо получить рассчитанное значение. Например, подобные функции могут быть частью условного выражения if или цикла while , а также подаваться на вход других функций, таких как print или range. В функциях, не предназначенных для возвращения результата, совсем не обязательно использовать ключевое слово return, поскольку возврат в основную программу автоматически произойдет после выполнения по- следней инструкции в теле функции. Но программист вправе использо- вать слово return без следующего за ним значения для преждевременного выхода из функции. Кроме того, в любой функции, вне зависимости от того, возвращает она значение или нет, ключевое слово return может по- являться множество раз. Выход из подобной функции произойдет по до- стижении первого из этих слов. Рассмотрим еще один пример. Геометрическая прогрессия представ- ляет собой последовательность чисел, начинающуюся с числа a и про- должающуюся до бесконечности. При этом каждый следующий член по- следовательности, за исключением первого, получается путем умножения предыдущего на r, называемое знаменателем прогрессии. В результате прогрессию можно выразить как последовательность a, ar, ar 2 , ar 3 , … . При r, равном единице, сумма первых n элементов геометрической прогрессии составит a×n. В противном случае сумму первых n элементов можно вы- числить по следующей формуле: Несложно написать функцию на языке Python, вычисляющую эту сумму для любой геометрической прогрессии при известном n. Функция будет принимать на вход три параметра – a, r и n – и возвращать сумму первых n элементов последовательности. Код функции показан ниже. ## Вычислить сумму первых n элементов геометрической прогрессии # @param a – первый элемент последовательности # @param r – знаменатель последовательности # @param n – количество элементов, сумму которых необходимо получить # @return s – сумма первых n элементов def sumGeometric(a, r, n): Функции 77 # Вычисляем и возвращаем сумму первых n элементов при r, равном 1 if r == 1: return a * n # Вычисляем и возвращаем сумму первых n элементов при r, не равном 1 s = a * (1 – r ** n) / (1 – r) return s Функция начинается с использования условной конструкции if для определения того, равняется ли r единице. Если это так, сумму первых n элементов можно вычислить по простой формуле a * n, после чего вернуть результат вызывающей программе, не выполняя оставшийся код функ- ции. Если значение переменной r не равно единице, тело условного выра- жения пропускается, а вместо него в переменную s помещается результат подсчета нужной нам суммы по формуле, описанной выше. После этого результат возвращается в виде переменной s, и выполнение функции на этом заканчивается. В следующей программе мы рассмотрим пример использования нашей функции sumGeometric для вычисления суммы первых n элементов геометри- ческой прогрессии, пока пользователь не введет для переменной a нулевое значение. Каждое значение суммы рассчитывается отдельно, возвращается и присваивается переменной с именем total. Полученная сумма выводится на экран, после чего происходит следующий запрос пользователю. def main(): # Запрашиваем значение переменной a для первой последовательности init = float(input("Введите значение переменной a (0 для выхода): ")) # Пока вводимое значение не равно нулю while init != 0: # Запрашиваем знаменатель и количество элементов ratio = float(input("Введите знаменатель последовательности, r: ")) num = int(input("Введите количество элементов, n: ")) # Вычисляем и отображаем результат total = sumGeometric(init, ratio, num) print("Сумма первых", num, "элементов равна", total) # Запрашиваем значение переменной a для следующей последовательности init = float(input("Введите значение переменной a (0 для выхода): ")) # Вызываем основную функцию main() 4.4. и мпорт функций в другие программы Одним из преимуществ написания функций является то, что впослед- ствии вы можете обращаться к ним из различных мест. Если объявление 78 Упражнения функции и ее вызов располагаются в одном файле, никаких проблем нет. В этом случае вам достаточно вызвать функцию по имени с круглыми скобками и аргументами. Но однажды вам непременно захочется воспользоваться написанной ранее функцией в новом проекте. Многие программисты, даже самые опытные, предпочитают просто копировать код функций из старых фай- лов и вставлять в новые, но это не лучший подход. Копирование функции приводит к ее полному дублированию, и если вам вдруг придется внести изменения в работу функции, вы вынуждены будете делать это во всех файлах. Гораздо лучше просто импортировать функцию из старого файла в новый так же точно, как мы импортировали функции из встроенных в Python модулей, – при помощи ключевого слова import с последующим указанием имени файла (без расширения .py), в котором находятся нуж- ные функции. Это позволит обращаться к нужным функциям, но при этом будет также запущена программа из старого файла. В некоторых ситуациях это допустимо, но не всегда. В подобном случае обычно соз- дается функция с именем main, содержащая необходимые выражения для решения задачи. В конце кода ставится вызов функции main. И наконец, вставляется условная конструкция, приведенная ниже, предотвращающая запуск функции main при выполнении импорта из другого файла. if __name__ == "__main__": main() Такую структуру файла стоит использовать всякий раз, когда вы знаете, что написанные в нем функции в будущем могут пригодиться в других программах. 4.5. у пражнения Функции позволяют нам именовать целые блоки кода на языке Python и вызывать их впоследствии из разных мест. Такой подход дает целый ряд преимуществ по сравнению с программами, написанными без функций, включая возможность повторного использования кода и дополнительные опции для локального тестирования программы. Функции также позво- ляют программисту вынести за скобки детали реализации того или ино- го блока кода и сосредоточиться на более важных вещах. Эффективное использование функций позволит вам улучшить свои программы в це- лом, особенно когда речь идет о решении довольно серьезных задач. Все упражнения из данной главы должны быть выполнены с применением функций. Функции 79 Упражнение 85. Вычисляем длину гипотенузы (23 строки) Напишите функцию, принимающую на вход длины двух катетов прямо- угольного треугольника и возвращающую длину гипотенузы, рассчитан- ную по теореме Пифагора. В главной программе должен осуществляться запрос длин сторон у пользователя, вызов функции и вывод на экран полученного результата. Упражнение 86. Плата за такси (22 строки) Представьте, что сумма за пользование услугами такси складывается из базового тарифа в размере $4,00 плюс $0,25 за каждые 140 м поездки. Напишите функцию, принимающую в качестве единственного параметра расстояние поездки в километрах и возвращающую итоговую сумму опла- ты такси. В основной программе должен демонстрироваться результат вызова функции. Подсказка. Цены на такси могут меняться со временем. Используйте константы для представления базового тарифа и плавающей ставки, чтобы программу можно было легко обновлять при изменении цен. Упражнение 87. Расчет стоимости доставки (23 строки) Интернет-магазин предоставляет услугу экспресс-доставки для части своих товаров по цене $10,95 за первый товар в заказе и $2,95 – за все последующие. Напишите функцию, принимающую в качестве единствен- ного параметра количество товаров в заказе и возвращающую общую сумму доставки. В основной программе должны производиться запрос количест ва позиций в заказе у пользователя и отображаться на экране сумма доставки. Упражнение 88. Медиана трех значений (Решено. 43 строки) Напишите функцию, которая будет принимать на вход три числа в качест- ве параметров и возвращать их медиану. В основной программе должен производиться запрос к пользователю на предмет ввода трех чисел, а так- же вызов функции и отображение результата. 80 Упражнения Подсказка. Медианой называется число, находящееся ровно посередине отсорти- рованной по возрастанию последовательности. Его можно получить путем реали- зации условных блоков if или с применением творческого подхода к математике и статистике. Упражнение 89. Переводим целые числа в числительные (47 строк) Такие слова, как первый, второй, третий, являются числительными. В дан- ном упражнении вам необходимо написать функцию, принимающую на вход в качестве единственного аргумента целое число и возвращающую строковое значение, содержащее соответствующее числительное (на анг- лийском языке). Ваша функция должна обрабатывать числа в диапазоне от 1 до 12. Если входящее значение выходит за границы этого диапазона, вывод должен оставаться пустым. В основной программе запустите цикл по натуральным числам от 1 до 12 и выведите на экран соответствующие им числительные. Ваша программа должна запускаться только в том слу- чае, если она не импортирована в виде модуля в другой файл. Упражнение 90. Двенадцать дней Рождества (Решено. 52 строки) «Двенадцать дней Рождества» (The Twelve Days of Christmas) – старая анг- лийская песня, построение которой базируется на постоянно увеличи- вающемся списке подарков в каждый из 12 дней Рождества. В первый день был послан один подарок, в следующий – второй и т. д. Первые три куплета песни приведены ниже. Полностью текст песни можно без труда найти в интернете. On the first day of Christmas my true love sent to me: A partridge in a pear tree. On the second day of Christmas my true love sent to me: Two turtle doves, And a partridge in a pear tree. On the third day of Christmas my true love sent to me: Three French hens, Two turtle doves, And a partridge in a pear tree. Функции 81 Напишите программу, которая будет сама строить куплеты этой песен- ки. В программе должна присутствовать функция для отображения одного куплета. В качестве входного параметра она должна принимать порядко- вый номер дня, а в качестве результата возвращать готовый куплет. Далее в основной программе эта функция должна быть вызвана 12 раз подряд. Каждая строка с очередным подарком должна присутствовать в вашей программе лишь раз, за исключением строки «A partridge in a pear tree». В этом случае вы можете отдельно хранить такой вид строки для первого куплета и слегка измененный («And a partridge in a pear tree») – для всех последующих. Импортируйте свою функцию из упражнения 89 для вы- полнения этого задания. Упражнение 91. Григорианский календарь в порядковый (72 строки) Порядковая дата содержит номер года и порядковый номер дня в этом году – оба в целочисленном формате. При этом год может быть любым согласно григорианскому календарю, а номер дня – числом в интервале от 1 до 366 (чтобы учесть високосные годы). Порядковые даты удобно использовать при расчете разницы в днях, когда счет ведется именно в днях, а не месяцах. Например, это может касаться 90-дневного периода возврата товара для покупателей, расчета срока годности товаров или прогнозируемой даты появления малыша на свет. Напишите функцию с именем ordinalDate, принимающую на вход три целых числа: день, месяц и год. Функция должна возвращать порядковый номер заданного дня в указанном году. В основной программе у пользо- вателя должны запрашиваться день, месяц и год соответственно и выво- диться на экран порядковый номер дня в заданном году. Программа долж- на запускаться только в том случае, если она не импортирована в виде модуля в другой файл. Упражнение 92. Порядковая дата в григорианский календарь (103 строки) Разработайте функцию, принимающую в качестве единственного па- раметра порядковую дату, включающую в себя год и день по порядку. В качестве результата функция должна возвращать день и месяц, соот- ветствующие переданной порядковой дате. Убедитесь, что ваша функция корректно обрабатывает високосные годы. Используйте эту функцию, а также функцию ordinalDate, написанную при выполнении упражнения 91, для разработки основной программы. Для начала должен производиться запрос порядковой даты у пользова- 82 Упражнения теля. После этого программа должна вычислить вторую дату, отстоящую от первой на определенное количество дней. Например, ваша программа могла бы запрашивать у пользователя порядковую дату, когда был при- обретен товар, и выводить последнюю дату, когда можно осуществить возврат (согласно определенным правилам возврата товаров). Или вы могли бы спрогнозировать дату появления ребенка на свет на основании срока беременности в 280 дней. Удостоверьтесь, что программа коррект- но обрабатывает ситуации, когда заданная дата и расчетная находятся в разных годах. Упражнение 93. Центрируем строку (Решено. 29 строк) Напишите функцию, которая будет принимать в качестве параметров строку s, а также ширину окна в символах – w. Возвращать функция долж- на новую строку, в которой в начале добавлено необходимое количество пробелов, чтобы первоначальная строка оказалась размещена по цент- ру заданного окна. Новая строка должна формироваться по следующему принципу: если длина исходной строки s больше или равна ширине заданного окна, возвращаем ее в неизменном виде; в противном случае должна быть возвращена строка s с ведущими пробелами в количестве (len(s) – w) // 2 штук. В вашей основной программе должен осуществляться пример вывода нескольких строк в окнах разной ширины. Упражнение 94. Треугольник ли? (33 строки) Всем известно, что из трех веточек разной длины далеко не всегда можно составить треугольник, соединив их концы. Например, если все они будут длиной 6 см, можно без труда построить равносторонний треугольник. Но если одна веточка будет длиной 6 см, а остальные две длиной 2 см, тре- угольник просто не получится. Правило здесь простое: если длина одной стороны больше или равна сумме двух оставшихся сторон, треугольник НЕ образуется. Иначе это возможно. Напишите функцию для определения возможности построения тре- угольника на основании длин трех его потенциальных сторон. Функция должна принимать три числовых параметра и возвращать булево значе- ние. Если длина хотя бы одной из трех сторон меньше или равна нулю, функция должна вернуть False. В противном случае необходимо выпол- нить проверку на допустимость построения треугольника на основании введенных длин сторон и вернуть соответствующее значение. Напиши- Функции 83 те основную программу, запрашивающую у пользователя длины сторон и выводящую на экран информацию о том, может ли при заданных зна- чениях получиться треугольник. Упражнение 95. Озаглавим буквы (Решено. 68 строк) Многие в своих сообщениях не ставят заглавные буквы, особенно если ис- пользуют для набора мобильные устройства. Создайте функцию, которая будет принимать на вход исходную строку и возвращать строку с восста- новленными заглавными буквами. По существу, ваша функция должна: сделать заглавной первую букву в строке, не считая пробелы; сделать заглавной первую букву после точки, восклицательного или вопросительного знака, не считая пробелы; если текст на английском языке, сделать заглавными буквы «i», ко- торым предшествует пробел или за которыми следует пробел, точка, восклицательный или вопросительный знак. Реализация такого рода автоматической корректуры исключит боль- шую часть ошибок с регистром букв. Например, строку «what time do i have to be there? what’s the address? this time i’ll try to be on time!» ваша функция должна преобразовать в более приемлемый вариант «What time do I have to be there? What’s the address? This time I’ll try to be on time!». В основной программе запросите у пользователя исходную строку, обработайте ее при помощи своей функции и выведите на экран итоговый результат. Упражнение 96. Является ли строка целым числом? (Решено. 30 строк) В данном упражнении вам предстоит написать функцию с именем isIn- teger , определяющую, представляет ли введенная строка целочисленное значение. При проверке вы можете игнорировать ведущие и замыкаю- щие пробелы в строке. После исключения лишних пробелов строку можно считать представляющей целое число, если ее длина больше или равна одному символу и она целиком состоит из цифр. Возможен также вариант с ведущим знаком «+» или «-», после которого должны идти цифры. В основной программе у пользователя должна запрашиваться исходная строка и выводиться сообщение о том, можно ли введенное значение вос- принимать как целое число. Убедитесь, что основная программа не будет запускаться, если файл импортирован в другой файл в качестве модуля. Подсказка. При работе с этим заданием вам, вероятно, понадобятся методы lstrip, rstrip и/или strip. Их описание можно найти в интернете. 84 Упражнения Упражнение 97. Приоритеты операторов (30 строк) Напишите функцию с именем precedence, которая будет возвращать целое число, представляющее собой приоритет или старшинство математиче- ского оператора. В качестве единственного параметра эта функция будет принимать строку, содержащую оператор. На выходе функция должна давать 1 для операторов «+» и «–», 2 для «*» и «/» и 3 для «ˆ». Если строка, переданная в функцию, не содержит ни один из перечисленных операто- ров, должно быть возвращено значение -1. Дополните функцию основной программой, в которой будет выполняться запрос оператора у пользова- теля и выводиться на экран его приоритет или сообщение об ошибке, если был осуществлен неверный ввод. Программа должна запускаться только в том случае, если она не импортирована в виде модуля в другой файл. Примечание. В данном упражнении, как и во всех последующих в этой книге, мы бу- дем использовать оператор «ˆ» (крышечка) для возведения в степень. Применение этого символа вместо стандартного для Python «**» позволит облегчить написание программы, поскольку в этом случае все операторы будут состоять из одного сим- вола. Упражнение 98. Простое число? (Решено. 28 строк) Простое число представляет собой число, большее единицы, которое без остатка делится лишь на само себя и единицу. Напишите функцию для определения того, является ли введенное число простым. Возвращаемое значение должно быть либо True, либо False. В основной программе, как и ожидается, пользователь должен ввести целое число и получить ответ о том, является ли оно простым. Убедитесь, что основная программа не будет запускаться, если файл импортирован в другой файл в качестве модуля. Упражнение 99. Следующее простое число (27 строк) В данном упражнении вам нужно написать функцию с именем nextPrime, которая находит и возвращает первое простое число, большее введенного числа n. Само число n должно передаваться в функцию в качестве един- ственного параметра. В основной программе запросите у пользователя это значение и выведите на экран первое простое число, большее за- данного. Для решения этой задачи импортируйте функцию, созданную в упражнении 98. Функции 85 Упражнение 100. Случайный пароль (Решено. 33 строки) Напишите функцию, которая будет генерировать случайный пароль. В па- роле должно быть от 7 до 10 символов, при этом каждый символ должен быть случайным образом выбран из диапазона от 33 до 126 в таблице ASCII. Ваша функция не должна принимать на вход параметры, а возвра- щать будет сгенерированный пароль. В основной программе вы должны просто вывести созданный случайным образом пароль. Программа долж- на запускаться только в том случае, если она не импортирована в виде модуля в другой файл. Подсказка. При решении этого упражнения вам, возможно, понадобится функция chr . Полную информацию о ней можно найти в интернете. Упражнение 101. Случайный номерной знак (45 строк) Представьте, что в вашем регионе устаревшим является формат номер- ных автомобильных знаков из трех букв, следом за которыми идут три цифры. Когда все номера такого шаблона закончились, было решено об- новить формат, поставив в начало четыре цифры, а за ними три буквы. Напишите функцию, которая будет генерировать случайный номерной знак. При этом номера в старом и новом форматах должны создаваться примерно с одинаковой вероятностью. В основной программе нужно сге- нерировать и вывести на экран случайный номерной знак. Упражнение 102. Проверка пароля на надежность (Решено. 40 строк) В данном упражнении вам необходимо написать функцию, проверяющую введенный пароль на надежность. Определим как надежный пароль, со- стоящий минимум из восьми символов и включающий хотя бы по одной букве в верхнем и нижнем регистрах и как минимум одну цифру. Функция должна возвращать True, если переданный в качестве параметра пароль отвечает требованиям надежности. В противном случае возвращаемым значением должно быть False. В основной программе необходимо запро- сить у пользователя пароль и оповестить его о том, является ли он до- статочно надежным. Программа должна запускаться только в том случае, если она не импортирована в виде модуля в другой файл. 86 Упражнения Упражнение 103. Случайный надежный пароль (22 строки) Используя решения из упражнений 100 и 102, напишите программу, ге- нерирующую случайный надежный пароль и выводящую его на экран. Посчитайте, с какого раза удастся создать пароль, отвечающий нашим требованиям надежности, и выведите на экран количество попыток. Им- портируйте функции из предыдущих упражнений и вызывайте их при необходимости для решения этой задачи. Упражнение 104. Шестнадцатеричные и десятичные числа (41 строка) Напишите две функции с именами hex2int и int2hex для конвертации значений из шестнадцатеричной системы счисления (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E и F) в десятичную (по основанию 10) и обратно. Функ- ция hex2int должна принимать на вход строку с единственным символом в шестнадцатеричной системе и преобразовывать его в число от нуля до 15 в десятичной системе, тогда как функция int2hex будет выполнять обратное действие – принимать десятичное число из диапазона от 0 до 15 и возвращать шестнадцатеричный эквивалент. Обе функции должны принимать единственный параметр со входным значением и возвращать преобразованное число. Удостоверьтесь, что функция hex2int корректно обрабатывает буквы в верхнем и нижнем регистрах. Если введенное поль- зователем значение выходит за допустимые границы, вы должны вывести сообщение об ошибке. Упражнение 105. Произвольные системы счисления (Решено. 71 строка) Напишите программу, которая позволит пользователю преобразовывать числа из одной системы счисления в другую произвольным образом. Ваша программа должна поддерживать все системы счисления в диапазоне от 2 до 16 как для входных, так и для выходных данных. Если пользователь выберет систему с основанием, выходящим за границы допустимого, на экран должна быть выведена ошибка. Разделите код программы на не- сколько функций, включая функцию, конвертирующую число из произ- вольной системы счисления в десятичную, и обратную функцию, пере- водящую значение из десятичной системы в произвольную. В основной программе необходимо запросить у пользователя исходную систему счис- ления, целевую систему, а также число для преобразования. При выполне- нии данного упражнения вам могут пригодиться функции из заданий 81, 82 и 104. Функции 87 Упражнение 106. Дни в месяце (47 строк) Напишите функцию для определения количества дней в конкретном ме- сяце. Ваша функция должна принимать два параметра: номер месяца в виде целого числа в диапазоне от 1 до 12 и год, состоящий из четырех цифр. Убедитесь, что функция корректно обрабатывает февраль високос- ного года. В основной программе запросите у пользователя номер месяца и год и отобразите на экране количество дней в указанном месяце. При решении этой задачи вам может пригодиться написанная вами функция из упражнения 58. Упражнение 107. Максимальное сокращение дробей (Решено. 46 строк) Напишите функцию, принимающую на вход два целочисленных пара- метра, представляющих числитель и знаменатель дроби. В теле функции должно выполняться максимально возможное сокращение дроби, а полу- ченные в итоге числитель и знаменатель должны быть возвращены исход- ной программе. Например, если на вход функции передать числа 6 и 63, числитель и знаменатель итоговой дроби должны быть 2 и 21. В основной программе нужно запросить у пользователя числитель и знаменатель ис- ходной дроби, передать их в функцию и вывести на экран результат. Подсказка. В упражнении 79 вы писали функцию для определения наибольшего общего делителя для двух целых чисел. Воспользуйтесь ей в этом задании. Упражнение 108. Переводим меры (Решено. 87 строк) Во многих кулинарных книгах до сих пор можно встретить рецепты, в ко- торых ингредиенты отмеряются стаканами, чайными и столовыми лож- ками. И хотя при наличии этих нехитрых предметов таким рецептам сле- довать довольно удобно, бывает трудно быстро преобразовать подобные меры при приготовлении рождественского ужина на огромную семью. Например, если в рецепте сказано взять четыре столовые ложки того или иного ингредиента, то при увеличении выхода в четыре раза можно прос- то отсчитать 16 столовых ложек. Однако гораздо проще было бы привести эту меру к одному стакану. Напишите функцию, выражающую заданный объем ингредиентов с ис- пользованием минимально возможных замеров. Функция должна при- нимать в качестве параметра количество единиц измерения, а также их тип (стакан, столовая или чайная ложка). На выходе мы должны получить 88 Упражнения строку, представляющую указанное количество вещества, с задействова- нием минимального количества действий и предметов. Например, если на вход функции вы подали объем, равный 59 чайным ложкам, возвращенная строка должна быть такой: «1 cup, 3 tablespoons, 2 teaspoons». Примечание. Используйте в этом упражнении английское написание мер: cup, table- spoon и teaspoon, добавляя к ним во множественном числе окончание s. Подсказка. Один стакан вмещает 16 столовых ложек, а одна столовая ложка эквива- лентна трем чайным ложкам. Упражнение 109. Магические даты (Решено. 26 строк) Магическими называются даты, в которых произведение дня и месяца составляет последние две цифры года. Например, 10 июня 1960 года – магическая дата, поскольку 10 ´ 6 = 60. Напишите функцию, определя- ющую, является ли введенная дата магической. Используйте написан- ную функцию в главной программе для отображения всех магических дат в XX ве ке. Возможно, вам пригодится здесь функция, разработанная в упражнении 106. |