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

Python Discussion :

problème de liste, avec des dates ?


Sujet :

Python

  1. #1
    Membre du Club
    Homme Profil pro
    Inscrit en
    Août 2011
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2011
    Messages : 57
    Points : 46
    Points
    46
    Par défaut problème de liste, avec des dates ?
    Bonjour,

    je suis occupé à essayer d'utiliser un module 'Workdays' permettant de calculer une différence entre deux dates en excluant les jours de congés que voici:

    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
    49
    50
    51
    52
     
    from datetime import date, timedelta
     
    # started from the code of Casey Webster at
    # http://groups.google.com/group/comp.lang.python/browse_thread/thread/ddd39a02644540b7
     
    # Define the weekday mnemonics to match the date.weekday function
    (MON, TUE, WED, THU, FRI, SAT, SUN) = range(7)
    weekends=(SAT,SUN)
     
     
    def networkdays(start_date, end_date, holidays=[]):
        delta_days = (end_date - start_date).days + 1
        full_weeks, extra_days = divmod(delta_days, 7)
        # num_workdays = how many days/week you work * total # of weeks
        num_workdays = (full_weeks + 1) * (7 - len(weekends))
        # subtract out any working days that fall in the 'shortened week'
        for d in range(1, 8 - extra_days):
            if (end_date + timedelta(d)).weekday() not in weekends:
                 num_workdays -= 1
        # skip holidays that fall on weekends
        holidays =  [x for x in holidays if x.weekday() not in weekends]
        # subtract out any holidays
        for d in holidays:
            if d >= start_date and d <= end_date:
                num_workdays -= 1
        return num_workdays
     
    def _in_between(a,b,x):
        #return cmp(a,x) * cmp(x,b) > 0
        return a <= x and x <= b or b <= x and x <= a
     
     
    def workday(start_date,days, holidays=[]):
     
        full_weeks, extra_days = divmod(days,7 - len(weekends))
        new_date = start_date + timedelta(weeks=full_weeks)
        for i in range(extra_days):
            new_date += timedelta(days=1)
            while new_date.weekday() in weekends:
                new_date += timedelta(days=1)
        delta = timedelta(days=1 * cmp(days,0))
        # skip holidays that fall on weekends
        holidays =  [x for x in holidays if x.weekday() not in weekends ]
        holidays =  [x for x in holidays if x <> start_date ]
        for d in sorted(holidays, reverse = (days < 0)):
            # if d in between start and current push it out one working day
            if _in_between(start_date, new_date, d):
                new_date += delta
                while new_date.weekday() in weekends:
                    new_date += delta
        return new_date
    Pour son utilisation, il faut faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    #workday(start_date,days,[list_of_holidays])
    days = workday(date(2009,12,25),656, [ date(2009,12,25), date(2009,07,13),date(2011,02,02)] )
    print days
    jusque là, ca fonctionne, je peux sans problème ajouter mes dates holidays à la liste...
    Mais bon, pour mettre en application, je voudrais récupérer une liste depuis un fichier de style:

    date(21,07,2013),date(22,07,2013),date(2013,07,14)

    ou encore:
    21-07-2013
    22-07-2013
    14-07-2013


    et créer une liste avec:

    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
     
    # lecture d'un fichier et retourne une liste
    def lireFichierRetourTab(path):
        fichier = open(path,"r")
        ligne = fichier.read()
     
        ligne = ligne.split()
        ligne = list(ligne)
        return ligne;
     
    test= lireFichierRetourTab('F:\exos python\workdays-1.0.tar\workdays-1.0\conges.txt')
     
     
    days = workday(date(2013,07,01),12, test)
     
    print days
    mais la sortie me donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Traceback (most recent call last):
      File "F:\exos python\workdays-1.0.tar\workdays-1.0\workdays2.py", line 67, in <module>
        days = workday(date(2013,07,01),12, test)
      File "F:\exos python\workdays-1.0.tar\workdays-1.0\workdays2.py", line 43, in workday
        holidays =  [x for x in holidays if x.weekday() not in weekends ]
    AttributeError: 'str' object has no attribute 'weekday'
    pourtant avec un print type(), j'ai bien un type liste ['date(21,07,2013),date(22,07,2013)']

    Donc, en fin de compte, ma question est, comment faire pour obtenir une liste de dates dans un fichier lisibles par datetime

    Un tout grand merci d'avance

  2. #2
    Membre régulier
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Janvier 2010
    Messages : 58
    Points : 93
    Points
    93
    Par défaut
    Salut,

    Ta variable test est bien un tableau mais c'est un tableau contenant une seule string 'date(21,07,2013),date(22,07,2013)'.
    Il faut que tu split ta string et que tu transformes tes strings en date.

    Courage

  3. #3
    Membre du Club
    Homme Profil pro
    Inscrit en
    Août 2011
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2011
    Messages : 57
    Points : 46
    Points
    46
    Par défaut
    je split à la ligne 7

    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
     
     
    # lecture d'un fichier et retourne une liste
    def lireFichierRetourTab(path):
        fichier = open(path,"r")
        ligne = fichier.read()
     
        ligne = ligne.split()
        ligne = list(ligne)
        return ligne;
     
    test= lireFichierRetourTab('F:\exos python\workdays-1.0.tar\workdays-1.0\conges.txt')
     
     
    days = workday(date(2013,07,01),12, test)
     
    print days
    mais rien à faire

  4. #4
    Membre expérimenté Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Points : 1 481
    Points
    1 481
    Par défaut
    Un peu d'initiative et de curiosité, que diable !
    Un simple split, sans paramètre, découpe une chaîne avec, comme séparateur, un "espace" (à prendre au sens large).
    M'est avis que la virgule serait plus appropriée (même si elle apparaît à plusieurs endroits, et notamment dans les dates)

  5. #5
    Membre du Club
    Homme Profil pro
    Inscrit en
    Août 2011
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2011
    Messages : 57
    Points : 46
    Points
    46
    Par défaut
    Bonjour,

    Après plusieurs jours de réflexions, j'ai enfin trouvé.
    Voici le solution:
    soit un fichier nommé holydays.txt qui reprends les dates suivantes:

    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
     
    1-1-2013
    2-1-2013
    1-4-2013
    1-5-2013
    9-5-2013
    10-5-2013
    20-5-2013
    15-8-2013
    16-8-2013
    1-11-2013
    11-11-2013
    24-12-2013
    25-12-2013
    31-12-2013
    1-1-2014
    pour le lister:
    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
     
    """ Ouverture du fichier vacances et listage des dates """
     
    f=open('Data\holidays.txt');
    fdata = f.read()
    definedholidays=fdata.split();
    f.close();
    liste =[]
    #exclude any holidays that have been marked in the companies academic year
    for definedholiday in definedholidays:
        flag=0;
        day , month , year = definedholiday.split('-')
        holidate = date(int(year) , int(month) , int(day))
        liste.append (holidate)
    print liste
    et la sortie:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    [datetime.date(2013, 1, 1), datetime.date(2013, 1, 2),
     datetime.date(2013, 4, 1), datetime.date(2013, 5, 1),
     datetime.date(2013, 5, 9), datetime.date(2013, 5, 10),
     datetime.date(2013, 5, 20), datetime.date(2013, 8, 15),
     datetime.date(2013, 8, 16), datetime.date(2013, 11, 1),
     datetime.date(2013, 11, 11), datetime.date(2013, 12, 24),
     datetime.date(2013, 12, 25), datetime.date(2013, 12, 31),
     datetime.date(2014, 1, 1)]

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 297
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 297
    Points : 36 794
    Points
    36 794
    Par défaut
    Salut,

    La sortie:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    HOLIDAYS=[datetime.date(2013, 1, 1), datetime.date(2013, 1, 2),
     datetime.date(2013, 4, 1), datetime.date(2013, 5, 1),
     datetime.date(2013, 5, 9), datetime.date(2013, 5, 10),
     datetime.date(2013, 5, 20), datetime.date(2013, 8, 15),
     datetime.date(2013, 8, 16), datetime.date(2013, 11, 1),
     datetime.date(2013, 11, 11), datetime.date(2013, 12, 24),
     datetime.date(2013, 12, 25), datetime.date(2013, 12, 31),
     datetime.date(2014, 1, 1)]
    est une représentation des "holidays" utilisable par votre programme.

    Construire cela a partir d'un fichier texte suppose réfléchir a faciliter leur entrée par l'utilisateur.
    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    [YEAR_2013]
    april=1
    may=1,9,10,20
    august=15,16
    ...
    Il n'est pas non plus a exclure que la liste puisse être récupérée sur le Web dans un format JSON.
    Tout ça pour dire que, définir HOLIDAYS par ce qui est attendu par votre programme et écrire le code qui permettra de le construire a partir d'informations externes répondent a des besoins différents.

    Dans tous les cas (et ce n'est pas intuitif), on part d'un /buffer/ (ici, le fichier) dont on extrait des /block/ d'information qui serviront a construire les /item/ attendus (ici des objets de type date).

    Avec un /buffer/ (file.read()) de la forme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    1-1-2013
    2-1-2013
    1-4-2013
    ...
    les /block/ sont les lignes et s'obtiennent via buffer.splitlines()
    Comme on veut transformer cela en /item/ de type date, on se rappellera qu'on peut indiquer le format du /block/ via .strptime.

    Votre code pourrait se réduire a:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    with open('Data\holidays.txt') as f:
        HOLIDAYS=[ datetime.strptime(line, '%d-%m-%Y').date() for line in f.read().splitlines() ]
    - W

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [MySQL-5.0] Problème de requête avec des dates
    Par trivet61 dans le forum Requêtes
    Réponses: 2
    Dernier message: 11/09/2013, 10h50
  2. Problème de débutant avec des listes !
    Par bootinette dans le forum Général Python
    Réponses: 6
    Dernier message: 30/11/2011, 11h40
  3. Problème de rendu avec des listes
    Par Erwane dans le forum Scheme
    Réponses: 19
    Dernier message: 03/03/2008, 21h27
  4. [Dates] Problème avec des dates et Heures
    Par snakejl dans le forum Langage
    Réponses: 9
    Dernier message: 16/05/2006, 18h04
  5. [VBA-E] Problème avec des dates !
    Par yaya54 dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 21/03/2006, 13h12

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