Hatena::ブログ(Diary)

西尾泰和のはてなダイアリー

2010-09-29

たまにはブログを書く

やる夫と Python で学ぶ Twitter の OAuth - YoshioriのBlog

よいまとめ!


はてブコメントより引用

id:agricola Python, あれげ リスト内包の使い方に美がないなぁ……。辞書のキーと値を、キーで並べ替えて取り出して=で連結するなら

['='.join((k, v)) for k, v in sorted(d.items(), key = lambda x: x[0])]

とか書く気がする。

そんな餌で俺様が釣られクマーーーーーーっ

>>> ['='.join((k, v)) for k, v in sorted(d.items(), key = lambda x: x[0])]
['a=k', 'b=j', 'c=i', 'd=h', 'e=g', 'f=f', 'g=e', 'h=d', 'i=c', 'j=b']

ふむ。なんだこのゴテゴテといらないものがくっついたコードは。

>>> ['='.join((k, d[k])) for k in sorted(d)]
['a=k', 'b=j', 'c=i', 'd=h', 'e=g', 'f=f', 'g=e', 'h=d', 'i=c', 'j=b']

>>> ['%s=%s' % (k, d[k]) for k in sorted(d)]
['a=k', 'b=j', 'c=i', 'd=h', 'e=g', 'f=f', 'g=e', 'h=d', 'i=c', 'j=b']

>>> ['%s=%s' % p for p in sorted(d.items())]
['a=k', 'b=j', 'c=i', 'd=h', 'e=g', 'f=f', 'g=e', 'h=d', 'i=c', 'j=b']

どれでもOK。僕なら2番目で書くかな。挙動は100%イコールというわけではなくて、"%s=%s"の方は辞書の値がstrでなくてもエラーにならない。


でもまあ、OAuthをコード付きで解説することがみんなに与えた価値に比べれば、1行のコードをどう書いたらきれいかだなんて1000分の1の価値もないよなー。つまりYoshiori GJ!!!

P.S. ついコメント欄のコードだけ見てつっこんでから気づいたけど、OAuthのどこに「ソートしてから結合したい辞書」が出てくるんだ?


id:showyou OAuth関連のパラメータ(oauth_signature_methodとかoauth_nonceとか)を送るときにはパラメータをソートした状態で送んないとダメ

なるほど、順番が変わるとハッシュ値が変わってしまうからかな。


id:agricola Python, あほか urllib.quote()でクォートした文字列を=で連結してるのに%使えば文字列以外もOKとは的外れな。元コードの意義は否定しないが、リスト内包で可読性を低下させて技巧に走ったのに美が無いのはいただけない。

(つд⊂)ゴシゴシ (;゚д゚) (つд⊂)ゴシゴシ

挙動が100%イコールじゃないよ、って書いただけなのに的外れって言われた。ふむ。はてブに書いてあったコードと等価なコードが元記事のどれなのかわからなかったのではてブに書かれていたコードが受理できる入力なら何でも受理できるように書いたというだけの話。日本語がよくわからないけど「リスト内包で可読性を低下させて技巧に走ったのに美が無い」って、もちろん僕のことじゃないよね?自虐コメントかー。


某チャットより転載(改行詰めたり誤植直したり言葉補ったりしてあります):

tokibito: ところで内包表記の元記事の該当のコードって

# パラメータをソートし,URIエンコードした key=value の形にして & で繋げます
params_str = '&'.join(['%s=%s' % (urllib.quote(key, ''),urllib.quote(params[key], ''))
                       for key in sorted(params)])

これ?

西尾泰和: そうなの?だったら僕の書いたコードとほぼ同じじゃない?これを添削して(quoteとかをすてて)はてブコメントのあれになってたの?それってquoteすてたから綺麗になったんじゃないの…

tokibito: そもそもurlencodeでいいような気がした

西尾泰和: urlencodeは忘れたが、なんかこういうの標準ライブラリにすでにありそうな気はした。urlencodeか。

tokibito: urllib.urlencode

西尾泰和: >Convert a mapping object or a sequence of two-element tuples to a “percent-encoded” string

西尾泰和: これでいいじゃんね

tokibito: ソートしたタプルを渡してもいいし、順序保証付きの辞書使ってもいいし。本気で書くならそうする

