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

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

Материал из Linuxformat
(Различия между версиями)
Перейти к: навигация, поиск
(Raspberry Pi Про­грам­ми­руй­те свой Pi на Scratch и Python)
(Ре­ше­ние про­блем)
 
(не показаны 6 промежуточных версий 1 участника)
Строка 11: Строка 11:
  
 
Мы на­пи­шем про­стую про­грам­му для ри­со­вания линий на эк­ране с по­мо­щью кла­виш управ­ления кур­со­ром. Пер­вое, что нам нуж­но – соз­дать код, ко­то­рый по­зво­лит пе­ре­ме­щать по эк­ра­ну кар­тин­ку с ко­том. Мы восполь­зу­ем­ся тре­мя от­дель­ны­ми бло­ка­ми, ка­ж­дый из ко­то­рых бу­дет за­пускать­ся по на­жа­тию кла­ви­ши.
 
Мы на­пи­шем про­стую про­грам­му для ри­со­вания линий на эк­ране с по­мо­щью кла­виш управ­ления кур­со­ром. Пер­вое, что нам нуж­но – соз­дать код, ко­то­рый по­зво­лит пе­ре­ме­щать по эк­ра­ну кар­тин­ку с ко­том. Мы восполь­зу­ем­ся тре­мя от­дель­ны­ми бло­ка­ми, ка­ж­дый из ко­то­рых бу­дет за­пускать­ся по на­жа­тию кла­ви­ши.
[[Файл: |left |100px |thumb|> Рис. 1. Бло­ки ок­ра­ше­ны в раз­ные цве­та — что­бы бы­ло по­нят­нее, из ка­ко­го ме­ню их вы­брать.]]  
+
[[Файл:LXF168.tut_rpi.scratch_opt.jpeg |left |400px |thumb|> Рис. 1. Бло­ки ок­ра­ше­ны в раз­ные цве­та — что­бы бы­ло по­нят­нее, из ка­ко­го ме­ню их вы­брать.]]  
 
На­жми­те Control [Управ­ление], за­тем пе­ре­та­щи­те в скрип­ты блок When Space Key Pressed [При на­жа­тии кла­ви­ши про­бе­ла]. Так соз­да­ет­ся скрипт, ко­то­рый за­пуска­ет­ся по на­жа­тию поль­зо­ва­те­лем этой кла­ви­ши. В вы­па­даю­щем спи­ске из­мените Space [Про­бел] на Right Arrow [Стрел­ка впра­во] и пе­ре­та­щи­те под него Move 10 steps [Пе­ре­мес­тить на 10 ша­гов]. Тогда при на­жа­тии стрел­ки впра­во кот бу­дет пе­ре­ме­щать­ся. За­тем соз­дай­те по­хо­жие скрип­ты, с ко­то­ры­ми кот бу­дет сво­ра­чи­вать вниз при на­жа­тии стрел­ки вниз и вверх при на­жа­тии стрел­ки вверх. На рис. 1 по­ка­за­но, как это долж­но вы­гля­деть. Те­перь мы мо­жем пе­ре­ме­щать­ся во всех на­прав­лениях, и оста­лось до­ба­вить блок, от­ве­чаю­щий за про­ри­сов­ку линий. Мы не бу­дем ри­со­вать постоянно, по­это­му восполь­зу­ем­ся дей­ст­вия­ми Scratch pen up [под­нять ка­ран­даш] и pen down [опустить ка­ран­даш]. Когда ка­ран­даш опу­щен, кот остав­ля­ет за со­бой след, когда поднят – не остав­ля­ет.
 
