IT戦記 このページをアンテナに追加 RSSフィード Twitter

2008-04-08

駄文 - 株式会社 Dino の新人研修がすごい

この前紹介した

駄文 - 4 月からプログラマになったあなたへ - IT戦記

スタートアップ研修記

Dino という会社の新人研修ですが、すごいです。

何がすごいか

講義を動画で公開しているのです。

no title

そして、新人はプログラミング未経験者

新人の方はプログラミング経験のない方なので、当然以下のような質問が飛びます。

などです。

この質問に対して、なるべく正しく、そして、イメージが湧くような説明をするってすごく難しいと思うんです。

逆に、生半可な知識で説明すると誤解を与えてしまうことになります。

でも、この動画の講師はすごく丁寧な説明で言い切るところは言い切って的確に教えているなあと思いました。

すごいです。

講師、新人両方に良い

さっきも言ったように、基本的な説明ってすごく難しくて、すぐに曖昧なことを言っちゃうと思うんですよね。

それを動画で公開するということによって、講師も曖昧なことは言いにくい環境なわけです。

だから、講師の経験、勉強にもなるなあと思いました。

これは一粒で二度おいしいですね。

あと、動画の個人的な感想

ほとんどの動画を見ました。

中でも emacs の最初の説明が良かったです。僕は vim 使いだけど、 emacs 愛を感じました。

ちょっと昔を思い出した。

でも、よく考えたら僕も 21 歳でプログラマになったときは何にもできなかったんだよなあ。

さらにそこから 2 年たってようやくシェルvimJavaScript を触ったんだ。

だから、 Dino の新人さんたちがうらやましい!

一年目で、シェルを使って、 emacs からスタートするプログラマなんて本当に幸せだと思うんだ!

頑張れー!頑張ってー!

Google App Engine が楽しかったので Python 温泉にいくことを決意しました!

Google App Engine 楽しい!

ということで、勇気を出して Python 温泉に行ってみることにしました。

Python 温泉とは

第3回 Python 温泉 無事終了 - Twisted Mind

Pythonista の皆様

まだまだ Python 初心者ですが、よろしこです><

いじめないでね><

いや、むしろ色々教わるためにはいじめられたほうがいいのか!

ライフハック!ライフファッk(自重しました

Google App Engine で Tropy っぽいやつ作ってみた

Google App EngineSDK

何か作ってみよう!

というわけで、 Tropy みたいなやつを作ってみる

python で 20 行以上のプログラムを書くのはたぶん初めてだ

Tropy とは

以下が詳しいです。

Tropyとは - はてなキーワード

ちなみに、以下のスクリーンショットid:naoya さんが作った TropyクローンHaropy です。

f:id:amachang:20080409012639p:image

で、僕もそんな感じのものを作ってみた

ソースを晒しておきます。

ファイル構成
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テンプレート

<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テンプレート

<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

動かしてみる

f:id:amachang:20080409005529p:image

わーいわーい動いたー

あれ、複数行入れるとエラーになるなあ。たぶん、モデル定義のといに型の指定を間違えたっぽい><

でも、まあ、そこは本質的な作業じゃないので間違えたままにしておきます。

あれ、タイムスタンプもおかしいな。まあいいや。

俺も俺も! Google App Engine!

これを見て

秋元@サイボウズラボ・プログラマー・ブログ: Google App Engine SDKを使ってみた

俺も俺もやりたいよ><

ってことで骨髄反射的に

今からインストールするよ!

f:id:amachang:20080408164823p:image

ダウンロード完了

インストーラ起動

f:id:amachang:20080408165405p:image

ひたすら「continue

インストール先選んで

f:id:amachang:20080408165404p:image

パスワード入れて

f:id:amachang:20080408165402p:image

はい、完了

f:id:amachang:20080408165400p:image

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 を取得して、リダイレクトさせる

これは、楽だ

なんか作ってみよう

次ぎのエントリに続く