This is a further development of the Space Game. First I wrote the procedures in tcl, and got them past the "very rough" stage. Then I put them into a Tk script.
Well, I tried to, anyway. For the longest time I could not get the thing to work, because I did not understand how to make a label change after the widget was packed and presented. However, I flipped through Clif Flynt's book
BOOK Tcl/Tk for Real Programmers and found an example that showed it
could be done. I just needed to figure out how to do it.
This is round two of coding. The best thing I did was start fresh, and delete everything. Well, I kept the "quit" button.....
#!/bin/sh
#\
exec wish "$0" "${1+$@}"
# EE: Explanation of previous line can be found in page [exec magic]
# Are there ever any arguments to this? :)
# EE: Doesn't matter. better to have it there for future possibility.
#### All the procedures up front
# Proc to evaluate the coordinates given
# Returns the list of coordinates
# Input should be in the form of xxx,yyy,zzz
# Split by commas, test for 3 variables, and test for non-numerics.
# Then, and only then, return the list as valid.
# Needs a Tk based error message instead of an "exit" if fails to
# validate. Done 2 jun 01.
# Does it need quite the level of math precision?
proc validateCoord { coord } {
global goodVectors
set coordName [ split $coord , ]
if {([ llength $coordName ] != "3") || ([regexp {[^0-9 ]} \
"$coordName"])} {
# Okay, this was an early issue. If the user entered a bad datum
# the program would die. No forgiveness
# exit
# Change "exit" to:
errorMsg $coord
set goodVectors false
}
return $coordName
}
proc calcVector { hN tT } {
# Add the "goodVectors" value
global goodVectors
# clear goodVectors if set earlier
if { [ info exists goodVectors ] } {
unset goodVectors
}
set hereCoord [ validateCoord $hN ]
set thereCoord [ validateCoord $tT ]
# This was added, it tests for the variable "goodVectors"
# If it is set, that means there are problems, and it
# sets the output label to show an error.
# If the goodVectors is not set, then continue on. The problem
# was that the math needed to be wrapped so that it did not
# try to compute if the information was bad.
# Does that make sense? :)
if { [ info exists goodVectors ] } {
set distance "error-please redo"
} else {
foreach x1 $hereCoord x2 $thereCoord {
lappend vector [expr {$x2 - $x1}]
}
foreach {X Y Z} $vector break
set distance [expr {hypot($X, hypot($Y,$Z))}]
return "${X},${Y},${Z} @ $distance "
}
}
# This whole proc was added to give better error messaging
# than a program crash. :)
proc errorMsg { badInfo } {
# If they blow it, wake them up!
bell
# This is a failed try to handle 2 sets of exactly similar
# bad input.
# if { [ info exists errLabel ] } {
# set badInfo ${badInfo}2
# }
set errLabel $badInfo
# The ".ack$badInfo covers if the user inputs a blank
toplevel .ack$badInfo
message .ack${badInfo}.1 -text "Please use standard Galactic \
format: xx,yy,zz. not $badInfo"
wm title .ack${badInfo} "ERROR"
pack .ack${badInfo}.1
}
#### Put up the UI
# Quit button
button .quit -text "Quit" -command exit
set hN [ entry .e1 -width 12 -textvariable input1 ]
set tT [ entry .e2 -width 12 -textvariable input2 ]
set out [ label .l1 -width 30 -textvariable output ]
set action [ button .b1 -text "Get Vector" -command {\
set output [ calcVector $input1 $input2 ] } ]
pack $hN $tT $out $action .quit -side left