اداره تامین اجتماعی این دادههای دقیق را بر اساس سال در مورد نامهایی که برای نوزادانی که در آن سال متولد شدهاند در ایالات متحده آمریکا محبوبتر است ( به نامهای نوزاد تامین اجتماعی مراجعه کنید) در اختیار دارد.
فایلهای این تمرین در دایرکتوری "babynames" در داخل google-python-exercises قرار دارند (اگر قبلاً google-python-exercises.zip را دانلود نکردهاید، برای جزئیات بیشتر به تنظیمات مراجعه کنید). کد خود را در babynames.py اضافه کنید. فایل های baby1990.html baby1992.html ... حاوی html خام، مشابه آنچه در سایت تامین اجتماعی فوق دریافت می کنید. به html نگاهی بیندازید و به این فکر کنید که چگونه می توانید داده ها را از آن حذف کنید.
قسمت A
در فایل babynames.py، تابع extract_names(filename) را پیاده سازی کنید که نام فایل یک فایل baby*.html را می گیرد و داده ها را از فایل به صورت یک لیست برمی گرداند - رشته سال در ابتدای لیست و به دنبال آن رشته های نام-رتبه به ترتیب حروف الفبا. ['2006', 'Aaliyah 91', 'Abagail 895', 'Aaron 57', ...]. Main() را تغییر دهید تا تابع extract_names() شما را فراخوانی کند و آنچه را که برمی گرداند چاپ کند (main قبلاً کد تجزیه آرگومان خط فرمان را دارد). اگر در کار کردن عبارات منظم برای سال و هر نام گیر کرده اید، الگوهای عبارت منظم راه حل در انتهای این سند نشان داده شده است. توجه داشته باشید که برای تجزیه صفحات وب به طور کلی، عبارات منظم کار خوبی ندارند، اما این صفحات وب قالب ساده و ثابتی دارند.
به جای اینکه اسم پسر و دختر را جداگانه بررسی کنیم، فقط همه آنها را با هم جمع می کنیم. در برخی سال ها، یک نام بیش از یک بار در html ظاهر می شود، اما ما فقط از یک عدد برای هر نام استفاده می کنیم. اختیاری: الگوریتم را در مورد این مورد هوشمند کنید و هر عدد را کوچکتر انتخاب کنید.
برنامه را بهعنوان مجموعهای از نقاط عطف کوچک بسازید و هر مرحله را قبل از امتحان کردن مرحله بعدی، اجرا کنید/چاپ کنید. این الگویی است که توسط برنامه نویسان باتجربه استفاده می شود - به جای ساختن کل برنامه در یک مرحله بزرگ، یک سری نقاط عطف افزایشی ایجاد کنید، که هر کدام خروجی هایی برای بررسی دارند.
چاپ دادههایی که در پایان یک نقطه عطف دارید به شما کمک میکند در مورد چگونگی ساختاردهی مجدد آن دادهها برای نقطه عطف بعدی فکر کنید. پایتون برای این سبک از توسعه تدریجی مناسب است. به عنوان مثال، ابتدا آن را به نقطه ای برسانید که سال را استخراج و چاپ می کند و sys.exit(0) را فراخوانی می کند. در اینجا چند نقطه عطف پیشنهادی وجود دارد:
- تمام متن را از فایل استخراج کرده و آن را چاپ کنید
- سال را پیدا کنید و استخراج کنید و آن را چاپ کنید
- اسامی و اعداد رتبه را استخراج کرده و چاپ کنید
- دادههای نامها را در یک دیکت دریافت کنید و آن را چاپ کنید
- فهرست [سال، «رتبه نام»، ... ] را بسازید و آن را چاپ کنید
- برای استفاده از لیست ExtractNames، main() را رفع کنید
قبلاً ما توابعی را داشتیم که فقط به صورت استاندارد چاپ می شدند. استفاده مجدد از تابع *بازگرداندن* داده های استخراج شده بیشتر است، بنابراین تماس گیرنده می تواند آن را چاپ کند یا کار دیگری با آن انجام دهد. (همچنان می توانید برای آزمایش های کوچک خود در طول توسعه مستقیماً از داخل توابع خود چاپ کنید.)
برای هر خط فرمان arg از main() فراخوانی کنید و یک خلاصه متن را چاپ کنید. برای تبدیل لیست به یک متن خلاصه معقول، در اینجا یک استفاده هوشمندانه از join وجود دارد: text = '\n'.join(mylist) + '\n'
متن خلاصه برای هر فایل باید به شکل زیر باشد:
2006 Aaliyah 91 Aaron 57 Abagail 895 Abbey 695 Abbie 650 ...
قسمت B
فرض کنید به جای اینکه متن را به صورت استاندارد چاپ کنیم، می خواهیم فایل های حاوی متن را بنویسیم. اگر پرچم --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>'