proc num->7seg string { foreach i {a b c} {set $i " "} array set 7segment { 0 {{ _ } {| |} {|_|}} 1 {{ } { |} { |}} 2 {{ _ } { _|} {|_ }} 3 {{ _ } { _|} { _|}} 4 {{ } {|_|} { |}} 5 {{ _ } {|_ } { _|}} 6 {{ _ } {|_ } {|_|}} 7 {{ _ } { |} { |}} 8 {{ _ } {|_|} {|_|}} 9 {{ _ } {|_|} { _|}} - {{ } { _ } { }} E {{ _ } {|_ } {|_ }} r {{ } { _ } {| }} o {{ } { _ } {|_|}} A {{ _ } {|_|} {| |}} B {{ } {|_ } {|_|}} C {{ _ } {| } {|_ }} D {{ } { _|} {|_|}} F {{ _ } {|_ } {| }} } foreach char [split $string ""] { if {$char eq "."} { set c [string replace $c end end .] } else { foreach i {a b c} row $7segment($char) { append $i $row " " } } } return $a\n$b\n$c } % num->7seg 12345.67890-Error
_ _ _ _ _ _ _ _ _ | _| _| |_| |_ |_ | |_| |_| | | _ |_ _ _ _ _ | |_ _| | _|.|_| | |_| _| |_| |_ | | |_| |
MPJ: "Drive-by hacking" ... I added A,B,C,D,F so hex displays look right ;-)RS: Thanks Mike, but that B is indistinguishable from 8, and D from 0... We'd have to use lowercase for these two:
B {{ } {|_ } {|_|}} D {{ } { _|} {|_|}}
% num->7seg 012345.6789ABCDEF _ _ _ _ _ _ _ _ _ _ _ _ | | | _| _| |_| |_ |_ | |_| |_| |_| |_ | _| |_ |_ |_| | |_ _| | _|.|_| | |_| _| | | |_| |_ |_| |_ |MPJ: You're right; I just saw that on LCD hexa panel.TV: Such things can also be applied to hardware LED display driven by the parallel port under tcl control, my routine wasn't as neatly defining the segments, just a list of decimal numbers...
FW: I thought of a (seemingly) clever way to store these characters, to make a little obfuscated puzzler, but the result is really not that much shorter, and not even as obfuscated as I had hoped. Ah well ;) It just replaces the "array set" construct with this:
foreach {char pc} [split "0o1\t2^3\[495s6w7I8\1779{_\20Evr\24o\27A}B7CfD Ft" ""] { binary scan $pc B8 bin set b2 "" for {set i 1} {$i < 8} {incr i} { append b2 [expr {[string index $bin $i] ? ([lsearch {1 3 6} $i] != -1 ? "_" : "|") : " "}] } set 7segment($char) [list " [string index $b2 0] " [string range $b2 1 3] [string range $b2 4 6]] }