PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Python3 int oder nicht int fu



Huhn Hur Tu
29.11.16, 10:42
Hi,

mal wieder iene Python3 Frage, ich komme mit den Variablen Typen nicht klar
Ich erzeuge beim parsen eines Logs eine Variable die int sein sollte


.
.
.
VertragTmp = int(line.split(';')[11])
.
.
.
VertragTmp = VertragTmp * 100 + 2


Bei der anschliessenden Berechnung "2652367598 * 100 + 2" bekomme ich jedoch den Fehler



VertragTmp = VertragTmp * 100 + 2
TypeError: Can't convert 'int' object to str implicitly


Nach dem Erzeugen der Variable ein Type(VertragTmp), da zuerst dieser Fehler bemaengelt wird

Gruss Stefan

nopes
29.11.16, 12:53
line = '1;2;3;4;5;6;7;8;9;10;11;2652367598'
VertragTmp = int(line.split(';')[11])
VertragTmp = VertragTmp * 100 + 2
print('%s (%s)' % (VertragTmp, type(VertragTmp)))
VertragTmp = 'foo' * 100 + 2
print('%s (%s)' % (VertragTmp, type(VertragTmp)))

'''
ergibt diese Ausgaben:
265236759802 (<class 'int'>)
Traceback (most recent call last):
File "main.py", line 6, in <module>
VertragTmp = 'foo' * 100 + 2
TypeError: Can't convert 'int' object to str implicitly
'''
Klar was ich meine, oder?

[edit]Komma oder sonstiges Zeichen dran geschlichen?

Huhn Hur Tu
30.11.16, 08:20
Das Problem waren unerwartete Werte die in die Variable geschrieben wurde, die haben mir den Tag versaut.

Man beachte, dass eine Variable leer , bzw einen string enthalten enthalten kann, damit ist das wandeln nach int eben mist.

Hab das jetzt abgefangen und es tut

Bloody learning

fork
30.11.16, 08:49
Ich kann nur empfehlen da immer gleich ein halbwegs vernünftiges logging einzubauen, das kann man dann auch im Produktivbetrieb bei Bedarf kurz mal hochdrehen und dann sieht man recht schnell wo's krankt.

Z. B. in PHP:



<?PHP

include "config.php";

function _log($msg_level,$msg) {

global $log_level;
global $log_file;

if ( $msg_level <= $log_level ) {

$loghandle = fopen("$log_file","a");
fputs($loghandle, date(DATE_RFC822)." ".$msg."\n");
fclose($loghandle);
}
}

function lg_err ($msg) { global $LOG_ERROR; _log($LOG_ERROR, $msg); }
function lg_info($msg) { global $LOG_INFO; _log($LOG_INFO, $msg); }
function lg_dbg ($msg) { global $LOG_DEBUG; _log($LOG_DEBUG, $msg); }
function lg_dbg2($msg) { global $LOG_DEBUG2; _log($LOG_DEBUG2, $msg); }
function lg_dbg3($msg) { global $LOG_DEBUG3; _log($LOG_DEBUG3, $msg); }

?>

ThorstenHirsch
30.11.16, 09:14
Hab' mich gewundert, warum Python nicht schon beim int() einen Fehler wirft. Also bei mir wirft er dort schon einen Fehler:

$ ./test.py
Traceback (most recent call last):
File "./test.py", line 3, in <module>
print int(null)
NameError: name 'null' is not defined
...und...

$ ./test.py
Traceback (most recent call last):
File "./test.py", line 3, in <module>
print int("")
ValueError: invalid literal for int() with base 10: ''
Warum läuft Dein Skript weiter?

Huhn Hur Tu
30.11.16, 18:35
Ja das habe ich mich getsern auch gefragt, heute morgen habe ich einiges so umgebaut, dass nur noch int in einem Pfad weiterverarbeitet werden, und alles andere in einem anderen Pfad, Frage mich jetzt aber nicht was ich geaendert habe.

