前回は「配列」が並んだデータを一つの変数にまとめたものであることを説明した。
音符のデータをまとめて楽譜の配列を作ったのでしたね。
今回は配列に格納されたデータを個別に扱う方法を説明しよう。
はじまりマ~ス!
配列の要素とインデックス
前回扱った音楽を演奏するプログラムを思い出してみよう。2行目が音符のデータをまとめた配列だ。
- _1行目 import music
- _2行目 tune = [“C4:4”, “D4:4”, “E4:4”, “C4:4”, “C4:4”, “D4:4”, “E4:4”, “C4:4”, “E4:4”, “F4:4”, “G4:8”, “E4:4”, “F4:4”, “G4:8”]
- _3行目 music.play(tune)
「グーチョキパーで何作ろう?」の曲でしたね。
2行目の配列「tune」には音符のデータが格納されている。それぞれの音符のデータのように、配列に格納されたデータのことを、「配列の要素」と呼ぶ。覚えておいてくれたまえ。
「”C4:4″」などの音符のデータが「配列の要素」ということになるのですね?
ウム。そして、「配列の要素」には、0から始まる番号が付けられている。この番号を「インデックス」というのだ。
「インデックス」は、どうやって使うのですか?
配列の変数に「[]」でくくったインデックスを付ければ、それぞれの要素を個別に指定することができる。例えば・・・
tune[0]
とすれば、最初の要素「”C4:4″」を指定できるのだ。
準備として配列と関数を作ります。
今回は、マイクロビットのLED表示部分に時計の針を表示させて、グルっと一回転させてみようと思う。
動きがあって、面白そうですね!
Aボタンが押されたら時計が一回転するプログラムを作るのだ。まとめると、以下となる。
「Aボタンが押されると、マイクロビットのLED表示部分で時計の針のイメージが一回転する。」
時計のイメージを表示する部分を「Clock()」という関数として置き、関数「Clock()」の内容を作り変えることで、具体的に配列をどう扱うかを説明しよう。
なんか難しそうですけど、ガンバリマス!
初めに配列を作っておきますよ。
まず初めに「配列」を作っておこう。「hari」という配列を作り、1時から12時までの時計のイメージを格納したのだ。
- 1行目 from microbit import *
- 2行目 hari = [Image.CLOCK1, Image.CLOCK2, Image.CLOCK3, Image.CLOCK4, Image.CLOCK5, Image.CLOCK6, Image.CLOCK7, Image.CLOCK8, Image.CLOCK9, Image.CLOCK10, Image.CLOCK11, Image.CLOCK12]
マイクロビットのライブラリには、時計も用意されているのだ。(イメージの表示機能については、以下をご覧ください。新しいタブで開きます。)
【マイクロビット入門】(10)マイクロビットの機能を使ってみよう。
配列「hari」ってことは、針のイメージデータの配列ってことかな。「Image」の配列も作れるのですね!
関数を作ってAボタンを押すと呼び出されるようにする。
時計の針のイメージを表示する部分は「Clock()」という関数にしてまとめておく。そして、Aボタンが押されると、関数「Clock()」が呼び出されるようにする。
- 1行目 from microbit import *
- 2行目 hari = [Image.CLOCK1, Image.CLOCK2, Image.CLOCK3, Image.CLOCK4, Image.CLOCK5, Image.CLOCK6, Image.CLOCK7, Image.CLOCK8, Image.CLOCK9, Image.CLOCK10, Image.CLOCK11, Image.CLOCK12]
- 3行目
- 4行目 def Clock():
- 5行目 #中身はこれから作ります。
- 6行目
- 7行目 while True:
- 8行目 if button_a.get_presses():
- 9行目 Clock()
4行目~5行目が関数「Clock()」だ。中身はまだ作っていないのだ。
8行目と9行目がAボタンで関数「Clock()」を呼び出す部分ですね。(関数とボタンについては、以下をご覧ください。新しいタブで開きます。)
関数
ボタン
配列に格納したイメージを表示してみよう。
いよいよ関数「Clock()」の中身を作って、時計を表示するのですね。
ウム。いろいろな方法で表示してみようと思う。
一番簡単な方法
イメージを表示するには、「display.show()」関数を使うのでしたね。今回は「hari」という変数にイメージが格納されているので・・・
display.show(hari)
・・・とすればよいのですか?
ィエ~ス。試しにやってみよう。上の「display.show(hari)」を先ほど作った関数「Clock()」の中身とする。
- 4行目 def Clock():
- 5行目 display.show(hari)
マイクロビットに書き込んで・・・Aボタンを押すと・・時計の針がクルッと一回転しましたね!
「display.show()」に配列を渡すと、配列「hari」に格納されたものを1つずつ順番に表示してくれるのだね。
なんか、でも、少しぎこちないですね。もう少し速く一回転させられないですか?
各要素を個別に表示する。
そのためには、配列の要素をひとつずつ「display.show()」で表示しつつ、表示する時間間隔を指定する必要がある。そこで「インデックス」を使って、個別に「要素」を指定することとなる。
ど、どうやってやればよいのですか?(なんか難しいことを言い始めたぞ)
例えば今回作成した配列「hari」の最初の要素「Image.CLOCK1」を指定するには、次のようにプログラムを変更する。
- 4行目 def Clock():
- 5行目 display.show(hari[0])
「hari」の代わりに「hari[0]」としたのですね。
このままでは、「Image.CLOCK1」しか表示されないので、他の要素も表示されるようにする。インデックスを1ずつ増やしている点に注意してくれたまえ。
- 4行目 def Clock():
- 5行目 display.show(hari[0])
- 6行目 display.show(hari[1])
- 7行目 display.show(hari[2])
- 8行目 display.show(hari[3])
- :
- 16行目 display.show(hari[11])
マイクロビットで動かすと・・・針が表示されますが、動かないですね。
表示が切り替わるスピードが速すぎるのだね。そこで、各「display.show()」の間に「Sleep()」を入れて、表示が切り替わる時間を調節してみる。
- 4行目 def Clock():
- 5行目 display.show(hari[0])
- 6行目 sleep(100)
- 7行目 display.show(hari[1])
- 8行目 sleep(100)
- 9行目 display.show(hari[2])
- 10行目 sleep(100)
- 11行目 display.show(hari[3])
- 12行目 sleep(100)
- :
- 26行目 sleep(100)
- 27行目 display.show(hari[11])
マイクロビットで動かすと・・・おぉ、クルッと一回転しましたね!
「sleep(100)」の100の部分を別の数字に変えると、針が動くスピードを変えられるのだ。
う~ん、なんだかプログラムが長ったらしくなってしまってますし、11個ある「sleep(100)」の100の部分を全部変えるのは大変ですね。何とかならないのですか?
ループと変数で配列を扱う。
なかなか良いところに気がついたね。その問題を解決するには、「ループ」と「変数」を使えばよい。
「ループ」ということは「while」文ですね!
イエ~ス、その通り!「while」文でループを作る前に、配列「hari」の要素を指定するための変数「a」を用意しておこう。
- 4行目 def Clock():
- 5行目 a = 0
変数「a」の値は、最初は0にしておくのですね。
ウム。配列「hari」の最初の要素から順番に指定していくので、インデックスとなる変数「a」は最初は0としておくのだ。
配列の要素の番号は0から始まるのでしたね。
そして、次に、whileループの中で「display.show(hari[a])」と「sleep(100)」を呼び出すようにする。
- 4行目 def Clock():
- 5行目 a = 0
- 6行目 while a < 12:
- 7行目 display.show(hari[a])
- 8行目 sleep(100)
ループの中で「display.show()」と「sleep(100)」が呼び出されるということは、繰り返し呼び出される、ということですね?
その通りなのだ。「display.show()」→「sleep(100)」→「display.show()」→・・・と呼び出されることで、「display.show()」の間に「sleep(100)」が入り、針がある程度のスピードで動いているように見える、という訳なのだ。
whileループの判定部分が「a < 12」ですが、変数「a」の値は0ですね。これは新手の無限ループってことですか?
- 5行目 a = 0
- 6行目 while a < 12:
このままでは、そうなってしまうね。しかし、変数「a」は配列「hari」のインデックスで、1ずつ増えていかないといけない。つまり、プログラムはこうなる。
- 4行目 def Clock():
- 5行目 a = 0
- 6行目 while a < 12:
- 7行目 display.show(hari[a])
- 8行目 sleep(100)
- 9行目 a = a + 1
ループが一回りするたびに変数「a」の値が1増える。変数「a」は配列「hari」のインデックスなので、7行目で表示される時計の針のイメージが配列に格納された順番に変わっていくのだ。
なるほど!変数「a」がどんどん増えていくので、12になったところでループが終了するのですね!これで出来上がりなのですか?
イエ~ス、その通りデ~ス。
さっきの関数「Clock()」は27行目まであったけど、今回のはかなりシンプルにまとまっていますね!
しかも、時計の針を動かす速さを変える場合は、8行目を変えるだけで良いのだ。
修正も楽ですね。ところで、配列の要素は12個なのに、変数「a」が増えるのは11までなのはなぜですか?
変数「a」は0から始まって11まで増える。0から11までの間に整数は12個あるので、配列の12個の要素をすべて指定できるのだ。従って、変数「a」は11まで増えればよいのだョ。
いやぁ、そうだと思ってたんですけど・・・念のため、ちょっと聞いてみただけですぅ。
まとめ
今回のまとめなのだ!
- 配列の中に格納されたデータ一つ一つを「要素」という。
- 配列の要素には、「インデックス」と呼ばれる0から始まる番号が付けられている。
- 配列の要素を指定するには、「[]」で囲った「インデックス」を配列名に付加する。
- ループを組み合わせることで、各要素を扱うプログラムをシンプルに作成できる。
ところで、ループを作るには、今回使った「while」文とは異なる方法があるのだ!
な な な、ナンですと!
それは「for」文というものを使う方法なのだ。次回は「for」文について説明するぞ。
どんなものか、気になりますね。
今回作ったプログラムの全文デ~ス。
- 1行目 from microbit import *
- 2行目 hari = [Image.CLOCK1, Image.CLOCK2, Image.CLOCK3, Image.CLOCK4, Image.CLOCK5, Image.CLOCK6, Image.CLOCK7, Image.CLOCK8, Image.CLOCK9, Image.CLOCK10, Image.CLOCK11, Image.CLOCK12]
- 3行目
- 4行目 def Clock():
- 5行目 a = 0
- 6行目 while a < 12:
- 7行目 display.show(hari[a])
- 8行目 sleep(100)
- 9行目 a = a + 1
- 10行目
- 11行目 while True:
- 12行目 if button_a.get_presses():
- 13行目 Clock()
次回も、お楽しみに!
コメント