カテゴリー: (別ブログのアーカイブ)

ちょっと中断します

昨年夏以来、全然このブログを更新できない日々が続いています。

正直、Pythonをやる勢いもなくなってきている今、仕事も忙しくなってきたこともあるので、ちょっとこのMKの制作自体を中断したいと思います。もしかしたらJavaで再開するかもしれないし、違うかたちにするかもしれません。

かならず何かしらの形で再開したいとは思っていますが、とりあえず、ご報告まで。

広告

きっかけ

“だれかのMKを見て、「仕事で失敗してへこんでたけど、ちょっと気が楽になったな」と思えたり、「よし、明日もちょっとがんばってみるか」と思えたりするかもしれない。もしかしたら、目からウロコが落ちるようなこともあるかもしれない。”

“みなのMKがたくさん集まっていく中で、新しい何かが生まれるかもしれない。”

f:id:junya-hosono:20090826132556j:image:left:w150

きっかけは、数日前に「ブログになにをかこうか」と項目をあげていたときになんとなく感じた、そんな思いでした。

とっておきのMKを持っている人は、実は、他の人に自分のMKを見せてどう思うかを聞きたいんじゃないかな。「うわ!すごい!」って思って共感してもらえたらすごくうれしいんじゃないかな、とも思ったんです。

有名人のMKを集めているサイトはいくつもあるけれど、それって本当に共感できるんだろうか。もちろんいいMKはたくさんあるし、私の好きなものもたくさんあるけれど、有名人でもなんでもない、普通に暮らしている私たちだって、みな自分なりのMKをひとつやふたつ持ってるはず。

自分が思いついたこともあれば、先生や先輩から教わったものかもしれないし、有名人のものを見ていつのまにか「自分が思いついた」と思いこんでいるものもあるかもしれない、でもそれでもいいんじゃないか。それがそのひとにとってのMKなら。

早く思いついたから、多く知ってるから、もっと言うと、オリジナルだからって、えらいわけじゃない。そのMKが、その人のそのときの気持ちにどれだけストレートにつながれるか、それが大事だと思うんです。

例えば、よくあるサクセスストーリーでも、あまりにすごい人のストーリーって、「すごいなぁ」とは思うけれど、それはある意味特殊であって「自分にも同じことができるかな?」と考えると、ちょっと厳しいですよね。

それと同じように、有名人のMKではなくて、普通の人の生活から生まれてくるMKであっても、共感できるんじゃないだろうか、と思います。

でも、普通の人のMKを集約・共有できる仕組みって、実はあまりないんじゃないだろうか。

そのとき、昔だれかに聞いた言葉を思い出しました。

「ないものは、作れ」

というわけで、この「MKを集約・共有するウェブサービス」を作ってみるプロジェクトを開始したのです。

(この記事を書いていて、「これだけ書くとMKのことがわかっちゃうかもなぁ」とも思いましたが、別にそれでもいいか、とも思ってます。この出発点の考えというか想いを、後出しじゃなくて、いま出しておこう、残しておこうと思ったので)

初心者によるPython勘所メモ

この記事は、Python初心者である私が『みんなのPython 改訂版』を読み進める中で、「お、Pythonてこんなことができるんだ」と思ったことを蓄積・随時更新していきたいと思います。

ちなみに、これまでに(業務・私用含めてですが)C、C++、Java、VBA(EXCEL,ACCESS)、PASCAL、PHP、PowerBuilder(windows上のGUI開発ツール)、昔懐かしいX68000でのアセンブラ、それとPerlをちょっと、といった程度にはプログラミング言語を使ってきました(もちろん、今となってはほとんど覚えていない言語もありますが…)。

他の言語でもできるようなことをひとおとりまとめる、というようなことは、Python リファレンスマニュアルや他にも優秀なサイトさんがたくさんありますのでそちらにまかせて、あくまで独断と偏見でということです。自分へのリマインドの意味合いが強いです。

「もっとこんなこともできるんだぜ!」「Pythonの真髄はこれだ!」というコメント大歓迎です。なにぶん初心者なので、Pythonマスターな方々に助けていただきたいです。

「Chapter2 変数と組み込み型」のあたり

文字列型とユニコード文字列型を分けていること
これは判りやすいですね。特に文字列の長さを判別する際に気をつける必要がある、と。内部での処理の際に文字列をどの文字コードで扱うかを最初に決めたほうがいいのでしょう。u”~”というリテラルで指定できることもあるので、ユニコードで統一したほうが扱いやすいのかな?
他の言語でいう配列にあたる(であろう)「リスト」が超便利
この辺はもう、特に単なるCとかから見れば「ありがたい!」と叫びたくなりますね。言語設計にオブジェクト指向がきちんと生きている、とでも言えばいいのか、やりたいことに対応するメソッドがきちんと整っている、という印象を受けます。なかでもスライスと、文字列とあわせて使うsplitとjoinあたり、ありがたいです。
「タプル」の使いどころを見極めたい
これは、実際に使っていない現時点ではありがたみがいまいちわかりませんが、まぁ今後の課題ということで。この本では、タプルの利点・使いどころとしては辞書(いわゆるHashtable)のキーに使えるよ、とありました。

「Chapter3 条件分岐とループ」のあたり

「Pythonと言えばインデント」?
if文の判定後処理部分などの範囲をインデントで判定する、というのは、言い換えれば「いやでもインデントされたソースが作られることになる」ということですよね。とても良い事だと思います。たまに「どっからどこまでがどうなんだ?」というようなソースを見ますからね…。おもしろい特徴だと思います。あ、でもセミコロンをつかえばそうでなくてもいいのかな?

「Chapter4 関数」のあたり

キーワード引数と引数のデフォルト値
このあたりが柔軟なのは実際に組む段階になったら便利だと思いますね。でも、キーワード引数に関しては、呼び出される関数の側であとから受け取る変数名を変えたいとなったら、逆に呼び出している部分のキーワード引数の部分の引数名をすべて変えなければいけなくなるのかな、と思うと、要は(キーワード引数に頼らずに)ちゃんと設計しておけ、ということですかね。

【8/24:とりあえずここまでとします】

【9/15:追加】

「chapter05 組み込み型を使いこなす」のあたり

しばらく時間があきましたが、再開します。

この章は「こういうメソッドなどをこのように使えばプログラムをよりスマートに組めます」といった感じのことが様々書かれています。まぁスマートだからいいのか、というとまたわかりませんが…

辞書キーを指定した埋め込み

いわゆるC言語などでいうsprintfに該当する文字列フォーマットがpythonにもあり、C言語などと同様に使えると共に、これに代入する変数が辞書に入っている際に、辞書キーを元に埋め込める、とのこと。

linkattrs = {"href":"http://host.to/path/",
"titie":"My Blog"}
formatstr = "<a href="%(href)s" title="%(title)s">%(title)s</a>"
atag = formatstr % linkattrs
print atag
<a href="http://host.to/path/" title="My Blog">My Blog</a>

これは辞書を使ったちょっとしたメッセージを場面に従って出力する際などに便利ですね。エラーメッセージなどこの典型でしょうか。エラーコード+メッセージ本文で辞書を作っておいてこの機能を使う、といったこととか。事前に分岐処理などが必要ないですし。ただ、大量処理の際に処理速度がどうなのかがちょっと気になりますので、使う場面は考える必要がありそうです。

リストのsort()メソッド

リストを通常以外の並び順にしたいときに、それ専用の関数を指定して並び順をコントロールできるとのこと。

set型

set型は内容の重複がないリスト、ということ。集合演算ができること。リスト同様のメソッドを使えるとのことですが、要素の取り出しが不便そうなので、集合演算を行いたい場合専用、なのでしょうか。

辞書のキーをスマートに使う

そのキーが辞書に存在するかは通常has_keyメソッドを使うので、文字列中の単語カウントを得る、ということをする際に、

for word in line.split():
if wordcount.has_key(word):
wordcount[word] = wordcount[word] + 1
else:
wordcount[word] = 1

となると。これはロジックそのままなので読みやすい。これが辞書のgetメソッドを使うと、キーに対応する値を得てかつキーがない場合にはデフォルト地を返せるということで、下のように書き換えられるとのこと。

for word in line.split():
wordcount[word] = wordcount.get(word,0) + 1

うーん、判ってしまえばこのほうが楽ですが、判るまではパッと見の可読性が落ちてしまうので、コメントでフォローですかね。「自分で書いてて後で読めなくなる」という典型のような書式ですが、もちろん悪いのはこうした書式自体でなく書くほうの記憶力ですよね。

