LXF161:Хакерство: Raspberry Pi
|
|
|
Raspberry Pi Начните знакомство с Linux и новым карманным компьютером
Содержание |
Raspberry Pi: Рулим Guido
Raspberry Pi был создан, чтобы научить детей программированию. Джонатан Робертс представляет идеальную среду для начинающих: Guido van Robot.
В двух наших первых руководствах по Raspberry Pi мы задали вам разгон. Мы объяснили, как настроить RPi и убедиться, что все работает нормально. Мы также познакомили вас с основными навыками работы в Linux, включая управление пакетами и удаленный доступ к SSH и VNC. Если у вас только появился Raspberry Pi и вам не терпится начать, вы сможете найти эти два руководства на диске этого месяца.
На этом уроке мы хотим сделать нечто иное. Мы рассмотрим Raspberry Pi в качестве платформы для обучения программированию, а для этого воспользуемся приложением под названием Guido van Robot (сокращенно – GvR).
Черепашки и роботы
Если вы выросли в Великобритании и учились в школе в компьютерную эпоху BBC, вы, возможно, помните черепашек и LOGO, несложный язык программирования, в котором было всего несколько команд. У черепашки была ручка для рисования разных фигур, и с помощью правильных команд в LOGO вы могли нарисовать любую фигуру (существовали даже физические версии, которые разгуливали по столам и полам).
Нарисовать квадрат в LOGO можно было командами
FORWARD 100
LEFT 90
FORWARD 100
LEFT 90
FORWARD 100
LEFT 90
FORWARD 100
LEFT 90
Этот язык программирования учил детей основам – как разбивать решение проблемы на шаги, необходимые для ее решения, то есть мыслить в виде процедур. Именно этому мы обучим вас на нашем уроке, только вместо LOGO у нас будет Guido van Robot.
Прежде чем приступать к чему бы то ни было, установите GvR на ваш Raspberry Pi, чтобы вы могли следовать инструкциям нашего руководства. Это делается запуском LXTerminal из меню приложений и вводом
sudo apt-get install gvrng pythongtksourceview2
Если, взглянув на эту команду, вы решили, что она бессмысленна, загляните во второе руководство по Raspberry Pi на диске: «Строим NAS».
Знакомьтесь: Guido
Установив GvR, можете запускать его из меню приложений в нижней левой части экрана – оно находится пониже подменю Education. В появившемся окне вы увидите место для Guido и его мира в левой части, и место для инструкций, которые вы будете ему давать, и для создания его мира в правой части.
Давайте начнем со знакомства с миром Guido. Первое, что надо сделать – скопировать файлы в папке GvR на диске этого месяца в ваш Raspberry Pi. Можете использовать для этого любой удобный для вас способ, но самым простым будет USB-брелок, если вы используете для доступа SSH или VNC, поскольку в этом случае один из портов USB остается свободным. Затем переключитесь на вкладку World Editor в правой части окна, выберите File > Open [Файл > Открыть] и GvR1.wld. Левая часть мира заполнится изображениями, представляющими мир Guido, а сам Guido символизируется треугольником с буквой G.
Мир Guido похож на наш (ну, на американский город точно похож): он состоит из улиц (протянувшихся с востока на запад) и авеню (идущих с севера на юг), и окружен крепкими внешними стенами, через которые Guido не может перебраться. На пересечении каждой улицы и авеню располагается угол.
В этом мире есть еще пара вещей. Beeper – это такой маленький маячок-пищалка, который можно поместить на углу. Он издает сигналы, которые Guido может расслышать, только находясь на том же углу. Имеются также внутренние стены – они, как и внешние, для Guido непроходимы. В мире GvR1, помимо Guido, есть единственный маячок, представленный голубым кружком.
Первые шаги
Guido – не самый продвинутый робот. Он умеет выполнять только пять действий:
- move [двигаться]
- turnleft [повернуть налево]
- pickbeeper [взять маячок]
- putbeeper [поставить маячок]
- turnoff [выключить]
Команда move заставляет Guido двигаться по единственной улице или авеню вперед, а команда turnleft заставляет его повернуться на 90 градусов влево. Если вы, например, хотите, чтобы Guido передвинулся вперед на три авеню, вам нужно позаботиться, чтобы он смотрел в нужном направлении (задав нужное число в командах turnleft) и затем задать три команды move.
В этом первом мире все, что нам от вас нужно, ограничивается перемещением Guido к маячку, возможностью его взять, переместить его на один угол дальше и затем выключить его. Это означает, что Guido остановится на углу 4-й авеню и 2-й улицы.
Чтобы сделать это, переключитесь со вкладки World Editor на вкладку Code Editor. Затем можете ввести любую комбинацию из вышеприведенных команд в текстовое поле справа, поставив каждую из них на собственную строку, чтобы Guido переместился к маячку и взял его. Когда у вас будет набор команд, который, по вашему мнению, должен будет сработать, нажмите на Execute и посмотрите, что произойдет.
Помните, что Guido может слышать маячок, только находясь на одном углу с ним – а команда pickbeeper срабатывает только тогда, когда маячок есть в наличии. Если вы попытаетесь использовать pickbeeper при отсутствии маячка, то получите сообщение об ошибке, и вам придется перезапустить программу, что делается посредством нажатия Reload.
Компактнее — удобнее
Как дела? Если все сработало, значит, у вас должен получиться примерно такой набор инструкций:
move
turnleft
turnleft
turnleft
move
move
pickbeeper
move
turnoff
Самая хитрая часть этой проблемы – повернуть направо. Поскольку Guido не знает, как это сделать, вам придется осознать, что один поворот направо равен трем поворотам налево.
Это довольно громоздко и затрудняет чтение нашей программы: если бы у нашей программы была проблема – например, Guido неправильно повернулся и пришел к стене, от которой он и начал – было бы трудно понять, что подразумевалось под всеми этими turnleft и что один был явно лишним. Это также означает, что нам придется писать одно и то же много раз, а поскольку мы – ленивые программисты, нам это совсем не нравится!
К счастью, Guido не так глуп, как кажется на первый взгляд. Хотя на данный момент он знает только пять команд, он быстро учится, и он готов, чтобы мы научили его чему-то новому на основе того, что ему уже известно. Иными словами, мы можем сделать подборку инструкций, таких, как три turnlefts, дать ей название, и Guido будет исполнять ее каждый раз, когда мы введем это название.
Схватывает на лету
Чтобы это продемонстрировать, и чтобы сделать наш код более легким для чтения, менее ошибочным и более быстрым для ввода, давайте научим Guido поворачивать направо. Для этого нам надо будет использовать новый вид инструкции:
define turnright:
turnleft
turnleft
turnleft
Первая строка сообщает Guido, что мы определили новую инструкцию под названием turnright. Строки с отступом, следующие за двоеточием – это уже существующие команды в том порядке, в котором они должны выполняться, когда мы хотим, чтобы Guido повернул направо.
Отступ играет важную роль. Все строки с отступом считаются частью определения define. Как только вы введете строку без отступа, GvR будет считать, что введенное больше не является частью определения.
Чтобы использовать это в программе, вам нужно поставить определение наверх, а все остальные команды разместить внизу, таким образом:
define turnright:
turnleft
turnleft
turnleft
move
turnright
move
Попробуйте переписать нашу первую программу, но используйте инструкцию turnright вместо трех turnleft. Разве не проще стало читать?
Повторяемся
К этому моменту вы освоили первый мир, так что давайте перейдем к чему-нибудь поинтереснее. Переключитесь снова на вкладку World Editor на правой стороне и выберите File > Open, на сей раз открыв файл GvR2.wld. Это похожий мир, за исключением того, что здесь нет стены позади маячка, и все расстояния увеличены (возможно, вам придется расширить окно и перетащить линию, разделяющую панели мира и редактора, чтобы увидеть маячок).
Цель та же: Guido должен переместиться к маячку, взять его, переместить на один угол дальше и выключить. Мы может сделать это точно так же, как раньше, отдельно указывая каждое движение и каждый поворот, но, поскольку сейчас все находится на большем расстоянии, это будет выглядеть так же путано, как раньше все эти многочисленные turnleft.
К счастью, Guido знает еще несколько команд, которые несколько облегчат нашу задачу. Первая из тех, которые мы собираемся рассмотреть – команда do. Выглядит она так:
do <number>:
<instructions>
Как видите, по формату она подобна команде define. Сначала мы сообщим Guido, что это команда do, созданная для повторения любых <instructions> [инструкций] указанное <number> [количество] раз. В GvR2 мы можем использовать ее, чтобы начать нашу программу так:
do 4:
move
Это намного быстрее, чем вводить четыре отдельных команды move. Более того, если нам нужно выполнить 100 перемещений, на это потребуется ровно такое же количество инструкций. Попробуйте написать оставшуюся часть программы для GvR2 с помощью отдельных команд move, а потом с помощью команд do, и обратите внимание, насколько последняя короче.
Время принятия решений
Еще одна способность Guido – принимать решения. Например, Guido может спросить: «На этом углу есть маячок?» и решить исполнять pickbeepers только при его наличии. Или он может спросить, есть ли перед ним стена, и двинуться вперед, только если путь свободен. Формат для этого типа команды таков:
if <condition>:
<instructions>
Здесь вам все знакомо, за исключением условия. Это – вопрос, который задает Guido, и есть подборка вопросов, которые он умеет задавать. Их 18, и все они перечислены во вкладке Language Reference интерфейса GvR.
Вы увидите, что все они являются вопросами типа Да/Нет, с ответами true [истинно] или false [ложно] – это единственный тип вопросов, с которыми Guido (и большинство компьютеров) могут работать.
Вот пример того, как можно написать код, который обеспечит движение вперед только при отсутствии стены перед Guido.
if front_is_clear:
move
Иногда вы, возможно, решите проверить, является ли условие истинным, и выполнить действие, если оно таково, или другое действие, если условие ложно. Это можно сделать с помощью команды if ... else ..., которая используется так:
if front_is_clear:
move
else:
turnoff
Можно даже проверять множественные условия, с помощью команды if ... elif ...
else:
if front_is_clear:
move
elif right_is_clear:
turnright
move
elif left_is_clear:
turnleft
move
else:
turnoff
Конечное else является опциональным. Оно обеспечивает ответ на ситуацию по умолчанию: если все остальное ложно, делайте это – так что обычно его стоит использовать.
Помимо простого предоставления Guido возможности принимать самостоятельные решения, вы можете увидеть, насколько это может быть удобно. Где-то в начале этого руководства вы увидели, что, если вы попытаетесь выполнить команду pickbeeper при отсутствии маячка на углу, где находится Guido, вы получите ошибку, и программа остановится. Если бы вы сделали ошибки в других частях программы, вы, возможно, увидели бы то же самое, попытавшись провести Guido через стену. Условные инструкции позволяют нам добавлять безопасную проверку нашего кода, чтобы программа не завершала свою работу из-за такой ошибки.
Еще раз повторимся
Можно также использовать условные инструкции с помощью другой команды повторения: while. Эта инструкция проверяет, истинно ли условие, исполняет команду – или последовательность команд – в своем теле (части с отступом), а затем еще раз проверяет истинность условия. Если да, она снова исполнит «тело», и будет повторять это до тех пор, пока условие не окажется ложным. Мы говорим, что она будет зациклена на теле команды.
С командой while стоит быть поосторожнее. Если вы укажете условие, которое никогда не станет ложным, есть риск застрять в бесконечном цикле. Как и большинства других бесконечных вещей, бесконечных циклов лучше избегать
С помощью цикла while мы можем далее усовершенствовать нашу программу GvR2, сделав ее безопаснее и дав больше управления Guido. После первой партии команд move для перемещения Guido на нужную улицу и разворота его на восток, мы можем использовать команду while, чтобы перемещать его вперед, пока он не окажется на том же углу, что и маячок:
while not_next_to_a_beeper:
move
pickbeepers
move
Собрав воедино все, чему мы научились, мы можем завершить программу GvR2 всего за 10 строк. Используй мы только основные команды, у нас это заняло бы 20 строк. Наша программа стала не только короче – она стала более ясной, и ее можно с легкостью расширить для более крупных и сложных миров.
Мы рассказали вам все, что нужно знать о Guido. То, чему вы научились на нашем уроке, поможет вам заставить его делать более умные вещи, например, находить выход из лабиринта, чтобы найти в конце маячок в качестве приза.
Другие проекты
Для решения проблемы лабиринта у вас должен быть файл maze.wld, поставляемый с установкой GvR по умолчанию. Как и в предыдущих проблемах, вариантов ее решения множество: например, указать каждый шаг по отдельности, или поступить более разумно и дать Guido шанс самостоятельно принимать соответствующие решения. Советуем попробовать оба способа.
Если лабиринт покажется вам нудным, и вы захотите создать собственные миры, загляните в наш раздел «Создание Миров [World building]» – там есть инструкции для этого. |