На­жми­те Control [Управ­ление], за­тем пе­ре­та­щи­те в скрип­ты блок When Space Key Pressed [При на­жа­тии кла­ви­ши про­бе­ла]. Так соз­да­ет­ся скрипт, ко­то­рый за­пуска­ет­ся по на­жа­тию поль­зо­ва­те­лем этой кла­ви­ши. В вы­па­даю­щем спи­ске из­мените Space [Про­бел] на Right Arrow [Стрел­ка впра­во] и пе­ре­та­щи­те под него Move 10 steps [Пе­ре­мес­тить на 10 ша­гов]. Тогда при на­жа­тии стрел­ки впра­во кот бу­дет пе­ре­ме­щать­ся. За­тем соз­дай­те по­хо­жие скрип­ты, с ко­то­ры­ми кот бу­дет сво­ра­чи­вать вниз при на­жа­тии стрел­ки вниз и вверх при на­жа­тии стрел­ки вверх. На рис. 1 по­ка­за­но, как это долж­но вы­гля­деть. Те­перь мы мо­жем пе­ре­ме­щать­ся во всех на­прав­лениях, и оста­лось до­ба­вить блок, от­ве­чаю­щий за про­ри­сов­ку линий. Мы не бу­дем ри­со­вать постоянно, по­это­му восполь­зу­ем­ся дей­ст­вия­ми Scratch pen up [под­нять ка­ран­даш] и pen down [опустить ка­ран­даш]. Когда ка­ран­даш опу­щен, кот остав­ля­ет за со­бой след, когда поднят – не остав­ля­ет.
  
Строка 18: Строка 18:
 
Что­бы пе­ре­во­дить ка­ран­даш из од­но­го со­стояния в дру­гое, нам ну­жен код, ко­то­рый бы помнил со­стояние ка­ран­да­ша. В про­грам­мах для это­го ис­поль­зу­ют­ся пе­ре­мен­ные. Пе­ре­мен­ная – это уча­сток па­мя­ти, ку­да мож­но за­пи­сать и от­ку­да мож­но счи­тать дан­ные.
 
Что­бы пе­ре­во­дить ка­ран­даш из од­но­го со­стояния в дру­гое, нам ну­жен код, ко­то­рый бы помнил со­стояние ка­ран­да­ша. В про­грам­мах для это­го ис­поль­зу­ют­ся пе­ре­мен­ные. Пе­ре­мен­ная – это уча­сток па­мя­ти, ку­да мож­но за­пи­сать и от­ку­да мож­но счи­тать дан­ные.
 
[[Файл:LXF168.tut_rpi.scratc_opt2.jpeg | |thumb|400px|> Рис. 3. Бло­ки If…Then по­зво­ля­ют ва­шей про­грам­ме при­ни­мать ре­ше­ние, и это крае­уголь­ный ка­мень про­грам­ми­ро­ва­ния.]]
 
[[Файл:LXF168.tut_rpi.scratc_opt2.jpeg | |thumb|400px|> Рис. 3. Бло­ки If…Then по­зво­ля­ют ва­шей про­грам­ме при­ни­мать ре­ше­ние, и это крае­уголь­ный ка­мень про­грам­ми­ро­ва­ния.]]
[[Файл: |LXF168.tut_rpi.scratc_opt3.jpeg |thumb|400px|> Рис. 4. Точ­но так же мож­но до­ба­вить фи­гу­ры в на­бор ин­ст­ру­мен­тов для ри­со­ва­ния.]]
+
[[Файл: LXF168.tut_rpi.scratc_opt3.jpeg ||thumb|400px|> Рис. 4. Точ­но так же мож­но до­ба­вить фи­гу­ры в на­бор ин­ст­ру­мен­тов для ри­со­ва­ния.]]
 
+
 
Пре­ж­де чем восполь­зо­вать­ся пе­ре­мен­ной, на­до ве­леть ком­пь­ю­те­ру вы­де­лить под нее па­мять. Мы так­же да­дим ей имя, что­бы об­ра­щать­ся к ней в ко­ман­дах. Зай­ди­те в Variables [Пе­ре­мен­ные], на­жми­те Make a Variable [Соз­дать пе­ре­мен­ную] и ука­жи­те ее имя. По­сле это­го вы уви­ди­те на­бор команд для из­менения или ис­поль­зо­вания этой пе­ре­мен­ной. Те­перь мы мо­жем хранить дан­ные, и нуж­но ве­леть ком­пь­ю­те­ру ме­нять свое по­ве­дение в за­ви­си­мо­сти от зна­чения пе­ре­мен­ной. Это де­ла­ет блок If…Else [Если...То]. Он про­ве­ря­ет, ис­тин­но ли вы­ра­жение. Ес­ли да, вы­пол­ня­ет­ся пер­вый блок ко­да, ес­ли нет – вто­рой. В на­шей про­грам­ме мы про­ве­ря­ем пе­ре­мен­ную pen. Ес­ли она рав­на 0, мы опуска­ем ка­ран­даш и уста­нав­ли­ва­ем ее в 1, а ина­че поднима­ем ка­ран­даш и уста­нав­ли­ва­ем ее в 0. Так мож­но пе­ре­клю­чать­ся ме­ж­ду дву­мя со­стояния­ми с по­мо­щью про­бе­ла. Взгляните на рис. 3 – вот как долж­на вы­гля­деть про­грам­ма. Об­ра­ти­те внимание на опе­ра­тор = в вы­ра­жении if. Оно оз­на­ча­ет, что пер­вый блок ко­да вы­пол­ня­ет­ся, толь­ко ес­ли пе­ре­мен­ная pen со­дер­жит (equals) 0, в про­тив­ном слу­чае (else) вы­пол­ня­ет­ся вто­рой блок.
 
Пре­ж­де чем восполь­зо­вать­ся пе­ре­мен­ной, на­до ве­леть ком­пь­ю­те­ру вы­де­лить под нее па­мять. Мы так­же да­дим ей имя, что­бы об­ра­щать­ся к ней в ко­ман­дах. Зай­ди­те в Variables [Пе­ре­мен­ные], на­жми­те Make a Variable [Соз­дать пе­ре­мен­ную] и ука­жи­те ее имя. По­сле это­го вы уви­ди­те на­бор команд для из­менения или ис­поль­зо­вания этой пе­ре­мен­ной. Те­перь мы мо­жем хранить дан­ные, и нуж­но ве­леть ком­пь­ю­те­ру ме­нять свое по­ве­дение в за­ви­си­мо­сти от зна­чения пе­ре­мен­ной. Это де­ла­ет блок If…Else [Если...То]. Он про­ве­ря­ет, ис­тин­но ли вы­ра­жение. Ес­ли да, вы­пол­ня­ет­ся пер­вый блок ко­да, ес­ли нет – вто­рой. В на­шей про­грам­ме мы про­ве­ря­ем пе­ре­мен­ную pen. Ес­ли она рав­на 0, мы опуска­ем ка­ран­даш и уста­нав­ли­ва­ем ее в 1, а ина­че поднима­ем ка­ран­даш и уста­нав­ли­ва­ем ее в 0. Так мож­но пе­ре­клю­чать­ся ме­ж­ду дву­мя со­стояния­ми с по­мо­щью про­бе­ла. Взгляните на рис. 3 – вот как долж­на вы­гля­деть про­грам­ма. Об­ра­ти­те внимание на опе­ра­тор = в вы­ра­жении if. Оно оз­на­ча­ет, что пер­вый блок ко­да вы­пол­ня­ет­ся, толь­ко ес­ли пе­ре­мен­ная pen со­дер­жит (equals) 0, в про­тив­ном слу­чае (else) вы­пол­ня­ет­ся вто­рой блок.
  
Строка 45: Строка 44:
 
» Day Dream Scratch – еще и пре­крас­ный ин­ст­ру­мент для соз­дания анима­ции. http://scratch.mit.edu/projects/cremeglace/40150
 
» Day Dream Scratch – еще и пре­крас­ный ин­ст­ру­мент для соз­дания анима­ции. http://scratch.mit.edu/projects/cremeglace/40150
  
ben_new2.psd
+
==Python==
 +
{{Врезка|right|Заголовок= Мо­ду­ли расширения|Ширина=40%|Содержание=
 +
Од­на из луч­ших осо­бен­но­стей Python – ко­ли­че­­ст­во мо­ду­лей рас­ши­рения для него. Су­ще­ст­ву­ют спо­со­бы до­ба­вить до­полнитель­ную функ­цио­наль­ность, ко­то­рой вы мо­же­те восполь­зо­вать­ся. Хо­тя, воз­мож­но, не все они под­хо­дят но­вич­кам, все рав­но сто­ит по­смот­реть, что вы смо­же­те сде­лать, когда луч­ше по­зна­ко­ми­тесь с язы­ком. Вот на­ши пять глав­ных мо­ду­лей Python.
 +
 
 +
» pyGames Иг­ры – это кру­то, про­грам­ми­ро­вание – то­же кру­то, а про­грам­ми­ро­вать иг­ры, ви­ди­мо, кру­че все­го. Этот мо­дуль по­мо­жет соз­дать соб­ст­вен­ные иг­ры для уби­вания вре­мени.
 +
 
 +
» pyGTK Ра­но или позд­но вы за­хо­ти­те уй­ти из команд­ной стро­ки и соз­да­вать гра­фи­че­­ские про­грам­мы. Этот мо­дуль по­мо­жет соз­да­вать их для GTK.
 +
 
 +
» pyQT GTK – это пре­крас­но, ес­ли вы поль­зуе­тесь Gnome, но поль­зо­ва­те­лям KDE боль­ше по­нра­вит­ся этот мо­дуль.
 +
 
 +
» RPi.GPIO В Raspberry Pi есть на­бор вхо­дов и вы­хо­дов об­ще­го на­зна­чения [General Purpose Input and Output – GPIO] для свя­зи с внешним ми­ром. Этот мо­дуль по­мо­жет ими поль­зо­вать­ся.
 +
 
 +
» NumPy Для умников, ко­то­рые лю­бят ма­те­ма­ти­ку! С ним лег­ко манипу­ли­ро­вать циф­ра­ми. }}
 +
Scratch от­лич­но под­хо­дит для изу­чения основ про­грам­ми­ро­вания, но ра­но или позд­но вы уп­ре­тесь в его ог­раничения. Те­перь мы рас­смот­рим по­пу­ляр­ный язык об­ще­го на­зна­чения Python. Пер­вое, что о нем нуж­но знать – в от­ли­чие от Scratch, он пол­но­стью тек­сто­вый. Не то что на нем нель­зя соз­да­вать гра­фи­че­­ские про­грам­мы – про­сто код про­грам­мы пред­став­ля­ет со­бой текст, а не пе­ре­тас­ки­вае­мые бло­ки.
 +
 
 +
По­это­му, что­бы на­пи­сать про­грам­му, от­крой­те тек­сто­вый ре­дак­тор. По­дой­дет лю­бой; по умол­чанию в Raspberry Pi есть Leafpad, им мы и восполь­зу­ем­ся; но ес­ли вы про­дол­жи­те про­грам­ми­ро­вать, сто­ит по­экс­пе­ри­мен­ти­ро­вать с дру­ги­ми и най­ти са­мый под­хо­дя­щий для се­бя (у но­вич­ков в Python до­воль­но по­пу­ля­рен Geany). Об­ра­ти­те внимание, что тек­сто­вые про­цес­со­ры, та­кие как LibreOffice Write или Abiword, не по­дой­дут: они на­ру­шат фор­ма­ти­ро­вание.
 +
 
 +
Соз­дай­те но­вый файл в Leafpad и до­бавь­те в пер­вую стро­ку сле­дую­щее:
 +
 
 +
#!/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 и сле­дую­щим син­так­си­сом:
 +
{{Врезка|right|Заголовок=Ин­те­рак­тив­ный ре­жим |Ширина=20%|Содержание=
 +
 
 +
По­ка что скрип­ты на Python мы за­пуска­ли, но это не един­ст­вен­ный спо­соб. С ним так­же мож­но ра­бо­тать в ин­те­рак­тив­ном ре­жи­ме: вво­дим стро­ку, Python ее об­ра­ба­ты­ва­ет, вво­дим сле­дую­щую, и т. д. Это от­лич­ный спо­соб бы­ст­ро что-нибудь оп­ро­бо­вать. Для вхо­да в обо­лоч­ку Python про­сто на­бе­ри­те python в команд­ной стро­ке. За­кон­чив, на­бе­ри­те exit() для воз­вра­та в обыч­ную обо­лоч­ку.
 +
 
 +
В ин­те­рак­тив­ном ре­жи­ме нам бы­ло осо­бен­но удоб­но экс­пе­ри­мен­ти­ро­вать с но­вы­ми биб­лио­те­ка­ми и за­пускать от­дель­ные ко­ман­ды, как в Bash.
 +
 
 +
По­сле вы­хо­да из ин­те­рак­тив­но­го ин­тер­пре­та­то­ра вся ва­ша ра­бо­та ис­чезнет, по­это­му про­грам­мы луч­ше пи­сать в тек­сто­вом ре­дак­то­ре, как мы и де­ла­ли на на­шем уро­ке. }}
 +
while <expression> :
 +
 
 +
<indent>code block
 +
 
 +
Мы мо­жем ос­та­но­вить про­грам­му, вве­дя имя quit. По­это­му наш цикл while бу­дет та­ким:
 +
 
 +
