Consignes

La partie obligatoire de ce TP sera notée par votre intervenant pendant la séance de TP. Vous devrez donc appeler votre intervenant à chaque fois que vous avez terminé une question.

Les questions « bonus » peuvent être envoyée par email à votre intervenant pendant la semaine (7 jours) qui suivent votre séance de TP. N'oubliez pas de mettre votre nom ainsi que votre filière en commentaire dans les fichiers que vous nous envoyez...

Attention : pour que les questions bonus soient prises en compte, il faut que les questions obligatoires aient été traitées. Si vous n'avez pas fini les questions obligatoires en TP, il faut donc les finir chez vous avant de traiter les questions bonus...

La note ne valide pas seulement le résultat de votre programme, mais également son style :

Vérifiez ces points avant de demander à votre intervenant de valider votre code.

Liens utiles

Préliminaires

Le but de ce TP est d'apprendre à manipuler les chaînes de caractères en utilisant la bibliothèque standard de Python. N'oubliez pas les consignes données en cours concernant la qualité du code écrit.

1. Préliminaires : chaînes

1.1. Exercice : compter les mots d'un texte

Le but de cet exercice est de compter les mots présents dans une chaîne de caractères. Pour éviter d'avoir à écrire des chaînes de caractères pour tester votre programme, vous utiliserez un fichier.

En vous reportant aux consignes si dessous, programmez une fonction "mots_courants" qui affiche la liste des 10 mots les plus courants dans un fichier.

>>> mots_courants("test.txt")
Le mot "de"            apparait  162 fois dans le fichier.
Le mot "le"            apparait   93 fois dans le fichier.
Le mot "la"            apparait   90 fois dans le fichier.
Le mot "et"            apparait   83 fois dans le fichier.
Le mot "à"             apparait   69 fois dans le fichier.
Le mot "les"           apparait   67 fois dans le fichier.
Le mot "que"           apparait   54 fois dans le fichier.
Le mot "ne"            apparait   47 fois dans le fichier.
Le mot "Lupin"         apparait   44 fois dans le fichier.
Le mot "plus"          apparait   43 fois dans le fichier.

Le fichier "test.txt" est disponible ici.

Consignes

Pour obtenir la liste des lignes d'un fichier texte, il faut utiliser le code Python suivant :

fichier = "./mon_fichier.txt"
lignes = open(fichier).readlines()

Attention : :

Le plus simple pour programmer votre fonction "mots_courants" est de suivre la méthode suivante :

  1. on récupère la liste des lignes du fichier.
  2. On colle toutes les lignes ensembles pour obtenir une grande chaîne de caractères contenant tout le fichier (indice : utilisez la méthode "join").
  3. On découpe cette chaîne de caractères pour obtenir la liste de tous les mots.
  4. Pour compter, on va utiliser un dictionnaire, qui associe le nombre d'occurrences pour chaque mot du texte :
    • on initialise le dictionnaire avec dic = {}, et on trouve le nombre d'occurrences d'un mot existant avec "dic[mot]" ou avec "dic.get(mot)",
    • on parcourt la liste des mots, pour chaque mot trouvé, on incrémente le compteur d'occurrences.
  5. Pour obtenir la liste des mots triés par nombre d'occurrences, le plus simple est de parcourir le dictionnaire pour créer la liste qui contient les paires "(nb_occurences , mot)" ; on peut ensuite trier cette liste (méthode "sort") pour avoir les mots selon leurs nombre d'occurrences, et par ordre alphabétique en cas d'égalité.
  6. Il suffit ensuite d'afficher ce que l'on veut dans cette liste...

Bonus (facile) Ajouter les fonctionnalités suivantes en utilisant des arguments supplémentaire, avec une valeur par défaut bien choisie :

1.2. Bonus : mélanges

Vous avez peut-être déjà vu passer ce petit texte :

Sleon une édtue de l'Uvinertisé de Cmabrigde, l'odrre des ltteers dnas les mtos n'a pas d'ipmrotncae, la suele coshe ipmrotnate est que la pmeirère et la drenèire soit à la bnnoe pclae. Le rsete peut êrte dnas un dsérorde ttoal et vuos puoevz tujoruos lrie snas porlblème. C'est prace que le creaveu hmauin ne lit pas chuaqe ltetre elle-mmêe, mias le mot cmome un tuot.

(texte original)

Bonus

Écrivez une petite fonction "melange" qui prend en argument un fichier, et qui l'affiche mais en modifiant l'ordre des lettres de chaque mot, en gardant la première et dernière lettre fixe.

Consignes :

Bonus (difficile)

Votre fonction ne fait probablement pas la différence entre les lettres et la ponctuation. Modifier la fonction pour qu'elle ne mélange pas la ponctuation.

1.3. Bonus : retour sur le comptage

Il existe une autre manière de programmer la fonction "mots_courants" :

  1. on récupère la liste des lignes du fichier.
  2. On colle toutes les lignes ensembles pour obtenir une grande chaîne de caractères contenant tout le fichier (indice : utilisez la méthode "join").
  3. On découpe cette chaîne de caractères pour obtenir la liste de tous les mots (indice : utilisez la méthode "split").
  4. pour compter, on va utiliser simplement utiliser la méthode "count" sur chacun des mots. On ajoutera la paire "(nb_occurences, mot)" dans une liste.

    On peut itérer sur l'ensemble de tous les mots avec

        for mot in set(tous_les_mots):
            ... mot ...
    
    Ceci évite de recompter plusieurs fois le même mot...

  5. On peut ensuite trier cette liste (méthode "sort") pour avoir les mots selon leurs nombre d'occurrences, et par ordre alphabétique en cas d'égalité.
  6. Il suffit ensuite d'afficher ce que l'on veut dans cette liste triée...

Bonus

Écrivez la fonction "mots_courant_bis" correspondante.

Si vous testez les deux fonctions sur un gros fichier, vous remarquerez que "mots_courants_bis" prend beaucoup plus de temps que "mots_courants".

Bonus

Donnez une explication à ce phénomène.

2. Seconde partie : expressions régulières

Accèder à une URL

La fonction suivante, à copier / coller dans votre propre fichier, permet d'obtenir un tableau de lignes pour une adresse web donnée sous forme de chaîne de caractères. (Pour que les appels suivants se fassent plus rapidement, la fonction sauve le contenu de l'URL dans un fichier afin de ne pas tout retélécharger à chaque fois. Vous pouvez donner la valeur "False" au paramètre "local" pour forcer le téléchargement...)

from urllib.request import urlopen
import os
import hashlib

def get_url(url, local=True):
    nom_fichier = hashlib.md5(url.encode("utf8")).hexdigest() + ".tmp"

    if os.path.exists(nom_fichier) and local:
        lignes = open(nom_fichier).readlines()
    else:
        fichier = open(nom_fichier, "w")
        lignes = urlopen(url).read().decode("utf8","ignore").split("\n")
        for ligne in lignes:
            fichier.write(ligne + "\n")
        fichier.close()
    return(lignes)

2.1. Liste des images dans une page web

En utilisant la bibliotheque sur les expressions régulières, il est assez facile de repérer les images présentes sur une page web grâce à la balise HTML "<img src="..."/>"

Programmez une fonction "liste_images" qui affiche la liste des images présentes dans le contenu d'une URL.

>>> liste_images("http://www.univ-savoie.fr")
  - image    0 : 'fileadmin/templates/main/images/intranet.jpg'
  - image    1 : 'fileadmin/templates/main/images/bt_aide.gif'
  - image    2 : 'fileadmin/templates/main/images/logo_print.gif'
  - image    3 : 'fileadmin/templates/main/images/spacer.gif'
  - image    4 : 'fileadmin/templates/main/images/coin_gauche_menu.gif'
  - image    5 : 'fileadmin/templates/main/images/coin_droit_menu.gif'
  - image    6 : 'http://www.univ-savoie.fr/fileadmin/Communication/Accueil/accueil_JDL.png'
  - image    7 : 'fileadmin/templates/main/images/slogan.gif'
  - image    8 : 'fileadmin/templates/main/images/logofb.png'
  - image    9 : 'fileadmin/templates/main/images/logotwitter.png'
  - image   10 : 'fileadmin/templates/main/images/picto_unite.gif'
  - image   11 : 'fileadmin/templates/main/images/picto_unite.gif'
  - image   12 : 'fileadmin/templates/main/images/picto_biblio.gif'
  - image   13 : 'fileadmin/templates/main/images/picto_marches.gif'
  - image   14 : 'fileadmin/templates/main/images/picto_contactez.gif'
  - image   15 : 'fileadmin/templates/main/images/picto_annuaire.gif'
  - image   16 : 'fileadmin/templates/main/images/picto_venir.gif'
  - image   17 : 'fileadmin/templates/main/images/picto_plan.gif'

Attention : les balises HTML peuvent s'utiliser aussi bien en majuscule qu'en minuscule ; et il est possible que les balises soient sur plusieurs lignes...

Bonus : obtenir l'adresse complète des images

Bonus

Comme le montre l'exemple ci dessus, les images peuvent être donnée avec un chemin absolu ("'http://www.univ-savoie.fr/fileadmin/Communication/Accueil/accueil_JDL.png'") ou avec un chemin relatif ("'fileadmin/templates/main/images/intranet.jpg'").

Modifiez votre fonction en ajoutant un paramètre booléen "chemin absolu" qui permettra d'afficher le chemin absolu des images :

...
  - image   11 : 'http://www.univ-savoie.fr/fileadmin/templates/main/images/picto_unite.gif'
...

2.2. La météo à Chambéry et Kuala Lumpur

Yahoo propose un service de météo par « flux RSS » sur le web. Par exemple, la page http://weather.yahooapis.com/forecastrss?p=MYXX0008 contient les lignes suivantes :

...
<yweather:location city="Kuala Lumpur" region=""   country="MY"/>
<yweather:units temperature="F" distance="mi" pressure="in" speed="mph"/>
<yweather:wind chill="77"   direction="0"   speed="0" />
<yweather:atmosphere humidity="94"  visibility="2.49"  pressure="29.83"  rising="0" />
<yweather:astronomy sunrise="7:26 am"   sunset="7:25 pm"/>
...
<pubDate>Tue, 24 Jan 2012 1:00 am MYT</pubDate>
<yweather:condition  text="Fog"  code="20"  temp="77"  date="Tue, 24 Jan 2012 1:00 am MYT" />
...

Notez que la ligne "units" contient "temperature="F"" car la température est donnée en degrés Fahrenheit. (Si on avait "temperature="c"", la température serait un degrés Celsius...) Pour convertir une température en Fahrenheit en degrés Celsius, il faut faire Tc = (Tf-32) * 5/9.

Écrivez une fonction "meteo" qui prend un code (comme "MYXX0008" pour Kualalumpur, ou "FRXX0147" pour Chambéry) et affiche la météo, avec la température en degrés Celsius :

>>> meteo("FRXX0147")
Bulletin actuel pour Chambery :
  - température : 7.2
  - lever du soleil à '8:07 am' et coucher du soleil à '5:28 pm'

Bonus

Vous pourrez utilisez la description ("text="Fog") ci dessus, de la balise yweather:condition, et la transformer en un caractère Unicode pour rendre l'affichage plus explicite dans certain cas:

Bonus

Ajouter quelques lignes à votre fonction "meteo" pour faire cet affichage :

>>> meteo("FRXX0212")
Bulletin actuel pour Chamonix :
  - il fait : ☔ 
  - température : 1.1
  - lever du soleil à '8:07 am' et coucher du soleil à '5:19 pm'

>>> meteo("MXDF0132")
Bulletin actuel pour Mexico City :
  - il fait : ☀ 
  - température : 21.1
  - lever du soleil à '7:11 am' et coucher du soleil à '6:21 pm'