IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Problème insoluble à la vue de mes connaissances !


Sujet :

C#

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    110
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 110
    Points : 44
    Points
    44
    Par défaut Problème insoluble à la vue de mes connaissances !
    Bonjour,

    Je cherche depuis des jours et des jours mais je n'arrive pas à résoudre ce problème.

    Partant d'une liste maListe<objetPeriode>

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class objetPeriode
    {
        public DateTime? DateDebut { get; set; }
        public DateTime? DateFin { get; set; }
        public decimal Taux { get; set; }
    }
    Comment faire pour fusionner les périodes adjacentes dont le taux est identique en veillant à ce que les dates continuent à se suivre ?

    exemple : en partant de cette liste

    A partir du 21/07/2012 1,00%
    Du 20/07/2012 au 20/07/2012 2,00%
    Du 18/07/2012 au 19/07/2012 3,00%
    Du 15/07/2012 au 17/07/2012 3,00%
    Du 10/07/2012 au 14/07/2012 4,00%
    jusqu'au 09/07/2012 4,00%

    il faudrait arriver à celle-ci

    A partir du 21/07/2012 1,00%
    Du 20/07/2012 au 20/07/2012 2,00%
    Du 15/07/2012 au 19/07/2012 3,00%
    Du 09/07/2012 au 14/07/2012 4,00%

    Ceci si possible en LINQ ou alors autre chose...

    Quelqu'un de calé en LINQ ou une idée de génie pourrait-il me résoudre ce problème ?

    Merci d'avance

    Cordialement

  2. #2
    Membre éprouvé

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2011
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2011
    Messages : 487
    Points : 945
    Points
    945
    Par défaut
    Hello,

    Juste pour info, il y a aussi un forum Linq ( http://www.developpez.net/forums/f11...-donnees/linq/ )

    Personnellement, je ne l'aurais pas fait en Linq mais plutôt "à la main" avec quelque chose du genre:

    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
     
    List<objetPeriode> list = new List<objetPeriode>();
    List<objetPeriode> newList = new List<objetPeriode>();
     
    foreach(objetPeriode item in list)
    {
    	if(newList.Exists((i) => i.HasSameRate(item)))
    		continue;
     
    	IEnumerable<objetPeriode> sameRateItems = list.Where((i) => i.HasSameRate(item));
     
    	if(sameRateItems.Count() > 1)
    	{
    		item.DateDebut = sameRateItems.Min((i) => i.DateDebut);
    		item.DateFin = sameRateItems.Max((i) => i.DateFin);
    	}
     
    	newList.Add(item);
    }
    Il suffit d'ajouter la méthode :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    public bool HasSameRate(objetPeriode other)
    {
    	return this.Taux == other.Taux;
    }
    C'est loin d'être parfait mais je pense que ça fait le boulot que tu cherches Par contre ça implique que tous les taux égaux sont des dates qui se cotoient.
    Mon blog sur les technos .NET et Agile -> http://blog.developpez.com/maximepalmisano/

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    110
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 110
    Points : 44
    Points
    44
    Par défaut
    Bonjour,

    Merci pour cette réponse aussi rapide !!!

    Ça fonctionne très bien à l'exception de 2 cas : lorsqu'on rencontre des périodes dont il n'existe que la date de début ou la date de fin. Mais sur ces 2 points, je me suis débrouillé autrement.

    Un grand merci à toi.

  4. #4
    Membre éprouvé Avatar de sisqo60
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2006
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 754
    Points : 1 188
    Points
    1 188
    Par défaut
    Bonjour,

    A mon avis tu aura certains bugs, voir les commentaires
    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
    List<objetPeriode> list = new List<objetPeriode>();
    List<objetPeriode> newList = new List<objetPeriode>();
    foreach(objetPeriode item in list) 
    {     
    if(newList.Exists((i) => i.HasSameRate(item)))
             continue;
    IEnumerable<objetPeriode> sameRateItems = list.Where((i) => i.HasSameRate(item));
    if(sameRateItems.Count() > 1)     
    {
    // A ce niveau là, si l'ensemble de tes dates n'est pas continu, tu auras des erreurs
    // Exemple : Taux 1% du 01/01/2000 au 31/10/2010
    //           Taux 1% depuis 01/01/2012 
    // Il y a un trou, mais toi tu diras : Taux 1% a partir du 01/01/2000
    // A prendre en compte si le cas peut se produire
    item.DateDebut = sameRateItems.Min((i) => i.DateDebut);
    item.DateFin = sameRateItems.Max((i) => i.DateFin);
         
    }       
    newList.Add(item); 
    }
    bon dév.
    Un âne se croit savant parce qu'on le charge de livres (proverbe américain)

    N'oubliez pas de avant de
    Pas de question techniques par MP, c'est contre la philosophie du forum

  5. #5
    Membre éprouvé

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2011
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2011
    Messages : 487
    Points : 945
    Points
    945
    Par défaut
    Salut sisqo60,

    Le code que j'ai fourni n'est la qu'à titre d'exemple pour lui donner une idée de comment résoudre le problème. C'est fait sur un coin de table sans tests ni rien.

    C'est à celui qui a le problème d'écrire le vrai algorithme et de le tester pour être sur que tous les usecases sont bons

    (Btw j'ai précisé que c'était valable que si les taux égaux avaient des intervalles collés)
    Mon blog sur les technos .NET et Agile -> http://blog.developpez.com/maximepalmisano/

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Problème intéressant, je me suis bien amusé pour le résoudre

    Pour commencer, quelques mises au point

    • je pense qu'il y a une petite erreur concernant le résultat attendu :
      exemple : en partant de cette liste

      A partir du 21/07/2012 1,00%
      Du 20/07/2012 au 20/07/2012 2,00%
      Du 18/07/2012 au 19/07/2012 3,00%
      Du 15/07/2012 au 17/07/2012 3,00%
      Du 10/07/2012 au 14/07/2012 4,00%
      jusqu'au 09/07/2012 4,00%

      il faudrait arriver à celle-ci

      A partir du 21/07/2012 1,00%
      Du 20/07/2012 au 20/07/2012 2,00%
      Du 15/07/2012 au 19/07/2012 3,00%
      Du 09/07/2012 au 14/07/2012 4,00%
      Il me semble que la dernière ligne du résultat devrait plutôt être : "jusqu'au 14/04/2012 4,00%", vu que les données en entrée ne précisent pas de date de début pour la période "jusqu'au 09/07/2012". En tous cas je suis parti sur cette hypothèse...
    • Pour modéliser la date de fin, il faudrait ajouter un jour par rapport à la date de l'énoncé. En effet, si pour un humain il est clair que "du 20/07 au 20/07" signifie "toute la journée du 20/07", pour un ordinateur c'est une période de durée nulle (la date de début et la date de fin étant égales). En fait, la période qui représente la journée du 20/07 commence le 20/07 à 0:00 et se termine le 21/07 à 0:00. Donc il faut soit modifier les données en entrée, soit ajouter 1 jour à la date de fin dans le code. Vu que tu ne peux sans doute pas modifier facilement les données d'entrée, on va prendre la 2e option et corriger dans le code en ajoutant 1 jour.


    Vu que c'est un problème qui peut se retrouver dans différentes situations, autant faire une solution générique qui sera réutilisable.

    On va commencer par créer une classe pour représenter un intervalle entre deux valeurs :

    Code C# : 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
        public class Interval<T>
        {
            private readonly T _start;
            private readonly T _end;
     
            public Interval(T start, T end)
            {
                _start = start;
                _end = end;
            }
     
            public T Start
            {
                get { return _start; }
            }
     
            public T End
            {
                get { return _end; }
            }
     
            public bool OverlapsWith(Interval<T> other, IComparer<T> comparer = null)
            {
                comparer = comparer ?? Comparer<T>.Default;
                return this.Includes(other.Start, comparer)
                    || this.Includes(other.End, comparer)
                    || other.Includes(this.Start, comparer)
                    || other.Includes(this.End, comparer);
            }
     
            public Interval<T> Merge(Interval<T> other, IComparer<T> comparer = null)
            {
                comparer = comparer ?? Comparer<T>.Default;
                T start = comparer.Min(this.Start, other.Start);
                T end = comparer.Max(this.End, other.End);
                return Interval.Create(start, end);
            }
     
            public bool Includes(T value, IComparer<T> comparer = null)
            {
                comparer = comparer ?? Comparer<T>.Default;
                return (this.Start == null || comparer.Compare(this.Start, value) <= 0)
                    && (this.End == null || comparer.Compare(value, this.End) <= 0);
            }
        }

    Dans ton cas, T sera de type DateTime?La méthode OverlapsWith indiquent si deux intervalles se chevauchent
    La méthode Merge fusionne deux intervalles en un seul
    On laisse la possibilité de préciser un compateur spécifique pour comparer les valeurs, mais dans ton cas on ne l'utilisera pas, puisque le comparateur par défaut convient.
    Les méthodes Min et Max sont des méthodes d'extension définies comme suit :

    Code C# : 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
            public static T Min<T>(this IComparer<T> comparer, T x, T y)
            {
                if (comparer == null)
                    throw new ArgumentNullException("comparer");
                if (comparer.Compare(x, y) <= 0)
                    return x;
                return y;
            }
     
            public static T Max<T>(this IComparer<T> comparer, T x, T y)
            {
                if (comparer == null)
                    throw new ArgumentNullException("comparer");
                if (comparer.Compare(x, y) >= 0)
                    return x;
                return y;
            }
    (à placer dans une classe statique, nommée par exemple ExtensionMethods)

    Voyons maintenant la méthode qui fait tout le boulot, c'est à dire la consolidation des intervalles qui se chevauchent. C'est encore une méthode d'extension :

    Code C# : 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
            public static IEnumerable<Interval<T>> Consolidate<T>(this IEnumerable<Interval<T>> intervals, IComparer<T> comparer = null)
            {
                comparer = comparer ?? Comparer<T>.Default;
                bool first = true;
                Interval<T> prev = null;
                intervals = intervals.OrderBy(i => i.Start, comparer)
                                     .ThenBy(i => i.End, comparer);
                foreach (var item in intervals)
                {
                    if (first)
                    {
                        prev = item;
                        first = false;
                        continue;
                    }
     
                    if (item.OverlapsWith(prev))
                    {
                        prev = item.Merge(prev);
                    }
                    else
                    {
                        yield return prev;
                        prev = item;
                    }
                }
                if (!first)
                    yield return prev;
            }

    En résumé :
    - on trie les intervalles par date de début, puis par date de fin
    - on prend les intervalles un par un
    - si l'intervalle actuel et le précédent se chevauchent, on les fusionne
    - sinon, c'est le début d'un nouvel intervalle ; on renvoie le précédent puisqu'il est terminé


    Maintenant qu'on a une solution générique, voyons comment l'appliquer à ton problème. Il faut :
    • faire correspondre à chaque objet Periode un objet Interval<DateTime?> (puisque c'est la dessus que l'algorithme travaille)
    • grouper les intervalles par taux, puisqu'on ne doit fusionner que les périodes qui ont le même taux
    • dans chaque groupe, fusionner les intervalles qui peuvent l'être (en utilisant la méthode Consolidate ci-dessus)
    • retransformer chaque intervalle en un objet Periode

    Bref, que des choses faciles à faire avec Linq... ça donne quelque chose comme ça :

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
                var results =
                    from p in periodes
                    let i = new Interval<DateTime?>(p.DateDebut, p.DateFin.AddDays(1))                     // création d'un intervalle pour chaque période
                    group i by p.Taux into g                                                               // groupement des intervalles par taux
                    from i in g.Consolidate()                                                              // consolidation des intervalles dans chaque groupe
                    select new Periode { DateDebut = i.Start, DateFin = i.End.AddDays(-1), Taux = g.Key }; // transformation des intervalles en objets Periode
     
                // affichage des résultats
                foreach (var periode in results)
                {
                    string debut = periode.DateDebut.HasValue ? periode.DateDebut.Value.ToShortDateString() : "          ";
                    string fin = periode.DateFin.HasValue ? periode.DateFin.Value.ToShortDateString() : "          ";
                    Console.WriteLine("{0} => {1} : {2}", debut, fin, periode.Taux);
                }

    AddDays permet de corriger les dates de fin (comme expliqué plus haut) ; on l'appelle à nouveau pour retrancher 1 jour à la fin pour que les résultats suivent la même logique que les données d'entrée. Par contre, la vraie méthode AddDays est une méthode de DateTime, on ne peut pas l'utiliser directement sur un objet DateTime? (nullable). Ici on utilise donc une méthode d'extension créée spécifiquement pour ça :

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
            public static DateTime? AddDays(this DateTime? date, int days)
            {
                if (date.HasValue)
                    return date.Value.AddDays(days);
                return null;
            }

    Au final, le résultat est le suivant :

    21/07/2012 =>            : 1,0
    20/07/2012 => 20/07/2012 : 2,0
    15/07/2012 => 19/07/2012 : 3,0
               => 14/07/2012 : 4,0

  7. #7
    Membre éprouvé Avatar de sisqo60
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2006
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 754
    Points : 1 188
    Points
    1 188
    Par défaut
    Citation Envoyé par MaximePalmisano Voir le message
    Salut sisqo60,

    Le code que j'ai fourni n'est la qu'à titre d'exemple pour lui donner une idée de comment résoudre le problème. C'est fait sur un coin de table sans tests ni rien.

    C'est à celui qui a le problème d'écrire le vrai algorithme et de le tester pour être sur que tous les usecases sont bons

    (Btw j'ai précisé que c'était valable que si les taux égaux avaient des intervalles collés)
    C'était pas un reproche, je voulais juste le prévenir qu'il y aurait des problèmes si il copiait collait le code tel qu'il est. C'est déjà pas mal que tu aies pris le temps d'écrire un début d'algo pour lui

    Bon dév.
    Un âne se croit savant parce qu'on le charge de livres (proverbe américain)

    N'oubliez pas de avant de
    Pas de question techniques par MP, c'est contre la philosophie du forum

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    110
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 110
    Points : 44
    Points
    44
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Il me semble que la dernière ligne du résultat devrait plutôt être : "jusqu'au 14/04/2012 4,00%", vu que les données en entrée ne précisent pas de date de début pour la période "jusqu'au 09/07/2012". En tous cas je suis parti sur cette hypothèse...
    Erreur grave ! . Ce que j'ai écrit comme exemple dans la seconde liste est bien le résultat que je dois obtenir. C'est de ma faute je n'ai pas été assez explicite. Les périodes 'Jusqu'au' correspondent à une date de fin, les périodes 'A partir du' correspondent à une date de début.
    Dans mon cas, les périodes dites 'complètes' (celles qui ont une date de début et de fin) son prioritaires.

    Quoiqu'il en soit merci pour cette leçon, j'ai encore mal à la tête suite à la lecture de ces quelques lignes...

    @sisqo60
    @tomlev


    Je vous rassure tous les deux, les dates se suivent toujours, je veille au grain. J'effectue un traitement de façon à ce que les périodes ne comportes jamais de 'trou'. En reprenant comme exemple - cas le plus tordu - une partie d'une période existante remplacée en partie par une autre avec un taux différent bien évidemment.

    On part d'une période existante qui court du 15/07/2012 au 19/07/2012 :

    1) J'insère une nouvelle qui va du 17/07/2012 au 18/07/2012.

    Après remaniement, le résultat obtenu est

    a) modification de l'ancienne période du 18/07/2012 au 19/07/2012,
    b) création d'unu nouvelle période allant du 15/07/2012 au 16/07/2012,
    c) ensuite j'insère la nouvelle période qui va du 17/07/2012 au 18/07/2012entre les deux.

    Dans tous les cas, les périodes se suivent, et ce, quel que soit la manipulation qui est effectuée. Création, modification, allongement, réduction, remplacement d'une période.

    Il ne me manquait plus que la fusion des périodes dont le taux est identique. Là je coinçais vraiment.

    @tomlev

    Maintenant, il n'y a plus qu'à modifier la requête LINQ afin qu'elle colle parfaitement au résultat escompté. Mais je l'ai déjà dit, ce n'est pas une obligation, en effet, pour le cas des périodes incomplètes (date de début ou date de fin non renseignés), j'ai codé un petit traitement qui résoud ce problème.

    Dans tous les cas je vous remercie chaleureusement de votre aide précieuse.

  9. #9
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par sylvebarbe78 Voir le message
    Erreur grave ! . Ce que j'ai écrit comme exemple dans la seconde liste est bien le résultat que je dois obtenir. C'est de ma faute je n'ai pas été assez explicite. Les périodes 'Jusqu'au' correspondent à une date de fin, les périodes 'A partir du' correspondent à une date de début.
    Dans mon cas, les périodes dites 'complètes' (celles qui ont une date de début et de fin) son prioritaires.
    OK, mais dans ce cas, que devient cette ligne ?
    jusqu'au 09/07/2012 4,00%
    Tel que je le comprends, ça vaut dire que n'importe quand avant le 09/07, le taux est de 4%, non ? Ce qui n'apparait pas du tout dans le résultat que tu veux...

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    110
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 110
    Points : 44
    Points
    44
    Par défaut
    Citation Envoyé par tomlev Voir le message
    OK, mais dans ce cas, que devient cette ligne ?

    Tel que je le comprends, ça vaut dire que n'importe quand avant le 09/07, le taux est de 4%, non ? Ce qui n'apparait pas du tout dans le résultat que tu veux...
    Et non, et personnellement je trouve cela logique ! Il en serait tout autrement si son taux était différent. Une fois les périodes fusionnées, libre à l'utilisateur de créer une nouvelle période 'Jusqu'au' se finissant le 08/07/2012 mais avec un taux différent. La règle est stricte, toutes les périodes adjacentes possédant un taux identique doivent être fusionnées.

    Tu me suis ?

    Quoi qu'il en soit étant qu'un débutant en C#, je n'arrive pas à faire fonctionner ton code. J'ai bien créé la classe statique ExtensionMethods avec son contenu comme indiqué (public static T Min<T> & public static T Max<T>). J'ai beau recopier les autres portions de code dans ma page .aspx et suivre tes indications, j'ai de nombreuses indications qui me disent que cela ne va pas...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public Interval<T> Merge(Interval<T> other, IComparer<T> comparer = null)
                {
                    ...
                    return Interval.Create(start, end);
                }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
            public static DateTime? AddDays(this DateTime? date, int days)
            {
                ...
            }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public static IEnumerable<Interval<T>> Consolidate<T>(this IEnumerable<Interval<T>> intervals, IComparer<T> comparer = null)
    {
    ...
    }
    Tes classe Interval , AddDays, Consolidate où dois-je les mettre, pas dans ma page .aspx ?


    @MaximePalmisano

    aïe ! Après quelques essais j'ai relevé un gros bug. La fusion est trop efficace... En effet, en reprenant la liste de départ, si je rajoute une nouvelle période dont le taux est identique à une période existante mais non adjacente à la nouvelle, elle disparait !!!! curieux... En fait, c'est plus grave que cela, ton traitement fait en sorte qu'il ne peut y avoir qu'une seule période avec un taux donné !

    Du coup je me retrouve à la case départ :-(

    Cordialement

  11. #11
    Membre éprouvé

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2011
    Messages
    487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2011
    Messages : 487
    Points : 945
    Points
    945
    Par défaut
    Ah je croyais que c'était justement ce que tu voulais, avoir une seule période pour un taux donné.

    J'ai pas pu consacrer beaucoup de temps à ton problème, du coup j'ai vraiment donné une idée d'implémentation en survolant le truc. Essaye de voir avec la solution de tomlev qui est meilleure sur bien des points


    PS: Si tu veux que les périodes soit mergées seulement si elles sont collées ou imbriquées, tu peux reprendre la méthode de tomlev.
    Mon blog sur les technos .NET et Agile -> http://blog.developpez.com/maximepalmisano/

  12. #12
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par sylvebarbe78 Voir le message
    Et non, et personnellement je trouve cela logique ! Il en serait tout autrement si son taux était différent. Une fois les périodes fusionnées, libre à l'utilisateur de créer une nouvelle période 'Jusqu'au' se finissant le 08/07/2012 mais avec un taux différent. La règle est stricte, toutes les périodes adjacentes possédant un taux identique doivent être fusionnées.

    Tu me suis ?
    Non, pas du tout...

    Peut-être que je me trompe, mais pour moi la période "jusqu'au 09/07/2012" est équivalente à "depuis l'origine des temps jusqu'au 09/07/2012", avec un taux de 4%.
    La période suivante, du 10/07 au 14/07, est adjacente et a également un taux de 4 %

    Donc il faut fusionner les 2, ce qui donne une période "depuis l'origine des temps jusqu'au 14/07/2012"

    Je ne vois vraiment pas selon quelle logique tu décides d'ignorer la période avant le 09/07, alors que tu prends bien en compte la période après le 21/07...

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    110
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 110
    Points : 44
    Points
    44
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Non, pas du tout...

    Peut-être que je me trompe, mais pour moi la période "jusqu'au 09/07/2012" est équivalente à "depuis l'origine des temps jusqu'au 09/07/2012", avec un taux de 4%.
    La période suivante, du 10/07 au 14/07, est adjacente et a également un taux de 4 %

    Donc il faut fusionner les 2, ce qui donne une période "depuis l'origine des temps jusqu'au 14/07/2012"

    Je ne vois vraiment pas selon quelle logique tu décides d'ignorer la période avant le 09/07, alors que tu prends bien en compte la période après le 21/07...
    Voilà une question qu'elle est bonne ! Pas l'origine des temps, mais depuis une date de début de période comptable mais qui n'apparait pas ici dans ce traitement. Et la logique du traitement, c'est pas moi qui la décide mais d'autres personnes... Par contre, ce serait super sympa de ta part de m'expliquer comment mettre en place ton traitement car je rencontre pas mal de problèmes décrits dans mon post précédent.

    Merci

    @MaximePalmisano

    Pas de problème, et encore merci !

  14. #14
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par sylvebarbe78 Voir le message
    Pas l'origine des temps, mais depuis une date de début de période comptable mais qui n'apparait pas ici dans ce traitement.
    Mouais... enfin c'est quand même bizarre : dans les données d'entrée, le 09/07 est une date de fin, je vois pas par quelle miracle elle devient une date de début

    Citation Envoyé par sylvebarbe78 Voir le message
    Par contre, ce serait super sympa de ta part de m'expliquer comment mettre en place ton traitement car je rencontre pas mal de problèmes décrits dans mon post précédent.
    J'ai oublié un bout en écrivant mon post... Interval.Create(...) est en fait juste un "helper" pour créer un intervalle en utilisant l'inférence de type, tu peux remplacer par new Inverval<T>(...).

    AddDays et Consolidate sont des méthodes d'extensions, donc à mettre aussi dans la classe ExtensionMethods

  15. #15
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    110
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 110
    Points : 44
    Points
    44
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Mouais... enfin c'est quand même bizarre : dans les données d'entrée, le 09/07 est une date de fin, je vois pas par quelle miracle elle devient une date de début
    Certes, il est vrai que le 09/07 est une date de fin, je te l'accorde mais en quelque sorte c'est une date de début... Comme je l'ai précédemment, lorsque 2 périodes se suivent, que leur taux est identique et que l'une des 2 est une période "Jusqu'au", c'est la période pleine qui est prioritaire. En d'autres termes la période pleine "absorbe" l'autre période. A la charge de l'utilisateur d'ajouter une nouvelle période "Jusqu'au" venant s'insérer entre la date comptable de départ et la date de début de la période suivante, du moment qu'elle possède une date de fin inférieure à la date de début et surtout avec un taux différent de la période suivante. Pas facile à suivre, hein ?

    Prenons par exemple une date comptable qui démarre le 01/01/2012. Supposons qu'il existe une période "Jusqu'au" finissant le 01/02/2012 avec un taux de 3%, suivie d'une période pleine qui court du 02/02/2012 au 10/02/2012 avec un taux identique, il est normal que l'on remplace la période "Jusqu'au" par une période pleine courant du 01/01/2012 au 10/02/2012 ! L'utilisation d'une période "Jusqu'au" suppose que la période suivante possède un taux différent :

    du 02/02/2012 au 10/02/2012 à 3%
    du 01/01/2012 jusqu'au 01/02/2012 à 3%
    =
    du 01/01/2012 au 10/02/2012 à 3%

    (note qu'on aurait pu remplacer la période finale du 01/01/2012 au 10/02/2012 à 3% par Jusqu'au 10/02/2012 à 3%...)

    Les choses seraient bien différentes si la période "Jusqu'au" s'arrêtait le 01/02/2012 avec un taux de 3% suivie d'une période pleine avec un taux de 4% :

    du 02/02/2012 au 10/02/2012 à 4%
    du 01/01/2012 jusqu'au 01/02/2012 à 3%
    =
    du 02/02/2012 au 10/02/2012 à 4%
    du 01/01/2012 jusqu'au 01/02/2012 à 3%



    Toujours pas convaincu ?

  16. #16
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par sylvebarbe78 Voir le message
    Toujours pas convaincu ?
    Non, mais ça fait rien... C'est pour ça que je trouve ça gonflant de développer des applications métiers, tu es obligé de prendre en compte des "logiques" qui n'ont rien de logique, juste parce que c'est comme ça que le business fonctionne . Et c'est pour ça que je fais un boulot purement technique où je n'ai pas à prendre en compte ce genre d'aberrations

  17. #17
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    110
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 110
    Points : 44
    Points
    44
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Non, mais ça fait rien... C'est pour ça que je trouve ça gonflant de développer des applications métiers, tu es obligé de prendre en compte des "logiques" qui n'ont rien de logique, juste parce que c'est comme ça que le business fonctionne . Et c'est pour ça que je fais un boulot purement technique où je n'ai pas à prendre en compte ce genre d'aberrations
    D'accord avec toi. Au début, j'ai eu la même réaction que la tienne, puis je me suis fait une raison. Il y a longtemps que je ne cherche plus à comprendre des logiques qui en ont aucune, ça m'évite les migraines

    Quoi qu'il en soit, je te remercie pour ton aide précieuse . Peut-être reviendrai-je bientôt à propos de ta solution. (c'est pour cela que je ne vais pas fermer ce sujet tout de suite)

    A bientôt...

Discussions similaires

  1. Problème résolution d'ecran dans mes vues
    Par Cyang dans le forum Développement Web en Java
    Réponses: 0
    Dernier message: 06/09/2011, 15h25
  2. Réponses: 1
    Dernier message: 19/04/2006, 16h32
  3. Problème avec l'initialisation de mes variables
    Par francois.delpierre dans le forum Langage
    Réponses: 4
    Dernier message: 18/10/2005, 02h18
  4. problème insoluble avec CHECK
    Par NiBicUs dans le forum SQL Procédural
    Réponses: 6
    Dernier message: 25/03/2004, 17h13
  5. Problèmes avec des vues
    Par dady dans le forum MFC
    Réponses: 22
    Dernier message: 09/01/2004, 16h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo