24122012 家庭菜園
タイミング逃しまくりで、先週やっとスナップエンドウとブロッコリー、カリフラワーを定植した。
カリフラワーは一度きりの収穫だが、ブロッコリーは定期的に畑詣でする必要があって面倒くさいので、ベランダでも育てることにした。

敷き藁が余っていたのでプランターにも敷いてみた。

24122012 家庭菜園
タイミング逃しまくりで、先週やっとスナップエンドウとブロッコリー、カリフラワーを定植した。
カリフラワーは一度きりの収穫だが、ブロッコリーは定期的に畑詣でする必要があって面倒くさいので、ベランダでも育てることにした。

敷き藁が余っていたのでプランターにも敷いてみた。

24122012 Haskell
この前mkvirthualenvを書いたんだけど、消したりリストできないと使いづらいのでvirthualenvwrapperという名前でGitHubにあげておいた。
git cloneしてcabal installすればmkvirthualenv,rmvirthualenv,lsvirthualenvの3つのコマンドが使えるようになるはずですが、cabalで設定するの初めてなのでおかしかったら指摘してください。
mkvirthualenv yesod
で仮想環境が作られるのでworkhonで入る
$ workhon yesod Activating yesod Virtual Haskell Environment (at /Users/kzfm/.virthualenv/yesod). Use regular Haskell tools (ghc, ghci, ghc-pkg, cabal) to manage your Haskell environment. To exit from this virtual environment, enter command 'deactivate'. (yesod)localhost@kzfm:~ $
好きなライブラリを入れまくる。そもそもpersistentがおかしくて、仮想環境を作っては消しを繰り返していたのが、ラッパー構築の動機
cabal install yesod-platform-1.1.5 cabal install persistent-sqlite-1.0.1
lsvirthualenvコマンドを使う
$ lsvirthualenv
diagrams
hakyll
per2
persistent
scotty
snap
yesod
ちょっとyesodが嫌になってsnapに浮気しかけた時期(今朝とか)がありました。
rmvirthualenvコマンド
$ rmvithualenv snap $ lsvirthualenv diagrams hakyll per2 persistent scotty yesod
個人的にはフルスタックのフレームワークよりも、Flaskのように好きに組み合わせて作っていくのが好きなのでsnapに惹かれたんだけど、Modelのsnapletがコアについていってない感じがした。
HDBCもエラーになるし、sqlite-simpleもORマッパーぽくなくてなんかいまいちだった。あとドキュメントが少ないので困ったので、yesodで行こうと思った。
Developing Web Applications With Haskell and Yesod23122012 life
本棚があふれてどうしようもないので少し処分することにした。ブックオフに持っていけそうなものはそっちに出すとして、技術書や洋書は面倒くさいので次のゴミの日に捨てる予定。
知り合いのなかで、もし欲しいのがあったら教えてください。今度会う時に持っていきます。



写真に撮り忘れたけど、ふつうのHaskellと入門Haskellも不要なので欲しい人がいれば僕まで連絡お願いします。
22122012 Haskell
普段はFlask使ってるし、NodeでWebアプリ使う時にはExpressを使うので、これ以上Sinatraクローンを覚えたいとは思わないが、ソースコードを読んで勉強するにはちょうどいいサイズだった。
newtype ActionM a = AM { runAM :: ErrorT ActionError (ReaderT ActionEnv (StateT Response IO)) a } deriving ( Monad, MonadIO, Functor , MonadReader ActionEnv, MonadState Response, MonadError ActionError)
モナド変換子の重ね方が参考になった。Scottyの場合はErroTでリダイレクトとかの処理をするようになっている。
defaultHandler :: ActionError -> ActionM () defaultHandler (Redirect url) = do status status302 header "Location" url defaultHandler (ActionError msg) = do status status500 html $ mconcat ["<h1>500 Internal Server Error</h1>", msg] defaultHandler Next = next
参考
括弧が省略できてインデントでネストが表現できる言語だとコードの見通しが良くていいですね。
{-# LANGUAGE OverloadedStrings #-} import Web.Scotty import Data.Monoid main :: IO () main = scotty 3000 $ do get "/" $ text "Helllo Scotty" get "/lang" $ do v <- param "type" html $ mconcat ["<h1>", v, "</h1>"]
22122012 Haskell
モナモナ言うモナド入門を読んでプチ圏論ブームがやってきたっぽいので、改めてはじめての圏論 その第1歩:しりとりの圏を読んでみた。
読んだ当時は、射の集合がひらがなの文字列っていうのがいまいちイメージがわかなかったのだけど、改めて読んでみるとdomとcodを決めるルールなんだから文字列でいいのかと納得した。
さて、カタカナの文字の集合を考えてしりとりの圏を作ったとする。この場合、ひらがなの圏をカタカナの圏に関連付けるものはfunctorなのだろう。
アルファベットのしりとりの圏を作ってそれをひらがなの圏と対応付けるのもまたfunctorなのだろうか(一対一で対応しないけど)?と思ったが、これの圏論の説明をみるかぎりそんな気がする。
Basic Category Theory for Computer Scientists (Foundations of Computing)20122012 Haskell
Persistentを触ってみている
{-# LANGUAGE QuasiQuotes, TemplateHaskell, TypeFamilies, OverloadedStrings #-} {-# LANGUAGE GADTs, FlexibleContexts #-} import Database.Persist import Database.Persist.Sqlite import Database.Persist.TH import Control.Monad.IO.Class (liftIO) share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persist| Person name String age Int Maybe loc String default="Japan" deriving Show |] main :: IO () main = withSqliteConn "test.db" $ runSqlConn $ do runMigration migrateAll johnId <- insert $ Person "kzfm" (Just 20) "Fuji" liftIO $ print johnId
実行するとデータベースが作られる。実行されるSQLはごく普通のcreate文
CREATE TABLE "Person"("id" INTEGER PRIMARY KEY,"name" VARCHAR NOT NULL,"age" INTEGER NULL)
続いてEntityを変更してみる。locを追加してdefaultも付けておく。ついでにinsertのとこも修正しておく
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persist| Person name String age Int Maybe loc String default="Japan" deriving Show |] main :: IO () main = withSqliteConn "test.db" $ runSqlConn $ do runMigration migrateAll johnId <- insert $ Person "kzfm" (Just 20) "Fuji" liftIO $ print johnId
バックアップテーブルにデータが移され、もとのテーブルが変更された後、データが戻されて移行が無事に完了する。
CREATE TEMP TABLE "Person_backup"("id" INTEGER PRIMARY KEY,"name" VARCHAR NOT NULL,"age" INTEGER NULL,"loc" VARCHAR NOT NULL DEFAULT "Japan") INSERT INTO "Person_backup"("id","name","age") SELECT "id","name","age" FROM "Person" DROP TABLE "Person" CREATE TABLE "Person"("id" INTEGER PRIMARY KEY,"name" VARCHAR NOT NULL,"age" INTEGER NULL,"loc" VARCHAR NOT NULL DEFAULT "Japan") INSERT INTO "Person" SELECT "id","name","age","loc" FROM "Person_backup" DROP TABLE "Person_backup"
Entityのデフォルトはデータ移行時のもとのカラムに付加される値であって、insertで省略できるわけではないので、insertは明示的に値を入れないといけない。databaseを見てみるともとのデータのlocにはEntityのデフォルトで指定したJapanという値が入っていることがわかる。
sqlite> select * from person; 1|kzfm|20|Japan 2|kzfm|20|Fuji
ちなみにEntityのデフォルトを指定しないとマイグレーションに失敗するが、Maybe型にしておけばnullが入るので移行できる。
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persist| Person name String age Int Maybe loc String Maybe deriving Show |]
開発している時にスキーマの変更はそれなりに苦痛を伴う作業なので、ある程度面倒見てくれるのはありがたい。ダメなときはダメって言ってくれるし。
Persistentのマイグレーションは保守的なので安心らしい。次のケースで自動的にスキーマの変更がなされる。
Developing Web Applications With Haskell and Yesod20122012 Haskell
persistent-1.1.0.1,persistent-template-1.1.1が入っている。
Persistentのsynopsisの例を実行すると
No instance for (Control.Monad.Trans.Resource.MonadResource IO) arising from a use of `selectList' Possible fix: add an instance declaration for (Control.Monad.Trans.Resource.MonadResource IO) In a stmt of a 'do' block: oneJohnPost <- selectList [BlogPostAuthorId ==. johnId] [LimitTo 1] In the second argument of `($)', namely `do { runMigration migrateAll; johnId <- insert $ Person "John Doe" $ Just 35; janeId <- insert $ Person "Jane Doe" Nothing; insert $ BlogPost "My fr1st p0st" johnId; .... }' In the second argument of `($)', namely `runSqlConn $ do { runMigration migrateAll; johnId <- insert $ Person "John Doe" $ Just 35; janeId <- insert $ Person "Jane Doe" Nothing; insert $ BlogPost "My fr1st p0st" johnId; .... }'
困った。
Developing Web Applications With Haskell and Yesodこれは動く
{-# LANGUAGE QuasiQuotes, TemplateHaskell, TypeFamilies, OverloadedStrings #-} {-# LANGUAGE GADTs, FlexibleContexts #-} import Database.Persist import Database.Persist.Sqlite import Database.Persist.TH import Control.Monad.IO.Class (liftIO) share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persist| Person name String age Int Maybe deriving Show |] main :: IO () main = withSqliteConn "test.db" $ runSqlConn $ do runMigration migrateAll -- johnId <- insert $ Person "John Doe" $ Just 35 -- liftIO $ print johnId
insertしたりselectListしたりするとNo instance for (Control.Monad.Trans.Resource.MonadResource IO)が出る。
これか? - Simplified Persistent Types
バージョンを下げたら動いたので当分この組み合わせで使う
19122012 Haskell
diagramsを使ってみた。
{-# LANGUAGE NoMonomorphismRestriction #-} import Diagrams.Prelude import Diagrams.Backend.SVG.CmdLine import Data.Colour tri c n = dots <> (strokeT edges # lc c # lw 0.2 # fcA (c `withOpacity` 0.5)) where rows = map (hcat' with { sep = 1 }) . zipWith replicate [n,n-1..1] . repeat $ dot c dots = decorateTrail (rotateBy (1/6) edge) rows edge = fromOffsets . replicate (n-1) $ unitX # scale 3 edges = close (edge <> rotateBy (1/3) edge <> rotateBy (2/3) edge) dot c = unitCircle # lw 0 # fc c rowSpc = height (rotateBy (1/6) $ strutY 1 :: D R2) row k n s c = hcat' with {sep = 1 + 3*s} (replicate k (tri c n)) law4 k n c1 c2 = vcat' with {sep = rowSpc} (map tRow [1..k]) where tRow k = (row k n 0 c1 # centerX # alignT) <> (row (k-1) (n-1) 1 c2 # reflectY # centerX # alignT) exampleRow f = hcat' with {sep = 4} . map (alignB . f) law4Dia = exampleRow law4' [2..4] where law4' k = law4 k 3 purple gold example = pad 1.1 $ law4Dia # centerXY main = defaultMain example
これだけで下のような図が作成できる

18122012 Python
僕はJade派なのでPythonでもJadeを使うわけだが、jadeテンプレートのなかでゴニョゴニョしたい時にハックっぽいことをしないといけないのは何とかならんかなぁと思っている。
配列のインデックス値が欲しい時
for elm in ary i = ary.index(elm)
とやっている。
Intを文字列にしたい時str関数が使えないので
elm.id.__str__()
とやっている。
pythonの組込み関数使えると嬉しいんだけど、やり方あるのかな?