初めてのGraphQL
オライリーからGraphQLの入門書が出たので購入。
今やってる仕事はバックエンドをRESTにしてるけど、複雑な問い合わせ画面だとクエリストリングが長くなりすぎてエラーになるからGETは諦めてPOSTにしちゃうとか、ちょっと残念な気分になることがあるので、紹介系のAPIは GraphQLの方が向いてそうな気がしてる。
前半 は GraphQL の概説、スキーマ―の解説で、後半は JavaScript の GraphQL ライブラリである Apollo を利用して簡単な画像投稿サイトを実際に作成するチュートリアルという構成。
文章はかなり平易で読みやすい。チュートリアルの方はフロントエンドが React、バックエンドは Node.js + Express をベースにしていてそこら辺の解説はほぼないが、知識が薄くとも読む分にはとくに困ったり引っかかるようなとこはなかった。今回、手は動かしていないので写経するとなるとまた話は違うものがあるかもしれない。
GraphQLのクエリのパースなどの面倒な部分は完全に Apollo に任せる感じで、サーバーを自力で実装しなければならないとか、JavaScirpt 以外の言語で実装するといった用途には向かないかも。
仕事だとバックエンドはC#を使用することが多いので、C#用のライブラリを探してみる必要があるな。
初めてのGraphQL ―Webサービスを作って学ぶ新世代API
- 作者: Eve Porcello,Alex Banks,尾崎沙耶,あんどうやすし
- 出版社/メーカー: オライリージャパン
- 発売日: 2019/11/13
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
M5Stack 導入手順メモ
注文していたM5StackとUSBケーブルが届いたのでセットアップを行う。
環境は
- 母艦:MacBook PRO 15inch 2018 (Cataline)
- 子機:M5Stack Gray
以下のページを参考にセットアップを行う。
↑ページの書いてあるとおりに実行するだけで特に問題なくセットアップは完了。 一応、念の為、手順のメモを残しておく。
1. USBドライバのインストール
M5Stack の公式サイトからUSBドライバ(CP210X Driver)をダウンロードしてインストールする。
ダウンロードしたZIPを解凍するとdmgが出てくるのでマウントする。中の Silicon Labs VCP Driver.pkg だおダブルクリックでインストールする。途中、セキュリティに関する警告が出るので、システム環境設定のセキュリティとプライバシーのパネルでアクセスを許可してやる必要がある。
/dev/tty.SLAB_USBtoUART
が存在すればインストールは成功。
2. ArduinoIDEのインストール
ダウンロードしたZIPを解凍するとプログラムが出てくるので、アプリケーションフォルダにコピーする。
3. Arduino core for the ESP32 のインストール
サイトにあるドキュメント「Installation instructions for Mac OS」に従い、以下のコマンドを実行する。
mkdir -p ~/Documents/Arduino/hardware/espressif && \ cd ~/Documents/Arduino/hardware/espressif && \ git clone https://github.com/espressif/arduino-esp32.git esp32 && \ cd esp32 && \ git submodule update --init --recursive && \ cd tools && \ python get.py
4. ArduinoIDEの設定。
ArduinoIDEを起動して以下の設定を行う。
- メニュー:ツール→シリアルポートより、/dev/tty.SLAB_USBtoUART を選択。
- メニュー:ツール→ボードより、M5Stack-Core-ESP32 を選択。
- メニュー:スケッチ→ライブラリをインクルード→ライブラリを管理を選択。
- 表示されるライブラリマネージャーのダイアログより、M5Stack用のライブラリ「M5Stack by M5Stack」をインストールする。
5.Hello Worldの実行
テストに、サンプルで用意されている Hello World をM5Stackに転送・実行してみる。
- M5StackをUSBケーブルでMacに接続。
- M5Stackの電源をON
- ArduinoIDEで、メニュー:ファイル→スケッチ例→M5Stack→Basic→Hello World を選択。
- 開かれたスケッチの「マイコンボードに書き込む」ボタンをクリック。
- スケッチがコンパイルされてM5Stackに転送後、再起動して Hellow World が液晶パネルに表示される。
とりあえず動作確認までOK。
Rust 入門 簡単な関数を書いてみる(2)
Rust 入門つづき。
前回、簡単な関数のサンプルとして住所から都道府県を切り出すトコロを書いたので、次は市区町村を切り出す関数。
その前に、前回は関数の戻り値として Option を返すようにしていたのだが、良く考えるとあまり意味がなく冗長なだけなので、単純にタプルを返すように修正。 今回作成する市区町村を切り出す関数も同様の仕様とする。
とりあえず、以前に書いたC#のコードを元に書いてはみたが、変数 re2 を用いた正規表現のチェックを2か所でやってるのがイマイチ。何か巧いやり方はないものか。
Rust の String と &str の使い分けは初学者にはややこしい。イメージとしては String は一般的な文字列型、&str は文字列のスライスと(今のところ)理解していて、 関数の引数には &str で戻り値には String ぐらいのザックリとした感覚で書いている。(最初、&str を戻り値で返そうとしたら怒られた)
今回、ちょっと引っかかったのは、
let city: &str; if let Some(m) = re.captures(address) { city = &m[1] }
というような感じのコードを書いたら
borrowed value does not live long enoughrustc(E0597)
と怒られたことで、変数mの値はif文のブロックを抜けた時点で破棄されるため、参照をブロックの外に持ち出しちゃダメよということらしい。
当たり前のことだが、まだ身についてないのでついついこういうしょーもないミスをしてしまう。
extern crate regex; use regex::Regex; const PREFECTURES:[(&str, &str); 47] = [ ("01","北海道"), ("02","青森県"), ("03","岩手県"), ("04","宮城県"), ("05","秋田県"), ("06","山形県"), ("07","福島県"), ("08","茨城県"), ("09","栃木県"), ("10","群馬県"), ("11","埼玉県"), ("12","千葉県"), ("13","東京都"), ("14","神奈川県"), ("15","新潟県"), ("16","富山県"), ("17","石川県"), ("18","福井県"), ("19","山梨県"), ("20","長野県"), ("21","岐阜県"), ("22","静岡県"), ("23","愛知県"), ("24","三重県"), ("25","滋賀県"), ("26","京都府"), ("27","大阪府"), ("28","兵庫県"), ("29","奈良県"), ("30","和歌山県"), ("31","鳥取県"), ("32","島根県"), ("33","岡山県"), ("34","広島県"), ("35","山口県"), ("36","徳島県"), ("37","香川県"), ("38","愛媛県"), ("39","高知県"), ("40","福岡県"), ("41","佐賀県"), ("42","長崎県"), ("43","熊本県"), ("44","大分県"), ("45","宮崎県"), ("46","鹿児島県"), ("47","沖縄県") ]; // 住所から都道府県とそれ以降を分割する fn get_prefecture(address: &str) -> (String, String) { let prefectures = PREFECTURES.iter().map(|x| x.1).collect::<Vec<&str>>().join("|"); let pattern = format!("^({})(.+*)$", prefectures); let re = Regex::new(&pattern).unwrap(); match re.captures(address) { Some(m) => ((&m[1]).to_string(), (&m[2]).to_string()), None => ("".to_string(), address.to_string()) } } // 住所から市区町村とそれ以降を分割する fn get_city(address: &str) -> (String, String) { let re1 = Regex::new(concat!( "^(余市郡(仁木町|赤井川村|余市町)|余市町|柴田郡村田町|(武蔵|東)村山市|", "[東西北]村山郡...?町|田村(市|郡..町)芳賀郡市貝町|(佐波郡)?玉村町|[羽大]村市|", "(十日|大)町市|(中新川郡)?上市町|(野々|[四廿]日)市市|西八代郡市川三郷町|", "神崎郡市川町|高市郡(高取町|明日香村)|(吉野郡)?下市町|(杵島郡)?大町町)(.+)" )).unwrap(); let re2 = Regex::new("^(.+[市区町村])(.+)").unwrap(); match re1.captures(address) { Some(m) => { match re2.captures(&m[12]) { Some(m2) => (format!("{}{}",(&m[1]),(&m2[1])), (&m2[2]).to_string()), None => ((&m[1]).to_string(), (&m[12]).to_string()) } }, None => { match re2.captures(address) { Some(m2) => ((&m2[1]).to_string(), (&m2[2]).to_string()), None => ("".to_string(), address.to_string()) } } } } fn main() { let (prefecture, tmp1) = get_prefecture("大阪府大阪市北区ほげほげ9丁目99-909"); let (city, tmp2) = get_city(&tmp1); println!("Prefecture: {:?}", prefecture); println!("City: {:?}", city); println!("...: {:?}", tmp2); }
みんなのM5Stack入門
以前から気になっていた M5Stack を入門書&タイアップのスターターキットが発売されたのが良い機会かなと思い、スイッチサイエンスで注文。 とりあえず商品が届くまでの間、その入門書である「みんなのM5Stack入門」(下島健彦・リックテレコム)を買って読んでみた。
内容はハードの紹介から始まって、単体で動作するプログラムで画面やボタン、内臓の9軸センサの制御の仕方を学んで、その後、定番のLチカなど 各種センサやデバイスを繋いでのデジタル・アナログの入出力ライブラリの解説、最後に内蔵のWIFIとBluetoothを利用した通信の解説とM5Stackでできることを一通り網羅している。 入門書としては一般的な手堅い内容。電子工作の基礎的な話は控えめでプログラム主体で進んでいくためプログラマとしては馴染みやすいのが個人的には気に入ったところ。サンプルの 電子工作も非接触の温度センサーとサーボモーターを利用して簡易なサーモグラフィを作成するなど興味深い題材を扱ってる。
ブツが届く前に読む本としては期待度がMAXにまで高まる良い本だった。
iPhone11 Pro に機種変更
先日の連休、近所のソフトバンクで端末を iPhone X から iPhone11 Pro に機種変更した。
2年ぶりの機種変更だが、契約の説明が店員の口頭から動画の視聴になってたり、旧端末の店頭での回収を受け付けてくれなくなったりといろいろ進化?していて戸惑うが、iPadでの契約のサインが未だに Apple Pencil ではなくゴム頭のスタイラスでさせたりするのがソフトバンクの駄目なとこだろう。
二、三日使ってみたけど、カメラが良くなった(超広角とナイトモードは良い)以外は体感的に大きく変わるものはなく感動はまあそれなりといった感じ。iPhone7、iPhone X と2回連続でスクリーンにヒビを入れてしまったので、今回は嫌々ながらケースとガラスフィルムを付けたのが一番の感覚的な違いだろうか。
Rust 入門 簡単な関数を書いてみる(1)
Rust 入門その2
前回、FizzBuzzを書いてとりあえずコンパイルと実行の仕方は判ったので、次ももう少しまともなコードを書いてみることにする。
適当な題材はないかと考えて、以前C#で書いた住所の文字列から都道府県や市区町村を分割するコードがあるので、それをRustで書き直してみる。
想像以上に手間取ったので、とりあえず住所から都道府県を切り出す部分のみ。
やりかたは都道府県の名称を正規表現で切り出すだけなのだが、勝手が判らず簡単そうなトコでも思ったようにいかない。
引っかかったのは以下の箇所。
- 静的な配列の定義のしかた。
- タプルの配列から要素を取り出し一つの文字列に連結する方法
- 正規表現の使い方
- Stringと&strの違い などなど
関数はRustっぽくResultを返すようにしたけど、単純に都道府県とそれ以降のタプルを返す方が後の処理が単純で良いかもしれない。
extern crate regex; use regex::Regex; const PREFECTURES:[(&str, &str); 47] = [ ("01","北海道"), ("02","青森県"), ("03","岩手県"), ("04","宮城県"), ("05","秋田県"), ("06","山形県"), ("07","福島県"), ("08","茨城県"), ("09","栃木県"), ("10","群馬県"), ("11","埼玉県"), ("12","千葉県"), ("13","東京都"), ("14","神奈川県"), ("15","新潟県"), ("16","富山県"), ("17","石川県"), ("18","福井県"), ("19","山梨県"), ("20","長野県"), ("21","岐阜県"), ("22","静岡県"), ("23","愛知県"), ("24","三重県"), ("25","滋賀県"), ("26","京都府"), ("27","大阪府"), ("28","兵庫県"), ("29","奈良県"), ("30","和歌山県"), ("31","鳥取県"), ("32","島根県"), ("33","岡山県"), ("34","広島県"), ("35","山口県"), ("36","徳島県"), ("37","香川県"), ("38","愛媛県"), ("39","高知県"), ("40","福岡県"), ("41","佐賀県"), ("42","長崎県"), ("43","熊本県"), ("44","大分県"), ("45","宮崎県"), ("46","鹿児島県"), ("47","沖縄県") ]; // 住所から都道府県とそれ以降を分割する fn get_prefecture(address: &str) -> Result<(String, String), String> { let prefectures = PREFECTURES.iter().map(|x| x.1).collect::<Vec<&str>>().join("|"); let pattern = format!("^({})(.+*)$", prefectures); let re = Regex::new(&pattern).unwrap(); match re.captures(address) { Some(m) => Ok(((&m[1]).to_string(), (&m[2]).to_string())), None => Err("No match".to_string()) } } // main fn main() { match get_prefecture("大阪府大阪市北区ほげほげ1-2-3") { Ok(ret) => println!("{:?}", ret), Err(e) => println!("{}", e) }; }
DXライブラリで、描画した図形に穴をあける
DXライブラリを利用して児童向けの学習教材を作成しているのだが、MakeScreen()したグラフィックに描画した矩形などの図形に穴をあけて背景を透過させる必要が出てきた。
DrawCircle() などの関数に指定する色に透明色?が指定できれば良いのだが、DXライブラリで使用する色コードには透明度の情報はない。
最初、マスク関係関数の機能を利用すればできそうかなと考えたが、マスクデータがDXライブラリのグラフィックではなくバイナリの配列データで用意する必要があり面倒。
もうちょっと手軽にできる方法はないかと検索してみたら、DXライブラリ質問掲示板で 「MakeGraph() による背景の透明化」という記事を見つけた。
その記事によると、SetDrawBlendMode()で、乗算モードを指定してパラメーターに0を指定することで、描画時のアルファチャンネルの値を0にすることができるらしい。この時、乗算モードを指定するのをリファレンスに記載されている DX_BLENDMODE_MULA(11)ではなく、DX_BLENDMODE_MUL(4)を指定しなくてはいけない。ここら辺の仕組みリファレンスに記載がないので何がどうしてどうなってるのかさっぱりだが、とりあえず試してみると期待していた描画ができた。
// ■ 穴の開いた矩形を描画する。 // 矩形を描く DX.DrawBox(0, 0, 640, 480, red , DX.TRUE); // ブレンドモードで乗算モードを指定 DX.SetDrawBlendMode(DX.DX_BLENDMODE_MUL, 0); // ここで描画した円はアルファチャンネルが0で描画されるため透明になる。 // 結果として透明になるので指定する色は何色でも良い。 DX.DrawCircle(100, 100, 50, WHITE, DX.TRUE); // ブレンドモードを元に戻す DX.SetDrawBlendMode(DX.DX_BLENDMODE_NOBLEND, 255);