“0” to int

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
the_real_noob
User
Beiträge: 20
Registriert: Donnerstag 26. Januar 2017, 09:57

Tach gesagt!

Ich habe folgendes Problem:

Code: Alles auswählen

with open("G:\var.txt", "r") as filehandle:
	filecontent = filehandle.readlines()
	for line in filecontent:
		fill_list = line[:-1]
		myList.append(fill_list)
	filehandle.close()	
	new = int(myList[0])
	old = int(myList[1])
Wenn ich 0 aus der Datei auslese erhalte ich folgende Fehlermeldung:

ValueError: invalid literal for int() with base 10: ' '

Mit "1" läuft das Ding durch. Hat jemand eine Erklärung dafür.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

Die Fehlermeldung zeigt Dir, dass Du einen leeren String und nicht '0' eingelesen hast. Du hast also nicht das gelesen, was Du dachtest. Prüfe einmal genau, was in Deiner Datei steht. Z.B. wäre es vorstellbar, dass Du nur eine Zeile mit dem Zeichen '0' aber ohne CR am Zeilenende hast. Das würde zu dem beobachteten Verhalten führen. Den wahren Grund aber musst Du selbst herausfinden.
Benutzeravatar
__blackjack__
User
Beiträge: 13112
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@the_real_noob: Das kann so nicht sein, denn laut Ausnahe versuchst Du keine '0' sondern eine leere Zeichenkette '' in eine Zahl umzuwandeln. Kann es sein das die 0 in der letzten Zeile steht und nicht durch ein Zeilenendezeichen abgeschlossen wurde? Dann entfernst Du nämlich mit ``line[:-1]`` die 0 selbst. Falls das das Zeilenenende entfernen soll, ist das ungünstig und sollte eher durch `line.rstrip()` ersetzt werden. Wobei „whitespace“-Zeichen für `int()` kein Problem darstellen, man das also auch einfach komplett sein lassen könnte.

`filehandle` ist ein Name aus einer anderen Programmiersprache wo man nur „handles“ für Dateien in die Hand bekommt und keine Dateiobjekte hat. Der Name ist also falsch.

Das `readlines()` kann man sich sparen da Dateiobjekte über ihre Zeilen iterierbar sind.

`fill_list` ist kein sinnvoller Name für etwas das gar keine Liste ist. Wobei Grunddatentypen auch nicht in Namen stehen sollten. `line` würde passen.

Bei `myList` ist da erst einmal die Schreibweise: Namen werden in Python klein_mit_unterstrichen geschrieben. Ausgenommen Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase). Dann hat der Grunddatentyp wie gesagt nichts im Namen verloren. Und zu guter letzt: was soll das `my` bedeuten? Gibt es auch eine `ourList` und eine `theirList`? Falls nicht ist das eher ein Zeichen dafür das sich keine Gedanken über einen guten Namen gemacht wurden.

Das ``with`` sorgt schon für das schliessen der Datei. Deswegen verwendet man das ja.

Wird die Liste auch sonst noch für irgend etwas verwendet? Und wie wird dann mit den ersten beiden Einträgen umgegangen? Die sind dann ja immer noch in der Liste. Als Zeichenketten. Die beiden Werte würde man wohl eher nicht in einer Schleife abhandeln, sondern vor den anderen Zeilen. Sofern die überhaupt verwendet werden.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
the_real_noob
User
Beiträge: 20
Registriert: Donnerstag 26. Januar 2017, 09:57

kbr hat geschrieben: Sonntag 17. Februar 2019, 15:33 Die Fehlermeldung zeigt Dir, dass Du einen leeren String und nicht '0' eingelesen hast. Du hast also nicht das gelesen, was Du dachtest. Prüfe einmal genau, was in Deiner Datei steht. Z.B. wäre es vorstellbar, dass Du nur eine Zeile mit dem Zeichen '0' aber ohne CR am Zeilenende hast. Das würde zu dem beobachteten Verhalten führen. Den wahren Grund aber musst Du selbst herausfinden.
Danke, dass Problem war der fehlende Zeilenwechsel nach der 2ten Zeile. Jetzt habe ich den eingefügt und das Ding läuft.
the_real_noob
User
Beiträge: 20
Registriert: Donnerstag 26. Januar 2017, 09:57

