Bibm@th

Forum de mathématiques - Bibm@th.net

Bienvenue dans les forums du site BibM@th, des forums où on dit Bonjour (Bonsoir), Merci, S'il vous plaît...

Vous n'êtes pas identifié(e).

#1 23-02-2014 11:08:35

Dico
Membre
Inscription : 12-12-2009
Messages : 120

[Python] Programme calendrier perpétuel

Salut à tous
Je poste si dessous les lignes de code de mon programme calendrier perpétuel. donnez lui n'importe quelle date (passée comme future), il vous donne le jour de la semaine correspondant.


# -*- coding : Latin - 1 -*
import os

def bissextile(annee):
    bissextile = False
    if (annee % 400 == 0) or (annee % 4 ==0 and not annee % 100 ==0):
       bissextile = True
    return bissextile

def nb_jour(annee):
  som = 0
  i = 1
  while i < annee:
    if bissextile(i):
      som += 366
    else:
      som += 365
    i += 1
  return som

def reste(jour, mois, annee):
    if not bissextile(annee):
       if mois == 'janvier':
          rest = jour - 1
       if mois == 'février' or mois == 'fevrier':
          rest = 31 + jour - 1
       if mois == 'mars':
          rest = 31+28+jour - 1
       if mois == 'avril':
          rest = 31+28+31+jour - 1
       if mois == 'mai':
          rest = 31+28+31+30+jour - 1
       if mois == 'juin':
          rest = 31+28+31+30+31+jour - 1
       if mois == 'juillet':
          rest = 31+28+31+30+31+30+jour - 1
       if mois == 'aout' or moi == 'août':
          rest = 31+28+31+30+31+30+31+jour - 1
       if mois == 'septembre':
          rest = 31+28+31+30+31+30+31+31+jour - 1
       if mois == 'octobre':
          rest = 31+28+31+30+31+30+31+31+30+jour - 1
       if mois == 'novembre':
          rest = 31+28+31+30+31+30+31+31+30+31+jour - 1
       if mois== 'decembre':
          rest = 31+28+31+30+31+30+31+31+30+31+30+jour - 1
    else:
       if mois == 'janvier':
          rest = jour - 1
       if mois == 'février' or mois == 'fevrier':
          rest = 31 + jour - 1
       if mois == 'mars':
          rest = 31+29+jour - 1
       if mois == 'avril':
          rest = 31+29+31+jour - 1
       if mois == 'mai':
          rest = 31+29+31+30+jour - 1
       if mois == 'juin':
          rest = 31+29+31+30+31+jour - 1
       if mois == 'juillet':
          rest = 31+29+31+30+31+30+jour - 1
       if mois == 'aout' or moi == 'août':
          rest = 31+29+31+30+31+30+31+jour - 1
       if moi == 'septembre':
          rest = 31+29+31+30+31+30+31+31+jour - 1
       if mois == 'octobre':
          rest = 31+29+31+30+31+30+31+31+30+jour - 1
       if mois == 'novembre':
          rest = 31+29+31+30+31+30+31+31+30+31+jour - 1
       if mois == 'decembre':
          rest = 31+29+31+30+31+30+31+31+30+31+30+jour - 1
    return rest

print("Ce programme va vous aider à déterminer le jour de la semaine d'une date")

jour = input("saisissez le jour : ")
moi = input("saisissez le mois (en lettre) : ")
annee = input("saisissez enfin L'année : ")
jour = int(jour)
annee = int(annee)
s = nb_jour(annee) + reste(jour, mois, annee)

if s % 7 == 0:
   print("lundi, ", jour, mois, annee)
elif s % 7 == 1:
   print("mardi, ", jour, mois, annee)
elif s % 7 == 2:
   print("mercredi, ", jour, mois, annee)
elif s % 7 == 3:
   print("jeudi, ", jour, mois, annee)
elif s % 7 == 4:
   print("vendredi, ", jour, mois, annee)
elif s % 7 == 5:
   print("samedi, ", jour, mois, annee)
else:
   print("dimanche, ", jour, mois, annee)

os.system("pause")

 

Bon après-midi


Bon après-midi!

Hors ligne

#2 23-02-2014 12:50:34

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 948

Re : [Python] Programme calendrier perpétuel

Salut,

Je vais y aller moi aussi de mon programme...
Mais pas tout de suite, j'ai une revue trimestrielle à finir et à remettre ensuite à l'Imprimeur.
Une petite question :
Je lis :

def bissextile(annee):
    bissextile = False
    if (annee % 400 == 0) or (annee % 4 ==0 and not annee % 100 ==0):
       bissextile = True
    return bissextile

bissextile(300) me renvoie False.
Or, ici : http://b.villemin.pagesperso-orange.fr/bissexti.html, je lis:

2/ Le calendrier JULIEN.

Décidé donc par Jules César, d'où son nom, il fut élaboré plus sérieusement, sur les conseils de Sosigène, un astrologue d'Alexandrie, qui décida de " coller " au plus près d'une année qu'il avait estimée à pratiquement 365,25 jours.

La solution était alors des années de 365 jours, avec un jour supplémentaire tous les 4 ans.

Systématiquement, à ce bémol près (même auteur) :

Pour être clair, et en adoptant la numérotation astronomique des années négatives (voir plus loin), les années suivantes ont été bissextiles, depuis la création du calendrier Julien:

-44, -41, -38, -35, -32, -29, -26, -23, -20, -17, -14, -11, -8; ensuite -4, 0, 4 et 8 n'ont pas été bissextiles (réforme d'Auguste). Les choses repartent normalement tous les 4 ans à partir de l'an 12, 16, 20 etc...

L'an 300, quoique non multiple de 400, devait donc être bissextile.

Confirmé par Wikipedia :

Le calendrier julien, qui avait cours avant le calendrier actuel, ne distinguait pas les fins de siècles (années divisibles par 100). Une année était bissextile tous les 4 ans, sans autre exception. Le calendrier julien avait ainsi une année moyenne de 365,25 jours, au lieu des 365,2422 jours nécessaires au cycle terrestre. Ce qui a engendré l'accumulation d'une dizaine de jours de retard en quinze siècles.

De plus http://www.mbokamosika.com/article-l-or … 33506.html:

Année bissextile & bissexte

Une année bissextile, comme 2012, est une année de 366 jours, comprenant un 29 février. En latin, on emploie le terme de bisextus pour désigner le jour intercalaire que l'on plaçait tous les quatre ans dans le calendrier julien. Ce mot est composé de bis (deux fois) et de sextus (sixième). On doublait le sixième jour avant les calendes de mars, c'est à dire le 24 février. Un bissexte, c'est à l'origine un 24 bis de février !

En ancien français, le jour intercalaire portait le nom de bissestre (ou besistre). Aujourd'hui, on parle plutôt du 29 février que du bissexte !

Comment concilies-tu tout ça ?

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#3 24-02-2014 11:16:08

Dico
Membre
Inscription : 12-12-2009
Messages : 120

Re : [Python] Programme calendrier perpétuel

De calendrier en calendrier, je perds la boule! Le bon code est ci-dessous.

Avant 1583, c'est le calendrier julien qu'il faut considérer. La date de référence que je considère comme vrai pour faire marcher cette partie, est le jeudi 4 octobre 1582.

A partir de 1583, c'est le calendrier grégorien, la date d'aujourd'hui peut servir comme référence.

Par ailleurs, ce n'est qu'à partir des années 300 qu'on a les semaine à sept jour et donc avant cette date, parler de jour de la semaine n'est pas correct, pas grave.


# -*- coding : Latin - 1 -*
import os

def bissextile_julien(annee):
    bissextile = False
    if (annee % 4 ==0):
       bissextile = True
    return bissextile

def bissextile_gregorien(annee):
    bissextile = False
    if (annee % 400 == 0) or (annee % 4 ==0 and not annee % 100 ==0):
       bissextile = True
    return bissextile

def nb_jour(annee):
    som = 0
    i = 1
    if annee < 1583:
        while i < annee:
            if bissextile_julien(i):
                som += 366
            else:
                som += 365
            i += 1
    else:
        while i < annee:
            if bissextile_gregorien(i):
                som += 366
            else:
                som += 365
            i += 1
    return som

def reste(jour, moi, annee):
    if annee < 1583:
        if not bissextile_julien(annee):
            if moi == 'janvier':
                rest = jour - 1
            if moi == 'février' or moi == 'fevrier':
                rest = 31 + jour - 1
            if moi == 'mars':
                rest = 31+28+jour - 1
            if moi == 'avril':
                rest = 31+28+31+jour - 1
            if moi == 'mai':
                rest = 31+28+31+30+jour - 1
            if moi == 'juin':
                rest = 31+28+31+30+31+jour - 1
            if moi == 'juillet':
                rest = 31+28+31+30+31+30+jour - 1
            if moi == 'aout' or moi == 'août':
                rest = 31+28+31+30+31+30+31+jour - 1
            if moi == 'septembre':
                rest = 31+28+31+30+31+30+31+31+jour - 1
            if moi == 'octobre':
                rest = 31+28+31+30+31+30+31+31+30+jour - 1
            if moi == 'novembre':
                rest = 31+28+31+30+31+30+31+31+30+31+jour - 1
            if moi == 'decembre':
                rest = 31+28+31+30+31+30+31+31+30+31+30+jour - 1
        else:
            if moi == 'janvier':
                rest = jour - 1
            if moi == 'février' or moi == 'fevrier':
                rest = 31 + jour - 1
            if moi == 'mars':
                rest = 31+29+jour - 1
            if moi == 'avril':
                rest = 31+29+31+jour - 1
            if moi == 'mai':
                rest = 31+29+31+30+jour - 1
            if moi == 'juin':
                rest = 31+29+31+30+31+jour - 1
            if moi == 'juillet':
                rest = 31+29+31+30+31+30+jour - 1
            if moi == 'aout' or moi == 'août':
                rest = 31+29+31+30+31+30+31+jour - 1
            if moi == 'septembre':
                rest = 31+29+31+30+31+30+31+31+jour - 1
            if moi == 'octobre':
                rest = 31+29+31+30+31+30+31+31+30+jour - 1
            if moi == 'novembre':
                rest = 31+29+31+30+31+30+31+31+30+31+jour - 1
            if moi == 'decembre':
                rest = 31+29+31+30+31+30+31+31+30+31+30+jour - 1
    else:
        if not bissextile_gregorien(annee):
            if moi == 'janvier':
                rest = jour - 1
            if moi == 'février' or moi == 'fevrier':
                rest = 31 + jour - 1
            if moi == 'mars':
                rest = 31+28+jour - 1
            if moi == 'avril':
                rest = 31+28+31+jour - 1
            if moi == 'mai':
                rest = 31+28+31+30+jour - 1
            if moi == 'juin':
                rest = 31+28+31+30+31+jour - 1
            if moi == 'juillet':
                rest = 31+28+31+30+31+30+jour - 1
            if moi == 'aout' or moi == 'août':
                rest = 31+28+31+30+31+30+31+jour - 1
            if moi == 'septembre':
                rest = 31+28+31+30+31+30+31+31+jour - 1
            if moi == 'octobre':
                rest = 31+28+31+30+31+30+31+31+30+jour - 1
            if moi == 'novembre':
                rest = 31+28+31+30+31+30+31+31+30+31+jour - 1
            if moi == 'decembre':
                rest = 31+28+31+30+31+30+31+31+30+31+30+jour - 1
        else:
            if moi == 'janvier':
                rest = jour - 1
            if moi == 'février' or moi == 'fevrier':
                rest = 31 + jour - 1
            if moi == 'mars':
                rest = 31+29+jour - 1
            if moi == 'avril':
                rest = 31+29+31+jour - 1
            if moi == 'mai':
                rest = 31+29+31+30+jour - 1
            if moi == 'juin':
                rest = 31+29+31+30+31+jour - 1
            if moi == 'juillet':
                rest = 31+29+31+30+31+30+jour - 1
            if moi == 'aout' or moi == 'août':
                rest = 31+29+31+30+31+30+31+jour - 1
            if moi == 'septembre':
                rest = 31+29+31+30+31+30+31+31+jour - 1
            if moi == 'octobre':
                rest = 31+29+31+30+31+30+31+31+30+jour - 1
            if moi == 'novembre':
                rest = 31+29+31+30+31+30+31+31+30+31+jour - 1
            if moi == 'decembre':
                rest = 31+29+31+30+31+30+31+31+30+31+30+jour - 1
    return rest

print("ce programme va vous aider à déterminer le jour de la semaine d'une date")

jour = input("saisissez le jour du mois : ")
moi = input("saisissez le mois (en lettre) : ")
annee = input("saisissez enfin L'année : ")
jour = int(jour)
annee = int(annee)
s = nb_jour(annee) + reste(jour, moi, annee)

if annee < 1583:
  if s % 7 == 0:
    print("samedi, ", jour, moi, annee)
  elif s % 7 == 1:
    print("dimanche, ", jour, moi, annee)
  elif s % 7 == 2:
    print("lundi, ", jour, moi, annee)
  elif s % 7 == 3:
    print("mardi, ", jour, moi, annee)
  elif s % 7 == 4:
    print("mercredi, ", jour, moi, annee)
  elif s % 7 == 5:
    print("jeudi, ", jour, moi, annee)
  else:
    print("vendredi, ", jour, moi, annee)
