いきなりPython 〜Hello! world編〜

何故にカエルの天敵であるヘビ(Python)をやらねば(?)いけなくなったのか。

とあるきっかけで、”Google App Engine上で動作する Twitterのbotを開発してみるイベント”
(通称BOT2UKU)のお誘いを受けて、ぜひ勉強会に参加してみたい!と思ってはみたものの、
そこでは、Pythonベースでの勉強だったという...。


Rubyも全くできないのに、Pythonとか無謀すぎる...とは思いつつ、
まぁ、それでも、言語は違えども、勉強にはなるかなぁと思って、とりあえずbot2kuを受講する際に必要な環境設定をして、
勉強会の資料をもとに、自分でちょっとやってみよう。なんて軽い気持ちでやったのが始まり。


とりあえず、BOT2UKUの"GAEでTwitterのbotを作る のまとめページ"を参照しながら設定しよう。
ど初心者でもわかる設定のしかた(Python版)

pythonをインストールする    
   私のPC環境:
   Windows Vista / Intel Core 2 Duo CPU / 32ビットオペレーションシステム
  インストールするPython version:python-2.5.4.msi 

2 pythonを便利に使うための設定をする
3 GAEのアカウント設定して使えるようにする。
4 GAEのSDK(開発用キット)のインストール

4番まで設定完了。さて、実際にGAEを動かしてみようかなと。
まずは、Hello, World!チュートリアルに従って、
helloworldという名前のディレクトリ(=フォルダ)を作成。
helloworld ディレクトリで、helloworld.py という名前のファイルを作成し、次のようなコンテンツを入れる。

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

次に、helloworld ディレクトリで、app.yaml という名前のファイルを作成し、次のようなコンテンツを入れる。

application: helloworld
version: 1
runtime: python
api_version: 1

handlers:
- url: /.*
  script: helloworld.py

よし、ファイル作成完了。
次はアプリケーションのテスト。

ハンドラ スクリプトと設定ファイルを使用して、各 URL にハンドラをマッピングすれば、
アプリケーションは完成です。App Engine SDK に含まれる Web サーバーでこれをテストすることができます。

ハンドラ??マッピング??それって何だ??
ぐぐってみたけどよくわからない...orz

と、とりあえず、コマンド入力してみよう。

次のコマンドで helloworld ディレクトリまでのパスを指定し、Web サーバーを起動します。

google_appengine/dev_appserver.py helloworld/


....?
エラーでるぞ。
うーん、やっぱり「URLにハンドラをマッピング」ってのをしないとだめなのかなぁ(´・ω・`)
ああ、でも、Rubyの時って、rubyて入力してからでないと、rbファイル実行できないよな。
ってことは、これって、pythonって入力してしないとだめなんじゃね?
と思って、あれこれやったけど、syntax errorとかでてしまった。

も一度、整理しよう。
現在の作業環境

Python
C:\Python25

GAE
C:\Program Files\Google\google_appengine\dev_appserver.py

helloworld
C:\Program Files\Google\google_appengine\helloworld\helloworld.py
C:\Program Files\Google\google_appengine\helloworld\app.yaml

しかし、各urlに ハンドラをマッピングの意味がわからないまま(´・ω・`)ショボーン

テストその1
C:\Program Files\Google\google_appengine\dev_appserver.py helloworld/
を入力すると、EmEditorでdev_appserver.pyが開く(´・ω・`)


テストその2
インタプリタpythonと入力して実行してみる。
C:\Program Files\Google\google_appengine>python dev_appserver.py helloworld/

結果

C:\Program Files\Google\google_appengine>python dev_appserver.py helloworld/
Traceback (most recent call last):
  File "dev_appserver.py", line 60, in <module>
    run_file(__file__, globals())
  File "dev_appserver.py", line 57, in run_file
    execfile(script_path, globals_)
IOError: [Errno 2] No such file or directory: 'C:\\Program Files\\Google\\google
_appengine\\google\\appengine\\tools\\dev_appserver_helloworld.py'

なんかPATH通ってなくない?\\とかになってる...。
ちなみに、line57、line60はこんな感じになってた。

def run_file(file_path, globals_, script_dir=SCRIPT_DIR):
  """Execute the file at the specified path with the passed-in globals."""
  sys.path = EXTRA_PATHS + sys.path
  script_name = os.path.basename(file_path)
  script_name = SCRIPT_EXCEPTIONS.get(script_name, script_name)
  script_path = os.path.join(script_dir, script_name)
  execfile(script_path, globals_)    ←line 57

if __name__ == '__main__':
  run_file(__file__, globals())      ←line 60


とりあえず、も一度ユーザー環境設定見直そう。
PATH>>C:\Program Files\Ruby-1.8\bin;C:\work;C:\Python25;C:\Python25\Scripts;C:\Python25\Lib\site-packages;C:\Program Files\Google\google_appengine\;C:\helloworld

う〜ん。これがあっているかどうかもよくわからなくなってきた。
なんか設定いじってしまってるのかもしれないと思い、GoogleAppEngine_1.2.0をREPAIRした。

で、今度は、最後のhelloworldの前まで入力してみた。

C:\Program Files\Google\google_appengine>python dev_appserver.py
Invalid arguments
Runs a development application server for an application.

dev_appserver.py [options] 

Application root must be the path to the application to run in this server.
Must contain a valid app.yaml or app.yml file.

お?Invalid argumentsってでた。
ってことは、引数がないって事??

dev_appserver.py [options]

この [options] ってところに値「helloworld」を入れろって事かな?
よし、今度こそ!

C:\Program Files\Google\google_appengine>python dev_appserver.py helloworld

INFO     2009-10-05 11:29:29,216 appengine_rpc.py] Server: appengine.google.com
Allow dev_appserver to check for updates on startup? (Y/n): 

おおおお?!うまくいきそう??とりあえず、「Y」入力

Allow dev_appserver to check for updates on startup? (Y/n): y
dev_appserver will check for updates on startup.  To change this setting, edit C
:\Users\sachiko/.appcfg_nag
INFO     2009-10-05 11:29:46,438 appcfg.py] Checking for updates to the SDK.
WARNING  2009-10-05 11:29:46,967 datastore_file_stub.py] Could not read datastor
e data from c:\users\sachiko\appdata\local\temp\dev_appserver.datastore
WARNING  2009-10-05 11:29:46,967 datastore_file_stub.py] Could not read datastor
e data from c:\users\sachiko\appdata\local\temp\dev_appserver.datastore.history
WARNING  2009-10-05 11:29:47,049 dev_appserver.py] Could not initialize images A
PI; you are likely missing the Python "PIL" module. ImportError: No module named
 _imaging
INFO     2009-10-05 11:29:47,398 dev_appserver_main.py] Running application hell
oworld on port 8080: http://localhost:8080

なんかエラーでまくってるけど大丈夫だろうか...
とりあえず、ブラウザにhttp://localhost:8080を入力してみよう。

....orz 
やっぱりだめだった(´;ω;`)
にゅ〜ん、わからんよぉう。

そして、ふたたび、ぐぐる→ぐぐる→ぐぐる→ぐぐr(ry
と、無限loopしかけたところに、ヒントを発見!!!!!
それはここだーーーーーーーーー!ヽ(≧▽≦)ノ
GAE+Vista Ulitmateでのdev_appserver.pyの起動

調べてみたら、まさにこれと全く同じ!!
C:\Windows\System32\drivers\etc\hostsをエディタで開いたら、
::1 localhostとなっている!!!><

というわけで
「::1 localhost」になってるところを、「127.0.0.1 localhost」に編集しなおす。
で、再度 http://localhost:8080にアクセス。

できたーーーーーーーー!Hello, world! ヽ(≧▽≦)ノ

(マジで)ゼロからRubyする編  〜Date::today(追記)〜

私、日付表示するのに、

$KCODE="sjijs"  
require 'date'

dobj=Date.today
y=dobj.year
m=dobj.month
d=dobj.day

puts "#{y.to_s}/#{m.to_s}/#{d.to_s}";

とか、長ったらしく書いてたけど、

$KCODE="sjijs"  
require 'date'

d=Date.today
puts d.to_s

これだけでもいいんじゃん....orz
まぁ、表示形式は違うけど。

ちなみに表示結果は、
2009/9/21か2009-09-21かの違い。

(マジで)ゼロからRubyする編  〜ブロックってなんだ?〜

前回、日付を記録する為に、'date'ライブラリを使ったわけだけど、
その時に、記録をする為のファイルに書き込みをする際に、File.openを使いました。
(これしか知らなかったからだけど)

file=File.open "twit_log.txt","a" 
puts "="*80
puts "#{y.to_s}/#{m.to_s}/#{d.to_s}";
file.close

fileは開いたら、必ずcloseしなくてはならない。
でも、間に色々書いてたら閉じる事を忘れちゃったりする。
この閉じ忘れを回避する為に「ブロック付きopen」というものが便利らしい。

というわけで「Karnel#open」の「ブロック付きopen」で書き直してみる。

open "twit_log.txt","a" do |f|
f.puts "="*80
f.puts "#{y.to_s}/#{m.to_s}/#{d.to_s}";
end

あまりかわらない気が...とか思ったんだけど、File.openの場合だと、
閉じ忘れたら、fileは開きっぱなしになってしまうけど、
ブロック付きにすると、必ず閉じられるらしい。


よくわからんけどvbaの「Do While 〜Loop」的な感じで、「do 〜end」なのかと勝手に思ってたんだけど、
これってブロックだったのね(´・ω・`)
よくわからないまま使ってたけど、「each do」とかもそうらしい。


§ブロック付きメソッド呼び出し

レシーバ.メソッド名(引数,xxx)do |ブロックパラメータ|処理 end
もしくは
レシーバ.メソッド名(引数,xxx){|ブロックパラメータ|処理}


とりあえず、今の私には、書き方を換える事によって、
何がどう影響してくるかが分かる段階ではないので、
とりあえず、ブロック使った方が色々便利という程度に覚えておこう。

(マジで)ゼロからRubyする編  〜Date::today〜

ファイルに読み込んだデータを書き込んだりする時に、
最初に日付を記録するする為に'date'ライブラリを使ってみる。

$KCODE="sjijs"  
require 'date'

dobj=Date.today
y=dobj.year
m=dobj.month
d=dobj.day

file=File.open "twit_log.txt","a" 
puts "="*80
puts y,"/",m,"/",d
file.close

実行結果

2009
/
9
/
20


おおう(ノ´∀`*) やっちまいましたよw
print じゃなくて puts だから強制改行されてるんだな。
と思って、putsをprintにしたけど同じ結果に。あり?
こんな基本中の基本でつまずくと思わなかった...

で、考えてみた。「,」があやしい。
取ってみる。

実行結果

twit_test.rb:14: syntax error, unexpected tIDENTIFIER, expecting $end
p y"/"m"/"d
       ^

ですよねぇ。いや、わかってたけどさ。一応ね。
で、思いだしましたよ。っていうか式展開の事忘れてました(ノ´∀`*)

file=File.open "twit_log.txt","a" 
puts "="*80
puts "#{y.to_s}/#{m.to_s}/#{d.to_s}";
file.close

実行結果

2009/9/20

やっとできた!w

※追記:y.to_sとかにしなくても"#{y}/#{m}/#{d}";でも結果同じだった(´・ω・`)

iPhoneでirbをやりたい!ヽ(≧▽≦)ノ

プログラミングはとにかくいっぱい書いて書いて書きまくって経験を積め的な事は分かってはいるけれども、
私みたいな、一般事務系OLには、なかなかそれは難しい。
会社でのネット環境は、全て監視されてるし、
ましてやTwitterなんてフィルタリングかけられてるから見れないし(当たり前)。
お昼休みや通勤の合間に本やブログでコードの勉強くらいしかできない。
でも、やっぱり、その場で確認したいって思う事がしばしばある。


というわけで、ちょっとした簡単なスクリプトとかなら、使えるかも。
という事で教えてもらったサイトを試してみた。
JSRuby Test - Ruby for Javascript
http://labs.cybozu.co.jp/blog/nakatani/jsruby/jsruby_test.html

入力内容

a=3
b=5
puts a+b

parse(分析)

[[M(*let,[V'a', 3])], [M(*let,[V'b', 5])], [M(puts,[E'[R'a', R'b', O'+']'])]]

execute(実行結果)

8

まんなかの「parse」って部分の意味がさっぱりなんだけど、
とりあえず実行結果としては合ってるのでよしとしよう!ヽ(≧▽≦)ノ


ちなみにこのサイトって、ギャグで作られたらしい。
どのへんがギャグなんだ?とか思ったんだけど、以前、JavaScriptRubyの違いを聞いたら、
使う用途が違うので、比較する事がそもそも間違ってると言われた事があるんだけど、
いまだに使う用途がよく分かってない私には、やっぱりこのサイトがギャグサイトというのが理解できなかった(´・ω・`)

まぁ、でもギャグだとしても、これがRubyっぽい何かだとしても、
初心者の私が練習するには、充分な環境かと思われ。


でも、よくよく考えてみたら、ほんとにギャグでこんなの作っちゃうなんて、
すごい事なんだなぁ。と思った。

プログラムの言語ってさ、普通の日常生活に置き換えたら、
ドイツ語とかフランス語とかみたいなもの程度に考えていたんだけど、そんな簡単なものじゃないんだよね。


このサイト見た時に思ったのは、普通の英語やドイツ語の翻訳サイトみたいに、
ボタンひとつで言語の切り替えできたら他の言語と比較できて面白いし便利なのになぁ。
とか思ったけど、それはとてつもなく大変な事なんだねぇ。


でも、将来的に、そういうサイトができたら素敵だよね。
日々是、妄想中(*´∀`)

@scriptter で東横線を走らせてみた!ヽ(≧▽≦)ノ

@scriptter宛てにプログラム名を表すコードとソースをつぶやくと、
実行結果を返してくれる@scriptterを使って、東横線を走らせてみた。


post方法は、@scriptter usage とpostすると、返ってきます。
まず、@scriptter の後に、LANGUAGE_CODE SOURCE の順に入力します。使用する言語がRubyなら @scriptter rb と入力します。

《お手本》@matsuuさんのpostを参考にさせていただきました。

@scriptter ruby print "東海道線 ε=",("⋤⋥" * 15)"   
実行結果:  東海道線 ε=⋤⋥⋤⋥⋤⋥⋤⋥⋤⋥⋤⋥⋤⋥⋤⋥⋤⋥⋤⋥⋤⋥⋤⋥⋤⋥⋤⋥⋤⋥

1回目

rb a="⋤⋥",print "東横線 ε= #{a* 15}"

実行結果
syntax error, unexpected tSTRING_BEG, expecting kDO or '{' or (snip)

2回目

rb a="⋤⋥", print "東横線 ε= #{[a]*15}"

実行結果
syntax error, unexpected tSTRING_BEG, expecting kDO or '{' or '('\na= (snip)

どちらも同じようなエラーがでた。
意味を調べようとググってみたが、なかなか見つけられない。
さまよったあげく、三項演算子(条件演算子ともいう)という言葉にたどり着いた。(結局まったく関係なかったんだけど)


で、この三項演算子ってところからヒントを得た。
ようは、通常は複数行に渡って記述するものを、一行で表示するので、記述方法も換える必要がある。


ただ、unexpected tSTRING_BEG ってところから推測するに、文字(String)の始め(Begin)とかが不明とか、
expecting kDO はよくわからないけど、
'{' or '('\na= (snip)  このsnipは英語で、チョキンと切るという意味だった。
つまり、{ を認識してくれてないとかではなく、コードの最後が切れてるよ。って意味とかなのかなと予想。

例えば、今回の場合、エディタで作成した場合、

a="⋤⋥"
print "東横線 ε= #{a*15}"

となる。つまり、「a="⋤⋥"」の後に改行を入れている。
これを一行にする為に、私は何も考えずに、「a="⋤⋥",」と「,」を入れていた。当然、エラーがでるわけだ。
同じように、irbを使ってコマンドプロンプトから入力し、改行せずに入力すると、同様のエラーが起きる。
じゃあ、どうすればいいのか。



C言語では、行のプログラムの終わりには「;」を使うらしい。
Rubyは空気読んでくれるので、通常行末に「;」とかが不要なのだそうだけど、今回はこの曖昧さのおかげで
エラーになってるやもしれん。
ということで、ここは、あえて「;」を使ってみました。

a="⋤⋥";print "東横線 ε= #{a*15}"

実行結果

東横線 ε=⋤⋥⋤⋥⋤⋥⋤⋥⋤⋥⋤⋥⋤⋥⋤⋥⋤⋥⋤⋥⋤⋥⋤⋥⋤⋥⋤⋥⋤⋥

《学んだこと》
Rubyスクリプトを実行するには、3種類の方法があることを知った(今更だけどw)

1.コマンドラインRubyの式を実行する方法。
  今回のような一行で入力する方式。ワンライナーという。
  通常は、コマンドライン上で、Ruby -e と入力して、その後ろにRubyスクリプト文字列を指定する

例:Ruby -e 'a=2;b=5;puts a+b'

2.irbを使う方法。
3.スクリプトファイル名を指定して実行する方法。


《今日の目からウロコ》
ワンライナーを実行する時で、ハッキリとここでこの行のプログラム終わり、と言いたいときは「;」を使う。

(マジで)ゼロからRubyする編  〜File.open(書き出し)〜

File.openメソッドを使って、ファイルの書き出しメソッドを作ってみる。
前回作ったtextlineメソッドに、第2引数に write_filename を追加。

$KCODE="sjis"

def textline(read_filename,write_filename)
    #Filename=read_filename
    data=Array.new
    n=0
    
    file=File.open read_filename
    file.each_line do |line|
      line2=line.chomp
      data[n]=(n+1).to_s + ': '+line2
      n+=1
    end
    
    read_text=data
    file=File.open write_filename, 'w' do |file|
      file.write read_text
      puts(data)
      file.close   
    end
end 

実行結果(テキストファイル上の表示)

1: 空を見上げてごらん。2: 広くてすてきな宇宙じゃないか!

コマンドプロンプト上の実行結果(なんで表示が違うんだ?)

1: 空を見上げてごらん。
2: 広くてすてきな宇宙じゃないか!

ちなみにputsをpにした場合の実行結果

#=>["1: 空を見上げてごらん。", "2: 広くてすてきな宇宙じゃないか!"]

data=Array.newで作成したデータに、きちんと格納されてるね。

data[0]=>"1: 空を見上げてごらん。"
data[1]=>"2: 広くてすてきな宇宙じゃないか!"




補足説明
Fileクラスのopenメソッドで、write_filename ファイルを開く。


ファイルの読み込み時に省略していた、openメソッドの第2引数に、書き出しモードの'w'を使用する。
この'w'は、書き出しをする為のファイルがない場合は、自動的にファイルを作成してくれる。
でも、既に書き出し用のファイルが存在する場合は、ファイルを上書きして作成される。

file=File.open write_filename, 'w' do |file|

ちなみに、ファイルの上書きをせず、既存明細に追加をしたい場合は、'a'を使う。

file=File.open write_filename, 'a' do |file|

実行結果

1: 空を見上げてごらん。2: 広くてすてきな宇宙じゃないか!1: 空を見上げてごらん。2: 広くてすてきな宇宙じゃないか!