автордың кітабын онлайн тегін оқу Большая книга проектов Python
Переводчик И. Пальти
Эл Свейгарт
Большая книга проектов Python. — СПб.: Питер, 2022.
ISBN 978-5-4461-1907-3
© ООО Издательство "Питер", 2022
Все права защищены. Никакая часть данной книги не может быть воспроизведена в какой бы то ни было форме без письменного разрешения владельцев авторских прав.
Об авторе
Эл Свейгарт (Al Sweigart) — разработчик программного обеспечения, автор и участник Python Software Foundation. Ранее работал руководителем по вопросам образования в Музее искусств и цифровых развлечений — музее компьютерных игр Окленда, Калифорния. Эл написал несколько книг по программированию, включая Automate the Boring Stuff with Python1 и Invent Your Own Computer Games with Python2. Книги Эла свободно доступны под лицензией Creative Commons на его сайте https://inventwithpython.com/. Его кошка Зофи обожает снеки с водорослями нори.
Эл Свейгарт (Al Sweigart) — разработчик программного обеспечения, автор и участник Python Software Foundation. Ранее работал руководителем по вопросам образования в Музее искусств и цифровых развлечений — музее компьютерных игр Окленда, Калифорния. Эл написал несколько книг по программированию, включая Automate the Boring Stuff with Python1 и Invent Your Own Computer Games with Python2. Книги Эла свободно доступны под лицензией Creative Commons на его сайте https://inventwithpython.com/. Его кошка Зофи обожает снеки с водорослями нори.
Эл Свейгарт (Al Sweigart) — разработчик программного обеспечения, автор и участник Python Software Foundation. Ранее работал руководителем по вопросам образования в Музее искусств и цифровых развлечений — музее компьютерных игр Окленда, Калифорния. Эл написал несколько книг по программированию, включая Automate the Boring Stuff with Python1 и Invent Your Own Computer Games with Python2. Книги Эла свободно доступны под лицензией Creative Commons на его сайте https://inventwithpython.com/. Его кошка Зофи обожает снеки с водорослями нори.
Свейгарт Э. Автоматизация рутинных задач с помощью Python. — М.: Вильямс, 2017.
Свейгарт Э. Учим Python, делая крутые игры. — М.: Эксмо, 2021.
О научном редакторе
Сара Кучински (Sarah Kuchinsky) — магистр естественных наук, корпоративный инструктор и консультант. Она использует Python для множества целей, включая моделирование систем здравоохранения, разработку игр и автоматизацию задач. Сара — один из основателей конференции North Bay Python, председатель комиссии по обучающим пособиям конференции PyCon US и ведущий организатор группы PyLadies Silicon Valley. Защитила дипломы по теории управления, инженерии и математике.
Введение
Программировать легко, когда можно просто скопировать print('Hello,world!'). Вероятно, вам случалось читать хорошо структурированную книгу или проходить онлайн-курс для начинающих, прорабатывая упражнения и поддакивая жаргонным словечкам, которые вы (более или менее) понимали. Однако когда пришло время покидать гнездо и писать собственные программы, возможно, летать самостоятельно оказалось не так просто. Вы обнаружили, что пялитесь в пустое окно редактора и не знаете, как начать писать свои программы на Python.
Проблема в том, что следовать учебнику очень полезно для усвоения теории, но это далеко не всегда то же самое, что учиться писать новые программы с нуля. На данном этапе часто рекомендуют изучать программное обеспечение с открытым исходным кодом или работать над собственными проектами, но проекты с открытым исходным кодом далеко не всегда хорошо документированы или доступны для начинающих. И хотя работа над собственными проектами очень стимулирует, вы остаетесь совершенно без руководства.
В книге вы найдете практические примеры применения различных идей программирования в виде коллекции более чем 80 игр, имитационных моделей и объектов цифрового искусства. Они представляют собой не просто фрагменты кода, а полноценные работающие программы на Python. Вы можете скопировать их код, чтобы лучше познакомиться с тем, как они работают, поэкспериментировать, а затем попытаться воссоздать их самостоятельно в качестве практики. Вскоре вы найдете идеи для собственных программ и, главное, будете знать, как приступить к их реализации.
Проектирование маленьких программ
Программирование зарекомендовало себя как навык, открывающий большие возможности, в том числе по созданию технологических компаний стоимостью миллиарды долларов и потрясающих технических достижений. Стремиться к большему при создании своего ПО легко, но когда переоцениваешь свои силы — в конце концов получаешь только незаконченные программы и разочарование. Однако вовсе не нужно быть компьютерным гением, чтобы создавать интересные и креативные программы.
Проекты на Python в этой книге отвечают нескольким основным принципам проектирования, чтобы упростить для начинающих понимание исходного кода.
• Они маленькие — большинство приведенных в книге программ не превышает 256 строк кода, а часто они намного короче. Благодаря таким ограничениям размера читателю проще понять эти программы. Число 256 выбрано случайно, но 256 = 28, а степени двойки — счастливые для программистов числа.
• Приводятся в виде текста — текст проще, чем графика. Когда и исходный код, и выводимые программой результаты представляют собой текст, можно легко отследить, скажем, причинно-следственную связь между оператором print('Thanksforplaying!') в коде и выводимой на экран надписью Thanksforplaying!.
• Не требуют установки — все программы заключены в отдельные, самодостаточные файлы исходного кода Python с расширением .py, например tictactoe.py. Не нужно запускать программу установки и можно легко разместить такую программу в интернете, чтобы поделиться ею с другими.
• Их много — в книге приведена 81 программа. Вы обязательно найдете программы себе по вкусу среди настольных игр, карточных игр, художественных цифровых изображений, имитационных моделей, математических загадок, лабиринтов и развлекательных программ.
• Они простые — эти программы были написаны так, чтобы быть понятными даже для начинающих. Выбирая между кодом на основе сложных, высокопроизводительных алгоритмов и простым и ясным кодом, я всегда в этой книге склонялся к последнему.
Программы в текстовом формате могут показаться несколько старомодными, но подобный стиль программирования позволяет не отвлекаться на нюансы, связанные со скачиванием графических данных, установкой дополнительных библиотек и организацией каталогов проекта. Вместо этого можно сосредоточиться на самом коде.
Для кого эта книга
Книга написана для двух групп людей. В первую входят те, кто уже освоил основы Python и программирования вообще, но все еще не вполне представляет, как писать собственные программы. Этим людям может казаться, что программирование для них «не сложилось». Можно успешно решать практические упражнения из учебников, но с трудом представлять себе, как выглядит полная программа. Благодаря сначала копированию, а затем и воссозданию игр из данной книги эти люди постепенно поймут, как изучаемые здесь понятия программирования компоновать во множество настоящих программ.
Во вторую группу входят новички в сфере программирования, достаточно азартные и настроенные на приключения, желающие погрузиться в работу с головой и сразу же начать создавать игры, имитационные модели и программы, обрабатывающие большие массивы числовых данных. Таких людей устраивает копирование кода и изучение его по ходу дела. Или, возможно, они уже умеют программировать на другом языке, но Python им внове. Эта книга, хотя и не заменяет полноценный вводный курс Python, кратко знакомит читателя с его основами и учит использовать отладчик для исследования внутренних механизмов работы программы во время выполнения.
Опытные программисты тоже могут развлечься с программами из этой книги, но учтите, что она написана все-таки для новичков.
Что можно найти в издании
Хотя основная часть книги посвящена конкретным программам, в ней вы найдете также дополнительные источники информации по общим вопросам программирования и Python.
• Проекты — перечислять здесь 81 проект будет слишком долго, но каждому из них посвящена отдельная глава, включающая название проекта, описание, пример результатов работы программы и ее исходный код. Вдобавок приводятся рекомендации относительно изменений, которые вы можете внести в код, чтобы адаптировать эти программы к своим требованиям.
• Приложение A «Указатель тегов» — перечислены все проекты, разбитые на категории по тегам проектов.
• Приложение Б «Таблица кодов символов» — список кодов символов для сердечек, линий, стрелок и блоков, которые могут выводить ваши программы.
Как научиться чему-то на программах из этой книги
Эта книга не учит языку Python или каким-либо понятиям программирования, подобно обычному учебнику. В ней применяется подход «учеба на практике», при котором читателя призывают вручную копировать программы, экспериментировать с ними и исследовать внутренние механизмы их работы путем запуска их под отладчиком.
Основная идея книги состоит не в подробном пояснении синтаксиса языка программирования, а в демонстрации полноценных примеров программ, реализующих нечто реальное: карточные ли игры, воспроизведение ли анимации, исследование ли математической загадки. Поэтому я рекомендую придерживаться следующих этапов.
1. Скачайте программу и запустите ее, чтобы посмотреть, что она делает.
2. Начав с пустого файла, скопируйте код игры из книги, вручную набрав его (не используйте команды копирования/вставки!).
3. Запустите программу снова, вернитесь и исправьте все опечатки и ошибки, которые вы могли случайно внести в код.
4. Запустите программу из-под отладчика, чтобы последовательно выполнить код построчно и разобраться, что делает каждая строка.
5. Найдите комментарии, отмеченные (!), чтобы найти код, который можно изменить и посмотреть, как это повлияет на программу при следующем запуске.
6. Наконец, попробуйте воссоздать программу самостоятельно с нуля. Не обязательно точную ее копию; можете привнести в нее что-то свое.
При копировании кода из книги можете не набирать комментарии (текст в конце строк, следующий за символом #) — это примечания для программистов, игнорируемые Python. Однако старайтесь писать свой код на Python на строках с теми же номерами, что и программы в данном издании, чтобы упростить их сравнение. Если у вас не получается найти опечатки в своих программах, то можете сравнить свой код с кодом из книги с помощью онлайн-утилиты diff по адресу https://inventwithpython.com/bigbookpython/diff/.
Каждую программу описывает набор тегов, например настольнаяигра, имитационная модель, художественная и длядвухигроков. Пояснения ко всем этим тегам и перекрестный указатель тегов и проектов приведены в приложении A.
Скачивание и установка Python
Python — название как языка программирования, так и интерпретатора, выполняющего код на языке Python. Утилита-интерпретатор совершенно бесплатна и свободно доступна для скачивания и использования. Можете проверить, не установлен ли уже в вашей системе Python, с помощью командной строки. В Windows откройте командную строку и введите py--version. Если выведено примерно следующее, значит, Python установлен:
C:\Users\Al>py --version
Python 3.9.1
В macOS и Linux откройте терминал и введите python3--version. Если будет выведено примерно следующее, значит, Python установлен:
$ python3 --version
Python 3.9.1
В этой книге используется Python версии 3. При переходе от Python 2 к Python 3 было внесено несколько обратно несовместимых изменений, и для работы описанных здесь программ требуется как минимум Python версии 3.1.1 (выпущена в 2009 году). Если вы увидите сообщение об ошибке, гласящее, что Python не найден или версия Python — 2, можете скачать свежий установочный пакет Python для вашей операционной системы с сайта https://python.org/. В случае проблем с установкой Python дополнительные инструкции можно найти здесь: https://installpython3.com/.
Скачивание и установка редактора Mu
Код Python вы будете вводить в текстовом редакторе или интегрированной среде разработки (IDE) приложений. Я рекомендую использовать в качестве IDE редактор Mu, если вы новичок; он прост и не отвлекает ваше внимание множеством расширенных опций.
Откройте сайт https://codewith.mu/ в браузере. В Windows и macOS скачайте установочный пакет для соответствующей операционной системы и запустите его, дважды щелкнув на файле. В macOS запуск установочного пакета приведет к открытию окна, в котором необходимо перетащить пиктограмму Mu в каталог Applications для продолжения установки. В Ubuntu придется установить Mu в качестве пакета Python. В этом случае откройте новое окно терминала и выполните команду pip3installmu-editor для установки и mu-editor — для запуска. Нажмите кнопку Instructions в разделе Python Package страницы загрузки для подробных инструкций.
Запуск редактора Mu
После установки запустите Mu:
• в Windows 7 или более поздней версии щелкните на пиктограмме Start в нижнем левом углу экрана, введите mu в поле поиска и выберите Mu, когда он появится;
• в macOS откройте окно Finder, щелкните на Applications, а затем на mu-editor;
• в Ubuntu нажмите Ctrl+Alt+T, чтобы открыть окно терминала, и введите команду python3-mmu.
При первом запуске Mu появится окно Select Mode (Выберите режим) со следующими вариантами: Adafruit CircuitPython, BBC micro:bit, Pygame Zero и Python 3. Выберите Python3. При желании позднее всегда можно изменить режим, нажав кнопку Mode вверху окна редактора.
Вы сможете вводить код в главном окне Mu, а затем сохранять его, открывать и запускать файлы с помощью кнопок вверху.
Запуск IDLE и других редакторов
Можете использовать какие угодно редакторы для написания кода на Python. Вместе с Python устанавливается ПО IDLE (Integrated Development and Learning Environment, интегрированная среда разработки и изучения), которое может служить альтернативным редактором, если по какой-либо причине вам не удалось установить Mu или заставить его работать. Запустим IDLE.
• В Windows 7 или более поздней версии щелкните на пиктограмме Start в нижнем левом углу экрана, введите idle в поле поиска и выберите IDLE (Python GUI).
• В macOS откройте окно Finder, нажмите Applications
• В Ubuntu выберите Applications
• На Raspberry Pi нажмите кнопку меню Raspberry Pi в левом верхнем углу; щелкните на Programming, а затем встав на Python 3 (IDLE). Можете также выбрать Thonny Python IDE из меню Programming.
Существует еще несколько бесплатных редакторов, с помощью которых можно вводить и выполнять код Python, например:
• Thonny, IDE Python для начинающих по адресу https://thonny.org/;
• PyCharm Community Edition — IDE Python, которую используют разработчики-профессионалы, по адресу https://www.jetbrains.com/pycharm/.
Установка модулей Python
Для большинства программ из этой книги требуется только стандартная библиотека Python, устанавливаемая автоматически вместе с Python. Однако для некоторых программ требуются сторонние модули, например pyperclip, bext, playsound и pyttsx3. Их все можно установить сразу, загрузив модуль bigbookpython.
Что касается редактора Mu, то необходимо установить версию 1.1.0-alpha (или более позднюю). По состоянию на 2020 год эту версию можно найти вверху страницы скачивания по адресу https://codewith.mu/en/download в разделе Try the Alpha of the Next Version of Mu (Попробуйте альфа-версию обновленного Mu). После установки нажмите значок с шестеренкой в левом нижнем углу окна, чтобы вызвать окно Mu Administration (Администрирование Mu). Выберите вкладку Third Party Packages (Сторонние пакеты), введите bigbookpython в текстовое поле и нажмите Ok. В результате этого будут установлены все сторонние модули, используемые программами из книги.
При использовании Visual Studio Code или редактора IDLE откройте редактор и выполните следующий код Python в интерактивной командной оболочке:
>>> import os, sys
>>> os.system(sys.executable + ' -m pip install --user bigbookpython')
0
Число 0, выводимое после второй инструкции, означает, что все работает должным образом. В противном случае, если вы увидите сообщение об ошибке или другое число, попробуйте выполнить следующие команды без опции --user:
>>> import os, sys
>>> os.system(sys.executable + ' -m pip install bigbookpython')
0
При использовании любого редактора можете попробовать выполнить команду importpyperclip или importbext, чтобы убедиться, что установка прошла успешно. Если эти команды импорта не возвращают сообщения об ошибке, значит, соответствующие модули установлены правильно и вы сможете запускать использующие их проекты из книги.
Копирование кода из книги
Программирование — навык, совершенствуемый прежде всего практикой. Не стоит просто читать код в этой книге и копировать/вставлять его в свой компьютер. Потратьте немного времени, но наберите код в редакторе вручную. Обращайте внимание на номера строк, чтобы случайно не пропустить ничего. Если вы столкнетесь с ошибками, то воспользуйтесь онлайн-утилитой diff по адресу https://inventwithpython.com/bigbookpython/diff/, чтобы сравнить свой код с кодом из книги. Чтобы лучше разобраться в работе программ, попробуйте запустить их под отладчиком.
После того как исходный код будет введен и запущен несколько раз, попробуйте поэкспериментировать с внесением в него изменений. Идеи относительно возможных небольших изменений вы можете найти в комментариях, помеченных (!), вдобавок в каждом проекте есть список идей более крупных изменений.
Далее попробуйте воссоздать программу с самого начала, не глядя на исходный код в книге. Ваша программа не должна в точности воспроизводить программу из книги, вы можете придумать собственную версию.
Проработав все программы из книги, вероятно, вы захотите начать создавать собственные. Большинство современных компьютерных игр и прикладных программ достаточно сложны, их создание требует команды, состоящей из программистов, архитекторов и графических дизайнеров. Однако многие настольные, карточные игры и игры на бумаге достаточно просты, чтобы для них можно было разработать соответствующую программу. Многие из них относятся к категории абстрактных стратегических игр. Их список можно найти по адресу https://en.wikipedia.org/wiki/List_of_abstract_strategy_games.
Запуск программ из терминала
Использующие модуль bext программные проекты из книги выводят разноцветный текст. Однако эти цвета не отображаются, если запускать программы из Mu, IDLE или других редакторов, так что их необходимо запускать из окна терминала (командной строки). В Windows для этого запустите программу CommandPrompt (Командная строка) из меню Пуск. В macOS запустите Terminal (Терминал) из Spotlight. В Ubuntu Linux запустите Terminal (Терминал) из Ubuntu Dash или нажмите Ctrl+Alt+T.
Когда откроется окно терминала, перейдите в каталог с вашими файлами .py с помощью команды cd (change directory — «сменить каталог»). Например, если я работаю под Windows и сохранил программы Python в каталог C:\Users\Al, то должен ввести следующую команду:
C:\>cd C:\Users\Al
C:\Users\Al>
Далее, чтобы запустить программы Python, введите команду pythonвашаПрограмма.py в Windows или python3вашаПрограмма.py в macOS или Linux, заменив вашаПрограмма.py на название соответствующей программы на Python:
C:\Users\Al>python guess.py
Угадайте число, (c) Эл Свейгарт al@inventwithpython.com
Я загадал число от 1 до 100.
У вас осталось 10 попыток. Угадывайте.
--сокращено--
Прервать выполнение программы можно из терминала нажатием Ctrl+C, вместо того чтобы закрывать само окно терминала.
Запуск программ со смартфона или планшета
Работать с ноутбука или стационарного компьютера с полноценной клавиатурой будет удобнее, поскольку набирать код на клавиатуре телефона или даже планшета очень утомительно. И хотя не существует официальных интерпретаторов Python для Android или iOS, есть сайты с интерактивными онлайн-оболочками, которые можно использовать из браузера. Они подходят и для ноутбуков/стационарных компьютеров на случай, если вы преподаватель, у которого нет прав на установку нового программного обеспечения на компьютерах в учебном классе.
Интерпретаторы Python на сайтах https://repl.it/languages/Python3/ и https://www.pythonanywhere.com/ можно свободно использовать в браузере. Эти сайты подходят для большинства проектов из данной книги, но не для программ, использующих сторонние модули, например bext, pyperclip, pyttsx3 и playsound, и не для программ, читающих или записывающих файлы с помощью функции open(). Если вы увидите эти элементы в коде программы, значит, она не будет работать в указанных онлайн-интерпретаторах Python. Однако большинство программ из книги будет в них прекрасно работать.
Где получить помощь
Если вы не можете нанять частного преподавателя и у вас нет друга-программиста, который мог бы ответить на вопросы по программированию, то вам придется самостоятельно искать ответы на них. К счастью, эти вопросы практически наверняка кто-то уже задавал. Умение найти ответы самостоятельно — важный навык для любого программиста.
Не расстраивайтесь, если поймете, что постоянно ищете в интернете ответы на вопросы по программированию. Пока вы учитесь, нет ничего постыдного в том, чтобы искать что-то в интернете, вместо того чтобы запоминать все нюансы программирования с самого начала. Даже профессиональные разработчики ПО каждый день ищут что-то в Сети. В этом разделе вы узнаете, как задавать «умные» вопросы и искать ответы на них в интернете.
Когда программа пытается выполнить недопустимую инструкцию, отображается сообщение об ошибке: трассировка, описывающая тип произошедшей ошибки и то, на какой строке кода она произошла. Вот пример программы, в которой произошла ошибка во время вычисления того, сколько кусков пиццы должен получить каждый:
Traceback (most recent call last):
File "pizza.py", line 5, in <module>
print('Each person gets', (slices / people), ' slices of pizza.')
ZeroDivisionError: division by zero
Из этой трассировки не сразу ясно, что проблема вызвана переменной people, значение которой равно 0, вследствие чего выражение slices/people приводит к ошибке деления на ноль. Сообщения об ошибках зачастую настолько коротки, что даже не являются предложениями. Поскольку программисты сталкиваются с этими сообщениями постоянно, они играют роль скорее оповещений, а не полноценных пояснений. Если вы встретили какое-то сообщение об ошибке впервые, то скопируйте его и поищите в интернете, почти наверняка вы найдете подробное пояснение, что означает эта ошибка и чем она могла быть вызвана.
Если в интернете найти решение проблемы не удалось, то можете выставить свой вопрос на онлайн-форуме или задать кому-либо по электронной почте. Для большей эффективности процесса задавайте конкретные, четко сформулированные вопросы. То есть приведите полный исходный код и полное сообщение об ошибке со всеми подробностями, расскажите, какие решения проблемы уже пробовали, а также какую операционную систему и версию Python используете. Изложенные на форуме ответы не только позволят решить вашу проблему, но и помогут в будущем другим программистам с тем же вопросом, которые найдут ваше сообщение.
Набор кода
Программисту не обязательно уметь быстро печатать на клавиатуре, но лишним это умение не будет. Многие люди печатают двумя пальцами, в то время как более быстрый набор может значительно облегчить написание программ. По мере работы над программами из книги вам будет удобнее смотреть на код, а не на клавиатуру. Существуют бесплатные сайты для обучения быстрому набору текста, например https://typingclub.com/ и https://www.typing.com/. Хорошая программа для обучения набору текста отображает клавиатуру и прозрачные руки на экране, чтобы вы могли практиковаться, избавляясь от вредной привычки смотреть на клавиатуру в поисках клавиш. Как и любой другой навык, набор — дело привычки, а написание кода даст вам множество возможностей привыкнуть к набору.
Выполнять различные действия намного быстрее, не перемещая указатель мыши к пункту меню, позволяют также сочетания горячих клавиш. Они часто записаны в виде наподобие Ctrl+C, означающем, что нужно нажать одну из двух клавиш Ctrl и затем, не отпуская ее, нажать клавишу C. Но не нажать клавишу Ctrl, отпустить ее, а затем нажать клавишу C.
Выучить распространенные сочетания горячих клавиш, например Ctrl+C для копирования или Ctrl+S для сохранения, можно, открыв мышью меню вверху приложения (в Windows и Linux) или вверху экрана (в macOS). Время, потраченное на изучение этих сочетаний клавиш, окупится с лихвой.
Другие сочетания горячих клавиш не так очевидны. Например, Alt+Tab в Windows и Linux и Command+Tab в macOS позволяет переключиться на окно другого приложения. Чтобы выбрать конкретное окно, можно зажать Alt или Command и последовательно нажимать Tab.
Копирование и вставка
Буфер обмена (clipboard) — элемент операционной системы, предназначенный для временного хранения данных для вставки, которые могут представлять собой текст, изображения, файлы и другие типы информации, хотя в этом разделе мы будем говорить только о текстовых данных. При копировании (copying) текста копия выбранного в текущий момент времени текста попадает в буфер обмена. При вставке (pasting) текст из буфера вставляется в то место, где сейчас находится курсор, как если бы вы мгновенно набрали его сами. Копирование и вставка текста освобождают вас от необходимости заново набирать уже имеющийся на вашем компьютере текст, неважно, одну строку или сотни страниц.
Чтобы копировать и вставить текст, сначала выберите (выделите, highlight) текст, который будете копировать. Для этого можно нажать основную кнопку мыши (левую, если мышь предназначена для правшей) и перетащить указатель мыши по всему выбираемому тексту. Однако зачастую быстрее и точнее будет нажать кнопку Shift и переместить курсор с помощью сочетания горячих клавиш. Многие приложения позволяют мгновенно выделить целое слово путем двойного щелчка на нем. Можно также выделить целую строку или абзац тройным щелчком.
Следующий шаг: нажать Ctrl+C в Windows или Command+C в macOS, чтобы копировать выделенный текст в буфер обмена. В нем может содержаться только один элемент, так что копируемый текст замещает находившееся в буфере до этого.
Наконец, передвиньте курсор туда, куда нужно вставить текст, и нажмите Ctrl+V в Windows или Command+V в macOS. Вставлять текст можно столько раз, сколько нужно; он остается в буфере обмена до тех пор, пока вы не скопируете новый текст.
Поиск и замена текста
Дэн Рассел (Dan Russell), поисковый антрополог в Google, в статье 2011 года в Atlantic пояснил: при изучении привычек использования компьютеров людьми оказалось, что 90 % из них не знали, что можно нажать Ctrl+F (в Windows и Linux) или Command+F (в macOS) для поиска слов в приложениях. Это исключительно удобная возможность не только в редакторах кода, но и в текстовых редакторах, браузерах, приложениях электронных таблиц и практически во всех прочих программах, отображающих текст. Вы можете нажать Ctrl+F — и появится окно Find (Найти), куда можно ввести слово для поиска в программе. Нажатие клавиши F3 обычно позволяет повторить поиск и найти следующее вхождение слова. Эта возможность экономит колоссальное количество времени по сравнению с поиском слова с помощью просмотра документа вручную.
В редакторах также есть возможность поиска и замены текста, с которой обычно связано сочетание клавиш Ctrl+H (Command+H). Она позволяет находить вхождения какого-либо фрагмента текста и заменять его другим. Это очень удобно, например, для переименования переменной или функции. Однако возможность поиска и замены текста следует использовать с осторожностью, чтобы не заменить текст, случайно совпавший с критерием поиска.
Отладчик
Отладчик — утилита, выполняющая программы построчно, с возможностью просмотра текущего состояния переменных программы. Это ценный инструмент для поиска программных ошибок. В данном разделе я расскажу о возможностях отладчика редактора Mu. Не волнуйтесь: возможности всех отладчиков одинаковы, даже если интерфейсы пользователя различаются.
Чтобы запустить программу в отладчике, воспользуйтесь пунктом меню Debug (Отладка) в своей IDE вместо пункта меню Run (Запуск). Отладчик запустится в приостановленном состоянии на первой строке программы. У всех отладчиков есть кнопки Continue (Продолжить), Step In (Шаг с заходом), Step Over (Шаг с обходом), Step Out (Шаг с выходом) и Stop (Останов).
При нажатии кнопки Continue (Продолжить) программа выполняется как обычно, до тех пор пока не завершится или не достигнет точки останова (о них я расскажу позже в этом разделе). Если вы закончили отладку и хотите, чтобы программа далее выполнялась обычным образом, то нажмите Continue (Продолжить).
При нажатии кнопки Step In (Шаг с заходом) отладчик выполняет следующую строку кода, после чего останавливается. Если следующая строка кода представляет собой вызов функции, то отладчик «заходит» в эту функцию и переходит к первой строке ее кода.
При нажатии кнопки Step Over (Шаг с обходом) отладчик выполняет следующую строку кода аналогично кнопке Step In (Шаг с заходом). Но если следующая строка кода представляет собой вызов функции, то отладчик «обходит» код этой функции. Функция выполняется с обычной скоростью, и отладчик приостанавливается после возврата из ее вызова. Кнопку Step Over (Шаг с обходом) используют чаще, чем кнопку Step In (Шаг с заходом).
При нажатии кнопки Step Out (Шаг с выходом) отладчик выполняет строки кода с обычной скоростью, пока не происходит возврат из текущей функции. Если вы «зашли» в вызов функции с помощью кнопки Step In (Шаг с заходом) и просто хотите выполнить оставшиеся инструкции, пока не выйдете обратно, то нажмите кнопку Step Out (Шаг с выходом), чтобы отладчик «вышел» из текущего вызова функции.
Если вы хотите полностью завершить сеанс отладки и не продолжать выполнение остатка программы, то нажмите кнопку Stop (Останов). Она немедленно завершает выполнение программы.
Можно установить точку останова (breakpoint) на конкретной строке, при этом программа будет выполняться с обычной скоростью, до тех пор пока не достигнет данной строки. Затем отладчик остановит выполнение программы, чтобы вы могли изучить значения переменных и продолжить пошаговое выполнение отдельных строк кода. В большинстве IDE установить точку останова можно с помощью двойного щелчка на номере строки в левой части окна.
В любом отладчике где-нибудь в окне отладки отображаются значения, хранящиеся в текущий момент в переменных программы. Впрочем, один из распространенных методов отладки программ — отладка с выводом значений (print debugging). Метод заключается в добавлении вызовов print() для отображения значений переменных и в повторном запуске программы. Этот подход к отладке прост и удобен, однако часто требует больше времени, чем использование отладчика. При отладке с выводом значений необходимо добавлять вызовы print(), перезапускать программу, а затем удалять эти вызовы. Однако после перезапуска программы часто оказывается, что нужно добавить дополнительные вызовы print(), чтобы узнать значения других переменных. А значит, приходится перезапускать программу еще раз, что может означать еще один цикл добавления вызовов print() и т.д. Кроме того, легко можно упустить какие-либо из этих вызовов, что потребует дополнительного цикла их удаления. Отладка с выводом значений удобна для простых ошибок, но в конечном счете использование настоящего отладчика экономит время.
Резюме
Программирование — интересный и творческий навык. Хотите ли вы овладеть основами синтаксиса Python или просто посмотреть на настоящие программы на Python — проекты в этой книге породят новые идеи о том, чего можно добиться с помощью всего нескольких страниц кода.
Лучший способ работы с этими программами — не просто читать их код и копировать его. Потратьте немного времени, но наберите код в редакторе вручную, чтобы выработать «мышечную память». Помимо всего прочего, это немного замедлит вас, так что вы поневоле будете внимательнее обдумывать каждую из строк кода в ходе их набора, а не просто пробегать по ним глазами. Старайтесь искать в интернете все незнакомые инструкции или пробовать выполнять их в интерактивной командной оболочке.
Наконец, не поленитесь повторить программу с нуля, а затем модифицировать ее, добавив что-то свое. Благодаря этим упражнениям вы освоите концепции, на основе которых создаются настоящие работающие программы, а главное, хорошо проведете время!
От издательства
Ваши замечания, предложения, вопросы отправляйте по адресу comp@piter.com (издательство «Питер», компьютерная редакция).
Мы будем рады узнать ваше мнение!
На веб-сайте издательства www.piter.com вы найдете подробную информацию о наших книгах.
1. Бейглз
В дедуктивной логической игре «Бейглз» необходимо по подсказкам угадать секретное число из трех цифр. В ответ на ваши попытки угадать игра выдает одну из трех подсказок: Pico, если вы угадали правильную цифру на неправильном месте, Fermi, если в вашей догадке есть правильная цифра на правильном месте, и Bagels, если в догадке не содержится правильных цифр. На угадывание секретного числа у вас десять попыток.
Программа в действии
Результат выполнения bagels.py выглядит следующим образом:
Bagels, a deductive logic game.
By Al Sweigart al@inventwithpython.com
I am thinking of a 3-digit number. Try to guess what it is.
Here are some clues:
When I say: That means:
Pico One digit is correct but in the wrong position.
Fermi One digit is correct and in the right position.
Bagels No digit is correct.
I have thought up a number.
You have 10 guesses to get it.
Guess #1:
> 123
Pico
Guess #2:
> 456
Bagels
Guess #3:
> 178
Pico Pico
--сокращено--
Guess #7:
> 791
Fermi Fermi
Guess #8:
> 701
You got it!
Do you want to play again? (yes or no)
> no
Thanks for playing!
Описание работы
Обратите внимание: в данной программе используются не целочисленные значения, а строковые, содержащие цифры. Например, '426' — вовсе не то же значение, что и 426. Это необходимо, поскольку мы производим строковое сравнение с секретным числом, а не математическую операцию. Учтите, что '0' может быть значащей цифрой: строковое значение '026' отличается от '26', в то время как целочисленное значение 026 то же самое, что 26.
1. """Бейглз, (c) Эл Свейгарт al@inventwithpython.com
2. Дедуктивная логическая игра на угадывание числа по подсказкам.
3. Код размещен на https://nostarch.com/big-book-small-python-projects
4. Один из вариантов этой игры приведен в книге Invent Your Own
5. Computer Games with Python на https://nostarch.com/inventwithpython
6. Теги: короткая, игра, головоломка"""
7.
8. import random
9.
10. NUM_DIGITS = 3 # (!) Попробуйте задать эту константу равной 1 или 10.
11. MAX_GUESSES = 10 # (!) Попробуйте задать эту константу равной 1 или 100.
12.
13.
14. def main():
15. print('''Bagels, a deductive logic game.
16. By Al Sweigart al@inventwithpython.com
17.
18. I am thinking of a {}-digit number with no repeated digits.
19. Try to guess what it is. Here are some clues:
20. When I say: That means:
21. Pico One digit is correct but in the wrong position.
22. Fermi One digit is correct and in the right position.
23. Bagels No digit is correct.
24.
25. For example, if the secret number was 248 and your guess was 843, the
26. clues would be Fermi Pico.'''.format(NUM_DIGITS))
27.
28. while True: # Основной цикл игры.
29. # Переменная, в которой хранится секретное число, которое
30. secretNum = getSecretNum() # должен угадать игрок
31. print('I have thought up a number.')
32. print(' You have {} guesses to get it.'.format(MAX_GUESSES))
33.
34. numGuesses = 1
35. while numGuesses <= MAX_GUESSES:
36. guess = ''
37. # Продолжаем итерации до получения правильной догадки:
38. while len(guess) != NUM_DIGITS or not guess.isdecimal():
39. print('Guess #{}: '.format(numGuesses))
40. guess = input('> ')
41.
42. clues = getClues(guess, secretNum)
43. print(clues)
44. numGuesses += 1
45.
46. if guess == secretNum:
47. break # Правильно, выходим из цикла.
48. if numGuesses > MAX_GUESSES:
49. print('You ran out of guesses.')
50. print('The answer was {}.'.format(secretNum))
51.
52. # Спрашиваем игрока, хочет ли он сыграть еще раз.
53. print('Do you want to play again? (yes or no)')
54. if not input('> ').lower().startswith('y'):
55. break
56. print('Thanks for playing!')
57.
58.
59. def getSecretNum():
60. """Возвращает строку из NUM_DIGITS уникальных случайных цифр."""
61. numbers = list('0123456789') # Создает список цифр от 0 до 9.
62. random.shuffle(numbers) # Перетасовываем их случайным образом.
63.
64. # Берем первые NUM_DIGITS цифр списка для нашего секретного числа:
65. secretNum = ''
66. for i in range(NUM_DIGITS):
67. secretNum += str(numbers[i])
68. return secretNum
69.
70.
71. def getClues(guess, secretNum):
72. """Возвращает строку с подсказками pico, fermi и bagels
73. для полученной на входе пары из догадки и секретного числа."""
74. if guess == secretNum:
75. return 'You got it!'
76.
77. clues = []
78.
79. for i in range(len(guess)):
80. if guess[i] == secretNum[i]:
81. # Правильная цифра на правильном месте.
82. clues.append('Fermi')
83. elif guess[i] in secretNum:
84. # Правильная цифра на неправильном месте.
85. clues.append('Pico')
86. if len(clues) == 0:
87. return 'Bagels' # Правильных цифр нет вообще.
88. else:
89. # Сортируем подсказки в алфавитном порядке, чтобы их исходный
90. # порядок ничего не выдавал.
91. clues.sort()
92. # Склеиваем список подсказок в одно строковое значение.
93. return ' '.join(clues)
94.
95.
96. # Если программа не импортируется, а запускается, производим запуск:
97. if __name__ == '__main__':
98. main()
Когда вы введете исходный код и запустите его несколько раз, попробуйте поэкспериментировать с внесением в него изменений. Идеи относительно возможных небольших изменений вы найдете в комментариях, помеченных (!). Можете также сами попробовать придумать, как сделать следующее:
• изменить количество цифр в секретном числе, изменив константу NUM_DIGITS;
• изменить количество попыток угадывания, доступных игроку, изменив константу MAX_GUESSES;
• создать версию, в которой в секретном числе могут содержаться не только цифры, но и буквы.
Исследование программы
Попробуйте найти ответы на следующие вопросы. Поэкспериментируйте с изменениями кода и снова запустите программу, чтобы увидеть, как они повлияют на ее работу.
1. Что будет, если изменить константу NUM_DIGITS?
2. Что будет, если изменить константу MAX_GUESSES?
3. Что будет, если задать значение NUM_DIGITS больше 10?
4. Что будет, если secretNum=getSecretNum() в строке 30 заменить на secretNum='123'?
5. Какое сообщение об ошибке вы получите, если удалите или закомментируете numGuesses=1 в строке 34?
6. Что будет, если вы удалите или закомментируете random.shuffle(numbers) в строке 62?
7. Что будет, если вы удалите или закомментируете ifguess==secretNum: в строке 74 и return'Yougotit!' в строке 75?
8. Что будет, если вы закомментируете numGuesses+=1 в строке 44?
2. Парадокс дней рождения
Парадокс дней рождения, также известный как задача о днях рождения, заключается в удивительно высокой вероятности того, что у двух человек совпадает день рождения даже в относительно небольшой группе людей. В группе из 70 человек вероятность совпадения дней рождения у двух людей составляет 99,9 %. Но даже в группе всего лишь из 23 человек вероятность совпадения дней рождения составляет 50 %. Приведенная программа производит несколько вероятностных экспериментов, чтобы определить процентные соотношения для групп различного размера. Подобные эксперименты с определением возможных исходов с помощью множества случайных испытаний называются экспериментами Монте-Карло.
Узнать больше о парадоксе дней рождения можно в соответствующей статье «Википедии»: https://ru.wikipedia.org/wiki/Парадокс_дней_рождения.
Программа в действии
Результат выполнения birthdayparadox.py выглядит следующим образом:
Birthday Paradox, by Al Sweigart al@inventwithpython.com
--сокращено--
How many birthdays shall I generate? (Max 100)
> 23
Here are 23 birthdays:
Oct 9, Sep 1, May 28, Jul 29, Feb 17, Jan 8, Aug 18, Feb 19, Dec 1, Jan 22,
May 16, Sep 25, Oct 6, May 6, May 26, Oct 11, Dec 19, Jun 28, Jul 29, Dec 6,
Nov 26, Aug 18, Mar 18
In this simulation, multiple people have a birthday on Jul 29
Generating 23 random birthdays 100,000 times...
Press Enter to begin...
Let's run another 100,000 simulations.
0 simulations run...
10000 simulations run...
--сокращено--
90000 simulations run...
100000 simulations run.
Out of 100,000 simulations of 23 people, there was a
matching birthday in that group 50955 times. This means
that 23 people have a 50.95 % chance of
having a matching birthday in their group.
That's probably more than you would think!
Описание работы
Выполнение 100 000 операций имитационного моделирования займет немало времени, поэтому в строках 94 и 95 выводятся сообщения о каждых 10 000 произведенных операций. Такая обратная связь демонстрирует пользователю, что программа не зависла. Обратите внимание на знаки подчеркивания в некоторых числах, например, 10_000 в строке 95 и 100_000 в строках 93 и 103. Никакого особого смысла у этих знаков подчеркивания нет, но Python позволяет их указывать, чтобы программисты могли упростить чтение чисел в их программах. Другими словами, число «сто тысяч» в форме 100_000 понятнее, чем 100000.
1. """Имитационное моделирование парадокса дней рождения, (c) Эл Свейгарт
2. al@inventwithpython.com Изучаем неожиданные вероятности из "Парадокса
3. дней рождения". Больше информации — в статье
4. https://ru.wikipedia.org/wiki/Парадокс_дней_рождения
5. Код размещен на https://nostarch.com/big-book-small-python-projects
6. Теги: короткая, математическая, имитационное моделирование"""
7. import datetime, random
8.
9.
10. def getBirthdays(numberOfBirthdays):
11. """ Возвращаем список объектов дат для случайных дней рождения."""
12. birthdays = []
13. for i in range(numberOfBirthdays):
14. # Год в нашем имитационном моделировании роли не играет, лишь
15. # бы в объектах дней рождения он был одинаков.
16. startOfYear = datetime.date(2001, 1, 1)
17.
18. # Получаем случайный день года:
19. randomNumberOfDays = datetime.timedelta(random.randint(0, 364))
20. birthday = startOfYear + randomNumberOfDays
21. birthdays.append(birthday)
22. return birthdays
23.
24.
25. def getMatch(birthdays):
26. """ Возвращаем объект даты дня рождения, встречающегося
27. несколько раз в списке дней рождения."""
28. if len(birthdays) == len(set(birthdays)):
29. return None # Все дни рождения различны, возвращаем None.
30.
31. # Сравниваем все дни рождения друг с другом попарно:
32. for a, birthdayA in enumerate(birthdays):
33. for b, birthdayB in enumerate(birthdays[a + 1 :]):
34. if birthdayA == birthdayB:
35. return birthdayA # Возвращаем найденные соответствия.
36.
37.
38. # Отображаем вводную информацию:
39. print('''Birthday Paradox, by Al Sweigart al@inventwithpython.com
40.
41. The Birthday Paradox shows us that in a group of N people, the odds
42. that two of them have matching birthdays is surprisingly large.
43. This program does a Monte Carlo simulation (that is, repeated random
44. simulations) to explore this concept.
45.
46. (It's not actually a paradox, it's just a surprising result.)
47. ''')
48.
49. # Создаем кортеж названий месяцев по порядку:
50. MONTHS = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
51. 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')
52.
53. while True: # Запрашиваем, пока пользователь не введет допустимое значение.
54. print('How many birthdays shall I generate? (Max 100)')
55. response = input('> ')
56. if response.isdecimal() and (0 < int(response) <= 100):
57. numBDays = int(response)
58. break # Пользователь ввел допустимое значение.
59. print()
60.
61. # Генерируем и отображаем дни рождения:
62. print('Here are', numBDays, 'birthdays:')
63. birthdays = getBirthdays(numBDays)
64. for i, birthday in enumerate(birthdays):
65. if i != 0:
66. # Выводим запятую для каждого дня рождения после первого.
67. print(', ', end='')
68. monthName = MONTHS[birthday.month - 1]
69. dateText = '{} {}'.format(monthName, birthday.day)
70. print(dateText, end='')
71. print()
72. print()
73.
74. # Выясняем, встречаются ли два совпадающих дня рождения.
75. match = getMatch(birthdays)
76.
77. # Отображаем результаты:
78. print('In this simulation, ', end='')
79. if match != None:
80. monthName = MONTHS[match.month - 1]
81. dateText = '{} {}'.format(monthName, match.day)
82. print('multiple people have a birthday on', dateText)
83. else:
84. print('there are no matching birthdays.')
85. print()
86.
87. # Производим 100 000 операций имитационного моделирования:
88. print('Generating', numBDays, 'random birthdays 100,000 times...')
89. input('Press Enter to begin...')
90.
91. print('Let\'s run another 100,000 simulations.')
92. simMatch = 0 # Число операций моделирования с совпадающими днями рождения.
93. for i in range(100_000):
94. # Отображаем сообщение о ходе выполнения каждые 10 000 операций:
95. if i % 10_000 == 0:
96. print(i, 'simulations run...')
97. birthdays = getBirthdays(numBDays)
98. if getMatch(birthdays) != None:
99. simMatch = simMatch + 1
100. print('100,000 simulations run.')
101.
102. # Отображаем результаты имитационного моделирования:
103. probability = round(simMatch / 100_000 * 100, 2)
104. print('Out of 100,000 simulations of', numBDays, 'people, there was a')
105. print('matching birthday in that group', simMatch, 'times. This means')
106. print('that', numBDays, 'people have a', probability, '% chance of')
107. print('having a matching birthday in their group.')
108. print('That\'s probably more than you would think!')
Исследование программы
Попробуйте найти ответы на следующие вопросы. Поэкспериментируйте с изменениями кода и запустите программу снова, чтобы увидеть, как они повлияют на ее работу.
1. Как в программе представлены дни рождения? (Подсказка: взгляните на строку 16.)
2. Как убрать ограничение в 100 генерируемых дней рождения, установленное в программе?
3. Какое сообщение об ошибке вы получите, если удалите или закомментируете numBDays=int(response) в строке 57?
4. Как сделать так, чтобы программа отображала полные названия месяцев, например, 'January' вместо 'Jan'?
5. Как сделать так, чтобы надпись 'Xsimulationsrun...' выводилась каждые 1000 операций имитационного моделирования, а не 10 000?
3. Сообщение в виде битовой карты
В этой программе битовая карта (bitmap) — двумерное изображение, каждый пиксел которого может быть одного из двух цветов, представлена в виде многострочного строкового значения и служит для определения способа отображения пользовательского сообщения. В нашей битовой карте пробелы соответствуют пустому пространству, а все прочие символы заменяются символами из пользовательского сообщения. Представленная битовая карта напоминает карту мира, но вы можете заменить ее на любую другую, какую пожелаете. Простота системы двоичного представления «пустое пространство или символы сообщения» делает ее идеально подходящей для начинающих. Попробуйте поэкспериментировать с различными сообщениями и посмотрите, что получится.
Программа в действии
Результат выполнения bitmapmessage.py выглядит следующим образом:
Bitmap Message, by Al Sweigart al@inventwithpython.com
Enter the message to display with the bitmap.
> Hello!
Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!He
lo!Hello!Hello l !He lo e llo!Hello!Hello!Hello!Hello!He
llo!Hello!Hello!Hello He lo H l !Hello!Hello!Hello!Hello!Hello H
el lo!Hello!Hello!He lo!Hello!Hello!Hello!Hello!Hel
o!Hello!Hello lo e lo!H ll !Hello!Hello!H l
!Hello!He llo!Hel Hello!Hello!Hell ! e
Hello!He ello!Hello!Hello!Hello!Hell H
l H llo! ell ello!Hello!Hell !Hello el o
lo!H l ello!Hello!Hell ell !He o
!Hello llo!Hello!Hel el He o
!Hello!H lo!Hello!Hell l !H llo
ello!Hel Hello!He H llo Hell
ello!Hell ello!H l Hell !H l o!
ello!Hell ello!H l o o!H l H
lo!Hel ello! el o!Hel H
lo!He llo! e llo!Hell
llo!H llo! llo!Hello
llo! ll lo!Hell e
llo l e
ll l H
Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!Hello!He
Описание работы
Вместо того чтобы по отдельности вводить все символы шаблона карты мира, вы можете скопировать его целиком из https://inventwithpython.com/bitmapworld.txt и вставить. Строки из 68 точек вверху и внизу шаблона служат «линейками» для упрощения правильного выравнивания. Однако программа будет работать и при наличии каких-либо опечаток в этом шаблоне.
Вызываемый в строке 43 метод bitmap.splitlines() возвращает список отдельных строк из многострочного строкового значения bitmap. Благодаря использованию многострочного строкового значения можно легко заменить нашу битовую карту любым другим шаблоном. Программа заполнит все непробельные символы в шаблоне, так что нет разницы, какие это символы: звездочки, точки или любые другие символы.
Код message[i%len(message)] повторяет текст в message. Когда i, увеличиваясь с 0, доходит до числа len(message), выражение i%len(message) снова становится равно 0. В результате этого выражение message[i%len(message)] повторяет символы в message при росте i.
1. """Сообщение в виде битовой карты, (c) Эл Свейгарт al@inventwithpython.com
2. Отображает текстовое сообщение в соответствии с указанной битовой картой.
3. Код размещен на https://nostarch.com/big-book-small-python-projects
4. Теги: крошечная, для начинающих, графика"""
5.
6. import sys
7.
8. # (!) Попробуйте заменить это многострочное строковое значение на любое
9. # другое изображение
10. # Вверху и внизу строки расположено 68 точек:
11. # (Можете также скопировать и вставить это строковое значение из
12. # из https://inventwithpython.com/bitmapworld.txt)
13. bitmap = """
14. ....................................................................
15. ************** * *** ** * ******************************
16. ********************* ** ** * * ****************************** *
17. ** ***************** ******************************
18. ************* ** * **** ** ************** *
19. ********* ******* **************** * *
20. ******** *************************** *
21. * * **** *** *************** ****** ** *
22. **** * *************** *** *** *
23. ****** ************* ** ** *
24. ******** ************* * ** ***
25. ******** ******** * *** ****
26. ********* ****** * **** ** * **
27. ********* ****** * * *** * *
28. ****** ***** ** ***** *
29. ***** **** * ********
30. ***** **** *********
31. **** ** ******* *
32. *** * *
33. ** * *
34. ...................................................................."""
35.
36. print('Bitmap Message, by Al Sweigart al@inventwithpython.com')
37. print('Enter the message to display with the bitmap.')
38. message = input('> ')
39. if message == '':
40. sys.exit()
41.
42. # Проходим в цикле по всем строкам битовой карты:
43. for line in bitmap.splitlines():
44. # Проходим в цикле по всем символам строки:
45. for i, bit in enumerate(line):
46. if bit == ' ':
47. # Выводим пустое пространство согласно пробелу в битовой карте:
48. print(' ', end='')
49. else:
50. # Выводим символ сообщения:
51. print(message[i % len(message)], end='')
52. print() # Выводим символ новой строки.
Когда вы введете исходный код и запустите его несколько раз, попробуйте поэкспериментировать с внесением в него изменений. Можете, например, изменить строковое значение в bitmap и создать совершенно другие шаблоны.
Исследование программы
Попробуйте найти ответы на следующие вопросы. Поэкспериментируйте с изменениями кода и запустите программу снова, чтобы увидеть, как они повлияют на ее работу.
1. Что будет, если игрок введет в качестве сообщения пустую строку?
2. Играет ли какую-либо роль то, какие именно не пробельные символы указаны в переменной bitmap?
3. Каков смысл переменной i, созданной в строке 45?
4. Какая программная ошибка возникнет, если удалить или закомментировать print() в строке 52?
4. Блек-джек
Блек-джек, известный также как «двадцать одно», — карточная игра, в которой игроки пытаются набрать количество очков, как можно более близкое к 21, но не больше. В данной программе используются изображения, составленные из текстовых символов, так называемая ASCII-графика. ASCII (American Standard Code for Information Interchange, американский стандартный код обмена информацией) представляет собой таблицу соответствий текстовых символов числовым кодам, она применялась до того, как ее заменила кодировка Unicode3. Игральные карты в этой программе представляют собой пример ASCII-графики:
___ ___
|A | |10 |
| ♣ | | ♦ |
|__A| |_10|
Прочие правила и историю этой карточной игры вы можете найти в статье «Википедии»: https://ru.wikipedia.org/wiki/Блэкджек.
Программа в действии
Результат выполнения blackjack.py выглядит следующим образом:
Blackjack, by Al Sweigart al@inventwithpython.com
Rules:
Try to get as close to 21 without going over.
Kings, Queens, and Jacks are worth 10 points.
Aces are worth 1 or 11 points.
Cards 2 through 10 are worth their face value.
(H)it to take another card.
(S)tand to stop taking cards.
On your first play, you can (D)ouble down to increase your bet
but must hit exactly one more time before standing.
In case of a tie, the bet is returned to the player.
The dealer stops hitting at 17.
Money: 5000
How much do you bet? (1-5000, or QUIT)
> 400
Bet: 400
DEALER: ???
___ ___
|## | |2 |
|###| | ♥ |
|_##| |__2|
PLAYER: 17
___ ___
|K | |7 |
| ♠ | | ♦ |
|__K| |__7|
(H)it, (S)tand, (D)ouble down
> h
You drew a 4 of ♦.
--сокращено--
DEALER: 18
___ ___ ___
|K | |2 | |6 |
| ♦ | | ♥ | | ♠ |
|__K| |__2| |__6|
PLAYER: 21
___ ___ ___
|K | |7 | |4 |
| ♠ | | ♦ | | ♦ |
|__K| |__7| |__4|
You won $400!
--сокращено--
Описание работы
Символов для мастей карт на клавиатуре нет, поэтому нам приходится вызывать chr() для их отображения. Передаваемое в chr() целое число называется кодом символа (code point) кодировки Unicode, оно представляет собой уникальное число, идентифицирующее символ в соответствии со стандартом Unicode. Unicode часто понимают неправильно. Прекрасное введение в Unicode — доклад Неда Бачхелдера (Ned Batchelder) Pragmatic Unicode, or How Do I Stop the Pain?, сделанный на конференции PyCon US 2012. Вы можете найти его по адресу https://youtu.be/sgHbC6udIqc/. В приложении Б приведен полный список символов Unicode, которые можно использовать в программах Python.
1. """Блек-джек, (c) Эл Свейгарт al@inventwithpython.com
2. Классическая карточная игра, известная также как "двадцать одно".
3. (В этой версии нет страхования или разбиения.)
4. Больше информации — в статье https://ru.wikipedia.org/wiki/Блэкджек
5. Код размещен на сайте https://nostarch.com/big-book-small-python-projects
6. Теги: большая, игра, карточная игра"""
7.
8. import random, sys
9.
10. # Задаем значения констант:
11. HEARTS = chr(9829) # Символ 9829 — '♥'.
12. DIAMONDS = chr(9830) # Символ 9830 — '♦'.
13. SPADES = chr(9824) # Символ 9824 — '♠'.
14. CLUBS = chr(9827) # Символ 9827 — '♣'.
15. # (Список кодов chr можно найти в https://inventwithpython.com/charactermap)
16. BACKSIDE = 'backside'
17.
18.
19. def main():
20. print('''Blackjack, by Al Sweigart al@inventwithpython.com
21.
22. Rules:
23. Try to get as close to 21 without going over.
24. Kings, Queens, and Jacks are worth 10 points.
25. Aces are worth 1 or 11 points.
26. Cards 2 through 10 are worth their face value.
27. (H)it to take another card.
28. (S)tand to stop taking cards.
29. On your first play, you can (D)ouble down to increase your bet
30. but must hit exactly one more time before standing.
31. In case of a tie, the bet is returned to the player.