@fork, danke, das werde ich in Zukunft wohl oefter brauchen.

Nachdem ich jetzt einiges mit Python verbrechen durfte und vorher mit bash marodiert habe, muss ich sagen,d ass ich Funktionen wie "bash -x" sehr vermisse, gibt es hierfuer ein python aequvalent?

fork
30.11.16, 19:16
Ich finde nicht, dass das nötig ist, so etwas wie "-x" zu haben. Bash ist da mit den ganzen Interpolationsregeln die sie mittlerweile so hat doch recht komplex. Mir ist so etwas bei Scriptscprachen auch nicht bekannt - aber vielleicht gibt es das ja doch. Ansonsten würden mir da irgendwelche Debugger bzw. Einzelschrittmodus einfallen - habe ich auch noch nicht verwendet. Debugging-Tools gibt's bestimmt so einige.

Bei Scriptsprachen schaue ich mir persönlich bei Fehlern immer genau die Variablen und vor allem die Datentypen an. Nicht immer passen die Typen zusammen und nicht immer bricht das Programm sofort ab. Manchmal sind die Vergleiche aus eigener Unwissenheit - ich spreche da aus Erfahrung :) - auch einfach falsch und man muss testen ob mit den verschiedenen Werten auch tatsächlich eine Bedingung so entschieden wird, wie man das erwartet.

Ansonsten teste ich neue Konstrukte auch immer mal isoliert vorher im interaktiven Interpreter der jeweiligen Scriptsprache. Da sehe ich dann recht schnell ob das so funktioniert, wie ich mir das ausgemalt habe, ob es bricht oder ob ganz andere Ergebnisse als erwartet auftreten.

marce
30.11.16, 19:19
Nachdem ich jetzt einiges mit Python verbrechen durfte und vorher mit bash marodiert habe, muss ich sagen,d ass ich Funktionen wie "bash -x" sehr vermisse, gibt es hierfuer ein python aequvalent?
Meinst Du sowas?
https://docs.python.org/3/library/pdb.html

... oder noch ein anderes Google-Ergebnis:
http://stackoverflow.com/questions/15760381/what-is-the-python-equivalent-of-set-x-in-shell

nopes
30.11.16, 19:51
Ich sag mal so, Python und Testen ist einfach, sogar sehr sehr Einfach. Es macht absolut Sinn, sich da umzustellen, zusätzlich noch pep8 checker drüber rennen lassen und man braucht so ein -x nicht mehr wirklich.

[edit]PHP Ansatz von vorher in Python3 - https://docs.python.org/3/howto/logging-cookbook.html:
import logging


logger = logging.getLogger()
logger.debug('debug msg')
logger.info('info msg')
logger.warning('warning msg')
logger.error('error msg')
logger.critical('critical msg')

BetterWorld
30.11.16, 19:52
ipython ist dein Freund

ThorstenHirsch
30.11.16, 21:05
Logging vs. debugging/tracing... also ich baue in viele meiner Skripte zwar auch einen debug-Modus ein, bei dem mir das Skript Ausgaben liefert, die ich im normalen Betrieb nicht brauche, sondern nur um Fehlern auf die Schliche zu kommen, aber das ist zusätzlicher Code, der nicht dem Zweck des Programms dient und im Normalfall gar nicht ausgeführt wird - bläht den Code also nur unnötig auf.

Mit "sh -x" oder "perl -d" braucht's keinen unnötigen Code. Aber dann hat man gleich den ganzen Batzen an zusätzlicher Ausgabe und darf seine Fehlerursache wie die Nadel im Heuhaufen suchen. Mittlerweile bin ich bei Perl soweit, dass ich weiterhin einen debug-Modus implementiere, aber keine manuelle Ausgabe ins Skript einstreue, sondern (nur im debug-Modus) mittels Carp::longmess den stack trace ausgeben lasse. Ohne debug-Modus gibt's nur einfache Fehlermeldungen. Das funktioniert natürlich nur, wenn das Skript abbricht statt Fehler stillschweigend hinzunehmen. Aber es heißt ja auch "crash early, crash often".

