Упражнение «Имена детей на языке Python»

Администрация социального обеспечения располагает точными данными по годам о том, какие имена наиболее популярны для детей, родившихся в этом году в США (см. Имена детей, получающих социальное обеспечение ).

Файлы для этого упражнения находятся в каталоге «babynames» внутри google-python-exercisions (загрузите google-python-exercisions.zip , если вы еще этого не сделали, подробности см. в разделе «Настройка» ). Добавьте свой код в babynames.py. Файлы baby1990.html baby1992.html ... содержат необработанный HTML-код, аналогичный тому, который вы получаете, посещая указанный выше сайт социального обеспечения. Взгляните на HTML и подумайте, как можно извлечь из него данные.

Часть А

В файле babynames.py реализуйте функцию extract_names(filename), которая принимает имя файла baby*.html и возвращает данные из файла в виде единого списка — строку года в начале списка, за которой следует строки ранга имени в алфавитном порядке. ['2006', 'Аалия 91', 'Абагайль 895', 'Аарон 57', ...]. Измените main() так, чтобы она вызывала вашу функцию extract_names() и печатала то, что она возвращает (в main уже есть код для анализа аргументов командной строки). Если вы застряли при разработке регулярных выражений для года и каждого имени, шаблоны регулярных выражений для решения показаны в конце этого документа. Обратите внимание, что для анализа веб-страниц в целом регулярные выражения не очень хороши, но эти веб-страницы имеют простой и согласованный формат.

Вместо того, чтобы рассматривать имена мальчиков и девочек отдельно, мы просто объединим их все вместе. В некоторые годы имя появляется в HTML более одного раза, но мы будем использовать только одно число для каждого имени. Необязательно: сделайте алгоритм умным в этом случае и выберите то число, которое меньше.

Создайте программу как серию небольших этапов, заставляя каждый шаг запускать/распечатывать что-то, прежде чем переходить к следующему шагу. Это шаблон, используемый опытными программистами: создайте серию дополнительных этапов, каждый из которых имеет определенный результат для проверки, вместо того, чтобы создавать всю программу за один огромный шаг.

Распечатка данных, которые у вас есть в конце одной вехи, поможет вам подумать о том, как реструктурировать эти данные для следующей вехи. Python хорошо подходит для такого стиля поэтапной разработки. Например, сначала доведите его до момента, когда он извлекает и печатает год и вызывает sys.exit(0). Вот некоторые рекомендуемые этапы:

  • Извлеките весь текст из файла и распечатайте его.
  • Найдите и извлеките год и распечатайте его.
  • Извлеките имена и номера рангов и распечатайте их.
  • Получите данные об именах в словарь и распечатайте их.
  • Создайте список [год, «ранг имени», ...] и распечатайте его.
  • Исправьте main() для использования списка ExtractNames.

Раньше у нас были функции, просто выводящие данные на стандартный вывод. Гораздо удобнее повторно использовать функцию, *возвращающую* извлеченные данные, так что у вызывающей стороны будет выбор: распечатать их или сделать с ними что-нибудь еще. (Вы по-прежнему можете печатать прямо из своих функций для небольших экспериментов во время разработки.)

Попросите main() вызвать Extract_names() для каждого аргумента командной строки и распечатать текстовую сводку. Чтобы превратить список в разумно выглядящий сводный текст, вот умное использование соединения: text = '\n'.join(mylist) + '\n'

Сводный текст для каждого файла должен выглядеть следующим образом:

2006
Aaliyah 91
Aaron 57
Abagail 895
Abbey 695
Abbie 650
...

Часть Б

Предположим, что вместо вывода текста на стандартный вывод мы хотим записать файлы, содержащие текст. Если присутствует флаг --summaryfile, сделайте следующее: для каждого входного файла «foo.html» вместо вывода на стандартный вывод напишите новый файл «foo.html.summary», содержащий текст сводки для этого файла.

Как только функция --summaryfile заработает, запустите программу для всех файлов, используя * вот так: "./babynames.py --summaryfile baby*.html". Это генерирует все сводки за один шаг. (Стандартное поведение оболочки заключается в том, что она расширяет шаблон «baby*.html» в список совпадающих имен файлов, а затем оболочка запускает babynames.py, передавая все эти имена файлов в список sys.argv.)

Когда данные организованы в сводные файлы, вы можете увидеть закономерности с течением времени с помощью команд оболочки, например:

$ grep 'Trinity ' *.summary
$ grep 'Nick ' *.summary
$ grep 'Miguel ' *.summary
$ grep 'Emily ' *.summary

Подсказки по регулярным выражениям -- год: r'Popularity\sin\s(\d\d\d\d)' имена: r'<td>(\d+)</td><td>(\w+)</td >\<td>(\w+)</td>'