西尾泰和:

>>> urllib.urlencode([(k, d[k]) for k in sorted(d)])
'a=k&b=j&c=i&d=h&e=g&f=f&g=e&h=d&i=c&j=b'

したかったことはこうなの?

tokibito: だと思うんだけどどうだろう。そもそも内包表記に関する指摘が蛇足な感じか

西尾泰和: っていうか元コードのどれに対する指摘なのか読んでなかったんだけど、元コードを変に添削したのを僕が元コード見ずに添削したら元コードとほぼ同じに戻ったってこと?

tokibito: そんな気がする


チャット続き

yoshiori: urllib.urlencodeは、駄目だお。スペースを + にしちゃう。あと、外の指摘で判明したんだけど、 ~ もエスケープしちゃだめ

yoshiori: http://tools.ietf.org/html/rfc5849#section-3.6

yoshiori:

>>> urllib.urlencode({'foo':'bar hoge'})
'foo=bar+hoge'
>>> urllib.quote('bar hoge','~')
'bar%20hoge'

あとはてブコメントでも:

id:mattn urlencodeは内部でquote_plus使うので%20の結果が違って認証失敗するんじゃないかな。あと、quoteでちゃんとやるなら urllib.quote(s, safe='~') かも

thanks!

2010-09-26

黒魔術について

Twitterから引用

黒魔術を使ってDSLを作り易くしている言語の作者たちって、ファイル冒頭でuse BlackMagic;しないと黒魔術使えないようにするとかuse BlackMagic::MetaClassHack;とか書かせてどんな魔術が使われているか明示的にするとか考えないのかなぁ

nishio/nishio hirokazu 2010-09-25 15:53:05

PythonのPEP 20には「明示的なのは暗黙的なのより良い(Explicit is better than implicit)」と書かれており、「C++の設計と進化」P.284には「柔軟性や表現の自由を求める気持ちと、安全性、予見性、そして単純性を望む気持ちは衝突する」と書かれている。実際にOption Explicitやuse strictなどの「柔らかくしすぎた言語を固くするオプション」が導入された事例もある。

もう柔軟性を重視する言語設計は避けたほうがいいんじゃないの?


話者に理解できるものが「言語の機能をうまく使ったクールなハック」であって、できないものが「黒魔術」なのでは。太古の強力な魔術に「LISPのマクロ」があるが、普及しているとは言いがたい。強力な魔術であればあるほど、理解する人は少なくなり、黒魔術として忌み嫌われる。

2010-09-23

SPYSEEの会社に遊びに行ってきました

先週の金曜日、id:amachangの新しい会社(オーマ株式会社)に遊びに行ってきました。

f:id:nishiohirokazu:20100917182652j:image

正直なところ、最初に話を聞いたときには誰か悪い人に騙されてるんじゃないかとか思ったけども、中を見てみたらアットホームな雰囲気のベンチャー企業でした。目標が熱い!世界を変えるSPYSEEへ!

f:id:nishiohirokazu:20100917190111j:image

受託抜きできちんと黒字化してるところや、良好な産学連携関係を構築しているところも考えると、世の中のベンチャー企業の中ではかくだんに「いい会社」の部類に入ると思いました。amachangが入ることでどんな化け方をするのか、今後が楽しみです。


ちなみにamachangが弊社を退社した日の僕のエントリー「SPYSEEのトップに美人画像が出るようになっている!」は伏線だったのですが、転職先予想トトカルチョ #amatoto には影響を与えなかったようでした(苦笑) id:yukobaの「@yukoba なるほど!もっと燃料を投下しよー!僕は"amachang 転職先の会社名"でGoogleで最初に出るページに、いたずらしてるんだけど直されちゃう。かわいいのにぃ〜〜」でいたずらされたかわいいamachang画像はこちら> http://b.hatena.ne.jp/entry/spysee.jp/amachang/1013724/

多重継承まとめ

JavaはInterfaceという特殊な実装を持たないものだけ多重継承できる。実装を多重継承する仕組みはない。同じシグネチャのメソッドを持っている2つのInterfaceを継承した際にエラーにならないので衝突に気付けない。

Pythonはクラスを多重継承できる。同じ名前のメソッドを持っている2つのクラスを継承した際にどのメソッドが呼ばれるかはC3線形化を使って決定される。see: A Monotonic Superclass Linearization for Dylan

