Node.js + JQuery + herokuによる時間計測サービス

と言っても、「仕事」などカテゴリーを選択してタイマースタートして、自分がしている作業時間を測る簡単なものを検討しています。
このアイデア自体は友人が以前からほしいと思っていたもので、なら勉強がてら作ってみようと思ってリーンキャンバスをさくっと作ってみました。

f:id:uramonk:20150823174942p:plain

勉強中のランニングリーンの本を参考に見よう見まねで短時間で作ってみたので、コスト構造とかよくわからない部分もありますが、、、まずは実践してみることが大事かなと思いました。

ちなみに実装の部分ですが、今までNode.js + JQueryを勉強してきましたので、それらを使ってWebサービスを作ってみようとまずは簡単な画面だけ作成し、せっかくなので以前から気になっていたherokuにアップしてみました。

github.com

IdealTime

下記サイトによると、herokuは無料版だと一日18時間までしか使えないようで、スケジューラー等で起動している時間と寝ている時間を管理していたりするようですが、私はまだheroku自体今回始めたばかりなので何もしていません。アクセスしても見れない時があると思います。

iyuichi.hatenablog.jp

ちなみにherokuの使い方は下記公式サイトのIntroductionを参考にすれば簡単に使えました。

devcenter.heroku.com

今後ですが、まずは画面だけ作ったので、これから画面をブラッシュアップしつつ、タイマー処理やデータベース処理、計測時間を表示する画面や処理を作っていこうかと思います。

はじめてのNode.js覚え書き④ あとで調べること

はじめてのNode.js覚え書き① - uramonk's blog
はじめてのNode.js覚え書き② ECONREFUSEDが発生する - uramonk's blog
はじめてのNode.js覚え書き③ - uramonk's blog

jquery関連が分からない点が多いので、あとで調べるリスト。

  • div(data-role='header') と .header(data-role='header') の違い。

ドットはクラス。.headerはdiv.headerの略。ただクラス名を指定しているかしていないかの違い。

  • data-ajax='false' とは。
  • label(for='topic-post-name') と input(type='text', id='topic-post-name', name='name') でforとidを合わせる理由。

ラジオボタンで名称を表示する場合はlabelで指定するので、forを使うことでどのinputにラベルを表示するかを指定できる。

  • h1#topic-title トピック:#{topic.title} h1の後の#とは。

#はid.

  • .ul-bar(data-role='footer') の.ui-barとは。
  • ul#topics-listview(data-role='listview') のulとは。

はじめてのNode.js覚え書き③

はじめてのNode.js覚え書き① - uramonk's blog
はじめてのNode.js覚え書き② ECONREFUSEDが発生する - uramonk's blog

本の第12章を参考にスマートフォン用BBSを作成していましたが、 MongoDBやJQueryのバージョンが異なるためうまく動作しない箇所がありました。

MongoDB

getLatestを実行してデータベースからtopicを取得しようとすると、下記のようなエラーが発生しました。

MongoError: Can't canonicalize query: BadValue bad order array [2]

内容からして、下記ソートを行う箇所でエラーが発生している感じでした。

cursor.sort([['date', -1]]).limit(end -start).skip(start);

エラー内容で検索したところ、下記サイトを見つけました。stackoverflow.com

こちらを参考に下記のようにコードを変更したところ、うまく動作するようになりました。

cursor.sort({'date':-1}).limit(end -start).skip(start);

JQuery

mobbs.jsファイル内で、pagebeforeshowイベントハンドラーを定義していたのですが、Webページにアクセスしてもこちらのコードに到達されませんでした。
調べたところ、バージョンアップによってlive()が使えなくなり、代わりにon()を使うようにする、さらに引数の記述方法も変わっていました。h2ham.net

サイトを参考に、こちらのコードを、

