Изучаем Python Эрик Метиз. Crash course2 n d e d i t i o na h a n d s o n, p r o j e c t b a s e d i n t r o d u c t i o n t o p r o g r a m m i n g
Скачать 6.19 Mb.
|
УПРАЖНЕНИЯ 7.4. Топпинг для пиццы: напишите цикл, который предлагает пользователю вводить до- полнения для пиццы до тех пор, пока не будет введено значение 'quit' . При вводе каждого дополнения выведите сообщение о том, что это дополнение включено в заказ. 7.5. Билеты в кино: кинотеатр установил несколько вариантов цены на билеты в зависи- мости от возраста посетителя. Для посетителей младше 3 лет билет бесплатный; в возрасте от 3 до 12 билет стоит $10; наконец, если возраст посетителя больше 12, билет стоит $15. Напишите цикл, который предлагает пользователю ввести возраст и выводит цену билета. 7.6. Три выхода: напишите альтернативную версию упражнения 7.4 или упражнения 7.5, в которой каждый пункт следующего списка встречается хотя бы один раз: • Завершение цикла по проверке условия в команде while • Управление продолжительностью выполнения цикла в зависимости от переменной active • Выход из цикла по команде break, если пользователь вводит значение 'quit' 7.7. Бесконечный цикл: напишите цикл, который никогда не завершается, и выполните его. (Чтобы выйти из цикла, нажмите Ctrl+C или закройте окно с выводом.) Использование цикла while со списками и словарями До настоящего момента мы работали только с одним фрагментом информации, полученной от пользователя. Мы получали ввод пользователя, а затем выво- Использование цикла while со списками и словарями 139 дили ответ на него. При следующем проходе цикла while программа получала новое входное значение и реагировала на него. Но чтобы работать с нескольки- ми фрагментами информации, необходимо использовать в циклах while списки и словари. Цикл for хорошо подходит для перебора списков, но скорее всего, список не дол- жен изменяться в цикле, потому что у Python возникнут проблемы с отслежива- нием элементов. Чтобы изменять список в процессе обработки, используйте цикл while . Использование циклов while со списками и словарями позволяет собирать, хранить и упорядочивать большие объемы данных для последующего анализа и обработки. Перемещение элементов между списками Возьмем список недавно зарегистрированных, но еще не проверенных пользова- телей сайта. Как переместить пользователей после проверки в отдельный список проверенных пользователей? Одно из возможных решений: используем цикл while для извлечения пользователей из списка непроверенных, проверяем их и включаем в отдельный список проверенных пользователей. Код может выглядеть так: confirmed_users.py # Начинаем с двух списков: пользователей для проверки # и пустого списка для хранения проверенных пользователей. ❶ unconfirmed_users = ['alice', 'brian', 'candace'] confirmed_users = [] # Проверяем каждого пользователя, пока остаются непроверенные # пользователи. Каждый пользователь, прошедший проверку, # перемещается в список проверенных. ❷ while unconfirmed_users: ❸ current_user = unconfirmed_users.pop() print(f"Verifying user: {current_user.title()}") ❹ confirmed_users.append(current_user) # Вывод всех проверенных пользователей. print("\nThe following users have been confirmed:") for confirmed_user in confirmed_users: print(confirmed_user.title()) Работа программы начинается с двух списков: непроверенных пользователей и пустого списка для проверенных пользователей. Цикл while в точке выпол- няется, пока в списке unconfirmed_users остаются элементы. Внутри этого списка функция pop() в точке извлекает очередного непроверенного пользователя из конца списка unconfirmed_users . В данном примере список unconfirmed_users завершается пользователем Candace ; это имя первым извлекается из списка, со- храняется в current_user и добавляется в список confirmed_users в точке . Далее следуют пользователи Brian и Alice 140 Глава 7 • Ввод данных и циклы while Программа моделирует проверку каждого пользователя выводом сообщения, после чего переносит пользователя в список проверенных. По мере сокращения списка непроверенных пользователей список проверенных пользователей растет. Когда в списке непроверенных пользователей не остается ни одного элемента, цикл оста- навливается и выводится список проверенных пользователей: Verifying user: Candace Verifying user: Brian Verifying user: Alice The following users have been confirmed: Candace Brian Alice Удаление всех вхождений конкретного значения из списка В главе 3 функция remove() использовалась для удаления конкретного значения из списка. Функция remove() работала, потому что интересующее нас значение встречалось в списке только один раз. Но что, если вы захотите удалить все вхож- дения значения из списка? Допустим, имеется список pets , в котором значение 'cat' встречается многократно. Чтобы удалить все экземпляры этого значения, можно выполнять цикл while до тех пор, пока в списке не останется ни одного экземпляра 'cat' : pets.py pets = ['dog', 'cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat'] print(pets) while 'cat' in pets: pets.remove('cat') print(pets) Программа начинает со списка, содержащего множественные экземпляры 'cat' После вывода списка Python входит в цикл while , потому что значение 'cat' при- сутствует в списке хотя бы в одном экземпляре. После входа цикл Python удаляет первое вхождение 'cat' , возвращается к строке while , а затем обнаруживает, что экземпляры 'cat' все еще присутствуют в списке, и проходит цикл заново. Вхож- дения 'cat' удаляются до тех пор, пока не окажется, что в списке значений 'cat' не осталось; в этот момент Python завершает цикл и выводит список заново: ['dog', 'cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat'] ['dog', 'dog', 'goldfish', 'rabbit'] Заполнение словаря данными, введенными пользователем При каждом проходе цикла while ваша программа может запрашивать любое необходимое количество данных. Напишем программу, которая при каждом про- Использование цикла while со списками и словарями 141 ходе цикла запрашивает имя участника и его ответ. Собранные данные будут со- храняться в словаре, потому что каждый ответ должен быть связан с конкретным пользователем: mountain_poll.py responses = {} # Установка флага продолжения опроса. polling_active = True while polling_active: # Запрос имени и ответа пользователя. ❶ name = input("\nWhat is your name? ") response = input("Which mountain would you like to climb someday? ") # Ответ сохраняется в словаре: ❷ responses[name] = response # Проверка продолжения опроса. ❸ repeat = input("Would you like to let another person respond? (yes/ no) ") if repeat == 'no': polling_active = False # Опрос завершен, вывести результаты. print("\n--- Poll Results ---") ❹ for name, response in responses.items(): print(f"{name} would like to climb {response}.") Сначала программа определяет пустой словарь ( responses ) и устанавливает флаг ( polling_active ), показывающий, что опрос продолжается. Пока polling_active содержит True , Python будет выполнять код в цикле while В цикле пользователю предлагается ввести имя и название горы, на которую ему хотелось бы подняться . Эта информация сохраняется в словаре responses в строке , после чего программа спрашивает у пользователя, нужно ли продол- жать опрос . Если пользователь отвечает положительно, то программа снова входит в цикл while . Если же ответ отрицателен, флаг polling_active переходит в состояние False , цикл while перестает выполняться и завершающий блок кода выводит результаты опроса. Если вы запустите эту программу и введете пару ответов, результат будет выглядеть примерно так: What is your name? Eric Which mountain would you like to climb someday? Denali Would you like to let another person respond? (yes/ no) yes What is your name? Lynn Which mountain would you like to climb someday? Devil's Thumb Would you like to let another person respond? (yes/ no) no --- Poll Results --- 142 Глава 7 • Ввод данных и циклы while Lynn would like to climb Devil's Thumb. Eric would like to climb Denali. УПРАЖНЕНИЯ 7.8. Сэндвичи: создайте список с именем sandwich_orders , заполните его названиями раз- личных видов сэндвичей. Создайте пустой список с именем finished_sandwiches . В цикле переберите элементы первого списка и выведите сообщение для каждого элемента (напри- мер, «I made your tuna sandwich»). После этого каждый сэндвич из первого списка пере- мещается в список finished_sandwiches . После того как все элементы первого списка будут обработаны, выведите сообщение с перечислением всех изготовленных сэндвичей. 7.9. Без пастрами: используя список sandwich_orders из упражнения 7.8, проследите за тем, чтобы значение 'pastrami' встречалось в списке как минимум три раза. Добавьте в на- чало программы код для вывода сообщения о том, что пастрами больше нет, и напишите цикл while для удаления всех вхождений 'pastrami' из sandwich_orders . Убедитесь в том, что в finished_sandwiches значение 'pastrami' не встречается ни одного раза. 7.10. Отпуск мечты: напишите программу, которая опрашивает пользователей, где бы они хотели провести отпуск. Включите блок кода для вывода результатов опроса. Итоги В этой главе вы научились использовать input() для того, чтобы пользователи могли вводить собственную информацию в своих программах. Вы научились рабо- тать с числовыми и текстовыми данными, а также управлять продолжительностью выполнения своих программ с помощью циклов while . Также мы рассмотрели несколько способов управления циклами while : установка флага, команда break и команда continue . Вы узнали, как использовать цикл while для перемещения элементов из одного списка в другой и как удалить все вхождения некоторого значения из списка. Также были рассмотрены возможности применения циклов while со словарями. Глава 8 посвящена функциям. Функции позволяют разделить программу на мень- шие части, каждая из которых решает одну конкретную задачу. Функции можно хранить в отдельных файлах и вызывать их столько раз, сколько потребуется. Бла- годаря функциям вы сможете писать более эффективный, более простой в отладке и сопровождении код, который к тому же можно повторно использовать в разных программах. 8 Функции Эта глава посвящена функциям — именованным блокам кода, предназначенным для решения одной конкретной задачи. Чтобы выполнить задачу, определенную в виде функции, вы вызываете функцию, отвечающую за эту задачу. Если задача должна многократно выполняться в программе, вам не придется заново вводить весь не- обходимый код; просто вызовите функцию, предназначенную для решения задачи, и этот вызов прикажет Python выполнить код, содержащийся внутри функции. Как вы вскоре убедитесь, использование функций упрощает чтение, написание, тестирование кода и исправление ошибок. В этой главе также рассматриваются возможности передачи информации функ- циям. Вы узнаете, как писать функции, основной задачей которых является вывод информации, и другие функции, предназначенные для обработки данных и возвра- щения значения (или набора значений). Наконец, вы научитесь хранить функции в отдельных файлах, называемых модулями, для упорядочения файлов основной программы. Определение функции Вот простая функция с именем greet_user () , которая выводит приветствие: greeter.py ❶ def greet_user(): ❷ """Выводит простое приветствие.""" ❸ print("Hello!") ❹ greet_user() В этом примере представлена простейшая структура функции. Строка при по- мощи ключевого слова def сообщает Python, что вы определяете функцию. В опре- делении функции указывается имя функции и если нужно — описание информации, необходимой функции для решения ее задачи. Эта информация заключается в круглые скобки. В данном примере функции присвоено имя greet_user() и она не нуждается в дополнительной информации для решения своей задачи, поэтому 144 Глава 8 • Функции круглые скобки пусты. (Впрочем, даже в этом случае они обязательны.) Наконец, определение завершается двоеточием. Все строки с отступами, следующие за def greet_user(): , образуют тело функ- ции. Текст в точке представляет собой комментарий — строку документации с описанием функции. Строки документации заключаются в утроенные кавычки; Python опознает их по этой последовательности символов во время генерирования документации к функциям в ваших программах. «Настоящий» код в теле этой функции состоит всего из одной строки print("Hello!") — см. . Таким образом, функция greet_user() решает всего одну задачу: выполнение команды print("Hello!") Когда потребуется использовать эту функцию, вызовите ее. Вызов функции при- казывает Python выполнить содержащийся в ней код. Чтобы вызвать функцию, укажите ее имя, за которым следует вся необходимая информация, заключенная в круглые скобки, как показано в строке . Так как никакая дополнительная ин- формация не нужна, вызов функции эквивалентен простому выполнению команды greet_user() . Как и ожидалось, функция выводит сообщение Hello! : Hello! Передача информации функции С небольшими изменениями функция greet_user() сможет не только сказать «Привет!» пользователю, но и поприветствовать его по имени. Для этого следует включить имя username в круглых скобках в определении функции def greet_ user() . С добавлением username функция примет любое значение, которое будет заключено в скобки при вызове. Теперь функция ожидает, что при каждом вызове будет передаваться имя пользователя. При вызове greet_user() укажите имя (на- пример, 'jesse' ) в круглых скобках: def greet_user(username): """Выводит простое приветствие.""" print(f"Hello, {username.title()}!") greet_user('jesse') Команда greet_user('jesse') вызывает функцию greet_user() и передает ей информацию, необходимую для выполнения команды print . Функция получает переданное имя и выводит приветствие для этого имени: Hello, Jesse! Точно так же команда greet_user('sarah') вызывает функцию greet_user() и передает ей строку 'sarah' , в результате чего будет выведено сообщение Hello, Sarah! Функцию greet_user() можно вызвать сколько угодно раз и передать ей любое имя на ваше усмотрение — и вы будете получать ожидаемый результат. Передача аргументов 145 Аргументы и параметры Функция greet_user() определена так, что для работы она должна получить зна- чение переменной username . После того как функция будет вызвана и получит не- обходимую информацию (имя пользователя), она выведет правильное приветствие. Переменная username в определении greet_user() — параметр, то есть условные данные, необходимые функции для выполнения ее работы. Значение 'jesse' в greet_user('jesse') — аргумент, то есть конкретная информация, переданная при вызове функции. Вызывая функцию, вы заключаете значение, с которым функция должна работать, в круглые скобки. В данном случае аргумент 'jesse' был передан функции greet_user() , а его значение было сохранено в переменной username ПРИМЕЧАНИЕ Иногда в литературе термины «аргумент» и «параметр» используются как синонимы . Не удивляйтесь, если переменные в определении функции вдруг будут названы аргументами, а значения, переданные при вызове функции, — параметрами . УПРАЖНЕНИЯ 8.1. Сообщение: напишите функцию display_message() для вывода сообщения по теме, рассматриваемой в этой главе. Вызовите функцию и убедитесь в том, что сообщение выво- дится правильно. 8.2. Любимая книга: напишите функцию favorite_book() , которая получает один пара- метр title . Функция должна выводить сообщение вида «One of my favorite books is Alice in Wonderland». Вызовите функцию и убедитесь в том, что название книги правильно пере- дается как аргумент при вызове функции. Передача аргументов Определение функции может иметь несколько параметров, и может оказаться, что при вызове функции должны передаваться несколько аргументов. Существуют несколько способов передачи аргументов функциям. Позиционные аргументы перечисляются в порядке, точно соответствующем порядку записи параметров; именованные аргументы состоят из имени переменной и значения; наконец, суще- ствуют списки и словари значений. Рассмотрим все эти способы. Позиционные аргументы При вызове функции каждому аргументу должен быть поставлен в соответствие параметр в определении функции. Проще всего сделать это на основании порядка перечисления аргументов. Значения, связываемые с аргументами подобным об- разом, называются позиционными аргументами. Чтобы понять, как работает эта схема, рассмотрим функцию для вывода информа- ции о домашних животных. Функция сообщает тип животного и его имя: 146 Глава 8 • Функции pets.py ❶ def describe_pet(animal_type, pet_name): """Выводит информацию о животном.""" print(f"\nI have a {animal_type}.") print(f"My {animal_type}'s name is {pet_name.title()}.") ❷ describe_pet('hamster', 'harry') Из определения видно, что функции должен передаваться тип животного ( animal_type ) и его имя ( pet_name ). При вызове describe_pet() необходимо пере- дать тип и имя — именно в таком порядке. В этом примере аргумент 'hamster' сохраняется в параметре animal_type , а аргумент 'harry' сохраняется в параметре pet_name . В теле функции эти два параметра используются для вывода инфор- мации: I have a hamster. My hamster's name is Harry. Многократные вызовы функций Функция может вызываться в программе столько раз, сколько потребуется. Для вывода информации о другом животном достаточно одного вызова describe_pet() : def describe_pet(animal_type, pet_name): """Выводит информацию о животном.""" print(f"\nI have a {animal_type}.") print(f"My {animal_type}'s name is {pet_name.title()}.") describe_pet('hamster', 'harry') describe_pet('dog', 'willie') Во втором вызове функции describe_pet() передаются аргументы 'dog' и 'willie' По аналогии с предыдущей парой аргументов Python сопоставляет аргумент 'dog' с параметром animal_type , а аргумент 'willie' — с параметром pet_name Как и в предыдущем случае, функция выполняет свою задачу, но на этот раз вы- водятся другие значения: I have a hamster. My hamster's name is Harry. I have a dog. My dog's name is Willie. Многократный вызов функции — чрезвычайно эффективный механизм. Код вы- вода информации о домашнем животном пишется один раз в функции. Каждый раз, когда вам понадобится вывести информацию о новом животном, вы вызыва- ете функцию с данными нового животного. Даже если код вывода информации разрастется до 10 строк, вы все равно сможете вывести информацию всего одной командой — для этого достаточно снова вызвать функцию. |