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 :

Différence entre deux dates


Sujet :

Python

  1. #1
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut Différence entre deux dates
    Salut,

    EDIT1 : J'ai modifié ce message suite aux remarques...

    Comment coderiez-vous une fonction qui calcule le nombre de jours entre deux dates d1 et d2 (non inclus) ?

    Je sais qu'il existe des librairies toutes faites pour faire cela mais voyez cela comme un exercice...

    EDIT2:
    Citation Envoyé par binarygirl Voir le message
    A titre d'info ce module datetime traite les dates de 1 à 9999 (MAXYEAR) donc il devrait satisfaire vos exigences.
    Ok bon prenons donc cet intervalle pour l'exercice...

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    J'aime bien réinventer la roue mais là...
    Pourquoi ne pas utiliser datetime ?

    Sinon une idée à la c¤n :
    Tu codes un dictionnaire avec toutes les dates entre 1970 et 2050 par exemple du style : {'01/01/1970' : 0, '02/01/1970' : 1, ...}.
    Ce qui te permet de calculer plus rapidement par la suite la différence entre deux dates comprises entre 1970 et 2050.

  3. #3
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    Citation Envoyé par LeNarvalo Voir le message
    J'aime bien réinventer la roue mais là...
    Pourquoi ne pas utiliser datetime ?
    Ben tu peux voir ça comme un exercice... C'est bien connu qu'on fait réinventer la roue aux apprenants afin qu'ils s’exercent, qu'ils cogitent, mettent en pratique le cours théorique pour résoudre des problèmes concrets...

    Sinon oui pour l'usage il vaut mieux utiliser une librairie toute faite, c'est plus prudent et plus fiable, surtout que cela prend en compte d'autres difficultés (secondes intercalaires, décalage horaire, changement d'heure...).

    Au départ je pensais à des exercices plus simples autour des dates et je suis tombé sur cet os qui mine de rien n'est pas forcément aussi évident que ce que l'on peut croire au premier abord...

    Citation Envoyé par LeNarvalo Voir le message
    Tu codes un dictionnaire avec toutes les dates entre 1970 et 2050 par exemple du style : {'01/01/1970' : 0, '02/01/1970' : 1, ...}.
    Ce qui te permet de calculer plus rapidement par la suite la différence entre deux dates comprises entre 1970 et 2050.
    Cela me semble plus long que la solution avec la boucle que j'ai postée.

    Mais c'est vrai que je pars pour l'instant du cas simple où on prend l'année a1 en entier et où on exclut l'année a2, par exemple si a1 vaut 2001 et a2 2004 alors on a 3 années complètes : 2001, 2002 et 2003. Et comme aucune de ces années n'est bissextile alors le nombre de jours entre a1 et a2 est : 365 * (a2-a1).

    Et si il y a n années bissextiles entre a1 et a2 alors le nombre de jours est : 365 * (a2-a1) + n.

    C'est donc plutôt simple et rapide à la base sauf pour certains cas dont j'ai parlés...

  4. #4
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Beginner. Voir le message
    Ben tu peux voir ça comme un exercice...
    Ok !

    Citation Envoyé par Beginner. Voir le message
    Cela me semble plus long que la solution avec la boucle que j'ai postée.
    Sur mon ordi créer un dico de 1970 à 2050 prends 20 msec ensuite c'est de la tarte pour calculer la différence.
    Je ne sais pas si cette technique porte un nom, de mon côté je vais solliciter la RAM plutôt que le processeur durant le calcul de la différence. (Si je ne dis pas de c¤nnerie)

    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
    def is_bissextile(annee):
        return annee % 4 == 0 and annee % 100 != 0 or annee % 400 == 0
     
    def build_calendar():
        calendar = []
        #Year
        for y in range(1970, 2051):
            #Month
            for m in range(1, 13):
     
                maxi = 32
                if m in (4, 6, 9, 11):
                    maxi = 31
                elif m == 2:
                    maxi = 29
                    if is_bissextile(y):
                        maxi = 30
                #Day        
                for d in range(1, maxi):
                    calendar.append(f'{y}/{m:>02d}/{d:>02d}')
     
        dico = {k:i for i, k in enumerate(calendar)}
        return dico
     
    calendar = build_calendar()
     
    def diff(date1:"oldest date", date2:"newest date"):
        return calendar[date2]-calendar[date1]
    #PS : Je ne sais pas si utiliser LISTE.index(date1) - LISTE.index(date2) est plus ou moins rapide que mon dictionnaire...

  5. #5
    Membre Expert
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 068
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 068
    Par défaut
    Citation Envoyé par LeNarvalo Voir le message
    Bonjour,
    J'aime bien réinventer la roue mais là...
    Pourquoi ne pas utiliser datetime ?

    Sinon une idée à la c¤n :
    Tu codes un dictionnaire avec toutes les dates entre 1970 et 2050 par exemple du style : {'01/01/1970' : 0, '02/01/1970' : 1, ...}.
    Ce qui te permet de calculer plus rapidement par la suite la différence entre deux dates comprises entre 1970 et 2050.
    C'est pas bête ça, j'y aurais jamais pensé.

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    721
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2006
    Messages : 721
    Par défaut
    Bonjour,

    Quitte à réinventer la roue, je pense qu'il faudrait définir le but de l'exercice avec plus de rigueur. Calculer la différence entre deux dates, c'est vague. Voulez-vous simplement calculer le nombre de jours qui séparent deux dates, ou bien voulez-vous quelque chose d'autre, éventuellement de plus fin ?
    Il faut aussi définir les contraintes d'utilisation, par exemple si vous voulez sortir de l'intervalle 1970-2038, alors les stratégies à mettre en oeuvre sont potentiellement différentes (un calcul de timestamp sur 32 bits ne suffit plus).

    Le code sera plus ou moins complexe en fonction de ces critères d'utilisation. Mais tant que vous n'avez pas clairement défini le "scope", chacun va interpréter le problème à sa manière.
    D'expérience, il n'y a rien de pire que les projets mal définis car ils ne sont jamais finis puisque les attentes ne sont pas clairement exprimées !

    Comme dit précédemment, datetime est inclus par défaut dans Python et ne nécessite donc pas d'installer des packages tiers, et timedelta est très pratique.

  7. #7
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    Salut,

    Citation Envoyé par LeNarvalo Voir le message
    Sur mon ordi créer un dico de 1970 à 2050 prends 20 msec ensuite c'est de la tarte pour calculer la différence.
    Chez moi cela prend environ 28ms... Ton PC est plus rapide...

    Citation Envoyé par LeNarvalo Voir le message
    Je ne sais pas si cette technique porte un nom, de mon côté je vais solliciter la RAM plutôt que le processeur durant le calcul de la différence.
    Merci pour ton exemple de solution.

    Citation Envoyé par LeNarvalo Voir le message
    #PS : Je ne sais pas si utiliser LISTE.index(date1) - LISTE.index(date2) est plus ou moins rapide que mon dictionnaire...
    Bonne question.

    -----
    Citation Envoyé par binarygirl Voir le message
    Quitte à réinventer la roue, je pense qu'il faudrait définir le but de l'exercice avec plus de rigueur. Calculer la différence entre deux dates, c'est vague. Voulez-vous simplement calculer le nombre de jours qui séparent deux dates, ou bien voulez-vous quelque chose d'autre, éventuellement de plus fin ?
    Oui vous avez raison, j'ai modifié mon message. Pour l'instant, pour faire simple, il s'agit de calculer le nombre de jours...

    Citation Envoyé par binarygirl Voir le message
    Il faut aussi définir les contraintes d'utilisation, par exemple si vous voulez sortir de l'intervalle 1970-2038, alors les stratégies à mettre en oeuvre sont potentiellement différentes (un calcul de timestamp sur 32 bits ne suffit plus).
    Pour les dates, pas de contraintes particulières mais l'intervalle le plus large possible (sans que cela devienne trop compliqué) est bienvenu... Cela peut être de l'an 1500 à l'an 3000 par exemple...

    Mais faut-il obligatoirement un timestamp pour cette question/exercice ?

    Citation Envoyé par binarygirl Voir le message
    Comme dit précédemment, datetime est inclus par défaut dans Python et ne nécessite donc pas d'installer des packages tiers, et timedelta est très pratique.
    Oui je sais bien qu'il y a des librairies toutes faites mais voyez cela comme un exercice.

    Et c'est vrai que la question que j'avais en tête au départ, avant celle de la différence en deux dates, c'était : "Comment coderiez-vous une fonction qui calcule le nombre d'années bissextiles entre deux années a1 et a2 (non inclus) ?".

    J'ai du coup ouvert un autre fil pour cette question : Nombre d'années bissextiles entre deux années et j'ai modifié la question de ce présent fil...

    Et j'y ai d'ailleurs ajouter la question 2, pour cette question/exercice est-ce que l'usage d'une librairie est plus efficace ?

  8. #8
    Invité
    Invité(e)
    Par défaut
    Petite adaptation :
    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
    def is_bissextile(annee):
        return annee % 4 == 0 and annee % 100 != 0 or annee % 400 == 0
     
    def build_calendar(d1,d2):
        y1, y2 = int(d1[:4]), int(d2[:4])+1
        calendar = []
        #Year
        for y in range(y1, y2):
            #Month
            for m in range(1, 13):
     
                maxi = 32
                if m in (4, 6, 9, 11):
                    maxi = 31
                elif m == 2:
                    maxi = 29
                    if is_bissextile(y):
                        maxi = 30
                #Day        
                for d in range(1, maxi):
                    calendar.append(f'{y}/{m:>02d}/{d:>02d}')
     
        dico = {k:i for i, k in enumerate(calendar)}
        return dico
     
    test_ram = {} #A SUPPRIMER
    def diff(date1:"oldest date", date2:"newest date"):
        calendar = build_calendar(date1, date2)
        global test_ram #A SUPPRIMER
        test_ram = calendar #A SUPPRIMER
        return calendar[date2]-calendar[date1]
    Quelques 222 Mo de RAM et environ 1.1 seconde, pour un diff('1111/01/01','5000/01/01'). L'idée ensuite serait de ne pas recharger le calendrier à chaque fois !

  9. #9
    Membre Expert
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    721
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2006
    Messages : 721
    Par défaut
    Citation Envoyé par Beginner. Voir le message
    Pour les dates, pas de contraintes particulières mais l'intervalle le plus large possible (sans que cela devienne trop compliqué) est bienvenu... Cela peut être de l'an 1500 à l'an 3000 par exemple...
    C'est pas hyper-précis mais bon

    Citation Envoyé par Beginner. Voir le message
    Mais faut-il obligatoirement un timestamp pour cette question/exercice ?
    Non, mais c'est une approche possible. Mais pour cela il faut justement avoir une idée du degré de précision voulu et de l'amplitude des dates. On peut faire quelque chose de simple, astucieux si on sait à l'avance les valeurs extrêmes à traiter.
    En gros, on essaie de réaliser un arbitrage entre souplesse, performance et simplicité.
    Si j'ai cité 2038 ce n'est pas par hasard, faites une recherche sur le bug Y2K38 par curiosité.

    En clair, si vous développez un programme pour une caisse de retraite, vous aurez besoin d'une amplitude de 100 ans et plus pour calculer correctement les retraites des individus. Mais pas d'un millénaire ou plus. On est donc dans un cas de figure différent.

    Citation Envoyé par Beginner. Voir le message
    Et j'y ai d'ailleurs ajouter la question 2, pour cette question/exercice est-ce que l'usage d'une librairie est plus efficace ?
    Qu'entend-on par efficace ?
    Si on parle de simplicité et rapidité (mettre un truc en route rapidement à moindre effort), il ne faut pas réinventer la roue sans raison valable, donc on utilise la lib qui va bien.

    Si on parle de performance, on ne peut pas le savoir à l'avance, tout dépend de votre implémentation. Il y a des modules en Python comme timeit qui permettent de mesurer le temps d'exécution.
    Il est d'ailleurs fortement conseillé de mesurer les performances de son propre code. Donc n'hésitez pas à comparer le résultat final avec celui obtenu en utilisant les modules natifs comme datetime.

    Il n'est pas impossible que votre fonction "faite maison" performe mieux qu'un module éprouvé comme datetime, dans un cadre très restreint, à condition que le code soit bien construit et optimisé.

    A titre d'info ce module datetime traite les dates de 1 à 9999 (MAXYEAR) donc il devrait satisfaire vos exigences.

    Par contre, si vous devez traiter les dates dans le passé avant J-C, on rentre dans une autre problématique et ce n'est pas pour rien que le scope de l'exercice doit être défini clairement.

  10. #10
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    Citation Envoyé par LeNarvalo Voir le message
    Petite adaptation :
    Merci je vais tester...

    Citation Envoyé par binarygirl Voir le message

    Non, mais c'est une approche possible. Mais pour cela il faut justement avoir une idée du degré de précision voulu et de l'amplitude des dates. On peut faire quelque chose de simple, astucieux si on sait à l'avance les valeurs extrêmes à traiter.
    En gros, on essaie de réaliser un arbitrage entre souplesse, performance et simplicité.
    Si j'ai cité 2038 ce n'est pas par hasard, faites une recherche sur le bug Y2K38 par curiosité.
    Oui j'ai regardé pour le "bug de 2038"...

    Mais justement, c'est une raison (sans être déterminante) qui va plutôt en faveur de faire l'exercice sans utiliser le timestamp...

    Citation Envoyé par binarygirl Voir le message
    A titre d'info ce module datetime traite les dates de 1 à 9999 (MAXYEAR) donc il devrait satisfaire vos exigences.
    Ok bon prenons donc cet intervalle pour l'exercice...

    Citation Envoyé par binarygirl Voir le message
    Qu'entend-on par efficace ?
    Si on parle de simplicité et rapidité (mettre un truc en route rapidement à moindre effort), il ne faut pas réinventer la roue sans raison valable, donc on utilise la lib qui va bien.
    Une des raisons valables c'est d'en faire un exercice.

    Citation Envoyé par binarygirl Voir le message
    Si on parle de performance, on ne peut pas le savoir à l'avance, tout dépend de votre implémentation. Il y a des modules en Python comme timeit qui permettent de mesurer le temps d'exécution.
    Ben quand on compare les performances il faut utiliser la même machine sinon cela n'a aucun sens...

    Citation Envoyé par binarygirl Voir le message
    Donc n'hésitez pas à comparer le résultat final avec celui obtenu en utilisant les modules natifs comme datetime.
    Ben à vous de me dire si les solutions utilisant les modules natifs pour la question 2 sont plus performantes qu'une solution "faite maison" pour s'exercer...

    Bon je vais poster dans l'autre fil une solution "faites maison"...

  11. #11
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par LeNarvalo Voir le message
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    maxi = 32
    if m in (4, 6, 9, 11):
    	maxi = 31
    elif m == 2:
    	maxi = 29
    	if is_bissextile(y):
    		maxi = 30
    #Day        
    for d in range(1, maxi):
    	calendar.append(f'{y}/{m:>02d}/{d:>02d}')
    Pour faciliter la compréhension, j'aurais plutôt mis les bonnes valeurs des jours (31/30/29/28) et mis un range sur maxi+1. Bon c'est pas que c'est vraiment compliqué à comprendre que 32 c'est pour 31 jours mais si on peut éviter toute complexité (même minime) inutile...
    Et j'essaye toujours de mettre en premier le cas présumé le plus probable (ou si pas possible, au-moins en dernier le cas le moins probable)
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if m in (4, 6, 9, 11): maxi = 30
    elif m != 2: maxi=31
    else: maxi = 28 if not is_bissextile(y) else 29
     
    #Day        
    calendar.extend(f'{y}/{m:>02d}/{d:>02d}' for d in range(1, maxi+1))
    Après, question intérêt de créer tous les écarts pour ensuite n'en récupérer qu'un seul, autant utiliser l'algo pour simplement compter les jours et renvoyer le résultat du comptage. C'est un peu comme si on te demandait l'écart entre 3 et 8 et qu'au lieu de calculer 8-3 tu crées le dico {3 : 0, 4 : 1, 5 : 2, 6 : 3, 7: 4, 8 : 5} pour renvoyer la valeur [8]...

    Code python : 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
    def count_calendar(d1,d2):
    	(y1,m1,d1)=map(int, d1.split("/"))
    	(y2,m2,d2)=map(int, d2.split("/"))
    	cpt=0
    	while (y1, m1, d1) != (y2, m2, d2):
    		cpt+=1
     
    		# day
    		if m1 in (4, 6, 9, 11): maxi = 30
    		elif m1 != 2: maxi=31
    		else: maxi=28 if not is_bissextile(y1) else 29
    		if d1 < maxi:
    			d1+=1
    			continue
    		# if
     
    		# month
    		d1=1
    		if m1 < 12:
    			m1+=1
    			continue
    		# if
     
    		# year
    		m1=1
    		y1+=1
    	# while
    	return cpt
    # count_calendar()
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  12. #12
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Après, question intérêt de créer tous les écarts pour ensuite n'en récupérer qu'un seul, autant utiliser l'algo pour simplement compter les jours et renvoyer le résultat du comptage.
    L'idée initiale c'était de n'avoir à construire le dictionnaire ou la liste qu'une seule fois, puis l'agrandir au besoin (ce qui complexifie le script je te l'accorde)...

  13. #13
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par LeNarvalo Voir le message
    L'idée initiale c'était de n'avoir à construire le dictionnaire ou la liste qu'une seule fois, puis l'agrandir au besoin
    J'y ai pensé (tu en avais parlé dans le post où tu as écrit cet algo) mais même comme ça ça ne fonctionne pas car si la date de départ change, il faut reconstruire tout le dico
    Prenons mon exemple avec 3 et 8 et le dico créé pour l'occasion {3 : 0, 4 : 1, 5 : 2, 6 : 3, 7: 4, 8 : 5}. Puis on te demande ensuite entre 4 et 7 et là ben...

    Accessoirement j'ai rajouté dans mon post précédent le code qui fait le décompte
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  14. #14
    Invité
    Invité(e)
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Puis on te demande ensuite entre 4 et 7 et là ben...
    Ben là ça fonctionne vu que c'est dans l'intervalle du dico de ton exemple ! Hi hi !
    4-1 = 3 tout comme 7-4 = 3

    Mais bon j'ai compris ce que tu voulais dire, par exemple si je cherche entre 2 et 9 du coup l'utilisation d'une liste est préférable !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    sorted([3, 4, 5, 6, 7, 8, 2, 9])
    [2, 3, 4, 5, 6, 7, 8, 9]
     
    sorted(['2020/01/02', '2020/01/01'])
    ['2020/01/01', '2020/01/02']

    Sinon, je trouve ta proposition moins claire que ma mienne.

  15. #15
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par LeNarvalo Voir le message
    Mais bon j'ai compris ce que tu voulais dire, par exemple si je cherche entre 2 et 9 du coup l'utilisation d'une liste est préférable !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    sorted([3, 4, 5, 6, 7, 8, 2, 9])
    [2, 3, 4, 5, 6, 7, 8, 9]
     
    sorted(['2020/01/02', '2020/01/01'])
    ['2020/01/01', '2020/01/02']
    Euh non, quitte à les regénérer autant rester sur le dico (sinon tu dois retrier ta liste à chaque re-génération). Faut juste un algo qui "complète" le dico et non pas qui le génère de zéro.
    Mon point de désaccord était surtout sur l'utilité de stocker tous les écarts pour juste les compter...

    Citation Envoyé par LeNarvalo Voir le message
    Sinon, je trouve ta proposition moins claire que ma mienne.
    Oui, parce qu'elle est plus brillante

    En fait je fais comme toi, je balaye toutes les dates existantes entre les deux dates demandées. Sauf que je me contente de compter combien j'en balaye.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  16. #16
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Et j'essaye toujours de mettre en premier le cas présumé le plus probable (ou si pas possible, au-moins en dernier le cas le moins probable)
    J'essaie de faire pareil du moins quand j'y pense...En moyenne cela devrait être plus rapide...

    Je fais pareil pour les "ou logique" car si la première opérande est vraie les autres opérandes ne sont pas évaluées...

    Après parfois ça peut être au contraire moins performant de faire cela (si l’évaluation de la première opérande prend beaucoup plus de temps que l'évaluation des autres opérandes).

    Citation Envoyé par Sve@r Voir le message
    En fait je fais comme toi, je balaye toutes les dates existantes entre les deux dates demandées. Sauf que je me contente de compter combien j'en balaye.
    Merci pour cette solution.

    J'aime bien ton usage de la fonction map, c'est plus lisible et plus pratique.
    Je crois que je vais l'utiliser à la place de la fonction que j'ai écrite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    def split_jour_mois_annee(d):
        d = d.split(d)
        return int(d[0]), int(d[1]), int(d[2])
    Citation Envoyé par Sve@r Voir le message

    Pour faciliter la compréhension, j'aurais plutôt mis les bonnes valeurs des jours (31/30/29/28) et mis un range sur maxi+1. Bon c'est pas que c'est vraiment compliqué à comprendre que 32 c'est pour 31 jours mais si on peut éviter toute complexité (même minime) inutile...
    Pour le calcule de maxi on peut aussi utiliser une liste contenant le nombre de jours de chaque mois :
    nbr_jours_mois= [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] et maxi=nbr_jours_mois[m] et si m vaut 2 (février) et que l'année est bissextile on incrémente maxi.


    Citation Envoyé par LeNarvalo Voir le message
    Petite adaptation :
    Oui c'est mieux car plus polyvalent, on peut choisir les deux dates mais du coup si l'intervalle est plus grand que l'intervalle [1970, 2051[ de la première fonction alors le temps d’exécution dépasse les 20ms...

    Citation Envoyé par LeNarvalo Voir le message
    Quelques 222 Mo de RAM et environ 1.1 seconde, pour un diff('1111/01/01','5000/01/01'). L'idée ensuite serait de ne pas recharger le calendrier à chaque fois !
    Comment as-tu fait pour calculer la RAM utilisée ?

  17. #17
    Membre Expert
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 068
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 068
    Par défaut
    pour chipoter, je me dis qu'il y à quand même plus d'années non bissextiles... donc si on veut tester une plage d'années (au lieu de calculer, ce qui serait évidemment plus efficace):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def is_bissextile(annee):
        if annee%4   : return False
        if annee%100 : return True
        if annee%400 : return False
        return True
    me paraît plus logique.

  18. #18
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Beginner. Voir le message

    Comment as-tu fait pour calculer la RAM utilisée ?
    Tout bonnement en ouvrant le gestionnaire des taches.


    Citation Envoyé par Sve@r
    Euh non, quitte à les regénérer autant rester sur le dico (sinon tu dois retrier ta liste à chaque re-génération). Faut juste un algo qui "complète" le dico et non pas qui le génère de zéro.
    Mon point de désaccord était surtout sur l'utilité de stocker tous les écarts pour juste les compter...
    Ouai mais un tel algo ne me paraît pas simple à coder !
    Je pense que sorted est amplement suffisant vu le peu de temps que ça prend :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def toto():
        jours = 365*10000
        LISTE = [_ for _ in range(jours+1)]
        #random.shuffle(LISTE)
        t0 = time.time()
        L = sorted(LISTE+[_ for _ in range(-1,-10000,-1)]+[_ for _ in range(jours+1,jours+10000,+1)])
        print(time.time() - t0)
    Pas besoin de re-générer l'entièreté de la liste, tu utilises une liste globale et si tu fais une recherche en dehors de la plage ben c'est pas compliqué d'itérer seulement en dehors de cette plage puis de rajouter ça à la liste globale et ensuite faire un sorted (cf. le code ci-dessus).

    PS : En faite chui très con, il suffit de rajouter les nouvelles plages avant et après la plage initiale... Pas besoin de sorted !

  19. #19
    Membre Expert
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    2 910
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 2 910
    Par défaut
    Citation Envoyé par josmiley Voir le message
    pour chipoter, je me dis qu'il y à quand même plus d'années non bissextiles... donc si on veut tester une plage d'années (au lieu de calculer, ce qui serait évidemment plus efficace):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def is_bissextile(annee):
        if annee%4   : return False
        if annee%100 : return True
        if annee%400 : return False
        return True
    me paraît plus logique.
    Oui c'est bien vu, merci.

    Tu as appliqué ce dont parlait Sve@r :

    Citation Envoyé par Sve@r Voir le message
    Et j'essaye toujours de mettre en premier le cas présumé le plus probable (ou si pas possible, au-moins en dernier le cas le moins probable)
    Citation Envoyé par josmiley Voir le message
    pour chipoter, je me dis qu'il y à quand même plus d'années non bissextiles...
    Oui, par exemple pour la première condition, 3 fois / 4 l'année n'est pas multiple de 4, il est donc plus performant de tester la condition "si annee n'est pas multiple de 4" plutôt que la condition "si annee est multiple de 4"...

    Sinon pour la lisibilité je préfère parfois ajouter les opérateurs de comparaison.

    Citation Envoyé par LeNarvalo Voir le message
    Tout bonnement en ouvrant le gestionnaire des taches.
    Ok merci.

  20. #20
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    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 741
    Par défaut
    Citation Envoyé par Beginner. Voir le message
    Oui, par exemple pour la première condition, 3 fois / 4 l'année n'est pas multiple de 4, il est donc plus performant de tester la condition "si annee n'est pas multiple de 4" plutôt que la condition "si annee est multiple de 4"...
    Le but serait plutôt de terminer la fonction en réduisant le nombre de tests.
    Et de ce côté là, les instructions:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        if annee%4   : return False
        if annee%100 : return True
        if annee%400 : return False
        return True
    sont équivalentes à:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        return annee % 4 == 0 and annee % 100 != 0 or annee % 400 == 0
    car lorsque le premier terme d'un AND est faux, on retournera False sans évaluer la suite.

    Après on peut discutailler sur la justesse de l'expression pour retourner l'information qu'on veut sur année.
    A mon sens, annee % 4 == 0 and (annee % 100 != 0 or annee % 400 == 0) serait plus correct.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 21/07/2006, 14h04
  2. Nombre de minutes de différence entre deux dates
    Par Oberown dans le forum SQL Procédural
    Réponses: 4
    Dernier message: 05/05/2006, 15h41
  3. Différence entre deux dates
    Par Azharis dans le forum Access
    Réponses: 3
    Dernier message: 11/01/2006, 10h58
  4. Différence entre deux dates
    Par pittzz dans le forum Oracle
    Réponses: 5
    Dernier message: 18/07/2005, 12h24
  5. Comment obtenir la différence entre deux dates ?
    Par jbat dans le forum Langage
    Réponses: 4
    Dernier message: 02/06/2005, 09h34

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