Python aktuelle Zeile aus Datei löschen

OP #7383921
Lesenswert?

Hi ich habe eine Datei numbers.txt mit Zahlen von 1 bis 1000, und folgenden Python Code:

1
def is_prime(n):
2
  for i in range(2,n):
3
    if (n%i) == 0:
4
      return False
5
  return True
6

7
def main():
8
  with open("numbers.txt","r") as file:
9
      lines = file.readlines()
10
      for i, line in enumerate(lines):
11
        number = int(line.strip())
12
        if (is_prime(number)):
13
          print ("number", number, "is prime")
14
        else:
15
          # --> lösche aktuelle Zeile aus numbers.txt
16
          pass
17
  print ("Done")
18

19
main()

Mein Ziel ist es nun, die Zahlen die nicht prime sind, aus der genannten Datei zu löschen, ohne eine Hilfsdatei zu erzeugen. Ist dies möglich? z.I., das code snippet ist nur zum Testen und wird dann in einem wesentlich komplexeren Programm implementiert.

#7383924
Lesenswert?

Das hat mir ChatGPT ausgespuckt, probiere das mal aus (bei mir funktioniert es). Achso, ich lösche die Primzahlen, du musst einfach nur das not entfernen:

1
import math
2
import fileinput
3

4
def is_prime(n):
5
    """Check if a number is prime."""
6
    if n <= 1:
7
        return False
8
    for i in range(2, int(math.sqrt(n)) + 1):
9
        if n % i == 0:
10
            return False
11
    return True
12

13
for i, line in enumerate(fileinput.input("input.txt", inplace=True), 1):
14
    if not is_prime(i):
15
        print(line.rstrip())
#7383958
Lesenswert?

MaWin O. schrieb:

Man programmiert heute also in einem Englisch-Dialog? Warum sollte ich das tun wollen, statt das Programm einfach selbst zu schreiben? Manche verschlafen halt die neue Technologie.

Weil es wesentlich schneller und zuverlässiger geht. Hier die Korrektur von ChatGPT.

1
import math
2
import fileinput
3

4
def is_prime(n):
5
    """Check if a number is prime."""
6
    if n <= 1:
7
        return False
8
    for i in range(2, int(math.sqrt(n)) + 1):
9
        if n % i == 0:
10
            return False
11
    return True
12

13
for line in fileinput.input("input.txt", inplace=True):
14
    if not is_prime(int(line.strip())):
15
        print(line.rstrip())
#7383959
Lesenswert?

Ben S. schrieb:

Norbert schrieb:

Das macht es? Da hast du aber einen speziellen Computer.

Määh, wein doch. Ich habe die Zeile dessen Zeilennummer einer Prizahl entspricht entfernt.

Eine kleine Anfrage a ChatGPT und du hast das korrigiert. Das war MEIN Fehler und nicht von der KI.

Ändert nichts an der Tatsache das einem Erwachsenen schon bei der einfachen Betrachtung der Zeile mit dem enumerate sämtliche Alarmglocken geklingelt hätten.

Du beauftragst ein auf Labern optimiertes Programm, gibst falsche Anfangsbedingungen ein und ›postest‹ den Erguss ohne zumindest flüchtige Prüfung.

#7383961
Lesenswert?

Sebastian W. schrieb:

fileinput erzeugt eine Hilfsdatei. Die Aufgabe war, das Problem ohne Hilfsdatei zu lösen.

aber aber aber aber aber dann musst du ChatGPT nur darauf hinweisen. Und dann ist ChatGPT überlegen! So jedenfalls die Logik der ChatGPT-Jünger. Dass die Programmierleistung in Wirklichkeit auf der menschlichen Seite liegt - nun halt nur auf Englisch - sieht man wieder niemand der ChatGPT-Verblendeten.

#7383962
Lesenswert?

Norbert schrieb:

Du beauftragst ein auf Labern optimiertes Programm, gibst falsche Anfangsbedingungen ein und ›postest‹ den Erguss ohne zumindest flüchtige Prüfung.

Das ist hier halt keine Raketenforschung, sondern der TO ist zu faul seine Hausaufgaben zu machen.

Dann passieren einem selber natürlich auch Fehler.

