Formule de révision

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Formule de révision

par thierry_sco » 02 déc. 2008, 07:31

Merci.

Je me remets dessus ce week end.

par Sékiltoyai » 01 déc. 2008, 23:53

Je ne vais pas non plus te l'écrire, je peux juste te montrer une autre voie.

A savoir que j'aurais fait une organisation du style :
$operation = new mult(
    new variable('prix'),
    new div(
        new indice(
            'ichtts',
            new variable('date')
        ),
        new indice(
            'ichtts',
            new sous(new variable('date'), 1)
        )
    )
);
Et pour l'implémentation j'aurais fait une classe abstraite que j'aurais implémenté ainsi :
abstract class fonction
{

    private $args = array();

    public function __construct()
    {
        $this->args = func_get_args();
    }

    public function resultat()
    {

         $resultats = array()
         foreach($args as $arg)
         {
          
             if($arg instanceof fonction)
             {
                 $resultats[] = $arg->resultat();
             }
             else
             {
                 $resultats[] = $arg;
             }
         
         }
         
         return call_user_func_array(array($this, 'calcul'), $resultats);
    
    }

}
Un exemple de classe :
class indice
{

    public function calcul($indice, $date)
    {
        
        // On récupère l'indice $indice à la date $date
        
    }

}
Pour stocker l'opération dans une chaine on fait :
$chaine = serialize($operation);
Pour la décoder :
$operation = deserialize($chaine);
Pour l'exécuter :
$resultat = $operation->resultat();

Il reste quelques petits problèmes, par exemple notamment je n'ai pas entièrement réglé les problèmes de perfomance d'accès à la base de données, mais si tu optes pour cette solution on peut en rediscuter…

par Invité » 01 déc. 2008, 20:10

Je suis d accord avec toi.

Mais rien ne t'empêche de m'aider si tu sais.

Comme je te l'ai dit cette solution fonctionne même si elle n'est pas correcte.
Elle n'a pour vertu que de provoquer l'envie à quelqu'un de ne pas me laisser l'utiliser et de m'en proposer une autre. ;-).

par Sékiltoyai » 01 déc. 2008, 15:29

Excuse moi mais ta solution est très sale…
D'une part tu pourris les performances de ton serveur sql avec des requêtes imbriqués car, c'est une règle quasiment absolue, on ne met pas des requêtes dans des boucles. Les données d'un serveur SQL, ce n'est pas comme un tableau, que l'on peut accéder un peu n'importe comment.
Les requêtes SQL sont faites pour récupérer un maximum d'enregistrement en même temps…

Ensuite, je m'attendais à ce que tu fasses une solution de ce style, à savoir faire évaluer l'opération par un eval(). Sache que c'est vraiment mauvais, pour la sécurité et la performance entre autres. Et je suis près à parier que dans quelques mois, lorsque tu voudras ajouter un nouvel indice ou bien une nouvelle formule, tu seras limité par ton système ou bien tu auras des gros bugs…

En bref, comme je le disais, la théorie des langages, cela ne s'invente pas, et si on veut traiter une chaine arithmétique il faut le faire sérieusement ou bien opter pour des solutions qui ne demandent pas d'analyse syntaxique comme la sérialisation d'objets…

par thierry_sco » 01 déc. 2008, 10:06

Bien, après un dimanche et quelques recherches pour devenir ingénieur...

N'étant pas informaticien, je vous livre la réponse.

Le script n'est certes pas parfait, et certainement que certains pourront apporter des modifications. Mais il a le mérite de fonctionner.

Code : Tout sélectionner

//ETABLI LA CONNEXION Global $conn; //RECUPERE LA FORMULE ET LE DERNIER PRIX $Libelle_Revalorisation = 'ICHTTS1,+,0.15,*,PSDC'; $P = 100; //TRAITEMENT DE LA FORMULE $Formule = $Libelle_Revalorisation; $Variable = explode(",", $Formule); //COMPTE LE NOMBRE DE VARIABLE DANS LA FORMULE $Nbre_Variable = count($Variable); //TRAITEMENT DES DATES //Extrait le jour et le mois de la date du mois de revalorisation $Date_Indice_Mois = 1; $Jour = 1; $Mois_Date_Indice_Mois = $Date_Indice_Mois; //DEFINI L ANNEE $Annee = date("y"); $Annee_1 = $Annee - 1; $Annee_2 = $Annee_1 - 1; $Date_1 = mktime(0, 0, 0, date($Mois_Date_Indice_Mois), date($Jour), date($Annee_1)); $Date_2 = mktime(0, 0, 0, date($Mois_Date_Indice_Mois), date($Jour), date($Annee_2)); $Date_Form_1 = "'".date("Y-m-d",$Date_1)."'"; $Date_Form_2 = "'".date("Y-m-d",$Date_2)."'"; //COMPTE LE NOMBRE D INDICE DIFFERENT DANS LA TABLE INDICE $sSqlWrk = " SELECT DISTINCT Libelle FROM indice"; $rswrk = $conn->GetArray($sSqlWrk); $Nbre = count($rswrk); //______________________________________________ //CREE UNE BOUCLE POUR AFFECTER LES COEFS for($i=0;$i < $Nbre_Variable ;$i++) { for($j=0;$j < $Nbre ;$j++) { $tableau = $rswrk[$j] ['Libelle']; $Var = $Variable[$i]; //RECUPERE LES VALEURS DES INDICES $sSqlWrk = "SELECT Valeur FROM indice WHERE Libelle = '$Var' AND Date = $Date_Form_1"; $rswrk = $conn->GetArray($sSqlWrk); $Indice_1 = $rswrk[0] ['Valeur']; $sSqlWrk2 = "SELECT Valeur FROM indice WHERE Libelle = '$Var' AND Date = $Date_Form_2"; $rswrk2 = $conn->GetArray($sSqlWrk2); $Indice_2 = $rswrk2[0] ['Valeur']; //____________________________A COMPLETER A CHAQUE NOUVEL INDICE //CALCUL LE COEF DE ICHTTS1 IF ($Var == 'ICHTTS1') { $ICHTTS1 = round($Indice_1/$Indice_2, 4); } //CALCUL LE COEF DE PSDC IF ($Var == 'PSDC') { $PSDC = round($Indice_1/$Indice_2, 4); } }//FIN DE FOR $Nbre }//FIN DE FOR $Nbre_Variable //____________________________A COMPLETER A CHAQUE NOUVEL INDICE //REMPLACE LES VARIABLES PAR LES COEFS $patterns[0] = '/ICHTTS1/'; $patterns[1] = '/PSDC/'; $patterns[2] = '/,/'; $replacements[2] = $ICHTTS1; $replacements[1] = $PSDC; $replacements[0] = ''; //REALISE LE CALCUL DE LA FORMULE $Calcul = preg_replace($patterns, $replacements, $Libelle_Revalorisation); eval('$resultat = '.$Calcul.';'); $Nouveau_Prix = $P*$resultat; echo $resultat.'<br>'; echo $Nouveau_Prix.'<br>';

