Pythonロボティクスコース レッスン 49

テーマ.12-4 オープンソースの利用

オープンソースを利用して、効率的にプログラムを開発しよう!

このレッスンで学ぶこと

このレッスンでは、インターネット上でオープンソースとして公開されているMicroPython用のモジュールをStuduino:bitへインストールする方法を紹介していきます。実際にインストールしたモジュールを利用して、簡単なプログラムを作成してみましょう。また、オープンソースの定義や利用する上で重要なライセンスの種類についても合わせて理解しておきましょう。

オープンソースの利用

プログラミング言語で書かれたテキストは「ソース(source)」や「コード(code)」または「ソースコード(source code)」と呼ばれます。ソースコードをコンピューターが実際に実行できるようにするためには、2進数で表現された機械語のファイルに変換する必要があり、これを「コンパイル(compile)」または「アセンブル(assemble)」と言います。

オープンソース(open source)」は簡単に言うと、特定のライセンスのもとで、誰もが自由に利用できように公開されたソースコードのことを指しており、オープンソースの促進を目的として活動を行っている組織であるオープンソース・イニシアティブ(Open Source Initiative)では、オープンソースを次のように定義しています。

【 オープンソースの定義 】
  1. 自由な再頒布
    オープンソースは、これを利用して開発されたソフトウェアを頒布(はんぷ)したり、販売したりすることに対しての制限を行いません。またソフトウェアの販売に対して、ライセンスによる使用料(ロイヤルティ)やその他の費用の請求を行うことはありません。
  2. ソースコードの公開
    公開されるプログラムは、コンパイルされた形式だけでなく、ソースコードが含まれている必要があります。また、ソースコードはプログラマが変更するのに適した形式である必要があり、意図的に難読化されたものであってはいけません。
  3. 派生ソフトウェアの自由な再頒布
    ライセンスは、ソースコードの変更と派生したソフトウェアの作成を許可し、さらに元のソフトウェアと同じライセンスでそれらの頒布も認める必要があります。
  4. 原著作者のソースコードの完全性
    元のソースコードと一緒にパッチファイル(ソフトウェアの機能を追加したり修正を行うためのファイル)を頒布することを認める場合に限り、変更を加えたソースコードの頒布を制限することができます。変更されたソースコードから制作された派生ソフトウェアの頒布は許可しなければなりませんが、派生ソフトウェアに元のソフトウェアとは異なる名前やバージョン番号をつけるように義務付けるのは構いません。
  5. 個人またはグループに対する差別の禁止
    ライセンスは、どんな個人またはグループも差別してはいけません。
  6. 利用分野に対する差別の禁止
    ライセンスは特定分野でのプログラムの利用を制限してはいけません。
  7. ライセンスの分配
    プログラムに付随する権利は、そのプログラムが再頒布された者に等しく認められなければいけません。
  8. 特定の製品に依存するライセンスの禁止
    プログラムに付随する権利は、特定のソフトウェア頒布の一部でなければ利用できないような制限をしてはいけません。
  9. 他のソフトウェアへのライセンス制限の禁止
    ライセンスは、ライセンスされたソフトウェアと一緒に頒布される別のソフトウェアについて、例えばオープンソースでなければならないことを主張したりなどの制限をしてはいけません。
  10. 特定技術への依存の禁止
    ライセンスには、特定の技術に依存する条項があってはならない。オープンソース・イニシアティブ「オープンソースの定義」 https://opensource.org/osd.html(参照 2020-09-24)

インターネット上で検索すると、世界中のプログラマが参画するコミュニティで開発された良質なオープンソースを多数見つけることができます。それらのオープンソースの恩恵を受けることで、目的のソフトウェアを効率良く開発することができますが、一方で利用にあたっては、ライセンスに注意する必要があります。ライセンスに違反した場合、著作権者から訴訟を起こされる可能性もあります。

オープンソースのライセンスには様々な種類があります。以下にその中から代表的なものを紹介します。

【 オープンソースのライセンスの代表例 】
  • GPL(General Public License)
    公開されているソースコードを自由に入手、利用、改編、再頒布することが認められています。ただし、GPLで公開されているソースコードを改編したり、自らのプログラムの一部として組み込んだりした二次的著作物については同じくGPLを適用し、オープンソースとして公開しなければならない。
  • BSD(Berkeley Software Distribution)ライセンス
    GPLと同様に、公開されているソースコード自由に入手、利用、改編、再頒布することが認められているが、GPLとは違い、二次的著作物への同じライセンスの適用が強要されていません。また、公開されているソースコードについては開発者・頒布者がいかなる保証も行わず、それらを利用することで生じた損害についても一切の責任を負わないことが明記されています。他にも再頒布時には、著作権者とライセンスを表示することや、二次的著作物の宣伝に開発者や頒布者の名前を無断で使用してはならないことが定められています。
  • MITライセンス
    BSDと似た性格を持つライセンスですが、規約がよりシンプルになっています。公開されたソースコードを自由に扱って良いことや、再頒布時に著作権者とライセンスの表示を含めること、著作権者がいかなる責任も負わないことを定めています。
  • MPL(Mozilla Public License)
    GPLと似た性格をもつライセンスです。他のライセンスで保護されたファイルや自ら開発した非公開のファイルと組み合わせることが可能ですが、MPLで保護されたソースコードは永続的にMPLでライセンスされ続け、ソースコードの状態で利用可能であることが求められます。

オープンソースだからと言って好き勝手に利用しても良いわけではなく、上記のようにライセンスで認められる範囲で利用しなければなりません。

upipモジュールを使用したモジュールやパッケージのインストール方法

このチャプターでは、「PyPI(Python Package Index)」というオープンソースなPythonパッケージを管理するリポジトリから、MicroPython用に開発されたパッケージをインストールする方法を紹介します。

リポジトリ・・・情報分野ではデータを保管・管理する貯蔵庫の意味で使われる言葉。

まずは、以下のURLからPyPIのWebサイトにアクセスしてみましょう。

https://pypi.org

表示されたページの中央に検索窓があります。ここにキーワードを入力して検索をかけると、関連したパッケージの一覧が表示されます。PyPIに登録されているパッケージの多くは通常のPython用に開発されたものです。残念ながら、それらの便利なパッケージはMicroPythonでは使用できません。MicroPythonで利用できるパッケージには、既存のPython用のパッケージを移植したものがあり、それらは区別がつくように、名前の先頭に「micropython」が付けられています。では、検索窓に「micropython」と入力して検索をかけてみましょう。

初期設定では、入力したキーワードと関連性の高いとみなされた順番で、パッケージの一覧が表示されます。全体の数と比べると少ないとはいえ、1000件以上ものパッケージがヒットします。これらすべてを確認するのは大変なので、まずは簡単なパッケージを実際にインストールして利用してみましょう。

3. 1 「micropython-keyword」パッケージのインストール

これからインストールするパッケージは、「micropython-keyword」です。このパッケージには、Pythonの「keyword」というモジュールをMicroPython用に移植したモジュールが含まれています。このkeywordモジュールには、文字列がPythonの予約語であるかどうかをチェックするための関数が定義されています。

それでは、検索結果ページの左上の検索窓で「micropython-keyword」と入力して再検索しましょう。目的のパッケージは、一覧のトップに表示されます。

「micropython-keyword」の後ろに続く数字の並びは、このパッケージのバージョン情報を表しています。パッケージの機能拡張やソースコードの不具合の修正などを行ったときには、このバージョンの数字が更新されます。このテキストを執筆した2020年9月の段階では、「3.3.3」が最新版です。では、上記のリンクをクリックして次のページに移動しましょう。

表示されたページでは、このパッケージに関する情報が確認できます。例えば、パッケージ名の下にある「pip install micropython-keyword」は、このパッケージをインストールするときに実行するコマンドです。実は、PyPIに登録されているパッケージは、このようにpipから始まる1文のコマンドをターミナル(またはコマンドプロンプト)上で実行するだけで簡単にインストールできるようになっています。MicroPythonではこのコマンドは使えませんが、同じくらい簡単なプログラムでインストールを行うことができます。

