Skip to main content
Join the official 2019 Python Developers SurveyStart the survey!

A small package containing some musical functions such as viewing chords of a note and key information.

Project description

music-harmony

music-harmony is a small project I made in a day for personal use. Eventually I thought I might as well upload it as a package as practice for package management so here we are. It isn't too much but it gets the job done. You can see installation at the bottom of this README.md file.

Scales

These tuples hold all the musical notes in either sharp or flat form. It is in a tuple because you can not change the names of note. If beethoven isn't allowed to invent notes, neither are you. The two values for scales are sharp_scale and flat_scale.

sharp_scale = ('C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B', 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B', 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B')
flat_scale = ('C', 'Db', 'D', 'Eb', 'E', 'F', 'Gb', 'G', 'Ab', 'A', 'Bb', 'B', 'C', 'Db', 'D', 'Eb', 'E', 'F', 'Gb', 'G', 'Ab', 'A', 'Bb', 'B', 'C', 'Db', 'D', 'Eb', 'E', 'F', 'Gb', 'G', 'Ab', 'A', 'Bb', 'B')

CheckNote

checkNote() is a function that checks notes the user inputs to see if they're actually notes using the scale tuples. From there, it can be customized to show an error message, whether it should exit after an error is ran and how long it should wait should the program be exited.

checkNoteError = False  # This variable is used by checkNote().

# checkNote(): This function checks if note entered by the user (stored in a variable) is a real note or not. It can be configured on what to do if the note is false.
def checkNote(base_note, showErrorMessage=True, errorMessage="\nThe note you have entered does not exist.", exitOnError=False, timeBeforeExit=2):
    global checkNoteError
    if base_note not in sharp_scale and base_note not in flat_scale:  # Looks through the scale tuples and compares the notes to the note the user inputted.
        checkNoteError = True
    else:
        checkNoteError = False
    if checkNoteError == True:
        if showErrorMessage:
            print(errorMessage)   # This can be disabled and have its message changed.
        if exitOnError == True:
            time.sleep(timeBeforeExit)   # This can be disabled and have its time changed.
            os._exit(0)   # This can be disabled.

swapEquivilance

swapEquivilance is a short and simple function that takes one parameter, the note the user inputs. If the note is a normal note, like a C or G, nothing happens. If the note is a sharp note like G# or F#, they will be converted to their equivilant opposites: Ab or Gb. If the note is a flat note like Db or Eb, they will be converted to their equivilant opposites: C# or D#.

# swapEquivilance: This function will swap a note from its respective sign to the equivilant oposite. For example: C# -> Db.
def swapEquivilance(base_note):
    checkNote(base_note, exitOnError=False)  # Checks if the note you entered was even a real note.
    # SHARPS -> FLATS.
    if base_note == 'C#':
        base_note = 'Db'
        return(base_note)
    elif base_note == 'D#':
        base_note = 'Eb'
        return(base_note)
    elif base_note == 'F#':
        base_note = 'Gb'
        return(base_note)
    elif base_note == 'G#':
        base_note = 'Ab'
        return(base_note)
    elif base_note == 'A#':
        base_note = 'Bb'
        return(base_note)

    # FLATS -> SHARPS.
    elif base_note == 'Db':
        base_note = 'C#'
        return(base_note)
    elif base_note == 'Eb':
        base_note = 'D#'
        return(base_note)
    elif base_note == 'Gb':
        base_note = 'F#'
        return(base_note)
    elif base_note == 'Ab':
        base_note = 'G#'
        return(base_note)
    elif base_note == 'Bb':
        base_note = 'A#'
        return(base_note)

    # If the note is normal, we don't want the note to change. If the checkNote function spotted an error earlier one, we don't want to return the random note.
    else:
        if checkNoteError == False:
            return(base_note)
        else:
            # Error message from the checkNote function will be displayed one line above this message:
            return('The list of notes you can use are C, C#/Db, D#/Eb, E, F, F#/Gb, G, G#/Ab, A, A#/Bb and B.\n')

All Chord Functions

Each chord function takes two parameters, the note the user wants chords for and the scale (determines whether the chords use sharps or flats. This parameter should be equal to either sharp_scale or flat_scale).

The Chord Functions are: major() minor() augmented() diminished() sus2() sus4() major7() minor7() dominant7() halfDiminished7() diminished7() minorMajor7() augmented7() sevenSus2() sevenSus4() majorAdd9() minorAdd9() nineSus4() nineSus2() sevenFlat9() sevenSharp9() major9() minor9() minor7flat9() major69() minor69() augmented9() major11() minor11() dominant11() elevenSus4() elevenSus2() major13() minor13() dominant13() thirteenSus4() thirteenSus2()

Example (major())

def major(base_note, scale=sharp_scale):  # Takes the note given by the user (base_note) and either the sharp or flat scale tuple.
    if scale == sharp_scale:
        try:
            base_note_index = scale.index(base_note)  # Goes to the first index of that note.
        except ValueError:  # If there is a value error, due to perhaps the wrong scale being used, it'll try the equivilant opposite.
            base_note = swapEquivilance(base_note)
            base_note_index = scale.index(base_note)  # If there's another value error, the program will crash. You can prevent this by using checkNote() before these functions are called to filter bad results out.
        secondNote = scale[base_note_index + 4]  # Second Note is (+ x) semitones away from root.
        finalNote = scale[base_note_index + 7]  # Thrid Note is (+ x) semitones away from root.
        return f"{base_note} maj: {base_note} {secondNote} {finalNote}"  # Prints out the chord name and the notes in the chord.

    if scale == flat_scale:
        try:
            base_note_index = scale.index(base_note)
        except ValueError:
            base_note = swapEquivilance(base_note)
            base_note_index = scale.index(base_note)  # Does all the stuff again but this time using the flat scale.
        secondNote = scale[base_note_index + 4]
        finalNote = scale[base_note_index + 7]  # Notes will be different due to the different tuples.
        return f"{base_note} maj: {base_note} {secondNote} {finalNote}"

Key Function

The key function takes two parameters. Key is simply what note the key should be (i.e C Major = C). Tonality should either be set to major or minor.

