Language Expect
Date: | 04/20/05 |
Author: | Don Libes |
URL: | n/a |
Comments: | 2 |
Info: | n/a |
Score: | (3.01 in 137 votes) |
#!/usr/local/bin/expect # 99 bottles of beer on the wall, Expect-style # Author: Don Libes <libes@nist.gov> # Unlike programs (http://www.ionet.net/~timtroyr/funhouse/beer.html) # which merely print out the 99 verses, this one SIMULATES a human # typing the beer song. Like a real human, typing mistakes and timing # becomes more erratic with each beer - the final verse is barely # recognizable and it is really like watching a typist hunt and peck # while drunk. # Finally, no humans actually sing all 99 verses - particularly when # drunk. In reality, they occasionally lose their place (or just get # bored) and skip verses, so this program does likewise. # Because the output is timed, just looking at the output isn't enough # - you really have to see the program running to appreciate it. # Nonetheless, for convenience, output from one run (it's different # every time of course) can be found in the file beer.exp.out # But it won't show the erratic timing; you have to run it for that. proc bottles {i} { return "$i bottle[expr $i!=1?"s":""] of beer" } proc line123 {i} { out $i "[bottles $i] on the wall,\n" out $i "[bottles $i],\n" out $i "take one down, pass it around,\n" } proc line4 {i} { out $i "[bottles $i] on the wall.\n\n" } proc out {i s} { foreach c [split $s ""] { # don't touch punctuation; just looks too strange if you do if [regexp "\[,. \n\]" $c] { append d $c continue } # keep first couple of verses straight if {$i > 97} {append d $c; continue} # +3 prevents it from degenerating too far # /2 makes it degenerate faster though set r [rand [expr $i/2+3]] if {$r} {append d $c; continue} # do something strange switch [rand 3] { 0 { # substitute another letter if [regexp \[aeiou\] $c] { # if vowel, substitute another append d [string index aeiou [rand 5]] } elseif [regexp \[0-9\] $c] { # if number, substitute another append d [string index 123456789 [rand 9]] } else { # if consonant, substitute another append d [string index bcdfghjklmnpqrstvwxyz [rand 21]] } } 1 { # duplicate a letter append d $c$c } 2 { # drop a letter } } } set arr1 [expr .4 - ($i/333.)] set arr2 [expr .6 - ($i/333.)] set shape [expr log(($i+2)/2.)+.1] set min 0 set max [expr 6-$i/20.] set send_human "$arr1 $arr2 $shape $min $max" send -h $d } set _ran [pid] proc rand {m} { global _ran set period 259200 set _ran [expr ($_ran*7141 + 54773) % $period] expr int($m*($_ran/double($period))) } for {set i 99} {$i>0} {} { line123 $i incr i -1 line4 $i # get bored and skip ahead if {$i == 92} { set i [expr 52+[rand 5]] } if {$i == 51} { set i [expr 12+[rand 5]] } if {$i == 10} { set i [expr 6+[rand 3]] } } Sample output: 99 bottles of beer on the wall, 99 bottles of beer, take one down, pass it around, 98 bottles of beer on the wall. 11 botqle off baer oc tbe wakl, 1 botplo of beer, take onne da, pass itt arounm, 0 yotglees oof beeeer on tte walll.
Download Source | Write Comment
Download Source | Write Comment
Add Comment
Please provide a value for the fields Name,
Comment and Security Code.
This is a gravatar-friendly website.
E-mail addresses will never be shown.
Enter your e-mail address to use your gravatar.
Please don't post large portions of code here! Use the form to submit new examples or updates instead!
Comments
ron hudson said on 06/05/06 07:30:11
Cool, it must be actually drinking the beer as it goes...
:^)
Kiyoshi Akima said on 06/06/06 20:30:21
Shouldn't the program mistype the punctuation now and then?