export dictionary
[iramuteq] / corpus.py
1 # -*- coding: utf-8 -*-
2 #Author: Pierre Ratinaud
3
4 import codecs
5 import os
6 import gettext
7 _ = gettext.gettext
8 import locale
9 import sys
10 from time import time
11 from functions import decoupercharact, ReadDicoAsDico, DoConf
12 import re
13 import sqlite3
14 import itertools
15 import logging
16 from operator import itemgetter
17 from uuid import uuid4
18 from chemins import PathOut
19 from dialog import CorpusPref
20 from functions import ReadLexique, ReadDicoAsDico
21 from colors import colors
22 import datetime
23
24
25 log = logging.getLogger('iramuteq.corpus')
26
27
28 def copycorpus(corpus) :
29     log.info('copy corpus')
30     copy_corpus = Corpus(corpus.parent, parametres = corpus.parametres)
31     copy_corpus.ucis = corpus.ucis
32     copy_corpus.formes = corpus.formes
33     copy_corpus.pathout = corpus.pathout
34     copy_corpus.conn_all()
35     return copy_corpus
36
37
38
39 class Corpus :
40     """Corpus class
41     list of uci
42
43     """
44     def __init__(self, parent, parametres = {}, read = False) :
45         self.parent = parent
46         self.parametres = parametres
47         self.cformes = None         
48         self.connformes = None
49         self.connuces = None
50         self.conncorpus = None
51         self.islem = False
52         self.cuces = None
53         self.ucis = []
54         self.formes = {}
55         self.flems = {}
56         self.lems = None
57         self.idformesuces = {}
58         self.iduces = None
59         self.idformes = None
60         self.uceuci = None
61         if read :
62             self.pathout = PathOut(dirout = parametres['pathout'])
63             self.read_corpus()
64
65     def add_word(self, word) :
66         if word in self.formes :
67             self.formes[word].freq += 1
68             if self.formes[word].ident in self.idformesuces :
69                 if self.ucis[-1].uces[-1].ident in self.idformesuces[self.formes[word].ident] :
70                     self.idformesuces[self.formes[word].ident][self.ucis[-1].uces[-1].ident] += 1
71                 else :
72                     self.idformesuces[self.formes[word].ident][self.ucis[-1].uces[-1].ident] = 1
73             else :
74                 self.idformesuces[self.formes[word].ident] = {self.ucis[-1].uces[-1].ident: 1}
75         else :
76             if word in self.parent.lexique :
77                 gramtype = self.parent.lexique[word][1]
78                 lem = self.parent.lexique[word][0]
79             elif word.isdigit() :
80                 gramtype = 'num'
81                 lem = word
82             else :
83                 gramtype = 'nr'
84                 lem = word
85             self.formes[word] =  Word(word, gramtype, len(self.formes), lem)
86             self.idformesuces[self.formes[word].ident] = {self.ucis[-1].uces[-1].ident : 1}
87
88     def conn_all(self): 
89         """connect corpus to db"""
90         if self.connformes is None :
91             log.info('connexion corpus')
92             self.connuces = sqlite3.connect(self.pathout['uces.db'])
93             self.cuces = self.connuces.cursor()
94             self.connformes = sqlite3.connect(self.pathout['formes.db'])
95             self.cformes = self.connformes.cursor()
96             self.conncorpus = sqlite3.connect(self.pathout['corpus.db'])
97             self.ccorpus = self.conncorpus.cursor()
98             self.cformes.execute('PRAGMA temp_store=MEMORY;')
99             self.cformes.execute('PRAGMA journal_mode=MEMORY;')
100             self.cformes.execute('PRAGMA  synchronous = OFF;')
101             self.cuces.execute('PRAGMA temp_store=MEMORY;')
102             self.cuces.execute('PRAGMA journal_mode=MEMORY;')
103             self.cuces.execute('PRAGMA  synchronous = OFF;')
104             self.ccorpus.execute('PRAGMA temp_store=MEMORY;')
105             self.ccorpus.execute('PRAGMA journal_mode=MEMORY;')
106             self.ccorpus.execute('PRAGMA  synchronous = OFF;')
107
108     def read_corpus(self) :
109         log.info('read corpus')
110         self.parametres['syscoding'] = sys.getdefaultencoding()
111         if self.conncorpus is None :
112             self.conn_all()
113         res = self.ccorpus.execute('SELECT * FROM etoiles;')
114         for row in res :
115             self.ucis.append(Uci(row[0], row[1], row[2]))
116             uces = self.conncorpus.cursor().execute('SELECT * FROM luces where uci=?;',(`self.ucis[-1].ident`,))
117             for uce in uces:
118                 self.ucis[-1].uces.append(Uce(uce[2], uce[1], uce[0]))
119         res = self.ccorpus.execute('SELECT * FROM formes;')
120         self.formes = dict([[forme[1], Word(forme[1], forme[3], forme[0], lem = forme[2], freq = forme[4])] for forme in res])
121         self.ccorpus.close()
122     
123     def getworduces(self, wordid) :
124         if isinstance(wordid, basestring) :
125             wordid = self.formes[wordid].ident
126         res = self.cformes.execute('SELECT uces FROM uces where id=? ORDER BY id;', (`wordid`,))
127         return list(itertools.chain(*[[int(val) for val in row[0].split()] if not isinstance(row[0], int) else [row[0]] for row in res]))
128
129     def getformeuceseff(self, formeid) :
130         if isinstance(formeid, basestring) :
131             formeid = self.formes[formeid].ident
132         res = self.cformes.execute('SELECT uces FROM uces where id=? ORDER BY id;', (`formeid`,))
133         uces = list(itertools.chain(*[[int(val) for val in row[0].split()] if not isinstance(row[0], int) else [row[0]] for row in res]))
134         query = 'SELECT eff FROM eff where id=%i ORDER BY id' % formeid
135         res = self.cformes.execute(query)
136         eff = list(itertools.chain(*[[int(val) for val in row[0].split()] if not isinstance(row[0], int) else [row[0]] for row in res]))
137         formeuceeff = {}
138         for i, uce in enumerate(uces) :
139             formeuceeff[uce] = formeuceeff.get(uce, 0) + eff[i]
140         return formeuceeff    
141
142     def getlemuces(self, lem) :
143         formesid = ', '.join([`val` for val in self.lems[lem].formes])
144         query = 'SELECT uces FROM uces where id IN (%s) ORDER BY id' % formesid
145         res = self.cformes.execute(query)
146         return list(set(list(itertools.chain(*[[int(val) for val in row[0].split()] if not isinstance(row[0], int) else [row[0]] for row in res]))))
147
148     def getlemucis(self, lem) :
149         uces = self.getlemuces(lem)
150         return list(set([self.getucefromid(val).uci for val in uces]))
151
152     def getlemuceseff(self, lem, luces = None) :
153         formesid = ', '.join([`val` for val in self.lems[lem].formes])
154         query = 'SELECT uces FROM uces where id IN (%s) ORDER BY id' % formesid
155         res = self.cformes.execute(query)
156         uces = list(itertools.chain(*[[int(val) for val in row[0].split()] if not isinstance(row[0], int) else [row[0]] for row in res]))
157         query = 'SELECT eff FROM eff where id IN (%s) ORDER BY id' % formesid
158         res = self.cformes.execute(query)
159         eff = list(itertools.chain(*[[int(val) for val in row[0].split()] if not isinstance(row[0], int) else [row[0]] for row in res]))
160         lemuceeff = {}
161         for i, uce in enumerate(uces) :
162             lemuceeff[uce] = lemuceeff.get(uce, 0) + eff[i]
163         return lemuceeff    
164
165     def getlemclustereff(self, lem, cluster) :
166         return len(list(set(self.lc[cluster]).intersection(self.getlemuces(lem))))
167
168     def getlemeff(self, lem) :
169         return self.lems[lem].freq
170
171     def getlems(self) :
172         return self.lems
173
174     def getforme(self, formeid) :
175         if self.idformes is None : self.make_idformes()
176         return self.idformes[formeid]
177
178     def gettotocc(self) :
179         return sum([self.formes[forme].freq for forme in self.formes])
180
181     def getucemean(self) :
182         return float(self.gettotocc())/self.getucenb()
183
184     def getucenb(self) :
185         return self.ucis[-1].uces[-1].ident + 1
186
187     def getucinb(self) :
188         return self.ucis[-1].ident + 1
189
190     def getucisize(self) :
191         ucesize = self.getucesize()
192         return [sum(ucesize[uci.uces[0].ident:(uci.uces[-1].ident + 1)]) for uci in self.ucis]
193     
194     def getucesize(self) :
195         res = self.getalluces()
196         return [len(uce[1].split()) for uce in res]
197
198     def getconcorde(self, uces) :
199         return self.cuces.execute('select * from uces where id IN (%s);' % ', '.join([`i` for i in uces])) 
200
201     def getwordconcorde(self, word) :
202         return self.getconcorde(self.getworduces(word))
203
204     def getlemconcorde(self, lem) :
205         return self.getconcorde(self.getlemuces(lem))
206
207     def getalluces(self) :
208         return self.cuces.execute('SELECT * FROM uces')
209
210     def getucesfrometoile(self, etoile) :
211         return [uce.ident for uci in self.ucis for uce in uci.uces if etoile in uci.etoiles]
212
213     def getetoileuces(self) :
214         log.info('get uces etoiles')
215         etoileuces = {}
216         idpara = 0
217         for uci in self.ucis :
218             etoiles = uci.etoiles[1:]
219             for et in etoiles :
220                 if et in etoileuces :
221                     etoileuces[et] += [uce.ident for uce in uci.uces]
222                 else :
223                     etoileuces[et] = [uce.ident for uce in uci.uces]
224             if uci.paras != [] :
225                 for et in uci.paras :
226                     if et in etoileuces :
227                         etoileuces[et] += [uce.ident for uce in uci.uces if uce.para == idpara]
228                     else :
229                         etoileuces[et] = [uce.ident for uce in uci.uces if uce.para == idpara]
230                     idpara += 1
231             else :
232                 idpara += 1
233         return etoileuces
234
235     def getucefromid(self, uceid) :
236         if self.iduces is None : self.make_iduces()
237         return self.iduces[uceid]
238
239     def gethapaxnb(self) :
240         return len([None for forme in self.formes if self.formes[forme].freq == 1])
241
242     def getactivesnb(self, key) :
243         return len([lem for lem in self.lems if self.lems[lem].act == key])
244 #    def make_lems(self, lem = True) :
245 #        log.info('make lems')
246 #        self.lems = {}
247 #        for forme in self.formes :
248 #            if self.formes[forme].lem in self.lems :
249 #                if self.formes[forme].ident not in self.lems[self.formes[forme].lem] :
250 #                    self.lems[self.formes[forme].lem][self.formes[forme].ident] = 0
251 #            else :
252 #                    self.lems[self.formes[forme].lem] = {self.formes[forme].ident : 0}
253
254     def getetbyuceid(self, uceid) :
255         if self.uceuci is None : self.uceuci = dict([[uce.ident,uci.ident] for uci in self.ucis for uce in uci.uces])
256         return self.ucis[self.uceuci[uceid]].etoiles
257
258     def make_lems(self, lem = True) :
259         log.info('make lems')
260         self.lems = {}
261         if lem :
262             for forme in self.formes :
263                 if self.formes[forme].lem in self.lems :
264                     if self.formes[forme].ident not in self.lems[self.formes[forme].lem].formes :
265                         self.lems[self.formes[forme].lem].add_forme(self.formes[forme])
266                 else :
267                     self.lems[self.formes[forme].lem] = Lem(self, self.formes[forme])
268         else :
269             self.lems = dict([[forme, Lem(self, self.formes[forme])] for forme in self.formes])
270                 
271     def make_idformes(self) :
272         self.idformes = dict([[self.formes[forme].ident, self.formes[forme]] for forme in self.formes])
273
274     def make_iduces(self) :
275         if self.iduces is None :
276             self.iduces = dict([[uce.ident, uce] for uci in self.ucis for uce in uci.uces])
277
278     def make_lexitable(self, mineff, etoiles) :
279         tokeep = [lem for lem in self.lems if self.lems[lem].freq >= mineff]
280         etuces = [[] for et in etoiles]
281         for uci in self.ucis :
282             get = list(set(uci.etoiles).intersection(etoiles))
283             if len(get) > 1 :
284                 log.info('2 variables sur une ligne')
285             if get != [] :
286                 etuces[etoiles.index(get[0])] += [uce.ident for uce in uci.uces]
287         etuces = [set(val) for val in etuces]
288         tab = []
289         for lem in tokeep :
290             deff = self.getlemuceseff(lem)
291             ucesk = deff.keys()
292             tab.append([lem] + [sum([deff[uce] for uce in et.intersection(ucesk)]) for et in etuces])
293         tab.insert(0, [''] + etoiles)
294         return tab
295     
296     def make_efftype_from_etoiles(self, etoiles) :
297         dtype = {}
298         etuces = [[] for et in etoiles]
299         for uci in self.ucis :
300             get = list(set(uci.etoiles).intersection(etoiles))
301             if len(get) > 1 :
302                 return '2 variables sur la meme ligne'
303             elif get != [] :
304                 etuces[etoiles.index(get[0])] += [uce.ident for uce in uci.uces]
305         etuces = [set(val) for val in etuces]
306         for lem in self.lems :
307             deff = self.getlemuceseff(lem)
308             ucesk = deff.keys()
309             gram = self.lems[lem].gram
310             if gram in dtype :
311                 dtype[gram] = [i + j for i, j in zip(dtype[gram], [sum([deff[uce] for uce in et.intersection(ucesk)]) for et in etuces])]
312             else :
313                 dtype[gram] = [sum([deff[uce] for uce in et.intersection(ucesk)]) for et in etuces]
314         tabout = [[gram] + dtype[gram] for gram in dtype]
315         tabout.insert(0, [''] + etoiles)
316         return tabout
317
318     def make_uceactsize(self, actives) :
319         res = self.getalluces()
320         ucesize = {}
321         for lem in actives: 
322             deff = self.getlemuceseff(lem)
323             for uce in deff :
324                 ucesize[uce] = ucesize.get(uce, 0) + 1
325         return ucesize
326
327     def make_uc(self, actives, lim1, lim2) :
328         uceactsize = self.make_uceactsize(actives)
329         last1 = 0
330         last2 = 0
331         uc1 = [[]]
332         uc2 = [[]]
333         lastpara = 0
334         for uce in [uce for uci in self.ucis for uce in uci.uces] :
335             if uce.para == lastpara :
336                 if last1 <= lim1 :
337                     last1 += uceactsize.get(uce.ident,0)
338                     uc1[-1].append(uce.ident)
339                 else :
340                     uc1.append([uce.ident])
341                     last1 = 0
342                 if last2 <= lim2 :
343                     last2 += uceactsize.get(uce.ident, 0)
344                     uc2[-1].append(uce.ident)
345                 else :
346                     uc2.append([uce.ident])
347                     last2 = 0
348             else :
349                 last1 = uceactsize.get(uce.ident, 0)
350                 last2 = uceactsize.get(uce.ident, 0)
351                 lastpara = uce.para
352                 uc1.append([uce.ident])
353                 uc2.append([uce.ident])
354         return uc1, uc2
355
356     def make_and_write_sparse_matrix_from_uc(self, actives, sizeuc1, sizeuc2, uc1out, uc2out, listuce1out, listuce2out) :
357         uc1, uc2 = self.make_uc(actives, sizeuc1, sizeuc2)
358         log.info('taille uc1 : %i - taille uc2 : %i' % (len(uc1), len(uc2)))
359         self.write_ucmatrix(uc1, actives, uc1out)
360         self.write_ucmatrix(uc2, actives, uc2out)
361         listuce1 = [['uce', 'uc']] + [[`uce`, `i`] for i, ucl in enumerate(uc1) for uce in ucl]
362         listuce2 = [['uce', 'uc']] + [[`uce`, `i`] for i, ucl in enumerate(uc2) for uce in ucl]
363         with open(listuce1out, 'w') as f :
364             f.write('\n'.join([';'.join(line) for line in listuce1]))
365         with open(listuce2out, 'w') as f :
366             f.write('\n'.join([';'.join(line) for line in listuce2]))
367         return len(uc1), len(uc2)
368
369     def write_ucmatrix(self, uc, actives, fileout) :
370         log.info('write uc matrix %s' % fileout)
371         uces_uc = dict([[uce, i] for i, ucl in enumerate(uc) for uce in ucl])
372         deja_la = {}
373         nbl = 0
374         with open(fileout + '~', 'w+') as f :
375             for i, lem in enumerate(actives) :
376                 for uce in self.getlemuces(lem):
377                     if (uces_uc[uce], i) not in deja_la :
378                         nbl += 1
379                         f.write(''.join([' '.join([`uces_uc[uce]+1`,`i+1`,`1`]),'\n']))
380                         deja_la[(uces_uc[uce], i)] = 0
381             f.seek(0)
382             with open(fileout, 'w') as ffin :        
383                 ffin.write("%%%%MatrixMarket matrix coordinate integer general\n%i %i %i\n" % (len(uc), len(actives), nbl))
384                 for line in f :
385                     ffin.write(line)
386         os.remove(fileout + '~')
387         del(deja_la)
388
389     def export_corpus(self, outf) :
390         #outf = 'export_corpus.txt'
391         self.make_iduces()
392         res = self.getalluces()
393         self.make_iduces()
394         actuci = ''
395         actpara = False
396         with open(outf,'w') as f :
397             for uce in res :
398                 if self.iduces[uce[0]].uci == actuci and self.iduces[uce[0]].para == actpara :
399                     f.write(uce[1].encode(self.parametres['syscoding']) + '\n')
400                 elif self.iduces[uce[0]].uci != actuci :
401                     actuci = self.iduces[uce[0]].uci
402                     if self.ucis[self.iduces[uce[0]].uci].paras == [] :
403                         actpara = self.iduces[uce[0]].para
404                         f.write('\n' + ' '.join(self.ucis[self.iduces[uce[0]].uci].etoiles).encode(self.parametres['syscoding']) + '\n' + uce[1].encode(self.parametres['syscoding']) + '\n')
405                     else :
406                         ident = 0
407                         actpara = self.iduces[uce[0]].para
408                         f.write('\n'.join([' '.join(self.ucis[self.iduces[uce[0]].uci].etoiles).encode(self.parametres['syscoding']), self.ucis[self.iduces[uce[0]].uci].paras[ident].encode(self.parametres['syscoding']), uce[1].encode(self.parametres['syscoding'])]) + '\n')
409                 elif self.iduces[uce[0]].para != actpara :
410                     actpara = self.iduces[uce[0]].para
411                     ident += 1
412                     f.write('\n'.join([self.ucis[self.iduces[uce[0]].uci].paras[ident].encode(self.parametres['syscoding']), uce[1].encode(self.parametres['syscoding'])]) + '\n')
413     
414     def export_corpus_classes(self, outf, alc = True, lem = False) :
415         ucecl = {}
416         for i, lc in enumerate(self.lc) :
417             for uce in lc : 
418                 ucecl[uce] = i + 1
419         for uce in self.lc0 :
420             ucecl[uce] = 0
421         res = self.getalluces()
422         self.make_iduces()
423         with open(outf, 'w') as f :
424             for uce in res :
425                 guce = uce[1]
426                 actuci = self.iduces[uce[0]].uci
427                 if lem :
428                     guce = ' '.join([self.formes[forme].lem for forme in guce.split()])
429                 if alc :
430                     etline = ' '.join(self.ucis[self.iduces[uce[0]].uci].etoiles + ['*classe_%i' % ucecl[uce[0]]])
431                 else :
432                     etline = ' '.join(['<' + '='.join(et.split('_')) + '>' for et in self.ucis[self.iduces[uce[0]].uci].etoiles[1:]])
433                 f.write(etline.encode(self.parametres['syscoding']) + '\n')
434                 f.write(guce.encode(self.parametres['syscoding']) + '\n\n')
435
436     def make_and_write_sparse_matrix_from_uces(self, actives, outfile, listuce = False) :
437         log.info('make_and_write_sparse_matrix_from_uces %s' % outfile)
438         nbl = 0
439         with open(outfile + '~', 'w+') as f :
440             for i, lem in enumerate(actives) :
441                 for uce in sorted(self.getlemuces(lem)) :
442                     nbl += 1
443                     f.write(''.join([' '.join([`uce+1`, `i+1`,`1`]),'\n']))
444             f.seek(0)
445             with open(outfile, 'w') as ffin :        
446                 ffin.write("%%%%MatrixMarket matrix coordinate integer general\n%i %i %i\n" % (self.getucenb(), len(actives), nbl))
447                 for line in f :
448                     ffin.write(line)
449         os.remove(outfile + '~')
450         if listuce :
451             with open(listuce, 'w') as f :
452                 f.write('\n'.join(['uce;uc'] + [';'.join([`i`,`i`]) for i in range(0, self.getucenb())]))
453
454     def make_and_write_sparse_matrix_from_uci(self, actives, outfile, listuci = False) :
455         log.info('make_and_write_sparse_matrix_from_ucis %s' % outfile)
456         nbl = 0
457         with open(outfile + '~', 'w+') as f :
458             for i, lem in enumerate(actives) :
459                 for uci in sorted(self.getlemucis(lem)) :
460                     nbl += 1
461                     f.write(''.join([' '.join([`uci+1`, `i+1`,`1`]),'\n']))
462             f.seek(0)
463             with open(outfile, 'w') as ffin :        
464                 ffin.write("%%%%MatrixMarket matrix coordinate integer general\n%i %i %i\n" % (self.getucinb(), len(actives), nbl))
465                 for line in f :
466                     ffin.write(line)
467         os.remove(outfile + '~')
468         if listuci :
469             with open(listuci, 'w') as f :
470                 f.write('\n'.join(['uci;uc'] + [';'.join([`i`,`i`]) for i in range(0, self.getucinb())]))
471                     
472     def make_and_write_sparse_matrix_from_classe(self, actives, uces, outfile) :
473         log.info('make_and_write_sparse_matrix_from_classe %s' % outfile)
474         nbl = 0
475         duces = dict([[uce, i] for i, uce in enumerate(uces)])
476         with open(outfile + '~', 'w+') as f :
477             for i, lem in enumerate(actives) :
478                 uces_ok = list(set(self.getlemuces(lem)).intersection(uces))
479                 for uce in uces_ok :
480                     f.write(''.join([' '.join([`duces[uce]+1`,`i+1`,`1`]),'\n']))
481             f.seek(0)
482             with open(outfile, 'w') as ffin :        
483                 ffin.write("%%%%MatrixMarket matrix coordinate integer general\n%i %i %i\n" % (self.getucenb(), len(actives), nbl))
484                 for line in f :
485                     ffin.write(line)
486         os.remove(outfile + '~')
487     
488     def make_table_with_classe(self, uces, list_act) :
489         table_uce = [[0 for val in list_act] for line in range(0,len(uces))]
490         uces = dict([[uce, i] for i, uce in enumerate(uces)])
491         for i, lem in enumerate(list_act) :
492             lemuces = list(set(self.getlemuces(lem)).intersection(uces))
493             for uce in lemuces :
494                 table_uce[uces[uce]][i] = 1
495         table_uce.insert(0, list_act)
496         return table_uce      
497
498     def parse_active(self, gramact, gramsup = None) :
499         log.info('parse actives')
500         for lem in self.lems :
501             if lem.startswith('_') and lem.endswith('_') :
502                 self.lems[lem].act = 2
503             elif self.lems[lem].gram in gramact :
504                 self.lems[lem].act = 1
505             elif gramsup is not None :
506                 if self.lems[lem].gram in gramsup :
507                     self.lems[lem].act = 2
508                 else :
509                     self.lems[lem].act =  0
510             else :
511                 self.lems[lem].act = 2
512
513     def make_actives_limit(self, limit, key = 1) :
514         if self.idformes is None :
515             self.make_idformes()
516         return [lem for lem in self.lems if self.getlemeff(lem) >= limit and self.lems[lem].act == key]
517     
518     def make_actives_nb(self, nbmax, key) :
519         log.info('make_actives_nb : %i - %i' % (nbmax,key))
520         if self.idformes is None :
521             self.make_idformes()
522         allactives = [[self.lems[lem].freq, lem] for lem in self.lems if self.lems[lem].act == key and self.lems[lem].freq >= 3]
523         self.activenb = len(allactives)
524         allactives = sorted(allactives, reverse = True)
525         if len(allactives) <= nbmax :
526             log.info('nb = %i - eff min = %i ' % (len(allactives), allactives[-1][0]))
527             return [val[1] for val in allactives], allactives[-1][0]
528         else :
529             effs = [val[0] for val in allactives]
530             if effs.count(effs[nbmax - 1]) > 1 :
531                 lim = effs[nbmax - 1] + 1
532                 nok = True
533                 while nok :
534                     try :
535                         stop = effs.index(lim)
536                         nok = False
537                     except ValueError:
538                         lim -= 1
539             else :
540                 stop = nbmax - 1
541                 lim = effs[stop]
542         log.info('nb actives = %i - eff min = %i ' % (stop + 1, lim))
543         return [val[1] for val in allactives[0:stop + 1]], lim
544
545     def make_and_write_profile(self, actives, ucecl, fileout) :
546         log.info('formes/classes')
547         tab = [[lem] + [len(set(self.getlemuces(lem)).intersection(classe)) for classe in ucecl] for lem in actives]
548         tab = [[line[0]] + [`val` for val in line[1:]] for line in tab if sum(line[1:]) >= 3]
549         with open(fileout, 'w') as f :
550             f.write('\n'.join([';'.join(line) for line in tab]).encode(self.parametres['syscoding']))
551
552     def make_etoiles(self) :
553         etoiles = set([])
554         for uci in self.ucis :
555             etoiles.update(uci.etoiles[1:])
556         return list(etoiles)
557
558     def make_etoiles_dict(self) :
559         etoiles = [et for uci in self.ucis for et in uci.etoiles[1:]]
560         det = {}
561         for etoile in etoiles :
562             et = etoile.split('_')
563             if et[0] in det :
564                 try :
565                     endet = '_'.join(et[1:])
566                     if etoile in det[et[0]] :
567                         det[et[0]][etoile] += 1
568                     else :
569                         det[et[0]][etoile] = 1
570                 except IndexError :
571                     det[et[0]] += 1
572             else :
573                 try :
574                     endet = '_'.join(et[1:])
575                     det[et[0]] = {etoile :1}
576                 except IndexError :
577                     det[et[0]] = 1
578         return det
579
580     def make_etline(self, listet) :
581         etuces = [[] for et in listet]
582         for uci in self.ucis :
583             get = list(set(uci.etoiles).intersection(listet))
584             if len(get) > 1 :
585                 return '2 variables sur la meme ligne'
586             elif get != [] :
587                 etuces[listet.index(get[0])] += [uce.ident for uce in uci.uces]
588         return etuces
589
590     def make_and_write_profile_et(self, ucecl, fileout) :
591         log.info('etoiles/classes')
592         etoileuces = self.getetoileuces()
593         etoileuces = dict([[et, etoileuces[et]] for et in etoileuces if len(etoileuces[et]) > 1])
594         with open(fileout, 'w') as f :
595             f.write('\n'.join([';'.join([et] + [`len(set(etoileuces[et]).intersection(classe))` for classe in ucecl]) for et in etoileuces]).encode(self.parametres['syscoding']))
596         #etoiles = self.make_etoiles()
597         #with open(fileout, 'w') as f :
598         #    f.write('\n'.join([';'.join([etoile] + [`len(set(self.getucesfrometoile(etoile)).intersection(classe))` for classe in ucecl]) for etoile in etoiles]).encode(self.parametres['syscoding']))
599
600     def make_colored_corpus(self) :
601         ucecl = {}
602         for i, lc in enumerate(self.lc) :
603             for uce in lc : 
604                 ucecl[uce] = i + 1
605         for uce in self.lc0 :
606             ucecl[uce] = 0
607         color = ['black'] + colors[len(self.lc) - 1]        
608         txt = '''<html>
609         <meta http-equiv="content-Type" content="text/html; charset=%s" />
610         <body>
611 ''' % sys.getdefaultencoding()
612         res = self.getalluces()
613         self.make_iduces()
614         actuci = ''
615         actpara = False
616         for uce in res :
617             if self.iduces[uce[0]].uci != actuci :
618                 actuci = self.iduces[uce[0]].uci
619                 txt += '<br><hr>' + ' '.join(self.ucis[self.iduces[uce[0]].uci].etoiles) + '<br><br>'
620                 txt += '<font color="%s">' % (color[ucecl[uce[0]]]) + uce[1] + '</font><br><br>'
621             else :
622                 txt += '<font color="%s">' % (color[ucecl[uce[0]]]) + uce[1] + '</font><br><br>'
623         return txt + '\n</body></html>'
624
625     def count_from_list(self, l, d) :
626         for val in l :
627             if val in d :
628                 d[val] += 1
629             else :
630                 d[val] = 1
631         return d
632
633     def count_from_list_cl(self, l, d, a, clnb) :
634         for val in l :
635             if val in d :
636                 d[val][a] += 1
637             else :
638                 d[val] = [0] * clnb
639                 d[val][a] = 1
640         return d
641
642     def find_segments(self, taille_segment, taille_limite) :
643         d = {}
644         for uce in self.getalluces() :
645             uce = uce[1].split()
646             d = self.count_from_list([' '.join(uce[i:i+taille_segment]) for i in range(len(uce)-(taille_segment - 1))], d)
647         l = [[d[val], val] for val in d if d[val] >= 3]
648         del(d)
649         l.sort()
650         if len(l) > taille_limite :
651             l = l[-taille_limite:]
652         return l
653
654     def find_segments_in_classe(self, list_uce, taille_segment, taille_limite):
655         d={}
656         for uce in self.getconcorde(list_uce) :
657             uce = uce[1].split()
658             d =self.count_from_list([' '.join(uce[i:i+taille_segment]) for i in range(len(uce)-(taille_segment - 1))], d)
659         l = [[d[val], val, taille_segment] for val in d if d[val] >= 3]
660         del(d)
661         l.sort()
662         if len(l) > taille_limite :
663             l = l[-taille_limite:]
664         return l
665             
666     def make_segments_profile(self, fileout, lenmin = 3, lenmax = 10, effmin = 50, lem = False) :
667         d = {}
668         for b, classe in enumerate(self.lc) :
669             for uce in self.getconcorde(classe) :
670                 uce = uce[1].split()
671                 if lem :
672                     uce = [self.formes[forme].lem for forme in uce]
673                 for taille_segment in range(lenmin,lenmax) :
674                     d =self.count_from_list_cl([' '.join(uce[i:i+taille_segment]) for i in range(len(uce)-(taille_segment - 1))], d, b, len(self.lc))
675         result = [[seg] + [str(val) for val in d[seg]] for seg in d if sum(d[seg]) >= effmin]
676         with open(fileout, 'w') as f :
677             f.write('\n'.join([';'.join(line) for line in result]))
678     
679     def make_proftype(self, outf) :
680         res = {}
681         for lem in self.lems :
682             gram = self.lems[lem].gram
683             if not gram in res :
684                 res[gram] = [0 for val in self.lc]
685             lemuceeff = self.getlemuceseff(lem)
686             for i, classe in enumerate(self.lc) :
687                 concern = set(classe).intersection(lemuceeff.keys())
688                 res[gram][i] += sum([lemuceeff[uce] for uce in concern])
689         res = [[gram] + [`val` for val in res[gram]] for gram in res]
690         res.sort()
691         with open(outf, 'w') as f :
692             f.write('\n'.join([';'.join(line) for line in res]).encode(self.parametres['syscoding']))
693
694
695     def make_ucecl_from_R(self, filein) :
696         with open(filein, 'rU') as f :
697             c = f.readlines()
698         c.pop(0)
699         self.lc = []
700         for line in c :
701             line = line.replace('\n', '').replace('"', '').split(';')
702             self.lc.append([int(line[0]) - 1, int(line[1])])
703         classesl = [val[1] for val in self.lc]
704         clnb = max(classesl)
705         self.lc = sorted(self.lc, key=itemgetter(1))
706         self.lc = [[uce[0] for uce in self.lc if uce[1] == i] for i in range(clnb+1)]
707         self.lc0 = self.lc.pop(0)
708         #return ucecl
709     
710     def get_stat_by_cluster(self, outf) :
711         log.info('get_stat_by_cluster')
712         t1 = time()
713         occurrences = dict([[i + 1, 0] for i in range(len(self.lc))])
714         formescl = dict([[i + 1, 0] for i in range(len(self.lc))])
715         hapaxcl = dict([[i + 1, 0] for i in range(len(self.lc))])
716         lenclasses = dict([[i+1,len(cl)] for i, cl in enumerate(self.lc)])
717         sets = [set(cl) for cl in self.lc]
718         for forme in self.formes :
719             formeuceeff = self.getformeuceseff(forme)
720             for i, classe in enumerate(self.lc) :
721                 concern = sets[i].intersection(formeuceeff.keys())
722                 if len(concern) :
723                     occurrences[i+1] += sum([formeuceeff[uce] for uce in concern])
724                     formescl[i+1] += 1
725                     if self.formes[forme].freq == 1 :
726                         hapaxcl[i+1] += 1
727         toprint = '\n'.join([';'.join([`i`, `occurrences[i]`, `formescl[i]`, `hapaxcl[i]`, `lenclasses[i]`, `float(hapaxcl[i])/float(formescl[i])`]) for i in occurrences])
728         with open(outf, 'w') as f :
729             f.write(toprint)
730         log.info('%f' % (time() - t1))        
731
732     def gethapaxbyet(self, etoiles) :
733         hapaxuces = [self.getlemuces(forme)[0] for forme in self.lems if self.lems[forme].freq == 1]
734         hucesdict = {}
735         for uce in hapaxuces :
736             if uce in hucesdict :
737                 hucesdict[uce] += 1
738             else :
739                 hucesdict[uce] = 1
740         etuces = [[] for et in etoiles]
741         for uci in self.ucis :
742             get = list(set(uci.etoiles).intersection(etoiles))
743             if len(get) > 1 :
744                 return '2 variables sur la meme ligne'
745             elif get != [] :
746                 etuces[etoiles.index(get[0])] += [uce.ident for uce in uci.uces]
747         etuces = [set(val) for val in etuces]
748         return [sum([hucesdict[uce] for uce in list(etuce.intersection(hapaxuces))]) for etuce in etuces]
749
750     def gethapaxuces(self) :
751         hapaxuces = [self.getlemuces(forme)[0] for forme in self.lems if self.lems[forme].freq == 1]
752         hapax = [forme for forme in self.lems if self.lems[forme].freq == 1]
753         hucesdict = {}
754         for i,uce in enumerate(hapaxuces) :
755             if uce in hucesdict :
756                 hucesdict[uce][0] += 1
757                 hucesdict[uce][1].append(hapax[i])
758             else :
759                 hucesdict[uce] = [1,[hapax[i]]]
760         huces = {}
761         for uce in hucesdict :
762             if hucesdict[uce][0] in huces :
763                 huces[hucesdict[uce][0]].append(uce)
764             else :
765                 huces[hucesdict[uce][0]] = [uce]
766         huces = zip(huces, huces.values())
767         huces.sort(reverse=True)
768         txt = """
769         <html><body>
770         """
771         for nb in huces[0:4] :
772             txt += "<p><h2>%i hapax par uce</h2><p>\n" % nb[0]
773             for uce in nb[1] :
774                 res = self.getconcorde([uce])
775                 for row in res :
776                     ucetxt = ' ' + row[1] + ' '
777                     uceid = row[0]
778                 for hap in hucesdict[uce][1] :
779                     laforme = self.getforme([forme for forme in self.lems[hap].formes][0]).forme
780                     ucetxt = ucetxt.replace(' '+laforme+' ', ' <font color=red>'+laforme+'</font> ')
781                 txt += '<p><b>' + ' '.join(self.getetbyuceid(uceid)) + '</b></p>'
782                 txt += '<p>'+ucetxt+'</p>\n'
783         txt += """
784         </body></html>
785         """
786         with open('/tmp/testhapxuce.html','w') as f :
787             f.write(txt)
788
789     def export_dictionary(self, fileout, syscoding) :
790         listformes = [[self.formes[forme].freq, forme, self.formes[forme].lem, self.formes[forme].gram] for forme in self.formes]
791         listformes.sort(reverse = True)
792         listformes = [forme[1:] + [`forme[0]`] for forme in listformes]
793         with open(fileout, 'w') as f :
794             f.write('\n'.join(['\t'.join(forme) for forme in listformes]).encode(syscoding))
795
796     def export_lems(self, fileout, syscoding) :
797         self.make_idformes()
798         listlem = [[lem, '\t'.join(['\t'.join([self.idformes[forme].forme, `self.lems[lem].formes[forme]`]) for forme in self.lems[lem].formes])] for lem in self.lems]
799         listlem.sort()
800         with open(fileout, 'w') as f :
801             f.write('\n'.join(['\t'.join(lem) for lem in listlem]).encode(syscoding))
802
803
804
805
806 class MakeUciStat :
807     def __init__(self, corpus) :
808         ucinb = corpus.getucinb()
809         ucisize = corpus.getucisize()
810         ucimean = float(sum(ucisize))/float(ucinb)
811         detoile = corpus.make_etoiles_dict()
812         
813
814 class Uci :
815     def __init__(self, iduci, line, paraset = None) :
816         self.ident = iduci
817         self.etoiles = line.split()
818         self.uces = []
819         if paraset is not None :
820             self.paras = paraset.split()
821         else :
822             self.paras = []
823
824 class Uce :
825     def __init__(self, iduce, idpara, iduci) :
826         self.ident = iduce
827         self.para = idpara
828         self.uci = iduci
829
830 class Word :
831     def __init__(self, word, gramtype, idword, lem = None, freq = None) :
832         self.forme = word
833         self.lem = lem
834         self.gram = gramtype
835         self.ident = idword
836         self.act = 1
837         if freq is not None :
838             self.freq = freq
839         else :
840             self.freq = 1
841
842 class Lem :
843     def __init__(self, parent, forme) :
844         self.formes = {forme.ident : forme.freq}
845         self.gram = forme.gram
846         self.freq = forme.freq
847         self.act = forme.act
848
849     def add_forme(self, forme) :
850         self.formes[forme.ident] = forme.freq
851         self.freq += forme.freq
852
853 def decouperlist(chaine, longueur, longueurOptimale) :
854     """
855         on part du dernier caractère, et on recule jusqu'au début de la chaîne.
856         Si on trouve un '$', c'est fini.
857         Sinon, on cherche le meilleur candidat. C'est-à-dire le rapport poids/distance le plus important.
858     """
859     separateurs = [[u'.', 6.0], [u'?', 6.0], [u'!', 6.0], [u'£$£', 6.0], [u':', 5.0], [u';', 4.0], [u',', 1.0], [u' ', 0.01]]
860     dsep = dict([[val[0],val[1]] for val in separateurs])
861     trouve = False                 # si on a trouvé un bon séparateur
862     iDecoupe = 0                # indice du caractere ou il faut decouper
863     
864     longueur = min(longueur, len(chaine) - 1)
865     chaineTravail = chaine[:longueur + 1]
866     nbCar = longueur
867     meilleur = ['', 0, 0]        # type, poids et position du meilleur separateur
868     
869     try :
870         indice = chaineTravail.index(u'$')
871         trouve = True
872         iDecoupe = indice - 1
873     except ValueError :
874         pass
875     if not trouve:
876         while nbCar >= 0:
877             caractere = chaineTravail[nbCar]
878             distance = abs(longueurOptimale - nbCar) + 1
879             meilleureDistance = abs(longueurOptimale - meilleur[2]) + 1
880             if caractere in dsep :
881                 if (float(dsep[caractere]) / distance) > (float(meilleur[1]) / meilleureDistance) :
882                     meilleur[0] = caractere
883                     meilleur[1] = dsep[caractere]
884                     meilleur[2] = nbCar
885                     trouve = True
886                     iDecoupe = nbCar
887             else :
888                 if (float(dsep[' ']) / distance) > (float(meilleur[1]) / meilleureDistance) :
889                     meilleur[0] = ' '
890                     meilleur[1] = dsep[' ']
891                     meilleur[2] = nbCar
892                     trouve = True
893                     iDecoupe = nbCar
894             nbCar = nbCar - 1
895     # si on a trouvé
896     if trouve:
897         #if meilleur[0] != ' ' :
898         #    fin = chaine[iDecoupe + 1:]
899         #    retour = chaineTravail[:iDecoupe]
900         #else :
901         fin = chaine[iDecoupe + 1:]
902         retour = chaineTravail[:iDecoupe + 1]
903         return len(retour) > 0, retour, fin
904     # si on a rien trouvé
905     return False, chaine, ''
906
907 def testetoile(line) :
908     return line.startswith(u'****')
909
910 def testint(line) :
911     return line[0:4].isdigit() and u'*' in line
912
913 def prep_txtlist(txt) :
914     return txt.split() + [u'$']
915
916 def prep_txtcharact(txt) :
917     return txt + u'$'
918
919 class BuildCorpus :
920     """
921     Class for building a corpus
922     """
923     def __init__(self, infile, parametres_corpus, lexique = None, expressions = None, dlg = None) :
924         log.info('begin building corpus...')
925         self.lexique = lexique
926         self.expressions = expressions
927         self.dlg = dlg
928         self.corpus = Corpus(self, parametres_corpus)
929         self.infile = infile
930         self.last = 0
931         self.lim = parametres_corpus.get('lim', 1000000)
932         self.encoding = parametres_corpus['encoding']
933         self.corpus.pathout = PathOut(filename = parametres_corpus['originalpath'], dirout = parametres_corpus['pathout'])
934         self.corpus.pathout.createdir(parametres_corpus['pathout'])
935         self.corpus.parametres['uuid'] = str(uuid4())
936         self.corpus.parametres['corpus_name'] = os.path.split(self.corpus.parametres['pathout'])[1]
937         self.corpus.parametres['type'] = 'corpus'
938         if self.corpus.parametres['keep_ponct'] :
939             self.ponctuation_espace = [' ', '']
940         else :
941             self.ponctuation_espace =  [' ','.', u'£$£', ';', '?', '!', ',', ':','']
942         self.cleans = []
943         self.tolist = self.corpus.parametres.get('tolist', 0)
944         self.buildcleans()
945         self.prep_makeuce()
946         #create database
947         self.connect()
948         self.dobuild()
949
950     def prep_makeuce(self) :
951         method = self.corpus.parametres.get('ucemethod', 0)
952         if method == 1 :
953             self.decouper = decouperlist
954             self.prep_txt = prep_txtlist
955             self.ucesize = self.corpus.parametres.get('ucesize', 40)
956         elif method == 0 :
957             self.decouper = decoupercharact
958             self.prep_txt = prep_txtcharact
959             self.ucesize = self.corpus.parametres.get('ucesize', 240)
960         log.info('method uce : %s' % method)
961
962     def dobuild(self) :    
963         t1 = time()
964         try :
965             self.read_corpus(self.infile)
966         except Warning, args :
967             log.info('pas kool %s' % args)
968             raise Warning
969         else :    
970             self.indexdb()
971             self.corpus.parametres['ira'] = self.corpus.pathout['Corpus.cira']
972             self.time = time() - t1
973             self.dofinish()
974             DoConf().makeoptions(['corpus'],[self.corpus.parametres], self.corpus.pathout['Corpus.cira'])
975             log.info('time : %f' % (time() - t1))
976
977     def connect(self) :
978         self.conn_f = sqlite3.connect(self.corpus.pathout['formes.db'])
979         self.cf = self.conn_f.cursor()
980         self.cf.execute('CREATE TABLE IF NOT EXISTS uces (id INTEGER, uces TEXT);')
981         self.cf.execute('CREATE TABLE IF NOT EXISTS eff (id INTEGER, eff TEXT);')
982         self.conn_f.commit()
983         self.cf = self.conn_f.cursor()
984         self.cf.execute('PRAGMA temp_store=MEMORY;')
985         self.cf.execute('PRAGMA journal_mode=MEMORY;')
986         self.cf.execute('PRAGMA  synchronous = OFF;')
987         self.cf.execute('begin')
988         self.conn = sqlite3.connect(self.corpus.pathout['uces.db'])
989         self.c = self.conn.cursor()
990         self.c.execute('CREATE TABLE IF NOT EXISTS uces (id INTEGER, uces TEXT);')
991         self.conn.commit()
992         self.c = self.conn.cursor()
993         self.c.execute('PRAGMA temp_store=MEMORY;')
994         self.c.execute('PRAGMA journal_mode=MEMORY;')
995         self.c.execute('PRAGMA  synchronous = OFF;')
996         self.c.execute('begin')
997
998     def indexdb(self) :
999         #commit index and close db
1000         self.conn.commit()
1001         self.conn_f.commit()
1002         self.cf.execute('CREATE INDEX iduces ON uces (id);')
1003         self.cf.execute('CREATE INDEX ideff ON eff (id);')
1004         self.c.close()
1005         self.cf.close()
1006         #backup corpora
1007         self.conn_corpus = sqlite3.connect(self.corpus.pathout['corpus.db'])
1008         self.ccorpus = self.conn_corpus.cursor()
1009         self.ccorpus.execute('CREATE TABLE IF NOT EXISTS etoiles (uci INTEGER, et TEXT, paras TEXT);')
1010         self.ccorpus.execute('CREATE TABLE IF NOT EXISTS luces (uci INTEGER, para INTEGER, uce INTEGER);')
1011         self.ccorpus.execute('CREATE TABLE IF NOT EXISTS formes (ident INTEGER, forme TEXT, lem TEXT, gram TEXT, freq INTEGER);')
1012         self.conn_corpus.commit()
1013         self.ccorpus = self.conn_corpus.cursor()
1014         self.ccorpus.execute('PRAGMA temp_store=MEMORY;')
1015         self.ccorpus.execute('PRAGMA journal_mode=MEMORY;')
1016         self.ccorpus.execute('PRAGMA  synchronous = OFF;')
1017         self.ccorpus.execute('begin')
1018         self.backup_corpus()
1019         self.ccorpus.execute('CREATE INDEX iduci ON luces (uci);')
1020         self.conn_corpus.commit()
1021         self.conn_corpus.close()
1022         #self.corpus.parametres['corpus_ira'] = self.corpus.pathout['corpus.cira']
1023
1024     def buildcleans(self) :
1025         if self.corpus.parametres.get('lower', 1) :
1026             self.cleans.append(self.dolower)
1027         if self.corpus.parametres.get('firstclean', 1) :
1028             self.cleans.append(self.firstclean)
1029         if self.corpus.parametres['charact'] :
1030             self.rule = self.corpus.parametres.get('keep_caract', u"^a-zA-Z0-9àÀâÂäÄáÁéÉèÈêÊëËìÌîÎïÏòÒôÔöÖùÙûÛüÜçÇßœŒ’ñ.:,;!?*'_")
1031             self.cleans.append(self.docharact)
1032         if self.corpus.parametres.get('expressions', 1) :
1033             self.cleans.append(self.make_expression)
1034         if self.corpus.parametres.get('apos', 1) :
1035             self.cleans.append(self.doapos)
1036         if self.corpus.parametres.get('tiret', 1):
1037             self.cleans.append(self.dotiret)
1038
1039     def make_expression(self,txt) :
1040          for expression in self.expressions:
1041             if expression in txt :
1042                 txt = txt.replace(expression, self.expressions[expression][0])
1043          return txt
1044     
1045     def dolower(self, txt) :
1046         return txt.lower()
1047
1048     def docharact(self, txt) :
1049         #rule = u"^a-zA-Z0-9àÀâÂäÄáÁéÉèÈêÊëËìÌîÎïÏòÒôÔöÖùÙûÛüÜçÇßœŒ’ñ.:,;!?*'_-"
1050         list_keep = u"[" + self.rule + "]+"
1051         return re.sub(list_keep, ' ', txt)
1052     
1053     def doapos(self, txt) :
1054         return txt.replace(u'\'', u' ')
1055
1056     def dotiret(self, txt) :
1057         return txt.replace(u'-', u' ')
1058
1059     def firstclean(self, txt) :
1060         txt = txt.replace(u'’',"'")
1061         txt = txt.replace(u'œ', u'oe')
1062         return txt.replace('...',u' £$£ ').replace('?',' ? ').replace('.',' . ').replace('!', ' ! ').replace(',',' , ').replace(';', ' ; ').replace(':',' : ').replace(u'…', ' £$£ ')
1063
1064     def make_cleans(self, txt) :
1065         for clean in self.cleans :
1066             txt = clean(txt)
1067         return txt
1068
1069     def backup_uce(self) :
1070         if self.corpus.idformesuces != {} :
1071             log.info('backup %i' % len(self.corpus.idformesuces))
1072             touce = [(`forme`, ' '.join([`val` for val in  self.corpus.idformesuces[forme].keys()])) for forme in self.corpus.idformesuces]
1073             toeff = [(`forme`, ' '.join([`val` for val in  self.corpus.idformesuces[forme].values()])) for forme in self.corpus.idformesuces]
1074             self.cf.executemany('INSERT INTO uces VALUES (?,?);', touce)
1075             self.cf.executemany('INSERT INTO eff VALUES (?,?);', toeff)
1076         self.corpus.idformesuces = {}        
1077         self.count = 1
1078
1079     def backup_corpus(self) :
1080         log.info('start backup corpus')
1081         t = time()
1082         for uci in self.corpus.ucis :
1083             self.ccorpus.execute('INSERT INTO etoiles VALUES (?,?,?);' ,(uci.ident,' '.join(uci.etoiles), ' '.join(uci.paras,)))
1084             for uce in uci.uces : 
1085                 self.ccorpus.execute('INSERT INTO luces VALUES (?,?,?);',(`uci.ident`,`uce.para`,`uce.ident`,))
1086         for forme in self.corpus.formes :
1087             self.ccorpus.execute('INSERT INTO formes VALUES (?,?,?,?,?);', (`self.corpus.formes[forme].ident`, forme, self.corpus.formes[forme].lem, self.corpus.formes[forme].gram, `self.corpus.formes[forme].freq`,))
1088         log.info('%f' % (time() - t))
1089
1090     def dofinish(self) :
1091         self.corpus.parametres['date'] = datetime.datetime.now().ctime()
1092         minutes, seconds = divmod(self.time, 60)
1093         hours, minutes = divmod(minutes, 60)
1094         self.corpus.parametres['time'] = '%.0fh %.0fm %.0fs' % (hours, minutes, seconds)
1095         self.corpus.parametres['ucinb'] = self.corpus.getucinb()
1096         self.corpus.parametres['ucenb'] = self.corpus.getucenb()
1097         self.corpus.parametres['occurrences'] = self.corpus.gettotocc()
1098         self.corpus.parametres['formesnb'] = len(self.corpus.formes)
1099         hapaxnb = self.corpus.gethapaxnb()
1100         pourhapaxf = (float(hapaxnb) / len(self.corpus.formes)) * 100
1101         pourhapaxocc = (float(hapaxnb) / self.corpus.parametres['occurrences']) * 100
1102         self.corpus.parametres['hapax'] = '%i - %.2f %% des formes - %.2f %% des occurrences' % (hapaxnb, pourhapaxf, pourhapaxocc)
1103
1104
1105 class BuildFromAlceste(BuildCorpus) :
1106     def read_corpus(self, infile) :
1107         if self.dlg is not None :
1108             self.dlg.Pulse('textes : 0 - segments : 0')
1109         self.limitshow = 0
1110         self.count = 1
1111         if self.corpus.parametres['ucimark'] == 0 :
1112             self.testuci = testetoile
1113         elif  self.corpus.parametres['ucimark'] == 1 :
1114             self.testuci = testint
1115         txt = []
1116         iduci = -1
1117         idpara = -1
1118         iduce = -1
1119         try :
1120             with codecs.open(infile, 'r', self.encoding) as f :
1121                 for linenb, line in enumerate(f) :
1122                     line = line.rstrip('\n\r')
1123                     if self.testuci(line) :
1124                         iduci += 1
1125                         if txt != [] :
1126                             iduce, idpara = self.treattxt(txt, iduce, idpara, iduci - 1)
1127                             txt = []
1128                             self.corpus.ucis.append(Uci(iduci, line))
1129                         else :
1130                             if iduci > 0 :
1131                                 if self.corpus.ucis[-1].uces == [] :
1132                                     log.info(u'Empty text : %i' % linenb)
1133                                     iduci -= 1
1134                                     self.corpus.ucis.pop()
1135                             self.corpus.ucis.append(Uci(iduci, line))
1136                         if self.dlg is not None :
1137                             if not (iduci + 1) % 10 :
1138                                 self.dlg.Pulse('textes : %i - segments : %i' % (iduci + 1, iduce +1))
1139                     elif line.startswith(u'-*') :
1140                         if iduci != -1 :
1141                             if txt != [] :
1142                                 iduce, idpara = self.treattxt(txt, iduce, idpara, iduci)
1143                                 txt = []
1144                             idpara += 1
1145                             self.corpus.ucis[-1].paras.append(line.split()[0])
1146                         else :
1147                             raise Exception('paragrapheOT %i' % linenb)
1148                     elif line.strip() != '' and iduci != -1 :
1149                         txt.append(line)
1150             if txt != [] and iduci != -1 :
1151                 iduce, idpara = self.treattxt(txt, iduce, idpara, iduci)
1152                 del(txt)
1153             else :
1154                 if iduci != -1 :
1155                     iduci -= 1
1156                     self.corpus.ucis.pop()
1157                     log.info(Exception("Empty text %i" % linenb))
1158                 else :
1159                     raise Exception('EmptyText %i' % linenb)
1160             if iduci != -1  and iduce != -1:
1161                 self.backup_uce()
1162             else : 
1163                 log.info(_(u"No Text in corpora. Are you sure of the formatting ?"))
1164                 raise Exception('TextBeforeTextMark %i' % linenb)
1165         except UnicodeDecodeError :
1166             raise Exception("CorpusEncoding")
1167
1168     def treattxt(self, txt, iduce, idpara, iduci) :
1169         if self.corpus.parametres.get('ucemethod', 0) == 2 and self.corpus.parametres['douce']:
1170             txt = 'laphrasepoursplitter'.join(txt)
1171             txt = self.make_cleans(txt)
1172             txt = ' '.join([val for val in txt.split() if val not in self.ponctuation_espace])
1173             ucetxt = txt.split('laphrasepoursplitter')
1174         else :
1175             txt = ' '.join(txt)
1176             txt = self.make_cleans(txt)
1177             ucetxt = self.make_uces(txt, self.corpus.parametres['douce'])
1178         if self.corpus.ucis[-1].paras == [] :
1179             idpara += 1
1180         for uce in ucetxt :
1181             iduce += 1
1182             self.corpus.ucis[-1].uces.append(Uce(iduce, idpara, iduci))
1183             self.c.execute('INSERT INTO uces VALUES(?,?);', (`iduce`,uce))
1184             if not self.tolist :
1185                 uce = uce.split()
1186             else :
1187                 uce = list(uce)
1188             for word in uce :
1189                 self.last += 1
1190                 self.corpus.add_word(word)
1191         log.debug(' '.join([`iduci`,`idpara`,`iduce`]))
1192         if self.last > self.lim :
1193             self.backup_uce()
1194             self.last = 0
1195         return iduce, idpara
1196
1197     def make_uces(self, txt, douce = True, keep_ponct = False) :
1198         txt = ' '.join(txt.split())
1199         if douce :
1200             out = []
1201             reste, texte_uce, suite = self.decouper(self.prep_txt(txt), self.ucesize + 15, self.ucesize)
1202             while reste :
1203                 uce = ' '.join([val for val in texte_uce if val not in self.ponctuation_espace])
1204                 if uce != '' :
1205                     out.append(uce)
1206                 reste, texte_uce, suite = self.decouper(suite, self.ucesize + 15, self.ucesize)
1207             uce = ' '.join([val for val in texte_uce if val not in self.ponctuation_espace])
1208             if uce != '' : 
1209                 out.append(uce)
1210             return out
1211         else :
1212             return [' '.join([val for val in txt.split() if val not in self.ponctuation_espace])]
1213
1214 #decouper (list_sep)
1215 #make_uces (decouper)
1216 #treat_txt (make_uces)
1217 #read (treat_txt)
1218
1219 class Builder :
1220     def __init__(self, parent, dlg = None) :
1221         self.parent = parent
1222         self.dlg = dlg
1223         parametres = DoConf(os.path.join(self.parent.UserConfigPath,'corpus.cfg')).getoptions('corpus')
1224         parametres['pathout'] = PathOut(parent.filename, 'corpus').mkdirout()
1225         dial = CorpusPref(parent, parametres)
1226         dial.CenterOnParent()
1227         dial.txtpath.SetLabel(parent.filename)
1228         #dial.repout_choices.SetValue(parametres['pathout'])
1229         self.res = dial.ShowModal()
1230         if self.res == 5100 :
1231             parametres = dial.doparametres()
1232             parametres['originalpath'] = parent.filename
1233             PathOut().createdir(parametres['pathout'])
1234             ReadLexique(self.parent, lang = parametres['lang'])
1235             if parametres['lang'] != 'other' and  os.path.exists(self.parent.DictPath.get(parametres['lang']+'_exp', 'french_exp')):
1236                 self.parent.expressions = ReadDicoAsDico(self.parent.DictPath.get(parametres['lang']+'_exp', 'french_exp'))
1237             else :
1238                 self.parent.expressions = {}
1239             self.parametres = parametres
1240         else :
1241             if self.dlg is not None :
1242                 self.dlg.Destroy()
1243         dial.Destroy()
1244
1245     def doanalyse(self) :
1246         return BuildFromAlceste(self.parent.filename, self.parametres, self.parent.lexique, self.parent.expressions, dlg = self.dlg).corpus
1247
1248
1249 if __name__ == '__main__' :
1250     t1 = time()
1251     parametres = {'formesdb':'formes.db', 'ucesdb': 'uces.db', 'corpusdb' : 'corpus.db', 'syscoding' : 'utf-8', 'encoding' : encoding}
1252     intro = BuildCorpus(infile, parametres)#, tar_in, tar_infouce)#, tar_formes)
1253     print time() - t1