L'administration de la sécurité sociale dispose de ces données détaillées, classées par année, sur les noms les plus populaires pour les bébés nés cette année-là aux États-Unis (voir la page noms de bébés de la sécurité sociale).
Les fichiers de cet exercice se trouvent dans le dossier « babynames » dans google-python-exercises (téléchargez le fichier google-python-exercises.zip si ce n'est pas déjà fait, ou consultez Configuration pour plus d'informations). Ajoutez votre code dans babynames.py. Les fichiers baby1990.html baby1992.html ... contiennent du html brut, similaire à celui que vous obtenez sur le site de sécurité sociale mentionné ci-dessus. Jetez un œil au code html et réfléchissez à la manière dont vous pourriez en extraire les données.
Partie A
Dans le fichier babynames.py, implémentez la fonction extract_names(filename) qui prend le nom d'un fichier baby*.html et renvoie les données du fichier sous la forme d'une liste unique (la chaîne d'année au début de la liste suivie des chaînes de rang dans l'ordre alphabétique). ['2006', 'Aaliyah 91', 'Abagail 895', 'Aaron 57', ...]. Modifiez main() de sorte qu'elle appelle votre fonction extract_names() et imprime ce qu'elle renvoie (main dispose déjà du code pour l'analyse des arguments de ligne de commande). Si vous avez du mal à définir les expressions régulières pour l'année et chaque nom, les modèles d'expression régulière de la solution sont présentés à la fin de ce document. Notez que pour l'analyse des pages Web en général, les expressions régulières ne sont pas efficaces, mais le format de ces pages Web est simple et cohérent.
Plutôt que de traiter les noms des garçons et des filles séparément, nous allons les regrouper. Certaines années, un nom apparaît plusieurs fois dans le code html, mais nous n'utiliserons qu'un chiffre par nom. Facultatif: Faites en sorte que l'algorithme soit intelligent pour ce cas de figure et choisissez le nombre le plus petit.
Élaborez le programme sous la forme d'une série d'étapes simples, où chaque étape consiste à exécuter/imprimer quelque chose avant de passer à l'étape suivante. C'est le modèle utilisé par les programmeurs expérimentés : créez une série de jalons incrémentiels, chacun avec des résultats à vérifier, au lieu de construire l'ensemble du programme en une seule étape importante.
L'impression des données dont vous disposez à la fin d'un jalon vous aide à réfléchir à la façon de restructurer ces données pour le prochain jalon. Python est parfaitement adapté à ce style de développement incrémentiel. Par exemple, allez d'abord jusqu'au point où il extrait et imprime l'année, puis appelle sys.exit(0). Voici quelques suggestions de jalons:
- Extraire tout le texte du fichier et l'imprimer
- Trouvez et extrayez l'année, puis imprimez-la
- Extraire les noms et les nombres de classement, puis les imprimer
- Extraire les données de noms dans un dictionnaire et les imprimer
- Créez la liste [year, 'name Rank', ... ] et imprimez-la
- Correction de main() pour utiliser la liste ExtractNames
Auparavant, les fonctions impliquaient simplement la sortie standard. Il est plus facile à réutiliser que la fonction *renvoie* les données extraites, de sorte que l'appelant a le choix de les imprimer ou d'en faire autre chose. (Vous pouvez toujours imprimer directement à partir de vos fonctions pour vos petits tests pendant le développement.)
Demandez à main() d'appeler extract_names() pour chaque argument de ligne de commande et d'imprimer un résumé au format texte. Pour transformer la liste en un texte récapitulatif d'apparence raisonnable, voici une utilisation intelligente de la jointure: text = '\n'.join(mylist) + '\n'
Le texte récapitulatif doit se présenter comme suit pour chaque fichier:
2006 Aaliyah 91 Aaron 57 Abagail 895 Abbey 695 Abbie 650 ...
Partie B
Supposons qu'au lieu d'imprimer le texte sur la sortie standard, nous voulons écrire des fichiers contenant le texte. Si l'indicateur --summaryfile est présent, procédez comme suit: pour chaque fichier d'entrée "foo.html", au lieu d'imprimer sur la sortie standard, écrivez un nouveau fichier "foo.html.summary" qui contient le texte récapitulatif pour ce fichier.
Une fois que la fonction --summaryfile fonctionne, exécutez le programme sur tous les fichiers en utilisant * comme ceci : "./babynames.py --summaryfile baby*.html". Tous les récapitulatifs sont alors générés en une seule étape. (Le comportement standard du shell est qu'il développe le modèle "baby*.html" dans la liste des noms de fichiers correspondants, puis le shell exécute babynames.py, en transmettant tous ces noms de fichiers dans la liste sys.argv.)
Avec les données organisées dans des fichiers de résumé, vous pouvez voir des modèles au fil du temps à l'aide de commandes shell, comme ceci:
$ grep 'Trinity ' *.summary $ grep 'Nick ' *.summary $ grep 'Miguel ' *.summary $ grep 'Emily ' *.summary
Expressions régulières -- année: r'Popularité\sin\s(\d\d\d\d)' noms: r'<td>(\d+)</td><td>(\w+)</td>\<td>(\w+)</td>'