Planet Python Japan

RSS 2.0 ATOM
日本語で読める Python のお勧めフィードがありましたら nakagamiまで御連絡ください

2013-05-21

methaneのブログ

pip install や easy_install を速くするための pypi の設定変更

pip や easy_install が突然速くなるかもしれない で紹介した pypi からのインストール高速化の第一弾が始まりました。 といっても、いきなり勝手に pypi 側でスクレイピングするURLを変更するのではなくて、パッケージ管理者が明示的に指定する方法になります。 …

11:45:58

aodag's posthaven

Python2.4から3.2までで通用するexcept句の書き方

まあ3系文法との互換性って2.6からの話なんで、2.5とかの非互換は結構あきらめていたのですが。

PasteDeployは2to3なしで、2.5から3.2をサポートしてるのですね。

except句って、2.5だと

except Exception, e:

という書き方で、2.6以降で導入された

except Exception as e:

じゃないと3で通用しないわけです。

PasteDeployが、これをどう解決してるかというと、

except Exception:
    e = sys.exc_info()[1]

 

 

な、なるほど。これなら確かにどちらのバージョンでも通用する!

が、こんな書き方するよりは、2.5を切り捨ててしまいたい。

 

http://www.voidspace.org.uk/python/articles/porting-mock-to-python-3.shtml

 

ちなみに2/24のBPStudy #54 で、こんな感じの話をしますのよ。

http://connpass.com/event/268/

まだ枠あいてるっぽいです。どうぞよろしく。

08:58:42

BPStudy #54で発表してきたよ!

ということで第二部で、Python3移行の話をしました。

組織的な移行じゃなくて、オープンソースコミュニティでのライブラリ対応の話です。

http://www.slideshare.net/aodag/bpstudy54-python3

 

なんか誤解されちゃってる気がするので、補足しとく。

Python3自体は別に難しくないし面倒でもないです。

スライド中の苦しい話は、2と3と両方で動くように書くので面倒なんです。

そういうの気にしなければ、Python3使うのなんて簡単なんだからね!

08:58:42

virtualenvなしでもプロジェクトごとのライブラリを管理する方法 #python

ついうっかりvirtualenvせずに setup.py develop してしまったわけですが。

しかもwindowsだったので、権限でのストップがかからずそのまま大元のsite-packagesにざっくりインストールされました。

さて、setup.py developの場合、pipとは違い、eggごとのディレクトリにインストールされます。

で、これだけじゃPYTHONPATHに入ってこないわけで、site-packages内の *.pth ファイルにパスが羅列されているというのが、結構前に調べた結果。

インストールされてしまった、eggたちも、全部削除するんでなく、easy-install.pthの記述を消してしまえば、問題ないわけです。

さて、このeggたちを有効活用できないものか。

というか、そうするためにeggはディレクトリが分けられていまして、 pkg_resources.require() を使って、sys.pathに追加できます。

ポイントは、 pkg_resources.requireを使うと、そのeggが依存するeggもsys.pathに追加されるということ。

なので、今開発しているパッケージが bucho という名前で、きちんとsetup.pyに依存ライブラリを指定してあるなら、 pkg_resource.require('bucho') と書けば一発で必要なライブラリがsys.pathに追加されます。

さて、ちょっと目先を変えて、setup.pyから実行できるサブコマンドはサードパーティライブラリからも追加できます。

有名どころでは、noseのnosetestsコマンド、sphinxのbuild_sphinxコマンド。

で、先ほどの pkg_resources.requireですが、setup.pyから起動されるサブコマンドでは、setupされてるeggを内部でrequireしてあるようで、 コマンド自体のライブラリ(たとえばnose)があらかじめimport可能な状態なら、問題なく setup.py nosetestなどできます。

さらに、pkg_resources.requireはバージョン指定も可能です。また、easy_installコマンドは-m (マルチバージョン)オプションがあり、このオプションをつけると easy_install.pthに追記されずにインストールされます。このあたりの仕組みを使いこなせば、どんどん増えていくvirtualenvに悩まされることはなかったでしょう。

という、もうすぐpackaging/distutils2が出てしまう段階で、こんなTIPを調べたことに腹正しさを感じつつvirtualenvしなおしています...

08:58:42

2012 Pythonアドベントカレンダー 18日目 PasteDeployを知ってるかい?

From Evernote:

2012 Pythonアドベントカレンダー 18日目 PasteDeployを知ってるかい?

PasteDeployを知ってるかい?

さて、2012 Pythonアドベントカレンダーの18日目です。

一応Webフレームワークに関連してればよいということで、普段あまり言及されないPasteDeployの話をしておきます。

PasteDeployとは?
ああ、プロジェクトのテンプレートを展開するやつですよね?とかしたり顔で聞いてくる奴は自分で穴掘ってもぐっといてください。
PasteScriptのpaster createのことではありません。
paster serveのほうです。

PasteDeployは、iniファイルでWSGIアプリケーションやミドルウェア、サーバーの設定や構成を管理するものです。
で、そのiniファイルを paster serveに渡せば WSGIアプリケーションが実行されるわけですね。

WSGIがわからない人は、 http://shomah4a.bitbucket.org/advent_calendar/2012/wsgi.html を読んでね。

ちょっとだけWebOb
まあ、とりあえずHelloなWSGIアプリケーションでも作って動かしてみましょう。

helloapp.py

from webob.dec import wsgify

@wsgify
def hello(request):
    return u"Hello, world!"

shomah4a の例と違うのはWebOb使ってるところ。

ではこれを動かすので、 webob と pastescriptをインストールしましょう。

$ pip install webob pastescript

pasterコマンドが使えるようになりますが、これでいきなりWSGIアプリケーションを動かせるわけではありません。
WSGIアプリ、ミドルウェア、サーバーの構成を定義する ini ファイルが必要です。

PasteDeployしてみよう
ひとまず最少の構成では、WSGIアプリとサーバーを指定すればOKです。

hello.ini

[app:main]
paste.app_factory = helloapp:main

[server:main]
use = egg:paste#http
host = 0.0.0.0
port = 5000

さて、今あるのは単に helloというアプリケーションだけです。
pastedeployでは、直接アプリケーションを参照するのではなく、アプリケーションを返す関数(ファクトリ)を指定するようになっています。

helloapp.py

def main(global_conf, **app_conf):
    return hello

今のところ特に設定を必要としてないので、さっきの hello をそのまま返すようにします。

$ paster serve hello.ini

で動きますね。

設定を使う
実際のところWebアプリケーションだと、データベースへの接続だとかそういった設定が必要です。
が、ここでSQLAlchemyの話を出すと説明しきれないので、messsageとか渡すことにしましょう。

設定をもとにアプリケーション作成するので、クラスにします。

class HelloApp(object):
    def __init__(self, message):
        self.message = message

    @wsgify
    def __call__(self, request):
        return self.message

def main(global_conf, message, **app_conf):
    return HelloApp(message)

で、 hello.ini は以下のように変更します

[app:main]
paste.app_factory = helloapp:main
message = Hello, world!

(´・ω・`)さて、ここからが本編です。
ええ、ここまでは、PasteDeploy自体知らないなんていう人が多いのではないかということで書きました。
なんせ、このアドベントカレンダーは8割がたDjangoネタですからね。おまいらフレームワーク1つしか知らないのか。

PasteDeployの設定を共有する
とりあえず設定値を2つにしてみます。

helloapp.py

class HelloApp(object):
    def __init__(self, message1, message2):
        self.message1 = message1
        self.message2 = message2

    @wsgify
    def __call__(self, request):
        return u"{0} {1}".format(self.message1, self.message2)

def main(global_conf, message1, message2, **app_conf):
    return HelloApp(message1, message2)

hello.ini

[app:main]
paste.app_factory = helloapp:main
message1 = Hello
message2 = world!

まあこんなもんです
が、たまにmessage1だけを変えたい時があるかもしれません。

そんなときには
セクションを追加します。

[app:hello]
use = main
message1 = Hi

このように use でセクションを指定して、変えたいところだけ設定します。
このappを実行するには、 paster serve に -n オプションで hello と指定します。

$ paster serve hello.ini -n hello

という、pastedeployで設定の共有や上書きができるよ。というお話でした。
これで、 production.iniやdevelopment.iniなどで、設定を共有しながら、デバッグフラグやDB接続など、必要な部分だけを変更して扱うことができますね。

19日目は @podhmo お願いします。

08:58:42

IT業界Heavy Metal Advent Calendar 2012 22日目

http://www.adventar.org/calendars/50 こちらからのアドベントカレンダー。

 

眠気を吹き飛ばすメタルを紹介ということらしいので

SavatageのJesus Saveです。

アルバムがロックオペラってことで全体通して聞いてると眠気が襲ってくることになりますが:D

 

次は速弾き野郎Impellitteli の kindom of light

その前のアルバムでブレそうだったこともあり、このアルバムでは吹っ切れたようにひたすら速弾き。

コーディングのお供に最適です。

で、ロブ・ロックのボーカルが地味にはまってきたりもするわけで。

 

という2枚を紹介しときます。

(あ、両方Chrisだ。

08:58:42

PySPAアドベントカレンダー

From Evernote:

PySPAアドベントカレンダー

PySPAアドベントカレンダー

はい。皆勤賞にして、すべてのいただきますを唱和したaodagです。

公式には全10回、4食ずつで40回の「いただきます」「ごちそうさまでした」をしてきたことになりますが、
(´・ω・`)どうでもいいですね。

「いただきます」の動画が残ってました。

(´・ω・`)はい、ほほえましいですね。

半年に1回ペースで10回あったということは、5年以上たったわけですね。
その間の僕のPythonへの関わりはどのように変わったか考えてみました。

興味の対象
TurboGears,WSGI,Pylons,Repoze,buildout,pyramidなどなど

ひたすら強力なものを追い求めた結果ですが、まあ、僕が選ぶものがどれだけ流行らないのかという歴史です。

というわけでなんか振り返りとしてもぐだぐだなので、この辺で。

08:58:42

2012の新年のあれがどうなったか

PyConJP の併設イベントを入れて4回開催した!達成!

(´・ω・`)なう、検討中。

PyramidとかRepozeに貢献できたと思うので達成!

EuroPython行ったので達成!

(´・ω・`)がんばってる。

(´・ω・`)50どころか2桁いってない事実..

 

