@ledsun blog

無味の味は佳境に入らざればすなわち知れず

日本kindle化計画 その1

背景

占有体積コストがバカにならないので、漫画を極力Kindleで買うようにしています。 Kindle版は紙の書籍より遅れて登録されます。 紙の書籍を発見されてから、Kindle版が出ているかどうか定期的に確認する必要があります。

既存のKindle化チェックツール

既存のチェックツールがあります。

ざっくり、以下の点が僕の要望とミスマッチです。

通知方法がメール

  • kindlize-itは通知方法がメールです

以下、Kindle Alertのみの話です。

ログインが必要な理由が書いていない

  • ツイッターID確認のためだとは思う
  • 他人のIDを登録しても大した悪さはできない気がする・・・
  • メンション自体は自由に飛ばせる
  • 全く使っていない人はブロックすればいい
  • 使っている人に、自分の好みでないものを勝手に追加されると辛い気はする
  • 削除できないのが問題な気もする

キーワード検索

  • 使う時点で、紙の書籍があることは知っています
  • asinを直接指定したい

検索結果にkindleがあるか載っていない

  • 毎回amazonへのリンクを開くの?
  • kindleがあっても登録できてしまう・・・

自分への通知が登録済みかどうかわからない

  • ストーキングに使える?
  • twilogで検索しても一緒なので、過去に対しては意味がない

どういう通知が来るのかわからない

  • 直近のツイートが表示されていると良さそう

APIがない

  • Chrome拡張から登録できない

その他

  • 検索結果がconfirm?
  • なぜ1アカウントずつツイートなんだろう?他人のアカウントが見えたらまずい?
  • ハッシュタグが入っていればいいのに
  • 既にkindleが出ているものも通知してくる

自作

とりあえずチェック部分だけ作りました。 まだデータ投入は生クエリです。

さっそく、入力データをミスりました。 次は、入力インタフェースを作ろうと思います。

辛さ

AWSTwitterの二つのAPIで6個の秘密情報を管理するのが辛いです。

#TestingFrameworkMeeting に参加しました(1) - テスティングフレームワークの歴史

参加した時のメモです。

t-wadaさん

Testing Framwork Meeting

テスティングフレームワークの歴史

http://www.slideshare.net/everzet/bdd-in-symfony2/42 のスライドがベース。

有史以前

make checkのように、テストを自動化する風習はあった。 開発者はそれぞれ秘伝の手法でテストコードを書いていた。

JUnit

Kent BeckJUnitを書いた。

プロダクトコード書いてから、テストコードを書くまでの時間が短いほうが、 プロダクトコードに対する気づきが得られ、それをプロダクトコードに反映できることがわかった。

テストコードをさらに早く、プロダクトコードより早く書いた。 テストファーストが生まれ、ユーザーの視点でプロダクトコードを設計できるようになった。

自動テストがあれば、設計して実装してから、実装だけを直せる。 サイクルをもっと短くし、テストファーストリファクタリングを繰り返すテスト駆動開発(TDD)が生まれた。 *1

JUnitの語彙assertEqualsがテストコードを支配した。

JUnit Pocket Guide - O'Reilly Media がテスティングフレームワーク作者ののバイブルになった。

BDD

テストコードが表しているのは、テストではなく仕様であると考える者達が居た。 Dan Northは、それにbehavior driven development(BDD)と名付けた。

RSpecが生まれ、振る舞いを記述するための語彙、should, expect ... 、が増えた。 各プログラミング言語にXSpecが生まれ、語彙が乱れていった。

また、自然言語のように書けテストコードをのように動く仕様で、 お客さんと一緒に仕様を書くことを考える者達が居た。 Fitが生まれ、cucumberが生まれた。

BDD派は、前者がSpec BDD派へ、後者がScenario BDD派へ分派していった。

power-assert

RSpec3が生まれた。テストコードの語彙がさらに増え、いろいろな書き方ができるようになった。 テストコードを書くのに学ぶべきことが増えた。

多くのRuby on Rails使用者は、Rails本体とRSpec、両方の変化の速さについて行くために苦しんだ。

テストが失敗した原因をわかりやすくするために、 語彙を増やす以外にテスティングフレームワークができることはないか考えた者が居た。 Groovyにspockが生まれた。 そこにはPowerAssertと呼ばれる力があった。

Condition not satisfied:

name.size() == length
|    |      |  |
|    6      |  7
Scotty      false
魅惑的(Fascinating)なテスティングフレームワーク Spock - A Memorandum

エラーに失敗した時だけ饒舌なassertが生まれた。 ASTをごにょごにょして、t-wadaさんがJavaScript版のpower-assertを作った。

evolve slowly

テスティングフレームワークは、直接的にプロダクトコードを改善しない。 10年くらいのペースで変わるのが望ましい。

議論

語彙と階層
  • RSpecの語彙の多さは、目的が仕様記述言語を目指しているから。 多くのユーザーは階層化と語彙の多さは分離して欲しいが、わけて使えない。 それで批判に繋がっているのでは?
  • RSpec以降のライブラリは階層と語彙を分けれるようになっている。(例えば)mochaは階層化だけを提供していて、assertライブラリは別に組み合わせて使う。
学習コスト
  • RSpecのシェアが大きすぎるので、学習コストの批判が目立っているのでは?
  • 政治的な理由でRSpecを選択していることもある。それで批判されやすいのかもしれない。
日本語でシナリオBDD
  • cucumberは正規表現で実装されている。日本語で使える可能性や価値はあるのか?
  • 過去に、「なでしこUnit」を作った。日本語の語順と制御の順が合わないので、そんなに嬉しくなかった。
テストコードのレイヤーが増えること
  • (プロダクトコードと異なるプログラミング言語で描かれている)cucumberを使った、テストは落ちたときに原因を探すレイヤーが増えて辛かった。
  • JavaのテストコードをGroovyで書く人たちがいる。テストコードを書く効率はあがる。
Reads like as spoken language
  • RSpecには読みやすさを提供する目的があったのでは?
  • JUnit4でisが入って読みやすくなった。覚えるコストは増えた。これは二律背反、当分解消できそうにない。
Expamleとしてのテストコード
  • Expamleとしてのテストコードを考えると、TDDではプロダクトコードに近く例としてわかりやすい。 BDDで仕様記述に近いと、例として使えなくなっていく。
  • Exampleとしてのテストコードは一部なので分けて考えた方がよさそう。 Haskellにはdoctestという、公開するAPIにExampleとしてのテストコードをつける文化が生まれている。公開しない部分はhspecで書く。
  • Goでは、Exampleとしてのテストコードを書くツールがある。

simple vs easy

power-assertの設計思想について。

で、衝撃を受けたという話。

  • Simple 客観的
  • Easy 主観的

SimpleとEasyは混同しやすいけど、分けて考えた方が良い。 原則はSimpleを目指し、EasyはEasyを提供する別レイヤーを提供すると良い設計になる。

実際にソフトウェアを作る時は、怠惰・短気・傲慢の怠惰を元に、 簡単さを求めて作り始めて、複数の簡単さの競合に気づいて、「シンプル」と「簡単」に分けるようになることが多い 。

qunit-tapの開発では、当初Easyを求めて「自動的にQUnitを探す」設計にしていた。 多様な環境に対応できなかったので、Simpleな「QUnti引数で受け取る」設計に変えた。 結果、より多くの人に使いやすくなってユーザーが増えた。

リンク

つづき

は、書かないかもしれません。

*1:詳しくはわからないがXP本の1版と2版の間の、どこか

ゴー・ノーゴー課題の原著論文を発見

最近の小学生における高次神経活動の特徴 : go/no-go 実験における誤反応と型判定を基に

計測方法

Pavlov, I. P. 理論(ハ・エス・コシトヤンツ,1955)に基づいて 
Luria, A. R.(1969)により考案された方法

形成実験

「いまから,みなさんの目の前のランプがこの色(赤色)に光ります。この色に光ったら,
すばやくゴム球を握ってください。消えたらパッと離してください」との指示を与え,
10 回の練習を行った後,直ちに 3 ~ 6 秒間隔で,1 回 0.5 ~ 1.5 秒間の光刺激を5 回呈示した

分化実験

次に,「今度はこの色(黄色)に光る時もあります。でも,その時は握ってはいけません。先ほどと同じ,
この色(赤色)の時だけすばやく握ってください」と の指示を与えて,
4 回(go task:2 回,no-go task:2 回)の練習を行った後,直ちに go task と no-go task を
ランダムに呈示した(分化実験)。
この時の光刺激の 呈示間隔と時間は先の形成実験と同様であるが,刺激回数は go task,
no-go task とも 11 回ずつとした

逆転分化実験

最後に,「最後は先ほどと反対です。この色(黄色)の時にすばやく握ってください。この色(赤色)の時
は握らないでください」との指示を与え,4回(go task:2 回,nogo task:2 回)の練習を行った後,
直ちにgo taskと nogo task をランダムに呈示した
この時の光刺激の呈示間隔,時間,回数は,すべて分化実験の場合と同様とした

各型の分類基準

分類型 分化実験 逆転分化実験
不活発型 no-go taskに対する誤反応3個以上かつgo taskに対する誤反応1個以上
興奮型 no-go taskに対する誤反応3個以上かつgo taskに対する誤反応0個
抑制型 no-go taskに対する誤反応3個未満かつgo taskに対する誤反応1個以上
おっとり型 no-go taskに対する誤反応3個未満かつgo taskに対する誤反応0個 no-go taskに対する誤反応3個以上もしくはgo taskに対する誤反応1個以上
活発型 no-go taskに対する誤反応3個未満かつgo taskに対する誤反応0個 no-go taskに対する誤反応3個未満かつgo taskに対する誤反応0個

考察

元来,ヒトは 5 つの型の中でも最も幼稚な型といえる「不活発型」からスタートし,加齢とともに子ども
らしい「興奮型」の時期を経て,次第に成人らしい「活発型」に移行していく(正木・森山,1971;
西條ほか,1981)ものと考えられてきた

これはあまり違和感を感じません。

1998 年調査の結果では,小学校に入学する頃になっても「不活発型」が 5 ~ 6 割にも達しており,
かつその後の推移をみても,男子ではなかなかこのタイプの子どもたちが減っていかない様子から
「学校崩壊」と呼ばれているような事象が起きてしまうのもある程度うなずけるのではないか,
と推察されている(野井,2006)

これはちょっとだけ違和感があります。

感想

go task 11回試行中1ミスで不活発型が興奮型に分類されるのがシビアに思えます。 ですが、結果を見ると、抑制型の出現率は10%前後です。妥当なのかもしれません。

実施環境(明るさ、環境音)によって結果が左右されそうな実験に思えます。 複数の対象群を比較しても意味はないのかもしれません*1

前記事

ledsun.hatenablog.com

*1:ソフトウェア工学でも「異なるソフトウェアを作る異なるスキルのエンジニアで構成されたチームを、同じ計測方法で計測すれば比較できる」と考えてしまうミスが、しばしば起こります

ゴー・ノーゴー課題

はじまり

あまり共感できなかったある本のP20に

旧ロシアの生理学者・パブロフさんの理論に基づいて、子どもたちの大脳前頭葉の特徴を
前頁の表2に示した5つのタイプに分類し、判定しています。
この調査は、「go/no-go実験」と呼ばれているもので

という記述がありました。どういう調査方法なのか調べてみました。

ゴー・ノーゴー課題

認知心理学に「ゴー・ノーゴー課題」というものがあるそうです。

ゴー・ノーゴー課題では、単純な反応を抑止する能力を測定する。
参加者は、ゴー試行(例えば、画面上にQ. P, Tの文字)ではできる限り早く反応(ボタン押しなど)を、
ノーゴー試行(例えば、画面上にXの文字)では反応を抑止するように教示される。
ノーゴー試行でどの程度エラーを産出したかが指標となる

そして

児童期以降は、成人と同じStroop課題やゴー・ノーゴー課題が用いられ、
12歳から16歳頃までに緩やかに発達することが示されている

児童の成長に伴い、エラーが減るようです。 もとは前頭前野の働きを調べる方法だったようです。

前頭前野に損傷のある患者は,ノーゴー反応が求められても,運動反応をしないように抑制することが
困難である。

