Seite 1 von 1
in Datei schreiben... ARG
Verfasst: Donnerstag 10. April 2008, 17:38
von Peak_me
Hallo!
Code: Alles auswählen
for i in range()
text1=...
zeile1=...
text=text1+' * '+zeile1+' * '
Datei.write(text)
In der Schleife laufen hier mit text1 und zeile1 verschiedene Sachen ab.
Sie sollen dann beide in eine Zeile mit ein bisschen Verschönerung dazwischen geschrieben werden. Doch habe ich mir dann überlegt, dass ich doch alles hintereinander in einer Zeile haben will und habe es deshalb so umgeformt:
Code: Alles auswählen
for i in range():
text=text+text1+' * '+zeile1+' * '
Datei.write(text)
"text" wächst hier bei jedem Schleifendurchlauf um "text1+' 1 '+zeile1+' '" an.
Ich möchte ja, dass das alles nach dem kompletten Schleifendurchlauf in die Datei in *eine* Zeile geschrieben wird.
Doch wird es das nicht. Nach "text" findet jedesmal ein Zeilenumbruch statt. Ich habe auch die beteiligten Dateitypen verändert, es hat nichts gebracht.
´
Wieso tut es das nur?
Gruß
peak
Verfasst: Donnerstag 10. April 2008, 18:31
von BlackJack
Der Quelltext da oben tut gar nicht:
Code: Alles auswählen
In [46]: for i in range():
....: pass
....:
---------------------------------------------------------------------------
<type 'exceptions.TypeError'> Traceback (most recent call last)
/home/bj/<ipython console> in <module>()
<type 'exceptions.TypeError'>: range expected at least 1 arguments, got 0
Wenn der echte Quelltext Zeilenumbrüche in die Datei schreibt, dann müssen in den Daten halt irgend wo Zeilenumbrüche enthalten sein. Auf "magische" Weise kommen die da nicht hinein.
Zeig doch mal ein kleines, lauffähiges Stück Quelltext mit dem Problem, so dass man das auch nachvollziehen kann.
Verfasst: Donnerstag 10. April 2008, 18:47
von Peak_me
Natürlich funktioniert das da oben nicht; Teile funktionieren auch nicht.
Ich wollte es aber nicht so abschreckend viel aussehen lassen
Code: Alles auswählen
fd=open("C:\Dokumente und Einstellungen\Besitzer\Desktop\Deutsch.txt")
Indew = open("C:\Dokumente und Einstellungen\Besitzer\Desktop\Index.txt", "w")
buch=fd.readlines()
alpha=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','Ä','Ö','Ü']
laenge=len(alpha)
zeile=buch[0]
zeilenanfang=zeile[0]+zeile[1]+zeile[2]
n=0
for i in range(laenge):
for j in range(laenge):
for k in range(laenge):
text=alpha[i]+alpha[j]+alpha[k]
if text==zeilenanfang:
while text==zeilenanfang:
textw=text+' 1 '+zeile
Indew.write(textw)
n=n+1
zeile=buch[n]
zeilenanfang=zeile[0]+zeile[1]+zeile[2]
else:
textr=text+' 0 '+'\n'
Indew.write(textr)
Dazu brauch man ne Textdatei, in der in jeder Zeile ein Wort in Großbuchstaben steht (Deutsch.txt) und ne leere Datei (Index.txt).
In der Index-Datei sollen später alle Kombinationen mit drei Buchstaben stehen; also:
"
AAA
AAB
AAC
...
ÜÜÜ
"
Wenn in der Deutsch.txt ein Wort mit einer dieser Kombinationen anfängt, soll auf die Kombination eine "1" folgen und danach alle zutreffenden Wörter. Wenn es kein passendes Wort gibt, soll dahinter ne "0" stehen.
Jetzt wird aber für jedes Wort eine eigenen Zeile angelegt, was ich vermeiden will.
Verfasst: Donnerstag 10. April 2008, 23:17
von BlackJack
Ich könnte Dir jetzt sagen wo die Zeilenumbrüche her kommen, aber vielleicht lernst Du mehr wenn Du das selber heraus findest. Lass Dir an den entscheidenden Stellen mal die Einzelteile mit ``print repr(objekt)`` anzeigen.
Ansonsten braucht man die Zeilen nicht komplett einlesen, sondern kann die Datei Zeile für Zeile abarbeiten. Damit spart man schon einmal das `n` ein.
`zeile` und `zeilenanfang` muss man auch nicht vor den Schleifen bestimmen, wenn man den Quelltext ein wenig umstellt.
Statt den `range()`\s kann man direkt über die Elemente von `alpha` iterieren. Ausserdem würde ich aus `alpha` eine Unicode-Zeichenkette machen und den Dateiinhalt auch dekodieren (`codecs.open()`). Da auch Umlaute vorkommen, funktioniert dieser Quelltext zum Beispiel nicht mehr wenn diese Zeichen mit mehr als einem Byte kodiert werden.
`zeilenanfang` lässt sich mit "slicing" kürzer schreiben.
Können Worte mit weniger als drei Zeichen vorkommen? Falls ja, verhält sich das Programm wie gewünscht?
Verfasst: Freitag 11. April 2008, 10:14
von BlackJack
Ein Lösungsansatz mit `itertools.groupby()`:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import division, with_statement
import codecs
import string
from itertools import groupby
def iter_words_file(filename, encoding, min_length=3):
"""Returns iterable over upper cased words from `filename`
that are at least `min_length` characters long.
:rtype: iterable of `unicode`
"""
with codecs.open(filename, 'rb', encoding) as lines:
for line in lines:
line = line.strip()
if len(line) >= min_length:
yield line.upper()
def iter_groups(words, index_length=3):
"""Returns an iterable over tuples of an index key and all words
for that key separated by spaces.
The `words` must be sorted.
>>> words = ['foo', 'foobar', 'python', 'pythonista', 'spam']
>>> groups = iter_groups(words)
>>> groups.next()
('foo', 'foo foobar')
>>> groups.next()
('pyt', 'python pythonista')
>>> groups.next()
('spa', 'spam')
"""
return ((k, ' '.join(w))
for k, w in groupby(words, lambda word: word[:index_length]))
def main():
alphabet = string.uppercase + u'ÄÖÜ'
index_keys = (a + b + c
for a in alphabet
for b in alphabet
for c in alphabet)
key2words = dict(iter_groups(iter_words_file('/usr/share/dict/ngerman',
'iso-8859-1')))
for index_key in index_keys:
print '%s %d %s' % (index_key,
index_key in key2words,
key2words.get(index_key, ''))
if __name__ == '__main__':
main()
Verfasst: Freitag 11. April 2008, 16:45
von Peak_me
Hallo!
Ich habe alles mal mit repr(obj) durchgeschaut.
Was macht dieser Befehl eigentlich?
Dabei ist mir aufgefallen, dass "zeile" immer noch ein "\n" am Ende enthält.
Deshalb habe ich versucht mit
das letzte Element (='\n') aus dem String zu löschen.
Doch gibt es diesen Befehl bei Strings nicht, deswegen habe ich ein bisschen rungesucht und bin auf
gestoßen. Ist zwar nicht das Wahre, aber es funktioniert.
Danke für deine Hilfe!
Deine eigene Version versuche ich mal zu verstehen.
Verfasst: Freitag 11. April 2008, 16:50
von Peak_me
Ach und:
"Können Worte mit weniger als drei Zeichen vorkommen? Falls ja, verhält sich das Programm wie gewünscht?"
Ja, dass dabei das Programm abbricht, habe ich schon gemerkt.
Deswegen habe ich ein anderes Programm geschrieben, das alle 2er-Wörter aus der Datei löscht. Die kann ich später sowieso nicht gebrauchen.
Dabei ist mir aufgefallen, dass zeilenlaenge=len(zeile) immer einen um 1 zu großen Wert geliefert hat. Ich dachte, dass das nen Bug oder so wäre und habe dann einfach alle Wörter mit der Länge 3 gelöscht, was dann alle mit der realen Länge von 2 gelöscht hat.
Jetzt weiß ich, dass dieser "Bug" das angehängte "\n" war

Verfasst: Freitag 11. April 2008, 17:00
von mkesper
Peak_me hat geschrieben:
Dabei ist mir aufgefallen, dass "zeile" immer noch ein "\n" am Ende enthält.
Siehe
"Strings" im Tutorial.
Verfasst: Freitag 11. April 2008, 18:41
von Peak_me
Danke, hab ich gleich eingearbeitet!