Журнал LinuxFormat - перейти на главную

LXF168Raspberry Pi. Про­грам­ми­ро­вание:

Материал из Linuxformat
Перейти к: навигация, поиск

Raspberry Pi: Про­грам­мы

Содержание

Raspberry Pi Про­грам­ми­руй­те свой Pi на Scratch и Python

Бен Эве­рард по­мо­га­ет осво­ить два стан­дарт­ных язы­ка, вхо­дя­щих в Raspbian, и на­пи­сать па­ру про­стых про­грамм.

(thumbnail)
> Рис. 2. По умол­ча­нию пе­ре­мен­ным при­сваи­ва­ет­ся зна­че­ние 0, а за их те­ку­щим зна­че­ни­ем мож­но сле­дить в об­лас­ти ри­со­ва­ния
(thumbnail)
Наш эксперт Бен Эве­рард ос­та­вил ра­бо­ту IT-кон­суль­тан­та и на два го­да от­пра­вил­ся в Тан­за­нию ус­та­нав­ли­вать сис­те­мы на ба­зе Ubuntu в ме­ст­ных шко­лах. Те­перь его зна­ния на­хо­дят при­ме­не­ние в бур­ля­щем кот­ле от­кры­тий – ре­дак­ции Linux Format.

На этом уро­ке мы вернем­ся к из­на­чаль­ной идее Raspberry Pi: обу­чению поль­зо­ва­те­лей но­вым тех­но­ло­ги­ям. На сле­дую­щих че­ты­рех страницах мы крат­ко прой­демся по двум язы­кам про­грам­ми­ро­вания, вхо­дя­щим в Raspbian, ре­ко­мен­дуе­мый ди­ст­ри­бу­тив для Pi. Ес­ли у вас нет Pi, вы все рав­но мо­же­те сле­до­вать за на­ми – про­сто уста­но­ви­те эти язы­ки че­рез менед­жер па­ке­тов. Ес­ли вы не про­грам­ми­ро­ва­ли рань­ше, не пе­ре­жи­вай­те: мы начнем бу­к­валь­но с ну­ля [англ. from scratch, – прим. пер.].

Scratch – пре­крас­ный язык для изу­чения основ про­грам­ми­ро­вания: с ним не нуж­но бес­по­ко­ить­ся о со­вер­шен­ст­ве ко­да. Так как про­грам­ма пи­шет­ся пу­тем пе­ре­тас­ки­вания бло­ков в скрипт, не при­дет­ся за­по­ми­нать ни од­ной ко­ман­ды.

Мы на­пи­шем про­стую про­грам­му для ри­со­вания линий на эк­ране с по­мо­щью кла­виш управ­ления кур­со­ром. Пер­вое, что нам нуж­но – соз­дать код, ко­то­рый по­зво­лит пе­ре­ме­щать по эк­ра­ну кар­тин­ку с ко­том. Мы восполь­зу­ем­ся тре­мя от­дель­ны­ми бло­ка­ми, ка­ж­дый из ко­то­рых бу­дет за­пускать­ся по на­жа­тию кла­ви­ши.

(thumbnail)
> Рис. 1. Бло­ки ок­ра­ше­ны в раз­ные цве­та — что­бы бы­ло по­нят­нее, из ка­ко­го ме­ню их вы­брать.

На­жми­те Control [Управ­ление], за­тем пе­ре­та­щи­те в скрип­ты блок When Space Key Pressed [При на­жа­тии кла­ви­ши про­бе­ла]. Так соз­да­ет­ся скрипт, ко­то­рый за­пуска­ет­ся по на­жа­тию поль­зо­ва­те­лем этой кла­ви­ши. В вы­па­даю­щем спи­ске из­мените Space [Про­бел] на Right Arrow [Стрел­ка впра­во] и пе­ре­та­щи­те под него Move 10 steps [Пе­ре­мес­тить на 10 ша­гов]. Тогда при на­жа­тии стрел­ки впра­во кот бу­дет пе­ре­ме­щать­ся. За­тем соз­дай­те по­хо­жие скрип­ты, с ко­то­ры­ми кот бу­дет сво­ра­чи­вать вниз при на­жа­тии стрел­ки вниз и вверх при на­жа­тии стрел­ки вверх. На рис. 1 по­ка­за­но, как это долж­но вы­гля­деть. Те­перь мы мо­жем пе­ре­ме­щать­ся во всех на­прав­лениях, и оста­лось до­ба­вить блок, от­ве­чаю­щий за про­ри­сов­ку линий. Мы не бу­дем ри­со­вать постоянно, по­это­му восполь­зу­ем­ся дей­ст­вия­ми Scratch pen up [под­нять ка­ран­даш] и pen down [опустить ка­ран­даш]. Когда ка­ран­даш опу­щен, кот остав­ля­ет за со­бой след, когда поднят – не остав­ля­ет.

При­меним пе­ре­мен­ные

Что­бы пе­ре­во­дить ка­ран­даш из од­но­го со­стояния в дру­гое, нам ну­жен код, ко­то­рый бы помнил со­стояние ка­ран­да­ша. В про­грам­мах для это­го ис­поль­зу­ют­ся пе­ре­мен­ные. Пе­ре­мен­ная – это уча­сток па­мя­ти, ку­да мож­но за­пи­сать и от­ку­да мож­но счи­тать дан­ные.

(thumbnail)
> Рис. 3. Бло­ки If…Then по­зво­ля­ют ва­шей про­грам­ме при­ни­мать ре­ше­ние, и это крае­уголь­ный ка­мень про­грам­ми­ро­ва­ния.
(thumbnail)
> Рис. 4. Точ­но так же мож­но до­ба­вить фи­гу­ры в на­бор ин­ст­ру­мен­тов для ри­со­ва­ния.

Пре­ж­де чем восполь­зо­вать­ся пе­ре­мен­ной, на­до ве­леть ком­пь­ю­те­ру вы­де­лить под нее па­мять. Мы так­же да­дим ей имя, что­бы об­ра­щать­ся к ней в ко­ман­дах. Зай­ди­те в Variables [Пе­ре­мен­ные], на­жми­те Make a Variable [Соз­дать пе­ре­мен­ную] и ука­жи­те ее имя. По­сле это­го вы уви­ди­те на­бор команд для из­менения или ис­поль­зо­вания этой пе­ре­мен­ной. Те­перь мы мо­жем хранить дан­ные, и нуж­но ве­леть ком­пь­ю­те­ру ме­нять свое по­ве­дение в за­ви­си­мо­сти от зна­чения пе­ре­мен­ной. Это де­ла­ет блок If…Else [Если...То]. Он про­ве­ря­ет, ис­тин­но ли вы­ра­жение. Ес­ли да, вы­пол­ня­ет­ся пер­вый блок ко­да, ес­ли нет – вто­рой. В на­шей про­грам­ме мы про­ве­ря­ем пе­ре­мен­ную pen. Ес­ли она рав­на 0, мы опуска­ем ка­ран­даш и уста­нав­ли­ва­ем ее в 1, а ина­че поднима­ем ка­ран­даш и уста­нав­ли­ва­ем ее в 0. Так мож­но пе­ре­клю­чать­ся ме­ж­ду дву­мя со­стояния­ми с по­мо­щью про­бе­ла. Взгляните на рис. 3 – вот как долж­на вы­гля­деть про­грам­ма. Об­ра­ти­те внимание на опе­ра­тор = в вы­ра­жении if. Оно оз­на­ча­ет, что пер­вый блок ко­да вы­пол­ня­ет­ся, толь­ко ес­ли пе­ре­мен­ная pen со­дер­жит (equals) 0, в про­тив­ном слу­чае (else) вы­пол­ня­ет­ся вто­рой блок.

Вве­дение в цик­лы

Те­перь мож­но пе­ре­ме­щать ко­та и ри­со­вать кар­ти­ну, но ведь здо­ро­во бы­ло бы до­бав­лять го­то­вые фи­гу­ры, на­при­мер, круж­ки? Сей­час мы это сде­ла­ем. Хотя с техниче­­ской точ­ки зрения мы до­ба­вим 24-сто­ронний мно­го­угольник – он очень по­хо­ж на круг.

Это де­ла­ет­ся так: сна­ча­ла move forward 10 [пе­ре­мес­тить­ся впе­ред на 10 ша­гов], за­тем rotate 15 degrees [по­вер­нуть на 15 гра­ду­сов], за­тем сно­ва forward 10 [пе­ре­мес­тить­ся впе­ред на 10 ша­гов], за­тем rotate 15 degrees [по­вер­нуть на 15 гра­ду­сов] и так да­лее, по­ка не по­лу­чит­ся ок­руж­ность. Мож­но по­мес­тить в код 24 па­ры строк, и код бу­дет ра­бо­тать, но это не очень хо­ро­шо: и вы­гля­дит некра­си­во, и тре­бу­ет мно­го вре­мени на соз­дание, а ес­ли вы ре­ши­те из­менить раз­мер ок­руж­но­сти, при­дет­ся это де­лать в 24 мес­тах.