Ändert nichts an der Tatsache, dass solche einfache Scripte inzwischen schneller über KI geschrieben werden.

#7383965
Lesenswert?

Ben S. schrieb:

Manche verschlafen halt die neue Technologie.

Nein. Ich verfolge das Thema sehr genau.

Weil es wesentlich schneller und zuverlässiger geht. Hier die Korrektur von ChatGPT.

Lol, nein. Einfach nur nein.

Norbert schrieb:

Du beauftragst ein auf Labern optimiertes Programm, gibst falsche Anfangsbedingungen ein und ›postest‹ den Erguss ohne zumindest flüchtige Prüfung.

Aber es ist doch so viel schneller und zuverlässiger!

Ben S. schrieb:

fileinput erzeugt eine Hilfsdatei. Die Aufgabe war, das Problem ohne Hilfsdatei zu lösen.

Aber sicherlich nicht in der Funktionsweise wie der TO as meinte.

Achso. Man muss das Problem nur in einer lib verstecken und schon existiert es nicht mehr. Das hört sich nach heutiger Softwareentwicklung an.

#7383967
Lesenswert?

Ben S. schrieb:

sondern der TO ist zu faul seine Hausaufgaben zu machen.

Dann macht man sie ihm nicht, sondern gibt bestenfalls Hinweise! Damit er/sie/es selbst mit dem Denken anfängt.

Ändert nichts an der Tatsache, dass solche einfachen Scripte inzwischen schneller über KI geschrieben werden.

Rausgerotzt werden!

Der Initiator versteht sie ja noch nicht einmal. Wie soll denn dann die Prüfung auf Fehlerfreiheit ^H^H^H Fehlerarmut geschehen? Auch mit 'ner KI?

#7383970
Lesenswert?

Ben S. schrieb:

Ändert nichts an der Tatsache, dass solche einfache Scripte inzwischen schneller über KI geschrieben werden.

Ah. Eine "Tatsache" ist das also. Wie begründest du denn diese "Tatsache"?

Vielleicht so: Die KI schreibt sie schneller. Das ist richtig. Sie sind aber auch so gut wie immer falsch. Und wenn sie mal nicht falsch sind, muss ein Mensch sie trotzdem noch einmal komplett verstehen und kontrollieren. Es gibt überhaupt gar keinen Verifikationsmechanismus in GPT. Das Teil kotzt einfach nur irgendwas raus.

#7384014
Lesenswert?

Doc P. schrieb:

Mein Ziel ist es nun, die Zahlen die nicht prime sind, aus der genannten Datei zu löschen, ohne eine Hilfsdatei zu erzeugen. Ist dies möglich?

Wie immer driftet es hier vollkommen ab. Die Lösung wäre ziemlich simpel. In Zeile 9 wird ein file.readlines() genutzt. Damit ist die Datei im RAM. Danach die Datei schliessen und zum Schreiben neu öffnen.

#7384089
Lesenswert?

Klaus H. schrieb:

Doc P. schrieb:

Mein Ziel ist es nun, die Zahlen die nicht prime sind, aus der genannten Datei zu löschen, ohne eine Hilfsdatei zu erzeugen. Ist dies möglich?

Wie immer driftet es hier vollkommen ab. Die Lösung wäre ziemlich simpel. In Zeile 9 wird ein file.readlines() genutzt. Damit ist die Datei im RAM. Danach die Datei schliessen und zum Schreiben neu öffnen.

Sollte diese Lösung nicht gemeint sein, und wenn die Datei tatsächlich während des Lesens geschrieben werden soll, so ist dies auch möglich:

1
def is_prime(n):
2
  for i in range(2,n):
3
    if (n%i) == 0:
4
      return False
5
  return True
6

7
def main():
8
  wpos = 0
9
  with open("numbers.txt","r+") as file:
10
    line = file.readline()
11
    while line:
12
      number = int(line)
13
      if (is_prime(number)):
14
        print ("number", number, "is prime")
15
        rpos = file.tell()
16
        file.seek(wpos)
17
        print(number,file=file)
18
        wpos = file.tell()
19
        file.seek(rpos)
20
      line = file.readline()
21
    file.seek(wpos)
22
    file.flush()
23
    file.truncate()
24
  print ("Done")
