主にプログラミングに関して。Python, .NET Framework(C#), JavaScript, その他いくらか。
記事にあるサンプルやコードは要検証。使用に際しては責任を負いかねます

IronPython: PythonでExcelマクロ

                
 大量のExcelデータをさばきたいとき、世間でのスタンダードはVBAだ。だけど個人的にWindowsアプリはC#を使っていて、ファイルコピーや削除などの操作はPythonでやってきていて、VBAを使う必要に迫られてこなかった。だからPython書けるならPythonでExcelマクロやっちゃおうと。
参考:http://www.ironpython.info/index.php?title=Interacting_with_Excel
参考と違うところ:コンポーネントオブジェクトモデル(COM)ではなくてグローバルアセンブリキャッシュ(GAC)を使おう

環境: Windows 7(64bit), .NET Framework 4, IronPython 2.7, Office 2007, VS2010

 まずIronPythonのスクリプト上でExcelのワークシートやらセルなどをオブジェクトとして使えるようにするための準備。参考ページで説明しているCOMを使う方法は若干めんどう。
import clr
clr.AddReferenceByName('Microsoft.Office.Interop.Excel, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c')

 バージョン番号が入ったりキートークンなるものも入ってるので、OSやExcelのバージョンが変わったらこの部分がエラー吐きそう。そもそもCOMのラッパーDLLも用意しなければならんはず。それがCOM。
 そこでGACを使う。GACとは?
”共通言語ランタイムがインストールされている各コンピューターには、グローバル アセンブリ キャッシュと呼ばれる、コンピューター全体にわたって使用されるコード キャッシュがあります。 グローバル アセンブリ キャッシュは、そのコンピューター上の複数のアプリケーションで共有するように指定されたアセンブリを格納します”
http://msdn.microsoft.com/ja-jp/library/yf1d93sz(v=vs.110).aspx
ラッパーDLLの用意とかいらない。ExcelのGACは以下のコードで使えるようになる。
import clr
clr.AddReference("Microsoft.Office.Interop.Excel")

色々めんどそうな名前や番号が外れて、Microsoft.Office.Interop.Excelというわりとシンプルな名前だけになった。ちなみにこれで読み込まれるDLLを調べたところ、VS2010を入れている私の環境ではVS2010のインストールディレクトリ下にあった。

 GACを使ってExcelのもろもろをオブジェクトとして使う準備ができた。あとはスクリプト書くだけ。セルにHello Absurd World!の文字を分解してつっこむスクリプトを書いてみた。ついでに保存もしている。
import System
import clr

clr.AddReference("Microsoft.Office.Interop.Excel")
import Microsoft.Office.Interop.Excel as Excel

CURRENT_DIR = System.IO.Directory.GetCurrentDirectory()

ex = Excel.ApplicationClass()
ex.Visible = True
ex.DisplayAlerts = False

#workbook = ex.Workbooks.Open('foo.xls')
workbook = ex.Workbooks.Add(Excel.XlWBATemplate.xlWBATWorksheet)
ws = workbook.Worksheets[1]
row = 1
col = 1
for ch in "Hello Absurd World!":
ws.Cells[row, col] = ch
if ch == " ":
row += 1
col = 1
else:
col += 1

ws.SaveAs(CURRENT_DIR + r"\foo.xls")

1407151402468.png
↑をexcel.pyで保存したとして、プロンプトから"[ironpython path]\ipy.exe excel.py"で実行。
Cells[row, col]でワークシート内のセルにアクセスできるが、rowやcolの値は1から。0からではない。
スポンサーサイト



IronPython: MongoDBを使う

                
 Pythonの.NET Framework開発であるIronPython。pystoneで計測するとCPythonを超えるパフォーマンスを出したりしながらも、.NET Frameworkで用意されたAPIを利用できるので、GUIアプリなどを即席で作ったりするのにけっこう使える。今回はMongoDBをIronPythonからいじってみる。


 CPythonで動かしていたアプリケーションをIronPythonに移そうとしたら、エラーが出て動かなかった。原因はMongoDBに接続するために使っていたPythonモジュールのPyMongo。調べてみるとPyMongoはIronPythonに対応していない。ここで出てくる選択肢は自分で開発するか諦めるか。しかしIronPythonならもう一つの手が出てくる、C#や.NET Framework向けに開発されたドライバ使えばいいじゃない。というわけでIronPythonからMongoDBに接続するためのドライバとしてC# Driverを使う。

 C#コードを参考に、IronPythonでドキュメント(RDBでいうところのレコード)の挿入、検索、削除をやってみる。
http://www.codeproject.com/Articles/273145/Using-MongoDB-with-the-Official-Csharp-Driver
不明瞭なところは公式ドキュメントを参考にしながら。
http://api.mongodb.org/csharp/current/

 ドライバのZIPを落として解凍し、Pythonコードと同じディレクトリにMongoDB.Driver.dllとMongoDB.Bson.dllを置いて、以下のようにコードを書けばMongoDBに接続できる(もちろんMongoDBを立ち上げた状態で)。
import clr
clr.AddReference("MongoDB.Bson")
clr.AddReference("MongoDB.Driver")

import MongoDB.Bson
import MongoDB.Driver


 ここでコーディングを容易にするため、補完機能を使う準備をする(しなくてもいい)。コーディングに使うIDEはSharpDevelop 4.4。Pythonプロジェクトを作成して、プロジェクトウィンドウの参照設定にMongoDB.Driver.dllとMongoDB.Bson.dllを追加。MongoDB.Driver.xmlとMongoDB.Bson.xmlも同じディレクトリにコピーしておく。これで補完機能が効くようになる。
1407021654079.png


 改めて下記のコードを。
import clr
clr.AddReference("MongoDB.Bson")
clr.AddReference("MongoDB.Driver")

import MongoDB.Bson
import MongoDB.Driver

これはDLLファイルへの参照を行ったあとで、その機能が使えるようにするためPythonのいつもどおりのimportを行っている。

 続いてデータベースへの接続をする。MongoDBをローカルで、ポートも初期設定で動かしていれば、とくにパラメータを渡すことなく接続できる。
client = MongoDB.Driver.MongoClient()
server = client.GetServer()
db = server.GetDatabase("test")
collection = db.GetCollection("foos")


 挿入をする。今回用意したC# Driverではドキュメントを、.NET Frameworkのディクショナリで表している。これはIronPythonで用意されているディクショナリを使ってもOK。なのでPythonの辞書型でドキュメントとして保存するデータを書く。
# insertion
for p in xrange(10):
foo = MongoDB.Bson.BsonDocument({"x":p, "y":p})
#foo = MongoDB.Bson.BsonDocument()
#foo["x"] = p
#foo["y"] = p
collection.Insert(foo)


 検索をする。QueryDocumentを使って条件を指定できる。
# no filter query
q = MongoDB.Driver.QueryDocument()
cols = collection.Find(q)
for col in cols:
print "no filter", col

# y==0
q.Add("y", 0)
cols = collection.Find(q)
for col in cols:
print "y==0", col

# y!=0
q = MongoDB.Driver.QueryDocument()
q.Add(MongoDB.Driver.Builders.Query.NE("y", 0))
cols = collection.Find(q)
for col in cols:
print "y!=0", col


 削除する。
collection.RemoveAll()
print collection.Count()


 C#のコードから型指定などを省けば、C#ドライバとして用意されていたものがほぼそのまま使える。
http://docs.mongodb.org/ecosystem/tutorial/getting-started-with-csharp-driver/#getting-started-with-csharp-driver

 というわけでPythonのサードパーティモジュールが使えないような場合においても、C#向け、あるいは.NET Framework向けとされるライブラリを探して使えば抱えていた問題が解決される。意外と使えてしまうIronPython。

IronPython, WPF: Windowsスクリーンショットアプリケーション

                
140613175202.png

 記事をわかりやすく書こうとするとき、説明のためにデスクトップのスクリーンショットが欲しくなることがある。だけどもキーを押してから、イメージエディタを開いて、ペーストして編集しやすい表示倍率に直して、余白とかをトリミングして、リサイズして、ファイル名を与えて、ファイル形式を選択して保存するという一連の手順が面倒でたまにそれをやらなかった。
 ファイル名は重複が起きないように日時を使っていて、形式は文字などがにじまないようにPNGにしている。そのルールで、いちいちイメージエディタを開かずにスクショが得られるようにアプリケーションを書いた。

 アプリケーションを立ち上げたら半透明なウィンドウと、右下にもう一つウィンドウが出てくる。半透明なウィンドウが覆っている領域がそのままスクショの領域になるので、半透明ウィンドウをドラッグして動かしたりウィンドウ右下のThumbをドラッグしてサイズ調整したり。右下のウィンドウでShoot!ボタンを押せばデスクトップに日時がファイル名になったPNG画像が保存される。出力画像の横幅を入力すれば、画像の縦横比がそのままでリサイズされた画像が保存されるし、必要に応じてスクショを任意時間経過後に撮るタイマー機能もある。

確認済み動作環境
.NET Framework 4 on Windows 7
.NET Framework 4.5.1 on Windows 8.1

おもにBoo: ウィンドウズアプリケーションを作るまで

                
http://elicon.blog57.fc2.com/blog-entry-298.html

130826.png


ウィンドウズアプリケーションをおもにBooで作った。技術的なことをざくっとまとめておく。


そもそもBooとは:
 Booとは.NET Framework、もしくはMono上で動作する静的型付けの言語。ゲーム制作で近年Unityが話題になったが、Unityでの開発言語としてC#、JavaScriptに並んでBooが用意されている。基本的に実行速度はC#に遜色ない。
 Pythonと同じくブロックがブレース"{}"でなくインデントで表現されており、コードの視認性が良い。


BooからC#のクラスを使う:
 .NET FrameworkではC#を始め、VB.NET、IronPythonやIronRubyなどのIron系言語など様々な言語が使える。これらのコードは共通中間言語というものにコンパイルされる。共通のものになるということで、相互運用が容易にできるように作られている。C#のクラスを書いてDLLにコンパイルしたら、BooからはDLLを参照に追加して名前空間をインポートすればそれでC#で作成したクラスが使える。


BooからIronPythonのクラスを使う:
 .NET Framework上では異なる言語の相互運用が楽ではあるが、静的型付け言語から動的型付け言語を使う場合はほんのすこしだけ特殊なことをしなければならない。
Boo: コンパイルされたIronPythonモジュールを使う


辞書型オブジェクトのデータ保持のためにYAMLを使う:
 辞書型やリスト型のデータを保存するにはXMLという手段もあるが、YAMLという手段もある。世にあるWebAPIではXML形式が採用されている場合が多い。しかし一般的に言えばヒトからしたらYAMLのほうが見やすいし、編集も容易だろう。YAMLのロードのためにC#ですでに作成されているライブラリを見つけつつ、YAMLの仕様を確認した。
http://www.aaubry.net/page/YamlDotNet-Documentation-Serializing-an-object-graph
http://magazine.rubyist.net/?0009-YAML
http://www.ibm.com/developerworks/jp/xml/library/x-matters23/


COMオブジェクトに用意されているものでオーディオファイルを集める:
WMAやMP3、M4Aのタグ情報の読み込み関数も用意しているクラスがある。
http://elicon.blog57.fc2.com/blog-entry-297.html


非同期UI処理:
UI更新をしているあいだはアプリケーションが入力を受け付けないというのは、のろまに思えて少しばかりいらついてくる。UI更新をしつつ入力受付をさせるため、マルチスレッド処理をしつつ、DispatcherでUIをいじる。
def RenewUI():
pass

uiElement.Dispatcher.Invoke(Action(RenewUI))

http://msdn.microsoft.com/ja-jp/magazine/cc163328.aspx


ウィンドウズインストーラの作成:
http://elicon.blog57.fc2.com/blog-category-8.html

タッチパッド向けメディアプレーヤー for Windows OS

                
130831.png

140304.png

 タッチパッドでも使いやすいようなメディアプレーヤーを考えてみた。小さいボタンは廃止し、ボタンにそれなりのサイズを持たせつつ間隔をあけるなど。あと従来のWindowsMediaPlayerやiTunesなどのプレイヤーにあるような画面遷移がわずらわしかったのでなくした。 アプリケーションには自分の持っているアルバム一覧がでかでかと表示されるので、それをダブルクリックするだけ。それで曲が流れ始め、プレーヤー右側のスペースに収録曲が表示される。

曲は基本的にWindowsMediaPlayerのライブラリから取ってくるようになっている。新しい曲をWindowsMediaPlayerに加えたら、アプリケーション右下の更新ボタンで表示されているアルバム一覧の更新ができる。

動作環境: .NET Framework 4.5以上(Win 8.1、Win 7で動作確認済)

PlaneAudio.zip


曲の読み込みをするフォルダを状況に分けて指定することもできる。PlaneAudio\lib.xmlが初期では以下のようになっている。
<?xml version="1.0" encoding="UTF-8"?>
<dir>
<second>library</second>
</dir>


このファイルに下記のようにフォルダを指定を加えることで(複数フォルダの追加が可能)、曲の読み込み先をライブラリから変更することができる。firstに指定しているフォルダへ一つでもアクセスできない状況だと、secondで指定しているフォルダへ曲を取得しにいく。
<?xml version="1.0" encoding="UTF-8"?>
<dir>
<first>\\other1\music</first>
<first>\\other2\music</first>
<second>library</second>
</dir>

プロフィール

h

Author:h

最新記事
リンク
作ったものなど
月別アーカイブ
カテゴリ
タグリスト

検索フォーム
Amazon