Erreurs courantes en Python¶

Marc BUFFAT, dpt mécanique, Université Lyon 1 et [1]

python

L’erreur est une formidable opportunité d’apprentissage

Contenu

  • 1  Rappel de la méthodologie du calcul scientifique
  • 2  Que faire en cas d'erreur
    • 2.1  Règles générales
  • 3  Erreurs sur l'exécution du notebook
    • 3.1  utiliser bouton Exécuter ou Run
    • 3.2  Exécuter les cellules dans l'ordre
    • 3.3  Suivre les instructions à la lettre!
    • 3.4  Executer toutes les cellules (ne pas en omettre)
    • 3.5  Bien comprendre la notation de variable
    • 3.6  Bien comprendre la notion de fonction
  • 4  Erreurs de syntaxe courantes
    • 4.1  Erreur d'indentation
      • 4.1.1  exemples: IndentationError
    • 4.2  Utilisation d'un variable non définie
      • 4.2.1  exemples : NameError
    • 4.3  Erreur de syntaxe
      • 4.3.1  exemples : syntaxError
    • 4.4  Erreur de type
      • 4.4.1  exemples : TypeError
      • 4.4.2  autres exemples
    • 4.5  Erreur d'entrée/sortie ES
      • 4.5.1  exemples : IOError
  • 5  Points clés
  • 6  Erreurs algorithmiques
    • 6.1  Exemple 1
    • 6.2  Exemple 2
    • 6.3  Exemple 3
    • 6.4  Exemple 4
    • 6.5  Exemple 5
    • 6.6  Exemple 6
In [1]:
import numpy as np

Rappel de la méthodologie du calcul scientifique¶

  • méthode scientifique d'utilisation d'un outil numérique

    • analyse du problème pour définir ce que l'on doit faire (analyse)
    • définir la manière dont on doit le faire (algorithme)
    • mise en oeuvre sur ordinateur (programmation)
    • vérification / validation de la méthode (validation)
    • analyse "critique" des résultats
  • qualités nécessaires !!!
    1. rigueur dans l'analyse algorithmique
    2. rigueur dans la programmation
    3. rigueur dans la validation

Que faire en cas d'erreur¶

Si vous suivez la démarche précédente et faites preuve de rigueur, alors la recherche d'erreurs se limite souvent à la recherche d'erreurs de syntaxe.

Les erreurs (de syntaxe) en programmation sont récurrentes. Avec de la méthode ce sont les erreurs les plus simples à corriger. C'est l'objectif principal de ce notebook.

Attention cependant, l'absence d'erreurs de syntaxe ne garantie aucunement que résultat fournit par le programme est correcte, car il existe un autre type d'erreur: l'erreur algorithmique, qui consiste à utiliser la mauvaise méthode (algorithme) pour résoudre le problème. Seule une analyse du problème avec des tests et des validations permettra de trouver ce type d'erreur.

Règles générales¶

Lorsqu'une erreur (de syntaxe) est détectée par l'interpréteur Python, un message d'erreur est affichée, en général en anglais et sur plusieurs lignes (Traceback). Quelles sont les informations importantes:

  1. la ligne où l'erreur est détectée est indiquée avec une flèche ---> avec un numéro de ligne
  2. le dernier message d'erreur (en générale en anglais) qui indique le type d'erreur. C'est la dernière ligne affichée. C'est ce message qu'il faut comprendre, les autres messages sont en général moins importants.

Avec ces 2 éléments, on peut commencer à chercher l'origine de l'erreur.

  1. On commence par chercher l'erreur de syntaxe sur la ligne indiquée par la flèche --->.
  2. Si la syntaxe est correcte, alors on remonte les lignes de code précédentes, car l'erreur peut etre due à une erreur induite par les instructions précédentes.
  3. Si on ne trouve pas, on vérifie chaque étape en affichant la valeur des variables avec une instruction print

Erreurs sur l'exécution du notebook¶

utiliser bouton Exécuter ou Run¶

Exécuter toujours tout le notebook depuis le début (en appuyant sur le bouton Executer ou Run)

En particulier certaines cellules servent à l'initialisation. Les erreurs suivantes sont liés à la non execution des cellules en début de notebook

NameError                                 Traceback (most recent call last)
<ipython-input-38-3daac93200e0> in <module>
----> 1 printmd("### Exercice test: écrire une fonction func t.q.")
      2 nom = Exos[0]
      3 get_ipython().system('test_exo -e $nom')

NameError: name 'printmd' is not defined


NameError                                 Traceback (most recent call last)
<ipython-input-50-e53591bcd8b5> in <module>
----> 1 assert(check_function(func,Exos[0]))
      2 Note_exos[0] = 1
      3 print("Tests de validation OK! note =",sum(Note_exos)," sur",len(Note_exos))

