2014年9月8日月曜日

Djangoのフォーム


Djangoで同じモデルからModelFormとAdminでCreate画面を作成。

ModelForm

Admin

2014年6月7日土曜日

minichatをpyramidに対応させるための変更点


サーバーをwsgirefからgeventに変更

development.ini

[server:main]でegg:pyramid#wsgirefをegg:minichat#server_factoryに書き換える。


setup.py

requiresにgeventを追加
entrypointに[paste.server_factory]とminichat:server_factoryを追加


__init__.py

server_factory関数を追加


FlaskからPyramidに変更

__init__.py

ルーティングを追加


views.py

@app.routeを@view_configに変更
ここで使用するテンプレートも指定する

view関数の引数をrequestだけにする

matchdictからrouteで指定した変数を取得する

戻り値をテンプレートに渡すdictに変更する

その他の変更点

pcreateを使用したのでその時に作成されたとラバー猿関係の処理も削除しています。

2014年6月6日金曜日

geventのサンプルminichatをpyramidで書いてみた

GeventのチュートリアルにあったFlaskで書かれたminichatをpyramidで書きなおしてみた。

やってみてわかったのはFlaskと比べて、ルーティングとビューの割り当てがわかれていることやルートパターンから変数を取り出すのに、flaskだとそのまま関数の引数になるが、Pyramidだとmatchdictから変数をとり出さないといけず、どうしてもコード量が増える。

minichatのリポジトリ https://bitbucket.org/witten/minichat/

2014年4月4日金曜日

aiohttpを使ってダウンロードする

aiohttpライブラリを使って複数のサイトを並列ダウンロードする。

import asyncio
import aiohttp

@asyncio.coroutine
def download(url):
    response = yield from aiohttp.request('GET', url)
    return (yield from response.read_and_close())

urls = ['http://www.yahoo.co.jp', 'http://www.google.co.jp']
loop = asyncio.get_event_loop()
f = asyncio.wait([download(u) for u in urls])
r = loop.run_until_complete(f)
for i in r[0]:
    print(i.result())

asyncio.waitは複数のコルーチンを1つのFutureにまとめる
asyncio.waitの戻り値は(done, pendding)のタプル
future.doneがTrueの場合はdoneにfutureが格納される。
run_until_completeは引数futureの戻り値(future.result())
なのでr[0]には処理が完了したfutureが格納されており、そのリストのなかのfutureの結果にdownload関数の戻り値が格納されている

2014年3月3日月曜日

Check IO Open Labyrinth

Open Labyrinth

1=壁、0=通路の二次元配列で表された迷路をスタート(1,1)からゴール(10,10)まで移動経路を返す問題。

スタートが迷路の端なので右手法や左手法でもクリアできる。

Check IO roman-numerals

roman-numerals

アラビア数字をローマ数字に置き換える問題。
例えば  10 → Xのようにする。

1桁ずつ変換していけばいいので簡単にできる。

2014年2月26日水曜日

Check IO Xs and Os Referee

Xs and Os Referee
○×ゲームの勝敗を返す。縦と横3列と斜め1列づつをすべて調べれば簡単にできる。
どうやって調べるかが重要になると思う。

Check IO Speech Module

Speech Module

与えられた数値を英単語に変換する問題。
100の位、10の位、1の位それぞれで英単語に変換すればいい。

Check IO Feed Pigeons

Feed Pigeons

餌がなくなるまで鳥を増やしながらループをすれば簡単に解ける問題。

Check IO The Most Wanted Letter

The Most Wanted Letter

渡された文字列から一番使われているアルファベットの小文字を返す。
一番多く使われている文字数が複数ある場合は、アルファベット順が割きのアルファベットを返す。

気をつけないといけないのはcollectionsのCounterを使う場合、most_commmonを使うと文字数が同じ場合にアルファベット順にならない。

2014年2月25日火曜日

Check IO House password

House password

10文字以上で、大文字、小文字、数値をすべて含む文字列の場合、Trueを返す。
この問題は正規表現を使っても解けると思う。

Check IO Median

Median

リストの中の中央値を返す。
リスト長が奇数の場合は中央値を返し、偶数の場合は中央値が2つあるので2つの平均を返す。

Check IO Non-unique Elements

Non-unique Elements

uniqueの逆で重複していない要素をリストから削除する。
リストの中に同じデータが何個あるか調べて、1個しかなかったらリストから削除すればいい。

2014年2月11日火曜日

geventとlxmlを同時に使うとフリーズする

import gevent.monkey
gevent.monkey.patch_socket()
import urllib2
from lxml import html

r = urllib2.urlopen('http://www.yahoo.co.jp')
et = html.parse(r)
上記のようなコードを実行するとhtml.parseで処理が帰ってこずフリーズすることがある。
import gevent.monkey
gevent.monkey.patch_socket()
import urllib2
from lxml import html
from io import StringIO

r = r = StringIO(urllib2.urlopen('http://www.yahoo.co.jp').read().decode('utf-8','replace'))
et = html.parse(r)
urlopenの戻り値を直接使わずにいったんStringIOにデータを格納してからhtml.parseを実行すると、理由はよくわからないがフリーズしなくなる。

2014年2月9日日曜日

web2pyのクエリー

web2pyでtypeがdatetimeなフィールドのyearなどでクエリーを作成する方法でハマった。
#モデル
#db.py
db.define_table('post',
    Field('title'),
    Field('pub_date', 'datetime'),
    format = '%(title)s')

#コントローラー
#default.py
def date():
    rows = db(db.post.pub_date.year == 2014).select()
    return dict(rows=rows)
このようなコードを書いて実行するとdb.post.pub_date.year == 2014がQueryを返さずboolを返していてエラーになっていた。
正しくは
#モデル
#db.py
db.define_table('post',
    Field('title'),
    Field('pub_date', 'datetime'),
    format = '%(title)s')

#コントローラー
#default.py
def date():
    rows = db(db.post.pub_date.year() == 2014).select()
    return dict(rows=rows)
yearではなくyear()にしないとQueryにならなかった。
web2pyは使いやすいがこのへんのドキュメントがないととても困る。

2014年1月30日木曜日

jinja2のcallブロック

callブロックを実行するとcallで指定した関数がキーワード引数"caller"が追加されて呼び出される。

callerの中身は関数で呼び出すとcallブロック内のテキストが取得できる。

戻り値に文字列を設定するとその文字列が出力される。

2014年1月11日土曜日

scrapyではてなブックマークのエントリーを取得する

Scrapyを利用してテクノロジーのホットエントリーを取得する。

Scrapyのインストール

http://doc.scrapy.org/en/0.20/intro/install.htmlを参考にインストールする。
pip install scrapyでインストールする場合lxmlのインストールに失敗する場合は、バイナリーパッケージをインストールした後、pip install scrapy -Iでインストールする。
Ubuntuの場合はhttp://doc.scrapy.org/en/0.20/topics/ubuntu.html#topics-ubuntuを参考にインストールしてもいい。

プロジェクトの作成

チュートリアルを参考にプロジェクトを作成する。

プロジェクトの雛形を作成

scrapy startproject hatena
でプロジェクトの雛形を作成する。

items.pyの更新

hatena/items.pyのHatenaItemクラスを更新して出力するデータ構造を定義する。
今回はtitle,description,user,dateの4つのデータを定義する。


hatena.pyの作成

hatena/hatena/hatena.pyを作成し、ダウンロードするサイトとHTMLからHatenaItemにデータを格納するコードを書く。
今回はテクノロジーのホットエントリーを取得するのでstart_urlsに'http://b.hatena.ne.jp/hotentry/it'を指定する。

HatenaItemにデータを格納

XPathItemLoaderを使用してHatenaItemにデータを格納するため
XPathItemLoderのコンストラクトにitemとselectorを指定する。
selectorだけでなくresponseを指定することもできる。
add_xpathメソッドの引数にHatenaItemのフィールド名とXPathを指定しデータを取得する。XPathで取得したデータが第1引数で指定したアイテムのフィールドに格納される。
load_itemメソッドでItemLoaderからItemを取得する。

プロジェクトを実行する

scrapy crawl hatena
でプロジェクトを実行してスクレイピングを行う。