@__blackjack__

Zur Kenntnis genommen!
Benutzeravatar
__blackjack__
User
Beiträge: 13112
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Das bei der zweiten Zeile das Zeilenende fehlte, lässt vermuten, das die Datei tatsächlich nur die beiden Zahlen enthält. Dann braucht man dafür nur diese beiden Zeilen:

Code: Alles auswählen

    with open(r'G:\var.txt', 'r', encoding='ascii') as file:
        new, old = map(int, file)
Und hier wäre das fehlende Zeilenende auch egal.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
Perlchamp
User
Beiträge: 172
Registriert: Samstag 15. April 2017, 17:58

@ _blackjack_ :
Verständnisfrage:
und 'new' und 'old' dann nicht mittels print, sondern mittels list anzeigen ?
wer lesen kann ist klar im Vorteil ;-)
es gibt keine Probleme, sondern nur Lösungen !
Bildung ist die Freude auf mich selbst !
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Mit `list` kann man nichts anzeigen. `new` und `old` sind ganz normaler Variablen, wie sie auch der OP nach dem Umweg über eine Liste erzeugt hat. Was dann damit gemacht wird, wissen wir nicht.
Benutzeravatar
Perlchamp
User
Beiträge: 172
Registriert: Samstag 15. April 2017, 17:58

@ sirius3:
ok, wieder etwas gelernt. Ich halte mich wohl besser einmal zurück.
danke
wer lesen kann ist klar im Vorteil ;-)
es gibt keine Probleme, sondern nur Lösungen !
Bildung ist die Freude auf mich selbst !
the_real_noob
User
Beiträge: 20
Registriert: Donnerstag 26. Januar 2017, 09:57

__blackjack__ hat geschrieben: Sonntag 17. Februar 2019, 15:52 Das bei der zweiten Zeile das Zeilenende fehlte, lässt vermuten, das die Datei tatsächlich nur die beiden Zahlen enthält. Dann braucht man dafür nur diese beiden Zeilen:

Code: Alles auswählen

    with open(r'G:\var.txt', 'r', encoding='ascii') as file:
        new, old = map(int, file)
Und hier wäre das fehlende Zeilenende auch egal.
Verständnisfrage:
Du verwendest beim Öffnen der Datei zweimal das Argument r. Einmal vor dem Dateinamen und einmal danach. Warum?
Und ist es zwingend, dass encoding anzugeben? Und für die Umlaute ist doch UTF-8 besser, oder?
Kann man das nicht mit

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-
zentral angeben?

Und vielleicht kannst Du mir noch eine andere Frage beantworten, denn ich werde gerade wahnsinnig.

Ich möchte mit einer while-Schleife über eine Liste iterieren:

Code: Alles auswählen

a = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 ...]
c = 5
f = 0
while f != c
	del c[f]
	f += 1
Ergebnis:
2,4,6,8,9,10,11,12,13,14,15 ...

Also anstatt 1,2,3,4,5 und 6 zu löschen, löscht die Schleife nur jede 2te Zahl. f wird aber ordnungsgemäß hochgezählt. Siehst Du meinen Gedankenfehler? Oder ist Dir ein ähnliches Problem schon einmal untergekommen?
Benutzeravatar
Perlchamp
User
Beiträge: 172
Registriert: Samstag 15. April 2017, 17:58

@ the_real_noob :
mein lieber Freund, du bist recht unkonzentriert. Erstens solltest du deinen code richtig präsentieren und zweitens vielleicht aus Debugging-Gründen mal ein print(a) in die while-Schleife setzen, damit du auch weißt, was da geschieht.
richtig geschriebener Code (der trotzdem nicht das macht, was du gerne hättest):

Code: Alles auswählen

a = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]      # Punkte weglassen
c = 5
f = 0
while f != c :                 # wo ist der Doppelpunkt nach c ?
	del c[f]               # was soll das? c ist eine Zahl und keine Liste => del a[f] 
	print(a)               # zum Debuggen
	f += 1
so, was passiert denn hier?
Du veränderst den Index von der Liste a (0, 1, 2, 3, 4), so dass bei der ersten Schleife das erste Element aus a (Index 0) gelöscht wird (=> 1). Ein print(a) würde nun [2, 3, 4, 5, ..., 15] ausgeben.
Beim zweiten Durchgang wird jedoch das zweite Element (Index 1) aus der (neuen) Liste a gelöscht (=> 3). Ein print(a) würde nun [2, 4, 5, ..., 15] ausgeben, usw. Du verstehst ?
also:

Code: Alles auswählen

>>> a = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
>>> c = 5
>>> f = 0
>>> while f != c :                  # 5 Schleifendurchgänge
	    del a[0]                # es wird immer das erste Element der (neuen) Liste gelöscht
	    f += 1
	    print(a)                # für's Debuggen

>>> a
[6, 7, 8, 9, 10, 11, 12, 13, 14, 15]  # das gewünschte Ergebnis !
du könntest auch range() verwenden :

Code: Alles auswählen

>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
>>> c = 5
>>> for i in range(c) :
           del a[0]
           i += 1
           
>>> a
[6, 7, 8, 9, 10, 11, 12, 13, 14, 15]  # das gewünschte Ergebnis !
zur ersten Frage kann ich nur bedingt etwas sagen:

Code: Alles auswählen

with open(r'G:\var.txt', 'r', encoding='ascii') as file:
das erste r:
dies ist ein sog. r-String (r steht für raw), sonst müsste 'G:\\\\var.txt' hier stehen (@ _blackjack: ist doch richtig, oder?).
das zweite r:
dies ist die Methode, mit der du die Textdatei lädst. 'r' steht für 'read', also zum (zeilenweise) (Aus)Lesen des Dateiinhaltes. Beispielsweise 'w' würde 'write' bedeuten, also zum Beschreiben der Datei, wobei der Inhalt überschrieben wird.
ascii deswegen, denke ich, weil man international bleiben sollte ?
wer lesen kann ist klar im Vorteil ;-)
es gibt keine Probleme, sondern nur Lösungen !
Bildung ist die Freude auf mich selbst !
Benutzeravatar
Perlchamp
User
Beiträge: 172
Registriert: Samstag 15. April 2017, 17:58

Perlchamp hat geschrieben: Dienstag 19. Februar 2019, 06:01 du könntest auch range() verwenden :

Code: Alles auswählen

>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
>>> c = 5
>>> for i in range(c) :
           del a[0]
           i += 1
           
>>> a
[6, 7, 8, 9, 10, 11, 12, 13, 14, 15]  # das gewünschte Ergebnis !
EDIT :
das 'i += 1' ist natürlich Quatsch, da range() automatisch hochzählt ...
wer lesen kann ist klar im Vorteil ;-)
es gibt keine Probleme, sondern nur Lösungen !
Bildung ist die Freude auf mich selbst !
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

@the_real_noob: Die Liste zu verändern, über die man iteriert, ist keine gute Idee. In Python geht mam so vor, dass man eine neue Liste erstellt. Und im besten Fall.mit einer List Comprehension.

@Perlchamp: Deine "Antworten" verwirren mehr als zu helfen.
Benutzeravatar
Perlchamp
User
Beiträge: 172
Registriert: Samstag 15. April 2017, 17:58

@ sparrow:
Du hast Recht. Als Anfänger sollte man nicht helfen. Danke für deine Ehrlichkeit !
Zuletzt geändert von Perlchamp am Dienstag 19. Februar 2019, 08:16, insgesamt 1-mal geändert.
wer lesen kann ist klar im Vorteil ;-)
es gibt keine Probleme, sondern nur Lösungen !
Bildung ist die Freude auf mich selbst !
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

the_real_noob hat geschrieben: Dienstag 19. Februar 2019, 00:42 Du verwendest beim Öffnen der Datei zweimal das Argument r. Einmal vor dem Dateinamen und einmal danach. Warum?
Das erste `r` kennzeichnet einen Raw-String, das heißt, \ wird nicht als Escapezeichen interpretiert, so dass z.B. \n zwei Zeichen bleiben, statt einen Zeilenumbruch zu ergeben. Unter Windows wäre es aber sowieso besser / als Verzeichnistrenner zu benutzen, dann hat man das Problem erst gar nicht.
the_real_noob hat geschrieben: Dienstag 19. Februar 2019, 00:42 Und ist es zwingend, dass encoding anzugeben? Und für die Umlaute ist doch UTF-8 besser, oder?
Kann man das nicht mit

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-
zentral angeben?
Die `zentrale` Angabe sagt nur, mit welchem Encoding die Python-Datei geschrieben wurde, und hat keinen Einfluß darauf, wie Dateien gelesen wurden.
Das encoding explizit anzugeben ist immer gut, weil ansonsten das Encoding geraten wird und man sich nie sicher sein kann, dass das nicht irgendwo oder irgendwann anders nicht mehr funktioniert. `ASCII` ist dabei der kleinste gemeinsame Nenner. Wenn Du weißt, dass die Datei UTF-8-kodiert ist, dann kannst Du das natürlich auch angeben, bei zwei Zahlen ist das aber egal.

Zum Verstehen Deines Schleifenproblems hat Perlchamp Dir ja schon den Tipp gegeben, innerhalb der Schleife in jedem Schritt `a` und besser auch noch `f` auszugeben. Dann kannst Du hoffentlich nachvollziehen, was da passiert.
So eine Schleife tritt aber in Realität nie auf, da erstens, while der falsche Schleifentyp ist und zweitens Listen nicht verändert werden sollten, sondern man immer eine neue, veränderte, Liste erzeugt.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@the_real_noob: Listen ändern während über diese iteriert wird, ist eine schlechte Idee. Was Du vermutlich suchst, ist so etwas (oder, bei Modifikation der Inhalte, eine Variante per List-Comprehension):

Code: Alles auswählen

a = a[c:]
Und in Ergänzung zu Sirius3 beschreibt der Header

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-
von welchem Encoding Python beim lesen dieser Datei ausgehen soll. Es liegt aber in Deiner Verantwortung, die Datei auch tatsächlich mit diesem Coding zu speichern.
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

@Perlchamp: Klar sollen Anfänger helfen. Das nicht falsch verstehen.

@the_real_noob: Slicing ist in Python sehr wichtig.
the_real_noob
User
Beiträge: 20
Registriert: Donnerstag 26. Januar 2017, 09:57

Erst einmal vielen Dank für die vielfachen Rückmeldungen.

Einiges war mir klar und hatte ich auch schon durchgeführt, so z.B. print-Einweisungen einzubauen. Problem: Das hatte mit der while-Schleife funktioniert, bevor ich anfing, dass Programm auseinander zu nehmen, weil es mir zu unübersichtlich wurde und die einzelnen Programmteile in Funktionen umzuwandeln. Irgendwas habe ich da falsch umgebaut.

Als ich dann heute morgen wach wurde, kam mir das auch mit der while-Schleife, dass das so nicht funktionieren kann, aber Ihr kennt das bestimmt auch, wenn man vor der Kiste sitzt, ein dickes Brett vor dem Kopf hat und sich mehr mit der Frage beschäftigt, warum man das Problem hat, als mit dem Problem selbst. War gut, ins Bett zu gehen.

Kann es sein, dass ich das so geschrieben hatte?

Code: Alles auswählen

xyz = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 ...]
c = 5
f = 0
while f != c
	del xyz[0]
	f += 1
Getestet! Jau, genau so hatte ich es gemacht.

Schön, dass ich selbst auf die Lösung gekommen bin, aber vielen Dank nochmal, auch für die darüber hinaus gehenden Hinweise.

Wenn ich das jetzt richtig verstanden habe mit dem Slicing, dann hätte ich mir die Schleife auch sparen können und:

Code: Alles auswählen

s = xyz[5:] 
schreiben können. Oder?

Warum einfach, wenn's auch kompliziert geht?

P.S.:

@Perlchamp

Mach mal ruhig. Wer ein Avatarbild von Jim Morrison hat, kann gar nicht alles falsch machen.
Antworten