Вза­мен мы при­меним цикл. Это блок, ко­то­рый по­вто­ря­ет сам се­бя. Есть несколь­ко ви­дов цик­лов – неко­то­рые по­вто­ря­ют­ся, по­ка некое вы­ра­жение не станет лож­ным (нечто вро­де мно­го­кратно по­вто­ряе­мой ко­ман­ды if); но мы восполь­зу­ем­ся тем, ко­то­рый по­вто­ря­ет­ся за­дан­ное ко­ли­че­­ст­во раз.

Внут­ри цик­ла нам нуж­ны все­го две ко­ман­ды: move forward 10 и rotate 15. Под­роб­но­сти по­ка­за­ны на рис. 4. Ва­ша пер­вая про­грам­ма на Scratch го­то­ва! Файл про­ек­та есть на DVD и на www.linuxformat.com/archives.

Про­грам­ми­ро­вание – не са­мо­цель, а спо­соб за­ста­вить ком­пь­ю­тер де­лать то, что нам нуж­но, и те­перь вас ог­раничи­ва­ет толь­ко во­об­ра­жение. Мо­же­те на­пи­сать стре­лял­ку, ра­бо­чее при­ло­жение или нечто фу­ту­ри­сти­че­­ское, для че­го и на­звания еще нет. Что­бы раз­бу­дить ва­ше во­об­ра­жение, вот несколь­ко про­ек­тов из Ин­тернета (ес­ли у вас уста­нов­лен Flash, их мож­но за­пустить в брау­зе­ре):

» Super Mario Galaxy Бе­гае­те по све­ту, со­би­рая звез­доч­ки. http://scratch.mit.edu/projects/Dolfus555/162167

» Wipeout На осно­ве те­ле­шоу. Гра­фи­ка так се­бе, но иг­рать ве­се­ло. http://scratch.mit.edu/projects/awesomestickdude/1149306

» Space War 4 Ста­рая стре­лял­ка косми­че­­ских ко­раб­лей с вер­тикаль­ной про­крут­кой. http://scratch.mit.edu/projects/illusionist/879463

» Snake Chamber По­зна­комь­тесь с генети­кой и раз­ве­дением змей! http://scratch.mit.edu/projects/DewleafWolf/2758178

» Day Dream Scratch – еще и пре­крас­ный ин­ст­ру­мент для соз­дания анима­ции. http://scratch.mit.edu/projects/cremeglace/40150

Python

Scratch от­лич­но под­хо­дит для изу­чения основ про­грам­ми­ро­вания, но ра­но или позд­но вы уп­ре­тесь в его ог­раничения. Те­перь мы рас­смот­рим по­пу­ляр­ный язык об­ще­го на­зна­чения Python. Пер­вое, что о нем нуж­но знать – в от­ли­чие от Scratch, он пол­но­стью тек­сто­вый. Не то что на нем нель­зя соз­да­вать гра­фи­че­­ские про­грам­мы – про­сто код про­грам­мы пред­став­ля­ет со­бой текст, а не пе­ре­тас­ки­вае­мые бло­ки.

По­это­му, что­бы на­пи­сать про­грам­му, от­крой­те тек­сто­вый ре­дак­тор. По­дой­дет лю­бой; по умол­чанию в Raspberry Pi есть Leafpad, им мы и восполь­зу­ем­ся; но ес­ли вы про­дол­жи­те про­грам­ми­ро­вать, сто­ит по­экс­пе­ри­мен­ти­ро­вать с дру­ги­ми и най­ти са­мый под­хо­дя­щий для се­бя (у но­вич­ков в Python до­воль­но по­пу­ля­рен Geany). Об­ра­ти­те внимание, что тек­сто­вые про­цес­со­ры, та­кие как LibreOffice Write или Abiword, не по­дой­дут: они на­ру­шат фор­ма­ти­ро­вание.

Соз­дай­те но­вый файл в Leafpad и до­бавь­те в пер­вую стро­ку сле­дую­щее:

  1. !/usr/bin/python

Эта стро­ка, несколь­ко за­га­доч­но на­зы­вае­мая «шап­кой», ве­лит сис­те­ме за­пускать наш файл с по­мо­щью про­грам­мы python в ка­та­ло­ге /usr/bin/. Эту стро­ку нуж­но ука­зы­вать в на­ча­ле всех сво­их про­грамм.

