liste de conditions

Eléphanteau du PHP | 22 Messages

30 nov. 2023, 22:56

Bonjour,
Je souhaite modifier le texte d'une cellule en fonction de résultat d'une mesure (qualité de l'air)

Je fais mon calcul :

Code : Tout sélectionner

$avg_pm25 = avgReadingpm('pm25'); $message_Pm25 = definition_messagePm25($avg_pm25);
ensuite la fonction devrait faire le choix :

Code : Tout sélectionner

function definition_messagePm25($valeur) { if($valeur<0 ) { return 'ERREUR'; } if($valeur<10 ) { return 'BON'; } if($valeur<20 && $valeur>10) { return 'MOYEN'; } if($valeur<25 && $valeur>20) { return 'DEGRADE'; } if($valeur<50 && $valeur>25) { return 'MAUVAIS'; } if($valeur<75 && $valeur>50) { return 'TRES MAUVAIS'; } if($valeur>75) { return 'EXTREMEMENT MAUVAIS'; } }
Affichage :

Code : Tout sélectionner

<td style="background-color: <?php echo $couleur_Pm25 ?>;"> <?php echo $message_Pm25 ?> </td>

Le résultat reste systématiquement extrêmement mauvais soit le dernier si
Mon approche est peut être trop simpliste

Mammouth du PHP | 2703 Messages

30 nov. 2023, 23:10

$avg_pm25 contient bien ce qui est attendu ?

Eléphanteau du PHP | 22 Messages

30 nov. 2023, 23:12

Oui j'affiche la valeur

Code : Tout sélectionner

<td><?php echo round(((float) $avg_pm25['avg_amount']),0) ?></td>

Mammouth du PHP | 2703 Messages

30 nov. 2023, 23:37

que donne un
var_dump($valeur);
au début de la fonction definition_messagePm25 ?
pour savoir si c'est un problème de type.

Avatar du membre
Mammouth du PHP | 1609 Messages

01 déc. 2023, 12:33

Salut, si je lis bien le code,
$avg_pm25
est un tableau et le montant est dans
$avg_pm25['avg_amount']
.

Déjà pourquoi ne pas stocker la valeur du
round(((float) $avg_pm25['avg_amount']),0)
directement dans
$avg_pm25
?

Ensuite lors de l'appel à
definition_messagePm25($avg_pm25);
utiliser le bon index du tableau et non pas le tableau.

Par exemple
definition_messagePm25($avg_pm25['avg_amount']);

Aussi typer les paramètres des fonctions peut être une bonne chose, ainsi si tu passes un array mais attend un integer, PHP lèvera une erreur.
Développeur web depuis + de 20 ans

Eléphanteau du PHP | 22 Messages

01 déc. 2023, 14:36

Bonjour Saian & Or1,

Merci à vous pour le temps que vous voulez bien passer sur mon problème.
Pour être exhaustif je suis parti d'un tuto et ensuite j'ai beaucoup travaillé en adaptant à mes besoins, raison pour laquelle je n'ai pas les réponses à certains choix, d'appels de variables

Or1 :
j'ai essayé ta proposition

Code : Tout sélectionner

function definition_messagePm25($valeur) { var_dump($valeur); if($valeur<0 ) { return 'ERREUR'; } else if ($valeur<10 ) { return 'BON'; } else if (($valeur<20) && ($valeur>10)) { return 'MOYEN'; } else if (($valeur<25) && ($valeur>20)) { return 'DEGRADE'; } else if (($valeur<50) && ($valeur>75)) { return 'MAUVAIS'; } else if (($valeur<75) && ($valeur>50)) { return 'TRES MAUVAIS'; } else if ($valeur>75) { return 'EXTREMEMENT MAUVAIS'; }
A l'affichage : array(1) { ["avg_amount"]=> string(7) "60.3158" }

Saian :
Salut, si je lis bien le code,
$avg_pm25
est un tableau et le montant est dans
$avg_pm25['avg_amount']
.

Déjà pourquoi ne pas stocker la valeur du
round(((float) $avg_pm25['avg_amount']),0)
directement dans
$avg_pm25
?
Là tu mets le doigt sur mes limites, ça fait clairement parti des choses préexistantes dans le programme du tuto et je ne fais pas vraiment la différence entre $avg_pm25['avg_amount'] et $avg_pm25 peux tu m'éclairer
Par contre je sais que $avg_pm25 est une valeur unique provenant de la fonction de calcul de la moyenne
L'erreur vient peut être d'une mauvaise compéhension.

%Merci

Avatar du membre
Mammouth du PHP | 1609 Messages

01 déc. 2023, 16:05

Le problème est bien celui que j'ai pointé, le
var_dump($valeur);
ici
function definition_messagePm25($valeur) {
var_dump($valeur);
le confirme bien :
array(1) { ["avg_amount"]=> string(7) "60.3158" }

Comme tu peux le lire, c'est un array avec 1 élément (le (1) de array(1)). De plus la valeur de avg_amount est un string.

Lors de l'appel à la fonction definition_messagePm25 tu dois donc faire à minima :
definition_messagePm25((float) $avg_pm25['avg_amount']);
ensuite ça devrait fonctionner sans problème.

La avec le code actuel le
if ($valeur < 0)
c'est comme un
if (['avg_amount' => '60.3158'] < 0)
et ça ne peut évidemment pas fonctionner comme tu l'espères.

Avec le système de cast automatique de php ça doit évaluer le tableau comme la chaine 'array' et les comparaisons doivent résulter en comparaison de chaines 'array' < '10' etc et la sortie doit logiquement toujours être EXTREMEMENT MAUVAIS car la seule condition qui sera vraie est 'array' > '75'.

A noter aussi, tu vas avoir un problème avec les valeurs 10, 20, 25, 50 et 75 car aucune des conditions ne sera évaluée à vraie.
Pour ces valeurs, tu dois choisir sur quelle condition elles doivent être évaluées vraie en utilisant le >= ou <= OU ALORS tester seulement la valeur supérieure étant donné qu'à chaque if il y a un return et que tu utilises des elseif.

Par exemple :
function definition_messagePm25($valeur) {
    $valeur = (float) $valeur;
	
    if ($valeur < 0) {
        return 'ERREUR';
    }
    if ($valeur < 10) {
        return 'BON';
    }
    if ($valeur < 20) {
        return 'MOYEN';
    }
    if ($valeur < 25) {
        return 'DEGRADE';
    }
    if ($valeur < 50) {
        return 'MAUVAIS';
    }
    if ($valeur < 75) {
        return 'TRES MAUVAIS';
    }
    
    return 'EXTREMEMENT MAUVAIS';
}

// OU

function definition_messagePm25($valeur) {
    $valeur = (float) $valeur;
    $definition = '';
    
    if ($valeur < 0) {
        $definition = 'ERREUR';
    } elseif ($valeur < 10) {
        $definition = 'BON';
    } elseif ($valeur < 20) {
        $definition = 'MOYEN';
    } elseif ($valeur < 25) {
        $definition = 'DEGRADE';
    } elseif ($valeur < 50) {
        $definition = 'MAUVAIS';
    } elseif ($valeur < 75) {
        $definition = 'TRES MAUVAIS';
    } else {
        $definition = 'EXTREMEMENT MAUVAIS';
    }
    
    return $definition;
}

// TEST

$avg_pm25 = [
    'avg_amount' => '60.3158',
];
echo definition_messagePm25($avg_pm25['avg_amount']);
// TRES MAUVAIS
Développeur web depuis + de 20 ans

Mammouth du PHP | 2703 Messages

01 déc. 2023, 18:03

la bonne résolution de ce problème, c'est que cette fonction :
$avg_pm25 = avgReadingpm('pm25');
fasse ce qu'on peut attendre d'elle, à savoir retourner une valeur moyenne (donc un float), et non un tableau d'un élément.
Modifié en dernier par or 1 le 01 déc. 2023, 20:09, modifié 1 fois.

Avatar du membre
Mammouth du PHP | 1609 Messages

01 déc. 2023, 18:42

Je suis d'accord avec le commentaire de or1 à propos de la fonction avgReadingpm. Si le tableau retourné ne contient toujours que l'index avg_amount, que c'est bien le seul but de cette fonction, à quoi bon retourner cette moyenne dans un tableau ? autant la retourner directement et la convertir en float à ce moment la.

PS : comme tu n'as pas l'air de savoir/comprendre ce qu'est un tableau (array), je t'encourage vivement à lire la documentation.
https://www.php.net/manual/fr/language.types.array.php
Développeur web depuis + de 20 ans

Eléphanteau du PHP | 22 Messages

02 déc. 2023, 05:07

Merci Or et Saian,
Effectivement je ne suis au fait de la gestion des tableaux, donc je vais suivre tes conseils et lire la documentation.
Second point, le tuto d'origine part d'une BD en varchar(10) avec des valeurs qui sont envoyés d'un ESP:
https://RandomNerdTutorials.com/cloud-w ... 2-esp8266/
Je me pose la question si une partie de mes problèmes ne viennent pas également de ce choix ?

Avatar du membre
Mammouth du PHP | 1609 Messages

02 déc. 2023, 18:55

En effet pour stocker des nombres décimaux il vaut mieux utiliser le format decimal de mysql. Logiquement dans les résultats de la requête ces nombres devraient alors bien être interprétés par php comme des float. Mais ton problème initial ne vient pas de ça.
Développeur web depuis + de 20 ans

Eléphanteau du PHP | 22 Messages

06 déc. 2023, 15:04

Bonjour Saian et Or,
J'ai pris le temps de lire les documents et vos propositions avant de revenir je pense mieux comprendre maintenant et ça semble fonctionner, je vais encore tester sur les prochains jours pour confirmer.

Comme évoqué dans un de mes précédent messages je rencontre également un soucis dans le calcul de la moyenne,.
Je reçois dans ma BD SQL une valeur de particules de mon ESP toutes les 30mn et toutes les 10mn pour la température donc 2 fois sur 3 j'ai NULL dans la colonne particules (pas de valeurs reçues).

J'essaye d'ajouter une condition dans la requête ci-dessous avec IS NOT NULL après le WHERE mais j'ai systématique une erreur
J'ai vérifié avec var_dump le résultat est float(0) float(0)

Ma condition :

Code : Tout sélectionner

$sql = "SELECT AVG(CAST(" . $value . " AS SIGNED)) AS avg_amount FROM SensorData WHERE reading_time BETWEEN NOW() - INTERVAL 6 HOUR AND NOW() ";
J'ai testé cela mais le résultat est 0

Code : Tout sélectionner

$sql = "SELECT AVG(CAST(" . $value . " AS SIGNED)) AS avg_amount FROM SensorData WHERE (" . $value . " IS NOT NULL ) AND (reading_time BETWEEN NOW() - INTERVAL 6 HOUR AND NOW()) ";

La fonction complète :

Code : Tout sélectionner

function avgReadingpm($value) { global $servername, $username, $password, $dbname; $value = (float)$value; // Create connection $conn = new mysqli($servername, $username, $password, $dbname); // Check connection if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } $sql = "SELECT AVG(CAST(" . $value . " AS SIGNED)) AS avg_amount FROM SensorData WHERE reading_time BETWEEN NOW() - INTERVAL 6 HOUR AND NOW() "; if ($result = $conn->query($sql)) { return $result->fetch_assoc(); } else { return false; } $conn->close(); }