dotcloudにRailsをデプロイ
dotcloudが楽しそうなので使ってみました。
dotcloudでアプリケーション作成
dotcloudにでサインアップしてください。
サインアップしたらダッシュボードでcreate a new applicationしてください。
アプリケーション名は先程作ったものと合わせてmyappとします。
セットアップ
cd $HOME/myapp dotcloud setup
以下の様なmyapp/dotcloud.ymlを$HOME/myappに作成します。
www: type: ruby approot: app postinstall: ./postinstall.rb db: type: mysql
postinstallはインストール後に実行されるスクリプトです。配置はapp下。
なくても良いです。
ビルド
dotcloud connect myapp dotcloud push
簡単!
無料枠で色々できそうなのでお遊びにはもってこいですね。
SQLアンチパターン「ランダムセレクション」の補足(でもないけど)
解決策③「すべてのキー値のリストを受けとり、ランダムに 1 つを選択する」では、当然の話だけどトランザクションの考慮も必要ですよねって話。なんだか書いてて当たり前すぎて消そうかと思ったけどもったいないので公開します笑
例えば以下のような手順をとるとする。
(execute_queryはクエリを実行して結果セットを良い感じに取得するメソッドを想像してください)
ids = execute_query(u'SELECT bug_id FROM Bugs;') target_id = random.choice(ids) record = execute_query(u'SELECT * FROM Bugs WHERE bug_id = %d;' % target_id)
この場合、target_idのレコードを3行目実行前に別のプロセスにより削除された場合はrecordを取得することができませんので、アプリケーション側でrecordが取得できないことを考慮できていない場合に思わぬ例外に繋がり得ます。
これを防ぐために、取得できなかった場合は後続の処理を実行しない、または例外を投げるなどの配慮が必要ですね。
基本的なことですがこういう考慮が抜けるとバグにつながるので気をつけましょう。>自分
- 作者: Bill Karwin,和田卓人(監訳),和田省二(監訳),児島修
- 出版社/メーカー: オライリージャパン
- 発売日: 2013/01/26
- メディア: 大型本
- 購入: 5人 クリック: 634回
- この商品を含むブログ (13件) を見る
pythonの日時系操作まとめ
プログラミングをしていれば、日時系の操作をする機会ってかなり多いですよね?
何日前を計算したり、文字列を日時オブジェクトにしたりその逆をしたり、曜日や月末日が欲しかったり。
自分が忘れっぽいのか、この辺の操作はすぐ忘れてしまい何度もググってしまうので、自戒の念も込めてまとめておきます。
バージョンは2.6。
datetimeの加算減算
# 現在日時から1日進める datetime.datetime.now() + datetime.timedelta(1) # 現在日時から1時間戻す datetime.datetime.now() - datetime.timedelta(hours = 1)
dateをdatetimeに変換
d = datetime.date.today(2012, 12, 12) t = datetime.time(12, 12, 12) datetime.datetime.combine(d, t)
datetimeをdateに変換
dt = datetime.datetime.now() dt.date()
エポックからの経過秒数をdatetime(ローカル)に変換
utc = time.time() datetime.datetime.fromtimestamp(utc)
datetimeをエポックからの経過秒数に変換
now = datetime.datetime.now()
timetuple = datetime.datetime.timetuple(now)
int(time.mktime(timetuple))
月末日を求める
youbi, end_of_month = calendar.monthrange(year, month) datetime.date(year, month, end_of_month)
日付が属する曜日を求める
# ※曜日を表す数値はcalendarの定数として定められている(calendar.SUNDAYなど)
datetime.date.today().weekday()
日付が属する週の初日を求める
# 週の初日を日曜日と仮定 d = datetime.date.today() weekday = d.weekday() if weekday == calendar.SUNDAY: return d else: delta = datetime.timedelta(7 - (calendar.SUNDAY - weekday)) return d - delta
とりあえずこの辺で。
へび年なのでpythonで占い
あけましておめでとうございます!
今年はへび年なのでpythonで占いしてみますね。
>>> import random >>> print random.choice([u'大吉', u'中吉', u'マジ吉', u'凶', u'大凶']) 中吉
悪くないですね!
今年もよろしくお願いします。
PythonのGood Parts
pythonを使い始めて1年半ほどになります。
ここらで、pythonの良いと感じたとこをまとめてみよう。
1. リスト内包表記
リスト内包表記とは、以下のようなものです。
# 通常のリスト生成 r = [] for i in range(100): r.append(i) # リスト内包表記 r = [i for i in range(100)]
良いと思うとこを箇条書き。
- 簡潔で直感的。
- 素のforループと違い、ループ処理がインタープリターにより最適化されるのでループ速度も向上します。(「Learning Python」では、"often roughly twice as fast"とあります。)
- 抽出条件や抽出した要素に対する処理を記述できる。
例えば、
# 対象のリストから3以上の値を取り出して2倍して新たなリストを作る r = [i * 2 for i in target if i >= 3] # これを素のfor文で書くとコードブロックが2段階発生して雑多な感じになります。 r = [] for i in target: if i < 3: continue r.append(i * 2)
なお、pythonにはリストの各要素に関数を適用するmap関数や、ある条件の要素抽出するfilter関数もあります。
# 全ての文字にord関数を適用 r = map(ord, 'spam') # リスト内包の場合 r = [ord(c) for c in 'spam'] # 3で割り切れる値を取り出す r = filter(lambda x: x % 3 == 0, range(10)) # リスト内包の場合 r = [i for i in range(10) if i % 3 == 0]
- ネストしたfor文も可能。(ただしやりすぎると可読性を損なう。)
# ネストしたfor文を内包表記 nested = [x + y for x in 'spam' for y in 'SPAM'] # 素で書くとこう。 nested = [] for x in 'spam': for y in 'SPAM': nested.append(x + y)
リストではなくジェネレータが欲しい時は()で囲みます。(リスト内包表記とは言わないけど)
g = (i ** i for i in range(10))
2. キーワード引数
元々Java使いだったのですが、これはかなり感動しました。
キーワード引数とは、関数に渡す引数を "keyword = value" の形で渡せる機構です。
def f(x, y, z): ... f(x=2, y=4, z=5) # 順序を崩すことも可能 f(y=2, z=3, x=5) # dictを展開して渡すことも可能 args = {"x":2, "y": 3, "z": 4} f(**args)
これ、何が良いってコードの可読性が増す点だと思います。
上記の関数のように引数が3個以上ある関数だと、どの位置がどの引数と対応づけられているか確認するのがなかなか手間だったりしますし、うっかり位置を間違えてしまうこともあります。
キーワード引数の仕組みを使えば、順序を気にすることもないですし初めてコードを読む人にとっても何を渡しているかわかりやすいコードになります。
デフォルト引数
またキーワード引数では以下のように、引数のデフォルト値を設定できます。
def load_users_by_type(user_type, max_results=100): ユーザーをuser_typeで絞ってid順にDBから取得する処理 # 呼び出し側は、max_resultsなしで呼べる。 users = load_users_by_type(1) # max_resultsを変動させたい場合 users = load_users_by_type(1, max_results=200)
max_resultsが大抵の場合は100だが、特定のケースでは200取りたい、というような場合に便利です。
それ以上に便利なシチュエーションが、メソッド引数の変更時。
例えば、load_users_by_typeメソッドにソートキーを指定したくなったとします。
キーワード引数が無い言語ならば、load_users_by_typeに引数を追加すると呼び出し箇所全てに修正が入ることになります。
それを避けるためにsort_key引数を加えたラッパーメソッドを作るというのもイマイチな気がします。
しかし、キーワード引数があるとload_users_by_typeの引数を、他の呼び出し箇所を気にせず変えられます。
def load_users_by_type(user_type, max_results=100, sort_key='id'):
まぁメソッド引数がそう簡単に変更されないような設計をするのが望ましいのですが、そううまくはいかないので、キーワード引数は非常に助かります。
キーワード引数はRuby2.0でもサポートされるみたいですね(デフォルト値の仕組みはすでにありますが)。
- 作者: Mark Lutz
- 出版社/メーカー: Oreilly & Associates Inc
- 発売日: 2009/10/02
- メディア: ペーパーバック
- 購入: 1人 クリック: 7回
- この商品を含むブログ (3件) を見る
リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)
- 作者: Dustin Boswell,Trevor Foucher,須藤功平,角征典
- 出版社/メーカー: オライリージャパン
- 発売日: 2012/06/23
- メディア: 単行本(ソフトカバー)
- 購入: 68人 クリック: 1,802回
- この商品を含むブログ (116件) を見る
DevLove2012に行ってMyTDDを見直そうと思った
DevLove2012に行って来ました。
登壇者の皆さん、スタッフの皆さん、参加者の皆さんお疲れ様でした!
さて、2日間ぶっ通しでたくさん中身の濃いセッションが行われましたが、僕にとって今回のDevLoveは自分がやってきたTDDを見直すきっかけとなりましたので、覚書としてブログに起こしておきます。
TDDとの出会い
僕が開発でTDDを取り入れるようになったのは今年の9月。
当時テストというと、単体すっとばして結合をやったりしてました。単体テストもせいぜいインタプリタでちょろっと動かす程度でした。
(それでも大きな問題なく開発できてましたが)
ところで、僕には以前から「美しいコードを書きたい」という思いがあります。
リファクタリングが美しいコードを書く有効な手法だと感じているのですが、風の噂で「TDDをやるとリファクタリングがやりやすくなる」みたいな話を小耳に挟んだので、試しにケント・ベック本を読んでみて、「これは良さげ!」と感じTDDを取り入れてみました。
確かにテストがあればリファクタの結果デグレしてないってことを保証できるので、コードを綺麗にするスピードと既存のコードに手を入れる安心感が高まると感じたんです。
My TDD
私のやったTDD。
早速テストファースト原則を破ります。なぜなら、「テストでリファクタをやりやすくしたい」っていう目的なら初めにテスト書く必要なんてないと思ったからです。リファクタしよう!って思ったときにその箇所のテスト書けば済む話ですから、順序なんてどうでも良いって思ってました。
勿論、テストを最初に書くことでインターフェースが洗練するって話も本では読みましたが半信半疑でした。
My TDDの結果・・・
期待通り、リファクタが捗りました。インタプリタで手打ちして確認してたのが馬鹿らしくなりましたね。
ただ、テストが書きづらいケースなんかも出てきて、これは設計が汚いか、テストが書きやすくない設計か、その両方かって疑問を持ったのが最近です。
テストが書きづらいとリファクタが進みません。テストのメンテナンスコストも高まります。テストを書きやすくするにはテストを先に書くのがよさそうだ。これはテストファーストってやっぱ大事かもと思ったわけです。
DevLoveで語られたTDD
さて、今回のDevLoveでは以下の3つのTDD関連セッションに参加しました。
- 「テストに開発をもっと駆動させたい」(諸橋恭介さん)
- 「世界を少しだけ前に動かすということ」(和智右桂さん)
- 「愛せないコードを書くには人生はあまりにも短い」(和田卓人さん)
それぞれのセッションで感じたことを簡単にまとめます。
諸橋さんのセッション
印象的だったのは、「テストは将来のための高い保険料を払うようなものではない」ってとこ。「テストによるリファクタのしやすさ向上や品質向上は副次的効果」とバッサリでした。
自分はTDDはリファクタありきだと思っていたのでちょっとショック。諸橋さんは、テストをまさに今現在の開発を駆動させるために使ってるんだなと感じました。
講演資料
devlove2012-let-yor-test-drive-dev-more // Speaker Deck
和智さんのセッション
GOOSという本の訳本(実践テスト駆動開発)を出したそうで、ケント・ベック本に続くバイブルとか言われてるそうです。
モックについて語らてるらしいです。モックってすげー便利だけどなんだかうまく使えてない感が激しかったので(モック差し込み周りのコードがゴチャゴチャしやすい)、藁をも掴む思いで読んでみようとおもいます!
(「モックは設計の手法として価値がある」ようなことも仰ってましたので余計に気になりました)
講演資料
世界を少しだけ前に進めるということ
これからのMy TDD
これらのセッションから感じたことは、TDDはリファクタをやりやすくしたり品質を保証するだけでなく、設計を美しする、更には仕事を楽しくするっていう力を秘めてるんではないかということです。
今自分がやってるTDDは、「テスト駆動開発」というか「テスト駆動リファクタリング」であったわけです。話を聞くに、テストを書くことが、どんな設計にするか考える事にも役立つというのは本当っぽいので、とりあえず愚直にTDDの原則(テストファースト)に立ち返ってコードを書いてみたいと思います。「守破離」の「守」って大事ですね。
- 作者: ケントベック,Kent Beck,長瀬嘉秀,テクノロジックアート
- 出版社/メーカー: ピアソンエデュケーション
- 発売日: 2003/09
- メディア: 単行本
- 購入: 44人 クリック: 1,022回
- この商品を含むブログ (154件) を見る
実践テスト駆動開発 テストに導かれてオブジェクト指向ソフトウェアを育てる (Object Oriented SELECTION)
- 作者: Steve Freeman,Nat Pryce,和智右桂,高木正弘
- 出版社/メーカー: 翔泳社
- 発売日: 2012/09/14
- メディア: 大型本
- 購入: 4人 クリック: 241回
- この商品を含むブログ (14件) を見る
Backbon.jsのextendの仕組み
Backbone.js Advent Calendarの13日目を担当しますAttsun_1031です。普段はpythonとjs使ってます。
Backbone.js使いでもないんですが、javascriptでコード再利用のパターンを検討している時にBackbone.jsのextendがヒッジョーに参考になったので、その仕組みについて書きます。(バージョンは0.9.2)
どうでも良い話ですが、python(ニシキヘビ)って背骨あるんでしょうか。
extendって?
新しいクラスを定義するために使います。extendの引数に渡したオブジェクトがそのクラスのインスタンスのメンバーになります。第2引数に渡したオブジェクトはクラスの静的なメンバーになります。利用例は以下。
// Personクラスを定義する var Person = Backbone.Model.extend({ // initializeはBackbone.jsで規定されている初期化処理で、newした時に呼ばれます。 initialize: function(name, age) { this.name = name; this.age = age; }, say: function() { return "I am " + this.name; } }, { TYPE: "Mammal" }); // Personのインスタンスを生成 var me = new Person('Attsun_1031', 26); console.log(me.say()); > 'I am Attsun_1031' console.log(Person.TYPE); > 'Mammal'
本来、プロトタイプベースのオブジェクト指向言語であるjsにはクラスやインスタンスといった概念が存在しないのですが、Backbone.jsではそれをエミュレートすることでコード再利用の方法を提供しています。
もちろん、こんな仕組みなくてもコード再利用は可能なんですが、クラスベースOOPに慣れてる人が圧倒的に多いからこうしてるんでしょうかね。
私もJavaやPythonのようなクラスベースのOOPを触っているのでクラス・インスタンスという概念があるほうが書きやすいです。
extendの仕組み
では本題に戻ってextendのソースコードを見ながら仕組みを紐解いていきます。
var extend = function (protoProps, classProps) { var child = inherits(this, protoProps, classProps); child.extend = this.extend; return child; };
これがextendのコードです。
protoPropsというのがインスタンスメンバー、classPropsというのがその名の通りクラスの静的なメンバーです。
動作は、inherits関数を呼んでchildを生成し、そのchildにextendメソッドを設定して返します。
これは、サブクラスから更なる継承を可能にするためです。
終わり。
・・・
ではなくて、肝心のinheritsメソッドの中身を見てみましょう。もとのコードからコメントを削除し、番号を振ってます。
var ctor = function(){}; var inherits = function(parent, protoProps, staticProps) { // 1 var child; // 2 if (protoProps && protoProps.hasOwnProperty('constructor')) { child = protoProps.constructor; } else { child = function(){ parent.apply(this, arguments); }; } // 3 _.extend(child, parent); // 4 ctor.prototype = parent.prototype; child.prototype = new ctor(); // 5 if (protoProps) _.extend(child.prototype, protoProps); if (staticProps) _.extend(child, staticProps); // 6 child.prototype.constructor = child; // 7 child.__super__ = parent.prototype; return child; };
1. 戻り値となるchildを定義します。これがサブクラス(コンストラクタ関数)です。こういう長い関数において、冒頭に戻り値を定義するのは良いプラクティスですね。
2. protoPropsに 'constructor' という名前の関数がある場合、それをchildにセットします。そうでない場合は、child自身をthisとしてparent関数を呼ぶ関数をセットします。parent関数はextendを呼んでいる関数なので、冒頭の例でいえばModel関数がコールされたことになります。
Model関数の詳細は省きますが、内部でthis.initialize.applyをコールしています。つまり、constuructorの指定がなければinitializeが必ず呼ばれる、ということになります。
3. これはBackbone.jsが依存しているunderscore.jsのextendを呼んでいる(と思われます)。childにparentのプロパティ(メソッドとか)をコピーしているのです。
4. inheritsの上で定義しているctorという空の関数にparentのprototypeをセットし、childのprototypeにはそれをnewしたものをセットします。
単純にparentのインスタンスをprototypeとしてセットしたいだけなら
child.prototype = new parent();
とやってしまえば良いのですが、これだとparentのインスタンス固有の変数(parent関数内でセットされる値)をchildが受け継いでしまいます。
やりたいのは、parentのプロトタイププロパティのみ継承することなので、空の関数にprototypeをコピーし、それをnewすることで解決しています。
この辺の話を理解するにはプロトタイプチェーンの理解が欠かせません(私も最近学びました)。オライリーの「JavaScriptパターン ―優れたアプリケーションのための作法」が非常に参考になります。この一時的なコンストラクタのテクニックの他、コード再利用パターンが色々書いてあるのでオススメです。
5. child.prototypeにprotoPropsをコピーします。これが所謂インスタンスメンバーになります。また、childそのものにstaticPropsをコピーすることで、Child.HOGEHOGEのような呼び出しができる静的メンバーをセットします。
6. child.prototypeのconstructorにchild自身をセットします。このconstuructorは2で出てきたconstuructorとは別物で、javascriptのあらゆるオブジェクトが持つプロパティです。これをしないとconstructorがparentのままになってしまうので設定しています。
7. __super__にparent.prototypeをセットします。こうすることで子クラスの中で以下のように親のメソッドを呼ぶことが可能になります。
Child.__super__.parentMethod.apply(this, some_args);
以上です。
extendはクラスベースOOPにおける継承をエミュレートしていますが内部ではプロトタイプの仕組みを使っているので、非常に勉強になりました。
JavaScriptパターン ―優れたアプリケーションのための作法
- 作者: Stoyan Stefanov,豊福剛
- 出版社/メーカー: オライリージャパン
- 発売日: 2011/02/16
- メディア: 大型本
- 購入: 20人 クリック: 886回
- この商品を含むブログ (68件) を見る