2017/12/31-2018/1/1,2,3,4,5 久々に名古屋に帰っていた
年末風邪気味だったのが徐々に落ち着いてきた頃に、名古屋に帰った。 RubyKaigiが開催された大須がとても近かったので、観光と初詣がてら行ってみたら、予想をはるかに超えた人の波でかなり混雑していた。 イメージ的には仙台の商店街をイメージしていたがそれよりもはるかに大須は巨大だった。大通りが複数あって、さらに脇道にも小さな商店や屋台がポツポツと軒を連ねており、近年ではグルメブームもあって食べ歩きの町として売り出しているらしい。
写真はパオパオ亭の焼き包子(パオズ) 確かマツコの知らない世界で放送されていて、是非一度食べてみたかったやつ。噂通りの肉汁が出てきてとても美味しかった。ここは毎年のリピート決定。お土産で買って帰っても、フライパンで温め直してアツアツで食べることができて、みんなに美味しいととても喜ばれた。 1個160円なのでもっと多めに買って行ってもよかったかもしれない。
からあげ彩音で食べた唐揚げもボリューミーで味が濃くて美味しかった。これでたったの500円。これをおかずにご飯を食べたかった。 真っ赤な唐辛子がかかっているけどそんなには辛くない。
他には喫茶店やドックカフェに行ったり、コンパルのエビカツサンドを食べた。エビカツサンドは手羽先などに隠れてあまり目立たない名古屋飯かもしれないが、名古屋駅のすぐ近くのメイチカで買えてかつ、しっかり美味しいのでかなりおすすめ。 [コンパル メイチカ店](https://tabelog.com/en/aichi/A2301/A230101/23006112/)
あとは、中古の宝石を扱うコメ兵というローカルチェーン店に行ってみた。興味本位で見ていると、宝石でも結構安いのが多くて、妻に後でそのことを話したら安いならば買ってきてくれればよかったのにと言われて、「余計なことを言ってしまった」という感じだった。
2018/1/7 オブスキュラに久しぶりに行った
近くにある馴染みの神社である池尻稲荷に初詣に行ってきて、おみくじを引いたら大吉だった。おそらく人生初の大吉ではないかと思う。出産が安産だったのが何より。相場に山気を出すなと書いてあって、これは今年は仮想通貨には手を出さずにおとなしく投信でも買っておきなさいという神の啓示なのかもしれない。
学問に関心手は安心して励めという内容で、昨年からコツコツとよく使うツール周りの内部動作がどうなっているか知りたくて、時間のあるときにコードを追っている。普段何気なく使っているツール類でも内部挙動がどうなっているかを知っておくと安心感がある。こういう部分が、何か問題があった時の対応力につながってくると思う。
その後、去年のお札を奉納した後に、あのフレッシュでとろけるようなレアチーズケーキが久しぶりに食べたくなって、三茶のカフェのマメヒコに行ったらあいにくの臨時休業だったので、久しぶりにオブスキュラまで足を伸ばした。酸味のあるあっさりしたコーヒーと、濃厚なチーズケーキをいただいた。
あるオブジェクトに対して1回で複数のメソッドを呼ぶ
書いて見た。jbuilderっぽい見た目になった。
class Object def call(*methods) methods.map do |method| self.send(method) end end end p [1,2,3].(:first, :last, :class) # => [1, 3, Array]
Reactのメモ
準備
sudo npm install -g react-tools # jsファイルをwatch して自動ビルドをさせる jsx --watch src/ build/
html
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <script src="https://fb.me/react-15.1.0.js"></script> <script src="https://fb.me/react-dom-15.1.0.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script> </head> <body> 関数定義 <div id="hello"></div> <br> クラスとして関数を定義 <div id="hello2"></div> <br> component の中から別のコンポーネントを呼ぶ <div id="hello3"></div> <br> 配列の内容を出力 <div id="print_array"></div> <br> 全部まとめて呼び出し <div id="all_sample"></div> <script src="build/hello.js"></script> </body> </html>
javascript
- ファイル名を
hello.js
として/src
ディレクトリに保存すると、build されて/build/hello.js
が生成される。
// 関数として定義 const Hello = (props) => { // props.name で引数取得 return ( <div className="Hello"> Hello {props.name} </div> ); }; // 呼び出し ReactDOM.render( <Hello name="Mr. Sato" />, // name で引数を指定 document.getElementById('hello') ); // クラスとして関数を定義 class Hello2 extends React.Component { constructor(props) { super(props); } render() { return ( <div> Hello2 </div> ); } } // 呼び出し ReactDOM.render( <Hello2 />, document.getElementById('hello2') ); // component の中から別のコンポーネントを呼ぶ const Foo = (props) => { return ( <div> <Hello name="Mr. Suzuki"/> <Hello name="Mr. Kaede"/> <Hello name="Mr. Minato"/> </div> ); } // 呼び出し ReactDOM.render( <Foo />, document.getElementById('hello3') ); // jsの配列の内容を出力 ar = [1,2,3,4] /* comment */ const PrintArray = (props) => { // JSXの中で{}で変数展開できる return ( <ul> {props.items.map((item, index) => ( <li key={index}>{item}</li> ))} </ul> ); } // 呼び出し ReactDOM.render( <PrintArray items={ar}/>, document.getElementById('print_array') ); // 全部まとめて呼び出し. renderは1つの要素のみ扱えるので <div> で全体を囲む必要がある ReactDOM.render( <div> <Hello name="Mr. Sato" /> <Hello2 /> <Foo /> <PrintArray items={ar} /> </div> , document.getElementById('all_sample') );
トラブルシューティング
- JSXについて何かしらの変換に失敗している場合、エラーログで教えてくれる便利
- よくあるのは
<Foo />
を<Foo \>
と書いてしまうミス
built Module("hello") ["bar","foo","hello","style"] hello.js changed; rebuilding... Error while reading module hello: Error: Parse Error: Line 21: Invalid regular expression: missing / at throwError (/usr/local/lib/node_modules/react-tools/node_modules/jstransform/node_modules/esprima-fb/esprima.js:2813:21) at scanRegExpBody (/usr/local/lib/node_modules/react-tools/node_modules/jstransform/node_modules/esprima-fb/esprima.js:1490:17) at scanRegExp (/usr/local/lib/node_modules/react-tools/node_modules/jstransform/node_modules/esprima-fb/esprima.js:1569:16) at parsePrimaryExpression (/usr/local/lib/node_modules/react-tools/node_modules/jstransform/node_modules/esprima-fb/esprima.js:3562:43)
実行結果
outer join を使ってみる
テストデータ
# towns table id name 1 アテネ 2 ヴェネチア 3 ローマ 5 ピサ # users table id name town_id 1 taro 1 2 jiro 2 3 saburo 3 4 shiro 4
inner join
- town_id 4 のレコードは towns tableに存在しないので表示されない
select * from users AS u join towns AS t on u.town_id = t.id ; id name town_id id name 1 taro 1 1 アテネ 2 jiro 2 2 ヴェネチア 3 saburo 3 3 ローマ
left outer join
- こちらの
outer join
では town_id 4 のレコードは towns tableに存在しないので NULL になってる
select * from users AS u left outer join towns AS t on u.town_id = t.id ; id name town_id id name 1 taro 1 1 アテネ 2 jiro 2 2 ヴェネチア 3 saburo 3 3 ローマ 4 shiro 4 NULL NULL
right outer join
select * from users AS u right outer join towns AS t on u.town_id = t.id ; id name town_id id name 1 taro 1 1 アテネ 2 jiro 2 2 ヴェネチア 3 saburo 3 3 ローマ NULL NULL NULL 5 ピサ
まとめ
- inner join : 片方だけに存在するレコードは表示しない
- outer join : 片方だけに存在するレコードはNULLで表示する. こちらはleft, rightの向きがある.
TOC と CCPMに関する本を読んだ
夏休みの読書感想文。
最近 TOC と CCPMに関する本を会社からいただいて読んだ。
また、会社での研修にも参加することができそこでも座学とワークショップで CCPM, TOC について学んだ。
これにより、スケジュール通りに品質を落とさずに、仕事を進めるための方法論をいくつか学んだ。
人間の心理的な性質
(1). パーキンソンの第1法則: 仕事の量は、完成のために与えられた時間をすべて満たすまで膨張する
- ➡️ 結果として、スケジュールを長めに取ってもやることをふやしてしまい、プロジェクトの終盤になって工数がたりなくなってしまう
(2). 学生症候群 : 人は締め切り直前にならないと本気で仕事をしないという人間の行動特性
- ➡️ 結果として、スケジュールを長めに取っても、初めから本気になって仕事をしないから効率性がよくない
(3). 心理的安全性 : チームの中で 気兼ねなく安心して 発言や行動できるか?を示す言葉 どんな発言をしても決して非難されることはないという安心感
- ➡️ チーム内でこれが低いと, 例えば, スケジュール通りに終わらないと、怒られるという恐怖から、サバ読み工数の申請や、深夜残業や体調を崩しても終わらせようとしてしまう.
- 例. 見積もりをしてタスクを終わらせた場合…心理的な安全性が低いと…
- 見積もりよりも、早く終わった場合 : 「見積もりの精度が低い」と怒られる. 本来なら早く終わったら、良いことなので、ほめられるべき.
- 見積もりよりも、遅く終わった場合 : 「見積もりより超えている」と怒られる. そもそも、プロジェクトは「不確定」なもの. やってみないとわからない部分はある.
- 結果として、工数の鯖読みや、見積もりのばかしあいが発生し、そもそも見積もりの正確性が低下し、スケジュールの正確性も低下する
これらにより、
- ➡️ スケジュールに余裕があると、人はタスクをスケジュール通りに終わらせることができるというのは 「幻想」 ということになる。
プロジェクトの性質
- 「がんばる」だけでは、プロジェクトはうまくいかない
- プロジェクトとはそもそも、「不確定」なもの
- プロジェクトには新規性がある. (やってみないとわからない)
- プロジェクトには有期性がある. (期間が決まっている)
- +上記の人間の心理的な性質
プロジェクトマネジメントの3つの性質
- QCD(quality,cost,delivery) という制約の矛盾
- 的確な優先順位をつけられない : おおきなPJになるほど詳細を把握することが困難になる為
- かけた工数では、プロジェクトの進捗を計れない
じゃあどうするか?
以上が、「プロジェクト」、「プロジェクトマネジメント」とそれにかかわる「人間」の性質になる。
これを踏まえた上で、どう工夫してプロジェクトを進めるとよいのか?
を述べたものが、CCPMの方法論として、以下のものになる。
とくに、ここのタスクからバッファを排除し、プロジェクト単位でまとめてバッファを管理することで、個々のタスクの工数を限界ギリギリまで短くする。
これにより学生証症候群とパーキンソンの第1法則に陥ることを防いでいる。
CCPM5つの特徴
- マルチタスクを排除
- クリティカルチェーン(そこのタスクの流れが遅れたら全体が遅れてしまう部分のこと) によるマネジメント
- 個々のタスクからバッファを取り出す
- バッファの消費状況でプロジェクトを管理する
- フルキット(タスクに取りかかれる万全の状態)にして、タスクに取りかかる
CCPMの3つの心がけ
- 毎日の朝会で問題を解決する
- 後何日で終わりそうか?
- こまっていることは?
- 何か支援できることは?
- 個々のタスクの遅れを責めない
- 最も重要な課題 に対応する
感想
なんとなく自分が今までの仕事の経験でやってきた中でのうまくいったパターンが言語化されていて驚いた。自分のやり方は間違っていなかったという印象を得て救われた気分。
とはいえ、これを今すぐにチーム全体に適用しましょうというのはむずかしいので、できるところから徐々にやっていこうと思っている。
具体的には、自分のスケジュール部分だけはバッファの切り出して、まとめて管理をやってみるなどかなぁと。
講師の方とも話したのだが、やはりチームに展開するときに理論やってドラスティックに実践!というかんじではなく、ちょこちょこ細かいプラクティスをやっていって、うまくいったねー!よかったねー!でプロジェクトを終える感じらしい。
それで、より深掘りしたい方がいたら初めて理論や書籍を紹介する的なながれがうまくいっているという話を伺った。なるほどなぁ。そうだよなぁ。という感。
読んだ本
進む! 助け合える! WA(和)のプロジェクトマネジメント―――プロマネとメンバーのためのCCPM理論
- 作者: 宮田一雄
- 出版社/メーカー: ダイヤモンド社
- 発売日: 2017/04/06
- メディア: 単行本
- この商品を含むブログを見る
ARのjoinまわりのメソッドを勉強した
ARのjoinまわりのメソッドを勉強した。N+1を解消するのにとても便利。
joins
- アソシエーションをキャッシュしない
- アソシエーションを検索条件でだけつかいたいときに有効
- 内部的には普通にjoinしてる
preload
- アソシエーションをキャッシュする
- 必要なテーブルをまとめて別のselect文で読み込みするのでクエリは2回に発行される
- あまりjoinしたくないでかいテーブルに有効
- joinしてないので、絞り込み条件に関連テーブルを使えない
- index系のAPIでの N+1 の解消に有効
eager_load
- アソシエーションをキャッシュする
- joinする
- joinしているので、絞り込み条件に関連テーブルを使える
includes
- preload と eager_load を適切に使い分けてくれる
- join先で絞り込んでいたら eager_load
- してなかったら preload
merge
- joinsをチェインすることができる
- ちょっと初見だとどんなクエリになるか判断つかないかもしれない
Comment.joins(:entry).where(Entry.merge(:draft)) # scopeを使うとき Comment.joins(:entry).merge(Entry.where(published_at: nil)) # scopeを使わないとき
これらのメソッドを使ってもどうしてもN+1が解決できない場合
最後に、これらのメソッドを使ってもどうしてもN+1が解決できない場合は、
一旦Rubyの配列に確保してしまってからループの中でRubyの方のselect メソッドを使うことで解決した。
# N+1 の発生を防ぐため, あらかじめまとめて読み込んでおく user_favs = @user.favs.where( target_id: Articles.published.pluck(:id) ).to_a users = list.map do |elem| user_fav = user_favs.select{ |f| f.id == elem.fav_id } # Array#select を使う # user_favを使って諸々の処理をする end