ますきーた

mascii(ますきー)がQiita(きーた)に書いてなかった記事を書くブログ

PythonでもNode.jsでも動くコードを書いてみた

プログラミング初学者にとっては完全に毒記事でしかないので、今回はQiitaではなくこちらのブログに書きます。

PythonJavaScript は似ている文法を持っている(オブジェクト・辞書、配列・リスト、関数呼び出しなど)気がして、 簡単な計算なら共通コードで動作するのでは? という疑問が浮かび、2次方程式の解の公式の実装をしてみることにしました。

動作環境

書いたコード

複素数解も考慮します(Python なら複素数の計算も簡単ですが、JSはそうはいかないので実部と虚部に分けて計算しています)
変数はすべてグローバル変数です。snake_case, CamelCase みたいなルールはもはや適当です。

以下、シンタックスハイライトは JS です。

1//1# JS判定
is_js = 1 // 2

eval_js = eval
1 // int(not exec('eval_js = lambda x: None'))

eval_py = eval
eval_js("eval_py = () => {}")

eval_js("exec = () => {}")
exec_py = exec

1//1# Print関数を定義
eval_js("Print = console.log")
exec_py("Print = print")

1//1# JSのみstrを定義
eval_js("str = String")

1//1# 三項演算子 iif を定義
eval_js("iif = (c,x,y) => c ? x : y")
exec_py("iif = lambda c,x,y: x if c else y")

1//1# 代入演算子(?) Var を定義
1//1# 例) Var(x = 100), Var(x = 100, y = 200)
exec_py(
    "def Var(**kwargs):\n" +
    "    for k, v in kwargs.items():\n" +
    "        exec('global ' + k + ';' + k + ' = v')"
)
eval_js("Var = () => {}")

1//1# Hello, world!
Print("Hello, " + iif(is_js, "JavaScript", "Python") + "!")

1//1# 二次方程式の解を求める
a = 1
b = 3
c = 2

D = b ** 2 - 4 * a * c

if (D > 0) // 1:
    {
        Print("D = " + str(D) + " > 0"),
        Print("x = " + str((-b + D ** 0.5) / (2 * a)) + ", " + str((-b - D ** 0.5) / (2 * a)))
    }

if (D == 0) // 1:
    {
        Print("D = " + str(D)),
        Print("x = " + str(-b / (2 * a)))
    }

if (D < 0) // 1:
    {
        Var(re = -b / (2 * a), im = ((-D) ** 0.5) / (2 * a)),
        Print("D = " + str(D) + " < 0"),
        Print("x = " + str(re) + iif(im > 0, "+", "") + str(im) + "i, " + str(re) + iif(im < 0, "+", "") + str(-im) + "i")
    }

実行結果

(a,b,c)=(1,3,2)

Hello, JavaScript!
D = 1 > 0
x = -1, -2
Hello, Python!
D = 1 > 0
x = -1.0, -2.0

(a,b,c)=(1,4,5)

Hello, JavaScript!
D = -4 < 0
x = -2+1i, -2-1i
Hello, Python!
D = -4 < 0
x = -2.0+1.0i, -2.0-1.0i

工夫したこと

  • JSのコメントアウト // を積極的に活用
    • Python では切り捨て除算の演算子扱い
    • is_js = 1 // 2 で JS なら 1, Python なら 0 が入るような変数を作れた
  • とりあえず eval (JS, Python) と exec (Python) で必要そうな関数を定義
    • eval_js, eval_py, exec_py でそれぞれの言語でだけ引数の文字列を評価するようにした
    • 演算子は「数学的には、基本的には、関数をあらわすある種の糖衣構文のようなものに過ぎない」(by Wikipedia)ので、三項演算子を関数化
  • if に続く { ... } は JS だとブロック、Python だと集合扱いなので、Python に合わせて中身はすべて式にした
  • Var 関数
    • Python では受け取ったキーワード引数をグローバルに定義する
    • JS ではこの関数は何もしなくて良く、 Var(x = 1)x1 が代入される

わかったこと

  • Python でも文末の ; は使える
  • JS の代入は式だが Python 3.7 までの代入は文である
    • Python 3.8 で代入式 := が導入される可能性があることを知った
  • Python では intstr+ がエラーとなる
  • Python str は class, JS の String は関数
    • JS に慣れてしまっていて str が関数に見えてしまっていた
  • if 文まではなんとか JS でも Python でも解釈できるように書けたが、 elif や else は無理だった

