Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented jazz minor scale and relative key functionality on harmonic, melodic, and jazz minors #1044

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

Phantasmogenesis
Copy link

@Phantasmogenesis Phantasmogenesis commented Jun 25, 2021

Closes #955 and also allows getRelativeMinor/getRelativeMajor functions to be used on minor scales other than natural minor, as per the documentation.

@coveralls
Copy link

coveralls commented Jun 25, 2021

Coverage Status

Coverage decreased (-0.004%) to 92.295% when pulling 48c3695 on Phantasmogenesis:master into a4594ae on cuthbertLab:master.

Copy link
Member

@jacobtylerwalls jacobtylerwalls left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, Jazz minor will be a nice addition as I see it. Some questions about the rest. Cheers, Jacob

music21/scale/__init__.py Show resolved Hide resolved
music21/scale/__init__.py Outdated Show resolved Hide resolved
music21/scale/__init__.py Outdated Show resolved Hide resolved
Comment on lines 858 to 859
self.relativeMinorDegree = 1
self.relativeMajorDegree = 3
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise, can you explain why this is needed?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without this code, an error message like this is given when using the getRelativeMinor/getRelativeMajor functions on the harmonic/melodic/jazz minor scales:

AttributeError: 'AbstractHarmonicMinorScale' object has no attribute 'relativeMinorDegree'

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, got it, any of the non-natural minors, thanks. Yes, this should work because it's a method on DiatonicScale.

Can we move these attribute assignments to buildNetwork()? That's where they seem to be in all other cases.

@jacobtylerwalls jacobtylerwalls changed the title Implemented jazz minor scale and expanded relative key functionality Implemented jazz minor scale and implemented relative key functionality on harmonic, melodic, and jazz minors Jun 25, 2021
Added description to jazz minor scale, rearranged so harmonic minor and melodic minor would be directly adjacent, and removed certain unnecessary comments.
@jacobtylerwalls jacobtylerwalls changed the title Implemented jazz minor scale and implemented relative key functionality on harmonic, melodic, and jazz minors Implemented jazz minor scale and relative key functionality on harmonic, melodic, and jazz minors Jun 25, 2021
Copy link
Member

@mscuthbert mscuthbert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making great progress. Happy to add this to music21!

music21/scale/__init__.py Outdated Show resolved Hide resolved
music21/scale/__init__.py Outdated Show resolved Hide resolved
music21/scale/__init__.py Outdated Show resolved Hide resolved
Western European classical music, but it is common in other parts of the
world, but where the term "HarmonicMinor" would not be appropriate).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for the space, but the "but" should remain

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, because "where" is not delimiting certain parts of the world where the term is/is not meaningful.

music21/scale/__init__.py Show resolved Hide resolved
<music21.pitch.Pitch B4>
>>> sc.pitchFromDegree(1) # scale degree 1 is treated as lowest
<music21.pitch.Pitch E4>
>>> sc = scale.JazzMinorScale()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space above and explain what's happening here.

<music21.pitch.Pitch E4>
>>> sc.getDominant()
<music21.pitch.Pitch B4>
>>> sc.pitchFromDegree(1) # scale degree 1 is treated as lowest
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

usually no need for comments in doc tests, write it as documentation just above.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<music21.pitch.Pitch B4>
>>> sc.pitchFromDegree(1) # scale degree 1 is treated as lowest
<music21.pitch.Pitch E4>
>>> sc = scale.JazzMinorScale()

explain what's happening here.
usually no need for comments in doc tests, write it as documentation just above.

To clarify, these comments are largely borrowed from other diatonic scales (mainly the harmonic minor) that I had used as a template. Should I rework the comments on these other scales as well?

Comment on lines -845 to -847
class AbstractHarmonicMinorScale(AbstractScale):
'''
A true bi-directional scale that with the augmented
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're losing two documented classes without a deprecation process. Why are these being removed?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thought was that it would be better to be able to create non-natural minor keys in one line, especially considering the fact that in the existing documentation, abstract scales are described as "rarely created or manipulated directly by most users." For example, with the changes in this most recent commit, in order to create a harmonic minor key, users would type:
minorKey = key.Key(mode='harmonic minor')
vs. what was previously required and seems unnecessary:
minorKey = key.Key(mode='minor')
minorKey.abstract = AbstractHarmonicMinor()
Additionally, as far as I can tell, no functionality that a user would manipulate is lost by moving the abstract harmonic/melodic/jazz minor scale classes entirely into the AbstractDiatonicScale class. However, this is my first PR ever; would it be better to leave those abstract classes?

Copy link
Member

@jacobtylerwalls jacobtylerwalls Jun 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Smaller PRs are usually better for this very reason. This started as a small feature and bugfix and then added a proposal for a refactor. But that's three motivations, and the bugfix and feature probably could have been merged already were they isolated.

We would ordinarily wait a whole version to deprecate documented classes, with notice on the list and issuing warnings in the code for people still using the old pattern. For such an unclear benefit I'm -1. You can certainly wait to hear from Michael before changing the PR, though.

Thanks for the PR and welcome aboard 👍🏻

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hiya @Phantasmogenesis, absolutely no rush here or anything, and I hope I haven't sounded short, I am genuinely pleased to see more folks lend a hand to m21. It's what I was hoping for when I marked this as a good first issue!

So please do say if you're waiting on anyone to offer guidance or direct any part of the implementation. All the best, and thanks again, it will be great to get JazzMinor and the bugfix you identified into the system. 🥇

>>> minorKey.abstract = scale.AbstractHarmonicMinorScale()
>>> minorKey.abstract = key.Key(mode='harmonic minor').abstract
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This strikes me as a strange way of deriving a scale, i.e., creating a Key object, throwing it away, and then getting the .abstract. Either way we're exposing the user to the concept of abstract scales, so I'm not sure this is an improvement.

@mscuthbert
Copy link
Member

Hello -- just as a note (from the music21list Google Group) I'm taking a sabbatical from reviewing music21 issues and PRs until at least Jan 1, 2024, so this PR will be deferred until then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Create JazzMinor scale
4 participants