25

26
main()

Interessant ist, dass das übliche Konstrukt "for line in file", also der file object iterator, die Anwendung von file.tell() verhindert und hier also nicht benutzt werden kann ...

LG, Sebastian

(Firma: Privat) #7384348
Lesenswert?

Man braucht ja auch nicht die ganze originale Datei im RAM haben. Ich würde die Datei zeilenweise bis Eof lesen und wenn eine Primzahl identifiziert wird, diese in ein Array, Liste o. ä. schreiben. Danach Datei schließen oder löschen (je nach Wunsch) und die Datei mit den Arrayeinträgen bzw. Liste-Einträgen neu schreiben.

OP #7384374
Lesenswert?

Hi

Wie erwähnt ist der Code nur zum Testen und sollte dann in einem wesentlich umfanreicheren Programm laufen (die Prime Funktion hier wird dort nicht verwendet)

Um es kurz zu erklären: Es wird dort auf einer Webseite mittels einer Referenznummer (1-10.000.000) über einen get request ein entsprechender Eintrag) abgefragt. Es sind aber nie gleichzeitig alle Einträge verfügbar, sodass unter Umständen bestimmte Einträge mehrere Male abgefragt werden müssen. Das Programm sollte dann über Wochen hinweg laufen und eben nur die Referenznummern abfragen, zu denen bisher noch kein Eintrag gefunden wurde. Die Möglichkeit, das ganze mittels einer Textdatei abzuarbeiten, scheinte mir die sinnvollste Möglichkeit. Somit kann das Programm auch immer wieder mal unterbrochen und später neu gestartet werden

#7384390
Lesenswert?

Das ändert aber schon die Perspektive...

Eine Datei als Input zu nehmen und im Programm zu ändern, sollte man nur machen, wenn es unproblematisch ist, dass ein Absturz kein undefiniertes Verhalten verursacht. Was machst Du wenn das Programm irgendwann abstürzt und eine halbe Dateileiche übrig bleibt?

Das würde ich dann doch lieber mit einer DB Anwendung umsetzen und sei es nur mit einer SQLite Datenbank, mit der sowas durchaus abgefangen werden kann (Rollback-Journal).

Meine 10 Cent...

#7384442
Lesenswert?

Doc P. schrieb:

Um es kurz zu erklären: Es wird dort auf einer Webseite mittels einer Referenznummer (1-10.000.000) über einen get request ein entsprechender Eintrag) abgefragt. Es sind aber nie gleichzeitig alle Einträge verfügbar, sodass unter Umständen bestimmte Einträge mehrere Male abgefragt werden müssen. Das Programm sollte dann über Wochen hinweg laufen und eben nur die Referenznummern abfragen, zu denen bisher noch kein Eintrag gefunden wurde.

Ganz stumpf: https://docs.python.org/3/library/dbm.html

#7384458
Lesenswert?

Doc P. schrieb:

Die Möglichkeit, das ganze mittels einer Textdatei abzuarbeiten, scheinte mir die sinnvollste Möglichkeit.

Ich wüsste keine Möglichkeit, eine Zeile einer Textdatei zu löschen, ausser die Datei von dort an neu zu schreiben.

Man könnte sich natürlich ein Format entwickeln, bei der die Zeile nicht gelöscht wird, sondern als gelöscht markiert wird.

Dann ist man aber sehr schnell bei Key-Value-Stores und ähnlichen Off-The-Shelf Lösungen.

Gerade auch wenn Programmabbrüche und/oder Rechnerneustarts überstanden werden sollen.

LG, Sebastian

Gast #7384478
Lesenswert?

Ben S. schrieb:

Wieso, es funktioniert. Ich glaube da hat jemand Angst, dass die KI einem bald den Job wegnimmt.

