Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- #-*- coding: utf8 -*-
- """
- guitar chords manager.py
- """
- """
- this is a stand-alone module that gives guitar chords (taking the postion
- of fingers) their notes and names.
- Instructions :
- just call :
- -- GuitarChords(arg) --
- where arg is a list of your chords ie [0,0,2,2,1,0] for a Am
- """
- # import
- import sys, logging
- from collections import Iterable
- # logging
- l = logging.WARNING
- logging.basicConfig(level=l, format="%(levelname)s : %(message)s")
- info = logging.info
- # class
- class GuitarChords(object) :
- # consts
- __SCALE = { 0 : "C",
- 1 : "C#",
- 2 : "D",
- 3 : "D#",
- 4 : "E",
- 5 : "F",
- 6 : "F#",
- 7 : "G",
- 8 : "G#",
- 9 : "A",
- 10 : "A#",
- 11 : "B",
- 12 : "C",
- -1000 : "x" }
- __RSCALE = {j:i for i,j in __SCALE.items()}
- __CORDS = ["E", "A", "D", "G", "B", "E"]
- __RCORDS = [ 4, 9, 2, 7, 11, 4]
- #-------------------------------------------
- # add banjo and ukulele chords
- #-------------------------------------------
- def __init__(self, *arg) :
- # consts
- self.scale = GuitarChords.__SCALE
- self.rscale = GuitarChords.__RSCALE
- self.cords = GuitarChords.__CORDS
- self.rcords = GuitarChords.__RCORDS
- info("self.cords : "+ str(self.cords))
- # handle argument type
- if len(arg) == 1 :
- arg = arg[0]
- # good length
- if len(arg) != 6 :
- raise ValueError("arg must be iterable of 6 elements")
- self.init_arg = list(arg)
- info("init_arg : "+ str(arg))
- info("len init_arg : "+str(len(arg)))
- # good type
- self.convert_arg = [(i if isinstance(i, int) else -1) for i in arg]
- # len
- try:
- arg = [int(i) for i in arg]
- except Exception as e:
- raise ValueError("arg must be iterable of 6 ints")
- # if a cords is not played
- self.non_cords = [i for i,j in enumerate(self.convert_arg) if j == -1]
- info("non_cords : "+ str(self.non_cords))
- self.chords = [i for i in arg if i != -1]
- info("chords : "+ str(self.chords))
- for i in self.non_cords :
- self.cords.pop(i)
- self.rcords.pop(i)
- info("cords : "+ str(self.cords))
- info("rcords : "+ str(self.rcords))
- # attribute creator
- self.ints = self.cords_to_ints(self.chords)
- info("ints : "+ str(self.ints))
- self.notes = self.ints_to_notes(self.ints)
- info("notes : "+ str(self.notes ))
- self.acc = self.ints_to_acc(self.ints)
- info("acc : "+ str(self.acc))
- self.order_notes = self.ordered_notes()
- info("order_notes : "+ str(self.order_notes))
- self.name = self.acc_to_name(self.acc)
- info("name : "+ str(self.name))
- print(self)
- def cords_to_ints(self, arg) :
- info("arg : "+ str(arg))
- info("rcords : "+ str(self.rcords))
- arg = [(i+j) for i,j in zip(self.rcords, arg)]
- arg = [i% 12 for i in arg]
- return arg
- def notes_to_ints(self, arg) :
- if isinstance(arg, Iterable) :
- # add upper
- return self.__modulo([self.rscale[i] for i in arg])
- else :
- # add uper
- return self.rscale[self.self.__modulo(arg)]
- def ints_to_notes(self, arg) :
- if isinstance(arg, Iterable) :
- return [self.scale[i] for i in self.__modulo(arg)]
- else :
- return self.scale[self.__modulo(arg)]
- def __unique(self, arg) :
- return list(set(arg))
- def __modulo(self, arg) :
- if isinstance(arg, Iterable) :
- return [i%12 for i in arg]
- else :
- return arg%12
- def ints_to_acc(self, arg) :
- # __unique
- arg = self.__unique(arg)
- arg = sorted(arg)
- # init default values
- tonic, sec, tierc, quart, quint, sixt, sept = [-1] * 7
- acc = tonic, sec, tierc, quart, quint, sixt, sept
- # handle len of arg
- if len(arg)< 3 :
- raise ValueError("Min 3 notes for accord")
- if len(arg) == 3 :
- a0, a1, a2 = arg
- _arg = [ (a0, a1, a2),
- (a1, a2, a0+12),
- (a2, a0+12, a1+12) ]
- if len(arg) == 4 :
- a0, a1, a2, a3 = arg
- _arg = [ (a0, a1, a2, a3),
- (a1, a2, a3, a0+12),
- (a2, a3, a0+12, a1+12),
- (a3, a0+12, a1+12, a2+12) ]
- if len(arg) == 5 :
- a0, a1, a2, a3, a4 = arg
- _arg = [ (a0, a1, a2, a3,a4),
- (a1, a2, a3, a4, a0+12),
- (a2, a3, a4, a0+12, a1+12),
- (a3, a4, a0+12, a1+12, a2+12),
- (a4, a0+12, a1+12, a2+12, a3+12) ]
- # # tonic and quint JUST ONLY
- for a in _arg :
- tup = [(t,q) for t in a for q in a if q-t == 7 ]
- if len(tup) == 1 :
- tonic, quint = tup[0]
- arg = a
- break
- info("acc : " + str(arg))
- # info("acc : " + str(ints_to_notes(__modulo(arg))))
- # all others
- for note in arg :
- inter = int(note - tonic)
- if inter in [1, 2] : sec = note
- if inter in [3, 4] : tierc = note
- if inter in [6] : quart = note
- if inter in [8, 9] : sixt = note
- if inter in [10, 11] : sept = note
- # regroup in acc
- acc = [tonic, sec, tierc, quart, quint, sixt, sept]
- # info("acc : " + str(acc))
- # # delete notes if needed
- # acc = [i for i in acc if i>=0]
- # acc = [i%12 for i in acc]
- return acc
- def acc_to_name(self, arg) :
- if len(arg) !=7:
- raise ValueError("call ints_to_acc() before")
- # init default values
- str_tonic, str_tierc, str_sept = [""] * 3
- # tonic
- str_tonic = self.ints_to_notes(self.__modulo(arg[0]))
- # shift idexes to have arg[3] => Tierce
- arg = [-100] + arg
- # ask for toniq == 0
- t = arg[1]
- arg = [i- t for i in arg]
- # tierc
- if arg[3] == 3 : str_tierc = "m"
- elif arg[3] == 4 : str_tierc = " "
- # sept
- if arg[7] == 10 : str_tierc = "7"
- elif arg[7] == 11 : str_tierc = "M7"
- # -----------------------------------
- # add sus 2 sus4, dim, aug, 9, 11, 13
- # -----------------------------------
- txt = str_tonic + str_tierc + str_sept
- return txt
- def ordered_notes(self) :
- if self.acc :
- acc = [i for i in self.acc if i !=-1]
- acc = self.__modulo(acc)
- acc = self.ints_to_notes(acc)
- return acc
- return None
- def __str__(self) :
- return self.__repr__()
- def __repr__(self) :
- txt =str(
- "init_arg : " + str(self.init_arg) +"\n"
- "notes : " + str(self.notes) +"\n"
- "order_notes : " + str(self.order_notes) +"\n"
- "name : " + str(self.name) +"\n" )
- return txt
- # main
- def main():
- print(str( "\n"
- "-------------------------------------------\n"
- "exemple with g = GuitarChords(0,2,2,1,0,0) \n"
- "-------------------------------------------\n\n"))
- g = GuitarChords(0,2,2,1,0,0)
- if __name__ == '__main__':
- main()
Add Comment
Please, Sign In to add comment