Aller au contenu

Fonctions - découverte

I. PremiĂšre situation : le parc d'attraction⚓

Chair-O-Planes, night

user:Solipsist, CC BY-SA 2.0 https://creativecommons.org/licenses/by-sa/2.0, via Wikimedia Commons

1. La caisse est tombĂ©e en panne đŸ˜Ș⚓

Le droit d'entrĂ©e journalier dans un parc d’attraction est de 37€ pour un adulte et de 28€ pour un enfant.
Alice et Bob doivent faire payer les entrĂ©es, mais leur caisse est malheureusement tombĂ©e en panne, et la queue s’allonge trĂšs vite

On leur fourni en urgence une calculatrice qui dispose de Python pour les aider.

  • Un groupe de 2 adultes et 2 enfants se prĂ©sente Ă  la caisse. Il faut donc calculer : \(2 \times 37 + 2 \times 28\)
  • Un groupe de 3 adultes et 5 enfants se prĂ©sente Ă  la caisse. Il faut donc calculer : \(3 \times 37 + 5 \times 28\)
  • Un groupe de 1 adulte et 3 enfants se prĂ©sente Ă  la caisse. Il faut donc calculer : \(1 \times 37 + 3 \times 28\)

😱 Ces calculs sont trĂšs rĂ©pĂ©titifs, et prennent du temps. La queue continue Ă  s’allonger 


Ils remarquent qu’il suffirait de saisir le nombre d’adultes et le nombre d’enfants pour automatiser le calcul. Ils dĂ©cident d’écrire une fonction en Python :

Exécuter ce script

Que se passe-t-il ?

###(DĂ©s-)Active le code aprĂšs la ligne # Tests (insensible Ă  la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Shift+Esc ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein Ă©cran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activĂ©, le texte copiĂ© dans le terminal est joint sur une seule ligne avant d'ĂȘtre copiĂ© dans le presse-papier

Solution

😱 Il ne se passe rien ...

Si on « appelle » prix(3, 2) :
‱ 3 est automatiquement affectĂ© Ă  la variable nbre_adultes
‱ 2 est automatiquement affectĂ© Ă  la variable nbre_enfants

Tester des appels de fonction

Recopier dans la console (Ă  la main !) ci-dessous.

⚠ Attention, il faut bien avoir exĂ©cutĂ© le code ci-dessus pour que cela fonctionne. Sinon, la fonction prix ne sera pas connue.

prix(3, 2)
Exécuter, puis recopier dans la console (à la main !) ci-dessous

prix(2, 3)

Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activĂ©, le texte copiĂ© dans le terminal est joint sur une seule ligne avant d'ĂȘtre copiĂ© dans le presse-papier

Vos propres essais

A vous ...

Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activĂ©, le texte copiĂ© dans le terminal est joint sur une seule ligne avant d'ĂȘtre copiĂ© dans le presse-papier

Résumé

👉 Alice et Bob ont crĂ©Ă© la fonction dont le nom est prix, qui a deux paramĂštres nbre_adultes et nbre_enfants.

2. La situation d’Alice et Bob s'amĂ©liore đŸ˜Šâš“ïžŽ

La situation d’Alice et Bob s’est nettement amĂ©liorĂ©e, mais ils veulent aller encore plus vite.
Ils voudraient juste saisir les nombres d’adultes et d’enfants, par exemple 3 et 2 , et ne pas avoir Ă  Ă©crire prix(3, 2)
Pour cela, ils Ă©crivent le script suivant :

Exécuter ce script

Que se passe-t-il ?

###(DĂ©s-)Active le code aprĂšs la ligne # Tests (insensible Ă  la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Shift+Esc ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein Ă©cran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activĂ©, le texte copiĂ© dans le terminal est joint sur une seule ligne avant d'ĂȘtre copiĂ© dans le presse-papier

Ce qu'il s'est passé