NameError: name 'check_function' is not defined

Exécuter les cellules dans l'ordre¶

et attention au nom des variables !!!

Suivre les instructions à la lettre!¶

Executer toutes les cellules (ne pas en omettre)¶

Bien comprendre la notation de variable¶

variable case mémoire permettant de stocker une valeur

  • une variable doit être définie (avec une affectation) avant utilisation

  • l'affectation définie le type de la variable

     x = 1
     # création variable x entiere
     x = x + 1
     # on modifie la variable x
     x = '1'
     # on a crée une nouvelle variable car on a changé le type 
    

Bien comprendre la notion de fonction¶

une fonction est un algorithme avec:

  • des données qui sont les arguments de la fonction

  • un résultat qui est la valeur de retour

  • les variables utilisées dans une fonction sont des variables locales

     def ma_fonction(a,b, c):
         # a, b, c dont les données : arguments
         mean = (a*b*c)**(1./3.)
         # mean est une variable locale
         return mean
         # renvoie le résultat avec return
     # utilisation
     m1 = ma_fonction(1.,2.,3.)
     # appel de la fonction avec des valeurs numériques
     m2 = ma_fonction(m1, 2*m1 +1, 4.)
     # appel de la fonction avec des variables
    

Erreurs de syntaxe courantes¶

Erreur d'indentation¶

IndentationError: unexpected indent

IndentationError: expected an indented block

IndentationError: unindent does not match any outer indentation level

indique que l'instruction ne respecte pas les règles d'indentation de Python.

En particulier, les instructions doivent toutes commencées en colonne 1 (sans espace avant) sauf pour délimiter des blocs de code, comme:

  • les boucles for
  • les tests conditionnels if
  • la définition de fonction def

exemples: IndentationError¶

corriger les erreurs suivantes

In [2]:
a = 2
 b = 3
  Cell In [2], line 2
    b = 3
    ^
IndentationError: unexpected indent
In [3]:
somme = 0
for i in range(5):
somme = somme + i*i    
  Cell In [3], line 3
    somme = somme + i*i
    ^
