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 :

Compter les mardis hors vacances scolaires et jours fériés


Sujet :

Python

  1. #1
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut Compter les mardis hors vacances scolaires et jours fériés
    Je souhaite compter, sur une période donnée, le nombre de mardis hors vacances scolaires et jours fériés. Quelqu'un sait-il s'il existe une bibliothèque qui gère cela ?

  2. #2
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Il serait étonnant qu'il existe un module Python qui sache calculer les jours fériés France, mais bon. Pourquoi pas...

    En tout cas, tu peux t'inspirer de mes fonctions de dates qui n'utilisent pas (ou peu) les modules date de Python, mais qui savent calculer la date de Paques, ainsi que les jours fériés qui y sont liés:

    http://python.jpvweb.com/mesrecettes..._et_aux_heures

    Tu peux tester la plupart de ces fonctions avec ma calculatrice en ligne:

    http://calculext.jpvweb.com/

    Je peux t'aider à utiliser ces fonctions pour résoudre ton pb si tu le souhaites.

    Tyrtamos
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  3. #3
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Citation Envoyé par tyrtamos Voir le message
    Il serait étonnant qu'il existe un module Python qui sache calculer les jours fériés France, mais bon. Pourquoi pas...
    Au temps pour moi, j'ai mal posé ma question. Je pars du principe que les dates des vacances et des jours fériés sont connues car ceci est effectivement très spécifiques à un contexte donné.

    En résumé, j'ai une période donnée dans laquelle se trouvent d'autres périodes non travaillées, et il me faut juste compter les mardis travaillés. Est-ce plus clair ?

  4. #4
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    C'est bien dommage, c'était plus compliqué...

    Peux-tu dire comment les jours fériés et les vacances sont données: liste de couple de date (datedébut <-> datefin)?

    Tyrtamos
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  5. #5
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Citation Envoyé par tyrtamos Voir le message
    C'est bien dommage, c'était plus compliqué...
    Désolé...

    Citation Envoyé par tyrtamos Voir le message
    Peux-tu dire comment les jours fériés et les vacances sont données: liste de couple de date (datedébut <-> datefin)?
    Tout simplement oui.

  6. #6
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    L’un des bénéfices de l'informatique et de l'internet: augmenter la productivité.
    La preuve: il n'a fallu qu'une heure pour obtenir l'énoncé.
    Par voie postale, à raison d'une lettre par jour, ça aurait pris 4 jours.

  7. #7
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Citation Envoyé par eyquem Voir le message
    L’un des bénéfices de l'informatique et de l'internet: augmenter la productivité.
    La preuve: il n'a fallu qu'une heure pour obtenir l'énoncé.
    Par voie postale, à raison d'une lettre par jour, ça aurait pris 4 jours.
    Exellent ! Toujours plus fou, on a même une réponse de celui qui a posé la question...
    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
    #!/usr/bin/env python
    #coding=utf-8
     
    import time
     
    # Easy definitions of the differents dates.
    firstDay = "2-9-2009"
    lastDay = "2-7-2010"
     
    hollidays = [
        ("24-10-2009", "05-11-2009"),
        ("19-12-2009", "04-01-2010"),
        ("13-02-2010", "01-03-2010"),
        ("10-04-2010", "26-04-2010")
                ]
     
    # We work in second since the epoch.
    def secunds(strDate):
        return time.mktime(time.strptime(strDate, "%d-%m-%Y"))
     
    # The following lines find the Thuesday worked.
    oneDay = 60*60*24
    firstDay = secunds(firstDay)
    lastDay = secunds(lastDay)
    hollidays = [(secunds(x[0]),secunds(x[1])) for x in hollidays]
     
    dayToTest = firstDay
     
    while dayToTest <= lastDay:
        strDate = time.ctime(dayToTest)
    # We have something like :
    #   Thu Sep  3 00:00:00 2009
     
        if strDate.split()[0] == 'Thu':
            print ' '.join(time.ctime(dayToTest).split()[:3])
        dayToTest += oneDay
    Toute remarque constructive sur ce code est la bienvenue.

  8. #8
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Une petite amélioration (enfin de mon point de vue) :
    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
    #!/usr/bin/env python
    #coding=utf-8
     
    import time
    # Cf.  http://docs.python.org/library/time.html
     
     
    # Easy definitions of the differents dates.
    firstDay = "2-9-2009"
    lastDay = "2-7-2010"
     
    hollidays = [
        ("24-10-2009", "05-11-2009"),
        ("19-12-2009", "04-01-2010"),
        ("13-02-2010", "01-03-2010"),
        ("10-04-2010", "26-04-2010")
                ]
     
     
    # We work in second since the epoch.
    def user2sec(strDate):
        return time.mktime(time.strptime(strDate, "%d-%m-%Y"))
     
    def sec2user(secDate):
        secDate = time.ctime(secDate).split()
        secDate = ' '.join(secDate[1:3] + secDate[4:])
        secDate = time.strptime(secDate, "%b %d %Y")
        return time.strftime("%d-%m-%Y", secDate)
     
     
    # The following lines find the Thuesday worked.
    oneDay = 60*60*24
    firstDay = user2sec(firstDay)
    lastDay = user2sec(lastDay)
    hollidays = [(user2sec(x[0]),user2sec(x[1])) for x in hollidays]
     
    dayToTest = firstDay
     
    while dayToTest <= lastDay:
        strDate = time.ctime(dayToTest)
    # We have something like :
    #   Thu Sep  3 00:00:00 2009
     
        if strDate.split()[0] == 'Thu':
            print sec2user(dayToTest)
     
        dayToTest += oneDay

  9. #9
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Au temps pour moi, j'ai juste oublié les vacances... C'est un peu dommage. Je reviens de suite avec le bon script..

  10. #10
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Voilà.

    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
    53
    #!/usr/bin/env python
    #coding=utf-8
     
    import time
    # Cf.  http://docs.python.org/library/time.html
     
     
    # Easy definitions of the differents dates.
    firstDay = "2-9-2009"
    lastDay = "2-7-2010"
     
    hollidays = [
        ("24-10-2009", "05-11-2009"),
        ("19-12-2009", "04-01-2010"),
        ("13-02-2010", "01-03-2010"),
        ("10-04-2010", "26-04-2010")
                ]
     
     
    # We work in second since the epoch.
    def user2sec(strDate):
        return time.mktime(time.strptime(strDate, "%d-%m-%Y"))
     
    def sec2user(secDate):
        secDate = time.ctime(secDate).split()
        secDate = ' '.join(secDate[1:3] + secDate[4:])
        secDate = time.strptime(secDate, "%b %d %Y")
        return time.strftime("%d-%m-%Y", secDate)
     
    def notInHolliday(date, hollidays):
        for x in hollidays:
            if x[0] <= date <= x[1]:
                return False
        return True
     
    # The following lines find the Thuesday worked.
    oneDay = 60*60*24
    firstDay = user2sec(firstDay)
    lastDay = user2sec(lastDay)
    hollidays = [(user2sec(x[0]),user2sec(x[1])) for x in hollidays]
     
    dayToTest = firstDay
     
    while dayToTest <= lastDay:
        strDate = time.ctime(dayToTest)
    # We have something like :
    #   Thu Sep  3 00:00:00 2009
     
        if strDate.split()[0] == 'Thu':
            if notInHolliday(dayToTest, hollidays):
                print sec2user(dayToTest)
     
        dayToTest += oneDay

  11. #11
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    A faire plusieurs choses en même temps, j'ai fait une étourderie sans conséquence : mon script trouve les jeudis (Thursday) et non les mardis (Tuesday).

  12. #12
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Alors, finalement, combien trouves-tu de mardis?

    Moi, avec tes dates et mes codes, j'en trouve 36:

    08/09/2009 marche
    15/09/2009 marche
    22/09/2009 marche
    29/09/2009 marche
    06/10/2009 marche
    13/10/2009 marche
    20/10/2009 marche
    27/10/2009 ne marche pas
    03/11/2009 ne marche pas
    10/11/2009 marche
    17/11/2009 marche
    24/11/2009 marche
    01/12/2009 marche
    08/12/2009 marche
    15/12/2009 marche
    22/12/2009 ne marche pas
    29/12/2009 ne marche pas
    05/01/2010 marche
    12/01/2010 marche
    19/01/2010 marche
    26/01/2010 marche
    02/02/2010 marche
    09/02/2010 marche
    16/02/2010 ne marche pas
    23/02/2010 ne marche pas
    02/03/2010 marche
    09/03/2010 marche
    16/03/2010 marche
    23/03/2010 marche
    30/03/2010 marche
    06/04/2010 marche
    13/04/2010 ne marche pas
    20/04/2010 ne marche pas
    27/04/2010 marche
    04/05/2010 marche
    11/05/2010 marche
    18/05/2010 marche
    25/05/2010 marche
    01/06/2010 marche
    08/06/2010 marche
    15/06/2010 marche
    22/06/2010 marche
    29/06/2010 marche
    il y a 36 mardis
    Tyrtamos
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  13. #13
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    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
    08-09-2009   OK
    15-09-2009   OK
    22-09-2009   OK
    29-09-2009   OK
    06-10-2009   OK
    13-10-2009   OK
    20-10-2009   OK
    27-10-2009   PAS OK
    03-11-2009   PAS OK
    10-11-2009   OK
    17-11-2009   OK
    24-11-2009   OK
    01-12-2009   OK
    08-12-2009   OK
    15-12-2009   OK
    22-12-2009   PAS OK
    29-12-2009   PAS OK
    05-01-2010   OK
    12-01-2010   OK
    19-01-2010   OK
    26-01-2010   OK
    02-02-2010   OK
    09-02-2010   OK
    16-02-2010   PAS OK
    23-02-2010   PAS OK
    02-03-2010   OK
    09-03-2010   OK
    16-03-2010   OK
    23-03-2010   OK
    30-03-2010   OK
    06-04-2010   OK
    13-04-2010   PAS OK
    20-04-2010   PAS OK
    27-04-2010   OK
    04-05-2010   OK
    11-05-2010   OK
    18-05-2010   OK
    25-05-2010   OK
    01-06-2010   OK
    08-06-2010   OK
    15-06-2010   OK
    22-06-2010   OK
    29-06-2010   OK
     
    35
    Où est l'erreur ? Sûrement une erreur de compteur... C'est bien cela : tu as 43 lignes moins 8 dates ne convenant pas, soit 35 mardis.

    Ton code est-il simple ?

  14. #14
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Effectivement il y en a 35 et c'est un pb de compteur...

    Tyrtamos
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  15. #15
    Candidat au Club
    Inscrit en
    Avril 2007
    Messages
    1
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 1
    Points : 3
    Points
    3
    Par défaut
    Attention à ne pas oublier les jours fériés

  16. #16
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    Je m’étonne que personne n’ait trouvé à redire sur ton code passable, rambc. Il ne dégage pourtant pas cette impression de concision pythonienne si prisée et il suit un algorithme qui ne s’épargne aucune longueur.



    Son défaut de départ est de faire des comparaisons de jours sous forme float.

    Les floats supportant ces comparaisons représentent en fait des durées depuis EPOCH jusqu'à leur instant 0h 0mn 0s 0ms: ce n’est pas naturel de comparer des durées quand il s’agit en fait de jours.

    Cela rend aussi nécessaire tout un attirail de fonctions du module time pour faire des allers-retours entre les jours sous forme chaîne et les jours sous forme float.

    Pour des manipulations sur des jours, préférer le module datetime, avec sa classe date qui est suffisante en l’occurence.



    Pendant que j’y suis, ta fonction sec2user(secDate) peut se simplifier:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def sec2user(secDate):
        secDate = time.ctime(secDate).split()
        secDate = ' '.join(secDate[1:3] + secDate[4:])
        secDate = time.strptime(secDate, "%b %d %Y")
        return time.strftime("%d-%m-%Y", secDate)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    def sec2user_rac(secDate):
        secDate = time.localtime(secDate)
        return time.strftime("%d-%m-%Y",secDate)








    Coté algorithme, tu fais parcourir à dayToTest l’ensemble des jours entre deux dates.

    Dans le code suivant que je propose, le principe est différent:
    - les variables giorno sont des jours sous forme datetime.date(2010, 1, 19)
    - les deux lignes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        giorno = ngay(startday)
        giorno += timedelta((-giorno.weekday()+j+7)%7)
    fixent giorno au premier jour de nature voulue (Mardi dans ton exemple) qui soit >= au jour firstDay
    - puis on fait faire à giorno des sauts de +7 jours jusqu’à lastDay. On s’assure ainsi de n’itérer que sur les jours j (tous les Mardis dans ton exemple)
    - à chacune des valeurs qu’il prend, on teste s’il est dans les périodes de vacances et les jours fériés ou non
    - on affecte giorno à l’une des deux listes du couple de listes T en fonction du résultat du test

    La fonction ngay() permet de passer d’un jour exprimé sous forme chaîne à un jour sous forme d’une instance datetime.date

    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
    from datetime import date, timedelta
    from time import strptime,clock
     
    # Easy definitions of the different dates.
    firstDay = "2-9-2009"
    lastDay = "2-7-2010"
     
    holidays = [("24-10-2009", "5-11-2009"),
                 ("19-12-2009", "04-01-2010"),
                 ("13-2-2010", "01-03-2010"),
                 ("10-04-2010", "26-04-2010") ]
     
    feries = ("01-11-2009","11-11-2009","25-12-2009","01-01-2010","05-04-2010",\
              "01-05-2010","08-05-2010","13-05-2010","24-05-2010","14-07-2010","15-08-2010")
     
    def cribleur_jour(startday, endday, holstrings, j, T = ([],[]) ):
        def ngay(daystring): # ngay = jour en vietnamien, renvoie un objet date
            y,m,d = strptime(daystring,'%d-%m-%Y')[0:3]
            return date(y,m,d)
     
        holdates = [ (ngay(a),ngay(b)) for (a,b) in holstrings ]
        ferdates = [ ngay(f) for f in feries ]
        delta7 = timedelta(7) # duree de 7 jours sous forme d'un objet
     
        giorno = ngay(startday)
        giorno += timedelta((-giorno.weekday()+j+7)%7)
        # a ce stade, giorno est le premier jour j >= firstDay
        while giorno <= ngay(endday):
            krit = False
            for ud,vd in holdates:
                krit = krit or (ud<=giorno<=vd)
            krit = krit or (giorno in ferdates)
            T[krit].append(giorno) # 0=travail 1=vacances
            giorno += delta7
        return T
     
     
    j = 100
    while j not in (0,1,2,3,4,5,6):
        j = input('Entrer le numero du jour dans la semaine :\n   0  pour  Lundi'\
                  +'\n   1  pour  Mardi\n   2  pour  Mercredi\n   3  pour  Jeudi'\
                  +'\n   4  pour  Vendredi\n   5  pour  Samedi\n   6  pour  Dimanche\n   ')
    te = clock()
    jtravail, jvacances = cribleur_jour(firstDay,lastDay,holidays,j)
    tf = clock()
    print tf-te
    Il me semble que ce code est plus lisible, sauf la pincée de mathématique qui se trouve dans timedelta((-giorno.weekday()+j+7)%7)






    Mesures de temps:

    0.01271083336
    0.0127686619389
    0.0130661857866
    0.012735696856
    0.0127446365395
    0.0127608397161
    0.0127194936786 mon code moyenne: 0,012786

    0.0185869991856
    0.0186336531588
    0.0207065423128
    0.0180754816611
    0.0176265419195
    0.0175868720744
    0.0207615772397 de rambc moyenne: 0,018854
    soit 47 % de temps en plus

  17. #17
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    J’ai amélioré le code.

    Le défaut du précédent est que pour chaque giorno allant de 7 jours en 7 jours entre firstDay = "2-9-2009" et lastDay = "2-7-2010", on effectue les lignes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            krit = False
            for ud,vd in holdates:
                krit = krit or (ud<=giorno<=vd)
            krit = krit or (giorno in ferdates)
    J’ai déporté l’élimination des jours présents dans les périodes de vacances en dehors de cette itération.
    L'algorithme devient plus simple:
    j désigne le numéro du jour de la semaine spécifié : Mardi, Mercredi, etc
    - on dresse la liste des jours j tombant dans des périodes de vacances -> jvacances
    - on dresse la liste de tous les jours j entre firstDay et lastDay -> jtravail provisoire
    - on garde des jours feriés ceux qui ne tombent pas dans des périodes de vacances et qui sont des jours j (pour éviter de refaire un test, cette deuxième condition est équivalente à celle de leur présence dans jtravail) -> jferies
    - on purge jtravail des jours de vacances et feriés restants -> jtravail final




    J’ai aussi modifié append(giorno) en append( giorno.strftime('%d-%m-%Y') ) ==> les listes résultats contiennent des dates sous forme de chaînes et non plus sous forme d’instances de datetime.date.


    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
    53
    54
    55
    from datetime import date, timedelta
    from time import strptime,clock
     
    # Easy definitions of the different dates.
    firstDay = "2-9-2009"
    lastDay = "2-7-2010"
     
    holidays = [("24-10-2009", "5-11-2009"),
                 ("19-12-2009", "04-01-2010"),
                 ("13-2-2010", "01-03-2010"),
                 ("10-04-2010", "26-04-2010") ]
     
    feries = ("01-11-2009","11-11-2009","25-12-2009","01-01-2010","05-04-2010",\
              "01-05-2010","08-05-2010","13-05-2010","24-05-2010","14-07-2010","15-08-2010")
     
    def cribleur_jour(firstDay, lastDay, holidays, j, jvacances = []):
     
        delta7 = timedelta(7) # duree de 7 jours sous forme d'instance datetime.timedelta
     
        def prelevj(startday, endday, j, L=[]): # startday, endday sont des chaines
            y,m,d,_,_,_,wd,_,_ = strptime(startday,'%d-%m-%Y')
            giorno = date(y,m,d)+ timedelta((-wd+j+7)%7)
            # A ce stade, giorno est le premier jour j >= firstDay
            # Les variables giorno sont des instances datetime.date. 
            y,m,d = strptime(endday,'%d-%m-%Y')[0:3]
            while giorno <= date(y,m,d):
                L.append(giorno.strftime('%d-%m-%Y'))
                giorno += delta7
            return L
     
        [ prelevj(a,b,j,jvacances) for a,b in holidays ]
        jtravail = prelevj(firstDay,lastDay,j)
        jferies = [ f for f in feries if f not in jvacances and f in jtravail ]
        [ jtravail.remove(jour) for jour in jvacances+jferies ]
     
        return jtravail,jvacances,jferies
     
     
    sem = ('Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi','Dimanche')
    j = 'go'
    while j not in ('0','1','2','3','4','5','6'):
        j = raw_input('Entrer le numero du jour dans la semaine :\n   '\
                  + ''.join((str(k)+'  pour  '+sem[k]+'\n   ' for k in xrange(7))))
    j = int(j)
     
    te = clock()
    jtravail,jvacances,jferies = cribleur_jour(firstDay, lastDay, holidays, j)
    tf = clock()
     
    if not jferies:
        jferies = 'aucun'
    print    '\n' + sem[j] + 's  travailles:\n' + '\n'.join(jtravail)\
          +'\n\n' + sem[j] + 's dans vacances:\n'+'\n'.join(jvacances)\
          +'\n\n' + sem[j] + 's feries\n' + ''.join(jferies)
    print '\n',tf-te,' secondes'

    Mesures de temps:

    0.00553310546456
    0.00549259752279
    0.00558534674019
    0.00574514358686
    0.00545572132796
    0.00558478801031
    0.00572111818747 Moyenne 0,005588



    Soit un temps divisé par 2,2


    Entrer le numero du jour dans la semaine :
    0 pour Lundi
    1 pour Mardi
    2 pour Mercredi
    3 pour Jeudi
    4 pour Vendredi
    5 pour Samedi
    6 pour Dimanche
    1

    Mardis travailles:
    08-09-2009
    15-09-2009
    22-09-2009
    29-09-2009
    06-10-2009
    13-10-2009
    20-10-2009
    10-11-2009
    17-11-2009
    24-11-2009
    01-12-2009
    08-12-2009
    15-12-2009
    05-01-2010
    12-01-2010
    19-01-2010
    26-01-2010
    02-02-2010
    09-02-2010
    02-03-2010
    09-03-2010
    16-03-2010
    23-03-2010
    30-03-2010
    06-04-2010
    27-04-2010
    04-05-2010
    11-05-2010
    18-05-2010
    25-05-2010
    01-06-2010
    08-06-2010
    15-06-2010
    22-06-2010
    29-06-2010

    Mardis dans vacances:
    27-10-2009
    03-11-2009
    22-12-2009
    29-12-2009
    16-02-2010
    23-02-2010
    13-04-2010
    20-04-2010

    Mardis feries
    aucun

    0.00553925149711 secondes

  18. #18
    Membre chevronné

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Points : 1 752
    Points
    1 752
    Par défaut
    Citation Envoyé par eyquem Voir le message
    Je m’étonne que personne n’ait trouvé à redire sur ton code passable, rambc. Il ne dégage pourtant pas cette impression de concision pythonienne si prisée et il suit un algorithme qui ne s’épargne aucune longueur.
    C'est fait...

    Sinon merci pour ton code même si je ne suis pas fan des noms de tes variables mais rien de grave.

    Sinon pour récupérer les dates des vacances scolaires, il "suffirait" d'utiliser le site de l'Education Nationale via des adresses du type suivant (requête JavaScript) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    http://www.education.gouv.fr/pid184/le-calendrier-scolaire.html?za=Zone+A&zb=Zone+B&zc=Zone+C&dept=70&cp=&annee=5&x=10&y=12
    Plus intéressant serait d'avoir de façon automatique les jours fériés.

  19. #19
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par rambc Voir le message
    Plus intéressant serait d'avoir de façon automatique les jours fériés.
    Si ça t'interesse, je peux te fournir le code pour calculer tous les jours fériés (France) d'une année donnée.

    Tyrtamos
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  20. #20
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Points : 1 658
    Points
    1 658
    Par défaut
    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
    import urllib,re
     
    zone = {13:'A',14:'B',15:'C'}
    nmois = {'janvier':'01','février':'02','f\xe9vrier':'02','f&eacute;vrier':'02',\
             'mars':'03','avril':'04','mai':'05','juin':'06','juillet':'07',\
             'août':'08','ao\xfbt':'08','ao&ucirc;t':'08',\
             'septembre':'09','octobre':'10','novembre':'11',\
             'décembre':'12','d\xe9cembre':'12','d&eacute;mbre':'12'}
     
    for z in (13,14,15):
     
        print '\nZone '+zone[z]
        url = 'http://www.education.gouv.fr/pid184/le-calendrier-scolaire.html?zone='+str(z)+'&dept=0&annee=5&cp='
        sock = urllib.urlopen(url)
        ch = sock.read()
        sock.close()
     
        ens = ch.find('">Rentr\xe9e scolaire des enseignants</td>\r\n')
        tu = ('">Rentr\xe9e scolaire des enseignants</td>\r\n',
              '<td class="zone'+str(z-13)+'" colspan="2">\r\n',
              ' [a-z]+ ([ \d]\d)(?:er)? ([\xe9a-z]+) (\d{4})\r\n')
        a,b,c = re.compile(''.join(tu)).match(ch,ens).groups()
        firstDay = a+'-'+nmois[b]+'-'+c
     
        tu = ('">Vacances d\'\xe9t\xe9</td>\r\n',
              '<td class="zone'+str(z-13)+'" colspan="2">\r\n',
              ' [a-z]+ ([ \d]\d)(?:er)? ([\xe9a-z]+) (\d{4})\r\n')
        a,b,c = re.compile(''.join(tu)).search(ch,ens).groups()
        lastDay = a+'-'+nmois[b]+'-'+c
     
        print 'firstDay,lastDay :\n',(firstDay,lastDay)
     
        tu = ('td class="zone'+str(z-13)+'">Vacances d.+?</td>\r\n',
              '<td class="zone'+str(z-13)+'" >\r\n',
              ' [a-z]+ ([ \d]\d)(?:er)? ([\xe9a-z]+) (\d{4})\r\n',
              '</td>\r\n',
              '<td class="zone'+str(z-13)+'">\r\n',
              ' [a-z]+ ([ \d]\d)(?:er)? ([\xe9a-z]+) (\d{4})\r\n')
     
        holidays = [ (a+'-'+nmois[b]+'-'+c,d+'-'+nmois[e]+'-'+f)\
                     for a,b,c,d,e,f in re.compile(''.join(tu)).findall(ch,ens) ]
        print 'holidays :\n'+'\n'.join(repr(t) for t in holidays)
    Zone A
    firstDay,lastDay :
    (' 1-09-2009', ' 2-07-2010')
    holidays :
    ('24-10-2009', ' 5-11-2009')
    ('19-12-2009', ' 4-01-2010')
    ('13-02-2010', ' 1-03-2010')
    ('10-04-2010', '26-04-2010')

    Zone B
    firstDay,lastDay :
    (' 1-09-2009', ' 2-07-2010')
    holidays :
    ('24-10-2009', ' 5-11-2009')
    ('19-12-2009', ' 4-01-2010')
    (' 6-02-2010', '22-02-2010')
    (' 3-04-2010', '19-04-2010')

    Zone C
    firstDay,lastDay :
    (' 1-09-2009', ' 2-07-2010')
    holidays :
    ('24-10-2009', ' 5-11-2009')
    ('19-12-2009', ' 4-01-2010')
    ('20-02-2010', ' 8-03-2010')
    ('17-04-2010', ' 3-05-2010')
    Je laisse à Tyrtamos le soin de te fournir les jours fériés.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [Calendrier] Récupérer les dates des vacances scolaires, c'est possible ?
    Par fayred dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 13
    Dernier message: 10/10/2016, 18h45
  2. Script pour compter les jours entre deux dates
    Par bomonde dans le forum Shell et commandes GNU
    Réponses: 12
    Dernier message: 17/10/2012, 18h54
  3. lire date dans cellule et compter les jours
    Par biche1 dans le forum Excel
    Réponses: 6
    Dernier message: 29/09/2008, 16h41
  4. Comment compter les jours par mois entre deux dates
    Par Doo89 dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 10/01/2008, 21h21
  5. [MS-DOS] Compter les nombres de jours entre deux dates diffé
    Par Furius dans le forum Scripts/Batch
    Réponses: 4
    Dernier message: 19/02/2006, 13h33

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