Skip to content

Commit 2e132ee

Browse files
kytrinyxkotp
authored andcommitted
Redesign scale-generator
This changes the design of the scale-generator class to always have a base chromatic scale, and then operate with intervals on that scale. This brings the exercise more in line with the data in problem-specifications.
1 parent e5c3c6e commit 2e132ee

File tree

2 files changed

+63
-87
lines changed

2 files changed

+63
-87
lines changed

exercises/practice/scale-generator/.meta/example.rb

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
class Scale
22
ASCENDING_INTERVALS = %w(m M A)
3-
CHROMATIC_SCALE = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']
3+
CHROMATIC_SCALE = %w(C C# D D# E F F# G G# A A# B)
44
FLAT_CHROMATIC_SCALE = %w(C Db D Eb E F Gb G Ab A Bb B)
55
FLAT_KEYS = %w(F Bb Eb Ab Db Gb d g c f bb eb)
66

7-
def initialize(tonic, pattern = nil)
7+
def initialize(tonic)
88
@tonic = tonic.capitalize
9-
@pattern = pattern
109
@chromatic_scale = FLAT_KEYS.include?(tonic) ? FLAT_CHROMATIC_SCALE : CHROMATIC_SCALE
1110
end
1211

13-
def pitches
14-
return reorder_chromatic_scale unless pattern
12+
def chromatic
13+
reorder_chromatic_scale
14+
end
15+
16+
def interval(pattern)
1517
last_index = 0
1618
scale = pattern.each_char.with_object([]) do |c, collector|
1719
collector << reorder_chromatic_scale[last_index]
@@ -21,10 +23,10 @@ def pitches
2123

2224
private
2325

24-
attr_reader :tonic, :pattern, :chromatic_scale
26+
attr_reader :tonic, :chromatic_scale
2527

2628
def reorder_chromatic_scale
27-
return chromatic_scale if tonic == 'C'
29+
return chromatic_scale if tonic == "C"
2830
index = chromatic_scale.index(tonic)
2931
chromatic_scale[index..-1] + chromatic_scale[0..index - 1]
3032
end

exercises/practice/scale-generator/scale_generator_test.rb

Lines changed: 54 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -2,131 +2,105 @@
22
require_relative 'scale_generator'
33

44
class ScaleGeneratorTest < Minitest::Test
5-
def test_chromatic_scale
5+
def test_chromatic_scales_chromatic_scale_with_sharps
6+
# skip
7+
scale = Scale.new("C")
8+
assert_equal ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"], scale.chromatic
9+
end
10+
11+
def test_chromatic_scales_chromatic_scale_with_flats
612
skip
7-
chromatic = Scale.new('C')
8-
expected = %w[C C# D D# E F F# G G# A A# B]
9-
actual = chromatic.pitches
10-
assert_equal expected, actual
13+
scale = Scale.new("F")
14+
assert_equal %w[F Gb G Ab A Bb B C Db D Eb E], scale.chromatic
1115
end
1216

13-
def test_another_chromatic_scale
17+
def test_scales_with_specified_intervals_simple_major_scale
1418
skip
15-
chromatic = Scale.new('F')
16-
expected = %w[F Gb G Ab A Bb B C Db D Eb E]
17-
actual = chromatic.pitches
18-
assert_equal expected, actual
19+
scale = Scale.new("C")
20+
assert_equal %w[C D E F G A B], scale.interval("MMmMMMm")
1921
end
2022

21-
def test_major_scale
23+
def test_scales_with_specified_intervals_major_scale_with_sharps
2224
skip
23-
major = Scale.new('C', 'MMmMMMm')
24-
expected = %w[C D E F G A B]
25-
actual = major.pitches
26-
assert_equal expected, actual
25+
scale = Scale.new("G")
26+
assert_equal ["G", "A", "B", "C", "D", "E", "F#"], scale.interval("MMmMMMm")
2727
end
2828

29-
def test_another_major_scale
29+
def test_scales_with_specified_intervals_major_scale_with_flats
3030
skip
31-
major = Scale.new('G', 'MMmMMMm')
32-
expected = %w[G A B C D E F#]
33-
actual = major.pitches
34-
assert_equal expected, actual
31+
scale = Scale.new("F")
32+
assert_equal %w[F G A Bb C D E], scale.interval("MMmMMMm")
3533
end
3634

37-
def test_minor_scale
35+
def test_scales_with_specified_intervals_minor_scale_with_sharps
3836
skip
39-
minor = Scale.new('f#', 'MmMMmMM')
40-
expected = %w[F# G# A B C# D E]
41-
actual = minor.pitches
42-
assert_equal expected, actual
37+
scale = Scale.new("f#")
38+
assert_equal ["F#", "G#", "A", "B", "C#", "D", "E"], scale.interval("MmMMmMM")
4339
end
4440

45-
def test_another_minor_scale
41+
def test_scales_with_specified_intervals_minor_scale_with_flats
4642
skip
47-
minor = Scale.new('bb', 'MmMMmMM')
48-
expected = %w[Bb C Db Eb F Gb Ab]
49-
actual = minor.pitches
50-
assert_equal expected, actual
43+
scale = Scale.new("bb")
44+
assert_equal %w[Bb C Db Eb F Gb Ab], scale.interval("MmMMmMM")
5145
end
5246

53-
def test_dorian_mode
47+
def test_scales_with_specified_intervals_dorian_mode
5448
skip
55-
dorian = Scale.new('d', 'MmMMMmM')
56-
expected = %w[D E F G A B C]
57-
actual = dorian.pitches
58-
assert_equal expected, actual
49+
scale = Scale.new("d")
50+
assert_equal %w[D E F G A B C], scale.interval("MmMMMmM")
5951
end
6052

61-
def test_mixolydian_mode
53+
def test_scales_with_specified_intervals_mixolydian_mode
6254
skip
63-
mixolydian = Scale.new('Eb', 'MMmMMmM')
64-
expected = %w[Eb F G Ab Bb C Db]
65-
actual = mixolydian.pitches
66-
assert_equal expected, actual
55+
scale = Scale.new("Eb")
56+
assert_equal %w[Eb F G Ab Bb C Db], scale.interval("MMmMMmM")
6757
end
6858

69-
def test_lydian_mode
59+
def test_scales_with_specified_intervals_lydian_mode
7060
skip
71-
lydian = Scale.new('a', 'MMMmMMm')
72-
expected = %w[A B C# D# E F# G#]
73-
actual = lydian.pitches
74-
assert_equal expected, actual
61+
scale = Scale.new("a")
62+
assert_equal ["A", "B", "C#", "D#", "E", "F#", "G#"], scale.interval("MMMmMMm")
7563
end
7664

77-
def test_phrygian_mode
65+
def test_scales_with_specified_intervals_phrygian_mode
7866
skip
79-
phrygian = Scale.new('e', 'mMMMmMM')
80-
expected = %w[E F G A B C D]
81-
actual = phrygian.pitches
82-
assert_equal expected, actual
67+
scale = Scale.new("e")
68+
assert_equal %w[E F G A B C D], scale.interval("mMMMmMM")
8369
end
8470

85-
def test_locrian_mode
71+
def test_scales_with_specified_intervals_locrian_mode
8672
skip
87-
locrian = Scale.new('g', 'mMMmMMM')
88-
expected = %w[G Ab Bb C Db Eb F]
89-
actual = locrian.pitches
90-
assert_equal expected, actual
73+
scale = Scale.new("g")
74+
assert_equal %w[G Ab Bb C Db Eb F], scale.interval("mMMmMMM")
9175
end
9276

93-
def test_harmonic_minor
77+
def test_scales_with_specified_intervals_harmonic_minor
9478
skip
95-
harmonic_minor = Scale.new('d', 'MmMMmAm')
96-
expected = %w[D E F G A Bb Db]
97-
actual = harmonic_minor.pitches
98-
assert_equal expected, actual
79+
scale = Scale.new("d")
80+
assert_equal %w[D E F G A Bb Db], scale.interval("MmMMmAm")
9981
end
10082

101-
def test_octatonic
83+
def test_scales_with_specified_intervals_octatonic
10284
skip
103-
octatonic = Scale.new('C', 'MmMmMmMm')
104-
expected = %w[C D D# F F# G# A B]
105-
actual = octatonic.pitches
106-
assert_equal expected, actual
85+
scale = Scale.new("C")
86+
assert_equal ["C", "D", "D#", "F", "F#", "G#", "A", "B"], scale.interval("MmMmMmMm")
10787
end
10888

109-
def test_hexatonic
89+
def test_scales_with_specified_intervals_hexatonic
11090
skip
111-
hexatonic = Scale.new('Db', 'MMMMMM')
112-
expected = %w[Db Eb F G A B]
113-
actual = hexatonic.pitches
114-
assert_equal expected, actual
91+
scale = Scale.new("Db")
92+
assert_equal %w[Db Eb F G A B], scale.interval("MMMMMM")
11593
end
11694

117-
def test_pentatonic
95+
def test_scales_with_specified_intervals_pentatonic
11896
skip
119-
pentatonic = Scale.new('A', 'MMAMA')
120-
expected = %w[A B C# E F#]
121-
actual = pentatonic.pitches
122-
assert_equal expected, actual
97+
scale = Scale.new("A")
98+
assert_equal ["A", "B", "C#", "E", "F#"], scale.interval("MMAMA")
12399
end
124100

125-
def test_enigmatic
101+
def test_scales_with_specified_intervals_enigmatic
126102
skip
127-
enigmatic = Scale.new('G', 'mAMMMmM')
128-
expected = %w[G G# B C# D# F F#]
129-
actual = enigmatic.pitches
130-
assert_equal expected, actual
103+
scale = Scale.new("G")
104+
assert_equal ["G", "G#", "B", "C#", "D#", "F", "F#"], scale.interval("mAMMMmm")
131105
end
132106
end

0 commit comments

Comments
 (0)