CraftLaunchからckwでIPythonを実行して、Pythonプログラミングがもっと便利に

IPythonは、Pythonを対話的に実行するためのシェル。
標準のPythonのシェルよりも多機能で強力。

CraftLaunchは、愛用しているキーボードランチャ。
Windowsをキーボード中心で操作している人なら、とっても便利。

ckwはシェルのGUIラッパー。シェルを使いやすく拡張するソフト。
ckwはいくつもの修正版がありますが、「NYAOS.ORG – Where is ckw ?」のすばらしいまとめによると、最新版は「Downloads for deflis’s ckw-mod – GitHub」のようです。

CraftLaunchの設定ファイルに次のように登録することで、CraftLaunchから手軽に、強力なIPythonを、便利なckwで実行できます。

# コマンドを登録する
window.launcher.command_list += [
    …
    ( u"ipython",   window.command_ShellExecute( None, u"C:/Program Files/nyacus/ckw.exe", u'-e "c:\python26\python.exe" "c:\python26\Scripts\ipython"', u"" ) ),
]

Pythonプログラミングがもっと楽しくなりますね。

絵文字変換用Pythonライブラリ emoji-python

このライブラリは、絵文字バイナリと内部タグの変換を行ないます。

  • 絵文字バイナリ => 内部タグ
  • 内部タグ => 絵文字バイナリ

の、双方向の変換をサポートしています。

このライブラリを使うと、携帯電話の絵文字バイナリを含む文字列を扱うことができるようになるようだ。

#絵文字を変換するクラスのインスタンスを生成
import converter = emoji.factory('docomo', 'sjis')
#携帯電話から受け取った絵文字バイナリを含む文字列を 内部タグに変換する
converted_text = converter.convert(input_text)

後で試したい。

Pythonで直積を求める

Pythonで直積を求めるには、Python2.6で導入されたitertools.productを使う。

from itertools import product

Python2.5以前では、ドキュメントに示されているitertools.productと等価の以下のコードを使う。

def product(*args, **kwds):
    pools = map(tuple, args) * kwds.get('repeat', 1)
    result = [[]]
    for pool in pools:
        result = [x+[y] for x in result for y in pool]
    for prod in result:
        yield tuple(prod)

簡単な例

>>> for i in product(('a','b','c'), ('X','Y'), ('1','2')):
...   print i
...
('a', 'X', '1')
('a', 'X', '2')
('a', 'Y', '1')
('a', 'Y', '2')
('b', 'X', '1')
('b', 'X', '2')
('b', 'Y', '1')
('b', 'Y', '2')
('c', 'X', '1')
('c', 'X', '2')
('c', 'Y', '1')
('c', 'Y', '2')

引数のイテラブルが同じ時はrepeatで繰り返し回数を指定できる。

「product((‘1′,’2’), repeat=3)」は「product((‘1′,’2’), (‘1′,’2’), (‘1′,’2’))」と同じ。

>>> for i in product(('1','2'), repeat=3):
...   print i
...
('1', '1', '1')
('1', '1', '2')
('1', '2', '1')
('1', '2', '2')
('2', '1', '1')
('2', '1', '2')
('2', '2', '1')
('2', '2', '2')

Pythonの実行環境の情報を取得する

Pythonの実行環境の情報を取得する方法。

OSの名前

>>> os.name
'nt'

プラットフォーム

>>> sys.platform
'win32'

Pythonインタープリターのバージョン

>>> sys.version
'2.5.4 (r254:67916, Dec 23 2008, 15:10:54) [MSC v.1310 32 bit (Intel)]'

Pythonのバージョン番号

>>> sys.version_info
(2, 5, 4, 'final', 0)

Windowsのバージョン

>>> sys.getwindowsversion()
(5, 0, 2195, 2, 'Service Pack 4')

デフォルトエンコーディング名

>>> sys.getdefaultencoding()
'ascii'

ファイル名のエンコーディング名

>>> sys.getfilesystemencoding()
'mbcs'

参考

Pythonで辞書(dictionary)のループ

辞書(dictionary)のキーでループ

>>> d = dict(a='aa', b='bb', c='cc')
>>> for key in d:
...    print key

辞書(dictionary)のキーと値でループ

>>> d = dict(a='aa', b='bb', c='cc')
>>> for key, value in d.iteritems():
...   print key, value

辞書(dictionary)のiteritems()は、(key, value) ペアのイテレータを返します。

辞書(dictionary)の値でループ

>>> d = dict(a='aa', b='bb', c='cc')
>>> for value in d.itervalues():
...   print value

辞書(dictionary)のitervalues()は、値列のイテレータを返します

追記

辞書の次の2つの書き方はどちらも同じ意味です。

d = dict(a='aa', b='bb', c='cc')
d = {'a':'aa', 'b':'bb', 'c':'cc'}

dict(…)を使うと、キーとなる文字列をクォーテーションで囲まなくてもよく、ソースコードがシンプルになります。

KayのRESTfull APIでデータを追加する

Google App Engine用フレームワークKayを使ったWebアプリケーションに、RESTfull APIを使ってデータを追加する方法を紹介します。

最初に、Kayを使ったWebアプリケーションを作成して、RESTfull APIを使用できるように設定します。

今回の例では、myapp.models.MyModelをRESTfull APIで操作できるようにします。

myapp/models.py

from google.appengine.ext import db

class MyModel(db.Model):
    user_name = db.StringProperty()
    message = db.TextProperty()

myapp/urls.py

from kay.generics.rest import RESTViewGroup

class MyRESTViewGroup(RESTViewGroup):
    models = ['myapp.models.MyModel']

view_groups = [
    MyRESTViewGroup(),
    ViewGroup(
        Rule('/', endpoint='index', view='myapp.views.index'),
    )
]

開発サーバーを起動します。

python manage.py runserver

このWebアプリケーションからRESTfull APIでMyModelの情報を取得するのは簡単です。

MyModelの一覧を取得するコード

# -*- coding: utf-8 -*-
import urllib2
res = urllib2.urlopen('http://localhost:8080/rest/MyModel')
print res.code #=> 200
print res.msg #=> OK
print res.read() #=> MyModelの一覧データ

MyModelの特定のデータを取得するコード

# -*- coding: utf-8 -*-
import urllib2
key = … #モデルのキー
res = urllib2.urlopen('http://localhost:8080/rest/MyModel/%s' % key)
print res.code #=> 200
print res.msg #=> OK
print res.read() #=> モデルのデータ

WebアプリケーションのMyModelに新しいデータを登録します。

データを登録するときのURLは一覧取得の時と同じですが、GETではなくPOSTで送信します。

# -*- coding: utf-8 -*-
import urllib2
req = urllib2.Request('http://localhost:8080/rest/MyModel')

データを登録するには、登録するデータをXML形式で送信します。

xml = '<?xml version="1.0" encoding="UTF-8"?><MyModel><user_name>test</user_name><message>テスト</message></MyModel>'
req.add_data(xml)

リクエストのヘッダにContent-Typeを設定する必要があります。

req.add_header('Content-Type', 'application/xml')

準備が出来たらリクエストを送信します。
登録に成功したら、登録したモデルのキーが返ります。

res = urllib2.urlopen(req)
print res.code #=> 200
print res.msg #=> OK
print res.read() #=> 登録したモデルのキー

登録処理の全体のソースコードは次のようになります。

# -*- coding: utf-8 -*-
import urllib2

req = urllib2.Request('http://localhost:8080/rest/MyModel')

#Content-Typeの設定が必要
req.add_header('Content-Type', 'application/xml')

#登録するデータをXML形式で設定する
xml = '<?xml version="1.0" encoding="UTF-8"?><MyModel><user_name>test</user_name><message>テスト</message></MyModel>'
req.add_data(xml)

res = urllib2.urlopen(req)

print res.code #=> 200
print res.msg #=> OK
print res.read() #=> 登録したモデルのキー

関連ページ

Google App Engine(Python)で動的にCSVファイルを作成してダウンロードさせる

Google App Engine(Python)で動的にCSVファイルを作成してダウンロードさせる方法。

今回の例ではGoogle App Engine用フレームワークKayを使用しています。

CSVファイルを作成するにはcsvモジュールのWriterオブジェクトを使用します。

import csv
…
writer = csv.writer(data)

Writerオブジェクトのコンストラクタの最初の引数は、ファイルライクなオブジェクトをとります。
ここではStringIOを使用します。

import StringIO
data = StringIO.StringIO()

csvファイルのデータは、Writerオブジェクトのwriterow()で書き込みます。
引数には、行データ(バイト列)の配列をとります。
ユニコード文字列はencode()でバイト列にエンコードします。

writer.writerow([u'5560005'.encode('utf-8'), u'大阪府大阪市浪速区日本橋'.encode('utf-8')])
writer.writerow([u'5560006'.encode('utf-8'), u'大阪府大阪市浪速区日本橋東'.encode('utf-8')])
writer.writerow([u'5560004'.encode('utf-8'), u'大阪府大阪市浪速区日本橋西'.encode('utf-8')])

ブラウザでダウンロードさせるには、ヘッダの’Content-Type’に’application/octet-stream’を指定します。

header = Headers()
header.add('Content-Type', 'application/octet-stream');

ヘッダの’Content-Disposition’で、ダウンロードさせるCSVファイルのファイル名をで指定します。

header.add('Content-Disposition', 'attachment', filename='sample.csv')

全体のソースコードは以下のようになります。

views.py

def index(request):
  import csv
  import StringIO
  from werkzeug.datastructures import Headers
  from werkzeug import Response

  data = StringIO.StringIO()
  writer = csv.writer(data)
  writer.writerow([u'5560005'.encode('utf-8'), u'大阪府大阪市浪速区日本橋'.encode('utf-8')])
  writer.writerow([u'5560006'.encode('utf-8'), u'大阪府大阪市浪速区日本橋東'.encode('utf-8')])
  writer.writerow([u'5560004'.encode('utf-8'), u'大阪府大阪市浪速区日本橋西'.encode('utf-8')])

  header = Headers()
  header.add('Content-Type', 'application/octet-stream');
  header.add('Content-Disposition', 'attachment', filename='sample.csv')
  return Response(data.getvalue(), headers=header)

###関連ページ

Google App Engine(Python)用フレームワークKayを使い、動的にExcelファイルを作成してZIP形式で圧縮しダウンロードさせる

Google App Engine(Python)用フレームワークKayを使い、動的にExcelファイルを作成してZIP形式で圧縮しダウンロードさせる方法。

Google App Engine(Python)用フレームワークKayを使い、動的にZIP形式で圧縮してダウンロードさせる」と「Google App Engine用フレームワークKayでExcelファイルをダウンロードさせる」の合わせ技になります。

Excelファイルの作成には、xlwtを使用します。
xlwtはpure pythonなので、Google App Engineで使用することが出来ます。

xlwtからソースをダウンロードして展開します。
xlwtフォルダーをKayのプロジェクトのルートフォルダーにコピーします。
xlwtフォルダー中のdocフォルダーやexamplesフォルダーは不要です

次のようなフォルダー構成になります。

myproject/
 ├ kay/
 ├ myapp/
 └ xlwt/

xlwtでExcelデータを作成します。

wb = xlwt.Workbook()
ws1 = wb.add_sheet('Sheet1')
ws1.write(0, 0, u'セル:A1')
ws1.write(1, 0, u'セル:A2')
ws1.write(0, 1, u'セル:B1')
ws1.write(1, 1, u'セル:B2')
data = StringIO.StringIO()
wb.save(data)

xlwt.save()は引数にファイルライクなオブジェクトをとります。
引数に指定したオブジェクトにExcelデータが書き込まれます。

ZipFileオブジェクトを作成します。

ZipFileオブジェクトのコンストラクタの1番目の引数にファイルライクなオブジェクトを指定します。
引数に指定したファイルライクなオブジェクトに、ZIPデータが書き込まれます。

zipdata = StringIO.StringIO()
zipobj =  zipfile.ZipFile(zipdata, 'w', zipfile.ZIP_DEFLATED)

ZipFileオブジェクトにファイルを登録します。
1番目の引数にファイル名を、2番目の引数にファイルのデータ(バイト列)を指定します。

zipobj.writestr('example.xls', data.getvalue())

ここで、1番目の引数にZipInfoオブジェクトを指定すると、ファイルの情報を細かく設定することが出来ます。

最後に閉じます。

zipobj.close()

以上で、ZIPデータを作成できました。

作成したZIPデータをダウンロードさせるために、HTTPヘッダの設定を行います。

header = Headers()
header.add('Content-Type', 'application/octet-stream');
header.add('Content-Disposition', 'attachment', filename='foo.zip')

最後に、ZIPデータをレスポンスとして返します。

return Response(zipdata.getvalue(), headers=header)

全体のソースコードは以下のようになります。

def index(request):
    import xlwt
    import StringIO
    import zipfile
    from werkzeug.datastructures import Headers
    from werkzeug import Response

    wb = xlwt.Workbook()
    ws1 = wb.add_sheet('Sheet1')
    ws1.write(0, 0, u'セル:A1')
    ws1.write(1, 0, u'セル:A2')
    ws1.write(0, 1, u'セル:B1')
    ws1.write(1, 1, u'セル:B2')
    data = StringIO.StringIO()
    wb.save(data)

    zipdata = StringIO.StringIO()
    zipobj =  zipfile.ZipFile(zipdata, 'w', zipfile.ZIP_DEFLATED)
    zipobj.writestr('example.xls', data.getvalue())
    zipobj.close()

    header = Headers()
    header.add('Content-Type', 'application/octet-stream');
    header.add('Content-Disposition', 'attachment', filename='foo.zip')
    return Response(zipdata.getvalue(), headers=header)

関連ページ

Google App Engine(Python)用フレームワークKayを使い、動的にZIP形式で圧縮してダウンロードさせる

Google App Engine(Python)用フレームワークKayを使い、動的にZIP形式で圧縮してダウンロードさせる方法。

フレームワークにKayを使用していますが、処理の内容はKayに依存しません。
webappやDjangoでも同様の処理は可能です。

まず、ZIPファイルに登録するファイルのデータ(バイト列)を作成します。

# example.htmlの内容
data = '<html><body><p>Hello, world!</p></body></html>'

ZipFileオブジェクトを作成します。

ZipFileオブジェクトのコンストラクタの1番目の引数にファイルライクなオブジェクトを指定します。
引数に指定したファイルライクなオブジェクトに、ZIPデータが書き込まれます。

zipdata = StringIO.StringIO()
zipobj =  zipfile.ZipFile(zipdata, 'w', zipfile.ZIP_DEFLATED)

ZipFileオブジェクトにファイルを登録します。
1番目の引数にファイル名を、2番目の引数にファイルのデータ(バイト列)を指定します。

zipobj.writestr('example.html', data)

ここで、1番目の引数にZipInfoオブジェクトを指定すると、ファイルの情報を細かく設定することが出来ます。

最後に閉じます。

zipobj.close()

以上で、ZIPデータを作成できました。

作成したZIPデータをダウンロードさせるために、HTTPヘッダの設定を行います。

header = Headers()
header.add('Content-Type', 'application/octet-stream');
header.add('Content-Disposition', 'attachment', filename='foo.zip')

最後に、ZIPデータをレスポンスとして返します。

return Response(zipdata.getvalue(), headers=header)

全体のソースコードは以下のようになります。

def index(request):
    import StringIO
    import zipfile
    from werkzeug.datastructures import Headers
    from werkzeug import Response

    # example.htmlの内容
    data = '<html><body><p>Hello, world!</p></body></html>'

    # ZIPデータの作成
    zipdata = StringIO.StringIO()
    zipobj =  zipfile.ZipFile(zipdata, 'w', zipfile.ZIP_DEFLATED)
    zipobj.writestr('example.html', data)
    zipobj.close()

    # データを返す
    header = Headers()
    header.add('Content-Type', 'application/octet-stream');
    header.add('Content-Disposition', 'attachment', filename='foo.zip')
    return Response(zipdata.getvalue(), headers=header)

関連ページ

Pythonでサブフォルダー削除する

Pythonでサブフォルダーごと削除する方法。

  1. os.removedirs()を使う

    os.removedirs()はサブフォルダーも再帰的に削除してくれます。
    ただし、フォルダー内にファイルがあると削除に失敗します。

    import os
    os.removedirs(path)
    
  2. shutil.rmtree()を使う

    shutil.rmtree()は、フォルダー内にファイルがあってもフォルダーを削除します。

    import shutil
    shutil.rmtree(path)