(´・ω・`)と、いうことで、3/6達成でした。

英語とか

08:58:42

New Year's Python Meme 2012 #2012pythonmeme

From Evernote:

New Year's Python Meme 2012 #2012pythonmeme

New Year's Python Meme 2012

去年 http://aodag.posterous.com/new-years-python-meme-2012pythonmeme

1. What’s the coolest Python application, framework or library you have discovered in 2012 ?

obviel, that is zopish javascript framework.

2. What new programming technique did you learn in 2012 ?

  • ZCA
  • Client Side MVC

3. Which open source project did you contribute to the most in 2012 ? What did you do ?

pyramid, repoze. Mainly, i've committed to support python3.

4. Which Python blog or website did you read the most in 2012 ?

reddit, stackoverflow

5. What are the three top things you want to learn in 2013 ?

async programming: gevent, tornado, zeromq
HTML5 and Mobile Web


6. What is the top software, application or library you wish someone would write in 2013 ?

  • pip with new generation packaging

08:58:42

新年的なアレ

From Evernote:

新年的なアレ

新年的なアレ

  • coffescript,dart,typescriptのどれか1つを勉強する
  • 自炊がんばる
  • ポモドーロとかGTDとか、なんかそんなので改善なやつをする
  • (´・ω・`)ブログは30エントリ目指す

08:58:42

pytest, mock, testfixture!

