When it’s ready.

出来るまで出来ない

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のメソッドがまとめて書けるようになっている。わかりやすくなっててグッド。

Ustreamer with SocialStream がなんとなく動きかけてきた。

昔はUstreamIRCクライアントですんでたけどどうやら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に問い合せると本家UstreamFQDNが返ってくるのでそれをスプリットしてチャンネル名をゲットする。

以下ソース

#!/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

pitのコンフィグにgdataのエントリーを追加

~/.pit/default.yaml

gdata:
  email: yourID@gmail.com
  password: yourPasswd

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に登録しても正常に動いてくれません、設定方法わかる方いたら是非教えてください。