Raspberry Pi 日記

長嶋 洋一


2013年6月7日(金)

朝は久しぶりの小雨だったが、午後から山口に出発する頃には晴れて、あとは週末まで晴れそうである。 1限の終わりにアポを入れていた4回生の藤本さんとメイルで何往復かしたが、前回の作品「植物会議」( ) の続編として、今度は50個ほどのLEDとモーターを付けるのだという(^_^;)。 これは「SUAC board」の出番だと思うが、とりあえず以下のようにメイルしてみた。
インスタで多数の入出力の事例を以下に紹介しますので、来週までに研究してみて下さい。

●SUACインスタレーション(1)
http://nagasm.org/1106/installation/index.html
以下のそれぞれの作品解説の部分にあるリンクを参照

靄夜(もや) LED64個
Chessでポン! スイッチ64個
段虎 LED240個
磨く LED168個
ハコロ スイッチ24個

●SUACインスタレーション(2)
http://nagasm.org/1106/installation2/index.html
以下のそれぞれの作品解説の部分にあるリンクを参照

風見屏風(かざみびょうぶ) モーター100個
Cyber Kendang LED320個
Beat Box スイッチ384個
Octagon パソコン8台
circles LED168個
団欒 -だんらん- タッチスイッチ8個
白い絵本 RFIDカード15枚、磁気センサ5個
電子十二影坊 (Dodeca Propeller) マイコン13個、ビデオ12系統
はやくスシになりたい RFIDカード15枚
おはなしパネル RFIDセンサ(15枚用)×4系統
OTOkakecco マウス4個
ネジマキウォール ステッピングモーター100個(モーター400回路分)

●SUACインスタレーション(3)
http://nagasm.org/1106/installation3/index.html
以下のそれぞれの作品解説の部分にあるリンクを参

Fantastic World Journey ! スイッチ24個
二人はウラハラ RFIDカード15枚、パソコン3台
海潮音 可動金属板168枚、ソレノイド5個
双極灯のヒ モーター50個
girl's apartment パソコン10台
日本の住まいに木の文化を取り戻す提案 スイッチ25個
Revolution-J 改造ジャミネータ5台
OTOcakecco 衝撃センサ21個、3色LED21個(LED63個分)
双極式箱庭 モーター50個
カラーオーケストラ IDキューブ44個(個別電子回路内蔵)
誰かを待つ街 LED24個
植物会議 LED6個、モーター6個、センサ2個
Nepic 紫外線センサ24個

●ArduinoやPropellerから周辺回路を増設するために僕が作った基板の情報です
(望月さんの作品に使いました)

だいたい
http://nagasm.org/ASL/Propeller2/index4.html
あたりから読み始めて、
http://nagasm.org/ASL/Propeller3/index3.html
まで続きます。
この最後のページには、過去のインスタの技術情報もまとめてます
仮ゼミの土佐谷さんの「傘に仕込む加速度センサ」、「しゃみーず」の改造三味線用タッチセンサ、そしてこの藤本さんのシステムの支援、と、いよいよあれこれ製作モードに追われる日々が迫ってきているのを実感する(^_^)。 今週末の出張が終わると、とりあえずRaspberry Piを横に置いて、ハンダごてがテーブルの中央に陣取りそうである。

さて、2限のゼミ(とその直前に動態保存の作品「植物会議」の借用に来る藤本さん)までの約1時間、昨日のおさらいである。 アプリケーションとしてインストールした「Python」フォルダにリンクが置かれていたドキュメントHTMLの本体は、「file:///Library/Frameworks/Python.framework/Versions/3.3/Resources/English.lproj/Documentation/index.html」にインストールされていた。 この「Tutorial」は「file:///Library/Frameworks/Python.framework/Versions/3.3/Resources/English.lproj/Documentation/tutorial/index.html」にあり、最初の「2. Using the Python Interpreter」の先頭「2.1. Invoking the Interpreter」によれば、IDLEが起動しなくても関係なく、ターミナルで「python3.3」と入れればいいのであった。 以下のように無事、起動した。(^_^)

昨日のスクリーンショットでも連発したが、この画面はもはやターミナルではなくてPythonインタプリタなので、「ls」とか「pwd」とやっても駄目なのである(^_^;)。 使い方はチュートリアルに従って、なぞっていくしかないので、まぁ、いい英語の勉強である。 ターミナルで「python3.3」と入れたらPythonが起動したのは、「/usr/local/bin」という、通常シェルのパスが通っている場所にインストールされているためなので、Windowsではパスを指定する必要があるというが、ここは華麗にスルーである。(^_^;)

Pythonインタプリタを抜けてターミナルに戻るには、「>>>」というプロンプト直後に「ctrl+D」である。 「quit()」というコマンドでも同様に戻ることが出来た。 その後なにやらゴチャゴチャ書かれているところは、あまり重要でもなさそうなのでパスした。 その次の「2.1.1. Argument Passing」も、呼ばれた事に返すargの話のようだが、華麗にスルーした。

その次は「2.1.2. Interactive Mode」であるが、これはちょっと面倒くさい予感が出て来た(^_^;)。 サンプルリストをコピペでPythonインタプリタ画面に入れたのに、エラーが出たのである。 「>>>」のプロンプトで、まず「the_world_is_flat = 1」と入れた。 そしてまた出て来た「>>>」のプロンプトで、「if the_world_is_flat:」と入れると、続いての入力を待つということで、プロンプトが「...」になったので、ここで「print("Be careful not to fall off!")」を入れたら、サンプルでは表示される筈なのに、エラーが出たのだ。 試してみると、「...」の後に入れたのが駄目だったようで、タブでインデントしないといけないらしい。 改めてインデントしたら、以下のようにOKだった。 こういうのを「面倒くさい奴」と言う。Propellerのspin言語が、まさにこれである(^_^;)。 Pythonは、CやJavaのようにスペースやタブのインデントを無視してくれず、人間はインデントを意識しなければならないのだろうか。 それとも、これはインタプリタに限定した条件なのだろうか。

nagasm-Mac-mini:~ nagasm$ python3.3
Python 3.3.2 (v3.3.2:d047928ae3f6, May 13 2013, 13:52:24) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> the_world_is_flat = 1
>>> if the_world_is_flat:
... print("Be careful not to fall off!")
  File "", line 2
    print("Be careful not to fall off!")
        ^
IndentationError: expected an indented block
>>> if the_world_is_flat:
...     print("Be careful not to fall off!")
... 
Be careful not to fall off!
>>> 
タブでなくスペースだとどうなるか、と試してみると、なんと以下のように超・面倒くさいことが判明してきた。 こりゃ、なんか理念とは別に、Pythonにはあまり深入りしたくないカモ。(^_^;) こりゃ、なかなかPythonは繊細である。というか面倒くさい。 とりあえず次の「2.2. The Interpreter and Its Environment」に進む。 最初の「2.2.1. Error Handling」はパス。 次の「2.2.2. Executable Python Scripts」というのは、Pythonスクリプトを複数行のプログラムとして書いた時に、最初の行に「#! /usr/bin/env python3.3」というおまじないを入れておけば、「Python」に続けて呼び出すと、シェルスクリプトのように実行できるという。 また「$ chmod +x myscript.py」とすれば、Pythonナシでも実行可能に出来るという。 ここは重要そうなので実験してみると、以下のように、出来た。 見やすくするためにスペースを挟んでみたが、sudoでパーミッションを変えて実行可能にすればいいのであった。
nagasm-Mac-mini:Desktop nagasm$ cat test.py
#! /usr/bin/env python3.3
print("Hello, World (^_^)")

nagasm-Mac-mini:Desktop nagasm$ Python test.py
Hello, World (^_^)

nagasm-Mac-mini:Desktop nagasm$ test.py
-bash: test.py: command not found

nagasm-Mac-mini:Desktop nagasm$ ./test.py
-bash: ./test.py: Permission denied

nagasm-Mac-mini:Desktop nagasm$ $ chmod +x test.py
-bash: $: command not found

nagasm-Mac-mini:Desktop nagasm$ sudo chmod +x test.py
Password:

nagasm-Mac-mini:Desktop nagasm$ test.py
-bash: test.py: command not found

nagasm-Mac-mini:Desktop nagasm$ ./test.py
Hello, World (^_^)

nagasm-Mac-mini:Desktop nagasm$ 
「sudo chmod +x test.py」によって完成したPythonプログラムを、「sudo cp test.py /usr/local/bin/」としてPATHの通っている場所にコピーすれば、「./」を添えることなくどこからでも実行できる。 またその後に、「sudo mv /usr/local/bin/test.py /usr/local/bin/test」とやって拡張子を取れば、もはやどこからでも「test」という名前によって、ターミナルとかシェルで実行できるプログラムになるわけである。 これは今後、Pythonの機能を活用して、Raspberry Piのバックグラウンドで走るサービスプログラムに活用する予定である。 この後の「2.2.3. Source Code Encoding」はとりあえず「UTF-8」なのでパス、「2.2.4. The Interactive Startup File」と「2.2.5. The Customization Modules」もあまり重要そうでもないのでパスすることにした。

ここで午前中にゼミがあり、その後、大学から浜松駅に行き昼食。 そして新山口に向かう「のぞみ」に名古屋で乗り継ぐ「こだま」を待つ待合室で、次章、「3. An Informal Introduction to Python」からのスタートである。 「Formal」であるよりは期待できるかもしれない(^_^;)。 最初に「コメントアウトは[#}」というのがあったが、まぁこれは普通である。 当然だと思うが、以下のように、文字列としてダブルコーテーションで囲まれた中の[#}は無視される。

nagasm-3:Desktop nagasm$ cat test.py
#! /usr/bin/env python3.3
# this is the first comment
SPAM = 1                 # and this is the second comment
                         # ... and now a third!
STRING = "# This is not a comment."
print(STRING)

nagasm-3:Desktop nagasm$ Python test.py
# This is not a comment.

nagasm-3:Desktop nagasm$
次のトピックはインタプリタでは定番の「3.1. Using Python as a Calculator」である。 いちいちトレースするほどの事もなく、斜め読みでいこう。 まずは「3.1.1. Numbers」である。 Pythonでは「7/3」は「2.3333333333333335」であり、「7//3」とすると整数の商として「2」になった。 変数については、嬉しいことに以下のように型宣言など不要で使えるようだ。
>>> x = y = z = 0  # Zero x, y and z
>>> x
0
>>> y
0
>>> z
0
浮動小数点に関して、以下のようにいじわるテストをしたが、ちゃんとしていた。 さすがである。(^_^)
>>> 1+1
2
>>> 1/3
0.3333333333333333
>>> 7/3
2.3333333333333335
>>> 7//3
2
>>> 1/3*3
1.0
>>> (1/3) * 3.0
1.0
>>> 3*(1/3)
1.0
>>> 1/3/3*9
1.0
これまで使ったことが無かったが、以下のように複素数も出来るらしい。 これは素晴らしい。(^_^)
>>> 1j * 1J
(-1+0j)
>>> 1j * complex(0, 1)
(-1+0j)
>>> 3+1j*3
(3+3j)
>>> (3+1j)*3
(9+3j)
>>> (1+2j)/(1+1j)
(1.5+0.5j)
記述の規則はちょっとJavaっぽいが、以下のように複素数の実部と虚部も取り出せるらしい。 だからといって、Pythonでフーリエ変換をする事は無いと思うが。(^_^;)
>>> a=1.5+0.5j
>>> a.real
1.5
>>> a.imag
0.5
ここから「こだま」車内である。 整数部のint()と小数部のfloat()という便利なものもあるが、当然ながら以下のようにこれは実数にしか効かないという。 そりゃ当然だ。(^_^;)
>>> a=3.0+4.0j
>>> float(a)
Traceback (most recent call last):
  File "", line 1, in ?
TypeError: can't convert complex to float; use abs(z)
>>> abs(a)  # sqrt(a.real**2 + a.imag**2)
5.0
Pythonのインタラクタティブモードでは、最後に表示された数値が後で「_」で参照できるという。 まさに電卓だが、このアイデアはなかなか面白い。 ただし、この変数「_」はread onlyで、ここに値を割り当てる変数として使っては駄目である。
>>> tax = 12.5 / 100
>>> price = 100.50
>>> price * tax
12.5625
>>> price + _
113.0625
>>> round(_, 2)
113.06
数値はほぼ想定内であった。 「こだま」が豊橋に着くあたり、次は「3.1.2. Strings」である。 文字列の柔軟な取り扱いについてはJavaが出て来たときに驚き、JavaScriptでまた驚いた。 アセンブラ/Cの世代には常に新鮮なのである(^_^;)。 いきなり以下の例に驚いた。 こんなの覚えられないぞ。(^_^;)
>>> 'spam eggs'
'spam eggs'
>>> 'doesn\'t'
"doesn't"
>>> "doesn't"
"doesn't"
>>> '"Yes," he said.'
'"Yes," he said.'
>>> "\"Yes,\" he said."
'"Yes," he said.'
>>> '"Isn\'t," she said.'
'"Isn\'t," she said.'
考えてみれば、このMcBook Airでは「バックスラッシュ」も辞書登録していなかった(^_^;)。 さっそく、「\」を「ば」で登録した。 「\n\」というのが、以下のように「長い行を繋ぐ」のに使われるらしい。
nagasm-3:Desktop nagasm$ cat test.py
#! /usr/bin/env python3.3
hello = "This is a rather long string containing\n\
several lines of text just as you would do in C.\n\
    Note that whitespace at the beginning of the line is\
 significant."
print(hello)

nagasm-3:Desktop nagasm$ Python test.py
This is a rather long string containing
several lines of text just as you would do in C.
    Note that whitespace at the beginning of the line is significant.
nagasm-3:Desktop nagasm$ 
だんだん次第にPythonのテキスト関係の変態さが出て来たようで、3つ連結したダブルコーテーションとかシングルコーテーションの以下の使い方はもう、ほぼ変態である。(^_^;)
>>> print("""\
... Usage: thingy [OPTIONS]
...      -h                        Display this usage message
...      -H hostname               Hostname to connect to
... """)
Usage: thingy [OPTIONS]
     -h                        Display this usage message
     -H hostname               Hostname to connect to
>>> 
文字列の「+」での連結はJavaで驚いて知っていたが、かけ算は参った(^_^;)。 やはり変態っぽい気がするが、これを活用すると「F5連打」のようなサイト攻撃ツールは簡単になるのかな。
>>> word = 'Help' + 'A'
>>> word
'HelpA'
>>> '<' + word*5 + '>'
''
なんとPythonでは「+」ナシでも、文字列をただ並べていると自動的に連結してくれるという。 余計なお世話のようだが、さらに以下のように「+」との混在はややこしい(^_^;)。
>>> 'str' 'ing'                   #  <-  This is ok
'string'
>>> 'str'.strip() + 'ing'   #  <-  This is ok
'string'
>>> 'str'.strip() 'ing'     #  <-  This is invalid
  File "", line 1, in ?
    'str'.strip() 'ing'
                      ^
SyntaxError: invalid syntax
Maxの「zl」を思い出すが、文字列から配列のように適当な場所の文字を取り出す、以下のようなものもあるらしい。
>>> word = 'Help' + 'A'
>>> word
'HelpA'
>>> word[4]
'A'
>>> word[0:2]
'He'
>>> word[2:4]
'lp'
>>> word[:2]    # The first two characters
'He'
>>> word[2:]    # Everything except the first two characters
'lpA'
三河安城を出たあたりでますますPythonの変態度は上がってきた(^_^;)。 Pythonでは以下のように、なんとC言語のように文字列の変更(文字単位の代入)ができないのだ。
>>> word = 'Help' + 'A'
>>> word
'HelpA'
>>> word[0] = 'x'
Traceback (most recent call last):
  File "", line 1, in ?
TypeError: 'str' object does not support item assignment
>>> word[:1] = 'Splat'
Traceback (most recent call last):
  File "", line 1, in ?
TypeError: 'str' object does not support slice assignment
そこでということか、取り出した文字列を自在に連結することで新しい文字列を作るという事らしい。 以下のように、文字列を参照するポインタがマイナスでも機能するあたり、まぁ変態であろう。(^_^;)
>>> word = 'Help' + 'A'
>>> word
'HelpA'>>> 'x' + word[1:]
'xelpA'
>>> 'Splat' + word[4]
'SplatA'
>>> word[:2] + word[2:]
'HelpA'
>>> word[:3] + word[3:]
'HelpA'
>>> word[1:100]
'elpA'
>>> word[10:]
''
>>> word[2:1]
''
>>> word[-1]     # The last character
'A'
>>> word[-2]     # The last-but-one character
'p'
>>> word[-2:]    # The last two characters
'pA'
>>> word[:-2]    # Everything except the last two characters
'Hel'
>>> word[-0]     # (since -0 equals 0)
'H'
>>> word[-100:]
'HelpA'
>>> word[-10]    # error
Traceback (most recent call last):
  File "", line 1, in ?
IndexError: string index out of range
解説として「One way to remember how slices work is to think of the indices as pointing between characters, with the left edge of the first character numbered 0. Then the right edge of the last character of a string of n characters has index n.」とあり、以下の図があるが、こんなのとても覚えきれないぞ。(^_^;)
上の図の解説は「The first row of numbers gives the position of the indices 0...5 in the string; the second row gives the corresponding negative indices. The slice from i to j consists of all characters between the edges labeled i and j, respectively. For non-negative indices, the length of a slice is the difference of the indices, if both are within bounds. For example, the length of word[1:3] is 2.」という事である。 勝手にしろ、というカンジである(^_^;)。

名古屋駅で「のぞみ」に乗り換えての続きである。 この「文字列」のトピックの末尾には、以下のリファレンスへのリンクが並んでいる。 これを全部追いかけたら、山口に着いても終わらないので、あっさりとパスする事にした。

次は「3.1.3. About Unicode」であるが、これは興味ないのでパスである。 その次は「3.1.4. Lists」である。 これは数値も文字列もごった煮にした「配列」ということだろうか。 ここを外すことは出来ないので眺めてみたが、さすがPython、以下のようにかなり自由である。
>>> a = ['spam', 'eggs', 100, 1234]
>>> a
['spam', 'eggs', 100, 1234]
>>> a[0]
'spam'
>>> a[3]
1234
>>> a[-2]
100
>>> a[1:-1]
['eggs', 100]
>>> a[:2] + ['bacon', 2*2]
['spam', 'eggs', 'bacon', 4]
>>> 3*a[:3] + ['Boo!']
['spam', 'eggs', 100, 'spam', 'eggs', 100, 'spam', 'eggs', 100, 'Boo!']
>>> a[:]
['spam', 'eggs', 100, 1234]
>>> a
['spam', 'eggs', 100, 1234]
>>> a[2] = a[2] + 23
>>> a
['spam', 'eggs', 123, 1234]
>>> # Replace some items:
... a[0:2] = [1, 12]
>>> a
[1, 12, 123, 1234]
>>> # Remove some:
... a[0:2] = []
>>> a
[123, 1234]
>>> # Insert some:
... a[1:1] = ['bletch', 'xyzzy']
>>> a
[123, 'bletch', 'xyzzy', 1234]
>>> # Insert (a copy of) itself at the beginning
>>> a[:0] = a
>>> a
[123, 'bletch', 'xyzzy', 1234, 123, 'bletch', 'xyzzy', 1234]
>>> # Clear the list: replace all items with an empty list
>>> a[:] = []
>>> a
[]
お約束のlen()だけでなく、文字列のネスティングもPythonはアリだった(^_^;)。 これもMaxの「prepend」「append」を思い出す、リストの連結ももちろんOKである。
>>> a = ['a', 'b', 'c', 'd']
>>> len(a)
4

>>> q = [2, 3]
>>> p = [1, q, 4]
>>> len(p)
3
>>> p[1]
[2, 3]
>>> p[1][0]
2
>>> p[1].append('xtra')
>>> p
[1, [2, 3, 'xtra'], 4]
>>> q
[2, 3, 'xtra']
「のぞみ」が岐阜羽島を通過する頃になって、ようやく、「3.2. First Steps Towards Programming」にやってきた(^_^)。 さて、いよいよプログラミングだ。 最初の例はフィボナッチ数列の計算・表示であるが、ここで気になっていたインデントを再び試してみると、「while」のループ内で、「インデント無し」はエラーだったが、以下のように「スペース1個」「スペース2個」「タブ1個」「タブ2個」は全てOKだった。 ちょっと安心した。(^_^;)
nagasm-3:Desktop nagasm$ cat test.py
#! /usr/bin/env python3.3
a, b = 0, 1
while b < 10:
print(b)
a, b = b, a+b

nagasm-3:Desktop nagasm$ Python test.py
  File "test.py", line 4
    print(b)
        ^
IndentationError: expected an indented block

nagasm-3:Desktop nagasm$ cat test.py
#! /usr/bin/env python3.3
a, b = 0, 1
while b < 10:
 print(b)
 a, b = b, a+b

nagasm-3:Desktop nagasm$ Python test.py
1
1
2
3
5
8

nagasm-3:Desktop nagasm$ cat test.py
#! /usr/bin/env python3.3
a, b = 0, 1
while b < 10:
  print(b)
  a, b = b, a+b

nagasm-3:Desktop nagasm$ Python test.py
1
1
2
3
5
8

nagasm-3:Desktop nagasm$ cat test.py
#! /usr/bin/env python3.3
a, b = 0, 1
while b < 10:
	print(b)
	a, b = b, a+b

nagasm-3:Desktop nagasm$ Python test.py
1
1
2
3
5
8

nagasm-3:Desktop nagasm$ cat test.py
#! /usr/bin/env python3.3
a, b = 0, 1
while b < 10:
		print(b)
		a, b = b, a+b

nagasm-3:Desktop nagasm$ Python test.py
1
1
2
3
5
8

nagasm-3:Desktop nagasm$ 
print()の書式は以下のように、ほぼ一般的である。 これはまぁ、助かる。
>>> i = 256*256
>>> print('The value of i is', i)
The value of i is 65536
そして以下のように、フィボナッチ数列をもっとたくさん表示するために、なんとコンマを指定することが出来るらしい。 このあたりは、さすがPythonというところかな。 ちょぅど「のぞみ」は京都に着いて、このセクションは終わりである。
>>> a, b = 0, 1
>>> while b < 1000:
...     print(b, end=',')
...     a, b = b, a+b
...
1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,
いよいよ次章は「4. More Control Flow Tools」、プログラミングのための本格的な制御構造である。 まぁ、CでもJavaでもspinでも、幾種類となく触れて来たものなので、そんじょそこらの変態度では驚かないぞ(^_^;)。 最初は「4.1. if Statements」からである。 いきなり以下のように、Pythonでは「elif」という単語が出て来た。 うーーーむ、気持ちは判るけど・・・。
>>> x = int(input("Please enter an integer: "))
Please enter an integer: 42
>>> if x < 0:
...      x = 0
...      print('Negative changed to zero')
... elif x == 0:
...      print('Zero')
... elif x == 1:
...      print('Single')
... else:
...      print('More')
...
More
次は「4.2. for Statements」である。 いきなり「The for statement in Python differs a bit from what you may be used to in C or Pascal.」ということで、身構える。 Pythonでは、「for」は以下のように再帰的に使えるということであるが、これは、君子危うきに近づかず、という事になりそうである。(^_^;)
>>> # Measure some strings:
... words = ['cat', 'window', 'defenestrate']
>>> for w in words:
...     print(w, len(w))
...
cat 3
window 6
defenestrate 12

>>> for w in words[:]:  # Loop over a slice copy of the entire list.
...     if len(w) > 6:
...         words.insert(0, w)
...
>>> words
['defenestrate', 'cat', 'window', 'defenestrate']
次は「4.3. The range() Function」である。 これは知らないので、ちょっと楽しみだが、どうやら数値の領域について再帰的にやってくれる組み込み関数らしい。
>>> for i in range(5):
...     print(i)
...
0
1
2
3
4

>>> a = ['Mary', 'had', 'a', 'little', 'lamb']
>>> for i in range(len(a)):
...     print(i, a[i])
...
0 Mary
1 had
2 a
3 little
4 lamb
ここまでは判ったが、次のサンプルで悩んでいるうちに新大阪を過ぎた。 以下のように、ステップについて解説しているのだが、これを実行して表示できないのだ。(^_^;)
range(5, 10)
   5 through 9

range(0, 10, 3)
   0, 3, 6, 9

range(-10, -100, -30)
  -10, -40, -70
以下の最初の部分にあった現象で悩んでいるうちに、もう新神戸になった。 そして、さらに後の「In many ways the object returned by range() behaves as if it is a list, but in fact it isn’t. It is an object which returns the successive items of the desired sequence when you iterate over it, but it doesn’t really make the list, thus saving space.」と「We say such an object is iterable, that is, suitable as a target for functions and constructs that expect something from which they can obtain successive items until the supply is exhausted. We have seen that the for statement is such an iterator.」という解説で、ようやく以下のように「list()」を使って以下のように表示できた。
>>> print(range(10))
range(0, 10)

>>> list(range(5))
[0, 1, 2, 3, 4]

>>> list(range(5, 10))
[5, 6, 7, 8, 9]

>>> list(range(0, 10, 3))
[0, 3, 6, 9]

>>> list(range(-10, -100, -30))
[-10, -40, -70]
>>> 
新神戸を出て、次は「4.4. break and continue Statements, and else Clauses on Loops」である。 これもよくある制御系であるが、まぁbreakを使うというのは既に危ないのである(^_^;)。 Pythonの例は以下であった。
>>> for n in range(2, 10):
...     for x in range(2, n):
...         if n % x == 0:
...             print(n, 'equals', x, '*', n//x)
...             break
...     else:
...         # loop fell through without finding a factor
...         print(n, 'is a prime number')
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3
PythonではC言語と同様に、breakとともにcontinueというのに以下のように対応しているという。 僕はbreakはswitch()で使うだけで、ifでは使わないようにしているりで、continueを使った記憶はあまり無い。 これを使わないと絶対に書けないロジックはたぶん無いし、使わないに越したことはないだろう。
>>> for num in range(2, 10):
...     if num % 2 == 0:
...         print("Found an even number", num)
...         continue
...     print("Found a number", num)
Found an even number 2
Found a number 3
Found an even number 4
Found a number 5
Found an even number 6
Found a number 7
Found an even number 8
Found a number 9
次のトピックは「4.5. pass Statements」だという。 なんだこれは。 passとは、名前のように「何もしない」という。 以下の例を見ても、何もピンと来ない。(^_^;)
>>> while True:
...     pass  # Busy-wait for keyboard interrupt (Ctrl+C)
...

>>> class MyEmptyClass:
...     pass
...

>>> def initlog(*args):
...     pass   # Remember to implement this!
...
次は「4.6. Defining Functions」である。 なんだかSuperColliderを思い出す。 しかし、ここで岡山までの時間を費やして、どうやらPythonのバグにひっかかった(^_^;)。 ここにある以下のサンプルをコピペでなく、実際に実行させようとしても出来ないのである。
>>> def fib(n):    # write Fibonacci series up to n
...     """Print a Fibonacci series up to n."""
...     a, b = 0, 1
...     while a < n:
...         print(a, end=' ')
...         a, b = b, a+b
...     print()
...
>>> # Now call the function we just defined:
... fib(2000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
やってみると以下のようになるのである。 これは試してみると、以前にあったdefを使わないサンプルでも同様であった。
nagasm-3:Desktop nagasm$ cat test.py
#! /usr/bin/env python3.3
def fib(n):    # write Fibonacci series up to n
	a, b = 0, 1
	while a < n:
		print(a, end=' ')
		a, b = b, a+b
fib(2000)

nagasm-3:Desktop nagasm$ Python test.py
  File "test.py", line 5
    print(a, end=' ')
                ^
SyntaxError: invalid syntax

nagasm-3:Desktop nagasm$
Pythonのチュートリアルのサンブルとして載っている、つまり「出来る」はずのコードでエラーが出るのである。 あれこれリファレンスを探ってみると、以下のように、ちゃんとprint()の書式の中に、「end=' '」と記述できる筈なのに。
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)

Print objects to the stream file, separated by sep and followed by 
end. sep, end and file, if present, must be given as keyword arguments.

All non-keyword arguments are converted to strings like str() does 
and written to the stream, separated by sep and followed by end. 
Both sep and end must be strings; they can also be None, which means 
to use the default values. If no objects are given, print() will just write end.

The file argument must be an object with a write(string) method; if it is 
not present or None, sys.stdout will be used. Whether output is buffered 
is usually determined by file, but if the flush keyword argument is true, 
the stream is forcibly flushed.

Changed in version 3.3: Added the flush keyword argument.
・・・どうしてもこの部分が解決できないまま、新山口まであと1時間となった。 別に結果を横に並べて表示できなくても本質的には関係ないとはいえ、なんか気持ち悪い(^_^;)。 仕方ないので、以下のようにして、続けようと思い切るまでにiPadで数曲を聞いて気を落ち着けた。
nagasm-3:Desktop nagasm$ cat test.py
#! /usr/bin/env python3.3
def fib(n):    # write Fibonacci series up to n
	a, b = 0, 1
	while a < n:
		print(a)
		a, b = b, a+b
fib(2000)

nagasm-3:Desktop nagasm$  Python test.py
0
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597

nagasm-3:Desktop nagasm$ 
このdefine関数は、以下のように値を返すサブルーチンにもなる。 まぁ、これもよくあるものだ。 ただし以下については、Pythonのチュートリアルのサンブルと違う。 バグを発見したので、ちゃんと出るように直してある。(^_^;)
nagasm-3:Desktop nagasm$ cat test.py
#! /usr/bin/env python3.3
def fib2(n): # return Fibonacci series up to n
	result = []
	a, b = 0, 1
	while a < n:
		result.append(a)
		a, b = b, a+b
	return result

f100 = fib2(100)
print(f100)

nagasm-3:Desktop nagasm$ Python test.py
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

nagasm-3:Desktop nagasm$
ここで広島、あと新山口まで30分である。 次には「4.7. More on Defining Functions」ということで「4.7.1. Default Argument Values」とか「4.7.2. Keyword Arguments」とか「4.7.3. Arbitrary Argument Lists」とか「4.7.4. Unpacking Argument Lists」とか「4.7.5. Lambda Forms」とか「4.7.6. Documentation Strings」とか「4.7.7. Function Annotations」とか「Intermezzo: Coding Style」とかあったが、あまりソソラレなかったので華麗にスルーした(^_^;)。 これでこの章はおしまいである。

「のぞみ」が広島駅を出発するのと同時に「5. Data Structures」のセクションとなった。 最初は何故か補遺ということで「5.1. More on Lists」とあり、以下のようにリストに追加されるメソッドがずらりと並んだ。 こりゃコピペ整形するだけで新山口に着いてしまいそうであるが、たぶん重要なのでメモとして置いておこう。 Maxの膨大な「zl」ファミリと同じようなものかな。

以下がそのサンプルだという。 ただしコピペなので、実際に走らせたらバグがある可能性は排除できない(^_^;)。
>>> a = [66.25, 333, 333, 1, 1234.5]
>>> print(a.count(333), a.count(66.25), a.count('x'))
2 1 0
>>> a.insert(2, -1)
>>> a.append(333)
>>> a
[66.25, 333, -1, 333, 1, 1234.5, 333]
>>> a.index(333)
1
>>> a.remove(333)
>>> a
[66.25, -1, 333, 1, 1234.5, 333]
>>> a.reverse()
>>> a
[333, 1234.5, 1, 333, -1, 66.25]
>>> a.sort()
>>> a
[-1, 1, 66.25, 333, 333, 1234.5]
そして次は「5.1.1. Using Lists as Stacks」である。 なんだか、このあたりから次第にPythonの自由なデータ構造の変態世界に入っていきそうな予感がある(^_^;)。 以下がサンプルだというが、リストをスタックとして使うなんて、良い子はやってはイケナイのではないか。
>>> stack = [3, 4, 5]
>>> stack.append(6)
>>> stack.append(7)
>>> stack
[3, 4, 5, 6, 7]
>>> stack.pop()
7
>>> stack
[3, 4, 5, 6]
>>> stack.pop()
6
>>> stack.pop()
5
>>> stack
[3, 4]
この次は「5.1.2. Using Lists as Queues」である。 このあたりもまた、SuperColliderとかProcessingとかを思い出してしまう。 あまりデータ構造とかに凝ったことが無かった、と思い知らされる。
>>> from collections import deque
>>> queue = deque(["Eric", "John", "Michael"])
>>> queue.append("Terry")           # Terry arrives
>>> queue.append("Graham")          # Graham arrives
>>> queue.popleft()                 # The first to arrive now leaves
'Eric'
>>> queue.popleft()                 # The second to arrive now leaves
'John'
>>> queue                           # Remaining queue in order of arrival
deque(['Michael', 'Terry', 'Graham'])
次は「5.1.3. List Comprehensions」である。 一瞥すると、ここはちょっと厄介そうである。 ちょうど新山口もあと10分というところなので、ここで新幹線車中お勉強をオシマイにして、パソコンを仕舞うことにしよう。 これだけお勉強できるというのは、テンションが上がる出張ならではの醍醐味である(^_^;)。

「Raspberry Pi日記」トップに戻る