Introduction to Tcl
Total Page:16
File Type:pdf, Size:1020Kb
ESPResSo Summer School 2012 Introduction to Tcl Pedro A. Sánchez Institute for Computational Physics Allmandring 3 D-70569 Stuttgart Germany Outline History, Characteristics, Online resources, Getting things running Variables, grouping and nested commands Math expressions Control structures Hands on! User defined commands Hands on! Lists and Arrays Hands on! Working with files, command line arguments, modularization Hands on! http://www.icp.uni-stuttgart.de 2/26 History “Tool command language”, pronounced “tickle” or “tee-see-ell” John Ousterhout, Berkley, 1988 Originally invented for GUI programming (Tcl/Tk) Very successful language in the 1990s, adopted by many companies Not very active and popular anymore Some scientific programs still use Tcl/Tk, e.g. VMD and NAMD … but most are slowly switching to Python... http://www.icp.uni-stuttgart.de 3/26 Characteristics Interpreted scripting language, cross-platform (available almost everywhere), originally (and mainly used as) procedural Motto: “Radically simple”. Simple syntax No data types: all data treated as strings All operations are commands (=functions), including control structures Dynamic: everything can be (re-)defined easily, including source code Simple C-API, easy to extend and embed Free, open-source (BSD license) Current version 8.5.12 (July 27, 2012) http://www.icp.uni-stuttgart.de 4/26 Online resources Huge documentation and resources at the official website: http://www.tcl.tk http://wiki.tcl.tk/ Built-in commands quick reference: http://www.tcl.tk/man/tcl8.5/TclCmd/contents.htm Complete tutorial: http://www.tcl.tk/man/tcl/tutorial/tcltutorial.html Nice interactive offline tutorial for self-learning, written in Tcl/Tk: http://www.msen.com/~clif/TclTutor.html http://www.icp.uni-stuttgart.de 5/26 Getting things running... Interactive consoles: Standard interpreter: tclsh Improved console: tkcon http://tkcon.sourceforge.net/ Script files: Usual extension: *.tcl Run from command line: $>tclsh$>tclsh myNiceScript.tclmyNiceScript.tcl Executable scripts: prepend script with #!/usr/bin/tclsh#!/usr/bin/tclsh http://www.icp.uni-stuttgart.de 6/26 Hello world! General syntax: commandcommand argument1argument1 argument2argument2 ...... Commands end with newline or semicolon ; "" or {} used to group arguments Arguments are represented as strings Comments start with # ## ThisThis isis aa commentcomment putsputs "Hello"Hello World!"World!" putsputs "This"This isis lineline 1"1";; putsputs "this"this isis lineline 2"2" putsputs "Hello,"Hello, WorldWorld -- InIn quotes"quotes" ;;## ThisThis isis aa commentcomment putsputs "Hello,"Hello, World;World; -- semicolonsemicolon insideinside thethe quotes"quotes" putsputs {{Hello,Hello, WorldWorld –– inin BracesBraces}} putsputs HelloWorldHelloWorld putsputs {{BadBad syntaxsyntax exampleexample}} ## *Error**Error* nono semicolon!semicolon! http://www.icp.uni-stuttgart.de 7/26 Variables Assignement command: set setset variableNamevariableName valuevalue Variable substitution: before a command is executed all variables, referenced as $variableName, are substituted for its value Backslash \ prevents subtitution of the next character. Usual backslashed codes (“backslash-sequences”) exist \n, \t, ... Unset variables are reported setset myMessagemyMessage "Hello"Hello World!"World!" putsputs $myMessage$myMessage setset aa 1.01.0 putsputs $a+$a$a+$a putsputs $a$a\n\n$a$a putsputs \$a\$a putsputs $unknownVar$unknownVar http://www.icp.uni-stuttgart.de 8/26 Variable substitution and argument grouping Argument grouping via "": Variable substitution and backslash-sequences work Use for strings Argument grouping via {}: No substitution nor backslash-sequences Use for code blocks setset myMessagemyMessage "Hello"Hello World!"World!" putsputs "Say"Say $myMessage$myMessage\nNext\nNext line”line” putsputs {{SaySay $myMessage$myMessage\nNext\nNext lineline}} setset myFullMessagemyFullMessage "Say"Say $myMessage$myMessage\nNext\nNext line”line” putsputs $myFullMessage$myFullMessage http://www.icp.uni-stuttgart.de 9/26 Nested commands Command substitution: strings within square brackets [] are evaluated as commands Variable substitution works within command substitution Command substitution works within quotes, not within braces setset yy [set[set xx "def""def"]] ;;## commandcommand setset returnsreturns thethe assignedassigned valuevalue setset xx "def""def" setset zz [set[set yy $x$x]] setset zz ""[set[set xx {{ThisThis isis aa stringstring withinwithin bracesbraces withinwithin quotes}quotes}]]"" setset zz {[set{[set xx "This"This isis aa stringstring withinwithin quotesquotes withinwithin braces"braces"]}]} http://www.icp.uni-stuttgart.de 10/26 Math: expression evaluation Mathematical operations computed with the command expr Expressions mostly like C operators and mathematical functions: +, -, *, /, %, pow, sin, cos, ... putsputs "1+1”"1+1” putsputs 1+11+1 putsputs [expr[expr 1+11+1]] putsputs [expr[expr "1+1”"1+1”]] putsputs [expr[expr 1/21/2]] putsputs [expr[expr 1./21./2]] setset xx 22 putsputs "$x"$x plusplus $x$x isis [expr[expr $x+$x$x+$x]]"" putsputs "The"The squaresquare rootroot ofof $x$x isis [expr[expr sqrt($x)sqrt($x)]]"" putsputs [expr[expr pow($x,2)pow($x,2)]] putsputs [expr[expr (($x+1)$x+1) %% 22]] http://www.icp.uni-stuttgart.de 11/26 Math: type conversion and random numbers Since all data is treated as a string, numbers should be transformed to and from strings → slow numerics in Tcl!!!! Explicit type conversions: abs, int, double, round Tcl provides a pseudo-random number generator: rand(), srand() putsputs [expr[expr double(double(11))]] putsputs [expr[expr rand()rand()]] ;;## pseudo-randompseudo-random numbernumber (0.,(0., 1.)1.) exprexpr srand(srand(11)) ;;## setset seedseed forfor aa reproduciblereproducible sequencesequence exprexpr rand()rand() http://www.icp.uni-stuttgart.de 12/26 Control structures: conditionals The if command: ifif expr1expr1 thenthen body1body1 elseifelseif expr2expr2 thenthen body2body2 ...... elseelse bodyNbodyN The words then and else are optional The test expressions following the word if are evaluated as in the expr command setset xx 11 ifif {{$x$x ==== 11}} {puts{puts "x"x isis 1"1"}} elseelse {puts{puts "x"x isis notnot 1"1"}} ## mindmind thethe spacesspaces betweenbetween arguments!!!arguments!!! ifif {{$x$x ==== 11}{puts}{puts "x"x isis 1"1"}} ifif {{$x$x ==== 11}} {{ ;;## thisthis isis moremore readablereadable inin scriptsscripts putsputs "x"x isis 1"1" }} elseelse {{ putsputs "x"x isis notnot 1"1" }} http://www.icp.uni-stuttgart.de 13/26 Control structures: loops The while command: whilewhile testtest bodybody The for command: forfor startstart testtest nextnext bodybody The command break breaks a loop. The command incr increments the integer value of a variable setset ii 00 whilewhile {{$i$i << 33}} {puts{puts $i;$i; incrincr ii}} forfor {set{set ii 00}} {{$i<$i<33}} {incr{incr ii}} {puts{puts $i$i}} forfor {set{set ii 00}} {{$i<$i<33}} {incr{incr ii}} {{ putsputs $i$i } } http://www.icp.uni-stuttgart.de 14/26 Hands on! Write a tcl script to calculate the center of mass of this system: 10 100 point particles . in a square x-y lattice: 2 .. 1 ... {(X, Y)}={(1, 1); (1, 2); … 1 2 10 ... ; (10, 9); (10, 10)} Mass depends on the product of the coordinates: Particles with even product X*Y have mass 2.0 (“even mass”) Particles with odd product X*Y have mass 1.0 (“odd mass”) http://www.icp.uni-stuttgart.de 15/26 Adding new commands Command proc creates a new command procproc commandNamecommandName argumentsarguments bodybody All variables in body are local (including arguments) except those explicitly declared global with global or upvar The new command returns to the caller a value optionally specified with return or the output of the last command found within body by default setset myglobalmyglobal "global""global";; setset othervarothervar "other""other" procproc myProcmyProc {{arg1arg1 {{arg2arg2 "default""default"}}}} {{ globalglobal myglobal;myglobal; putsputs "arg1"arg1 isis $arg1$arg1"";; putsputs "arg2"arg2 isis $arg2$arg2"" putsputs "Global"Global varvar isis $myglobal$myglobal"";; returnreturn "returned""returned" }} setset resultresult [[myProcmyProc "first""first"]] http://www.icp.uni-stuttgart.de 16/26 Pass-by-reference to procs Pass-by-reference of variables to commands is emulated with upvar: procproc myIncrmyIncr {{arg1arg1 {{arg2arg2 11}}}} {{ upvarupvar $arg1$arg1 resres setset resres [expr[expr resres ++ $arg2$arg2]] returnreturn $res$res }} setset aa 11 putsputs [[myIncrmyIncr aa]] http://www.icp.uni-stuttgart.de 17/26 Hands on! Rewrite your script using a command definition: Write a command to calculate the COM of the x-y square lattice system for NxN particles and arbitrary “even” and “odd masses” Particles with even product X*Y have “even mass” Particles with odd product N . X*Y have “odd mass” . 2 .. 1 ... 1 2 N http://www.icp.uni-stuttgart.de 18/26 Lists A list is just an ordered collection of data, is the basic data structure in Tcl. Lists are strings, can be defined in many ways Data items can be accessed and extended with list commands: lindex, foreach, lappend, llength Lists can be nested setset myListmyList "1"1 22 3"3",, setset myListmyList {1{1 22 3}3} putsputs [lindex[lindex $myList$myList 22]];; putsputs [llength[llength $myList$myList]] foreachforeach jj $myList$myList {puts{puts $j$j}} lappendlappend myListmyList 44 55 66;; putsputs $myList$myList setset myEmptyListmyEmptyList {}{} ;; lappendlappend myEmptyListmyEmptyList {Not{Not emptyempty anymore!!}anymore!!}