Partage
  • Partager sur Facebook
  • Partager sur Twitter

Compter les vendredis 13.

    29 novembre 2020 à 2:14:04

    Bonjour!

    Actuellement je dois faire un programme python pour compter le nombre de vendredi 13 entre 2019 et 2099.

    Afin de le tester, j'ai réalisé 3 tests : Pour l'année 2019, j'ai 2 vendredi 13, 2020 aussi, et entre 2019 et 2419, 686.

    Mon problème est que d'après Wikipédia, dans un cycle grégorien de 400 ans, il y a 688 vendredis 13. Si Wikipédia a raison,  pourriez vous me dire dans quel cas mon algorithme a pu rater un vendredi 13?

    Je ne suis pas bien sûr si je peux vraiment faire une demande comme ça, mais voici un code que j'ai réalisé pour compter le nombre de vendredi 13.

    Il est très (Trop?) détaillé afin de vous aider au mieux sur mon problème. J'espère juste qu'il n'est pas trop indigeste.

    #1er janvier 2019 est un mardi.
    #Toutes les années congrues à 0 modulo 4 sont bissetiles entre 2019 et 2099
    #3 Janvier,Mars,Mai, Juiller,Août, Octobre, décembre ont 31 jours,
    #Avril, Juin, Septembre, Novembre en ont 30,
    #Février en a 28 sauf les années bisextiles où il en a 29.
    #Proposer un programme python qui compte le nombre de Vendredi 13 entre Janvier 2019 et Décembre 2099 (compris).
    
    
    
    def main():
        listeMois = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] #Liste des mois représenté par leur nombre de jour (pour une année non bisextile.
        jourActuel = 1 # On commence le premier Janvier
        indiceJour = 1 # 1er Janvier est un mardi. On considère indice lundi = 0 et indice dimanche = 6.
        compteurVendredi13 = 0 # Le nombre de vendredi 13.
        # Boucle pour rejoindre le premier Vendredi du premier mois. On pourrait aussi le faire à la main.
        while indiceJour != 4 : #Tant que l'on est pas vendredi
            indiceJour += 1 #On augmente le nombre de jour
            jourActuel += 1 #Et le libellé du Jour.
            
        #Boucle pour vérifier tous les vendredis 13 entre 2019 et 2099
        for annee in range(2019, 2100):#Pour chaque année entre 2019 (compris) et 2100 (non compris)
           
            for indiceMois in range(12):  #Pour chaque mois, représenté par leur nombre de jour dans le tableau listeMois.
                nombreJourDuMois = listeMois[indiceMois] #je prend le nombre de jour du mois.
                if indiceMois == 1 and annee%4 == 0: #Si on est en février d'année bisextile
                    nombreJourDuMois += 1 # Je rajoute un jour.
                while jourActuel <= nombreJourDuMois: #Tant que le jour actuel est compris dans le mois
                    if jourActuel == 13 : #Si l'on est vendredi 13
                        compteurVendredi13 += 1 #J'augmente le compteur de vendredi 13 de 1.
                    jourActuel += 7 #Puis je vais au vendredi suivant (7jours + tard)
                #Fin du while, signifie que l'on a dépassé le nombre de jour du mois.
                jourActuel -= nombreJourDuMois #Dans ce cas on retire le nombre de jour du mois pour avoir le premier vendredi du mois suivant.
                #Fin d'une boucle for de mois, on passe au mois suivant
            #Fin d'une boucle for année, on passe à l'année suivante.
        print(compteurVendredi13) #Afficher le résultat.
                
    main()
    

    Merci d'avance pour votre aide! :D

    -
    Edité par HugoCarpentier1 29 novembre 2020 à 2:17:10

    • Partager sur Facebook
    • Partager sur Twitter
      29 novembre 2020 à 2:44:48

      Salut,
      Premièrement, à partir de quelle date commence le calcul de Wikipedia? Est-ce 2000? Est-ce que 2400 est compris?
      Ensuite, les années divisibles par 100 et pas par 400 ne sont pas bissextiles. L'année 2100 n'est pas bissextile.
      Dès que je passerais à une nouvelle année, je changerais tout de suite le nombre de jours de février, je n'aurais pas besoin de le tester tout le temps.
      Février serait un mois comme les autres. Tu peux le faire car tu es dans une liste.
      Ce n'est pas vraiment une norme mais un usage, le jour 0 est un dimance et samedi est le jour 6. Vendredi serait 5.
      • Partager sur Facebook
      • Partager sur Twitter

      Le Tout est souvent plus grand que la somme de ses parties.

        29 novembre 2020 à 11:30:13

        Bonjour

        Comme te l'a dit Pierrot, ta condition de détection d'une année bissextile est incorrecte. Ton exercice est relativement classique, tu le trouveras par exemple dans mon cours Découverte de la programmation, page 335-6 avec des questions intermédiaires. Basiquement, ton code a l'air d'aller dans le principe, visiblement, tu progresses de 7 en 7.

        Une autre méthode mais je ne pense pas que ce soit ce que l'on te demande est d'utiliser le module datetime :

        from datetime import date
        
        def suivant(x):
            m = x.month
            d = x.day
            y = x.year
            if d < 13:
                return date(y, m, 13)
            else:
                if m < 12:
                    return date(y, m + 1, 13)
                else:
                    return date(y + 1, 1, 13)
        
        x = date.today()
        
        cpt=0
        N=10
        
        while cpt<N:
            x = suivant(x)
            if x.weekday() == 4:
                print('vendredi 13/%d/%d' % (x.month, x.year))
                cpt+=1

        qui affiche les N=10 prochains vendredis 13 à partir du jour d'aujourd'hui :

        vendredi 13/8/2021
        vendredi 13/5/2022
        vendredi 13/1/2023
        vendredi 13/10/2023
        vendredi 13/9/2024
        vendredi 13/12/2024
        vendredi 13/6/2025
        vendredi 13/2/2026
        vendredi 13/3/2026
        vendredi 13/11/2026
        




        -
        Edité par PascalOrtiz 29 novembre 2020 à 11:33:12

        • Partager sur Facebook
        • Partager sur Twitter
          29 novembre 2020 à 12:39:56

          Ouaip ta condition pour les années bissextiles est fausse pour les années 2100, 2200 et 2300.

          Sinon on trouve effectivement 688 avec ce code :

          from datetime import date
          
          friday = 0
          for year in range(2019, 2419):
              for month in range(1, 13):
                  if date(year, month, 13).weekday() == 4:
                      friday += 1
          
          print(friday)

          J'ai aussi une solution sans datetime. Mais à part ça, je me demande si on ne peut pas calculer ça sans boucle.

          -
          Edité par thelinekioubeur 29 novembre 2020 à 13:03:14

          • Partager sur Facebook
          • Partager sur Twitter
            29 novembre 2020 à 17:08:33

            J'ai encore des problèmes avec l'interactiion entre ma synthèse vocale et l'éditeur du forum. J'ai précédé chaque ligne avec #*
            Cette méthode ne vérifie l'année bissextile qu'au changement d'année. Je met 28 ou 29 dans listeMois[1].
            Ça va environ 4 fois plus vite avec le  test sur %7 == 6 et en avançant de 28 au lieu de     7
            Et j'obtiens bien les 688 vendredi 13 en question.
            Je me synchronise rapidement sur le premier vendredi.
            -
            #*# Compter les vendredi 13.
            #*listeMois = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
            #*annee = 2019
            #*indiceMois = 0
            #*jourActuel = 1 + (5-2+7)%7   # Le 1 janvier 2019 est un mardi (2) et on veut se rendre au vendredi (5).
            #*# Si le 1 janvier avait été un samedi (6), on aurait écrit   jourActuel = 1 + (5-6+7)%7   et ça aurait fonctionné.
            #*compteurVendredi13 = 0
            #*while annee < 2420:   # Pour une période de 400 ans.
            #*    if jourActuel%7 == 6:   # Ça doit être 6, 13, 20, 27 pour attraper le 13.
            #*        compteurVendredi13 += 1   # 6, 13, 20, 27
            #*    jourActuel += 28   # on passe presque à coup sûr au mois suivant.
            #*    # On ne peut pas sauter un mois.
            #*    if jourActuel > listeMois[indiceMois]:
            #*        jourActuel -= listeMois[indiceMois]
            #*        indiceMois += 1
            #*        if indiceMois > 11:
            #*            indiceMois -= 12
            #*            annee += 1
            #*            # Sachant que False est équivalent à 0 et True est équivalent à 1:
            #*            # Le mois de février aura 29 jours si l'année est bissextile.
            #*            listeMois[1] = 28 + ((annee%4 == 0 or annee%400 == 0) and annee%100 != 0)
            #*print(compteurVendredi13)
            • Partager sur Facebook
            • Partager sur Twitter

            Le Tout est souvent plus grand que la somme de ses parties.

            Compter les vendredis 13.

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown