Exercice Python sur les noms de bébés

L'administration de la sécurité sociale dispose de ces données précises par année concernant les noms les plus populaires pour les bébés nés cette année-là aux États-Unis (voir la section Prénoms de bébé nés à la sécurité sociale).

Les fichiers correspondant à cet exercice se trouvent dans le répertoire "babynames" dans google-python-exercises (téléchargez le fichier google-python-exercises.zip si ce n'est pas déjà fait ; pour en savoir plus, consultez Configurer). Ajoutez votre code dans le fichier babynames.py. Les fichiers baby1990.html baby1992.html ... contiennent du html brut, semblable à ce que vous obtenez sur le site de sécurité sociale ci-dessus. Jetez un œil au html et réfléchissez à la façon 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 de fichier d'un fichier baby*.html et renvoie les données du fichier sous la forme d'une liste unique, à savoir la chaîne d'année au début de la liste suivie des chaînes de classement par nom dans l'ordre alphabétique. ['2006', 'Aaliyah 91', 'Abagail 895', 'Aaron 57', ...]. Modifiez main() pour qu'elle appelle votre fonction extract_names() et affiche ce qu'elle renvoie (main contient déjà le code pour l'analyse de l'argument de ligne de commande). Si vous rencontrez des difficultés à travailler sur les expressions régulières pour l'année et pour chaque nom, vous trouverez des modèles d'expressions régulières de solution à 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. Toutefois, ces pages Web ont un format simple et cohérent.

Plutôt que de traiter les prénoms de garçon et de fille séparément, nous allons simplement les regrouper. Certaines années, même si un nom apparaît plusieurs fois dans le code html, nous n'utiliserons qu'un seul chiffre par nom. Facultatif: Dans ce cas précis, utilisez l'algorithme intelligent et choisissez la valeur la plus faible.

Construisez le programme sous la forme d'une série de petits jalons, en faisant en sorte que chaque étape exécute/imprime quelque chose avant de passer à l'étape suivante. C'est le principe 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.

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 bien adapté à ce style de développement incrémentiel. Par exemple, commencez par l'atteindre 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
  • Localisez et extrayez l'année, puis imprimez-la
  • Extraire les noms et classer les nombres, et les imprimer
  • Extraire les données des noms dans un dictionnaire et l'imprimer
  • Construire la liste [year, 'name Rank', ... ] et l'imprimer
  • Correction de main() pour utiliser la liste ExtractNames.

Précédemment, nous avons utilisé des fonctions qui s'affichent sur la sortie standard. Il est plus facile de réutiliser une fonction que la fonction *renvoie* les données extraites. Ainsi, l'appelant peut choisir de les imprimer ou d'en faire autre chose. (Vous pouvez toujours imprimer directement depuis 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'afficher un résumé au format texte. Pour que la liste fournisse un texte récapitulatif raisonnable, voici une utilisation astucieuse 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" contenant le texte récapitulatif de ce fichier.

Une fois que la fonctionnalité --summaryfile fonctionne, exécutez le programme sur tous les fichiers en utilisant * comme ceci: "./babynames.py --summaryfile baby*.html". Tous les résumés 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 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 récapitulatifs, 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

Suggestions d'expressions régulières -- année: r'Popularity\sin\s(\d\d\d\d)' names: r'<td>(\d+)</td><td>(\w+)</td>\<td>(\w+)</td>'