Also ich habe inzwischen recht viel mit mit ChatGPT experimentiert, und ich bin der Meinung, dass sich kein Programmierer Sorgen um seinen Job machen muss! ChatGPT funktioniert zumindest bei mir nur für einfachste Aufgaben, und es würde mich wundern, wenn das in nächster Zeit so skalieren würde, dass sich das ändert. Dazu müsste ChatGPT nämlich unter anderem sehr komplexe Beschreibungen analysieren können. Und schon das sehe ich aktuell noch nicht. Meine Erfahrung ist eher, dass chatGPT sich wie ein erweitertes Google verhält, dass das Ergebnis spezieller auf die jeweilige Anfrage anpasst und in menschlicher Sprache ausgibt (was ja eigentlich auch der Zweck des Systems ist). Alle nur etwas anspruchsvolleren Themen sind, jedenfalls bei mir, komplett schief gelaufen. Also Leute, ich denke, ihr braucht wirklich keine Angst zu haben, und ich kann den Hype echt nicht verstehen, noch nicht...

Und ich sage nur: selbstfahrende Autos. Schon vor einigen Jahren war man sicher, bis heute würden alle neuen Autos selbstverständlich komplett autonom fahren. Leider ist aktuell aber kein einziges Fahrzeug auch nur ansatzweise dazu in der Lage. Ich habe sogar das Gefühl, dass die Fortschritte in letzter Zeit eher weniger werden. Aber das ist halt das Problem, denn die letzten 5 Prozent, die zum Level 5 noch fehlen, brauchen halt noch extrem viel Forschungsarbeit.

Sorry für den langen Post, aber ich hoffe, er war nicht uninteressant...

ciao

Marci

#7384535
Lesenswert?

Marci W. schrieb:

Dazu müsste ChatGPT nämlich unter anderem sehr komplexe Beschreibungen analysieren können. Und schon das sehe ich aktuell noch nicht.

Jeder Softwareentwickler, der einmal eine Software aus einem Anforderungsdokument erstellt hat weiß, dass das völlig unmöglich ist.

Solche komplexen Beschreibungen sind komplexer und aufwändiger als das zugehörige Programm, weil man in natürlicher Sprache gar nicht alle Details beschreiben kann, ohne sehr viel Text zu produzieren.

Das eigentliche Problem ist nicht aus Beschreibungen Software zu generieren. Das ist ein längst gelöstes Problem. Es nennt sich Compiler. Das Problem ist die Beschreibungen in natürlicher Sprache hinreichend genau zu bekommen, um ein Programm zu beschreiben. Das ist unlösbar.

#7385443
Lesenswert?

Aus einer Datei kann man soweit ich weiss nicht einfach so eine Zeile löschen. Man kann Inhalte Überschreiben, Anhängen, und die Datei verkleinern, aber Zeichen Löschen geht nicht. Man kann höchstens alles nach dem zu löschenden über das zu löschende kopieren.

Aber da ja nur Zeilen gelöscht werden, kann man die Datei einmal lesen, und gleichzeitig nur das Gebrauchte wieder schreiben, wie in Beitrag "Re: Python aktuelle Zeile aus Datei löschen"

Wobei, ich würde die Datei zweimal öffnen, dann muss man nicht mit dem seek herumspringen.

1
#!python3
2
with open("numbers.txt","rt") as fr:
3
  with open("numbers.txt","r+t") as fw:
4
    for line in fr:
5
      line = line.strip()
6
      if line and is_prime(int(line)):
7
        fw.write(line+'\n')
8
    fw.truncate()

Oder untr Linux man könnte auch:

1
#!python3
2
import sys
3
for line in sys.stdin:
4
  line = line.strip()
5
  if line and is_prime(int(line)):
6
    print(line)
7
sys.stdout.truncate()

Und das öffnen in bash machen:

1
python3 program.py <numbers.txt 1<>/proc/self/fd/0

(Der Grund, warum ich hier nicht >&0 nehme, ist, dass dann beide file descriptoren die selbe file description hätten, also auch wieder die gleiche seek position. 1<>/proc/self/fd/0 öffnet die Datei neu, stat nur den file descriptor zu duplizieren.)

(Firma: Privat) #7385654
Lesenswert?

Früher, unter DOS konnte man mit Turbo Pascal Dateien abschneiden. War aber sehr umständlich, da man das NICHT Gebrauchte ganz ans Ende der Datei verschieben mußte (Append).

Truncate Schneidet die Datei an der Lese/Schreibposition ab Truncate(f);

Heutzutage, unter Windows wird das wohl nicht mehr gehen.

Beitrag #7386018 wurde von einem Moderator gelöscht.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren