CSV code

Résolu

Hello ! 

J'ai écrit un programme qui lit un fichier csv. Mais lors de son exécution, j'ai l'erreur suivante :

line 23, in decode
    return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x9d in position 16: character maps to <undefined>

Voici le code :

import csv

contenu = csv.reader(open('eleve.csv'), delimiter=';')
new_tab = []

for row in contenu:
    new_tab.append(row)
    
with open("nv_fichier.csv", "w", newline='') as csvfile:
    New = csv.writer(csvfile)
    New.writerow(new_tab[0])
    
    for row in new_tab:
        if row[0][0] == "N" or row [0][0] == "B" or row[0][0] == "Z" :
            continue
        if row[1] == "M" and row[2] == "16":
            continue 
        elif [3] != "Externe":
            continue
        elif row[4] == "1re7":
            continue
        else:
            New.writerow(row)

Est-ce que quelqu'un pourrait me dire ce qui ne va pas ? Est-ce que c'est sensé afficher dans le nv_fichier.csv ?


Merci

6 réponses

  1. Modérateur

    Bonjour,

    Merci pour le fichier csv #8. Je peux maintenant tester ton programme #0.

    La lecture est correct. Tu peux ajouter ligne 8 :

    print(new_tab)

    ... pour t'en convaincre. Le programme produit un fichier nv_fichier.csv qui contient :

    ABDOU,M,16,Externe,1re7

    (je ne sais pas si c'est ce que tu veux).

    Comme tu peux le voir je n'ai pas d'erreur. Cependant ton message d'erreur me laisse penser que ton fichier est stocké sous une forme bizarre (pourquoi en Unicode alors que de l'ASCII suffit). Je suspecte donc que comme jouat l'évoque #3, ton fichier unicode contient des caractères invisibles bizarre.

    Mon conseil serait donc le suivant : comme moi, crée un fichier csv (ASCII) dans ton bloc note, puis copie-colle dedans ce que tu as reporté dans ton message #8.

    Ensuite, comme Pierrot #1 l'a indiqué, le test ligne 18 est incorrect (tu compares la liste [3] avec la chaîne de caractère "Externe" et donc ce test est toujours faux), tu voulais sans doute écrire :

        elif row[3] == "Externe":

    Bonne chance

    1
    1. ça y est je l'ai testé; a fonctionne, merci !

      0
  2. Cette ligne n'est pas correcte:
            elif [3] != "Externe":
    L'erreur dit qu'il y a un caractère invalide sur une de tes lignes du fichier d'entrée en position 16.
    À toi de voir ce qu'il y a dans ce fichier dans cette position.

    0
    1. Merci pour ta réponse :)

      Mais jvois pas l'erreur :((

      Ca c'est le fichier eleve.csv sur Excel - ca veut dire que y aurait une erreur à la ligne 16 ?

      0
      1. Salut, tu peux constater que le nom contient un espace, et c'est ce caractère qui pose problème, cela ne doit pas être un espace "standard', remplace ce caractère qui n'est pas reconnu et conforme par un simple espace.

        Comment a été généré ce csv ? C'est un espace insécable ? Un caractère propre à excel ?

        0
      2. Modérateur
        @jouat

        Bonjour,

        Peux-tu copier coller le contenu de ton fichier csv plutôt que de mettre une capture d'écran en le partageant comme expliqué ici ? Cela sera plus pratique pour tout le monde, plus écologique, et nous permettra de reproduire ton problème et de mieux en comprendre la cause.

        0
    2. ABDOU;M;16;Externe;1re7
      ABOU;M;16;Demi-pensio;1re4
      ALLA;F;16;Externe;1re7
      AMANZ;M;16;Demi-pensio;1re8
      ASSIA;F;16;Demi-pensio;1re5
      BARBOT;M;16;Externe;1re3
      BASSAN;M;16;Externe;1re4
      BEN SALAH;M;16;Demi-pensio;1re8
      BERNARDI;F;16;Demi-pensio;1re98
      BOUAK;F;16;Externe;1re7
      BOULAIN;M;16;Demi-pensio;1re9
      BOUSSER;M;16;Externe;1re10
      BRETON;F;16;Demi-pensio;1re11
      COPIN;M;16;Demi-pensio;1re12
      D'ONGU;M;16;Demi-pensio;1re7
      DEFURIO;M;16;Demi-pensio;1re14
      DONIO;M;17;Demi-pensio;1re7
      ELBAZ;F;16;Demi-pensio;1re16
      FASSY;M;16;Demi-pensio;1re17
      FODHI;M;16;Externe;1re7
      GALIEN;F;17;Externe;1re19
      GOLFIN;M;16;Demi-pensio;1re20
      GOUCEM;F;16;Demi-pensio;1re21
      JACQUELIN;M;16;Demi-pensio;1re22
      JOLIBERT;M;16;Demi-pensio;1re23
      JUBERT;F;16;Demi-pensio;1re24
      KAZAN;M;16;Demi-pensio;1re25
      LECOU;M;16;Demi-pensio;1re26
      LOPATO;M;16;Demi-pensio;1re27
      LOUREI;M;16;Demi-pensio;1re28
      LOVISO;M;15;Demi-pensio;1re29
      MAGDE;M;16;Demi-pensio;1re30
      MELYON;F;15;Demi-pensio;1re7
      MEYER;M;16;Demi-pensio;1re32
      MITT;M;15;Demi-pensio;1re33
      OLIVER;M;16;Demi-pensio;1re34
      PASTORE;M;16;Demi-pensio;1re35
      PIDERRE;F;16;Externe;1re36
      PILAT;M;15;Demi-pensio;1re37
      PONSONNAILLE;F;16;Demi-pensio;1re38
      RAUV;M;16;Demi-pensio;1re39
      REN;M;17;Demi-pensio;1re33
      SZWED;M;16;Demi-pensio;1re34
      THOMAS;M;16;Demi-pensio;1re35
      TO;M;16;Demi-pensio;1re36
      TOUIL;M;16;Externe;1re37
      VU;F;16;Externe;1re38
      ZHANG;M;16;Demi-pensio;1re39
      ZHANG;F;16;Demi-pensio;1re40
      ZHENG;F;17;Demi-pensio;1re41
      ZHENG;M;17;Externe;1re7
      ZURCHER;M;16;Demi-pensio;1re43
      
      0
      1. d'accord merci :)

        Oui je vais tester comme vous me l'avez conseillez (merci !!)

        Oui je trouve aussi que la ligne 18 est bizarre, mais c'est le code que j'ai sur mon document :(

        A vrai dire, j'ai décidé de tester ce code avec les fichiers csv pour vérifier que ma réponse et celle qu'allait me donner le nouveau fichier csv correspondraient. Le truc c'est que tu me dis que y a qu'un seul nom qui sort; mais la question du doc est la suivante "le script en question va créer un nouveau fichier CSV, on peut voir le fichier vide en annexe (c'est un simple tableau avec plusieurs lignes), remplissez le document en fonction des informations données dans le script"

        J'avais effectivement pensé que la condition remplie serait la 2e mais donc c'est bizarre. Est ce que tu penses que je devrais mettre juste la ligne que t'as écrite, ou plutôt les lignes qui correspondent à la 2e condition ?

        0
        1. jpense que je vais juste mettre 

          ABDOU,M,16,Externe,1re7

          Merci  beaucoup !!!!

          0
        2. Modérateur
          @Utilisateur anonyme

          Le code tel qu'il est écrit ignore :

          • les lignes dont le nom commence par N, B ou Z (l14)
          • les lignes dont le nom a pour seconde lettre M et  pour âge 16 (l16)
          • le test ligne 18 ne filtre rien
          • les lignes dont la quatrième colonne est 1re7 (l20)

          Tu peux donc faire l'exercice à la main en rayant sur l'énoncé de ton exercice (ou en supprimant au fur et à mesure de ton fichier csv) les élèves ainsi ignorés. Apparemment, seul ABDOU n'est pas filtré.

          Bonne chance

          1
      2. j'ai une toute toute dernière question (merci :)

        quand dans un code t'as deux if et puis deux elif qui se suivent (comme là) est ce que ce sont les 2 if qui sont pris en compte ou c'est où l'un où l'autre et pareil pour les elif ? (je sais pas si c'est très clair)

        0
        1. Modérateur

          Bonjour,

          Le mot clé else / elif (elif est une contraction de else if) se rapporte toujours au if / elif qui est au même niveau d'indentation et qui le précède immédiatement.

          Si on reprend le code partagé dans ton message initial :

          • Le else (l22) est évalué si et seulement si le elif (l20) est faux, qui lui-même est évalué si et seulement si le elif (l18) est faux, qui lui-même est évalué si et seulement si le if (l16) est faux.
          • À cause du continue (l15), si le test if (l14) est vrai, alors le code à partir de la ligne (16) ne sera pas considéré. Si à la place de continue (l15) on avait disons un print, alors peu importe le résultat du test if (l14), le test if (l16) est évalué.

          En conséquence, un elif est considéré si et seulement si l'ensemble des tests qui le précèdent dans ton bloc [if ... elif ... elif ...] sont tous faux. Note que l'ordre des tests est important.

          Prenons deux exemples :

          • Ici on rentre dans le if, donc le programme affiche "> 2". On voit au passage que l'on rentre dans le else si et seulement si le if et le elif sont faux. Dit autrement, les if et elif précédent permettent de restreindre progressivement à quel ensemble x appartient.
          x = 3
          if x > 2:
              print("> 2")
          elif x >= 2:
              print(">= 2")
          else:
              print("< 2")
          • Ici le programme affiche >= 2 et quelque soit la valeur de x, on ne peut jamais rentrer dans le elif. En effet, si x > 2, alors a fortiori x >= 2 et on rentre dans le if. Si x < 2, on ne rentre bien évidemment pas dans le elif.
          x = 3
          if x >= 2:
              print(">= 2")
          elif x > 2:
              print("> 2")
          else:
              print("< 2")

          Ces deux exemples mettent en évidence que l'ordre dans lequel on fait les tests est important, car on a juste permuté les tests effectués dans le if et le elif, et pourtant le comportement de ces deux programmes diffère.

          Bonne chance

          1