tl;dr: Eigentlich sind die Zeiten vorbei, zu denen man (fachlich nicht relevante) Log-Ausgabe in seine Skripte einbauen musste um Fehler zu debuggen.

BetterWorld
30.11.16, 21:51
ipython ist dein Freund
Ich glaube, ich sagte schon mal, dass ipython dein Freund wäre.

fork
03.12.16, 00:16
Logging vs. debugging/tracing... also ich baue in viele meiner Skripte zwar auch einen debug-Modus ein, bei dem mir das Skript Ausgaben liefert, die ich im normalen Betrieb nicht brauche, sondern nur um Fehlern auf die Schliche zu kommen, aber das ist zusätzlicher Code, der nicht dem Zweck des Programms dient und im Normalfall gar nicht ausgeführt wird - bläht den Code also nur unnötig auf.

Ja es bläht den Code ein bisschen auf. Nach etwas Überlegung meine ich, dass das der Weg des Debuggings ist, den ich haben will. Wenn ich ein grösseres Projekt habe, dann will ich beim besten willen nicht eine "set -x" - artige Ausgabe von endlosen Schleifendurchläufen haben. Da möchte ich ein niedriges Debuglevel haben und bei kritischen Stellen zur Fehlersuche dann das gezielt und partiell nach oben drehen.

Grundsätzlich ist es auch immer die Frage, wie man programmiert und wieviel Zeit man sich dafür nimmt. Von dem, was ich schreibe ist nicht so viel für die Ewigkeit gedacht. Und nicht immer will man das sofort der kleinste Fehler bricht und die Anwendung nicht mehr funktioniert. Manche Fehler sind auch nicht solche, die man aus Faulheit in Kauf nimmt, sondern solche die man gar nicht ahnt. Genau dort ist es dann der Punkt an dem ich dann notgedrungen anfange für die Problemlösung Debuggingcode einzufügen und mich ärgere, dass ich es nicht gleich gemacht habe.

Was den Bloat angeht: Debugging-Code finde ich wertvoll, und er erhöht auch die Lesbarkeit des Codes. Die Komplexität erhöht sich dadurch nicht besonders.

Aber es gibt natürlich immer wieder Umgebungen, wo es gar nicht schnell genug sein kann. Bei dem, was ich geschrieben habe ist das bisher nie so gewesen, dass das wirklich so kriegsentscheidend war. Wenn doch, dann gibt es mit Sicherheit Möglichkeiten, Geschwindigkeitseinbußen durch Debugging-Code zu eliminieren:


Man könnte die Debugging-Funktionen durch leere Funktionen überschreiben
Man könnte per Policy definieren, dass ein Debug-Statement immer in einer eigenen Zeile sein muss und für das ein- und ausschalten von Debug-Code wird dann rekursiv per Suchen+Ersetzen ein spezieller Kommentarmarker gesetzt oder enternt.
Man könnte mit einem Makro-Präprozessor wie m4 arbeiten, der den Quellcode vor Ausführung bearbeitet und je nachdem ob die Debugging-Option aktiviert ist, oder nicht, wird der Code eben eingebunden oder nicht

BetterWorld
03.12.16, 00:59
Am Rande: Es gibt einen bash Debugger (http://bashdb.sourceforge.net/).
Ist zwar etwas gewöhnungsbedürftig und erfordert ein wenig Einarbeitungszeit, bis man das begriffen hat, abba dann!!!

Für einfacher Sachen, hab ich mir eine lib_bash_debug geschrieben. Die wird einfach gesourced und man hat dann einfach Statements, wie DEBUGvar <name>, was nicht nur Vars, sondern auch Arrays ausgeben kann, DEBUBstart/stop usw. zur Verfügung.
Mittlerweile nehme ich nur noch bashdb.