Те­перь пе­рей­дем к внут­рен­но­стям про­грам­ми­ро­вания. У про­грам­ми­стов есть дав­няя тра­ди­ция пер­вой пи­сать про­грам­му, вы­во­дя­щую на эк­ран сло­ва “Hello World!”, и мы не бу­дем из­ме­нять ей. Ос­тавь­те вто­рую стро­ку пустой (это не обя­за­тель­но, но так код луч­ше чи­та­ет­ся), а в треть­ей на­пи­ши­те:

print “Hello World!”

и со­храните свой труд в фай­ле hello.py. Для за­пуска про­грам­мы от­крой­те тер­ми­нал и пе­рей­ди­те в ка­та­лог, где вы со­хранили файл. Вы­полните ко­ман­ду chmod a+x hello.py, что­бы ска­зать сис­те­ме, что файл ис­пол­няе­мый, и вве­ди­те ./hello.py для его за­пуска. На эк­ране долж­но поя­вить­ся Hello World!

Про­грам­ма по­ка­зы­ва­ет, что сис­те­ма ра­бо­та­ет пра­виль­но, но про­ку от нее немно­го. Как и в про­ек­те Scratch, до­ба­вим немно­го поль­зо­ва­тель­ско­го вво­да. Од­на­ко с Python нуж­но до­ба­вить пе­ре­мен­ную для со­хранения то­го, что ввел поль­зо­ва­тель. Уда­ли­те стро­ку Hello World (оста­вив толь­ко «шап­ку») и до­бавь­те стро­ку:

name = raw_input(‘What is your name [Как вас зо­вут]? ‘)

В этой стро­ке соз­да­ет­ся пе­ре­мен­ная name, ото­бра­жа­ет­ся со­об­щение Как вас зо­вут?, и вве­ден­ные поль­зо­ва­те­лем дан­ные со­хра­ня­ют­ся в name. Со­об­щение мы за­клю­чи­ли в об­рат­ные ка­выч­ки, что­бы ком­пь­ю­тер знал, что это од­на стро­ка тек­ста. За­тем мы мо­жем восполь­зо­вать­ся этой пе­ре­мен­ной, что­бы вы­вес­ти чуть бо­лее пер­со­наль­ное со­об­щение опе­ра­то­ром print:

print ‘Hello’, name

Так как ком­пь­ю­тер вы­пол­ня­ет ко­ман­ды по оче­ре­ди, эта ко­ман­да долж­на быть ниже пре­ды­ду­щей. Ес­ли рас­по­ло­жить их в об­рат­ном по­ряд­ке, про­грам­ма вы­даст ошиб­ку, так как мы поль­зу­ем­ся пе­ре­мен­ной до то­го, как она соз­да­на. Те­перь со­храните файл и на­бе­ри­те ./hello.py в команд­ной стро­ке для за­пуска про­грам­мы.

Ре­шения, ре­шения

На­ша про­грам­ма ста­ла чуть бо­лее функ­цио­наль­ной, но все рав­но до­воль­но нежизнен­на. Она лишь вы­пол­ня­ет те же два дей­ст­вия и за­вер­ша­ет­ся. Что­бы она ста­ла по­лез­на, нуж­но до­ба­вить дей­ст­вие с при­ня­ти­ем ре­шения, когда ком­пь­ю­тер смот­рит на то, что ввел поль­зо­ва­тель, и в за­ви­си­мо­сти от это­го вы­пол­ня­ет раз­ные дей­ст­вия.

Помните блок if в Scratch? То же са­мое есть и здесь. Ба­зо­вая струк­ту­ра бло­ка та­ко­ва:

if <expression> :

<indent> code block

Здесь <expression> нуж­но за­менить вы­ра­жением, ко­то­рое мо­жет быть ис­тин­ным или лож­ным. На­при­мер, 1 > 2, или, что по­лезнее, num > 2, где num – пе­ре­мен­ная. В на­шем слу­чае мы про­ве­рим, что в ка­че­­ст­ве имени вве­де­но кон­крет­ное зна­чение:

if name == ‘Бен’ :

По­че­му == ? Ну, ком­пь­ю­те­ры (да и про­грам­ми­сты) не лю­бят неоп­ре­де­лен­но­сти. У ка­ж­до­го сим­во­ла или сло­ва долж­но быть толь­ко од­но зна­чение, ина­че мож­но за­пу­тать­ся. = ис­поль­зу­ет­ся для при­своения пе­ре­мен­ной зна­чения, по­это­му для про­вер­ки на ра­вен­ст­во нуж­но что-то еще. Опять же, «Бен» за­клю­че­но в об­рат­ные ка­выч­ки, что­бы ком­пь­ю­тер знал: это текст. Двое­то­чие оз­на­ча­ет, что вы­ра­жение за­кон­чи­лось и сей­час мы ска­жем компьютеру, что де­лать.

