Bye Bye Moore

PoCソルジャーな零細事業主が作業メモを残すブログ

Hy環境からグラフ描画環境matplotlibを使う

matplotlibはnumpyと合わせて使われる事も多い、
グラフ描画ライブラリです。
qiitaの記事は5000件超、最新で使われてる事例もここ一ヶ月で複数個あるので
使われているライブラリと言っていいでしょう。
今回は、これをHylang経由で使って見ます。

実際のところ

python

"""
=======================================
A simple plot with a custom dashed line
=======================================

A Line object's ``set_dashes`` method allows you to specify dashes with
a series of on/off lengths (in points).
"""
import numpy as np
import matplotlib.pyplot as plt


x = np.linspace(0, 10, 500)
dashes = [10, 5, 100, 5]  # 10 points on, 5 off, 100 on, 5 off

fig, ax = plt.subplots()
line1, = ax.plot(x, np.sin(x), '--', linewidth=2,
                 label='Dashes set retroactively')
line1.set_dashes(dashes)

line2, = ax.plot(x, -1 * np.sin(x), dashes=[30, 5, 10, 5],
                 label='Dashes set proactively')

ax.legend(loc='lower right')
plt.show()

f:id:shuzo_kino:20191128004109p:plain

【イベントログ】調布祭2019年度

電気通信大学の学祭である
調布祭オープンキャンパス
展示をしてきました。

暗号制御のリファレンス実装を持って行ったのですが
それだけでは寂しいので
景品がミニドーナツなクレーンゲームを作りました。

一個一個掴む前提で組んだのですが、
二個スタックしてゲットされる方が。
こういうモノは実地に持って行くと面白い事が起こりがちですが
これもそういった楽しい誤算の一つですね。

【読書メモ】伽藍とバザール WEB版

伽藍とバザール

伽藍とバザール

翻訳本は大学図書館で読んだ事があったのですが、今回はそれのWEB版。
近いうちに新しいプロジェクトを始めようと思い、久々に読み返してみました。

普段の仕事だと、責任ウンタラの関係でドキュメント山盛りで会議も盛りだくさんな
「伽藍スタイル」の進め方をしないといけない事が多いです。

とはいえ、LinuxArduinoのようなオープンソース系プロジェクトのほうが
個人的には参加していて気分が良いのも事実。


参考もと

cruel.org

Hyの公式コーディングルールでは"->"が推奨

"->"はthreading macroといい、Hylangを特徴付ける記法の一つです。
シェルスクリプト のPipeのような感じで記述できるので、
Lisp系特有の地獄の括弧ネストを幾分見通しよくすることができます。

実際のところ

伝統的書き方だと

(setv *names*
  (with [f (open "names.txt")]
  (sorted (.split "," (.replace "\"" "" (.strip (.read f)))))))

これがhreading macroであれば以下のように

(setv *names*
  (with [f (open "names.txt")]
    (-> (.read f) (.strip) (.replace "\"" "") (.split ",") (sorted))))

パッと見では解釈が難しいこんな式も

(import [sh [cat grep wc]])
(wc (grep (cat "/usr/share/dict/words") "-E" "^hy") "-l")

これが

(import [sh [cat grep wc]])
=> (-> (cat "/usr/share/dict/words") (grep "-E" "^hy") (wc "-l"))

hy2pyを使ってhyスクリプトをpythonスクリプトに転換する

hy2pyはhy環境に付属するpythonスクリプトコンバーターです。
何からの事情でPythonしかない先で使うときに活用できそうです。

実際のところ

(import time)
(import serial)

(setv ser ( serial.Serial "/dev/ttyACM0" 57600))

(defn robotTask [dist] (-> (+ "task," dist "\n") (str.encode) (ser.write)))

(robotTask "up")
(for [x ["right" "down" "left"]]
  (robotTask x)
  (.sleep time 6.0))

これを

$ echo sample.hy | hy2py3

でコンバートすると……こうなります

import time
import serial
ser = serial.Serial('/dev/ttyACM0', 57600)


def robotTask(dist):
    return ser.write(str.encode('task,' + dist + '\n'))


robotTask('up')
for x in ['right', 'down', 'left']:
    robotTask(x)
    time.sleep(6.0)

Hylang環境でpySerialをつかってシリアル通信やる

巷で大人気のPythonには豊富なライブラリ群があります。
教材の類も充実してますし、会社や研究室の先行プロジェクト資産もあるでしょう。
Hylangは幸いにしてPythonとの連携機能が充実しているので
こういった先行資産を活用しながら、徐々にLisp色に染めていくというスタイルを
現実的に実行可能なヤベぇ特徴を備えています。

今回はオープンソースなロボットアームOpen Manipulator Xを
シリアル通信経由で操作する単純なアプリケーションを考えます。

実際のところ

当該ロボットアームはUbuntu端末からシリアル通信経由で所定の指令文を送ることで操作します。
Pythonでやると、こんな感じになります。

import serial
ser = serial.Serial('/dev/ttyACM0', 57600)
ser.write("task,up\n")

これをHylangで書き直してみましょう。

ライブラリのインポート

まず、ライブラリインポートですが、これはそのまんま。

(import serial)

変数設定

次に変数設定。
letは残念ながらない*1ので、
Hy公式のスタイルに則ってsetvで値を定義します。
文字列はダブルクオートじゃないと受け取って貰えないので注意!

(setv ser ( serial.Serial "/dev/ttyACM0" 57600))

シリアルの書き込み

次に書き込みです。なんも考えないと、こんな感じの実装になるかと思います。

 (ser.write (str.encode "task,back\n"))

Clojure由来らしい魔界記法"スレッドマクロ"をつかうと……以下のように書き下せます。

(-> (str.encode "task,up\n") (ser.write) )

指令文本体は単体の要素として先に切り出して渡してあげてもいいので……

(-> "task,up\n" (str.encode) (ser.write) )

この例ですと旨味がないですが、"."記法を使う場合、
スレッドテイル・マクロを使い末尾にくっつけるようにして
こう書くこともできますね。

(->> "task,down\n" (.encode str) (.write ser) )

書き込み部を関数に切り分ける

スレッドテイル方式のものを関数に切り分けましょう。
defunじゃなくてdefnです。

(defn robotTask [dist] (-> (+ "task," dist "\n") (str.encode) (ser.write)))

(robotTask "up")

繰り返し処理も見通しよくなりますね。

(import time)
(for [x ["right" "down" "left"]]
  (robotTask x)
  (.sleep time 6.0))

感想

データをつくって渡していく構造、シェルスクリプト っぽいですね。
本格的にS式で作り込んで行けば、PythonやCだと目が回るような複雑な処理も
スマートに記述できそうです。

*1:欲しい時は自分で作りましょう