19 avr. 2020

[Dynamo+=Python] Debogage - Printez vos variables




Lorsqu'on développe en Python et qu'on arrive la première fois sous Dynamo, on peut être surpris par l'absence de console quand un on écrit dans un nœud Python.
À ce jour, seule la variable OUT permet d'afficher des données



La première idée pour connaitre la/les valeurs d'objets serait de les affecter à la variable OUT, mais ce n'est pas toujours possible ou alors il faut apporter plusieurs modifications de code.

Un exemple d'un parcours où l'on souhaite connaître les valeurs d'un dictionnaire Python avec des nombres en guise de clés.
J'ai pris volontairement cet exemple car Dynamo n'accepte que du texte comme clés pour les dictionnaires affectés à la variable OUT

On  commence simplement par essayer d'affecter le dictionnaire à la variable OUT...et ça ne marche pas...



On essaie ensuite de le convertir en Dictionnaire .NET....toujours pas ...


Il faut convertir les clés en chaine de caractères (string) et cette fois c'est bon on peut analyser notre dictionnaire



Voici une alternative pour connaitre la/les valeurs de variables/d'objets.
On utilise le "file-like object"  stdout qui permet de capturer l’affichage des "prints" d’un code Python.

1/ on redirige (remplace) le flux  stdout vers un nouveau fichier en mémoire (via le module cstring)
sys.stdout = StringIO()


2/On print les variables souhaitées
print "Start Test"


3/On pointe vers le début du "fichier mémoire"
sys.stdout.seek(0)

4/ on récupère le contenu des prints et on l'affecte à variable OUT
OUT =  sys.stdout.read()
 




import System
import sys
pf_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86)
sys.path.append(pf_path + '\\IronPython 2.7\\Lib')
if sys.version_info.major >= 3 :
    from io import StringIO    
else:
    from cStringIO import StringIO
sys.stdout = StringIO()
alphabet = [chr(i) for i in range(ord('a'),ord('z')+1)]
def funtest():
    global dict
    for numb, alpha in zip(range(1,60,1), alphabet):
        dict[numb] = alpha
dict = {}
print "Start Test"
funtest()
print dict
print "End Test"
sys.stdout.seek(0)
OUT =  sys.stdout.read()


Une fois le débogage finit, vous pouvez mettre ces lignes en commentaires (ou les supprimer)
#sys.stdout = StringIO()
#sys.stdout.seek(0)
#sys.stdout.read()

un autre exemple avec une levée d'exception


  
import System
import sys
pf_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86)
sys.path.append(pf_path + '\\IronPython 2.7\\Lib')
if sys.version_info.major >= 3 :
    from io import StringIO    
else:
    from cStringIO import StringIO
sys.stdout = StringIO()
alphabet = [chr(i) for i in range(ord('a'),ord('z')+1)]

class CustomException(Exception):
    pass

def funtest():
    global dict
    for numb, alpha in zip(range(1,60,1), alphabet):
        dict[numb] = alpha
    try:    
        raise CustomException('Problem Check this dict -->  ', dict) 
    except Exception as ex:
        print type(ex)
        print ex
        #unpack variables
        var1 , var2 = ex
        print var2
        
        
dict = {}
print "Start Test"
funtest()
print "End Test"
sys.stdout.seek(0)
OUT =  sys.stdout.read()  


Voilà, pour finir un très bon article pour continuer la lecture
http://sametmax.com/capturer-laffichage-des-prints-dun-code-python/

Note:
pour un débogage plus poussé il est également possible d'utiliser la Console de RevitPythonWrapper dans Dynamo
https://forum.dynamobim.com/t/debugging-python-code/12729/14

0 commentaires:

Enregistrer un commentaire