Raspberry Pi 日記
長嶋 洋一
2013年6月7日(金)
朝は久しぶりの小雨だったが、午後から山口に出発する頃には晴れて、あとは週末まで晴れそうである。 1限の終わりにアポを入れていた4回生の藤本さんとメイルで何往復かしたが、前回の作品「植物会議」( ★ ★ ★ ) の続編として、今度は50個ほどのLEDとモーターを付けるのだという(^_^;)。 これは「SUAC board」の出番だと思うが、とりあえず以下のようにメイルしてみた。仮ゼミの土佐谷さんの「傘に仕込む加速度センサ」、「しゃみーず」の改造三味線用タッチセンサ、そしてこの藤本さんのシステムの支援、と、いよいよあれこれ製作モードに追われる日々が迫ってきているのを実感する(^_^)。 今週末の出張が終わると、とりあえずRaspberry Piを横に置いて、ハンダごてがテーブルの中央に陣取りそうである。インスタで多数の入出力の事例を以下に紹介しますので、来週までに研究してみて下さい。 ●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 まで続きます。 この最後のページには、過去のインスタの技術情報もまとめてますさて、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のようにスペースやタブのインデントを無視してくれず、人間はインデントを意識しなければならないのだろうか。 それとも、これはインタプリタに限定した条件なのだろうか。
タブでなくスペースだとどうなるか、と試してみると、なんと以下のように超・面倒くさいことが判明してきた。 こりゃ、なんか理念とは別に、Pythonにはあまり深入りしたくないカモ。(^_^;)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は繊細である。というか面倒くさい。 とりあえず次の「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でパーミッションを変えて実行可能にすればいいのであった。
- タブでインデントしないと、「IndentationError: expected an indented block」というエラーで叱られた(上述)
- タブを入れると、正常に反応して表示された(上述)
- 全角モードでスペースを入れると、「??」と表示されてブザーが鳴って叱られる
- 半角モードでスペースを入れると、何も反応しないで無視されて「...」のまま
- 半角モードで2個スペースを入れると、「IndentationError: unexpected indent」というエラーで叱られた
「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」もあまり重要そうでもないのでパスすることにした。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$ここで午前中にゼミがあり、その後、大学から浜松駅に行き昼食。 そして新山口に向かう「のぞみ」に名古屋で乗り継ぐ「こだま」を待つ待合室で、次章、「3. An Informal Introduction to Python」からのスタートである。 「Formal」であるよりは期待できるかもしれない(^_^;)。 最初に「コメントアウトは[#}」というのがあったが、まぁこれは普通である。 当然だと思うが、以下のように、文字列としてダブルコーテーションで囲まれた中の[#}は無視される。
次のトピックはインタプリタでは定番の「3.1. Using Python as a Calculator」である。 いちいちトレースするほどの事もなく、斜め読みでいこう。 まずは「3.1.1. Numbers」である。 Pythonでは「7/3」は「2.3333333333333335」であり、「7//3」とすると整数の商として「2」になった。 変数については、嬉しいことに以下のように型宣言など不要で使えるようだ。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$浮動小数点に関して、以下のようにいじわるテストをしたが、ちゃんとしていた。 さすがである。(^_^)>>> 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記述の規則はちょっとJavaっぽいが、以下のように複素数の実部と虚部も取り出せるらしい。 だからといって、Pythonでフーリエ変換をする事は無いと思うが。(^_^;)>>> 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)ここから「こだま」車内である。 整数部のint()と小数部のfloat()という便利なものもあるが、当然ながら以下のようにこれは実数にしか効かないという。 そりゃ当然だ。(^_^;)>>> a=1.5+0.5j >>> a.real 1.5 >>> a.imag 0.5Pythonのインタラクタティブモードでは、最後に表示された数値が後で「_」で参照できるという。 まさに電卓だが、このアイデアはなかなか面白い。 ただし、この変数「_」はread onlyで、ここに値を割り当てる変数として使っては駄目である。>>> 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 数値はほぼ想定内であった。 「こだま」が豊橋に着くあたり、次は「3.1.2. Strings」である。 文字列の柔軟な取り扱いについてはJavaが出て来たときに驚き、JavaScriptでまた驚いた。 アセンブラ/Cの世代には常に新鮮なのである(^_^;)。 いきなり以下の例に驚いた。 こんなの覚えられないぞ。(^_^;)>>> tax = 12.5 / 100 >>> price = 100.50 >>> price * tax 12.5625 >>> price + _ 113.0625 >>> round(_, 2) 113.06考えてみれば、このMcBook Airでは「バックスラッシュ」も辞書登録していなかった(^_^;)。 さっそく、「\」を「ば」で登録した。 「\n\」というのが、以下のように「長い行を繋ぐ」のに使われるらしい。>>> '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.'だんだん次第にPythonのテキスト関係の変態さが出て来たようで、3つ連結したダブルコーテーションとかシングルコーテーションの以下の使い方はもう、ほぼ変態である。(^_^;)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$文字列の「+」での連結はJavaで驚いて知っていたが、かけ算は参った(^_^;)。 やはり変態っぽい気がするが、これを活用すると「F5連打」のようなサイト攻撃ツールは簡単になるのかな。>>> 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 >>>なんとPythonでは「+」ナシでも、文字列をただ並べていると自動的に連結してくれるという。 余計なお世話のようだが、さらに以下のように「+」との混在はややこしい(^_^;)。>>> word = 'Help' + 'A' >>> word 'HelpA' >>> '<' + word*5 + '>' '' Maxの「zl」を思い出すが、文字列から配列のように適当な場所の文字を取り出す、以下のようなものもあるらしい。>>> '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 三河安城を出たあたりでますますPythonの変態度は上がってきた(^_^;)。 Pythonでは以下のように、なんとC言語のように文字列の変更(文字単位の代入)ができないのだ。>>> 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'そこでということか、取り出した文字列を自在に連結することで新しい文字列を作るという事らしい。 以下のように、文字列を参照するポインタがマイナスでも機能するあたり、まぁ変態であろう。(^_^;)>>> 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 解説として「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.」とあり、以下の図があるが、こんなのとても覚えきれないぞ。(^_^;)>>> 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 上の図の解説は「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、以下のようにかなり自由である。
- Text Sequence Type ― str
Strings are examples of sequence types, and support the common operations supported by such types.- String Methods
Strings support a large number of methods for basic transformations and searching.- String Formatting
Information about string formatting with str.format() is described here.- printf-style String Formatting
The old formatting operations invoked when strings and Unicode strings are the left operand of the % operator are described in more detail here.お約束のlen()だけでなく、文字列のネスティングもPythonはアリだった(^_^;)。 これもMaxの「prepend」「append」を思い出す、リストの連結ももちろんOKである。>>> 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 []「のぞみ」が岐阜羽島を通過する頃になって、ようやく、「3.2. First Steps Towards Programming」にやってきた(^_^)。 さて、いよいよプログラミングだ。 最初の例はフィボナッチ数列の計算・表示であるが、ここで気になっていたインデントを再び試してみると、「while」のループ内で、「インデント無し」はエラーだったが、以下のように「スペース1個」「スペース2個」「タブ1個」「タブ2個」は全て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']print()の書式は以下のように、ほぼ一般的である。 これはまぁ、助かる。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$そして以下のように、フィボナッチ数列をもっとたくさん表示するために、なんとコンマを指定することが出来るらしい。 このあたりは、さすがPythonというところかな。 ちょぅど「のぞみ」は京都に着いて、このセクションは終わりである。>>> i = 256*256 >>> print('The value of i is', i) The value of i is 65536いよいよ次章は「4. More Control Flow Tools」、プログラミングのための本格的な制御構造である。 まぁ、CでもJavaでもspinでも、幾種類となく触れて来たものなので、そんじょそこらの変態度では驚かないぞ(^_^;)。 最初は「4.1. if Statements」からである。 いきなり以下のように、Pythonでは「elif」という単語が出て来た。 うーーーむ、気持ちは判るけど・・・。>>> 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.2. for Statements」である。 いきなり「The for statement in Python differs a bit from what you may be used to in C or Pascal.」ということで、身構える。 Pythonでは、「for」は以下のように再帰的に使えるということであるが、これは、君子危うきに近づかず、という事になりそうである。(^_^;)>>> 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.3. The range() Function」である。 これは知らないので、ちょっと楽しみだが、どうやら数値の領域について再帰的にやってくれる組み込み関数らしい。>>> # 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']ここまでは判ったが、次のサンプルで悩んでいるうちに新大阪を過ぎた。 以下のように、ステップについて解説しているのだが、これを実行して表示できないのだ。(^_^;)>>> 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以下の最初の部分にあった現象で悩んでいるうちに、もう新神戸になった。 そして、さらに後の「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()」を使って以下のように表示できた。range(5, 10) 5 through 9 range(0, 10, 3) 0, 3, 6, 9 range(-10, -100, -30) -10, -40, -70新神戸を出て、次は「4.4. break and continue Statements, and else Clauses on Loops」である。 これもよくある制御系であるが、まぁbreakを使うというのは既に危ないのである(^_^;)。 Pythonの例は以下であった。>>> 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] >>>PythonではC言語と同様に、breakとともにcontinueというのに以下のように対応しているという。 僕はbreakはswitch()で使うだけで、ifでは使わないようにしているりで、continueを使った記憶はあまり無い。 これを使わないと絶対に書けないロジックはたぶん無いし、使わないに越したことはないだろう。>>> 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次のトピックは「4.5. pass Statements」だという。 なんだこれは。 passとは、名前のように「何もしない」という。 以下の例を見ても、何もピンと来ない。(^_^;)>>> 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.6. Defining Functions」である。 なんだかSuperColliderを思い出す。 しかし、ここで岡山までの時間を費やして、どうやらPythonのバグにひっかかった(^_^;)。 ここにある以下のサンプルをコピペでなく、実際に実行させようとしても出来ないのである。>>> while True: ... pass # Busy-wait for keyboard interrupt (Ctrl+C) ... >>> class MyEmptyClass: ... pass ... >>> def initlog(*args): ... pass # Remember to implement this! ...やってみると以下のようになるのである。 これは試してみると、以前にあったdefを使わないサンプルでも同様であった。>>> 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 1597Pythonのチュートリアルのサンブルとして載っている、つまり「出来る」はずのコードでエラーが出るのである。 あれこれリファレンスを探ってみると、以下のように、ちゃんとprint()の書式の中に、「end=' '」と記述できる筈なのに。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$・・・どうしてもこの部分が解決できないまま、新山口まであと1時間となった。 別に結果を横に並べて表示できなくても本質的には関係ないとはいえ、なんか気持ち悪い(^_^;)。 仕方ないので、以下のようにして、続けようと思い切るまでにiPadで数曲を聞いて気を落ち着けた。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.このdefine関数は、以下のように値を返すサブルーチンにもなる。 まぁ、これもよくあるものだ。 ただし以下については、Pythonのチュートリアルのサンブルと違う。 バグを発見したので、ちゃんと出るように直してある。(^_^;)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$ここで広島、あと新山口まで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」とかあったが、あまりソソラレなかったので華麗にスルーした(^_^;)。 これでこの章はおしまいである。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$「のぞみ」が広島駅を出発するのと同時に「5. Data Structures」のセクションとなった。 最初は何故か補遺ということで「5.1. More on Lists」とあり、以下のようにリストに追加されるメソッドがずらりと並んだ。 こりゃコピペ整形するだけで新山口に着いてしまいそうであるが、たぶん重要なのでメモとして置いておこう。 Maxの膨大な「zl」ファミリと同じようなものかな。
以下がそのサンプルだという。 ただしコピペなので、実際に走らせたらバグがある可能性は排除できない(^_^;)。
- list.append(x)
Add an item to the end of the list. Equivalent to a[len(a):] = [x].- list.extend(L)
Extend the list by appending all the items in the given list. Equivalent to a[len(a):] = L.- list.insert(i, x)
Insert an item at a given position. The first argument is the index of the element before which to insert, so a.insert(0, x) inserts at the front of the list, and a.insert(len(a), x) is equivalent to a.append(x).- list.remove(x)
Remove the first item from the list whose value is x. It is an error if there is no such item.- list.pop([i])
Remove the item at the given position in the list, and return it. If no index is specified, a.pop() removes and returns the last item in the list. (The square brackets around the i in the method signature denote that the parameter is optional, not that you should type square brackets at that position. You will see this notation frequently in the Python Library Reference.)- list.index(x)
Return the index in the list of the first item whose value is x. It is an error if there is no such item.- list.count(x)
Return the number of times x appears in the list.- list.sort()
Sort the items of the list in place.- list.reverse()
Reverse the elements of the list in place.そして次は「5.1.1. Using Lists as Stacks」である。 なんだか、このあたりから次第にPythonの自由なデータ構造の変態世界に入っていきそうな予感がある(^_^;)。 以下がサンプルだというが、リストをスタックとして使うなんて、良い子はやってはイケナイのではないか。>>> 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.2. Using Lists as Queues」である。 このあたりもまた、SuperColliderとかProcessingとかを思い出してしまう。 あまりデータ構造とかに凝ったことが無かった、と思い知らされる。>>> 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.3. List Comprehensions」である。 一瞥すると、ここはちょっと厄介そうである。 ちょうど新山口もあと10分というところなので、ここで新幹線車中お勉強をオシマイにして、パソコンを仕舞うことにしよう。 これだけお勉強できるというのは、テンションが上がる出張ならではの醍醐味である(^_^;)。>>> 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'])
「Raspberry Pi日記」トップに戻る