Forum: PC-Programmierung Python aktuelle Zeile aus Datei löschen


von Doc P. (plato)


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.

von Ben S. (bensch123)


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())

: Bearbeitet durch User
von Norbert (der_norbert)


Lesenswert?

Datei nicht Read-Only sondern mit Read-Write/Random Access öffnen.

Zwei Zeiger (einen zum Lesen, einen zum Schreiben) mit os.lseek() 
manipulieren.

Nebenbei, die ›is_prime()‹ kann man doppelt so schnell machen!

von MaWin O. (mawin_original)


Lesenswert?

Hausaufgaben bekommen?

Doc P. schrieb:
> Ist dies möglich?

Ja.

Doc P. schrieb:
> def is_prime(n):
>   for i in range(2,n):

eieiei

Norbert schrieb:
> Datei nicht Read-Only sondern mit Read-Write/Random Access öffnen.

Ja.

Norbert schrieb:
> mit os.lseek()

Nein.

von Norbert (der_norbert)


Lesenswert?

Ben S. schrieb:
> ChatGPT …

Mehr muss man dazu nicht sagen.

Kann man bitte, BITTE - wenn schon dieser Dreck gepostet wird - 
zumindest einmal oberflächlich darüber schauen?

Ich zumindest habe selten einen solchen Dreck gesehen!

von Norbert (der_norbert)


Lesenswert?

MaWin O. schrieb:
> Norbert schrieb:
>> mit os.lseek()
>
> Nein.

Na da bin ich aber gespannt!

von Ben S. (bensch123)


Lesenswert?

Norbert schrieb:
> Mehr muss man dazu nicht sagen.
>
> Kann man bitte, BITTE - wenn schon dieser Dreck gepostet wird -
> zumindest einmal oberflächlich darüber schauen?
>
> Ich zumindest habe selten einen solchen Dreck gesehen!

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

: Bearbeitet durch User
von MaWin O. (mawin_original)


Lesenswert?

Norbert schrieb:
>>> mit os.lseek()
>> Nein.
> Na da bin ich aber gespannt!

Worauf?

von Norbert (der_norbert)


Lesenswert?

Ben S. schrieb:
> Wieso, es funktioniert.

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

Aus:
1
2
2
4
3
5
4
6
5
7
6
8
7
11
8
33
9
37

Wird:
1
2
2
6
3
8
4
33
5
37

von Norbert (der_norbert)


Lesenswert?

MaWin O. schrieb:
> Worauf?

Na auf die Begründung deines ›Neins‹

von MaWin O. (mawin_original)


Lesenswert?

Norbert schrieb:
> Na auf die Begründung deines ›Neins‹

Achso. Ich dachte es wäre offensichtlich, dass es eine schlechte Idee 
ist die rohen OS-Schnittstellen in Python zu verwenden. Was soll der 
Vorteil gegenüber den Methoden des file-Objekts sein?

von Ben S. (bensch123)


Lesenswert?

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 - nicht den Inhalt.

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

: Bearbeitet durch User
von MaWin O. (mawin_original)


Lesenswert?

Ben S. schrieb:
> Määh, wein doch. Ich habe die Zeile dessen Zeilennummer einer Prizahl
> entspricht entfernt.

Also vollkommen falsch.

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

Man programmiert heute also in einem Englisch-Dialog? Warum sollte ich 
das tun wollen, statt das Programm einfach selbst zu schreiben?

von Sebastian W. (wangnick)


Lesenswert?

Ben S. schrieb:
> Eine kleine Anfrage a ChatGPT und du hast das korrigiert. Das war MEIN
> Fehler und nicht von der KI.

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

LG, Sebastian

von Ben S. (bensch123)


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())

von Norbert (der_norbert)


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.

von Ben S. (bensch123)


Lesenswert?

Sebastian W. 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.

von MaWin O. (mawin_original)


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.

von Ben S. (bensch123)


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.

: Bearbeitet durch User
von G. K. (zumsel)


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?

Ja.

von MaWin O. (mawin_original)


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.

von Norbert (der_norbert)


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?

von MaWin O. (mawin_original)


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.

von Klaus H. (klummel69)


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.

: Bearbeitet durch User
von MaWin O. (mawin_original)


Lesenswert?

Klaus H. schrieb:
> ie 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.

Dann müssen wir ja nur noch herausfinden, wie wir ChatGPT dazu überreden 
können es genau so auch auszugeben.

von Norbert (der_norbert)


Lesenswert?

Klaus H. schrieb:
> Die Lösung wäre ziemlich
> simpel. In Zeile 9 wird ein file.readlines() genutzt. Damit ist die
> Datei im RAM.

Was ja gerade bei Dateien welche größer als der verfügbare Speicher 
sind, immer wieder gerne für Verwunderung sorgt. ;-)

Und ja, für Hausaufgaben reicht es wohl.

von Sebastian W. (wangnick)


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

von Heinz B. (Firma: Privat) (hbrill)


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.

von Doc P. (plato)


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

von Klaus H. (klummel69)


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...

: Bearbeitet durch User
von MaWin O. (mawin_original)


Lesenswert?

Doc P. schrieb:
> Die Möglichkeit, das ganze mittels einer Textdatei abzuarbeiten,
> scheinte mir die sinnvollste Möglichkeit.

Mir nicht. Daten hält man in Datenbanken.

von G. K. (zumsel)


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

von Sebastian W. (wangnick)


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

: Bearbeitet durch User
von Marci W. (Gast)


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

von MaWin O. (mawin_original)


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.

von Sheeva P. (sheevaplug)


Lesenswert?

Doc P. schrieb:
> Es wird dort auf einer Webseite mittels einer Referenznummer
> (1-10.000.000) über einen get request ein entsprechender Eintrag)
> abgefragt.

Dann ist vielleicht Scrapy [1] etwas für Dich.

[1] https://scrapy.org/

von Daniel A. (daniel-a)


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.)

von Heinz B. (Firma: Privat) (hbrill)


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.

: Bearbeitet durch User
von MaWin O. (mawin_original)


Lesenswert?


von G. K. (zumsel)


Lesenswert?

Daniel A. schrieb:

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

In ASCII codierte Zahlen in Textfiles brauchen unterschiedliche Mengen 
an Speicherplatz, daher kann diese Methode schiefgehen.

von Sebastian W. (wangnick)


Lesenswert?

G. K. schrieb:
> In ASCII codierte Zahlen in Textfiles brauchen unterschiedliche Mengen
> an Speicherplatz, daher kann diese Methode schiefgehen.

Wenn man nur Zeilen filtert kann eigentlich nichts schiefgehen. Mit der 
Zeilenendekennung sollte man sich aber vorsehen ...

LG, Sebastian

Beitrag #7386018 wurde vom Autor gelöscht.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.