else:
  if s % 7 == 0:
    print("lundi, ", jour, moi, annee)
  elif s % 7 == 1:
    print("mardi, ", jour, moi, annee)
  elif s % 7 == 2:
    print("mercredi, ", jour, moi, annee)
  elif s % 7 == 3:
    print("jeudi, ", jour, moi, annee)
  elif s % 7 == 4:
    print("vendredi, ", jour, moi, annee)
  elif s % 7 == 5:
    print("samedi, ", jour, moi, annee)
  else:
    print("dimanche, ", jour, moi, annee)

os.system("pause")
 

Samedi, 1er janvier 0001   (pour julien)

Lundi, 1er janvier 0001   (pour grégorien)

Bon après-midi !


Bon après-midi!

Hors ligne

#4 24-02-2014 13:49:06

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 948

Re : [Python] Programme calendrier perpétuel

Salut,

J'ai bouclé mon programme...
Il fonctionne entre 1583 et la suite...
Avant, pas testé encore because ma revue.
Il sera beaucoup, beaucoup plus court (46 lignes), puisque je fais appel au module intégré à Python : datetime.
Si j'ai bien compris la doc python, il calcule "naïvement" (dit-elle) avec un calendrier grégorien depuis l'an 1.
J'ai vérifié.
Pour Python :
* Les années 4 et 8 juliennes étaient bissextiles, ce qu'elles n'étaient pas...
* Les années séculaires 100, 200, 300 par ex  sont considérées comme non bissextiles par Python selon notre vision actuelle. Ce qui est faux aussi.   
   Jusqu'en 1582, était considérée comme bissextile, une année multiple de 4, point-barre.
* Enfin cerise sur le gâteau, le module datetime permet de trouver que l'année 1582 a eu ... 365 jours, alors qu'on est passé directement du Jeudi 4 octobre au vendredi 15 octobre...
Cela m'a obligé à calculer la correction à appliquer pour toute date antérieure à 1583...
C'est fini depuis ce matin : il me reste donc encore à tester ça minutieusement.
En informatique, il y a une règle à ne pas perdre de vue : un programme n'est jamais bon du premier coup. Du point de vue du matheux, c'est frustrant, mais on s'y fait : il faut laisser du temps au temps a dit l'ancien Président F. M.
Moi ce qui m'intéresse, c'est que si je m'installe dans ma machine à remonter le temps, que je remonte (par ex) jusqu'au 15 août 800, en sortant de la machine, je veux voir sur le calendrier que le jour écrit est bien celui que j'ai calculé... ;-)

@+

