Partage
  • Partager sur Facebook
  • Partager sur Twitter

Condition if avec un string comme condition

    9 novembre 2018 à 9:09:40

    Mon cher Fredo54, avant d'émettre des jugements de valeur peu opportun, il faut aussi peut-être ouvrir ton champ de perception !

    Il y a de nombreux cas dans notre métier ou la possiblité de personnaliser un mode de calcul, laissée à la libre imagination de l'utilisateur, revet une importance capitale.

    A 17 ans j'ai écris un logiciel qui permettait d'étudier le comportement de gaz dans des conteneurs, via des capteurs de température et de pression, et de comparer les résultats au modèle des gaz parfaits. Chaque client pouvait avoir des capteurs différents, souvent fabriqués par eux même dans leur laboratoire (le soft était destiné à des labos / structures d'enseignement).

    De fait, la courbe de réponse du capteur, jamais linéaire, était une fonction mathématique complexe qu'il fallait pouvoir évaluer dynamiquement pour calculer la vraie valeur à partir de la mesure retournée sous 8 bits. La seule solution était de laisser l'utilisateur saisir l'équation de réponse et de concevoir un évaluateur mathématique stricte. Si j'avais eu la connaissance que j'ai aujourd'hui, j'aurais fait ça en 1/2 journée alors que, à l'époque, j'ai galéré des jours entiers pour un résultat très approximatif !

    Plus récemment, j'ai eu besoin de faire un outil de scripting capable de faire des choses identiques afin de permettre à un client de construire ses tableaux de bord personnalisés à partir de données brutes mises à disposition par un noyau logiciel.

    Plus récemment encore, c'est un système de calcul du nombre de jours à décompter lorsqu'on pose des congés d'une date à une autre qu'il a fallu qu'on rendre scriptable dans notre solution, pour permettre l'adaptation aux quelques 550 conventions collectives de France, mais aussi pouvoir l'ouvrir à un usage dans tous les pays, de sorte qu'on puisse ouvrir un nouveau client sans devoir livrer du code sur la prod.

    Et le plus célèbre des logiciels tableur passe son temps à faire ce que tu nommes comme étant "crade et peu conceptuel"...c'est un des logiciels les plus utilisés au monde.

    Maintenant, il est clair que le besoin initial, le fonctionnel global visé n'ayant pas été explicité (malgré tous ces messages), on peut se demander s'il est réellement utile de sortir ce genre d'artillerie. Mais il existe bien des cas ou ce type d'approche a tout son sens et se révèle parfaitement "clean et conceptuellement pertinent".

    • Partager sur Facebook
    • Partager sur Twitter
      9 novembre 2018 à 9:37:03

      Fredo54 a écrit:

      Je dois parler en chinois, bref !

      Je prends ton exemple,

      Pour chaque traitement dans dictionnaire
          Si "a==1 && b==2" dans dictionnaire[traitement]
              executer(traitement)
      
      # dictionnaire[traitement] contient la liste des conditions possibles pour exécuter le traitement.
      # traitement est la clé du dictionnaire

      Je n'en reviens pas que certains ici proposent d'appuyer une solution aussi crade et aussi peu conceptuelle que l'évaluation d'une chaîne de caractères en code java.

      J'ai bien compris ce que tu me dis, en gros tu me conseille de tester des égalité de String entre mon test et tous les test potentiel. Cela oui ça marcherais sauf que ensuite tu me dis de faire executer(traitement) avec je suppose la fonction executer() qui est de cette forme :
      executer(String traitement)
      {
         switch(traitement)
         {
           case "action1" : ... break;
           case "action..." : ... break;
           ...
          }
      
      }
      Tu me dis si je me trompe. Sauf que je ne connais pas en avance l'action a effectuer dans tous ces case simplement car c'est l'utilisateur qui choisira ces actions. Donc le problème reste le même , le if est résolu mais le then non.


      • Partager sur Facebook
      • Partager sur Twitter
        9 novembre 2018 à 10:53:47

        necbfrt a écrit:

        Sauf que je ne connais pas en avance l'action a effectuer dans tous ces case simplement car c'est l'utilisateur qui choisira ces actions.

        Sauf que tu ne l'as pas spécifié, tu as parlé des conditions possibles pour un traitement donné, d'ailleurs je ne vois pas comment on peut prévoir une condition sans en connaître le traitement à adopter.

        D'ailleurs executer dans mon exemple c'est juste algorithmique, dans un sens, on préférerait

        traitement();

        En java il me semble, qu'on utiliserait l'interface Function, un exemple ICI.

        Mais il existe bien des cas ou ce type d'approche a tout son sens et se révèle parfaitement "clean et conceptuellement pertinent".

        Ok ça se fait en java peut-être et dans d'autres situations, nous en python, c'est dégueulasse et complètement inutile.

        Mais tu me diras peut-être que la conception diffère entre langages objets (je déconne, je n'y crois absolument pas) :D

        -
        Edité par Fredo54 9 novembre 2018 à 11:04:08

        • Partager sur Facebook
        • Partager sur Twitter

        Bonne journée...

          9 novembre 2018 à 11:09:21

          Fredo54 a écrit:

          Je dois parler en chinois, bref !

          Je prends ton exemple,

          Pour chaque traitement dans dictionnaire
              Si "a==1 && b==2" dans dictionnaire[traitement]
                  executer(traitement)
          
          # dictionnaire[traitement] contient la liste des conditions possibles pour exécuter le traitement.
          # traitement est la clé du dictionnaire

          Je n'en reviens pas que certains ici proposent d'appuyer une solution aussi crade et aussi peu conceptuelle que l'évaluation d'une chaîne de caractères en code java.

          Ta solution est bien plus crade, que ce passe-t-il si il y a 10 variable à tester : seulement 1024 cas à rentrer à la main dans un dictionnaire,

          si dans l’évaluation de code java tu as 10 variable, cela ne change rien ... 

          • Partager sur Facebook
          • Partager sur Twitter
            9 novembre 2018 à 11:14:04

            Splintz a écrit:

            Fredo54 a écrit:

            Je dois parler en chinois, bref !

            Je prends ton exemple,

            Pour chaque traitement dans dictionnaire
                Si "a==1 && b==2" dans dictionnaire[traitement]
                    executer(traitement)
            
            # dictionnaire[traitement] contient la liste des conditions possibles pour exécuter le traitement.
            # traitement est la clé du dictionnaire

            Je n'en reviens pas que certains ici proposent d'appuyer une solution aussi crade et aussi peu conceptuelle que l'évaluation d'une chaîne de caractères en code java.

            Ta solution est bien plus crade, que ce passe-t-il si il y a 10 variable à tester : seulement 1024 cas à rentrer à la main dans un dictionnaire,

            si dans l’évaluation de code java tu as 10 variable, cela ne change rien ... 

            C'est pas moi qui dit qu'il y a plein de conditions à vérifier pour un seul traitement. Il faut bien déterminer quelles sont les conditions pour le traitement à exécuter, ça ne se devine pas !

            • Partager sur Facebook
            • Partager sur Twitter

            Bonne journée...

              9 novembre 2018 à 11:15:03

              Pour résumer (j'irai relire plus tard le sujet pour voir toutes les nouveautés), c'est l'utilisateur qui tape le code et toi du dois l'exécuter, c'est bien ça ? Donc tu ne sais pas ce qui est tapé, tu as juste un code source à exécuter ? 

              Tu compares le code python avec quelle méthode en Java ?

              Fredo54 a écrit:

              Splintz a écrit:

              Fredo54 a écrit:

              Je dois parler en chinois, bref !

              Je prends ton exemple,

              Pour chaque traitement dans dictionnaire
                  Si "a==1 && b==2" dans dictionnaire[traitement]
                      executer(traitement)
              
              # dictionnaire[traitement] contient la liste des conditions possibles pour exécuter le traitement.
              # traitement est la clé du dictionnaire

              Je n'en reviens pas que certains ici proposent d'appuyer une solution aussi crade et aussi peu conceptuelle que l'évaluation d'une chaîne de caractères en code java.

              Ta solution est bien plus crade, que ce passe-t-il si il y a 10 variable à tester : seulement 1024 cas à rentrer à la main dans un dictionnaire,

              si dans l’évaluation de code java tu as 10 variable, cela ne change rien ... 

              C'est pas moi qui dit qu'il y a plein de conditions à vérifier pour un seul traitement. Il faut bien déterminer quelles sont les conditions pour le traitement à exécuter, ça ne se devine pas !

              D'où l'intérêt de faire un petit langage et de l'interpréter. Les DSL c'est fait pour ça :/

              -
              Edité par 3ch0 9 novembre 2018 à 11:18:19

              • Partager sur Facebook
              • Partager sur Twitter
                9 novembre 2018 à 11:19:27

                3ch0 a écrit:

                Pour résumer (j'irai relire plus tard le sujet pour voir toutes les nouveautés), c'est l'utilisateur qui tape le code et toi du dois l'exécuter, c'est bien ça ? Donc tu ne sais pas ce qui est tapé, tu as juste un code source à exécuter ? 

                Tu compares le code python avec quelle méthode en Java ? 


                Avec ça ou ça!

                -
                Edité par Fredo54 9 novembre 2018 à 11:31:36

                • Partager sur Facebook
                • Partager sur Twitter

                Bonne journée...

                  9 novembre 2018 à 15:35:25

                  Je vais essayé d'expliquer mon cas concret.

                  Je dois créer une interface permettant à des professionnels du secteur social d'orienter des personne selon des tas de critères. Le logiciel développé doit pouvoir choisir lui même les orientations les plus approprié, un exemple tout à fait incongru serait : si "la personne vit dans Ville1 et possède un chat" (l'ensemble des conditions) alors "elle doit aller acheter une baguette" (l'orientation = le traitement).

                  Sauf que ce logiciel sera distribué à des dizaines de professionnel qui auront chacun leurs préférences d'orientation.

                  Par exemple pour le professionnel 1 les conditions précédentes doivent aboutir à l'orientation "aller acheter du poisson" tandis que le professionnel 2 préfère garder l'orientation de base, à savoir "aller acheter une baguette".

                  Le professionnel 3 peut également décider de garder l'orientation "aller acheter une baguette" sauf qu'il souhaite ajouter une condition, par exemple " si la personne vit dans Ville1 et possède un chat et ne sait pas nager".

                  En résumé moi en tant que développeur je ne connais ni les cause ni les conséquences de ces orientations, en revanche je sais que dans ma base de donnée ces causes et ces conséquences sont présente sous forme de boolean à tester (pour les cause) et de ligne de commande java (pour les orientations) et qu'elles n'ont aucune erreurs de syntaxe,etc.

                  Ce que je n'ai pas en revanche c'est la solution qui me permettrais de tester mes boolean (la solution de fredo54 avec le test d’égalité de String est une éventualité) et surtout d’exécuter des lignes java qui sont dans un String.

                  Je ne connait aucune cause et aucune orientation en avance, c'est les professionnels qui les créer (la création n'est pas un problème).

                  • Partager sur Facebook
                  • Partager sur Twitter
                    9 novembre 2018 à 16:52:51

                    L'orientation est sans doute déjà connu, sinon comment pourrais-tu conclure que telle et telle condition résulte d'une orientation ?

                    Pour moi ton cas de figure, c'est connaître toutes les orientations possibles et d'en déduire déjà sur papier les conditions possibles.

                    Pour les conditions, j'obterai pour des choix multiples qui varient selon les choix précédents, afin d'éviter tous les choix possibles et inimaginables.

                    Ce que tu proposais permettait une infinité de solutions possibles, et tu dois limiter avec des orientations et des conditions bien précises.

                    Pourquoi pas du JSON, base de données, ... ?

                    • Partager sur Facebook
                    • Partager sur Twitter

                    Bonne journée...

                      9 novembre 2018 à 20:01:54

                      Fredo54 a écrit:

                      L'orientation est sans doute déjà connu, sinon comment pourrais-tu conclure que telle et telle condition résulte d'une orientation ?

                      Pour moi ton cas de figure, c'est connaître toutes les orientations possibles et d'en déduire déjà sur papier les conditions possibles.

                      Pour les conditions, j'obterai pour des choix multiples qui varient selon les choix précédents, afin d'éviter tous les choix possibles et inimaginables.

                      Ce que tu proposais permettait une infinité de solutions possibles, et tu dois limiter avec des orientations et des conditions bien précises.

                      Pourquoi pas du JSON, base de données, ... ?


                      Crois moi il n'y a pas de problème dans mon modèle, il n'y aura pas une infinité de test. Et je le répète car tu me demande si "L'orientation est sans doute déjà connu" : non l'orientation n'est pas connu par moi lorsque j'écris le code Java, elle sera connu lorsque l'utilisateur l'aura créer (peut-être demain, peut-être dans 150 ans, en tout cas je ne toucherais pas au code java pour ajouter ces nouvelles conditions). L'utilisateur l'aura créer grâce à une interface que j'ai créer. Quand à la manière dont je teste les conditions ce n'est pas le problème non plus.

                      Je connais la liste des causes (vivre dans Ville1, savoir nager, etc) et la liste des lieu d'orientation (boulangerie, poissonerie, etc) mais je ne connais pas la combinaison de cause qui aboutisse au lieu d'orientation. L'utilisateur (grâce à l'interface que j'ai déjà créer) fait trois choses :

                      • choisi la liste des cause en les liant entre eux avec des et et des ou
                      • choisi la liste des lieu d'orientation possible
                      Ensuite moi je traite ce qu'il a créer comme ceci, si je recois
                      • si "vivre dans ville1 ou savoir nager"
                      • alors "acheter du poisson"
                      Je le transforme en deux String
                      • " if(existe("vivre_dans_ville1") || existe("savoir_nager") )"
                      • "{ acheterPoisson(); }"

                      Ce que je demande c'est simplement une implémentation (ou une technologie) qui permette d'executer ces deux string, pas la peine de se demander si le reste tiens la route.

                      • Partager sur Facebook
                      • Partager sur Twitter
                        9 novembre 2018 à 20:17:10

                        Donc tu veux créer une IA quoi ?
                        • Partager sur Facebook
                        • Partager sur Twitter

                        Bonne journée...

                          9 novembre 2018 à 20:51:38

                          Non pas vraiment car en réalité le seul traitement derrière acheterPoisson serais d'ajouter dans une base de donnée tel personne a eu l'orientation "acheter du poisson". En revanche je me rends compte que le test des causes par une égalité de String n'est pas faisable car j'aurais certe un tableau de String contenant toutes les conditions possible pré-enregistré par l'utilisateur mais je n'aurais pas les conditions remplis par le professionel à chaque passage. En gros je ne pourrais pas faire if(condition existe dans toutes les conditions) car je n'ai pas condition sous forme de String.

                          • Partager sur Facebook
                          • Partager sur Twitter
                            9 novembre 2018 à 21:02:48

                            Je ne comprend plus rien...
                            • Partager sur Facebook
                            • Partager sur Twitter

                            Bonne journée...

                              9 novembre 2018 à 21:46:27

                              Forcement puisqu'on s'éloigne du problème initial, je répète ma question. Comment je peux executer une ligne de code Java contenu dans un String. En oubliant tout le reste. Je l'ai déjà dis mais je veux pouvoir faire
                              executeString("system.out.println("hello world");");
                              
                              
                              et que ceci soit équivalent à faire
                              system.out.println("hello world");
                              Je ne pense pas que je puisse être plus claire, le problème est simple, la solution je ne la connais pas.

                              • Partager sur Facebook
                              • Partager sur Twitter
                                10 novembre 2018 à 9:47:22

                                En Java ça n'existe pas, il faut passer par des libs hors standard, voir cette discussion.

                                Mais je te conseille de lire cette discussion qui se trouve à la même adresse... car soit le problème est mal posé, soit c'est la résolution.

                                D'ailleurs un problème bien posé pour ce type d'exercice devrait avoir bien plus de détails (un genre de cahier des charges).

                                • Partager sur Facebook
                                • Partager sur Twitter

                                Bonne journée...

                                  10 novembre 2018 à 14:26:32

                                  necbfrt a écrit:

                                  Forcement puisqu'on s'éloigne du problème initial, je répète ma question. Comment je peux executer une ligne de code Java contenu dans un String. En oubliant tout le reste. Je l'ai déjà dis mais je veux pouvoir faire

                                  executeString("system.out.println("hello world");");
                                  
                                  

                                  et que ceci soit équivalent à faire

                                  system.out.println("hello world");

                                  Je ne pense pas que je puisse être plus claire, le problème est simple, la solution je ne la connais pas.

                                  tu peux compiler et exécuter comme pour ton programme, sauf que tu le fais depuis le code (par contre il faudra rajouter les lignes nécessaire à Java) si les variables du code ne sont pas mélangées avec celles des String

                                  -
                                  Edité par Splintz 10 novembre 2018 à 14:29:47

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    10 novembre 2018 à 20:23:39

                                    Splintz a écrit:

                                    necbfrt a écrit:

                                    Forcement puisqu'on s'éloigne du problème initial, je répète ma question. Comment je peux executer une ligne de code Java contenu dans un String. En oubliant tout le reste. Je l'ai déjà dis mais je veux pouvoir faire

                                    executeString("system.out.println("hello world");");
                                    
                                    

                                    et que ceci soit équivalent à faire

                                    system.out.println("hello world");

                                    Je ne pense pas que je puisse être plus claire, le problème est simple, la solution je ne la connais pas.

                                    tu peux compiler et exécuter comme pour ton programme, sauf que tu le fais depuis le code (par contre il faudra rajouter les lignes nécessaire à Java) si les variables du code ne sont pas mélangées avec celles des String

                                    -
                                    Edité par Splintz il y a environ 5 heures

                                    C'est à dire compiler directement mes String ? Cela n'impliquerais pas que je doivent "créer" moi même mon propre compilateur ? J'ai également trouvé cette solution je vais essayer de m'y pencher : http://www.java2s.com/Tutorial/Java/0120__Development/CompileString.htm

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      10 novembre 2018 à 22:10:11

                                      Non juste que tu réutilise celui que tu as utilisé pour compiler ton programme mais encore une fois faut rajouter pas mal de truc au string pour qu'il soit valide

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        12 novembre 2018 à 18:43:10

                                        @Fredo54 Je vois de la condescendance, mais pas d'arguments...je dois bigler...

                                        Le "scripting" de code Java est une solution très utilisée dans le milieu industriel pour différentes raisons, et pour des buts divers et variés. Le traitement de conditions que l'on ne connaît pas à l'avance par exemple...issus d'une configuration (XML, CSV ou bien même provenant d'un script évalué comme du Java). Pour effectuer un séquencement d'actions inhérent au process industriel (dont le client veut peut-être cacher le fonctionnement), pour effectuer des tests particuliers...etc...

                                        Cette solution, que je trouve élégante, est codée en 15 minutes top chrono (45 minutes si on ne connaît pas le moteur de script). Ta solution peut fonctionner, mais dans l'état, elle est bancale :

                                        • Comment la rendre générique (Fonctionnelle pour tous les cas possibles et imaginables) ? -> C'est faisable...mais il y a du boulot
                                        • Comment savoir à qui fait référence la variable "a" ? et si elle s'appelle "w" ? -> mince...encore du "mapping"...
                                        • Un nouveau traitement à effectuer -> mince faut compléter et recréer la librairie.
                                        • Je veux utiliser des mnémoniques de variables issus d'un serveur OPC -> mince, j'avais pas prévu le coup
                                        • Je veux maintenant faire du calcul et créer de nouvelles variables "calculées" -> et op...encore du temps de développement
                                        • Le client impose de la couverture de code et des tests unitaires pour tous les traitements -> t'as pas fini de coder mon gars
                                        • Un traitement ne s'effectue pas correctement -> et op...on debug...

                                        Tous ces soucis sont transparents voir inexistants avec un moteur de script.

                                        En théorie (à l'école), c'est bien beau d'apprendre les concepts de fonctionnement de telle ou telle chose. Dans la vraie vie (en milieu pro), on veut des solutions fiables, réutilisables et éprouvées. Le langage JAVA offre des possibilités qui permettent de ne pas recréer la roue à chaque fois...autant en profiter...par contre...en C++ pour une application avec des contraintes temps réel "souple", je préconiserai d'utiliser une librairie spécifique faite à la mano, en un peu plus sophistiquée et polyvalente que de simplement chercher un clef dans une map ( un AST/Abstract Syntax Tree par exemple).

                                        -
                                        Edité par CeBiM 12 novembre 2018 à 20:36:42

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                        Les seules questions bêtes sont celles qui ne sont pas posées. Mieux vaut paraître bête une fois que de le rester à vie."Vis comme si tu devais mourir demain. Apprends comme si tu devais vivre toujours."
                                          13 novembre 2018 à 7:00:10

                                          Le "scripting" de code Java est une solution très utilisée dans le milieu industriel pour différentes raisons

                                          Si tu m'en montres un exemple, je veux bien te croire...

                                          • Partager sur Facebook
                                          • Partager sur Twitter

                                          Bonne journée...

                                            13 novembre 2018 à 8:23:05

                                            Fredo54 a écrit:

                                            Le "scripting" de code Java est une solution très utilisée dans le milieu industriel pour différentes raisons

                                            Si tu m'en montres un exemple, je veux bien te croire...


                                            Ne serait-ce que pour rajouter dynamiquement des fonctionnalités à un logiciel, non connues à l'avance (vu que scripté et chargé à un instant t non connu non plus en avance). J'avais fait ça en L3, bah la compilation à la volée, c'était la vie XD

                                            -
                                            Edité par 3ch0 13 novembre 2018 à 8:23:22

                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              13 novembre 2018 à 8:46:44

                                              3ch0 a écrit:

                                              Fredo54 a écrit:

                                              Le "scripting" de code Java est une solution très utilisée dans le milieu industriel pour différentes raisons

                                              Si tu m'en montres un exemple, je veux bien te croire...


                                              Ne serait-ce que pour rajouter dynamiquement des fonctionnalités à un logiciel, non connues à l'avance (vu que scripté et chargé à un instant t non connu non plus en avance). J'avais fait ça en L3, bah la compilation à la volée, c'était la vie XD

                                              Un genre de plugin ?

                                              • Partager sur Facebook
                                              • Partager sur Twitter

                                              Bonne journée...

                                                13 novembre 2018 à 11:13:59

                                                @Fredo54

                                                Bon..bah...malgré moi...je vais faire un peu de pub : -> http://fr.clemessy.com/activites/systemes-et-expertises/process-temps-reel-et-critique/

                                                La solution Syclone, qui est une boîte à outils logiciels composée de nombreux "modules" logiciels, permet avec un éditeur de synoptique de créer des IHM spécifiques dédiés (aérospatiale, aéronautique, défense, automobile...etc...). Un exemple d'utilisation (parmi d'autres) est le fait de pouvoir affecter une action particulière à un bouton, il est possible de "connecter" l'appui de ce bouton au lancement d'un script Groovy. Avec un peu de configuration du moteur de script, il est possible d'appeler n'importe quelle fonction disponible dans les librairies :

                                                • Envoyer un mail
                                                • Modifier l'état d'une variable sur un serveur OPC
                                                • Ecrire/Lire en base de données
                                                • Effectuer une commande qui passe par un driver particulier (Liaison série, TCP, MODBUS, 1553 et j'en passe...)
                                                • Effectuer une séquence d'actions spécifiques
                                                • Effectuer une gestion d’événements non-critiques. Par exemple, mettre en surveillance certaines variables afin de déclencher une action en fonction de certaines conditions (Comme dans le besoin initial de ce post).
                                                • ..etc...

                                                Le client peut le faire lui-même et adapter seul son IHM ainsi que créer de nouvelle commande à l'aide de ces scripts. Le tout, ne nécessite en aucun cas de toucher au code source de base d'aucun projet. Seul le fichier de description du synoptique est modifié, et un script est rajouté à l'endroit qui va bien. Cela permet une grande flexibilité au système de supervision, et d'améliorer la pérennité de l'application, car elle peut évoluer juste en ajoutant du script. C'est un exemple concret qui est utilisé dans de nombreux projets.

                                                -
                                                Edité par CeBiM 13 novembre 2018 à 12:17:32

                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                Les seules questions bêtes sont celles qui ne sont pas posées. Mieux vaut paraître bête une fois que de le rester à vie."Vis comme si tu devais mourir demain. Apprends comme si tu devais vivre toujours."
                                                  13 novembre 2018 à 12:25:48

                                                  D'accord il peut faire son IHM, mais il est limité par les possibilités du logiciel. Il peut créer des boutons, ... comme le ferait un framework Qt, Tk, ...

                                                  Maintenant imaginons qu'il veut créer un bouton en forme de losange jaune fluo. Où il écrit dans une zone texte "créer bouton forme losange de couleur jaune fluo" ? On est d'accord qu'il est limité par les fonctionnalités du logiciel ?

                                                  • Partager sur Facebook
                                                  • Partager sur Twitter

                                                  Bonne journée...

                                                    13 novembre 2018 à 13:06:09

                                                    Dans mon exemple, l'édition graphique est décorrélée de l'action réalisée par l'élément graphique. Tu peux éditer ton bouton et lui donner le style que tu veux (Une forme originale avec toutes les couleurs de l'arc-en-ciel et même des gradients de couleurs avec le texte, la police et la taille de ton choix), cela sera retranscris dans le fichier de description de l'IHM. L'action est "décrite" dans ce fichier mais en est indépendante (par exemple action=script("toto.groovy")), la description du synoptique n'a pas connaissance de ce que réalise le script (de son implémentation), donc on peut modifier l'action d'appel d'un bouton sans modifier le fichier de description de l'IHM, mais juste le script. Pour une action particulière qui n'est pas codée en "dure" dans le soft, on passe par un script qui réalise ce que l'on veut. Après, c'est sûr qu'on ne fait pas de magie, on ne peut pas appeler une fonction d'un driver dont la librairie n'est pas accessible. Mais comme il est possible de créer de nouvelles classes dans un script, rien n'empêche de charger dynamiquement une librairie (.jar en Java et même .dll/.so codé en C++), et d'en appeler une fonction depuis un script, donc pas de réelle limitation.

                                                    La vraie différence avec Qt et Tk, c'est qu'avec un éditeur de synoptiques, les seules lignes de codes écrites, sont celles du script qui réalise l'action spécifique. "Qt C++" compile les fichiers de description d'interface graphique..donc pas comparable (sauf si on utilise QUiLoader pour les charger dynamiquement, mais c'est un peu chaud pour gérer les "connections" de manière dynamique, sans les coder en "dure" ^^). "Tk" je ne sais pas, mais cela dépend certainement de la plateforme qui l'utilise, si c'est Python, je pense qu'il est possible de modifier une interface graphique, juste en modifiant du code python, ce qui ne nécessite pas de "re-compilation" ou de re-création de l'exécutable, mais on écrit quand même du code pour cela...du coup faut connaitre un peu, alors qu'avec un éditeur...C'est juste de la manipulation de souris et clavier, et de la lecture d'un manuel utilisateur.

                                                    De la même manière, il est possible d'embarquer un moteur de script Python (IronPython en C#, avec boost_python en C++ ou directement avec les headers de Python) dans un software et d'interpréter du texte comme étant du Python avec un éditeur dédié dans ce soft (J'ai aussi des exemples concrets d'utilisation mais je ferai encore de la pub...).

                                                    Ah oui...et Groovy est standardisé :

                                                    JSR-241 -> This specification will standardize the Groovy programming language so that vendors can provide compliant implementations and developers will have a sanctioned scripting language they can use on the JavaTM platform (approved).


                                                    Fredo54 a écrit: > En Java ça n'existe pas, il faut passer par des libs hors standard, voir cette discussion.

                                                    FAUX ! Archi FAUX !

                                                    C'est juste un peu plus compliqué que de juste appeler une méthode "eval" comme en Python : https://docs.oracle.com/javase/7/docs/api/javax/tools/JavaCompiler.html

                                                    -
                                                    Edité par CeBiM 13 novembre 2018 à 16:41:29

                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                    Les seules questions bêtes sont celles qui ne sont pas posées. Mieux vaut paraître bête une fois que de le rester à vie."Vis comme si tu devais mourir demain. Apprends comme si tu devais vivre toujours."
                                                      13 novembre 2018 à 17:57:39

                                                      C'est juste un peu plus compliqué que de juste appeler une méthode "eval" comme en Python

                                                      Et en java vous pouvez utiliser ce genre d'outil, il n'y a pas de problème de sécurité ? C'est même conseillé de l'utiliser, c'est ça ?

                                                      Après, c'est sûr qu'on ne fait pas de magie

                                                      J'ai bien l'impression que c'est ce que veut le PO apparemment quand il dit que les utilisateurs peuvent entrer tout et n'importe quoi sans imposer un cahier des charges... C'est aussi pour cela que je parlais d'IA, peut-être voulait-il un programme évolutif dans le temps ?

                                                      • Partager sur Facebook
                                                      • Partager sur Twitter

                                                      Bonne journée...

                                                        13 novembre 2018 à 19:46:10

                                                        CeBiM a écrit:

                                                        @Fredo54 Je vois de la condescendance, mais pas d'arguments...je dois bigler...

                                                        Le "scripting" de code Java est une solution très utilisée dans le milieu industriel pour différentes raisons, et pour des buts divers et variés. Le traitement de conditions que l'on ne connaît pas à l'avance par exemple...issus d'une configuration (XML, CSV ou bien même provenant d'un script évalué comme du Java). Pour effectuer un séquencement d'actions inhérent au process industriel (dont le client veut peut-être cacher le fonctionnement), pour effectuer des tests particuliers...etc...

                                                        Cette solution, que je trouve élégante, est codée en 15 minutes top chrono (45 minutes si on ne connaît pas le moteur de script). Ta solution peut fonctionner, mais dans l'état, elle est bancale :

                                                        • Comment la rendre générique (Fonctionnelle pour tous les cas possibles et imaginables) ? -> C'est faisable...mais il y a du boulot
                                                        • Comment savoir à qui fait référence la variable "a" ? et si elle s'appelle "w" ? -> mince...encore du "mapping"...
                                                        • Un nouveau traitement à effectuer -> mince faut compléter et recréer la librairie.
                                                        • Je veux utiliser des mnémoniques de variables issus d'un serveur OPC -> mince, j'avais pas prévu le coup
                                                        • Je veux maintenant faire du calcul et créer de nouvelles variables "calculées" -> et op...encore du temps de développement
                                                        • Le client impose de la couverture de code et des tests unitaires pour tous les traitements -> t'as pas fini de coder mon gars
                                                        • Un traitement ne s'effectue pas correctement -> et op...on debug...

                                                        Tous ces soucis sont transparents voir inexistants avec un moteur de script.

                                                        En théorie (à l'école), c'est bien beau d'apprendre les concepts de fonctionnement de telle ou telle chose. Dans la vraie vie (en milieu pro), on veut des solutions fiables, réutilisables et éprouvées. Le langage JAVA offre des possibilités qui permettent de ne pas recréer la roue à chaque fois...autant en profiter...par contre...en C++ pour une application avec des contraintes temps réel "souple", je préconiserai d'utiliser une librairie spécifique faite à la mano, en un peu plus sophistiquée et polyvalente que de simplement chercher un clef dans une map ( un AST/Abstract Syntax Tree par exemple).

                                                        -
                                                        Edité par CeBiM il y a environ 23 heures

                                                        CeBiM merci pour ton commentaire, pourrais tu m'orienter ou me guider (voir me donner la solution) pour le scripting . Tu as dis "Cette solution, que je trouve élégante, est codée en 15 minutes top chrono (45 minutes si on ne connaît pas le moteur de script). Ta solution peut fonctionner, mais dans l'état, elle est bancale ", donc je suppose qu'il y a une solution très simple et que je suis passé à coté, pourrais tu me l'indiquer s'il te plait.

                                                        Fredo54 a écrit:

                                                        C'est juste un peu plus compliqué que de juste appeler une méthode "eval" comme en Python

                                                        Et en java vous pouvez utiliser ce genre d'outil, il n'y a pas de problème de sécurité ? C'est même conseillé de l'utiliser, c'est ça ?

                                                        Après, c'est sûr qu'on ne fait pas de magie

                                                        J'ai bien l'impression que c'est ce que veut le PO apparemment quand il dit que les utilisateurs peuvent entrer tout et n'importe quoi sans imposer un cahier des charges... C'est aussi pour cela que je parlais d'IA, peut-être voulait-il un programme évolutif dans le temps ?


                                                        Fredo54 je n'ai pas dis que "que les utilisateurs peuvent entrer tout et n'importe quoi sans imposer un cahier des charges",  les règles sont présentes mais elle sont appliqué lors de la création des script et pas de leur utilisation



                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                          14 novembre 2018 à 8:47:43

                                                          @necbfrt La solution simple, c'est Groovy. (http://www.groovy-lang.org/)

                                                          Tu mets en place le moteur de script (Mon code date un peu donc faut voir avec les nouvelles versions ce qui change. Il y a aussi certainement des choses à améliorer.) :

                                                          • Dire au moteur quelles sont les classes auxquelles il a accès. Encore mieux, rendre les "import" dont tu as besoin paramétrable. -> c'est la classe org.codehaus.groovy.control.customizers.ImportCustomizer
                                                          • Si tu veux passer des variables de manières "générique", tu peux envoyer une liste d'objet (Object). -> utilisation de la classe groovy.lang.Binding
                                                          • Utiliser la classe Groovyshell qui s'occupe de "parser" le script, de mettre en place les "binding" de paramètres (décrit plus haut).
                                                          • Création de l'objet qui représente ton script ---> groovy.lang.Script
                                                          • Lancement du script --> script .run();

                                                          Ça répond parfaitement à ton besoin, et permet de couvrir pleins de besoins futurs. Voilà un exemple qui date de quelques année, il te manquera certaines classes (CeBScript par exemple, qui ne sert qu'à retenir certains attributs (un objet "File" qui représente le script.groovy, tu peux t'en passer et utiliser des "String" sans soucis. Voir http://docs.groovy-lang.org/latest/html/api/groovy/lang/GroovyShell.html)). Ça vaut ce que ça vaut :

                                                          import java.io.File;
                                                          import java.io.IOException;
                                                          import java.util.HashMap;
                                                          import java.util.Map;
                                                          import java.util.concurrent.ExecutorService;
                                                          import java.util.concurrent.Executors;
                                                          
                                                          import org.apache.log4j.LogManager;
                                                          import org.apache.log4j.Logger;
                                                          import org.codehaus.groovy.control.CompilationFailedException;
                                                          import org.codehaus.groovy.control.CompilerConfiguration;
                                                          import org.codehaus.groovy.control.customizers.ImportCustomizer;
                                                          
                                                          import ceb.utils.file.FileUtils;
                                                          import groovy.lang.Binding;
                                                          import groovy.lang.GroovyShell;
                                                          import groovy.lang.Script;
                                                          
                                                          /**
                                                           * @author CeBiM
                                                           */
                                                          public abstract class GroovyFactory {
                                                          
                                                              private static Logger logger = LogManager.getLogger(GroovyFactory.class);
                                                          
                                                              private static Map<CeBScript, ExecutorService> scriptExecutors = new HashMap<CeBScript, ExecutorService>();
                                                          
                                                              /**
                                                               * @param fileName
                                                               *            Chemin et nom du script
                                                               * @param listParam
                                                               *            liste des paramètres envoyés au scipt
                                                               * @return Le script
                                                               */
                                                              public static CeBScript createScript(String fileName, final Object[] listParam) {
                                                                  CeBScript script = null;
                                                                  fileName = (fileName.contains(".groovy")) ? fileName : (fileName += ".groovy");
                                                          
                                                                  File scriptFile = new File(fileName);
                                                                  try {
                                                                      scriptFile.createNewFile();
                                                                  } catch (final IOException ge) {
                                                                      logger.error(ge.getMessage(), ge);
                                                                  }
                                                                  script = new CeBScript();
                                                                  script.setFile(scriptFile);
                                                                  script.setName(scriptFile.getName());
                                                                  final Binding binding = new Binding();
                                                                  if (listParam != null) {
                                                                      binding.setVariable("args", listParam);
                                                                  }
                                                                  script.setBinding(binding);
                                                                  return script;
                                                              }
                                                          
                                                              private static Script prepareScript(CeBScript script) throws CompilationFailedException, IOException {
                                                                  final GroovyShell shell = createGroovyShell();
                                                                  Script s = shell.parse(script.getFile());
                                                                  s.setBinding(script.getBinding());
                                                                  return s;
                                                              }
                                                          
                                                              /**
                                                               * @param script
                                                               * @return Execution du script en paramètre
                                                               */
                                                              public static CeBScript newScript(String fileName) {
                                                                  fileName = (fileName.contains(".groovy")) ? fileName : (fileName += ".groovy");
                                                                  File newScript = new File(fileName);
                                                                  String tmp = "println \"New script !\"";
                                                                  FileUtils.writeFile(newScript, tmp);
                                                                  return createScript(fileName, null);
                                                              }
                                                          
                                                              public static CeBScript saveScript(String fileName, String toWrite) {
                                                                  fileName = (fileName.contains(".groovy")) ? fileName : (fileName += ".groovy");
                                                                  File newScript = new File(fileName);
                                                                  FileUtils.writeFile(newScript, toWrite.trim());
                                                                  return createScript(fileName, null);
                                                              }
                                                          
                                                              public static Object runScriptAndGetReturn(CeBScript script, Object... args)
                                                                      throws IOException, CompilationFailedException {
                                                                  return prepareScript(script).run();
                                                              }
                                                             
                                                              public static void launchScript(String scriptPath, Object... args) {
                                                                  CeBScript script = createScript(scriptPath, args);
                                                                  GroovyFactory.runScript(script);
                                                              }
                                                          
                                                              public static void runScript(CeBScript script, Object... args) {
                                                                  script.running().set(true);
                                                                  try {
                                                                      prepareScript(script).run();
                                                                  } catch (Exception e) {
                                                                      Thread.currentThread().getUncaughtExceptionHandler().uncaughtException(Thread.currentThread(), e);
                                                                      logger.error(e.getMessage(), e);
                                                                  } finally {
                                                                      script.running().set(false);
                                                                  }
                                                              }
                                                          
                                                              public static void runScriptAsync(CeBScript script, Object... args) {
                                                                  ExecutorService exe = Executors.newSingleThreadExecutor(r -> {
                                                                      Thread t = new Thread(r);
                                                                      t.setName(script.getName());
                                                                      t.setUncaughtExceptionHandler(new GroovyUncaughtExceptionHandler());
                                                                      return t;
                                                                  });
                                                                  scriptExecutors.put(script, exe);
                                                                  exe.submit(() -> {
                                                                      runScript(script);
                                                                      scriptExecutors.remove(script);
                                                                  });
                                                              }
                                                          
                                                              public static boolean stopScript(CeBScript script) {
                                                                  if (scriptExecutors.containsKey(script)) {
                                                                      scriptExecutors.get(script).shutdownNow();
                                                                      scriptExecutors.remove(script);
                                                                      script.running().set(false);
                                                                      return true;
                                                                  } else {
                                                                      return false;
                                                                  }
                                                              }
                                                          
                                                              public static GroovyShell createGroovyShell() {
                                                                  final ImportCustomizer customizer = new ImportCustomizer();
                                                                  customizer.addImport("JOptionPane", "javax.swing.JOptionPane");
                                                                  customizer.addImport("CeBFxDialog", "ceb.fx.dialog.view.CeBFxDialog");
                                                                  customizer.addImport("Platform", "javafx.application.Platform");
                                                          
                                                                  CompilerConfiguration conf = new CompilerConfiguration();
                                                                  conf.addCompilationCustomizers(customizer);
                                                          
                                                                  final GroovyShell shell = new GroovyShell(conf);
                                                          
                                                                  return shell;
                                                              }
                                                          }

                                                          Fredo54 a écrit: > Et en java vous pouvez utiliser ce genre d'outil, il n'y a pas de problème de sécurité ? C'est même conseillé de l'utiliser, c'est ça ?

                                                          Non. La sécurité de Java est ce qu'elle est. Rien n'empêche de manipuler le bytecode à la volée...

                                                          Après, il n'est jamais dit que c'est "conseillé" de l'utiliser. On dit que ça peut être utile pour certains cas. Tout dépend du besoin et du contexte.

                                                          Fredo54 a écrit: > J'ai bien l'impression que c'est ce que veut le PO apparemment quand il dit que les utilisateurs peuvent entrer tout et n'importe quoi sans imposer un cahier des charges... C'est aussi pour cela que je parlais d'IA, peut-être voulait-il un programme évolutif dans le temps ?

                                                          Non plus. Le moteur de script sera configuré pour n'accéder qu'aux librairies dont il a besoin. Cette configuration peut évoluer, mais c'est une configuration "statique" de manière générale (même si on peut automatiser pour accéder à tout, je conseille plutôt une configuration en fichier). On ne parle pas de programme "automorphe" (pas au sens mathématique, au sens qu'il se modifie seul), ni de réseaux de neurones (Hmmmm la bonne masturbation intellectuelle ^^).

                                                          On parle d'un logiciel qui peut exécuter du code...code qui est décrit sous forme de chaine de caractère...un peu de la même manière que ton IDE le fait. Eclipse est principalement codé en Java par exemple, et il permet d'exécuter, entre autre, du Java (Peut aussi gérer C/C++, PHP, JavaScript, COBOL et peut-être d'autres) ^^ Il fonctionne avec un système de "plugin" et est donc "évolutif"/"paramétrable"..mais on ne parle pas d'IA pour cela. Sauf que là...je ne pense pas qu'il veut coder un IDE...mais juste un soft qui peut exécuter du script, donc pas besoin de passer par les outils de "compilation".

                                                          -
                                                          Edité par CeBiM 14 novembre 2018 à 11:07:28

                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                          Les seules questions bêtes sont celles qui ne sont pas posées. Mieux vaut paraître bête une fois que de le rester à vie."Vis comme si tu devais mourir demain. Apprends comme si tu devais vivre toujours."
                                                            14 novembre 2018 à 13:49:30

                                                            La plus part des systèmes de plugin fonctionne avec des du code déjà compiler, ce qui est beaucoup plus simple à effectuer en utilisant la réflexivité de Java
                                                            • Partager sur Facebook
                                                            • Partager sur Twitter
                                                              14 novembre 2018 à 14:09:59

                                                              Oui tout à fait !

                                                              • Partager sur Facebook
                                                              • Partager sur Twitter
                                                              Les seules questions bêtes sont celles qui ne sont pas posées. Mieux vaut paraître bête une fois que de le rester à vie."Vis comme si tu devais mourir demain. Apprends comme si tu devais vivre toujours."

                                                              Condition if avec un string comme condition

                                                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                              • Editeur
                                                              • Markdown