2017年の振り返り
今年は書くぞー。
設計
プログラムの設計とかファイル構成なんかに、だいぶ気を遣うようになった。
一人だと何やっても勝手ではあるけど、やっぱりちゃんと整理しておいたほうが機能追加も仕様変更も対応しやすい(当たり前だ・・・)。
ただ、設計に凝りすぎてなかなか手が動かなかったり、ファイルを分割しすぎて逆に全体が把握できなくなったりもしたので、その辺のさじ加減はもうちょっとうまくできるようになりたい。
たぶん、もうちょっとゆるく書き始めて、複雑になってきたら分割すれば良いんじゃないか、と思う。
React
WebアプリケーションのフロントはほぼReactで書くようになった。
簡単なものだったらReact+Fluxで、複雑になってきたらRedux、XHRが入るならredux-thunk、で4〜5つ作ったor作りかけている。
たぶん、Component志向でVirtualDOMならReactでなくてもいいんだとは思うけど、慣れてしまったので、しばらくはこれでいいかなーという心境。
あとは以前にBackbone.jsをカオスにして作ったけっこう大規模なアプリケーションを書き直したい・・・。
Vue.jsとAngular2
も、ちょっと触りました。
先にReact触った人間なので、Vue.jsのほうがとっつきやすかった。
ただ、昼間に大学でReactを書き、夜に自宅(フリーランス)でVueを書く、という事態に陥った時期があり、両者の記法が混同してものすごく効率が悪かった・・・。
CSS
BEMにECSSをちょっと足した、みたいな独自の設計方針で落ち着いてました。
で、Webアプリでどうせbuildする場合はSASSで書く感じ。
CSSの仕様はひととおり把握できてきたようで、「なんでこういう表示になる(ならない)の?」と思うことはなくなった。なんか一定の段階には達した気がする。
サーバサイド
RESTfulAPIをフロントと同じだけ作ってるけど、RubyだったりPHPだったりNode.jsだったり。
内容にもよるけど、どれも一長一短な気がして定まっていないので、来年はなんとかしたい。
その他
nginxの設定とか、Neo4jとかSPARQLとか。あとPythonが少し。
旅行記
いろんなとこに行きました(@出張)
大阪
京都・・・写真がない
盛岡・・・写真がこれしかない
ダブリン
からの、ロンドン
東京が何度か・・・わざわざ写真撮ってない
熊本
来年もどこか行けますかね。
仕事とはいえ好きにさせてもらって、家族には感謝してます。
named pipeでオンデマンド・ダウンロード
「オンデマンド・ダウンロード」って勝手に呼んでるんですけど、要するに、ダウンロード要求があった時に、サーバーサイドで動的に(複数ファイルから)tarを生成してダウンロードさせる、というのを実装した時のメモです。
サーバにダウンロード対象のファイルが数万あって、どのセットをダウンロードしたいかが動的に決まるので、予めzipなどを用意することができない、でもファイル1つずつダウンロードしてもらうのは面倒、という状況でした。
デメリットとしては、tarなので圧縮されない、というのはあります。(今回の状況では、対象のファイルはバイナリが主で、大幅な圧縮は期待できないのでそれでも構わないとしました。)
実装にはnamed pipeを使いました。
named pipeとは:
名前付きパイプ - Wikipedia
これを使えば、一旦ファイルに書き出さなくても、プロセス間で通信(データの受け渡し)ができます。今回はtarの中身をパイプに流して、Webサーバのレスポンスとして使います。
named pipeを作って、tarを流す。
$ mkfifo pipe_path $ tar cvfh pipe_path tar_path
pipeに流れているものをPHPからレスポンス。
if (file_exists($pipe_path)) { header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="tar_name.tar"'); header('Content-Transfer-Encoding: binary'); header('Expires: 0'); header('Cache-Control: must-revalidate'); header('Pragma: public'); header('Connection: close'); ob_end_clean(); readfile($pipe_path); exit(); }
最終的なファイルサイズが決まらないため、ブラウザではダウンロードの残り時間の予測は表示されません。
また、環境によるかもしれませんが、上記のような感じで、
1. PHPからnamed pipeを作るシェルスクリプトを実行
2. ダウンロード(レスポンス)開始
とやる場合、1と2の間で1秒くらいsleep()を入れるとスムーズでした。そうでないと、file_exists($pipe_path)でfalseが返ってくる場合がありました。
NDS第52回勉強会に行ってきたよ
51回に引き続き、第52回勉強会(2017/06/17) - 長岡 IT開発者 勉強会(NDS)に行ってきました。
前回も書きましたが、NDSは名称に「IT開発者」とあるとおり、幅広い分野の開発者さんが参加しているところが好きです。
私は今回はCSSのお話をさせてもらいました。
今日から使えるCSSパターン // Speaker Deck
自分自身がCSSのコーディング業務で取り入れてよかったもの、みたいな切り口で、短め(10分)の発表にしました。
もうちょっときちんとした設計論みたいなものに昇華できたかな、という気もしますが、そういったものはすでに世の中に出てますし、勉強会のテーマも「初心者むけ」だったので、と言い訳しておきます。
その次元に持ち上げる論理的回路が私の頭にはないみたいです・・・。
ひとつだけ補足で、ECSSという手法に触れていますが、
日本語記事ではこちらのシリーズがとても分かりやすいです。
連載 | Enduring CSS | HTML5Experts.jp
以下、みなさんの発表を聞きながらのメモ・感想など:
「はじめてのC#プログラミング」ailightさん
「C#」にとどまらず、アセンブリあたりからの流れをお話ししてくださっておもしろかったです。
実際にコードを見せてもらうと、やったことない言語でも少し触ってみたら学びがありそうだな、と思いました。
「うまく書きたいと願わないと書いてもうまくならない」「プログラムを書かなければバグは出ない」はまさに真理だと思います!
「なんてかんたんなJavaEE」civicさん
JavaEEには馴染みがなく、どんなものか知らなかったのですが、
JSONを返すREST APIを作るデモを見せていただいて、概要をつかむことができました。
以前にJavaでWebアプリケーションを開発している人とお話したことがあって、
(類似のサービスを私が作っていたため、どんな仕組みか説明してくれた)
あれはきっとこういうフレームワークを使っていたのだ、と悟りました。
「文字コードとプログラミング(仮)」gonchan93さん
文字コードは深く考えると大変そうで、いつもなんとなくUTF-8でやっていましたが、
どうやらそれで大丈夫だということと、
今はメールもUTF-8でOK、という学び!
データベースが絡む場合など、みなさん苦労してるんだな、ということが分かったのも良かったです。
「Ncatを使おう」hayajoさん
Ncatって何だろう、と思っていたら、コマンドでした。
HTTPクライアントにもサーバにもなってくれる、とても便利そうなものでした。
HTTP->HTTPSの変換ができるとか、さっそく開発に活かせそうな感じがしました。
とりあえずHTTP/2通信できるかやってみたいです。
「怖くないし役に立つ設計原則の話」neko_gata_sさん
実際にプログラムを組むにあたって、どのように設計原則を活かすのか、というお話でした(と理解しました)。
自分自身を「設計」を考えるのがわりと好きなタイプだと思っているので、とても興味深かったです。
DRYでないコードが出てきたときには、共通化のほかに分割し直す、というアプローチを考慮すべきということ、と、
将来的に変わるかもしれない仕様と、変わりにくい仕様、という視点があるということ、の2つが大きな学びでした。
※私の発表の背景にあった設計についての概念に似た部分があって、自分の発表の前にこのお話があったことで、意図せずフォローしてもらった感じがします。大変助かりました!
「はじめてのソフトウェアテスト」kasacchifulさん
テストについて、種類や原則、手法まで取り上げられていて、「テスト」というのは自分が漠然と思っていたよりも広い世界なんだな、という印象を受けました。
<自分的メモ>
ドキュメントの段階で欠陥がある場合
費用や時間との兼ね合い
3色ボールペン
テストの設計・実施をそれぞれどのタイミングで行うか
「はじめての修羅場」hiro_ishibashiさん
タイトルのインパクトが強大ですが、内容はとても冷静に分析されているものでした。
こんなPMさんが修羅場に降りてきたら間違いなく救世主に見えます。
「新人研修の作り方」のその後 LT5min masaru_b_cl
習得速度のばらつきなどを検証して、改善していっているとのこと。
小さなステップに分割する、チュートリアルのコードを拡張してもらう、など。
私の場合、大学でわりとほったらかし気味(?)に教わっただけなので、企業での研修のお話は新鮮でした。
Neo4j + Rubyでグラフデータベース探索(Neo4j v3.1.2 + Ruby)
久しぶりにグラフデータベースをいじったのでメモ。
Neo4j・・・NoSQLに分類されるグラフデータベース。
公式ページ:Neo4j, the world's leading graph database - Neo4j Graph Database
少し前になりますが、パナマ文書の解析にも使用されたと紹介されていました。
こちらの日本語記事がとても興味深いです:「パナマ文書」解析の技術的側面 – Keiichiro Ono – Medium
グラフデータベースなので、人物の相関図(Twitterのフォロー・フォロワー関係のような)や、路線図を格納・検索するのには適していますが、テーブル構造のデータには当然リレーショナルデータベースを使うべきなので、「これはNeo4jを使おう!」という場面は私のお仕事の範囲ではまだそれほど多くありません。また、データ自体がグラフ構造でも検索目的によってはRDBが適している、という場合もあります。
ということで、久しぶりになってしまったので、最低限のデータロードと探索方法のメモです。
Neo4jの起動
Neo4jはメジャーバージョンが3になっていました。
個人で非商用に使うぶんには無料ですので、https://neo4j.com/download/ からダウンロードしてインストールします。
バージョン2系のときはコマンドラインから起動していたのですが、3からは簡単なGUIアプリケーションが付属しています。
これを起動してサーバをスタートします。
サーバが起動していれば、ブラウザから http://localhost:7474 にアクセスするとコンソールが表示されます。
パスワードを聞かれますが、初期設定は「neo4j」です。ログインするとまず「パスワード」を変更するようにうながされますので、変更します。
(そのまま「neo4j」にするとエラーになるので、何か別のものにする必要があります。)
Rubyから操作する
RubyからNeo4jを操作するためのドライバは、Neo4jの公式ページで紹介されているものでは、
- neography
- neo4j-core
- neo4j (これはRubyのドライバとしての名前で、データベース本体の「Neo4j」とは別物)
の3つがあります。
neographyは何年も前からあり、私も以前使用していたのですが、GitHubを見ると最近はリリース・開発ともにあまり活発ではないようです。(ある程度完成している、という面もあるのかもしれませんが。)
neo4jも以前からありますが、こちらはRubyOnRailsやActiveRecordと合わせての利用向けという印象で、「スクリプトを書いて探索したいだけ」の用途にはオーバースペックに思えて使用したことがありませんでした。
そういう人が他にもいたのかどうか分かりませんが、neo4jからローレベルAPIだけを取り出したneo4j-coreというものができていましたので、今回はこちらを使ってみます(もしかしたらだいぶ以前から存在していたのかもしれませんが・・・)。
GitHub:https://github.com/neo4jrb/neo4j-core
Gem:https://rubygems.org/gems/neo4j-core/
ドライバ本体は、
gem install neo4j-core
でインストールできます。
ここから先のサンプルコードは全部まとめてGitHubに置きました。
GitHub - yuw27b/neo4j_ruby_sample: Load and search data on Neo4j with Ruby driver
サンプルデータ:都道府県の隣接関係
サンプル用にこんな感じのデータを用意してみました(*)。くっついている都道府県のリストです。接続方法が橋かどうか、という情報を持っています。
#pref1 | #pref2 | #bridge |
---|---|---|
北海道 | 青森県 | 1 |
岩手県 | 青森県 | |
秋田県 | 青森県 | |
宮城県 | 岩手県 | |
つづく・・・ |
グラフのロード
Neo4j本体にはCSVロード用のコマンドラインツールも付属していますが、わざわざインポート用CSVの成形をするくらいなら、Rubyでデータをパースしながらneo4j-core経由でロードしていくほうがやりやすく感じます。
(手元のCSVファイルがneo4jのツールでそのまま使えるフォーマットであれば別ですが、私の経験上そういうケースはあまりないので。)
ロード用スクリプト:
https://github.com/yuw27b/neo4j_ruby_sample/blob/master/load.rb
ロードしたらコンソール(http://localhost:7474)で確認してみます。
※コンソールの左側メニューにあるボタンは、25ノードor25エッジまで表示します。あまり大きなネットワークをプレビューしようとすると、ブラウザが重くなってくるので、自分でCypher queryを実行する場合も100くらいでLIMITをかけておいたほうが無難です。
グラフの探索
Cypher Queryの一例です。
新潟県のお隣のお隣
MATCH (a{name: '新潟県'})-[*2]->(b) RETURN DISTINCT b
橋でつながっているところ
MATCH (a)-[:Adjoin{connection: 'bridge'}]->(b) RETURN a, b
新潟県から神奈川県までの経路10個まで。ただし、経由する都道府県は9まで。
MATCH p = (a{name: '新潟県'})-[*..10]->(b{name: '神奈川県'}) RETURN p LIMIT 10
※グラフなので、経路探索の場合は容易に組み合わせ爆発が起こります。経路の長さやマッチさせる数に制限をかけないといつまで経ってもレスポンスが帰ってきません。
新潟県から神奈川県までを最短経路で
この場合は、距離を無視しているので、経由する都道府県が最も少ない、という検索になります。また、同様に組み合わせ爆発が起きる可能性があるので、経由数の上限もつけてあります。
MATCH p=shortestPath((a:Pref {name: '新潟県'})-[*0..10]-(b:Pref {name: '神奈川県'})) RETURN p
2つ以上ある場合に全部取るなら、
MATCH p=allShortestPaths((a:Pref {name: '新潟県'})-[*0..10]-(b:Pref {name: '神奈川県'})) RETURN p
ドライバ経由の探索
ドライバ(neo4j-core)経由の場合は、
そのままCypher Queryを投げるやり方
Neo4j::Session.query("MATCH (a{name: '新潟県'})-[*2]->(b) RETURN DISTINCT b.name")
と、
Cypher DSL APIを利用して、もう少し読みやすい(?)感じで書くやり方
Neo4j::Session.query.match('(a)-[*2]->(b)').where(a: {name: '新潟県'}).pluck('DISTINCT b.name')
があります。
個人的には別にDSLじゃなくてもいいかなあ、と思っていますが・・・。
簡単なコード例はこちらにあります:
GitHub - yuw27b/neo4j_ruby_sample: Load and search data on Neo4j with Ruby driver
以下、公式サイトなどのリンクです。
こういうのはできるのかな?どうやるのかな?というときはこのあたりを調べるとだいたいあるような気がします。
公式ページ https://neo4j.com/
Cypher Queryのドキュメント https://neo4j.com/developer/cypher/
Cypher Queryチートシート https://neo4j.com/docs/cypher-refcard/current/
また、Rubyのドライバ(neo4j-core)に関してはGitHubリポジトリにドキュメントがあります。
Home · neo4jrb/neo4j-core Wiki · GitHub
※データはこちらを参考にさせてもらいました:http://uub.jp/prf/rinsetsu.html
NDS第51回勉強会に行ってきたよ
第51回勉強会(2017/03/25) - 長岡 IT開発者 勉強会(NDS) に行ってきました。
50回は行けなかったので、半年ぶりのNDS、半年ぶりの長岡でした。
NDSは名称に「IT開発者」とあるとおり、幅広い分野の開発者さんが参加しているところが好きです。
私はWeb周りをやっているので、普段SIerさんとお話しする機会はなかなかないですが、NDSでそういった方の発表を聞くと勉強になります。
また、今回は「データに関わるなにか」がテーマということで、グラフ構造データについて発表させてもらいました。
スライドはこれです:
yuw27b.github.io
という、それぞれ独立したものを詰め合わせたのですが、「独立したもの」ってちゃんと伝わったかどうかがちょっと不安です(もうちょっと強調してしゃべるべきだったかな、と。)
そもそもは、Neo4jやSPARQLを使ったことある人はあんまりいないんじゃないかな、と思って題材に選びました。
質問していただけたり、知らなかったよ、と言ってもらったりしたので、その点は良かったです。
今すぐ業務に使う、ということはあまりないかもしれませんが、こんなものもあるんだな、と思っていただけてたらうれしいな。
以下、みなさんの発表を聞きながらのメモ・感想など、備忘録:
Vue.jsから始めるDOMにデータを持たせないアプリケーション開発への第1歩 nemuzukaさん
サーバからJSON返してもらうような業務用Webアプリケーションを作っているとのこと。
jQueryやテンプレートエンジンでは辛くなってきたが、業務アプリでReactとかAngularを覚えるのもちょっと、ということでVue.jsを採用したそう。
HTMLのクラスがJS用かCSS用かわからなくなるなど、DOMにデータを持たせるのは限界だった、とおっしゃってましたが、非常に共感できました。
ちょうどVue.jsやってみたいな、というところだったので、タイムリーな発表でした!
RDBMS のトランザクション分離レベルやレプリケーションとか。あと苦労話。 bell-miyaさん
なんとなくサーバサイドもやっている(けどフロントメイン)な私が一番分かってない部分な気がしていて、楽しみにしていた発表でした。で、やっぱり私分かってないな、と。
分離レベルやSQL標準など、まだ理解しきれませんでしたが、勉強していきたいです。
入門系の本を一冊も読まずにデータサイエンスの世界に足を突っ込んでみる sakapunさん
チートシートがわかりやすかったです!やはりこの分野はPythonなんですね。
職場に機械学習をやっている人たちがいて、彼らはChainerを使っているようでしたが、今はいっぱいあるんだな、と。
あと「そろそろ本を読む」とのことでした。
PostgreSQL データ型 civicさん
「数値・文字列・日付ぐらいしか使ってない」って私のとこですね・・・。
PostgreSQLはデータ型が多いと思ったが、現在はそれほど差がなかった、というのが興味深かったです。
Python SQL Alchemyが便利とか。
排他制約とか、そもそも適切な型を指定するとか、もっとちゃんとやるべきだな、と思いました。