Bitte um Tipps

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.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

keppla hat geschrieben:implementiert ist er afaik aber als utf-32, will heissen: u'x' hätte eine "Nutzlast" von 4 Bytes im speicher.
Es gibt sowohl UCS2 als auch UCS4-Versionen von Python...
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

Leonidas hat geschrieben:
keppla hat geschrieben:implementiert ist er afaik aber als utf-32, will heissen: u'x' hätte eine "Nutzlast" von 4 Bytes im speicher.
Es gibt sowohl UCS2 als auch UCS4-Versionen von Python...
Was ich eigentlich sagen wollte, war, dass man über unicodestrings keine annahmen Treffen sollte, die über länge und inhalt hinausgehen. Das intern verwendete encoding ist afaik nicht ermittelbar (ist auch gut so), und es kann eben auch mal utf32 sein.
Imho sollte man sich über sowas keine Gedanken machen (Zustimmung zu BlackJacks Post).
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

keppla hat geschrieben:Das intern verwendete encoding ist afaik nicht ermittelbar (ist auch gut so), und es kann eben auch mal utf32 sein.
Direkt nicht, indirekt schon. Habe aber gerade keine UCS2-Version von Python zur Hand um das zu prüfen.
keppla hat geschrieben:Imho sollte man sich über sowas keine Gedanken machen (Zustimmung zu BlackJacks Post).
Von mir auch Zustimmung.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
TEXTiX-X
User
Beiträge: 20
Registriert: Montag 22. Oktober 2007, 08:40
Wohnort: Dortmund
Kontaktdaten:

Kann mir einer helfen indem er mir vielleicht zeigt wie man bei meinem code alles sequentiell einlesen und abfragen kann?

Ich habe eine wörterbuch datei. da sind regelrecht richtige wörter drin. so um die 500000.

jetzt hab ich eine datei mit sätzen. eine normale text datei mit ca. 11 mb sätze.

das ganze dauert schon im moment eine lange zeit wenn ich das mit diesem code mache:

Code: Alles auswählen

# -*- coding: cp1252 -*-
import time

def readWordlist(filename):
    words = set()
    for line in open(filename, "r"):
        words.update(set([w for w in line.strip().split()]))
    return words

def main():
    start = time.time()
    wordList = readWordlist("vollform.txt")
    for line in open("sentences.txt", "r"):
        words = line.strip() \
                    .replace('.', '') \
                    .replace('"', '') \
                    .replace('!', '') \
                    .replace('?', '') \
                    .replace('---', '') \
                    .replace(',', '') \
                    .replace('“', '') \
                    .replace('”', '') \
                    .replace("'", '' ) \
                    .split()
        for w in words:
            f = open("words.txt", "w")
            g = open("wordsinvollform.txt", "w")
            if w in wordList:
                g.write(w)
            else:
                f.write(w)
                
    print time.time() - start, "s"

    print f

if __name__ == "__main__":
    main()
das ganze muss ja irgendwie praktischer berbeitet werden können das das schneller und besser geht.

p.s.: ja ich weiß das mit den sonderzeichen ist nicht gerade ideal gelöst. aber ich hab auch keine ahnung wie ich da erstmal alle sonderzeichen einlese die's gibt... noch nix im net gefunden.. *schäm, ich noob*
TEXTiX-X
User
Beiträge: 20
Registriert: Montag 22. Oktober 2007, 08:40
Wohnort: Dortmund
Kontaktdaten:

Okay ich hab's herausgefunden.. das ganze läuft jetzt nicht mehr allzu langsam.

allerdings will man ja das ding so genau wie möglich machen.... jetzt hab ich natürlich noch ein paar sonderzeichen hinzugefügt die durch leerzeichen ersetzt werden, aber je mehr sonderzeichen ich da natürlich rein mache desto länger dauert das.

also theoretisch brauch der jetzt 45 sek für einen durchlauf:

kann mir jemand erklären wie genau ich das ganze schneller machen kann und trotzdem noch genau bin?
ich weiß das es schneller geht.... aber nicht wie-.-

Code: Alles auswählen

# -*- coding: cp1252 -*-
import time

def readWordlist(filename):
    words = set()
    for line in open(filename, "r"):
        words.update(set([w for w in line.strip().split()]))
    return words

def main():
    start = time.time()
    wordList = readWordlist("vollform.txt")
    data = readWordlist("sentences.txt")
    #positiv = ["J" , "j", "y", "yes", "jap", "Y", "Yes", "Jo"] (für erweiterung)
    #negativ = ["nein","ne","Nein","Ne","noe","Noe","n","N","nE","nope"] (für erweiterung)
    for line in data:
        words = line.strip() \
                    .replace('ue', 'ü') \
                    .replace('oe', 'ö') \
                    .replace('ae', 'ä') \
                    .replace('Ae', 'Ä') \
                    .replace('Oe', 'Ö') \
                    .replace('Ue', 'Ü') \
                    .replace('.', '') \
                    .replace('"', '') \
                    .replace('!', '') \
                    .replace('?', '') \
                    .replace('-', '') \
                    .replace(',', '') \
                    .replace('“', '') \
                    .replace('”', '') \
                    .replace('_', '') \
                    .replace(';', '') \
                    .replace('(', '') \
                    .replace(')', '') \
                    .replace('[', '') \
                    .replace(']', '') \
                    .replace('}', '') \
                    .replace('=', '') \
                    .replace('{', '') \
                    .replace(':', '') \
                    .replace("'", '' ) \
                    .replace("1", '' ) \
                    .replace("2", '' ) \
                    .replace("3", '' ) \
                    .replace("4", '' ) \
                    .replace("5", '' ) \
                    .replace("6", '' ) \
                    .replace("7", '' ) \
                    .replace("8", '' ) \
                    .replace("9", '' ) \
                    .replace("0", '' ) \
                    .split()
        for w in words:
            f = open("wordsnotinvollform.txt", "a")
            g = open("wordsinvollform.txt", "a")
            wl = w + "\n"
            if w in wordList:
                g.writelines(wl)
            else:
                f.writelines(wl)
                
    print time.time() - start, "s"


    f.close()
    g.close()
    

if __name__ == "__main__":
    main()
BlackJack

Schau Dir mal die `translate()`-Methode auf Zeichenketten an.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Mmh, wenn du nicht zwei Zeichen mit einem Zeichen erzetzen wolltest, sondern jeweils ein Zeichen mit genau einem Zeichen, wuerde ich dir translate ans Herz legen:

Code: Alles auswählen

>>> import string
>>> s = "asldfk{sdf{sdf}ASd[AS]2lkj(h342346534lk)6j.erZZZ"
>>> transtable = string.maketrans("Z", "A")
>>> deletechars = string.punctuation + string.digits
>>> print s.translate(transtable, deletechars)
asldfksdfsdfASdASlkjhlkjerAAA
Du koenntest es zumindest verwenden, um die ueberfluessigen Zeichen loszuwerden, wenn du in Zeile 3 schreibst:

Code: Alles auswählen

>>> transtable = string.maketrans("", "")
Aber da du ja ausserdem "Ae" mit "Ä" ersetzen willst... eventuell kann man da seinen eigenen Codec fuer schreiben und mit encode arbeiten? K.A., wieviel Aufwand das zu Programmieren waere, und wie die Performance da ist.
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Mehrere Dingen fallen mir auf:
Warum öffnest Du die Dateien bei jedem Schleifendurchlauf neu? Sie nur einmal vor den Schleifen zu öffnen, würde sicher viel Zeit sparen.

Code: Alles auswählen

[w for w in line.strip().split()]
dürfte dasselbe Ergebnis wie

Code: Alles auswählen

line.strip().split()
liefern.
Enthalten line und words wirklich mehrere Worte?
Reicht statt writelines nicht auch write?
MfG
HWK
TEXTiX-X
User
Beiträge: 20
Registriert: Montag 22. Oktober 2007, 08:40
Wohnort: Dortmund
Kontaktdaten:

Puuuhhh danke erstmal.....

