Si pour lui toutes les opérandes sont vraies cela vient a priori des entrées du dictionnaire, pas de l'algorithme. Encore une fois le débogage pas-à-pas avec l'inspection des valeurs à tout instant permettra de vérifier cette hypothèse.
Si pour lui toutes les opérandes sont vraies cela vient a priori des entrées du dictionnaire, pas de l'algorithme. Encore une fois le débogage pas-à-pas avec l'inspection des valeurs à tout instant permettra de vérifier cette hypothèse.
je crois que l'on ne sait pas compris.
Je t'explique si je saisi 4 paramètres et que ma règle correspond à ceci :
(1&2)|(3&4).
Il faut qu'en sorti j'ai false car je dois avoir saisi soit 1&2 soit 3&4.
Mon dictionnaire aura en entrée :
1 True
2 True
3 True
4 True
Ce qui est juste car cela correspond à la saisi des paramètres.
Effectivement on ne se comprend pas : vrai & vrai donne vrai, vrai | vrai donne vrai. Donc l'algo a raison de renvoyer "vrai".
Tout mon algo est foireux. Il faut que je le reprenne alors.
Pourrais tu m'aider sur ce coup?
Merci
Justement, non, l'algo est juste d'après l'exemple que tu donnes.
Ou alors est-ce que tu veux dire que tu t'es trompé de problème ?
Qu'est-ce qui ne va pas ?
Je t'explique mon but.
Il me faut une fonction qui me renvoi un booleen.
Cette fonction a en entrée une règle et un dictionnaire:
- règle : peut etre de type (1&2)|(3&4)
- dictionnaire est de type <int,booleen>. Le int correspond au numéro du paramètre et le booleen permet de savoir si ce paramètre a été renseigné.
Mon but est en fonction de la règle renvoyé un booleen qui check si les paramètres sont saisie en fonction de la règle.
Si j'ai rule = (1&2)|(3&4)
et dictionnaire =
1 True
2 True
3 True
4 True
alors je dois renvoyé false car ma rule contient un |(ou). Je devrais avoir soit (1&2) de saisi soit (3&4).
Il peut y avoir toute sorte de règle mais elles sont bien regroupé dans des parenthèses et mon dictionnaire sera toujours bien renseigné en fonction de la saisie des param.
J'espere avoir été clair sur mon but. J'espere aussi que l'on trouvera un moyen de mettre cela en place pour tout type de règle.
Merci
Désolé mais ça n'a aucun sens, tu fais une erreur de logiquecar (vrai & vrai) | (vrai & vrai) est vrai.
Vrai & vrai -> vrai
Vrai | vrai -> vrai.
Si tu veux que vrai $ vrai renvoie faux, alors $ n'est pas la règle "OU" (|). Est-ce que tu ne confonds pas avec le OU exclusif (^) ?
"|" veut dire "A ou B ou les deux"
"^" veut dire "soit A soit B mais pas les deux".
C'est exactement ce que je veux avec le ^. Je pensais pas qu'il servait à cela. Je ne l'avais jamais utilisé.
Cela signifie que j'ai juste à modifier mon code au niveau du |et mettre ^.
C'est bien cela ?
Merci pour ton aide. J'ai appris plein de choses
J'ai effectué des tests avec le ^ mais ça ne marche pas pour tous les cas.
si j'ai vrai^vrai => false ok pour moi
si j'ai vrai^false => vrai nok pour moi
si j'ai false^vrai => false ok pour moi
si j'ai false^false => false ok pour moi
Il manque un cas à gérer vrai^false
La table de l'opérateur ^est :
1^1 -> 0
1^0 -> 1
0^1 -> 1
0^0 -> 0
D'après ce que tu nous décris il y a donc deux problèmes :
* L'algo a un bogue car il ne respecte pas cette table de vérité.
* Tu t'es encore trompé dans ce que tu veux : si ton programme doit toujours renvoyer faux, alors remplace tout le code par "return false".
J'ai l'impression que tout cela t'énerve et j'en suis vraiment désole.
Tout dépend de ma règle. En fonction de ma règle et de la saisi de mes paramètres alors je renvois vrai ou faux.
si j'ai (1&2) et que 1 et 2 sont saisi alors je renvoi Vrai
si j'ai (1&2) et que 1 saisi et 2 non saisi alors je renvoi false
etc
si j'ai (1&2)|(3&4) et que 1,2,3,4 saisi alors je renvoi false car d'après ma règle je devrai avoir que 1&2 de saisi ou 3&4 mais pas les quatre.
j'espère être assez clair dans mon explication.
Je ne suis pas du tout énervé. Mais tu n'arrives pas à expliquer correctement ce que tu veux ou quel est ton problème.
Là tu me dis que (1&1)^(1&1) doit donner 0. Je suis parfaitement d'accord mais tu m'as dit que ça fonctionnait dans ton précédent message. Ça ne fonctionne plus ? Si oui à quel moment est-ce que ça plante ? Au passage je présume que tu voulais écrire "^" et non "|", sinon le comportement est normal.
Relis mon précédent message (#50) : tes attentes correspondent-elles à la table que j'avais donnée ?
Je ne sais toujours pas ce que tu veux ni ce qui ne va pas. Essaie d'être plus formel et plus clair. Utilise une table de vérité au besoin, etc.
Salut,
je suis de retour et désolé pour mon absence j'étais pris sur un autre projet.
Alors je savais que j'allais pas trop me faire comprendre vu la complexité de mon algo. Mais je vais reprendre avec une table de vérité comme demandé.
La table de l'opérateur ^ est :
1^1 -> 0
1^0 -> 1
0^1 -> 1
0^0 -> 0
La table de l'opérateur & est :
1&1 -> 1
1&0 -> 0
0&1 -> 0
0&0 -> 0
Plusieurs Exemples détaillés par rapport à mes règles et que j'ai testé avec l'algo:
(1&1)^(1&1) ==> (1)^(1) => 0 (j'obtiens ce résultat avec l'algo)
(0&0)^(0&0) ==> (0)^(0) => 0 (j'obtiens ce résultat avec l'algo)
(1&1)^(0&0) ==> (1)^(0) => 1 (j'obtiens ce résultat avec l'algo)
(0&0)^(1&1) ==> (0)^(1) => 1 (je n'obtiens pas ce résultat avec l'algo, mon algo me renvoi 0)
D'autres exemples de fonctionnement voulu:
(1&0)^(1&1) ==> 0 je devrais obtenir 0 en retour car d'après ma règle seule la première parenthèse ou la deuxième doit être rempli. Si j'ai des données saisi dans la 1er et la 2eme je dois renvoyer false
Tout dépend de ma règle. si j'ai ^alors seul il faut checker que seul un lot de donnée d'une parenthèse doit être renseigné. Il faut aussi vérifier que le & dans la parenthèse est ok c'est dire que les 2 doit être renseigné.
C'est un peu complexe et pas simple à comprendre et expliquer mais je fais de mon mieux.
Sincèrement, n'hésite pas à revenir vers moi pour toute autres explications et si tu le souhaites on peut reprendre pas à pas le détail de l'explication
Merci pour ta patience et ton aide précieuse DonQuiche
Je te remercie pour ce dernier message, qui est très clair.
Voici mes remarques:
* Ce que tu veux est bien la règle "^" (ou exclusif). Et il y a bien un bogue dans le programme au vu du premier problème. Pourrais-tu me montrer ton code actuel s'il te plaît ? Et quid du débogage pas-à-pas ? As-tu notamment vérifié les valeurs retournées pour les deux opérandes de "^" ?
* Je t'invite à refaire le cas problématique en plaçant un point d'arrêt (F9) sur la dernière ligne de ta fonction principale ("return resultat") et à me donner les valeurs successives rencontrées pour resultat au cours d'une exécution (F5, relève, F5, relève, F5, relève, etc). Normalement ça devrait être dans l'ordre :
0 (pour "a")
0 (pour "b")
0 (pour "a&b")
0 (pour "(a&b)")
1 (pour "c")
1 (pour "d")
1 (pour "c&d")
1 (pour "(c&d)")
1 (pour "(a&b)^(c&d)")
* Concernant le deuxième problème, en réalité (1&0)^(1&1) -> 0^1 -> 1, et non pas 0 comme tu l'avais écrit. Pas de bogue ici. Le comportement que tu semble décrire me fait plutôt penser à (a|b)^(c|d).
Merci pour ton retour
Voici mon code actuel
Mon appel pour la fonction checkRule:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 protected bool checkRule(string rules, Dictionary<int?, bool> groupValids,ref int position) { int len = rules.Length; bool resultat =true; if (string.IsNullOrEmpty(rules)) return true; if (PositionValide(rules,position)) { if (PositionValide(rules,position) && rules[position] == '(') { position++; resultat &= checkRule(rules, groupValids, ref position); } else { string operande = LireNombre(rules, ref position); if (!string.IsNullOrEmpty(operande)) { resultat = groupValids[int.Parse(operande)]; //position++; resultat &= checkRule(rules, groupValids, ref position); } } if (PositionValide(rules,position) && rules[position] == '&') { position++; resultat &= checkRule(rules, groupValids, ref position); } if (PositionValide(rules,position) && rules[position] == '|') { position++; resultat ^= checkRule(rules, groupValids, ref position); } if (PositionValide(rules,position) && rules[position] == ')') { position++; resultat &= checkRule(rules, groupValids, ref position); } } return resultat; }
rules = (1&2)|(3&4)
groupvalids =
1,False
2,False
3,true
4,true
5,true (mais à ne pas prendre en compte car pas dans la règle)
position = 0
Voici le résultat que j'obitens en effectuant le debug comme tu me l'as dit:
1
1
1
1
1
1
0
0
0
0
0
0
Voila
Sinon concernant le |ce n'est pas précisément ce que je veux car si je fais cela je serais pas bon dans d'autres cas pour mon debug
Ok, je vois le problème avec ton code : tu as des appels inutiles à checkRule, qui sèment la pagaille. Rappelle-toi que checkRule est supposé parser l'opérande sur laquelle le code est positionné. Il n'y a aucune raison de parser une opérande après un nombre ou après une parenthèse fermée.
Tu vois maintenant l'intérêt d'écrire un code qui plante en cas de problème : ce bogue aurait été détecté plus tôt parce que l'algo t'aurait sauté au visage. Par exemple si tu vires te test "string.IsNullOrEmpty(operande)" alors ton code actuel lèvera une erreur parce que tu appelles checkRule au mauvais moment. Du coup en remontant dans la pile d'appel tu tomberas sur la ligne problématique. Même chose si tu avais remis le test pour la parenthèse fermante dans le bloc gérant la parenthèse ouverte.
Tout ça étant dit, deux problèmes qui rendent ton code confus à la lecture :
* Tu as des "&=" inutiles. A l'exception du cas de l'opérateur "&" ce devraient être de simples assignations.
* Tu devrais réécrire tes règles pour y remplacer "|" par "^" plutôt que redéfinir le sens de "|" dans ton code. Si tu désignes un chat, ne l'appelle pas "un chien", c'est le meilleur moyen pour rendre ton code incompréhensible et causer des bogues plus tard.
* Si tu utilises l'anglais, utilises un anglais correct : validGroups, et non pas groupValids.
J'ai l'impression qu'en fait, voici l'ensemble des règles qui se cachent derrière sa syntaxe "(a&b)|(c&d)" :
C'est à dire que le formulaire est découpé en deux parties :
Partie 1 contenant les champs A et B.
Partie 2 contenant les champs C etD.
Il faut que tous les champs d'une seule des deux parties soient tous remplis, et que tous les champs de l'autre ne le soient pas.
Donc c'est vrai si (combinaison avec un et logique) :
1/ a égale à b
2/ c égale à d
3/ a différent c
Ce qui donne, si je ne m'abuse :
(a&b)|(c&d)&!(a&c)
Non ?
On ne jouit bien que de ce qu’on partage.
Peut-être bien. Si tu as raison sur ton interprétation de ses propos alors la formule serait plutôt (tous trois équivalents) :
"(a et b mais ni c ni d) OU (c et d mais ni a ni b)"
((a&b) & !(c|d)) | ((c&d) & !(a|b))
(a & b & !c & !d) | (c & d & !a & !b)
Tes trois points sont justes mais la traduction serait en fait :Donc c'est vrai si (combinaison avec un et logique) :
1/ a égale à b
2/ c égale à d
3/ a différent c
Ce qui donne, si je ne m'abuse :
(a&b)|(c&d)&!(a&c)
!(a^b) & !(c^d) & (a^c)
On doit pouvoir prouver que c'est équivalent aux deux autres.
En effet le "ou exclusif" est vrai si et seulement si les deux opérandes sont distinctes. Le "et" correspond pour sa part à "toutes deux vraies".
C'est tout à fait ça qu'il me faut stringBuilder.
Mon formulaire est découpé en fonction de ma règle.
Du coup en fonction du & et du |(correspond ^), je dois gérer la saisi des champs.
Comme vous l'avez indiqué, si (a&b)|(c&d) alors:
"(a et b mais ni c ni d) OU (c et d mais ni a ni b)"
Bien évidement tout doit s'adapter à ma règle qui peut être écrite de différentes manières en fonction de mes formulaires.
si j'ai (a&b&c)|(d) alors (a et b et c mais ni d) OU (d mais ni a et b et c)
etc etc
Du coup, ai je un gros changement à faire dans mon code ?
Que dois je retirer ou ajouter car la je n'ai pas compris ce que tu veux dire ?Tu vois maintenant l'intérêt d'écrire un code qui plante en cas de problème : ce bogue aurait été détecté plus tôt parce que l'algo t'aurait sauté au visage. Par exemple si tu vires te test "string.IsNullOrEmpty(operande)" alors ton code actuel lèvera une erreur parce que tu appelles checkRule au mauvais moment. Du coup en remontant dans la pile d'appel tu tomberas sur la ligne problématique. Même chose si tu avais remis le test pour la parenthèse fermante dans le bloc gérant la parenthèse ouverte.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager