Dateiinhalt überschreiben, bzw. immer wieder neu generieren

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.
Antworten
wido
User
Beiträge: 11
Registriert: Montag 16. Januar 2017, 23:11

Hallo,

Ich möchte mit Ausführen meines Programms Inhalte in eine Datei schreiben. Es handelt sich um ca. 10 Zeilen. Wenn ich das Programm erneut ausführe, möchte ich, dass das Programm den bestehenden Inhalt überschreibt. Momentan ist es leider so, dass ich nur mit dem 'a'ppend weiterkomme. Konsequenz ist jedoch, dass mit jedem Ausführen des Programms die Inhalte in die Datei dazugefügt werden, statt dass es neu erzeugt wird. Hier mein Code:

Code: Alles auswählen

import re

text = open("abc.txt")
for line in text:
    if re.search(r"\|+", line):
        new_line = line.replace("|", "\t\t")

        article = open("article.txt", "a")
        article.write(str(new_line))
        article.close()

Könntet Ihr mir eventuell helfen und erklären, wie eine Datei samt Inhalt immer wieder neu generiert werden kann?

Danke und Gruß,
wido
Zuletzt geändert von Anonymous am Montag 16. Januar 2017, 23:36, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@wido: Öffne die Datei im 'w'-Modus. Dann wird der alte Inhalt beim öffnen verworfen. Allerdings darfst Du dann nicht für jede Zeile die Datei erneut öffnen und schliessen, weil dann natürlich nur die letzte Zeile in der Datei stehen wird.

Der reguläre Ausdruck ist mit Kanonen auf Spatzen geschossen, denn Du willst ja eigentlich nur nach einem '|' suchen. Das geht auch mit ``if '|' in line:``.
wido
User
Beiträge: 11
Registriert: Montag 16. Januar 2017, 23:11

@BlackJack Wie muss ich die Datei dann öffnen? :K Habe es in anderen Konstellationen probiert, leider ohne Erfolg.
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

BlackJack hat geschrieben:Öffne die Datei im 'w'-Modus.
Was hast Du denn konkret versucht?
wido
User
Beiträge: 11
Registriert: Montag 16. Januar 2017, 23:11

Sirius3 hat geschrieben:
BlackJack hat geschrieben:Öffne die Datei im 'w'-Modus.
Was hast Du denn konkret versucht?
@Sirius3 Ich habe beispielsweise, wie von BlackJack vorgeschlagen, die Datei nicht im Rahmen einer Schleife immer wieder neu geöffnet, sondern außerhalb. Trotzdem kommt im Ergebnis immer nur die eine letzte Zeile meines erwarteten Outputs. Hier der Code:

Code: Alles auswählen

line = ""
text = open("abc.txt")
for line in text:
    if "|" in line:
        line.replace("|", "\t\t")

article = open("article.txt", "w")
article.write(str(line))
article.close()
Zuletzt geändert von Anonymous am Dienstag 17. Januar 2017, 11:04, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@wido: Warum hättest Du hier etwas anderes als die letzte Zeile erwartet? Da wird nur *einmal* `write()` aufgerufen, *nach* der Schleife die alle Zeilen aus der Eingabe abarbeitet. Und dabei effektiv nichts tut weil einfach nur `replace()` aufzurufen ohne mit dem Rückgabewert irgend etwas zu machen — zum Beispiel ihn in eine Datei zu schreiben — keinen Effekt hat, ausser ein bisschen Rechenzeit und Speicher zu verwenden.
wido
User
Beiträge: 11
Registriert: Montag 16. Januar 2017, 23:11

Hmm, stimmt. Ich habe jetzt den Dateiinhalt in ein Array gesteckt und durchlaufe es, so oft wie es lang ist. Und dabei gebe ich mit einer write-Anweisung an, dass in die Datei reingeschrieben werden soll. Das funktioniert jetzt zwar, d. h. es werden mehrere Zeilen reingeschrieben, bzw. der Dateiinhalt überschrieben, jedoch ist es immer die selbe Zeile die immer wieder reingeschrieben wird. Hier mein Code

Code: Alles auswählen

text = open("abc.txt")
lines = text.readlines()
for line in lines:
    if "|" in line:
        line.replace("|", "\t\t")

        article = open("article.txt", "w")
        for i in range(len(lines)):
            article.write(str(line))
        article.close()
Ich habe das Gefühl, dass ich der Lösung immer näher komme. Was fehlt mir noch im Code, damit alle Dateiinhalte reingeschrieben werden? Momentan wird immer die gleiche letzte Zeile mehrfach reingeschrieben. Hier der Output zur besseren Veranschaulichung:

European Game All-American12
European Game All-American12
European Game All-American12
European Game All-American12
European Game All-American12
European Game All-American12
European Game All-American12
European Game All-American12
European Game All-American12
European Game All-American12
European Game All-American12
European Game All-American12


Danke im Voraus.
Zuletzt geändert von Anonymous am Dienstag 17. Januar 2017, 12:13, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

@wido: versuche mal zu lesen, was Du da machst, und dabei genau auf jedes Wort achten. Wenn wird was wie oft in die Datei geschrieben?
BlackJack