Sitze grad ein bisschen dran und ist irgendwie schiwierig umzusetzen. der nimmt words nicht als variable (in Rebecca's Beispiel "s") an. spuckt deshlab nen fehler aus

die translate methode sieht plausibel aus (gut das es sowas gibt) auf die ö's, ä's, und ü's verzichte ich diesmal... denn die kann man auch noch hinterher vom programm korrigieren lassen.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Rebecca hat geschrieben:eventuell kann man da seinen eigenen Codec fuer schreiben
Mmh, das codecs-Modul bringt anscheinend auch nur Helfer fuer das Umwandeln einzelner Zeichen in einzelne Zeichen mit (charmaps). Den Rest muss man da anscheinend auch von Hand machen, bringt also nichts.
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Rebecca hat geschrieben:Mmh, das codecs-Modul bringt anscheinend auch nur Helfer fuer das Umwandeln einzelner Zeichen in einzelne Zeichen mit (charmaps).
In Python 3.0 wird man Codecs auch nur für Zeichen -> Zeichen verwenden können, daher ist das auch nicht zukunftssicher.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Leonidas hat geschrieben:
keppla hat geschrieben:Das intern verwendete encoding ist afaik nicht ermittelbar (ist auch gut so), und es kann eben auch mal utf32 sein.
Direkt nicht, indirekt schon. Habe aber gerade keine UCS2-Version von Python zur Hand um das zu prüfen.
Es geht auch direkt und ohne Umwege.

Code: Alles auswählen

>>> import sys
>>> sys.maxunicode
1114111
Das ist ucs4, bei ucs2 wärs 65535.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Leonidas hat geschrieben:In Python 3.0 wird man Codecs auch nur für Zeichen -> Zeichen verwenden können, daher ist das auch nicht zukunftssicher.
Also kein decode("bz2") mehr?
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Rebecca hat geschrieben:Also kein decode("bz2") mehr?
Nein:
http://www.artima.com/weblogs/viewpost.jsp?thread=208549 hat geschrieben:We are adopting a slightly different approach to codecs: while in Python 2, codecs can accept either Unicode or 8-bits as input and produce either as output, in Py3k, encoding is always a translation from a Unicode (text) string to an array of bytes, and decoding always goes the opposite direction. This means that we had to drop a few codecs that don't fit in this model, for example rot13, base64 and bz2 (those conversions are still supported, just not through the encode/decode API).
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Markus12
User
Beiträge: 195
Registriert: Dienstag 6. März 2007, 19:32
Wohnort: Frankfurt am Main

Damit man das besser überblicken kann würde ich gerne wissen was in den Textdateien zu finden ist mit den Namen "vollform.txt" und "sentences.txt".
Das sind für mich nicht aussagende Namen.
"story.txt" allerdings konnte ich mir denken, dass dies die datei sein soll, in der dein Text steht.
TEXTiX-X
User
Beiträge: 20
Registriert: Montag 22. Oktober 2007, 08:40
Wohnort: Dortmund
Kontaktdaten:

In vollform.txt befinden sich etwa 500000 Wörter die korrekt geschrieben sind.. etwa eine art wörtersammlung/Duden
In sentences.txt befindet sich im moment eine satzsammlung mit geschätzt 200000 sätzen.
story.txt ist ein ganz normaler text.. irgendetwas was ich aus dem internet per copy/paste reinkopiert habe (im grunde als testdatei damit ich das ganze fix testen kann.

story.txt und sentences.txt sind im grunde die dateien die überprüft werden, ob es fehler in dem text gibt, oder o sie wörter enthalten die in der Vollform noch nicht enthalten sind.

Das ganze soll hinterher so funktionieren, wie ein rechtschreib programm in msword.

was es im moment tut und zwar problemlos ist, dass es die wörter die noch nicht in vollform enthalten sind hinzufügt.

aber was ich noch nicht hinbekommen habe ist, dass das programm dieses wort im text korrigiert. das ganz soll natürlich per eingabeaufforung geregelt werden.

jetzt weiß ich das ich das auf 2 möglichkeiten realisieren kann.

1. Ich kann das programm dazubringen, den text den es überprüft, danach Wort für Wort in die datei wieder reinzuschreiben... was sehr unpraktisch wäre, denn satzzeichen reinzubringen wäre zusätzliche arbeit und das programm würde in der geschwindigkeit sehr drunter leiden.

2. ich finde einen befehl der das wort was überprüft wird und nicht passt durch das korrekt geschriebene ersetzt(replace-befehl)


meine frage ist: gibt es einen replace befehl in diesem fall oder wie kann man das umsetzen.

anbei der aktuelle code:

Code: Alles auswählen

# -*- coding: cp1252 -*-
import time
import sys

def readWordlist(filename):
    words = set()
    for line in open(filename, "r"):
        words.update(set([w for w in line.strip().split()]))
    return words

def main():
    start = time.time()
    wordList = readWordlist("vollform.txt")
    data = readWordlist("story.txt")
    positiv = ["J" , "j", "y", "yes", "jap", "Y", "Yes", "Jo"] #(für erweiterung)
    negativ = ["nein","ne","Nein","Ne","noe","Noe","n","N","nE","nope"] #(für erweiterung)
    for line in data:
        words = line.strip() \
                    .replace('Ae', 'Ä') \
                    .replace('Oe', 'Ö') \
                    .replace('Ue', 'Ü') \
                    .replace('.', '') \
                    .replace('"', '') \
                    .replace('!', '') \
                    .replace('?', '') \
                    .replace('-', '') \
                    .replace(',', '') \
                    .replace('“', '') \
                    .replace('”', '') \
                    .replace('_', '') \
                    .replace(';', '') \
                    .replace('(', '') \
                    .replace(')', '') \
                    .replace('[', '') \
                    .replace(']', '') \
                    .replace('}', '') \
                    .replace('=', '') \
                    .replace('{', '') \
                    .replace(':', '') \
                    .replace("'", '' ) \
                    .replace("1", '' ) \
                    .replace("2", '' ) \
                    .replace("3", '' ) \
                    .replace("4", '' ) \
                    .replace("5", '' ) \
                    .replace("6", '' ) \
                    .replace("7", '' ) \
                    .replace("8", '' ) \
                    .replace("9", '' ) \
                    .replace("0", '' ) \
                    .split()
        for w in words:
            d = open("story.txt", "a")
            v = open("vollform.txt", "a")
            f = open("wordsnotinvollform.txt", "a")
            g = open("wordsinvollform.txt", "a")
            wl = w + "\n"
            if w in wordList:
                g.writelines(wl)
            else:
                edit = raw_input("Möchten Sie den Begriff " + w + " zum Wörterbuch hinzufügen?")
                if edit in positiv:
                    v.writelines(wl)
                    print w + " wurde zum Wörterbuch hinzugefügt!"
                elif edit in negativ:
                    edit2 = raw_input("Möchten Sie den Begriff " + w + " im Text ändern?")
                    if edit2 in positiv:
                        editw = raw_input("Schreiben Sie das Wort bitte richtig.")
                        w = editw
                        d.write(w)
                    elif edit2 in negativ:
                        f.writelines(w)
               
    print time.time() - start, "sec"


    f.close()
    g.close()
   

if __name__ == "__main__":
    main()
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Hi TEXTiX-X!
  1. Dieses replace-Ding kannst du in einer Schleife oder mit re viel kürzer schreiben.
  2. Du öffnest für jedes Wort in der zu testenden Datei 4 Weitere Dateien, die 500.000 oder 200.000 Wörter enthalten.
  3. Die eingentliche Textdatei wird zu einem set-Objekt eingelesen.

    :arrow: So kannst du das Wort nicht ersetzen. Du kannst zwar die gesammte Textdatei einlesen, dann "dein text mit feler".replace("feler", "fehern") schreiben, und das ganze wieder in die datei schreiben, aber da hast du 3 große Probleme:
    1. Du ersetzt alle Worte im Text, was nicht erwünscht sein muss.
    2. Du weißt selbst nicht, welches Wort gemeint ist, da durch das set'ten
      viele Infos verloren gehen, und mit .find() ist da auch nix zu machen,
      denn die Identität der einzelnen Wörter wird durch set zerstört.
    3. Du erkennst keine Gramatik, so würdes du "felers" nach user-eingabe durch "fehler" ersetzen, im kontex ist es aber eine andere Form (~"des fehlers größter...")
:arrow: So ein Rechtschreibprogramm ist wesentlich komplizierter als man denkt, und "nur worte ersetzen" geht halt auch nicht. :wink:

Gruß, jj
TEXTiX-X
User
Beiträge: 20
Registriert: Montag 22. Oktober 2007, 08:40
Wohnort: Dortmund
Kontaktdaten:

danke für die antwort:

zu 1.: das mit re ist so ne sache... ich hab das noch nicht ganz verstanden.... irgendwie

zu 2.: 2 der texdateien sind leer. alle 4 dateien werde geöffnet damit aus ihnenn weiterhin gelesen werden kann dachte ich und das in ihnen auch geschrieben werden kann.

zu 3. das versteh ich nicht ganz. ich dachte mir das ich meine wörterbuch-datei mit dem set-datentyp einlese damit das programm schneller wird. was es letztendlich auch ist....

wenn dadurch das wort nicht ersetzbar ist, hhmmmm dann ist das ja doof -.-
BlackJack

Vielleicht ist dieses Projekt für den Anfang einfach eine Nummer zu gross.

zu 1.: Für das Erkennen und Ersetzen der Worte bietet sich `re.sub` an. Da kann man statt eines Ersetzungstextes auch eine Funktion angeben, die mit dem Match-Objekt aufgerufen wird und die Ersetzung zurückgibt. Wenn das Wort bekannt ist, gibt man es einfach zurück, sonst fragt man den Benutzer.

zu 2.: Das öffnen der Dateien geschieht an einer sehr ungünstigen Stelle. Du öffnest für *jedes Wort* diese vier Dateien. Wenn Du 1000 Worte hast, dann werden die Dateien auch 1000 mal geöffnet. Und nie geschlossen. Das funktioniert bei CPython zufällig, da sollte man sich aber nicht drauf verlassen. Und selbst hier verschwendet man einfach Zeit mit dem öffnen/erstellen von 3996 unnötigen Dateiobjekten.

Das schreiben eines neuen Wortes in die Wörterbuchdatei berücksichtigt das Wort im aktuellen Programmlauf noch nicht, es wird also trotzdem immer wieder als falsch angezeigt. Ich würde die Wörter in das `set()` speichern und das erst am Ende wieder (sortiert) in eine Textdatei schreiben.

zu 3.: Ja das einlesen des *Wörterbuchs* in ein `set()` beschleunigt das Programm. Weil man für ein Wort nun schnell testen kann, ob es in diesem `set()` enthalten ist. Das Problem ist das einlesen von `story.txt` in ein `set()`. Damit hast Du den Text nicht mehr sondern nur noch die Worte.

----

Es ist auch immer noch viel zu viel in der Hauptfunktion. Eine Funktion die den Benutzer nach einer Ja/Nein-Eingabe fragt und entsprechend `True` oder `False` zurückgibt, kann man da zum Beispiel rausziehen. Die ganzen Antwortmöglichkeiten sind Spielerei. Wenn die Frage in deutsch gestellt wird, sollte als Antwort Ja oder Nein bzw. der jeweilige Anfangsbuchstabe unabhängig von Gross-/Kleinschreibung genügen.

Wenn das ordentlich funktionieren soll, kommt man um Unicode nicht herum, nicht jeder benutzt 'cp1252' als Textkodierung, und ich denke auch um OOP ist schwer herumzukommen, wenn man das sauber schreiben möchte. Wie gesagt, ein relativ grosses Projekt.

Und eventuell ist es auch viel einfacher PyEnchant zu benutzen.
Markus12
User
Beiträge: 195
Registriert: Dienstag 6. März 2007, 19:32
Wohnort: Frankfurt am Main

@TEXTiX-X:

(Nur falls du es nicht weißt...) OOP bedeutet Objekt Orientierte Programmierung, einfach gesagt gibt es keine einzelnen Funktionen wie bei deinem Programm, sondern Klassen, in denen sie zu finden sind. OOP bietet einige sinnvolle Möglichkeiten, solltest du meiner Meinung nach in naher Zukunft anfangen zu lernen :D
Antworten