par Sékiltoyai » 29 nov. 2008, 16:43

Tu organises tes formules dans des tableaux ou des objets (entendre des formes structurées) et tu utilises la serialisation. Parce que avec ton organisation actuelle ta question porte sur la théorie des langages, que l'on n'étudie pas avant l'école d'ingénieur ou bien la deuxième année d'IUT informatique…

par thierry_sco » 29 nov. 2008, 16:35

Oui.

Cependant seul l'administrateur peut écrire les formules dans la table.

Je ne vois pas comment faire autrement dans le sens ou le nombre de variables type ichtts1, psdc, sont nombreuses et peuvent être mélangés dans les formules.
Les opérateurs également.

par Sékiltoyai » 29 nov. 2008, 15:33

Tu me fais peur là… Tu veux dire que les formules sont directement écrites sous forme de chaine de caractère dans tes tables ??

par thierry_sco » 29 nov. 2008, 09:20

Merci pour la remarque.

Comme je vois que tout le monde sèche...Je vais reformuler mon problème.

Prenons deux chaînes de caractères, pour exemple :
- p*(ichtts1/ichtts1a-1) et p*(0.15+(0.9(psdc/psdca-1)).

p = prix_actuel
ichtts1 = variable 1
ichtts1a-1 = variable 1 de l'année précédente
psdc = variable 2
psdca-1 = variable 2 de l'année précédente


Une table indice :
id_indice : 1 - libelle_indice : ichtts1 - valeur : 100 - date 01/2007;
id_indice : 2 - libelle_indice : ichtts1 - valeur : 103 - date 02/2007;
id_indice : 3 - libelle_indice : ichtts1 - valeur : 110 - date 01/2008;
id_indice : 4 - libelle_indice : ichtts1 - valeur : 120 - date 02/2008;
id_indice : 5 - libelle_indice : psdc - valeur : 100 - date 01/2007;
id_indice : 6 - libelle_indice : psdc - valeur : 105 - date 01/2008;


Une table produit :
id_produit : 1 - libelle_produit : installation1 - formule : p=(ichtts1/ichtts1a-1) - mois_de_ref : 1 - Prix_Actuel : 200;
id_produit : 2 - libelle_produit : installation2 - formule : p=0.15+(0.9(psdc/psdca-1) - mois_de_ref : 1 - Prix_Actuel : 250;

Je souhaite obtenir pour :
id_produit : 1 le calcul suivant 200*(110/100) soit 220;
id_produit : 2 le calcul suivant 250*(0.15+(0.9(105/100)) soit 273

merci pour vos réponses.

par zeus » 24 nov. 2008, 22:00

Modération :
Merci de ne pas abuser des capitales dans ton message.
C'est moins lisible et ça n'apporte rien de plus.

Formule de révision

par thierry_sco » 24 nov. 2008, 20:23

Bonjour,

Je cherche une petite solution, voilà le petit bébé.

J'ai des sites avec des installations certaines ont un contrat.
Pour gérer la revalorisation par période de 12 mois, j'applique une formule de révision.

Voici le schéma :

J'ai une table 'indice_revalorisation' avec 4 champs l'ID, le 'Libelle_Revalorisation', la valeur et la date de référence de cette valeur.
Dans la table contrat nous récupérons l''ID_indice_revalorisation' et son 'Libelle_Revalorisation'.

Cette dernière est rattachée à une table installation par le num_installation.
Dans cette table contrat j'ai :
- Un champ 'Libelle_Revalorisation (varchar 50)' dans lequel j'inscris des formule tel que :
- P*(ICHTTS1/ICHTTS1 a-1) soit le Prix actuel * ( l'indice "ichtts1" du mois de référence
divisé par "ichtts1" du même mois de l'année précédente.
Bien sur les indices peuvent être différents, l'emplacement des calculs également.

- Un champ mois : pour le mois de référence et le mois de l'année précédente.

Dans la table installation j'ai le dernier prix facturé.

Ma question est comment récupérer des indices différents inscrit dans la formule et retrouver leur valeur en fonction des mois, sachant que les formules mathématiques et les indices changent souvent.

[Note : ce message a été posté de manière anonyme avant d'être réattribué à son auteur]