From 9bc1682ec1649422c4238a58b90c335dcd5cd99e Mon Sep 17 00:00:00 2001 From: Frank Harkins Date: Mon, 12 Apr 2021 21:06:45 +0100 Subject: [PATCH 1/6] add melopy to imports --- melopy/chords.py | 4 ++-- melopy/melopy.py | 4 ++-- melopy/scales.py | 4 ++-- melopy/utility.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/melopy/chords.py b/melopy/chords.py index ff5b2f7..2da2a5c 100644 --- a/melopy/chords.py +++ b/melopy/chords.py @@ -1,8 +1,8 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from utility import note_to_key, key_to_note, iterate -from exceptions import MelopyGenericError +from melopy.utility import note_to_key, key_to_note, iterate +from melopy.exceptions import MelopyGenericError CHORD_INTERVALS = { 'maj': [4,3], diff --git a/melopy/melopy.py b/melopy/melopy.py index 77020db..a2dd3ea 100644 --- a/melopy/melopy.py +++ b/melopy/melopy.py @@ -4,8 +4,8 @@ import wave, struct, random, math import os, sys -from utility import * -from scales import * +from melopy.utility import * +from melopy.scales import * # same included wave functions # a function of frequency and tick diff --git a/melopy/scales.py b/melopy/scales.py index c18c11f..ae898db 100644 --- a/melopy/scales.py +++ b/melopy/scales.py @@ -1,8 +1,8 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from utility import note_to_key, key_to_note, iterate -from exceptions import MelopyGenericError +from melopy.utility import note_to_key, key_to_note, iterate +from melopy.exceptions import MelopyGenericError SCALE_STEPS = { "major":[2,2,1,2,2,2,1], diff --git a/melopy/utility.py b/melopy/utility.py index e92e17b..a7ba54d 100644 --- a/melopy/utility.py +++ b/melopy/utility.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- from math import log -from exceptions import MelopyGenericError, MelopyValueError +from melopy.exceptions import MelopyGenericError, MelopyValueError def key_to_frequency(key): """Returns the frequency of the note (key) keys from A0""" From d49c75e75e989ff91ff734e900627abc6cd5f1aa Mon Sep 17 00:00:00 2001 From: Frank Harkins Date: Mon, 12 Apr 2021 21:38:33 +0100 Subject: [PATCH 2/6] / --> // --- melopy/utility.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/melopy/utility.py b/melopy/utility.py index a7ba54d..7d66c5c 100644 --- a/melopy/utility.py +++ b/melopy/utility.py @@ -11,7 +11,7 @@ def key_to_frequency(key): def key_to_note(key, octaves=True): """Returns a string representing a note which is (key) keys from A0""" notes = ['a','a#','b','c','c#','d','d#','e','f','f#','g','g#'] - octave = (key + 8) / 12 + octave = (key + 8) // 12 note = notes[(key - 1) % 12] if octaves: From 5d5f9af5e728aab27664c61e7f14fa3444908f2b Mon Sep 17 00:00:00 2001 From: Frank Harkins Date: Mon, 12 Apr 2021 21:56:51 +0100 Subject: [PATCH 3/6] update readme --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8a6c596..1c79717 100644 --- a/README.md +++ b/README.md @@ -18,9 +18,9 @@ $ python Python 2.7.2 (default, Jun 20 2012, 16:23:33) [GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin Type "help", "copyright", "credits" or "license" for more information. ->>> import melopy ->>> melopy.major_scale('C5') -['C5', 'D5', 'E5', 'F5', 'G5', 'A5', 'B5'] +>>> from melopy.scales import generateScale +>>> generateScale('major', 'c4') +['C4', 'D4', 'E4', 'F4', 'G4', 'A4', 'B4', 'C5'] >>> ``` From d10ba8ce6a75ed80ee51932b3138c9ed8f7c3ab3 Mon Sep 17 00:00:00 2001 From: Frank Harkins Date: Thu, 27 May 2021 20:52:10 +0100 Subject: [PATCH 4/6] make work with python2 --- README.md | 2 +- README.txt | 2 +- melopy/chords.py | 1 + melopy/melopy.py | 2 + melopy/scales.py | 1 + melopy/utility.py | 1 + tests/__init__.py | 2 - tests/melopy_tests.py | 144 ------------------------------------------ 8 files changed, 7 insertions(+), 148 deletions(-) delete mode 100644 tests/__init__.py delete mode 100644 tests/melopy_tests.py diff --git a/README.md b/README.md index 1c79717..4859d60 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ For examples, check out the `examples` directory: To run the tests: - $ python tests/melopy_tests.py + $ python tests.py ### Organization diff --git a/README.txt b/README.txt index 69cbe61..b9da1ee 100644 --- a/README.txt +++ b/README.txt @@ -51,7 +51,7 @@ To run the tests: :: - $ python tests/melopy_tests.py + $ python tests.py Organization ============ diff --git a/melopy/chords.py b/melopy/chords.py index 2da2a5c..032ec94 100644 --- a/melopy/chords.py +++ b/melopy/chords.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +from __future__ import absolute_import, division from melopy.utility import note_to_key, key_to_note, iterate from melopy.exceptions import MelopyGenericError diff --git a/melopy/melopy.py b/melopy/melopy.py index a2dd3ea..63c8e5d 100644 --- a/melopy/melopy.py +++ b/melopy/melopy.py @@ -1,6 +1,8 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +from __future__ import division, absolute_import + import wave, struct, random, math import os, sys diff --git a/melopy/scales.py b/melopy/scales.py index ae898db..2a4cf09 100644 --- a/melopy/scales.py +++ b/melopy/scales.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +from __future__ import absolute_import, division from melopy.utility import note_to_key, key_to_note, iterate from melopy.exceptions import MelopyGenericError diff --git a/melopy/utility.py b/melopy/utility.py index 7d66c5c..2e43c73 100644 --- a/melopy/utility.py +++ b/melopy/utility.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +from __future__ import division, absolute_import from math import log from melopy.exceptions import MelopyGenericError, MelopyValueError diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index 8e637f0..0000000 --- a/tests/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# Licensed under The MIT License (MIT) -# See LICENSE file for more \ No newline at end of file diff --git a/tests/melopy_tests.py b/tests/melopy_tests.py deleted file mode 100644 index bf6f1da..0000000 --- a/tests/melopy_tests.py +++ /dev/null @@ -1,144 +0,0 @@ -#!/usr/bin/env -# -*- coding: utf-8 -*- - -import unittest - -from melopy import chords, scales, utility, exceptions - -def data_provider(data): - def decorator(fn): - def repl(self, *args): - for i in data(): - fn(self, *i) - return repl - return decorator - -class LibraryFunctionsTests(unittest.TestCase): - def test_key_to_frequency(self): - key = 49 - self.assertEqual(440, utility.key_to_frequency(key)) - - def test_note_to_frequency(self): - note = 'A4' - self.assertEqual(440, utility.note_to_frequency(note)) - - def test_note_to_key(self): - note = 'A4' - self.assertEqual(49, utility.note_to_key(note)) - - def test_key_to_note(self): - key = 49 - self.assertEqual('A4', utility.key_to_note(key)) - - def test_iterate(self): - start = 'D4' - pattern = [2, 2, 1, 2, 2, 2] - should_be = ['D4', 'E4', 'F#4', 'G4', 'A4', 'B4', 'C#5'] - self.assertEqual(should_be, utility.iterate(start, pattern)) - - def test_generate_major_scales(self): - start = 'D4' - should_be = ['D4', 'E4', 'F#4', 'G4', 'A4', 'B4', 'C#5','D5'] - self.assertEqual(should_be, scales.generateScale('major', start)) - - def test_generate_chromatic_scales(self): - start = 'C5' - should_be= ['C5', 'C#5', 'D5', 'D#5', 'E5', 'F5', 'F#5', 'G5', 'G#5', 'A5', 'A#5', 'B5'] - self.assertEqual(should_be, scales.generateScale('chromatic', start)) - - def test_generate_major_pentatonic_scales(self): - start = 'C5' - should_be = ['C5', 'D5', 'E5', 'G5', 'A5'] - self.assertEqual(should_be, scales.generateScale('major_pentatonic', start)) - - def test_generate_minor_pentatonic_scales(self): - start = 'A5' - should_be = ['A5', 'C6', 'D6', 'E6', 'G6'] - self.assertEqual(should_be, scales.generateScale('minor_pentatonic', start)) - - def test_generate_dorian_mode(self): - start = 'D5' - should_be = ['D5','E5','F5','G5','A5','B5','C6','D6'] - self.assertEqual(should_be, scales.generateScale('major', start, mode=2)) - - def test_generate_phrygian_mode(self): - start = 'E5' - should_be = ['E5','F5','G5','A5','B5','C6','D6','E6'] - self.assertEqual(should_be, scales.generateScale('major', start, mode=3)) - - def test_generate_lydian_mode(self): - start = 'C5' - should_be = ['C5','D5','E5','F#5','G5','A5','B5','C6'] - self.assertEqual(should_be, scales.generateScale('major', start, mode=4)) - - def test_generate_mixolydian_mode(self): - start = 'C5' - should_be = ['C5','D5','E5','F5','G5','A5','A#5','C6'] - self.assertEqual(should_be, scales.generateScale('major', start, mode=5)) - - def test_generate_dorian_flat_nine(self): - start = 'D5' - should_be = ['D5','D#5','F5','G5','A5','B5','C6','D6'] - self.assertEqual(should_be, scales.generateScale('melodic_minor', start, mode=2)) - - def test_generate_lydian_augmented(self): - start = 'C5' - should_be = ['C5','D5','E5','F#5','G#5','A5','B5','C6'] - self.assertEqual(should_be, scales.generateScale('melodic_minor', start, mode=3)) - - def test_generate_lydian_dominant(self): - start = 'C5' - should_be = ['C5','D5','E5','F#5','G5','A5','A#5','C6'] - self.assertEqual(should_be, scales.generateScale('melodic_minor', start, mode=4)) - - def test_generate_major_triad(self): - start = 'C5' - should_be = ['C5','E5','G5'] - self.assertEqual(should_be, chords.generateChord('maj', start)) - - def test_generate_min_triad(self): - start = 'C5' - should_be = ['C5','D#5','G5'] - self.assertEqual(should_be, chords.generateChord('min', start)) - - def test_generate_maj_first_inversion(self): - start = 'C5' - should_be = ['E5','G5','C5'] - self.assertEqual(should_be, chords.generateChord('maj', start, inversion=1)) - - def test_generate_maj_second_inversion(self): - start = 'C5' - should_be = ['G5','C5','E5'] - self.assertEqual(should_be, chords.generateChord('maj', start, inversion=2)) - - def test_generate_maj_seven(self): - start = 'C5' - should_be = ['C5','E5','G5','B5'] - self.assertEqual(should_be, chords.generateChord('maj7', start)) - - def test_generate_maj_seven(self): - start = 'C5' - should_be = ['C5','E5','G5','B5'] - self.assertEqual(should_be, chords.generateChord('maj7', start)) - - def test_generate_aug(self): - start = 'C5' - should_be = ['C5','E5','G#5'] - self.assertEqual(should_be, chords.generateChord('aug', start)) - - def test_generate_dim(self): - start = 'C5' - should_be = ['C5','D#5','F#5'] - self.assertEqual(should_be, chords.generateChord('dim', start)) - - def test_generate_seven(self): - start = 'C5' - should_be = ['C5','E5','G5','A#5'] - self.assertEqual(should_be, chords.generateChord('7', start)) - - -if __name__ == '__main__': - unittest.main() - -# Licensed under The MIT License (MIT) -# See LICENSE file for more From f626a628665d7089c70695989220fa469e93a13d Mon Sep 17 00:00:00 2001 From: Frank Harkins Date: Thu, 27 May 2021 20:56:21 +0100 Subject: [PATCH 5/6] update README.txt --- README.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.txt b/README.txt index b9da1ee..54e7bfd 100644 --- a/README.txt +++ b/README.txt @@ -24,8 +24,8 @@ Load it Python 2.7.2 (default, Jun 20 2012, 16:23:33) [GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin Type "help", "copyright", "credits" or "license" for more information. - >>> import melopy - >>> melopy.major_scale('C5') + >>> from melopy.scales import generateScale + >>> generateScale('major', 'C5') ['C5', 'D5', 'E5', 'F5', 'G5', 'A5', 'B5'] >>> From 570ca0258968805559657d83285f59ea0db56428 Mon Sep 17 00:00:00 2001 From: Frank Harkins Date: Thu, 27 May 2021 21:02:10 +0100 Subject: [PATCH 6/6] add missing file --- tests.py | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 tests.py diff --git a/tests.py b/tests.py new file mode 100644 index 0000000..0477f25 --- /dev/null +++ b/tests.py @@ -0,0 +1,145 @@ +#!/usr/bin/env +# -*- coding: utf-8 -*- +from __future__ import absolute_import, division, nested_scopes + +import unittest + +from melopy import chords, scales, utility, exceptions + +def data_provider(data): + def decorator(fn): + def repl(self, *args): + for i in data(): + fn(self, *i) + return repl + return decorator + +class LibraryFunctionsTests(unittest.TestCase): + def test_key_to_frequency(self): + key = 49 + self.assertEqual(440, utility.key_to_frequency(key)) + + def test_note_to_frequency(self): + note = 'A4' + self.assertEqual(440, utility.note_to_frequency(note)) + + def test_note_to_key(self): + note = 'A4' + self.assertEqual(49, utility.note_to_key(note)) + + def test_key_to_note(self): + key = 49 + self.assertEqual('A4', utility.key_to_note(key)) + + def test_iterate(self): + start = 'D4' + pattern = [2, 2, 1, 2, 2, 2] + should_be = ['D4', 'E4', 'F#4', 'G4', 'A4', 'B4', 'C#5'] + self.assertEqual(should_be, utility.iterate(start, pattern)) + + def test_generate_major_scales(self): + start = 'D4' + should_be = ['D4', 'E4', 'F#4', 'G4', 'A4', 'B4', 'C#5','D5'] + self.assertEqual(should_be, scales.generateScale('major', start)) + + def test_generate_chromatic_scales(self): + start = 'C5' + should_be= ['C5', 'C#5', 'D5', 'D#5', 'E5', 'F5', 'F#5', 'G5', 'G#5', 'A5', 'A#5', 'B5'] + self.assertEqual(should_be, scales.generateScale('chromatic', start)) + + def test_generate_major_pentatonic_scales(self): + start = 'C5' + should_be = ['C5', 'D5', 'E5', 'G5', 'A5'] + self.assertEqual(should_be, scales.generateScale('major_pentatonic', start)) + + def test_generate_minor_pentatonic_scales(self): + start = 'A5' + should_be = ['A5', 'C6', 'D6', 'E6', 'G6'] + self.assertEqual(should_be, scales.generateScale('minor_pentatonic', start)) + + def test_generate_dorian_mode(self): + start = 'D5' + should_be = ['D5','E5','F5','G5','A5','B5','C6','D6'] + self.assertEqual(should_be, scales.generateScale('major', start, mode=2)) + + def test_generate_phrygian_mode(self): + start = 'E5' + should_be = ['E5','F5','G5','A5','B5','C6','D6','E6'] + self.assertEqual(should_be, scales.generateScale('major', start, mode=3)) + + def test_generate_lydian_mode(self): + start = 'C5' + should_be = ['C5','D5','E5','F#5','G5','A5','B5','C6'] + self.assertEqual(should_be, scales.generateScale('major', start, mode=4)) + + def test_generate_mixolydian_mode(self): + start = 'C5' + should_be = ['C5','D5','E5','F5','G5','A5','A#5','C6'] + self.assertEqual(should_be, scales.generateScale('major', start, mode=5)) + + def test_generate_dorian_flat_nine(self): + start = 'D5' + should_be = ['D5','D#5','F5','G5','A5','B5','C6','D6'] + self.assertEqual(should_be, scales.generateScale('melodic_minor', start, mode=2)) + + def test_generate_lydian_augmented(self): + start = 'C5' + should_be = ['C5','D5','E5','F#5','G#5','A5','B5','C6'] + self.assertEqual(should_be, scales.generateScale('melodic_minor', start, mode=3)) + + def test_generate_lydian_dominant(self): + start = 'C5' + should_be = ['C5','D5','E5','F#5','G5','A5','A#5','C6'] + self.assertEqual(should_be, scales.generateScale('melodic_minor', start, mode=4)) + + def test_generate_major_triad(self): + start = 'C5' + should_be = ['C5','E5','G5'] + self.assertEqual(should_be, chords.generateChord('maj', start)) + + def test_generate_min_triad(self): + start = 'C5' + should_be = ['C5','D#5','G5'] + self.assertEqual(should_be, chords.generateChord('min', start)) + + def test_generate_maj_first_inversion(self): + start = 'C5' + should_be = ['E5','G5','C5'] + self.assertEqual(should_be, chords.generateChord('maj', start, inversion=1)) + + def test_generate_maj_second_inversion(self): + start = 'C5' + should_be = ['G5','C5','E5'] + self.assertEqual(should_be, chords.generateChord('maj', start, inversion=2)) + + def test_generate_maj_seven(self): + start = 'C5' + should_be = ['C5','E5','G5','B5'] + self.assertEqual(should_be, chords.generateChord('maj7', start)) + + def test_generate_maj_seven(self): + start = 'C5' + should_be = ['C5','E5','G5','B5'] + self.assertEqual(should_be, chords.generateChord('maj7', start)) + + def test_generate_aug(self): + start = 'C5' + should_be = ['C5','E5','G#5'] + self.assertEqual(should_be, chords.generateChord('aug', start)) + + def test_generate_dim(self): + start = 'C5' + should_be = ['C5','D#5','F#5'] + self.assertEqual(should_be, chords.generateChord('dim', start)) + + def test_generate_seven(self): + start = 'C5' + should_be = ['C5','E5','G5','A#5'] + self.assertEqual(should_be, chords.generateChord('7', start)) + + +if __name__ == '__main__': + unittest.main() + +# Licensed under The MIT License (MIT) +# See LICENSE file for more