IndentationError: expected an indented block after 'for' statement on line 2
In [4]:
i = 2
if i %2 :
print("i," est paire")
  Cell In [4], line 3
    print("i," est paire")
                        ^
SyntaxError: unterminated string literal (detected at line 3)
In [6]:
def Somme(n):
    s = 0
    for i in range(5):
        s = s + i*i
   return s
  File <tokenize>:5
    return s
    ^
IndentationError: unindent does not match any outer indentation level

Utilisation d'un variable non définie¶

NameError: name 'X' is not defined indique que l'on utilise une variable, ici X qui n'a pas été définie.

rappel on ne peut pas utiliser de variables que l'on a pas définie précédemment avec une instruction d'affectation.

Cette erreur peut indiquer que l'on a pas utilisé la bonne variable

exemples : NameError¶

corriger les erreurs suivantes

In [7]:
x = 1
x = X + 1
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In [7], line 2
      1 x = 1
----> 2 x = X + 1

NameError: name 'X' is not defined
In [8]:
for i in range(5):
    ss = ss + i**3
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In [8], line 2
      1 for i in range(5):
----> 2     ss = ss + i**3

NameError: name 'ss' is not defined

Erreur de syntaxe¶

SyntaxError: invalid syntax

cette erreur générique peut indiquer:

  1. l'oublie d'un symbole ':' pour définir le début d'un bloc:
  • test if, boucle for ou définition de fonction def
  1. la confusion d'opérateur: par exemple l'affectation = et l'égalité ==

  2. l'oublie de parenthèses

SyntaxError: EOL while scanning string literal

  1. erreurs de délimiteur de chaîne de caractères

exemples : syntaxError¶

corriger les erreurs suivantes

In [9]:
x = -1
if x > 0
    print(x," est positif")
  Cell In [9], line 2
    if x > 0
            ^
SyntaxError: expected ':'
In [10]:
def Somme(n)
    s = 0
    for i in range(5)
        s = s + i*i
    return s
  Cell In [10], line 1
    def Somme(n)
                ^
SyntaxError: expected ':'
In [11]:
x  = 2
if x = 3 :
    print(X,' est égale à 3')
  Cell In [11], line 2
    if x = 3 :
       ^
SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?
In [12]:
s =0.5
x = round(2*(s+1)
print("x=",x)
  Cell In [12], line 2
    x = round(2*(s+1)
             ^
SyntaxError: '(' was never closed
In [13]:
message = "Python est facile à apprendre
print(message)
  Cell In [13], line 1
    message = "Python est facile à apprendre
              ^
SyntaxError: unterminated string literal (detected at line 1)

Erreur de type¶

TypeError: 'list' object is not callable

TypeError: 'numpy.ndarray' object is not callable

utilisation de ( ) à la place de [ ] dans une liste ou un tableau numpy

IndexError: index 3 is out of bounds for axis 0 with size 3

IndexError: list index out of range

utilisation d'un indice en dehors des limites d'une liste ou d'un tableau

TypeError: 'int' object is not iterable

utilisation d'un entier à la place d'une liste ou d'un tableau (itérable)

exemples : TypeError¶

corriger les erreurs suivantes

In [14]:
X = [ 1, 2, 3 ]
X(0)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In [14], line 2
      1 X = [ 1, 2, 3 ]
----> 2 X(0)

TypeError: 'list' object is not callable
In [15]:
X = np.array([1,2,3])
X(0)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In [15], line 2
      1 X = np.array([1,2,3])
----> 2 X(0)

TypeError: 'numpy.ndarray' object is not callable
In [16]:
X = np.array([1,2,3])
X[3]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Cell In [16], line 2
      1 X = np.array([1,2,3])
----> 2 X[3]

IndexError: index 3 is out of bounds for axis 0 with size 3
In [17]:
X = [ 1, 2, 3 ]
X[3]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Cell In [17], line 2
      1 X = [ 1, 2, 3 ]
----> 2 X[3]

IndexError: list index out of range
In [18]:
for i in 8:
    print(i)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In [18], line 1
----> 1 for i in 8:
      2     print(i)

TypeError: 'int' object is not iterable

autres exemples¶

ValueError                                Traceback (most recent call last)
<ipython-input-83-b474eb3d7114> in <module>
      8       cours_id.append(cours_info[0].strip())
      9       cours_titre.append(cours_info[1].strip())
---> 10       cours_ects.append(int(cours_info[2].strip()))
     11       cours_semestre.append(int(cours_info[3].strip()))

 ValueError: invalid literal for int() with base 10: '6 ECTS'

Erreur d'entrée/sortie ES¶

OSError: file not found

FileNotFoundError: [Errno 2] No such file or directory

PermissionError: [Errno 13] Permission denied:

on essaye de lire des données dans un fichier qui n'existe pas, ou on a pas les droits d'accès au contenu du ficgier en lecture ou en écriture

exemples : IOError¶

corriger les erreurs suivantes

In [19]:
Tab=np.random.rand(4,5)
np.savetxt('test.dat',Tab)
F1 = open('Test.dat')
F1.close()
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
Cell In [19], line 3
      1 Tab=np.random.rand(4,5)
      2 np.savetxt('test.dat',Tab)
----> 3 F1 = open('Test.dat')
      4 F1.close()

FileNotFoundError: [Errno 2] No such file or directory: 'Test.dat'
In [20]:
Tab1 = np.loadtxt('Test.dat')
---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
Cell In [20], line 1
----> 1 Tab1 = np.loadtxt('Test.dat')

File ~/venvs/jupyter/lib/python3.10/site-packages/numpy/lib/npyio.py:1318, in loadtxt(fname, dtype, comments, delimiter, converters, skiprows, usecols, unpack, ndmin, encoding, max_rows, quotechar, like)
   1315 if isinstance(delimiter, bytes):
   1316     delimiter = delimiter.decode('latin1')
-> 1318 arr = _read(fname, dtype=dtype, comment=comment, delimiter=delimiter,
   1319             converters=converters, skiplines=skiprows, usecols=usecols,
   1320             unpack=unpack, ndmin=ndmin, encoding=encoding,
   1321             max_rows=max_rows, quote=quotechar)
   1323 return arr

File ~/venvs/jupyter/lib/python3.10/site-packages/numpy/lib/npyio.py:955, in _read(fname, delimiter, comment, quote, imaginary_unit, usecols, skiplines, max_rows, converters, ndmin, unpack, dtype, encoding)
    953     fname = os.fspath(fname)
    954 if isinstance(fname, str):
--> 955     fh = np.lib._datasource.open(fname, 'rt', encoding=encoding)
    956     if encoding is None:
    957         encoding = getattr(fh, 'encoding', 'latin1')

File ~/venvs/jupyter/lib/python3.10/site-packages/numpy/lib/_datasource.py:193, in open(path, mode, destpath, encoding, newline)
    156 """
    157 Open `path` with `mode` and return the file object.
    158 
   (...)
    189 
    190 """
    192 ds = DataSource(destpath)
--> 193 return ds.open(path, mode, encoding=encoding, newline=newline)

File ~/venvs/jupyter/lib/python3.10/site-packages/numpy/lib/_datasource.py:533, in DataSource.open(self, path, mode, encoding, newline)
    530     return _file_openers[ext](found, mode=mode,
    531                               encoding=encoding, newline=newline)
    532 else:
--> 533     raise FileNotFoundError(f"{path} not found.")

FileNotFoundError: Test.dat not found.
In [ ]:
F1 = open('/etc/sudoers')

Points clés¶

Les messages de "TRaceBack" peuvent sembler intimidants, mais ils nous donnent beaucoup d'informations utiles sur ce qui n'a pas fonctionné dans notre programme, y compris où l'erreur s'est produite et de quel type d'erreur il s'agissait.

  • Une erreur liée à la syntaxe du programme est appelée SyntaxError.

  • Si le problème est lié à la façon dont le code est indenté, il sera alors appelé IndentationError.

  • Une erreur NameError se produira si vous utilisez une variable qui n'a pas été définie (soit parce que vous vouliez utiliser des guillemets autour d'une chaîne, vous avez oublié de définir la variable, ou vous venez de faire une faute de frappe).

  • Les listes, les dictionnaires ou les tableaux généreront des erreurs si vous essayez d'accéder à des éléments qui n'existent pas. Pour les listes ou les tableaux, ce type d'erreur est appelé IndexError pour les dictionnaires, cela s'appelle une KeyError.

  • Essayer de lire un fichier qui n'existe pas vous donnera une erreur IOError. Essayer de lire un fichier ouvert en écriture, ou écrire dans un fichier ouvert en lecture, vous donnera également une erreur IOError.

Erreurs algorithmiques¶

L'erreur algorithmique consiste à utiliser la mauvaise méthode (algorithme) pour résoudre le problème en utilisant un programme sans erreurs de syntaxe. Seule une analyse du problème avec des tests et des validations permettra de trouver ce type d'erreur.

Exemple 1¶

Calcul de la somme des carrés des nombres entiers de 1 à 10

Trouvez l'erreur ou les erreurs dans les programmes suivants

In [21]:
for i in range(10):
    somme = 0
    somme = somme + i**2
In [24]:
print("somme des carrés de 1 a 10: ",somme)
somme des carrés de 1 a 10:  81

Exemple 2¶

Calcul du produit des nombres entiers de 1 à 10

Trouvez l'erreur ou les erreurs dans les programmes suivants

In [23]:
prod = 1
for i in range(10):
    prod = prod*i
In [25]:
print("produit des entiers de 1 à 10: ",prod)
produit des entiers de 1 à 10:  0

Exemple 3¶

Ecrire une fonction qui calcule le produit des carrés des n premiers entiers strictement positifs

In [28]:
def produit(n):
    prod = 1
    for i in range(n):
        prod = prod*(i+1)**2
    print(prod)
In [29]:
p3 = produit(3)
print("produit des carrées des 3 premiers entiers :",p3)
36
produit des carrées des 3 premiers entiers : None

Exemple 4¶

Calcul de la somme des valeurs d'une liste

In [30]:
L = [1,2,3,4,5]
somme = 0
for i in range(5):
    somme = somme + i
In [31]:
print("somme de la liste:",somme)
somme de la liste: 10

Exemple 5¶

  • algorithme faux qui marche à peu près !!!!
  • trouvez l'erreur
In [32]:
# fonction a écrire
def func(chaine):
    ''' renvoie une chaîne contenant les 2 premiers et 2 derniers caractères,
         ou une chaine vide si la longueur est < a 2 '''
    resultat = chaine[0]+chaine[1]+chaine[-2]+chaine[-1]
    if len(chaine)<2:
        return ""
    else:
        return resultat
func('BonJOUR')
Out[32]:
'BoUR'
In [33]:
func("B")
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Cell In [33], line 1
----> 1 func("B")

Cell In [32], line 5, in func(chaine)
      2 def func(chaine):
      3     ''' renvoie une chaîne contenant les 2 premiers et 2 derniers caractères,
      4          ou une chaine vide si la longueur est < a 2 '''
----> 5     resultat = chaine[0]+chaine[1]+chaine[-2]+chaine[-1]
      6     if len(chaine)<2:
      7         return ""

IndexError: string index out of range

Exemple 6¶

  • attention boucle infinie:
  • trouvez l'erreur
In [34]:
# ajoute l'élément 8 à malist
malist = [1, 2, 3, '4', [5, 'six'], [7]]
for i in malist:
    malist.append(8)
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
Cell In [34], line 4
      2 malist = [1, 2, 3, '4', [5, 'six'], [7]]
      3 for i in malist:
----> 4     malist.append(8)

KeyboardInterrupt: 
In [35]:
malist
Out[35]:
[1,
 2,
 3,
 '4',
 [5, 'six'],
 [7],
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 8,
 ...]

FIN¶