<string>

<string>

Table des matières

Mission 4 - Strings et listes

Mission 4 : Strings et listes

Mission 4 : Strings et listes

Introduction

Une étudiante en biologie que vous venez de rencontrer vous demande de l'aide pour un problème de bioinformatique. Grâce aux progrès des techniques de séquençage automatiques de l'ADN, il est maintenant facile d'obtenir l'ADN d'un être vivant. L'ADN est composé de quatre types de bases : Adénine, Cytosine, Guanine et Thymine. Pour manipuler ces séquences ADN, les biologistes ont pris l'habitude de les représenter sous la forme d'une (longue) suite de caractères représentants les 4 bases qui forment l'ADN. A titre d'exemple, voici un extrait de séquence ADN provenant de la base de données GenBank:

LOCUS       SCU49845     5028 bp    DNA             PLN       21-JUN-1999
DEFINITION  Saccharomyces cerevisiae TCP1-beta gene, partial cds, and Axl2p
            (AXL2) and Rev7p (REV7) genes, complete cds.
...

ORIGIN
        1 gatcctccat atacaacggt atctccacct caggtttaga tctcaacaac ggaaccattg
       61 ccgacatgag acagttaggt atcgtcgaga gttacaagct Aaaacgagca gtagtcagct
      121 ctgcatctga agccgctgaa gttctactaa gggtggataa catcatccgt gcaagaccaa
      181 gaaccgccaa tagacaacat atgtaacata tttaggatat acctcgaaaa taataaaccg
      241 ccacactgtc attattataa ttagaaacag aacgcaaaaa ttatccacta tataattcaa
      301 agacgcgaaa aaaaaagaac aacgcgtcat agaacttttg gcaattcgcg tcacaaataa
...
     4861 ttctccactt cactgtcgag ttgctcgttt ttagcggaca aagatttaat ctcgttttct
     4921 ttttcagtgt tagattgctc taattctttg agctgttctc tcagctcctc atatttttct
     4981 tgccatgact cagattctaa ttttaagcta ttcaatttct ctttgatc

Une séquence d'ADN d'un gène peut être très longue. A titre d'exemple, on estime que l'ADN humain contient de l'ordre de 3 × 109 bases découpées en environ 20.000 gènes. L'ADN d'une bactérie contient de l'ordre de 4 millions de bases. Les biologistes ont séquencé l'ADN d'un grand nombre d'espèces qu'ils stockent dans des bases de données spécialisées comme GenBank. Le traitement de toutes ces données a mené à la création de la bio-informatique, discipline qui rassemble des biologistes et des informaticiens.

Afin d'aider cette étudiante en biologie, vous allez écrire durant cette mission vos premiers algorithmes de bio-informatique.

Objectifs

Objectifs individuels

A l'issue de ce problème, chacun d'entre vous :

  • sera en mesure d'être de plus en plus précis sur certains concepts sous-jacents à un programme Python simple (après une quatrième prise de connaissance) :
    • chaînes de caractères
    • listes
    • fonctions qu'on peut appliquer sur chaînes et listes
    • création de listes imbriquées
  • aura montré une capacité à écrire des méthodes permettant de manipuler des chaînes de caractères et des listes.

Préparation, étude et apprentissage

La matière relative à cette mission est décrite dans les sections suivantes du syllabus :

Il est cependant important que vous puissiez facilement vous y retrouver dans la documentation de Python pour y trouver les renseignements dont vous avez besoin pour écrire des programmes efficaces. Pour des fonctions qui peuvent être exécutées sur des chaînes de caractères, regardez ici.

Questionnaire de démarrage

Questions à choix multiple

Les questions à choix multiples de cette mission sont également accessibles en ligne depuis https://inginious.info.ucl.ac.be/course/LSINF1101-PYTHON/Session4_QCM


        
        

Question 1

Vous voulez dire bonjour à l'utilisateur de votre programme. Le nom de l'utilisateur est enregistré dans une variable appelée name et vous voulez enregistrer vos salutations dans une variable nommée hello. Cette chaine de caractères aura la forme suivante : "Hello, name!"

Par exemple, si "Charles" est assigné à name, votre code écrirait "Hello, Charles!" dans la variable hello.


        
        

Question 2

Dans le programme ci-dessous, quelle ligne faut-il écrire pour afficher la longueur de la chaîne de caractères s ?

s = "Informatique1"

Question 3

Dans le programme ci-dessous, quelle ligne faut-il écrire pour afficher la chaîne en majuscules ?

s = "Informatique1"
.

Question 4

Etant donnée une chaîne de caractères stockée dans un variable l, par exemple, l = "louvain-la-neuve" ou l = "braine-le-compte", comment feriez-vous pour :

  • Afficher le premier caractère de l
 
 

  • Afficher le premier caractère de l en majuscule
 
 

  • Afficher toute la chaîne sauf le premier caractère
 
 

  • Afficher la chaîne avec le premier caractère en majuscule (sur les exemples, "Louvain-la-neuve" et "Braine-le-compte")
 
 

  • Afficher une liste des positions des traits d'union (sur les exemples, [7,10], [6,9])
 
 
 
 

  • Afficher le mot avant le premier trait d'union. (Sur les exemples, "Louvain", "Braine")
 
 
 
 

Question 4

La fonction max_index(lst) doit retourner l'index de l'élément avec la plus grande valeur dans une liste. La valeur None doit être retournée quand la liste est vide. Définissez cette fonction.


        
        

 
 
 
 

Question 5

Écrivez une fonction triangle(n) qui pour un nombre entier donné n, retourne la liste de listes imbriquées

[ [ 0 ],
  [ 0, 1 ],
  [ 0, 1, 2 ],
  ...,
  [ 0, 1, 2, ..., n ] ]


        
        

Question 6

Écrivez une fonction carre(n) qui pour un nombre entier donné n, retourne la matrice

[ [         0,             1, ...,     n - 1 ],
  [         n,         n + 1, ..., 2 * n - 1 ],
  [     2 * n,     2 * n + 1, ..., 3 * n - 1 ],
  ...,
  [ (n-1) * n, (n-1) * n + 1, ..., n * n - 1 ] ]

Par exemple, pour n=4, la fonction retourne

[ [  0,  1,  2,  3 ],
  [  4,  5,  6,  7 ],
  [  8,  9, 10, 11 ],
  [ 12, 13, 14, 15 ] ]


        
        

Question 7

Écrivez une fonction recherche ( m, v ) qui pour un nombre entier donné v, retourne True si ce nombre apparaît dans la matrice, et False si non. Par exemple, pour la matrice suivante et la valeur v=4, le résultat doit être False. Pour la valeur v=3 le résultat doit être True.

[ [  0,  3,  2,  8 ],
  [  6,  5,  2,  1 ],
  [  7,  0,  3,  2 ] ]


        
        

Question 8

Écrivez une fonction ajoute ( l, v ) qui pour une liste donnée l, ajoute le nombre v à la fin de la liste, si ce nombre n'est pas encore présent dans la liste. Si le nombre apparaît déjà, la liste doit rester non modifiée. Pour ce code:

l = [ 3, 1, 5, 4 ]
ajoute ( l, 4 )
ajoute ( l, 6 )
ajoute ( l, 7 )
ajoute ( l, 6 )
print ( l )

Le programme doit imprimer [ 3, 1, 5, 4, 6, 7 ]. La fonction ajoute ne retourne rien.


        
        

Question 9

Les nombres premiers (https://en.wikipedia.org/wiki/Prime_number) sont des nombres avec les caractéristiques suivantes:

  • ce sont des nombres plus grands que 1
  • ils n'ont pas des diviseurs autres que 1 et eux-mêmes.

Des nombres premiers sont 2, 3, 5, 7, 11, 13, ...

Pour calculer les nombres premiers on peut utiliser le crible d'Eratosthène : pour chaque nombre successif, on vérifie si on peut le diviser par un des nombres premiers déjà trouvés. Si non, on peut ajouter le nombre à la liste. Ecrivez la fonction primes(max) qui retourne une liste de tous les nombres premiers jusque max (max inclus si max est un nombre premier). Si max est négatif ou zéro, la liste vide doit être retournée.

Pour limiter la complexité de la solution, decomposez votre solution en sous-problèmes comme nécessaire; utilisez des boucles for.


        
        

Mission 4

Mission 4

Les séquences d'ADN sont composées d'un suite de caractères A, T, C et G. Pour traiter de telles séquences en Python, le plus simple est de les manipuler comme des chaînes de caractères.

Votre objectif durant cette mission est de développer quelques fonctions permettant de traiter des séquences d'ADN stockées sous la forme de chaînes de caractères.

  1. Chargez le fichier exemples.py dans la tâche sur INGInious (plus bas). Ecrivez toutes les fonctions demandées durant cette mission dans ce fichier. Vous trouverez dans ce fichier plusieurs chaînes de caractères représentants des séquences ADN que vous pouvez réutiliser pour tester vos fonctions.

  2. La première fonction à écrire est la fonction is_adn(s). Elle prend comme argument une chaîne de caractères s et retourne True si la chaîne de caractères contient uniquement les caractères a, t, c ou g (à la fois en majuscules et en minuscules) et False sinon. Une chaîne de caractères vide ("") n'est pas considérée comme étant de l'ADN.

  3. La deuxième fonction à écrire est la fonction positions(s, p). Elle prend comme arguments deux chaînes de caractères s et p. Elle retourne les positions des occurences de p dans s. Par exemple, pour ACGACCG (majuscules) et cg (minuscule) le résultat doit être [1,5]. Vous ne pouvez pas utiliser la fonction find de Python.

  4. La troisième fonction à écrire est baptisée distance_h. Elle calcule la distance de Hamming (http://fr.wikipedia.org/wiki/Distance_de_Hamming) entre deux chaînes de caractères de longueurs égales. En théorie de l'information, cette distance est définie comme étant le nombre de positions où les deux chaînes de caractères diffèrent. Voici quelques exemples qui devraient vous aider à mieux comprendre cette distance :

    Chaîne 1 Chaîne 2 Distance
    A A 0
    AG GG 1
    AG AT 1
    ATGAC ATGAC 0
    ATGAC AGGAG 2
    ATGAC TGACG 5

    Si les chaînes n'ont pas la même longueur, la fonction doit retourner None.

  5. La quatrième fonction à écrire est distances_matrice(l). Étant donné une liste de chaînes de caractères, la fonction doit calculer une matrice des distances de Hamming entre toutes ces chaînes de caractères. Par exemple, pour cette liste: ["AG", "AT", "GT", "ACG", "ACT" ] la fonction doit retourner:

    [ [     0,   1,    2, None, None ],
      [     1,   0,    1, None, None ],
      [     2,   1,    0, None, None ],
      [ None, None, None, 0,    1    ],
      [ None, None, None, 1,    0    ] ]
    

    Utilisez la fonction que vous avez écrit dans l'exercice précédente.

  6. Dans les séquences d'ADN, on retrouve parfois des palindromes. Un palindrome est un mot dont l'ordre des caractères reste le même qu'on le lise de gauche à droite ou de droite à gauche, comme "radar" ou "kayak". Une séquence ADN telle que CTAGGATC est un exemple de palindrome. A titre d'exemple, le plus long palindrome de la séquence ACCTGTTAGGATTC est TTAGGATT. Certains palindromes ont un rôle particulier d'un point de vue biologique et il est intéressant de pouvoir trouver dans une séquence donnée le plus long palindrome.

    Votre dernier objectif dans cette mission est d'écrire la fonction plus_long_palindrome qui prend comme argument une chaîne de caractères et retourne une chaîne de caractères contenant le plus long palindrome de la chaîne passée en argument. Dans cette phase de réalisation, nous considérons qu'un caractère unique est lui-même un palindrome. Lorsque la fonction ne trouve aucun palindrome dans une chaîne de caractères, elle devra retourner "".

    En Python, il existe une construction pour extended slices, qui n'a pas été discuté pendant le cours et qui n'est pas discuté dans le syllabus. Il n'est pas permis d'utiliser cette construction.

    Détecter le plus long palindrome dans une chaîne de caractères est un problème compliqué. En informatique, lorsque l'on est face à un problème compliqué, la meilleure approche pour le résoudre est de le découper en petits problèmes plus simples. Il suffit ensuite d'écrire une fonction pour résoudre chaque petit problème et de combiner ces fonctions pour résoudre le problème compliqué.

    Pour rechercher le plus long palindrome, une piste est de d'abord écrire une fonction permettant d'extraire d'une chaîne de caractères de longueur n les sous-chaînes de longueur n-1, n-2, ...

Remise de votre solution

Pour cette mission, vous devez soumettre votre fichiers bioinfo.py au serveur de soumissions de programmes du cours. Votre fichier bioinfo.py doit au moins contenir les fonctions :

is_adn(text)
positions(text,car)
distance_h(text1,text2)
distances_matrice(l)
plus_long_palindrome(text)

        
        
Questions complémentaires

Questions complémentaires

La méthode sum(list) retourne la somme des éléments contenus dans list.

Exemple: la somme de [1,2,3] est 6

Notez que votre algorithme devrait être capable de calculer la somme même si la liste list contient des éléments malicieux (pas des nombres).


        
        

La méthode average(list) retourne la moyenne arithmétique des éléments contenu dans list, sauf si list est vide auquel cas, elle devrait retourner None.


        
        

La méthode diff_count(lst) retourne le nombre d'éléments différents contenus dans la liste lst.

Par exemple:

  • Si lst est égal à [3, 5, 3] alors la méthode devrait retourner 2.
  • Si tous les éléments sont les mêmes, la méthode devrait retourner 1.
  • Si la liste lst est vide, elle devrait retourner 0.


        
        

Les équations du second degré sont des équations de la forme suivante:

$$ax^2 + bx + c = 0$$

avec a ≠ 0

Pour déterminer si l'équation dispose d'une solution, on calcule le nombre ρ = b2 − 4ac. Si ρ est strictement positif, l'équation a exactement deux solutions. La première solution s'obtient via la formule suivante :

( − b + (ρ))/(2a)

Et la seconde racine s'obtient via la formule suivante :

( − b − (ρ))/(2a)

Si ρ est nul, l'équation a exactement une solution, dont la valeur est égale à  − b ⁄ (2a). Si ρ est négatif, l'équation n'a aucune solution.

Un étudiant vous demande de l'aider à résoudre des équations à tour de bras. Vous disposez de la fonction suivante, qui est une variante de la fonction implémentée dans un exercice complémentaire de la Session 3:

def solution(a, b, c):
"""
pre:  a, b et c sont 3 nombres réels
post: la valeur de retour de cette fonction dépend du nombre
      de solutions de l'équation ax^2 + bx + c = 0.
- 0 solution: retourne la liste vide
- 1 solution: retourne une liste contenant la solution de l'équation
- 2 solutions: retourne une liste contenant les deux solutions,
              la plus petite solution en première place
"""

Écrivez la signature et le corps de la fonction solveur, dont le but est de résoudre une liste d'équations du second degré. Une équation est représentée par la liste [a, b, c]. La fonction solveur doit retourner une liste. L'élément à l'indice i de la valeur de retour contient le résultat de la fonction solution appliquée sur l'équation située à l'indice i de l'input.

Pour réussir cette exercice, vous devez utiliser une list comprehension.

Voici un exemple de la valeur de retour de la fonction solveur :

>>> solveur([])
[]

>>> solveur([[1, 1, -1], [4, 4, 1], [1, 2, 3], [-1, 2, 3]])
[[-1.618033988749895, 0.6180339887498949], [-0.5], [], [-1.0, 3.0]]


        
        

Une fois de plus, la Grosse Dame a bu tout le vin de la peinture des moines ivres et le Chevalier du Catogan n'est pas disponible pour la remplacer. L'accès à la salle commune des Gryffondor n'est pas gardée et les intentions des Serpentards sont mauvaises.

Nous avons besoin que vous conceviez un vérificateur de mot de passe pour combler le vide laisser par le départ de la Grosse Dame.

Créez une fonction portrait(right_password, entered_password) qui retourne True si les deux mots de passe sont identiques et False sinon.


        
        

Anonymous vient de vous engager sur le dark web pour une tâche dangereuse. Ils essayent de craquer un code depuis quelques jours mais ne sont arrivés à rien... pour le moment!

Ils veulent que vous construisiez une fonction qui analysera chaque caractère dans un code donné et que vous déterminiez sa nature. Le but est simple : ils ont l'intention d'utiliser les informations que vous leur fournirez pour trouver un pattern dans le code.

Créez une fonction extract(code) pour fournir des infos concernant la nature de chaque élément du code :

Par exemple, si le code 'AeB7' est donné en entrée, la fonction devrait produire 'vowel-up vowel-low consonant-up number' comme sortie. En général :

  • Ajoutez un number à la réponse si l'élément du code est un chiffre.
  • Ajoutez un vowel à la réponse si l'élément du code est une voyelle.
  • Ajoutez un consonant à la réponse si l'élément du code est une consonne.
  • Suivez cela par -up si la voyelle/consonne est en majuscule.
  • Suivez cela par -low si la voyelle/consonne est en minuscule.

Exemple :

Avec le code '65AeBc7' la fonction devrait sortir 'number number vowel-upvowel-low consonant-up consonant-up number'.


        
        

Etant donné que votre travail était remarquable, Anonymous vous a à nouveau contacté avec une autre tâches risquée. Ils manquent de main d'oeuvre et aimeraient que traitiez les données que vous leur avez donné.

Ils veulent que vous construisiez une fonction qui transformera votre précédente sortie en quelque chose de plus simple et plus rapide à traiter. C'est à vous de voir comment transformer l'information en un pattern utilisable!

Créez une fonction treatment(data) pour transformer l'information que vous avez précédemment retourné en un pattern :

Chaque suite d'éléments communs devrait être indiqué par la nature de l'élément suivi de '*' et le nombre d’occurrence sans autre éléments entre.

Exemple:

Avec le code '66AeB7' votre précédente fonction sortirait 'number number vowel-up vowel-low consonant-up number'.

Avec cette sortie en entrée votre nouvelle fonction treatment sortirait la string suivante 'number*2 vowel-up*1 vowel-low*1 consonant-up*1 number*1'.

N'hésitez pas à utiliser autant de sous-méthodes que vous jugez nécessaires.


        
        
<string>

Table des matières

Mission 5 - Tuples, Tests et Algorithmes de Recherche

Mission 5 : Tuples, Tests, et Algorithmes

Mission 5 : Tuples, Tests, et Algorithmes

Introduction

Vous travaillez pour une entreprise qui est active dans toute la Belgique. En tant que composant d'un système plus grand, l'entreprise a besoin d'outils qui permettent de trouver l'emplacement des communes belges. Vous avez trouvé une liste des communes et leur coordonnées GPS en ligne et devez utiliser Python pour créer les outils demandés.

Objectifs

Objectifs individuels

A l’issue de ce problème, chacun d’entre vous :

  • sera en mesure d’exploiter les notions suivantes :
    • tuples
    • algorithmes de recherche linéaire et binaire
    • tests
  • aura modifié un algorithme de recherche binaire pour l'utilisation dans une situation spécifique
  • aura découpé un gros problème en petits problèmes

Objectifs collectifs

A l’issue de ce problème, le groupe tout entier :

  • aura montré sa capacité à travailler ensemble pour répondre à une série de questions relatives à ce qui aura été appris dans le cadre de la mission,
  • peut lire et écrire des spécifications qui sont lisibles pour les autres membres de l'équipe,
  • peut écrire des testes pour vérifier la fonctionnalité de fonctions écrites par d'autres membres de l'équipe.

Préparation, étude et apprentissage

La matière relative à cette mission est décrite dans les sections suivantes du syllabus en ligne :

Questionnaire de démarrage

Questions à choix multiple

Les questions à choix multiples de cette mission sont également accessibles en ligne depuis https://inginious.info.ucl.ac.be/course/LSINF1101-PYTHON/Session5_QCM


        
        

Question 1

Donnée est une liste d'événements qui ont lieu sur certains coordonnées. Un exemple d'une telle liste est la suivante:

events = [(0,1),(2,3),(0,1),(4,5),(1,2),(0,1),(1,1),(0,2),(1,1)]

Donnée est une coordonnée (i,j), créez une fonction count(events,i,j) pour calculer le nombre d'événement sur cette coordonnée.


        
        

Question 2

Étant données deux listes ordonnées de nombres entiers, on veut calculer une nouvelle liste ordonnée des nombres entiers qui sont communs entre les deux listes. Par exemple, étant données les listes ordonnées [-2,-1,0,1,2,3,4] et [0,1,2,5,6], on veut calculer la liste [0,1,2], qui contient les nombres entiers [0,1,2] qui sont communs entre les deux listes.

Une idée pour calculer cette liste est de parcourir les deux listes en même temps; pour chaque élément de la première liste, on regarde si on peut trouver l'élément dans la deuxième partie qu'on n'a pas encore regardé. Cette idée a été mise en oeuvre dans la fonction suivante:

def intersect ( l1, l2 ):
    """ Retourne une liste ordonnée des nombres entiers communs entre l1 et l2.

    Args:
        l1: une liste ordonnée de nombres entiers, positif ou négatif
        l2: une liste ordonnée de nombres entiers, positif ou négatif
    Retourne:
        Une liste ordonnée de nombres entiers communs entre l1 et l2.
    """
    l = []
    p1 = 0
    p2 = 0
    while p1 < len(l1):
        while l1[p1] > l2[p2]:
            p2 += 1
        if l1[p1] == l2[p2]:
            l.append ( p2 )
        p1 += 1
    return l

Malheureusement, le code ne fonctionne pas encore correctement.

  • Écrivez quelques testes qui permettent de découvrir que le code n'est pas correct.
 
 
 
 

  • Corrigez le programme pour résoudre le problème, sans ajouter des lignes au programme.
 
 
 
 
 
 

Question 3

Dans les exercices suivants, on va étudier une répresentation d'un ensemble de chaînes de caractères et un ordre de ces chaînes. Cette répresentation se compose d'une liste de tuples; dans chaque tuple, le premier élément contient une chaîne de caractères; le deuxième élément contient la position de l'élément suivant dans l'ordre voulu. Par exemple :

l = [ ( "", 2 ), ( "Bertram", 5 ), ( "Anna", 1 ), ( "Xavier", None ), ( "Nicolas", 3 ), ( "Dominic", 4 ) ]

On suppose que le premier tuple correspond toujours à la chaîne de caractères vide; si il n'y pas un élément suivant, on utilise None. Notez que dans la liste, on peut avoir seulement un élément None.

L'ordre des chaînes de caractères indiqué par les nombres entiers dans cette liste est ["Anna","Bertram","Dominic","Nicolas","Xavier"] -- par conséquent, l'ordre alphabétique.

Étudiez maintenant la spécification suivante d'une fonction is_sorted_tuple_list(l).

def is_sorted_tuple_list ( l ):
    """ Détermine si l se compose d'une liste de tuples ordonnés par ordre alphabétique.

    Une liste est considérée ordonnée par ordre alphabétique si e[0] < l[e[1]][0], pour tous
    les éléments de la liste tels que e[1] != None; en plus, l[i][0] doit correspondre à "";
    il ne peut y avoir qu'un seul tuple dans la liste pour lequel e[1] == None.

    Args:
        l:  une liste de tuples, dont chacun se compose d'une chaîne de caractères et un nombre entier ou None.
    Returns:
        True si l se compose d'une liste de tuples (chaîne de caractères, nombre entier) ordonnés, False si non.
    """

Écrivez quelques tests en utilisant assert pour évaluer l'exactitude de cette fonction.

 
 
 
 
 
 
 
 
 
 

Question 4

Faites une implémentation de la fonction is_sorted_tuple_list et évaluez-la en utilisant les tests d'exercice 3.

 
 
 
 
 
 
 
 
 
 

Question 5

Étudiez la spécification de la fonction suivante.

def get_index ( l, s ):
    """ Retourne l'indexe de la plus grande chaîne de caractères plus petite que s dans la liste l.

    Une chaîne de caractères en l est plus petite que s, si cette chaîne est plus petite dans l'ordre alphabétique ou égale.

    Args:
        l:  une liste de tuples, dont chacun se compose d'une chaîne de caractères et un nombre entier ou None;
            la première chaîne de caractères en l est "".
        s:  une chaîne de caractères.
    Retourne:
        L'indexe de la chaîne de caractères la plus grande en l, mais plus petite que s.
    """

Écrivez quelques tests pour évaluer l'exactitude de cette fonction.

 
 
 
 
 

Question 6

Créez une implémentation de la fonction get_index et évaluez-la avec vos tests.

 
 
 
 
 
 
 
 
 
 

Question 7

Étudiez la spécification de la fonction suivante.

def add ( l, s ):
    """ Ajoute la chaîne de caractères s à la liste ordonnée de telle sorte que la liste reste ordonnée.
    Si s se trouve déjà dans la liste, la liste n'est pas modifiée.

    Une liste est considérée ordonnée par ordre alphabétique si e[0] < l[e[1]][0], pour tous
    les éléments de la liste tels que e[1] != None; en plus, l[i][0] doit correspondre a "";
    il ne peut y avoir qu'un seul tuple dans la liste pour lequel e[1] == None.

    Si la chaîne s ne se trouve pas déjà dans la liste, la fonction ajoute l'élément à la fin de
    la liste l, de telle sorte que les nombres entiers continuent à indiquer l'ordre alphabétique des chaines
    de caractères.

    Args:
        l: une liste de tuples, dont chacun se compose d'une chaîne de caractères et un nombre entier ou None;
          la première chaîne de caractères en l est "". Les nombres entiers indiquent l'ordre alphabétique
          des chaines de caractères.
        s:  une chaîne de caractères.
    Retourne:
        Rien; l est modifiée comme indiqué.
    """

Écrivez quelques tests pour évaluer l'exactitude de cette fonction.

 
 
 
 
 

Question 8

Écrivez une implémentation de cette fonction et évaluez-la avec vos tests; considérez réutiliser une fonction que vous aviez écrite pour un exercice précédent! Cet exercice est le dernier exercice sur le sujet de listes ordonnées.

 
 
 
 
 
 

Question 9

On représente les cours suivis par des étudiants en utilisant des listes imbriquées, comme suit:

[('LINFO1101', ['Jean', 'Pierre']), ('LINFO1110', ['Jean']),\
 ('LINFO1111', ['Jean']), ('LINFO1112', ['Jacques', 'Pierre']),\
 ('LINFO1113', ['Pierre'])]

Donnez un algorithme binary_search(course,list_of_courses) pour trouver tous les étudiants d'un cours dans cette structure de données. Copiez le code du cours et modifiez-le.


        
        

Question 10

On peut appliquer l'algorithme de question 9 pour trouver les étudiants de plusieurs cours. Supposez que chaque fois que vous calculez middle, tu imprimes la valeur calculée pour middle. Dans ce cas, le nombre de valeurs imprimées pour middle correspond à la nombre de fois que la boucle while est exécutée. Combien de fois est-ce que la boucle est exécutée pour l'exemple suivant ?

La liste est:

[('LINFO1101', ['Jean', 'Pierre']), ('LINFO1110', ['Jean']),\
 ('LINFO1111', ['Jean']), ('LINFO1112', ['Jacques', 'Pierre']), \
 ('LINFO1113', ['Pierre'])]

Les cours donnés sont: LINFO1110, LINFO1112, LINFO1111, LINFO1114.

 
 
 

Question 11

On suppose donnés deux noms de cours et une structure de données comme donnée en question 9. Écrivez un algorithme pour retourner tous les noms de cours entre les deux noms spécifiés.

Notez qu'il y a beaucoup d'algorithmes qu'on pourrait utiliser pour cette tâche. On pourrait modifier binary_search, ou utiliser binary_search pour le premier nom, le deuxième nom, etc. Réfléchissez sur les différents algorithmes possibles!

 
 
 
 
 
 
Mission 5

Mission 5

Pour cette mission, vous devez écrire des fonctions et tester leur bon fonctionnement. Comme dans les exercices de préperation, vous devez travailler à deux de cette façon: pendant qu'un étudiant écrit une fonction, l'autre développe la fonction de test correspondante. Lorsqu'une fonction est correctement spécifiée, on peut écrire les tests permettant de vérifier son bon fonctionnement sans connaître son code.

Dans cette mission vous allez créer plusieurs fonctions qui fonctionnent sur une liste de communes de la Belgique.

Etapes

Etape 1

Téléchargez le fichier sorted_belgian_communes.py, qui contient une liste de toutes les communes de la Belgique ainsi que leurs coordonnées (selon une projection Mercator). Ecrivez toutes les fonctions demandées durant cette mission dans ce fichier.

  • Écrivez une fonction verify_order(communes) qui vérifie que la liste de communes communes est triée par nom. Cette fonction doit retourner True quand la liste est triée, et False autrement. Faites attention: commencez avec une spécification de la fonction dans le style de Google!
  • Écrivez des tests pour cette fonction, en utilisant des exemples plus petits. Les tests doivent se baser sur la spécification de la fonction, comme convenu avec votre partenaire. Ajoutez les tests dans le même fichier, dans une fonction test_verify_order() sans arguments. Dans cette fonction de test, des instructions assert doivent être utilisé pour vérifier l'exactitude de la fonction verify_order(communes).

Finalement, appliquez votre fonction à la liste all_communes.

Etape 2

  • Écrivez une fonction coordinate(commune,all_communes) pour trouver les coordonnées d'une commune dans la liste all_communes. Utilisez une variation de binary_search. La fonction doit retourner un tuple qui représente les coordonnées selon la projection Mercator.
  • Écrivez des tests pour cette fonction, en utilisant des exemples plus petits. Ajoutez les testes dans le même fichier, dans une fonction test_coordinate().

Etape 3

Écrivez une fonction distance(commune1, commune2, all_communes) pour calculer la distance euclidienne entre deux communes dont les noms sont donnés. La distance euclidienne entre deux coordonnées (x1,y1) et (x2,y2) est:

((x1 − x2)2 + (y1 − y2)2)

Rappel: le module math contient une implémentation d'une fonction sqrt. Écrivez une fonction auxiliaire pour calculer la distance entre deux coordonnées (x1,y1) et (x2,y2).

De nouveau: ajoutez des spécifications pour toutes les fonctions, ainsi que des tests, dans une fonction test_distance().

Etape 4

Écrivez une fonction tour_distance(communes, all_communes) pour calculer la distance totale d'une tournée à travers tous les communes dans la liste communes. La tournée commence à communes[0], va ensuite vers communes[1], communes[2], ..., communes[-1], pour finalement retourner à communes[0].

De nouveau: ajoutez des spécifications pour la fonction, ainsi que des tests, dans une fonction test_tour_distance().

Etape 5

Écrivez une fonction closest(commune, all_communes) pour calculer la commune la plus proches d'une commune donnée commune. Ajoutez les spécifications pour cette fonction, ainsi que des testes pour vérifier l'exactitude de la fonction, dans une fonction test_closest ().

Remise de votre solution

Pour cette mission, vous devez soumettre votre fichiers sorted_belgian_communes.py et README.txt au serveur de soumissions de programmes du cours. Les fonctions et les testes doivent être dans le même fichier. Le fichier ne doit contenir que des fonctinos. Votre fichier sorted_belgian_communes.py doit au moins contenir les fonctions :

verify_order(communes)
coordinate(commune,all_communes)
distance(commune1, commune2, all_communes)
tour_distance(communes, all_communes)
closest(commune all_communes)

        
        
Questions complémentaires

Questions complémentaires

Question 1

Donnée est une liste de coordonnées. Par exemple:

System Message: ERROR/3 (<string>, line 14)

Content block expected for the "code-block" directive; none found.

.. code-block:: python

l = [ ( 2.0, 5.0 ), ( 8.0, 12.0 ), ( 10.0, 40.0 ), (8.0, 50.0), (8.0, 50.0) ]

Nous voulons créer un dictionnaire pour identifier rapidement les valeurs y pour une x donnée. Pour l'exemple:

System Message: ERROR/3 (<string>, line 21)

Content block expected for the "code-block" directive; none found.

.. code-block:: python

d = { 2.0: [ 5.0 ], 8.0: [ 12.0, 50.0, 50.0 ], 10.0: [ 40.0 ] }

Écrivez une fonction create_dict(l) qui crée cette dictionnaire (pas limité à cet exemple).


        
        

Question 2

Donnée est une liste de coordonnées, comme dans l'exercice précédente. Nous voulons créer un dictionnaire pour identifier rapidement la valeur maximale y pour une x donnée. Pour l'exemple:

System Message: ERROR/3 (<string>, line 52)

Content block expected for the "code-block" directive; none found.

.. code-block:: python

d = {2.0: 5.0, 8.0: 50.0, 10.0: 40.0}

Écrivez une fonction create_dict_max(l) qui crée ce dictionnaire (pas limité à cet exemple).


        
        

  • Écrivez une fonction get_ordered_list(l) selon les spécifications suivantes, ainsi que les tests pour vérifier l'exactitude de cette fonction. (La fonction est écrite par membre B de votre groupe; les tests sont écrit par membre A.)
def get_ordered_list ( l ):
    """ Retourne les chaînes de caractères dans la liste l dans l'ordre indiquée par la liste l

    L'ordre est déterminée par les nombres entiers dans la liste: pour chaque tuple e dans la liste l,
    le successeur est l[e[1]], si e[1] != None.

    Args:
        l:  une liste de tuples, dont chacun se compose d'une chaîne de caractères et un nombre entier ou None;
            les nombres entiers définissent un ordre total sur les éléments de la liste.
    Retourne:
        Les chaines de caractères dans la liste l dans l'ordre indiqué par les nombres entiers.
    """
 
 
 
 
 
 
 
 
 
 

Nous avons la structure de données suivante pour stocker la relation entre étudiants et cours qu'ils ont suivis:

student_courses = [ ( "Jean", "LINFO1111" ), ( "Jean", "LINFO1101"), \
     ( "Pierre", "LINFO1101" ), ( "Pierre", "LINFO1112" ) ]

Écrivez le code pour ajouter un tuple ("Jacques", "LINFO1112") à student_courses.


        
        

Créez une fonction students(course, student_courses) qui, pour un cours donné, renvoie une liste des étudiants qui suivent le cours. Par exemple, si on appelle la fonction avec "LINFO1101" et la liste de la question 3 comme paramètres, le résultat doit être ["Jean", "Pierre"].

On présume qu'il n'y a pas d'ordre dans la liste student_courses.


        
        

Écrivez une fonction remove_student(student,student_courses) qui, pour un étudiant donné présent dans une liste donnée, retourne la liste sans les tuples qui concernent cet étudiant.

System Message: ERROR/3 (<string>, line 164)

Unexpected indentation.

Par exemple, si on appelle la fonction avec "Jean" et la liste de la question 1 comme paramètres le résultat doit être :

[ ( "Pierre", "LINFO1101" ), ( "Pierre", "LINFO1112" ) ]

On présume qu'il n'y a pas d'ordre dans la liste student_courses.

System Message: WARNING/2 (<string>, line 257)

Explicit markup ends without a blank line; unexpected unindent.

Écrivez une fonction nest_students(student_courses) qui, pour chaque cours, crée une liste imbriquée des étudiants qui suivent le cours. Sur l'exemple précédent, la fonction doit retourner cette structure de données:

[('LINFO1101', ['Jean', 'Pierre']), ('LINFO1111', ['Jean']), ('LINFO1112', ['Pierre'])]

La liste doit être triée par ordre de cours. Utilisez le code de question 4 et de question 5 comme inspiration. Réfléchissez sur la question: comment est-ce qu'on peut ajouter un élément dans une liste imbriquée qui vient d'être créée?


        
        

Vous faites partie de l'organisation des 5 et 10 miles de Louvain-la-Neuve. Mais le système est tombé en panne juste avant le départ.

Il y avait deux étudiants pour prendre note des arrivées des coureurs. Heureusement, il n'y avait que deux lignes à compter. Votre job consiste à faire une liste de ces deux listes pour avoir un classement général.

Les listes que vous recevez sont une succession de ['name', time] avec le temps dans un ordre croissant. Créez une fonction merge(first_list, second_list) qui retournera une liste qui a les éléments des deux listes dans l'ordre.


        
        

En sciences informatiques, un algorithme de tri est un algorithme qui place les éléments d'une liste dans un certain ordre. Les ordres les plus utilisés sont l'ordre numérique et l'ordre lexicographique. Un tri efficace est important pour optimiser l'utilisation d'autres algorithmes (tels que les algorithmes de recherche ou de fusion) qui ont besoin d'une liste triée en entrée ; c'est aussi souvent utile pour la canonicalisation des données et pour produire des sorties lisibles par les humains. Plus formellement, la sortie doit satisfaire deux conditions :

  • La sortie est en ordre croissant (chaque élément n'est pas plus petit que l'élément précédent selon l'ordre choisi);
  • La sortie est une permutation (réorganisation mais avec tous les éléments originaux) de l'entrée.


        
        

Une fois de plus, c'est l'heure de la cérémonie de la répartition . Les premières années attendent en rangs devant un vieux chapeau, à la fois anxieux et excités. Le directeur fait un long discours pour les accueillir et laisse la place à un mystérieux intervenant.

Tous les premières années sont ébahis lorsque le Choixpeau Magique brise le silence en chantant l'une de ses célèbres chansons.

Cependant, le choixpeau en fait un peu trop et rencontre quelques problèmes. Il perd sa voix et ne sera pas en état d'assurer la suite de la cérémonie. Heureusement, nous avons toujours accès aux connaissances des fondateurs et nous pourrons répartir les élèves avec votre aide.

Créez une fonction house_designation(student_qualities) qui va retourner une liste avec les noms des quatres maisons, la première étant celle où l'étudiant devrait aller et la dernière, celle qui convient le moins à l'étudiant. Pour décider de cette répartition, l'étudiant devrait être placé dans la maison où il a le plus d'affinités, c'est-à-dire, la maison avec laquelle il partage le plus de qualités. Si deux maisons sont à égalité, on les retourne dans l'ordre dans lequel elles sont placées dans les connaissances des fondateurs.


        
        











<string>

Table des matières

Mission 6 - Fichiers et exceptions

Mission 6 : Fichiers et exceptions

Mission 6 : Fichiers et exceptions

Introduction

Vous allez développer un programme qui permets l’exécution de certaines tâches. Très fréquemment, un utilisateur doit faire le tâches suivantes :

  • Operations arithmétiques (ex. addition des chiffres) ;
  • chercher des mots dans un dictionnaire ;
  • calculer des statistiques d'un fichier.

Les exercices préparatoires vous permettent de completer certains éléments de cette mission.

Objectifs

Objectifs individuels

A l’issue de ce problème, chacun d’entre vous sera en mesure d’exploiter les notions suivantes :

  • exceptions ;
  • fichiers ;
  • opérations plus compliquées sur chaînes de caractères.

Préparation, étude et apprentissage

La matière relative à cette mission est décrite dans les sections suivantes du syllabus en ligne :

Il peut être utile de relire:

Questionnaire de démarrage

Questions à choix multiple

Les questions à choix multiples de cette mission sont également accessibles en ligne depuis https://inginious.info.ucl.ac.be/course/LSINF1101-PYTHON/Session6_QCM


        
        

Question 1

Considérez le code suivant:

file = open ( "file.txt", "r" )
for line in file:
    print  ( line.strip ().split (",") )
file.close ()

Le contenu du fichier file.txt est le suivant:

X   , X   , \n   , X \n X X , , X

Expliquez le résultat de code.

 
 
 
 
 
 

Question 2

Dans les exercices suivants, vous pouvez supposer que les fichiers à lire existent et qu'il ne faut pas traiter les erreurs.

  • Créez une fonction line_count(filename) qui retourne, pour le nom d'un fichier donné, le nombre de lignes dans le fichier.
  • Créez une fonction char_count(filename) qui retourne, pour le nom d'un fichier donné, le nombre de caractères dans le fichier.
  • Créez une fonction space(filename,n) qui crée un nouveau fichier filename qui se compose seulement de n espaces.
  • Créez une fonction capitalize(filename_in,filename_out) qui crée, pour le fichier filename_in, un nouveau fichier filename_out, dans lequel tous les caractères sont en majuscule.


        
        

Question 3

On donne des listes contenant des paires de coordonnées comme [(0.5,0.5),(0.1,0.3),(0.4,0.5)].

  • Écrivez une fonction write_coordinates(filename, l) pour créer un fichier qui contient les coordonnées de la liste l dans le format suivant:
0.5,0.5
0.1,0.3
0.4,0.5
  • Écrivez une fonction read_coordinates(filename) qui lit les coordonnées du fichier filename, dans le format ci-dessus, et retourne une liste de tuples, comme donnée.

Considérez l'utilisation de méthodes de string telles que : * split * strip

Voyez la documentation de ces méthodes dans le manuel de référence de Python.


        
        

Question 4

Considérez le code suivant.

command = input ( "Enter your command: " )
parameters = command.split ()
if parameters[0] == "divide":
    print ( "The value of your division is: " + str ( float(parameters[1])/float(parameters[2])))
else: if parameters[0] == "showfile":
    file = open ( parameters[1] )
    print ( file.read () )
    file.close ()
else:
    print ( "Command not recognized")
  • Identifiez quelles erreurs pourraient survenir lors de l'exécution de ce code. Il n'est pas nécessaire d'identifier les noms exacts des erreurs en Python; il suffit de décrire les erreurs en français.
 
 
 
 
 
 

  • Ajoutez un bloc try ... except pour attraper les exceptions d'une façon générique. Donnez un message générique There was an error dans ce cas. Assurez-vous que le fichier est aussi correctement fermé en cas d'erreur!
  • Modifiez le code tel que dans le cas d'une commande qui n'existe pas, une exception est lancée.


        
        

  • (Seulement à faire s'il reste du temps.) Modifiez le bloc try ... except pour que les messages soient plus informatifs. Pour cet exercice, vous devez exécuter le code et déclencher les différentes erreurs afin de déterminer leur nom (comme ValueError, FileNotFoundError, ...). Vous trouvez la liste de toutes les différentes exceptions sur https://docs.python.org/3/library/exceptions.html, mais il est plus facile de déterminer leur nom en regardant les messages de Python.
 
 
 
 
 
 

Question 5

Dans la mission, vous devrez lire un fichier qui contient des mots avec leur fréquence d'occurrence. Par exemple:

this,5146
that,10790
these,1575
the,69975
those,864

Identifiez les différentes erreurs que l'on pourrait rencontrer en lisant ce fichier. Il n'est pas nécessaire d'identifier les noms exacts des erreurs; il suffit de les décrire en mots.

 
 
 
 
 
 

Mission 6

Mission 6

Dans cette mission nous allons développer un simple assistant qui fonctionne sur la console Python. L'utilisateur doit être capable de donner des commandes simples, pour lesquelles l'outil doit répondre avec une réponse pertinente. L'objective dans cette mission est de montrer que l'outil continue à fonctionner même si l'utilisateur donne des commandes incomplètes ou incorrectes.

Les commandes qui doivent être supportées sont:

  • file <name>: spécifie le nom d'un fichier sur lequel l'outil doit travailler
  • info: montre le nombre de lignes et de caractères du fichier
  • dictionary: utilise le fichier comme dictionnaire à partir de maintenant
  • search <word>: cherche le mot le plus similaire au mot spécifié dans le dictionnaire
  • sum <number1> ... <numbern>: calcule la somme des nombres spécifiés
  • avg <number1> ... <numbern>: calcule la moyenne des nombres spécifiés
  • help: montre des instructions à l'utilisateur
  • exit: arrête l'outil

En outre, il vous est demandé d'ajouter une commande de votre choix à l'outil.

Par exemple, l'outil doit supporter cette séquence de commandes :

Bienvenue dans votre outil personnalisé!
> file all-words.dat
Loaded all-words.dat
> info
11304 lines
1330218 caracters
> dictionary
Read file as dictionary
> search presbytaerial
Closest word is presbyterial
> search prebyteriaal
Closest word is presbyterial
> exit

Si l'utilisateur spécifie un fichier autre qu'un dictionnaire, ou si l'utilisateur cherche un mot sans avoir spécifié un dictionnaire, l'outil doit produire un message d'erreur et continuer à fonctionner.

Le format des dictionnaires est spécifié dans les exercices préparatoires. Pour éviter tout problème avec l'encodage des caractères accentués, votre dictionnaire vérifiera des mots en anglais (sans accents). Si l'utilisateur spécifie un mot qui n'est pas présent dans le dictionnaire, l'outil doit retourner le mot le plus similaire.

La phase de réalisation de cette mission est moins guidée que les précédentes. Par conséquent :

  • Vous pouvez choisir comment définir la similarité entre mots : par exemple, vous pouvez utiliser la fréquence des mots, puisqu'elle est spécifiée dans le fichier dictionnaire.
  • Vous pouvez créer une commande supplémentaire: cela peut être une autre commande mathématique, mais aussi une autre commande liée au dictionnaire.
  • Vous devez choisir vous-même la subdivision de votre programme en fonctions.

Néanmoins, on vous suggère de procéder comme suit:

  • Commencez avec une boucle while qui demande à l'utilisateur de donner des commandes.
  • Utilisez le code de la phase de préparation pour lire des commandes et réagir sur les commandes.
  • Écrivez au moins une fonction séparée pour chaque commande.
  • Utilisez des variables globales pour stocker l'état de l'outil (par exemple le nom du fichier).
  • Au début vous pouvez ignorer les erreurs: assurez-vous que l'outil fonctionne si l'utilisateur donne des commandes correctes.
  • Ensuite, améliorez le code afin que le programme continue quand une commande incorrecte est donnée.

Pour vous aider, vous avez à disposition le fichier all-words.dat qui contient une centaine de milliers de mots de la langue anglaise ainsi que le nombre d'occurrences de ce mot. Ce dictionnaire a été construit en se basant sur deux sources d'information : le dictionnaire utilisé par ispell (http://wordlist.sourceforge.net/) et la Global Service List (http://jbauman.com/gsl.html), c'est-à-dire les 2000 mots les plus fréquemment utilisés par un personne qui apprend l'anglais. Ce fichier contient les mots en minuscules et n'est pas trié dans l'ordre alphabétique. La première ligne contient le nombre de mots présents dans le fichier.

La mission de cette semaine n'aura pas de correction automatique donc soyez bien attentifs pendant la séance de feedback.

Tests

Vous devrez aussi écrire des tests de vos fonctions. Si assistant.py est le fichier qui contient votre code, nous attendons que vous écrivez un deuxième fichier test.py dans lequel vous faites des appels aux fonctions que vous avez fournies. Il est décrit dans le syllabus théorique comment faire des tests quand on a plusieurs fichiers (Section Tests).

Remise de votre solution

Vous devez soumettre un fichier assistant.py avec le code de votre outil et un fichier test.py avec vos tests. N'oubliez pas d'ajouter dans ce fichier des spécifications (docstrings) et aussi d'écrire un fichier README.


        
        
Questions complémentaires

Questions complémentaires

Écrivez une fonction table(filename_in, filename_out, width) qui crée pour un fichier donné un autre fichier dans lequel toutes les lignes ont été mises dans un tableau. Pour cet exemple:

Mons
Bruxelles
Ottignies
Jean Charles

le résultat avec width = 8 doit être:

::
Mons Bruxelle Ottignie Jean Cha

Remarquez qu'il y a un espace avant et après chaque ligne. Considérez l'utilisation des méthodes suivantes de string:

  • la méthode format
  • la méthode rstrip

Consultez la documentation de Python si vous ne connaissez pas encore ces méthodes. Vous pouvez présumer que le fichier filename_in existe.


        
        

Toute votre vie vous vous êtes demandé "Où cette stupide chouette a-t-elle égaré ma lettre ?", "Quand irais-je enfin à Poudlard ?" ou même à la fin "Suis-je un Cracmol ?". Ne vous inquiétez pas!

Poudlard vous a enfin contacté pour une tâche importante. Même si vous êtes trop vieux pour apprendre la sorcellerie, ils ont de la chance parce que vous avez appris une différente sorte de magie : la programmation.

Ils ont décidé de moderniser un peu leurs services d'admission et veulent que vous créiez un programme qui sera capable de remplir un fichier (template d'un lettre d'admission) avec le nom de l'étudiant. De cette manière, ils pourront réduire le coût en plumes et réduire la charge de travail des elfes!

Implémentez la fonction write(letter_template, name) en Python.

N'oubliez pas de lever une exception si elle se produit.


        
        

Les règles du Quidditch ont été établie en 1750 par le Département des jeux et sports magiques. Et il n'est dit nul part que l'arbitre ne peut recevoir un petit coup de main.

Madame Bibine est plutôt occupée à regarder pour le boutenchoc, le croc-en-manche, le hochequeue et tout un tas d'autres vilaines fautes de Quidditch. Donc elle a pensé que vous pourriez écrire une programme qui déciderait le vainqueur d'un match en se basant sur la liste des points.

La liste des scores serait fournie dans un fichier. Le contenu de ce fichier suivrait le format suivant :

  • Les deux premières lignes : Noms des équipes
  • Les lignes qui suivent : Team_scoring points

S'il y a une erreur, pensez à lever une exception.

Rappelez-vous qu'attraper le vif d'or en plus de rapporter 150 points marque la fin du match.

Implémentez la fonction referee(score_file) en Python.


        
        

Pour votre prochain gros jeu, Dieu de la Destruction Massive : Edition Jeu du Siècle, vous devez créer une fonction pour charger et sauvegarder les données du joueur.

Vous devez créer deux fonctions : une pour sauvegarder les données et une pour les charger. Vous êtes libres d'enregistrer les données comme vous le souhaitez dans le fichier, mais placer un entier par ligne est probablement la méthode la plus simple. S'il n'y a pas de fichier à charger quand vous voulez utiliser le fontion load_data (par exemple, le joueur commence un nouveau jeu), vous devez lever une FileNotFoundError.

Les deux fonctions auront ces définitions :

#sauvegarder les 4 entiers dans le fichier nommé filename
def save_data(filename, life, mana, position_x, position_y)

#retourne un tuple contenant les valeurs (life, mana, position_x et position_y précédemment sauvegardées
def load_data(filename)


        
        
<string>

Table des matières

Mission 7 - Dictionnaires

Mission 7 : Dictionnaires

Mission 7 : Dictionnaires

Introduction

Le but de cette mission est de développer un outil qui permet un utilisateur de chercher répétitivement dans un fichier de texte: pour des mots donnés, l'outil va imprimer les phrases dans lesquelles tous les mots donnés sont présents. Pour assurer que l'outil ne prend pas trop de temps pour déterminer ces phrases, on va construire un index des mots présents dans les phrases des documents. On utilisera les dictionnaires pour stocker l'index.

Objectifs

Objectifs individuels

A l’issue de ce problème, chacun d’entre vous sera en mesure d’exploiter les notions suivantes :
  • dictionnaires
  • fichiers

Préparation, étude et apprentissage

La matière relative à cette mission est décrite dans les sections suivantes du syllabus en ligne :

Questionnaire de démarrage

Questions à choix multiple

Les questions à choix multiples de cette mission sont également accessibles en ligne depuis https://inginious.info.ucl.ac.be/course/LSINF1101-PYTHON/Session7_QCM


        
        

Question 1

Considérez le code suivant:

codes = {"Bruxelles" : [1000,1020,1030], "Louvain-la-Neuve" : [1348], "Wavre": [1300,1301]}

Les morceaux de code ci-dessous sont executés chacun après ce code. Décrivez ce qui se passe pour chacun des cas.

  • On exécute :
print(codes["Bruxelles"])
 
 

  • On exécute :
print(codes["Mons"])
 
 

  • On exécute :
print(codes[1000])
 
 

  • On exécute :
print(codes.get("Mons",[]))
 
 

  • On exécute:
codes["Liege"] = [4000]
    print(codes)
 
 

  • On exécute:
codes["Bruxelles"].append(1040)
    print(codes)
 
 

  • On exécute:
codes.get("Bruxelles",[]).append(1050)
    print(codes)
 
 

  • On exécute:
codes.get("Arlon",[]).append(8362)
    print(codes)
 
 

  • On exécute:
if "Bruxelles" in codes:
      print("Found!")
else:
  print("Not found!")
 

  • On exécute:
if 1000 in codes:
      print("Found!")
else:
  print("Not found!")
 

  • On exécute:
for x in codes:
      print(x)
 
 
 

  • On exécute:
for x in codes:
      print(codes[x])
 
 
 

  • On exécute:
for x in codes.items():
      print(x)
 
 

  • On exécute:
for x, y in codes.items():
      y = y + [2000]
    print(codes)
 
 

  • On exécute:
for x, y in codes.items():
      y.append(2000)
    print(codes)
 
 

  • On exécute:
for x, y in codes.items():
      x = x + "*"
    print(codes)
 
 

Question 2

Donnée sont

  • une matrice representée en utilisant des listes imbriquées
  • une matrice representée en utilisant un dictionnaire, où les zéros ne sont pas stockées.

Par exemple,

l = [ [ 0, 2, 4 ], [ 4, 1, 0 ] ]
d = { (0,1): 2, (0,2): 4, (1,0): 4, (1,1): 1 }
Écrivez une fonction equal(l,d) qui détermine si d contient les même valeurs pour chaque élément
de l. (Nous permettons que d soit plus large que l.)


        
        

Question 3

Écrivez un outil qui fait la suivante:

  • l'outil lit un fichier text.txt, sépare chaque ligne en mots, et crée un dictionnaire avec, pour chaque mot, un compte du nombre d'occurrences de ce mot. On peut présumer que tous les mots sont en minuscules et qu'il n'y a pas de ponctuation.
  • l'outil demande à l'utilisateur de donner un mot, après lequel le programme retourne le nombre d'occurrences de ce mot.

Séparez le programme en fonctions, avec au moins - une fonction create_dictionary(name) pour lire le fichier name et créer le dictionnaire - une autre fonction pour demander les mots à l'utilisateur. Pour simplifier l'exercice, il n'est pas nécessaire de traiter les erreurs.


        
        

Question 4

Donné une structure de données comme la suivante:

System Message: ERROR/3 (<string>, line 380)

Content block expected for the "code-block" directive; none found.

.. code-block:: python

l = [{"City": "Bruxelles", "Country": "Belgium"},
{"City": "Berlin", "Country": "Germany"}, {"City": "Paris", "Country": "France"}]

Écrivez une fonction get_country(l,name) qui, pour le nom d'une ville name et une structure de données l du format illustré dans l'exemple, retourne le nom du pays dans lequel la ville est localisée. La fonction retourne None si la ville n'est pas dans l.


        
        

Mission 7

Mission 7

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

Il faut implementer les fonctions suivantes, et les utiliser dans l'outil final:

  • readfile(filename): cette fonction retourne une liste des lignes dans le fichier avec le nom filename. Tous les caractères de chaque ligne doivent être inclus.

  • get_words(line): pour une chaîne de caractères donnée, cette fonction retourne une liste des mots dans la chaîne, en minuscules, et sans ponctuation. Par exemple, pour la ligne

    Turmoil has engulfed the Galactic Republic.
    

    Le résultat est

    ["turmoil", "has", "engulfed", "the", "galactic", "republic"]
    
  • create_index(filename) crée un index pour le fichier avec nom filename. En général, un index pour une texte est une structure de données qui permet de chercher rapidement dans cette texte. Dans cette mission, l'index doit se composer de dictionnaires imbriqués: le premier dictionnaire permit de chercher un mot; pour chaque mot, on utilise un dictionnaire imbriqué pour chercher le nombre d'occurrences dans une ligne. Par exemple, pour ces lignes:

    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 notre index, representée comme dictionnaire, est:

    {"while": {0: 1}, "the": {0: 2, 1: 1}, "congress": {0: 1}, \
     "of": {0: 1, 1: 1}, "republic": {0: 1}, ... , "jedi": {2: 1}, ...}
    

    Ici, le dictionnaire contient tous les mots; dans le dictionnaire, "the" : {0: 2, 1: 1} indique que le mot the est associé à deux lignes; il y a deux occurrences dans la ligne avec index 0 et une occurrence dans la ligne avec index 1.

    La fonction doit retourner les dictionnaires imbriqués.

  • get_lines(words,index) retourne les identifiants des lignes qui contiennent tous les mots spécifiés dans la liste words, en utilisant le dictionnaire contenant l'index index. Par exemple, pour la liste ["the","republic"] la fonction doit retourner la liste [0] (puisque la première ligne contient les deux mots). Plusieurs approches sont possible pour faire cette calculation. Une possibilité est de traverser les occurences du premier mot, et de vérifier si on trouve dans ces lignes aussi les autre mots, en utilisant l'index de chaque mot. Il est recommandé de créer des fonctions supplémentaires.

Après avoir demandé le nom d'un fichier, dans une boucle infinie, l'interface doit demander à l'utilisateur de donner une liste de mots en utilisant la fonction input; chaque fois, l'outil cherche les lignes dans lequelles tous les mots spécifiés sont présents, et imprime ces lignes.

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

Pour toutes les fonctions spécifiées ci-dessus, il faut écrire des tests pour vérifier que les fonctions sont correctes. 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.

L'outil doit bien traiter les erreurs (un fichier qui n'existe pas, on cherche un mot qui n'existe pas, ...)

Dans cette mission, nous attendons que vous faites un effort pour produire de code qui est bien lisible. Faites attention que:

  • il y a des commentaires?
  • il y a des pre/post conditions, ou un docstring de style Google?
  • les variables ont des noms bien comprehensibles?
  • les fonctions ne sont pas trop longues?
  • vous pouvez suivre la logique du programme?

Remise de votre solution

Pour cette mission, vous devez soumettre:

  • un fichier search.py avec tout votre code
  • un fichier test.py avec les tests
  • 2 petits fichiers de texte que vous utilisez dans vos tests
  • un fichier README

        
        
Questions complémentaires

Questions complémentaires

Lors de la dernière session du club de duel, les sabliers comptant les points de chaque maison ont été détruits même un reparo n'a rien pu faire et la célébration de la Coupe des Quatre Maisons arrive à grands pas!

Heureusement, Rusard, qui ne fait pas confiance à la magie, a gardé les comptes de tous les accomplissements perpétrés par les étudiants. Il vous a fourni un dictionnaire associant chaque élève à sa maison et un parchemin avec tous leurs gains.

La liste des scores est donnée dans un fichier. Le contenu de ce fichier suit le format suivant :

  • Lignes: student_name points

Merci de retourner le nom de la maison gagnante, dans le cas d'un ex-aequo : retournez une liste des meilleures maisons.

S'il y a une erreur, levez une exception.

Implémentez la fonction winning_house(scroll) en Python.

Vous avez déjà la liste des étudiants triés par maison à votre disposition :

students = {'gryffindor': ['Harry', 'Hermione', 'Ron', 'Ginny', 'Fred', ' Georges', 'Neville'],
            'ravenclaw': ['Cho', 'Luna', 'Sybill', 'Marcus', 'Marietta', 'Terry', 'Penelope'],
            'hufflepuff': ['Pomona', 'Zacharias', 'Teddy', 'Cedric', 'Nymphadora', 'Newton', 'Justin'],
            'slytherin': ['Malfoy', 'Severus', 'Dolores', 'Horace', 'Blaise', 'Pansy', 'Bellatrix']}


        
        

Anonymous a été épaté par votre travail et a décidé de vous faire confiance pour l'analyse de toutes les données qu'ils ont intercepté.

Avec l'aide des deux fonctions que vous avez déjà créées, vous allez transformer chaque ligne de données en un pattern et extraire le nombre d’occurrences présentes dans le fichier.

Créez une fonction collect(data) pour lire le fichier, extraire les patterns et les enregistrer dans un dictionnaire avec leurs occurrences.

S'il y a une erreur, levez une exception.

Rappel:

  • extract(code): donne la nature de chaque élément d'une string.
  • treatment(code): transforme une suite d'éléments en un pattern.


        
        

Après la troisième guerre mondiale, la planète est laissée dans un état post-apocalyptique. Vous êtes l'un des seuls survivants et vous cherchez un peu de compagnie. Mais vous ne pouvez pas trop swiper sur Tinder vu que le réseau est mort..

Heureusement votre meilleur ami est avec vous... Votre ordinateur (oui, ça craint!) Avec son aide, aide vous allez pouvoir entrer en contact avec le reste du monde. Puisque vous avez un dictionnaire Morse enregistré sur votre machine (Matt Damon avait bien une table ASCII avec lui dans "Seul sur Mars" , donc c'est pas si absurde), vous allez l'utiliser pour traduire votre texte et l'émettre grâce à une vieille radio.

Notez que si vous devez essayer de traduire un caractère non-enregistré, vous devez lever une exception TypeError.

Implémentez la fonction translate(data) en Python.

Avec data comme chaine de caractère que vous voulez encoder en Morse et un dictionnaire morse utile pour faire les traductions.

morse = {
"A" : ".-",
"B" : "-...",
"C" : "-.-.",
"D" : "-..",
"E" : ".",
...
}


        
        

Votre tinder par radio a bien fonctionné et vous pouvez désormais discuter avec beaucoup de gens intéressants. Encore plus intéressant, une merveilleuse créature vient de vous contacter et est parvenue à vous envoyer une image à travers des points et des espaces (Dieu bénisse le code Morse).

Vous voulez vraiment lui parler ainsi qu'à vos autres futurs matchs mais vous venez de réaliser que vous n'avez jamais bien étudier les langues étrangères. Heureusement, vous avez des dictionnaires sur votre ordinateur (qui a apparemment téléchargé l'entierté d'internet). Vous devez simplement coder un traducteur!

Notez que si un mot que vous voulez traduire n'est pas dans le dictionnaire, vous devez laisser le mot dans son langage original.

Exemple:

"I'm fond of Dean" deviendrait en français avec le dictionnaire fr: "je suis amoureux de doyen" Notez qu'on ne s'attend pas à ce que vous donniez des traductions exactes mais bien une traduction mot par mot. De plus, les clés sont enregistrées en minuscules dans le dictionnaire.

Implémentez la fonction translate(data, lan) en Python.

Avec data comme la chaine de caractère que vous souhaiter traduire et les dictionnaires nommés selon lan utilisable pour faire les traductions dans le langage ciblé.


        
        

Vous et vos amis vous prêtez souvent de l'argent. Plutôt que d'utiliser une application spéciale pour se rappeler qui doit combien d'argent et à qui, vous décidez de faire votre propre programme python pour réaliser cette tâche.

Spécifiquement, vous aimeriez pouvoir:

  • dire qui doit combien d'argent à qui;
  • changer les comptes quand quelqu'un rembourse ou prête de l'argent à un autre;
  • ajouter une personne qui emprunte et/ou rembourse de l'argent;
  • calcule la somme de tout l'argent emprunté à ce moment précis.

Notez que de l'argent prêté à quelqu'un doit être emprunté. En d'autres termes, si Woody a prêté 3€ à Buzz, votre programme devrait dire que Buzz doit 3€ à Woody et que Woody doit -3€ à Buzz.

Pour faire cela, vous allez utiliser un dictionnaire de dictionnaires appelé borrowed_money, indexé par le nom des personnes (comme des strings). Le premier index sera le nom de "l'emprunteur"; le deuxième, celui du "prêteur".

Par exemple, si Woody a prêté 3€ à Buzz, votre dictionnaire devrait être comme suit:

borrowed_money[\"Buzz\"][\"Woody\"] == 3  # Lisez \"Buzz doit 3€ à Woody\"
borrowed_money[\"Woody\"][\"Buzz\"] == -3

Par conséquent, vous pouvez obtenir un dictionnaire qui contient tout l'argent que Buzz emprunte:

borrowed_money[\"Buzz\"] == {\"Woody\": 3, \"Hamm\": 60, \"Rex\": -5}

Faites une fonction give_money(borrowed_money, from_person, to_person, amount) qui sera appelée quand from_person donne amount € à to_person (soit parce que from_person prête de l'argent to_person, ou bien parce qu'il rembourse de l'argent qu'il a emprunté). Si une des deux personnes n'est pas déjà une clé dans le dictionnaire, elle doit y être ajoutée. Vous devez lever une ValueError dans le cas où quelqu'un essaye de se donner de l'argent à lui-même.

Faites une autre fonction total_money_borrowed(borrowed_money) qui retourne le montant total d'argent emprunté en ce moment (c'est-à-dire, la somme des montants positifs se trouvant dans le dictionnaire).

Note: vous devez lever une ValueError``*si l'un des arguments passé à ces fonctions est invalide (c'est-à-dire si les noms ne sont pas de strings, si* ``borrowed_money n'est pas un dictionnaire ou si le montant d'argent n'est pas un integer ou un float). Vous pouvez tester si une variable est du bon type des manières suivantes :

variable = 5
type(variable) == int  # retourne True
# OR
isinstance(variable, int)  # retourne True

Enfin, implémentez l'exemple où Mark prête 2 000 000 € à Bill et Steve, Serguei prête 5 000 000 € à Bill, Bill prête 6 000 000 € à Larry et enfin, Larry prête 5,5 € à Linus. Ensuite, Steve rembourse Mark. Utilisez la variable borrowed_money.