いずれにせよ、「ゴー・ノーゴー課題」自体には、「5つのタイプに分類」は含まれていないようです。

出典

前出の本でデータの出典が「子どものからだと心白書2006」とありました。 子どものからだと心白書2013を参照したところ、P132 に最近の調査結果が掲載されていました。

調査結果のみで、調査方法は記載されていませんでした。

感想

「ゴー・ノーゴー課題」の計測結果をどのように「5つのタイプに分類」するのか興味深いところです。

また、今の所はイワン・パブロフと「ゴー・ノーゴー課題」の関連も発見できていません。 こちらも気になるところです。

アドテク情報調査中

なぜ今アドテクが流行っているのか?

広告主と消費者のマッチングが適切になると

  • 広告主は少ない費用で売り上げに繋げられる
  • 消費者は全く興味がない広告を見ないで済む

win-winになります。

2014年からネット広告を取引する電子市場が成立しはじめました。 広告主と消費者のマッチングアルゴリズムの工夫次第では、広告の効果を増やせる可能性が出てきました。

そもそも広告市場は巨大です。 5兆円を超えています。ネット広告は1兆円に迫る勢いで成長しています。

ネット広告取引の歴史

以下の順で取引手段が増えました。

  1. 純広
  2. アドサーバー
  3. アドネットワーク
  4. アドエクスチェンジ

純広

広告を売るメディアが、広告枠を売ります。 一般的には広告代理店が広告主に「枠」を売るようです。

アドサーバー

広告をメディアのサーバーからでなく配信サーバーから配信サーバーします。

  1. 広告主はメディアの直接入稿しなくてよい
  2. メディアは期間ではなく表示回数で広告を売れる

アドネットワーク

メデイアは表示数以上に広告を売ることはできません。 見込み表示数より少し少なめに広告枠を売るため、在庫が余りがちです。 在庫の余り分だけ、アドネットワークから出稿を買います。

アドネットワークが複数の広告主から出稿受けておきます。 在庫の余り分なので、あらかじめ安めの価格で売ります。

  1. メディアは余剰在庫がなくなる
  2. 広告主は安い価格で出稿できる

アドエクスチェンジ

アドネットワークでの余剰在庫取引量が増えてくると、普通の広告枠もリアルタイムに取引したくなりました。 そこで出てきたのがRTB(リアルタイムビッディング)です。 広告枠を1表示単位でオークションします。

メディアと広告主がリアルタイムオークションに対応できるシステムを持っていません。 それぞれのシステムを提供するサービス会社を

  • SSP(サプライサイドプラットフォーム)
  • DSP(デマンドサイドプラットフォーム)

と呼びます。

これらの広告取引エコシステムをひっくるめて、アドエクスチェンジと呼びます。

知っておきたい略語

参考図書

ザ・アドテクノロジー データマーケティングの基礎からアトリビューションの概念まで

ザ・アドテクノロジー データマーケティングの基礎からアトリビューションの概念まで

広告用語から説明があって、広告業界初心者にやさしいです。 この記事は、この本からの受け売りです。

DSPはなぜアドネットワークに勝てないのか: 『枠から人へ』は間違いだった

DSPはなぜアドネットワークに勝てないのか: 『枠から人へ』は間違いだった

売上金額でアドエクスチェンジ業者とアドネットワーク業者をみると、未だアドネットワーク業者の方が圧倒的だそうです。 なので、「アドエクスチェンジは真新しいだけで、アドネットワークを完全に置き換えるようなものではない」という趣旨の本です。

ただアドネットワークの代表として上がっている業者が、下記カオスマップではモバイル向けです。 アドネットワークが優位なのもスマートフォンブームによるものかもしれません。

参考URL

アドテク業界では業界地図のことをカオスマップと呼ぶらしいです。 2015年版は複雑すぎます。初心者には2013が優しいです。

海外で枝豆が人気とかいう話を聞いて

そもそも枝豆も食べる食習慣がないのだろうか?

枝豆の歴史 枝豆の総合情報サイト えだまめ日和 によると

未成熟大豆としての枝豆を食べるという食文化は、長い間、アジア諸国独自のものでした。
1991年に出版された *3「New Crops」に「EDAMAME」がアジア特有の新作物として紹介されています。
したがって、この時期までは一般的にアジア以外の諸国では食物としての「枝豆」は知られていなかった
とみてよいでしょう

1991年まで、大豆を枝豆として食べる文化は、アジア以外に知られていなかったらしい。

大豆は?大豆は一般的なんじゃないの?

世界の大豆(生産量、消費量、輸出量、輸入量、価格の推移) によると

大豆の主要な生産国は

  1. アメリカ
  2. ブラジル
  3. アルゼンチン

大豆を作っているのに枝豆にしないのはなぜ?

大豆の歴史|世界の大豆生産国の変遷 によると

ヨーロッパでも大豆を栽培してみようという動きが出てきましたが、
登熟までに必要な日照時間が足りないなどの理由で栽培が難しく、断念しています

ヨーロッパでは生産できないようです。確かに主な生産地に入っていません。 枝豆を食べる習慣がないのも納得です。

では、アメリカでは?

20世紀に入ると大豆は食料の他にも工業原料としての大豆油にも注目が集まりました。
大豆油は石鹸、クレヨン、ローソク、洗剤、ペンキ、ワックス、潤滑油、インクなどの原料として
用途が広がっていき、ヨーロッパ、アメリカは大豆油確保に真剣に取り組み始めました

生産当初は大豆油の原料扱いだっため、食べ物としての認識していなかったのかもしれません。

牛乳、牛肉、卵を生産するための畜産飼料に大豆タンパクが有効であることを見出した

次に飼料用になり、やはり、食べ物ではなかったのかもしれません。

また、南米も

大豆の購入先を失ったソ連はこれに対抗して南米のブラジル、
アルゼンチンに資金を投入して大豆調達の道を広げていった

と、あります。

結論

大豆は(アジア以外では)食べ物ではなかったようです。

Form で遊ぶために対抗サーバーを作って公開した

背景

HTML fromを新人に説明しようとしました。 うまく説明できませんでした。 つまり、よく分かっていません。

ドキュメントを読んで言葉で理解し、 パラメーターを変えながら実際に動かして、心で理解したいです。 しかし、formは対抗するサーバーがないと試しづらいです。*1

