杉山フルーツの生ゼリー

二年くらい前に行ったきりだったが、みんなが食べたいと言ったのでまた行ってみた。

そういえば、高糖度トマトを使用した生フルーツゼリーはブログで見かけて気になっていたので購入

1298158599

これは美味かった。トマトなのに砂糖が入ってんじゃないかってくらい甘い。トマト好き兼ゼリー好きの娘と息子にスマッシュヒット。

僕はパッションフルーツを選択。これも酸味が効いていて種のプツプツ感とゼリーの固さが絶妙で美味かった。

1298158615

一方、フルーツミックスは前回同様イマイチ響かなかった。多分、ゼリーと果汁が分離しているのはあんま好みじゃないんだな。娘はゼリーと果実を分離しながらおいしそうに食べてたけど。

次のコミュニティFで勉強会の際にはおやつ候補にあげておこうかな。買えるかどうかわからんけど。

「Javascriptパターン」を読んだ

Perl Best PracticesのJavascript版という位置づけの本かな(でも薄い)

ProductName JavaScriptパターン ―優れたアプリケーションのための作法
Stoyan Stefanov
オライリージャパン / 2940円 ( 2011-02-16 )


まえがきにもこう書いてある

この本は入門書ではありません。Javascriptの技をもう一段上に引き上げたい、そういう開発者やプログラマを想定しています。

Perl Best PracticesとかエキスパートPythonプログラミングを読んでるようなヒトが「Javascriptのお作法ってどうすればいいのかね?」となったときに役立つことが書いてあると思う。

二章にコーディングの作法が載っているでひと通り目を通すと良い感じ。

ちなみに個人的には最近読書会でJavascriptの名前空間ってどう管理すんだよ?という疑問がわいてそのままだったのだけど5章に丁寧に書いてあったのですっきりして良かった。

6章はコンストラクタと継承の話で、これだけに一章を割いている。クラスっぽく書くやり方をクラシカル、プロトタイプベースの継承をモダンって読んで両方紹介してた。

7章はいわゆるデザパタ。GoFのデザインパターンのうちの9つを紹介しているが、この章はあまり興味が持てなかったので流し読みした。

8章はブラウザでのパターンの紹介。

4,5,6章が特に面白く読めた。

JGPは良いJavascriptの文法を学ぼうという本なのに対して、本書は実用的なJavascriptを書くにはどうしたらよいかに対してヒントを与える本かな。

今日の畑(110219)

久々に行ったら雑草が生えてきてたので抜きまくった。あとは牛肥入れて石灰撒いて、ジャガイモを植える準備をしてきた。ちなみに紅あかりを植えることにしたが、娘がコロッケ作りたいって言ってたのが選定の理由。

ソラマメは育ってきた。スナップエンドウ(右)は4株植えてみたけど寒さ対策してなかったので2株しか残ってない。

1298110114 1298110098

春菊はちょっと間引いた。大きくなったらとっとと収穫したい。右はニンニクと春菊

1298110092 1298110108

浅葱も新芽が出てきたので来月辺りから収穫できるようになるかな。

1298110120

JGP 2章の例外処理

JGP読んでてよくわからなかったのが、throwするのはnameとmessageのプロパティを含むオブジェクトリテラルを投げるというところで、

try {
  throw {name:"TestError", message:"oops"}
} catch(e) {
  console.dir(e);
}

のあたり。Errorオブジェクト投げないのはなんでだろか?

var e = new Error("oops");
console.dir(e);

ってやるとnameとmessage(と他に幾つか)のプロパティに値が入ってるから、直接nameにエラーに対応する名前入れるだけでいいじゃんという判断なんだろうか?

そしたらErrorオブジェクトを用意する必要ない気がすんだけど。

ProductName JavaScript: The Good Parts ―「良いパーツ」によるベストプラクティス
Douglas Crockford
オライリージャパン / 1890円 ( 2008-12-22 )


なんか深い理由があるんだろうかね。

Javascriptで末尾最適化

元ネタはspencertipping / js-in-ten-minutes

Function.prototype.tail = function () {return [this, arguments]};
Function.prototype.call_with_tco = function () {
  var c = [this, arguments];
  var escape = arguments[arguments.length-1];
  while(c[0] !== escape)
    c = c[0].apply(this, c[1]);
  return escape.apply(this,c[1]);
};

// var sum  = function (n,acc) { return n > 0 ? sum(n-1,acc+n) : acc};
var sum2 = function (n,acc,k) { return n > 0 ? sum2.tail (n-1,acc+n,k) : k.tail (acc);};
var id   = function (x) {return x};
console.log(sum2.call_with_tco(100000,0,id));

これはDelimited Continuationになっているらしい。コードの動きは分かるけど継続とDelimited Continuationの違いが良くわからん。

選曲候補を記録するスクリプトをPythonで書いた

DJ選曲術を読んだり田中フミヤのviaのダイジェストを見たりしてたら、選曲というものが楽しくなってきた。どういう曲のつながりを気持いいと思うかは結局自分をよく知ることになるので意味のある行為ではないかと思う。

で、iTunesで聴いてる曲のつながりを記録するCUIアプリをPythonで書いてみた。単にヘッドとテイルを記録するだけの有向グラフなんだけど、sqliteにぶち込んでいるので後から検索するとき便利だと思う。データが溜まったらチェインをたどりながらplaylistに書きだすようなスクリプトも用意しようかな。

あとは選曲のつながりぐあいをnetworkxとかcytoscape視覚化して見てみたいという個人的な興味もあったりするのでそういうデータが欲しかったりする。

djutil

