SSブログ

Tcl(/Tk) でグラフ [Tcl]

Lightweight Language のサイトの「キミならどう書く 2.0 - ROUND 3 -」というトラックバック企画 [1] で今回のお題が「いくつかのデータを与えたときにグラフを出力するプログラム」(細かい仕様無し)ということだった。

今までこの企画で Tcl や Tcl/Tk で参加している人は意外にもいないっぽいので書いてみることにしました(それにこのお題はいかにも Tcl/Tk 向き)。

まずちょっと仕様を制限したもの。キャンバスの幅をはみ出すようなデータは考慮しない。

# graph.tcl
pack [canvas .canvas -width 200 -height [expr 20*[llength $argv]] -bg white]
set ypos 10
foreach num $argv {
  .canvas create line 0 $ypos [expr $num*10] $ypos -width 18 -fill blue
  .canvas create text 2 $ypos -text $num -anchor w -fill white
  incr ypos 20
}

実行するには

wish graph.tcl 2 5 9 18 15

などとする。実行結果はこうなる。

次はちゃんとキャンバスの大きさに合わせて伸縮するようにしたもの。

# graph2.tcl
set height 150; set width 200; # キャンバスの大きさ

set max [lindex [lsort -integer $argv] end]; # 要素の最大値
set lwidth [expr $height/[llength $argv]]; # 線の取れる太さ

pack [canvas .canvas -width $width -height $height -bg white]

set ypos [expr $lwidth/2]
foreach num $argv {
  set xpos [expr $width*$num/$max]
  .canvas create line 0 $ypos $xpos $ypos -width [expr $lwidth-2] -fill blue
  .canvas create text $xpos $ypos -text $num -anchor e -fill white
  incr ypos $lwidth
}

実行結果は以下のとおり。

wish graph2.tcl 2 5 9 30 18 15

しかしここまでだと何のひねりもなくて、単なる Tcl/Tk 入門みたいな話になってしまう。そして「***/Tk ならもっとスマートに書ける。なんだその expr は」とか言われそうだ。

こういう企画は「そんなものを使ってグラフを表現するなんて!」とか「おっと、そんな書き方があったか」とか「ここはワンライナーで」みたいな部分が面白みだと思うので Tk なしの Tcl 版で1行で収まるように書いてみたものを最後に紹介します(とはいえ tclsh には awk や perl のようにコマンド引数から直接プログラムを与える書き方はない)。

eval [regsub -all {(\d+)} $argv {puts [format "%2d : " \1][string repeat * \1];}]

実行結果はこんな風。

F:\>tclsh graph3.tcl 2 5 9
 2 : **
 5 : *****
 9 : *********

ループ構文が出てこないところがちょっといい感じ(かな?)。

[1] http://ll.jus.or.jp/2006/blog/doukaku3


nice!(1)  コメント(0)  トラックバック(0) 
共通テーマ:パソコン・インターネット

nice! 1

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。