Ко­ман­де if мо­жет по­на­до­бить­ся вы­пол­нять боль­ше од­ной стро­ки ко­да – зна­чит, ну­жен спо­соб объ­е­ди­нять код в бло­ки. В Python для это­го ис­поль­зу­ют­ся от­сту­пы (Python в этом от­но­шении бо­лее или менее уника­лен, и это кость в горле для нена­ви­стников Python). В ка­че­­ст­ве от­сту­пов мож­но ис­поль­зо­вать про­бе­лы или та­бу­ля­цию, но в од­ном про­ек­те важ­но поль­зо­вать­ся чем-то одним, по­то­му что зна­чение име­ет не раз­мер, а чис­ло от­сту­пов. Лич­но я ис­поль­зую от­ступ на два про­бе­ла, по­то­му что ме­ня учи­ли так, и я ниче­го не хо­чу ме­нять.

Итак, что дол­жен сде­лать ком­пь­ю­тер, ес­ли name == ‘Бен’? Ну, ра­зу­ме­ет­ся, мы долж­ны по­при­вет­ст­во­вать Бе­на со­от­вет­ст­вен­но:

if name == ‘Бен’ :

print “Бен, you’re awesome [ну ты кру­той]”

Об­ра­ти­те внимание на два про­бе­ла в на­ча­ле вто­рой стро­ки, а так­же на двой­ные ка­выч­ки. Двой­ные ка­выч­ки нуж­ны по­то­му, что внут­ри фра­зы есть апо­ст­роф. Дру­гим лю­дям мы то­же гру­бить не бу­дем, по­это­му до­ба­вим блок else, вы­пол­няе­мый во всех слу­ча­ях, когда усло­вие в if лож­но:

else :

print ‘Hello’, name

По­след­няя воз­мож­ность, ко­то­рую мы до­ба­вим в про­грам­му – цикл. Он очень по­хож на цикл из про­грам­мы на Scratch, толь­ко что вы­пол­ня­ет­ся не 24 раза, а до тех пор, по­ка мы не ве­лим ему оста­но­вить­ся. Для это­го восполь­зу­ем­ся цик­лом while и сле­дую­щим син­так­си­сом:

while <expression> :

<indent>code block

Мы мо­жем ос­та­но­вить про­грам­му, вве­дя имя quit. По­это­му наш цикл while бу­дет та­ким:

while name != ‘quit’ :

Ре­ше­ние про­блем

Не спра­ши­вай­те ме­ня – по­че­му, но воскли­ца­тель­ные зна­ки в про­грам­ми­ро­вании час­то оз­на­ча­ют от­ри­цание (not). Тем не менее, неболь­шая про­бле­ма все рав­но оста­ет­ся. Ес­ли по­мес­тить цикл перед присвоением name = raw_input…, поя­вит­ся со­об­щение об ошиб­ке: дескать, неиз­вест­но, что это за пе­ре­мен­ная name. А ес­ли по­мес­тить цикл по­сле присвоения, имя бу­дет за­про­ше­но все­го од­на­ж­ды, а да­лее цикл про­дол­жит бес­конеч­но вы­пле­вы­вать при­вет­ст­вия.

Что­бы ре­шить эту про­бле­му, мож­но про­сто при­сво­ить name пустую стро­ку пе­ред цик­лом while. Тогда со­об­щение об ошиб­ке ис­чезнет, и цикл начнет ра­бо­тать. Те­перь на­ша ма­лень­кая про­грам­ма вы­гля­дит так:

  1. !/usr/bin/python

name = ‘’

while name != ‘quit’ :

name = raw_input(‘Как вас зо­вут? ‘)

If name == ‘Бен’ :

print “Бен, ну ты крутой”

else :

print ‘Hello’, name

Об­ра­ти­те внимание: пе­ред ка­ж­дой стро­кой print уже че­ты­ре про­бе­ла – по­то­му, что у ка­ж­дой стро­ки два от­сту­па: один для цик­ла while и один для опе­ра­то­ра if. Мо­же­те со­хранить файл под именем hello.py, как и пре­ж­де, и за­пустить его ко­ман­дой ./hello.py.


Персональные инструменты
купить
подписаться
Яндекс.Метрика