Programm für Textanalyse

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
M***

@Marc: Lass doch bei den Schlüsseln in dem Dictionary mit der Häufigkeitsverteilung einfach den Postfix '_dt' weg. Und auch wenn das Dictionary nur zur Anzeige dient, hätte ich die Werte als Fliesskommazahlen eingetragen. Falls man doch mal irgendwann damit rechnen will. Zum Beispiel wenn man die Abweichung eines analysierten Textes von der typischen Häufigkeit ausrechnen möchte oder so.
Das "_dt" kann ich weglassen, stimmt wohl.

Ich wollte die Zahlen als Fließkommazahl schreiben, aber dann passiert folgendes bekanntes Problem:

Code: Alles auswählen

>>> f = {'a': 6.51}
>>> f
{'a': 6.5099999999999998}
Sieht bei der Ausgabe verwirrend und nicht schön aus. Im Python-Wiki habe ich mir die Lösung angeguckt, da wird empfohlen, mit Strings zu arbeiten.
DaSch
User
Beiträge: 72
Registriert: Mittwoch 28. März 2007, 20:04
Kontaktdaten:

benutz doch einfach Sttringformatierung für die Ausgabe

Ich hab jetzt meine Version auch nochmal ein wenig überarbeitet und das alles mit funktionen etwas übersichtlicher gemacht

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-
import optparse
import time

def main():
    start=time.time()
    options,args,parser=parsing()
    text,char2count=fileopen(options,args,parser)
    if options.lower:
        text = text.lower()
    numworte,numchar,numchartotal=count(text,char2count)
    output(numworte,numchar,numchartotal,char2count,options)
    if options.test:
        test(start)

def parsing():

    parser = optparse.OptionParser()
    parser.set_usage("%prog [options] File")
    parser._add_version_option()
    parser.version="%prog 0.1"
    parser.add_option("-c","--case-sensitive",action="store_false", dest="lower",default=True,help="don't convert Letters to lowercase")
    parser.add_option("-p","--percentage",action="store_true", dest="percentage",default=False,help="Show Percentage of default Characters")
    parser.add_option("-P","--Percentage",action="store", type="string", dest="charcount",help="Show Percentage of charactres spezified in File",metavar="charfile")
    parser.add_option("-s","--special",action="store_true", dest="special",default=False,help="Analyse special charactres")
    parser.add_option("-t","--test",action="store_true", dest="test",default=False,help="Make a Speedtest")
    
    (options, args) = parser.parse_args()
    return options,args,parser

def fileopen(options,args,parser):    
    if len(args)>0:
        try:
            daten = file (args[0],'r')
            text = daten.read()
            daten.close()
        except IOError, err:
            print 'Error when reading File "%s":\n\t%s' % (err.filename, err)
            parser.exit()
    else:
        parser.print_help() 
        parser.exit()
    
    if options.charcount is not None:
        try:
            chardaten = file (options.charcount,'r')
            chartext = chardaten.read()
            chardaten.close()
            char2count=list(chartext)
        except IOError, err:
            print 'Error when reading File "%s":\n\t%s' % (err.filename, err)
            parser.exit()
    else:
        char2count=set(options)
    return text,char2count

def set(options):
    if options.lower:
        char2count=list("abcdefghijklmnopqrstuvwxyz")
    else:
        char2count=list("AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz")
    if options.special:
        char2count.append("--")
        char2count.extend(" ")
        spezial_char=".,;.´:-_#'+*~!?§$€%&()[]{}=\/|<>"
        char2count.extend(spezial_char)
    return char2count

def count (text,char2count):
    numworte=len(text.split())
    numchar = [text.count(char) for char in char2count]
    numchar = map(text.count, char2count)
    numchartotal = sum(numchar)
    return numworte,numchar,numchartotal

def output(numworte,numchar,numchartotal,char2count,options):
    percentage = options.percentage
    print "Anzahl der Worte:",numworte
    print "Anzahl der Buchstaben:",numchartotal
    print "Durchschnittliche Anzahl der Buchstaben pro Wort:",numchartotal/numworte
    if percentage:
        print "Anteile der Zeichen"
        for i in range(len(char2count)):
            char_tmp=char2count[i]
            if char_tmp != "--":
                num_tmp=float(numchar[i])
                numchartotal=float(numchartotal)
                proz=(num_tmp/numchartotal)*100
                print "Der Anteil von",char_tmp,"ist","%5.2f" % proz,"% Absolut:",numchar[i]
            else:
                print "------------------------------------------------------"
def test(start):
    print "Runtime: %.4f"%(time.time()-start),"Sekunden"
    print "Cputime: %.4f"%(time.clock()),"Sekunden"
    
if __name__ == '__main__':
    main()
M***

benutz doch einfach Sttringformatierung für die Ausgabe
Habe ich in meinem Programm ja benutzt. BlackJack meinte dann, ich solle Fließkommazahlen verwenden, um mit damit ggf. noch rechnen zu können. Darauf habe ich dann im Beitrag über deinem geantwortet.
BlackJack

Mit Stringformatierung war der ``%`` Operator gemeint und wenn man eine Fliesskommazahl als Zeichenkette oder als Fliesskommazahl formatiert, dann taucht das Problem nicht auf weil entsprechend gerundet wird:

Code: Alles auswählen

In [42]: 6.51
Out[42]: 6.5099999999999998

In [43]: '%s' % 6.51
Out[43]: '6.51'

In [44]: '%f' % 6.51
Out[44]: '6.510000'

In [45]: '%5.2f' % 6.51
Out[45]: ' 6.51'
Man kann also beides haben: Fliesskommazahlen mit denen sich rechnen lässt und eine Darstellung als Zeichenkette, die die Unvollkommenheit von Fliesskommazahlen versteckt.
M***

Ich verstehe nicht, wieso ich dann beides habe. Die Ausgabe ist doch ein String und keine Fließkommazahl. Wenn ich den Eintrag aus dem Dictionary aufrufe, dann wird doch der String benutzt:

Code: Alles auswählen

>>> f = {'a': '%s' % 6.51}
>>> f
{'a': '6.51'}
>>> f['a']
'6.51'
Was ist mein Denkfehler?
BlackJack

Wenn Du die Zahl schon im Dictionary als Zeichenkette formatierst, kannst Du natürlich gleich Zeichenketten schreiben.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Marc hat geschrieben:Was ist mein Denkfehler?
Am sinnvollsten ist, wenn du das Dictionary mit den Häufigkeiten mit konkreten Zahlen füllst, da du wahrscheinlich irgendwann mal mit diesen etwas berechnen musst und dir das Konvertieren von einem String in eine Fließkommazahl sprarst:

Code: Alles auswählen

f = {"a":6.51}
Wenn du den Wert als String haben möchtest, verwendetst du dann einfach immer den %-Operator mit entsprechenden Formatierungsangeben (wie ja schon von BlackJack angegeben):

Code: Alles auswählen

in_string = "Hier noch ein wenig Text: %5.2f. Und hier auch noch ein wenig" % f["a"]
M***

Das hatte ich missverstanden. Es hat jetzt funktioniert. Danke.
Antworten