(´・ω・`)はい。こんにちは。パーフェクトPythonも無事?発売されて一安心なaodagです。 まあ、なんかテスト関連でよくいろいろ言ってる気がするのですが、最近ツールを変えたので、覚書を。 これまで:

という組み合わせでした。 unittest2の豊富なassert系メソッドとnoseの豊富なプラグインってところです。 テストケース自体はunittest2で書いて、noseのテストランナーを使うと。   が、最近もうこの2つはpytestに変えました。 だいたいいつも使ってるようなのは、pytestでまかなえるし、pytest-covがあれば十分かな。 追加で使うツールとして、mockは続投、testfixtureが便利な気がするので、使い始めてます。 それぞれのツールの使い方はだいたいそこらへんのマニュアルとか見てくれればいいと思うので、pytestでどのようなことをしてるかってのを。 zopeやpyramid界隈では、テスト用のダミーやフィクスチャ(データフィクスチャじゃないよ。まったく某フレームワークのせいでフィクスチャっていうとデータのことばかり...)を testing というモジュールにまとめておくのが慣例です。 で、pyramidにもtestingモジュールがあり、 testing.setUp, testing.tearDownというのが、テスト用のコンポーネントレジストリを初期化するフィクスチャです。 pytest的なフィクスチャにしてみます。

@pytest.fixture

def config(request):

    from pyramid import testing
    config = testing.setUp()

    def fin():
        testing.tearDown()

    request.addfinalizer(fin)

    return config
 

pytest.fixtureデコレータでフィクスチャの登録をします。 なかでやってるのは、testing.setUpの呼び出しと、testing.tearDownをテスト後に呼び出すための設定です。 requestがそういうフックを設定するためのオブジェクトです。 このフィクスチャを使うには、テストケースの引数にconfigという名前をつけます。 pytestが、フィクスチャの名前と同じ引数のところに自動でフィクスチャの戻り値を渡してくれます。

from .testing import config

def test_it(config):

    config.include('test.under.the.module')
 

楽ですね。 testfixtureは、汎用的なフィクスチャがそろっています。 日付やログ、ファイル出力、ファイルシステムの操作など、ユニットテストでよくあるめんどうな部分をカバーしてくれてるので、便利に使えるようになりたいものです。 テストツールのセットアップ テストツールが増えてくるとそれをインストールするのも簡単にすませたいところです。 テストツールようのrequirementsを用意しといてもいいのですが、 setup.pyに書く場所があるので、そっちを使います。

setup(name="...",
      ....
      tests_require=["pytest", "mock", "testfixtures"],
      ....
     )
 

このように書いておくと、 python setup.py test とすれば、現在のディレクトリにインストールされます。 うざいですね。 extras_requireを使うと、現在の環境にインストールできます。

tests_require = ["pytest", "mock", "testfixtures"]

setup(name="test.under.the.package",
      ....
      tests_require=tests_require,
      extras_require={"testing": tests_require},
      ....
      )
 
このようにしておくと、  python setup.py develop easy_install test.under.the.package[testing] などのコマンドでテストツールまで、インストールできます。
長くてめんどうなので、 setup.cfg にエイリアスを作ります。
[aliases]
dev = develop easy_install test.under.the.package[testing]
 
最近のpip (1.2以上のバージョン)も extrasをサポートしています。
pip を使う場合は pip install -e .[testing] というコマンドで、ほぼ同じようになります。
これらのツールはpython3対応もしてるので、長い付き合いができそうです。

08:58:42

2013-05-20

牌語備忘録 - pygo

[Rails] Rails4 から jbuilder がデフォみたいなので Rails3 で使ってみるメモ

(Rails3.2.13)

下準備

$ rails new jbuilder_app -T --skip-bundle
$ cd jbuilder_app
$ bundle install
$ rails generate scaffold Book title price:integer
$ rake db:migrate
db/seed.rb
Book.create(title: "明暗", price: 788)
Book.create(title: "草枕", price: 452)
$ rake db:seed

json出力確認

{"created_at":"2013-05-19T09:14:48Z","id":1,"price":788,"title":"明暗","updated_at":"2013-05-19T09:14:48Z"}

jbuilderを使ってみる

Gemfile

デフォルトで存在するがコメントアウトされているから解除する

gem 'jbuilder'
bundle install
app/controllers/books_controller.rb

respond_to を削除

  def show
    @book = Book.find(params[:id])
  end
app/views/books/show.json.jbuilder

新しくファイル作成

json.extract! @book, :title, :price
json.index_path books_path
Webブラウザで確認
{"title":"明暗","price":788,"index_path":"/books"}

Json を Javascript(coffeescript) を使って表示してみる

app/views/books/show.html.erb
:
<hr />
<%= link_to "show json", "#", id: "show_json_btn" %>
<div id="show_json"></div>
app/assets/javascripts/books.js.coffee
$ ->
  $json_content = $('#show_json')

  $(document).on 'click', '#show_json_btn', (e) ->
    e.preventDefault()
    $.getJSON location.pathname + ".json", (book)->
      $json_content.html('')
      $json_content.append(book.title + ": " + book.price + "yen<br />")
      $json_content.append("<a href='#{book.index_path}'>Books</a>" + "<br />")
      $json_content.append(JSON.stringify(book))

click button "show json"

f:id:CortYuming:20130520154010p:image

2013-05-19

牌語備忘録 - pygo

[Rails] Railsコマンドを高速化するらしいgem『Commands』を使ってみるメモ

(Rails3.2.13)

ほかに Spring や Zeus とかありますが、あえて DHH の Commands を使ってみた。

ちなみに Commands は rails console の中で使うものらしい。

確認用下準備

$ rails new commands -T --skip-bundle
$ cd commands
Gemfile
group :development, :test do
  gem 'rspec-rails'
  gem 'commands'
end
$bundle install
$ rails generate scaffold Book title price:integer

普通にrakeコマンドを試してみる

 $ rake routes
 :
 $ rake db:migrate
 :
 $ rake db:rollback

routes も db:migrate も表示されるまで3秒くらいかかった。

Commands 使ってみる。

$ rails console
> rake "routes"
:
> rake "db:migrate"
rake "db:migrate"
   (0.1ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" 
Migrating to CreateBooks (20130519032156)
   (0.1ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" 
=> "Completed"

どちらのコマンドも一瞬で表示された。1秒かからなかった。

Rspecも
> generate "rspec:install"
generate "rspec:install"
      create  .rspec
       exist  spec
      create  spec/spec_helper.rb
=> "Completed"
> rake "spec"
rake "spec"
:
Finished in 0.28643 seconds
30 examples, 0 failures, 2 pending

Randomized with seed 34888

=> "Completed"
Rake Tasks
> rake
rake
rake about              # List versions of all Rails frameworks and the env...
rake assets:clean       # Remove compiled assets
rake assets:precompile  # Compile all the assets named in config.assets.pre...
rake db:create          # Create the database from DATABASE_URL or config/d...
rake db:drop            # Drops the database using DATABASE_URL or the curr...
rake db:fixtures:load   # Load fixtures into the current environment's data...
rake db:migrate         # Migrate the database (options: VERSION=x, VERBOSE...
rake db:migrate:status  # Display status of migrations
rake db:rollback        # Rolls the schema back to the previous version (sp...
rake db:schema:dump     # Create a db/schema.rb file that can be portably u...
rake db:schema:load     # Load a schema.rb file into the database
rake db:seed            # Load the seed data from db/seeds.rb
rake db:setup           # Create the database, load the schema, and initial...
rake db:structure:dump  # Dump the database structure to db/structure.sql. ...
rake db:version         # Retrieves the current schema version number
rake doc:app            # Generate docs for the app -- also available doc:r...
rake log:clear          # Truncates all *.log files in log/ to zero bytes
rake middleware         # Prints out your Rack middleware stack
rake notes              # Enumerate all annotations (use notes:optimize, :f...
rake notes:custom       # Enumerate a custom annotation, specify with ANNOT...
rake rails:template     # Applies the template supplied by LOCATION=(/path/...
rake rails:update       # Update configs and some other initially generated...
rake routes             # Print out all defined routes in match order, with...
rake secret             # Generate a cryptographically secure secret key (t...
rake spec               # Run all specs in spec directory (excluding plugin...
rake spec:controllers   # Run the code examples in spec/controllers
rake spec:helpers       # Run the code examples in spec/helpers
rake spec:models        # Run the code examples in spec/models
rake spec:requests      # Run the code examples in spec/requests
rake spec:routing       # Run the code examples in spec/routing
rake spec:views         # Run the code examples in spec/views
rake stats              # Report code statistics (KLOCs, etc) from the appl...
rake time:zones:all     # Displays all time zones, also available: time:zon...
rake tmp:clear          # Clear session, cache, and socket files from tmp/ ...
rake tmp:create         # Creates tmp directories for sessions, cache, sock...
=> "Completed"

感想

シンプルでクールな感じ?

思ったよりいい感じな気がする。



2013-05-17

牌語備忘録 - pygo

[Rails] Rails4 の Webブラウザ上でのエラー画面が使ってみたら想定以上にいい感じだったから Rails3 でも better_errors を使ってみることにしたメモ

(Rails3.2.13)

エラー画面でコンソール使えるのがとても便利

エラー画面

Rails3.2(デフォルト)

f:id:CortYuming:20130517181623p:image

Rails3.2 で better_errors を利用した場合

Gemfile

(better_errors で irb を利用するに binding_of_caller も必要)

group :development do
  gem 'better_errors'
  gem 'binding_of_caller' # irb in better_errors
end

f:id:CortYuming:20130517181652p:image

[Rails] Rails4 rc1 で scaffold したときに 生成される Gemfile, model, controller などのメモ

(Rails4.0rc1)

$ rails new app --pre --skip-bundle
      create
      create  README.rdoc
      create  Rakefile
      create  config.ru
      create  .gitignore
      create  Gemfile
      create  app
      create  app/assets/javascripts/application.js
      create  app/assets/stylesheets/application.css
      create  app/controllers/application_controller.rb
      create  app/helpers/application_helper.rb
      create  app/views/layouts/application.html.erb
      create  app/mailers/.keep
      create  app/models/.keep
      create  app/controllers/concerns/.keep
      create  app/models/concerns/.keep
      create  bin
      create  bin/bundle
      create  bin/rails
      create  bin/rake
      create  config
      create  config/routes.rb
      create  config/application.rb
      create  config/environment.rb
      create  config/environments
      create  config/environments/development.rb
      create  config/environments/production.rb
      create  config/environments/test.rb
      create  config/initializers
      create  config/initializers/backtrace_silencers.rb
      create  config/initializers/filter_parameter_logging.rb
      create  config/initializers/inflections.rb
      create  config/initializers/mime_types.rb
      create  config/initializers/secret_token.rb
      create  config/initializers/session_store.rb
      create  config/initializers/wrap_parameters.rb
      create  config/locales
      create  config/locales/en.yml
      create  config/boot.rb
      create  config/database.yml
      create  db
      create  db/seeds.rb
      create  lib
      create  lib/tasks
      create  lib/tasks/.keep
      create  lib/assets
      create  lib/assets/.keep
      create  log
      create  log/.keep
      create  public
      create  public/404.html
      create  public/422.html
      create  public/500.html
      create  public/favicon.ico
      create  public/robots.txt
      create  test/fixtures
      create  test/fixtures/.keep
      create  test/controllers
      create  test/controllers/.keep
      create  test/mailers
      create  test/mailers/.keep
      create  test/models
      create  test/models/.keep
      create  test/helpers
      create  test/helpers/.keep
      create  test/integration
      create  test/integration/.keep
      create  test/test_helper.rb
      create  tmp/cache
      create  tmp/cache/assets
      create  vendor/assets/javascripts
      create  vendor/assets/javascripts/.keep
      create  vendor/assets/stylesheets
      create  vendor/assets/stylesheets/.keep
Gemfile
source 'https://rubygems.org'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.0.0.rc1'

# Use sqlite3 as the database for Active Record
gem 'sqlite3'

# Use SCSS for stylesheets
gem 'sass-rails', '~> 4.0.0.rc1'

# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'

# Use CoffeeScript for .js.coffee assets and views
gem 'coffee-rails', '~> 4.0.0'

# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby

# Use jquery as the JavaScript library
gem 'jquery-rails'

# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
gem 'turbolinks'

# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 1.0.1'

group :doc do
  # bundle exec rake doc:rails generates the API under doc/api.
  gem 'sdoc', require: false
end

# Use ActiveModel has_secure_password
# gem 'bcrypt-ruby', '~> 3.0.0'

# Use unicorn as the app server
# gem 'unicorn'

# Use Capistrano for deployment
# gem 'capistrano', group: :development

# Use debugger
# gem 'debugger', group: [:development, :test]

Scaffold

$ rails generate scaffold Book title price:integer
      invoke  active_record
      create    db/migrate/20130517001016_create_books.rb
      create    app/models/book.rb
      invoke    test_unit
      create      test/models/book_test.rb
      create      test/fixtures/books.yml
      invoke  resource_route
       route    resources :books
      invoke  jbuilder_scaffold_controller
      create    app/controllers/books_controller.rb
      invoke    erb
      create      app/views/books
      create      app/views/books/index.html.erb
      create      app/views/books/edit.html.erb
      create      app/views/books/show.html.erb
      create      app/views/books/new.html.erb
      create      app/views/books/_form.html.erb
      invoke    test_unit
      create      test/controllers/books_controller_test.rb
      invoke    helper
      create      app/helpers/books_helper.rb
      invoke      test_unit
      create        test/helpers/books_helper_test.rb
      invoke    jbuilder
       exist      app/views/books
      create      app/views/books/index.json.jbuilder
      create      app/views/books/show.json.jbuilder
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/books.js.coffee
      invoke    scss
      create      app/assets/stylesheets/books.css.scss
      invoke  scss
      create    app/assets/stylesheets/scaffolds.css.scss

Model

app/models/book.rb
class Book < ActiveRecord::Base
end

Controller

app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
end
app/controllers/books_controller.rb
class BooksController < ApplicationController
  before_action :set_book, only: [:show, :edit, :update, :destroy]

  # GET /books
  # GET /books.json
  def index
    @books = Book.all
  end

  # GET /books/1
  # GET /books/1.json
  def show
  end

  # GET /books/new
  def new
    @book = Book.new
  end

  # GET /books/1/edit
  def edit
  end

  # POST /books
  # POST /books.json
  def create
    @book = Book.new(book_params)

    respond_to do |format|
      if @book.save
        format.html { redirect_to @book, notice: 'Book was successfully created.' }
        format.json { render action: 'show', status: :created, location: @book }
      else
        format.html { render action: 'new' }
        format.json { render json: @book.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /books/1
  # PATCH/PUT /books/1.json
  def update
    respond_to do |format|
      if @book.update(book_params)
        format.html { redirect_to @book, notice: 'Book was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @book.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /books/1
  # DELETE /books/1.json
  def destroy
    @book.destroy
    respond_to do |format|
      format.html { redirect_to books_url }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_book
      @book = Book.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def book_params
      params.require(:book).permit(:title, :price)
    end
end

View

app/views/books/index.json.jbuilder
json.array!(@books) do |book|
  json.extract! book, :title, :price
  json.url book_url(book, format: :json)
end

2013-05-16

牌語備忘録 - pygo

[Rails] Rails で簡単に検索機能を利用できる『ransack』のメモ

f:id:CortYuming:20130517001329p:image

(Rails3.2.13)

前にやったMetaSearchのgithubをよく見たら開発が止まっているようで他になにかないかと探してたら発見した。

MetaSearch の後継らしい。

とりあえずやってみる

rails new app -T --skip-bundle
:
cd app/
Gemfile
gem "ransack"
shell
$ bundle install
$ rails g scaffold Person name articles_title
:
$ rake db:migrate
app/controllers/people_controller.rb
def index
  def index
    @q = Person.search(params[:q])
    @people = @q.result(distinct: true)
app/views/people/index.html.erb
<h1>Listing people</h1>

<%= search_form_for @q do |f| %>
  <div>
    <%= f.label "Name" %>
    <%= f.text_field :name_eq %>
  </div>
  <div>
    <%= f.label "Articles Title" %>
    <%= f.text_field :articles_title_cont %>
  </div>
  <div>
    <%= f.submit %>
  </div>  
<% end %>
Shell
$ rails s

Check the web browser



2013-05-15

偏った言語信者の垂れ流し

[Delphi]Delphi XE4での変更点を試す

Delphi XE4が先日発売されましたね。私はiOSアドオンなしでXE3からアップグレードしました。

XE3を購入したときのポイントが余ってたおかげで、SEshopで1,200円程度で購入できました。

iOS対応を除くと、機能追加はほとんどないのですが、リリースノートに載っているインデックスが0から始まるの文字列と、追加されたTIntegerHelperを試してみました。

Delphi XE4 および C++Builder XE4 の新機能 - RAD Studio

test_zerobased_str.dpr

ZEROBASEDSTRINGSにONを指定するとString型のインデックスは0から始まります。

program test_zerobased_str;

{$APPTYPE CONSOLE}
{$ZEROBASEDSTRINGS ON}

var
  Foo: String;
  I: Integer;

begin
  Foo := 'ABCDE';
  for I := 0 to Length(Foo) - 1 do
    Writeln(Foo[I]);
end.
実行結果
>dcc32 test_zerobased_str.dpr
>test_zerobased_str.exe
A
B
C
D
E

ちなみに、OFFの場合はこうなります。

>test_zerobased_str.exe

A
B
C
D

test_integer_helper.dpr

program test_integer_helper;

{$APPTYPE CONSOLE}

(* System.SysUtilsをusesに追加することでヘルパークラスが有効になる *)
uses
  System.SysUtils;

var
  IntValue, IntValue2: Integer;
  StrValue: String;

begin
  IntValue := 12345;
  (* IntegerからStringへ変換 *)
  StrValue := IntValue.ToString;
  Writeln(StrValue);
  (* StringからIntegerへ変換 *)
  IntValue2 := Integer.Parse('54321');
  Writeln(IntValue2);
end.
実行結果
>dcc32 test_integer_helper.dpr
>test_integer_helper.exe
12345
54321

参考

00:54:56

牌語備忘録 - pygo

[Rails][MacOSX] WEB+DB vol.73 の「Rails4 実践チュートリアル」をやってみるのに Rails4 rc1 と Ruby2.0 をインストールしてみるメモ

(MacOSX10.8, Ruby2.0, Rail4rc1)

rbenv と ruby-build を github からインストールしている前提で

以下、チュートリアルをする環境を整える

$ cd ~/.rbenv/plugins/ruby-build/
$ sudo git pull
$ sudo rbenv install 2.0.0-p195
$ mkdir rails4_test
$ cd rails4_test
$ rbenv local 2.0.0-p195
$ ruby -v
ruby 2.0.0p195 (2013-05-14 revision 40734) [x86_64-darwin12.3.0]
$ sudo gem install bundler
$ sudo gem install rake
$ sudo gem install rails --pre --no-ri --no-rdoc
$ rails new rails4_test -T
$ rails generate scaffold Book title price:integer
$ rake db:migrate
$ rails s

メモ

WEB+DB PRESS vol.73 買っててよかった。

「Rails4 実践チュートリアル」をやってみたら想定以上に勉強になった気がした。



[Javascript] Google Chrome 拡張機能 の Content Scripts で、Javascript で生成されたページのフレーム内のDOM要素にアクセスする場合のメモ

問題

とあるサイトだけで動く Google Chrome 拡張機能を作っていたら

DOM要素にアクセスできなくて、html を見たら document.write で frame が書き出されていた。

対策

all_frames を true にする

for example : manifest.json
:
    "content_scripts": [
        {
            "matches": ["https://hoge/*"],
            "js": ["jquery-1.9.1.min.js", "main.js"],
            "all_frames": true
        }
    ]

これでDOM要素にアクセスできるようになった。

2013-05-12

牌語備忘録 - pygo

[Javascript] Javascript で Base64 エンコード/デコードのメモ

> var encodedData = window.btoa("Hello, world");
undefined
> encodedData;
"SGVsbG8sIHdvcmxk"
> var decodedData = atob(encodedData); 
undefined
> decodedData;
"Hello, world"

2013-05-11

偏った言語信者の垂れ流し

[nginx]nginxのリバースプロキシでキャッシュする

メモ。nginxのリバースプロキシでファイルをキャッシュする方法。

設定したページはこれ。バックエンドはGoogleAppEngine。

http://www.nullpobug.com/

試したnginxのバージョンは0.7。Ubuntu10.04のなので古い。

nginxの設定

nginx.confの中でconf.dやsites-enabledがincludeされるようになってることが前提。

/etc/nginx/conf.d/proxy_cache.conf
proxy_cache_path /var/cache/nginx/cache levels=1:2 keys_zone=my-key:16m max_size=100m inactive=120m;
proxy_temp_path /var/cache/nginx/tmp;

httpディレクティブにproxy_cache_pathを設定する。levelsは、キャッシュファイルをサブディレクトリで保存する設定。

この例の場合、my-keyというキーの領域で共有メモリは16MB使用、キャッシュ全体のサイズは100MB、120分間アクセスが無ければキャッシュは削除される。

proxy_temp_pathで一時ディレクトリを設定する。対象のディレクトリはあらかじめ作成し、nginxのworkerプロセスがアクセスできるようにしておく。

/etc/nginx/sites-available/my-site
server {
        listen   80;
        server_name  www.example.com;
        proxy_set_header X-Real-IP $remote_addr;

        access_log  /var/log/nginx/my-site.access.log;
        error_log  /var/log/nginx/my-site.error.log;

        location / {
                proxy_pass http://127.0.0.1:8000;
                proxy_ignore_headers Cache-Control;
                proxy_cache my-key;
                proxy_cache_valid 200 302 60m;
                proxy_cache_valid 404 10m;
        }
}

サイトごとの設定では、proxy_cacheでkeys_zoneに指定した名前、proxy_cache_validでキャッシュ対象と有効な時間を指定する。

この例では、レスポンスのステータス番号が200と302の場合は60分、404の場合は10分としている。

リバースプロキシ先のレスポンスにCache-Controlヘッダがついていて、"no-cache"とされているとキャッシュされないので、その場合はproxy_ignore_headersで無効化する。

nginxの設定をリロードする

$ sudo /etc/init.d/nginx reload

参考

08:10:59

牌語備忘録 - pygo

[Ubuntu] Ubuntu セットアップする時にとりあえずインストールするものメモ

aptitude

$sudo aptitude install vim
$sudo aptitude install git
$sudo aptitude install build-essential
$sudo aptitude install ruby1.9.3
$sudo aptitude install imagemagick
$sudo aptitude install apache2
$sudo aptitude install mysql-server mysql-devel
$sudo aptitude install sysv-rc-conf
$sudo aptitude install nodejs

gem

$sudo gem install bundler
$sudo gem install passenger
$passenger-install-apache2-module
:
--------------------------------------------
The Apache 2 module was successfully installed.

Please edit your Apache configuration file, and add these lines:

   LoadModule passenger_module /var/lib/gems/1.9.1/gems/passenger-3.0.19/ext/apache2/mod_passenger.so
   PassengerRoot /var/lib/gems/1.9.1/gems/passenger-3.0.19
   PassengerRuby /usr/bin/ruby1.9.1

After you restart Apache, you are ready to deploy any number of Ruby on Rails
applications on Apache, without any further Ruby on Rails-specific
configuration!

Press ENTER to continue.

--------------------------------------------
Deploying a Ruby on Rails application: an example

Suppose you have a Rails application in /somewhere. Add a virtual host to your
Apache configuration file and set its DocumentRoot to /somewhere/public:

   <VirtualHost *:80>
      ServerName www.yourhost.com
      # !!! Be sure to point DocumentRoot to 'public'!
      DocumentRoot /somewhere/public
      <Directory /somewhere/public>
         # This relaxes Apache security settings.
         AllowOverride all
         # MultiViews must be turned off.
         Options -MultiViews
      </Directory>
   </VirtualHost>

And that's it! You may also want to check the Users Guide for security and
optimization tips, troubleshooting and other useful information:

  /var/lib/gems/1.9.1/gems/passenger-3.0.19/doc/Users guide Apache.html

Enjoy Phusion Passenger, a product of Phusion (www.phusion.nl) :-)
https://www.phusionpassenger.com

Phusion Passenger is a trademark of Hongli Lai & Ninh Bui.
:

2013-05-10

西尾泰和のはてなダイアリー

文字列の解析

プログラミング言語の処理系は、文字列として与えられたソースコードから意味を汲み取る必要があります。例えば"int x = 1234;"という文字列から、"1234"の部分が整数を意味しているということを理解する必要があります。

どうすればそのようなことができるでしょうか?

最初の一歩として"ab12cd"という文字列を受け取ると"12"を返す関数を作ることを考えてみましょう。

どうすればそのような関数を作れるでしょうか?

素朴に1文字ずつループ

まずはやりたいことをもっと明確に言語化してみましょう。やりたいことは「文字列を頭から1文字ずつ見ていって、0〜9の文字が続いている範囲を取り出したい」です

最初の文字が「0〜9の文字」でなかったら?その時は特に何もせずに次の文字を見れば良い。

次の文字も「0〜9の文字」でなかったら?その時も特に何もせずに次の文字を見れば良い。

次の文字が「0〜9の文字」だったら?これは結果として返すべき文字列の一部ですね。だけどまだreturnしてはいけません。だって次の文字の「0〜9の文字」かもしれませんから。と言うことは「後で結果として返すもの」を溜めておく必要がありますね。resultという名前で呼ぶことにします。

次の文字も「0〜9の文字」だったら?これも結果として返すべき文字列の一部です。これも溜めておく必要があります。

その次の文字が「0〜9の文字」でなかったら?ここでついに「0〜9の文字が続いている範囲」が終わりました!溜めておいた結果を返しましょう。

でも、「文字が『0〜9の文字』でない」という条件は「0〜9の文字が続いている範囲」の前と後と両方で使われていますね。「文字が『0〜9の文字』でない」という条件だけではどう行動するべきかが決まらないわけです。そこで「0〜9の文字が続いている範囲」が見つかったか、まだ見つかっていないのかを条件に含めることにします。これはis_foundという名前で呼ぶことにします。

こういう考え方で作られたPythonのコードが以下になります。

def find_int(string):
    result = ""
    is_found = False
    for char in string:
        print 'char=%r, result=%r, is_found=%r' % (char, result, is_found)
        if char in '0123456789':
            result += char
            is_found = True
        elif is_found:
            return result

    return ''


print find_int("ab12cd")

実行すると次のようになります。

char='a', result='', is_found=False
char='b', result='', is_found=False
char='1', result='', is_found=False
char='2', result='1', is_found=True
char='c', result='12', is_found=True
12


拙著「コーディングを支える技術」の読者から頂いた質問など対して、こんな感じで補足記事を書いて行きたいと思っています。質問・感想はおきがねなくどうぞ。

この解説は拙著の第3章と第4章の間に新しい章として入るのが適当かなと思います。その章のこの後の話の流れとしては

という感じかな。

拙著に関する他のエントリーは「「コーディングを支える技術」著者公式ページ」からたどれるようにします。

23:28:29

偏った言語信者の垂れ流し

[bash]bashのexecを試す

bashスクリプトでexecを使うと、シェルが実行したコマンドに置き換えられる。

Pythonのスクリプトをシェルスクリプトから実行することが結構あって、プロセスの監視云々とか考えるとexec使ったらいいんじゃないとかどっかで聞いた気がする。

execを使わない場合

以下のようなPythonスクリプトをbashスクリプト経由で実行してみる。

main.py
# coding: utf-8
import time


def main():
    while True:
        time.sleep(1)


if __name__ == '__main__':
    main()
run
#!/bin/bash
python main.py
実行結果
$ ./run
^Z
[1]+  Stopped                 ./run
$ ps aux
(中略)
tokibito 30303  0.0  0.1  12312  1160 pts/1    T    23:42   0:00 /bin/bash ./run
tokibito 30304  0.5  0.5  32172  5304 pts/1    T    23:42   0:00 python main.py

execを使う場合

run
#!/bin/bash
exec python main.py
実行結果
$ ./run
^Z
[1]+  Stopped                 ./run
$ ps aux
(中略)
tokibito 30348  0.1  0.5  32172  5308 pts/1    T    23:47   0:00 python main.py

execを使わない場合は2プロセスになってしまうけど、execを使うと1プロセスで済む。

参考

Man page of BASH

00:01:38

2013-05-09

偏った言語信者の垂れ流し

[Squeak]stファイルの読み込み

昔のファイルを整理していたら、大学時代に書いたコードが出てきたので動かしてみてた。

Worldのメニューから、[open]->[file list]でファイル一覧を開いて、stファイルを選択して[file in]で読み込める。

使い方忘れてるなー。

数年前のコードだけど、Squeak4.3でも問題なく動いてた。トランプのブラックジャックゲーム。

Squeakで簡単なゲームを何か作れって課題だった気がする。

f:id:nullpobug:20130509000133p:image

GUIのところはTextMorphとかを継承してがんばってたっぽい。

00:03:12