h(head)を押すとヘッドに現在聴いてるiTunesの曲名が、t(tail)だとテイルに挿入されてヘッドとテイルが揃うとグラフとして追加されるようにしてある。q押すとquitするようにしてあるんだけどquitしないのでなんかおかしい。後でどうにかする

そのうちGitHubで管理する予定

以下コード

#!/usr/bin/python
# -*- encoding:utf-8 -*-

# kzfm <kerolinq@gmail.com>

import curses
import os
from ScriptingBridge import *

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine,Column,Integer,String,ForeignKey,UniqueConstraint
from sqlalchemy.orm import scoped_session,sessionmaker

DATABASE = '/Users/kzfm/djutil.db'
engine = create_engine('sqlite:///'+DATABASE)
Session = scoped_session(sessionmaker(autocommit=False,
                                      autoflush=False,
                                      bind=engine))
Base = declarative_base(bind=engine)

class Music(Base):
    __tablename__ = 'music'
    __table_args__ = (UniqueConstraint('title','artist'),{})
    id = Column(Integer, primary_key=True)
    title  = Column(String(128))
    artist = Column(String(128))

class Graph(Base):
    __tablename__ = 'graph'
    __table_args__ = (UniqueConstraint('head','tail'),{})
    id = Column(Integer, primary_key=True)
    head = Column(Integer, ForeignKey('music.id'))
    tail = Column(Integer, ForeignKey('music.id'))

def main(stdscr):
    if not os.path.isfile(DATABASE):
        Base.metadata.create_all()

    session = Session()

    iTunes = SBApplication.applicationWithBundleIdentifier_("com.apple.iTunes")
    stdscr.nodelay(1)
    head_music = None
    tail_music = None

    while True:
        c = stdscr.getch()
        y,x = stdscr.getyx()
        if c == ord('h'):
            artist = iTunes.currentTrack().artist()
            title  = iTunes.currentTrack().name()
            head_music = session.query(Music).filter(Music.artist == artist) \
                                             .filter(Music.title == title) \
                                             .first()
            if head_music == None:
                head_music = Music(artist=artist,title=title)
                session.add(head_music)
                session.commit()

            if tail_music != None:
                mg = session.query(Graph).filter(Graph.head == head_music.id) \
                                             .filter(Graph.tail == tail_music.id) \
                                             .first()
                if mg == None:
                    mg = Graph(head=head_music.id,tail=tail_music.id)
                    session.add(mg)
                    session.commit()

                stdscr.addstr("%s / %s -> %s / %s" % (head_music.title,head_music.artist,tail_music.title,tail_music.artist))
                stdscr.move(y+1, 0)

                tail_music = None
            else:
                stdscr.addstr("%s / %s -> [] / []" % (head_music.title,head_music.artist))
                stdscr.move(y, 0)

        elif c == ord('t'):
            artist = iTunes.currentTrack().artist()
            title  = iTunes.currentTrack().name()
            tail_music = session.query(Music).filter(Music.artist == artist) \
                                .filter(Music.title == title) \
                                .first()

            if tail_music == None:
                tail_music = Music(artist=artist,title=title)
                session.add(tail_music)
                session.commit()

            if head_music != None:
                mg = session.query(Graph).filter(Graph.head == head_music.id) \
                                             .filter(Graph.tail == tail_music.id) \
                                             .first()
                if mg == None:
                    mg = Graph(head=head_music.id,tail=tail_music.id)
                    session.add(mg)
                    session.commit()

                stdscr.addstr("%s / %s -> %s / %s" % (head_music.title,head_music.artist,tail_music.title,tail_music.artist))
                stdscr.move(y+1, 0)
                tail_music = None

            else:
                stdscr.addstr("[] / [] -> %s / %s" % (tail_music.title,tail_music.artist))
                stdscr.move(y, 0)
        elif c == ord('q'):
            exit
        elif c != -1:
            # debug
            stdscr.addstr(str(c))
            stdscr.refresh()
            stdscr.move(0, 0)

if __name__ == '__main__':
    curses.wrapper(main)

「数学ガール/乱択アルゴリズム」を予約した

早速予約

ProductName 数学ガール/乱択アルゴリズム
結城 浩
ソフトバンククリエイティブ / 1995円 ( 2011-03-02 )


楽しみですな。

栗駒山

宮城のお酒。酒造好適米「蔵の華」を使った純米吟醸

1297768431

綿屋と比べて、酸が強めだったが色々試した結果、ぬる燗がベストだという結論に至り、後半はぬる燗で。これはこれで美味い気がする。飲み飽きしないし。

燗つけるといっても最近はひと肌よりもぬるいくらいの燗なんだかわからないような温度帯が好み。室温よりも冷たい気がするなぁ。

今度きちんと計ってみよう。

Javascriptのboxedとunboxed

メモリ上に直接のっているような値はunboxedなのでプロパティの設定ができない。数値リテラルとか。

var x = 1;
x.add1 = function () {return this.valueOf() + 1;} // これはだめ
console.log(x.add1());

でもコンストラクタからnewされた場合にはプロパティの追加ができる

var x = new Number(1);
x.add1 = function () {return this.valueOf() + 1;} 
console.log(x.add1());

コンストラクタのprototypeに関数突っ込んでチェインできるようにしてみる。

var x = new Number(1);
Number.prototype.succ = function () {
  var n = new Number(this+1);
  return n;
};

console.log(x.succ().succ().succ().succ().toString());

リテラル表記でもNumberから継承されているので、コンストラクタのprototypeに関数突っ込めばメソッドとして呼び出せる

var x = 1;
x.constructor.prototype.succ = function () {
  var n = new Number(this+1);
  return n;
};

console.log(x.succ().succ().succ().succ().toString());

これはなかなか面白い