🢀︎ mzk :: 04a1f6e


commit 04a1f6e01876eaee762033ca2f9ed372d8d99c2d
Author: acidvegas <acid.vegas@acid.vegas>
Date:   Sat Jul 13 18:52:23 2019 -0400

    Initial commit

diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..69997e8
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,15 @@
+ISC License
+
+Copyright (c) 2019, acidvegas <acid.vegas@acid.vegas>
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e69de29
diff --git a/mzk/constants.py b/mzk/constants.py
new file mode 100644
index 0000000..670489d
--- /dev/null
+++ b/mzk/constants.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python
+# mzk music theory helper - developed by acidvegas in python (https://acid.vegas/mzk)
+# constants.py
+
+circle = '''                        major
+
+                          C
+               F                     G
+                          ♮
+                  1♭              1♯
+                          a
+      B♭             d         c               D
+           2♭                           2♯
+                g       minor       b
+
+
+    E♭   3♭   c                       f♯   3♯   A
+
+
+                f                   c♯
+           4♭                            4
+      A♭            b♭         g♯             E
+                        e♭/d♯
+              5♭/7♯               7♭/5♯
+                        6♭/6♯
+              D♭                     B
+                        G♭/F♯
+          C♯                           C♭'''
+
+colors = {
+	'gray'  : '\033[0;90m',
+	'red'   : '\033[0;91m',
+	'green' : '\033[0;92m',
+	'reset' : '\033[0m'
+}
+
+intervals = {
+	'unison'           : {'semitones':0,  'short_name':'P1' },
+	'minor_second'     : {'semitones':1,  'short_name':'m2' },
+	'major_second'     : {'semitones':2,  'short_name':'M2' },
+	'minor_third'      : {'semitones':3,  'short_name':'m3' },
+	'major_third'      : {'semitones':4,  'short_name':'M3' },
+	'perfect_fourth'   : {'semitones':5,  'short_name':'P4' },
+	'augmented_fourth' : {'semitones':6,  'short_name':'+4' },
+	'diminished_fifth' : {'semitones':6,  'short_name':'d5' },
+	'perfect_fifth'    : {'semitones':7,  'short_name':'P5' },
+	'minor_sixth'      : {'semitones':8,  'short_name':'m6' },
+	'major_sixth'      : {'semitones':9,  'short_name':'M6' },
+	'minor_seventh'    : {'semitones':10, 'short_name':'m7' },
+	'major_seventh'    : {'semitones':11, 'short_name':'M7' },
+	'perfect_octave'   : {'semitones':12, 'short_name':'8va'}
+}
+
+notes         = ('A', 'A#', 'B',   'C',  'C#', 'D',  'D#',  'E',    'F',  'F#', 'G',  'G#'     )
+numerals      = ('I', 'II', 'III', 'IV', 'V',  'VI', 'VII', 'VIII', 'IX', 'X',  'XI', 'XII'    )
+scale_degrees = ('tonic','supertonic','mediant','subdominant','dominant''submediant','subtonic')
+
+scales = {
+	'algerian'              :  '2131131',
+	'aeolian'               :  '2122122',
+	'blues'                 :   '321132',
+	'chromatic'             :  '1111111',
+	'dorian'                :  '2122212',
+	'half_whole_diminished' : '12121212',
+	'harmonic_minor'        :  '2122131',
+	'ionian'                :  '2212221',
+	'locrian'               :  '1221222',
+	'lydian'                :  '2221221',
+	'major'                 :  '2212221',
+	'major_pentatonic'      :    '22323',
+	'melodic_minor'         :  '2122221',
+	'mixolydian'            :  '2212212',
+	'natural_minor'         :  '2122122',
+	'persian'               :  '1311231',
+	'phrygian'              :  '1222122',
+	'whole_half_diminished' : '21212121',
+	'whole_tone'            :  '2222222'
+}
\ No newline at end of file
diff --git a/mzk/functions.py b/mzk/functions.py
new file mode 100644
index 0000000..b3cf09a
--- /dev/null
+++ b/mzk/functions.py
@@ -0,0 +1,153 @@
+#!/usr/bin/env python
+# mzk music theory helper - developed by acidvegas in python (https://acid.vegas/mzk)
+# functions.py
+
+import constants
+
+def generate_notes(key):
+	notes = ['A','A#','B','C','C#','D','D#','E','F','F#','G','G#']
+	while notes[0] != key:
+		notes.append(notes.pop(0))
+	return notes
+
+def generate_scale(string, scale_notes, full=False):
+	notes = generate_notes(string.upper())*2 if full else generate_notes(string.upper())
+	notes.append(notes[0]) # add root note to the end
+	for index,note in enumerate(notes):
+		if note in scale_notes:
+			notes[index] = notes[index].center(5, '-')
+		else:
+			notes[index] = '-'*5
+	return notes
+
+def get_pattern(pattern):
+	new_pattern = list()
+	for step in pattern:
+		if   step == '1' : new_pattern.append('H')
+		elif step == '2' : new_pattern.append('W')
+		elif step == '3' : new_pattern.append('WH')
+	return ' '.join(new_pattern)
+
+def scale(type, key):
+	last = 0
+	notes = generate_notes(key)
+	scale_notes = [notes[0],]
+	for step in scales[type]:
+		last += int(step)
+		if last >= len(notes):
+			last -= len(notes)
+		scale_notes.append(notes[last])
+	return scale_notes
+
+def print_chord():
+	# todo: finish this
+	print('◯  ⬤ ')
+	print('''╳   ╳   ╳   ╳   ╳   ╳
+┌───┬───┬───┬───┬───┐
+│   │   │   │   │   │
+├───┼───┼───┼───┼───┤
+│   │   │   │   │   │
+├───┼───┼───┼───┼───┤
+│   │   │   │   │   │
+├───┼───┼───┼───┼───┤
+│   │   │   │   │   │
+├───┼───┼───┼───┼───┤
+│   │   │   │   │   │
+└───┴───┴───┴───┴───┘
+E   A   D   G   B   e''')
+
+def print_circle_of_fifths():
+	'''
+		definition:
+			the relationship among the 12 tones of the chromatic scale, their corresponding key signatures, & the associated major/minor keys
+
+		accidentals:
+			sharps - F, C, G, D, A, E, B
+			flats  - B, E, A, D, G, C, F
+
+		intervals:
+			unison
+			perfect   fifth
+			major     sencond
+			major     sixth
+			major     third
+			major     seventh
+			augmented fourth
+			minor     second
+			minor     sixth
+			minor     third
+			minor     seventh
+			perfect   fourth
+	'''
+	circle = constants.circle.replace('\n',' \n') + ' ' # todo: fix this
+	for note in ('major','C','F','B♭','E♭','A♭','D♭','C♯','G♭/F♯','B','C♭','E','A','D','G'): # todo: reverse
+		circle = circle.replace(f' {note} ', f' \033[91m{note}\033[0m ')
+	for item in ('♮','1♭','2♭','3♭','4♭','5♭/7♯','6♭/6♯','7♭/5♯','4','3♯','2♯','1♯'):
+		circle = circle.replace(f' {item} ', f' \033[90m{item}\033[0m ')
+	for note in ('minor','a','d','g','c','f','b♭','e♭/d♯','g♯','c♯','f♯','b','c'):
+		circle = circle.replace(f' {note} ', f' \033[92m{note}\033[0m ')
+	print(circle)
+	#print(print_circle_of_fifths.__doc__)
+
+def print_intervals():
+	'''
+	definition:
+		the distance between two notes or pitches
+
+	note:
+		semitone - half step
+		tone     - whole step (b to c & e to f is a tone)
+
+	types:
+		harmonic interval - notes played simultaneously
+		melodic  interval - notes played successively
+
+	makeup:
+		quantity - distance between two notes
+		quality  - number of semitones between notes
+
+	qualities:
+		major/minor - 2nds, 3rds, 6ths, 7ths
+		perfect     - 4ths, 5ths, octaves
+		diminished  - minor/perfect - 1 semitone
+		augmented   - major/perfect + 1 semitone
+	'''
+	print('            I N T E R V A L S           ')
+	print('┌───────────┬──────────────────┬───────┐')
+	print('│ semitones │ quality          │ short │')
+	print('├───────────┼──────────────────┼───────┤')
+	for interval, info in constants.intervals.items():
+		print('│ {0} │ {1} │ {2} │'.format(str(info['semitones']).rjust(9), interval.ljust(16), info['short_name'].ljust(5)))
+	print('└───────────┴──────────────────┴───────┘')
+	#print(print_intervals.__doc__)
+
+def print_scale(root, type, full=False):
+	frets = (24,147) if full else (12,75)
+	print(f'{root.upper()} {type.upper()} SCALE'.center(frets[1]))
+	print('  ┌' + '┬'.join('─'*5 for x in range(frets[0])) + '┐')
+	print('0 │' + '│'.join(str(x).center(5) for x in range(1,frets[0]+1)) + '│')
+	print('  ├' + '┼'.join('─'*5 for x in range(frets[0])) + '┤')
+	scale_notes = scale(type, root)
+	for string in ('eBGDAE'):
+		string_notes = generate_scale(string, scale_notes, full)
+		print(string + ' │' + '│'.join(note.center(5, '-') for note in string_notes[1:]) + '│')
+	print('  └' + '┴'.join('─'*5 for x in range(frets[0])) + '┘')
+	print((', '.join(scale_notes) + ' / ' + get_pattern(scales[type])).rjust(frets[1]))
+
+def print_scales():
+	'''
+	definition:
+		any set of musical notes ordered by fundamental frequency or pitch
+
+	note:
+		1 - half step
+		2 - whole step
+		3 - whole step half step'''
+	print('               S C A L E S               ')
+	print('┌───────────────────────┬─────────────────┐')
+	print('│ name                  │ intervals       │')
+	print('├───────────────────────┼─────────────────┤')
+	for name, pattern in constants.scales.items():
+		print(f'│ {name.ljust(21)} │ {get_pattern(pattern).rjust(15)} │')
+	print('└───────────────────────┴─────────────────┘')
+	#print(print_scales.__doc__)
\ No newline at end of file
diff --git a/mzk/main.py b/mzk/main.py
new file mode 100644
index 0000000..ab013d2
--- /dev/null
+++ b/mzk/main.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python
+# mzk music theory helper - developed by acidvegas in python (https://acid.vegas/mzk)
+# main.py
+
+import argparser
+import sys
\ No newline at end of file