でも、これだけ短く書けるのはそれはそれで魅力がありますね。「シンプルイズベスト」をどこでバランスをとるかでしょうか。

enumerate関数を使ったループ:

常、ループはfor文などを使いますが、ある一定の回数ではなくリストなどのシーケンスの要素数だけループさせる場合にはenumerate関数を使え、とのこと。enumerate関数が2つの要素を返す(一つ目が0から順番に増えていく数、2つめが引数のシーケンスで1つ目の数に該当するの要素)というわけですね。これはおそらく使用頻度が高いでしょう。

for cnt, item in enumerate(seq):
print cnt, item
関数から戻り値を複数返せる

これもなにげに便利ですね。リストで受け取り、かつ要素順でなくそのまま名前で参照できるとのこと。

minvalue, maxvalue, avarage = func()
def func()
....
return [minvalue, maxvalue, avarage]

ただし、返り値の数があっていないと例外が発生してしまうので注意。

日本語文字列について

日本語処理に関しては、ここでは文字コード変換に関してこと。日本語関連処理は日本語(≒マルチバイト文字)を利用する多くの処理で必要となるものなので、理解は必要でしょう。

ユニコードとマルチバイト文字列(Shift-JISやUTF-8など)を処理上明確にわけており、例えばchapter2であった、文字列の長さを得る組み込み関数len()の結果も、おなじ文字列に対してもユニコードかマルチバイト文字列かで結果が異なってくる、と。ユニコードのほうはいわゆる”文字数”、マルチバイト文字列の場合は、”バイト数”が返ってくる、といったイメージでしょうか。

なので、文字コード間の扱いの違いと相互のコード変換についての記述にスペースが割かれています。また、マルチバイト文字列→ユニコードへのエンコードなどで失敗した場合の対応がいくつか選べることは、場面によって判断を選べるので重宝しそうですね。データベースに格納する場合には厳しくは判断し、画面に表示する場合には多少の文字化けはOKとする、など。

【9/15:今日はここまでとします。もうちょっと更新頻度をあげたいです…】

チュートリアルその2:「Using the webapp Framework」

今日もGoogle App Engine のチュートリアルを進めます。

