IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Threading récupérer la valeur de sortie de inqueue.put


Sujet :

Python

  1. #1
    Membre averti
    Homme Profil pro
    Dmaths
    Inscrit en
    Février 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Dmaths
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2006
    Messages : 19
    Par défaut Threading récupérer la valeur de sortie de inqueue.put
    Bonjour à tous,

    J'essaie de créer un système interactif ou dit autrement d'émuler une console Python.
    Je me suis inspiré de la console de l'extension LibreOffice APSO. Je pourrai donner plus de précision si nécessaire.

    Comme l'illustre l'image, le code fonctionne.
    Je calcule 2+3, j'affecte à a la valeur 10, elle est conservée, puis je calcule 2*a.
    Cependant la fonction com retourne 'None' alors que je voudrais qu'elle renvoie les résultats affichés 5 dans le premier cas ou 20 dans le second.
    Nom : Capture.png
Affichages : 303
Taille : 19,9 Ko
    Que dois-je changer pour obtenir le résultat attendu c'est à dire que la fonction com renvoie '5' ou '20' ?
    Le module utilisé : essai.py

    Merci d'avance pour vos réponses.

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 699
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 699
    Par défaut
    Citation Envoyé par ddorange Voir le message
    Que dois-je changer pour obtenir le résultat attendu c'est à dire que la fonction com renvoie '5' ou '20' ?
    5 ou 20, c'est éventuellement ce qui sera affiché sur stdout par l'InteractiveConsole... que vous n'essayez même pas de lire.

    Reste l'intention de base: "J'essaie de créer un système interactif ou dit autrement d'émuler une console Python"... et le travail de conception à faire pour détailler ce que ça veut dire et le code à mettre en face.

    Car pour l'instant vous testez (mal) une piste sans trop savoir où ça va vous mener...

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre averti
    Homme Profil pro
    Dmaths
    Inscrit en
    Février 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Dmaths
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2006
    Messages : 19
    Par défaut
    Bonsoir,
    Certes je teste une piste mais je sais très bien ce que je veux : que la fonction com retourne le résultat du calcul '2+3' pour le premier ou 2*a soit 20 pour le second.
    Et si je n'utilise pas stdout de l'InteractiveConsole c'est que je ne sais pas faire.
    Plus généralement, quand on pose une question c'est qu'on a pas la réponse ?

    Didier DP.

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    1 520
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 1 520
    Par défaut
    queue.put ne renvoie rien, donc le a vaudra None quoique tu fasses avec.
    perso, si je lance ton script, je ne peux rien faire
    Si je rajoute com('5') à la fin, je ne vois que le résultat 5, si je fais un print(com('5')), j'ai le 5 et None

  5. #5
    Membre averti
    Homme Profil pro
    Dmaths
    Inscrit en
    Février 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Dmaths
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2006
    Messages : 19
    Par défaut
    Citation Envoyé par umfred Voir le message
    queue.put ne renvoie rien, donc le a vaudra None quoique tu fasses avec.
    Le inqueue.put ne renvoie rien, mais il affiche le résultat dans la console. Il devrait bien y avoir un moyen d'intercepter ce résultat.

    Ce qui suit suppose que Libreoffice soit installé. L'extension Apso émule une console Python.
    Pour vérifier lancer Outils -> Macros -> Gérer les Scripts Python, puis Mes macros -> APSO -> Tools -> Console -> Lancer.
    On tape 2+3 le retour est 5
    Le fichier apso_utils.py contient le code : Roaming -> LibreOffice -> 4 -> user -> uno_packages -> cache -> uno_packages -> ... -> apso.oxt -> python -> pythonpath
    A la ligne 590 de la classe ConsoleWindow on trouve self.inqueue.put(line) qui permet de faire afficher le résultat de 2+3 soit 5 dans la boîte de dialogue.

    C'est donc faisable d'utiliser inqueue.put pour obtenir un résultat.

    apso.oxt.zip

    Voili, voilà ...

    Merci pour votre aide.

  6. #6
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 198
    Par défaut
    Hello,
    j'ai fait une tentative en utilisant une Queue de sortie pour récupérer la valeur à l'intérieur du thread en capturant dans celui-ci le stdout . Voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    import threading
    import code
    import sys
    import traceback
    import contextlib
    from io import StringIO
    import copy
     
     
    EOT = b'\x04'
    #from sympy import sympify
    try:
        import queue
        #import builtins
    except ImportError:
        import Queue as queue
        #import __builtin__ as builtins
     
    @contextlib.contextmanager
    def capture():
        oldout,olderr = sys.stdout, sys.stderr
        try:
            out=[StringIO(), StringIO()]
            sys.stdout,sys.stderr = out
            yield out
        finally:
            sys.stdout,sys.stderr = oldout, olderr
            out[0] = out[0].getvalue()
            out[1] = out[1].getvalue()
     
     
    class InteractiveConsole(code.InteractiveConsole):
        def __init__(self, inqueue, exitevent,outqueue):
            code.InteractiveConsole.__init__(self)
            self.inqueue = inqueue
            self.outqueue = outqueue
            #self.exitevent = exitevent
            self.keep_prompting = True
            self.stdin = sys.stdin
            sys.stdin = self
     
     
        def readline(self):
            '''Implement sys.stdin readline method'''
            rl = self.inqueue.get()
            if rl == KeyboardInterrupt:
                print("KbInterrupt")
                raise KeyboardInterrupt()
            if rl == EOT:
                print("EOT")
                self.keep_prompting = False
            return rl
     
     
        def interact(self):
            more = 0
            try:
                while self.keep_prompting:
                    try:
                        #self.outqueue.queue.clear()
                        line = self.raw_input('')
                        with capture() as out:
                            more = self.push(line)
                        self.inqueue.task_done()
                        self.outqueue.put(out[0])
                    except KeyboardInterrupt:
                        self.write("\nKeyboardInterrupt\n")
                        self.resetbuffer()
                        more = 0
                    except SystemExit:
                        self.exitevent.set()
                    except:
                        print('INTERACT\n')
                        traceback.print_exc()
                        self.resetbuffer()
                        more = 0
            finally:
                sys.stdin = self.stdin
                #sys.stdout = self.stdout
     
     
     
     
    def run_interact(*args):
        '''Start the"python interpreter" engine'''
        iconsole = InteractiveConsole(*args)
        iconsole.interact()
     
     
    #EOT = b'\x04'
     
     
    inqueue = queue.Queue()
    outqueue = queue.Queue()
    exitevent = threading.Event()
    result=""
    proc = threading.Thread(target=run_interact, args=(inqueue, exitevent,outqueue))
    proc.start()
     
     
    #prompt = '...'
    def com(x):
        try:
            inqueue.put(x)
            #inqueue.join()
        except:
            inqueue.put(traceback.format_exc())    
        return "com : " + outqueue.get(True,3)
     
     
     
    def ecrit(x):
        return format(x)
    voici ce que j'obtiens dans Thonny (dans Pycharm cela ne marche pas certainement à cause de la gestion des stdin stdout) :

    Nom : ThonnyConsole.png
Affichages : 264
Taille : 3,4 Ko
    déjà une question : n'y-a-t-il pas plus simple pour récupérer le résultat ?
    Cela ne fonctionne pas dans LibreOffice en appelant la macro comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Sub testConsole()
    Dim masterSPF As Object, scriptP As Object, monScript As Object
    Dim data
    data = Array("2+2")
    masterSPF = createUnoService("com.sun.star.script.provider.MasterScriptProviderFactory")
    scriptP = masterSPF.createScriptProvider("")
    monScript = scriptP.getScript("vnd.sun.star.script:ModulesPython|ModConsole.py$com?language=Python&location=user")
    resultat = monScript.invoke(data, Array(), Array())
    Print resultat
    ce qui se passe : il y a un timeout sur le outqueue.get(True,3) me disant que la Queue est vide. peut-être un mauvais passage de paramètre dans les args de threading.Thread ?

    Pour ceux qui vont dire pour la fonction com il suffit de mettre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     def com(x):
           return eval(x)
    mais cela doit fonctionner avec aussi des affectations, des instructions et des enchaînements de commandes.

    [EDIT] j'ai trouvé un article concernant l'utilisation des queues avec les threads ici : Thread Pipeline in Python

    Ami calmant, J.P

  7. #7
    Membre averti
    Homme Profil pro
    Dmaths
    Inscrit en
    Février 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Dmaths
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2006
    Messages : 19
    Par défaut
    Bonjour JP,

    Cela fonctionne super.

    J'ai modifié la fonction com :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    def com(x):
        try:
            inqueue.put(x)
        except:
            inqueue.put(traceback.format_exc())
        res = outqueue.get(True,3)
        pos = res.find('\n')
        if pos>=0:
            return res[0:pos]
        else:
            return res
    J'ai configuré une extension dans LO pour tester.
    Cela fonctionne également avec la bibliothèque sympy (coller sympy et mpmath dans pythonpath).
    J'ai saisi data = Array('from sympy import *)
    puis data = Array('divisors(42)'), la fonction print retourne bien les diviseurs de 42.

    Des perspectives pour effectuer du calcul formel dans LO/AOo.

    Seul bemol, les fautes de syntaxe n'ont pas de retour. Exemple com('2+').

    En pièce attachée, une extension pour tester. J'ai retiré les bibliothèques sympy et mpmath pour raison de place.


    DDP.oxt.zip

  8. #8
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 198
    Par défaut
    tu n'as pas de blocage en appelant la fonction à partir du basic ?
    La différence avec toi c'est que mon code python est dans une macro user.

  9. #9
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 198
    Par défaut
    Citation Envoyé par ddorange Voir le message
    Seul bemol, les fautes de syntaxe n'ont pas de retour. Exemple com('2+').
    Il faut utiliser le out[1] qui correspond à la sortie d'erreur (stderr)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
                       self.outqueue.put(out[0])
                       self.outqueue.put(out[1])
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
            res = outqueue.get(True,3).strip("\n")
            err = outqueue.get(True,3).strip("\n")
        except:
            inqueue.put(traceback.format_exc())
        return "res : "  + res + " - error : " + err
    résultat avec Thonny :
    >>> %Run essai.py
    >>> com("2+")
    'res : - error : File "<console>", line 1\n 2+\n ^\nSyntaxError: invalid syntax'
    >>>
    Avec LibreOffice même avec ton extension cela bloque chez moi avec comme message d'erreur Queue Empty après le timeOut. J'ai aussi un plantage instantané en utilisant la macro essai de l'extension :
    Nom : errEssaiDDP.png
