moved kdeaccessibility kdeaddons kdeadmin kdeartwork kdebindings kdeedu kdegames...
[kdeedu.git] / ktouch / extras / training-gen / python / ktouchgen.py
blob97083c014f71faf058b427fd91a04f3a6942a2be
1 #!/usr/bin/python
2 ##################################################################################
4 # ktouchgen.py Builds Levelfiles for ktouch
5 # This is an enhanced reimplementation of a programm written by
6 # Haavard Froeiland <havard@student.unsw.edu.au>
7 #
8 # This Version was written by
9 # Hendrik Naumann <hn75@gmx.de>
10 # License: GPL
11 # Last edited: 11.10.2001
12 ##################################################################################
14 # SYNTAX OF THE CONFIGFILE
16 # Sections:
17 # [Main]
18 # level_rows = Generated rows per level
19 # row_length = Length of the generated rows
21 # [Level<Num>] Settings for the Levels to create
22 # lchars = Chars that must be in the words
23 # in the following levels these chars will be
24 # permitted to be in the words
25 # title = Title of the Level. If not given it is set to
26 # lchars
27 # rows = Number of rows. This overwrites level_rows.
28 # type = 0 Wordlist will be used for Level. If type is
29 # not given this is default.
30 # type > 0 Words will be created from lchars and permitted
31 # chars. The number of type indicates the length
32 # of the genrated words.
34 ##################################################################################
36 from whrandom import randint, random
37 import string
38 from string import join, maketrans, translate, count, strip, lower, find, upper
39 import time
40 import sys
41 import ConfigParser
42 import regex
44 DOCSTRING = """
45 Usage:
46 ./ktouchgen.py wordfile configfile outputfile
47 wordfile Is an file containing the words the levels are build from.
48 It should contain one word on each line
49 configfile File that contains the configuration of the levels.
50 See ktouchgen.py for documentation.
51 outputfile The name of the new levelfile. If it exists it will
52 be overwritten.
53 """
55 class LevelList:
56 "Level List Class"
57 def __init__(self, Levelchars, Permitchars):
58 self.list = {0:[join(Levelchars,"")]}
59 self.wordcount = 0.0
60 self.llist = Levelchars
61 self.plist = Permitchars
63 def SelectWords(self, Wordlist):
64 """
65 SelectWords(self, Wordlist)
66 Searches for words only contain Permitchars and at least
67 one Levelchar.
68 Calculate the number of levelchars / per chars of the word
69 and fill this values in an mapping
70 {lchars/chars*1000 :[list of words with this property]}
71 """
72 Transstring = maketrans("","")
73 pliststring = join(self.plist, "")
74 lliststring = join(self.llist, "")
76 for Word in Wordlist:
77 lchar_count = 0
78 if len(translate(Word, Transstring, pliststring)) == 0:
79 lchar_count = len(Word) - len(translate(Word, Transstring, lliststring))
80 if lchar_count:
81 weight = int((float(lchar_count) / float(len(Word))) * 1000)
82 if self.list.has_key(weight):
83 self.list[weight].append(Word)
84 else:
85 self.list[weight] = [Word]
86 self.wordcount = self.wordcount + 1
88 def GetRandomList(self, listlength):
89 """
90 GetRandomList(self, listlength)
91 Returns a list of randomwords with listlength length.
92 First choose words with most Levelchars, if these are
93 not enough, words with less are chosen.
94 """
95 retlist = []
96 selectlist = []
97 length = 0
98 val = 0
99 temp = 0
100 keys = self.list.keys()
101 keys.sort()
102 keys.reverse()
103 for key in keys:
104 if length < listlength:
105 for count in range(len(self.list[key]) - 1):
106 if length < listlength and key > 0 :
107 num = randint (0, len(self.list[key]) - 1)
108 word = self.list[key][num]
109 temp = temp + key
110 del(self.list[key][num])
111 val = val + 1
112 length = length + len(word)
113 selectlist.append(word)
114 else:
115 break
116 else:
117 break
118 temp = float(temp) / val / 10
119 print 'Got words with an averages of %(temp).2f %% lchars.' %vars()
120 # Select the returnlist from selectlist
121 val = val - 1
122 length = 0
123 while length < listlength:
124 word = selectlist[randint(0, val)]
125 length = length + len(word)
126 retlist.append(word)
128 return retlist
130 def GenArtWord(self, Wordlength):
132 GenArtWord(self, Wordlength)
133 Builds an artifical word (with length Wordlength) out of Levelchars and Permitchars.
134 Does it like: random(lchar) + random(pchar) + .....
136 ret = ""
137 while len(ret) < Wordlength:
138 ret = ret + self.llist[randint(0, len(self.llist) - 1)] + self.plist[randint(0, len(self.plist) - 1)]
139 return ret
141 def GetArtList(self, Listlength, Wordlength):
143 GetArtList(self, Listlength, Wordlength)
144 Buids an Wordlist with length Listlength out of artificial words.
145 See: self.GenArtWord()
147 length = 0
148 ret = []
149 while length < Listlength:
150 word = self.GenArtWord(Wordlength)
151 ret.append(word)
152 length = length + len(word)
153 return ret
156 def main(argv):
157 Wordlist = []
158 UpcaseWordlist = []
159 # Reading the Wordlist
160 try:
161 wordfile = open(argv[1], 'r')
162 except IOError:
163 print "\nWordfile couldn't be opened.\n", DOCSTRING
164 return 1
165 # Create two Wordlists, one with first char lowered
166 # (more words for the first levels) and one like it ist read
167 for wordstring in wordfile.readlines():
168 wordstring = strip(wordstring)
169 if lower(wordstring) != wordstring:
170 UpcaseWordlist.append(wordstring)
171 Wordlist.append(lower(wordstring))
172 wordfile.close()
174 # Parse the configfile
175 # Creates a List Levelops with [(Options), ]
176 # Optiontuple contains (lchars, title, rows)
177 conf = ConfigParser.ConfigParser()
178 try:
179 file = open(argv[2],'r')
180 except IOError:
181 print '\nConfigfile could not be opened.\n', DOCSTRING
182 return 1
183 file.close()
184 conf.read(argv[2])
185 try:
186 Rowlength = conf.getint('Main', 'row_length')
187 except ConfigParser.MissingSectionHeaderError:
188 print '\nWrong configfile. See ktouchgen.py for Documentation.' + DOCSTRING
189 Levelrows = conf.getint('Main', 'level_rows')
190 Levelops = []
191 Levelnum = 1
192 section = 'Level' + str(Levelnum)
193 while conf.has_section(section):
194 lchars = []
195 try:
196 for char in strip(conf.get(section, 'lchars')):
197 lchars.append(char)
198 except ConfigParser.NoOptionError:
199 print '\nNo characters defined for level %(Levelnum)s !' %vars()
200 return 1
201 try:
202 title = conf.get(section, 'title')
203 except ConfigParser.NoOptionError:
204 title = join(lchars)
205 try:
206 rows = conf.getint(section, 'rows')
207 except ConfigParser.NoOptionError:
208 rows = Levelrows
209 try:
210 type = conf.getint(section, 'type')
211 except ConfigParser.NoOptionError:
212 type = 0
214 Levelops.append((lchars, title, rows, type))
215 Levelnum = Levelnum + 1
216 section = 'Level' + str(Levelnum)
217 print '\nConfiguration for %(Levelnum)s levels read. \n!!! Be aware, if the Levels are not numberd correctly \n!!! they will not be read completely!' %vars()
219 # Generate Output
220 try:
221 outfile = open(argv[3], 'w')
222 except IOError:
223 print "Outputfile could not be opened.\n", DOCSTRING
224 return 1
225 outfile.write('#########################################################\n' +\
226 '# Trainingfile generaded ' + time.ctime(time.time()) + '\n' +\
227 '# Program written by Hendrik Naumann <hn75@gmx.de>\n' +\
228 '# Inspired by Håvard Frøiland\'s version\n' +\
229 '#########################################################\n')
230 permit_chars = []
231 Levelnum = 0
232 for Option in Levelops:
233 cachestring = ""
234 Levelnum = Levelnum + 1
235 for new_char in Option[0]:
236 if new_char not in join(permit_chars,""):
237 permit_chars.extend(Option[0])
238 outfile.write('\n# Level %(Levelnum)s\n' %vars() + Option[1] + "\n")
240 print "Generating Level " + str(Levelnum)
241 print join(permit_chars,"")
243 # Generate a LevelList object and give the needed Wordlists
244 levelwordlist = LevelList (Option[0], permit_chars)
245 if Option[3] == 0:
246 if lower(join(permit_chars,"")) != join(permit_chars,""):
247 if upper(join(Option[0],"")) != join(Option[0],""):
248 levelwordlist.SelectWords(Wordlist)
249 levelwordlist.SelectWords(UpcaseWordlist)
250 else:
251 levelwordlist.SelectWords(Wordlist)
252 randomlist = levelwordlist.GetRandomList(Rowlength * Option[2])
253 else:
254 randomlist = levelwordlist.GetArtList(Rowlength * Option[2], Option[3])
256 # Write the randomlist
257 for word in randomlist:
258 cachestring = cachestring + " " + word
259 if len(cachestring) > Rowlength - 3:
260 outfile.write(strip(cachestring) + "\n")
261 cachestring = ""
262 outfile.close()
263 return 0
265 if __name__ == "__main__":
266 if len(sys.argv) == 4:
267 main(sys.argv)
268 else:
269 print '\nWrong number of parameters\n' + DOCSTRING