Advertisement
bingnet

rhymeThis

May 7th, 2013
2,101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 5.12 KB | None | 0 0
  1. #So, I've had two *fantastic* margaritas, one *lucious* mojito, and two glasses of straight up rum-on-the-rocks. My girlfriend has a hankerin' for words that rhyme with Linux commands...so here ya go.
  2.  
  3. #Interactive pasteable paste of a bourne shell session employing Soundex and
  4. # Perl to find command-line executables that rhyme with each other
  5. #Requires: GNU/Linux, gcc, bash, perl5, and Internet egress and creates a new script named
  6. # rhymeThis.pl which has modes to create forward and reverse lookup tables that map
  7. #  words<==>sounds.
  8.  
  9. # The default mode accepts a word as an argument and returns a sorted list of rhymes
  10.  
  11. # TODO
  12. # * parameterize library name
  13. # * automatically generate lookup tables
  14. # * accept multiple words and weight results by intersecting pronunciation
  15.  
  16. #generate a library of words from all unique commands on this GNU/Linux system
  17. :; compgen -A function -abck|sort -u >./compgen.out
  18.  
  19. #lookup a command in the library
  20. # output looks like 'head'
  21. :; grep "^head" ./compgen.out
  22.  
  23. #download the "DoubleMetaphone" phonetic encoding software, which is based on Soundex, and
  24. # inform your current shell about its location
  25. :; { curl -sL cpanmin.us | perl - --local-lib=~/perl5 local::lib Text::DoubleMetaphone; } && eval \
  26.     $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
  27.  
  28. #use DoubleMetaphone to generate a forward lookup table mapping each command in the library as a
  29. # whole as well as its vowel-delimited suffix to the primary and secondary phonetic encodings
  30. #  (I'd use the trailing phoneme instead if I knew how)
  31. :; cat<<\HERE > ./rhymeThis.pl && chmod -c +x ./rhymeThis.pl && ./rhymeThis.pl cmd2code < ./compgen.out > ./rhymeThis.fwd
  32. #!/usr/bin/perl
  33. use Text::DoubleMetaphone qw(double_metaphone);
  34. use strict;
  35. my $mode = shift;
  36. my %modes =
  37.   (
  38.     'cmd2code' => \&cmd2code,
  39.     'code2cmd' => \&code2cmd,
  40.   );
  41. if (!$modes{$mode}) {
  42.   &pretty($mode);
  43. } else {
  44.   $modes{$mode}->();
  45. }
  46. sub cmd2code() {
  47.   while (<STDIN>) {
  48.     chomp;
  49.     my($rhyme) = my($cmd) = lc($_);
  50.     $rhyme =~ s/.*([aeiou][^aeiou]+)$/$1/;
  51.     my($first, $second) = double_metaphone($cmd);
  52.     my($third, $fourth) = double_metaphone($rhyme);
  53.     print "$cmd,$rhyme,$first,$second,$third,$fourth\n";
  54.   };
  55. };
  56.  
  57. HERE
  58.  
  59. #lookup a word in the fwd table
  60. # output looks like 'head,ad,HT,,AT,'
  61. :; grep "^head" ./rhymeThis.fwd
  62.  
  63. #the lookup table isn't really useful since it only gives us a pronunciation for the word we lookup, so let's add a subroutine to map each phonetic code in the fwd table to all of the commands that have the same sound
  64. :; cat<<\HERE >> ./rhymeThis.pl && ./rhymeThis.pl code2cmd < ./rhymeThis.fwd > ./rhymeThis.rev
  65. sub code2cmd() {
  66.   my (%commands,%encodings);
  67.   while (<STDIN>) {
  68.     chomp;
  69.     my($command,$rhyme,$first,$second,$third,$fourth) = split(/,/);
  70.     my(@encodings) = ($first,$second,$third,$fourth);
  71.     $commands{$command} = \@encodings;
  72.   };
  73.   foreach my $command (keys %commands) {
  74.     foreach my $encoding (@{$commands{$command}}) {
  75.       unless (!$encoding) {
  76.         no strict 'refs';
  77.         $encodings{$encoding} = \@$encoding;
  78.         push(\@$encoding,$command);
  79.       };
  80.     };
  81.   };
  82.   foreach my $encoding (sort keys %encodings) {
  83.     print "$encoding:\t";
  84.     my (%uniqCmds) = map { $_ => 1 } @{$encodings{$encoding}};
  85.     foreach my $command (sort keys %uniqCmds) {
  86.       print $command . ", ";
  87.     };
  88.     print "\n";
  89.   };
  90. };
  91.  
  92. HERE
  93.  
  94. #lookup a word in the reverse table
  95. # output looks like 'HT:     head,'
  96. :; grep "head," ./rhymeThis.rev|tail -1
  97.  
  98. #some sounds have numerous matches so the results are visually noisy, so this returns a formatted result
  99. :; cat<<\HERE >> ./rhymeThis.pl
  100. sub pretty() {
  101.   open revTable,"./rhymeThis.rev" or die "Reverse lookup table not found. $!";
  102.   my (@matches,@rhymes);
  103.   while (<revTable>) {
  104.     next unless m/$_[0]/;
  105.     chomp;
  106.     $_ =~ s/^[^:]+:\t(.*)/$1/;
  107.     $_ =~ s/\s+//g;
  108.     push(@matches,split(/,/));
  109.   }
  110.   close revTable;
  111.   my (%uniqMatches) = map { scalar reverse($_) , 1 } @matches;
  112.   foreach (reverse sort keys %uniqMatches) {
  113.     push(@rhymes,scalar reverse($_));
  114.   }
  115.   foreach (@rhymes) {
  116.     printf("%48s\n",$_);
  117.   }
  118. }
  119.  
  120. HERE
  121.  
  122. #give it a whirl
  123. # output is like
  124. # …
  125. #                                          parted
  126. #                           popcon-largest-unused
  127. #                                            psed
  128. #                                             sed
  129. #                                           shred
  130. #                                             red
  131. #                                     _rl_enabled
  132. #                      landscape-is-cloud-managed
  133. #                                              ed
  134. # …
  135.  
  136. # find other commands that rhyme with any command on  this computer
  137. :;./rhymeThis.pl head
  138.  
  139. # find commands on this computer that rhyme with any english word
  140. :; cat<<\HERE > ./soundcode && chmod -c +x ./soundcode
  141. perl -MText::DoubleMetaphone='double_metaphone' -e '@codes = double_metaphone($ARGV[0]);foreach (@codes) { print "$_\n"; }' $1|grep -f - ./rhymeThis.fwd
  142. HERE
  143.  
  144. #say this to find sounds in the fwd lookup table that match an arbitrary english word
  145. :; ./soundcode head
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement