Mission 7

Mission 7

Le but de cette mission est de contribuer à un outil qui permet un utilisateur de chercher répétitivement dans un fichier de texte.

Il faut implementer les fonctions suivantes dans un fichier search.py et vérifier que ces fonctions sont correctes:

  • La fonction readfile(filename) avec la spécification suivante:

    def readfile ( filename ):
        """ Crée une liste des lignes contenues dans un fichier dont le nom est ``filename``
    
        Args:
            filename: le nom d'un fichier de texte
        Retourne:
            une liste dans laquelle chaque ligne du fichier filename est un élément.
            Si filename n'existe pas, la fonction retourne une liste vide.
        """
    
  • La fonction get_words(line) avec la spécification suivante:

    def get_words ( line ):
        """ pour une chaîne de caractères donnée, retourne une liste des mots dans la chaîne,
            en minuscules, et sans ponctuation, dans l'ordre d'apparence dans le texte.
            Par exemple, pour la chaîne de caractères
    
            "Turmoil has engulfed the Galactic Republic. The taxation of trade routes
            to outlying star systems is in dispute."
    
            Le résultat est
    
            ["turmoil", "has", "engulfed", "the", "galactic", "republic", "the",
            "taxation", "of", "trade", "routes", "to", "outlying", "star", "systems",
            "is", "in", "dispute" ]
    
            Un caractère est considéré comme une ponctuation si ce n'est pas une
            lettre, selon la fonction string.isalpha () .
    
        Args:
            line: une chaîne de caractères.
        Retourne:
            une liste des mots dans la chaîne, en minuscules, et sans ponctuation.
        """
    

    Ici, vous pouvez utiliser la méthode string.isalpha(); un exemple de l'utilisation de cette méthode se trouve ci-dessous:

    text = "a.b"
    r = ""
    for c in text:
      if c.isalpha ():
        r += c
    print(r)
    
  • La fonction create_index(filename) avec la spécification suivante:

    def create_index ( filename ):
        """ crée un index pour le fichier avec nom ``filename``. L'index se compose
            d'un dictionnaire dans lequel pour chaque mot du fichier ``filename``
            on retrouve une liste des indices des lignes du fichier qui contiennent
            ce mot.
    
            Par exemple, pour un fichier avec le contenu suivant:
    
              While the Congress of the Republic endlessly debates
              this alarming chain of events, the Supreme Chancellor has
              secretly dispatched two Jedi Knights.
    
            Une partie de l'index, representé comme dictionnaire, est:
    
    
              {"while": [0], "the": [0,1], "congress": [0], \
               "of": [0,1], "republic": [0], ... , "jedi": [2], ...}
    
        Args:
            filename: une chaîne de caractères
        Retourne:
            un dictionnaire avec pour chaque mot du fichier (en minuscules)
            la liste des indices des lignes qui contiennent ce mot.
        """
    

    Cette fonction doit utiliser les fonctions get_words et readfile.

  • La fonction get_lines(words,index) avec la spécification suivante:

    def get_lines ( words, index ):
       """ Détermine les lignes qui contiennent tous les mots indexes dans ``words``,
           selon l'index ``index``.
    
           Par exemple, pour l'index suivant:
    
             index = {"while": [0], "the": [0,1], "congress": [0], \
                      "of": [0,1], "republic": [0], ... , "jedi": [2], ...}
    
           La fonction retourne
             get_lines(["the"]) -> [0,1]
             get_lines(["jedi"]) -> [2]
             get_lines(["the","of"],index) -> [0,1]
             get_lines(["while","the"],index) -> [0]
             get_lines(["congress","jedi"]) -> []
             get_lines(["while","the","congress"]) -> [0]
    
       Args:
           words: une liste de mots, en minuscules
           index: un dictionnaire contenant pour mots (en minuscules) des listes de nombres entiers
       Retourne:
           une liste des nombres des lignes contenant tous les mots indiqués
       """
    

    Commencez par faire cette fonction uniquement pour les listes avec un mot; dans ce cas, l'outil marche au moins quand l'utilisateur spécifie un seul mot. Essayez de modifier cette fonction pour les listes plus longues ensuite.

    Plusieurs approches sont possible pour calculer le résultat de get_lines() pour des listes de mots plus longues. Une possibilité est de traverser la liste associé au premier mot, et de vérifier si on trouve dans ces lignes aussi les autre mots, en utilisant l'index de chaque mot.

De nouveau, les fonctions ci-dessus doivent être mises en oeuvre dans un fichier search.py.

L'outil est implementé dans un fichier utility.py, qui importe le fichier search.py. Voici le code de utility.py, que vous pouvez soumettre sans le modifier:

import search

filename = input ("Spécifiez le nom de fichier: ")
index = search.create_index ( filename )
while True:
  words = input ("Spécifiez les mots a rechercher, en utilisant des espaces entre les mots: ")
  lines = search.get_lines ( words.strip().split(), index )
  print("Les mots se retrouvent dans ces lignes:")
  for line in lines:
    print(line)

Autrement dit, après avoir demandé le nom d'un fichier, dans une boucle, l'interface demande à l'utilisateur de donner une liste de mots; chaque fois, l'outil cherche les lignes dans lesquelles les mots spécifiés sont présents, et imprime ces lignes. Votre tâche principale est de vous assurer que l'outil fonctionne correctement, en mettant en oeuvre les fonctions dans le fichier search.py.

Pour vous aider, vous trouverez un exemple de texte episodeIV_dialogues.txt.

Créez les fonctions dans l'ordre spécifié. Si vous n'arrivez pas à terminer toutes les fonctions, soumettez les fonctions que vous avez réussi à terminer.

Pour assurer que l'outil marche correctement, vous devez ajouter des tests pour vérifier que les fonctions sont correctes; par exemple, les tests pour la fonction get_words doivent être mis dans une fonction test_get_words. Puisque vous devez tester une fonction qui lit un fichier, créez des petits fichiers pour tester cette fonction; il faut soumettre ces fichiers de texte aussi.

Les tests doivent être mis dans un fichier test.py qui importe search.py. Un petit exemple du contenu du fichier test.py est:

import search


def test_get_words ():
  assert search.get_words ( "Turmoil has engulfed the Galactic Republic." ) == ["turmoil", "has", "engulfed", "the", "galactic", "replic"], "Petit exemple donné"

test_get_words ()

Si vous le souhaitez, vous pouvez étendre l'outil même, par exemple, pour montrer les lignes au lieu des nombres des lignes. Dans ce cas vous pouvez modifier le code du fichier utility.py. Indiquez ceci dans le commentaire de utility.py.

Remise de votre solution

Pour cette mission, vous devez soumettre:

  • un fichier search.py ;
  • un fichier utility.py (éventuellement non modifié en comparaison avec le code donné ci-dessus);
  • un fichier test.py avec les tests (qui étendent l'exemple donné ci-dessus);
  • 2 petits fichiers de texte que vous utilisez dans vos tests
  • un fichier README
You cannot see this exercise because you are currently not logged in. Click here to log in or get a direct access to the exercice on INGInious by following this link.

Page précédente Page suivante