GW Hackathonに参加した
黄金週間になぜかハッカソン
会場だった部屋がお喋り禁だったので、Lingrでコミュニケーションをとりながらの作業となった。話せないけどむしろコード片や画像が張り付けられるのでとても便利と再確認。
Django-jaや最近だとKay−jaなんてあるといいなぁとか・・・
知らないモジュールを調べるコマンド dir()を便利に改変 dir2
python標準のdir関数は、引数オブジェクトの内部関数か変数をリストで返してくれる。自分で作ってないやつだからわざわざdirで調べているのに、実際表示されるのは名前のみでそれが関数なのか変数なのかは分からない。
そこでメソッドなのか変数なのかを返してくれるdir2をアオダグ先生が素敵なLC作ってくれた。
>>> dir2 = lambda y:[x + ("*" if callable(getattr(y, x)) else "") for x in dir(y)] >>> import datetime >>> dir2(datetime) ['MAXYEAR', 'MINYEAR', '__doc__', '__file__', '__name__', 'date*', 'datetime*', 'datetime_CAPI', 'time*', 'timedelta*', 'tzinfo*']
こんな感じで、メソッドには*がつくようになった。
これは便利かもしれない。
AppEngine フレームワーク Kayのディスパッチと戯れる
KayのVer.0.10代をpullしてきて使っている。今日の段階では、ドキュメントの内容やurlsの内容が新旧二つの記述方法が並列されている。慣れていないので初め何が何だか分からなかったが、コメントアウトされているのが旧方式で、下のほうに書いてるのが新方式なようだ。
from kay.routing import ( ViewGroup, Rule ) view_groups = [ ViewGroup(Rule('/', endpoint='index', view='multiview.views.index')), ViewGroup(Rule('/hoge', endpoint='hoge', view='multiview.views.hoge')), ViewGroup(Rule('/ustForm/', endpoint='ustDataForm', view='multiview.views.ustDataForm')), ViewGroup(Rule('/ustForm/<chName>', endpoint='ustDataForm', view='multiview.views.ustDataForm')), ]
新方式だと、一行でURL、エンドポイント、Viewsのメソッドがまとめて書けるようになっている。わかりやすくなっててグッド。
easy_installでモジュールを解凍でインストールするやつ
いっっっっっっっっっっっっっっも忘れるのでめも
hgをアップデートしながら解凍でインストールする場合
easy_install -UZ mercurial
Ustreamer with SocialStream がなんとなく動きかけてきた。
昔はUstream+IRCクライアントですんでたけどどうやらSocialStreamと一緒に見た方がUstは楽しめるのでSocialStreamをインプリしてみた。力量不足でUstreamAPIからSocialStreamのエンベデットを抜き取ることが出来ない。今のところマニュアルでSocialStreamのタグを指定している(ダサすぎる・・)
http://ustview.appspot.com/multi
ボケボケだけど、ようつべに使ってるところを上げてみた。大きさを変えるスライダーもjQueryUI化してみた。
リクエストが有れば @atusi まで教えてください。
日本語のUstのチャンネルを3分間隔でひたすら取得してるんだけどとうやってランキング化して表示させるか考え中
GoogleAppEngine上で、短縮URLを展開する方法
Twitter上のUstreamのアドレスは短縮URLが使われているので展開する必要がある。
GAE上で上手くurllibが使えないのでurlfetchで行う
def expandUrl(url): req = urlfetch.fetch(url) ret = req.final_url return ret
これだけ、"final_url"に転送後のURLが入っているのでそれを使うことで取得出来た。
URLの展開で30秒の壁を超えるのでTaskQueueを使って避ける
TwitterのFeedからUstreamの短縮URLを抜いてきた後、展開するんだけど15個くらい展開するので1分弱かかる時がある。ほぼ確実に30秒を超えるので1展開毎にTaskQueueに登録する
class ExpandUrlHandler(webapp.RequestHandler): def get(self): feedUrl = "http://search.twitter.com/search.atom?lang=ja&q=ustre" atom = feedparser.parse(feedUrl) res = "" for i in atom.entries: m = re.search(r"http\:\/\/ustre.am\/[a-z|A-Z|0-9|:]*", i.description) res += "%s<br>"%(m.group()) taskqueue.add(url='/addMapWorker', params={'url': m.group()}) self.response.out.write(res) class ExpandUrlWorker(webapp.RequestHandler): def post(self): url = self.request.get('url') longURL = expandUrl(url) saveUrlMap(url, longURL)
Ustreamの現在の放送状況をTwitterのサーチ結果から取得しチャンネル名を特定する
Ustreamのサーチには、言語指定がない。どれくらい人気があるかは取れるが英語のチャンネルだらけ。
日本の方が大勢みているチャンネルをMultiUstreamViewer(http://ustview.appspot.com/multi)で利用するためにスクリプトを書いてみた。
GAE上ではたぶん動かないと思う。必要なのは、feedparserモジュール
Twitterのサーチを使って、TL上のUst短縮URLをひっかけてAtomをもらってくる。
http://search.twitter.com/search.atom?lang=ja&q=ustre Twitterサーチは言語指定が出来るので日本語を指定しておく。
あとは、feedparserでdescription抽出して本文中のUst短縮URLをゲットする。urllib2でustre.amに問い合せると本家UstreamのFQDNが返ってくるのでそれをスプリットしてチャンネル名をゲットする。
以下ソース
#!/usr/bin/env python # coding:utf-8 import feedparser, urllib2 import re def expandUrl(url): req = urllib2.urlopen(url) ret = req.geturl() return ret def main(): feedUrl = "http://search.twitter.com/search.atom?lang=ja&q=ustre" atom = feedparser.parse(feedUrl) for i in atom.entries: m = re.search(r"http\:\/\/ustre.am\/[a-z|A-Z|0-9|:]*", i.description) print "shortUrl: %s"%m.group() realUrl = expandUrl(m.group()) print "realUrl: %s"%realUrl print "channel: %s"%realUrl.split('/')[-1] print '-' * 80 if __name__ == '__main__': main()
実行結果
shortUrl: http://ustre.am/8VsV realUrl: http://www.ustream.tv/channel/zonbi channel: zonbi -------------------------------------------------------------------------------- shortUrl: http://ustre.am/epC7 realUrl: http://www.ustream.tv/channel/broadcast-life channel: broadcast-life -------------------------------------------------------------------------------- shortUrl: http://ustre.am/epC7 realUrl: http://www.ustream.tv/channel/broadcast-life channel: broadcast-life -------------------------------------------------------------------------------- shortUrl: http://ustre.am/foPp realUrl: http://www.ustream.tv/channel/ugtktv channel: ugtktv -------------------------------------------------------------------------------- shortUrl: http://ustre.am/epC7 realUrl: http://www.ustream.tv/channel/broadcast-life channel: broadcast-life -------------------------------------------------------------------------------- shortUrl: http://ustre.am/dmuc realUrl: http://www.ustream.tv/channel/radionion channel: radionion -------------------------------------------------------------------------------- shortUrl: http://ustre.am/dtJp realUrl: http://www.ustream.tv/channel/throughtone channel: throughtone -------------------------------------------------------------------------------- shortUrl: http://ustre.am/8VsV realUrl: http://www.ustream.tv/channel/zonbi channel: zonbi -------------------------------------------------------------------------------- shortUrl: http://ustre.am/eOlX realUrl: http://www.ustream.tv/channel/solchibirecords channel: solchibirecords -------------------------------------------------------------------------------- shortUrl: http://ustre.am/c1ZR realUrl: http://www.ustream.tv/channel/bside channel: bside -------------------------------------------------------------------------------- shortUrl: http://ustre.am/HiO realUrl: http://www.ustream.tv/channel/crakka channel: crakka -------------------------------------------------------------------------------- shortUrl: http://ustre.am/9Quu realUrl: http://www.ustream.tv/channel/dj-taro-live-show channel: dj-taro-live-show -------------------------------------------------------------------------------- shortUrl: http://ustre.am/4V2S realUrl: http://www.ustream.tv/channel/mazdabeam channel: mazdabeam -------------------------------------------------------------------------------- shortUrl: http://ustre.am/9Quu realUrl: http://www.ustream.tv/channel/dj-taro-live-show channel: dj-taro-live-show -------------------------------------------------------------------------------- shortUrl: http://ustre.am/cBDN realUrl: http://www.ustream.tv/channel/h2ospace-php channel: h2ospace-php --------------------------------------------------------------------------------
URL展開を待っているせいか意外と時間がかかる。
この結果をMultiUstreamViewer(http://ustview.appspot.com/multi)に組み込めばおしまい。
osx10.6でPyQt4のセットアップ
OS標準のPython2.6を使って、Qt4.7を利用できる環境を構築する。
なにげに日本語のQtフォーラム(http://qtusersforum.s2.zmx.jp/forum/index.php)とかあって、使い易いかも知れないと妄想に駆られている。
必要なもの
インストール
Qt4 > SIP > PyQt4 の順番で入れた。
Qt4はインストーラーがあるのでそれで入れる。
SIPは回答した後、configure.py > make > sudo make install
今回は、QT用にmkvirtualenvしてなるべくOSの環境を汚さないしたかったけど、色々OSにも入ったみたい。
# SIP解凍した階層まで降りる (sip-4.10)
python configure.py --use-arch=i386
make
sudo make install
PyQt4もconfigure.py > make > sudo make install
# PyQt4解凍した階層まで降りる(PyQt-mac-gpl-4.7)
python configure.py
make
make install
PyQt4のコンパイルにかなーり時間がかかった。
これで、QtDsignerをじっくり障れるようになれますように・・・
Pythonリスト内包表記文法 低速マスター
リスト内包表記(LC)使った方が圧倒的にコードが読みやすく、短くなる。慣れてないという理由で使われてない気がするので今後の自分のためにも、メモを残す。
LCは基本的に、ListやHashを処理する際に使用される。例えば、規則性のある並びのListが欲しい時などに利用すると良い。
1, 基礎
リストの作成
forの前が処理、forからList名までがひとつのforの段落で前から評価される。
src_list = [1,2,3,4,5] print [x for x in src_list] # [1,2,3,4,5]
リストの作成2
for部で取り出された要素が、その後ろif部で評価され真だったものだけが、初めのx*2に渡され処理される(この場合は、2.4だけ)
src_list = [1,2,3,4,5] print [x*2 for x in src_list if x % 2 == 0] # [4,8]
リストの作成3
一つ目のforで取り出されたlistが二つ目のforに渡され展開された結果が、先頭の処理部分に渡される。
X = [[10, 20], [11, 21], [12, 22], [13, 23], [14, 24], [15, 25], [16, 26], [17, 27], [18, 28], [19, 29]] [i for ii in X for i in ii] # [10, 20, 11, 21, 12, 22, 13, 23, 14, 24, 15, 25, 16, 26, 17, 27, 18, 28, 19, 29]
2,応用
渡された文字列を4文字ずつリストに分けなさい
s = 'abcdefghijklmnopqrstuvwxyz' [s[i:i+4] for i in range(0, len(s), 4)] # ['abcd', 'efgh', 'ijkl', 'mnop', 'qrst', 'uvwx', 'yz'] #4文字だけ欲しい場合は [s[i:i+4] for i in range(0, len(s), 4) if len(s[i:i+4]) == 4] # ['abcd', 'efgh', 'ijkl', 'mnop', 'qrst', 'uvwx']
要素二つのListAのList、Xがあります。ListAの前後を入れ替えなさい。
X = [[10, 20], [11, 21], [12, 22], [13, 23], [14, 24], [15, 25], [16, 26], [17, 27], [18, 28], [19, 29]] [[x[1], x[0]] for x in X] # [[20, 10], [21, 11], [22, 12], [23, 13], [24, 14], [25, 15], [26, 16], [27, 17], [28, 18], [29, 19]]
追記、こんなのも出来る
ビンゴカードプログラム、5x5の配列で各行には1-75の数字を15きざみでランダムに格納する
import random [(lambda xs: random.shuffle(xs) or xs)(xs)[0:5] for xs in [range(1,76)[i:][:15] for i in range(0,75,15)]] # [[13, 1, 7, 8, 9], [30, 16, 22, 21, 25], [42, 36, 33, 35, 31], [50, 47, 60, 52, 49], [65, 67, 72, 75, 63]]
配列を返さなくても必要なだけ処理をさせる時にもforを書かずに済ませられる
0.2秒ずつ停止を10回繰り返す(トータル2秒停止する)
from time import sleep [sleep(0.2) or x for x in range(10)] #2秒停止したのち #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
例題を考えるのがムズイ
FizzBuzかけるのかな?
追記:id:surgoさまよりFizzBuzzの解答例を教えてもらいました。ありがとうございます。
[(i%3==0 and 1 or 0)*"Fizz"+(i%5==0 and 1 or 0)*"Buzz" or i for i in range(1, 100)]
最後列のifをどう組むかをどうするのか考えていたのですがこの方法は、リターンされた文字をもとにどう返すのか決めています。このやり方はいろんなところで使えそう。
if hoge else foo みたいな処理をさせるにはどうすれば良いんだろ?
良くやりそうなforの処理は、40%くらいLCで書き直せそう。
Pythonで自動化、GoogleDocsのSpreadSheetを使ったディスク使用量モニタースクリプト
気づいたらDiskの残量がメチャ減ってるときってありますよね。Nagiosとか監視ツール使って閾値超えたら警告出すとかやってる人も居るかと思います。監視ツールはエラーの発生はログ取りするけど、日々の使用料を記録して見やすくなってないのが大気がします。大きめのファイルサーバ使っていると、今後の容量計画を行う場合は現状把握が大切です。各ドライブごとにどれくらいの容量増加傾向があるのかを知るためには、監視ツールのみだとやや物足りない感じがします。
ログる内容は、dfコマンドで表示出来る分で十分なのでコレを毎日ダンプし続けると良いかもしれないですが、やっぱり結果はグラフで見たいし、いつも最新の状態が見たいですよね。さらにグラフは、画像ファイルとかでサクっとウェブで見えたりしたらさらに便利
ということで、こんなの作ってみました。
dfで見えるようにドライブをマウントしておいて、dfコマンで出る各パラメータを日時とともにDocsのスプレッドシートに記録するPythonスクリプトです。また、各パラメータは、別々のシートに記録してグラフ化した際に見やすいようにしてあります。
virtualenv環境で各モジュールをインストール
virtualenvwrapperをインストールして、mkvirtualenvしました。
今回の環境名は、"gdata"にしました。
easy_install virtualenv easy_install virtualenvwrapper mkvirtualenv gdata
- gdata
- pit
- easy_installで入れた
Docs上でスプレッドシートを作成
スクリプトでは、ファイルがある前提でアクセスするので事前にスプレッドシートを作成しておきます。名前は、スクリプト内で変更可能です。デフォルトでの名前は
- スプレッドシート ファイル名
- MacBookDisk
- シート名(小文字アルファベットのみ推奨)
- all
- use
- available
- percent
- 各シートの1列目項目(英数小文字のみ、マウント名は変更してください)
- date
- media
- public
こんなスプレッドシートが出来るはず(イメージはすでにデータが入っている状態)
スクリプト
pythonファイル
df2docs.py
#!/bin/env python #encoding:utf-8 import os from pit import Pit import gdata.spreadsheet.text_db import subprocess import datetime os.environ['PATH'] = "/bin:/usr/bin" cwd = "/" cmdline = 'df -m' ################################################################## ### Settings # Google Docsで作成されるスプレッドシートファイル名 FILE_NAME='MacBookDisk' # スプレッドシートで作成されるシート名 TABLE_NAME = ['all', 'use', 'available', 'percent'] # 監視したいマウントポイントとそのラベル名 ELEM_TABLE = {'/Volumes/Media':'media', '/Volumes/Public':'public'} ################################################################### account = Pit.get('gdata') p = subprocess.Popen(cmdline,shell=True,cwd=cwd, stdin = subprocess.PIPE,stdout = subprocess.PIPE, stderr = subprocess.PIPE, close_fds = True) (stdouterr, stdin) = (p.stdout, p.stdin) res = [i.strip().split() for i in stdouterr.readlines()] elm, all, use, ava, per = [], [], [], [], [] for d in res[5:7]: elm.append(ELEM_TABLE[d[5]]) all.append(d[1]) use.append(d[2]) ava.append(d[3]) per.append(d[4]) dflist = [elm, all, use, ava, per] date = datetime.datetime.today().strftime('%Y/%m/%d/%H:%M') print dflist client = gdata.spreadsheet.text_db.DatabaseClient( username=account['email'], password=account['password']) db = client.GetDatabases(name=FILE_NAME)[0] for tname in TABLE_NAME: table = db.GetTables(name=tname)[0] idx = TABLE_NAME.index(tname) + 1 table.AddRecord({'date':date, dflist[0][0]:dflist[idx][0], dflist[0][1]:dflist[idx][1], }) print 'status: Sheet "%s" OK'%(tname)
このPythonスクリプトを呼ぶshell
df_upload.sh
#/bin/bash source ~/.virtualenvwrapperrc workon gdata python ~/local/bin/df2docs.py
実行する
% ./df_upload.sh /Users/atusi/Dropbox/repos/dotFile/.virtualenvs/gdata/lib/python2.6/site-packages/gdata/tlslite/utils/cryptomath.py:9: DeprecationWarning: the sha module is deprecated; use the hashlib module instead import sha status: Sheet "all" OK status: Sheet "use" OK status: Sheet "available" OK status: Sheet "percent" OK
起動スクリプトがないと、毎回workonしするはめになるので作成しました。あとは記録したいときに、df_upload.shを実行するだけで実行時のディスクの使用量や残容量がシート別に各マウント分記録されます。実行しているのがPython2.6のためhashlib使いなさいと起こられますが、結果には影響ないみたい。cryptmath.pyをいじれば良いかと思います。>from hashlib import sha1 as sha にするとか
あとは、Docsの機能でグラフを作成しておけばデータがアップされる度に更新されてハッピー。
こんなふうになりました。サンプリング数とドライブが少ないのでショボーンですが・・・
cronで動かしたい
起動シェルをcronで動かす予定だったけど、なぜかcronに登録しても正常に動いてくれません、設定方法わかる方いたら是非教えてください。