Coverage for src/ensae_teaching_cs/td_1a/classiques.py: 61%
41 statements
« prev ^ index » next coverage.py v7.1.0, created at 2023-04-28 06:23 +0200
« prev ^ index » next coverage.py v7.1.0, created at 2023-04-28 06:23 +0200
1# -*- coding: utf-8 -*-
2# pylint: disable=W4701
3"""
4@file
5@brief quelques fonctions à propos de la première séance
7"""
9import datetime
12def commentaire_accentues():
13 """
14 L'aide de cette fonction contient assuréments des accents.
16 .. faqref::
17 :tag: python
18 :title: Python n'accepte pas les accents
20 .. index:: accent, accents, utf8, encoding
22 Le langage Python a été conçu en langage anglais. Dès qu'on on ajoute un caractère
23 qui ne fait pas partie de l'alphabet anglais (ponctuation comprise), il déclenche une erreur :
25 ::
27 File "faq_cvxopt.py", line 3
28 SyntaxError: Non-UTF-8 code starting with '\xe8' in file faq_cvxopt.py on line 4, but no encoding declared;
29 see http://python.org/dev/peps/pep-0263/ for details
31 Pour la résoudre, il faut dire à l'interpréteur que des caractères non anglais peuvent apparaître
32 et écrire sur la première ligne du programme :
34 ::
36 # -*- coding: latin-1 -*-
38 Ou pour tout caractère y compris chinois :
40 ::
42 # -*- coding: utf-8 -*-
44 Si vous utilisez l'éditeur `SciTE <http://www.scintilla.org/SciTE.html>`_ sous Windows,
45 après avoir ajouté cette ligne avec l'encoding `utf-8`,
46 il est conseillé de fermer le fichier puis de le réouvrir.
47 SciTE le traitera différemment.
49 **L'encodage ``utf-8`` est la norme sur Internet.** C'est pourquoi il est préférable d'utiliser celui-ci pour
50 partager son code via une page Web.
51 """
52 pass
55def dix_entiers_carre():
56 """
57 fait la somme des dix premiers entiers au carré
59 :returns: nombre réel
61 .. faqref::
62 :tag: python
63 :title: Quelle est la différence entre return et print ?
65 La fonction ``print`` sert à afficher un résultat sur la sortie standard.
66 Elle peut être utilisée à tout moment
67 mais elle n'a pas d'impact sur le déroulement programme. Le mot-clé ``return``
68 n'est utilisé que dans une fonction. Lorsque le programme rencontre
69 une instruction commençant par ``return``, il quitte la fonction
70 et transmet le résultat à l'instruction qui a appelé la fonction.
71 La fonction ``print`` ne modifie pas votre algorithme. La fonction ``return``
72 spécifie le résultat de votre fonction : elle modifie l'algorithme.
74 .. exref::
75 :title: calcul de la somme des dix premiers entiers au carré
76 :tag: Base
78 Ce calcul simple peut s'écrire de diffèrentes manières.
80 .. runpython::
81 :showcode:
83 s = 0
84 for i in range(1,11):
85 s += i**2
87 print(s)
89 D'une façon abrégée :
91 .. runpython::
92 :showcode:
94 s = sum ( [ i**2 for i in range(1,11) ] )
96 print(s)
97 """
98 s = 0
99 for i in range(1, 11):
100 s += i ** 2
101 return s
104def racine_carree(x):
105 """
106 retourne la racine carrée d'un nombre
108 @param x nombre
109 @return racine carrée
110 """
111 return x ** 0.5
114def repetition_a_eviter(serie):
115 """
116 Une répétition à éviter.
118 .. exref::
119 :title: Eviter d'effectuer le même appel deux fois
120 :tag: Base -
122 Dans cette fonction on calcule la variance d'une série d'observations.
124 ::
126 def moyenne(serie):
127 return sum(serie) / len(serie)
129 def variance_a_eviter(serie):
130 s = 0
131 for obs in serie :
132 s += (obs-moyenne(serie))**2
133 return s / len(serie)
135 La fonction ``variance_a_eviter`` appelle la fonction ``moyenne`` à chaque passage
136 dans la boucle. Or, rien ne change d'un passage à l'autre. Il vaut mieux stocker
137 le résultat dans une variable :
139 ::
141 def moyenne(serie):
142 return sum(serie) / len(serie)
144 def variance(serie):
145 s = 0
146 moy = moyenne(serie)
147 for obs in serie :
148 s += (obs-moy)**2
149 return s / len(serie)
151 Le coût de la variance passe alors d'un coût en :math:`O(n^2)` à :math:`O(n)`.
152 Ce n'est pas le seul endroit où cette erreur survient. Dans le code suivant,
153 on appelle deux fois la fonction ``major`` avec le même argument.
154 C'est à éviter.
156 ::
158 meilleur = major(data)[0] # retourne ("quelque chose", True)
159 if major(data)[1]:
160 return {"leaf":guess}
161 """
163 def moyenne(serie):
164 return sum(serie) / len(serie)
166 def variance_a_eviter(serie):
167 s = 0
168 for obs in serie:
169 s += (obs - moyenne(serie)) ** 2
170 return s / len(serie)
172 def variance(serie):
173 s = 0
174 moy = moyenne(serie)
175 for obs in serie:
176 s += (obs - moy) ** 2
177 return s / len(serie)
179 return variance(serie)
182def dictionnaire_modifie_dans_la_boucle():
183 """
184 Dictionnaires, listes modifiés dans la boucle qui les parcourt.
186 .. exref::
187 :title: Modifier un dictionnaire en le parcourant
188 :tag: Base -
190 Il faut éviter de modifier un container lorsqu'on le parcourt.
191 Lorsqu'on supprime un élément d'un dictionnaire, la structure de celui-ci
192 s'en trouve modifiée et affecte la boucle qui le parcourt. La boucle parcourt
193 toujours l'ancienne structure du dictionnaire, celle qui existait au début
194 au début de la boucle.
196 ::
198 d = { k: k for k in range(10) }
199 for k, v in d.items():
200 if k == 4 :
201 del d[k]
203 En Python, cela produit l'erreur qui suit mais d'autres langages ne préviennent
204 pas (C++) et cela aboutit à une erreur qui intervient plus tard dans le code
205 (comme une valeur numérique inattendue).
207 ::
209 Traceback (most recent call last):
210 File "session1.py", line 176, in <module>
211 l = liste_modifie_dans_la_boucle()
212 File "session1.py", line 169, in liste_modifie_dans_la_boucle
213 for k,v in d.items():
214 RuntimeError: dictionary changed size during iteration
216 Il faut pour éviter cela stocker les éléments qu'on veut modifier pour les supprimer
217 ensuite.
219 ::
221 d = { k:k for k in l }
222 rem = [ ]
223 for k,v in d.items():
224 if k == 4 :
225 rem.append(k)
226 for r in rem :
227 del d[r]
229 Même si :epkg:`Python` autorise cela pour les listes,
230 il est conseillé de s'en abstenir ainsi que pour tout type d'objets qui en contient d'autres.
231 C'est une habitude qui vous servira pour la plupart des autres langages.
232 """
233 li = [0, 1, 2, 3, 4, 5, 6]
234 for i in li:
235 if i == 2:
236 li.remove(3)
238 d = {k: k for k in li}
239 rem = []
240 for k in d:
241 if k == 4:
242 rem.append(k)
243 for r in rem:
244 del d[r]
246 return li, d
249def str2date(s, format="%d/%m/%Y"):
250 """
251 convertit une chaîne de caractères en datetime
253 @param s chaîne de caractères
254 @param format format de la conversion
257 .. exref::
258 :title: conversion d'une chaîne de caractère en datetime
259 :tag: Base
261 C'est le genre de fonction qu'on n'utilise pas souvent mais qu'on peine à retrouver
262 lorsqu'on en a besoin.
263 Il faut utiliser la fonction `strftime <https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior>`_.
265 .. runpython::
266 :showcode:
268 import datetime
269 dt = datetime.datetime.strptime("16/01/2014", "%d/%m/%Y")
270 print(dt)
271 """
272 return datetime.datetime.strptime(s, format)