👉La fonction prix a Ă©tĂ© appelĂ©e. Le rĂ©sultat renvoyĂ© par la fonction a Ă©tĂ© affectĂ© Ă  la variable a_payer. Cette variable a ensuite Ă©tĂ© affichĂ©e.

3. Le tarif Ă©tudiant⚓

On vient signaler Ă  Alice et Bob qu’un nouveau tarif entre en vigueur instantanĂ©ment : le tarif « Ă©tudiant » Ă  30€.

đŸ’» A vous de jouer 1

En vous inspirant de ce que vous avez déjà vu, compléter ce script qui tient compte de ce nouveau tarif.

Le tester pour 1 adulte, 2 Ă©tudiants, 3 enfants. Le prix Ă  payer doit ĂȘtre 181 €.

###(DĂ©s-)Active le code aprĂšs la ligne # Tests (insensible Ă  la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Shift+Esc ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein Ă©cran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activĂ©, le texte copiĂ© dans le terminal est joint sur une seule ligne avant d'ĂȘtre copiĂ© dans le presse-papier
Évaluations restantes : 5/5

.128013cP*-7 sSfbgn3x8k+vei(hl,mdo0p:_2)=tay1/ur050A0t0J0K0u0x0h0g0b0x0K0h0h0I010J0u0D010406050h0O0z0z0K0P0L040i0B0x0O0*0B0m050N0;0?0^0`0/0D04051a131d0N1a0/0A0u0s0Y0!0$0(0!0m0l0O0K0l0t0e0D0L0J0w110g0w0u0l0w0x1F0w0J0-050T0k0x0t1m0#0%011E1G1I1G0J1O1Q1M0J0P1b1A0Y0}0h0D0K0m0(0G011S1o010j0V0t0m0K0z0t1M1.1:1^1U1{1Q1~200-0a0g0c0P0B0D0B0h0u100m0g0R1,0P0P0t0b2l13230m1b0N1A2y1(1*1)1N0A251p0u0m1}2i1M1j1l0Z1T2I2K0m0B2O1M0D2r1b2w2y2#0:1/2m2Q1_2U0P0@0x1M0K1D2r0j0(030F0F0b2V0t1I2T0B0e0G0e0M0-0M130K2$2)0.2(242+1U2-2/2;2?0t2^012`2|2~302L33330-0G393b1:3d2w2H013i0K2:1b2=0w2@2_2{2}0R3s2U3u0n0-0n3y2v3c1e2Z132O2B0A1*2G3g0(3O211b3$1c3!2%143Y3-2!2)0g0u0A0(2{2w3u363I3|3~013N3r2J3t34360g290t3 3q3P4a3R4c1M0N3a3e2*1n1U0q0-0R0j3X3A0g4q3D0m0j0-2Y0u0o0F0S0O1j1:0J0h4y2x4B3+010,040v4Q3`3f4s0(0m0-0m0k2r0F0K0A0O0x0J0t4P3@3A4S4#4U0-0y4Y4A3C4T4%044)4+1}0j4N4?2%504`4V4}4@2x4 3{514(4*0t4J0J4L0u584Y4_2R4{040H0E4Y0/5f4Z2m3}4h41341?445E474i2 4k325H1@4f4h3-3Q5P3v2y3a0g5!5h4!5u522r0;4:0K0J4~5t1_0B0-0I5/5b5u0z0u3U0f4~5$4r5u5=040d5s5_2,5k4+4-4/4;593c603D630r5^5i4`5{3w0p6k5%5;0-655B6g5j535l4J4D5r6v5:1U6i6q611_6n040n0C6H6h6t6O6x545m4K4M0m4O5z663{5K402)3S3k6$5M5V6)4e1 4g5L5U5O6)5Y045#6w4`4u042r5o0P126D673h0-5*6c5-6Z5B133_3Z0t2y3:2z3(132C7l0K1P7g3#1k3d0N0R0T0V0h04.

4. 🎂 Jour d'anniversaire⚓

NouveautĂ© : si c’est le jour d’anniversaire d’une personne du groupe, tout le groupe bĂ©nĂ©ficie d’une rĂ©duction de 10 %.

đŸ’» A vous de jouer 2

Recopier sans la modifier la fonction du 3., complĂ©ter le programme pour qu’il demande si c’est un jour anniversaire, et qu’il affiche le prix Ă  payer suivant les cas.

On rappelle que pour diminuer un prix de 10%, il suffit de le multiplier par 0.9.

###(DĂ©s-)Active le code aprĂšs la ligne # Tests (insensible Ă  la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Shift+Esc ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein Ă©cran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activĂ©, le texte copiĂ© dans le terminal est joint sur une seule ligne avant d'ĂȘtre copiĂ© dans le presse-papier

Solution
🐍 Script Python
def prix(nbre_adultes, nbre_enfants, nbre_etudiants):
    resultat = 37  *nbre_adultes + 28 * nbre_enfants + 30 * nbre_etudiants
    return resultat

anniv = input("Jour d'anniversaire : saisir en toutes lettres oui ou non ")
adultes = int(input("nombre d'adultes ? "))
enfants = int(input("nombre d'enfants ? "))
etudiants = int(input("nombre d'Ă©tudiants ? "))
a_payer = prix(adultes, enfants, etudiants)
if anniv == "oui":
    a_payer = 0.9 * a_payer   
print("A payer : ", a_payer)

II. DeuxiĂšme situation : les tables de multiplication⚓

Aider le petit frĂšre de Bob

Le petit frĂšre de Bob doit apprendre ses tables de multiplication.

Pensant l’aider, Bob Ă©crit la fonction suivante :

Exécuter ce script. Que s'affiche-t-il ?

###(DĂ©s-)Active le code aprĂšs la ligne # Tests (insensible Ă  la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Shift+Esc ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein Ă©cran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activĂ©, le texte copiĂ© dans le terminal est joint sur une seule ligne avant d'ĂȘtre copiĂ© dans le presse-papier

Solution

Il ne s'affiche que 9

😹 Ce qu'il s'est passĂ©

👉 A noter : losque l'on rencontre l'instruction return, on sort de la fonction. Si un return se trouve dans une boucle for, on sort donc de la fonction dùs la premiùre rencontre de l'instruction return.

Note

Nous verrons dans le paragraphe IV. comment on peut faire.

Mais d'abord, regardons si une fonction peut renvoyer plusieurs choses.

III. Et si l'on veut que notre fonction fasse plusieurs choses ?⚓

Une fonction bizarre

Vous rencontrerez souvent des fonctions comme celle se trouvant dans le script ci-dessous :

Exécuter ce script. Que s'affiche-t-il ?

###(DĂ©s-)Active le code aprĂšs la ligne # Tests (insensible Ă  la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Shift+Esc ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein Ă©cran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activĂ©, le texte copiĂ© dans le terminal est joint sur une seule ligne avant d'ĂȘtre copiĂ© dans le presse-papier

Solution
(7, 10)
<class 'tuple'>

😹 Ce qu'il s'est passĂ©

👉Vous observez que des parenthĂšses sont apparues dans l’affichage du rĂ©sultat.

En fait il y a une seule variable renvoyĂ©e, et non deux, qui est de type tuple (ici un "couple" de deux entiers), comme l’affichage de la ligne suivante le confirme. Nous Ă©tudierons plus tard les tuples.

IV. Comment crĂ©er une fonction qui nous donne une table de multiplication ?⚓

👉 MĂ©thode 1 :

On écrit une fonction qui renvoie une « liste » ou un « tuple. »
Une telle fonction renverra par exemple pour la table de 9

  • Si la fonction renvoie une liste : [9, 18, 27, 36, 45, 54, 63, 72, 81, 90]
  • Si la fonction renvoie un tuple : (9, 18, 27, 36, 45, 54, 63, 72, 81, 90)

Nous Ă©tudierons les listes et les tuples un peu plus tard

👉 MĂ©thode 2 : avec une procĂ©dure :

On peut Ă©crire une fonction qui ne renvoie rien, mais qui fait des actions, comme par exemple des affichages.

procédure

👉 Une fonction qui ne renvoie rien s’appelle une procĂ©dure.

De plus en plus on appelle ce type de fonction des ... fonctions.

Table de multiplication

Exécuter le script ci-dessous et observer l'affichage obtenu.

###(DĂ©s-)Active le code aprĂšs la ligne # Tests (insensible Ă  la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Shift+Esc ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein Ă©cran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activĂ©, le texte copiĂ© dans le terminal est joint sur une seule ligne avant d'ĂȘtre copiĂ© dans le presse-papier

Pas de return ?

👉 Dans une procĂ©dure, la ligne return None est facultative

Supprimez-lĂ  dans l'exercice ci-dessus, puis testez Ă  nouveau.

V. Une fonction sans paramĂštre ?⚓

Jouons aux dés

Exécuter le script ci-dessous et observer l'affichage obtenu.

###(DĂ©s-)Active le code aprĂšs la ligne # Tests (insensible Ă  la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Shift+Esc ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein Ă©cran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activĂ©, le texte copiĂ© dans le terminal est joint sur une seule ligne avant d'ĂȘtre copiĂ© dans le presse-papier

VI. A retenir⚓

Résumé

  • Une fonction commence par le mot def, suivi du nom de la fonction, de la liste des paramĂštres entre parenthĂšses, et de :. Toutes les instructions d’une fonction sont indentĂ©es.

  • S’il n’y a pas de paramĂštres, il faut obligatoirement mettre des parenthĂšses vides.

  • Une fonction ne peut renvoyer qu’une seule variable. Cela se fait avec l’instruction return.

  • L’exĂ©cution de l’instruction return provoque obligatoirement la sortie de la fonction. Si d’autres instructions se trouvent aprĂšs return elles ne seront jamais exĂ©cutĂ©es.

  • La valeur renvoyĂ©e est indiquĂ©e par l’instruction (optionnelle) return. Si celle-ci n’est pas prĂ©sente, la valeur par dĂ©faut None est renvoyĂ©e.

VII. đŸ€” Appeler une fonction dans une fonction ...⚓

Les monnaies

La fonction euro_vers_yan appelle deux autres fonctions. Cela ne pose aucun problĂšme.

Exécuter le script ci-dessous et observer l'affichage obtenu.

###(DĂ©s-)Active le code aprĂšs la ligne # Tests (insensible Ă  la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Shift+Esc ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein Ă©cran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activĂ©, le texte copiĂ© dans le terminal est joint sur une seule ligne avant d'ĂȘtre copiĂ© dans le presse-papier

Remarque sur la "portée des variables"

  • euros est une variable locale dans la fonction euros_vers_dollars
  • dollars est une variable locale dans la fonction dollar_vers_yuan
  • montant une variable locale dans la fonction euro_vers_yuan.

Ces variables ne sont "connues" que dans ces fonctions.

ConsĂ©quence 1 : choix du nom des paramĂštres⚓

Nous aurions donc pu choisir pour chaque fonction le mĂȘme nom de paramĂštre.

Les monnaies

Exécuter, et tester le script suivant :

###(DĂ©s-)Active le code aprĂšs la ligne # Tests (insensible Ă  la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Shift+Esc ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein Ă©cran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activĂ©, le texte copiĂ© dans le terminal est joint sur une seule ligne avant d'ĂȘtre copiĂ© dans le presse-papier

Variable locale montant

Ici nous avons trois variables locales différentes montant dans les trois fonctions du script.

Les flottants

On devrait obtenir le résultat suivant : \(2 \times 1,19 \times 6,93 = 16,4934\)
Or le résultat affiché est : 16.493399999999998

C'est dû à la façon dont les nombres flottants sont codés dans la machine. C'est un problÚme général à tous les langages, et pas spécifique à Python.

Nous étudierons précisément pendant l'année comment sont codés les nombres flottants dans la machine.

ConsĂ©quence 2 : une variable “locale”, n’est pas reconnue Ă  "l’extĂ©rieur"⚓

Les monnaies

Exécuter, et tester le script suivant :

###(DĂ©s-)Active le code aprĂšs la ligne # Tests (insensible Ă  la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Shift+Esc ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein Ă©cran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activĂ©, le texte copiĂ© dans le terminal est joint sur une seule ligne avant d'ĂȘtre copiĂ© dans le presse-papier

Variable locale montant

👉 La variable resultat_dollars n'est pas connue Ă  l'extĂ©rieur de la fonction euro_vers_dollar(montant):

ConsĂ©quence 3 : mĂ©thode souvent utilisĂ©e⚓

🐘 A retenir

💡 On affecte Ă  une variable la valeur renvoyĂ©e par une fonction

Les monnaies

Exécuter, et tester le script suivant :

###(DĂ©s-)Active le code aprĂšs la ligne # Tests (insensible Ă  la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Shift+Esc ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein Ă©cran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activĂ©, le texte copiĂ© dans le terminal est joint sur une seule ligne avant d'ĂȘtre copiĂ© dans le presse-papier

Attention

⚠ Ne pas utiliser des noms de variables et des noms de fonctions identiques.

Les flottants

Si vous saisissez 10, vous devriez obtenir \(10 \times 1,19 = 11,9\) Or le résultat affiché est : 11.899999999999999

C'est dû à la façon dont les nombres flottants sont codés dans la machine. C'est un problÚme général à tous les langages, et pas spécifique à Python.

Nous étudierons précisément pendant l'année comment sont codés les nombres flottants dans la machine.

VIII. Docstring d’une fonction⚓

Docstring

Nous reviendrons plus tard dans l’annĂ©e sur les "docstring" d’une fonction, et ajouterons d’autres Ă©lĂ©ments. Pour le moment, nous les utiliserons pour expliquer le rĂŽle d’une fonction.

Cette "docstring" est composée de lignes de texte écrites entre """ et """.

Ces lignes ne sont pas exécutées par le programme, et simplement destinées à donner des explications à celui qui lit le code (script).

Par exemple :

def euro_vers_dollar(montant):
    """
    Cette fonction renvoie la valeur de montant euros convertie en dollars.
    par exemple euro_vers_dollar(2) doit renvoyer 2,38
    """
    return montant * 1.19 # en supposant qu'un euro vaut 1,19 dollars

IX. Exercice⚓

Pour dĂ©terminer la distance d’arrĂȘt d’une voiture on applique la formule suivante :

Distance d’arrĂȘt (en m) = distance parcourue pendant le temps de rĂ©action (en m) + distance de freinage (en m)

Une documentation donne les informations suivantes pour une route sĂšche : Notations :

  • V la vitesse d’un vĂ©hicule en km/h
  • R la distance parcourue pendant le temps de rĂ©action (en m)
  • F la distance de freinage (en m)
  • A la distance d’arrĂȘt du vĂ©hicule (en m)

On donne les formules suivantes :

  • R = V/3.6
  • F = VÂČ/200

Nous rappelons que les noms de variables en informatique doivent ĂȘtre explicites (avoir un sens) et commencer par une lettre minuscule.

ComplĂ©ter le script suivant, pour que : si l’on saisit la vitesse d’un vĂ©hicule, le programme affiche les trois renseignements suivants : la distance parcourue pendant le temps de rĂ©action (en m), la distance de freinage (en m), et enfin la distance d’arrĂȘt totale du vĂ©hicule (en m). Dans les fonctions donnĂ©es ci-dessous, il faut remplacer le mot pass par les instructions python nĂ©cessaires.

###(DĂ©s-)Active le code aprĂšs la ligne # Tests (insensible Ă  la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Shift+Esc ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein Ă©cran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activĂ©, le texte copiĂ© dans le terminal est joint sur une seule ligne avant d'ĂȘtre copiĂ© dans le presse-papier
Évaluations restantes : 5/5
.128013cPw*-7 sSf.bgn3T8xOk9+Ă©vei;(h4l,mdo0qVp65_:2)Ă =tQayC1/ur050I0z0W0Y0A0F0i0h0b0F0Y0i0i0V010W0A0N010406050i0%0H0H0Y0(0Z040j0J0F0%0|0J0o050$13151719110N04051p1i1s0$1p110I0A0y0;0?0^0`0?0o0n0%0Y0n0z0f0N0Z0W0D1g0h0D0A0n0D0F1U0D0W0 050,0m0F0z1B0@0_011T1V1X1V0W1%1)1#0W0(1q1P0;1c0i0N0Y0o0`0S011+1D010k0.0z0o0Y0H0z1#2022271-2a1)2d2f0 0a0h0c0(0J0N0J0i0A1f0o0h0*1~0(0(0z0b2A1i2i0o1q0$1P2N1`1|1{1$0I2k1E0A0o2c2x1#1y1A0=1,2X2Z0o0J2%1#0N2G1q2L2N2@12212B2)282-0(160F1#0Y1S2G0k0`030Q0Q0b2.0z1X2,0J0f0O0f0#0 0h0#1i0Y2^2{102`2j2}1-2 3133350z3701393b3d3f2!3i0f25040h0S3p3r223t2L2W013y0Y321q340D36383a3c0*3I2-3K0p3m0p3Q2K3s113U3w0`3X3Z053#3%3E3)3H2Y3J3j0E3m0E3=1j3@3u2|1C3x0J303Y3A3$3C3(3G3+443-3j0P3m0P4a2@3^2{3V3|4k403F3*3e4q3h3j0O3m0O4w4c3_4f3{4h3z3!3B3D4E433g3K0g3m0g4N3S4y3v4Q3W4S4j4U4l4W424p4Z3j0r3m0r4(2M4*4e2*4-4i3}3 4m414o4G4^0f0v3m0v4}3T4z3`524T3~4V4n4F3,4I3k0K0 0#0K5f4 4A4.545m575o4H3K0#3l045G5w4d5y534C564X4@453k3M0#3P0$3q3?4)5L5i4B4:4D4?595S0#3/5I3;5X3R4~5#4,5%5l4;5n4Y5,475I495;5Z5?4P515_554=585p5F4t5I4v624b5!652~5z5O695D5a0#4K5I4M6g4x5@666l5(5P5*6b3j0#4#5I4%6u4O5h5^6y5`5)6a5E6D4`5I4|6I6i6K6x5N6z6n5}4r3k5c5I5e6V646X6k6Z6N6A6P5a0S5s046^5K6j4g6:685|5R6%0S5H746|6.6~5k705C6$5q0S3M7f774+6Y7a5B5Q5+735.0S5:5Y6h6-7j6/7l5{7c727e5 0S617t6v6}4R6 7m6B6Q3L6d0S6f7G6J7w794/6;6#7B3K0S6r7#7i507x7W7b7n6C3L6F0S6H7S6W7U7J7y6O6o5S0S6S7~7(5M7`6=7|736)0S6+7?7v7)7V5A7z7-7N0p6_8i815$6M7,7M5a0p5H8r8l6L7K8f8p5S0p3M8A8u7k7+7L6?8z5.0p7s5=5g7^5j8F8x8H6%0p5 8U8D7*8e7{7d3.6d0p7R8M5x8m8w8!7Z3j0p6r8;8X8d6m717o5q0p6F8}8@7_8Q8.8{3.6S0p6U8a8N8c918Z848#8:6)0p898*6w8Y8_7A94466_0E5v6,9a82929e8/0f0E5H9B908P9d7Y9p9A3M0E5W998+8v839H7.0E5.9T9E678G855q0E5 9#9W8n9Y9f9A6d0E8)639v8,9Q8`9S6r0E6t9N9l8^6!9@7N0E6Fa25f1t2=1i2%2Q0I1|2V5i4F2$1z1q2;0z2?3s9:054Fal2j0A0I0`3a2L5F3Aasau8S5q3l0h2o0zaA9Zax2N5Y7I010u0 0*0k9:0h9}3{0k0 2G0Y2I0A1ganaM0~040Ca%783{0 0y2z0z0^0za,8Oa)0T0R9:117uaq2Baz01av2{7!ayatb3aBb6aE2eaGb9aI3j3M3=aM0d3m0hbna^9b010i0I0 020L0%0J0W0BbvbxbzbBby0Ba}bp0hb2b4223.b7aH9+3/bc2fbP9z5.bja-brbt3Nbn0h0!0+0W1*0k1ga!1R2G0o0y0J0A1*0?2C0A0i0,0o0b1*2D0(0xaZ2A0h2w0%0(0h0%2ZbHa 5LbK0Qaw46bObf9+47bSbe8y6%5 bX8Obsbmbnb 0(0,440h0y3Y0zc82C1*a:b*a?cd2_3Ucgci0f6d5lcgbgcR26aFbU9IcS62aMcvb#bn0c170h0z0s0z0H0N1)0haYb.0o0C0P0K0T2Cb?0Wc@2cb=0Z0zc95-0l0rdadb0ldd0lcMamcOb8bL0o3K6rcTdjba4JcXbdcZ7.dnc$bYc(b$0hbEbDbwbFdCbGa a~cN4zcPb53j6Fdodu7N4#codR5adP5;dAaU3WaPb{0W0Qc^aSd!0J0 0Vd+aM0oa/a;cLa aTaMd-040$d:bY0HaW040p0l6t6vcediaAcQ6SdQcl9z4`dUee9IecdYb$d!aO042G0Wc81hd_d!d=041yb|d)0zaZdg3ScfdpcQ6)edcq5q5ceheK3KeI5;dJdhdLeGdN5rckeO6D5seNdqeXaKb03VeoaQd 8O0oe20k2G2Y1Ja@e8bYa)a+e`e/d?cK0ie_dKa_0 a{eD2MeFeaeW5GeYe%fde$cVfde)d!blc)aTe~bqc(dGfsdEbzf8e*dMbM6Dbi34cU9+5VdsbTei7.fFfkc%b!dAb(1?b+b-c5b:b=b@0hb_eyb}b cH0he=0ze@1Kc60JcGcbf34cfpbJeVfz3kbWfCdpfibRcYfI7N5-1#dxcufNb$cycA2ZcCcEcG2DcJa=f2fwfab9cQ0#csf{dV5~fGcpffcsg4fqg6c*c,c.c:c=b+e?2d1Kc{c}c 2zd2b;0Jd5d70S0l6fe7f4b1f@dl6DcSgog06p4tfhfEc#aLdygxdBfubAg/dGgie9gkfcdng!eZ3k4Kg(9z6qg33qdZd;d$ezf(f*f:3Sd`bYd|d/euh504gfd^2@hc8Od|0e0ee.bq0H0A0 5Whld,0 d~hge0hu6`0K9tgTeTargW5FdPg{ffdTf g|6Eh2fnenaX0+eshr4Ah6d(h8gFha5?f=fygX3kechNfieghQffek3qeSeEg@dk5FeIh:fEeMh?fieQg+8Oe,3ChZ5$e217eqbI5ie|if5^f0ggh)e*igf6a|dIbIh,7!6_eJe%6^grgp73ivgv3VfmdZf=5ifrg;iKbCdHhHh{eUfbf^74fecViTg 9IiTfLg,cwb%b)fRb~fTd3b?b^34fZ22f#0WbycE2C0hid0+f,f.ccirh+hKbhfBf?iA7e25iX7.7fhTd!dzg7d6g9cIgcc9ged@ghj0gUj5g^iSf`jqg|7rizg#7}bWiDiIg-c+c9gAc;c?i{0WgHc~0Id0gLd4d63O0O0l97db0rdedfjohIgViRh-7EiU9+j)j97Nj)i!g5i$ftiMg=j!iPhJj%7!gZjuixg%i3j+g*hUaM0b5H030h0t2B0Y0N0N3ec?b_b,i*a#2Bc^c5i|1R0Y0k0k2Hb*fX0Yg?iQjrj(g`j iVg~k29z7#hTh4bYk70 k9cD1)cGfUgN0x1*0Ukwgb0(0A0Y1(c0d%i;0zeAeCj_f9h|cheW7;j*kHhPdtjy73dXh3emhhi:b~k*d*hBhnd.iaijepeBc_ii51ihiHl8hjjnjpio040Tkyj{kA7!h/kDj+h=k_jvh^3tj1j|bhh lskHi2lvixi5k5kLk8kakckekgi.f%fSklf%gEe^c-d1kqkskui.lnj$lp8:ivi0bVe#kG9I8ikJk~lKkNgbkQc9kS0ZkU0hkWb_cDkZk#c?l0b 0Qh%e^l%j cQ8rk?l:aDl/7.mee)kKe exk(l1m8lV1Kl751hemu2~0 m9mtlfld0 e}ljlgjmimd!a`mbit8:j4fDbVj8mi8hbieRisj20f8Kmfmjf~lGcVm!mll?8OkM04k91R0b3Y0b0%khi/mpf#0I02039i0BjJlX0hb/i,fWc?c2130F0,0WmMmY8Um#8hcnmT8qguk}bok m{k*jJmx1-mwl4bqewm6l2lant0`d|0wnCd#mob|k)mrf)h(nelAmZj~mQl:k1m(bQk4h`k.kzh}8:kCnSmjkFnVbVdwnnhmbqeoeqhYnwh!nIf!nr2F0+nOl)mZhMlDl:k^fHg|8}hTnYfxnflrn(8hluo5e%97jchhlhimn/3Vnvhxd;0mmz0F0J0YndmC28lemG66os042Y0N1elcozmEoI1-0i3MdG0X0%lPc-b|cCby2GcCmIc-2B0u0H0$0D0h0Rg.iMoL0`a`lmk-oanP9inh8qlFogm)lIevh#nKknklnGop3son5$hWc4p3oy1-oAj#n^olo.01mLo=gjn#9Al+o29Sl.n+9I9sojbYnynqnLh9p4l6n@p804mAmJa(oKpca.himIpipkiOnZlopn9Bo_5SpVj-5apVj:nxp0mqnspE4,p5hbo 04p*oBoJa*piewphpLpjf6n~pUmPf|cmmSpt9SmVh_mXnP9TpWcrm%o|cmjAi6bqm.k90qa=oxpRo?n 9#qb9!njq4a1nmin4,qj0h0M2xi`ks0A0b0De^0:0b0A0f0*0^f-0ip~k:f^9.qs3KqVpZpXk4evoD2;2YqnpflkmFq+4,oNbug/nzc6173cc8oRc62c0I22d1b_p21Ro+j^p=pd0 0GnGpynJmqr2etr6o/r8nGq:04dG0h0Hr5q.mDllqScQ9`qW46n*qe9zrvp$4Aq%kZ0oq*j`bqperI3VrkdGq?210(q_0(q{kf0oq~rGfXgDnMlWr4g/pPrip+66p(m7pHr)04r9r+28rNg/rnrprLlko;qopmqTh-a2rw9Ao4gscVs3rC5$rEq)r:q-r|q/oOq=nqq@rRf-rT1*rVrXr0i`n|d1r%o-p{a)r=oqpxr-n{iesyr*sBcusiiMr`r(sGrspl0$apa6aka8ah1i0WabsX2T2Om4sU0$a9a~0*cA0/04.