L'IA à créer l'Evaluateur et moi le Vérificateur.
Code : Tout sélectionner
; Fonction pour valider une chaîne représentant une expression mathématique.
; Créer par Shadow (Dieppedalle David) le 10/12/2024.
Procedure.s CheckMathExpression(Expression$)
; Si l'expression est vide ou ne contient que des espaces.
If Expression$ = "" Or ReplaceString(Expression$, Chr(32), "") = ""
ProcedureReturn "Erreur: L'expression est vide."
Else
; Initialisation des variables nécessaires à la validation.
ParenthesesCount.i = 0 ; Compteur pour suivre l'équilibre des parenthèses ouvrantes et fermantes.
LastChar.s = "" ; Précédent caractère significatif analysé.
PositionLastChar.i = 0 ; Position du précédent caractère significatif.
CurrentChar.s = "" ; Caractère actuellement analysé.
NombreVirgule.b = #False ; Indicateur de la gestion des virgules dans un nombre décimal.
ExpressionLength.i = Len(Expression$) ; Longueur totale de l'expression.
; Parcourir chaque caractère de l'expression.
For IndexExpression.i = 1 To ExpressionLength.i
; Extraire le caractère actuel.
CurrentChar.s = Mid(Expression$, IndexExpression.i, 1)
; Vérifier que le caractère est autorisé.
If Not FindString("0123456789+-*/(), ", CurrentChar.s)
ProcedureReturn "Erreur: Caractère non autorisé '" + CurrentChar.s + "' à la position " + Str(IndexExpression.i) + "."
EndIf
; Gestion des parenthèses ouvrantes.
If CurrentChar.s = "("
; Vérification: une parenthèse ouvrante ne peut pas suivre une virgule.
If LastChar.s = ","
ProcedureReturn "Erreur: Chiffre manquant après la Virgule à la position " + Str(PositionLastChar.i) + ": " + LastChar.s
EndIf
ParenthesesCount.i + 1 ; Incrémenter le compteur de parenthèses ouvrantes.
; Réinitialiser le suivi des virgules.
If NombreVirgule.b = #True
NombreVirgule.b = #False
EndIf
; Gestion des parenthèses fermantes.
ElseIf CurrentChar.s = ")"
; Vérification: parenthèse fermante inattendue.
If ParenthesesCount.i <= 0
ProcedureReturn "Erreur: Parenthèse fermante inattendue à la position " + Str(IndexExpression.i) + "."
Else
ParenthesesCount.i -1 ; Décrémenter le compteur de parenthèses.
; Vérifications contextuelles pour la parenthèse fermante.
If LastChar.s = "+" Or LastChar.s = "-" Or LastChar.s = "*" Or LastChar.s = "/"
ProcedureReturn "Erreur: Opérateur invalide à la position " + Str(PositionLastChar.i) + ": " + LastChar.s
ElseIf LastChar.s = ","
ProcedureReturn "Erreur: Chiffre manquant après la Virgule à la position " + Str(PositionLastChar.i) + "."
ElseIf LastChar.s = "("
ProcedureReturn "Erreur: Parenthèse vide à la position " + Str(IndexExpression.i) + "."
EndIf
EndIf
; Réinitialiser le suivi des virgules.
If NombreVirgule.b = #True
NombreVirgule.b = #False
EndIf
; Gestion des chiffres
ElseIf (CurrentChar.s >= "0" And CurrentChar.s <= "9")
; Vérification: un chiffre ne peut pas suivre une parenthèse fermante.
If LastChar.s = ")"
ProcedureReturn "Erreur: Parenthèse fermante invalide à la position " + Str(PositionLastChar.i)
EndIf
; Gestion des opérateurs (+, -, *, /)
ElseIf CurrentChar.s = "+" Or CurrentChar.s = "-" Or CurrentChar.s = "*" Or CurrentChar.s = "/"
; Réinitialiser le suivi des virgules après un opérateur.
If NombreVirgule.b = #True
NombreVirgule.b = #False
EndIf
; Vérification: un opérateur ne peut pas suivre un autre opérateur ou être isolé, sauf cas particulié pour l'oppérateur "-".
; Exemples qui fonctionne: 45 - -12 | 21 + -36 | 67 * -91 | 37 / -29.
; Si le précédent caractère n'est pas un chiffre, sinon c'est bon.
If (LastChar.s < "0" Or LastChar.s > "9")
Select CurrentChar.s
Case "+", "*", "/" ; Le caracère actuel est un Oppérateur autre que "-".
If LastChar.s = "+" Or LastChar.s = "-" Or LastChar.s = "*" Or LastChar.s = "/" Or LastChar.s = "(" Or LastChar.s = "" ; Si le précédent caractère n'est pas un Oppérateur ni "(", ni rien.
ProcedureReturn "Erreur: Opérateur invalide à la position " + Str(IndexExpression.i) + ": " + CurrentChar.s
EndIf
Case "-" ; Le caracère actuel est "-", cas spécial ici.
If LastChar.s = ","
ProcedureReturn "Erreur: Chiffre manquant après la Virgule à la position " + Str(PositionLastChar.i) + "."
EndIf
Default
EndSelect
If LastChar.s = "," ; Si le précédent caractère est une virgule.
ProcedureReturn "Erreur: Chiffre manquant après la Virgule à la position " + Str(PositionLastChar.i) + "."
EndIf
EndIf
; Gestion des virgules.
ElseIf CurrentChar.s = ","
; Vérification: une virgule ne peut pas suivre une autre virgule.
If LastChar.s = ","
ProcedureReturn "Erreur: Chiffre manquant après la Virgule à la position " + Str(PositionLastChar.i) + "."
; Vérification: une virgule doit suivre un chiffre.
ElseIf (LastChar.s < "0" Or LastChar.s > "9")
ProcedureReturn "Erreur: Virgule invalide à la position " + Str(IndexExpression.i) + "."
EndIf
; Mettre à jour le suivi des virgules.
If NombreVirgule.b = #False
NombreVirgule.b = #True
Else
ProcedureReturn "Erreur: Virgule invalide à la position " + Str(IndexExpression.i) + "."
EndIf
; Ignorer les espaces.
ElseIf CurrentChar.s = " "
Continue
EndIf
; Mise à jour des informations sur le précédent caractère significatif.
If CurrentChar.s <> Chr(32)
LastChar.s = CurrentChar.s
PositionLastChar.i = IndexExpression.i
EndIf
Next
; Vérification finale après la fin de la boucle.
If LastChar.s = "+" Or LastChar.s = "-" Or LastChar.s = "*" Or LastChar.s = "/"
ProcedureReturn "Erreur: Opérateur invalide à la position " + Str(PositionLastChar.i) + ": " + LastChar.s
ElseIf LastChar.s = "("
ProcedureReturn "Erreur: Parenthèse ouvrante invalide à la position " + Str(PositionLastChar.i) + "."
ElseIf ((LastChar.s < "0" Or LastChar.s > "9") And LastChar.s <> ")")
ProcedureReturn "Erreur: Caractère invalide à la position " + Str(PositionLastChar.i) + ": " + LastChar.s
EndIf
; Vérification de l'équilibre des parenthèses.
If ParenthesesCount.i <> 0
ProcedureReturn "Erreur: Parenthèse fermante manquante à la position " + Str(IndexExpression.i) + "."
EndIf
EndIf
; Si aucune erreur n'a été détectée, retourner "Pas d'erreur".
ProcedureReturn "Pas d'erreur."
EndProcedure
; Code Créé par ChatGpt le 08/12/2024.
; ---
; Fonction pour remplacer les virgules par des points dans une chaîne
Procedure.s ReplaceCommaWithDot(Expression$)
ProcedureReturn ReplaceString(Expression$, ",", ".")
EndProcedure
; Fonction pour déterminer la priorité des opérateurs
Procedure.i GetOperatorPrecedence(op$)
Select op$
Case "+", "-": ProcedureReturn 1
Case "*", "/": ProcedureReturn 2
Default: ProcedureReturn 0
EndSelect
EndProcedure
; Fonction pour appliquer un opérateur à deux valeurs
Procedure.d ApplyOperator(a.d, b.d, op$)
Select op$
Case "+": ProcedureReturn a + b
Case "-": ProcedureReturn a - b
Case "*": ProcedureReturn a * b
Case "/": ProcedureReturn a / b
EndSelect
EndProcedure
; Fonction pour analyser et évaluer une expression mathématique
Procedure.d EvaluateExpression(Expression$)
Protected operators$ = "+-*/()"
Protected NewList stackOperators.s()
Protected NewList stackValues.d()
Protected tempNumber.s
Protected i.i, result.d
; Vérifie avant l'expression pour voir si elle est correcte.
If CheckMathExpression(Expression$) = "Pas d'erreur."
; Remplacer les virgules par des points
Expression$ = ReplaceCommaWithDot(Expression$)
; Parcourir chaque caractère de l'expression
For i = 1 To Len(Expression$)
Define char.s = Mid(Expression$, i, 1)
If FindString("0123456789.", char)
tempNumber + char
ElseIf FindString(operators$, char)
If tempNumber <> ""
AddElement(stackValues())
stackValues() = ValD(tempNumber)
tempNumber = ""
EndIf
If char = "("
AddElement(stackOperators())
stackOperators() = char
ElseIf char = ")"
While ListSize(stackOperators()) > 0 And LastElement(stackOperators()) And stackOperators() <> "("
Define op.s = stackOperators()
DeleteElement(stackOperators())
Define b.d = stackValues()
DeleteElement(stackValues())
Define a.d = stackValues()
DeleteElement(stackValues())
result = ApplyOperator(a, b, op)
AddElement(stackValues())
stackValues() = result
Wend
DeleteElement(stackOperators())
Else
While ListSize(stackOperators()) > 0 And LastElement(stackOperators()) And GetOperatorPrecedence(stackOperators()) >= GetOperatorPrecedence(char)
Define op.s = stackOperators()
DeleteElement(stackOperators())
Define b.d = stackValues()
DeleteElement(stackValues())
Define a.d = stackValues()
DeleteElement(stackValues())
result = ApplyOperator(a, b, op)
AddElement(stackValues())
stackValues() = result
Wend
AddElement(stackOperators())
stackOperators() = char
EndIf
EndIf
Next
If tempNumber <> ""
AddElement(stackValues())
stackValues() = ValD(tempNumber)
EndIf
While ListSize(stackOperators()) > 0
Define op.s = stackOperators()
DeleteElement(stackOperators())
Define b.d = stackValues()
DeleteElement(stackValues())
Define a.d = stackValues()
DeleteElement(stackValues())
result = ApplyOperator(a, b, op)
AddElement(stackValues())
stackValues() = result
Wend
ProcedureReturn stackValues()
Else
ProcedureReturn 0
EndIf
EndProcedure
; ---
; Exemple 1
Expression$ = "(2+3)*4"
Debug "Expression: " + Expression$
Debug "Vérification de l'expression: " + CheckMathExpression(Expression$)
Debug "Calcule évalué: " + StrD(EvaluateExpression("(2+3)*4")) ; Résultat attendu : 20
; Étapes :
; (2+3) = 5
; 5*4 = 20
Debug "Calcule direct: " + StrD((2+3)*4) ; Résultat attendu : 20
Debug "----"
; Exemple 2
Expression$ = "2*(3+(4*5))"
Debug "Expression: " + Expression$
Debug "Vérification de l'expression: " + CheckMathExpression(Expression$)
Debug "Calcule évalué: " + StrD(EvaluateExpression("2*(3+(4*5))")) ; Résultat attendu : 46
; Étapes :
; (4*5) = 20
; (3+20) = 23
; 2*23 = 46
Debug "Calcule direct: " + StrD(2*(3+(4*5))) ; Résultat attendu : 46
Debug "----"
; Exemple 3
Expression$ = "((2+3)*4)/2"
Debug "Expression: " + Expression$
Debug "Vérification de l'expression: " + CheckMathExpression(Expression$)
Debug "Calcule évalué: " + StrD(EvaluateExpression("((2+3)*4)/2")) ; Résultat attendu : 10
; Étapes :
; (2+3) = 5
; (5*4) = 20
; 20/2 = 10
Debug "Calcule direct: " + StrD(((2+3)*4)/2) ; Résultat attendu : 10
Debug "----"
; Exemple 4
Expression$ = "29+(83*(47-82))/29"
Debug "Expression: " + Expression$
Debug "Vérification de l'expression: " + CheckMathExpression(Expression$)
Debug "Calcule évalué: " + StrD(EvaluateExpression("29+(83*(47-82))/29")) ; Résultat attendu : -71.1724137931
; Étapes :
; (47-82) = -35
; (83*-35) = -2905
; -2905/29 = -100.1724137931
; 29+(-100.1724137931) = -71.1724137931
Debug "Calcule direct: " + StrD(29+(83*(47-82))/29) ; Résultat attendu : -71.1724137931
Debug "----"
; Exemple 5
Expression$ = "2+3"
Debug "Expression: " + Expression$
Debug "Vérification de l'expression: " + CheckMathExpression(Expression$)
Debug "Calcule évalué: " + StrD(EvaluateExpression("2+3")) ; Résultat attendu : 5
; Étapes :
; 2+3 = 5
Debug "Calcule direct: " + StrD(2+3) ; Résultat attendu : 5
Debug "----"
; Exemple 6
Expression$ = "2+3*4"
Debug "Expression: " + Expression$
Debug "Vérification de l'expression: " + CheckMathExpression(Expression$)
Debug "Calcule évalué: " + StrD(EvaluateExpression("2+3*4")) ; Résultat attendu : 14
; Étapes :
; (3*4) = 12
; 2+12 = 14
Debug "Calcule direct: " + StrD(2+3*4) ; Résultat attendu : 14
Debug "----"
; Exemple 7
Expression$ = "10/2+5"
Debug "Expression: " + Expression$
Debug "Vérification de l'expression: " + CheckMathExpression(Expression$)
Debug "Calcule évalué: " + StrD(EvaluateExpression("10/2+5")) ; Résultat attendu : 10
; Étapes :
; (10/2) = 5
; 5+5 = 10
Debug "Calcule direct: " + StrD(10/2+5) ; Résultat attendu : 10
Debug "----"
; Exemple 8
Expression$ = "(2+3)*(4+5)"
Debug "Expression: " + Expression$
Debug "Vérification de l'expression: " + CheckMathExpression(Expression$)
Debug "Calcule évalué: " + StrD(EvaluateExpression("(2+3)*(4+5)")) ; Résultat attendu : 45
; Étapes :
; (2+3) = 5
; (4+5) = 9
; 5*9 = 45
Debug "Calcule direct: " + StrD((2+3)*(4+5)) ; Résultat attendu : 45
Debug "----"
; Exemple 9
Expression$ = "(10+5)/(2+3)"
Debug "Expression: " + Expression$
Debug "Vérification de l'expression: " + CheckMathExpression(Expression$)
Debug "Calcule évalué: " + StrD(EvaluateExpression("(10+5)/(2+3)")) ; Résultat attendu : 3
; Étapes :
; (10+5) = 15
; (2+3) = 5
; 15/5 = 3
Debug "Calcule direct: " + StrD((10+5)/(2+3)) ; Résultat attendu : 3
Debug "----"
; Exemple 10
Expression$ = "((2+3)*4)/(2+3)"
Debug "Expression: " + Expression$
Debug "Vérification de l'expression: " + CheckMathExpression(Expression$)
Debug "Calcule évalué: " + StrD(EvaluateExpression("((2+3)*4)/(2+3)")) ; Résultat attendu : 4
; Étapes :
; (2+3) = 5
; (5*4) = 20
; 20/5 = 4
Debug "Calcule direct: " + StrD(((2+3)*4)/(2+3)) ; Résultat attendu : 4
Debug "----"
; Exemple 11
Expression$ = "(5-10)*(3+7)"
Debug "Expression: " + Expression$
Debug "Vérification de l'expression: " + CheckMathExpression(Expression$)
Debug "Calcule évalué: " + StrD(EvaluateExpression("(5-10)*(3+7)")) ; Résultat attendu : -50
; Étapes :
; (5-10) = -5
; (3+7) = 10
; -5*10 = -50
Debug "Calcule direct: " + StrD((5-10)*(3+7)) ; Résultat attendu : -50
Debug "----"
; Exemple 12
Expression$ = "(((8+2)*3)-10)/(5+(7-3))"
Debug "Expression: " + Expression$
Debug "Vérification de l'expression: " + CheckMathExpression(Expression$)
Debug "Calcule évalué: " + StrD(EvaluateExpression("(((8+2)*3)-10)/(5+(7-3))")) ; Résultat attendu : 2.2222222222
; Étapes :
; (8+2) = 10
; (10*3) = 30
; (30-10) = 20
; (7-3) = 4
; (5+4) = 9
; 20/9 = 2.2222222222
Debug "Calcule direct: " + StrD((((8+2)*3)-10)/(5+(7-3))) ; Résultat attendu : 2.2222222222
Debug "----"
; Exemple 13
Expression$ = "496587,125478963 * 65123,397845412"
Debug "Expression: " + Expression$
Debug "Vérification de l'expression: " + CheckMathExpression(Expression$)
Debug "Calcule évalué: " + StrD(EvaluateExpression("496587,125478963 * 65123,397845412")) ; Résultat attendu : 32339440937.4760398865
; Étapes :
; Remplacement des virgules par des points
; (496587.125478963 * 65123.397845412) = 32339440937.4760398865
Debug "Calcule direct: " + StrD(496587.125478963 * 65123.397845412) ; Résultat attendu : 32339440937.4760398865
Debug "----"
; Exemple 14
Expression$ = "1,5 + 2,75"
Debug "Expression: " + Expression$
Debug "Vérification de l'expression: " + CheckMathExpression(Expression$)
Debug "Calcule évalué: " + StrD(EvaluateExpression("1,5 + 2,75")) ; Résultat attendu : 4.25
; Étapes :
; Remplacement des virgules par des points
; (1.5 + 2.75) = 4.25
Debug "Calcule direct: " + StrD(1.5 + 2.75) ; Résultat attendu : 4.25
Debug "----"
; Exemple 15
Expression$ = "10,0 / 3,2"
Debug "Expression: " + Expression$
Debug "Vérification de l'expression: " + CheckMathExpression(Expression$)
Debug "Calcule évalué: " + StrD(EvaluateExpression("10,0 / 3,2")) ; Résultat attendu : 3.125
; Étapes :
; Remplacement des virgules par des points
; (10.0 / 3.2) = 3.125
Debug "Calcule direct: " + StrD(10.0 / 3.2) ; Résultat attendu : 3.125
Debug "----"
; Exemple 16
Expression$ = "(10,5 + 2,25) * 4,1"
Debug "Expression: " + Expression$
Debug "Vérification de l'expression: " + CheckMathExpression(Expression$)
Debug "Calcule évalué: " + StrD(EvaluateExpression("(10,5 + 2,25) * 4,1")) ; Résultat attendu : 52.275
; Étapes :
; Remplacement des virgules par des points
; (10.5 + 2.25) = 12.75
; 12.75 * 4.1 = 52.275
Debug "Calcule direct: " + StrD((10.5 + 2.25) * 4.1) ; Résultat attendu : 52.275
Debug "----"
; Exemple 17
Expression$ = "29,5 + (83,75 * (47,5 - 82,25)) / 29,75"
Debug "Expression: " + Expression$
Debug "Vérification de l'expression: " + CheckMathExpression(Expression$)
Debug "Calcule évalué: " + StrD(EvaluateExpression("29,5 + (83,75 * (47,5 - 82,25)) / 29,75")) ; Résultat attendu : -68.3256302521
; Étapes :
; Remplacement des virgules par des points
; (47.5 - 82.25) = -34.75
; (83.75 * -34.75) = -2909.0625
; -2909.0625 / 29.75 = -97.8256302521
; 29.5 + (-97.8256302521) = -68.3256302521
Debug "Calcule direct: " + StrD(29.5 + (83.75 * (47.5 - 82.25)) / 29.75) ; Résultat attendu : -68.3256302521
Debug "----"
; Exemple 18
Expression$ = "(((200,5 + (50,25 * (6,5 - 4,25))) / (3,75 + 2,5)) * ((10,75 + 5,5) / (7,25 - 3,5)))"
Debug "Expression: " + Expression$
Debug "Vérification de l'expression: " + CheckMathExpression(Expression$)
Debug "Calcule évalué: " + StrD(EvaluateExpression("(((200,5 + (50,25 * (6,5 - 4,25))) / (3,75 + 2,5)) * ((10,75 + 5,5) / (7,25 - 3,5)))")) ; Résultat attendu : 217.4033333333
; Étapes :
; Remplacement des virgules par des points
; (6.5 - 4.25) = 2.25
; (50.25 * 2.25) = 113.0625
; (200.5 + 113.0625) = 313.5625
; (3.75 + 2.5) = 6.25
; (313.5625 / 6.25) = 50.169
; (10.75 + 5.5) = 16.25
; (7.25 - 3.5) = 3.75
; (16.25 / 3.75) = 4.3333333333
; (50.169 * 4.3333333333) = 217.4033333333
Debug "Calcule direct: " + StrD((((200.5 + (50.25 * (6.5 - 4.25))) / (3.75 + 2.5)) * ((10.75 + 5.5) / (7.25 - 3.5)))) ; Résultat attendu : 217.4033333333
Debug "----"