1. Lecture dans un fichier

Pour lire un fichier

  • On utilise la fonction built-in open qu accepte deux arguments qui sont le chemin d'accès et le type d'accès et qui sort un handle sur le fichier (essentiellement c'est le fichier sauf que l'on peut avoir plusieurs plusieurs handle sur le même fichier).
  • Pour le chemin on utilisera un chemin relatif au script courant (du type "fichier.txt" si fichier.txt et votre script sont dans le même dossier) mais alors il faut appuyer sur Ctrl-Shift-E (surtout pas Ctrl-E) car sinon le répertoire courant de la console («de pizo») peut ne pas correspondre à celui du dossier contenant votre script (sic!).
  • le type d'accès est "r" (read) pour un accès en lecture et "w" (write) pour un accès en écriture (et sous windows on peut ajouter un "b" pour un accès binaire…)
  • on mettra le tout dans un "bloc with" qui s'occupe de fermer le fichier quand on sort du bloc.
  • les handles sur les fichiers

    Commencer par télécharger ce fichier dans votre dossier pour ce TP. Ce fichier ressemble les délais et durée d'éruption d'un geyser (appelé old faithful) on supposera que la variable old_faithful_fpath contient le chemin d'accès vers ce fichier c'est à dire si vous avez enregistré ce fichier dans le dossier de votre TP à côté de vos script

    1. Ouvrir de fichier avec le bloc note (pas avec un logiciel de traitement de texte) pour voir à quoi il ressemble (remarquer que la première ligne est à part).
    2. Éxecuter le script suivant et vérifier que vousle comprenez

      def first_n_lines(n, fpath):
          with open(fpath, "r") as f:
              i = 0
              for line in f:
                  i += 1
                  print("- :", line)
                  print("----------")
                  if i > n:
                      return  # agit par effet de bord
      
      first_n_lines(4, old_faithful_fpath)
      
    3. Compléter le script suivant afin qu'il affiche le nombre de lignes du fichier

      def nbr_of_lines(fpath):
          nbr_of_lines = ??
          with open(fpath, "r") as f:
              for line in f:
                  ??
          ??
      
      n = nbr_of_lines(old_faithful_fpath)
      print(n)
      
    4. Une ligne d'un fichier est dite commentée si elle commence par un dièse "#" (et elle devra dans la suite être ignorée). Compléter le script suivant afin que la fonction nommée pair_commented_and_not retourne un couple d'entier avec dans l'ordre le nombre de lignes commentée et le nombre de lignes non commentées

      def pair_commented_and_not(fpath):
          ??
          with open(fpath, "r") as f:
              for line in f:
                  if line[0] ??
          ??
      
      nb_com, nb_not_com  = pair_commented_and_not(old_faithful_fpath)
      print(nb_com, nb_not_com)
      
    5. La méthode split du type str (string) permet de scinder une chaîne de caractères en sous-chaîne séparées par un séparateur (aussi de type string) passé en arguments.
      1. Vérifier que vous comprenez ce que fait le script suivant et modifier les lignes assert (plus précisément seulement la partie à droite du ==) afin qu'elles ne provoquent plus d'erreur

        chaine = "01/02/2048-12:03"
        
        date_as_str, time_as_str = chaine.split("-")
        assert type(date_as_str) == int
        
        date_as_list =  date_as_str.split("/")
        assert type(date_as_list) == str
        
      2. Parmi les expressions "10"+5, int("10.3")+5, "10.3"+5, float("10.3")+5 une seules deux ne provoquent pas d'erreur. Pourquoi?
      3. Vérifier que le script suivant provoque une erreur puis debogguer ce script.

        def anne_suivante(chaine_date):
            date_as_str, time_as_str = chaine_date.split("-")
            date_as_list =  date_as_str.split("/")
            year = date_as_list[?]
            return year+1 # À modifier
        
        next_year = anne_suivante("01/02/2048-12:03")
        print(next_year)
        
      4. Écrire un script qui affiche la moyenne des durées et des délais entre les éruptions de ce geyser. Vous devriez trouver dans l'ordre

        3.4877830882352936 70.8970588235294
        
      5. Commencer par executer le script suivant pour comprendre le fonctinnement de la fonction plt du module pyplot du paquet matplotlib et vérifier que vous obtenez un affichage similaire à l'image ci-dessous (il faut choisir tornado dans la connfiguration du shell dans pyzo pui relancer la console pour que cela prenne effet)

        import matplotlib.pyplot as plt
        
        # Maintenant si X est une liste d'abscisses et Y une liste d'ordonnées
        # (de même longueur!) alors la ligne
        # plt.plot(X, Y)
        # suivie de (à ne pas oublier!)
        # plt.show()
        # affiche les points de coordonnées données
        
        X = [1, 2, 3, 4, 1, 2]
        Y = [5, 5, 6, 0, 1, 4]
        
        plt.plot(X, Y, "x") # "x" pour une croix sans relier les points
        plt.show()
        
        3bcbfbe17847229079f1d95f25d1344e346bb270.png
      6. Compléter le script suivant afin qu'il affiche le délai en fonction de la durée des éruptions. Voux devez obtenir un affichage similaire à l'image ci-dessous. Interpréter.

        import matplotlib.pyplot as plt
        
        X, Y = [], []
        with open(old_faithful_fpath, "r") as f:
            for line in f:
                if not line[0] == "#":
                    vals_list = line.split(??)
                    num1, num2 = ??
                    X.append(??)
                    Y.append(??)
        
        plt.plot(X, Y, "x")
        plt.show()
        
        49be13544938c1ea241fd7b1aaa27928a8108314.png
      7. Sachant que plt.plot(X, Y, "xr") affiche des croix rouges et plt.plot(X, Y, "xb") des croix bleues. Afficher alors en rouge les points (correspondant à une éruption) plus proches de \(M_{1}=(2,50)\) que de \(M_{2}=(4.5,80)\) et les autres en bleu.

        8323e1c641be0ce14fe7431d157ec0fe228452bd.png
      8. On souhaite classer automatiquement les données précédentes en deux groupes (deux clusters). Pour cela on part de deux points de coordonnées (donc dans l'ordre durée et délai de l'éruption) M1=(20,50) et M2=(45,80) qui seront les barycentres () de nos groupes (clusters).

        • on fait deux listes d'éruptions (représentées seulement par le point dont les coordonnées sont dans l'ordre la durée et le délai de l'éruption) suivant qu'ils ont en distance plus proche de M1 ou de M2.
        • on remplace M1 et M2 par la barycentre du groupe de points qui lui sont le plus proches (que l'on a déterminés à la question précédente).
        • On reprend au premier point ci-dessus
        • on s'arrête soit après une certain nombre d'itération (plus simple) soit quand les barycentres ne bougent plus beaucoup.

        Implémenter cet algorithme avec le critère d'arrêt de voter choix

        46ffc6d3dd0b996abf05c31452da239db667f0ce.png

Auteur: Aurélien Bosché

Created: 2023-12-08 Fri 20:03

Validate