def key(key, tonality):  # Takes in the key (A note) and a tonality (Major or Minor).
    checkNote(key)
    if checkNoteError == True:
        return('The list of notes you can use are C, C#/Db, D#/Eb, E, F, F#/Gb, G, G#/Ab, A, A#/Bb and B.\n')
    if tonality.lower() == 'major':
        if key == 'C':
            return('\nKey: C Major\nSharps: 0\nFlats: 0\nNotes: C D E F G A B\n')
        elif key == 'G':
            return('\nKey: G Major\nSharps: 1\nFlats: 0\nNotes: G A B C D E F#\n')
        elif key == 'D':
            return('\nKey: D Major\nSharps: 2\nFlats: 0\nNotes: D E F# G A B C#\n')
        elif key == 'A':
            return('\nKey: A Major\nSharps: 3\nFlats: 0\nNotes: A B C# D E F# G#\n')
        elif key == 'E':
            return('\nKey: E Major\nSharps: 4\nFlats: 0\nNotes: E F# G# A B C# D#\n')
        elif key == 'B':
            return('\nKey: B Major\nSharps: 5\nFlats: 0\nNotes: B C# D# E F# G# A#\n')
        elif key == 'Gb':
            return('\nKey: Gb Major\nSharps: 0\nFlats: 6\nNotes: Gb Ab Bb Cb Db Eb F\n')
        elif key == 'F#':
            return('\nKey: F# Major\nSharps: 6\nFlats: 0\nNotes: F# G# A# B C# D# E#\n')
        elif key == 'Db':
            return('\nKey: Db Major\nSharps: 0\nFlats: 5\nNotes: Db Eb F Gb Ab Bb C\n')
        elif key == 'C#':
            return('\nKey: C# Major\nSharps: 7\nFlats: 0\nNotes: C# D# E# F# G# A# B#\n')
        elif key == 'Ab':
            return('\nKey: Ab Major\nSharps: 0\nFlats: 4\nNotes: Ab Bb C Db Eb F G\n')
        elif key == 'Eb':
            return('\nKey: Eb Major\nSharps: 0\nFlats: 3\nNotes: Eb F G Ab Bb C D\n')
        elif key == 'Bb':
            return('\nKey: Bb Major\nSharps: 0\nFlats: 2\nNotes: Bb C D Eb F G A\n')
        elif key == 'F':
            return('\nKey: F Major\nSharps: 0\nFlats: 1\nNotes: F G A Bb C D E\n')
        else:
            return(f'\n{key} {tonality.lower()} is not a valid key.\n')
    elif tonality.lower() == 'minor':
        if key == 'A':
            return('\nKey: A Minor\nSharps: 0\nFlats: 0\nNotes: A B C D E F G\n')
        elif key == 'E':
            return('\nKey: E Minor\nSharps: 1\nFlats: 0\nNotes: E F# G A B C D\n')
        elif key == 'B':
            return('\nKey: B Minor\nSharps: 2\nFlats: 0\nNotes: B C# D E F# G A\n')
        elif key == 'F#':
            return('\nKey: F# Minor\nSharps: 3\nFlats: 0\nNotes: F# G# A B C# D E\n')
        elif key == 'C#':
            return('\nKey: C# Minor\nSharps: 4\nFlats: 0\nNotes: C# D# E F# G# A B\n')
        elif key == 'G#':
            return('\nKey: G# Minor\nSharps: 5\nFlats: 0\nNotes: G# A B# C# D# E F#\n')
        elif key == 'Eb':
            return('\nKey: Eb Minor\nSharps: 0\nFlats: 6\nNotes: Eb F Gb Ab Bb Cb Db\n')
        elif key == 'D#':
            return('\nKey: D# Minor\nSharps: 6\nFlats: 0\nNotes: D# E# F# G# A# B C#\n')
        elif key == 'Bb':
            return('\nKey: Bb Minor\nSharps: 0\nFlats: 5\nNotes: Bb C Db Eb F Gb Ab\n')
        elif key == 'A#':
            return('\nKey: A# Minor\nSharps: 7\nFlats: 0\nNotes: A# B# C# D# E# F# G#\n')
        elif key == 'F':
            return('\nKey: F Minor\nSharps: 0\nFlats: 4\nNotes: F G Ab Bb C Db Eb\n')
        elif key == 'C':
            return('\nKey: C Minor\nSharps: 0\nFlats: 3\nNotes: C D Eb F G Ab Bb\n')
        elif key == 'G':
            return('\nKey: G Minor\nSharps: 0\nFlats: 2\nNotes: G A Bb C D Eb F\n')
        elif key == 'D':
            return('\nKey: D Minor\nSharps: 0\nFlats: 1\nNotes: D E F G A Bb C\n')
        else:
            return(f'\n{key} {tonality.lower()} is not a valid key.\n')
    else:
        return(f'\n"{tonality}" is not a tonality recognised by music-harmonics. Please use either major or minor.\n')

Installation

Do pip install music-harmony to install the module. Do from music_harmony.music_harmony import * to use the functions within the module.

GitHub

Click here to go to the GitHub page for music-harmony.

Thanks for reading. If you like this, give it a star.

Project details


Release history Release notifications

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for music-harmony, version 1.0.8
Filename, size File type Python version Upload date Hashes
Filename, size music_harmony-1.0.8-py3-none-any.whl (8.9 kB) File type Wheel Python version py3 Upload date Hashes View hashes
Filename, size music-harmony-1.0.8.tar.gz (9.6 kB) File type Source Python version None Upload date Hashes View hashes

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN SignalFx SignalFx Supporter DigiCert DigiCert EV certificate StatusPage StatusPage Status page