前回と同様にEclipse上からPyDev Google App Engine Projectで新規プロジェクトを作成。今回はテンプレートとして「Hello Webapp World」を選択しました。もしや…と思いましたが、今回もチュートリアルとそっくりそのままなソースファイルが生成されました。

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
class MainPage(webapp.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write('Hello, webapp World!')
application = webapp.WSGIApplication([('/', MainPage)], debug=True)
def main():
run_wsgi_app(application)
if __name__ == "__main__":
main()

ここで、webappとはウェブアプリケーションのフレームワーク(ブラウザ←→ウェブサーバやデータベース間の仲介役)のひとつなわけですよね。で、Google App Engine は多くのウェブアプリケーションフレームワーク(Pythonで書かれたもののみ?DjangoやCherryPyなど)に対応しているとのこと。webappもそのひとつ。

前回同様に実行環境を起動して、ブラウザからアクセスしたことろ、”Hello, webapp World!”と表示されました。

どのように動いているか

このソースがどうする順に動いているのかは、以下のようになるのかな、と理解しました。この辺、Python初心者(というよりもウェブアプリ初心者かな)のためにたぶん誤解があると思うので、そのあたりはご容赦ください。

  • Eclipse上でhelloworld.pyを実行する
    • 実行環境(dev_appserver.py経由)が稼動する
    • そこからmain()が呼ばれる
    • run_wsgi_app()が呼ばれる時にapplicationがインスタンス化され、URLとマッピング先クラスとのマッピングの準備が出来る
  • ブラウザから実行環境(=http://localhost:8080/)にアクセスする
    • applicationにブラウザからのリクエストが届き、URLを見てマッピング先(であるMainPage)をインスタンス化
    • MainPageのgetメソッドが起動され、responseプロパティを編集してブラウザにそれが返される

うーん、自分で書いててもあいまいな部分があると感じます。こうしたことを考えるときに、すべての事柄に対して主語と述語と目的語が適切に埋められないという時点で、要は「理解が足りない」ということですよね。ま、これからこれから。

また、WSGI(Web Server Gateway Interface)に関する現時点での理解ですが、ちょっと先行して参照した『みんなのPython Webアプリ編 [みんなのシリーズ]』の308ページに、

「WSGIとは」Pythonで作るWebアプリケーションの実装方法の標準化仕様です。(中略)WSGIの手法を活用してWebアプリケーションを構成する部品を実装することで、アプリケーションの再利用性を高めることができるのです。

とあるとおり、Pythonにおけるwebアプリ作成時の「お作法」なわけですね。で、webappやDjangoはこれに準拠していると。こうしたことにはおとなしく従ってみることにしましょう。

ということは、今回のチュートリアルは、前回のチュートリアルと同じ結果を得るために、このWSGIの作法に従ってwebappを用いて行うとこうなるね、ということなのでしょう。

今日はここまでです。次回は「Using the Users Service」、ユーザー管理のサンプルが見られるかな?

チュートリアルその1:「Hello, World!」

まずはやっぱり万国共通のチュートリアル、Hello Worldですね。

チュートリアル上では特にEclipse上で開発することへの言及はないですが、なるべくEclipse上で行います。

まずは、Eclipse上でプロジェクトを作成。「PyDev Google App Engine Project」というのが選べるので、これにしましょう。プロジェクト名はもちろん”helloworld”。Grammar Versionは2.5を選びます。

次に、Google App Engine Directoryを選べ、と言われますので、画面から「C:\Program Files\Google\google_appengine」を指定。

すると次はapplication idと、プロジェクトの元となるテンプレートを選べ、ときました。application idは、所詮ローカルでのテストなのでそのまま”helloworld”に、テンプレートはいくつか選べますが、これも一番シンプルなものであろう「Hello World」を選択。おそらくまだwebappは使わないでしょうし。

これで、helloworldという名前のプロジェクトフォルダ(アイコンは普通のPyDev Projectと同じもの)が作られ、なかにsrcフォルダもあり、そのなかにapp.yamlとhelloworld.pyの2つのファイルが作成されました。ここで作られるファイルとその構成は、おそらく一つ前で選択するテンプレートによって決まるのでしょう。

自動生成されたapp.yamlという名前のファイルの内容は以下のようになっていました。app.yamlはGoogle App Engine における設定ファイルのようですね。アクセスされるURLとその機能(=Pythonのソースファイル)を紐づけるような感じでしょうか。

application: helloworld
version: 1
runtime: python
api_version: 1
handlers:
- url: /.*
script: helloworld.py

また、helloworld.py(これがPythonのソースファイルですね)は以下のとおり。

print 'Content-Type: text/plain'
print ''
print 'Hello, world!'

ここで公式サイトのチュートリアルの説明を見ると、まんま上と同じ2つのファイル(中身も完璧に同じ)を作成しろ、となっています。うーん、やりますね、PyDev。

チュートリアルにはapp.yamlの内容説明があります。application idやバージョン管理、すべてのURL(/.*)がhelloworld.pyに紐づけられていること、などですね。

さて、実はこれですでに必要なファイルはできあがってしまっているので、実行しようとしたのですが、どうやってEclipse上から実行すればいいのかいまいちわかりません。

そこで、以下のページを参考にしてみました。

そこには、プロジェクトのpropertyでPYTHONPATHにGoogle App Engineのフォルダを追加しろ、とありました。propertyを確認したところ、これはすでに設定されていました。これは、おそらくPyDevGoogle App Engine Projectとして作成したからでしょう。よしよし。

次は、メニューからRun -> Open Run Dialogを開き、そこで「Python Run」の項目で新たに実行環境設定を作れ、とあります。おそらくEclipseのバージョンの違いでしょう、Run Configurationを選ぶと同じ画面が出てきました。また、「PyDev Google App Run」という項目があるので、こちらで実行環境設定を作ることにします。

  • Project欄:helloworldを選択
  • Main Module欄:Google App Engineフォルダのdev_appserver.pyを指定。これはなぜか選択できないので、ファイル名をフルパスで入力
  • ArgumentタブのProgram Arguments欄に”${project_loc}/src”を入力

この設定を、”Run on GAE local”と名づけて保存。すると、メニューのRunでこれが選べるようになります。選ぶと、Consoleに以下のように表示されて、ローカルの実行環境が起動したことがわかりました!

INFO     2009-08-22 14:23:40,592 appengine_rpc.py:157] Server: appengine.google.com
INFO     2009-08-22 14:23:40,625 appcfg.py:329] Checking for updates to the SDK.
INFO     2009-08-22 14:23:41,592 appcfg.py:343] The SDK is up to date.
WARNING  2009-08-22 14:23:42,296 dev_appserver.py:3358] Could not initialize images API; you are likely missing the Python "PIL" module. ImportError: No module named _imaging
INFO     2009-08-22 14:23:42,390 dev_appserver_main.py:465] Running application helloworld on port 8080: http://localhost:8080

ひとつ警告(WARNING)が出てますが、とりあえずあとまわしにしておきましょう。これで、http://localhost:8080が有効になっているわけですから、さっそくブラウザからアクセスしました。そして、見事に”Hello World!”が表示されました! Yes!

すると、同じくコンソールには

INFO     2009-08-22 14:24:46,078 dev_appserver.py:3029] "GET / HTTP/1.1" 200 -
INFO     2009-08-22 14:24:46,078 dev_appserver_index.py:212] Updating C:\eclipse_wsjvctest\helloworld\src\index.yaml
INFO     2009-08-22 14:24:46,265 dev_appserver.py:3029] "GET /favicon.ico HTTP/1.1" 200 -
INFO     2009-08-22 14:24:49,217 dev_appserver.py:3029] "GET /favicon.ico HTTP/1.1" 200 -

と表示されました。ウェブサーバのアクセスログがほぼそのまま出てくるイメージですかね。でも、favicon.icoにステータス200を返しているわりには、ブラウザのfaviconは変わらなかったけどなぁ。まぁいいか。

また、上の2行目では”index.yamlを更新した”とありますので、Package Explorerを見たら、index.yamlというファイルが以下のような内容で生成されていました。

indexes:
# AUTOGENERATED
# This index.yaml is automatically updated whenever the dev_appserver
# detects that a new type of query is run.  If you want to manage the
# index.yaml file manually, remove the above marker line (the line
# saying "# AUTOGENERATED").  If you want to manage some indexes
# manually, move them above the marker line.  The index.yaml file is
# automatically uploaded to the admin console when you next deploy
# your application using appcfg.py.

このファイルはいまのところは開発者は自分でいじる必要はなさそうですね。また、起動したローカルの実行環境は、Eclipseを終了させれば同時に終了するようです。

さて、今回のチュートリアルはここまでです。次回はGoogle App Engineのウェブアプリケーションフレームワークであるwebappを使ったチュートリアルになります。

Google App Engine SDKのインストール

いよいよGoogle App Engine SDK のインストールです。ダウンロードしておいたアーカイブのインストールはあっさり終了。

続いて、Eclipseのプラグインである Google plugin for Eclipse 3.5を以下のページにある方法でインストールします。

一度再起動して、Preferenceの画面にGoogleの欄がでてくることを確認しました。また、ツールバーにそれっぽいボタンも出てきました。「New Web Application Project」や「Deploy App Engine Project」などですね。

…と思っていたら、どうやらこのプラグインはJAVA開発のみサポートしている様子。公式サイトのメニューにも、Java側にしか関連記述がない。あらら。まぁ、PyDevがあるので、いいでしょう。

Google App Engine のチュートリアルを進めよう

さて、ここからは公式サイトのチュートリアルを一通り試してみましょう。

なお、これを日本語に訳されている以下のページはとても参考になります。訳し方も特徴があります。ご本人いわく「鬼教官風」だとか。読んでるとクセになってきます。

並列して読んでいるDjango本ともしかしたら重なる部分もあるかと思いますが、まずはこちらのチュートリアルを先行してすすめることにします。

Django本を読み始める

この記事で書いたDjango本が届いたのでちらっと読んでみました。

500ページ超でなかなか盛りだくさんな印象ですが、きちんとしたものをつくろうと思ったら、早い段階でこうした本に一通り目を通しておいたほうがあとあと役立ちますよね。知らずにへんな設計をしなくてすむし。

というわけで、開発環境の整備や設計と平行して目を通していきます。