RubyはModuleという「なにかを継承することはできなくてインスタンス化もできないもの」だけは多重継承できる。Moduleが別のものを継承できないためメソッドの解決は素朴な探索でOK(include A include BしたらBでの実装が優先)

SmalltalkにはTraitという実装の多重継承ができるしくみがある。同じシグネチャのメソッドを持っている2つのTraitを継承した際に、片方を隠して衝突を回避したり、名前を変更して両方呼べるようにしたりできる。 see: Traits: Composable Units of Behavior

ScalaのTraitは名前はTraitだがSmalltalkのとは大きく違う。同じシグネチャのメソッドを持っている2つのTraitを継承した際に、片方を隠して衝突を回避したり、名前を変更して両方呼べるようにしたりすることができない。メソッドにoverride修飾子がついていない場合はエラー、付いている場合はPythonと同じように直列化を使ってどのメソッドを呼ぶか決定する。

Perl6からRoleが入る。これはSmalltalkのTraitとほぼ同じもの。see http://publius-ovidius.livejournal.com/314737.html

PHPはJava風の単一継承、インターフェイスとかも持っている。PHP5.4からTraitが入る。これはPerlのRoleとほぼ同じもの。PHP: rfc:traits [PHP Wiki]

Acknowledgement

Python以外の知識は id:sumim, id:moriyoshi, id:kmizushima に教えていただきました。ありがとうございます!

Q&A

id:yujiorama C++/D が無いのはなんでだろう。既知だからか

C++, D, C#, OCaml, Eiffel, その他数多くのオブジェクト指向言語の記述が抜けているのは、たまたま話題に上がらなかったか、簡潔に整理できなかったか、書いても面白く無かったからです。 You can contribute!

2010-09-22

1377136101094667656108956765175025610

【鍵】 「算盤の書」


特別能力検定・第1回暗号検定-知的財産教育協会

今日の昼休みは光成さんがこの問題をプリントアウトして持ってきて「Aのヒントを見てこれが答えだと思ったけどもフェイクだったみたいで提出しても正解だって返事が来なかった」というので眺めてみた。Bのヒントを見てこれはアレじゃないの、とPythonで5行くらい書いてみたら光成さんの解答と同じ結論に到達したのでやっぱ答えはそれだと思うんだけどなぁ。答えと特Aの出題との間のマッピングルールがわからないのであった。

レバレッジメモ: C++の設計と進化

全部を読んでレバレッジメモ化するのはまだ時間の余裕がなくて出来てないけど、近いうちに使いそうなところだけメモしておく。

P.283 C++はCやFortranのように暗黙の昇格を選んだことによって、完全な解決のない困難な領域に入り込んだ。

P.284 柔軟性や表現の自由を求める気持ちと、安全性、予見性、そして単純性を望む気持ちは衝突する。

okyuu.com のインタビュー記事の転載許可を頂いた話

okyuu.com でインタビューしてもらった記事が消えちゃったので許可貰って転載します!! - YoshioriのBlog

yoshiori: みんな書かないからどうしたんだと思いつつ書いた

ひー。ちょっとドタバタしてて作業が進んでないのでした!

カカクコムの堀様に転載していいかどうかをお尋ねしたところ、ちゃんと会社側に確認を取った上で「まったく問題ない」とのご回答をいただきました。ただし「okyuu.comのロゴを使わない」という条件は付いています。

僕の手元にはwget -rしたので多分全員分のファイルがあるはずですがドタバタしてて自分のしか確認していない&ロゴを外してアップロードするつもりだったけどまだしていない、という状態です。

2010-09-19

プログラミンで論理回路

http://www.mext.go.jp/programin/app/

「状態がないからプログラミング難しい」「GOTOが9個しか使えないから無理」と言われたので「いや状態はあるでしょ。変数の形になってないだけで。GOTOもなくていいし」と思ってちょっといじってみた。

移動がグローバル座標系なのはどうなんだー。あと条件分岐が少なすぎて辛いね、実質的にプログラムで使えるのは衝突判定くらいか。

とりあえずNOT回路を作った

緑四角が青玉を吐きつつ、赤玉にあたったときには場所をずらすので「あたってないときに玉が飛ぶ位置」に物を置けばそれの衝突イベントは「赤玉が出ていないとき」というNOTの値になる。