while name != ‘quit’ :
 +
 
 +
===Ре­ше­ние про­блем===
 +
 
 +
Не спра­ши­вай­те ме­ня – по­че­му, но воскли­ца­тель­ные зна­ки в про­грам­ми­ро­вании час­то оз­на­ча­ют от­ри­цание (not). Тем не менее, неболь­шая про­бле­ма все рав­но оста­ет­ся. Ес­ли по­мес­тить цикл перед присвоением name = raw_input…, поя­вит­ся со­об­щение об ошиб­ке: дескать, неиз­вест­но, что это за пе­ре­мен­ная name. А ес­ли по­мес­тить цикл по­сле присвоения, имя бу­дет за­про­ше­но все­го од­на­ж­ды, а да­лее цикл про­дол­жит бес­конеч­но вы­пле­вы­вать при­вет­ст­вия.
 +
 
 +
Что­бы ре­шить эту про­бле­му, мож­но про­сто при­сво­ить name пустую стро­ку пе­ред цик­лом while. Тогда со­об­щение об ошиб­ке ис­чезнет, и цикл начнет ра­бо­тать. Те­перь на­ша ма­лень­кая про­грам­ма вы­гля­дит так:
 +
 
 +
#!/usr/bin/python
 +
 
 +
name = ‘’
 +
 
 +
while name != ‘quit’ :
 +
 
 +
name = raw_input(‘Как вас зо­вут? ‘)
 +
 
 +
If name == ‘Бен’ :
 +
 
 +
print “Бен, ну ты крутой”
 +
 
 +
else :
 +
 
 +
print ‘Hello’, name
 +
 
 +
Об­ра­ти­те внимание: пе­ред ка­ж­дой стро­кой print уже че­ты­ре про­бе­ла – по­то­му, что у ка­ж­дой стро­ки два от­сту­па: один для цик­ла while и один для опе­ра­то­ра if. Мо­же­те со­хранить файл под именем hello.py, как и пре­ж­де, и за­пустить его ко­ман­дой ./hello.py.
 +
 
 +
{{Врезка|right|Заголовок= Ку­да же те­перь податься?|Ширина=98%|Содержание=
 +
Ес­ли вы сле­до­ва­ли за мной и вам по­нра­ви­лось пи­сать про­грам­мы, вы, на­вер­ное, за­ду­ма­лись, что де­лать даль­ше. Что ж, и Scratch, и Python от­лич­но под­хо­дят для на­ча­ла, и пре­ж­де все­го нуж­но вы­брать язык се­бе по ду­ше. Ес­ли это Scratch, луч­ше все­го на­чать с http://scratch.mit.edu. Здесь вы най­де­те для изу­чения мно­же­ст­во про­ек­тов дру­гих поль­зо­ва­те­лей и ви­део­ру­ко­вод­ст­ва по сре­де раз­ра­бот­ки.
  
 +
Python го­раз­до по­пу­лярнее в ре­аль­ном ми­ре, и вы смо­же­те най­ти мас­су ре­сур­сов по нему. На офи­ци­аль­ном сай­те (www.python.org) есть ру­ко­во­дство, ко­то­рое хо­ро­шо объ­яс­ня­ет язык, но слег­ка су­хо­ва­то.
  
 +
Есть несколь­ко от­лич­ных книг по этой те­ме (на­при­мер, “Dive into Python [Ны­ря­ем в Python]”, ко­то­рая прилагается на DVD этого номера журнала и ко­то­рую вы смож­ете про­чи­тать бес­плат­но на www.diveintopython.net).
  
> Рис. 1. Бло­ки ок­ра­ше­ны в раз­ные цве­та — что­бы бы­ло по­нят­нее, из ка­ко­го ме­ню их вы­брать.
+
Подпис­чи­ки бу­маж­ной вер­сии Linux Format найдут все наши пре­ды­ду­щие ру­ко­во­дства по Python в ар­хи­вах на www.linuxformat.com и в на­шей се­рии «Кон­цеп­ции про­грам­ми­ро­вания», где мы рас­ска­зы­ва­ем о глав­ных иде­ях, ле­жа­щих в осно­ве про­грам­ми­ро­вания. }}  |

Текущая версия на 17:34, 10 ноября 2018

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.


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