argv Problem Kommazahl übergeben/umwandeln

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
goaran
User
Beiträge: 4
Registriert: Dienstag 10. Mai 2011, 20:09

Hallo,

bin neu hier und habe bisher nur sehr wenig Python Kenntnisse, erst am Wochenende damit angefangen also sry für die Anfängerfragen.
Ich habe ein Skript welches ich von einem Programm aus Aufrufe. Das Programm hat früher Zahlenwerte als Integer übergeben also so wie ein Aufruf mit

Code: Alles auswählen

python ./script.py 100
mittlerweile sendet es aber eine Kommazahl, so in etwa

Code: Alles auswählen

python ./script.py 100.0000000
Damit funktioniert es jetzt aber nicht mehr, was hat denn argv[1] für einen Datentypen oder wie muss ich das konvertieren?
Das Script sieht so aus:

Code: Alles auswählen

#!/usr/bin/env python
# encoding: utf-8

import sys
import getopt
import RepRapArduinoSerialSender

help_message = '''Help bla..'''

class Usage(Exception):
	def __init__(self, msg):
		self.msg = msg

def main(argv=None):

	gotTemp = False
	requestedTemp = 0
	verbose = False

	if argv is None:
		argv = sys.argv		

	#Get value of P
	if len(argv) > 1:
		if argv[1].isdigit() == True:
			requestedTemp = argv[1]
			gotTemp = True
			argv.remove(requestedTemp)
	
	if gotTemp == False:
		raise Usage(help_message)				

	opts, args = getopt.getopt(argv[1:], "ho:v", ["help", "output="])

	# option processing
	for option, value in opts:
		if option == "-v":
			verbose = True
		if option in ("-h", "--help"):
			raise Usage(help_message)
		
	if verbose:
		print >> sys.stdout, "Got Target Temperature of: " + requestedTemp
	
	sender = RepRapArduinoSerialSender.RepRapArduinoSerialSender(verbose)	
	data = "M104 P" + requestedTemp	
	sender.writeToArduino(data)	
	return 0

if __name__ == "__main__":
	sys.exit(main())
Der Zweck von dem Skript ist, dass es die Zahl welche es übergeben bekommt zusammen mit einem Buchstaben über die Rs232 schickt.
Eine Gerundete Zahl reicht aus, round() funktioniert aber nur bei Float Zahlen und argv[1] ist kein Float oder?

Danke schon mal
Zuletzt geändert von Anonymous am Dienstag 10. Mai 2011, 21:07, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Hallo,

bei 'sys.argv' handelt es sich um eine Liste aus strings. Wenn Du demnach beispielsweise

Code: Alles auswählen

python ./script.py 100.1234
startest, schaut 'sys.argv' folgendermaßen aus:

Code: Alles auswählen

['./script.py', '100.1234']
Somit spielt es keine Rolle, ob das Programm die Parameter als 'int', 'float' oder 'str' an das Skript übergibt. Im Skript kommt alles erstmal als 'str'-Elemente in 'sys.argv' an.

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Nebenbei sollte man `getopt` nicht mehr nutzen, sondern `argparse` oder `optparse` (sofern argparse nicht vorhanden).

In diesem Board gibt es ein spezielle Python-Code-Tag. Bitte benutze das doch in Zukunft für Python-Quellcode :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
goaran
User
Beiträge: 4
Registriert: Dienstag 10. Mai 2011, 20:09

Danke für die schnellen Antworten und den Tipp mit der Formatierung.
Ok, argv ist also immer eine String-Array, das ist schon mal gut zu wissen.
Alleridngs verstehe ich nicht wirklich wie ich python code debuggen kann.
Wenn ich das obige script mit

Code: Alles auswählen

python ./script.py 100

laufen lasse funktioniert alles
mit

Code: Alles auswählen

python ./script.py 100.0
kommt folgender Fehler:

Code: Alles auswählen

Traceback (most recent call last):
  File "./M104", line 110, in <module>
    sys.exit(main())
  File "./M104", line 83, in main
    raise Usage(help_message)			
__main__.Usage
Was bedeutet das denn? Bzw wo liegt das Problem?
hier habe ich noch das andere Script das dort aufgerufen wird, falls das was damit zu tun hat: robotik.dyyyh.de/reprap/RepRapArduinoSerialSender.py
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

goaran hat geschrieben:Was bedeutet das denn? Bzw wo liegt das Problem?
1: Das bedeutet, dass dein Programm einen Fehler wirft.
2: isdigit()
goaran
User
Beiträge: 4
Registriert: Dienstag 10. Mai 2011, 20:09

Ok, danke, digit ist also nur 0-9 ohne punkt und komma, das war mir nicht klar.

Code: Alles auswählen

#Get value of P
	if len(argv) > 1:
		reqTemp = argv[1]	
		T = reqTemp.split(".");
		if T[0].isdigit() == True:
			requestedTemp = T[0]
			gotTemp = True
			argv.remove(reqTemp)
			print >> sys.stdout, requestedTemp  
Die Nachkommastellen brauche ich nicht desswegn habe ich mal versucht es abzuschneiden mit split(".")
So funktioniert es jetzt.
Allerdings habe ich noch eine Frage.
das argv.remove löscht ja die Variable im Eingang.
das funktioniet aber nur wenn ich den Eingang direkt auf eine Variable zugewiesen habe, wenn ich z.B. split beutzte geht es nicht.
Geht das auch irgendwie dass ich direkt sage welchen wert er löschen soll, also so in etwa argv.remove(1) dass er die 1. argv löscht oder sowas in der Art?
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

goaran hat geschrieben:Die Nachkommastellen brauche ich nicht desswegn habe ich mal versucht es abzuschneiden mit split(".")
Ein einfaches Problem sollte eine einfache Lösung verwenden.

Code: Alles auswählen

try:
    foo = int('123.45')
except ValueError:
    print 'Fehler ...'
goaran hat geschrieben:Geht das auch irgendwie dass ich direkt sage welchen wert er löschen soll, also so in etwa argv.remove(1) dass er die 1. argv löscht oder sowas in der Art?
ein type(sys.argv) zeigt dir, dass es sich um eine Liste handelt. Damit kannst du dann auch die ganz normalen Methoden einer Liste verwenden. remove() entfernt anhand des Wertes. Die korrekte Lösung findest du im Tutorial zum del-Statement.

Jetzt stellt sich nur noch die Frage, warum du eigentlich diesen Wert aus der Liste entfernen möchtest.
BlackJack

@goaran: Warum willst Du überhaupt etwas aus `sys.argv` entfernen? Das ist eher ungewöhnlich.

In Python braucht man kein Semikolon um Anweisungen abzuschliessen. Man kann damit mehrere Anweisungen in einer Zeile trennen, aber aus Gründen der Übersichtlichkeit schreibt man eigentlich nie mehrere Anweisungen in eine Zeile. Ausnahme ist natürlich Code-Golf.

Ebenfalls sehr selten wird die ``>>``-Syntax bei ``print`` verwendet. Hier ist das auch völlig überflüssig, denn Ausgaben ohne diese Umleitung in eine Datei landen sowieso schon auf ``sys.stdout``.

Ebenso überflüssig ist der explizite Vergleich mit `True`. `str.isdigit()` gibt ja selbst schon `True` oder `False` zurück und ein Vergleich mit `True` ergibt nur wieder genau den gleichen Wert.

Einrückung ist per Konvention vier Leerzeichen pro Ebene.
goaran
User
Beiträge: 4
Registriert: Dienstag 10. Mai 2011, 20:09

@/me
so ist es natürlich einfacher.
@BlackJack
das ; habe ich aus versehen gesetzt, da ich das automatisich mache vom c und matlab programmieren her.
Ok, das sind alles kurzformen der selben Befehle, habe bisher noch nicht so den Überblick desshalb habe ich es erst mal so geschrieben.
das man das sys.argv entfernt hatte ich dem Beispiel gesehen, aber macht eigentlich nicht viel Sinn, dann werde ich es wohl weglassen

Danke für die schnelle Hilfe
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Wieso magst Du eigentlich nicht `argparse` nutzen, wie ich es vorgeschlagen habe? Da hast Du eine Umwandlung von Standardtypen bereits inklusive...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Hyperion hat geschrieben:Wieso magst Du eigentlich nicht `argparse` nutzen, wie ich es vorgeschlagen habe? Da hast Du eine Umwandlung von Standardtypen bereits inklusive...
Nun lass den armen Kerl doch erst mal anfangen mit Python. ;-)

optparse ist es allerdings durchaus wert, sich dort einzuarbeiten.
Antworten