form-exercise

formで送信したHTTPリクエストの内容(メソッド、クエリ、ボディ)を表示するサーバーを作りました。

配置先サイト

github

使い方

こういうformから

<form action="https://form-exercise.herokuapp.com/">
    <input type="submit" value="submit">
    <input type="text" name="name" value="1">
</form>

submitすると https://form-exercise.herokuapp.com/?name=1 を表示します。

postメソッドも受け付けます。

実装

connectを使って作りました。 Node.jsです。Herokuで動いています。

実装時にぶつかった課題

connectの標準middlewareは、どれを使うと今風なのかよく分からない

いつもbody-parserをそのまま使っていいのかで迷う。 いいかげんREADMEのサンプルを動かすと、警告出るの何とかして欲しいものです。

let app = connect()
    .use(bodyParser.urlencoded({
        extended: false
    }))

て、bodyParser は extended オプションを指定して使えばいいようです。

renderの共有

middlewareとして実装したい

render関数(データに表示用テンプレートを適用する)は複数のmiddlewareで共有したい。 それでいて、↓のような共通関数でなく

function render(res, values) {
    let html = `
        <div>Method: ${req.method}</div>
        <div>URL: ${req.url}</div>
        <div>Values: ${JSON.stringify(values)}</div>
    `

    res.end(html)
}

connectのmiddlewareとして実装したい。

connectのmiddleware

connectはmiddlewareを追加して機能を追加します。 middlewareはChain of Responsibilityです。

  1. requestとresponseをmiddlewareからmiddlewareと渡して行きます。
  2. 各middlewareはrequestとresponseの自分が興味がある部分を処理し、
  3. 次のmiddlewareにrequestとresponseを渡します。
結論

ExpressのAPIを真似してresponse に renderメソッドを生やすmiddlewareにしました。

デプロイ時にぶつかった課題

ES6をherokuで動かす方法

nodemon使って実装していました。 nodemonは--exec babel-nodeをつけるだけでbabelが動きます。 そこで調子に乗ってES6で実装したらHerokuでの動かし方で困りました。

gulpで変換

gulpで力技変換。こんな風に

var gulp = require('gulp');
var babel = require('gulp-babel');
var rimraf = require('rimraf');

gulp.task('clean', function(cb) {
    rimraf('./dist', cb);
});

gulp.task('lib', ['clean'], function() {
    return gulp.src([
            'src/lib/get.js',
            'src/lib/post.js',
            'src/lib/render.js'
        ])
        .pipe(babel())
        .pipe(gulp.dest('dist/lib'));
});

gulp.task('app', ['lib'], function() {
    return gulp.src([
            'src/app.js'
        ])
        .pipe(babel())
        .pipe(gulp.dest('dist'));
});

gulp.task('default', ['app']);
twitterで知見を得る

@tgfjtさんありがとうございます。

結論

package.jsonに下を書くだけで動きました

"start": "babel-node app.js"

Herokuもbabelも便利すぎる。神なのでしょうか?

※dependenciesにbabelを追加してください。

その他

全くどうでもいい蛇足情報

セキュリティ面ではノーガード実装です。 せっかくなので<script>alert()</script>投げてみると、次のエラーが出て、スクリプトは実行されませんでした。

The XSS Auditor refused to execute a script in 'https://form-exercise.herokuapp.com/?name=%3Cscript%3Ealert%3C%2Fscript%3E' because its source code was found within the request. The auditor was enabled as the server sent neither an 'X-XSS-Protection' nor 'Content-Security-Policy' header.

デフォルトでX-XSS-Protectionが有効なようです。 Google Chrome偉い。

*1:世の中にすでに、類似サーバーがあるかは確認していません。調べ方がよくわかりません。教えてください。

論理削除フラグという名の死亡フラグ

流行っているので乗っかります。

結論

「データ制約の強力さと集合としての表現力を捨てながら、Relational Databaseを使うのはなぜか?」

論理削除フラグのデメリット

大体三つあると考えています。

  1. ユーザーの言葉でない
  2. データ制約の弱さ
  3. 集合として認識できない

ユーザーの言葉でない

私の経験上は、ユーザーから「論理削除」という言葉を聞いたことがありません。 次のような要件は、聞いたことがあります

  • 社員が退職(・転属)する
  • 売掛金の回収を諦めて)売上を打ち消す
  • 「お知らせメッセージ」を公開日がくるまで非表示にする
  • 既読メッセージを表示しない
  • 保存期間が過ぎたアンケート結果をオペレーターが見れなくする

もしかして「論理削除」は実装パターンではないですか? ユーザーが「消す」と言ったのは「データベース上のレコードを削除する」ことでしょうか? ユーザーが「消す」と言った時、反射的に「消すよりは、削除フラグを立てた方が何かあった時に安心」と考えませんでしたか?

もうちょっとだけ、ユーザーがやりたいことを理解できそうです。

データ制約の弱さ

次のテーブルがあったとします。

名前 番号 生死
惣流・アスカ・ラングレー 3rd
綾波レイ 1st
綾波レイ 1st 死亡
綾波レイ 1st 死亡

データ制約上、次のような問題があります。

  • (よく使う)生きている適格者の取得時にwhere句で生死を絞りこみが必要
  • 番号にuniq制約がつけられない

これはアプリケーションカバーします。

  • レコード追加時に生きている適格者の番号が重複しないようにチェックする
  • レコード取得時はwhere句で生死を絞りこむ
  • (または)レコード取得時は「生きている適格者ビュー」を使う
  • レコード取得時に生きている適格者の番号が重複していないかチェックする

さらにデータメンテナンスでカバーします。

  • 重複レコードを発見したら、アプリケーションのバグなのかデータメンテナンスのミスなのか切り分けます。ソースコードやログとにらめっこする
  • 重複レコードを発見したら、SQL文を発行してレコードを修正する

「運用でカバー」は、本当に困った時だけにしたいものです。

集合として認識できない

多くの人は、生きている適格者と死んだ適格者が混じっているテーブルを集合として認識できません。 別のテーブルに分けると、集合として認識できます。

生きている適格者

名前 番号
惣流・アスカ・ラングレー 3rd
綾波レイ 1st