また、ページ左側のナビゲーションにある「Homepage」から、このパッケージを開発しているプロジェクトのページへ移動することができ、より詳細な情報を得ることができます。

それでは、このパッケージのインストールを進めていきましょう。まずは、Studuino:bitをインターネットに接続する必要があります。テーマ.11-1で作成したmywifiモジュールを利用して、教室のWi-Fiのアクセスポイントに接続しましょう。

Wi-Fiに接続できた場合は、「upipモジュール」を使用してインストールを行います。upipモジュールにはinstall()関数が用意されていて、引数にパッケージ名とインストール先のパス名を渡すだけで、自動でインストールが完了します。

upip.install(パッケージ名, パス名)

では、upipモジュールをインポートして、micropython-keywordをインストールするコードを追加しましょう。

追加【9~11行目】

このプログラムを実行して、インストールを開始します。インストール中は、以下のようなメッセージが表示されます。

では、無事にインストールできたことを確認しましょう。一度Studuino:bitのリセットボタンを押してから、Muエディタの「ファイル」を選択します。表示されたウィンドウの左側のリストにある「keyword.py」がパッケージのインストールで追加されたファイル(モジュール)です。

今度はこのファイルの内容を見てみましょう。ファイル名をクリックして、ウィンドウの左側から右側へドラッグ&ドロップします。これで、Studuino:bitからPCの「mu_code」のフォルダへファイルを転送できます。

PCへ転送した上記のファイルをMuエディタで開いてみましょう。メニューの「開く」から、ファイルを開きます。keyword.pyの内容は、以下のようになっていますね。

【 keyword.py のコード 】

15~51行目には、MicroPythonの予約語がリストで定義されています。また、53・54行目ではiskeywordという関数が定義されています。この部分は少し分かりにくいので解説しておきます。

まずは、53行目を見てください。Pythonには変更可能でミュータブルな「set型」とは別に、変更不可能でイミュータブルな「frozenset型」が存在します。通常のPythonのkeywordモジュールでは、frozenset型を用いてiskeyword関数が定義されているですが、MicroPythonにはfrozenset型がないために、frozenset = setとして、代わりにset型を使用しています。

次に54行目ですが、ここでは予約語のリストからset型のオブジェクトを作成して、set型のオブジェクトがもつ特殊メソッド「__contains__」をiskeyword関数として定義しています。

__contains__メソッドは、指定したデータが集合内に存在するかどうかをチェックするときに使うin演算子に対応したものであり、これでiskeyword("string")を実行すると、"string" in frozenset(kwlist)と同じ処理が行われ、TrueまたはFalseで結果が返ってきます。

56行目以降は予約語を定義した別のファイルを読み込んで、予約語のリストを上書きするためのコードが書かれています。

では実際に、新規作成したプログラムでkeywordモジュールをインポートして利用してみましょう。ここでは、"python""class"の2つの文字列がMicroPythonの予約語であるかどうかを、iskeyword関数を使って確認します。

【 サンプルコード 3-1-1 】
(実行結果)

インストールしたのは、予約語かどうかをチェックするだけのとてもシンプルなパッケージでしたが、これだけでも自分で一から作成する手間を考えると、利用するだけの価値が十分にありますよね。また、この"micropython-keyword"パッケージのライセンスは「MITライセンス」となっています。そのため、著作者権とライセンス全文の表示を行うことを守れば、自由に改変して再配布することができます。このように、オープンソースを上手に活用できれば、プログラムの開発効率を高めることができます。

3. 2 ディレクトリやファイルの操作方法について

そもそも「ディレクトリ」という言葉自体があまり聞きなれないかもしれませんが、PC上で利用している「フォルダ」と役割は同じです。ディレクトリにはテキストや画像、音声などのファイルや他のディレクトリが保管されています。

様々なパッケージをインストールして利用していると、それだけファイル数が増えてくるため、関連するものを同じディレクトリにまとめたり、不必要になったファイルをディレクトリから削除したりなど、データの整理を行いたくなります。

そのときに利用できるのが、uosモジュールです。uosモジュールでは、ディレクトリの作成や削除、ファイルの名前の変更や移動、削除を行うファイルシステムへアクセスするための関数が用意されています。下の表はその関数の一覧です。

【 uosモジュールに用意されているディレクトリやファイルの操作を行う関数の一覧 】
関数名処理内容
chdir(path)現在のディレクトリを指定されたパスのディレクトリに変更する。
getcwd()現在のディレクトリへのパスを返す。
listdir()現在のディレクトリ内のディレクトリやファイルのリストを返す。
mkdir(path)指定されたパスで新しいディレクトリを作成する。
remove(path)指定されたパスのファイルを削除する。
rmdir(path)指定されたパスのディレクトリを削除する。
rename(old_path, new_path)ファイル名を変更する。
参考:uosモジュール(公式ドキュメント)

では、実際にこれらの関数を使いながらディレクトリやファイルの操作方法を見ていきましょう。

■ 現在のディレクトリ位置の確認と移動

例えば、Muエディタ上でターミナルにコマンドを入力して、特定のPythonファイル(モジュール)をインポートするときは、from文を使い、現在の位置からファイルのあるディレクトリまでのパスを指定します。例えば、Studuino:bit内のlibディレクトリのさらに下のpyatcrobo2ディレクトリにあるbody.pyをインポートする場合は、以下のようにコードを入力します。

もちろん問題なくインポートできます。では、from文を省略するとどうなるでしょうか。

今度はエラーが発生しました。これは、実際にファイルが存在するディレクトリとは異なるディレクトリが指定されているためです。

from文では、現在開いているディレクトリからファイルが存在するディレクトリまでのパスを指定しています。これを「相対パス」といいます。ターミナルは最初、最上位のディレクトリを開いているため、from文を省略した方では、最上位のディレクトリでbody.pyを探していたことになります。

現在開いているディレクトリの位置は、getcwd()関数で確認することができます。以下のコードをターミナルに入力して実行してみましょう。

'/'」は最上位のディレクトリを表しています。今度はchdir()関数で現在のディレクトリをpyatcrobo2へ移動して、もう一度getcwd()関数を実行してみましょう。from文では「.」を付けて下位のディレクトリを表しましたが、chdir()関数に渡す引数では/を付けて表します。

これでpyatcrobo2が現在のディレクトリになったため、同じディレクトリ内のファイルはfrom文を省略してインポートすることができます。実際にconst.pyをインポートしてみましょう。

このように問題なくインポートできます。また、最上位のディレクトリに戻りたいときもchdir()関数を実行します。

>>> uos.chdir("/")
>>> uos.getcwd()
'/'

ここまでで気づいたかもしれませんが、from文が現在の位置からの相対的なパスを渡しているのに対して、chdir()関数には最上位のディレクトリから始まるパスを渡しています。このように最上位の位置が固定されたパスを「絶対パス」といいます。chdir()関数も含め、uosモジュールの関数には相対パスと絶対パスのどちらも指定することができ、先頭に/を付けた場合は絶対パス、そうでない場合は相対パスとみなされます。

■ 現在のディレクトリにあるディレクトリやファイルの一覧の取得

listdir()関数を実行すると、現在のディレクトリに存在する他のディレクトリやファイルの一覧をリストで取得することができます。

また、listdir()関数は引数に一覧を取得したいディレクトリを指定することもできます。以下のコードでは絶対パスでディレクトリを指定しています。

■ ディレクトリを作成する

新たにディレクトリを作成するときは、mkdir()関数を使います。以下のコードを実行して、libディレクトリの下にmylibディレクトリを作成しましょう。

中身が空のディレクトリは、Muエディタの「ファイル」から開いたウィンドウには表示されません。listdir()関数を実行して、mylibディレクトリが作成できていることを確認しましょう。

■ ファイルを移動する

ファイルを移動するときは、rename()関数を使います。また、rename()関数はファイル名の変更も行うことができます。インストールしたkeyword.pymykeyword.pyに変更して、上で作成したmylibディレクトリに移動してみましょう。

Muエディタの「ファイル」を選択して、mylibディレクトリにmykeyword.pyがあることを確認しましょう。

