2008-04-08
駄文 - 株式会社 Dino の新人研修がすごい
この前紹介した
駄文 - 4 月からプログラマになったあなたへ - IT戦記
Dino という会社の新人研修ですが、すごいです。
何がすごいか
講義を動画で公開しているのです。
そして、新人はプログラミング未経験者
新人の方はプログラミング経験のない方なので、当然以下のような質問が飛びます。
などです。
この質問に対して、なるべく正しく、そして、イメージが湧くような説明をするってすごく難しいと思うんです。
逆に、生半可な知識で説明すると誤解を与えてしまうことになります。
でも、この動画の講師はすごく丁寧な説明で言い切るところは言い切って的確に教えているなあと思いました。
すごいです。
講師、新人両方に良い
さっきも言ったように、基本的な説明ってすごく難しくて、すぐに曖昧なことを言っちゃうと思うんですよね。
それを動画で公開するということによって、講師も曖昧なことは言いにくい環境なわけです。
だから、講師の経験、勉強にもなるなあと思いました。
これは一粒で二度おいしいですね。
あと、動画の個人的な感想
ほとんどの動画を見ました。
中でも emacs の最初の説明が良かったです。僕は vim 使いだけど、 emacs 愛を感じました。
ちょっと昔を思い出した。
でも、よく考えたら僕も 21 歳でプログラマになったときは何にもできなかったんだよなあ。
さらにそこから 2 年たってようやくシェルや vim や JavaScript を触ったんだ。
だから、 Dino の新人さんたちがうらやましい!
一年目で、シェルを使って、 emacs からスタートするプログラマなんて本当に幸せだと思うんだ!
頑張れー!頑張ってー!
Google App Engine が楽しかったので Python 温泉にいくことを決意しました!
Google App Engine 楽しい!
ということで、勇気を出して Python 温泉に行ってみることにしました。
Python 温泉とは
第3回 Python 温泉 無事終了 - Twisted Mind
Pythonista の皆様
まだまだ Python 初心者ですが、よろしこです><
いじめないでね><
いや、むしろ色々教わるためにはいじめられたほうがいいのか!
ライフハック!ライフファッk(自重しました
Google App Engine で Tropy っぽいやつ作ってみた
Google App Engine の SDK で
何か作ってみよう!
というわけで、 Tropy みたいなやつを作ってみる
python で 20 行以上のプログラムを書くのはたぶん初めてだ
Tropy とは
以下が詳しいです。
ちなみに、以下のスクリーンショットは id:naoya さんが作った Tropy のクローンの Haropy です。
で、僕もそんな感じのものを作ってみた
ソースを晒しておきます。
ファイル構成
PyGropy |-- app.yaml |-- edit.html |-- entry.html `-- pygropy.py
app.yaml
設定ファイル
application: pygropy version: 1 runtime: python api_version: 1 handlers: - url: /.* script: pygropy.py
pygropy.py
コントローラとモデルのプログラム
import os from random import random import wsgiref.handlers from google.appengine.ext import webapp from google.appengine.ext.webapp import template from google.appengine.ext import db from pprint import pprint # models class Entry(db.Model): title = db.StringProperty (required=True) body = db.StringProperty (required=True) timestamp = db.DateTimeProperty(required=True, auto_now=True) def to_hash(self): return { 'id': self.key().id(), 'title': self.title, 'body': self.body, 'timestamp': self.timestamp, } # controllers class MainPage(webapp.RequestHandler): def get(self): redirect_random_id(self) class EntryPage(webapp.RequestHandler): def get(self): id = self.request.get('id'); if id: entry = Entry.get_by_id(int(id)) path = os.path.join(os.path.dirname(__file__), 'entry.html') self.response.out.write(template.render(path, entry.to_hash())) else: redirect_random_id(self) class EditPage(webapp.RequestHandler): def post(self): id = self.request.get('id'); title = self.request.get('title'); body = self.request.get('body'); entry = False if id: entry = Entry.get_by_id(int(id)) if not(entry): entry = Entry(title=title, body=body) else: entry.title = title; entry.body = body; id = entry.put().id() self.redirect('/entry?id=' + str(id)) def get(self): id = self.request.get('id'); entry = False if id: entry = Entry.get_by_id(int(id)) if entry: vars = entry.to_hash() else: vars = {} path = os.path.join(os.path.dirname(__file__), 'edit.html') self.response.out.write(template.render(path, vars)) def redirect_random_id(handler): count = db.GqlQuery('SELECT * FROM Entry').count(); if count == 0: handler.redirect('/edit') else: id = int(random() * count) + 1 handler.redirect('/entry?id=' + str(id)) def main(): application = webapp.WSGIApplication([('/', MainPage), ('/edit', EditPage), ('/entry', EntryPage), ], debug=True) wsgiref.handlers.CGIHandler().run(application) if __name__ == "__main__": main()
edit.html
<html> <head> <title>PyGropy ver.0721</title> </head> <body> <form action="/edit" method="post"> <ul> <li><input type="text" name="id" value="{{id|escape}}" /></li> <li><input type="text" name="title" value="{{title|escape}}" /></li> <li><textarea name="body">{{body|escape}}</textarea></li> <li>{{timestamp|escape}}</li> <li><input type="submit" name="_submit" value="submit" /></li> <li><a href="/">random</a></li> </ul> </form> </body> </html>
entry.html
<html> <head> <title>PyGropy ver.0721</title> </head> <body> <ul> <li>{{id|escape}}</li> <li>{{title|escape}}</li> <li>{{body|escape}}</li> <li>{{timestamp|escape}}</li> <li><a href="/edit?id={{id|escape}}">edit</a></li> <li><a href="/">random</a></li> </ul> </body> </html>
とりあえず、以下のコマンドでテストサーバが動きます。
$ dev_appserver.py ディレクトリ名 INFO 2008-04-09 00:48:48,665 appcfg.py] Checking for updates to the SDK. INFO 2008-04-09 00:48:49,392 appcfg.py] The SDK is up to date. INFO 2008-04-09 00:48:49,401 dev_appserver_main.py] Running application pygropy on port 8080: http://localhost:8080
動かしてみる
わーいわーい動いたー
あれ、複数行入れるとエラーになるなあ。たぶん、モデル定義のといに型の指定を間違えたっぽい><
でも、まあ、そこは本質的な作業じゃないので間違えたままにしておきます。
あれ、タイムスタンプもおかしいな。まあいいや。
俺も俺も! Google App Engine!
これを見て
秋元@サイボウズラボ・プログラマー・ブログ: Google App Engine SDKを使ってみた
俺も俺もやりたいよ><
ってことで骨髄反射的に
今からインストールするよ!
ダウンロード完了
インストーラ起動
ひたすら「continue」
インストール先選んで
パスワード入れて
はい、完了
Getting Started でも読むか
Developer's Guide - Google App Engine — Google Developers
Hello world できた
リアルにドキュメント読みながらやったので低速です。
早送りしながら見てね><
Hello world がこんなに簡単でした。
ちょっと partty.org を使いやすくするため jabanner をインストールします。
Index of /~i0611238/pub/jabanner
libgd をインストールしないとインストールできないようです。
libgd をインストール中。時間かかる
時間かかるー(libgd のメイクが)
jabanner のインストールにはまった
Mac だと
gettext のヘッダがないとか、色々怒られた><
以下のようにすれば入りました。
まず、 src/jabanner.cc に以下の include を書き足す
#include <libintrl.h>
で、以下のように configure && make する
$ ./configure -v --prefix=/opt/local --with-libintl-prefix=/opt/local --with-included-gettext $ LDADD="-L/opt/local/lib/ -lintl" make
jabanner と Partty!.org の相性は異常
脱線し過ぎだろ常識的に考えて><
というわけで、もう一個くらい Google App Engine のサンプルを作ってみる
以下のコードだけで Google のユーザ認証を使えるんだー。
from google.appengine.api import users user = users.get_current_user() if user: print 'Content-Type: text/plain' print '' print 'Hello, ' + user.nickname() + '!' else: # users.create_login_url('http://localhost:8080/welcome') # でログイン画面の URL を取得して、リダイレクトさせる
これは、楽だ
なんか作ってみよう
次ぎのエントリに続く







