Rückgabewert in .txt umleiten

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
Wostl
User
Beiträge: 4
Registriert: Freitag 26. August 2011, 09:57

Hallo Gemeinde,

gleich im Voraus: Ich habe erst vor kurzem mit der Programmierung in Python begonnen, da ich es für die Ansteuerung einer elektr. Last benötige.

Aber nun zu meinem Problem:
Die oben genannte Last kann mir Rückgabewerte über die getroffenen Einstellungen liefern.
Diese würde ich gerne in eine .txt-Datei schreiben, um diese weiterverwenden zu können.

Wenn ich das Gerät mittels cmd.exe und meines "control.py"-Files ansteuere liefert es mir folgenden Rückgabewert (in Hex):

aa .. 23 1a 31 .. .. .. .. ..
.. .. .. .. .. .. .. .. .. ..
.. .. .. .. .. 18

.. steht hierbei für hex 0.

Wenn ich die gleiche Variable aber in mein .txt-File schreibe bekomme ich leider nur "Datenmüll". ª|#|1||||||||||||||||||||||||
Hierbei steht | für das Nullzeichen.


Hier der Code für mein Programm:

Code: Alles auswählen

####################################################################################
# Set the DC load to Remote, Set the Voltage,Current and Power and turn the load on#
####################################################################################


import serial
length_packet = 26 # Number of bytes in a packet

def	DumpCommand(bytes):
	assert (len(bytes) == length_packet)
	header = " "*3
	print header
	for i in xrange (length_packet):
		
		if i % 10 == 0 and i !=0:
			print
			print header,
		if i % 5 == 0:
			print " ",
		s = "%02x" % ord(bytes[i])
		if s == "00":
			s = chr(250)*2
		print s,
	print
	
def CalculateChecksum(cmd):
	assert((len(cmd) == length_packet - 1) or (len(cmd) == length_packet))
	checksum=0
	for i in xrange (length_packet -1):
		checksum += ord(cmd[i])
	checksum %= 256
	return checksum

def main():
	
	##########
	#Settings#
	##########
	
	port=2 #COM3
	baudrate = 9600
	sp = serial.Serial(port, baudrate) #Open a serial connection

	###################################
	# Construct to read the settings  #
	###################################
	
	cmd = chr(0xaa) + chr(0x00) + chr(0x23) #First three bytes
	cmd += chr(0x00) + chr(0x00)+ chr(0x00)*(length_packet -1 -5)
	cmd += chr(CalculateChecksum(cmd))
	assert(len(cmd) == length_packet)
	
	# Send command to DC load
	sp.write(cmd)
	print "Set to remote command:"
	#DumpCommand(cmd)
	
	#Get response from DC load
	response = sp.read(length_packet)
	assert(len(response) == length_packet)
	f = open('c:/python25/python/tmp.txt', 'w')
	f.write(response)
	f.close()

	print "Response:"
	DumpCommand(response)	
	
	
main()
Was mache ich bei der Ausgabe in mein .txt-File falsch??
Für Antworten wäre ich sehr Dankbar!


Wostl
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Wenn Du nackte Bytes in eine Datei schreiben willst, solltest Du sie im Binärmodus öffnen:

Code: Alles auswählen

with open(filename, "wb") as handler:
    pass
Das `b` ist das wichtige Flag :-)

Dateien solltest Du auch immer in Kombination mit dem `with` Statement öffnen.

Dein Quellcode wirkt sehr "unordentlich". Lies Dir mal PEP8 durch und versuche, das besser einzuhalten.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Wostl
User
Beiträge: 4
Registriert: Freitag 26. August 2011, 09:57

Danke für die schnelle Antwort!

Ich habe nun versucht die Datei so wie du es beschrieben hast zu öffnen.
Allerdings bekomme ich nun die Fehlermeldung: Syntax Error: Invalid syntax
Hierbei zeigt er auf das "n" von "open".

Wenn ich die Datei so wie vorhin öffne, nur mit dem binär-Flag:

Code: Alles auswählen

f = open('c:/python25/python/tmp.txt', "wb")
Dann bekomme ich die selbe Ausgabe, wie wenn ich nur "w" schreibe.

Mein Quelltext gehört wirklich mal aufgeräumt, da hast du zu 100% Recht :wink:
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Poste doch mal die exakte Fehlermeldung und den exakten Code-Schnipsel, der dazu geführt hat. Kann es sein, dass Du Python < 2.5 einsetzt? Dann kennt Python das `with` Statement noch nicht.

Wenn es nicht am Binärmodus liegt, muss der Fehler vorher in Deiner Verarbeitung zu finden sein - das ist mir ehrlich gesagt zu mühsam, mich durch diesen Wust zu wühlen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Wostl
User
Beiträge: 4
Registriert: Freitag 26. August 2011, 09:57

So hab nun nach langer Suche und Testerei eine Lösung gefunden:

Hier der Code, für alle, die vor dem gleichen Problem stehen:

Code: Alles auswählen

import pickle

	f = open('c:/python25/python/tmp.txt', "w")
	pickle.dump(response, f)
	f.close()

Wostl
BlackJack

@Wostl: Falls Du Python 2.5 (oder älter) verwendest, musst Du die ``with``-Anweisung erst mit einem ``from __future__ import with_statement`` aktivieren.

Deine Lösung ist nur etwas wenn Du die Daten tatsächlich in dem Format haben möchtest.

Das Problem mit dem ursprünglichen Programm war, dass Du die rohen Bytedaten in die Datei geschrieben hast, zur Ausgabe aber eine Funktion verwendet hast, welche die Daten in eine hexadezimale Darstellung überführt hat.

Die Funktion wäre mit dem `binascii`-Modul aus der Standardbibliothek wahrscheinlich etwas einfach ausgefallen.
Wostl
User
Beiträge: 4
Registriert: Freitag 26. August 2011, 09:57

Danke BlackJack für den Hinweis auf das 'binascii'-Modul.

Die reine Pickle-Variante, hat mir zwar einen Hexcode ausgegeben, jedoch hat er sich genau bei den Bytes mit den Informationen "verschluckt" und diese nicht richtig ausgegeben.
Mit dem binascii-Befehl funktioniert es jetzt einwandfrei.

Nochmals Danke an all die schnellen und hilfreichen Antworten!


Wostl
Antworten