■ ファイルを削除する

ファイルを削除するときは、remove()関数を使います。先ほど名前を変更してディレクトリを移動したファイルmykeyword.pyを削除してみましょう。

■ ディレクトリを削除する

空になったディレクトリは、rmdir()関数で削除できます。mylibディレクトリを削除してみましょう。

Studuino:bitの保存領域のデータ容量はPCと比較すると非常に少ないため、このように定期的にディレクトリやファイルの操作を行って、データを整理するようにしましょう。

課題:より実用的なパッケージをインストールして利用しよう

この課題では、新たにPyPIから「micropython-scron」というパッケージをインストールして利用してみましょう。

micropython-scron (PyPI)

4. 1 micropython-scronパッケージについて

micropython-scronパッケージでは、定期的に実行したいジョブがあるときに、複数の曜日、時間(時、分、秒)を設定して、そのジョブを行う関数やメソッドの実行を予約することができます。

「CRON」という、macOSやLinuxなどUNIX系のシステムで用意されているジョブを自動的に実行するためのプロセスがあり、それを参考にして作成されています。また、ライセンスは「GNU Affero General Public License」です。

インストールすると、scronというディレクトリが自動作成され、その中にweek.pyというファイルがあります。

このファイルに定義されているsimple_cronオブジェクトがもつ、add()メソッドで関数やメソッドを実行するスケジュールを設定し、run()メソッドでプロセスを開始します。

【 利用例 】

関数やメソッドはRTC(リアルタイムクロック)の曜日・時刻に基づいて実行されます。例えば、毎日1分おきに、光センサーの値を調べてディスプレイに表示したい場合は次のようなコードを書きます。

【 サンプルコード 4-1-1 】
(実行結果の例)

(参考)
詳細な解説

  • range関数:
    • range(start, stop)は、startからstop - 1までの整数のシーケンスを生成します。startは含まれ、stopは含まれません。

具体的な例

weekdays = range(0, 7)

この場合、

  • start0
  • stop7

したがって、生成される整数のシーケンスは0, 1, 2, 3, 4, 5, 6です。これは週の各曜日(通常、日曜日を0、月曜日を1とする)を表すのに適しています。

*-*-*-*-*-*-*-*-*-

テーマ.9-1で学習したTimerクラスでも似たようなことはできますが、こちらの方が一度に複数の曜日や時刻で実行を予約できたり、実行の履歴を簡単に残しておけたりするため、非常に便利です。それでは前のチャプターで学習したことを踏まえて、自分でmicropython-scronのパッケージをインストールしてみましょう。また、インストールしたパッケージを使って、上記の【 サンプルコード 4-1-1 】を参考に簡単なプログラムを作成してみましょう。

おわりに

5. 1 このレッスンのまとめ

このレッスンでは「オープンソース」の目的や定義、そのライセンスの種類について学習しました。また、オープンソースとしてPyPI(Python Package Index)で公開されているMicroPython用のパッケージをインストールする方法を確認し、実際に2つのパッケージをインストールして利用しました。

オープンソースは上手に利用することで、プログラムの開発効率が上がるだけでなく、上級者の書いたソースコードを見ることで、自分のプログラミングスキルを上達させるための勉強にもなります。PyPIには、自分で開発したパッケージを登録することもできるので、Pythonのプログラミングに慣れてきたらぜひ挑戦してみてください。

また、今回でPythonロボティクス講座は最後になります。長期間の学習お疲れ様でした。Pythonの基本文法から始めて、ロボットの制御やゲームの制作を行い、最後はネットワーク通信に取り組むなど、ここまでとても長い道のりでしたが、将来エンジニアとして活躍していく上で土台となる基礎知識を身に着けることができました。技術は日々進歩していきますので、まだまだ学ばなければならないことはありますが、これから先は自分で制作したいものを決めて、それに必要な知識をつくりながら身に着けていくやり方をお勧めします。

それではこれでレッスン終了です。Pythonロボティクス講座制作スタッフ一同、みなさんがエンジニアの夢を実現できることを願っています。

TOP