@wido: Das ist doch ganz logisch das wenn Du eine Schleife schreibst die immer wieder die gleiche Zeichenkette schreibt, diese Zeichenkette so oft in der Datei ist, wie die Schleife durchlaufen wurde. Überleg doch mal systematisch was Du machen musst und hör auf wild herum zu probieren. Diese innere Schleife macht überhaupt keinen Sinn. Es wird auch nicht nur die letzte Zeile in dieser Schleife in eine Datei geschrieben sondern jede Zeile die ein '|' enthält wird dort mehrfach geschrieben. Da die Datei aber für jede dieser Zeilen mit 'w' geöffnet wird, bleibt am Ende halt nur eine Datei übrig in der das Ergebnis des letzten Treffers steht, weil die davor durch das öffnen mit 'w' wieder verworfen werden.
wido
User
Beiträge: 11
Registriert: Montag 16. Januar 2017, 23:11

@BlackJack, @Sirius3,

habs geschafft. Vielen Dank für eure Unterstützung und dass Ihr mich gefördert und gefordert habt. :-)

Erst mit euren Hinweisen konnte ich meinen Code lauffähig machen. Leider bin ich noch Programmieranfänger, deswegen wirke ich noch ein bißchen unbeholfen. Ich hoffe ich kann hier noch viel lernen. Hier noch der Code, falls es jemanden interessiert:

Code: Alles auswählen

import re

text = open("abc.txt")
lines = text.readlines()
for line in lines:
    if re.search(r"\|+", line):
        new_line = line.replace("|", "\t\t")
        lines.append(new_line)


        article = open("article.txt", "w")
        for i in range(int((len(lines)/2)),len(lines)):
            article.write(str(lines[i]))
        article.close()

Danke nochmal!
wido
Zuletzt geändert von Anonymous am Dienstag 17. Januar 2017, 12:53, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@wido: Du hast nicht wirklich verstanden wie das funktioniert, denn selbst wenn das Ergebnis stimmen sollte, ist das da falsch, eben weil man sehr deutlich sieht das nicht verstanden wurde wie Schleifen abgearbeitet werden.

Ausserdem wird nur die Hälfte der Zeilen geschrieben und Indexzugriffe sind in Python eher selten und hier absolut ”unpythonisch”.

Das unnötige `re` ist wieder im Spiel. Ebenfalls unnötig ist es Zeichenketten mit `str()` in Zeichenketten zu wandeln, denn das sind ja schon Zeichenketten. Was soll der Aufruf an der Stelle bewirken?
wido
User
Beiträge: 11
Registriert: Montag 16. Januar 2017, 23:11

BlackJack hat geschrieben: Das unnötige `re` ist wieder im Spiel. Ebenfalls unnötig ist es Zeichenketten mit `str()` in Zeichenketten zu wandeln, denn das sind ja schon Zeichenketten. Was soll der Aufruf an der Stelle bewirken?
Stimmt, 're' habe ich wieder getauscht. Ist mir wohl untergekommen, als ich mehrere Versionen des Codes offen hatte und wohl das falsche zu Ende bearbeitet habe. Und 'str" brauche ich wirklich nicht, Danke!

Ich weiß schon, dass mein Code unpythonisch ist. Für den Moment reicht mir das vorerst, da diese Aufgabe ein Teil von einem größeren Studien-Projekt ist und ich nun damit weiterarbeiten kann.

@BlackJack Ich finde es echt super, wie du mich zum vertieften Nachdenken zu animieren versuchst. Ich hoffe, ich kann eines Tages deinen Anforderungen gerecht werden :-)

Danke und bis demnächst!
wido
BlackJack

@wido: Neben ”unpythonisch” würde ich das aber generell auch noch als falsch ansehen da eine innere Schleife zu haben die völlig unnötigerweise eine quadratische Abhängigkeit in der Laufzeit von der Anzahl der Ausgabezeilen hat. Jede der Ausgabezeilen sollte genau *einmal* geschrieben werden, und wenn nur die hintere Hälfte der Ergebniszeilen geschrieben werden soll, dann sollten auch nur diese Zeilen einmal geschrieben werden.

Die Eingabedatei wird übrigens nicht geschlossen.

Mal die neu hinzugekommene Anforderung, dass es nur die zweite Hälfte des Ergebnisses sein soll ignorierend, sähe eine Lösung in QBasic so aus (wenn schon schlechte Lösungen dann Retro und mit Stil :-)):
[codebox=qbasic file=Unbenannt.txt]CONST OldDelim$="|"

InFile=FREEFILE
OPEN "abc.txt" FOR INPUT AS InFile
OutFile=FREEFILE
OPEN "test.txt" FOR OUTPUT AS OutFile
WHILE NOT EOF(InFile)
LINE INPUT #InFile,line$

IF INSTR(line$,OldDelim$)<>0 THEN
newLine$=""
i=1
DO
j=INSTR(i,line$,OldDelim$)
IF j<>0 THEN
newLine$=newLine$+MID$(line$,i,j-i)+CHR$(9)+CHR$(9)
i=j+1
END IF
LOOP UNTIL j=0
newLine$=newLine$+MID$(line$,i,LEN(line$))

PRINT #OutFile,newLine$
END IF
WEND
CLOSE InFile
CLOSE OutFile[/code]
wido
User
Beiträge: 11
Registriert: Montag 16. Januar 2017, 23:11

:!: :mrgreen:
Antworten