Question condition multiple (C++)

Bonjour à tous,

J'utilise un logiciel au boulot pour commander un automate, et le problème, c'est qu'il est très limité en terme de programation pure.

On a des "commandes pré-programmées", mais dès qu'on se trouve dans un cas un peu plus complexe, on est limité.

Pour compenser, il y a moyen d'injecter du code (HSL code. Jamais entendu parler de HSL avant, mais ça m'a l'air d'être un dérivé du C++).

Soucis, on sort un peu de mon domaine de compétence.

Je suis dans la situation ou j'aimerais vérifier la situation suivante :
Si 8 variables ont comme valeur 0,4 ou 6, et que une variable à comme valeur 0 ou 2 et qu'une dernière variable à une valeur inférieure ou égale à 32, alors ma condition est bonne.

J'ai essayé la structure suivante :

if ((variable1 && variable2 && variable3 && variable4 && variable5 && variable6 && variable7 && variable8 == 0||4||6) && (variable9 == 0||2) && (variable10 <= 32))
{
//What to do
}


Le soucis, c'est que quoi qu'il advienne, à moins que tout soit faux, ou que variable10 <=, il me considère que la condition est bonne (en gros j'ai l'impression qu'il ne vérifie que la dernière condition)
Je peux bidouiller un peu mon script pour palier à ce soucis (en inversant, == devient <= et <= devient >), mais du coup, c'est des étapes en plus, et ce n'est pas propre.

Du coup, quel est le soucis ? J'ai essayé avec un seul & et |, ça me donne le même résultat.

Merci de vos réponses.

5 réponses

  1. Contributeur
    En C, on pourrait faire ceci, en mettant les données à tester dans un tableau de
    int
    (je vais supposer que le type des données est
    int
    ) avec une fonction qui retourne vrai ou faux selon que toutes les conditions sont vérifiées ou non.

    #include <stdio.h>
    
    int is_situation_true(int * data) {
        int n;
        for (n = 0; n < 8; n++)
            if ( !((data[n] == 0) || (data[n] == 4) || (data[n] == 6)) )
                return 0;
        if ( !((data[8] == 0) || (data[8] == 2)) )
            return 0;
        if ( !(data[9] <= 32) )
            return 0;
        return 1;
    }
    
    int main(void) {
        /* jeu de données de test, situation "vrai" */
        int Choix_Vials_1 = 0; int Choix_Vials_2 = 4; int Choix_Vials_3 = 0; int Choix_Vials_4 = 0;
        int Choix_Vials_5 = 4; int Choix_Vials_6 = 0; int Choix_Vials_7 = 6; int Choix_Vials_8 = 0;
        int Choix_Vials_9 = 2;
        int Choix_Vials_10 = 30;
    
        /* mettre ces données dans un tableau de int */
        int data[10];
        data[0] = Choix_Vials_1; data[1] = Choix_Vials_2; data[2] = Choix_Vials_3; data[3] = Choix_Vials_4;
        data[4] = Choix_Vials_5; data[5] = Choix_Vials_6; data[6] = Choix_Vials_7; data[7] = Choix_Vials_8;
        data[8] = Choix_Vials_9;
        data[9] = Choix_Vials_10;
    
        /* tester */
        if (is_situation_true(data)) {
            printf("situation is true\n");
        } else {
            printf("situation is false\n");
        }
    }


    Si au lieu d'utiliser des variables Choix_Vials_1, Choix_Vials_2, etc., tu utilises directement le tableau
    int data[10];
    pour stocker tes données, c'est encore mieux, car tu n'as pas à affecter les contenus de ces variables au tableau. Elles y seront déjà sous une forme exploitable pour appliquer les tests souhaités sur la plage de données.

    Dal
    1. Contributeur
      Comme les tableaux commencent aux indices 0, ta valeur 1 est en position 0, etc., la numérotation de l'indice du tableau allant de 0 à 9 au lieu de 1 à 10 comme tu le fais dans tes variables.

      Si c'est un problème pour toi, parce que tu préfères que visuellement ce qui est dans Choix_Vials_10 soit associé à quelque chose nommé avec un 10 dedans, tu peux créer un enum en C, dont tu pourras utiliser les éléments pour nommer tes indices.

      #include <stdio.h>
      
      enum vials {
          VIALS1, VIALS2, VIALS3, VIALS4, VIALS5,
          VIALS6, VIALS7, VIALS8, VIALS9, VIALS10
      };
      
      int is_situation_true(int * data) {
          int n;
          for (n = VIALS1; n < VIALS9; n++)
              if ( !((data[n] == 0) || (data[n] == 4) || (data[n] == 6)) )
                  return 0;
          if ( !((data[VIALS9] == 0) || (data[VIALS9] == 2)) )
              return 0;
          if ( !(data[VIALS10] <= 32) )
              return 0;
          return 1;
      }
      
      int main(void) {
          /* jeu de données de test, situation "vrai" */
          int Choix_Vials_1 = 0; int Choix_Vials_2 = 4; int Choix_Vials_3 = 0; int Choix_Vials_4 = 0;
          int Choix_Vials_5 = 4; int Choix_Vials_6 = 0; int Choix_Vials_7 = 6; int Choix_Vials_8 = 0;
          int Choix_Vials_9 = 2;
          int Choix_Vials_10 = 30;
      
          /* mettre ces données dans un tableau de int */
          int data[10];
          data[VIALS1] = Choix_Vials_1; data[VIALS2] = Choix_Vials_2; data[VIALS3] = Choix_Vials_3; data[VIALS4] = Choix_Vials_4;
          data[VIALS5] = Choix_Vials_5; data[VIALS6] = Choix_Vials_6; data[VIALS7] = Choix_Vials_7; data[VIALS8] = Choix_Vials_8;
          data[VIALS9] = Choix_Vials_9;
          data[VIALS10] = Choix_Vials_10;
      
          /* tester */
          if (is_situation_true(data)) {
              printf("situation is true\n");
          } else {
              printf("situation is false\n");
          }
      }


      en réalité, VIALS1 vaudra effectivement 0, mais si cela t'aide de visualiser data[VIALS1] pour signifier que tu te réfères au premier élément, l'enum te donne la possibilité d’utiliser cette sémantique.
  2. Bonjour T3chN0g3n,

    Moi, pour simplifier tout ces tests, j'utiliserais une variable tableau

    int var[10];
    int total = 0;
    ensuite boucle k de 0 à 7
    --------si var[k] == 0 ou var[k] == 4 ou var[k] == 6 -> total = total +1
    apres la boucle
    si total == 8, c'est que les 8 premières variables sont ok

    donc, dernier test:
    si total == 8 et (var[8] == 0 ou var[8] ==2) et var[9] <= 32 -> Erreur_Valeur = 0

    "Btw c'est bizarre que ça donne true tout le temps non ? "

    ben non le test 0 ou 2 donne 2 donc vrai

    en faisant si v== 0||2 on fait donc si v == vrai, pas si v==0 ou bien v==2

    C'est valable dans n'importe quel langage ...
    1. Contributeur
      Bonjour,

      Il me semble qu'il faudrait d'abord clarifier quel est le langage de programmation, car si c'est bien celui-ci : https://docs.halon.io/hsl/about.html alors le langage ne ressemble pas tant que cela au C++ (et serait plutôt inspiré de PHP et Python selon cette doc), et, de fait, les opérateurs booléens ne sont pas
      &&
      et
      ||
      mais
      and
      et
      or
      comme en Python :

      https://docs.halon.io/hsl/operators.html#logic-boolean

      (comme l'a déjà dit T3chN0g3n)

      Les opérateurs
      &
      et
      |
      existent aussi, mais ces symboles sont alors utilisés pour les opérations bit à bit

      https://docs.halon.io/hsl/operators.html#bitwise

      Dal
      1. Salut,

        J'ai répondu à T3chN0g3n à ce propos, la réponse convient pour ton message également :)
    2. Bonjour,

      if(variable9 == 0||2)


      ca donne True, vrai tout le temps: 0 ou 2 est toujours vrai

      il faut faire

      if(variable9 == 0 || variable9 == 2)


      Au fait: "quel est le souci " sans s à la fin :-)
      1. Sorry pour la faute, il semble que je ne peux plus éditer :x

        Btw c'est bizarre que ça donne true tout le temps non ? Moi j'interprète ça comme
        "Si la variable 9 est égale à 0 ou 2". Donc si on a 3, ça devrait renvoyer false non ?

        Le soucis c'est vraiment que je vais être amené à utiliser beaucoup de variables avec plusieurs possibilités, donc j'ai tout intérêt à savoir condenser au maximum le code…

        EDIT : Je viens de faire le test avec cette structure la, et j'ai le même soucis : il ne réagit qu'au dernier test logique (donc Choix_Vials_Total <= 32)

        if (Choix_Vials_2 == 0 || Choix_Vials_2 == 4 || Choix_Vials_2 == 6 && Choix_Vials_3 == 0 || Choix_Vials_3 == 4 || Choix_Vials_3 == 6 && Choix_Vials_4 == 0 || Choix_Vials_4 == 4 || Choix_Vials_4 == 6 && Choix_Vials_5 == 0 || Choix_Vials_5 == 4 || Choix_Vials_5 == 6 && Choix_Vials_6 == 0 || Choix_Vials_6 == 4 || Choix_Vials_6 == 6 && Choix_Vials_7 == 0 || Choix_Vials_7 == 4 || Choix_Vials_7 == 6 && Choix_Vials_8 == 0 || Choix_Vials_8 == 4 || Choix_Vials_8 == 6 && Choix_Vials_1 == 0 || Choix_Vials_1 == 2 &&  Choix_Vials_Total <= 32)
        {
        Erreur_Valeur = 0;
        }
        else
        {
        Choix_Vials_Total = 0;
        }
        


        EDIT2 : J'ai dévellopé en "structure lourde" le résultat que je voudrais, ça donne ça :

        if (Choix_Vials_1 == 0 || Choix_Vials_1 == 2)
        {
           if (Choix_Vials_2 == 0 || Choix_Vials_2 == 4 || Choix_Vials_2 == 6)
           {
              if (Choix_Vials_3 == 0 || Choix_Vials_3 == 4 || Choix_Vials_3 == 6)
              {
                 if (Choix_Vials_4 == 0 || Choix_Vials_4 == 4 || Choix_Vials_4 == 6)
                 {
                    if (Choix_Vials_5 == 0 || Choix_Vials_5 == 4 || Choix_Vials_5 == 6)
                    {
                       if (Choix_Vials_6 == 0 || Choix_Vials_6 == 4 || Choix_Vials_6 == 6)
                       {
                          if (Choix_Vials_7 == 0 || Choix_Vials_7 == 4 || Choix_Vials_7 == 6)
                          {      
                             if (Choix_Vials_8 == 0 || Choix_Vials_8 == 4 || Choix_Vials_8 == 6)
                             {     
                                if (Choix_Vials_Total <= 32)
                                {
                                Erreur_Valeur = 0;
                                }
                             }
                          }
                       }
                    }
                 }
              }
           }
        }
        else
        {
        Choix_Vials_Total = 0;
        }


        La question est : commence réduire au maximum cette structure ?
    3. Bonjour,

      Avez vous essayé avec des "and" et pas des "&" ?

      Il y'a une doc ici (si c'est bien ce language) https://docs.halon.io/hsl/operators.html#logic-boolean

      Cordialement.
      1. Salut,

        Oui j'ai commencé par ça. Malheureusement quand je remplace mes & ou && par des and j'ai une erreur

        error 1002: syntax error before identifier 'and'

        Pour moi Hsl fait référence à Hamilton Star Lab qui est le robot que nous utilisons.
        Mais je vais creuser un peu dand le doute
      2. @FroyorstOK, oui effectivement dans la doc pour "MicroLab Star" ils précisent bien "The general syntax used in HSL is the C/C++ notation"

        Source
      3. @T3chN0g3nTu connais ou c'est suite à une recherche ?
      4. @FroyorstNon j'ai juste fait une petite recherche pour qu'on puisse être fixé sur le langage à utiliser :p