# Today I will create an application engine. Unlike the cards that we go through sequentially or randomly, I want those words that I don’t know were chosen more often, so you need to keep statistics. It is obvious that the question that will be asked is connected with this statistics, and also that the answer to the question - I know or do not know - the same is connected with this statistics. Let the question be an object of the Exam class with the appropriate methods pass, fail, question and answer. And the Exam class itself will be an instance of the Session metaclass that will deal with statistics. Thus, we have connected the logical relation of entities to the relation expressed in language.
# Below is the corresponding code.
Class Session -superclass Class ; # define Session metaclass
# Next I define an a-la method_missing method for processing code of the form: “Session data.db Exam”, where # data.db - statistics file # Exam is the name of the class, the file consists of lines of the form: “wins defeats { question answer } ”, where wins is the number of victories, defeats is the number of defeats, question is an unknown word, answer is its meaning # The method loads statistics and saves it as an Exam class variable and defines the Exam class itself.
Session proc unknown { file_name class_name } { Class $ class_name -parameter { id } ; # define class $ class_name
# I read the statistics from the file and save it in the array of knowledge as they say toads class variable set id 0 set db [ open $ file_name r ] while { ! [ eof $ db ] } { foreach { wins defeats dictionary } [ gets $ db ] { $ class_name set knowledge ($ id, wins) $ wins $ class_name set knowledge ($ id, defeats) $ defeats $ class_name set knowledge ($ id, dictionary) $ dictionary incr id } } close $ db $ class_name set knowledge (count) $ id
# define class method to save statistics $ class_name proc save { file_name } { set db [ open $ file_name w ] for { set id 0 } { $ id < [ [ self ] set knowledge (count) ] } { incr id } { set wins [ [ self ] set knowledge ($ id, wins) ] set defeats [ [ self ] set knowledge ($ id, defeats) ] set dictionary [ [ self ] set knowledge ($ id, dictionary) ] puts $ db [ list $ wins $ defeats $ dictionary ] } close $ db }
# overload the create message handler class instance $ class_name proc create { args } { # The code below determines which question to ask. Algorithm # about the following: I make a segment of the segments is long # which is equal to the ratio of the number of dips to the sum # attempts. I normalize it, and then I take a random number from # 0 to 1 and choose which segment it contains. set current null set i 0 set omega 0 for { set id 0 } { $ id < [ [ self ] set knowledge (count) ] } { incr id } { set wins [ [ self ] set knowledge ($ id, wins) ] .0 set defeats [ [ self ] set knowledge ($ id, defeats) ] .0 set sum [ expr { $ wins + $ defeats } ] set delta ($ id) [ expr { $ defeats / $ sum } ] set omega [ expr { $ omega + $ delta ($ id) } ] } set probe [ expr { rand () * $ omega } ] set sum 0 foreach key [ array names delta ] { set current $ key set sum [ expr { $ sum + $ delta ($ key) } ] if { $ probe <$ sum } break } # pass control to the standard creation mechanism # class instance with passing current parameter, # which indicates the question to be asked. next [ lindex $ args 0 ] -id $ current }
# passed the test $ class_name instproc pass { } { [ [ self ] class ] incr knowledge ( [ my id ] , wins) }
# failed test $ class_name instproc fail { } { [ [ self ] class ] incr knowledge ( [ my id ] , defeats) }
# returns the question $ class_name instproc question { } { lindex [ [ [ self ] class ] set knowledge ( [ my id ] , dictionary) ] 0 }
# returns the answer $ class_name instproc answer { } { lindex [ [ [ self ] class ] set knowledge ( [ my id ] , dictionary) ] 1 }
return $ class_name }
# Below is a simple example of using the written part of the program.
# Create an Exam object (actually a class) of a class (actually # meta-class) Session and load statistics into it from # data.db file Session data.db Exam
Exam test ; # Create test puts [ test question ] ; # Find out what question # If the question is green, then we pretend that we don’t know it and # look at the answer otherwise proudly say I know if { [ string equal [ test question ] green ] } { puts [ test answer ] test fail } { test pass } test destroy ; # delete object