Murga-Projects Forums

Full Version: Spelling/Typing Practice
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Here's a program I made to allow my daughter to cheat through spelling classes.
She's too good at both spelling and typing so this program made our days less of a drudgery.

It looks for a file "spellingList.lua" which is a table that is broken down into Units that contain a list per unit.
A quick and dirty Example would be:

Code:
spellingLists={{"global","solar"},{"pupil","community"}}


For simplicity I've also included the table inside of the program itself so the external file isn't necessary.

"Commonly mispelled words" might be a useful list to use for adult practice.
Or maybe a bunch of coding keywords to practice memorizing, I should probably make that.

The code also writes to a file "CurrentUnitCurrentWord.txt", to keep track of progress so the user can pick up where they left off over many sessions.
It also attempts to keep track of total time per session, as well as keystrokes, and words per minute typed.

I've attached the Fluid file

Code:
spellingLists={{"global","solar"},{"pupil","community"}}
  listFile="spellingLists.lua"
    local sl=io.open(listFile,"r*")
    if sl~=nil then
    dofile(listFile)
    sl:close()
    end
    
currentUnit={}
listCount = #spellingLists
totalwords = 0
for i = 1,listCount do
currentUnit = spellingLists[i]
unitCount = #currentUnit
for ii = 1,unitCount do
totalwords = totalwords + 1
--print(currentUnit[ii])
end
end
print(totalwords)

keystrokeCount = 0
totalLetters =0
wordscompleted=0
spellingTimerStart = os.time()
TotalElapsedTime = 0
UnitElapsedTime = 0
wordsPerMinute = 0
minuteCount = 0
elapsedWordtime = 0
wpmcount = 0
unitDepth = 1
listDepth = 1
wordsPerMinute=0

wordlistdepthfile = "CurrentUnitCurrentWord.txt"
myFile = io.open(wordlistdepthfile,"r")
if myFile ~= nil then
dofile(wordlistdepthfile)
myFile:close()
end



-- WriteSpellingListsToFile
function WriteSpellingListsToFile()
spellingListsFile = "spellingLists.lua"
    local f = io.open(spellingListsFile,"w")
    local Q = '"';
    local ba="{";
    local bb="}";
    local C=",";

    if f ~= nil then
    local listout = ""
    
        for i = 1,#spellingLists do
        local wordlist=""
        
            for ii = 1,#spellingLists[i] do
            wordlist=wordlist .. Q..spellingLists[i][ii]..Q..C
            end
            listout = listout..ba..string.sub(wordlist,1,-2)..bb..C.."\n"
            
        end
        listwrite = "spellingLists="..ba..string.sub(listout,1,-3)..bb;
        f:write(listwrite)
        f:write(string.char (10))
        io.close(f)
    end
end
-- WordInput_callback
function WordInput_callback(w)
wordtext = tostring(w:value())
realword = WordInput:label()
spellinglistWindow:make_current()
keystrokeCount = keystrokeCount + 1

if wordtext ~= realword then
    if string.sub(wordtext,-1,-1) == "." and string.len(wordtext)>2 then
    realword = string.sub(wordtext,1,-2)
    wordtext = realworld
    spellingLists[unitDepth][listDepth] = realword
    WordInput:label("")    
    WordInput:label(realword)
    WordInput:replace(0,string.len(realword)+1,realword)
    WordInput:redraw()

    WriteSpellingListsToFile()
    
    end
end

if wordtext == realword then
wordscompleted = wordscompleted + 1
totalLetters = totalLetters + string.len(wordtext)
    listDepth = listDepth + 1
    if listDepth > #spellingLists[unitDepth] then
    listDepth = 1
    unitDepth = unitDepth + 1
    if unitDepth > #spellingLists then
unitDepth=1
end

    UnitElapsedTime = 0
    end    
WordInput:label("")    
WordInput:label(spellingLists[unitDepth][listDepth])
UnitLabel = "Unit "..tostring(unitDepth)

WordInput:replace(0,string.len(wordtext),"")
WordInput:redraw()
wpmcount = wpmcount + 1



whatText = "unitDepth="..unitDepth.."\n".."listDepth="..listDepth.."\n"
myFile = io.open("CurrentUnitCurrentWord.txt","w")
if myFile ~= nil then
myFile:write(string.char (10))
myFile:write(whatText)
myFile:write(string.char (10))
io.close(myFile)
end

elapsedWordtime = os.time() - spellingTimerStart  
spellingTimerStart = os.time()
TotalElapsedTime = TotalElapsedTime + elapsedWordtime
UnitElapsedTime = UnitElapsedTime + elapsedWordtime

minuteCount = minuteCount + elapsedWordtime

if minuteCount > 60 then
minuteCount = 0
wordsPerMinute = wpmcount
wpmcount = 0
end

InfoBrowser:clear()
InfoBrowser:add(UnitLabel)
InfoBrowser:add("Word "..listDepth.." of "..#spellingLists[unitDepth])
InfoBrowser:add("Words Today: "..wordscompleted)
InfoBrowser:add("Keystrokes: "..keystrokeCount.." for "..totalLetters)

TimeBrowser:clear()
TimeBrowser:add("Word time: "..elapsedWordtime)
TimeBrowser:add("Unit Time: "..UnitElapsedTime)
TimeBrowser:add("Total Time: "..TotalElapsedTime)
TimeBrowser:add("WPM: "..wpmcount.."_"..minuteCount.." = "..wordsPerMinute)
spellinglistWindow:redraw()

end
WordInput:redraw()


end
do spellinglistWindow= fltk:Fl_Double_Window(0,0,0,0,"")
spellinglistWindow:callback(wClose)
spellinglistWindow:resize(6,50,742,322)

do fieldBackgrp= fltk:Fl_Group(0,0,0,0,"")
fieldBackgrp:resize(0,0,740,320)
fieldBackgrp:box(fltk.FL_DOWN_BOX)
Fl_Group:current(Fl_Group:current():parent())
end

do InfoBrowser= fltk:Fl_Browser(0,0,0,0,"")
InfoBrowser:resize(0,0,352,55)
InfoBrowser:box(fltk.FL_FLAT_BOX)
InfoBrowser:color(47)
InfoBrowser:labelsize(10)
InfoBrowser:textsize(10)
end

do TimeBrowser= fltk:Fl_Browser(0,0,0,0,"")
TimeBrowser:resize(350,0,389,55)
TimeBrowser:box(fltk.FL_FLAT_BOX)
TimeBrowser:color(47)
TimeBrowser:labelsize(10)
TimeBrowser:textsize(10)
end

do WordInput= fltk:Fl_Input(0,0,0,0,"")
if gLabelTable==nil then gLabelTable={} end
table.insert(gLabelTable, "1234567890123")
WordInput:label(gLabelTable[#gLabelTable])
WordInput:callback(WordInput_callback)
WordInput:resize(15,169,715,146)
WordInput:color(55)
WordInput:labelsize(94)
WordInput:labelcolor(179)
WordInput:align(5)
WordInput:when(1)
WordInput:textsize(70)
end
end
spellinglistWindow:show()
spellinglistWindow:make_current()
WordInput:label(spellingLists[unitDepth][listDepth])
UnitLabel= "Unit "..tostring(10+unitDepth)
spellingTimerStart = os.time()
elapsedWordtime = os.time() -spellingTimerStart
TotalElapsedTime = TotalElapsedTime + elapsedWordtime
UnitElapsedTime = UnitElapsedTime + elapsedWordtime
InfoBrowser:clear()
InfoBrowser:add(UnitLabel)
InfoBrowser:add("Word "..listDepth.." of "..#spellingLists[unitDepth])
InfoBrowser:add("Words Today: "..wordscompleted)
InfoBrowser:add("Keystrokes: "..keystrokeCount.." for "..totalLetters)
TimeBrowser:add("Word time: "..elapsedWordtime)
TimeBrowser:add("Unit Time: "..UnitElapsedTime)
TimeBrowser:add("Total Time: "..TotalElapsedTime)
TimeBrowser:add("WPM: "..wpmcount.."_"..minuteCount.." = "..wordsPerMinute)
spellinglistWindow:redraw()

Fl:run()

Interestingly I've been trying various typing programs very recently hoping to get my speed and accuracy back where it was in school.

First test, I got an error at the end of the lists.
Full output:

Code:
4
/home/deb/bin/murgaLua: /home/deb/bin/igame3d-spelling.lua:105: attempt to index field '?' (a nil value)
stack traceback:
        /home/deb/bin/igame3d-spelling.lua:105: in function </home/deb/bin/igame3d-spelling.lua:74>
        [C]: in function 'run'
        /home/deb/bin/igame3d-spelling.lua:214: in main chunk
        [C]: ?

105> WordInput:label(spellingLists[unitDepth][listDepth])
After that it would not run until I deleted CurrentUnitCurrentWord.txt

If you want to try coding keywords, murgaLua at least should be fairly easy to create lists for at runtime.

Code:
spellingLists={}

for i,v in pairs({math,alien,sys,fltk}) do
spellingLists[i]={}
for ii,vv in pairs(v) do table.insert(spellingLists[i],ii) end
end


EDIT: looped the second part for ease of use
EDIT2: optimization

Ok found the error. There was no test for reaching the end of all spelling units.
Now when it reaches the end, it loops back to the beginning.
Also removed the +10 for units and so it starts at one instead of eleven.
Code fixed in original post.

Your lua command variant is very cool.
It works well now.

I had to reduce the font size in order to display some of the longer fltk strings, but apart from that I'm liking it. I'd like to try loading simple one-word-per-line lists rather than table-based lists, since I believe it would be much easier from the end user's point of view. There are many places online that already have lists of this sort, in many subjects, and creating your own lists would be very easy.
For example, ls -1 /bin > bin.txt or echo $PATH|tr ':' '\n' > path.txt

Also added a line to "scramble" the list a little. It's not a real scramble, but at least takes them out of alphabetical order so it appears to be somewhat random.
table.sort(spellingLists[i], function(a,b) return a==b end)
I don't understand the sort function, though. I just made something up that resulted in the order being changed from what it was before.
Reference URL's