À la base j’aurais pas dû poster ça dans un journal mais dans un forum. Le fait que ce soit un journal m’incite à continuer à poster mon code...
Voici donc la dernière version de Reader.py, script dont le but est de prendre n’importe quel fichier texte en entrée, le découper en « phrases » et stocker la fréquence d’apparition de ces « phrases » dans une base SQLite.
#!/usr/bin/env python3"""Reader.py: Read text for sentences frequencies."""__author__="M4rotte"__copyright__="Copyright 2015, Institut Marotte for Mouling"__license__="GPL"__version__="0.4"importsysimportreimportsqlite3fromcollectionsimportCounterclassReader:def__init__(self):self.sb=''self.characters=Counter()self.sentences=Counter()self.signature=''self.sig96=''self.start=re.compile(r'^(\n|)[\-–—«ÉÀÇÔÎÖÏA-Za-z]$')# If string buffer (self.sb) match, just read next character.self.stop=re.compile(r'(.|\n)+[.!?...:]( |\n)$')# If self.sb match, consider self.sb valid sentence, store it in self.sentences and reset self.sb.self.discard=re.compile(r'^(([0-9]+)([\\:]+)|##)(.*)(\n|)')# If self.sb match, just drop it.self.correct_tiret=re.compile(r'^( |)-')# If match (it's obviously part of a dialog), replace the tiret with the designed Unicode character.self.cancel_stop=re.compile(r'(.*|)( |\n)(M|Me)(\.)( |\n|)$');# If match (means it matched self.stop first...), just don't "stop" and read next character.self.nb_insert=0# Number of inserts off the last read()self.nb_update=0# Number of updates off the last read() self.nb_record=0# Number of records in the updated databasedefread(self,f):"""Read input and populate `sentences`"""whileTrue:c=f.read(1)ifnotc:breakifc=='\xa0':c=' 'self.characters[c]+=1self.sb+=cifself.sbin[' ','\n','»']:self.sb=''continueifself.discard.match(self.sb):self.sb=''continueifself.start.match(self.sb):continueifself.stop.match(self.sb)andnotself.cancel_stop.match(self.sb):ifself.correct_tiret.match(self.sb):self.sb=self.sb.replace('-','–')self.sentences[self.sb.strip()]+=1self.sb=''continueforcinself.characters.most_common():self.signature+=c[0]self.sig96=self.signature[:96].replace('\n',' ')defstore(self,dbfile='reader.sqlite'):""" Update the database from `sentences` """connection=sqlite3.connect(dbfile)cursor=connection.cursor()cursor.execute('create table if not exists sentences (sentence text primary key unique, freq int)')## For futur use :) # cursor.execute('create virtual table if not exists fts_strings using fts4(string text, freq int, tokenize=unicode61 "remove_diacritics=0" "tokenchars= ")')# Store `sentences` into databaseforsinself.sentences.most_common():try:cursor.execute("insert into sentences values (?, ?)",(s[0],s[1]))self.nb_insert+=1exceptsqlite3.IntegrityError:self.nb_update+=1cursor.execute("update sentences set freq=freq+? where sentence = ?",(s[1],s[0]))self.nb_record=cursor.execute('select count(*) from sentences;')sys.stderr.write('Database update: '+str(self.nb_insert)+' inserts '+str(self.nb_update)+' updates '+str(self.nb_record.fetchone()[0])+' records. SIG96 : '+str(self.sig96)+'\n')connection.commit()try:reader=Reader()reader.read(sys.stdin)reader.store()exceptKeyboardInterruptaserror:print('\n'+repr(error),file=sys.stderr)sys.stderr.flush()sys.stdout.flush()exit(1)
La sortie en partant d’une base inexistante et en la renseignant à partir de classiques de la littérature française, posts du bouchot et contenu issu de Wikipédia (histoire d’avoir des entrées assez hétérogènes) :
$ for f in *.txt; do ./Reader.py < "$f"; done; sqlite3 ../linuxfr.org.sqlite 'select message from posts;' | ./Reader.py ; sqlite3 ../Wikipedia.sqlite 'select fact from facts;' | ./Reader.py
Database update: 7498 inserts 0 updates 7498 records. SIG128 : eaistnrulodcmp v,é’fqh.gbàx-jyè;–ALê?«»zkC!SEJMKDI:WPçO...îôâQVNT#œû_ùwBUïRG1FYÀ2()É307H5486][9ÔX
Database update: 7533 inserts 74 updates 15031 records. SIG128 : eaistnrulodcpm v,é’qf.hbgàjx-yè–;AêL?«»kCzE!SM:JIPDKWîçVôNOTâQ_...û#ùœBw0RïU1ÀF2G()3YHÉ5][847°69ü
Database update: 7367 inserts 33 updates 22398 records. SIG128 : easitnrulodcmp ,év’f.qgbhàèxj-êyMIL;EPCS«»Az!RâçJ:DFVûîTô...?ùOGQ–UœNïÀB1É8H{Ç45/kë#0w397XÔ2Z)6—]
Database update: 2496 inserts 2 updates 24894 records. SIG128 : esatinrulodcpmé, v'qfgbh.àxèCy;jê-LAG\:IRzôSBçâTHPîDûVMEù12Q3O«4»N5ï0U687œ?9FÉJ)(_!...ëÀW
Database update: 10914 inserts 71 updates 35808 records. SIG96 : easitnrulodc mp,év’.bfhgqxà»!èj«;-yMAêIECLFDz?P:çSRâOVJîTôQUBùN—...ûHG()ïk1#8X3Ç2w4590Yë6óW7Z\áñú
Database update: 1359 inserts 15 updates 37167 records. SIG96 : esitanrulodpmc '.é,v-qbfghjàxJèIEC!:ML?TyAêçPzQOS»«BVHûRîâùXôÇDNU2ï1F3()69À05Éë8Z°;7
Database update: 10707 inserts 62 updates 47874 records. SIG96 : eaistnrulodmpc év,’q.fhbgàjMx-èJêyL;CIz–!ERSVAP?Dâç:ûôQî...FBTNOœUùÀ#XHGÉï1*()0»«8Kw637k°924YW5ÊZ
Database update: 5734 inserts 79 updates 53608 records. SIG96 : eastinrulodcmp év'.,fqgbh-àjTxèyIêL!çJEC«»A?kMHPSzDOB...Nô*Qûâ:RUîV{ùXœ_ÀÇwGF;1ÉW/()2ï][YZ07438}Î
Database update: 7114 inserts 64 updates 60722 records. SIG96 : easintrulodm,cp vé’qf.hgbàjxè—-yêM:L!zEACJ?IP;çD»...«FôSVùTâOûNBQîR–œUHGÀ1kÉw2X907K5ü84ï#ëäÇY3WÈÊ
Database update: 10690 inserts 123 updates 71412 records. SIG96 : eastinrulodc,mp vé'.fghbq-àjxè!yMEêLC;N...zIPçADSâF?VBT:OôJûùîGURHQZœ_À»«Çk*{Éw1Xïë4Ô05W2Ê73Y
Database update: 24771 inserts 29 updates 96183 records. SIG96 : eastinruol:cpdm1 20fh/vé'5b3.qg4-,j76<>98"wyx?à[]=ç͌!kèêzCA’_;&SET)LPMOINJD(FBRU\VHG%ô...+W̚҉Qû█«
Database update: 67825 inserts 14 updates 164008 records. SIG96 : eainrstoludcmép,. ghvbf1q'()y9L02ACxè-MSjPàBk†8DRJ3IGçF5746T:EzNê°HV’OKUwÉ«W»Xôûî;ïZâYQœ%áù/í"ë
On peut voir que l’intégration du contenu Wikipédia amène à certains biais (et c’est pas Me Soleil qui s’en plaindra...) mais que « Ah ! » et « Oh ! » restent des valeurs sûres :
$ sqlite3 reader.sqlite "select * from sentences order by freq desc limit 30;"
Signe du zodiaque :|358
M.|224
Ah !|194
« Ah !|181
– Ah !|180
Mgr Paul Guérin, Vie des saints ; t.|162
– Oh !|148
Pas de journée internationale répertoriée pour cette date.|134
Oh !|100
« Oh !|87
Les noms de plusieurs voies, places, sites ou édifices, de pays ou régions francophones, contiennent cette date sous diverses graphies :|66
– Eh bien !|59
France :|59
Eh bien !|56
États-Unis :|52
Décembre :|49
Bahaïsme :|47
Février :|46
Juin :|43
– Tiens !|40
Octobre :|40
Hein ?|39
–C'est quoi ça ?|39
Mai :|39
Fêtes religieuses romaines :|39
Mars :|38
« Non !|37
dit Frédéric.|36
Japon :|36
— Ah !|35
# Ça avance
Posté par Marotte ⛧ . En réponse au journal Analyse de texte. Évalué à 2.
À la base j’aurais pas dû poster ça dans un journal mais dans un forum. Le fait que ce soit un journal m’incite à continuer à poster mon code...
Voici donc la dernière version de Reader.py, script dont le but est de prendre n’importe quel fichier texte en entrée, le découper en « phrases » et stocker la fréquence d’apparition de ces « phrases » dans une base SQLite.
La sortie en partant d’une base inexistante et en la renseignant à partir de classiques de la littérature française, posts du bouchot et contenu issu de Wikipédia (histoire d’avoir des entrées assez hétérogènes) :
On peut voir que l’intégration du contenu Wikipédia amène à certains biais (et c’est pas Me Soleil qui s’en plaindra...) mais que « Ah ! » et « Oh ! » restent des valeurs sûres :
Vous pouvez reprendre une activité normale.