死んだ適格者

名前 番号 死亡日
綾波レイ 1st x月x日
綾波レイ 1st x月x日

テーブルに入っているレコードが推測しやすくなります。

デメリットにならない条件

上記のデメリットが成り立たない時、論理削除フラグは有効です。

  • ユーザーが「消した」データに興味がない
  • アプリケーションの作成工数や運用工数が、データ設計工数より低い
  • (論理削除フラグに慣れた)複雑な集合を認識できるメンバーでチームを作る

JavaScript入門用のコンソールプログラムjavascriptingを翻訳しました

javascriptingを翻訳しました。

javascripting-jpとは何か?

ledsun/javascripting

JavaScriptの文法を学ぶコンソールアプリケーションです。 文字列や数値、条件文やforループなど文法を学びます。

次のコマンドでインストールできます。

npm install --global javascripting-jp

JavaScrpitを学ぶ時にブラウザのWeb APICSSを一緒に覚えるのは大変です。 文法に集中して学ぶことができます。

プログラミング初心者には、Node.jsのインストールが壁になりそうなのが心配です。

本家javascriptingの紹介

javascriptingはNodeSchoolというワークショップ向けのアプリケーションです。

課題の回答が正しいかチェックする機能があります。 コンソールへの出力内容が一致するか確認するシンプルなものです。

厳密なチェックはできませんが、 console.logが分かれば、課題に取り組めます。 面白い割り切りだと思います。

advetureについて

javascriptingはsubstack作の adventureを使って作られています。

adventureに課題と回答を登録すると ワークショップ向けのアプリケーションができます。 実行すると問題文の表示、回答合わせ、進捗管理をしてくれます。

細かい回答合わせ用のadventure-verify というライブラリもあるようです。 使ったことはありません。

多言語化はできません。 今回は問題文を全部書き換えました。 本家の更新に追従するのは諦めています。

多言語化したいときは workshopperというライブラリを使ってワークショッププログラムを作るのが良いようです。

NodeSchoolについて

大阪では定期的に開催されているようです。 NodeSchool | Doorkeeper

(私的)npmモジュールの作りかた

npmモジュールを作るときの自分の手順をまとめました。

プロトタイプをコーディング済みで、コンセプトが固まっている前提です。

モジュール名を決める

  1. npmを検索、類似ライブラリが無いか探す。 ついでに、APIや実装にパクれるネタを探します
  2. ハイフン区切りでモジュール名を決める
  3. npmを検索して名前が被らないか確認する

READMEを書く

  1. モジュール名のディレクトリをつくる
  2. エディタ*1でREADMEを書く。 内容は、
    1. Description: モジュールの価値を伝える一文です。 githubでプロジェクトを作るときと、npm initするときにも使います
    2. Usage: 自分の「こう使うと気持ちいい」イメージを伝える、サンプルコード。 最初のテストコードになるかもしれません
    3. API: 定義する関数とその引数など*2
    4. Setup: 対象環境(npm、browserify、bowerなど)を決める。各環境向けのインストールコマンドを書きます
    5. Development: ビルドやテストの手順です。npm run buildnpm testを必要に応じて羅列します
  3. commit
git init
git add README.md
git commit -m 'First commit.'

githubにpush

  1. githubでモジュール名のプロジェクトを作る。READMEやgitignoreは作りません
  2. git remote add
  3. git push origin master github上の見た目を確認します

package.jsonをつくる

  1. npm init 内容は、
    1. name: そのまま
    2. version: 0.0.1
    3. description: READMEで決めたもの
    4. entry point: そのまま
    5. test command: そのまま
    6. git repository: そのまま
    7. keyword: descriptionの単語から適当に選んで羅列
    8. author: ledsun*3
    9. license: MIT
  2. ライセンスを修正。細かすぎて伝わらない package.json 小ネタ三選 - t-wadaのブログを参考にして、mit-license.orgを使います
  3. fixpack commit前にやった方がdiffが汚れない
  4. git commit
git add package.json
git commit -m 'Add package.json.'

テストの枠組を用意する

  1. npm install --save-dev mocha
  2. .gitignoreをつくる。 node_modules echo node_modules/ > .gitignore
  3. npm run testmochaを書く。6to5使うなら mocha --compilers js:6to5/registerにします
  4. npm test してみる
  5. test.jsを書く require('./')(ES6ならimport)だけ書く
  6. index.jsを書く。空ファイルです
  7. git commit
git add index.js test.js .gitignore package.json
git commit -m 'Add package.json.'

開発する

普通にTDDします。

  1. ソースファイルが複数になったらsrcディレクトリを作ります
  2. ストファイルが複数になったらtestディレクトリを作ります
  3. ライブラリをES6で書いて公開する所から始めよう | Web Scratchを参考にして6to5を使うなら、 npm run buildを書いたり、index.js.gitignoreに追加したりします
  4. twada/power-assert · GitHubを使うなら、npm install --save-dev espower-loader power-assertして、
require('espower-loader')({
    cwd: process.cwd(),
    pattern: 'test.js'
});

enable-power-assert.jsを作って、npm testmocha --require enable-power-assert.jsに書き換えます

最初はpower-assertを使わないで書いています。 実装が難しくて、テストの失敗を繰り返す場合には、power-assertを追加します。

公開する

npmのアカウントを作ります。

  1. package.jsonfilesindex.jsを書く
  2. npm publish

*1:atomのmarkdown previewを使っています

*2:継続的にモジュールを拡張したことがありません。再生成のコストに実感がありません。修正する事は考えずに手で地道に書いています。

*3:メールアドレス入れてません。入れたほうがいいのでしょうか?

6to5で作ったnodeライブラリ

ライブラリをES6で書いて公開する所から始めよう | Web Scratch 読んで触発され、 6to5を使ってライブラリを書きました。

作ったライブラリ

チャットワークにメッセージをポストするだけの関数です*1

こんな感じで使います。

var apiToken = 'AAA',
    roomId = '1234'

postChatworkMessage(apiToken, roomId, 'hello world')

6to5の使い方

ライブラリをES6で書いて公開する所から始めよう | Web Scratch のままです。

build

6to5 src --out-dir lib --source-maps-inline

test

結果があることだけ確認して、中身は確認していないので、 power-assert無し。 mochaのみで書きました。

mocha --compilers js:6to5/register

package.jsonのfiles

libだけにしました。

個人的にnodeモジュールの使い方がわからないときに、テストコードを参考にします。 テストコードを公開パッケージに入れた方がいい気もします。

今回はテストコードがドキュメント以上のことを言わないので、 除外しました。

使ったES6構文

最初にES5で書いて traceur-compiler 入門 - from scratch を参考にしてES6に書き換えました。

  • const
  • let
  • arrow functions
  • modules
  • template strings

今回は、Array comprehensionsやGeneratorsのような、新しい使い方の文法は使いどころがありませんでした。

ドキュメントの話

同じく触発されてJSDocで書いてみました。 が

  • 一関数モジュールにはちょっと過剰?
  • jsdoc-to-markdown が生成するドキュメントは見た目があまり好みでない

JSDocが作るテーブルを真似して、手でMarkdownを書きました。 https://github.com/ledsun/post-chatwork-message#parameters

*1:AWS Lambdaでチャットワークに通知する処理に使いたくて書きました。複数メッセージ送信をPromise.allで待ち合わせたいので、Promiseを返します。

2014の成果

フロントエンドJavaScript

TextAE

LODQA

本業です。jQueryでDOM操作バリバリです。MVなんとかフレームワークは使っていません。忍者式テストの発表のネタになっています。

JavaScriptの日付に1日足したり2時間引いたり、計算するライブラリ

JavaScriptの日付に1日足したり2時間引いたり、計算するライブラリを作りました - @ledsun blog

JavaScriptのライブラリの作り方を学習しました。 CSS込みのフロントエンド向けライブラリはこの方法だと上手く行きません。

Rob Pike先生のサイン

いえーい!

グーグルカレンダーに予定を追加するURLを作るライブラリ

グーグルカレンダーに予定を追加するURLを作るライブラリを作りました - @ledsun blog

実用的な目的で作成しました。power-assertに初チャレンジしました。

とてか03 で忍者式テストの発表

とてか03にて発表してきました #toteka - @ledsun blog

レガシーコードと戦った話をメインに据えて、情熱成分を多めにしてみました。 概ね喜ばれたようで良かったです。

「俺のJavaScript、思っていたよりイケてるなー」とちょっと自信になりました。

Raspberry piをMQTT 気温 publisherにするAnsible Playbook

Raspberry piをMQTT 気温 publisherにするAnsible Playbookを公開しました - @ledsun blog

Raspberry PiとMQTTで遊ぶシリーズの成果物。結果的に温度を測るのは楽しくなくて、今は使っていません。

今はログを出す場所に悩むと、とりあえずMQTTで投げたりしています。

XP祭りで忍者式テストの発表

XP祭りに行きました #xpjug - @ledsun blog

とてかの発表の予告編。忍者式テストの説明が多めです。本編はもっと後に作りました。

Gitlabの更新情報をChatworkに通知するアプリケーション

Gitlabの更新情報をChatworkに通知するアプリケーション、Syamoを作りました - @ledsun blog

実用的で便利です。今見ると、実装があまりイケてません。

Blog オブジェクト指向設計とは

https://twitter.com/ledsun/status/538912200224567296

あまり鋭いマサカリは飛んで来ませんでした。 まあ時代遅れですよね。

ジョークアプリケーション 大拝承

大拝承

大拝承というWebアプリケーションを公開したら楽しかった話 - @ledsun blog

なぜかsocket.ioを使っています。 おかげでGuillermo Rauchに下手くそな英語で「socket.io超便利だった、ありがとう」とか言って握手できた。 イケメン充!

2014年 読んだ漫画の面白かった66

漫画

2014年もたくさん読みました。一言コメントなどを

ワールドトリガー

ワールドトリガー

漫画上手いですね

ACMA:GAME

ACMA:GAME

次のエピソードへの引きが上手くて続けて読んじゃう

テラフォーマーズ

テラフォーマーズ

初期の刃牙の「いろんな格闘技デパート」感あって面白い

絶望の犯島―100人のブリーフ男vs1人の改造ギャル

絶望の犯島―100人のブリーフ男vs1人の改造ギャル

1巻の設定の無茶苦茶さに笑った。衝撃的だった

ワイルド7

ワイルド7

面白いんですけど・・・幾ら何でも長いです

累

生きなさいキキ感ある。あそこまで悪い子全開じゃなくて迷いもある。続きが期待できていいです

狼の口 ヴォルフスムント

狼の口 ヴォルフスムント

6巻かけて、このカタルシス。さすがはビームです。普通の雑誌だとその前に連載終わる。もしかするとここがピーク

女の子が死ぬ話

女の子が死ぬ話

悪くない。でも全然印象に残らない。もったいない

双星の陰陽師

双星の陰陽師

健気な子たちは好きです。イマイチ方向性に迷っている感ある

天智と天武 ―新説・日本書紀

天智と天武 ―新説・日本書紀―

設定もおもろいし、敵役がねちねちしてて面白い。毎度毎度帯がウザい

マージナル・オペレーション

マージナル・オペレーション

現代戦術物。面白いですわ

高嶺の花

高嶺の花

おっさん恋愛漫画としてめっちゃ面白い

エリア51

エリア51

絵作りがかっこいい。ゼウスのおっさんがかっこいいのもいい

ホークウッド

ホークウッド

悪ぶっているいい人有能主人公で軍靴のバルツアー的。明るい中世ヨーロッパ戦争物

曹操孟徳正伝

曹操孟徳正伝

変態三国志漫画家による、曹操善人説漫画。蒼天航路以降だし、よく頑張ったと思う。

ホライズン

ホライズン

チンギスハンもの。子供時代から始めたのがまずかったんかな?ろくに話が始まる前に終了。蒼天航路感ある

キングダム

キングダム

戦争あってなんぼの書くのが辛い漫画に

野望の王国

野望の王国

序盤面白かったけど柿崎が強すぎて・・・もっと野望に向かって話が進むのだと思ってた。あとがきの自慢話がすごくうざい

redEyes

redEyes

アマードトルーパー戦争物。「そんな薄い素材で固過ぎ」とか思うけど、途中でフォロー入る。アクションシーンがいいよね。アーマー着てモノクロだと、キャラの見分けがつかないのが難点

