{"id":2504,"date":"2026-05-26T10:34:19","date_gmt":"2026-05-26T09:34:19","guid":{"rendered":"https:\/\/coding4phone.com\/?p=2504"},"modified":"2026-05-26T10:34:20","modified_gmt":"2026-05-26T09:34:20","slug":"evaluer-une-formule-mathematique-saisie-par-lutilisateur-avec-gizmo-et-mogwai","status":"publish","type":"post","link":"https:\/\/coding4phone.com\/?p=2504","title":{"rendered":"\u00c9valuer une formule math\u00e9matique saisie par l&rsquo;utilisateur avec GIZMO et MOGWAI"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">L&rsquo;application <strong>Formula Calculator<\/strong> est un exemple concret de ce qu&rsquo;on peut construire avec GIZMO en peu de lignes : l&rsquo;utilisateur saisit une formule math\u00e9matique avec une variable <code>X<\/code>, d\u00e9finit un intervalle et un pas, et obtient un tableau de valeurs calcul\u00e9es \u00e0 la vol\u00e9e.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"480\" height=\"448\" data-attachment-id=\"2505\" data-permalink=\"https:\/\/coding4phone.com\/?attachment_id=2505#main\" data-orig-file=\"https:\/\/i0.wp.com\/coding4phone.com\/wp-content\/uploads\/2026\/05\/formula.gif?fit=480%2C448&amp;ssl=1\" data-orig-size=\"480,448\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;,&quot;alt&quot;:&quot;&quot;}\" data-image-title=\"formula\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/coding4phone.com\/wp-content\/uploads\/2026\/05\/formula.gif?fit=480%2C448&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/coding4phone.com\/wp-content\/uploads\/2026\/05\/formula.gif?resize=480%2C448&#038;ssl=1\" alt=\"Interface d'une calculatrice de formules avec des champs pour entrer une formule, un d\u00e9but, une fin et un pas, ainsi qu'un bouton pour calculer.\" class=\"wp-image-2505\" style=\"width:619px;height:auto\"\/><figcaption class=\"wp-element-caption\">Interface TUI de formula.mog<\/figcaption><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Le code complet est disponible dans <a href=\"https:\/\/github.com\/Sydney680928\/Gizmo\/tree\/main\/examples\" target=\"_blank\" rel=\"noreferrer noopener\">les exemples du repo GIZMO<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Au-del\u00e0 du r\u00e9sultat visuel, cette petite app illustre trois patterns <a href=\"https:\/\/www.mogwai.eu.com\" target=\"_blank\" rel=\"noreferrer noopener\">MOGWAI<\/a> particuli\u00e8rement utiles que je vais d\u00e9tailler ici.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">1. Transformer une string en code ex\u00e9cutable avec <code>-&gt;code<\/code> et <code>eval<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">La formule est saisie par l&rsquo;utilisateur sous forme de texte \u2014 par exemple <code>2 X * 7 + X sin +<\/code>. C&rsquo;est une string ordinaire. Pour la calculer, il faut l&rsquo;ex\u00e9cuter comme du code MOGWAI.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">MOGWAI fournit <code>-&gt;code<\/code> pour compiler une string en un objet code, et <code>eval<\/code> pour l&rsquo;ex\u00e9cuter :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">wFormula ->code -> 'wFormula'<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\u00c0 partir de ce moment, <code>wFormula<\/code> n&rsquo;est plus une string mais un bloc de code pr\u00eat \u00e0 \u00eatre ex\u00e9cut\u00e9. Dans la boucle de calcul, pour chaque valeur de <code>X<\/code>, on affecte la variable et on ex\u00e9cute le code compil\u00e9 :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">wStart wEnd for 'X' step wStep do<br>{<br>    wFormula eval (.number) check -> 'v'<br>    &amp;values (! X v) +<br>}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">La formule est compil\u00e9e <strong>une seule fois<\/strong> avant la boucle. C&rsquo;est bien plus efficace que de parser la string \u00e0 chaque it\u00e9ration \u2014 sur de grands intervalles, la diff\u00e9rence est significative.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">2. Valider que les saisies sont bien des nombres<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Les champs D\u00e9but, Fin et Pas sont saisis sous forme de texte. Avant de lancer le calcul, il faut s&rsquo;assurer que ces valeurs sont des nombres valides. MOGWAI propose <code>-&gt;num<\/code> pour convertir une string en nombre \u2014 mais si la string n&rsquo;est pas un nombre valide, <code>-&gt;num<\/code> g\u00e9n\u00e8re une erreur.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">On s&rsquo;en sert justement pour d\u00e9tecter les entr\u00e9es invalides. Toute la fonction <code>calculate<\/code> est envelopp\u00e9e dans un <code>guard { } else { }<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">guard<br>{<br>    wFormula ->code -> 'wFormula'<br>    wStart ->num -> 'wStart'<br>    wEnd ->num -> 'wEnd'<br>    wStep ->num -> 'wStep'<br><br>    # ... boucle de calcul<br>}<br>else<br>{<br>    switch<br>    {<br>        (wStart ->type .number !=) then { \"start is not a valid number !\" }<br>        (wEnd   ->type .number !=) then { \"end is not a valid number !\" }<br>        (wStep  ->type .number !=) then { \"step is not a valid number !\" }<br>        (true) then { \"Error {! error.last}\" eval }<br>    }<br>}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Si l&rsquo;une des conversions \u00e9choue, l&rsquo;ex\u00e9cution saute directement dans le bloc <code>else<\/code>. Le <code>switch<\/code> identifie ensuite quelle entr\u00e9e est en cause et produit un message d&rsquo;erreur lisible. Le dernier cas <code>(true)<\/code> attrape les erreurs inattendues \u2014 par exemple une formule syntaxiquement invalide ou qui ne pousse pas de nombre sur la pile.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ce pattern <code>guard \/ switch<\/code> est une fa\u00e7on \u00e9l\u00e9gante de g\u00e9rer la validation sans multiplier les <code>if<\/code> imbriqu\u00e9s.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pour valider le r\u00e9sultat de la formule elle-m\u00eame, on utilise <code>(.number) check<\/code> :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">wFormula eval (.number) check -> 'v'<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>(.number) check<\/code> v\u00e9rifie que la valeur au sommet de la pile est bien de type <code>.number<\/code>. Si la formule pousse autre chose \u2014 une string, rien, plusieurs valeurs \u2014 l&rsquo;erreur est intercept\u00e9e par le <code>guard<\/code> et un message clair est affich\u00e9.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">3. Yielder le thread TUI avec <code>after 0 do { }<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Le calcul peut \u00eatre long selon l&rsquo;intervalle et le pas choisis. Avant de lancer le calcul, on vide le tableau et on met \u00e0 jour la statusbar pour indiquer \u00e0 l&rsquo;utilisateur que le calcul est en cours :<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">[window.update name: 'valuesTableview' rows: ()]<br>[window.update name: 'statusbar' title: \"Calculating...\"]<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Probl\u00e8me : MOGWAI et Terminal.Gui partagent le m\u00eame thread. Le calcul est bloquant \u2014 si on l&rsquo;ex\u00e9cute directement dans le <code>onClick:<\/code>, le moteur TUI n&rsquo;a pas l&rsquo;occasion de se redessiner. L&rsquo;utilisateur ne verra jamais le message \u00ab\u00a0Calculating&#8230;\u00a0\u00bb ni le tableau vid\u00e9.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La solution : <code>after 0 do { }<\/code>. Cette primitive MOGWAI diff\u00e8re l&rsquo;ex\u00e9cution du bloc de code au prochain cycle du moteur, en laissant Terminal.Gui rafra\u00eechir l&rsquo;\u00e9cran entre les deux.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">onClick: <br>{ <br>    [window.update name: 'valuesTableview' rows: ()]<br>    [window.update name: 'statusbar' title: \"Calculating...\"]<br><br>    after 0 do<br>    {<br>        now -> 'begin'<br><br>\t[!<br>            wFormula: {! [name: 'formulaEdit'] ui.gprop text: get}<br>            wStart: {! [name: 'startEdit'] ui.gprop text: get}<br>            wEnd: {! [name: 'endEdit'] ui.gprop text: get}<br>            wStep: {! [name: 'stepEdit'] ui.gprop text: get}<br>\t]<br><br>\tcalculate -> 'r'<br><br>\tnow begin - ->duration ms: get -> 'd'<br><br>\tif (r ->type .list ==) then<br>\t{<br>\t\t[! window.update name: 'valuesTableview' rows: r]<br>\t\t<br>                [! window.update <br>                    name: 'statusbar' <br>                    title: \"Ready - {! r size} values - calculation time {! d} ms\"<br>                ]<br>\t}<br>\telse<br>\t{<br>\t\t[window.update name: 'valuesTableview' rows: ()]<br>\t\t[! window.update name: 'statusbar' title: r]<br>\t}<br>    }<br>}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Le d\u00e9lai de <code>0<\/code> milliseconde suffit : on ne cherche pas \u00e0 attendre, juste \u00e0 c\u00e9der le contr\u00f4le au thread TUI le temps d&rsquo;un cycle. Le r\u00e9sultat est visible imm\u00e9diatement \u2014 l&rsquo;interface se met \u00e0 jour avant que le calcul commence.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">R\u00e9sultat<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ces trois patterns combin\u00e9s donnent une app r\u00e9active et robuste en quelques dizaines de lignes de MOGWAI. La formule est compil\u00e9e une fois, les entr\u00e9es sont valid\u00e9es proprement, et l&rsquo;interface reste fluide pendant le calcul.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Le code complet de Formula Calculator est disponible dans <a href=\"https:\/\/github.com\/Sydney680928\/Gizmo\/tree\/main\/examples\" target=\"_blank\" rel=\"noreferrer noopener\">les exemples du repo GIZMO<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Et si tu veux en savoir plus sur GIZMO ou MOGWAI :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Site GIZMO : <a href=\"https:\/\/gizmo.mogwai.eu.com\" target=\"_blank\" rel=\"noreferrer noopener\">gizmo.mogwai.eu.com<\/a><\/li>\n\n\n\n<li>Site MOGWAI : <a href=\"https:\/\/mogwai.eu.com\" target=\"_blank\" rel=\"noreferrer noopener\">mogwai.eu.com<\/a><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>L&rsquo;application Formula Calculator est un exemple concret de ce qu&rsquo;on peut construire avec GIZMO en peu de lignes : l&rsquo;utilisateur saisit une formule math\u00e9matique avec une variable X, d\u00e9finit un intervalle et un pas, et obtient un tableau de valeurs calcul\u00e9es \u00e0 la vol\u00e9e. Le code complet est disponible dans les exemples du repo GIZMO. &#8230; <a title=\"\u00c9valuer une formule math\u00e9matique saisie par l&rsquo;utilisateur avec GIZMO et MOGWAI\" class=\"read-more\" href=\"https:\/\/coding4phone.com\/?p=2504\" aria-label=\"En savoir plus sur \u00c9valuer une formule math\u00e9matique saisie par l&rsquo;utilisateur avec GIZMO et MOGWAI\">Lire la suite<\/a><\/p>\n","protected":false},"author":1,"featured_media":2515,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"D\u00e9couvrez l'application Formula Calculator, un exemple pratique de GIZMO pour calculer des formules math\u00e9matiques rapidement et efficacement.","jetpack_seo_html_title":"Cr\u00e9ez une calculatrice de formules avec GIZMO en MOGWAI","jetpack_seo_noindex":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_wpas_customize_per_network":false,"jetpack_post_was_ever_published":false},"categories":[8,152,6,48,50,9],"tags":[],"class_list":["post-2504","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","category-gizmo","category-mogwai","category-rpn","category-scripting","category-tutoriel"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/coding4phone.com\/wp-content\/uploads\/2026\/05\/coding-4-phone-6a1567efa93d6.png?fit=1024%2C1024&ssl=1","jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/pfoe4s-Eo","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/coding4phone.com\/index.php?rest_route=\/wp\/v2\/posts\/2504","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/coding4phone.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/coding4phone.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/coding4phone.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/coding4phone.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2504"}],"version-history":[{"count":10,"href":"https:\/\/coding4phone.com\/index.php?rest_route=\/wp\/v2\/posts\/2504\/revisions"}],"predecessor-version":[{"id":2516,"href":"https:\/\/coding4phone.com\/index.php?rest_route=\/wp\/v2\/posts\/2504\/revisions\/2516"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/coding4phone.com\/index.php?rest_route=\/wp\/v2\/media\/2515"}],"wp:attachment":[{"href":"https:\/\/coding4phone.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2504"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/coding4phone.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2504"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/coding4phone.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2504"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}