Exerciseur niveau lycée réalisé avec GeoGebra

Tout ce qui concerne les différents logiciels mathématiques (Matlab, Maxima, Scilab, R, Maple, Mathematica, ...) et les calculatrices scientifiques.
Règles du forum
Merci d'éviter le style SMS dans vos messages et de penser à utiliser la fonction Recherche avant de poster un message. Pour joindre des fichiers à vos messages, consulter ce sujet.
> Penser à utiliser les balises Code pour poster du code.
> Préciser le nom du logiciel concerné dans le titre de votre message.

Exerciseur niveau lycée réalisé avec GeoGebra

Messagepar joelGa » Vendredi 19 Novembre 2010, 12:52

Bonjour
J'ai réalisé une série d'exercices interactifs en ligne à l'aide d'Applets GeoGebra.
Exercices de mathématiques au lycée Valin

http://maths.valin-sciences.fr/maths/exercices_en_ligne/index.html

Ces exercices peuvent certainement être utiles aux lycéens.
Bonne visite!
Joël
joelGa
Utilisateur
 
Messages: 7
Inscription: Vendredi 19 Novembre 2010, 12:43
Statut actuel: Actif et salarié | Enseignant

Publicité

Re: Exerciseur niveau lycée ralisé avec GeoGebra

Messagepar Arnaud » Vendredi 19 Novembre 2010, 16:47

Merci pour ce partage de documents ;) ( je connaissais déjà la page )
Arnaud

Un peu d'info - Pyromaths
LaTeX - Exemples de formules LaTeX

Pas d'aide en MP (non plus)
Arnaud
Modérateur
 
Messages: 7115
Inscription: Lundi 28 Août 2006, 12:18
Localisation: Allemagne
Statut actuel: Actif et salarié | Enseignant

Re: Exerciseur niveau lycée ralisé avec GeoGebra

Messagepar projetmbc » Vendredi 19 Novembre 2010, 17:32

Au premier coup d'oeil, les exercices proposés semblent très bien vus et aussi très bien conçus.

Il reste à tester la gestion des réponses, ce que je ferais dès que je pourrais.

Question technique : comment sont faits les exos ? Te sers-tu de programmes pour t'aider ou fais-tu tout "à la main" ?
projetmbc
Péta-utilisateur
 
Messages: 1895
Inscription: Samedi 29 Décembre 2007, 00:58
Statut actuel: Actif et salarié | Enseignant

Re: Exerciseur niveau lycée ralisé avec GeoGebra

Messagepar joelGa » Vendredi 19 Novembre 2010, 18:53

Question technique : comment sont faits les exos ? Te sers-tu de programmes pour t'aider ou fais-tu tout "à la main" ?

Non je programme tout (HTML et Javascript) à la main sur le bloc-note de Window.

Merci pour les compliments

Joël
joelGa
Utilisateur
 
Messages: 7
Inscription: Vendredi 19 Novembre 2010, 12:43
Statut actuel: Actif et salarié | Enseignant

Re: Exerciseur niveau lycée ralisé avec GeoGebra

Messagepar projetmbc » Samedi 20 Novembre 2010, 11:49

Sacrée motivation.

Je vais me faire d'ici la rentrée scolaire prochaine, enfin je l'espère, des outils Python pour fabriquer "facilement" ce type d'exercices. L'idée étant de taper une sorte de script dans un fichier de type TXT, et ensuite de faire faire au programme Python la traduction GeoGebra, CarMetal, ..., HTML, JS. J'utiliserais aussi sûrement un peu de PhP pour autoriser l'utilisateur à taper des formules comme avec une calculatrice (même si une solution tout en JS me conviendrait plus).

Pour l'affichage des formules, je passerais par MathJax, pour l'interface graphique par jQuery, et côté applets, il y aura GeoGebra, CarMetal et peut-être aussi JavaView et/ou JMath 3D.

Il me reste un problème de taille : avoir un outil de calcul formel en ligne... Peut-être que GeoGebraCAS permettra cela.
projetmbc
Péta-utilisateur
 
Messages: 1895
Inscription: Samedi 29 Décembre 2007, 00:58
Statut actuel: Actif et salarié | Enseignant

Re: Exerciseur niveau lycée réalisé avec GeoGebra

Messagepar Arnaud » Samedi 20 Novembre 2010, 12:19

@projetmbc : je suppose que tu n'as pas de serveur dédié, non ?
Arnaud

Un peu d'info - Pyromaths
LaTeX - Exemples de formules LaTeX

Pas d'aide en MP (non plus)
Arnaud
Modérateur
 
Messages: 7115
Inscription: Lundi 28 Août 2006, 12:18
Localisation: Allemagne
Statut actuel: Actif et salarié | Enseignant

Re: Exerciseur niveau lycée ralisé avec GeoGebra

Messagepar kojak » Samedi 20 Novembre 2010, 16:43

projetmbc a écrit:Il me reste un problème de taille : avoir un outil de calcul formel en ligne...
Xcas en ligne existe.
pas d'aide par MP
kojak
Modérateur
 
Messages: 10397
Inscription: Samedi 18 Novembre 2006, 19:50
Statut actuel: Actif et salarié | Enseignant

Re: Exerciseur niveau lycée réalisé avec GeoGebra

Messagepar projetmbc » Samedi 20 Novembre 2010, 18:38

Merci.

Du PhP semble être utilisé. Donc cela me semble accessible. Par contre, est-ce "appelable" depuis un site perso. ? "J'va" aller "d'mander" cela sur le forum de giac.
projetmbc
Péta-utilisateur
 
Messages: 1895
Inscription: Samedi 29 Décembre 2007, 00:58
Statut actuel: Actif et salarié | Enseignant

Re: Exerciseur niveau lycée ralisé avec GeoGebra

Messagepar joelGa » Mardi 23 Novembre 2010, 16:22

projetmbc a écrit:Sacrée motivation.

Je vais me faire d'ici la rentrée scolaire prochaine, enfin je l'espère, des outils Python pour fabriquer "facilement" ce type d'exercices. L'idée étant de taper une sorte de script dans un fichier de type TXT, et ensuite de faire faire au programme Python la traduction GeoGebra, CarMetal, ..., HTML, JS. J'utiliserais aussi sûrement un peu de PhP pour autoriser l'utilisateur à taper des formules comme avec une calculatrice (même si une solution tout en JS me conviendrait plus).

Pour l'affichage des formules, je passerais par MathJax, pour l'interface graphique par jQuery, et côté applets, il y aura GeoGebra, CarMetal et peut-être aussi JavaView et/ou JMath 3D.

Il me reste un problème de taille : avoir un outil de calcul formel en ligne... Peut-être que GeoGebraCAS permettra cela.


Bonsoir projettmbc

Vaste projet :!:
Pour ma part, je pense que la prochaine version de GeoGebra me permettra de faire des choses plus intéressantes.
Connaitrais tu par hasard une fonction javascript qui aurait comme but de traduire une expression (comme on peut l'entrer sur une calculette) en code LaTex:
Par exemple: si la fonction recevait la chaîne "((x²+3)^3)/ (3x^3+2/x) " elle renverrait la chaîne " \frac{(x^2+3)^3^}{3x^3+\frac{2}{x}}" etc..
Ce ne doit pas être trop compliqué à programmer mais je n'ai pas encore eu le temps de le faire, alors si cela existe déjà ....

Joël
joelGa
Utilisateur
 
Messages: 7
Inscription: Vendredi 19 Novembre 2010, 12:43
Statut actuel: Actif et salarié | Enseignant

Re: Exerciseur niveau lycée ralisé avec GeoGebra

Messagepar Francky » Mardi 23 Novembre 2010, 18:37

joelGa a écrit:
projetmbc a écrit:Sacrée motivation.

Je vais me faire d'ici la rentrée scolaire prochaine, enfin je l'espère, des outils Python pour fabriquer "facilement" ce type d'exercices. L'idée étant de taper une sorte de script dans un fichier de type TXT, et ensuite de faire faire au programme Python la traduction GeoGebra, CarMetal, ..., HTML, JS. J'utiliserais aussi sûrement un peu de PhP pour autoriser l'utilisateur à taper des formules comme avec une calculatrice (même si une solution tout en JS me conviendrait plus).

Pour l'affichage des formules, je passerais par MathJax, pour l'interface graphique par jQuery, et côté applets, il y aura GeoGebra, CarMetal et peut-être aussi JavaView et/ou JMath 3D.

Il me reste un problème de taille : avoir un outil de calcul formel en ligne... Peut-être que GeoGebraCAS permettra cela.


Bonsoir projettmbc

Vaste projet :!:
Pour ma part, je pense que la prochaine version de GeoGebra me permettra de faire des choses plus intéressantes.
Connaitrais tu par hasard une fonction javascript qui aurait comme but de traduire une expression (comme on peut l'entrer sur une calculette) en code LaTex:
Par exemple: si la fonction recevait la chaîne "((x²+3)^3)/ (3x^3+2/x) " elle renverrait la chaîne " \frac{(x^2+3)^3^}{3x^3+\frac{2}{x}}" etc..
Ce ne doit pas être trop compliqué à programmer mais je n'ai pas encore eu le temps de le faire, alors si cela existe déjà ....

Joël


Personnellement, j'utiliserais xcas ou sagemath pour ce genre de requête, mais on revient au serveur dédié pour tout ça.
Autre avantage, au lieu de la sortie latex, on peut avoir du mathML, meilleur pour l'affichage web, et la possibilité de faire du copier-coller.
Linux Mint | TeXLive - TexMaker - asymptote | Python3 & C - Geany - Project Euler - SPOJ
Entia non sunt multiplicanda praeter necessitatem
Francky
Giga-utilisateur
 
Messages: 683
Inscription: Dimanche 11 Avril 2010, 13:01
Statut actuel: Actif et salarié | Enseignant

Re: Exerciseur niveau lycée ralisé avec GeoGebra

Messagepar projetmbc » Mardi 23 Novembre 2010, 19:12

Bonsoir.

joelGa a écrit:Vaste projet :!:

Le plus pénible a été fait, à savoir l'analyseur de formules mathématiques et celui de documents.

joelGa a écrit:Pour ma part, je pense que la prochaine version de GeoGebra me permettra de faire des choses plus intéressantes.

Pourquoi ?

joelGa a écrit:Connaitrais tu par hasard une fonction javascript qui aurait comme but de traduire une expression (comme on peut l'entrer sur une calculette) en code LaTex

Non mais il serait étonnant que quelqu'un n'est pas fait quelque chose. Est-ce visible sur la toile ? Pas sûr étant donné le fonctionnement de Google et à mon avis l'aspect un peu confidentiel de ce genre de script.

Dans le cadre de mon projet je vais en faire un mais ce ne sera pas pour tout suite car j'ai prévu de fabriquer un programme qui traduira tous mes codes Python gérant les formules en code JavaScript.

joelGa a écrit:Ce ne doit pas être trop compliqué à programmer mais je n'ai pas encore eu le temps de le faire, alors si cela existe déjà ...

Tout dépend comment tu t'y prends. Est-ce pour permettre la saisie de formules aux élèves ?

Francky a écrit:Personnellement, j'utiliserais xcas ou sagemath pour ce genre de requête

En local, je passerais par SymPy normalement. Par contre, l'auteur de xcas en ligne semble prêt à proposer des fonctions javascripts pour appeler xcas directement sur le serveur de xcas en ligne. Ceci permettrait d'utiliser xcas depuis un site. Affaire à suivre...

Francky a écrit:Autre avantage, au lieu de la sortie latex, on peut avoir du mathML, meilleur pour l'affichage web, et la possibilité de faire du copier-coller.

Pour les sorties des formules, il y a MathJax qui est très, très bien.
projetmbc
Péta-utilisateur
 
Messages: 1895
Inscription: Samedi 29 Décembre 2007, 00:58
Statut actuel: Actif et salarié | Enseignant

Re: Exerciseur niveau lycée réalisé avec GeoGebra

Messagepar Francky » Mardi 23 Novembre 2010, 19:30

Pour MathJax, je sais, il me semble que c'est moi qui est lâché l'info sur la sortie 2.0.
MathJax utilise le MathML, mais tu dois mieux le savoir que moi, tout cela me dépasse beaucoup.

Pour XCas, c'est cool, cela devrait lui redonner un coup de pub important.
Powered by XCas.
Linux Mint | TeXLive - TexMaker - asymptote | Python3 & C - Geany - Project Euler - SPOJ
Entia non sunt multiplicanda praeter necessitatem
Francky
Giga-utilisateur
 
Messages: 683
Inscription: Dimanche 11 Avril 2010, 13:01
Statut actuel: Actif et salarié | Enseignant

Re: Exerciseur niveau lycée ralisé avec GeoGebra

Messagepar projetmbc » Mardi 23 Novembre 2010, 19:39

J'avais oublié ma source... :oops:

projetmbc a écrit:
joelGa a écrit:Connaitrais tu par hasard une fonction javascript qui aurait comme but de traduire une expression (comme on peut l'entrer sur une calculette) en code LaTex

Non mais il serait étonnant que quelqu'un n'est pas fait quelque chose. Est-ce visible sur la toile ? Pas sûr étant donné le fonctionnement de Google et à mon avis l'aspect un peu confidentiel de ce genre de script.

J'ai encore perdu une occasion de me taire. Il faudrait tester ceci : JavaScript Expression Evaluator (je n'ai pas le temps de le faire en ce moment). La documentation parle de substitution, donc l'analyse de la formule est formelle.

Côté programmation, il va falloir voir si le code est modifiable rapidement. Avec un peu de chance, le programme est orienté objet, et un simple "sous-classage" sera possible (des infos ici).
projetmbc
Péta-utilisateur
 
Messages: 1895
Inscription: Samedi 29 Décembre 2007, 00:58
Statut actuel: Actif et salarié | Enseignant

Re: Exerciseur niveau lycée réalisé avec GeoGebra

Messagepar projetmbc » Mardi 23 Novembre 2010, 19:51

Curiosité quand tu nous tiens...

J'ai "zieuté" le code, et il semble modifiable et améliorable très facilement. Par exemple, la méthode toString, ligne 210, doit permettre de fabriquer "facilement" une méthode toLaTeX.

Ligne de codes correspondant à toString :
Code: Tout sélectionner
        toString: function (toJS) {
            var nstack = [];
            var n1;
            var n2;
            var f;
            var L = this.tokens.length;
            var item;
            var i = 0;
            for (i = 0; i < L; i++) {
                item = this.tokens[i];
                var type_ = item.type_;
                if (type_ === TNUMBER) {
                    nstack.push(escapeValue(item.number_));
                }
                else if (type_ === TOP2) {
                    n2 = nstack.pop();
                    n1 = nstack.pop();
                    f = item.index_;
                    if (toJS && f == "^") {
                        nstack.push("Math.pow(" + n1 + "," + n2 + ")");
                    }
                    else {
                        nstack.push("(" + n1 + f + n2 + ")");
                    }
                }
                else if (type_ === TVAR) {
                    nstack.push(item.index_);
                }
                else if (type_ === TOP1) {
                    n1 = nstack.pop();
                    f = item.index_;
                    if (f === "-") {
                        nstack.push("(" + f + n1 + ")");
                    }
                    else {
                        nstack.push(f + "(" + n1 + ")");
                    }
                }
                else if (type_ === TFUNCALL) {
                    n1 = nstack.pop();
                    f = nstack.pop();
                    nstack.push(f + "(" + n1 + ")");
                }
                else {
                    throw new Error("invalid Expression");
                }
            }
            if (nstack.length > 1) {
                throw new Error("invalid Expression (parity)");
            }
            return nstack[0];
        }

Si quelqu'un le fait, ce serait sympa de poster ici la modification.
projetmbc
Péta-utilisateur
 
Messages: 1895
Inscription: Samedi 29 Décembre 2007, 00:58
Statut actuel: Actif et salarié | Enseignant

Re: Exerciseur niveau lycée ralisé avec GeoGebra

Messagepar joelGa » Mardi 23 Novembre 2010, 20:39

projetmbc a écrit:Bonsoir.



joelGa a écrit:Pour ma part, je pense que la prochaine version de GeoGebra me permettra de faire des choses plus intéressantes.

Pourquoi ?

Je me suis mal exprimé : je pense faire des choses plus intéressantes que celles que j'ai faites .
La nouvelle version de GeoGebra intègrera entre autre du calcul formel .
Mais je suis très intéressé par ton projet.
Tiens nous au courant de son avancement.
Joël
joelGa
Utilisateur
 
Messages: 7
Inscription: Vendredi 19 Novembre 2010, 12:43
Statut actuel: Actif et salarié | Enseignant

Re: Exerciseur niveau lycée réalisé avec GeoGebra

Messagepar joelGa » Mardi 23 Novembre 2010, 20:42

projetmbc a écrit:Curiosité quand tu nous tiens...

J'ai "zieuté" le code, et il semble modifiable et améliorable très facilement. Par exemple, la méthode toString, ligne 210, doit permettre de fabriquer "facilement" une méthode toLaTeX.

Si quelqu'un le fait, ce serait sympa de poster ici la modification.


Je vais regarder cela quand j'aurais un instant.
Mais si quelqu'un s'y attèle avant je suis preneur.
Joël
joelGa
Utilisateur
 
Messages: 7
Inscription: Vendredi 19 Novembre 2010, 12:43
Statut actuel: Actif et salarié | Enseignant

Re: Exerciseur niveau lycée réalisé avec GeoGebra

Messagepar projetmbc » Mercredi 24 Novembre 2010, 07:13

Bonjour,
j'essaierais de regarder cela en fin de semaine.
projetmbc
Péta-utilisateur
 
Messages: 1895
Inscription: Samedi 29 Décembre 2007, 00:58
Statut actuel: Actif et salarié | Enseignant

Re: Exerciseur niveau lycée réalisé avec GeoGebra

Messagepar projetmbc » Mercredi 24 Novembre 2010, 13:31

Bonjour,
j'ai fait très rapidement, mais c'est INCOMPLET, le code ci-dessous suivi d'un exemple d'utilisation. Ce qui a été modifié est entre les lignes
/////////////////////////////////////////.

parser.js
Code: Tout sélectionner
/*
 Based on ndef.parser, by Raphael Graf(r@undefined.ch)
 http://www.undefined.ch/mparser/index.html

 Source for this file :
    http://silentmatt.com/math/evaluator.php
*/
var Parser = function () {
    function object(o) {
        function F() {}
        F.prototype = o;
        return new F();
    }

    var TNUMBER = 0;
    var TOP1 = 1;
    var TOP2 = 2;
    var TVAR = 3;
    var TFUNCALL = 4;

    function Token(type_, index_, prio_, number_) {
        this.type_ = type_;
        this.index_ = index_ || 0;
        this.prio_ = prio_ || 0;
        this.number_ = (number_ !== undefined && number_ !== null) ? number_ : 0;
        this.toString = function () {
            switch (this.type_) {
            case TNUMBER:
                return this.number_;
            case TOP1:
            case TOP2:
            case TVAR:
                return this.index_;
            case TFUNCALL:
                return "CALL";
            default:
                return "Invalid Token";
            }
        };
    }

    function Expression(tokens, ops1, ops2, functions) {
        this.tokens = tokens;
        this.ops1 = ops1;
        this.ops2 = ops2;
        this.functions = functions;
    }

    // Based on http://www.json.org/json2.js
    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        escapable = /[\\\'\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        meta = {    // table of character substitutions
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            "'" : "\\'",
            '\\': '\\\\'
        };

    function escapeValue(v) {
        if (typeof v === "string") {
            escapable.lastIndex = 0;
            return escapable.test(v) ?
                "'" + v.replace(escapable, function (a) {
                    var c = meta[a];
                    return typeof c === 'string' ? c :
                        '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
                }) + "'" :
                "'" + v + "'";
        }
        return v;
    }

    Expression.prototype = {
        simplify: function (values) {
            values = values || {};
            var nstack = [];
            var newexpression = [];
            var n1;
            var n2;
            var f;
            var L = this.tokens.length;
            var item;
            var i = 0;
            for (i = 0; i < L; i++) {
                item = this.tokens[i];
                var type_ = item.type_;
                if (type_ === TNUMBER) {
                    nstack.push(item);
                }
                else if (type_ === TVAR && (item.index_ in values)) {
                    item = new Token(TNUMBER, 0, 0, values[item.index_]);
                    nstack.push(item);
                }
                else if (type_ === TOP2 && nstack.length > 1) {
                    n2 = nstack.pop();
                    n1 = nstack.pop();
                    f = this.ops2[item.index_];
                    item = new Token(TNUMBER, 0, 0, f(n1.number_, n2.number_));
                    nstack.push(item);
                }
                else if (type_ === TOP1 && nstack.length > 0) {
                    n1 = nstack.pop();
                    f = this.ops1[item.index_];
                    item = new Token(TNUMBER, 0, 0, f(n1.number_));
                    nstack.push(item);
                }
                else {
                    while (nstack.length > 0) {
                        newexpression.push(nstack.shift());
                    }
                    newexpression.push(item);
                }
            }
            while (nstack.length > 0) {
                newexpression.push(nstack.shift());
            }

            return new Expression(newexpression, object(this.ops1), object(this.ops2), object(this.functions));
        },

        substitute: function (variable, expr) {
            if (!(expr instanceof Expression)) {
                expr = new Parser().parse(String(expr));
            }
            var newexpression = [];
            var L = this.tokens.length;
            var item;
            var i = 0;
            for (i = 0; i < L; i++) {
                item = this.tokens[i];
                var type_ = item.type_;
                if (type_ === TVAR && item.index_ === variable) {
                    for (var j = 0; j < expr.tokens.length; j++) {
                        var expritem = expr.tokens[j];
                        var replitem = new Token(expritem.type_, expritem.index_, expritem.prio_, expritem.number_);
                        newexpression.push(replitem);
                    }
                }
                else {
                    newexpression.push(item);
                }
            }

            var ret = new Expression(newexpression, object(this.ops1), object(this.ops2), object(this.functions));
            return ret;
        },

        evaluate: function (values) {
            values = values || {};
            var nstack = [];
            var n1;
            var n2;
            var f;
            var L = this.tokens.length;
            var item;
            var i = 0;
            for (i = 0; i < L; i++) {
                item = this.tokens[i];
                var type_ = item.type_;
                if (type_ === TNUMBER) {
                    nstack.push(item.number_);
                }
                else if (type_ === TOP2) {
                    n2 = nstack.pop();
                    n1 = nstack.pop();
                    f = this.ops2[item.index_];
                    nstack.push(f(n1, n2));
                }
                else if (type_ === TVAR) {
                    if (item.index_ in values) {
                        nstack.push(values[item.index_]);
                    }
                    else if (item.index_ in this.functions) {
                        nstack.push(this.functions[item.index_]);
                    }
                    else {
                        throw new Error("undefined variable: " + item.index_);
                    }
                }
                else if (type_ === TOP1) {
                    n1 = nstack.pop();
                    f = this.ops1[item.index_];
                    nstack.push(f(n1));
                }
                else if (type_ === TFUNCALL) {
                    n1 = nstack.pop();
                    f = nstack.pop();
                    if (f.apply && f.call) {
                        if (Object.prototype.toString.call(n1) == "[object Array]") {
                            nstack.push(f.apply(undefined, n1));
                        }
                        else {
                            nstack.push(f.call(undefined, n1));
                        }
                    }
                    else {
                        throw new Error(f + " is not a function");
                    }
                }
                else {
                    throw new Error("invalid Expression");
                }
            }
            if (nstack.length > 1) {
                throw new Error("invalid Expression (parity)");
            }
            return nstack[0];
        },

        toString: function (toJS) {
            var nstack = [];
            var n1;
            var n2;
            var f;
            var L = this.tokens.length;
            var item;
            var i = 0;
            for (i = 0; i < L; i++) {
                item = this.tokens[i];
                var type_ = item.type_;
                if (type_ === TNUMBER) {
                    nstack.push(escapeValue(item.number_));
                }
                else if (type_ === TOP2) {
                    n2 = nstack.pop();
                    n1 = nstack.pop();
                    f = item.index_;
                    if (toJS && f == "^") {
                        nstack.push("Math.pow(" + n1 + "," + n2 + ")");
                    }
                    else {
                        nstack.push("(" + n1 + f + n2 + ")");
                    }
                }
                else if (type_ === TVAR) {
                    nstack.push(item.index_);
                }
                else if (type_ === TOP1) {
                    n1 = nstack.pop();
                    f = item.index_;
                    if (f === "-") {
                        nstack.push("(" + f + n1 + ")");
                    }
                    else {
                        nstack.push(f + "(" + n1 + ")");
                    }
                }
                else if (type_ === TFUNCALL) {
                    n1 = nstack.pop();
                    f = nstack.pop();
                    nstack.push(f + "(" + n1 + ")");
                }
                else {
                    throw new Error("invalid Expression");
                }
            }
            if (nstack.length > 1) {
                throw new Error("invalid Expression (parity)");
            }
            return nstack[0];
        },



/////////////////////////////////////////
/////////////////////////////////////////
/////////////////////////////////////////

        toLatex: function () {
            var nstack = [];
            var n1;
            var n2;
            var f;
            var L = this.tokens.length;
            var item;
            var i = 0;
            for (i = 0; i < L; i++) {
                item = this.tokens[i];
                var type_ = item.type_;
                if (type_ === TNUMBER) {
                    nstack.push(escapeValue(item.number_));
                }
                else if (type_ === TOP2) {
                    n2 = nstack.pop();
                    n1 = nstack.pop();
                    f = item.index_;
                    if (f == "^") {
                        nstack.push("{" + n1 + "}^{" + n2 + "}");
                    }
                    else if (f == "*") {
                        nstack.push('(' + n1 + ')' + " \\times " + '(' + n2 + ')');
                    }
                    else if (f == "/") {
                        nstack.push("\\frac{" + n1 + "}{" + n2 + "}");
                    }
                    else {
                        nstack.push(n1 + " " + f + " " + n2);
                    }
                }
                else if (type_ === TVAR) {
                    nstack.push(item.index_);
                }
                else if (type_ === TOP1) {
                    n1 = nstack.pop();
                    f = item.index_;
                    if (f === "-") {
                        nstack.push("(" + f + n1 + ")");
                    }
                    else {
                        nstack.push(f + "(" + n1 + ")");
                    }
                }
                else if (type_ === TFUNCALL) {
                    n1 = nstack.pop();
                    f = nstack.pop();
                    nstack.push(f + "(" + n1 + ")");
                }
                else {
                    throw new Error("invalid Expression");
                }
            }
            if (nstack.length > 1) {
                throw new Error("invalid Expression (parity)");
            }
            return nstack[0];
        },


/////////////////////////////////////////
/////////////////////////////////////////
/////////////////////////////////////////


        variables: function () {
            var L = this.tokens.length;
            var vars = [];
            for (var i = 0; i < L; i++) {
                var item = this.tokens[i];
                if (item.type_ === TVAR && (vars.indexOf(item.index_) == -1)) {
                    vars.push(item.index_);
                }
            }

            return vars;
        },

        toJSFunction: function (param, variables) {
            var f = new Function(param, "with(Parser.values) { return " + this.simplify(variables).toString(true) + "; }");
            return f;
        }
    };

    function add(a, b) {
        return Number(a) + Number(b);
    }
    function sub(a, b) {
        return a - b;
    }
    function mul(a, b) {
        return a * b;
    }
    function div(a, b) {
        return a / b;
    }
    function mod(a, b) {
        return a % b;
    }
    function concat(a, b) {
        return "" + a + b;
    }

    function neg(a) {
        return -a;
    }

    function random(a) {
        return Math.random() * (a || 1);
    }
    function fac(a) { //a!
        a = Math.floor(a);
        var b = a;
        while (a > 1) {
            b = b * (--a);
        }
        return b;
    }

    // TODO: use hypot that doesn't overflow
    function pyt(a, b) {
        return Math.sqrt(a * a + b * b);
    }

    function append(a, b) {
        if (Object.prototype.toString.call(a) != "[object Array]") {
            return [a, b];
        }
        a = a.slice();
        a.push(b);
        return a;
    }

    function Parser() {
        this.success = false;
        this.errormsg = "";
        this.expression = "";

        this.pos = 0;

        this.tokennumber = 0;
        this.tokenprio = 0;
        this.tokenindex = 0;
        this.tmpprio = 0;

        this.ops1 = {
            "sin": Math.sin,
            "cos": Math.cos,
            "tan": Math.tan,
            "asin": Math.asin,
            "acos": Math.acos,
            "atan": Math.atan,
            "sqrt": Math.sqrt,
            "log": Math.log,
            "abs": Math.abs,
            "ceil": Math.ceil,
            "floor": Math.floor,
            "round": Math.round,
            "-": neg,
            "exp": Math.exp
        };

        this.ops2 = {
            "+": add,
            "-": sub,
            "*": mul,
            "/": div,
            "%": mod,
            "^": Math.pow,
            ",": append,
            "||": concat
        };

        this.functions = {
            "random": random,
            "fac": fac,
            "min": Math.min,
            "max": Math.max,
            "pyt": pyt,
            "pow": Math.pow,
            "atan2": Math.atan2
        };

        this.consts = {
            "E": Math.E,
            "PI": Math.PI
        };
    }

    Parser.parse = function (expr) {
        return new Parser().parse(expr);
    };

    Parser.evaluate = function (expr, variables) {
        return Parser.parse(expr).evaluate(variables);
    };

    Parser.Expression = Expression;

    Parser.values = {
        sin: Math.sin,
        cos: Math.cos,
        tan: Math.tan,
        asin: Math.asin,
        acos: Math.acos,
        atan: Math.atan,
        sqrt: Math.sqrt,
        log: Math.log,
        abs: Math.abs,
        ceil: Math.ceil,
        floor: Math.floor,
        round: Math.round,
        random: random,
        fac: fac,
        exp: Math.exp,
        min: Math.min,
        max: Math.max,
        pyt: pyt,
        pow: Math.pow,
        atan2: Math.atan2,
        E: Math.E,
        PI: Math.PI
    };

    var PRIMARY  = 1 << 0;
    var OPERATOR = 1 << 1;
    var FUNCTION = 1 << 2;
    var LPAREN   = 1 << 3;
    var RPAREN   = 1 << 4;
    var COMMA    = 1 << 5;
    var SIGN     = 1 << 6;
    var CALL     = 1 << 7;

    Parser.prototype = {
        parse: function (expr) {
            this.errormsg = "";
            this.success = true;
            var operstack = [];
            var tokenstack = [];
            this.tmpprio = 0;
            var expected = (PRIMARY | LPAREN | FUNCTION | SIGN);
            var noperators = 0;
            this.expression = expr;
            this.pos = 0;

            while (this.pos < this.expression.length) {
                if (this.isOperator()) {
                    if (this.isSign() && (expected & SIGN)) {
                        if (this.isNegativeSign()) {
                            this.tokenprio = 2;
                            this.tokenindex = "-";
                            noperators++;
                            this.addfunc(tokenstack, operstack, TOP1);
                        }
                        expected = (PRIMARY | LPAREN | FUNCTION | SIGN);
                    }
                    else if (this.isComment()) {

                    }
                    else {
                        if ((expected & OPERATOR) === 0) {
                            this.error_parsing(this.pos, "unexpected operator");
                        }
                        noperators += 2;
                        this.addfunc(tokenstack, operstack, TOP2);
                        expected = (PRIMARY | LPAREN | FUNCTION | SIGN);
                    }
                }
                else if (this.isNumber()) {
                    if ((expected & PRIMARY) === 0) {
                        this.error_parsing(this.pos, "unexpected number");
                    }
                    var token = new Token(TNUMBER, 0, 0, this.tokennumber);
                    tokenstack.push(token);

                    expected = (OPERATOR | RPAREN | COMMA);
                }
                else if (this.isString()) {
                    if ((expected & PRIMARY) === 0) {
                        this.error_parsing(this.pos, "unexpected string");
                    }
                    var token = new Token(TNUMBER, 0, 0, this.tokennumber);
                    tokenstack.push(token);

                    expected = (OPERATOR | RPAREN | COMMA);
                }
                else if (this.isLeftParenth()) {
                    if ((expected & LPAREN) === 0) {
                        this.error_parsing(this.pos, "unexpected \"(\"");
                    }

                    if (expected & CALL) {
                        noperators += 2;
                        this.tokenprio = -2;
                        this.tokenindex = -1;
                        this.addfunc(tokenstack, operstack, TFUNCALL);
                    }

                    expected = (PRIMARY | LPAREN | FUNCTION | SIGN);
                }
                else if (this.isRightParenth()) {
                    if ((expected & RPAREN) === 0) {
                        this.error_parsing(this.pos, "unexpected \")\"");
                    }

                    expected = (OPERATOR | RPAREN | COMMA | LPAREN | CALL);
                }
                else if (this.isComma()) {
                    if ((expected & COMMA) === 0) {
                        this.error_parsing(this.pos, "unexpected \",\"");
                    }
                    this.addfunc(tokenstack, operstack, TOP2);
                    noperators += 2;
                    expected = (PRIMARY | LPAREN | FUNCTION | SIGN);
                }
                else if (this.isConst()) {
                    if ((expected & PRIMARY) === 0) {
                        this.error_parsing(this.pos, "unexpected constant");
                    }
                    var consttoken = new Token(TNUMBER, 0, 0, this.tokennumber);
                    tokenstack.push(consttoken);
                    expected = (OPERATOR | RPAREN | COMMA);
                }
                else if (this.isOp2()) {
                    if ((expected & FUNCTION) === 0) {
                        this.error_parsing(this.pos, "unexpected function");
                    }
                    this.addfunc(tokenstack, operstack, TOP2);
                    noperators += 2;
                    expected = (LPAREN);
                }
                else if (this.isOp1()) {
                    if ((expected & FUNCTION) === 0) {
                        this.error_parsing(this.pos, "unexpected function");
                    }
                    this.addfunc(tokenstack, operstack, TOP1);
                    noperators++;
                    expected = (LPAREN);
                }
                else if (this.isVar()) {
                    if ((expected & PRIMARY) === 0) {
                        this.error_parsing(this.pos, "unexpected variable");
                    }
                    var vartoken = new Token(TVAR, this.tokenindex, 0, 0);
                    tokenstack.push(vartoken);

                    expected = (OPERATOR | RPAREN | COMMA | LPAREN | CALL);
                }
                else if (this.isWhite()) {
                }
                else {
                    if (this.errormsg === "") {
                        this.error_parsing(this.pos, "unknown character");
                    }
                    else {
                        this.error_parsing(this.pos, this.errormsg);
                    }
                }
            }
            if (this.tmpprio < 0 || this.tmpprio >= 10) {
                this.error_parsing(this.pos, "unmatched \"()\"");
            }
            while (operstack.length > 0) {
                var tmp = operstack.pop();
                tokenstack.push(tmp);
            }
            if (noperators + 1 !== tokenstack.length) {
                //print(noperators + 1);
                //print(tokenstack);
                this.error_parsing(this.pos, "parity");
            }

            return new Expression(tokenstack, object(this.ops1), object(this.ops2), object(this.functions));
        },

        evaluate: function (expr, variables) {
            return this.parse(expr).evaluate(variables);
        },

        error_parsing: function (column, msg) {
            this.success = false;
            this.errormsg = "parse error [column " + (column) + "]: " + msg;
            throw new Error(this.errormsg);
        },

//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

        addfunc: function (tokenstack, operstack, type_) {
            var operator = new Token(type_, this.tokenindex, this.tokenprio + this.tmpprio, 0);
            while (operstack.length > 0) {
                if (operator.prio_ <= operstack[operstack.length - 1].prio_) {
                    tokenstack.push(operstack.pop());
                }
                else {
                    break;
                }
            }
            operstack.push(operator);
        },

        isNumber: function () {
            var r = false;
            var str = "";
            while (this.pos < this.expression.length) {
                var code = this.expression.charCodeAt(this.pos);
                if ((code >= 48 && code <= 57) || code === 46) {
                    str += this.expression.charAt(this.pos);
                    this.pos++;
                    this.tokennumber = parseFloat(str);
                    r = true;
                }
                else {
                    break;
                }
            }
            return r;
        },

        // Ported from the yajjl JSON parser at http://code.google.com/p/yajjl/
        unescape: function(v, pos) {
            var buffer = [];
            var escaping = false;

            for (var i = 0; i < v.length; i++) {
                var c = v.charAt(i);

                if (escaping) {
                    switch (c) {
                    case "'":
                        buffer.push("'");
                        break;
                    case '\\':
                        buffer.push('\\');
                        break;
                    case '/':
                        buffer.push('/');
                        break;
                    case 'b':
                        buffer.push('\b');
                        break;
                    case 'f':
                        buffer.push('\f');
                        break;
                    case 'n':
                        buffer.push('\n');
                        break;
                    case 'r':
                        buffer.push('\r');
                        break;
                    case 't':
                        buffer.push('\t');
                        break;
                    case 'u':
                        // interpret the following 4 characters as the hex of the unicode code point
                        var codePoint = parseInt(v.substring(i + 1, i + 5), 16);
                        buffer.push(String.fromCharCode(codePoint));
                        i += 4;
                        break;
                    default:
                        throw this.error_parsing(pos + i, "Illegal escape sequence: '\\" + c + "'");
                    }
                    escaping = false;
                } else {
                    if (c == '\\') {
                        escaping = true;
                    } else {
                        buffer.push(c);
                    }
                }
            }

            return buffer.join('');
        },

        isString: function () {
            var r = false;
            var str = "";
            var startpos = this.pos;
            if (this.pos < this.expression.length && this.expression.charAt(this.pos) == "'") {
                this.pos++;
                while (this.pos < this.expression.length) {
                    var code = this.expression.charAt(this.pos);
                    if (code != "'" || str.slice(-1) == "\\") {
                        str += this.expression.charAt(this.pos);
                        this.pos++;
                    }
                    else {
                        this.pos++;
                        this.tokennumber = this.unescape(str, startpos);
                        r = true;
                        break;
                    }
                }
            }
            return r;
        },

        isConst: function () {
            var str;
            for (var i in this.consts) {
                if (true) {
                    var L = i.length;
                    str = this.expression.substr(this.pos, L);
                    if (i === str) {
                        this.tokennumber = this.consts[i];
                        this.pos += L;
                        return true;
                    }
                }
            }
            return false;
        },

        isOperator: function () {
            var code = this.expression.charCodeAt(this.pos);
            if (code === 43) { // +
                this.tokenprio = 0;
                this.tokenindex = "+";
            }
            else if (code === 45) { // -
                this.tokenprio = 0;
                this.tokenindex = "-";
            }
            else if (code === 124) { // |
                if (this.expression.charCodeAt(this.pos + 1) === 124) {
                    this.pos++;
                    this.tokenprio = 0;
                    this.tokenindex = "||";
                }
                else {
                    return false;
                }
            }
            else if (code === 42) { // *
                this.tokenprio = 1;
                this.tokenindex = "*";
            }
            else if (code === 47) { // /
                this.tokenprio = 2;
                this.tokenindex = "/";
            }
            else if (code === 37) { // %
                this.tokenprio = 2;
                this.tokenindex = "%";
            }
            else if (code === 94) { // ^
                this.tokenprio = 3;
                this.tokenindex = "^";
            }
            else {
                return false;
            }
            this.pos++;
            return true;
        },

        isSign: function () {
            var code = this.expression.charCodeAt(this.pos - 1);
            if (code === 45 || code === 43) { // -
                return true;
            }
            return false;
        },

        isPositiveSign: function () {
            var code = this.expression.charCodeAt(this.pos - 1);
            if (code === 43) { // -
                return true;
            }
            return false;
        },

        isNegativeSign: function () {
            var code = this.expression.charCodeAt(this.pos - 1);
            if (code === 45) { // -
                return true;
            }
            return false;
        },

        isLeftParenth: function () {
            var code = this.expression.charCodeAt(this.pos);
            if (code === 40) { // (
                this.pos++;
                this.tmpprio += 10;
                return true;
            }
            return false;
        },

        isRightParenth: function () {
            var code = this.expression.charCodeAt(this.pos);
            if (code === 41) { // )
                this.pos++;
                this.tmpprio -= 10;
                return true;
            }
            return false;
        },

        isComma: function () {
            var code = this.expression.charCodeAt(this.pos);
            if (code === 44) { // ,
                this.pos++;
                this.tokenprio = -1;
                this.tokenindex = ",";
                return true;
            }
            return false;
        },

        isWhite: function () {
            var code = this.expression.charCodeAt(this.pos);
            if (code === 32 || code === 9 || code === 10 || code === 13) {
                this.pos++;
                return true;
            }
            return false;
        },

        isOp1: function () {
            var str = "";
            for (var i = this.pos; i < this.expression.length; i++) {
                var c = this.expression.charAt(i);
                if (c.toUpperCase() === c.toLowerCase()) {
                    if (i === this.pos || c < '0' || c > '9') {
                        break;
                    }
                }
                str += c;
            }
            if (str.length > 0 && (str in this.ops1)) {
                this.tokenindex = str;
                this.tokenprio = 5;
                this.pos += str.length;
                return true;
            }
            return false;
        },

        isOp2: function () {
            var str = "";
            for (var i = this.pos; i < this.expression.length; i++) {
                var c = this.expression.charAt(i);
                if (c.toUpperCase() === c.toLowerCase()) {
                    if (i === this.pos || c < '0' || c > '9') {
                        break;
                    }
                }
                str += c;
            }
            if (str.length > 0 && (str in this.ops2)) {
                this.tokenindex = str;
                this.tokenprio = 5;
                this.pos += str.length;
                return true;
            }
            return false;
        },

        isVar: function () {
            var str = "";
            for (var i = this.pos; i < this.expression.length; i++) {
                var c = this.expression.charAt(i);
                if (c.toUpperCase() === c.toLowerCase()) {
                    if (i === this.pos || c < '0' || c > '9') {
                        break;
                    }
                }
                str += c;
            }
            if (str.length > 0) {
                this.tokenindex = str;
                this.tokenprio = 4;
                this.pos += str.length;
                return true;
            }
            return false;
        },

        isComment: function () {
            var code = this.expression.charCodeAt(this.pos - 1);
            if (code === 47 && this.expression.charCodeAt(this.pos) === 42) {
                this.pos = this.expression.indexOf("*/", this.pos) + 2;
                if (this.pos === 1) {
                    this.pos = this.expression.length;
                }
                return true;
            }
            return false;
        }
    };

    return Parser;
}();


test.html
Code: Tout sélectionner
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
    <head>
        <script src="parser.js" type="text/javascript"/>
        <script type="text/javascript">
            oneFomurlaParsed = Parser.parse('2^5*(1+4/5)');
            document.write( oneFomurlaParsed.toLatex() );
        </script>
    </head>

    <body>
    </body>
</html>


Sur ce, mes copies m'appellent...
projetmbc
Péta-utilisateur
 
Messages: 1895
Inscription: Samedi 29 Décembre 2007, 00:58
Statut actuel: Actif et salarié | Enseignant

Re: Exerciseur niveau lycée réalisé avec GeoGebra

Messagepar projetmbc » Samedi 27 Novembre 2010, 23:39

Voici un fichier test adapté d'un exemple de MathJax. Ceci permet de tester visuellement le fichier JavaScript modifié qui pourra être utile dans un premier temps même si cela est loin d'être parfait.
Code: Tout sélectionner
<!--
Sources :
    http://www.mathjax.org/resources/docs/?typeset.html
-->

<html>
    <head>
        <script src="parser.js" type="text/javascript"/>

        <script src="http://www.mathjax.org/mathjax/MathJax.js">
MathJax.Hub.Config({
    extensions: ["tex2jax.js"],
    jax: ["input/TeX","output/HTML-CSS"],
    tex2jax: {inlineMath: [["$","$"],["\\(","\\)"]]}
});
        </script>

        <script>
//
//  Use a closure to hide the local variables from the
//  global namespace
//
(function () {
    var QUEUE = MathJax.Hub.queue;  // shorthand for the queue
    var math = null;                // the element jax for the math output.

//
//  Get the element jax when MathJax has produced it.
//
    QUEUE.Push(function () {
        math = MathJax.Hub.getAllJax("MathOutput")[0];
    });

//
//  The onchange event handler that typesets the
//  math entered by the user
//
    window.UpdateMath = function (text) {
        TeX = Parser.parse(text).toLatex();
        QUEUE.Push(["Text",math,"\\displaystyle{"+TeX+"}"]);
    }
})();
        </script>
    </head>


    <body>
        Type some TeX code:
        <input id="MathInput" size="50" onchange="UpdateMath(this.value)" />

        <div id="MathOutput">
You typed: ${}$
        </div>
    </body>
</html>


Code parser.js à nettoyer (retirer les lignes inutiles)
Code: Tout sélectionner
/*
 Based on ndef.parser, by Raphael Graf(r@undefined.ch)
 http://www.undefined.ch/mparser/index.html

 Source for this file :
    http://silentmatt.com/math/evaluator.php
*/
var Parser = function () {
    function object(o) {
        function F() {}
        F.prototype = o;
        return new F();
    }

    var TNUMBER = 0;
    var TOP1 = 1;
    var TOP2 = 2;
    var TVAR = 3;
    var TFUNCALL = 4;

    function Token(type_, index_, prio_, number_) {
        this.type_ = type_;
        this.index_ = index_ || 0;
        this.prio_ = prio_ || 0;
        this.number_ = (number_ !== undefined && number_ !== null) ? number_ : 0;
        this.toString = function () {
            switch (this.type_) {
            case TNUMBER:
                return this.number_;
            case TOP1:
            case TOP2:
            case TVAR:
                return this.index_;
            case TFUNCALL:
                return "CALL";
            default:
                return "Invalid Token";
            }
        };
    }

    function Expression(tokens, ops1, ops2, functions) {
        this.tokens = tokens;
        this.ops1 = ops1;
        this.ops2 = ops2;
        this.functions = functions;
    }

    // Based on http://www.json.org/json2.js
    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        escapable = /[\\\'\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        meta = {    // table of character substitutions
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            "'" : "\\'",
            '\\': '\\\\'
        };

    function escapeValue(v) {
        if (typeof v === "string") {
            escapable.lastIndex = 0;
            return escapable.test(v) ?
                "'" + v.replace(escapable, function (a) {
                    var c = meta[a];
                    return typeof c === 'string' ? c :
                        '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
                }) + "'" :
                "'" + v + "'";
        }
        return v;
    }

    Expression.prototype = {
        simplify: function (values) {
            values = values || {};
            var nstack = [];
            var newexpression = [];
            var n1;
            var n2;
            var f;
            var L = this.tokens.length;
            var item;
            var i = 0;
            for (i = 0; i < L; i++) {
                item = this.tokens[i];
                var type_ = item.type_;
                if (type_ === TNUMBER) {
                    nstack.push(item);
                }
                else if (type_ === TVAR && (item.index_ in values)) {
                    item = new Token(TNUMBER, 0, 0, values[item.index_]);
                    nstack.push(item);
                }
                else if (type_ === TOP2 && nstack.length > 1) {
                    n2 = nstack.pop();
                    n1 = nstack.pop();
                    f = this.ops2[item.index_];
                    item = new Token(TNUMBER, 0, 0, f(n1.number_, n2.number_));
                    nstack.push(item);
                }
                else if (type_ === TOP1 && nstack.length > 0) {
                    n1 = nstack.pop();
                    f = this.ops1[item.index_];
                    item = new Token(TNUMBER, 0, 0, f(n1.number_));
                    nstack.push(item);
                }
                else {
                    while (nstack.length > 0) {
                        newexpression.push(nstack.shift());
                    }
                    newexpression.push(item);
                }
            }
            while (nstack.length > 0) {
                newexpression.push(nstack.shift());
            }

            return new Expression(newexpression, object(this.ops1), object(this.ops2), object(this.functions));
        },

        substitute: function (variable, expr) {
            if (!(expr instanceof Expression)) {
                expr = new Parser().parse(String(expr));
            }
            var newexpression = [];
            var L = this.tokens.length;
            var item;
            var i = 0;
            for (i = 0; i < L; i++) {
                item = this.tokens[i];
                var type_ = item.type_;
                if (type_ === TVAR && item.index_ === variable) {
                    for (var j = 0; j < expr.tokens.length; j++) {
                        var expritem = expr.tokens[j];
                        var replitem = new Token(expritem.type_, expritem.index_, expritem.prio_, expritem.number_);
                        newexpression.push(replitem);
                    }
                }
                else {
                    newexpression.push(item);
                }
            }

            var ret = new Expression(newexpression, object(this.ops1), object(this.ops2), object(this.functions));
            return ret;
        },

        evaluate: function (values) {
            values = values || {};
            var nstack = [];
            var n1;
            var n2;
            var f;
            var L = this.tokens.length;
            var item;
            var i = 0;
            for (i = 0; i < L; i++) {
                item = this.tokens[i];
                var type_ = item.type_;
                if (type_ === TNUMBER) {
                    nstack.push(item.number_);
                }
                else if (type_ === TOP2) {
                    n2 = nstack.pop();
                    n1 = nstack.pop();
                    f = this.ops2[item.index_];
                    nstack.push(f(n1, n2));
                }
                else if (type_ === TVAR) {
                    if (item.index_ in values) {
                        nstack.push(values[item.index_]);
                    }
                    else if (item.index_ in this.functions) {
                        nstack.push(this.functions[item.index_]);
                    }
                    else {
                        throw new Error("undefined variable: " + item.index_);
                    }
                }
                else if (type_ === TOP1) {
                    n1 = nstack.pop();
                    f = this.ops1[item.index_];
                    nstack.push(f(n1));
                }
                else if (type_ === TFUNCALL) {
                    n1 = nstack.pop();
                    f = nstack.pop();
                    if (f.apply && f.call) {
                        if (Object.prototype.toString.call(n1) == "[object Array]") {
                            nstack.push(f.apply(undefined, n1));
                        }
                        else {
                            nstack.push(f.call(undefined, n1));
                        }
                    }
                    else {
                        throw new Error(f + " is not a function");
                    }
                }
                else {
                    throw new Error("invalid Expression");
                }
            }
            if (nstack.length > 1) {
                throw new Error("invalid Expression (parity)");
            }
            return nstack[0];
        },

        toString: function (toJS) {
            var nstack = [];
            var n1;
            var n2;
            var f;
            var L = this.tokens.length;
            var item;
            var i = 0;
            for (i = 0; i < L; i++) {
                item = this.tokens[i];
                var type_ = item.type_;
                if (type_ === TNUMBER) {
                    nstack.push(escapeValue(item.number_));
                }
                else if (type_ === TOP2) {
                    n2 = nstack.pop();
                    n1 = nstack.pop();
                    f = item.index_;
                    if (toJS && f == "^") {
                        nstack.push("Math.pow(" + n1 + "," + n2 + ")");
                    }
                    else {
                        nstack.push("(" + n1 + f + n2 + ")");
                    }
                }
                else if (type_ === TVAR) {
                    nstack.push(item.index_);
                }
                else if (type_ === TOP1) {
                    n1 = nstack.pop();
                    f = item.index_;
                    if (f === "-") {
                        nstack.push("(" + f + n1 + ")");
                    }
                    else {
                        nstack.push(f + "(" + n1 + ")");
                    }
                }
                else if (type_ === TFUNCALL) {
                    n1 = nstack.pop();
                    f = nstack.pop();
                    nstack.push(f + "(" + n1 + ")");
                }
                else {
                    throw new Error("invalid Expression");
                }
            }
            if (nstack.length > 1) {
                throw new Error("invalid Expression (parity)");
            }
            return nstack[0];
        },



/////////////////////////////////////////
/////////////////////////////////////////
/////////////////////////////////////////

        toLatex: function () {
            var nstack = [];
            var n1;
            var n2;
            var f;
            var L = this.tokens.length;
            var item;
            var i = 0;
            for (i = 0; i < L; i++) {
                item = this.tokens[i];
                var type_ = item.type_;
                if (type_ === TNUMBER) {
                    nstack.push(escapeValue(item.number_));
                }
                else if (type_ === TOP2) {
                    n2 = nstack.pop();
                    n1 = nstack.pop();
                    f = item.index_;
                    if (f == "^") {
                        nstack.push("{(" + n1 + ")}^{(" + n2 + ")}");
                    }
                    else if (f == "*") {
                        nstack.push(n1 + " \\times " + n2);
                    }
                    else if (f == "/") {
                        nstack.push("\\frac{" + n1 + "}{" + n2 + "}");
                    }
                    else {
                        nstack.push(n1 + " " + f + " " + n2);
                    }
                }
                else if (type_ === TVAR) {
                    nstack.push(item.index_);
                }
                else if (type_ === TOP1) {
                    n1 = nstack.pop();
                    f = item.index_;
                    if (f === "-") {
                        nstack.push("(" + f + n1 + ")");
                    }
                    else {
                        nstack.push(f + "(" + n1 + ")");
                    }
                }
                else if (type_ === TFUNCALL) {
                    n1 = nstack.pop();
                    f = nstack.pop();
                    nstack.push(f + "(" + n1 + ")");
                }
                else {
                    throw new Error("invalid Expression");
                }
            }
            if (nstack.length > 1) {
                throw new Error("invalid Expression (parity)");
            }
            return nstack[0];
        },


/////////////////////////////////////////
/////////////////////////////////////////
/////////////////////////////////////////


        variables: function () {
            var L = this.tokens.length;
            var vars = [];
            for (var i = 0; i < L; i++) {
                var item = this.tokens[i];
                if (item.type_ === TVAR && (vars.indexOf(item.index_) == -1)) {
                    vars.push(item.index_);
                }
            }

            return vars;
        },

        toJSFunction: function (param, variables) {
            var f = new Function(param, "with(Parser.values) { return " + this.simplify(variables).toString(true) + "; }");
            return f;
        }
    };

    function add(a, b) {
        return Number(a) + Number(b);
    }
    function sub(a, b) {
        return a - b;
    }
    function mul(a, b) {
        return a * b;
    }
    function div(a, b) {
        return a / b;
    }
    function mod(a, b) {
        return a % b;
    }
    function concat(a, b) {
        return "" + a + b;
    }

    function neg(a) {
        return -a;
    }

    function random(a) {
        return Math.random() * (a || 1);
    }
    function fac(a) { //a!
        a = Math.floor(a);
        var b = a;
        while (a > 1) {
            b = b * (--a);
        }
        return b;
    }

    // TODO: use hypot that doesn't overflow
    function pyt(a, b) {
        return Math.sqrt(a * a + b * b);
    }

    function append(a, b) {
        if (Object.prototype.toString.call(a) != "[object Array]") {
            return [a, b];
        }
        a = a.slice();
        a.push(b);
        return a;
    }

    function Parser() {
        this.success = false;
        this.errormsg = "";
        this.expression = "";

        this.pos = 0;

        this.tokennumber = 0;
        this.tokenprio = 0;
        this.tokenindex = 0;
        this.tmpprio = 0;

        this.ops1 = {
            "sin": Math.sin,
            "cos": Math.cos,
            "tan": Math.tan,
            "asin": Math.asin,
            "acos": Math.acos,
            "atan": Math.atan,
            "sqrt": Math.sqrt,
            "log": Math.log,
            "abs": Math.abs,
            "ceil": Math.ceil,
            "floor": Math.floor,
            "round": Math.round,
            "-": neg,
            "exp": Math.exp
        };

        this.ops2 = {
            "+": add,
            "-": sub,
            "*": mul,
            "/": div,
            "%": mod,
            "^": Math.pow,
            ",": append,
            "||": concat
        };

        this.functions = {
            "random": random,
            "fac": fac,
            "min": Math.min,
            "max": Math.max,
            "pyt": pyt,
            "pow": Math.pow,
            "atan2": Math.atan2
        };

        this.consts = {
            "E": Math.E,
            "PI": Math.PI
        };
    }

    Parser.parse = function (expr) {
        return new Parser().parse(expr);
    };

    Parser.evaluate = function (expr, variables) {
        return Parser.parse(expr).evaluate(variables);
    };

    Parser.Expression = Expression;

    Parser.values = {
        sin: Math.sin,
        cos: Math.cos,
        tan: Math.tan,
        asin: Math.asin,
        acos: Math.acos,
        atan: Math.atan,
        sqrt: Math.sqrt,
        log: Math.log,
        abs: Math.abs,
        ceil: Math.ceil,
        floor: Math.floor,
        round: Math.round,
        random: random,
        fac: fac,
        exp: Math.exp,
        min: Math.min,
        max: Math.max,
        pyt: pyt,
        pow: Math.pow,
        atan2: Math.atan2,
        E: Math.E,
        PI: Math.PI
    };

    var PRIMARY  = 1 << 0;
    var OPERATOR = 1 << 1;
    var FUNCTION = 1 << 2;
    var LPAREN   = 1 << 3;
    var RPAREN   = 1 << 4;
    var COMMA    = 1 << 5;
    var SIGN     = 1 << 6;
    var CALL     = 1 << 7;

    Parser.prototype = {
        parse: function (expr) {
            this.errormsg = "";
            this.success = true;
            var operstack = [];
            var tokenstack = [];
            this.tmpprio = 0;
            var expected = (PRIMARY | LPAREN | FUNCTION | SIGN);
            var noperators = 0;
            this.expression = expr;
            this.pos = 0;

            while (this.pos < this.expression.length) {
                if (this.isOperator()) {
                    if (this.isSign() && (expected & SIGN)) {
                        if (this.isNegativeSign()) {
                            this.tokenprio = 2;
                            this.tokenindex = "-";
                            noperators++;
                            this.addfunc(tokenstack, operstack, TOP1);
                        }
                        expected = (PRIMARY | LPAREN | FUNCTION | SIGN);
                    }
                    else if (this.isComment()) {

                    }
                    else {
                        if ((expected & OPERATOR) === 0) {
                            this.error_parsing(this.pos, "unexpected operator");
                        }
                        noperators += 2;
                        this.addfunc(tokenstack, operstack, TOP2);
                        expected = (PRIMARY | LPAREN | FUNCTION | SIGN);
                    }
                }
                else if (this.isNumber()) {
                    if ((expected & PRIMARY) === 0) {
                        this.error_parsing(this.pos, "unexpected number");
                    }
                    var token = new Token(TNUMBER, 0, 0, this.tokennumber);
                    tokenstack.push(token);

                    expected = (OPERATOR | RPAREN | COMMA);
                }
                else if (this.isString()) {
                    if ((expected & PRIMARY) === 0) {
                        this.error_parsing(this.pos, "unexpected string");
                    }
                    var token = new Token(TNUMBER, 0, 0, this.tokennumber);
                    tokenstack.push(token);

                    expected = (OPERATOR | RPAREN | COMMA);
                }
                else if (this.isLeftParenth()) {
                    if ((expected & LPAREN) === 0) {
                        this.error_parsing(this.pos, "unexpected \"(\"");
                    }

                    if (expected & CALL) {
                        noperators += 2;
                        this.tokenprio = -2;
                        this.tokenindex = -1;
                        this.addfunc(tokenstack, operstack, TFUNCALL);
                    }

                    expected = (PRIMARY | LPAREN | FUNCTION | SIGN);
                }
                else if (this.isRightParenth()) {
                    if ((expected & RPAREN) === 0) {
                        this.error_parsing(this.pos, "unexpected \")\"");
                    }

                    expected = (OPERATOR | RPAREN | COMMA | LPAREN | CALL);
                }
                else if (this.isComma()) {
                    if ((expected & COMMA) === 0) {
                        this.error_parsing(this.pos, "unexpected \",\"");
                    }
                    this.addfunc(tokenstack, operstack, TOP2);
                    noperators += 2;
                    expected = (PRIMARY | LPAREN | FUNCTION | SIGN);
                }
                else if (this.isConst()) {
                    if ((expected & PRIMARY) === 0) {
                        this.error_parsing(this.pos, "unexpected constant");
                    }
                    var consttoken = new Token(TNUMBER, 0, 0, this.tokennumber);
                    tokenstack.push(consttoken);
                    expected = (OPERATOR | RPAREN | COMMA);
                }
                else if (this.isOp2()) {
                    if ((expected & FUNCTION) === 0) {
                        this.error_parsing(this.pos, "unexpected function");
                    }
                    this.addfunc(tokenstack, operstack, TOP2);
                    noperators += 2;
                    expected = (LPAREN);
                }
                else if (this.isOp1()) {
                    if ((expected & FUNCTION) === 0) {
                        this.error_parsing(this.pos, "unexpected function");
                    }
                    this.addfunc(tokenstack, operstack, TOP1);
                    noperators++;
                    expected = (LPAREN);
                }
                else if (this.isVar()) {
                    if ((expected & PRIMARY) === 0) {
                        this.error_parsing(this.pos, "unexpected variable");
                    }
                    var vartoken = new Token(TVAR, this.tokenindex, 0, 0);
                    tokenstack.push(vartoken);

                    expected = (OPERATOR | RPAREN | COMMA | LPAREN | CALL);
                }
                else if (this.isWhite()) {
                }
                else {
                    if (this.errormsg === "") {
                        this.error_parsing(this.pos, "unknown character");
                    }
                    else {
                        this.error_parsing(this.pos, this.errormsg);
                    }
                }
            }
            if (this.tmpprio < 0 || this.tmpprio >= 10) {
                this.error_parsing(this.pos, "unmatched \"()\"");
            }
            while (operstack.length > 0) {
                var tmp = operstack.pop();
                tokenstack.push(tmp);
            }
            if (noperators + 1 !== tokenstack.length) {
                //print(noperators + 1);
                //print(tokenstack);
                this.error_parsing(this.pos, "parity");
            }

            return new Expression(tokenstack, object(this.ops1), object(this.ops2), object(this.functions));
        },

        evaluate: function (expr, variables) {
            return this.parse(expr).evaluate(variables);
        },

        error_parsing: function (column, msg) {
            this.success = false;
            this.errormsg = "parse error [column " + (column) + "]: " + msg;
            throw new Error(this.errormsg);
        },

//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\

        addfunc: function (tokenstack, operstack, type_) {
            var operator = new Token(type_, this.tokenindex, this.tokenprio + this.tmpprio, 0);
            while (operstack.length > 0) {
                if (operator.prio_ <= operstack[operstack.length - 1].prio_) {
                    tokenstack.push(operstack.pop());
                }
                else {
                    break;
                }
            }
            operstack.push(operator);
        },

        isNumber: function () {
            var r = false;
            var str = "";
            while (this.pos < this.expression.length) {
                var code = this.expression.charCodeAt(this.pos);
                if ((code >= 48 && code <= 57) || code === 46) {
                    str += this.expression.charAt(this.pos);
                    this.pos++;
                    this.tokennumber = parseFloat(str);
                    r = true;
                }
                else {
                    break;
                }
            }
            return r;
        },

        // Ported from the yajjl JSON parser at http://code.google.com/p/yajjl/
        unescape: function(v, pos) {
            var buffer = [];
            var escaping = false;

            for (var i = 0; i < v.length; i++) {
                var c = v.charAt(i);

                if (escaping) {
                    switch (c) {
                    case "'":
                        buffer.push("'");
                        break;
                    case '\\':
                        buffer.push('\\');
                        break;
                    case '/':
                        buffer.push('/');
                        break;
                    case 'b':
                        buffer.push('\b');
                        break;
                    case 'f':
                        buffer.push('\f');
                        break;
                    case 'n':
                        buffer.push('\n');
                        break;
                    case 'r':
                        buffer.push('\r');
                        break;
                    case 't':
                        buffer.push('\t');
                        break;
                    case 'u':
                        // interpret the following 4 characters as the hex of the unicode code point
                        var codePoint = parseInt(v.substring(i + 1, i + 5), 16);
                        buffer.push(String.fromCharCode(codePoint));
                        i += 4;
                        break;
                    default:
                        throw this.error_parsing(pos + i, "Illegal escape sequence: '\\" + c + "'");
                    }
                    escaping = false;
                } else {
                    if (c == '\\') {
                        escaping = true;
                    } else {
                        buffer.push(c);
                    }
                }
            }

            return buffer.join('');
        },

        isString: function () {
            var r = false;
            var str = "";
            var startpos = this.pos;
            if (this.pos < this.expression.length && this.expression.charAt(this.pos) == "'") {
                this.pos++;
                while (this.pos < this.expression.length) {
                    var code = this.expression.charAt(this.pos);
                    if (code != "'" || str.slice(-1) == "\\") {
                        str += this.expression.charAt(this.pos);
                        this.pos++;
                    }
                    else {
                        this.pos++;
                        this.tokennumber = this.unescape(str, startpos);
                        r = true;
                        break;
                    }
                }
            }
            return r;
        },

        isConst: function () {
            var str;
            for (var i in this.consts) {
                if (true) {
                    var L = i.length;
                    str = this.expression.substr(this.pos, L);
                    if (i === str) {
                        this.tokennumber = this.consts[i];
                        this.pos += L;
                        return true;
                    }
                }
            }
            return false;
        },

        isOperator: function () {
            var code = this.expression.charCodeAt(this.pos);
            if (code === 43) { // +
                this.tokenprio = 0;
                this.tokenindex = "+";
            }
            else if (code === 45) { // -
                this.tokenprio = 0;
                this.tokenindex = "-";
            }
            else if (code === 124) { // |
                if (this.expression.charCodeAt(this.pos + 1) === 124) {
                    this.pos++;
                    this.tokenprio = 0;
                    this.tokenindex = "||";
                }
                else {
                    return false;
                }
            }
            else if (code === 42) { // *
                this.tokenprio = 1;
                this.tokenindex = "*";
            }
            else if (code === 47) { // /
                this.tokenprio = 2;
                this.tokenindex = "/";
            }
            else if (code === 37) { // %
                this.tokenprio = 2;
                this.tokenindex = "%";
            }
            else if (code === 94) { // ^
                this.tokenprio = 3;
                this.tokenindex = "^";
            }
            else {
                return false;
            }
            this.pos++;
            return true;
        },

        isSign: function () {
            var code = this.expression.charCodeAt(this.pos - 1);
            if (code === 45 || code === 43) { // -
                return true;
            }
            return false;
        },

        isPositiveSign: function () {
            var code = this.expression.charCodeAt(this.pos - 1);
            if (code === 43) { // -
                return true;
            }
            return false;
        },

        isNegativeSign: function () {
            var code = this.expression.charCodeAt(this.pos - 1);
            if (code === 45) { // -
                return true;
            }
            return false;
        },

        isLeftParenth: function () {
            var code = this.expression.charCodeAt(this.pos);
            if (code === 40) { // (
                this.pos++;
                this.tmpprio += 10;
                return true;
            }
            return false;
        },

        isRightParenth: function () {
            var code = this.expression.charCodeAt(this.pos);
            if (code === 41) { // )
                this.pos++;
                this.tmpprio -= 10;
                return true;
            }
            return false;
        },

        isComma: function () {
            var code = this.expression.charCodeAt(this.pos);
            if (code === 44) { // ,
                this.pos++;
                this.tokenprio = -1;
                this.tokenindex = ",";
                return true;
            }
            return false;
        },

        isWhite: function () {
            var code = this.expression.charCodeAt(this.pos);
            if (code === 32 || code === 9 || code === 10 || code === 13) {
                this.pos++;
                return true;
            }
            return false;
        },

        isOp1: function () {
            var str = "";
            for (var i = this.pos; i < this.expression.length; i++) {
                var c = this.expression.charAt(i);
                if (c.toUpperCase() === c.toLowerCase()) {
                    if (i === this.pos || c < '0' || c > '9') {
                        break;
                    }
                }
                str += c;
            }
            if (str.length > 0 && (str in this.ops1)) {
                this.tokenindex = str;
                this.tokenprio = 5;
                this.pos += str.length;
                return true;
            }
            return false;
        },

        isOp2: function () {
            var str = "";
            for (var i = this.pos; i < this.expression.length; i++) {
                var c = this.expression.charAt(i);
                if (c.toUpperCase() === c.toLowerCase()) {
                    if (i === this.pos || c < '0' || c > '9') {
                        break;
                    }
                }
                str += c;
            }
            if (str.length > 0 && (str in this.ops2)) {
                this.tokenindex = str;
                this.tokenprio = 5;
                this.pos += str.length;
                return true;
            }
            return false;
        },

        isVar: function () {
            var str = "";
            for (var i = this.pos; i < this.expression.length; i++) {
                var c = this.expression.charAt(i);
                if (c.toUpperCase() === c.toLowerCase()) {
                    if (i === this.pos || c < '0' || c > '9') {
                        break;
                    }
                }
                str += c;
            }
            if (str.length > 0) {
                this.tokenindex = str;
                this.tokenprio = 4;
                this.pos += str.length;
                return true;
            }
            return false;
        },

        isComment: function () {
            var code = this.expression.charCodeAt(this.pos - 1);
            if (code === 47 && this.expression.charCodeAt(this.pos) === 42) {
                this.pos = this.expression.indexOf("*/", this.pos) + 2;
                if (this.pos === 1) {
                    this.pos = this.expression.length;
                }
                return true;
            }
            return false;
        }
    };

    return Parser;
}();
projetmbc
Péta-utilisateur
 
Messages: 1895
Inscription: Samedi 29 Décembre 2007, 00:58
Statut actuel: Actif et salarié | Enseignant

Re: Exerciseur niveau lycée réalisé avec GeoGebra

Messagepar joelGa » Dimanche 28 Novembre 2010, 09:40

Merci beaucoup pour ce travail
J'ai un problème:
J'ai testé les fichiers, au lancement du fichier HTML j'obtiens le code d'erreur
Erreur : MathJax is not defined
Fichier Source : .................... Mon fichier .........html
Ligne : 24

La connexion au fichier http://www.mathjax.org/mathjax/MathJax.js se fait pourtant correctement.
Faut-il installer un pluging à Firefox ?

Merci d'avance pour ta réponse
Joël
joelGa
Utilisateur
 
Messages: 7
Inscription: Vendredi 19 Novembre 2010, 12:43
Statut actuel: Actif et salarié | Enseignant

Suivante

Retourner vers Logiciels mathématiques

 


  • Articles en relation
    Réponses
    Vus
    Dernier message

Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 1 invité