[EDIT] Mes tests son concluants. Mais je viens de me dire que pour ces années que le Python considère comme non-bissextiles - alors qu'elles l'étaient - je dois avoir une erreur pour les dates où les mois sont janvier et février...
Je corrigerai demain.
De même, je tenterai plus tard de "factoriser" ta programmation naïve : ce n'est pas une critique, il ne pouvait en être autrement...
Tu devrais te pencher sur l'usage des boucles for et des listes.
Une liste est une forme de tableau où chaque élément est accessible par son indice (l'indice de départ étant 0).
Si tous les éléments sont différents, on peu trouver l'indice de n'importe lequel d'entre eux par (L étant le nom de la liste) :
L.index(élément)..
Par ex, avec une liste J (par ex) des jours, tu évites d'énumérer, les 7 jours : tu résumes ça en une seule ligne.
Comme ça :
print(J[s%7], jour, mois, annee)
Gain : 6 lignes (2 fois dans ton cas)...

Tu peux procéder pareillement pour ton énumération des mois.
Crée donc une liste M de couples de mois et une liste E du nombre de jours écoulés :
M=["janvier","février","mars","avril"......]
E=[0,31,59,90,.... ]

Après la saisine du nom du mois, pour les noms accentués, teste si l'accent manque et rétablis-le.
Définis une variable m ainsi :
      m = Mois.index(mois).
Enfin remplace tes 12 tests de 2 ligne par une seule ligne sans test :
      rest = E[m]+jour - 1 + bissextile*(m>1)
bissextile vaut False ou True, 0 ou 1
(m>1) vaut False ou True, 0 ou 1

Que fais-je avec + bissextile*(m>1) ?

J'ajoute 1 à rst pour tout m >1 (soit les mois après la 2e position : mars, avril... si et seulement si bissextile vaut 1.
Si bissextile vaut 0, j'ajoute... 0

J'ai remplacé 48 lignes par 1 seule !

Voilà de quoi essayer en mode console :
M=['janvier','février','mars','avril','mai','juin','juillet','août','septembre','octobre','novembre','décembre']
E=[0,31,59,90,120,151,181,212,143,273,304,334]

Dernière modification par yoshi (24-02-2014 20:59:32)


Arx Tarpeia Capitoli proxima...

Hors ligne

#5 25-02-2014 10:21:12

Dico
Membre
Inscription : 12-12-2009
Messages : 120

Re : [Python] Programme calendrier perpétuel

Waouu! géniale! puissant ton truc!
Rectificatif: tu as remplacé 48 lignes par 3 et non 1.
Pour te citer, avec python, il faut ruser.

En fait mon but au départ (alors que je m'initiais à python) était de comprendre le fonctionnement des package, module et fonction. j'avais donc écrit ce programme avec un package jour contenant une fonction bissextile et un module nbre_de_jour, contenant une fonction nb_jour et une fonction rest. à ce moment là, je n'étais même pas encore arrivé dans la leçon sur les liste dans mon cours.

En ce qui concerne la "non-bissextilité" des années 4 et 8 que tu annonce, je cite une page de Wikipedia

wikipedia a écrit :

Bien que l'intercalation julienne soit plus simple que celle du calendrier romain, elle fut, semble-t-il, mal appliquée au début. Apparemment, les pontifes comprirent mal la méthode et ajoutèrent un jour intercalaire tous les trois ans, et non tous les quatre[4]. Auguste, Pontifex Maximus, après 36 ans, corrigea cette erreur en omettant plusieurs années bissextiles pour réaligner l'année civile sur le Soleil.
La suite des années bissextiles de cette période n'est donnée explicitement par aucune source ancienne...

Mais tous ceux qui se sont prononcés sur la question son d'accord sur le fait que, les années 4, 8, 12, etc. n'étaient pas bissextiles. Mais, quelles années mets-tu dans le etc.?

Je vais donc utiliser les listes et ton aide pour rendre mon  programme plus court et plus lisible. Mais, tu t’imagine que tu n'es pas le seul occupé!? Je m'y remet mercredi soir. Merci Yoshi!

Bon après-midi !

Dernière modification par Dico (25-02-2014 10:44:36)


Bon après-midi!

Hors ligne

#6 25-02-2014 11:28:11

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 948

Re : [Python] Programme calendrier perpétuel

Salut,

D'après mes sources, seules les années 4 et 8 n'étaient pas bissextiles.
A partir de l'an 12, toutes les années multiples de 4 sont devenues bissextiles sans exception : donc y compris les siècles dont le millésime n'est pas multiple de 4 : 100, 200,300, 500, 600, 700, 900, 1000, 1100, 1300, 1400, 1500.
Ces histoires de calendrier ne sont pas toujours explicitées clairement : certaines sources se contredisent, d'autres ont visiblement fait des copier/coller sans plus vérifier...

Ma revue me prend la tête : comment faire 4 pages sur le Tibet sans y être jamais allé ?
Je ne vais pas tarder à faire une pause.

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#7 25-02-2014 12:00:23

Dico
Membre
Inscription : 12-12-2009
Messages : 120

Re : [Python] Programme calendrier perpétuel

Tu n'as qu'à faire 4 pages sur la France et utiliser l'affectation France=Tibet !

Tes sources, sont des pages web? je peux les avoir?
As-tu lu la page que je cite au post #5?

Bon après-midi !

Dernière modification par Dico (25-02-2014 12:08:11)


Bon après-midi!

Hors ligne

#8 25-02-2014 13:06:29

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 948

Re : [Python] Programme calendrier perpétuel

Bonjour,

http://b.villemin.pagesperso-orange.fr/bissexti.html
C'est une page perso, mais je considère ses infos comme fiables : je ne l'ai encore jamais pris en train de raconter des bourdes.
http://www.auduteau.net/calendar/cal2_1.shtml
http://www.esraonline.com/index.php?pag … icle&id=17 (là il faut lire entre lignes du paragraphe "Auguste ne vaut pas moins que Jules")

Curiosités qui n'arrangent rien :
http://www.louisg.net/E_confusions_julien.htm
http://www.altcal.eu/earleap1.html
http://pages.infinit.net/histoire/calendrier.html

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#9 25-02-2014 20:22:12

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 948

Re : [Python] Programme calendrier perpétuel

Re,

Plutôt que de recopier des formules dont je ne comprends encore pas pourquoi elles fonctionnent, j'ai choisi ma propre voie.
J'ai contrôlé que le 1er janvier 1990 était un lundi puis j'ai choisi cette date comme date de référence.
Un 1er janvier était une date idéale pour déterminer si une date donnée est antérieure ou postérieure...
Je calcule donc via les fonctions natives de Python le nombre de jours d'écarts entre une date donnée et ma date de référence.
Jusqu'au 15 octobre 1582, je ne m'occupe pas des années bissextiles : c'est Python qui gère...
C'est avant le 4 octobre 1582 que ça se gâte, puisque Python prend les années bissextiles  à la mode actuelle.
Et donc exclut de fait les années 100, 200,300, 500, 600, 700, 900, 1000, 1100, 1300, 1400, 1500.
Pour une date donnée j'ai besoin de connaître le nombre de centenaires non comptabilisés écoulés entre la date donnée et 1582.
Soit par ex, l'année 1090. Il y a eu 1100, 1300, 1400, 1500  soit un déficit de 4
Je calcule donc mil = 1090//100 = 10
puis mil-(mil-1)//4 = 8 et enfin 12 - (mil-(mil-1)//4) = 4. 12 parce qu'il y a au total 1000 centenaires "oubliés"'
1090 <1582
Python a compté 365 jours pour 1582, j'ai donc un correctif de 10 jours de trop à apporter...
Mais Python a laissé pour compte des centenaires, il faut donc les soustraire aux 10 jours :
10- (12 - (mil-(mil-1)//4)) formule que j'ai simplifiée.
Mais, je marche à l'envers, je dois donc soustraire encore un  à ce nombre si la date coïncide avec un centenaire pour les mois de janvier et février.
Quant aux années inférieures à 12 : 4 et 8 sont comptées à tort bissextiles, je dois donc rajouter un décalage au nombre précédent de 1 jour les années entre 4 et 8, 2 avant, avec effet dès les mois de janvier et février 4 et 8.
Horrible...
Mais c'est la conséquence de mon choix
* d'une date de référence
* d'emploi des fonctions natives et "naïves" (sic) de Python
Cela dit, je n'ai pas la certitude absolue de ne pas "m'être emmêlé les pinceaux" pour les dates < 1582...
Je n'ai pas trop le temps de tests complets en ce moment...


#!/usr/bin/env python
# -*- coding: Latin-1 -*-

from __future__ import division
from datetime import datetime

def NumJourSemaine(Date):
    sens,cor=1,0
    jour,mois,an=int(Date[:2]),int(Date[3:5]),int(Date[6:])
    if an <1990:
        sens=-1
        if an<1583:
            cor=Correctif(an,mois,jour)
    if sens:
        ecart=datetime(an,mois,jour)-datetime(1990,1,1)
        ecart=datetime(1990,1,1)-datetime(an,mois,jour)
    else:
        ecart=datetime(1990,1,1)-datetime(an,mois,jour)
    nbj=ecart.days-cor
    numjour=(1+sens*nbj)%7
    return numjour,jour,mois,an

def Correctif(an,mois,jour):
    if an==1582:
        if mois>10:
            cr=0
        elif mois==10:
            if jour>14:
                cr=0
            else:
                cr=10
    else:        
        mil=an//100
        cr=mil-(mil-1)//4-2
        if an>=12 and mois<2 and (an%100==0 and an%4!=0):
            cr-=1
        if an>0 and an<12:
            cr+=((an==4 and mois<2)or an<4)+((an==8 and mois <2)or an<8)
    return cr
   
#Date de référence : Lundi 1er janvier 1990

Jours=["Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"]
Mois=['janvier','février','mars','avril','mai','juin','juillet','août',
      'septembre','octobre','novembre','décembre']

Date="27/11/511"
print "       Le", Date
njs,jour,mois,an=NumJourSemaine(Date)
print "     est en fait le"
print Jours[njs],str(jour)+"er"*(jour==1), Mois[mois-1], an
 

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#10 26-02-2014 08:20:32

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 948

Re : [Python] Programme calendrier perpétuel

Bonjour,

Une idée m'est venue durant la nuit.
Sur le même principe, je vais faire plus simple et donc plus fiable...
Le nombre de jours entre aujourd'hui et le 01/01/0001 donné par Python se trouve être exact. Heureux hasard !
En effet, la valeur donnée par Python est à :
--> +10 (l'année 1582 est comptée à 365 jours)
-->  -12  (les siècles dont le millésime n'est pas multiple de 4 ne sont pas comptabilisés)
--> + 2  (les années 4 et 8 sont comptées bissextiles alors qu'elles ne l'ont été qu'à partir de l'an 12)
Bilan : 0.

1. Je vais stocker le nombre de jours écoulés entre le lundi 1er janvier 1990 et le 01/01/0001
2. Je vais donc calculer le nb de jours entre une date donnée et le 01/01/0001
    Si l'année est postérieure à 1582, pas de correction à faire.
    Si l'année est antérieure, le correctif sera plus simple à appliquer.
3. Je calculerai alors la différence entre les deux nombres et j'obtiendrai modulo 7, le n° du jour cherché
N-B :
Même si le nombre jours calculés entre toute date postérieure à 1582, ça n'aurait aucune importance : la différence gommant les erreurs : c'est le principe de la "double pesée" apprise en 2nde à propos de la balance de Robertval.

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#11 26-02-2014 15:03:07

Dico
Membre
Inscription : 12-12-2009
Messages : 120

Re : [Python] Programme calendrier perpétuel

Vois-tu Einstein dans tes rêves la nuit?
Tes sources ne m'ont pas éclairé sur les années non bissextiles 4, 8, ...

Mais ton exposé précédent me permet de comprendre pourquoi lorsque j'utilisais uniquement le principe grégorien pour compter les jours du 01 janvier 0001 à une date postérieure, j'avais toujours de bon résultats pour les dates après 1582. Je vais ton supposer ta théorie 4, 8.

Bon après-midi !


Bon après-midi!

Hors ligne

#12 26-02-2014 15:43:53

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 948

Re : [Python] Programme calendrier perpétuel

Ave,

Vois-tu, Lycéen, j'avais souvent constaté, que j'emm... mon cerveau en lui donnant des directives dont il n'avait que faire. Donc, je lui soumets un problème, vais dormir (lui fout donc la paix) et le lendemain, en général, j'ai ma réponse offerte ur un plateau

Dico a écrit :

Tes sources ne m'ont pas éclairé sur les années non bissextiles 4, 8, ...

Et pourtant :

http://b.villemin.pagesperso-orange.fr/bissexti.html  a écrit :

-44, -41, -38, -35, -32, -29, -26, -23, -20, -17, -14, -11, -8; ensuite -4, 0, 4 et 8 n'ont pas été bissextiles (réforme d'Auguste). Les choses repartent normalement tous les 4 ans à partir de l'an 12, 16, 20 etc...

Bon, j'ai terminé la 2e méthode. Maintenant, il faut que je retourne à ma revue...

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#13 26-02-2014 17:00:33

Dico
Membre
Inscription : 12-12-2009
Messages : 120

Re : [Python] Programme calendrier perpétuel

Mince! ton truc m'arrive aussi. J'ai l’impression que une fois endormi, je résous certains problèmes restés en suspend dans mon cœur.


Bon après-midi!

Hors ligne

#14 27-02-2014 19:41:22

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 948

Re : [Python] Programme calendrier perpétuel

Bonsoir,

2e version : une 2 en 1, puisque 2 calculs différents selon que la date proposée est antérieure ou égale au jeudi 4 octobre 1582 ou postérieure ou égale au 15 octobre 1582.
Dans le 1er cas, j'ai décompté 577734 jours depuis le 01/01/0001 au 4 octobre 1582 et dans le 2e cas 726467 jours (décompte Python) du 01/01/0001 au 01/01/1990. Ce décompte se trouve être exact (cf post #10) et tout calcul de nombre de jours entre 01/01/0001 et toute date supérieure ou égale au 15/10/1582 sera exact aussi.
Je prends la valeur absolue de la différence que j'ajoute 1 (jour 1 = lundi) si ma date est postérieure au 01/01/1990 (ou retranche à 1 si antérieure ; dans le cas de dates antérieures au jeudi 4 octobre 1582 (jeudi : index 4 de ma liste) je retranche la différence à 4.
Et je prends le résultat modulo 7 qui me donne  l'index du jour dans ma liste.
1 ou 4 : variable d pour day

#!/usr/bin/env python
# -*- coding: Latin-1 -*-

from __future__ import division
from datetime import datetime

def NumJourSemaine(Date):
    # 726467  Nombre de jours de reférence depuis le 01/01/0001
    jour,mois,an=int(Date[:2]),int(Date[3:5]),int(Date[6:])
    sens,cor,d=1-2*(an<1990),0,1
    if an>1582:
        nbj=abs(datetime(an,mois,jour)-datetime(1990,1,1)).days      
    else:
        if an==1582:
            if mois==10 and jour>14:
                nbj=(datetime(1990,1,1)-datetime(an,mois,jour)).days
            elif mois<10 or (mois==10 and jour<=4):
                nb_ec=(datetime(an,mois,jour)-datetime(1,1,1)).days+10
                nbj,d=577734-nb_ec,4            
        else:
            cor=Correctif(an,mois,jour)
            nb_ec=(datetime(an,mois,jour)-datetime(1,1,1)).days+cor
            nbj,d=577734-nb_ec,4        
    numjour=(d+sens*nbj)%7  
    return numjour,jour,mois,an

def Correctif(an,mois,jour):
    Oubli =[0,1,2,3,5,6,7,9,10,11,13,14,15]
    mil=an//100
    if an in [1,2,3,4,5,6,7,8,9,10,11]:
        cr=-an//4
        if (an==4 or an==8)and mois<2:
            cr+=1
    elif an<1582:
        cr=(Oubli.index(mil)-2)
        if an%100==0 and mil%4!=0:
            if mois<2:
                cr-=1
    return cr
   
Jours = ["Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"]
Mois = ['janvier','février','mars','avril','mai','juin','juillet','août',
      'septembre','octobre','novembre','décembre']

Date="27/11/511"
print "       Le", Date
njs,jour,mois,an=NumJourSemaine(Date)
print "     est en fait le"
print Jours[njs],str(jour)+"er"*(jour==1), Mois[mois-1], an

Sorties :

Le 27/11/511
     est en fait le
Dimanche 27 novembre 511

       Le 01/04/300
     est en fait le
Lundi 1er avril 300

       Le 14/07/1789
     est en fait le
Mardi 14 juillet 1789

       Le 27/11/2114
     est en fait le
Mardi 27 novembre 2114

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#15 28-02-2014 10:40:29

nerosson
Membre actif
Inscription : 21-03-2009
Messages : 1 658

Re : [Python] Programme calendrier perpétuel

Salut à tous,

C'est exactement ce que dit le calendrier perpétuel de G.D. Moret.

Hourrah ! ! ! On a redécouvert l' Amérique, mais ça n'a pas été facile !

Hors ligne

#16 28-02-2014 19:53:21

Dico
Membre
Inscription : 12-12-2009
Messages : 120

Re : [Python] Programme calendrier perpétuel

Utilisons donc les modules intégrés de python!
calendar, est un module intégré de python permettant de: comparer deux dates, déterminer "le jour de la semaine" d'une date,...
Mais, il se trompe sur les années antérieures au 5 octobre 1582. Le but de la manœuvre est donc de corriger cela.
Dans le programme ci-dessous, je laisse donc python gérer les dates postérieures au 14 octobre 1582, et je m'occupe du reste.


# -*- coding : Latin - 1 -*
import os
import calendar
from datetime import datetime
reste = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]
M = ['janvier','février','mars','avril','mai','juin','juillet','août','septembre','octobre','novembre','décembre']
J = ['Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi', 'Dimanche']

def bissextile_julien(annee):
  bissextile = 0
  if annee > 8 and annee % 4 == 0:
    bissextile = 1
  return bissextile

def nb_jour(annee, mois, jour):
  nbre_jour, i = reste[M.index(mois)] + jour + bissextile_julien(annee)*(M.index(mois) > 1) - 1, 1
  while i < annee:
    if bissextile_julien(i):
      nbre_jour += 366
    else:
      nbre_jour += 365
    i += 1
  return nbre_jour

jour = int(input("saisissez le jour du mois : "))
mois = input("saisissez le mois (en lettre) : ")
annee = int(input("saisissez enfin L'année : "))

if datetime(annee, M.index(mois) + 1, jour) > datetime(1582, 10, 14):
  print(J[calendar.weekday(annee, M.index(mois) + 1, jour)],",", jour, mois, annee)
elif datetime(annee, M.index(mois) + 1, jour) < datetime(1582, 10, 5):
  print(J[nb_jour(annee, mois, jour) % 7],",", jour, mois, annee)
else:
  print("cette date n'a pas existé")
os.system("pause")
 

On peut après, gérer les accents. Si vous avez python installé, enregistrez ce code avec l'extension .py et testez-le
Je trouve aussi:
Dimanche, 27 novembre 511
Lundi, 1er avril 300
Mardi 14 juillet 1789
Mardi, 27 novembre 2114

Et toujours:
Lundi, 1er janvier 0001

Bon après-midi!

Dernière modification par Dico (02-03-2014 10:45:43)


Bon après-midi!

Hors ligne

#17 28-02-2014 20:27:47

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 948

Re : [Python] Programme calendrier perpétuel

Salut,

Bon, ici, il fait nuit noire et il pleut ! La neige n'est pas loin...
Bravo !
Voilà qui ressemble davantage à un programme ! Tu progresses à pas de géant...
Comme dirait nerosson : pourquoi réinventer la roue ? Les modules natifs sont bien plus rapides et bien plus fiables que tous nos substituts...
Encore un détail...
Ton programme n'est pas portable, i.e il ne fonctionnera pas sous Linux...
A cause de os.system(pause)...
Il faut utiliser input() en python 3.x et raw_input() en python 2.x...
D'autre part, ici ce n'est pas grave, les spécialistes te diront que tu crées ainsi, par appel à un programme externe, une faille de sécurité !

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#18 01-03-2014 16:36:24

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 948

Re : [Python] Programme calendrier perpétuel

Salut,

@Dico
En fait, tu triches en utilisant le module calendar de Python.
Alors, rien que pour te montrer, j'ai fait un exercice de style : je n'utilise aucune fonction Python autre que standard.
Seule concession : j'ai recalculé sans datetime, le nombre de jours écoulés depuis le 1/1/0001
- jusqu'au 01/01/12
- jusqu'au 01/01/1582
- jusqu'au 01/01/1983
- jusqu'au 01/01/1990
et ce avec les fonctions et opérations standard, puis j'ai calculé, pour les réutiliser, les écarts avec le nombre de jours jusqu'au 01/01/1990 puis le décalage par au jour n°1 (le lundi).

#!/usr/bin/env python
# -*- coding: Latin-1 -*-

def NumJourSemaine(Date):
    # 726467  Nombre de jours de reférence depuis le 01/01/0001
    jour,mois,an=int(Date[:2]),int(Date[3:5]),int(Date[6:])
    JoursEcoulesAnnee=[0,31,59,90,120,151,181,212,243,273,304,334]
    sens=1-2*(an<1990)
    if an<12:
        nb_ec=(an-1)*365+JoursEcoulesAnnee[mois-1]+jour-1
    elif an>=12 and an<1582:
        nb_ec=4015+(an-12)*365+JoursEcoulesAnnee[mois-1]+jour-1            
    elif an==1582:
        nb_ec=577458+JoursEcoulesAnnee[mois-1]+jour-1-10*(mois>10 or(mois==10 and jour>14))
    else:
        nb_ec=577813
        for j in range(1583,an):
            nb_ec+=365+((j%4==0 and j%100!=0) or j%400==0)
        nb_ec+=JoursEcoulesAnnee[mois-1]+jour-1+(((an%4==0 and an%100!=0) or an%400==0)and mois>2)  
    nbj=abs(726467-nb_ec)
    numjour=(1+sens*nbj)%7  
    return numjour,jour,mois,an
   
Jours = ["Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"]
Mois = ['janvier','février','mars','avril','mai','juin','juillet','août',
      'septembre','octobre','novembre','décembre']

Date="27/11/511"
print "       Le", Date
njs,jour,mois,an=NumJourSemaine(Date)
print "     est en fait le"
print Jours[njs],str(jour)+"er"*(jour==1), Mois[mois-1], an

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#19 02-03-2014 12:02:40

Dico
Membre
Inscription : 12-12-2009
Messages : 120

Re : [Python] Programme calendrier perpétuel

1-) Ton programme ne s'occupe que de la date: 27/11/511.
2-) Si on le fait communiquer avec un utilisateur, ce dernier devra entrer les mois avec les chiffres.
3-) A la ligne 17, tu ne devrai pas plutôt dire: range(1583, an-1)?
4-) Je ne parviens pas à l'exécuter.
5-) Peux-tu poster une version qui communiquera?
6)...

Bon après-midi!


Bon après-midi!

Hors ligne

#20 02-03-2014 13:59:47

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 948

Re : [Python] Programme calendrier perpétuel

Bonjour,

Alors pépère, je t'attendais là...
1. Pour que le programme fonctionne, tu dois savoir que print en python 2.6 est une instruction...
   J'écris donc print " Dico ne savait pas"
   En Python 3.x c'est devenu une fonction, donc on écrit :
   print (" Dico ne savait pas")
   Voilà les 3 lignes  à remplacer :
   print ("       Le", Date)
   ....................................
   print ("     est en fait le")
   print (Jours[njs],str(jour)+"er"*(jour==1), Mois[mois-1], an)

2. Pour changer de date, tu remplaces la ligne
   Date="27/11/511"
   par
   Date="jj/mm/aaaa"
   Vu la manière dont le programme est écrit je peux me dispenser d'écrire 0511, ou 0012...
   Explication de texte.
   La variable Date est un String que je coupe en tranches sur cette ligne :
   jour,mois,an=int(Date[:2]),int(Date[3:5]),int(Date[6:])
   
   Date[:2] signifie prendre du début à la position 2 non comprise
   Date[3:5] signifie prendre depuis l'index 3 à la position 5 non comprise, donc la sous-chaine composée des caractères n°3 et 4.
   Date[6:]  signifie prendre depuis l'index 6 à la fin 'je me fiche donc de connaitre la longueur)
   Mes tranches sont des string aussi que je convertis en entiers avec int()
   Donc, j'obtiens jour=27, mois=11 et an =511

   Exemples de manipulation des String :
   S="Bitcoin"
   S[:2] --> "Bi" , S[3:5] -->"co", S[6:] -->"n"
   Encore plus rigolo :
   S[-1:] --> "n"
   S[:-1] --> "Bitcoi"

   Oui, j'ai choisi de rentrer la date sous forme numérique, c'est plus simple.
