[Python] ValueError: Unknown format code ... for object of type ...


Status
Dieses Thema wurde gelöst! Zur Lösung gehen…

tklustig

Erfahrenes Mitglied
#1
Hallo Leute,
nutze Python eigentlich nie, deshalb ist mir folgende Fehlermeldung ein Rätsel
Code:
Traceback (most recent call last):
  File "AdafruitDHT.py", line 19, in <module>
    print('Temp={0:0.1f}C'.format(temperature))
ValueError: Unknown format code 'f' for object of type 'str'
Folgender Code funktioniert, liefert mit die Werte allerdings nicht so, wie ich sie benötige. Ich benötige sowohl die Temperatur als auch die Feuchtigkeit einzeln und nicht im Paket
Python:
import sys
import Adafruit_DHT
# Parse command line parameters.
sensor_args = { '11': Adafruit_DHT.DHT11,
                '22': Adafruit_DHT.DHT22,
                '2302': Adafruit_DHT.AM2302 }
if len(sys.argv) == 3 and sys.argv[1] in sensor_args:
    sensor = sensor_args[sys.argv[1]]
    pin = sys.argv[2]
else:
    print('Usage: sudo ./Adafruit_DHT.py [11|22|2302] <GPIO pin number>')
    print('Example: sudo ./Adafruit_DHT.py 2302 4 - Read from an AM2302 connected to GPIO pin #4')
    sys.exit(1)

humidity, temperature = Adafruit_DHT.read_retry(sensor, pin)

if humidity is not None and temperature is not None:
    print('Temp={0:0.1f}*  Humidity={1:0.1f}%'.format(temperature, humidity))
else:
    print('Failed to get reading. Try again!')
    sys.exit(1)
Folgender Versuch, nur die Temperatur auszulesen, klappt nicht und führt zu oben aufgezeigtem Fehler:
Python:
import sys
import Adafruit_DHT
# Parse command line parameters.
sensor_args = { '11': Adafruit_DHT.DHT11,
                '22': Adafruit_DHT.DHT22,
                '2302': Adafruit_DHT.AM2302 }
if len(sys.argv) == 3 and sys.argv[1] in sensor_args:
    sensor = sensor_args[sys.argv[1]]
    pin = sys.argv[2]
else:
    print('Usage: sudo ./Adafruit_DHT.py [11|22|2302] <GPIO pin number>')
    print('Example: sudo ./Adafruit_DHT.py 2302 4 - Read from an AM2302 connected to GPIO pin #4')
    sys.exit(1)

# Try to grab a sensor reading.  Use the read_retry method which will retry up
# to 15 times to get a sensor reading (waiting 2 seconds between each retry).
temperature = Adafruit_DHT.read_retry(sensor, pin)
if temperature is not None:
    print('Temp={0:0.1f}C'.format(temperature))
else:
    print('Failed to get reading. Try again!')
    sys.exit(1)
Wie kann ich die Werte jeweils einzeln auslesen, damit ich sie einem Shellscript zuweisen kann. Hier noch der Übersichtlichkeit wegen das Shellscript:
Bash:
#!/bin/bash 
cd /home/tklustig/

wert1=$(sudo python AdafruitDHT.py 11 4)
wert2=$(sudo python AdafruitDHT_copy.py 11 4)

uhrzeit=`date +%H:%M`
datum=`date +%d.%m.%Y `
echo $uhrzeit
echo $datum
echo "Temperatur:"$wert1
echo "Feuchtigkeit:"$wert2
user="root"
password="TopSecret"
database="TopSecret"
table="TopSecret"
server="localhost"
query="INSERT INTO $database.$table(datum,uhrzeit,Temperatur_Celsius,Luftfeuchtigkeit_Prozent) VALUES ('$datum','$uhrzeit','$wert1','$wert2')"
echo $query | mysql -u $user --password=$password $database -h $server
exit 0
 

ComFreek

Mod | @comfreek
Moderator
#2
humidity, temperature = Adafruit_DHT.read_retry(sensor, pin)
Das sagt mir, dass die Funktion auf der rechten Seite ein Tupel zurückgibt.

temperature = Adafruit_DHT.read_retry(sensor, pin)
Das sagt mir, dass du eigentlich nur den ersten Wert des Tupels haben möchtest, das ganze Tupel aber trotzdem (fälschlicherweise) in temperature speichrest.

ValueError: Unknown format code 'f' for object of type 'str'
Und diese Fehlermeldung sagt schlussendlich, dass du dieses Tupel fälschlicherweise an format übergibst, was einen Wert verlangt hat, dessen Typ zu 'f' korrespondiert. Wahrscheinlich bedeutet f sowas wie floating-point.

Die Lösung ist:
Python:
temperature, _ = Adafruit_DHT.read_retry(sensor, pin)
_ ist ein idiomatischer Python-Name, um Werte wegzuschmeißen. So entpackst du immer noch das Tupel, das von der rechten Seite zurückgegeben wird, speicherst nur den ersten Wert in temperature und wirfst den zweiten Wert weg.
(Beachte: _ ist ein normaler Variablenname, du kannst danach freilich immer noch auf _ zugreifen. Das Wegwerfen ist nur idiomatisch zu verstehen. Du hättest genauso gut temperature, iDontNeedThisAnymore = ... benutzen können. Das wäre halt unidiomatisch i. S. d. Python-Gemeinde.)
 

tklustig

Erfahrenes Mitglied
#3
Klappt. Aber auch so klappt es:
Python:
temperature,humidity = Adafruit_DHT.read_retry(sensor, pin)

if temperature is not None:
    print(temperature)
Das Tupel iefert zwar immer noch beide Werte, ich gebe allerdings nur den jeweils benötigten aus. Im zweiten Script gebe ich nur humidity aus und speicher so über das Shell-Script die jeweiligen Werte in die Datenbank
 
Status
Dieses Thema wurde gelöst! Zur Lösung gehen…