Guest User

Musical Names

a guest
Nov 7th, 2013
147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 3.77 KB | None | 0 0
  1. #!/usr/bin/perl -w
  2.  
  3. use strict;
  4.  
  5. use Parse::MediaWikiDump;
  6. use Text::MediawikiFormat as => 'wiki2html';
  7. use Time::Piece;
  8. use Unicode::Normalize;
  9.  
  10. no warnings 'utf8';
  11.  
  12. # Get a list of musicals
  13. my @musicals_tmp = category_members('Broadway musicals',500);
  14.  
  15. # Remove non-alphas from musicals
  16. my %musicals;
  17. my %hash_musicals;
  18. foreach my $musical (@musicals_tmp)
  19. {
  20.     #print "$musical\n";
  21.     $musical =~ s/[^A-Za-z ]//g;
  22.     $musicals{lc $musical} = 1;
  23.     $hash_musicals{word2num($musical)} = lc $musical;
  24. }
  25. #die;
  26.  
  27. # Read in famous names
  28. my @names;
  29. my %last_to_first;
  30. open FILE, 'FamousNames.txt' or die $!;
  31. while (<FILE>)
  32. {
  33.     chomp;
  34.     my $name = lc $_;
  35.     my $score = 100;
  36.     if ($name =~ /^(.*)\t(.*)$/) {$name = $1;$score = $2;}
  37.     #next unless $score >= 90;
  38.     my $firstname; my $lastname;
  39.     if ($name =~ /^([^ ]+) ([^ ]+)$/) {$firstname = $1; $lastname = $2;}
  40.     next unless $firstname;
  41.     push(@names,"$firstname $lastname");
  42.     push(@{$last_to_first{$lastname}},$firstname);
  43. }
  44. close FILE;
  45.  
  46. # Go through the names and pull out anyone with the same first name as a musical
  47. my @musical_names;
  48. foreach my $n (@names)
  49. {
  50.     my ($fn, $ln) = split(/ /,$n);
  51.     push(@musical_names,$n) if $musicals{$fn};
  52. }
  53.  
  54. foreach my $fullname (@musical_names)
  55. {
  56.     my ($fn, $ln) = split(/ /,$fullname);
  57.     #print " $fn\n";
  58.     # Find all others with the same last name
  59.     my $last_people_ref = $last_to_first{$ln};
  60.     # Check if any of these people have a first name that anagrams to a musical
  61.     foreach my $new_fn (@$last_people_ref)
  62.     {
  63.         next if $fn eq $new_fn;
  64.         #print "  $new_fn\n";
  65.         if ($hash_musicals{word2num($new_fn)} && $hash_musicals{word2num($new_fn)} ne $new_fn)
  66.         {
  67.             print "$fn and $new_fn $ln => " . $hash_musicals{word2num($new_fn)} . "\n";
  68.         }
  69.     }
  70. }
  71.  
  72.  
  73. ######
  74. # SUBS
  75. ######
  76.  
  77. sub category_members
  78. {
  79.     my ($category,$NUM) = @_;
  80.     $NUM = 500 unless $NUM;
  81.     my %wiki;
  82.    
  83.     # Rather than parsing this every time, it is MUCH better to store and retrieve.
  84.     my $text_file = $category;
  85.     $text_file =~ s/[^A-Za-z _]//g;
  86.     $text_file =~ s/ /_/g;
  87.     $text_file .= ".txt";
  88.    
  89.     if (-e $text_file)
  90.     {
  91.         my @ret;
  92.         open MYFILE, $text_file or die $!;
  93.         while (<MYFILE>)
  94.         {
  95.             chomp;
  96.             push(@ret,$_);
  97.         }
  98.         return @ret;
  99.     }
  100.     else
  101.     {
  102.         # This takes a LONG TIME (about an hour or more)
  103.         my $xmlfile = "enwiki-latest-pages-articles.xml";
  104.         my $pages = Parse::MediaWikiDump::Pages->new($xmlfile);
  105.  
  106.         my @category_members;
  107.  
  108.         # Go through the XML and pull out interesting entries.
  109.         my $ctr = 0;
  110.         while(defined(my $page = $pages->next) && $ctr < $NUM)
  111.         {
  112.             #main namespace only
  113.             next unless $page->namespace eq '';
  114.            
  115.             # Exclude redirects
  116.             next if defined($page->redirect);
  117.            
  118.             # Categories
  119.             my $c = $page->categories;
  120.            
  121.             # Only take musicals
  122.             next unless (grep {/$category/} @$c);
  123.            
  124.             # If we've gotten this far we can proceed
  125.             my $title = $page->title;
  126.             $title = remove_diacritics($title);
  127.             if ($title =~ /^(.*) \([^\)]+\)$/) {$title = $1;}
  128.            
  129.             push(@category_members,$title);
  130.             $ctr++;
  131.         }
  132.        
  133.         # Add this to a text file to pull up later
  134.         open OUTFILE, ">$text_file" or die $!;
  135.         foreach my $c (@category_members) {print OUTFILE "$c\n";}
  136.         close OUTFILE;
  137.         return @category_members;
  138.     }
  139. }
  140.  
  141. # Remove diacritics (from a title)
  142. sub remove_diacritics
  143. {
  144.    my $w = NFD(shift);
  145.    $w =~ s/\pM//g;
  146.    return $w;
  147. }
  148.  
  149. sub word2num
  150. {
  151.     # Given a word, turn it into an order-independent hash
  152.     # Convert the word to ALL CAPS
  153.     my $w = uc shift;
  154.     # Remove any non-alphas
  155.     $w =~ s/[^A-Z]//g;
  156.     my %convert = qw(A 2 B 3 C 5 D 7 E 11 F 13 G 17 H 19 I 23 J 29 K 31 L 37 M 41 N 43 O 47 P 53 Q 59 R 61 S 67 T 71 U 73 V 79 W 83 X 89 Y 97 Z 101);
  157.     my $val = 1;
  158.     foreach my $l (split(//,$w))
  159.     {
  160.         next unless $convert{$l};
  161.         $val *= $convert{$l};
  162.     }
  163.     return $val;
  164. }
Advertisement
Add Comment
Please, Sign In to add comment