Home > Enterprise >  In python3, will objects inside a class ONLY be available within that class unless other specified?
In python3, will objects inside a class ONLY be available within that class unless other specified?

Time:11-06

I am building a library of all the guitar scales. There are 10 scales, "Major", "Minor", "Major Pentatonic" ... with each scale including 12 different scales, but they are labeled the same letter. For instance; 10 scales

("Major | Minor | Major Pentatonic | Minor Pentatonic | Minor Harmonic | Melodic Minor | Blues | Mixolydian | Dorian | Lydian")

And each scale includes

("C | C#/D♭ | D | D#/E♭ | E | F | F#/G♭ | G | G#/A♭ | A | A#/B♭ | B")

So the issue is that after i build my first method for say, the "Major" scale

def major():
print("\nChoose A Major Scale")
print("C | C#/D♭ | D | D#/E♭ | E | F | F#/G♭ | G | G#/A♭ | A | A#/B♭ | B")

answer = input(">")

if answer == "C":
    c()
elif answer == "C#/D":
    c_sharp_d()
elif answer == "D":
    d()
elif answer == "D#/E":
    d_sharp_e()
elif answer == "E":
    e()
elif answer == "F":
    f()
elif answer == "F#/G":
    f_sharp_g()
elif answer == "G":
    g()
elif answer == "G#/A":
    g_sharp_a
elif answer == "A":
    a()
elif answer == "A#/B":
    a_sharp_b()
elif answer == "B":
    b()
else:
    print("Thats not an option...")

It works perfectly fine, but when I build a second method for say, the "Minor" scale when a user chooses any of the 12 scales, in the minor category it will return a scale thats build within the "Major" category. Now I know why, obviously because they are defined already in "Major" scales but what my question is, how can I get around this so that i dont have to change the name of the 12 scales in my if, elif, else, statments for each 10 different scales ? Of course, I could just add a letter or digit for each different scale say,

if answer == "C":  -- for major
    c()

if answer == "C":  -- for minor
    c1()

so on and so forth, but that doesn't seem very programmatic and there must be a cleaner way to go about it. I was thinking of grouping each individual 10 scales, and their 12 specific scales in their own classes ? Thats where my question lies, if I do that, then will the data only be available within that specific class ? Unless I call that data from the class specifically. For instance, I will still need some methods to be accessible across all classes, like my "main menu" class and such. SO unless its easier to create classes i may just define the different scales like the example above, changing them slightly with just a digit or letter.

note: i come from ruby, and i dont exactly remember classes but im pretty sure that you could encapsulate info that was only usable in that class unless specified.

CodePudding user response:

First of all, a tip from me would be to change the whole if-else huge block with something more elegant and more OCP-y such as a dictionary:

notes = {'C': c, 'D': d, 'C#/D': c_sharp_d, ...}

And call the function by the input given from the user:

notes.get(answer, lambda: 'Thats not an option...')()

(Or now in py3.10 you can use structural pattern matching)

If you want the same function to do different things as the scale changes you could use the singledispatch decorator from the functools modules:

from functools import singledispatch

@singledispatch
def f_sharp_g():
    ...
@f_sharp_g.register(Major_Pentatonic)
def _():
    """ Do F#/G Major Pentatonic """

CodePudding user response:

you have indentation error in 2nd line. Just after you define major. It should be like

def major():
    print("\nChoose A Major Scale")
    print("C | C#/D♭ | D | D#/E♭ | E | F | F#/G♭ | G | G#/A♭ | A | A#/B♭ | B")
  • Related