Si certains exercices n'ont pas pu être terminés dans le cadre de cette séance, il est fortement conseillé de les terminer par vous-même chez vous ou en salle libre service.
Le but de ce TP est de poursuivre l'apprentissage de la manipulation des tableaux. Il vous permet également d'être confronté à une démarche d'analyse descendante d'un problème donné (cf. cours).
On représente une date à l'aide d'un tableau de trois entiers correspondant, dans l'ordre d'apparition dans le tableau, au jour, au mois et à l'année. Ainsi, par exemple :
[1, 1, 2014]
;
[20, 10, 2014]
.
Pour rendre plus lisibles les programmes que nous allons écrire dans ce TP, nous allons introduire :
cree_date
qui prend 3 entiers j, m, a
en paramètres et construit un tableau correspondant à la date "j/m/a",
get_jour
qui prend une date (représentée sous la forme d'un tableau) en paramètre et renvoie le jour correspondant à la date (le 1er élément du tableau donc),
get_mois
qui prend une date (représentée sous la forme d'un tableau) en paramètre et renvoie le mois correspondant à la date (le 2ème élément du tableau donc),
get_an
qui prend une date (représentée sous la forme d'un tableau) en paramètre et renvoie l'année correspondant à la date (le dernier élément du tableau donc).
Exemple :
>>> cree_date(20, 10, 2014) [20, 10, 2014] >>> get_jour([20, 10, 2014]) 20 >>> get_mois([20, 10, 2014]) 10 >>> get_an([20, 10, 2014]) 2014
Ecrire les fonctions cree_date, get_jour, get_mois
et get_an
. Vous les utiliserez dans la suite du TP.
Écrire une fonction decale_date
qui prend en paramètres :
date
(c'est-à-dire un tableau de 3 entiers),
n
correspondant à un nombre de jours
et renvoie la date correspondant à une avancée de n jours dans le temps à partir de la date donnée. Par exemple :
Exemple :
>>> decale_date([20, 10, 2014], 7) [27, 10, 2014] >>> decale_date([31, 12, 2014], 1) [1, 1, 2015]
Pour écrire cette fonction, vous supposerez qu'il existe une fonction lendemain
prenant une date en paramètre et renvoyant la date du lendemain. Utilisez-la pour définir decale_date
: cela simplifiera grandement votre travail.
Faites valider ce que vous avez écrit à votre enseignant de TP. Il ne vous sera en effet pas possible, pour le moment, de tester votre fonction puisque la fonction lendemain
n'existe pas encore. C'est l'objectif de la question suivante que de définir lendemain
. Lorsqu'elle sera définie, vous pourrez alors tester decale_date
. Nous laissons de fait de côté, pour le moment, le test de decale_date
et nous passons à la définition de lendemain
.
Écrire une fonction lendemain
qui prend une date en paramètre et renvoie la date du lendemain.
Exemple :
>>> lendemain([20, 10, 2014]) [21, 10, 2014] >>> lendemain([31, 12, 2014]) [1, 1, 2015] >>> lendemain([31, 10, 2014]) [1, 11, 2014] >>> lendemain([29, 2, 2012]) [1, 3, 2012]
Nous allons ici aussi introduire des fonctions qui vont nous "faciliter la vie" pour définir lendemain
. Dans le cadre d'une démarche d'analyse descendante, il faudrait supposer l'existence de ces fonctions, les utiliser pour écrire lendemain
, les définir ensuite. L'inconvénient est qu'il n'est pas possible de tester tant que toutes les fonctions ne sont pas définies. Nous allons donc procéder "à l'envers". Laissons de côté pour le moment l'écriture de la fonction lendemain
. Nous y reviendrons lorsque les fonctions ci-dessous auront été définies.
Écrire une fonction fin_d_annee
qui prend une date en paramètre et teste si cette date correspond à la fin de l'année (c'est-à-dire au 31 décembre).
Ecrire une fonction fin_de_mois
qui prend une date en paramètre et teste si cette date correspond à une fin de mois.
Exemple :
>>>fin_de_mois([20, 10, 2014]) False >>> fin_de_mois([31, 12, 2014]) True >>> fin_de_mois([31, 10, 2014]) True >>> fin_de_mois([28, 2, 2012]) False >>> fin_de_mois([29, 2, 2012]) True
Pour écrire cette fonction, il faut au préalable définir les fonctions est_bissextile
et nb_jours_ds_mois
.
La fonction est_bissextile
prend en paramètre un entier correspondant à une année et teste si cette année est bissextile. Cette fonction est utilisée dans la définition de nb_jours_ds_mois
(cf. ci-dessous). Il est de fait nécessaire de la définir au préalable. Pour rappel, une année A est bissextile si A est multiple de 4, mais pas de 100, ou multiple de 400.
Exemple :
>>> est_bissextile(2014) False >>> est_bissextile(2012) True >>> est_bissextile(2000) True >>> est_bissextile(1900) False
La fonction nb_jours_ds_mois
prend en paramètres :
- un entiermois
correspondant à un numéro de mois - un entierannee
correspondant à un numéro d'année -
et renvoie le nombre de jours dans un mois donné, étant donné une année donnée. Le paramètre année
est nécessaire du fait des années bissextiles : février n'a en effet pas le même nombre de jours selon que l'année est bissextile ou pas.
Exemple :
>>> nb_jours_ds_mois(5, 2014) 31 >>> nb_jours_ds_mois(2, 2012) 29 >>> nb_jours_ds_mois(2, 2014) 28
La fonction nb_jours_ds_mois
est celle que vous avez écrite dans le CC1. Il s'agissait du dernier exercice.
Nous avions laissé de côté l'écriture de la fonction lendemain
car il fallait au préalable en définir d'autres (fin_de_mois
, fin_d_annee
, etc.). Ces fonctions sont maintenant définies : il est possible de les utiliser ppur écrire lendemain
.
lendemain
en utilisant les fonctions définies dans ce qui précède.
Nous avions laissé de côté le test de la fonction decale_date
car il fallait au préalable définir lendemain
. C'est maintenant chose faite; il est de fait possible de tester decale_date
.
Tester la fonction decale_date
en prenant des exemples de dates pertinents.
- Maman, c'était quel jour quand je suis né ? - Ououououh... je ne me rappelle plus bien. Il me semble que c''était un lundi... mais peut-être un samedi aussi. J''hésite... Demande donc à ton père. - ... - Papa, tu sais quel jour c'était quand je suis né ? - C'était un mercredi ! Je suis sûr, parce que ce jour-là, ta mère ... blablabla, blablabla...
Vous voilà bien avancé : ni Maman, ni Papa ne se souviennent exactement. Et cette question fondamentale va vous hanter pendant tout le reste de votre existence. Et si vous épatiez Papa et Maman en leur apportant vous-même la réponse ? Et si, non content de cela, vous leur donniez, en plus, le jour de leur propre naissance ? Quelle gloire ce serait pour vous ! C'est ce que nous vous proposons de faire dans cette partie en travaillant sur la notion de calendrier perpétuel
.
Un calendrier perpétuel (voir Wikipedia) est un calendrier qui donne le jour de la semaine (lundi, mardi, mercredi, ...) correspondant à une date donnée. Nous allons, dans cette partie, écrire une fonction calendrier_perpetuel
prenant une date en paramètre et renvoyant une chaîne de caractères correspondant au jour de la semaine de cette date. Nous ne traiterons que les dates appartenant au calendrier grégorien, c'est-à-dire à partir du 20 décembre 1582 en France.
Exemple :
>>> calendrier_perpetuel([20, 10, 2014]) "lundi" >>> calendrier_perpetuel([8, 10, 2003]) "mercredi" >>> calendrier_perpetuel([1, 6, 2014]) "dimanche" >>> calendrier_perpetuel([7, 1, 1994]) "vendredi"
C'est M. Moret qui a proposé ce calendrier. Il est composé, dans sa version initiale, de 3 tableaux dans lesquels il faut aller chercher des chiffres en fonction de la date en entrée et faire ensuite des calculs sur ces chiffres. Une version simplifiée a été proposée. Elle consiste à attribuer :
et à faire leur somme. Tous ces nombres sont définis modulo 7 (ex : 5 est équivalent à 12, 19, 26, ...). Le résultat de l'addition, modulo 7 lui aussi, est un nombre compris entre 0 et 6, qui donne le jour de la semaine selon la correspondance suivante :
Nous allons définir, dans ce qui suit, des fonctions permettant de calculer les nombres séculaire, annuel, mensuel et le quantième d'une date donnée. Nous les utiliserons pour définir la fonction calendrier_perpetuel
.
Le « nombre séculaire » est le même pour toutes les années commençant par les deux mêmes chiffres. Par exemple, toutes les années du 21ème siècle (années 2001 à 2099) auront un nombre séculaire égal à 0. C'est également le cas de l'année 2000.
Le tableau suivant donne les nombres séculaires pour chaque siècle :
Il est à noter que ce nombre diminue de deux unités chaque siècle (modulo 7) sauf lorsque les deux premiers chiffres sont un multiple de 4 (1600 à 1699, 2000 à 2099).
Ecrire une fonction nombre_seculaire
qui prend une année en paramètre et renvoie le nombre séculaire associé à cette année.
Exemple :
>>> nombre_seculaire(2014) 0 >>> nombre_seculaire(1996) 1
Vous pourrez introduire des fonctions intermédiaires pour écrire cette fonction, par exemple la fonction siecle
qui prend en paramètre une année A
et renvoie le nombre correspondant au siècle de A
.
Exemple :
>>> siecle(2014) 20 >>> siecle(1996) 19 >>> siecle(1900) 19
La ligne ci-dessous mentionne les années pour lesquelles le nombre annuel est égal à 0. À partir de ces années, le nombre annuel augmente d'une unité chaque année et de deux si l'année est bissextile.
Années dont le nombre annuel est 0 :
..04 ..10 ..21 ..27 ..32 ..38 ..49 ..55 ..60 ..66 ..77 ..83 ..88 ..94
Exemple :
On peut aussi remarquer que le résultat est donné par la formule suivante :
an
, on calcule la division entière de an
par 4 : on obtient un nombre divid
;
(a + divid - 5)
par 7
.
Exemple pour l'année 2010 :
Exemple pour l'année 2016 :
Ecrire une fonction nombre_annuel
qui prend une année en paramètre et renvoie le nombre annuel associé à cette année.
Exemple :
>>> nombre_annuel(2010) 0 >>> nombre_annuel(2016) 1
Vous pourrez introduire des fonctions intermédiaires pour écrire cette fonction, par exemple la fonction an
qui prend en paramètre une année A
et renvoie le nombre correspondant aux 2 derniers chiffres de A
.
Exemple :
>>> an(2014) 14 >>> an(1996) 96 >>> an(1900) 0
Le tableau suivant donne le nombre mensuel pour chaque mois de l'année (cf. Nombre mensuel sur Wikipedia):
Exemple : le mois de janvier a un nombre mensuel de 4 en 1995 et de 3 en 1996 (année bissextile).
Ecrire une fonction nombre_mensuel
qui prend en paramètres :
mois
correspondant à un numéro de mois,
annee
correspondant à une année
et qui renvoie le nombre mensuel associé à ces données.
Exemple :
>>> nombre_mensuel(1, 1995) 4 >>> nombre_mensuel(1, 1996) 3
Le quantième correspond au jour d'une date donnée. Ainsi par exemple :
Ecrire une fonction quantième qui prend une date en paramètre et renvoie le quantième de la date donnée.
Ecrire la fonction calendrier_perpetuel
qui prend une date en paramètre et renvoie une chaîne de caractères correspondant au jour de la semaine de la date donnée. Vous utiliserez pour cela les fonctions nombre_seculaire
, nombre_annuel
, nombre_mensuel
et quantieme
que vous venez d'écrire.
Il vous faut revenir au début de cette partie pour relire les explications sur le calendrier perpétuel et la manière de calculer le jour de la semaine en utilisant les 4 fonctions définies ci-dessus, ainsi que le tableau de correspondance entre un numéro et un jour de la semaine.
Les vendredis 13 ont toujours hanté l'imaginaire collectif. Pour certains, c'est une date maudite et il convient de rester confiné à la maison ce jour-là si l'on ne veut pas prendre le ciel sur la tête. Pour d'autres, c'est une date porte-bonheur.
Ecrire la fonction vendredi_13
qui prend en paramètres :
annee_initiale
correspondant à une année
annee_finale
correspondant à une année
et calcule le nombre de vendredis 13 qu'il y a entre le 1er janvier de l'année initiale et le 1er janvier de l'année finale. Vous introduirez au préalable une fonction nb_jours
permettant de compter le nombre de jours entre ces 2 dates (vous en aurez besoin pour écrire vendredi_13
Pour rappel, une année comporte 365 jours si elle n'est pas bissextile, 366 sinon.
Exemple :
>>> vendredi_13(2014, 2015) 1 >>> vendredi_13(2010, 2014) 7 >>> vendredi_13(2009, 2010) 3
Utilisez cette fonction pour compter le nombre de vendredis 13 entre 1600 et 2000. Que remarquez-vous ?