in reply to Practice your major scale modes

Great idea - thanks for a fun exercise :) In the spirit of TMTOWTDI, you might consider some of the techniques used below to achieve the same end. It's a little more 'Perlish', and demonstrates a few things - in particular, use of single hashes to replace whole 'lookup' subroutines.
#!/usr/bin/perl use strict; use Benchmark; my @white_keys = (0,2,4,5,7,9,11); my @modes = qw(Ionian Dorian Phrygian Lydian Mixolydian Aeolian Locria +n); my $note = int(rand(12)); my $mode = int(rand(7)); my $pref = qw(# b # b # b b # b # b #)[$note]; my %note2num = qw(C 0 C# 1 Db 1 D 2 D# 3 Eb 3 E 4 F 5 F# 6 Gb 6 G 7 G# + 8 Ab 8 A 9 A# 10 Bb 10 B 11); my %num2note = (($pref eq 'b') ? qw(0 C 1 Db 2 D 3 Eb 4 E 5 F 6 Gb 7 G 8 Ab 9 A 10 Bb 11 B) : qw(0 C 1 C# 2 D 3 D# 4 E 5 F 6 F# 7 G 8 G# 9 A 10 A# 11 B)); #rotate white_keys round to right mode foreach (0..$mode-1) {push @white_keys, shift @white_keys} my @scale = map {($_+$note-$white_keys[0])%12} @white_keys; print $num2note{$note}, " ", $modes[$mode], ":+\n"; my $t0 = new Benchmark; my $cool = <STDIN>; my $t1 = new Benchmark; my ($measure) = timestr(timediff($t1, $t0)) =~ /^\s?(\d+ wallclock sec ++s).*/; my $response = join(" ", map {$note2num{$_}} split(/\s/, $cool)); if ($response eq join (" ", @scale)) { print "You're Right! $measure\n"; } else { print "Sorry $measure\nThe correct scale was: ",join (",",map {$nu +m2note{$_}} @scale),"\n"; } exit;
Of course, the musicologists will notice that the enharmonic equivalents need sorting out - strictly speaking, for instance, Bb Phrygian should be Bb,Cb etc., attempting to maintain the 'always change the letter' directive...I leave this as a further exercise :)

Good luck with the impro - all the best people are jazzers. :)