valueerror invalid literal for int() with base 10

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
Mars23
User
Beiträge: 3
Registriert: Freitag 4. Dezember 2015, 08:01

Guten Morgen zusammen,
ich bin noch Python Anfänger und habe ein Problem bei einem gaaanz einfachen Testprogramm. Die Form ist vielleicht nicht so sauber, aber ich bin lernfähig ;)
Bekomme immer eine Fehlermeldung "valueerror invalid literal for int() with base 10" und komme damit nicht klar. :?: :?: :?:

Ich hoffe Ihr könnt mir helfen.

VG Marcel

test.py

Code: Alles auswählen

#! /usr/bin/python

banki = 0x1a
bank = bin(banki)
bankh = hex(banki)
pindic = {1 : 0x1, 2 : 0x2, 3 : 0x4, 4 : 0x8, 5 : 0x10, 6 : 0x20, 7 : 0x40, 8 : 0x80}
pin = int(8)
data = int(1)

def laenge(bank):
	l = len(bank)
	return l

def gesamt(bank):
	g = list(bank)
	n = laenge(bank)
	while n < 10:
		g.insert(2,'0')
		n = n+1
	return g

def pin_stand(pin):
	p = gesamt(bank)
	p = p[-pin]
	return p

def pin_aus(pin):
	p = pindic[pin]
	return p

def pin_up(banki,pinl):
	re = banki | pinl
	return re
	
pinl = pin_aus(pin)

print banki
print type(banki)
print bank
print bankh
print gesamt(bank)
print pin_stand(pin)
print type(pinl)
print pin_up(bank,pin)
Zuletzt geändert von cofi am Freitag 4. Dezember 2015, 09:51, insgesamt 1-mal geändert.
Grund: Code Highlighting korrigiert
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Willkommen zu Python und im Forum!

Vorab, benutze bitte eine Codebox zum highlighten deines Codes (Listbox ueber dem Textfeld) und poste den kompletten Traceback fuer einen Fehler.

Wenn ich deinen Code naemlich ausfuehre, sehe ich folgendes:

Code: Alles auswählen

26
<type 'int'>
0b11010
0x1a
['0', 'b', '0', '0', '0', '1', '1', '0', '1', '0']
0
<type 'int'>
Traceback (most recent call last):
  File "test.py", line 44, in <module>
    print pin_up(bank,pin)
  File "test.py", line 32, in pin_up
    re = banki | pinl
TypeError: unsupported operand type(s) for |: 'str' and 'int'
Anders als der ValueError den du eingangs erwaehnst, macht diese Fehlermeldung fuer deinen Code naemlich Sinn, denn `bank` ist ein String mit der Binaerrepresentation von `banki`.
Mars23
User
Beiträge: 3
Registriert: Freitag 4. Dezember 2015, 08:01

cofi hat geschrieben:Willkommen zu Python und im Forum!

Vorab, benutze bitte eine Codebox zum highlighten deines Codes (Listbox ueber dem Textfeld) und poste den kompletten Traceback fuer einen Fehler.

Wenn ich deinen Code naemlich ausfuehre, sehe ich folgendes:

Code: Alles auswählen

26
<type 'int'>
0b11010
0x1a
['0', 'b', '0', '0', '0', '1', '1', '0', '1', '0']
0
<type 'int'>
Traceback (most recent call last):
  File "test.py", line 44, in <module>
    print pin_up(bank,pin)
  File "test.py", line 32, in pin_up
    re = banki | pinl
TypeError: unsupported operand type(s) for |: 'str' and 'int'
Anders als der ValueError den du eingangs erwaehnst, macht diese Fehlermeldung fuer deinen Code naemlich Sinn, denn `bank` ist ein String mit der Binaerrepresentation von `banki`.
Danke für Deine Antwort. Ich habe mich mit der Fehlermeldung vertan :oops:

Ich verwende doch in Zeile 32 nur 'banki' und das ist Integer...
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

banki ist nur dann ein integer wenn du tatsächlich einen integer übergibst, tust du aber in Zeile 44 nicht.
Mars23
User
Beiträge: 3
Registriert: Freitag 4. Dezember 2015, 08:01

DasIch hat geschrieben:banki ist nur dann ein integer wenn du tatsächlich einen integer übergibst, tust du aber in Zeile 44 nicht.
Oh, ich habe in Zeile 44 einen Tipfehler....
Jetzt funktionierts. Danke :D
BlackJack

@Mars23: Das ist alles ziemlich unübersichtlich mit den verschiedenen Repräsentationen des selben Wertes mit kryptischen Namen auf Modulebene wo das Hauptprogramm auf Modulebene steht und durch Funktionsdefinitionen unterbrochen wird. Das auf Modulebene Namen definiert sind, die in Funktionen dann als lokale Namen wiederverwendet werden hilft auch nicht. Deshalb sollten auf Modulebene nur Definitionen von Konstanten, Funktionen, und Klassen stehen und das Hauptprogramm auch in einer Funktion stehen.

`pindic` scheint als Konstante gemeint zu sein, sollte also auf Modulebene stehen und komplett in Grossbuchstaben benannt sein. Allerdings ist der Name selbst schlecht weil er zuwenig über die Bedeutung und zu viel über den Typ aussagt. Der Typ hat in dem Namen nichts zu suchen weil man, wenn man den Typ ändert überall im Programm in den Namen auch die Typinformation in Namen ändern muss die davon betroffen sind. Hier ist sogar ein schönes Beispiel, denn es werten fortlaufende ganze Zahlen als Schlüssel verwendet, was eigentlich eher für eine Liste als für ein Wörterbuch spricht, denn das wäre eine Liste mit 8 Werten wenn man konventionell bei 0 anfängt zu zählen. Insgesamt ist die Datenstruktur aber nicht nötig denn die zugehören Werte kann man ja ganz leicht ausrechnen, entweder als ``2**pin`` oder ``1 << pin`` wenn man mit der Nummerierung der Pins mit 0 beginnt.

Der Name `pin_aus()` ist mir unverständlich‽ Und die Funktion, da sie so einfach ist, auch nicht wirklich notwendig. Gleiches gilt für `laenge()` was man auch einfach als ``laenge = len`` hätte definieren können, allerdings sehe ich da den Sinn nicht. Es macht das Programm eher unklarer weil jeder weiss was `len()` macht, bei `laenge()` aber vermutet das es etwas anderes macht, denn sonst hätte man ja `len()` verwenden können.

Die `int()`-Funktion mit literalen ganzen Zahlen aufzurufen ist komplett sinnfrei. Das sind ja schon ganze Zahlen, was soll der Aufruf denn bewirken‽ `data` wird zudem nirgends verwendet. So etwas fällt unter anderem deswegen nicht so schnell auf weil das so auf Modulebene sogar bei einem so relativ kurzen Programm schon zu unübersichtlich wird was eigentlich wo verwendet wird.

`gesamt()` ist kein guter Name weil der nicht verrät was die Funktion eigentlich macht. Gute Funktionsnamen sollten dem Leser vermitteln was die Funktion tut, und ist dementsprechend in der Regel auch nach einer Tätigkeit benannt.

Einbuchstabige Namen sind keine gute Namen, abgesehen von Ausnahmen wie Index-/Zählvariablen die ganze Zahlen enthalten (`i`, `j`, `k`) oder Koordinaten (`x`, `y`, `z`), was man halt so aus der Mathematik gewohnt ist, oder bei sehr begrenzter Gültigkeit („list/dict/set comprehension“, Generatorausdruck, anonyme Funktion).

Die `gesamt()`-Funktion kann man wesentlich einfacher mit Zeichenkettenformatierung schreiben und das dann auch ohne die zwei überflüssigen Zeichen am Anfang die ja im Grunde nicht zu der Zahl gehören:

Code: Alles auswählen

In [3]: format(0x1a, '08b')
Out[3]: '00011010'
Damit ist die `gesamt()`-Funktion eigentlich überflüssig, denn das kann man auch direkt in die `pin_stand()`-Funktion schreiben.

Diese Funktion greift einfach so auf `bank` zu ohne dass das als Argument übergeben wurde. Das ist keine Konstante, dementsprechend gibt es dieses `bank` nicht auf Modulebene wenn man sauber programmiert.

Das die verschiedenen Repräsentationen vom gleichen Wert an unterschiedliche Namen gebunden unübersichtlich sind, schrieb ich ja am Anfang schon mal. Diese Umwege über Zeichekettenrepräsentation von Bits sollte man sich sowieso sparen. Bei `pin_up()` gehst Du ja auch nicht über die Zeichekettenrepräsentation sondern arbeitest mit Bitoperationen. Das sollte man bei `pin_stand()` auch einfach machen. Und die Bitmaske sollte man nicht ausserhalb dieser Funktionen berechnen sondern in den Funktionen. Das ist ein Detail das den Aufrufer nicht interessieren muss. Ausserdem ist eine solche Lösung nicht nur für 8-Bit-Werte sondern funktioniert mit beliebig grossen Ganzzahlen.

Man muss nicht jedes kleine Zwischenergebnis an einen Namen binden. Insbesondere wenn man einen einfachen, kurzen Ausdruck hat, dessen Ergebnis von der Funktion an den Aufrufer zurückgegeben wird, macht es keinen Sinn sich dafür einen Namen ausdenken zu müssen oder einen total generischen Namen zu nehmen.

Anstelle von `pin_stand()` und `pin_up()` kann man die beiden Funktionen auch allgemeiner als `get_bit()` und `set_bit()` benennen. Denn das tun sie ja. Die Mischung aus deutschen und englischen Namen ist übrigens auch unschön.

Da bleibt dann am Ende so etwas übrig:

Code: Alles auswählen

def get_bit(value, bit_number):
    return (value & (1 << bit_number)) != 0


def set_bit(value, bit_number):
    return value | (1 << bit_number)


def main():
    bank = 0x1a
    pin = 7

    print bank
    print type(bank)
    print bin(bank)
    print hex(bank)
    print get_bit(bank, pin)
    print set_bit(bank, pin)


if __name__ == '__main__':
    main()
Eleocraft
User
Beiträge: 10
Registriert: Mittwoch 19. September 2018, 11:16

ich habe auch die Fehlermeldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "E:\PQ2.0.py", line 44, in <module>
    Button(screen, text='Ergebnis anzeigen', command=ergebnis(anzeige)).grid(row=3, column=0)
  File "E:\PQ2.0.py", line 39, in ergebnis
    p = int(ep.get())
ValueError: invalid literal for int() with base 10: ''
ich versuche ein Programm zur Lösung von pq-formeln zu programmieren und dazu will ich, dass nach drücken eines Knopfes ein zuvor ausgerechneter wert in einem label erscheint.
kann mir jemand helfen???

Code: Alles auswählen

from math import *
from tkinter import *

screen = Tk()
screen.title('PQ-Formel')


#pq ausrechnen


def pq(p, q):
    z = (p/2)**2 - q
    if z >= 0:
        x = -p / 2 + sqrt((p/2)**2 - q)
        y = -p / 2 - sqrt((p/2)**2 - q)
        Label(screen, text='                                                       ').grid(row=3, column=1)
        return x, y
    else:
        a = sqrt(q - (p/2)**2)
        x = complex(-p / 2, + a)
        y = complex(-p / 2, - a)
        Label(screen, text='Hinweis: diese lösung basiert auf komplexen zahlen').grid(row=3, column=1)
        return x, y


anzeige = Label(screen, text='                                                                  ').grid(row=1, column=2)


Label(screen, text='p: ').grid(row=0)
Label(screen, text='q: ').grid(row=1)


ep = Entry(screen)
eq = Entry(screen)
ep.grid(row=0, column=1)
eq.grid(row=1, column=1)

def ergebnis(anzeige):
    p = int(ep.get())
    q = int(eq.get())
    ergebnisM = pq(p, q)
    Label(screen, text='x1:       x2:').grid(row=0, column=3)
    anzeige.config(text=ergebnisM)
Button(screen, text='Ergebnis anzeigen', command=ergebnis(anzeige)).grid(row=3, column=0)

mainloop()
Benutzeravatar
__blackjack__
User
Beiträge: 13079
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Eleocraft: Du rufst `ergebnis()` auf mit `anzeige` als Argument, und der Rückgabewert dieses Aufrufs wird dann als `command`-Argumnet verwendet. Und zu dem Zeitpunkt wo Du das aufrufst ist das `ep`-Entry noch leer, und `get()` liefert deshalb eine leere Zeichenkette, und eine leere Zeichenkette kann man nicht mit `int()` in eine Zahl umwandeln. `command` muss man etwas übergeben was *aufrufbar* ist und *keine* Argumente erwartet.

Du brauchst `functools.partial()` um so eine Funktion zu erzeugen, oder einen ``lambda``-Ausdruck, oder noch besser Du lässt das mit der GUI-Programmierung erst einmal sein bis Du mit objektorientierter Programmierung (OOP) vertraut bist. Die braucht man nämlich für jedes nicht-triviale GUI-Programm.

Weitere Anmerkungen: Die `pq`-Funktion sollte tatsächlich nur die beiden Werte ausrechnen und nicht noch Ausgaben an den Benutzer machen, denn man möchte Funktionen in der Regel so schreiben, das sie nur einen in sich geschlossene Sache erledigen und einzeln testbar sind.

Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.

Funktionen und Methoden sollten alles was sie ausser Konstanten benötigen als Argument(e) übergeben bekommen, und nicht einfach so auf magische Weise aus der Umgebung verwenden können.

Edit: `anzeige` hat übrigens den Wert `None` – das ist sicher so nicht gewollt. Und man erstellt auch nicht während des Programmlaufs immer neue Label, sondern einmal am Anfang, und verändert dann wenn man das braucht den Textinhalt.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Sternchenimporte sind böse, weil man nicht kontrollieren kann, was für Namen da alles importiert werden. Funktionsdefinitionen gehören an den Anfang des Programms und alles was eine Funktion braucht, sollte sie über ihre Argumente bekommen (z.B. `screen`).

Das ganz könnte so aussehen:

Code: Alles auswählen

import tkinter as tk
from functools import partial

def pq(p, q):
    z = ((p/2)**2 - q) ** 0.5
    return -p/2 + z, -p/2 - z

def ergebnis(ep, eq, anzeige, header, message):
    p = float(ep.get())
    q = float(eq.get())
    x1,x2 = pq(p, q)
    header['text'] = 'x1:       x2:'
    anzeige['text'] = x1, x2
    message['text'] = 'Hinweis: diese lösung basiert auf komplexen Zahlen' if x1.imag else ''

def main():
    screen = tk.Tk()
    screen.title('PQ-Formel')
    anzeige = tk.Label(screen, text='                                                                  ')
    anzeige.grid(row=1, column=2)
    header = tk.Label(screen, text='')
    header.grid(row=0, column=3)
    message = tk.Label(screen, text='')
    message.grid(row=3, column=1)
    tk.Label(screen, text='p: ').grid(row=0)
    tk.Label(screen, text='q: ').grid(row=1)
    ep = tk.Entry(screen)
    eq = tk.Entry(screen)
    ep.grid(row=0, column=1)
    eq.grid(row=1, column=1)
    tk.Button(screen, text='Ergebnis anzeigen',
        command=partial(ergebnis, ep, eq, anzeige, header, message)).grid(row=3, column=0)
    screen.mainloop()

if _name__ = '__main__':
    main()
Wobei man hier schon merkt, dass `ergebnis` ziemlich viele Parameter braucht, was man besser mit Klassen lösen sollte.
Antworten