5 mars 2020

[Dynamo+=Python] Les Itérables et le Dynamo Wrappeur


  • Unwrapping vs Wrapping

Un petit rappel sur la fonction UnwrapElement()

Les éléments dans Dynamo sont exposés par défaut à l'API de Dynamo qui enveloppe l'API de Revit (d'où la notion de wrapp et de wrapped Elements)



Mais c'est quoi un Wrappeur?
D'un point de vue programmation un Wrapper, c'est une classe/ensemble de classe qui englobe une autre classe/ensemble de classe pour lui ajouter de nouvelles fonctionnalités.
On l'utilise aussi pour envelopper une API afin la rendre plus simple, comme Dynamo.

Et si l'on souhaite directement utiliser l'API de Revit dans Dynamo ?
Dynamo dispose d'une fonction "UnwrapElement()" qui permet d'exposer directement les éléments à l'API de Revit.

Cette fonction accepte en argument un élément ou une liste d'éléments.
Voici donc un mauvais exemple :


#soit Lstelem une liste en entrée [elemA, elemB, elemC, elemD]
Lstelem = IN[0]
Lstelem = [UnwrapElement(x) for x in Lstelem]

Il suffit de faire 

Lstelem = UnwrapElement(IN[0])

Bien entendu un objet créé avec l'API de Revit au sein d'un nœud Python n'a pas besoin par la suite d'être d'Évrapper par la suite dans ce même nœud.

  • isintance vs hasattr


Bien souvent lorsque l'on veut traiter des données d'entrée dans un nœud Python il faut s'assurer qu'il s'agisse bien d'une liste (ou plutôt d'un itérable).
La méthode la plus courante pour tester la Classe d'un objet Python est d'utiliser la fonction
isinstance (objectclassinfo).
Donc pour vérifier si l'objet est  une liste on utilisera : isinstance (objectlist)

Test avec la fonction isinstance, ici la valeur retournée est bien True

Note:
GetType() est une méthode vb.net (on est dans un environnement IronPython) qui retourne ici le Type de Classe de l'objet (comme la fonction native type() en Python)
Puis vient le temps où l'on décide d'utiliser l'API de Revit, on utilise donc la fonction UnwrapElement() et là ça se gâte...💥

 la valeur retournée devient False ❓❓❓ alors que l'on a bien une liste en entrée ❓❓❓

La liste n'est plus liste... elle est devenue une Collection (.Net)

  • une première solution consiste à tester d'abord la variable avec la fonction vue précédemment puis on applique la fonction UnwrapElement()



  • une deuxième méthode consiste à vérifier si la variable d'entrée est un itérable (dictionnaire, liste, collection, etc..) en passant par la fonction hasattr()



on vérifie si la variable d'entrée est un itérable en regardant si elle contient l'attribut "__iter__


  • dictionary vs Dictionnary (Net.Collection)


Avec Dynamo Il est tout à fait possible de travailler avec des dictionnaires Python, néanmoins pour les attribuer à la variable OUT, il est nécessaire de passer par des Dictionnaires DotNet avec en plus une petite spécificité "In Dynamo 2.0, keys can only be strings" , (les clés doivent être au format Texte)


Comparaison Dictionnaire Python vs Dictionnaire .Net affecté à la variable OUT






Pour un Dictionnaire Python il est toujours possible de le convertir en liste (String ou pas String...)

Conversion d'un Dictionnaire Python en liste 


Ou encore mieux, d'encapsuler le ou les dictionnaires dans un objet pour pouvoir les réutiliser dans un autre nœud Python

 Sans encapsulation avec un Dictionnaire de type  (System.Object, System.Object)
affecté à la variable OUT

Avec encapsulation avec un Dictionnaire de type (System.Object, System.Object) encapsulé dans une Classe (objet)



A vos Wraps! Prét? Coder!



0 commentaires:

Enregistrer un commentaire