A little fortune teller

Richard Suchenwirth 2003-07-24 - Linux systems, as well as Cygwin, contain the fortune(6) command which gives you a random adage every time you call it. It draws it from a set of files found in /usr/share/fortune. The big files are plain text, sections delimited by a % sign. Here is a simple fortune viewer that runs on Windows too - you just have to obtain a fortune file from somewhere, and put its path into the source.

The viewer uses a message widget, which I've almost never done before, but it has the advantage that it resizes automatically. Click on it for another fortune. Picking an arbitrary fortune is done by seeking to some random position in the file, advancing until the next % separator is found, and reading from there until the next % sign. Enjoy!

2009-04-28: If you want to choose the fortunes with uniform probability, instead of biasing towards longer fortunes, see random line from a file.

WikiDbImage tkfortune.jpg


 set filename /usr/share/fortune/fortunes ;# put your own here

 package require Tk
 pack [message .m -font {Courier 10} -textvariable fortune -width 800]
 bind . <1> showFortune

 set size [file size $filename]
 set fp [open $filename]

 proc showFortune {} {
     global fp size fortune
     seek $fp [expr {int(rand()*$size)}]
     while {[gets $fp line]>=0 && $line!="%"} {}
     set fortune ""
     while {[gets $fp line]>=0 && $line!="%"} {
         append fortune $line\n
     }
 }
 showFortune

ramsan (2003-07-24) says: if you plan also to deal with the offensive files (normally ended with -0, then it is necessary to unencrypt them. They are in rot13 format. Look at rot13 or use something like (taken from that page):

  set fortune [subst [regsub -all {[a-zA-Z]} \
                [regsub -all "\[\[$\\\\\]" $fortune {\\&}] \
                {[format %c [expr [set c [scan & %c]]\&96|(($c\&31)+12)%26+1]]}]]

RS prefers this:

 set text [string map -nocase {
     a n b o c p d q e r f s g t h u i v j w k x l y m z 
     n a o b p c q d r e s f t g u h v i w j x k y l z m} $line]