Gateway login program for kids

Andy Bradford amb-plugg at
Tue Aug 7 01:44:17 MDT 2012

Thus said Alan Young on Mon, 06 Aug 2012 13:13:57 MDT:

> E.g., he logs in. Instead of his regular window manager he's presented
> with  a spelling  test program  where he  has to  spell all  the words
> correctly  before he  can continue.  Once he's  spelled all  the words
> correctly  he can  then go  on to  whatever he  was going  to use  the
> computer for.

Here's  a quick  prototype. Place  it in  the appropriate  place in  the
$HOME/.xsession file (probably  somehwere near the top  before you start
the desktop/window manager).  Or wherever is appropriate  for your login
manager (I use xdm). Something like:

/usr/local/bin/spellguard /usr/share/dict/words || exit

Now, if sg  doesn't exit 0, then  .xsession will exit and  X will logout
the user. If you  press Control-r it will replay the  word. If you press
Control-n it  will pick a  different word (randomly  selected). Pressing
Enter after  typing a word  will trigger a spell  check and it  says the
word that you typed (or at least tries). Control-c causes the word to be
repeated, however, it  outputs the word to stderr (which  should show up
in the $HOME/.xsession-errors file so you  can inspect it remotely if he
simply cannot spell the word).

You can provide a path to your own list of words. If you want to provide
a sentence  that uses the word,  then place the sentence  after the word
separated by a tab. e.g.,

house	The house is falling, the house is falling.

It depends  only on  Tcl/Tk and  espeak (a command  line text  to speech
tool). Probably best to use sentences with the words because sometimes a
single word in espeak is difficult to understand.


-------------- next part --------------
# \
test $# -lt 1 && { echo "Usage: $0 <wordfile>"; exit 100; }; exec tclsh "$0" ${1+"$@"}

package require Tk

proc placewindow {} {
  set ww [winfo width .]
  set wh [winfo height .]
  set x [expr ([winfo screenwidth .] - $ww) / 2]
  set y [expr ([winfo screenheight .] - $wh) / 2]
  set geom "${ww}x$wh+$x+$y"
  if {$ww > 1 && $wh > 1} { wm geometry . $geom }
  puts stderr $geom

proc spellcheck {wi wc wlabel} {
  upvar $wlabel wl

  if {[string equal $wi $wc]} {
    $wl config -text "Correct" -fg green
    after 1000 {play {You may pass!}; exit 0}
  } else {
    $wl config -text "Wrong" -fg red
    play $wi

proc newword {wlist word warray} {
  upvar $word wd
  upvar $warray wa

  set l [lsearch -all -inline -regexp $wlist {^[a-z]{1,8}$}]
  set wd [lindex $l [expr int(rand() * [llength $wlist]) % [llength $l]]]
  playword $wd wa

proc playword {word warray} {
  upvar $warray wa

  play $word
  if {[info exists wa($word)]} {
    play $wa($word)

proc play {s} {
  exec espeak $s

. config -bg white
set f1 [frame .f1]
set f2 [frame .f2]
set f3 [frame .f3]
set bc [button $f1.bc -text "Check Spelling" -command {spellcheck $word $control el}]
set nw [button $f1.nw -text "New Word" -command {newword $wordlist control wordarray}]
set pp [button $f1.pp -text "Repeat Word" -command {playword $control wordarray}]
pack $bc -side left
pack $nw -side right
pack $pp -side left
set we [entry $f2.we -textvariable word]
bind $we <Enter> {focus %W}
bind $we <Return> {spellcheck $word $control el; break}
bind . <Enter> {focus $we}
bind all <Control-c> {puts stderr $control; playword $control wordarray}
bind all <Control-r> {playword $control wordarray} 
bind all <Control-n> {newword $wordlist control wordarray}
pack $we -side bottom
set el [label $f3.el -bg white]
pack $el
pack $f1 -side top -fill x
pack $f3 -side bottom
pack $f2 -side bottom

array set wordarray [list]

if {[llength $argv]} {
  set fd [open [lindex $argv 0] r]
  while {[gets $fd line] >= 0} {
    set sline [split $line "\t"]
    if {[llength $sline] > 1} {
      set wordarray([lindex $sline 0]) [lrange $sline 1 end]
    lappend wordlist [lindex $sline 0]
  catch {close $fd}
} else {
  exit 100

after 100 {placewindow}
after 1000 {newword $wordlist control wordarray}

More information about the PLUG mailing list