$('#topics').live('pagebeforeshow', function (e, data) {

下記のように変えたところ、イベントをキャッチすることができるようになりました。

$(document).on('pagebeforeshow', '#topics', function (e, data) {

はじめてのNode.js覚え書き② ECONREFUSEDが発生する

はじめてのNode.js覚え書き① - uramonk's blog

はじめてのNode.jsの第9章「Expressフレームワークを使う」のコードをExpress4で試したところ、localhost:3000へアクセスするとレスポンスが遅く、ECONREFUSEDが発生してしまいました。

いろいろ調べたところ、原因はセッション管理のようです。
同じような症状が発生しており、それについて記述しているサイトがありました。george-tsubota.hatenablog.com

ということでExpress4でセッション管理について調べたところ、下記サイトがあり、こちらを参考にapp.jsを修正したらアクセスできるようになりました。qiita.com

package.jsonには下記を追加してnpm installを実行しました。

"express-session": "^1.11.3",
"connect-mysql": "*"

ちなみに、修正したapp.jsのコードを抜粋します。

var session = require("express-session");
var MySQLSessionStore = require('connect-mysql')(session);
~~~
app.use(session({
    store: new MySQLSessionStore({
      secret: "hoge",
      config: {
        host: "localhost",
        database: "MySQLのデータベース名",
        user: "MySQLのユーザー名",
        password: "MySQLのユーザーのパスワード"
      }
    }),
    secret: "hoge"
}));

セッション管理についてはもっと勉強しないとならなそうです。

Running Lean 覚え書き③

Running Lean 覚え書き① - uramonk's blog
Running Lean 覚え書き② - uramonk's blog

Running Lean 覚え書き③は「プランで最もリスクの高い部分を見つける」です。
第3部は4章と5章で成り立っており、第1章で示されていた手順2に該当します。

第4章 ビジネスモデルの優先順位

リスクとは
  • 製品リスク
    • 課題、ソリューション、独自の価値提案、主要指標
  • 顧客リスク
  • 市場リスク
    • 既存の代替品、収益の流れ、コスト構造、圧倒的な優位性
ビジネスモデルの比較

目的:十分に大きな市場を持ち、製品の周りにビジネスを構築でき、製品を必要とする顧客に近づけるビジネスモデルを見つけ出す。

  • 評価基準(優先順位の高い順)
    • 顧客の不満レベル(課題)
      • 顧客セグメントに優先順位をつけ、課題を3つ挙げる
    • 近づきやすさ(チャネル)
    • 価格と粗利益(収益の流れとコスト構造)
    • 市場規模(顧客セグメント)
    • 技術的実現可能性(ソリューション)
外部の意見を求める
  • ビジネスモデルは最低でも自分以外の誰か一人と共有する
  • スライドを10枚にするのは止める
    • インタビューに必要なのはピッチよりも学習★具体的にどういう資料を作ればいいか?
  • 20%を準備に、80%を対話に使う
  • 具体的な質問をする
  • 「アドバイザーパラドックス」に気をつける
    • アドバイザーの言葉を決定や検証と思わない。リスクの特定や優先順位をつけるための手段

第5章 実験の準備

課題チームと解決チームを作る
  • 部門のことは忘れる
    • リーン・スタートアップでは部門は邪魔。2つのチームを作る。
    • 最初は1つのチームで両方の役割を担ってもいい。
    • 課題チーム
    • 解決チーム
      • 建物の中での活動。開発、テスト、リリースのデプロイなど
  • 絶対に必要な3つの要素
  • 課題/解決チームの外部委託は慎重に
    • すばやいイテレーションと学習の両方が犠牲になってしまう
    • 顧客について学習することは絶対に委託してはいけない
効果的な実験
  • 速度・学習・集中を最大化する
    • 速度は「構築−計測−学習」のループで計測できる
    • 顧客についての学習も必要
    • 注目されないが集中も必要
  • 主要指標と目標を特定する
    • 達成すべき学習や指標に集中する
  • 学習に必要な最も小さいことをやる
    • 製品以外の何かを構築して仮説をテストできる
  • 反証可能な仮説
    • 書きだした仮説を反証可能な仮説に変える
      • 間違いがはっきるとわかる文
  • 定性的検証と定量的検証
    • 最初の目標は強いシグナルを受け取ること
    • 5人の顧客インタビューで十分
    • 否定的な強いシグナルは仮説を改善するか破棄する
    • 肯定的な強いシグナルは、仮説を定量的に検証してもよいということ
イテレーションのメタパターンをリスクに適用する

中途半端な学習や否定的な学習でやる気を失い、早々にピボットや実験中止をしてしまうことに注意。
肯定的な学習から必要以上に楽観的になると後で行き詰まる。
目標をしっかり設定し、実験が「段階的なイテレーション」となるように学習を積み重ねていく。

  • ステージ1:課題を理解する
    • 課題、顧客セグメント、既存の代替品
  • ステージ2:ソリューションを決定する
  • ステージ3:定性的に検証する
    • 独自の価値提案、チャネル(アーリーアダプターをどう探すか)、収益の流れ(お金を払ってもらえるか)
  • ステージ4:定量的に検証する
    • 主要指標、チャネル(どう広範囲の顧客に連絡するか)、コスト構造

ここまでだと実験の準備だけなので、まだどう実験したらいいかがわからないですが、次の章から実験方法となります。

はじめてのNode.js覚え書き①

dotinstallでnode.jsの勉強はひと通りしたのですが、こちらの本が結構いいみたいなので、購入して勉強をしています。

node.jsの最大の特徴は「ノンブロッキングI/O」と「イベント駆動」という点。
node.jsはシングルスレッドなので、重たい処理をするときに同期処理(returnで値が返ってくるまで待つ)をしてしまうと、他の全ての処理が待ち状態になってしまうので、重たい処理をするときはイベントハンドラー(コールバック)を登録して、処理を実行するメソッド自体はすぐに返ってくるようにし、処理が完了したらイベントハンドラーでその後の処理を行う、とのことです。

今までC#はよく使っていたので、C#でもイベントが用意されているため、イメージはつきました。

例えば、Servierに対してPOSTされた場合に通知して欲しい場合は、下記のようなコードを記述します。

request.on("data", onReceived);

function onReceived(chunk) {
    ...
}

C#だと下記のようになるかと思います。

request.data += onReceived;
~~~
void onReceived(object sender, EventArgs e) {
    ...
}

ちなみに、本で一箇所うまくいかない場所がありました。
P97で下記のようなコードがあります。

if(request.method == 'POST') {
	request.data = '';
	request.on('data', function (chunk) {
		request.data += chunk;
	});
	request.on('end', sendResponse);
}
~~~~~~~~
function sendResponse() {
	var query = querystring.parse(request.data);	
	...
}

sendResponse内でrequestオブジェクトとresponseオブジェクトを使うのですが、引数として定義されていないため、
下記のように変更しました。

if(request.method == 'POST') {
	request.data = '';
	request.on('data', function (chunk) {
		request.data += chunk;
	});
	// 引数にrequestとresponseを追加。
	request.on('end', sendResponse(request, response));
}
~~~~~~~~
// 引数にrequestとresponseを追加。
function sendResponse(request, response) {
	var query = querystring.parse(request.data);	
	...
}

ただ、上記を実行すると、sendResponse内でrequest.dataの中に何も値が入っていない状態となり、エラーとなってしまいました。
そこで、下記のようにさらに変更したらうまくいきました。

if(request.method == 'POST') {
	request.data = '';
	request.on('data', function (chunk) {
		request.data += chunk;
	});
	request.on('end', function() {
		// 一度匿名関数にしてそのなかで実行する。
		sendResponse(request, response);
	});
}
~~~~~~~~
function sendResponse(request, response) {
	var query = querystring.parse(request.data);	
	...
}

記述の仕方がことなるだけで、内容は変わらないと思うのですが、何が違うか不明です。。。

初めてのスタックオーバーフロー回答

前々からスタックオーバーフロー自体は技術調査などでよく利用していましたが、登録して質問したり、逆に回答したりといったことはしてこなかったので、技術者としてアウトプットし、さらに他の人のためになればと思い、登録してみました。

ja.stackoverflow.com

ひとまず質問についてはCefSharpに関する質問を出しています。
回答もしてみたいと思い、C#に関する質問があったので回答したら、頼りになった回答としてマークされました。

自分の作品をアウトプットするだけでなく、技術者としてこういうことでも貢献していきたいですね。
まだまだ技術力は低いですが。。。