所感

今回のコーディングはコードゴルフ的な要素がありますが、新しい発見があり両方の言語の勉強になって良かったです。

各キャッシュレスのマネーフォワード連携対応状況(2019/05/04)

2019/05/04 現在の各キャッシュレスの MoneyForward ME 連携対応状況をまとめてみました。

比較対象

TL;DR

  • LINE Pay, Kyash はいい感じに対応
  • PayPay, メルペイは非対応
  • モバイルSuicaは利用金額と乗車区間のみ記録される

比較

MoneyForward ME 連携対応

残高の取得と、利用履歴の記録の取得に対応

LINE Pay

  • MoneyForward ME 連携対応
  • QRコード支払、LINE Pay カード共に「決済 株式会社ローソン」のような記録が残る
    • 店舗名が見やすい
  • LINE Pay もらえるくじの記録で1円貰えたことまで表示される。そこまでいらないのに... と思う人もいるかもしれない

Kyash

  • MoneyForward ME 連携対応
  • 「購入 NITORI」のような記録と、カードからのチャージ額が「VISA_0000」(0000はカードの下4桁)として残る
    • カード側の記録と突き合わせて振替扱いにしてくれる

モバイルSuica

  • MoneyForward ME 連携対応
    • My JR-EAST ID で連携しないと毎回画像認証が求められるので注意(公式ブログ)
  • 電車に乗ると「入 地 池袋 出 地 渋谷」(地=地下鉄)のような記録が残る
  • 電車以外の買い物では「物販」という記録が残り、どの店舗での買い物かは判別できない

MoneyForward ME 連携非対応

PayPay

  • MoneyForward ME 連携非対応
  • クレジット払いだとクレジット側で「VISA国内利用 VS ペイペイ ローソン」のような記録が残る
    • ただし、カード(Yahoo! JAPANカード以外)支払いではYahoo! JAPANカードとPayPay残高に比べ、還元率が下がる

メルペイ

  • MoneyForward ME 連携非対応
  • 自動で MoneyForward ME に記録を残す手段はないと思われる

最近の登壇活動を振り返ってみる(201812-201902)

最近の登壇活動を振り返ってみる

12月と2月にJSの勉強会で登壇させていただいたので、振り返りのメモを残してみます。

We Are JavaScripters! @27th【初心者歓迎LT大会】(WeJS)

JavaScriptのバージョンの話

初心者向けの会を開催します!とのことで、JSにはバージョン(と言いつつ、ECMAScriptのバージョン)があるよ〜というJS初心者向けの話をした。
IE11対応に苦労されているJS初心者(Webデザイナー含む)は多いのではないかと思い、この話をすることに。

speakerdeck.com

  • 伝えられたこと
    • ECMAScript におけるトランスパイラ、Polyfill の役割
    • CanIUseMDN をチェックすることで、ターゲットブラウザで使いたい機能が使えるか調べることができること
  • 伝えきれなかったこと
    • ECMAScript のバージョン差異とは別に、document, navigator 以下に生えているメソッド等にブラウザ間の挙動の差異があること
      • そういったものを吸収する役割を担う(担っていた)のが jQuery だということ
      • Proxyの他にも、WebUSB API や WebBluetooth API などといったトランスパイラや Polyfill で対応できないレベルの機能があるということ
    • Google Apps Script では今でも ES5 を書かないといけないこと
      • (clasp を使う手はある)

Meguro.es #19 @ oRo

Nuxt.js+Firebaseで個人サービスを作るまで

タイトルに Firebase を入れたけど、あまり Firebase の話ができなかった。
「ToDoアプリから始めてNuxt.jsを用いたSPAを作るまで」のようなタイトルの方が良かったのかもしれない。
登壇では2017年9月から2019年1月にかけ、Vue.js で作ったものを4個紹介。
そのうち4個目の「YouTubeを観ながら使えるMarkdown」サービスは、実家帰省中だった1月1日〜5日の間に思いつきで制作し、その勢いで登壇を申し込んだ。

speakerdeck.com

  • 伝えられたこと
    • Vue.js、Nuxt.js の学び方の一例
      • 自分は「作りたいもの」をモチベーションに進めていったこと
        • いますぐ作りたいものがない方に真似してもらえると嬉しいと思う
    • SSR を利用しなくても Nuxt.js を使ってよいこと
    • Nuxt.js の SSR はオンオフが容易であること
  • 伝えきれなかったこと
    • Firebase を使うメリット・デメリットの詳細
      • Authentication で認証が楽だが、DBの正規化ができないことだけしか伝えられなかった
        • 自分自身勉強不足だったと思う
      • タイトルに Firebase を付けるべきではなかったかもしれない
    • 最後に紹介した「YouTubeを観ながら使えるMarkdown」サービスの詳細

所感

WeJSの2次会で深見さんから登壇よかったよと言っていただけて嬉しかったです(ありがとうございます!!)。
懇親会においても、Twitterのフォロワーさんからお声がけをいただき、登壇では伝えきれなかったことをお伝えしたりしました。

Meguro.esでは、発想が色々出てくるのすごいな〜、的なツイートをお見かけました(こちらも、ありがとうございます!)。
実際のところは作りたいものがなかなか思いつかなかったりしますし、発想が出てから手を動かす流れは技術的な学びにブレーキをかけているのではないかと思うところはあります。
登壇では作りたくなるようなアイディアを共有しつつも、自分自身はアイディアに囚われずに手を動かしてみても良いんだろうなと思いました。

東電のでんき家計簿で30分ごとの電気使用量が見られるようになっていた

でんき家計簿ってなに?

東京電力Webサービスで、毎月の電気料金・使用量を確認できるものです。検針票に書いてある「お客様番号」があれば簡単に登録して利用できます。

スマートメーターに取り替えられた

3月に引っ越してきた今の物件で、5月にスマートメーターへの切り替え工事がありました(特に停電などはなかった)。

スマートメーターに切り替わると毎月の電気料金・使用量だけでなく、30分ごとの電気使用量が見られるようになると知っていたのですが、切り替わってすぐは見ることができませんでした。
久しぶりに、でんき家計簿を確認してみたところ「時間別グラフはこちら」ボタンが出現していて、見られる状態になっていました。

f:id:mascii:20180630210155p:plain:w500

前日以前のグラフを見ることができました。

棒グラフの棒にマウスカーソルをフォーカスすると、その時間帯の電気使用量(kWh)を見ることができます

f:id:mascii:20180630210451p:plain:w400

1日の電気使用量が出ていなかった

30分ごとの電気使用量が見られるようになったものの、1日の電気使用量の表示がありませんでした。48個もの値を手作業で足し算するのは辛いので、JavaScriptで計算してみました。

JSON.parse(vbar_usage_grp.toString().match(/var items = (.+);/)[1])[0].reduce(function(x,y,i){return i===0?0:(x+y)},0)+'kWh'

上記スクリプトを、でんき家計簿の時間別グラフページ上でJavaScriptコンソール開いて実行します。

f:id:mascii:20180630211322p:plain:w500

こんな感じで、1日の電気使用量の表示されます。

このスクリプトの処理内容は、vbar_usage_grp という関数の中にある items という配列(ここに30分ごとの電気使用量が格納されていた)を無理矢理取得して、総和を計算している感じです。
vbar_usage_grp 関数の中身を取得するために一旦この関数を toString() しているのですが、もっといい方法があったら教えていただきたいです。ちなみに、Internet Explorer 11でも一応動作しました。

KiCadでオリジナルのプリント基板を作ってみた

KiCadとは?

Wikipediaにも書いてあることですが、プリント基板の設計ができるオープンソースのソフトウェアです。

IoTな赤外線リモコンが欲しい

Nefry BTとGroveで作ろう!

そろそろ暑い季節がやってくるので、インターネット経由で外出先からエアコンを操作できる、IoTな赤外線リモコンを自作しようかと思いました。

ということで、以下のパーツを組み合わせて作ってみました:

こんな感じで、Nefry BTとGroveモジュールをGroveケーブルで接続します:
f:id:mascii:20180623162856j:plain:w300

ESP32用のArduinoスケッチ(プログラム)を書き、なんとかIoTな赤外線リモコンが完成しました。

完成したけどNefry BTがもったいない!

Nefry BTは高価ですが使い勝手が良く、今後も実験用として使いたかったため、Nefry BTよりも安価で小型なMH-ET LIVE ESP32 MiniKit(AliExpressなどで900円程度で輸入できるESP-WROOM-32搭載ボード)に置き換えることにしました。

f:id:mascii:20180623111741j:plain:w300

しかし、ESP32 MiniKitはNefry BTのようにGroveコネクタを持っていないため、赤外線LEDとESP32を接続することができません。
そこで、ESP32 MiniKitとGroveモジュールを接続するための基板を自作することにしました。

完成品がこちら:

f:id:mascii:20180623170943j:plain:w400

なぜプリント基板を作る必要があったのか?

電子工作をしているとブレッドボードやジャンパワイヤーなどを使って試作的な配線をすることがありますが、

  • ジャンパワイヤーは抜けやすい
  • 見栄えが良くない
  • 場所を取る

といった問題があります。

f:id:mascii:20180623111341j:plain:w400

配線をよりブラッシュアップする方法として

といった方法があります。

f:id:mascii:20180623110134j:plain:w400

今回は以下の理由でプリント基板を設計して製造することにしました

  • ホールユニバーサル基板はピッチ(穴の間隔、2.54mmなど)が固定されていて、ピッチ違いの部品を混在させることが難しい
    • 今回作りたい基板は2.54mmピッチの部品と2mmピッチの部品が混在する
  • ホールユニバーサル基板は自由なサイズにカットしにくい

EAGLEというCADにも無償版があるそうですが、以前に少し使い方を教わったのがKiCadだったためKiCadを選択しました。

設計してみた

KiCadは正直なところ操作性が直感的ではないので、初心者はKiCad入門的なサイトを参照すると良いと思います。ちなみに、こちらのサイトがわかりやすかったです:
www.kicad-de-kiban.net

f:id:mascii:20180623164511p:plain:w350

f:id:mascii:20180623164519p:plain:w350

f:id:mascii:20180623164514p:plain:w350

GNDベタとかやったほうが良いのかな...と思いつつ、とりあえず完成させることを目標としたため、太めの配線で済ませてしまいました。

発注してみた

発送時にメールで基板の写真を送ってくれると聞いたことがあったElecrowを利用しました。
小さめのサイズで10枚までだと安かったため、製造枚数は10枚、発送方法は最安だったRegistered Airmail(中国国内・日本国内で荷物の追跡可能)にしました。登録時に貰えたポイントを使ったりして送料込み$8.10でした(安い!)。

基板の色は青色で発注したつもりが、緑色で発注してしまったため、慌てて英語で「青色に変更して!」とメールを送ったところ、ちゃんと対応してくれました。発送前に送られてくる基板の写真もちゃんと青色だったので安心でした。

f:id:mascii:20180623170138p:plain:w200

5月27日に発注、6月2日に中国から発送、6月12日に郵便局の窓口で受け取りしました。

到着&はんだ付け

10枚発注したはずが、14枚入っていました(このことはElecrowガチャと言うそうです)。

届いた基板で作った「Groveシールド」がESP32 MinikitとGroveモジュールの間に入り、安価でIoTな赤外線リモコンが完成しました。
f:id:mascii:20180623171010j:plain:w400

Groveコネクタ・ケーブルを介さず直接ピンで接続してみたりもしました(はんだを取り除く作業に苦戦し、Groveモジュールを壊しかけました)。
f:id:mascii:20180623171012j:plain:w400

動いた!

以前に自分がQiitaに書いたGoogle Home + IFTTT + Beebotte(MQTT Broker) + ESP32でLチカしてみたという記事と同様にして、Google Homeに話しかけることでエアコンのオンオフができるようになりました。もちろん、外出先でもエアコンのオンオフができるようになっています。

電子工作全般に言えることですが、自分で作ったものがちゃんと動くと嬉しいですね。

まとめ

  • 一度はやってみたかった基板の設計を、自分が利用する実用的なモノを作るタイミングで実践することができた
  • 中国のメーカーに基板発注すると安い
  • 中国から輸入したESP32搭載ボードも安い
  • 赤外線リモコン製作ノウハウを手に入れた
    • 今回作ったArduinoスケッチや赤外線信号はGitで管理
      • ESP32 Minikitが壊れても作り直せる(予備を一台確保済み)
    • Beebotte(MQTT Broker)のサービスが終了しても、他のサービスに乗り換えることができる

