Ajout des TP faits jusque là.

Ajout des TP 2 et 3.
This commit is contained in:
Geoffrey Frogeye 2014-10-07 19:32:31 +02:00
parent 4ae3dfa87f
commit 798f58ba8f
8 changed files with 869 additions and 0 deletions

4
.gitignore vendored
View file

@ -52,3 +52,7 @@ docs/_build/
# PyBuilder
target/
# Custom
*/sujet/*
*.zip

View file

@ -0,0 +1,66 @@
# PREUD'HOMME BONTOUX Geoffrey - PeiP 12 - 2014/2015
# TP n°2 donné le 19/09/2014 - Conversion Celsius ↔ Fahrenheit
# http://www.fil.univ-lille1.fr/~wegrzyno/portail/Info/Doc/HTML/tp_donnees_expressions.html
# Q1
C = 20
# Q2
F = 9/5*C+32
# Q3
print("Une température de", C, "°C correspond à une température de", F, "F.")
# Q4
F2 = 75
C2 = 5/9*(F2-32)
print("Une température de", F2, "F correspond à une température de", C2, "°C.")
# Q5
def celsius_en_fahrenheit(celsius):
"""
Convertit une température en degrés Celsius en degrés Fahrenheit.
CU : celsius numérique
Exemple :
>>> celsius_en_fahrenheit(20)
68.0
"""
return 9/5*celsius+32
help(celsius_en_fahrenheit)
print("Q5", "Une température de 21 °C correspond à une température de", \
celsius_en_fahrenheit(21), "F.")
print("Q5", "Une température de 34 °C correspond à une température de", \
celsius_en_fahrenheit(34), "F.")
print("Q5", "Une température de 55 °C correspond à une température de", \
celsius_en_fahrenheit(55), "F.")
# Q6
def fahrenheit_en_celsius(fahrenheit):
"""
Convertit une température en degrés Fahrenheit en degrés Celsius.
CU : fahrenheit numérique
Exemple :
>>> fahrenheit_en_celsius(75)
23.88888888888889
"""
return 5/9*(fahrenheit-32)
# Q7
# On fait une composition de fonction (au moins deux fois pour vérifier les
# deux sens) avec un nombre choisi arbitrairement
nombreTest = 42
test = celsius_en_fahrenheit( \
fahrenheit_en_celsius( \
celsius_en_fahrenheit( \
fahrenheit_en_celsius(nombreTest)))) == nombreTest
print("Q7", "Le test sur la réciprocité des fonctions a retourné :", test)

View file

@ -0,0 +1,65 @@
# PREUD'HOMME BONTOUX Geoffrey - PeiP 12 - 2014/2015
# TP n°2 donné le 19/09/2014 - Début du developpement en fraction continue dun
# réel
# http://www.fil.univ-lille1.fr/~wegrzyno/portail/Info/Doc/HTML/tp_donnees_expressions.html
# Q1
from math import floor
# Q2
def afficher_debut(x):
"""
Réalise le début du développement en fraction continue dun nombre et
affiche les parties entières calculées.
CU : x numérique
Exemple :
>>> afficher_debut(3.14159265359)
a0 = 3
a1 = 7
a2 = 15
"""
# Calcul des valeurs
a0 = floor(x)
y = (x - a0) ** -1
a1 = floor(y)
z = (y - a1) ** -1
a2 = floor(z)
# Affichage des valeurs
print("a0 = ", a0)
print("a1 = ", a1)
print("a2 = ", a2)
# Q3
from math import pi
# Q4
afficher_debut(pi)
def afficher_debut_bis(x):
"""
Réalise le début du développement en fraction continue dun nombre et
affiche une approximation de ce nombre sous la forme d'une fraction
continue.
CU : x numérique
Exemple :
>>> afficher_debut_bis(3.14159265359)
3 + 1 / (7 + 1 / 15)
"""
# Calcul des valeurs
a0 = floor(x)
y = (x - a0) ** -1
a1 = floor(y)
z = (y - a1) ** -1
a2 = floor(z)
# Affichage des valeurs
print(str(a0) + " + 1 / (" + str(a1) + " + 1 / " + str(a2) + ")")
afficher_debut_bis(pi)

View file

@ -0,0 +1,50 @@
# PREUD'HOMME BONTOUX Geoffrey - PeiP 12 - 2014/2015
# TP n°2 donné le 19/09/2014 - Taille d'un entier en base 10
# http://www.fil.univ-lille1.fr/~wegrzyno/portail/Info/Doc/HTML/tp_donnees_expressions.html
# Q1
from math import log10
# Q2
from math import floor
print("Q2", "floor(3.14159265359) retourne", floor(3.14159265359))
# Q3
def taille(entier):
"""
Calcule la taille décimale dun entier positif.
CU : entier int 0
Exemple :
>>> taille(2014)
4
"""
return floor(log10(entier)) + 1
# Q4
print("Q4", "taille(2**100) retourne", taille(2**100))
# Q5
# Le code qui suit a été éxecuté dans l'interpréteur puis inseré ici en tant
# que commentaire pour garder le fichier valide car il provoque des erreurs
# >>> taille(-2014)
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# File "<stdin>", line 12, in taille
# ValueError: math domain error
# Lors de l'éxecution de ce script, Python détecte une erreur. Il affiche donc
# dans la console la liste des fonctions appelées en dernier afin de nous aider
# à voir d'où vient l'erreur. Ici, cette dernière vient de la fonction taille(),
# plus précisément de la ligne contenant l'instruction suivante :
# ```return floor(log10(entier)) + 1```
# Le texte de l'erreur est le suivant : "ValueError: math domain error". Cela
# signifie qu'une fonction a été appelée avec un argument en dehors de son
# domaine de définition. La fonction en question est log10 (nous pouvons le
# vérifier en tapant dans l'interpréteur ```log10(-2014)```, qui est une étape
# de la fonction taille(), ce qui affiche la même erreur), qui est définie
# pour tout réel strictement positif. Or, -2014 n'en est pas un, ce qui
# déclenche l'erreur.

View file

@ -0,0 +1,122 @@
# PREUD'HOMME BONTOUX Geoffrey - PeiP 12 - 2014/2015
# TP n°2 donné le 19/09/2014 - Votre âge en secondes
# http://www.fil.univ-lille1.fr/~wegrzyno/portail/Info/Doc/HTML/tp_donnees_expressions.html
# Q1
ref_an = 1900
ref_mois = 1
ref_jour = 1
# Q2
nbre_sec_jour = 24 * 60 * 60
# Q3
nbre_sec_an = 365.2425 * nbre_sec_jour
# Q4
nbre_sec_mois = nbre_sec_an / 12
# Q5
aujourdhui_jour = 19
aujourdhui_mois = 9
aujourdhui_an = 2014
# Q6
nbre_an_entre_1900_et_aujourdhui = aujourdhui_an - ref_an
nbre_mois_entre_1900_et_aujourdhui = aujourdhui_mois - ref_mois
nbre_jour_entre_1900_et_aujourdhui = aujourdhui_jour - ref_jour
nbre_sec_entre_1900_et_aujourdhui = \
nbre_an_entre_1900_et_aujourdhui * nbre_sec_an \
+ nbre_mois_entre_1900_et_aujourdhui * nbre_sec_mois \
+ nbre_jour_entre_1900_et_aujourdhui * nbre_sec_jour
print("Q6", "Secondes entre la date de référence et aujourdhui :", \
nbre_sec_entre_1900_et_aujourdhui)
# Q7
naissance_jour = 14
naissance_mois = 2
naissance_an = 1997
nbre_an_entre_1900_et_naissance = naissance_an - ref_an
nbre_mois_entre_1900_et_naissance = naissance_mois - ref_mois
nbre_jour_entre_1900_et_naissance = naissance_jour - ref_jour
nbre_sec_entre_1900_et_naissance = \
nbre_an_entre_1900_et_naissance * nbre_sec_an \
+ nbre_mois_entre_1900_et_naissance * nbre_sec_mois \
+ nbre_jour_entre_1900_et_naissance * nbre_sec_jour
# Q8
mon_age_en_secondes = \
nbre_sec_entre_1900_et_aujourdhui - nbre_sec_entre_1900_et_naissance
print("Q8", "Mon âge en secondes :", mon_age_en_secondes)
# Q9
def nbre_sec_depuis_1900(jour, mois, an):
"""
Calcule le nombre approximatif de secondes écoulées entre la date de
référence (le 1er janvier 1900) à 0h00 et la date passée en paramètre
CU : jour entier ; 1 jour 31 ; mois entier ; 1 mois 12 ;
an entier ; an 1900 ; la date doit avant aujourd'hui
Exemple :
>>> nbre_sec_depuis_1900(14, 2, 1997)
3064777290.0
"""
nbre_jour_entre_1900_et_date = jour - ref_jour
nbre_mois_entre_1900_et_date = mois - ref_mois
nbre_an_entre_1900_et_date = an - ref_an
nbre_sec_entre_1900_et_date = \
nbre_an_entre_1900_et_date * nbre_sec_an \
+ nbre_mois_entre_1900_et_date * nbre_sec_mois \
+ nbre_jour_entre_1900_et_date * nbre_sec_jour
return nbre_sec_entre_1900_et_date
# Q10
mon_age_en_secondes = \
nbre_sec_depuis_1900(aujourdhui_jour, aujourdhui_mois, aujourdhui_an) \
- nbre_sec_depuis_1900(naissance_jour, naissance_mois, naissance_an)
print("Q10", "Mon âge en secondes (via nbre_sec_depuis_1900) :", \
mon_age_en_secondes)
# Q11
from datetime import *
aujourdhui = date.today()
aujourdhui_jour = aujourdhui.day
aujourdhui_mois = aujourdhui.month
aujourdhui_an = aujourdhui.year
mon_age_en_secondes = \
nbre_sec_depuis_1900(aujourdhui_jour, aujourdhui_mois, aujourdhui_an) \
- nbre_sec_depuis_1900(naissance_jour, naissance_mois, naissance_an)
print("Q11", "Mon âge en secondes (via datetime) :", \
mon_age_en_secondes)
# Q12
def age_en_secondes(jour, mois, an):
"""
Calcule le nombre approximatif de secondes écoulées depuis la date passée
en paramètre.
CU : jour entier ; 1 jour 31 ; mois entier ; 1 mois 12 ;
an entier ; an 1900 ; la date doit avant aujourd'hui
Exemple (si nous sommes le 19/09/2014) :
>>> age_en_secondes(14, 2, 1997)
555308406.0
"""
ajd = date.today()
return nbre_sec_depuis_1900(ajd.day, ajd.month, ajd.year) \
- nbre_sec_depuis_1900(jour, mois, an)
mon_age_en_secondes = \
age_en_secondes(naissance_jour, naissance_mois, naissance_an)
print("Q12", "Mon âge en secondes (via age_en_secondes) :", \
mon_age_en_secondes)

8
S1/TP 3/Statistiques.md Normal file
View file

@ -0,0 +1,8 @@
#Statistiques sur le fichier date.py
##Brut :
**Caractères :** 14525
**Lignes :** 419
##Commentaires :
**Caractrès :** 9881 (68%)
**Lignes :** 243 (57%)

View file

@ -0,0 +1,136 @@
# Fonctions nécessaires au fonctionnement de afficher_calendrier()
def est_divisible_par(a, b):
return a % b == 0
def est_bissextile(annee):
return est_divisible_par(annee, 4) and \
(not est_divisible_par(annee, 100) or est_divisible_par(annee, 400))
def nbre_jours(m, a):
assert(type(m) is int and m in range(1, 13)), \
"Le mois doit être un entier compris entre 1 et 12 inclus."
assert(type(a) is int and a > 1582), \
"L'année doit être un entier supérieur à 1582."
if m in [4, 6, 9, 11]:
return 30
elif m == 2:
if est_bissextile(a):
return 29
else:
return 28
else:
return 31
def est_date_valide(j, m, a):
return type(j) is int and type(m) is int and type(a) is int and a > 1582 \
and m in range(1, 13) and j in range(1, nbre_jours(m, a)+1)
def corrige_mois(m, a):
assert(type(a) is int and a > 1582), \
"L'année doit être un entier supérieur à 1582"
assert(type(m) is int and m in range(1, 13)), \
"Le mois doit être un entier compris entre 1 et 12 inclus"
liste_corrections_mois = [4, 0, 0, 3, 5, 1, 3, 6, 2, 4, 0, 2]
if est_bissextile(a):
liste_corrections_mois[0] = 3
liste_corrections_mois[1] = 6
return liste_corrections_mois[m-1]
def num_jour(j, m, a):
assert(est_date_valide(j, m, a)), "La date n'est pas valide"
ab = a//100
cd = a%100
return (cd//4 + ab//4 + cd + corrige_mois(m, a) + j + 2 + 5 * ab) % 7
# REGARDER À PARTIR D'ICI
# Voici une fonction qui affiche un calendier approximatif,
# sois sûre de la comprendre avant de t'attaquer au complet
def imprimer_mois_simple(m, a):
# Première ligne
print("Mois", m, " Année", a)
# Deuxième ligne
print("di lu ma me je ve sa")
# Nombres
jour = 1
nbre_jours_mois = nbre_jours(m, a)
while jour <= nbre_jours_mois: # On parcourt les lignes
ligne = ["", "", "", "", "", "", ""] # On remet à zéro la liste des nombres sur la ligne
for jour_semaine in range(7): # On parcours les colonnes de la ligne
ligne[jour_semaine] = jour # On met le jour
jour += 1 # On augumente jour pour le prochain
print(ligne[0], ligne[1], ligne[2], ligne[3], ligne[4], ligne[5], \
ligne[6]) # On affiche la ligne
# Démonstration
print("Calendrier simple (et faux)")
imprimer_mois_simple(9, 2014)
# Voici la fonction complète, qui affichera un calendrier complet,
# et possède tous les attributs d'une fonction
def imprimer_mois(m, a):
"""
Imprime le calendrier du mois de l'année donné.
CU : m entier, a entier, 1 m 12, a > 1582
Exemple :
>>> imprimer_mois(9, 2014)
Septembre 2014
di lu ma me je ve sa
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
"""
assert(type(a) is int and a > 1582), \
"L'année doit être un entier supérieur à 1582"
assert(type(m) is int and m in range(1, 13)), \
"Le mois doit être un entier compris entre 1 et 12 inclus"
# On stocke les mois dans un tableau pour pouvoir y accéder facilement
liste_mois = ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", \
"Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"]
# Première ligne
print(liste_mois[m-1], a)
# Deuxième ligne
print("di lu ma me je ve sa")
# Nombres
jour = 1
jour_semaine_1er = num_jour(jour, m, a)
nbre_jours_mois = nbre_jours(m, a)
while jour <= nbre_jours_mois: # On parcourt les lignes
ligne = ["", "", "", "", "", "", ""] # On remet à zéro la liste des nombres sur la ligne
for jour_semaine in range(7): # On parcours les colonnes de la ligne
if jour == 1 and jour_semaine < jour_semaine_1er: # Si on est avant
# le premier jour du mois
ligne[jour_semaine] = " " # On met un espace
elif jour <= nbre_jours_mois: # Si on est avant la fin du mois
ligne[jour_semaine] = jour # On met le jour
jour += 1 # On augumente jour pour le prochain
print(ligne[0], ligne[1], ligne[2], ligne[3], ligne[4], ligne[5], \
ligne[6]) # On affiche la ligne
# Test
print("")
print("Calendrier complet")
imprimer_mois(9, 2014)
# Comme tu as pu le remarquer, les nombres <10 font un décalage
# J'ai pas trouvé comment résoudre ça sans utiliser des trucs qu'on
# a pas vu en cours.

418
S1/TP 3/date.py Normal file
View file

@ -0,0 +1,418 @@
# PREUD'HOMME BONTOUX Geoffrey - PeiP 12 - 2014/2015
# TP n°3 donné le 26/09/2014 - Autour du calendrier
# http://www.fil.univ-lille1.fr/~wegrzyno/portail/Info/Doc/HTML/tp_conditionnelle.html
# [Q] Programmez une fonction nommée est_divisible_par
def est_divisible_par(a, b):
"""
Indique si a est divisible par b.
CU : a entier, b entier
Exemple :
>>> est_divisible_par(2016, 4)
True
"""
# Si a est divisible par b, alors le reste de la division Euclidienne doit
# être nul
return a % b == 0
# [Tests]
# >>> est_divisible_par(1337, 7)
# True
# >>> est_divisible_par(997, 3)
# False
# [Q] Programmez une fonction nommée est_bissextile
def est_bissextile(annee):
"""
Indique si l'année a donnée est bissextile.
CU : annee entier > 1582
Exemple :
>>> est_bissextile(2016)
True
"""
# Transcription des données du sujet du TP en langage Python
# L'ordre des opérations [(A⋀B)C] ou [A⋀(BC)] est indifférent ici
return est_divisible_par(annee, 4) and \
(not est_divisible_par(annee, 100) or est_divisible_par(annee, 400))
# [Tests]
# >>> est_bissextile(2014)
# False
# >>> est_bissextile(2016)
# True
# >>> est_bissextile(2100)
# False
# >>> est_bissextile(2000)
# True
# [Q] Programmez une fonction nommée nbre_jours
def nbre_jours(m, a):
"""
Renvoie le nombre de jours contenus dans un mois m dune année a donné.
CU : m entier, a entier, 1 m 12, a > 1582
Exemple :
>>> nbre_jours(5, 1968)
31
"""
# [Q] Complétez votre fonction nbre_jours avec assert()
assert(type(m) is int and m in range(1, 13)), \
"Le mois doit être un entier compris entre 1 et 12 inclus."
assert(type(a) is int and a > 1582), \
"L'année doit être un entier supérieur à 1582."
# [/Q]
if m in [4, 6, 9, 11]: # Si le mois fait partie de ceux à 30 jours
return 30
elif m == 2: # Sinon, si le mois est février
if est_bissextile(a): # Si l'année est bissextile
return 29
else:
return 28
else: # Si les conditions ci-dessus ne sont pas vérifiées, c'est forcément
# un mois de 31 jours
return 31
# [Q] Testez votre fonction pour tous les mois de lannée 2014 et le mois
# de février 2016
test = "Test nbre_jours() : " # On crée une variable pour imprimer
# une seule ligne
for test_mois in range(1, 13): # On teste pour tous les mois de 2014
test += str(nbre_jours(test_mois, 2014)) + ", "
test += str(nbre_jours(2, 2016))
print(test) # Enfin, on affiche
# Test nbre_jours() : 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 29
# [Q] Que donne votre fonction avec un mois m=-1 ? Est-ce normal ?
# >>> nbre_jours(-1, 2014)
# 31
# On constate que la fonction retourne une valeur qui aurait pu être associée
# à certains mois valides. Le fait que la fonction retourne une valeur et ne
# déclenche pas une erreur d'elle-même est normal, car à aucun moment la
# validité des données (telles que définies dans les CU) passées en paramètres
# n'est vérifiée. Il aurait d'ailleurs été tout à fait possible que la fonction
# déclenche une erreur à cause d'une sous-fonction/procédure ne supportant pas
# qu'on lui passe certaines données interdites.
# La valeur retournée est 31, car la fonction est constituée d'une série
# d'instructions conditionelles. Dès lors qu'aucune des conditions n'est
# vérifiée, (m=-1 n'appartient pas aux mois à 30 jours ni au mois de février),
# il sera executé l'instruction "par défaut" du else, c'est à dire retourner la
# valeur 31.
# [Q] Quelle condition dutilisation faut-il envisager normalement pour
# cette fonction ?
# Il faut vérifier les valeurs passées en argument, afin de produire une erreur
# si ces dernières ne sont conformes au CU.
# De cette manière, le script s'arrêtera, et affichera un texte d'erreur
# décrivant le problème. L'avantage de faire cela au lieu de ne rien
# vérifier, est que le problème sera tout de suite montré au développeur
# utilisant la fonction, de cette manière cette dernière ne continuera pas en
# renvoiant une valeur fausse, qui faussera la partie du programme se basant
# sur celle-ci. Cette pratique permet donc d'économiser du temps de débogage.
# [Q] Quelle condition dutilisation faut-il envisager normalement pour
# cette fonction ?
# Il faut vérifier que le mois et l'année soient entier, que le mois soit
# valide, c'est à dire compris entre 1 et 12 inclus, et que la date
# soit supérieure au 15 octobre 1582 (nous arrondirerons à l'année, bien qu'il
# soit possible de vérifier si la date fournie est supérieure à la date de
# début du calendrier grégorien au jours près, il n'est pas nécessaire de
# rajouter de tels calculs en supplément pour un cas de figure qui ne sera
# probablement jamais rencontré dans le cadre de ce TP).
# [Q] Tapez les instructions.
# >>> a = 1
# >>> assert(a != 0), "a doit être différent de 0"
# Aucun message ne s'est affiché, ni aucune erreur ne s'est produite.
# a est bien différent de 0 comme le veut la chaîne de caractère, et cette
# condition est vérifiée à l'interieur de l'instruciton assert()
# >>> a = 0
# >>> assert (a != 0), "a doit être différent de 0"
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# AssertionError: a doit être différent de 0
# Un message d'erreur ayant pour message "AssertionError: a doit être différent
# de 0" pour est affiché. a n'est pas différent de 0, la condition dans
# l'instruction assert() n'est pas vérifiée.
# Nous pouvons en déduire que assert() vérifie que le test qui lui est
# donné est vrai (c'est donc un booléen), et sinon produit une erreur
# avec pour message le texte qui lui est apposé. Cette instruction pourra être
# utilisée pour vérifier les CU d'une fonction/procédure.
# [Q] Complétez votre fonction nbre_jours avec cette instruction
# Voir nbre_jours(), le code ajouté pour cette question a été encadré.
# Une assertion pour l'année a été ajoutée pour garder une cohérence
# avec les CU.
# [Q] Trouvez différents cas de non validité dun triplet dentiers pour
# représenter une date.
# Une date peut être invalide si son numéro de jour est inférieure strictement
# à 1 ou supérieur strictement au nombre de jours que peut comporter ce mois,
# ou bien si son numéro de mois est inférieur strictement à 1 ou supérieur
# strictement à 12. On considèrera comme invalide une date inférieure à 1582,
# car il est préférable de renvoyer une erreur indiquant que le programme ne
# gère pas les dates hors du calendrier grégorien plutôt que de renvoyer une
# valeur faussée, ce qui pourrait mener à d'éventuelles complications.
# Exemples : (-14, 7, 1789), (29, 2, 1997), (31, 6, 2014), (28, 120, 1969)
# [Q] Programmez une fonction nommée est_date_valide
def est_date_valide(j, m, a):
"""
Indique si la date donnée appartient au calendrier grégorien.
CU : -aucune-
Exemple :
>>> est_date_valide(25, 4, 1983)
True
"""
# Il n'est pas nécessaire de fournir de CU donc ne pas écrire d'instruction
# assert() car c'est le but même de la fonction.
# On vérifie les types en premier pour éviter de faire fonctionner les
# opérateurs sur d'éventuels types ne les supportant pas.
# La vérification du jour, donc l'appel de nbre_jours() est fait en dernier
# car cette dernière fonction nécessite que le mois et l'année soient
# valides.
return type(j) is int and type(m) is int and type(a) is int and a > 1582 \
and m in range(1, 13) and j in range(1, nbre_jours(m, a)+1)
# [Tests]
# >>> est_date_valide(25, 4, 1983)
# True
# >>> est_date_valide(-14, 7, 1789)
# False
# >>> est_date_valide(29, 2, 1997)
# False
# >>> est_date_valide(31, 6, 2014)
# False
# >>> est_date_valide(28, 120, 1969)
# False
# [Q] Le 15/09/2014 est un lundi. Donc, pour cette date, le numéro à
# calculer doit être 1. Vérifiez ce point.
# Un rapide et simple calcul à l'aide du prompt de Python nous permet de le
# vérifier. On est alors sûr de la syntaxe à utiliser pour num_jour().
# >>> (2014%100//4 + 2014//100//4 + 2014%100 + 2 + 15 + 2 + 5 * 2014//100) % 7
# 1
# [Q] Programmez une fonction nommée corrige_mois
def corrige_mois(m, a):
"""
Renvoie la valeur corrigée du mois selon lalgorithme de Delambre.
CU : m entier, a entier, 1 m 12, a > 1582
Exemple :
>>> corrige_mois(2, 2016)
6
"""
assert(type(a) is int and a > 1582), \
"L'année doit être un entier supérieur à 1582"
assert(type(m) is int and m in range(1, 13)), \
"Le mois doit être un entier compris entre 1 et 12 inclus"
# On crée un tableau de valeurs pour un accès facile aux données
liste_corrections_mois = [4, 0, 0, 3, 5, 1, 3, 6, 2, 4, 0, 2]
# Si l'année est bissextile, on y modifie uniquement les valeurs nécessaires
if est_bissextile(a):
liste_corrections_mois[0] = 3
liste_corrections_mois[1] = 6
# On prend dans le tableau la valeur qu'il faut
# On enlève 1 à l'index du tableau, car les mois comment à 1
# alors que le tableau commence lui à 0
return liste_corrections_mois[m-1]
# [Tests]
# >>> corrige_mois(2, 2016)
# 6
# >>> corrige_mois(9, 2014)
# 2
# [Q] Programmez une fonction nommée num_jour, paramétrée par trois
# entiers représentant une date supposée valide, qui renvoie le numéro du jour
# dans la semaine correspondant à cette date.
def num_jour(j, m, a):
"""
Renvoie le numéro du jour dans la semaine correspondant à la date donnée.
CU : Date valide (selon est_date_valide())
Exemple :
>>> num_jour(9, 11, 2004)
2
"""
# On peut utiliser le prélicat est_date_valide() précédemment écrite
# ce qui nous permet de nous libérer d'instructions assert() et de CU
assert(est_date_valide(j, m, a)), "La date n'est pas valide"
# On stocke les valeurs utilisées plusieurs fois dans des variables pour
# éviter de refaire deux fois le même calcul
ab = a//100
cd = a%100
return (cd//4 + ab//4 + cd + corrige_mois(m, a) + j + 2 + 5 * ab) % 7
# [Tests]
# >>> num_jour(9, 11, 2004)
# 2
# >>> num_jour(24, 10, 1929)
# 4
# [Q] Programmez une fonction nommée nom_jour
def nom_jour(j, m, a):
"""
Renvoie le nom du jour dans la semaine correspondant à la date donnée.
CU : Date valide (selon est_date_valide())
Exemple :
>>> nom_jour(24, 10, 1929)
"Jeudi"
"""
assert(est_date_valide(j, m, a)), "La date n'est pas valide"
num = num_jour(j, m, a)
# Au cas où la fonction num_jour() viendrait à dysfonctionner
assert(num in range(7)), "Jour de la semaine inconnu"
# On stocke les jours dans un tableau pour un accès facilité
liste_jours_semaine = ["Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", \
"Vendredi", "Samedi"]
return liste_jours_semaine[num]
# [Tests]
# >>> nom_jour(24, 10, 1929)
# 'Jeudi'
# >>> nom_jour(9, 11, 2004)
# 'Mardi'
# [Q] Programmez une procédure imprimer_mois
def imprimer_mois(m, a):
"""
Imprime le calendrier du mois de l'année donné.
CU : m entier, a entier, 1 m 12, a > 1582
Exemple :
>>> imprimer_mois(9, 2014)
Septembre 2014
di lu ma me je ve sa
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
"""
assert(type(a) is int and a > 1582), \
"L'année doit être un entier supérieur à 1582"
assert(type(m) is int and m in range(1, 13)), \
"Le mois doit être un entier compris entre 1 et 12 inclus"
# Affichage mois et année
# On stocke les mois dans un tableau pour un accès facilité
liste_mois = ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", \
"Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"]
# On enlève 1 à l'index du tableau, car les mois comment à 1
# alors que le tableau commence lui à 0
# On stocke dans une variable le titre brut (sans alignement / espacement)
titre = liste_mois[m-1] + " " + str(a)
# On affiche le titre centré en répètant sur la droite un certain nombre
# de caractères d'espacements. Ce dernier est calculé en enlevant la
# longueur du titre àl a longueur maximale de la ligne et en divisant le
# tout par deux
print(" " * ((20-len(titre))//2) + titre)
# Affichage nom des jours de la semaine
print("di lu ma me je ve sa")
# Affichage des jours
jour = 1 # Le jour à écrire (s'incrémente)
jour_semaine_1er = num_jour(jour, m, a) # Premier jour de la semaine
nbre_jours_mois = nbre_jours(m, a) # Nombre de jours du mois
# Boucle sur les lignes.
# Ne s'arrête pas tant que le jour final a été atteint
while jour <= nbre_jours_mois:
# La variable ligne stockera la ligne avant de l'imprimer
ligne = "" # On l'initialise / l'efface
# Boucle sur les jours de la semaine.
for jour_semaine in range(7):
# Si on en est au premier jour (donc sur la première ligne) mais que
# le premier jour n'a pas été dépassé, on ajoute du "vide"
if jour == 1 and jour_semaine < jour_semaine_1er:
ligne += " "
# Sinon, et si on a pas dépassé le nombre de jours
elif jour <= nbre_jours_mois:
# On ajoute un caractère d'espacement si le nombre ne possède
# qu'un chiffre pour l'aligner à droite
if jour < 10:
ligne += " "
# On ajoute le nombre du jour
ligne += str(jour)
# On incrémente jour pour passer au prochain jour
jour += 1
# Si on est entre deux jours, on ajoute un caractère d'espacement
if jour_semaine < 6 and jour <= nbre_jours_mois:
ligne += " "
print(ligne) # On affiche la ligne
# [Tests]
# >>> imprimer_mois(9, 2014)
# Septembre 2014
# di lu ma me je ve sa
# 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
# >>> imprimer_mois(5, 1968)
# Mai 1968
# di lu ma me je ve sa
# 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
# [Q] Écrivez une instruction utilisant la procédure imprimer_mois pour
# imprimer tous les mois de cette année
# Boucle sur les mois
for mois in range(1, 13):
imprimer_mois(mois, 2014)
# Si on est entre deux mois, on ajoute une ligne d'espacement
if mois < 12:
print("")