お、公開すればリンクを貼れるのか http://www.mext.go.jp/programin/share/?share_id=be612f8f3bf4b925886c454813772c84 あ、でもできたアプリで遊べるだでコードを読んだり書き換えたりはできないのか。残念。

続いてAND

下の矢印から青玉、上の矢印から赤玉が出るので、その両方が緑四角にあたった時だけ紫玉を出す。

肝心のコードはこちら:

簡単にいえば緑四角は「青玉があたった時だけ上に上がって赤玉の進路に入る」&「赤玉のにあたったら(それは青玉もあたってるってことだから)紫玉を打つ」ってだけ。残りの二つのルールは緑がどっかにいってしまわないように置いてある壁(五角形・六角形)との衝突処理ね。並列実行の中に無限回実行を入れてその先頭で衝突判定を使ってwaitさせることで衝突イベントをトリガーとしたコードが書けるわけだ。


物はこちら: http://www.mext.go.jp/programin/share/?share_id=eecbde1436a30bcc6401b886ade368fe

さて、NOTとANDが作れれば二進数の足し算が出来るわけだが、もうあとは頑張るだけなのでやる気が無くなった。誰か気が向いたらやって(ぇ

参考文献: 加算器 - Wikipedia

ORはANDの入力と出力にNOTを付ければ作れる。あ、でもプログラミンではORを作るほうがANDを作るよりもコストが低いな。直接作るほうがよさそうだ。

レバレッジメモ: Scalaスケーラブルプログラミング

言語も伽藍とバザールのように成長する--Steele "Growing a language" 1999

トレイト=インターフェイスに似ているがメソッド実装やフィールドを持つ、ミックスイン合成出来る

JavaのStringにtoIntがないことに気づいたときに、暗黙の型変換を参照してRichStringに変換し、そのtoIntを呼ぶ

アラン・ケイ「私は型に反対しているわけではない。『完全な苦痛』にはならないような型システムを見たことがないので動的な片付けを支持しているのである」2003 Dr. Alan Kay on the Meaning of "Object-Oriented Programming"

ダイクストラ「テストが証明できるのはエラーの存在であって、エラーの不在ではない」 1970 http://www.cs.utexas.edu/users/EWD/ewd02xx/EWD249.PDF

「ことなる応用分野への拡張性を持った言語」というアイデア1966 The next 700 Programming Languages http://www.thecorememory.com/Next_700.pdf

(arg: String) => println(arg)をprintlnって書けるのを「関数の部分適用」と呼ぶのは気持が悪いなぁ。 P.51

末尾がコロンである演算子は右オペランドのメソッドである

コンパニオンオブジェクト 4.3

タプルとリストの両方があって両方イミュータブル。Haskellのタプルとリストだと思えばだいたいあってる

フィールドとメソッドを総称してメンバーと呼ぶ。メンバーはデフォルトでpublic

varとvalがある。valは再代入不可。

Scalaのクラスは静的メンバ(static)を持てない。そのかわりにシングルトンオブジェクトがある。classキーワードの代わりにobjectキーワードを使う。シングルトンオブジェクトがクラスと同じ名前の時にコンパニオンオブジェクト、コンパニオンクラスと呼ぶ。同じ名前のクラスがないシングルトンオブジェクトはスタンドアロンオブジェクト。

import文で任意のオブジェクトからメンバーをインポート出来る。

すべてのメソッドが演算子になれる。s.indexOf('o')をs indexOf 'o'と書ける。

論理演算子もメソッド→じゃあショートサーキットはどうやってる?→実は全てのメソッドで名前渡しが可能(9.5)→なんだって!!

===各引用ごとにページ数を書くのは面倒なのでここでP.100===

イミュータブルなオブジェクトのトレードオフ P.105

長所:複雑な状態変化をしないので動作を推定しやすい、他のコードに渡す際に破壊を避けてコピーをとる必要がない、スレッドが同時アクセスしても壊れない、安全にハッシュのキーにできる

短所:大規模なオブジェクトのコピーが必要になることがある

P108 クラスパラメータはコンストラクタ内からしかアクセス出来ない?→クラスパラメータをフィールドに代入して解決→え、なんのためのクラスパラメータ… 10.6のパラメータフィールドで解決される??

def this(n: Int) = this(n, 1)で「2番目の引数に1を入れてコンストラクタを呼ぶ」っていう補助コンストラクタができる。基本コンストラクタだけがスーパークラスのコンストラクタを呼び出せる。これはJavaより若干制限が強い。see sec.10

演算子メソッドを使えばコードは簡潔になる、しかし読みやすくなるかどうかはクライアントプログラマが個々の演算子の意味を理解して覚えられるかどうかによる P.120

Scalaでは関数リテラルとの相性が悪いbreakとcontinueを取り除いている。末尾再帰や、whileの条件にtoExit的変数を入れたりループの後半をifで囲ったりすることでbreakやcontinueがなくても同等なコードが書けるという説明がされている。まあ、そりゃそうだけどね。どう相性がわるいのか知りたいけどどこに書いてあるのかわからない。

Scalaはネストしたスコープの内側で外側の変数をシャドーするような変数を定義できる。

「一人前の存在としての関数」(first-class functions)!

「(x: Int) => x > 0」は「_ > 0」とも書ける。「_ + _」は1引数の2倍になる関数ではなく2引数の足し算をする関数

Javaの内部クラスは外側のスコープで書き換えられる可能性のある変数にはアクセス出来ない。Scalaのクロージャは直感的に言えば変数事態を掴んで「閉じた」ものである。

Scalaは末尾再帰をジャンプに変換するので、末尾再帰の関数が失敗した時のスタックトレースにはいくつもの関数が出てこない。紛らわしい時は-g:notailcallsオプションでOFFにする。末尾再帰の最適化は文字通り自分自身を呼ぶ再帰の時にしか使えない。相互再帰や他の関数の呼び出しは最適化されない。

def foo(f: () => Boolean) = ...で定義される関数は foo(() => x > 0)と呼べる。これをdef foo(f: => Boolean)にするとfoo(x > 0)と呼べるようになる。foo(v: Boolean)との違いは評価のタイミング。これが名前渡しパラメータ。

単純なオブジェクトとは何か、単純なオブジェクトからより面白いオブジェクトを作るにはどうすればいいか、コンビネータ(合成演算)はどう組み合わされるか、最も一般的なコンビネータは何か?これらに答えられるならライブラリ設計は軌道にのっていると言えるだろう。P.173

サブクラスとサブ型の違い: 型引数を取らないクラス・トレイトに関してはサブクラスとサブ型は同じ。型引数を持つ場合それが共変(たとえばListはList[+A]なのでList[Cat] <: List[Animal])ならサブ型

パラメータフィールド:要するにclass Foo(val arg: Type)って書き方でフィールドもつくれる。class Foo(override val x)とかprivateなどの修飾も付けられる。

親クラスのコンストラクタは基本コンストラクタからしか呼べない。class Foo(...args...) extends SuperClass(...args for superclass...)

具象メンバのオーバライドにはoverride修飾が必須

Scalaスケーラブルプログラミングのレバレッジメモ


呼び出されるメソッドの定義は変数の型ではなく実行時のオブジェクトのクラスによって決まる。動的束縛。

継承を使う前にis-a関係かどうかを考えろ(Mayers, "Effective C++" 1991)、また、スーパークラス型としてサブクラス型を使いたいかどうかを考えろ(Eckel, "Thinking in Java" 1998)

最下位(bottom)の型: Null, Nothing。Nullは全ての参照クラス(AnyRefクラスを継承するクラス)の小クラス。Nothingは全ての小クラス。たとえばerrorの返り値など。失敗しうるIntを返す関数の型をMaybe Intとかにしない。Intを返して、エラー時には例外機構でNothingをIntとして使う前に別の処理に飛ばされる。

P.204 トレイト トレイトはクラスみたいなもの。違いはsuperの指すものが何か。traitのsuper呼出はそれがクラスにミックスインされたあとで線形化によって決まる。そのためtraitのabstractメソッドの中ではsuper.a_methodにアクセスすることができる。これはa_methodの具体的な定義を提供するクラスのあとでmixinしなければならないことを表明している。

このことによりtraitという形で表現された「変更の差分」を積み重ねることができる(僕は差分を積み重ねるコーディングスタイルがよいものかどうかは疑問だが)

Scalaのimportはどこにでも書ける。オブジェクトもインポートできる。インポートされたメンバの名前を変えられる。

クラスとコンパニオンオブジェクトは相互にprivate無視。これを使ってstaticメンバの代わりにする。

ケースクラス。

abstract class Expr
case class Var(name: String) extends Expr
case class Number(...) extends Expr
case ...

パターンマッチに使う。

ScalaもJavaも消去モデル(erasure model)のジェネリックプログラミングなので与えられたMapオブジェクトがMap<Int, Int>なのかどうかを知る方法は存在しない。

sealedクラスにすると同じファイルで定義されているサブクラス以外にはサブクラスを作ることができなくなる。

型パラメータとサブ型の組み合わせは面白い問題をはらんでいる。S <: T (SがTが期待されている箇所で型安全に使用できる)の時、Foo[S] <: Foo[T]ならFooは共変(covariant)といいFoo[+T]と表現する。Foo[-T]もありこれは反変(contravariant)。T <: Sの時にFoo[S] <: Foo[T]という意味。非変(nonvariant)はそれらの関係が成り立たないことで、デフォルトではこれ。Javaの配列は共変である。Object[]には任意のFooBar[]が入る。これはString[]にObject[]を介してIntegerを入れられてしまうということで、実行時エラーを引き起こす。ゴスリン曰く配列をジェネリックに扱う方法が欲しかった(P.358)しかし今ではJavaにもジェネリクスの機能が入っているので配列の共変は必要ではない。互換性のために残されている。

下限境界。def append[U >: T](x: U)などという書き方ができる。TかTのスーパクラスであるものを引数に取るという意味。上限境界もある。[T <: Ordered[T]]

lazy val x = ...;で遅延評価

暗黙の型変化。x + yがないときにconvert(x) + yが可能ではないか調べる。に通りの方法があるときはコンパイルエラー。型変換は1回しかしない。書かれているとおりで動く場合には変換しない。

むう、駄目だ、さすがに一気に読むのは脳が疲れた。まだ共変・反変の話と暗黙の型変換が残ってるんだけど、続きは今度。(追記した)

プログラミンで半加算器

頭が疲れたので息抜きに作ってみた http://www.mext.go.jp/programin/share/?share_id=4ade3b8667ce044112ec9001c9998cb4

左端の矢印をクリックすると入力の1/0が切り替えられる。右に玉が出ている状態が1なので、初期状態では 1 + 1 になる。右端で上方向に出る黒い丸が計算結果で、左側が2の位、右側が1の位。二進法では 1 + 1 = 10 だから最初は左だけに玉が出る。左の矢印をクリックして 0 + 1 や 1 + 0 にすると結果が 01 になり、0 + 0 にすると 00 になる。

Gyazoを1.0にアップデートしたらなぜか動かなくなってしまったのでスクリーンショットは省略。

ORを使った方が楽じゃないかって自分で書いておきながら使うのを忘れている罠…

2010-09-18

Omnigraffleの和文フォントがずれてる

便利なツールなんだけど

これってなんとかならないのかな。

2010-09-16

genkoに脚注機能をつけよう

HTMLで雑誌の原稿を書くためのツールで原稿を書いている。脚注を本文中に書きたいけど、見るときには本文中には(*)とか出して、脚注の本体は本文とは別のところに出したい。

<a class="footnote">(脚注: ほげほげ)<;/a>

と書くと本文としては(*)になってくれて、僕のCSS力では脚注・傍注として表示するのは難しいので、とりあえずクリックしたらalertで出すようにしようと思った。

これがそのコード

    // 脚注span.footnoteを(*)で表現
    $(".footnote").each(function(){
	var text = this.innerHTML;
	this.innerHTML = "(*)"
	this.href = "#";
	$(this).click(function(){
	    alert(text);
	});
    });

だけどクリックしてもalertがでないんだよな。何がいけないんだろう?


ああ、わかった、hrを本文の裏に入れたくて#containerでz-index: -2、hrでz-index: -1とかやっていたのがいけないようだ。これは親エレメントの値からの相対値で、これだとhrが-3になってしまう。あと負の値にはあまりしないようだ。多分これが原因でclickイベントをbodyとかが受け取ってしまってたんだろう。コンテナでz-index: 2をしてhrでz-index: -1したら期待通りの挙動になった。

2010-09-15

SPYSEEのトップに美人画像が出るようになっている!

あのひと検索 SPYSEE [スパイシー]

日替わりらしい。

で、これってどうやって美人かどうか判断してるんだろう?

2010-09-11

HTMLで雑誌の原稿を書くためのツール

こんなの作った

モチベーション

テキスト形式での納品を求められるけども、もうちょっとメタデータの乗せやすいフォーマットで書きたいなぁ、ついでに言えば自分が今どれくらい書けているかのイメージを掴む上でも、人に渡してレビューしてもらうにしても、編集しているものが手軽に見やすい形にできるといいなぁ。プログラムで扱うのが楽なフォーマットがいいなぁ。ってそれHTMLでいいんじゃない?

過去の実装

Jython本を執筆するときは「求められているテキストフォーマットに最低限のメタデータを載せられるようにした独自フォーマット」からHTMLと納品用テキストに変換していたが、メタデータの載せにくさと自分の書いている原稿のプレビューのたびに変換スクリプトを走らせるののめんどくさにこのアプローチはダメだと思った。

現在の仕様

1行23文字、1ページ42行、1ページ2カラム構成の紙面を想定。 JSとCSSで真面目に2カラム構成をやる気にはならなかったので1カラムだけを縦に表示して、およそ1ページ分の間隔で赤い横線をひくことにした。文字のフォントサイズは17pxに固定して、カラムの幅は400px(17 * 23 = 391)、ページの縦幅は1114px (17 * 42 * 1.5 = 1071)にしてある。Firefox以外だと想定外になったりしそうな気もするが、まあとりあえず原稿を書いてから考えよう。

出力フォーマット
$ convert.py genko.html

ってやると標準出力にタグとかdiv class="ignore"で囲われた部分とかを取り除いて出力するんで適当にリダイレクトしてファイルに保存してください。-oってオプションをつけるとアウトラインモードとして表題だけ出力するよ!

ライセンス

GPLv3だよ!あたりまえだけどもこれを使って作った原稿とかにライセンスは波及しないよ!


というものを作った。まだこれから実際にこれを使って書いてみて問題点を見つけてどんどん修正していくアルファ版だけどとりあえず公開しておく

http://bitbucket.org/nishio/genko

RubyとCの x = y + y = x について

Rubyで x = y + y = x と書くとこれは x = y + x と y = x を行ったのと同じ振る舞いをする。

> x = y = 1
=> 1
> x = y + y = x
=> 2
> [x, y]
=> [2, 1]
> x = y + y = x
=> 3
> [x, y]
=> [3, 2]
> x = y + y = x
=> 5
> [x, y]
=> [5, 3]
> x = y + y = x
=> 8
> [x, y]
=> [8, 5]

なぜかというと、まず

x = y + y = x

の y = x が実行されてその代入式の値はxになるから

x = y + x

ところで、これはCでも動くと思って試してみたがしたのようなエラーになってしまう。

error: lvalue required as left operand of assignment

これはおそらく+の結合強度の方が=の結合強度より高いから

x = (y + y) = x

と解釈されて、 y + y は左辺値ではないので代入の左辺にこれないってことなのだが、じゃあ、と

x = y + (y = x);

にしてみたら、これは x = x + x になってしまった。ふむ、+の引数って右辺から評価されるの?そう思って関数呼び出しに変えてみたら左辺が先に評価された

#include<iostream>
int y = 5;
int get_y(){
  std::cout << "get_y: " << y << std::endl;
  return y;
}

int main(){
  int x = 3;
  x = get_y() + (y = x);
  std::cout << x << "," << y << std::endl;
}

get_y()の時は8,3になり、そこをyに置き換えると6,3になる。C++ 演算子の優先順位 [C++ Reference]によれば式の評価順序は未定義な物が多いとのこと。要するに代入という「副作用のある処理」を式の中に混ぜると評価順序によって異なる結果になるからやめようね、ってことね。

ちなみにPythonでは

x = y = 1

という「= Expr が1個以上続いたもの」を「代入文」として定義しているので上のようなことがそもそもできない。下のように書く。

x, y = y, x + y


ささださんのTweetに反応して書いたのだけども、ささださん曰く出典はこれらしい: http://jarp.does.notwork.org/diary/201009a.html#201009101

2010-09-07

[]板カルタ

北海道の百人一首はとても特殊らしい!

大阪出身の僕にとって百人一首っていうと下のようなものなのだけど:

北海道の板カルタと呼ばれる百人一首は取り札が板で、しかも変体仮名の筆書きで書いてある。読めない。

http://www.itakaruta.com/ によれば、屯田兵が百人一首で遊ぶ際に、当時の北海道では紙の入手が難しかったので木に書いたのが始まりだそうな。

2010-09-02

LLの身軽さ

@shnsk Q. Javaでなくて,Pythonの方がプロトタイピングに向いているシーンって,どこだろう #spro2010

たとえば

[10/09/02 21:26:21] Y: 社内勉強会でScalaでこれを解く、というのが出されたから解いた

[10/09/02 21:26:22] Y: http://recruit.drecom.co.jp/event2010

[10/09/02 21:28:58] N: 重たい

[10/09/02 21:29:04] N: ぷれーんてきすとでおけ

[10/09/02 21:29:27] N: ふむ、問題読んだ

[10/09/02 21:29:54] Y: 7110を含むフィボナッチ数列で、

初期値の組み合わせが一番小さいものをあげろ。

自然数に限る

[10/09/02 21:30:02] Y: ぷれーんてきすと

[10/09/02 21:32:25] N: 解けた

[10/09/02 21:33:44] N: http://gist.github.com/561961

[10/09/02 21:33:45] N: 答え

3分ではEclipseを起動しただけで終わってしまう!

Pretty Print 7

さて、ここしばらくいじっていたpretty printだが、そろそろちゃんと動いたことに満足して関心が薄れてきたので、今までの経験上「ここでなんとなくほったらかすとしばらくしてからどういう状態だったのかわからなくなる!」と思って一気にリポジトリの公開とPython Package Indexに入れるところまでやっつけた。

Python Package Index : prettier 0.92

nishio / prettierprint / source — bitbucket.org

ここまでのストーリーのおさらい。

  • Pythonいじり2
    • Pythonで対話的実行の時に入力したコードの構文木を表示するようにしてみたが、構文木が長くなると適当に改行してくれないとみにくい。調べてみたらRubyはとある論文に基づいてprettyprint.rbを実装している。サンプルコードがHaskellで2ページ程度、これを移植すればいいんじゃない?
  • PrettyPrint 1
    • とりあえず気合でHaskellで書かれたサンプルコードを逐語訳。
  • Pretty Print 2
    • テスト
  • Pretty Print 3
    • テストのカバレッジを100%に。あとすごく遅い現象を発見して、それは遅延評価じゃなくなったせいだった。
  • Pretty Print 4
    • 元コードのutilityに入っていたspreadって関数は与えられたドキュメントのリストを水平に並べるものだが、それを「1行になる」と期待して使ったらならなかったのではまった話。っていうか今思うと1行になるようにするのがAPIの設計としては適切じゃないかという気がする。あと空白文字を挟んでつなげるのと改行を挟んでつなげるのの2つのユーティリティ関数が実装されていたがそんな決め打ちのセパレータじゃなくてPythonの", ".join(xs)みたいに引数として渡せるべきじゃないの。
    • まあここでもともと僕が欲しかった機能はサポート完了
  • Pretty Print 6
    • チューニング。最初に逐語訳をしたときに考えていた最適化をおおよそ実装し終わる。

今後について

まずセパレータとかインデントの幅とかが決め打ちなのは変更できるべき。Haskell的に表現するなら各種の関数が設定の入ったenvを引数に取るようにするべきで、Python的には「somethingが毎回渡される関数の群れ」ってのは要するに「あるクラスのメソッドたち」なわけだ。だからPrettyPrinterってクラスを作ってその中に移動するのがよかろう。

APIは若干整理の必要がある。論文に書いてあったのでそのまま実装したけど、fillwordsとか必要ないし。コア部分に関してはHaskell前提で書かれているものの直訳だから、Python前提で0から書けばもっと見やすくなるかも知れないなーという気がする。

最終的に標準ライブラリのpprintを置き換えられる性能・機能になれればいいなぁ。