画像ファイルの日付を一括で変更する

カメラに誤った時刻が設定されていて、画像ファイルのExifに間違った時刻が記録されていたときにコマンドで一括変更する方法を紹介します。

ExifToolをダウンロードして利用します(Windows版で動作確認)。

例: カメラの時刻設定が1年ずれていたので、CR2ファイルに記録されている時刻+1年に変更したい

exiftool "-alldates+=0001:00:00 00:00:00" *.CR2

DNG, JPEGなどでも変更できます。

レーザーカッターとMDFで新居で必要なモノを作った話

転職するので引っ越しすることに

転職に伴い、前職の会社の寮から出なくてはならなくなりました。
前職のときは寮の最寄駅から会社最寄駅まで電車で40分程度かかっていたのですが、築年数が15年程度だったため比較的設備は良いものでした。
今回の引っ越しでは築年数30年以内で電車で15分程度で行ける物件を探すことにし、条件に合った物件を見つけたのですが入居後...

  • キッチンの流し台下の収納が腐っている問題
  • ディスプレイに直射日光当たる問題
    • 間取り狭いため、机の位置がどうしても窓際になってしまった

という2つの問題に直面しました。これらの問題をレーザーカッターとMDF板で解決できたので紹介します。

新居の問題

問題1. キッチンの流し台下の収納が腐っている問題

ちょっと意味がわからないかもしれないですが、入居してから腐っていることに気付きました。

f:id:mascii:20180603212355j:plain

問題2. ディスプレイに直射日光当たる問題

PCとNintendo Switch用に使っているディスプレイの設置位置が窓際になってしまい、南向きの直射日光に当たってしまうため、ディスプレイの裏側が過熱するという問題が発生しました。

f:id:mascii:20180603212250j:plain

そうだ、レーザーカッターで解決しよう!

以前に柏の葉キャンパスにあるKOILのKOIL FACTORYでレーザーカッターの講習を受け、ライセンスのようなものを持っていたため、レーザーカッターの利用予約すればすぐに使えるという状況でした。
今回も、KOIL FACTORYにあるレーザーカッターと、そこで販売されている2.5mm厚のMDF板(中密度繊維板)を利用することにしました。
レーザーカッター利用のおおまかな流れは以下の通りです:

  • 家のWindows PCにインストールしてあるIllustrator CS6で適当な図面を作成
  • .aiファイルをUSBメモリで保存
  • KOILにUSBメモリを持ち込み、KOIL FACTORY内のPCのIllustrator CS6で.aiファイルを読み込み
  • レーザーカッターはPC上はプリンタとして認識しているので、印刷を実行
  • 素材をレーザーカッターにセットし、カットの始点を調整する
  • レーザーを出力してカットする

f:id:mascii:20180603213015p:plain 赤線はレーザーカッターでレーザーを出力してカットする部分の定義で、黒線は補助線として使っています。

問題1. キッチンの流し台下の収納が腐っている問題

f:id:mascii:20180603212255j:plain 腐っていた板をMDF板で覆い被すことに成功しました。なんということでしょう!
KOILにいた方に「靴用の防水スプレーをかけておくと耐水性能が上がるかもしれない」というアドバイスをいただき、アメダスの防水スプレーを4回くらい重ね塗りしたところ、水に強い板に仕上げることができました。

問題2. ディスプレイに直射日光当たる問題

f:id:mascii:20180603212252j:plain

モニターアーム用のネジ穴(VESAという規格で寸法等が定められています)にMDF製の日除けを取り付けることができました。これでディスプレイの過熱を防ぐことに成功しました!
ディスプレイ正面から見てもこのMDFは見えないよう、ディスプレイよりも少し小さめに作ったため、MDF製の日除けを装着していることを気にすることなく使えています。
なお、VESAマウントに取り付けるためのネジ(M4)は、秋葉原にある西川電子部品さんで購入しました。

まとめ

一点物で必要なモノがレーザーカッターや3Dプリンタで簡単に作れる良い時代になったな~と思います。
3Dプリンタはまだ使ったことがないので、機会があればチャレンジしてみたいです。
最近、趣味のIoT関連でKiCadでオリジナルのプリント基板を発注したので、今度はそのことを書こうかと思います -> 書きました!
KiCadでオリジナルのプリント基板を作ってみた