3. Si je veux réaliser un programme "communiquant", je ne pourrai pas me contenter de procéder comme toi : je vais doubler la longueur.
    Je vais être obliger de créer une boucle comme ça rien qu'à la fin :
   ok =0
   

while not ok:
         rep = Input ("Tester une autre date ? O/N)
         rep=rep.upper()  # je convertis en majuscules
         if rep  in ["O","N"]:
              ok=1
         else:
               print ("Réponse incorrecte, recommencez s'il vous plaît")

        Ça c'est juste pour savoir s'il répond Oui ou Non et pas autre chose
        Boucle que je vais être obligé d'inclure dans une autre :
       

While 1:
      Questions sur la date
       Traitement d'erreur après chaque question
       Appel fonction
       Affichage résultat
       ok =0
       while not ok:
             rep = Input ("Tester une autre date ? O/N)
             rep=rep.upper()  # je convertis en majuscules
             if rep  in ["O","N"]:
                  ok=1
             else:
                  print ("Réponse incorrecte, recommencez s'il vous plaît")
       if rep=="N":
            print ("Au revoir !")
            break
 

Traitement d'erreur.
Pour le jour : tu attends un nombre entier naturel <=31.
Mais tu as besoin avant d'avoir l'année pour savoir s'il est bissextile ou pas, le mois et enfin le jour.
Pour le mois; tu attends un mois en toutes lettres: et si quelqu'un écrit "Jeanvié" ton programme fait quoi ?
Donc, tu es obligé d'avoir une deuxième liste de mois avec ou sans accents, de tester si le mois entré fait partie de ta liste ou pas et boucler sans fin tant que la réponse est non.
Donc quand il entre le jour, tu es obligé de vérifier qu'il n'a pas été entré 31 pour le mois d'avril par ex ou 29 pour février alors que l'année n'est pas bissextile...
Tu es obligé de vérifier qu'il n'entre pas de lettre(s), de nb décimal, de nb négatif...
Tu as essayé de produire un programme interactif, c'est bien ! Mais tu es loin du compte...

J'ai choisi de faire abstraction de ça (pas le temps, pas envie) et de n'avoir à modifier que le contenu des guillemets de la variable Date.

4. A la ligne 17, tu ne devrai pas plutôt dire: range(1583, an-1)?
Non, la boucle for est un itérateur elle augmente de 1 à chaque tout, sauf si je choisis d'ajouter le paramètre facultatif step :
for i in range(debut, fin, step):
Donc de 1 en 1, ma boucle tourne et arrive à, par exemple,  1910 : là elle constate qu'elle est arrivée à la fin et elle n'exécute pas le tour suivant pour 1910, elle s'est arrêtée à 1909.
Regarde :
for i in range (1907,1910):
     print (i)

affiche :
1907
1908
1909

5. J'ai testé mon programme avec Python 3.3 : j'ai juste modifié les 3 lignes avec print.
Il tourne.
Je viens de tester avec les dates données par nerosson ici :
http://www.bibmath.net/forums/viewtopic … 532#p44532
Je suis en désaccord pour les dates antérieures à 1582...
Du coup, il faudra que je revérifie mes calculs : il peut avoir raison, comme il se peut que ce soit moi.
Mais pas maintenant....

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#21 02-03-2014 19:14:02

nerosson
Membre actif
Inscription : 21-03-2009
Messages : 1 658

Re : [Python] Programme calendrier perpétuel

Salut à tous

@Yoshi

J'ai fait de nombreuse vérifications par confrontation avec le calendrier de Moret. Je serais donc surpris d'être mis en échec

Hors ligne

#22 02-03-2014 19:46:52

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 948

Re : [Python] Programme calendrier perpétuel

Re,

Moi aussi...
Je ne crois pas avoir commis d'erreur de décompte...
Peut-être Moret et toi-même acceptez-vous les années 4 et 8 comme bissextiles ?
Cela dit, lorsque j'en aurais fini avec la rédaction de ma revue, je reprendrai les calculs de la dernière méthode, c'est la plus simple à vérifier. Je les reprendrai, moitié à la main, moitié informatique (pour la partie calcul pur).

Wait and see...

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#23 04-03-2014 08:52:08

Dico
Membre
Inscription : 12-12-2009
Messages : 120

Re : [Python] Programme calendrier perpétuel

Ca s'annonce chaud après la revue interminable.
Yoshi, serais-tu entrain de dire que tes output du post #14 ont changé? Puisque nerosson en était d'accord. En tout cas ça demeure mes réponses.

Bon après-midi!


Bon après-midi!

Hors ligne

#24 04-03-2014 20:01:22

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 948

Re : [Python] Programme calendrier perpétuel

Bonsoir,

J'ai bouclé ma revue et j'ai relu ce que j'avais fait pour le récrire - parfois - autrement mais dans le même esprit...
Ça colle !
Et ça m'épate parce que pour nerosson et Moret l'an 4 et l'an 8 étaient bissextiles. IL devrait donc, avant le 4/10/1582 y avoir 2 jours d'écart... Ce n'est pas le cas.
Je te prépare une version avec demande de date et analyse des erreurs d'entrée potentielles de façon aussi exhaustive que possible et ça, ce "n'est pas de la tarte"...
Le traitement d'erreurs fait partie des domaines les plus délicats de Python.
Jette un œil sur le couple "infernal" 
try:
.....
except:
.......

@+


Arx Tarpeia Capitoli proxima...

Hors ligne

#25 05-03-2014 15:05:09

yoshi
Modo Ferox
Inscription : 20-11-2005
Messages : 16 948

Re : [Python] Programme calendrier perpétuel

bonjour,

Voila je décline le programme en 2 versions :
- courte pour Python 2.6 où l'on rentre à la main sans demande d'entrée de date : on modifie simplement - et correctement la chaîne Date
- étoffée pour Dico avec des contrôles de validité d'entrée(s) : ou dans ce domaine, on essaie d'être exhaustif ou ne le fait pas...
  Je n'ai pas la certitude d'être passé partout, d'avoir tout prévu mais j'ai essayé et je ne pense pas être loin de la vérité...
  J'ai scindé en 4 étapes : avant l'an 12, [12;1582[, l'année 1582, [1583 ; +oo[
  J'ai compté les jours pour arriver à à 577734, puis ai contrôlé avec datetime() moyennant correctif...

Version 2.6 :


#!/usr/bin/env python
# -*- coding: Latin-1 -*-

def NumJourSemaine(Date):
    # 577734  Nombre de jours de reférence entre le 01/01/0001 et le 04/10/1582
    jour,mois,an=int(Date[:2]),int(Date[3:5]),int(Date[6:])
    JoursEcoulesAnnee=[0,31,59,90,120,151,181,212,243,273,304,334]
    if an<1582:
        if an<12:
            nb_ec=(an-1)*365+JoursEcoulesAnnee[mois-1]+jour-1
        else:
            nb_ec=4015+(an-12)*365+JoursEcoulesAnnee[mois-1]+jour+(an-12)//4
        nbj=577734-nb_ec
        numjour=(4-nbj)%7
    elif an==1582:
        if mois <10 or (mois==10 and jour<=4):
            nbj=577734-(JoursEcoulesAnnee[mois-1]+jour-1)
            numjour=(4-nbj)%7
        elif (mois==10 and jour>14)or mois>10:
            nbj=30*(mois==11)+jour-15*(mois==10)          
            numjour=(5+nbj)%7
    else:
        nbj=0
        for j in range(1583,an):
            nbj+=365+((j%4==0 and j%100!=0) or j%400==0)
        nbj+=JoursEcoulesAnnee[mois-1]+jour+(((an%4==0 and an%100!=0) or an%400==0)and mois>2)  
        numjour=(5+nbj)%7  
    return numjour,jour,mois,an
   
Jours = ["Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"]
Mois = ['janvier','février','mars','avril','mai','juin','juillet','août',
      'septembre','octobre','novembre','décembre']

Date="15/08/778"

print "       Le", Date
njs,jour,mois,an=NumJourSemaine(Date)
print "     est en fait le"
print Jours[njs],str(jour)+"er"*(jour==1), Mois[mois-1], an
 

----------------------------------------------------
Suit la version 3.3 avec contrôles : c'est le code Python 2.6 où j'ai remplacé chaque print par print() et ajouté les contrôles : je dois d'ailleurs pouvoir factoriser les tests mieux que cela.
Mentionner code=Python présente l'inconvénient (je vais en parler à Fred) d'ajouter une indentation de 4 caractères sur chaque ligne, après copier/coller, mais c'est plus joli.

La parade avec l'IDLE de Python :
- faire un copier/coller du programme dans une page vierge
- tout sélectionner
- Faire Format --> Dedent region


#!/usr/bin/env python
# -*- coding: Latin-1 -*-

def NumJourSemaine(jour,mois,an):
    # 577734  Nombre de jours de reférence entre le 01/01/0001 et le 04/10/1582
    JoursEcoulesAnnee=[0,31,59,90,120,151,181,212,243,273,304,334]
    if an<1582:
        if an<12:
            nb_ec=(an-1)*365+JoursEcoulesAnnee[mois-1]+jour-1
        else:
            nb_ec=4015+(an-12)*365+JoursEcoulesAnnee[mois-1]+jour+(an-12)//4
        nbj=577734-nb_ec
        numjour=(4-nbj)%7
    elif an==1582:
        if mois <10 or (mois==10 and jour<=4):
            nbj=577734-(JoursEcoulesAnnee[mois-1]+jour-1)
            numjour=(4-nbj)%7
        elif (mois==10 and jour>14)or mois>10:
            nbj=30*(mois==11)+jour-15*(mois==10)          
            numjour=(5+nbj)%7
    else:
        nbj=0
        for j in range(1583,an):
            nbj+=365+((j%4==0 and j%100!=0) or j%400==0)
        nbj+=JoursEcoulesAnnee[mois-1]+jour+(((an%4==0 and an%100!=0) or an%400==0)and mois>2)  
        numjour=(5+nbj)%7  
    return numjour,jour,mois,an

def teste_jours(mois,jour):
    ok=0
    if mois in [4,6,9,11]and jour>30:
        print (mois,"est un mois de 30 jours")
        recommence()
    elif mois in [1,3,5,7,8,10,12] and jour >31:
        print ("Les mois ont 31 jours maximum.")
        recommence()
    else:
        ok=1
    return ok

def recommence():
    print ("Veuillez recommencer s'il vous plaît")
    print()
   
Jours = ["Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"]
Mois = ['janvier','février','mars','avril','mai','juin','juillet','août',
      'septembre','octobre','novembre','décembre']
while 1:
    ok=0
    while not ok:
        ##### Date à écrire impérativement au format jj/mm/aaaa
       
        Date=input("Entrez votre date sous la forme mm/jj/aaaa : ")
   
        ########################################  
        if not (Date[2] == "/" and Date[5]=="/"):          
            print ("Les / ne sont pas au bon endroit ou manquants.")
            recommence()
        else:
            try:
                jour,mois,an=int(Date[:2]),int(Date[3:5]),int(Date[6:])
            except ValueError:
                print ("Entrée incorrecte : des nombres sont attendus.")
                recommence()      
            else:
                if mois<1 or mois>12:
                    print ("N° de mois incorrect.")
                    recommence()
                else:
                    if an<1:
                        print ("Année antérieure à l'an 1.")
                        recommence()
                    elif an>0 and an<12:
                        if mois==2 and jour>28:
                            print ("Pas d'année bissextile de l'an 1 à l'an 11.")
                            recommence()
                        else:
                            ok=teste_jours(mois,an)
                    elif an>12 and an<1582:
                        if jour==29 and (mois==2 and an%4!=0):
                            print ("L'année",an,"n'est pas une année bissextile.")
                            recommence()
                        else:
                            ok=teste_jours(mois,jour)
                    elif an==1582:
                        if jour==29 and (mois==2 and an%4!=0):
                            print("L'année",an,"n'est pas une année bissextile.")
                            recommence()
                        elif mois==10 and (jour>4 and jour<15):
                            print ("Ce jour de l'année 1582 n'a pas existé.")
                            recommence()
                        else:                          
                            ok=teste_jours(mois,jour)
                    else:
                        if jour==29 and (mois==2 and not((an%4==0 and an%100!=0) or an%400==0)):
                            print("L'année",an,"n'est pas une année bissextile.")
                            recommence()
                        else:
                            ok=teste_jours(mois,jour)
    print()
    print ("       Le", Date)
    njs,jour,mois,an=NumJourSemaine(jour,mois,an)
    print ("     est en fait le")
    print (Jours[njs],str(jour)+"er"*(jour==1), Mois[mois-1], an)
    print ()
    while 1:
        rep=input("(S)top ou (E)ncore (Répondre avec e,E,s ou S) ? : ").upper()
        if rep in "ES":
            print ()
            break
        else:
            recommence()
    if rep == "S":
        print()
        print ("Au revoir !")
        break
 

Voilà Dico, tu peux jouer...

@+

[EDIT]
Correction faite en ligne 56 : remplacement de or par and...

Dernière modification par yoshi (05-03-2014 20:43:09)


Arx Tarpeia Capitoli proxima...

Hors ligne

Pied de page des forums