Haskellでcat

bindの使い方メモ

import System.Environment

cat:: String -> IO ()
cat = (>>= putStr) . readFile

main = do (file:_) <- getArgs; cat file

追記10.02.13

コメントよりheadを使えば一行で書ける。

main=getArgs>>=readFile.head>>=putStr

チャイナカフェ 炎

以前から気になっていたチャイナカフェ炎へ。

1265883510

カニのあんかけチャーハンとラーメン

1265883504 1265883516

上海焼きそばと油淋鶏

1265883491 1265883498

ここは美味いし種類は豊富だし、近いうちにもう一度行きたいところ。

紀土の吟醸と梅酒

紀土の吟醸おりがらみをイワセさんで。

1265883179

若干苦味を感じるが、2Kきってるのでコストパフォーマンスは高い。

そして梅酒は奥さん用

1265883172

kikUUiki / サカナクション

予約した

ProductName kikUUiki(初回限定盤)
サカナクション
ビクターエンタテインメント / ¥ 2,800 (2010-03-17)
近日発売 予約可

PythonでK-means

Haskellな気分で。最後while入れたけど。

from itertools import groupby
from math import sqrt

zipWith = lambda f, xs, ys : [f(x, y) for x,y in zip(xs, ys)]
snd  = lambda x: x[1]
fst  = lambda x: x[0]
euclid  = lambda x, y : (x-y)**2

def distance(a,b): 
    return sqrt(sum(zipWith(euclid,a,b)))

def centroid(clusters): 
    sums = reduce(lambda x,y: zipWith(lambda a,b:a+b,x,y),clusters)
    return map(lambda x: x / float(len(clusters)), sums)

def closest(pts, pt):
    closest_ct = pts[0]
    for ct in pts[1:]:
        if distance(pt,closest_ct) > distance(pt,ct):
            closest_ct = ct
    return closest_ct

def recluster_(centroids,points):
    reclustered = [(closest(centroids,a), a) for a in points]
    reclustered.sort()
    return [map(snd,list(g)) for k, g in groupby(reclustered, fst)]

def recluster(clusters):
    centroids = map(centroid, clusters)
    concated_clusters = reduce(lambda a,b: a+b, clusters)
    return recluster_(centroids,concated_clusters)

def part(l,points):
    size = len(l)/points
    return [l[i:i+size] for i in range(0,len(l),size)]

def kmeans(k,points):
    cluster = part(k,points)
    newcluster = recluster(cluster)
    while(cluster !=  newcluster):
        cluster = newcluster
        newcluster = recluster(cluster)
    return newcluster

if __name__ == "__main__":
    pts = [[1,2,4],[1,3,3],[4,3,0],[2,5,1],[7,3,8],[0,0,0],[4,3,2],[6,1,8]]
    print kmeans(pts,3)

Hakellでテンポラリディレクトリやテンポラリファイル

テンポラリファイルをエディタでいじって、保存するとテンポラリファイルの内容を読んでHsSyckでパースして出力する

import System.IO
import System.Process
import System.Directory
import System.Environment
import Control.Monad (liftM)
import Data.Yaml.Syck

main :: IO ()
main = do
  tmpdir <- getTemporaryDirectory
  (pathOfTempFile, h) <- openTempFile tmpdir "temp.yaml"
  editor   <- liftM (lookup "EDITOR") getEnvironment
  case editor of Just ed -> (>>= waitForProcess) . runCommand $ ed ++ " " ++ pathOfTempFile
                 Nothing -> error "command error\n"
  hClose h

  inpStr <- readFile pathOfTempFile
  yamlstr <- parseYaml inpStr
  print yamlstr

  removeFile pathOfTempFile
  return ()

HoogleGHCの標準ライブラリドキュメントが手放せない身体になってきた。

ProductName Real World Haskell―実戦で学ぶ関数型言語プログラミング
Bryan O'Sullivan
オライリージャパン / 3990円 ( 2009-10-26 )


もっとHaskellの本出ないかなぁ。Principles of Biomedical InformaticsのHaskell阪みたいなのとか。

ProductName Principles of Biomedical Informatics
Ira J. Kalet PhD
Academic Press / 8335円 ( 2008-10-15 )


福梅 - Yuzuka - こどものくに

日曜は犬の餌を買いに。

二日連続ラーメンという娘の主張を退け、昼は福梅でうどんを。

1265714576 1265714582

1265714589

さらに裏手のyuzukaでパンを購入。

1265714570

そのまま、十里木経由でこどもの国で雪遊び。

1265714564

1265714595 1265714601

今日は気温が高くて雪がほとんどとけてしまったので、日曜に行っといて良かった。

HaskellでPitを使う

perlにもConfig::Pitあるし、Pythonにもあるしという状況なので、Haskellでネットワークのちょろっとしたものを書くときにもパスワードをハードコードしないで、pitのやつを使いたかった。

module HsPit (
            pitGet,
            pitSet
           )
where

import System.FilePath ((</>))
import System.Directory
import Data.Yaml.Syck

pitGet :: String -> IO [(String,String)]
pitGet query = do
  home <- getHomeDirectory
  do yaml <- parseYamlFile (home </> ".pit" </> "default.yaml")
     case n_elem yaml of
       EMap list -> return $ map (\keyval -> (,) ((fromYaml . fst) keyval) ((fromYaml . snd) keyval)) $ concatMap (fromEMap . snd) $ filter checkElem list
           where checkElem ynode = ((n_elem . fst) ynode) == (EStr (packBuf query))
       otherwise -> return []
       where 
         fromYaml MkNode {n_elem=EStr str}   = unpackBuf str
         fromEMap MkNode {n_elem=EMap nodes} = nodes

pitSet = error "Not implemented"

HsSyckの使い方はPugsのYamlコードを参考にした。

で、例えばtwitterでつぶやくときには

import Network.HTTP
import Network.URI
import Codec.Binary.Base64.String
import Data.Maybe
import HsPit

tweet username password msg = simpleHTTP req where 
    req = Request uri POST [ah] "" where
        ah = Header HdrAuthorization $ "Basic " ++ encode (username ++ ":" ++ password)
        uri = fromJust $ parseURI $ "http://twitter.com/statuses/update.xml?" 
              ++ urlEncodeVars [("status", msg)]

main = do 
  userdata <- pitGet "twitter"
  case lookup "username" userdata of Just username ->
                                         case lookup "password" userdata of Just password ->
                                                                                tweet username password "tWeet"

なんかごちゃごちゃとしてしまった。

ブレッドボーダーズ

読んだ。Arduinoの本と電子工作の本の中間くらいの内容。

ProductName 武蔵野電波のブレッドボーダーズ―誰でも作れる!遊べる電子工作
スタパ齋藤,船田戦闘機
オーム社 / ¥ 2,520 ()
在庫あり。

これ読んだらテスター欲しくなった。

ProductName Sanwa デジタルマルチメーター PM-3

三和電気計器 / ¥ 3,280 ()


キットはこれがいいらしい。

ProductName ENGINEER(エンジニア) マイキット KS-01

エンジニア / ¥ 5,565 ()


HaskellでYAML

HaskellでYAMLを扱うライブラリはyaml,HsSyckがあるんだけどlibyamlのバインディングであるyamlのほうは使い方がわからん。

なので、HsSyckの使い方を覚えた。

import Data.Yaml.Syck

global_tag  = mkNode $ EStr $ packBuf "Item 1"
name_tag    = mkNode $ EStr $ packBuf "name"
name_value  = mkNode $ EStr $ packBuf "kzfm"
email_tag   = mkNode $ EStr $ packBuf "address"
email_value = mkNode $ EStr $ packBuf "xxx@gmail.com"
pass_tag    = mkNode $ EStr $ packBuf "password"
pass_value  = mkNode $ EStr $ packBuf "snail"

item = mkNode $ EMap [(name_tag,name_value),(email_tag,email_value),(pass_tag,pass_value)]
node = mkNode $ EMap [(global_tag,item)]

main = do
  emitYamlFile "test.yaml" node

作成されたtest.yamlの中身

--- 
? "Item 1"
: 
  ? "name"
  : >-
    kzfm

  ? "address"
  : >-
    xxx@gmail.com

  ? "password"
  : >-
    snail

これをperlでparseしてみる

use YAML;
my $filename = "test.yaml";
my $doc = YAML::LoadFile($filename);
print YAML::Dump($doc);

実行結果

---
Item 1:
  address: xxx@gmail.com
  name: kzfm
  password: snail

ナイス!