ベイビーステップ

ベイビーステップ

天才スポーツ少年もの。作者がテニスオタクすぎて面白い。ここまでオタクじゃないとスポーツ漫画書けないのかという昨今の漫画界のハードルの高さ

オールラウンダー廻

オールラウンダー廻

天才スポーツ少年もの。作者が総合格闘オタクすぎて面白い。ここまでオタクじゃないとスポーツ漫画書けないのかという昨今の漫画界のハードルの高さ

のりりん

のりりん

おっさんスポーツもの。作者がロードバイクオタクすぎて面白い。ここまでオタクじゃないとスポーツ漫画書けないのかという昨今の漫画界のハードルの高さ

ちぃちゃんのおしながき

ちぃちゃんのおしながき

大井昌和 & 幼女 の鉄板さ加減

タケヲちゃん物怪録

タケヲちゃん物怪録

とよ田みのる の謎ハッピネス描写が安定

BIRDMEN

BIRDMEN

真面目の少年たちとちょっと悪い大人、いつもの 田辺イエロウ。どこに行く気なんだろう?

進撃の巨人

進撃の巨人

こんだけ進んでもネタが切れない設定がすごい

ブラッドラッド

ブラッドラッド

シリアスともギャグとの見分けにくい。不思議なバランス

地獄先生ぬ~べ~

地獄先生ぬ~べ~

今読んでも結構面白い。あの時代のジャンプすごかったんだな

EAT-MAN THE MAIN DISH

EAT-MAN THE MAIN DISH

吉富 昭仁から久しぶりのロリコン要素少なめ漫画だー!面白いかはまだわかんねー

強殖装甲ガイバー

強殖装甲ガイバー

もう殿堂入り、思う存分書いてください

イムリ

イムリ

話が進むようになって、面白くなってきました

高杉さん家のおべんとう

高杉さん家のおべんとう

ついに完結ですよ。お父さん気分で読んでました。

ヴィンランド・サガ

ヴィンランド・サガ

ヴィンランドが北米だってようやく気づきました。

孔雀王~戦国転生~

孔雀王~戦国転生~

最近の荻野 真、脱力パートがあって面白いんです

ナポレオン ~覇道進撃~

ナポレオン ~覇道進撃~

完走まで、がんばれーって感じです

深夜食堂

深夜食堂

地味にほっこり系

アド・アストラ ―スキピオハンニバル

アド・アストラ ―スキピオとハンニバル―

ローマ物。スキピオがんばれー

十 ~忍法魔界転生~

十 ~忍法魔界転生~

がんばれー

ゲート ―自衛隊彼の地にて、斯く戦えり

ゲート ―自衛隊彼の地にて、斯く戦えり

圧倒的な戦力差なのに相手に気を使ったりの心理描写が好き

機動戦士クロスボーン・ガンダム ゴースト

機動戦士クロスボーン・ガンダム ゴースト

平常運転

荒野に獣 慟哭す

荒野に獣 慟哭す

やっと完結すんの。クリーチャーの造形とアクションが素晴らしい

孔雀王ライジング

孔雀王ライジング

また孔雀王かよって思ったけど、結構あり。子供に見せられるの目指しているのは、なるほどって感じ

ビン 〜孫子異伝〜

ビン 〜孫子異伝〜

どうなるんじゃろね。がんばって完走してほしい

超人ロック 刻の子供達

超人ロック 刻の子供達

ずっと続けてんのに、よく新しい設定思いつくな

重機甲乙女 豆だけど

重機甲乙女 豆だけど

設定もいいしキャラもいい。いいぞ、もっとやれ

ヨルムンガンド

ヨルムンガンド

おもろかったよ。結末はこうするしかないですよね。贅沢を言えば、ここから体制が崩れていく話が読みたいです

墨攻(ぼっこう)

墨攻(ぼっこう)

戦術の泥臭ささ好き。中国歴史ものはハッピーエンドにはなりにくい

クライシス

クライシス

特命係長みたいなの

僕らはみんな生きている

僕らはみんな生きている

山本直樹 はエロい

ビリオンドッグズ

ビリオンドッグズ

現代版野望の王国みたいなの。続きが気になる

バベルハイムの商人

バベルハイムの商人

ブラックジャックとかアウターゾーンとかみたいなの

バーサスアース

バーサスアース

打ち切りなんだって・・・

レッツ☆ラグーン

レッツ☆ラグーン

岡崎武士復活。それ以上いらない

銃夢 Last Order

銃夢 Last Order

ついに完結っていうべきか?

White Tiger 3 〜白虎隊西部開拓譚〜

White Tiger 3 〜白虎隊西部開拓譚〜

暑苦しすぎんのかな?夏目 義徳さんてイマイチ受けないね

乱と灰色の世界

乱と灰色の世界

乱が好き勝手遊んでたあたりが俺的ピーク

ヘビ女はじめました

ヘビ女はじめました

ど安定

開花のススメ

開花のススメ

対象読者的に無理がある設定だし頑張ったんだと思います。

ハカイジュウ

ハカイジュウ

ひたすらパニックを描き続ける姿勢が素晴らしい

江戸の検屍官

江戸の検屍官

よくこんなマニアックな設定をみつけた。人相書きがキーなのと、顔を書き分けられる画風がマッチしていて素晴らしい

裸者と裸者~邪悪な許しがたい異端の~

裸者と裸者~邪悪な許しがたい異端の~

やっと終わったぜ。原作未完だけに続かないのが辛い。

エイス

エイス

綺麗だけど触ると壊れそうな話

サランドラの壺 光原 伸短編集

サランドラの壺 光原 伸短編集

見どころは「あの時代に長期連載してた俺すげーだろ」って作者が書いているところ

軍靴のバルツァー

軍靴のバルツァー

安定

宇宙戦艦ヤマト2199

宇宙戦艦ヤマト2199

もうちょっと女の子の表情が色々パターンがあるといいな

砂ぼうず

砂ぼうず

復活!・・・したのかなぁ

おまけ

この記事を書くために作ったスクリプトafi-blog

JavaScriptの日付に1日足したり2時間引いたり、計算するライブラリを作りました

IE9以降のブラウザとNede.jsで動きます。 AMDでも動くはずです。 試していません。動かなかったら教えてください。

どんなライブラリか?

こんな感じ

dateAdder(new Date(2014,10,27), {days: 1})
//Thu Nov 28 2014 00:00:00 GMT+0900 (JST)

dateAdder(new Date(2014,10,27), {hours: 1})
//Thu Nov 27 2014 01:00:00 GMT+0900 (JST)

dateAdder(new Date(2014,10,27), {days: 1, hours: 1})
//Thu Nov 28 2014 01:00:00 GMT+0900 (JST)

JavaScriptのDateオブジェクトに足し算したり引き算したりする関数です。

なぜ作ったか?

ledsun/generate-google-calendar-url · GitHubを使ってGoogleカレンダー用のURLを作る時に使おうと思いました。 予定に開始時刻だけあって終了時刻が無かったら、終了時刻を開始時刻の1時間後に設定します。

どうすればJavaScriptで一時間後の時刻が得られるでしょうか?

標準的なJavaScript

一般にJavaScriptで時間を足す処理を書くとこうです。

var newEnd = new Date(date.getTime())
newEnd.setHours(date.getHours() + value)

二行必要なのが、ちょっと嫌いです。

StackOverflowで検索しても似た感じです。

var today = new Date();
var tomorrow = new Date(today);
tomorrow.setDate(today.getDate()+1);

npmパッケージ

111247パッケージを誇るnpmを検索してみます。

parseメソッドやformatメソッドはちょっと余計です。 addメソッドの実装 は参考になりそうです。

1つのメソッドでget/setを両方やるjQueryぽいインターフェースは頂けません。 他のインターフェースと混ぜると辛いです。 実装やテストもコストが高いです。

Math Functionsに加算があります。新しいオブジェクトを返す、非破壊的なメソッドなのも良いです。 ただ、

  • 加算と減産を分ける価値が分かりません
  • 比較メソッドの価値も分かりません。getTimeすれば良くないです?
  • min/maxはreduceで十分な気もします
  • サポートしている単位が多いのも気になります。decadeって使います?10年足せば良くないですか?

名前がかっこいいです。 でも欲しいのはDateオブジェクトの代替えではありません。

そんな訳で、手頃なものが無いので作りました。

作っていた時の四方山話

Dateの標準API

主にゲッターセッター。 妙に統一感がありません。

特に年月日

  • getFullYear
  • getDate
  • getMonth

時以下は単位複数形で統一されて居るのに

英語的には正しいのかもしれませんね・・・。

日付のテストコードの話

https://twitter.com/ledsun/status/538131617382817792

変更した日付の値が期待通りかassertで比べたいです。 ところがassert.equalもstrictEqualも時刻の比較はしてくれない。 オブジェクトが同一かどうかを比較します。

結論からいうと頭に+を付けて数値に変換して比較しました。

オレオレassertはダメ

こんなの

var assertDate = function(expct, actual, message){
    assert.equal(expect.getTime(), actual.getTime(), message)
}

原則的にオレオレassertは悪手です。

  • オレオレassertの動作を理解しなくてはいけません
  • 関連のあるテストコード以外のコードも読まなくてはいけません

テストコードは定石がすくないので、 他人が書いたテストコードはメンテナンスしづらいです。 テストコードを書くコストが減っても、読むコストが増えると状況は悪化します。

getTime

最少単位で比較すれば良いのでミリ秒に変換して比較します。

assert.equal(expect.getTime(), actual.getTime())

毎回getTimeを書くのは面倒です。

Date系ライブラリのテストコードを見てみましょう。

valueOf派

https://github.com/JerrySievert/date-utils/blob/master/test/date-new-test.js#L11

assert.equal(expect.valueOf(), actual.valueOf())

プリミティブ値の比較は仕様上好ましそうです。 getTimeとメソッド名の長さも得られる値も同じです。

数値にキャスト派

https://github.com/jquense/date-math/blob/master/test.js#L27 https://github.com/timruffles/immutable-date/blob/master/test.js#L11

assert.equal(+expect, +actual)

JavaScriptの標準から外れずに、最も短く書けるのでこの記法にしました。

開発環境を自慢

saucelabsでクロスブラウザテスト

ソースコードはES5対応です。 実際に各ブラウザで動くかはsaucelabsで確認しました。 mochaで書いたテストコードをzuulでブラウザで動かしました。

最初はもっとたくさんのブラウザでテストしました。 時間掛かかりました。 各ブラウザの動作可能な最も古いバージョンだけテストすることにしました。 1セット約2分掛かかります。

こんなバッジがもらえます。 Sauce Test Status

最初はtestling使う予定でした。 ローカルでテストして、travis.ci設定して、githubにpushしても反応がありません。 調べてみたら ci.testling.com Service Timeout · Issue #88 · substack/testling · GitHub でした。

UMD.js

generate-google-calendar-url もブラウザとNode.jsで動きます。 EventEmitter2を真似て手で書きました。

UMD.jsという標準を知り、 従うことにしました。 ソフトウェア開発のコツは「解決したい問題以外は他人に押し付ける」です。

手で書いたら、ソースコードが読みにくくなったのでgulp-umdを使いました。

元が1ファイルだったので楽でした。 複数ファイルに分けるとどうなるんでしょうね?

Jxck_さんの教え

npm で依存もタスクも一元化する - Qiita

"script" を "npm run" で実行する場合は、パスが自動で通る

必要なコマンドはすべてnpmから実行出来るようにしました。

  • npm run build
  • npm test
  • npm run browser
  • npm run saucelabs

npm run saucelabstravis.ci用なので人間はあまり実行しないはずです。

t-wadaさんの教え

細かすぎて伝わらない package.json 小ネタ三選 - t-wadaのブログ

  • package.json の files フィールド
  • package.json のフィールド並び順に悩むくらいなら fixpack
  • ライセンス、 MIT で良いなら mit-license.org

一通りやりました。

もちろんpower-assert使いました。 途中でテストコマンド間違えてエラー詳細で無くなったらパニックに陥りました。 知らず知らずのうちに頼り切りです。

まとめ

npmモジュールの開発は簡単ですね<3

ソースコードは40行しかないのに、こんなに書くことがある!