Affichages : 254
Taille : 7,2 Ko
    J'utilise une macro à moi pour appeler la fonction python com à partir du basic.
    Tu es sous quel O.S et quelle version de L.O ?

  10. #10
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 816
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 816
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par ddorange Voir le message
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    res = outqueue.get(True,3)
    pos = res.find('\n')
        if pos>=0:
            return res[0:pos]
        else:
            return res
    return outqueue.get(True,3).replace("\n", "") ou mieux, return outqueue.get(True,3).strip().
    Accessoirement c'est plus propre de spécifier explicitement l'exception attendue plutôt que de ratisser large du style "bof je vais pas me fouler sur rechercher la cause du souci"...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  11. #11
    Membre averti
    Homme Profil pro
    Dmaths
    Inscrit en
    Février 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Dmaths
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2006
    Messages : 19
    Par défaut
    Bonsoir,

    J'ai fait quelques tests.
    LibreOffice cela fonctionne sous Ubuntu 20.04, MacOS, mais bloque avec Windows7.
    OpenOffice bloque sous Ubuntu 20.04 et Windows7.
    Pourtant type(res) indique bien qu'il s'agit d'une chaîne.

    Je n'aurai pas le temps de tester la gestion des erreurs avant demain matin.

  12. #12
    Membre averti
    Homme Profil pro
    Dmaths
    Inscrit en
    Février 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Dmaths
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2006
    Messages : 19
    Par défaut
    Hello,

    Bon ne fonctionne pas si bien ....

    Dans Thonny, si je saisis successivement com('2+3'), com('4+5'), com('6+9') etc j'ai des réponses qui reprennent les résultats précédents ....

  13. #13
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 816
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 816
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par ddorange Voir le message
    Dans Thonny, si je saisis successivement com('2+3'), com('4+5'), com('6+9') etc j'ai des réponses qui reprennent les résultats précédents ....
    Probablement une fonction de nettoyage à appeler au préalable (ou en fin de travail)...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  14. #14
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 198
    Par défaut
    Hello,
    Bon j'ai trouvé pourquoi cela coinçait quand on appelait la fonction com à partir du basic de LibreOffice , et je me demande comment cela a pu fonctionner chez ddorange :
    On ne passe jamais dans le readline ! Normal on est pas à "l'intérieur" de la console interactive et donc il n'y a pas de saisie comment on peut le faire par exemple dans Thonny. En fait, il faut mettre le get de la Queue d'entrée dans la boucle while self.keep_prompting à la place du raw_input : le get bloque jusqu'à ce qu'il y ait un put d'effectuer.
    voici le nouveau code que j'ai mis dans mon script interConsole.py :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    # coding: utf-8
    from __future__ import unicode_literals
    import threading
    import code
    import sys
    import time
    import traceback
    import contextlib
    try:
        from cStringIO import StringIO # Python 2
    except ImportError:
        from io import StringIO # Python 3
    try:
        import queue # Python 3
    except ImportError:
        import Queue as queue # Python 2
     
     
    EOT = b'\x04'
     
    class InteractiveConsole(code.InteractiveConsole):
        def __init__(self, inqueue,outqueue,exitevent):
            code.InteractiveConsole.__init__(self)
            self.inqueue = inqueue
            self.outqueue = outqueue
            #self.exitevent = exitevent
            self.keep_prompting = True
     
        def interact(self):
            more = 0
            try:
                while self.keep_prompting:
                    try:
                        #self.outqueue.queue.clear()
                        line = self.inqueue.get()
                        with capture() as out:
                            more = self.push(line)
                        self.inqueue.task_done()
                        self.outqueue.put(out[0])
                        self.outqueue.put(out[1])
                    except KeyboardInterrupt:
                        self.write("\nKeyboardInterrupt\n")
                        self.resetbuffer()
                        more = 0
                    except SystemExit:
                        self.exitevent.set()
                    except:
                        print('INTERACT\n')
                        traceback.print_exc()
                        self.resetbuffer()
                        more = 0
            finally:
                pass
     
     
    @contextlib.contextmanager
    def capture():
        oldout,olderr = sys.stdout, sys.stderr
        try:
            out=[StringIO(), StringIO()]
            sys.stdout,sys.stderr = out
            yield out
        finally:
            sys.stdout,sys.stderr = oldout, olderr
            out[0] = out[0].getvalue()
            out[1] = out[1].getvalue()
     
    def run_interact(*args):
        '''Start the"python interpreter" engine'''
        iconsole = InteractiveConsole(*args)
        iconsole.interact()
     
    #prompt = '...'
    def com(x):
        try:
            inqueue.put(x)
            inqueue.join()
        except:
            inqueue.put(traceback.format_exc())
        res =  outqueue.get(True,2).strip("\n")
        err =  outqueue.get(True,2).strip("\n")
        return (res,err)
     
    def ecrit(x):
        return format(x)
     
    #init
    inqueue = queue.Queue()
    outqueue = queue.Queue()
    exitevent = threading.Event()
    proc = threading.Thread(target=run_interact, args=(inqueue,outqueue,exitevent))
    proc.start()
    Attention ce code ne fonctionne plus avec Thonny car j'ai enlevé la fonction readline et le raw_input n'existe plus.
    Maintenant la fonction com renvoie un tuple du résultat et de l'erreur. Dans le Basic de LibreOffice ce tuple est vu comme un tableau de variants.
    Voici 2 codes de test similaires dans LibreOffice Basic, un utilisant la nouvelle bibliothèque ScriptForge (à partir de L.O 7.2) :
    Code Basic : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    Sub testInterConsole()
    Dim masterSPF As Object, scriptP As Object, monScript As Object
    Dim Operations,  Resultat(10)
    Dim i as Integer, message As string
    Operations = Array("a=10","b=15","c=a+b","c","a*b","2+")
    masterSPF = createUnoService("com.sun.star.script.provider.MasterScriptProviderFactory")
    scriptP = masterSPF.createScriptProvider("")
    monScript = scriptP.getScript("vnd.sun.star.script:interConsole.py$com?language=Python&location=user")
    message=""
    For i = Lbound(Operations) to Ubound(Operations)
    resultat(i) =   monScript.invoke(Array(Operations(i)), Array(), Array())
    message = message + Operations(i) + " --> " + resultat(i)(0) + "   " + resultat(i)(1) + chr(13) + chr(10)
    Next i
    msgbox message
    end Sub
     
    sub testInterConsoleSF()
    Dim session As Variant
    Dim Operations, Resultat(10)
    Dim i as Integer, message as String
    Operations = Array("a=10","b=15","c=a+b","c","a*b","2+")
    With GlobalScope.BasicLibraries
            If Not .IsLibraryLoaded("ScriptForge") Then .LoadLibrary("ScriptForge")
    End With
    session = CreateScriptService("Session")
    message=""
    For i = Lbound(Operations) to Ubound(Operations)
    resultat(i) =  session.ExecutePythonScript(session.SCRIPTISPERSONAL, "interConsole.py$com", Operations(i)) 
    message = message + Operations(i) + " --> " + resultat(i)(0) + "   " + resultat(i)(1) + chr(13) + chr(10)
    Next i
    msgbox message
    end sub
    Le premier code fonctionne chez moi avec OpenOffice 4.1.13 et LibreOffice 7.3.4 sous Windows 11 et avec LibreOffice 7.3.4 sous Ubuntu 20.04. A Noter que j'ai du faire des imports conditionnels dans le code python pour être compatible entre le python 2 d'OpenOffice et le python 3 de LibreOffice.

    Résultat sous Windows :
    Nom : IntConsLOwindows.png
Affichages : 245
Taille : 6,2 Ko


    Résultat sous Ubuntu :
    Nom : IntConsUbuntu.png
Affichages : 246
Taille : 56,2 Ko

    Comme on peut le voir le message d'erreur est plus conséquent sous Ubuntu.

    Voici l'équivalent en python du programme Basic de test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    import interConsole
     
    instructions = ["a=10","b=15","c=a+b","c","a*b","2+"]
    for inst in instructions:
        print(interConsole.com(inst))

    Finalement le sujet était intéressant car il a permis de voir comment transmettre des données entre threads en utilisant des Queue et comment capturer le stdout et stderr dans des chaînes.

    Ami calmant, J.P

  15. #15
    Membre averti
    Homme Profil pro
    Dmaths
    Inscrit en
    Février 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Dmaths
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2006
    Messages : 19
    Par défaut
    Bonjour à tous,

    Un grand coup de chapeau à JP.

    Du coup, j'ai mis à jour mon extension, en ajoutant la bibliothèque sympy 1.5. C'est la plus récente compatible avec le python de OpenOffice.

    J'ai tester avec LO et OOo sur Ubuntu 20.04 et Windows 7. Les erreurs sont bien gérées.

    Pour tester lancer la macro DDP -> Module1 -> Main

    Vous pouvez essayer x+2*x, puis divisors(42), puis expand((x+5)**2) etc.

    Reste une petite inquiétude, il me semble qu'après une erreur dans certain cas c'est le résultat du calcul n-1 qui s'affiche.

    Encore un grand merci à JP pour son expertise.
    Comme tu es le principal contributeur de ce fil, je te laisse le soin de mettre à jour le fil sur le forum LibreOffice-OpenOffice ou alors tu préfères que je le fasse ?

    L'extension pèse environ 10Mo. J'ai trouvé une solution de mise à disposition, il y a sûrement mieux.
    http://berthomaths.free.fr/InteractiveConsole.oxt

Discussions similaires

  1. Réponses: 4
    Dernier message: 01/10/2017, 13h16
  2. Réponses: 4
    Dernier message: 19/08/2014, 10h25
  3. [thread] Récupérer la valeur d'un JTextField
    Par _xme_ dans le forum Débuter
    Réponses: 0
    Dernier message: 27/09/2010, 10h08
  4. [VB.net][OleDB]récupérer la valeur d'un parametre de sortie
    Par glanumf dans le forum Accès aux données
    Réponses: 4
    Dernier message: 17/10/2006, 17h09
  5. récupérer la valeur de sortie d'un thread
    Par jakouz dans le forum Langage
    Réponses: 3
    Dernier message: 31/07/2002, 11h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo