From ad7d64c75c61f0763148c9985d2da95a89fa6135 Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 13:31:15 -1000 Subject: [PATCH 01/28] Standardize music21_tools to single quotes per music21 house style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds [tool.ruff] config mirroring music21's flake8-quotes settings (inline/multiline/docstring all single) and applies ruff --fix across music21_tools/ and tools/ — 752 quote fixes in 17 files. Co-Authored-By: Claude Opus 4.7 (1M context) --- music21_tools/__init__.py | 4 +- .../graphicalInterfaceGame.py | 16 +- .../audioSearchDemos/graphicalInterfaceSF.py | 114 ++++---- .../audioSearchDemos/humanVScomputer.py | 28 +- music21_tools/audioSearchDemos/omrfollow.py | 16 +- .../audioSearchDemos/repetitionGame.py | 32 +-- music21_tools/bhadley/harmonyRealizer.py | 2 +- music21_tools/bhadley/nips2011.py | 20 +- music21_tools/chant/chant.py | 79 +++--- music21_tools/choraleTools/mnum_fixer.py | 14 +- music21_tools/composition/__init__.py | 4 +- music21_tools/composition/arvo.py | 6 +- music21_tools/composition/aug30.py | 6 +- music21_tools/composition/phasing.py | 6 +- music21_tools/composition/seeger.py | 8 +- music21_tools/contour/contour.py | 24 +- music21_tools/counterpoint/__init__.py | 2 +- music21_tools/counterpoint/species.py | 118 ++++---- music21_tools/featureExtraction/ismir2011.py | 6 +- music21_tools/josquin/label_intervals.py | 14 +- music21_tools/midi/build_melody.py | 8 +- music21_tools/misc/eschbeg.py | 26 +- music21_tools/misc/gatherAccidentals.py | 14 +- music21_tools/misc/monteverdi.py | 62 ++-- music21_tools/theory/mgtaPart1.py | 16 +- music21_tools/theory/mgtaPart2.py | 2 +- music21_tools/theoryAnalysis/__init__.py | 2 +- .../theoryAnalysis/theoryAnalyzer.py | 266 +++++++++--------- music21_tools/theoryAnalysis/theoryResult.py | 8 +- music21_tools/theoryAnalysis/wwnortonMGTA.py | 44 +-- .../trecento/cadenceProbabilities.py | 18 +- music21_tools/trecento/cadencebook.py | 80 +++--- music21_tools/trecento/findSevs.py | 2 +- .../trecento/findTrecentoFragments.py | 28 +- music21_tools/trecento/find_vatican1790.py | 4 +- music21_tools/trecento/largestAmbitus.py | 4 +- music21_tools/trecento/medren.py | 24 +- music21_tools/trecento/notation.py | 38 +-- music21_tools/trecento/polyphonicSnippet.py | 32 +-- music21_tools/trecento/quodJactatur.py | 22 +- music21_tools/trecento/runTrecentoCadence.py | 12 +- music21_tools/trecento/tonality.py | 50 ++-- music21_tools/trecento/trecentoCadence.py | 4 +- pyproject.toml | 26 +- tools/exceldiff.py | 26 +- 45 files changed, 678 insertions(+), 659 deletions(-) diff --git a/music21_tools/__init__.py b/music21_tools/__init__.py index 766ebd2..7da1ed6 100644 --- a/music21_tools/__init__.py +++ b/music21_tools/__init__.py @@ -1,5 +1,5 @@ -""" +''' music21_tools — demonstration scripts and tools for music21. See README for an overview of subpackages. -""" +''' diff --git a/music21_tools/audioSearchDemos/graphicalInterfaceGame.py b/music21_tools/audioSearchDemos/graphicalInterfaceGame.py index 4fcf832..70a0a07 100644 --- a/music21_tools/audioSearchDemos/graphicalInterfaceGame.py +++ b/music21_tools/audioSearchDemos/graphicalInterfaceGame.py @@ -22,7 +22,7 @@ def __init__(self, master): self.master = master self.frame = tkinter.Frame(master) #self.frame.pack() - self.master.wm_title("Repetition game") + self.master.wm_title('Repetition game') self.sizeButton = 11 self.startScreen() @@ -32,13 +32,13 @@ def startScreen(self): master = self.master self.textRules = tkinter.StringVar() self.boxRules = tkinter.Label(master, textvariable=self.textRules) - self.textRules.set("Welcome to the music21 game!\n Rules:\n " + - "Two players: the first one plays a note.\n " + - "The second one has to play the first note and a new one.\n " + - "Continue doing the same until one fails.") + self.textRules.set('Welcome to the music21 game!\n Rules:\n ' + + 'Two players: the first one plays a note.\n ' + + 'The second one has to play the first note and a new one.\n ' + + 'Continue doing the same until one fails.') self.boxRules.grid(row=0, column=0, columnspan=4, rowspan=5, sticky=tkinter.W) - self.buttonAccept = tkinter.Button(master, text="Accept", width=self.sizeButton, + self.buttonAccept = tkinter.Button(master, text='Accept', width=self.sizeButton, command=self.callback, bg='white') self.buttonAccept.grid(row=8, column=1, columnspan=2) @@ -89,7 +89,7 @@ def callback(self): self.canvas2.create_oval(1, 1, 40, 40, fill='red') self.canvas2.grid(row=1, column=2) - self.buttonStart = tkinter.Button(master, text="Start Recording", width=self.sizeButton, + self.buttonStart = tkinter.Button(master, text='Start Recording', width=self.sizeButton, command=self.startGame, bg='green') self.buttonStart.grid(row=3, column=0, columnspan=3) @@ -153,7 +153,7 @@ def mainLoop(self): self.textFinal.set('Another game?') self.boxName6.grid(row=4, column=0, columnspan=3) -if __name__ == "__main__": +if __name__ == '__main__': root = tkinter.Tk() sfapp = SFApp(root) root.mainloop() diff --git a/music21_tools/audioSearchDemos/graphicalInterfaceSF.py b/music21_tools/audioSearchDemos/graphicalInterfaceSF.py index fe9223c..0949f31 100644 --- a/music21_tools/audioSearchDemos/graphicalInterfaceSF.py +++ b/music21_tools/audioSearchDemos/graphicalInterfaceSF.py @@ -55,10 +55,10 @@ class SFApp(): def __init__(self, master): self.debug = True if 'PIL' in _missingImport: - raise exceptions21.Music21Exception("Need PIL installed to run Score Follower") + raise exceptions21.Music21Exception('Need PIL installed to run Score Follower') self.master = master self.frame = tkinter.Frame(master) - self.master.wm_title("Score follower - music21") + self.master.wm_title('Score follower - music21') self.scoreNameSong = 'scores/d luca gloria_Page_' #'/Users/cuthbert/Desktop/scores/Saint-Saens-Clarinet-Sonata/Saint-Saens-Clarinet-Sonata_Page_' @@ -87,13 +87,13 @@ def __init__(self, master): unused_user32 = ctypes.windll.user32 # test for error... self.screenResolution = [1024, 600] #self.screenResolution = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1) - environLocal.printDebug("screen resolution (windows) %d x %d" % (self.screenResolution[0], self.screenResolution[1])) + environLocal.printDebug('screen resolution (windows) %d x %d' % (self.screenResolution[0], self.screenResolution[1])) self.resolution = True except: # mac and linux try: for screen in AppKit.NSScreen.screens(): # @UndefinedVariable self.screenResolution = [int(screen.frame().size.width), int(screen.frame().size.height)] - environLocal.printDebug("screen resolution (MAC or linux) %d x %d" % (self.screenResolution[0], self.screenResolution[1])) + environLocal.printDebug('screen resolution (MAC or linux) %d x %d' % (self.screenResolution[0], self.screenResolution[1])) self.resolution = True except: self.screenResolution = [1024, 600] @@ -105,8 +105,8 @@ def __init__(self, master): if self.x > self.screenResolution[0] / 2.6: # 2.6 is a factor to scale canvas self.x = int(self.screenResolution[0] / 2.6) self.y = int(self.x * 1.29) - environLocal.printDebug("resized! too big") - environLocal.printDebug("one page score size %d x %d" % (self.x, self.y)) + environLocal.printDebug('resized! too big') + environLocal.printDebug('one page score size %d x %d' % (self.x, self.y)) self.filenameRequest() @@ -117,7 +117,7 @@ def filenameRequest(self): self.textVarName.set(self.scoreNameSong) self.box.grid(row=0, column=3, columnspan=2) - self.buttonSubmit = tkinter.Button(master, text="Submit score name", + self.buttonSubmit = tkinter.Button(master, text='Submit score name', width=2 * self.sizeButton, command=self.startMainCanvas) self.buttonSubmit.grid(row=1, column=3, columnspan=2, padx=0) @@ -153,12 +153,12 @@ def initializeName(self): self.format) self.listNamePages.append(namePage) pilPage = PILImage.open(namePage) # @UndefinedVariable - if pilPage.mode != "RGB": - pilPage = pilPage.convert("RGB") + if pilPage.mode != 'RGB': + pilPage = pilPage.convert('RGB') pilPage = self.cropBorder(pilPage) self.pagesScore.append(pilPage.resize(self.newSize, PILImage.ANTIALIAS)) # @UndefinedVariable self.phimage.append(PILImageTk.PhotoImage(self.pagesScore[i])) # @UndefinedVariable - environLocal.printDebug("initializeName finished") + environLocal.printDebug('initializeName finished') def cropBorder(self, img, minColor=240, maxColor=256): @@ -298,9 +298,9 @@ def initializeScore(self): self.middlePages.append(noteCounter) middlePagesCounter += 1 noteCounter += 1 - environLocal.printDebug("beginning of the pages %s" % str(self.beginningPages)) - environLocal.printDebug("middles of the pages %s" % str(self.middlePages)) - environLocal.printDebug("initializeScore finished") + environLocal.printDebug('beginning of the pages %s' % str(self.beginningPages)) + environLocal.printDebug('middles of the pages %s' % str(self.middlePages)) + environLocal.printDebug('initializeScore finished') def initializeGraphicInterface(self): @@ -317,7 +317,7 @@ def initializeGraphicInterface(self): self.sizeCanvasy = self.y self.canvas1 = tkinter.Canvas(master, borderwidth=1, width=self.sizeCanvasx, - height=self.sizeCanvasy, bg="black") + height=self.sizeCanvasy, bg='black') self.canvas1.create_image(self.positionxLeft, self.positionyLeft, image=self.phimage[0], tag='leftImage') @@ -345,35 +345,35 @@ def initializeGraphicInterface(self): if self.firstTime == True: self.button2 = tkinter.Button(master, - text="START SF", + text='START SF', width=self.sizeButton, command=self.startScoreFollower, bg='green') self.button2.grid(row=5, column=3) self.button3 = tkinter.Button(master, - text="1st page", + text='1st page', width=self.sizeButton, command=self.goTo1stPage) self.button3.grid(row=4, column=3) - self.button3 = tkinter.Button(master, text="Last page", + self.button3 = tkinter.Button(master, text='Last page', width=self.sizeButton, command=self.goToLastPage) self.button3.grid(row=4, column=4) - self.button4 = tkinter.Button(master, text="Forward", + self.button4 = tkinter.Button(master, text='Forward', width=self.sizeButton, command=self.pageForward) self.button4.grid(row=3, column=4) - self.button7 = tkinter.Button(master, text="Backward", + self.button7 = tkinter.Button(master, text='Backward', width=self.sizeButton, command=self.pageBackward) self.button7.grid(row=3, column=3) - self.button5 = tkinter.Button(master, text="MOVE", + self.button5 = tkinter.Button(master, text='MOVE', width=self.sizeButton, command=self.moving, bg='beige') self.button5.grid(row=2, column=3) - self.button6 = tkinter.Button(master, text="STOP SF", + self.button6 = tkinter.Button(master, text='STOP SF', width=self.sizeButton, command=self.stopScoreFollower, bg='red') self.button6.grid(row=5, column=4) @@ -384,10 +384,10 @@ def initializeGraphicInterface(self): self.label2.grid(row=7, column=3, sticky=tkinter.E) self.firstTime = False - environLocal.printDebug("initializeGraphicInterface finished") + environLocal.printDebug('initializeGraphicInterface finished') def moving(self): - environLocal.printDebug("moving starting") + environLocal.printDebug('moving starting') if self.currentLeftPage + 1 < self.totalPagesScore: self.ntimes = 0 self.newcoords = self.positionxRight, self.positionyLeft @@ -401,26 +401,26 @@ def moving(self): + self.pageMeasureNumbers[self.currentLeftPage]) / 2.0: self.speed = self.speed = int(3.0 * (self.screenResolution[0] / 1024.0)) environLocal.printDebug( - "moving when last measure was at the first 50% of the right page") + 'moving when last measure was at the first 50% of the right page') elif self.ScF.scoreStream[self.ScF.lastNotePosition].measureNumber < 3 * ( self.pageMeasureNumbers[self.currentLeftPage + 1] + self.pageMeasureNumbers[self.currentLeftPage]) / 4.0: self.speed = self.speed = int(4.0 * (self.screenResolution[0] / 1024.0)) environLocal.printDebug( - "moving when last measure was between the first 50% " + - "and the 75% of the right page") + 'moving when last measure was between the first 50% ' + + 'and the 75% of the right page') else: self.speed = self.speed = int(5.0 * (self.screenResolution[0] / 1024.0)) - environLocal.printDebug("moving when last measure was after " + - "the 75% of the right page") + environLocal.printDebug('moving when last measure was after ' + + 'the 75% of the right page') else: - environLocal.printDebug("moving at default speed") + environLocal.printDebug('moving at default speed') self.speed = 3.0 * (self.screenResolution[0] / 1024.0) self.master.after(500, self.movingRoutine) def movingRoutine(self): - environLocal.printDebug("starting movingRoutine") + environLocal.printDebug('starting movingRoutine') if self.newcoords[0] > self.positionxLeft: self.newcoords = self.positionxRight - self.speed * self.ntimes, self.positionyRight self.canvas1.coords('rightImage', self.newcoords) @@ -431,7 +431,7 @@ def movingRoutine(self): self.master.after(self.refreshTime, self.movingRoutine) else: - environLocal.printDebug("finished main moving routine") + environLocal.printDebug('finished main moving routine') if self.currentLeftPage + 2 <= self.totalPagesScore: self.canvas1.delete('3rdImage') self.pageForward() @@ -460,7 +460,7 @@ def pageForward(self): self.canvas1.grid(row=1, column=0, columnspan=3, rowspan=7) self.currentLeftPage += 1 - environLocal.printDebug("page Forward %d, %d" % (self.currentLeftPage, + environLocal.printDebug('page Forward %d, %d' % (self.currentLeftPage, self.totalPagesScore)) def pageBackward(self): @@ -478,7 +478,7 @@ def pageBackward(self): self.canvas1.grid(row=1, column=0, columnspan=3, rowspan=7) self.currentLeftPage -= 1 - environLocal.printDebug("page Backward %d %d" % (self.currentLeftPage, self.totalPagesScore)) + environLocal.printDebug('page Backward %d %d' % (self.currentLeftPage, self.totalPagesScore)) def goTo1stPage(self): self.currentLeftPage = 1 @@ -511,8 +511,8 @@ def goToLastPage(self): def startScoreFollower(self): - environLocal.printDebug("startScoreFollower starting") - self.button2 = tkinter.Button(self.master, text="START SF", width=self.sizeButton, + environLocal.printDebug('startScoreFollower starting') + self.button2 = tkinter.Button(self.master, text='START SF', width=self.sizeButton, command=self.startScoreFollower, state='disable', bg='green') self.button2.grid(row=5, column=3) scNotes = self.scorePart.flatten().notesAndRests @@ -544,11 +544,11 @@ def startScoreFollower(self): def continueScoreFollower(self): - environLocal.printDebug("continueScoreFollower starting") + environLocal.printDebug('continueScoreFollower starting') self.ScF = self.scoreFollower self.timeStart = time.time() if self.stop == False and (self.firstTimeSF == True or self.rt.resultInThread == False): - environLocal.printDebug("firstTimeSF == True or resultInThread") + environLocal.printDebug('firstTimeSF == True or resultInThread') self.lastNoteString = 'Note: %d, Measure: %d, Countdown:%d, Page:%d' % ( self.ScF.lastNotePosition, @@ -556,7 +556,7 @@ def continueScoreFollower(self): self.ScF.countdown, self.currentLeftPage) if self.firstTimeSF == False: - self.textVarComments.set("1st meas: %d, last meas: %d" % ( + self.textVarComments.set('1st meas: %d, last meas: %d' % ( self.ScF.scoreStream[self.ScF.firstNotePage].measureNumber, self.ScF.scoreStream[self.ScF.lastNotePage].measureNumber)) self.firstTimeSF = False @@ -564,29 +564,29 @@ def continueScoreFollower(self): self.ScF.firstNotePage = self.beginningPages[self.currentLeftPage - 1] - 1 if self.currentLeftPage + 1 < self.totalPagesScore: self.ScF.lastNotePage = self.middlePages[self.currentLeftPage + 1] - 1 - environLocal.printDebug("3 or more pages remaining %d %d" % (self.firstTimeSF, + environLocal.printDebug('3 or more pages remaining %d %d' % (self.firstTimeSF, self.ScF.lastNotePage)) elif self.currentLeftPage < self.totalPagesScore: self.ScF.lastNotePage = self.beginningPages[self.currentLeftPage + 1] - 1 - environLocal.printDebug("2 pages on the screen %d %d" % (self.firstTimeSF, + environLocal.printDebug('2 pages on the screen %d %d' % (self.firstTimeSF, self.ScF.lastNotePage)) else: self.ScF.lastNotePage = self.beginningPages[self.currentLeftPage] - 1 - environLocal.printDebug("only one page on the screen %d %d" % (self.firstTimeSF, + environLocal.printDebug('only one page on the screen %d %d' % (self.firstTimeSF, self.ScF.lastNotePage)) self.rt = RecordThread(self.dummyQueue, self.sampleQueue, self.ScF) self.rt.daemon = True - environLocal.printDebug("2nd thread about to start") + environLocal.printDebug('2nd thread about to start') self.rt.start() # the 2nd thread starts here - self.dummyQueue.put("Start") - environLocal.printDebug("about to put analyzeRecording into master...") + self.dummyQueue.put('Start') + environLocal.printDebug('about to put analyzeRecording into master...') self.master.after(7000, self.analyzeRecording) else: - environLocal.printDebug("stopped...") + environLocal.printDebug('stopped...') self.button2.destroy() - self.button2 = tkinter.Button(self.master, text="START SF", width=self.sizeButton, + self.button2 = tkinter.Button(self.master, text='START SF', width=self.sizeButton, command=self.startScoreFollower, bg='green') self.button2.grid(row=5, column=3) self.textVarComments.set('END!! %s' % (self.rt.resultInThread)) @@ -596,7 +596,7 @@ def analyzeRecording(self): self.rt.outQueue.get() self.textVar3.set(self.lastNoteString) self.ScF.firstSlot = self.beginningPages[self.currentLeftPage - 1] - environLocal.printDebug("**** %d %d %d %d" % (self.ScF.lastNotePosition, + environLocal.printDebug('**** %d %d %d %d' % (self.ScF.lastNotePosition, self.beginningPages[self.currentLeftPage - 1], self.currentLeftPage, (self.ScF.lastNotePosition < @@ -636,14 +636,14 @@ def analyzeRecording(self): environLocal.printDebug('moving right page to left') self.moving() #self.isMoving = False - environLocal.printDebug("playing a note of the second half part of the right page") + environLocal.printDebug('playing a note of the second half part of the right page') elif (self.ScF.lastNotePosition >= self.beginningPages[self.currentLeftPage] and self.ScF.lastNotePosition < (self.middlePages[self.currentLeftPage] + self.beginningPages[self.currentLeftPage])): self.hits += 1 - environLocal.printDebug("playing a note of the first half part of the right " + - "page: hits=%d" % self.hits) + environLocal.printDebug('playing a note of the first half part of the right ' + + 'page: hits=%d' % self.hits) if self.hits == 2: self.hits = 0 if self.isMoving == False: @@ -653,7 +653,7 @@ def analyzeRecording(self): #self.isMoving = False else: self.hits = 0 - environLocal.printDebug("playing a note of the left page") + environLocal.printDebug('playing a note of the left page') print('------------------last note position', self.ScF.lastNotePosition) @@ -661,7 +661,7 @@ def analyzeRecording(self): def stopScoreFollower(self): self.stop = True - environLocal.printDebug("Stop button pressed!") + environLocal.printDebug('Stop button pressed!') @@ -720,18 +720,18 @@ def __init__(self, inQueue, outQueue, recordingObject): def run(self): unused_startCommand = self.inQueue.get() - environLocal.printDebug("start command received: recording!") + environLocal.printDebug('start command received: recording!') self.resultInThread = self.object.repeatTranscription() - environLocal.printDebug("repeatTranscription has been run") + environLocal.printDebug('repeatTranscription has been run') self.outQueue.put(1) - environLocal.printDebug("put into outQueue") + environLocal.printDebug('put into outQueue') self.outQueue.task_done() - environLocal.printDebug("task is done") + environLocal.printDebug('task is done') -if __name__ == "__main__": +if __name__ == '__main__': root = tkinter.Tk() sfapp = SFApp(root) root.mainloop() diff --git a/music21_tools/audioSearchDemos/humanVScomputer.py b/music21_tools/audioSearchDemos/humanVScomputer.py index d77f072..be3333d 100644 --- a/music21_tools/audioSearchDemos/humanVScomputer.py +++ b/music21_tools/audioSearchDemos/humanVScomputer.py @@ -24,22 +24,22 @@ def runGame(): good = True gameNotes = [] - print("Welcome to the music21 game!") - print("Rules:") - print("The computer generates a note (and it will play them in the future).") - print("The player has to play all the notes from the beginning.") + print('Welcome to the music21 game!') + print('Rules:') + print('The computer generates a note (and it will play them in the future).') + print('The player has to play all the notes from the beginning.') time.sleep(2) - print("3, 2, 1 GO!") - nameNotes = ["A", "B", "C", "D", "E", "F", "G"] + print('3, 2, 1 GO!') + nameNotes = ['A', 'B', 'C', 'D', 'E', 'F', 'G'] while(good == True): randomNumber = random.randint(0, 6) octaveNumber = 4 # I can put a random number here... - fullNameNote = "%s%d" % (nameNotes[randomNumber], octaveNumber) + fullNameNote = '%s%d' % (nameNotes[randomNumber], octaveNumber) gameNotes.append(note.Note(fullNameNote)) roundNumber = roundNumber + 1 - print("ROUND %d" % roundNumber) - print("NOTES UNTIL NOW: (this will not be shown in the final version)") + print('ROUND %d' % roundNumber) + print('NOTES UNTIL NOW: (this will not be shown in the final version)') for k in range(len(gameNotes)): print(gameNotes[k].fullName) @@ -52,23 +52,23 @@ def runGame(): j = 0 i = 0 while i < len(notesList) and j < len(gameNotes) and good == True: - if notesList[i].name == "rest": + if notesList[i].name == 'rest': i = i + 1 elif notesList[i].name == gameNotes[j].name: i = i + 1 j = j + 1 else: - print("WRONG NOTE! You played", notesList[i].fullName, "and should have been", gameNotes[j].fullName) + print('WRONG NOTE! You played', notesList[i].fullName, 'and should have been', gameNotes[j].fullName) good = False if good == True and j != len(gameNotes): good = False - print("YOU ARE VERY SLOW!!! PLAY FASTER NEXT TIME!") + print('YOU ARE VERY SLOW!!! PLAY FASTER NEXT TIME!') if good == False: - print("GAME OVER! TOTAL ROUNDS: %d" % roundNumber) + print('GAME OVER! TOTAL ROUNDS: %d' % roundNumber) -if __name__ == "__main__": +if __name__ == '__main__': runGame() diff --git a/music21_tools/audioSearchDemos/omrfollow.py b/music21_tools/audioSearchDemos/omrfollow.py index 0bc5113..8c0e053 100644 --- a/music21_tools/audioSearchDemos/omrfollow.py +++ b/music21_tools/audioSearchDemos/omrfollow.py @@ -16,7 +16,7 @@ from music21 import stream from music21 import environment -_MOD = "audioSearch.omrfollow" +_MOD = 'audioSearch.omrfollow' environLocal = environment.Environment(_MOD) # given an iterable of pairs return the key corresponding to the greatest value @@ -74,7 +74,7 @@ def recognizeScore(scorePart, pageMeasureNumbers, iterations=1): for i in range(0, totalNotes, 8): startNote = thisPage[i] startMeasure = startNote.measureNumber - print(" " + str(startMeasure)) + print(' ' + str(startMeasure)) newStream = stream.Stream(thisPage[i:i + 24]) newStream.pageNumber = pgMinus1 + 1 newStream.startMeasure = startMeasure @@ -82,7 +82,7 @@ def recognizeScore(scorePart, pageMeasureNumbers, iterations=1): for loopy in range(iterations): if loopy > 0: - print("\n\nstarting again in 3 seconds") + print('\n\nstarting again in 3 seconds') time.sleep(3) searchScore = audioSearch.transcriber.runTranscribe(show=False, plot=False, seconds=15.0, saveFile=False) @@ -94,21 +94,21 @@ def recognizeScore(scorePart, pageMeasureNumbers, iterations=1): scorePage = topStream.pageNumber - 1 scores[scorePage] += (topStream.matchProbability / (i + 1.5))*10 - print("\nBest guesses (pg#, starting measure, probability)") + print('\nBest guesses (pg#, starting measure, probability)') for i,st in enumerate(l): print(st.pageNumber, st.startMeasure, st.matchProbability) if i >= 7: break - print("\nWeighed top scores (pg#, score):") + print('\nWeighed top scores (pg#, score):') indexOfMaxScore = argmax_index(scores) for i in range(len(pages)): - print( (i + 1, scores[i]), end="") + print( (i + 1, scores[i]), end='') if i == indexOfMaxScore: - print(" **** ") + print(' **** ') else: - print("") + print('') if __name__ == '__main__': recognizeLuca() diff --git a/music21_tools/audioSearchDemos/repetitionGame.py b/music21_tools/audioSearchDemos/repetitionGame.py index 2fc7475..c0378bd 100644 --- a/music21_tools/audioSearchDemos/repetitionGame.py +++ b/music21_tools/audioSearchDemos/repetitionGame.py @@ -22,19 +22,19 @@ def __init__(self): self.round = 0 self.good = True self.gameNotes = [] - print("Welcome to the music21 game!") - print("Rules:") - print("Two players: the first one plays a note. \n" - + "The second one has to play the first note and a new one.") - print("Continue doing the same until one fails.") + print('Welcome to the music21 game!') + print('Rules:') + print('Two players: the first one plays a note. \n' + + 'The second one has to play the first note and a new one.') + print('Continue doing the same until one fails.') # time.sleep(2) - print("3, 2, 1 GO!") + print('3, 2, 1 GO!') def game(self): self.round = self.round + 1 - print("self.round %d" % self.round) + print('self.round %d' % self.round) # print "NOTES UNTIL NOW: (this will not be shown in the final version)" # for k in range(len(self.gameNotes)): # print self.gameNotes[k].fullName @@ -50,36 +50,36 @@ def game(self): j = 0 i = 0 while i < len(notesList) and j < len(self.gameNotes) and self.good == True: - if notesList[i].name == "rest": + if notesList[i].name == 'rest': i = i + 1 elif notesList[i].name == self.gameNotes[j].name: i = i + 1 j = j + 1 else: - print("WRONG NOTE! You played", notesList[i].fullName, - "and should have been", self.gameNotes[j].fullName) + print('WRONG NOTE! You played', notesList[i].fullName, + 'and should have been', self.gameNotes[j].fullName) self.good = False if self.good == True and j != len(self.gameNotes): self.good = False - print("YOU ARE VERY SLOW!!! PLAY FASTER NEXT TIME!") + print('YOU ARE VERY SLOW!!! PLAY FASTER NEXT TIME!') if self.good == False: - print("YOU LOSE!! HAHAHAHA") + print('YOU LOSE!! HAHAHAHA') else: - while i < len(notesList) and notesList[i].name == "rest": + while i < len(notesList) and notesList[i].name == 'rest': i = i + 1 if i < len(notesList): self.gameNotes.append(notesList[i]) #add a new note - print("WELL DONE!") + print('WELL DONE!') else: - print("YOU HAVE NOT ADDED A NEW NOTE! REPEAT AGAIN NOW") + print('YOU HAVE NOT ADDED A NEW NOTE! REPEAT AGAIN NOW') self.round = self.round - 1 return self.good -if __name__ == "__main__": +if __name__ == '__main__': rG = repetitionGame() good = True while good == True: diff --git a/music21_tools/bhadley/harmonyRealizer.py b/music21_tools/bhadley/harmonyRealizer.py index ff4f0bf..bf34b5e 100644 --- a/music21_tools/bhadley/harmonyRealizer.py +++ b/music21_tools/bhadley/harmonyRealizer.py @@ -220,7 +220,7 @@ def xtestRealizeLeadsheet(self, music21Stream): mergeLeadSheetAndBassLine(music21Stream, output).show() -if __name__ == "__main__": +if __name__ == '__main__': from music21 import base base.mainTest(Test, TestExternal) diff --git a/music21_tools/bhadley/nips2011.py b/music21_tools/bhadley/nips2011.py index 5a94cd9..9a7c053 100644 --- a/music21_tools/bhadley/nips2011.py +++ b/music21_tools/bhadley/nips2011.py @@ -27,7 +27,7 @@ orngTree = orange.classification.tree except ImportError: if __name__ == '__main__': - print("Orange must be installed to run this.") + print('Orange must be installed to run this.') exit() orange = None orngTree = None @@ -95,9 +95,9 @@ def nipsBuild(useOurExtractors=True, buildSet=1, evaluationMethod='coarse'): if evaluationMethod == 'coarse': #coarse evaluation (only "old" or "new") if year < 1961: - cv = "old" + cv = 'old' else: - cv = "new" + cv = 'new' else: # fine grained evaluations cv = year # if not using coarse but instead using the exact year as the class value @@ -217,7 +217,7 @@ def getLeadsheetDatesFromBillboard(): words.pop(0) for a in words: a.strip() - pretty = pretty +" "+ a + pretty = pretty +' '+ a if song == True: try: j = float(x) @@ -241,11 +241,11 @@ def getLeadsheetDatesFromBillboard(): groups = [] for strong in trs: x = strong.find(text=True) - if " " in str(x): + if ' ' in str(x): x = x.strip(' ') x = x.strip() if cnt < 100: - retstring = "" + retstring = '' loops = 1 for letter in x: if loops > 3: @@ -304,7 +304,7 @@ def getLeadsheetDatesFromBillboard(): matches = 0 rank = 0 - outputjson = '\'[' + outputjson = "'[" for i in indexValues: @@ -333,7 +333,7 @@ def getLeadsheetDatesFromBillboard(): #print "Title:", piece.metadata.movementName, " Composer:", piece.metadata.composer, " Date:", date, " Position on Billboard:", rank #print "Title:", piece.metadata.movementName, " Date:", date matches = matches + 1 - outputjson = outputjson + '{\"%s":[%s,%s]}, ' % (i, date, rank) + outputjson = outputjson + '{"%s":[%s,%s]}, ' % (i, date, rank) if (i % 500) == 0: j = ((i - 1000) / (11938.00)) * 100.00 print ('%s %%' %round(j, 2)) @@ -342,9 +342,9 @@ def getLeadsheetDatesFromBillboard(): foo = len(outputjson) - 2 - outputjson = outputjson[0:foo] + ']\'' + outputjson = outputjson[0:foo] + "]'" print (outputjson) - print ("FINISHED! Found this many matches: ", matches) + print ('FINISHED! Found this many matches: ', matches) def probabilityOfChance(): ''' diff --git a/music21_tools/chant/chant.py b/music21_tools/chant/chant.py index 246d05b..a29f877 100644 --- a/music21_tools/chant/chant.py +++ b/music21_tools/chant/chant.py @@ -8,8 +8,6 @@ # License: BSD, see license.txt # ------------------------------------------------------------------------------ ''' -``ALPHA MODULE``: Not directly supported by cuthbertLab. - Classes and Tools for converting Music21 Streams to Gregorio .gabc Requires the amazing Gregoio library: http://gregorio-project.github.io , which itself @@ -27,7 +25,7 @@ from music21 import stream from music21 import environment -_MOD = "chant.py" +_MOD = 'chant.py' environLocal = environment.Environment(_MOD) @@ -35,15 +33,15 @@ def fromStream(inputStream): if inputStream.metadata is not None: incipit = inputStream.metadata.title else: - incipit = "Benedicamus Domino" + incipit = 'Benedicamus Domino' out = '' out += 'name: ' + incipit + ';\n' - out += "%%\n" + out += '%%\n' return out class GregorianStream(stream.Stream): r''' - + >>> from music21_tools.chant.chant import GregorianStream, GregorianNote >>> s = GregorianStream() >>> s.append(clef.AltoClef()) >>> n = GregorianNote("C4") @@ -54,33 +52,32 @@ class GregorianStream(stream.Stream): >>> s.append(n) >>> s.toGABCText() '(c3) Po(ho)\n' - ''' def toGABCText(self): currentClef = None - outLine = "" + outLine = '' startedSyllable = False for e in self: if hasattr(e, 'isNote') and e.isNote is True: - if e.lyrics and e.lyrics[0] != "": + if e.lyrics and e.lyrics[0] != '': if startedSyllable: - outLine += ")" + outLine += ')' startedSyllable = False if e.lyrics[0].syllabic in ['begin', 'single']: - outLine += " " + outLine += ' ' outLine += e.lyrics[0].text - outLine += "(" + outLine += '(' startedSyllable = True outLine += e.toGABC(useClef=currentClef) elif 'Clef' in e.classes: if startedSyllable: - outLine += ") " + outLine += ') ' startedSyllable = False currentClef = e outLine += self.clefToGABC(e) + ' ' if startedSyllable: - outLine += ")\n" + outLine += ')\n' return outLine def clefToGABC(self, clefIn): @@ -90,7 +87,7 @@ def clefToGABC(self, clefIn): >>> s.clefToGABC(c) '(c3)' ''' - return "(" + clefIn.sign.lower() + str(clefIn.line) + ")" + return '(' + clefIn.sign.lower() + str(clefIn.line) + ')' class GregorianNote(note.Note): @@ -149,7 +146,7 @@ def __init__(self, *arguments, **keywords): def toGABC(self, useClef=None, nextNote=None): letter = self.toBasicGABC(useClef) if self.debilis: - letter = "-" + letter + letter = '-' + letter if self.inclinatum: letter = letter.upper() @@ -186,19 +183,19 @@ def toGABC(self, useClef=None, nextNote=None): raise ChantException('unable to do punctumMora with more than two notes') if self.episema != False: if self.episema == 'vertical': - letter += '\'' + letter += "'" elif self.episema == 'below': letter += '_0' else: letter += '_' if self.breakNeume != False: - letter += "!" + letter += '!' if self.choralSign != False: - letter += "[cs:" + self.choralSign + "]" + letter += '[cs:' + self.choralSign + ']' if self.polyphonic: - letter = "{" + letter + "}" + letter = '{' + letter + '}' return letter @@ -230,7 +227,7 @@ def toBasicGABC(self, useClef=None): if not hasattr(useClef, 'lowestLine'): raise ChantException( - "useClef has to define the diatonicNoteNum representing the lowest line") + 'useClef has to define the diatonicNoteNum representing the lowest line') stepsAboveLowestLine = inNote.pitch.diatonicNoteNum - useClef.lowestLine asciiNote = stepsAboveLowestLine + asciiD @@ -238,17 +235,17 @@ def toBasicGABC(self, useClef=None): if asciiNote < asciiA: if usedDefaultClef is True: raise ChantException( - "note is too low for the default clef (AltoClef), choose a lower one") + 'note is too low for the default clef (AltoClef), choose a lower one') else: raise ChantException( - "note is too low for the clef (%s), choose a lower one" % str(useClef)) + 'note is too low for the clef (%s), choose a lower one' % str(useClef)) elif asciiNote > asciiM: if usedDefaultClef is True: raise ChantException( - "note is too high for the default clef (AltoClef), choose a higher one") + 'note is too high for the default clef (AltoClef), choose a higher one') else: raise ChantException( - "note is too high for the clef (%s), choose a higher one" % str(useClef)) + 'note is too high for the clef (%s), choose a higher one' % str(useClef)) else: return chr(asciiNote) @@ -258,7 +255,7 @@ def _getFill(self): def _setFill(self, value): if value not in self.fillDic: - raise ChantException("Cannot set fill to value %s." % value) + raise ChantException('Cannot set fill to value %s.' % value) self._fill = value fill = property(_getFill, _setFill, doc='''Sets the @@ -320,15 +317,15 @@ class BaseScoreConverter: def __init__(self): self.environLocal = environLocal self.gregorioConverter = '/usr/local/bin/gregorio' - self.gregorioOptions = "" + self.gregorioOptions = '' self.gregorioCommand = None self.latexConverter = '/usr/texbin/lualatex' self.latexOptions = '--interaction=nonstopmode' - self.score = "" - self.incipit = "" - self.mode = "" + self.score = '' + self.incipit = '' + self.mode = '' self.paperType = None def writeFile(self, text=None): @@ -343,7 +340,7 @@ def writeFile(self, text=None): ''' - if text is None or text == "": + if text is None or text == '': raise ChantException('Cannot write file if there is no data') fp = self.environLocal.getTempFile('.gabc') f = open(fp, 'w') @@ -507,7 +504,7 @@ def substituteInfo(self, converter): wrapper = re.sub(r'INCIPITGOESHERE', incipit, wrapper) wrapper = re.sub(r'MODEGOESHERE', mode, wrapper) wrapper = re.sub(r'PAPERTYPEGOESHERE', paperType, wrapper) - wrapper = re.sub(r'\\endinput %', r'\\end{document}' + "\n" + r'\\endinput %', wrapper) + wrapper = re.sub(r'\\endinput %', r'\\end{document}' + '\n' + r'\\endinput %', wrapper) return wrapper @@ -533,27 +530,27 @@ def testSimpleFile(self): s = GregorianStream() s.append(clef.AltoClef()) - n = GregorianNote("C4") - l = note.Lyric("Po") - l.syllabic = "begin" + n = GregorianNote('C4') + l = note.Lyric('Po') + l.syllabic = 'begin' n.lyrics.append(l) n.oriscus = True s.append(n) - n2 = GregorianNote("D4") + n2 = GregorianNote('D4') s.append(n2) - n3 = GregorianNote("C4") + n3 = GregorianNote('C4') n3.stropha = True s.append(n3) - n4 = GregorianNote("B3") + n4 = GregorianNote('B3') n4.stropha = True s.append(n4) gabcText = s.toGABCText() bsc = BaseScoreConverter() bsc.score = gabcText - bsc.incipit = "Populus" + bsc.incipit = 'Populus' bsc.mode = 'VII' - fn = bsc.writeFile("style: modern;\n\n%%\n" + gabcText) + fn = bsc.writeFile('style: modern;\n\n%%\n' + gabcText) texfn = bsc.launchGregorio(fn) texfh = open(texfn) texcontents = texfh.read() @@ -574,7 +571,7 @@ def testSimpleFile(self): _DOC_ORDER = [] -if __name__ == "__main__": +if __name__ == '__main__': import music21 music21.mainTest(Test, 'moduleRelative') diff --git a/music21_tools/choraleTools/mnum_fixer.py b/music21_tools/choraleTools/mnum_fixer.py index 6069849..86f7601 100644 --- a/music21_tools/choraleTools/mnum_fixer.py +++ b/music21_tools/choraleTools/mnum_fixer.py @@ -48,7 +48,7 @@ def runOne(c, cName): mns = m.measureNumberWithSuffix() ts = m.timeSignature or m.getContextByClass('TimeSignature') if ts is None: - print("No time signature context!", cName, part.id, mns) + print('No time signature context!', cName, part.id, mns) continue barQl = ts.barDuration.quarterLength mQl = m.duration.quarterLength @@ -90,7 +90,7 @@ def runOne(c, cName): m.number = 0 measureNumberShift += 1 elif truncated and priorMeasureWasIncomplete and priorMeasureDuration == short: - print("Truncated measure following pickup...", cName, part.id, mn) + print('Truncated measure following pickup...', cName, part.id, mn) priorMeasure.paddingRight = priorMeasure.paddingLeft priorMeasure.paddingLeft = 0 measureNumberShift += 1 @@ -111,7 +111,7 @@ def runOne(c, cName): m.number = mn - measureNumberShift partNumSuffix.append((mn - measureNumberShift, ms)) elif pickup and not priorMeasureWasIncomplete: - print("Pickup following complete prior measure", cName, part.id, mn) + print('Pickup following complete prior measure', cName, part.id, mn) priorMeasureWasIncomplete = True m.paddingLeft = short priorMeasure = m @@ -133,7 +133,7 @@ def runOne(c, cName): m.numberSuffix = ms partNumSuffix.append((mn - measureNumberShift, ms)) elif pickup and priorMeasureWasIncomplete and ts is not priorMeasure.timeSignature: - print("Changing TS Pickup", cName, part.id, mn) + print('Changing TS Pickup', cName, part.id, mn) priorMeasureWasIncomplete = True m.paddingLeft = short priorMeasure = m @@ -147,7 +147,7 @@ def runOne(c, cName): if len(allSuffixesByPart) != 1: - print("Multiple conflicting measures!", cName) + print('Multiple conflicting measures!', cName) print(cName, allSuffixesByPart) try: @@ -156,14 +156,14 @@ def runOne(c, cName): sKOrig = str(kOrig) sKNew = str(kNew) if kOrig.sharps != kNew.sharps: - print("Key changed from", kOrig, kNew) + print('Key changed from', kOrig, kNew) if sKNew != sKOrig: kNew.activeSite.replace(kNew, kOrig) analysisKey = newScore.analyze('key') print('Mode would have been changed from ', sKOrig, sKNew) if str(analysisKey) != sKOrig: - print("Key mismatch: ", sKOrig, sKNew, str(analysisKey)) + print('Key mismatch: ', sKOrig, sKNew, str(analysisKey)) except IndexError: print('no key in ', cName) diff --git a/music21_tools/composition/__init__.py b/music21_tools/composition/__init__.py index 8915783..4c670d8 100644 --- a/music21_tools/composition/__init__.py +++ b/music21_tools/composition/__init__.py @@ -1,7 +1,7 @@ -""" +''' Files in this package relate to aiding in composition -""" +''' __all__ = ['arvo', 'phasing', 'seeger'] # leave off aug30 for now diff --git a/music21_tools/composition/arvo.py b/music21_tools/composition/arvo.py index 62884c1..f27bf6f 100644 --- a/music21_tools/composition/arvo.py +++ b/music21_tools/composition/arvo.py @@ -52,16 +52,16 @@ def partPari(show=True): else: n.accidental = cminor.accidentalByStep(n.step) if n.offset == (2 - 1) * 4 or n.offset == (74 - 1) * 4: - n.pitch = pitch.Pitch("C3") # exceptions to rule + n.pitch = pitch.Pitch('C3') # exceptions to rule elif n.offset == (73 - 1) * 4: n.tie = None - n.pitch = pitch.Pitch("C3") + n.pitch = pitch.Pitch('C3') top = copy.deepcopy(main.flatten()) main.insert(0, clef.Treble8vbClef()) middle = copy.deepcopy(main.flatten()) - cMinorArpeg = scale.ConcreteScale(pitches=["C2", "E-2", "G2"]) + cMinorArpeg = scale.ConcreteScale(pitches=['C2', 'E-2', 'G2']) # # dummy test on other data # myA = pitch.Pitch("A2") # myA.microtone = -15 diff --git a/music21_tools/composition/aug30.py b/music21_tools/composition/aug30.py index e1ab288..41d1a8c 100644 --- a/music21_tools/composition/aug30.py +++ b/music21_tools/composition/aug30.py @@ -93,9 +93,9 @@ def nextOrPreviousType(baseDuration): def addPart(minLength=80, maxProbability=0.7, instrument=None): s1 = rhythmLine(minLength=minLength, maxProbability=maxProbability) - ts1 = meter.TimeSignature("4/4") + ts1 = meter.TimeSignature('4/4') s1.insert(0, ts1) - s1.insert(0, tempo.MetronomeMark(number=180, text="very fast")) + s1.insert(0, tempo.MetronomeMark(number=180, text='very fast')) if instrument is not None: s1.insert(0, instrument) s1.makeAccidentals() @@ -131,7 +131,7 @@ def test(): sc1.insert(0, part) sc1.show() -if __name__ == "__main__": +if __name__ == '__main__': test() # ----------------------------------------------------------------------------- diff --git a/music21_tools/composition/phasing.py b/music21_tools/composition/phasing.py index ed1b126..0858f38 100644 --- a/music21_tools/composition/phasing.py +++ b/music21_tools/composition/phasing.py @@ -40,8 +40,8 @@ def pitchedPhase(cycles=None, show=False): ''' - sSrc = converter.parse("""tinynotation: 12/16 E16 F# B c# d F# E c# B F# d c# - E16 F# B c# d F# E c# B F# d c#""", makeNotation=False) + sSrc = converter.parse('''tinynotation: 12/16 E16 F# B c# d F# E c# B F# d c# + E16 F# B c# d F# E c# B F# d c#''', makeNotation=False) sPost = stream.Score() sPost.title = 'phasing experiment' sPost.insert(0, stream.Part()) @@ -188,7 +188,7 @@ def xtestPendulumMusic(self, show=True): # define presented order in documentation _DOC_ORDER = [pitchedPhase] -if __name__ == "__main__": +if __name__ == '__main__': if len(sys.argv) == 1: # normal conditions import music21 music21.mainTest(TestExternal) diff --git a/music21_tools/composition/seeger.py b/music21_tools/composition/seeger.py index b3e9e81..b382a30 100644 --- a/music21_tools/composition/seeger.py +++ b/music21_tools/composition/seeger.py @@ -50,20 +50,20 @@ def lowerLines(): if addNote == 0: if phraseNumber != 8: - appendNote.lyrics.append(note.Lyric(text="p" + str(phraseNumber), number=1)) + appendNote.lyrics.append(note.Lyric(text='p' + str(phraseNumber), number=1)) else: - appendNote.lyrics.append(note.Lyric(text="p8*", number=1)) + appendNote.lyrics.append(note.Lyric(text='p8*', number=1)) if (currentNote % 10 == (rotationNumber + 8) % 10) and (currentNote != 0): currentNote += 2 rotationNumber += 1 else: if currentNote % 10 == (rotationNumber + 9) % 10: - appendNote.lyrics.append(note.Lyric(text="r" + str(rotationNumber), number=2)) + appendNote.lyrics.append(note.Lyric(text='r' + str(rotationNumber), number=2)) if rotationNumber in range(13, 22): appendNote.transpose(correctTranspositions[rotationNumber - 13], inPlace=True) appendNote.pitch.simplifyEnharmonic(inPlace=True) - appendNote.lyrics.append(note.Lyric(text="*", number=3)) + appendNote.lyrics.append(note.Lyric(text='*', number=3)) currentNote += 1 if addNote == 20 - phraseNumber: # correct Last Notes diff --git a/music21_tools/contour/contour.py b/music21_tools/contour/contour.py index 44dea1d..84b40d8 100644 --- a/music21_tools/contour/contour.py +++ b/music21_tools/contour/contour.py @@ -80,9 +80,9 @@ def __init__(self, s=None): #self.metrics contains a dictionary mapping the name of a metric to a tuple (x,y) # where x=metric function and y=needsChordify - self._metrics = {"dissonance": (self.dissonanceMetric, True), - "spacing": (self.spacingMetric, True), - "tonality": (self.tonalDistanceMetric, False) } + self._metrics = {'dissonance': (self.dissonanceMetric, True), + 'spacing': (self.spacingMetric, True), + 'tonality': (self.tonalDistanceMetric, False) } self.isContourFinder = True @@ -209,14 +209,14 @@ def getContour(self, cType, window=None, slide=None, overwrite=False, if cType in self._contours: if window is not None or slide is not None: raise OverwriteException( - "Attempted to overwrite cached contour of type {0}".format(cType) + - " but did not specify overwrite=True") + 'Attempted to overwrite cached contour of type {0}'.format(cType) + + ' but did not specify overwrite=True') else: return self._contours[cType] elif cType in self._metrics: if metric is not None: raise OverwriteException("Attempted to overwrite '{0}' ".format(cType) + - "metric but did not specify overwrite=True") + 'metric but did not specify overwrite=True') else: metric, needsChordify = self._metrics[cType] else: @@ -226,7 +226,7 @@ def getContour(self, cType, window=None, slide=None, overwrite=False, if cType in self._metrics: metric, needsChordify = self._metrics[cType] else: - raise ContourException("Must provide your own metric for type: %s" % cType) + raise ContourException('Must provide your own metric for type: %s' % cType) if slide is None: @@ -770,7 +770,7 @@ def _runExperiment(): for cType in ['spacing', 'tonality', 'dissonance']: - print("considering", cType, ": ") + print('considering', cType, ': ') cf = ContourFinder() totalSuccesses = 0 @@ -793,10 +793,10 @@ def _runExperiment(): #print "GREAT SUCCESS!" else: totalFailures += 1 - print("failure: chorale " + goodChorales[j]) #index ", str(i) + print('failure: chorale ' + goodChorales[j]) #index ", str(i) - print(cType, ": totalSuccesses =", str(totalSuccesses), - "totalFailures =", str(totalFailures)) + print(cType, ': totalSuccesses =', str(totalSuccesses), + 'totalFailures =', str(totalFailures)) def _plotChoraleContours(): BCI = corpus.chorales.Iterator(1, 75, returnType='filename') @@ -821,7 +821,7 @@ class Test(unittest.TestCase): def runTest(self): pass -if __name__ == "__main__": +if __name__ == '__main__': import music21 music21.mainTest(Test, 'moduleRelative') diff --git a/music21_tools/counterpoint/__init__.py b/music21_tools/counterpoint/__init__.py index c73ef60..944f43d 100644 --- a/music21_tools/counterpoint/__init__.py +++ b/music21_tools/counterpoint/__init__.py @@ -1,5 +1,5 @@ -__all__ = ["species"] +__all__ = ['species'] from . import species # ----------------------------------------------------------------------------- diff --git a/music21_tools/counterpoint/species.py b/music21_tools/counterpoint/species.py index 9537a4a..6eb06ac 100644 --- a/music21_tools/counterpoint/species.py +++ b/music21_tools/counterpoint/species.py @@ -32,7 +32,7 @@ from music21 import voiceLeading from music21 import environment -_MOD = "counterpoint/species.py" +_MOD = 'counterpoint/species.py' environLocal = environment.Environment(_MOD) @@ -88,10 +88,10 @@ def findParallelFifths(self, srcStream, cmpStream): if (note2 is not None and note1.editorial.harmonicInterval is not None and note2.editorial.harmonicInterval is not None - and note1.editorial.harmonicInterval.semiSimpleName == "P5" - and note2.editorial.harmonicInterval.semiSimpleName == "P5"): + and note1.editorial.harmonicInterval.semiSimpleName == 'P5' + and note2.editorial.harmonicInterval.semiSimpleName == 'P5'): numParallelFifths += 1 - note2.editorial["parallelFifth"] = True + note2.editorial['parallelFifth'] = True return numParallelFifths def findHiddenFifths(self, stream1, stream2): @@ -134,7 +134,7 @@ def findHiddenFifths(self, stream1, stream2): hidden = self.isHiddenFifth(note1, note2, note3, note4) if hidden: numHiddenFifths += 1 - note2.editorial["hiddenFifth"] = True + note2.editorial['hiddenFifth'] = True return numHiddenFifths def isParallelFifth(self, note11, note12, note21, note22): @@ -250,15 +250,15 @@ def findParallelOctaves(self, stream1, stream2): for note1 in stream1: note2 = stream1.getElementAfterElement(note1, [Note]) if note2 is not None: - if note1.editorial.harmonicInterval.semiSimpleName == "P8": - if note2.editorial.harmonicInterval.semiSimpleName == "P8": + if note1.editorial.harmonicInterval.semiSimpleName == 'P8': + if note2.editorial.harmonicInterval.semiSimpleName == 'P8': numParallelOctaves += 1 note2.editorial.parallelOctave = True for note1 in stream2: note2 = stream2.getElementAfterElement(note1, [Note]) if note2 is not None: - if note1.editorial.harmonicInterval.semiSimpleName == "P8": - if note2.editorial.harmonicInterval.semiSimpleName == "P8": + if note1.editorial.harmonicInterval.semiSimpleName == 'P8': + if note2.editorial.harmonicInterval.semiSimpleName == 'P8': note2.editorial.parallelOctave = True return numParallelOctaves @@ -422,15 +422,15 @@ def findParallelUnisons(self, stream1, stream2): for note1 in stream1: note2 = stream1.getElementAfterElement(note1, [Note]) if note2 is not None: - if note1.editorial.harmonicInterval.name == "P1": - if note2.editorial.harmonicInterval.name == "P1": + if note1.editorial.harmonicInterval.name == 'P1': + if note2.editorial.harmonicInterval.name == 'P1': numParallelUnisons += 1 note2.editorial.parallelUnison = True for note1 in stream2: note2 = stream2.getElementAfterElement(note1, [Note]) if note2 is not None: - if note1.editorial.harmonicInterval.name == "P1": - if note2.editorial.harmonicInterval.name == "P1": + if note1.editorial.harmonicInterval.name == 'P1': + if note2.editorial.harmonicInterval.name == 'P1': note2.editorial.parallelUnison = True return numParallelUnisons @@ -565,12 +565,12 @@ def allValidHarmony(self, stream1, stream2): for note2 in stream2.notes: if note2.editorial.harmonicInterval.semiSimpleName not in self.legalHarmonicIntervals: return False - if stream1.notes[-1].editorial.harmonicInterval.specificName != "Perfect": + if stream1.notes[-1].editorial.harmonicInterval.specificName != 'Perfect': environLocal.printDebug([stream1.notes[-1].editorial.harmonicInterval.specificName + - " ending, yuk!"]) + ' ending, yuk!']) return False if abs(stream1.notes[-1].editorial.harmonicInterval.generic.value) == 5: - environLocal.printDebug(["Ends on a fifth, yuk!"]) + environLocal.printDebug(['Ends on a fifth, yuk!']) return False if (stream1.notes[-1].editorial.harmonicInterval.semiSimpleName == 'P8' and stream1.notes[-2].editorial.harmonicInterval.simpleName == 'M6'): @@ -618,9 +618,9 @@ def allValidHarmonyMiddleVoices(self, stream1, stream2): if (note2.editorial.harmonicInterval.semiSimpleName not in self.legalMiddleHarmonicIntervals): return False - if stream1.notes[-1].editorial.harmonicInterval.specificName != "Perfect": + if stream1.notes[-1].editorial.harmonicInterval.specificName != 'Perfect': environLocal.printDebug([stream1.notes[-1].editorial.harmonicInterval.specificName + - " ending, yuk!"]) + ' ending, yuk!']) return False return True @@ -1001,11 +1001,11 @@ def raiseLeadingTone(self, stream1, minorScale): note2 = s1notes[i + 1] note3 = s1notes[i + 2] if (note2.name == seventh and note3.name == tonic): - note1 = note1.transpose("A1") + note1 = note1.transpose('A1') elif (note1.name == seventh and i < maxNote - 1): note2 = s1notes[i + 1] if note2.name == tonic: - note1 = note1.transpose("A1") + note1 = note1.transpose('A1') stream2.append(copy.deepcopy(note1)) return stream2 @@ -1043,17 +1043,17 @@ def generateFirstSpecies(self, cantusFirmus, minorScale, choice='random'): environLocal.printDebug([note1.name + str(note1.octave) for note1 in cantusFirmus.notes]) if not goodHarmony: - environLocal.printDebug(["bad harmony"]) + environLocal.printDebug(['bad harmony']) else: - environLocal.printDebug(["harmony good"]) + environLocal.printDebug(['harmony good']) if not goodMelody: - environLocal.printDebug(["bad melody"]) + environLocal.printDebug(['bad melody']) else: - environLocal.printDebug(["melody good"]) + environLocal.printDebug(['melody good']) if not thirdsGood: - environLocal.printDebug(["too many thirds"]) + environLocal.printDebug(['too many thirds']) if not sixthsGood: - environLocal.printDebug(["too many sixths"]) + environLocal.printDebug(['too many sixths']) except ModalCounterpointException: pass @@ -1078,8 +1078,8 @@ def getValidSecondVoice(self, stream1, minorScale, choice='random'): # interval.transposeNote(firstNote, "P5"), # interval.transposeNote(firstNote, "P8")] choices = [copy.deepcopy(firstNote), - firstNote.transpose("P5"), - firstNote.transpose("P8")] + firstNote.transpose('P5'), + firstNote.transpose('P8')] if choice == 'random': note1 = random.choice(choices) elif choice == 'first': @@ -1096,7 +1096,7 @@ def getValidSecondVoice(self, stream1, minorScale, choice='random'): choices = self.generateValidNotes(prevFirmus, currFirmus, prevNote, afterLeap, minorScale) if not choices: - raise ModalCounterpointException("Sorry, please try again") + raise ModalCounterpointException('Sorry, please try again') if choice == 'random': newNote = random.choice(choices) elif choice == 'first': @@ -1129,27 +1129,27 @@ def generateValidNotes(self, prevFirmus, currFirmus, prevNote, afterLeap, minorS possibleNotes = [] - n1 = interval.transposeNote(prevNote, "m2") - n2 = interval.transposeNote(prevNote, "M2") - n3 = interval.transposeNote(prevNote, "m3") - n4 = interval.transposeNote(prevNote, "M3") + n1 = interval.transposeNote(prevNote, 'm2') + n2 = interval.transposeNote(prevNote, 'M2') + n3 = interval.transposeNote(prevNote, 'm3') + n4 = interval.transposeNote(prevNote, 'M3') if afterLeap: goingUp = [n1, n2, n3, n4] else: - n5 = interval.transposeNote(prevNote, "P4") - n6 = interval.transposeNote(prevNote, "P5") + n5 = interval.transposeNote(prevNote, 'P4') + n6 = interval.transposeNote(prevNote, 'P5') goingUp = [n1, n2, n3, n4, n5, n6] - n7 = interval.transposeNote(prevNote, "m-2") - n8 = interval.transposeNote(prevNote, "M-2") - n9 = interval.transposeNote(prevNote, "m-3") - n10 = interval.transposeNote(prevNote, "M-3") + n7 = interval.transposeNote(prevNote, 'm-2') + n8 = interval.transposeNote(prevNote, 'M-2') + n9 = interval.transposeNote(prevNote, 'm-3') + n10 = interval.transposeNote(prevNote, 'M-3') if afterLeap: goingDown = [n7, n8, n9, n10] else: - n11 = interval.transposeNote(prevNote, "P-4") - n12 = interval.transposeNote(prevNote, "P-5") + n11 = interval.transposeNote(prevNote, 'P-4') + n12 = interval.transposeNote(prevNote, 'P-5') goingDown = [n7, n8, n9, n10, n11, n12] possibleNotes.extend(goingUp) @@ -1159,7 +1159,7 @@ def generateValidNotes(self, prevFirmus, currFirmus, prevNote, afterLeap, minorS possibleNotes.extend(goingUp) else: possibleNotes.extend(goingDown) - environLocal.printDebug(["possible: ", [note1.name for note1 in possibleNotes]]) + environLocal.printDebug(['possible: ', [note1.name for note1 in possibleNotes]]) goodNotes = minorScale.getPitches('C2', 'C6') goodNames = [note2.name for note2 in goodNotes] @@ -1187,7 +1187,7 @@ def generateValidNotes(self, prevFirmus, currFirmus, prevNote, afterLeap, minorS continue if interval.Interval(currFirmus, note1).generic.value > 10: continue - environLocal.printDebug(["adding: ", note1.name, note1.octave]) + environLocal.printDebug(['adding: ', note1.name, note1.octave]) valid.append(note1) return valid @@ -1206,30 +1206,30 @@ def generateValidLastNotes(self, prevFirmus, currFirmus, prevNote, afterLeap, mi possibleNotes = [] - n1 = interval.transposeNote(prevNote, "m2") - n2 = interval.transposeNote(prevNote, "M2") + n1 = interval.transposeNote(prevNote, 'm2') + n2 = interval.transposeNote(prevNote, 'M2') if not topVoice: - n3 = interval.transposeNote(prevNote, "m3") - n4 = interval.transposeNote(prevNote, "M3") + n3 = interval.transposeNote(prevNote, 'm3') + n4 = interval.transposeNote(prevNote, 'M3') if afterLeap: goingUp = [n1, n2, n3, n4] else: - n5 = interval.transposeNote(prevNote, "P4") - n6 = interval.transposeNote(prevNote, "P5") + n5 = interval.transposeNote(prevNote, 'P4') + n6 = interval.transposeNote(prevNote, 'P5') goingUp = [n1, n2, n3, n4, n5, n6] else: goingUp = [n1, n2] - n7 = interval.transposeNote(prevNote, "m-2") - n8 = interval.transposeNote(prevNote, "M-2") + n7 = interval.transposeNote(prevNote, 'm-2') + n8 = interval.transposeNote(prevNote, 'M-2') if not topVoice: - n9 = interval.transposeNote(prevNote, "m-3") - n10 = interval.transposeNote(prevNote, "M-3") + n9 = interval.transposeNote(prevNote, 'm-3') + n10 = interval.transposeNote(prevNote, 'M-3') if afterLeap: goingDown = [n7, n8, n9, n10] else: - n11 = interval.transposeNote(prevNote, "P-4") - n12 = interval.transposeNote(prevNote, "P-5") + n11 = interval.transposeNote(prevNote, 'P-4') + n12 = interval.transposeNote(prevNote, 'P-5') goingDown = [n7, n8, n9, n10, n11, n12] else: goingDown = [n7, n8] @@ -1241,7 +1241,7 @@ def generateValidLastNotes(self, prevFirmus, currFirmus, prevNote, afterLeap, mi possibleNotes.extend(goingUp) else: possibleNotes.extend(goingDown) - environLocal.printDebug(["possible: ", [note1.name for note1 in possibleNotes]]) + environLocal.printDebug(['possible: ', [note1.name for note1 in possibleNotes]]) goodNotes = minorScale.ascending() goodNames = [note2.name for note2 in goodNotes] @@ -1272,7 +1272,7 @@ def generateValidLastNotes(self, prevFirmus, currFirmus, prevNote, afterLeap, mi if (interval.Interval(currFirmus, note1).simpleName == 1 or interval.Interval(currFirmus, note1).simpleName == 5): - environLocal.printDebug(["adding: ", note1.name, note1.octave]) + environLocal.printDebug(['adding: ', note1.name, note1.octave]) valid.append(note1) return valid @@ -1695,7 +1695,7 @@ def xtestGenerateFirstSpeciesThreeVoices(self): cf = cantusFirmi[0]# getRandomCF() environLocal.printDebug(['Using: ', cf['notes']]) - cantusFirmus = stream.Part(converter.parse(cf['notes'], "4/4").notes) + cantusFirmus = stream.Part(converter.parse(cf['notes'], '4/4').notes) baseNote = Note(cf['mode']) thisScale = scale.MinorScale(baseNote) @@ -1715,7 +1715,7 @@ def xtestGenerateFirstSpeciesThreeVoices(self): -if __name__ == "__main__": +if __name__ == '__main__': import music21 music21.mainTest(Test, 'moduleRelative') diff --git a/music21_tools/featureExtraction/ismir2011.py b/music21_tools/featureExtraction/ismir2011.py index e5f53c0..1756552 100644 --- a/music21_tools/featureExtraction/ismir2011.py +++ b/music21_tools/featureExtraction/ismir2011.py @@ -34,7 +34,7 @@ def _process(self): allPitches = self.data['flat.pitches'] fictaPitches = 0 for p in allPitches: - if p.name == "B-": + if p.name == 'B-': continue elif p.accidental is not None and p.accidental.name != 'natural': fictaPitches += 1 @@ -300,8 +300,8 @@ def tinyNotationBass(): fbLine1.showAllRealizations() def figuredBassScale(): - fbScale1 = figuredBass.realizerScale.FiguredBassScale("D", "major") - print (fbScale1.getSamplePitches("E3", "6")) + fbScale1 = figuredBass.realizerScale.FiguredBassScale('D', 'major') + print (fbScale1.getSamplePitches('E3', '6')) def exampleD(): diff --git a/music21_tools/josquin/label_intervals.py b/music21_tools/josquin/label_intervals.py index 284c46b..f8e62d6 100644 --- a/music21_tools/josquin/label_intervals.py +++ b/music21_tools/josquin/label_intervals.py @@ -11,11 +11,11 @@ from music21 import converter, interval def displayIntervals(file): - """ + ''' displayIntervals reads a music file and then displays it with an enumeration of the intervals above the lowest notes in the score at each sonority (after chordification). - """ + ''' sJosquinPiece = converter.parse(file) #dissonant_intervals = ['m2', 'M2', 'M7', 'd5', 'm7', 'A4', 'P4'] rJosquinPiece = sJosquinPiece.chordify() @@ -37,17 +37,17 @@ def displayIntervals(file): ##################################################################################### -if __name__ == "__main__": +if __name__ == '__main__': import os import sys - basedir = "" # "/Users/Victoria/Desktop/" - filename = "1202a-Missa_Sine_nomine-Kyrie.xml" #argv[1] + basedir = '' # "/Users/Victoria/Desktop/" + filename = '1202a-Missa_Sine_nomine-Kyrie.xml' #argv[1] if os.path.isfile(filename): displayIntervals(filename) elif os.path.isfile(basedir + filename): displayIntervals(basedir + filename) else: - print("Cannot find file ", sys.argv[1]) - print("Usage: " + sys.argv[0] + " filename") + print('Cannot find file ', sys.argv[1]) + print('Usage: ' + sys.argv[0] + ' filename') diff --git a/music21_tools/midi/build_melody.py b/music21_tools/midi/build_melody.py index 3974a27..60e864e 100644 --- a/music21_tools/midi/build_melody.py +++ b/music21_tools/midi/build_melody.py @@ -28,7 +28,7 @@ def populate_midi_track_from_data(mt, data): mt.events.append(dt) me = midi.MidiEvent(mt) - me.type = "NOTE_ON" + me.type = 'NOTE_ON' me.channel = 1 me.time = None # d me.pitch = p @@ -42,7 +42,7 @@ def populate_midi_track_from_data(mt, data): mt.events.append(dt) me = midi.MidiEvent(mt) - me.type = "NOTE_OFF" + me.type = 'NOTE_OFF' me.channel = 1 me.time = None # d me.pitch = p @@ -58,7 +58,7 @@ def populate_midi_track_from_data(mt, data): mt.events.append(dt) me = midi.MidiEvent(mt) - me.type = "END_OF_TRACK" + me.type = 'END_OF_TRACK' me.channel = 1 me.data = '' # must set data to empty string mt.events.append(me) @@ -91,7 +91,7 @@ def main(): env = environment.Environment() temp_filename = env.getTempFile('.mid') - print("Saving file to: %s" % temp_filename) + print('Saving file to: %s' % temp_filename) mf.open(temp_filename, 'wb') mf.write() mf.close() diff --git a/music21_tools/misc/eschbeg.py b/music21_tools/misc/eschbeg.py index ed45291..5c90fe9 100644 --- a/music21_tools/misc/eschbeg.py +++ b/music21_tools/misc/eschbeg.py @@ -22,16 +22,16 @@ eschbeg = '30ET47' def letterToNumber(letter): - if letter == "E": number = 11 - elif letter == "T": number = 10 + if letter == 'E': number = 11 + elif letter == 'T': number = 10 else: number = int(letter) return number def numberToLetter(number): if number == 11: - letter = "E" + letter = 'E' elif number == 10: - letter = "T" + letter = 'T' else: letter = str(number) return letter @@ -40,7 +40,7 @@ def numberToLetter(number): def setupTranspositions(): _eschbegTransposed = [] for i in range(12): - thisTransposition = "" + thisTransposition = '' for letter in eschbeg: number = letterToNumber(letter) newnum = (number + i) % 12 @@ -63,7 +63,7 @@ def generateToneRows(numberToGenerate=1000, cardinality=12): >>> #_DOCS_SHOW generateToneRows(4, 3) ['840', 'T61', 'T10', '173'] ''' - allNotes = "0123456789TE" + allNotes = '0123456789TE' firstRow = list(allNotes) returnRows = [] for i in range(numberToGenerate): @@ -82,7 +82,7 @@ def generateRandomRows(numberToGenerate=1000): returnRows = [] for i in range(numberToGenerate): myRow = [] - lastLetter = "" + lastLetter = '' for j in range(12): newLetter = numberToLetter(random.randint(0, 11)) if newLetter != lastLetter: @@ -199,14 +199,14 @@ def findEmbeddedChords(testSet='0234589', cardinality=3, skipInverse=False): ''' eschbegSplit12 = [letterToNumber(x) for x in testSet] - ret = "" + ret = '' for myTrichord in chord.tables.FORTE[cardinality]: if myTrichord is None: continue myPitches = myTrichord[0] myPitchString = ''.join([str(p) for p in myPitches]) - ret += "\n[" + myPitchString + "]: " + ret += '\n[' + myPitchString + ']: ' for i in range(12): notFound = False transPitches = [(p + i) % 12 for p in myPitches] @@ -215,7 +215,7 @@ def findEmbeddedChords(testSet='0234589', cardinality=3, skipInverse=False): notFound = True if notFound is False: transPitchesString = ''.join([str(p) for p in transPitches]) - ret += "(" + transPitchesString + ") " + ret += '(' + transPitchesString + ') ' if skipInverse is False: myInverse = [] @@ -227,7 +227,7 @@ def findEmbeddedChords(testSet='0234589', cardinality=3, skipInverse=False): myInverse = sorted(myInverse) myInverseString = ''.join([str(p) for p in myInverse]) if myInverseString != myPitchString: # some are symmetric - ret += "\n[" + myInverseString + "]: " + ret += '\n[' + myInverseString + ']: ' for i in range(12): notFound = False transInverse = [(p + i) % 12 for p in myInverse] @@ -236,7 +236,7 @@ def findEmbeddedChords(testSet='0234589', cardinality=3, skipInverse=False): notFound = True if notFound is False: transInverseString = ''.join([str(p) for p in transInverse]) - ret += "(" + transInverseString + ") " + ret += '(' + transInverseString + ') ' return ret.lstrip() def uniquenessOfEschbeg(cardinality=7, searchCardinality=3, skipInverse=False, showMatching=True): @@ -323,7 +323,7 @@ def uniquenessOfEschbeg(cardinality=7, searchCardinality=3, skipInverse=False, s return allHeptachordList -if __name__ == "__main__": +if __name__ == '__main__': import music21 music21.mainTest('moduleRelative') diff --git a/music21_tools/misc/gatherAccidentals.py b/music21_tools/misc/gatherAccidentals.py index c9de494..aced1a8 100644 --- a/music21_tools/misc/gatherAccidentals.py +++ b/music21_tools/misc/gatherAccidentals.py @@ -110,7 +110,7 @@ def getAccidentalCount(score, includeNonAccidentals=False, excludeZeros=True): ''' # check for non-streams if not score.isStream: - raise GatherAccidentalsException("Input score must be a music21.stream.Stream object") + raise GatherAccidentalsException('Input score must be a music21.stream.Stream object') notes = score.flatten().notes tally = _initializeTally() for obj in notes: @@ -152,7 +152,7 @@ def getAccidentalCountSum(scores, includeNonAccidentals=False, excludeZeros=True tally = _initializeTally() for score in scores: if not score.isStream: - raise exceptions21.Music21Exception("score must be a stream object") + raise exceptions21.Music21Exception('score must be a stream object') scoreTally = getAccidentalCount(score, includeNonAccidentals, False) # dict.update() won't suffice; list() for Python v3 for k in list(scoreTally.keys()): @@ -227,13 +227,13 @@ def testGetAccidentalCountBasic(self): def testGetAccidentalCountIntermediate(self): s = stream.Stream() - s.append(note.Note("C4")) # no accidental - s.append(note.Note("C#4")) # sharp - s.append(note.Note("D-4")) # flat + s.append(note.Note('C4')) # no accidental + s.append(note.Note('C#4')) # sharp + s.append(note.Note('D-4')) # flat self.assertEqual(getAccidentalCount(s), {'flat': 1, 'sharp': 1}) self.assertEqual(getAccidentalCount(s, True), {'flat': 1, 'sharp': 1, 'natural': 1}) - note4 = note.Note("C4") + note4 = note.Note('C4') self.assertIsNone(note4.pitch.accidental) note4.pitch.accidental = pitch.Accidental('natural') # add a natural accidental s.append(note4) @@ -280,7 +280,7 @@ def testAccidentalCountBachChorales(self): {'double-sharp': 4, 'flat': 7886, 'natural': 79869, 'sharp': 14940}) -if __name__ == "__main__": +if __name__ == '__main__': import music21 music21.mainTest(Test, 'moduleRelative') # replace 'Test' with 'TestSlow' to test it on all 371 Bach Chorales. diff --git a/music21_tools/misc/monteverdi.py b/music21_tools/misc/monteverdi.py index 98af791..f7650ea 100644 --- a/music21_tools/misc/monteverdi.py +++ b/music21_tools/misc/monteverdi.py @@ -47,12 +47,12 @@ def showAnalysis(book=3, madrigal= 3): print (minor) def analyzeBooks(books=(3,), start=1, end=20, show=False, strict=False): - majorFig = "" - minorFig = "" - majorSt = "" - minorSt = "" - majorRoot = "" - minorRoot = "" + majorFig = '' + minorFig = '' + majorSt = '' + minorSt = '' + majorRoot = '' + minorRoot = '' for book in books: for i in range(start, end + 1): filename = 'monteverdi/madrigal.%s.%s.rntxt' % (book, i) @@ -64,7 +64,7 @@ def analyzeBooks(books=(3,), start=1, end=20, show=False, strict=False): analysis = corpus.parse(filename) print(book,i) except Exception: - print("Cannot parse %s, maybe it does not exist..." % (filename)) + print('Cannot parse %s, maybe it does not exist...' % (filename)) continue if show == True: analysis.show() @@ -94,17 +94,17 @@ def iqChordsAndPercentage(analysisStream): ''' totalDuration = analysisStream.duration.quarterLength romMerged = analysisStream.flatten().stripTies() - major = "" - minor = "" + major = '' + minor = '' active = 'minor' for element in romMerged: - if "RomanNumeral" in element.classes: + if 'RomanNumeral' in element.classes: fig = element.figure fig = fig.replace('[no5]', '') fig = fig.replace('[no3]', '') fig = fig.replace('[no1]', '') - longString = fig + " (" + str(int( - element.duration.quarterLength * 10000 / totalDuration) / 100) + ") " + longString = fig + ' (' + str(int( + element.duration.quarterLength * 10000 / totalDuration) / 100) + ') ' if active == 'major': major += longString else: @@ -112,25 +112,25 @@ def iqChordsAndPercentage(analysisStream): elif hasattr(element, 'tonic'): if element.mode == 'major': active = 'major' - major += "\n" + element.tonic + " " + element.mode + " " + major += '\n' + element.tonic + ' ' + element.mode + ' ' else: active = 'minor' - minor += "\n" + element.tonic + " " + element.mode + " " + minor += '\n' + element.tonic + ' ' + element.mode + ' ' return (major, minor) def iqSemitonesAndPercentage(analysisStream): totalDuration = analysisStream.duration.quarterLength romMerged = analysisStream.flatten().stripTies() - major = "" - minor = "" + major = '' + minor = '' active = 'minor' for element in romMerged: - if "RomanNumeral" in element.classes: + if 'RomanNumeral' in element.classes: distanceToTonicInSemis = int((element.root().ps - pitch.Pitch(element.scale.tonic).ps) % 12) - longString = str(distanceToTonicInSemis) + " (" + str(int( + longString = str(distanceToTonicInSemis) + ' (' + str(int( element.duration.quarterLength * 10000 / totalDuration) - / 100) + ") " + / 100) + ') ' if active == 'major': major += longString else: @@ -138,20 +138,20 @@ def iqSemitonesAndPercentage(analysisStream): elif hasattr(element, 'tonic'): if element.mode == 'major': active = 'major' - major += "\n" + element.tonic + " " + element.mode + " " + major += '\n' + element.tonic + ' ' + element.mode + ' ' else: active = 'minor' - minor += "\n" + element.tonic + " " + element.mode + " " + minor += '\n' + element.tonic + ' ' + element.mode + ' ' return (major, minor) def iqRootsAndPercentage(analysisStream): totalDuration = analysisStream.duration.quarterLength romMerged = analysisStream.flatten().stripTies() - major = "" - minor = "" + major = '' + minor = '' active = 'minor' for element in romMerged: - if "RomanNumeral" in element.classes: + if 'RomanNumeral' in element.classes: #distanceToTonicInSemis = int((element.root().ps - # pitch.Pitch(element.scale.tonic).ps) % 12) elementLetter = str(element.root().name) @@ -168,20 +168,20 @@ def iqRootsAndPercentage(analysisStream): elementLetter = elementLetter.lower() else: pass - longString = elementLetter + " (" + str(int( + longString = elementLetter + ' (' + str(int( element.duration.quarterLength * 10000 / totalDuration) - / 100) + ") " + / 100) + ') ' if active == 'major': major += longString else: minor += longString - elif "Key" in element.classes: + elif 'Key' in element.classes: if element.mode == 'major': active = 'major' - major += "\n" + element.tonic + " " + element.mode + " " + major += '\n' + element.tonic + ' ' + element.mode + ' ' else: active = 'minor' - minor += "\n" + element.tonic + " " + element.mode + " " + minor += '\n' + element.tonic + ' ' + element.mode + ' ' return (major, minor) def monteverdiParallels(books=(3,), start=1, end=20, show=True, strict=False): @@ -199,7 +199,7 @@ def monteverdiParallels(books=(3,), start=1, end=20, show=True, strict=False): c = corpus.parse(filename) print (book,i) except: - print ("Cannot parse %s, maybe it does not exist..." % (filename)) + print ('Cannot parse %s, maybe it does not exist...' % (filename)) continue displayMe = False for i in range(len(c.parts) - 1): @@ -307,7 +307,7 @@ def findPhraseBoundaries(book=4, madrigal=12): print (thisOffset, psbo) relevantNote = flattenedBass.getElementAtOrBefore(thisOffset - 0.1) if hasattr(relevantNote, 'score'): - print ("adjusting score from %d to %d for note in measure %d" % ( + print ('adjusting score from %d to %d for note in measure %d' % ( relevantNote.score, relevantNote.score + psbo, relevantNote.measureNumber)) relevantNote.score += psbo else: diff --git a/music21_tools/theory/mgtaPart1.py b/music21_tools/theory/mgtaPart1.py index 2652561..a7c5ccf 100644 --- a/music21_tools/theory/mgtaPart1.py +++ b/music21_tools/theory/mgtaPart1.py @@ -67,11 +67,11 @@ def ch1_basic_I_B(show=True, *arguments, **keywords): n2 = note.Note(j) i1 = interval.notesToInterval(n1, n2) if i1.intervalClass == 1: # by interval class - unused_mark = "H" + unused_mark = 'H' elif i1.intervalClass == 2: - unused_mark = "W" + unused_mark = 'W' else: - unused_mark = "N" + unused_mark = 'N' # no keyboard diagram yet! # k1 = keyboard.Diagram() @@ -365,7 +365,7 @@ def ch1_writing_I_B_1(show=True, *arguments, **keywords): Transcribe these melodies into the clef specified without changing octaves. ''' # camptown races - ex = converter.parse("tinynotation: 2/4 g8 g e g", makeNotation=False) + ex = converter.parse('tinynotation: 2/4 g8 g e g', makeNotation=False) ex.insert(0, clef.AltoClef()) # maintain clef if show: ex.show() @@ -943,7 +943,7 @@ def ch2_writing_III_B_1(show=True, *arguments, **keywords): Renotate the following rhythms without ties. ''' - ex = converter.parse("tinynotation: 3/8 c8~ c16 c16 c16 c16 c8~ c8 c c16 c~ c c c8 c4~ c8") + ex = converter.parse('tinynotation: 3/8 c8~ c16 c16 c16 c16 c8~ c8 c c16 c~ c c c8 c4~ c8') ex = ch2_writing_III_B(ex) if show: @@ -955,7 +955,7 @@ def ch2_writing_III_B_1(show=True, *arguments, **keywords): def ch2_writing_III_B_2(show=True, *arguments, **keywords): '''p. 17 ''' - ex = converter.parse("tinynotation: 4/4 c4~ c8 c16 c c8 c~ c c c2~ c4 c8 c8 c8~ c16 c c8~ c16 c c2") + ex = converter.parse('tinynotation: 4/4 c4~ c8 c16 c c8 c~ c c c2~ c4 c8 c8 c8~ c16 c c8~ c16 c c2') ex = ch2_writing_III_B(ex) if show: @@ -967,7 +967,7 @@ def ch2_writing_III_B_2(show=True, *arguments, **keywords): def ch2_writing_III_B_3(show=True, *arguments, **keywords): '''p. 17 ''' - ex = converter.parse("tinynotation: 3/2 c2~ c4 c c~ c8 c c4 c~ c c c2 c2 c2~ c4 c c1~ c2") + ex = converter.parse('tinynotation: 3/2 c2~ c4 c c~ c8 c c4 c~ c c c2 c2 c2~ c4 c c1~ c2') ex = ch2_writing_III_B(ex) if show: @@ -1838,7 +1838,7 @@ def testBasic(self): # ------------------------------------------------------------------------------ -if __name__ == "__main__": +if __name__ == '__main__': #ch2_writing_III_A_1(show=True) if len(sys.argv) == 1: music21.mainTest(Test) diff --git a/music21_tools/theory/mgtaPart2.py b/music21_tools/theory/mgtaPart2.py index f8d2326..a2a8301 100755 --- a/music21_tools/theory/mgtaPart2.py +++ b/music21_tools/theory/mgtaPart2.py @@ -197,7 +197,7 @@ def test_Ch6_basic_II_B(self, *arguments, **keywords): -if __name__ == "__main__": +if __name__ == '__main__': import music21 import sys diff --git a/music21_tools/theoryAnalysis/__init__.py b/music21_tools/theoryAnalysis/__init__.py index ee3f05b..b4ff03a 100644 --- a/music21_tools/theoryAnalysis/__init__.py +++ b/music21_tools/theoryAnalysis/__init__.py @@ -1,5 +1,5 @@ -__all__ = ["theoryAnalyzer", "theoryResult", "wwnortonMGTA"] +__all__ = ['theoryAnalyzer', 'theoryResult', 'wwnortonMGTA'] # ----------------------------------------------------------------------------- diff --git a/music21_tools/theoryAnalysis/theoryAnalyzer.py b/music21_tools/theoryAnalysis/theoryAnalyzer.py index b58c235..ff4fe9e 100644 --- a/music21_tools/theoryAnalysis/theoryAnalyzer.py +++ b/music21_tools/theoryAnalysis/theoryAnalyzer.py @@ -975,15 +975,15 @@ def identifyParallelFifths(self, score, partNum1=None, partNum2=None, color=None 'Parallel fifth in measure 1: Part 1 moves from D to E while part 2 moves from G to A' ''' testFunction = lambda vlq: vlq.parallelFifth() - textFunction = lambda vlq, pn1, pn2: ("Parallel fifth in measure " + textFunction = lambda vlq, pn1, pn2: ('Parallel fifth in measure ' + str(vlq.v1n1.measureNumber) - + ": " - + "Part " + str(pn1 + 1) - + " moves from " + vlq.v1n1.name - + " to " + vlq.v1n2.name + " " - + "while part " + str(pn2 + 1) - + " moves from " + vlq.v2n1.name - + " to " + vlq.v2n2.name) + + ': ' + + 'Part ' + str(pn1 + 1) + + ' moves from ' + vlq.v1n1.name + + ' to ' + vlq.v1n2.name + ' ' + + 'while part ' + str(pn2 + 1) + + ' moves from ' + vlq.v2n1.name + + ' to ' + vlq.v2n2.name) self._identifyBasedOnVLQ(score, partNum1, partNum2, dictKey, testFunction, textFunction, color) @@ -1066,14 +1066,14 @@ def identifyParallelOctaves(self, score, partNum1=None, partNum2=None, ''' testFunction = lambda vlq: vlq.parallelOctave() - textFunction = lambda vlq, pn1, pn2: ("Parallel octave in measure " - + str(vlq.v1n1.measureNumber) + ": " - + "Part " + str(pn1 + 1) - + " moves from " + vlq.v1n1.name - + " to " + vlq.v1n2.name - + " while part " + str(pn2 + 1) - + " moves from " + vlq.v2n1.name - + " to " + vlq.v2n2.name) + textFunction = lambda vlq, pn1, pn2: ('Parallel octave in measure ' + + str(vlq.v1n1.measureNumber) + ': ' + + 'Part ' + str(pn1 + 1) + + ' moves from ' + vlq.v1n1.name + + ' to ' + vlq.v1n2.name + + ' while part ' + str(pn2 + 1) + + ' moves from ' + vlq.v2n1.name + + ' to ' + vlq.v2n2.name) self._identifyBasedOnVLQ(score, partNum1, partNum2, dictKey, testFunction, textFunction, color) @@ -1153,14 +1153,14 @@ def identifyParallelUnisons(self, score, partNum1=None, partNum2=None, color=Non ''' testFunction = lambda vlq: vlq.parallelUnison() - textFunction = lambda vlq, pn1, pn2: ("Parallel unison in measure " - + str(vlq.v1n1.measureNumber) + ": " - + "Part " + str(pn1 + 1) - + " moves from " + vlq.v1n1.name - + " to " + vlq.v1n2.name - + " while part " + str(pn2 + 1) - + " moves from " + vlq.v2n1.name - + " to " + vlq.v2n2.name) + textFunction = lambda vlq, pn1, pn2: ('Parallel unison in measure ' + + str(vlq.v1n1.measureNumber) + ': ' + + 'Part ' + str(pn1 + 1) + + ' moves from ' + vlq.v1n1.name + + ' to ' + vlq.v1n2.name + + ' while part ' + str(pn2 + 1) + + ' moves from ' + vlq.v2n1.name + + ' to ' + vlq.v2n2.name) self._identifyBasedOnVLQ(score, partNum1, partNum2, dictKey, testFunction, textFunction, color) @@ -1200,14 +1200,14 @@ def identifyHiddenFifths(self, score, partNum1=None, partNum2=None, ''' testFunction = lambda vlq: vlq.hiddenFifth() - textFunction = lambda vlq, pn1, pn2: ("Hidden fifth in measure " - + str(vlq.v1n1.measureNumber) +": " - + "Part " + str(pn1 + 1) - + " moves from " + vlq.v1n1.name - + " to " + vlq.v1n2.name - + " while part " + str(pn2 + 1) - + " moves from " + vlq.v2n1.name - + " to " + vlq.v2n2.name) + textFunction = lambda vlq, pn1, pn2: ('Hidden fifth in measure ' + + str(vlq.v1n1.measureNumber) +': ' + + 'Part ' + str(pn1 + 1) + + ' moves from ' + vlq.v1n1.name + + ' to ' + vlq.v1n2.name + + ' while part ' + str(pn2 + 1) + + ' moves from ' + vlq.v2n1.name + + ' to ' + vlq.v2n2.name) self._identifyBasedOnVLQ(score, partNum1, partNum2, dictKey, testFunction, textFunction, color) @@ -1247,14 +1247,14 @@ def identifyHiddenOctaves(self, score, partNum1=None, partNum2=None, color=None, ''' testFunction = lambda vlq: vlq.hiddenOctave() - textFunction = lambda vlq, pn1, pn2: ("Hidden octave in measure " - + str(vlq.v1n1.measureNumber) + ": " - + "Part " + str(pn1 + 1) - + " moves from " + vlq.v1n1.name - + " to " + vlq.v1n2.name - + " while part " + str(pn2 + 1) - + " moves from " + vlq.v2n1.name - + " to " + vlq.v2n2.name) + textFunction = lambda vlq, pn1, pn2: ('Hidden octave in measure ' + + str(vlq.v1n1.measureNumber) + ': ' + + 'Part ' + str(pn1 + 1) + + ' moves from ' + vlq.v1n1.name + + ' to ' + vlq.v1n2.name + + ' while part ' + str(pn2 + 1) + + ' moves from ' + vlq.v2n1.name + + ' to ' + vlq.v2n2.name) self._identifyBasedOnVLQ(score, partNum1, partNum2, dictKey, testFunction, textFunction, color) @@ -1295,14 +1295,14 @@ def identifyImproperResolutions(self, score, partNum1=None, partNum2=None, color editorialMarkList = [] #TODO: incorporate Jose's resolution rules into this method (italian6, etc.) testFunction = lambda vlq: not vlq.isProperResolution() - textFunction = lambda vlq, pn1, pn2: ("Improper resolution of " + + textFunction = lambda vlq, pn1, pn2: ('Improper resolution of ' + vlq.vIntervals[0].simpleNiceName + - " in measure " + str(vlq.v1n1.measureNumber) + ": " + - "Part " + str(pn1 + 1) + " moves from " + + ' in measure ' + str(vlq.v1n1.measureNumber) + ': ' + + 'Part ' + str(pn1 + 1) + ' moves from ' + vlq.v1n1.name + - " to " + vlq.v1n2.name + " " + - "while part " + str(pn2 + 1) + " moves from " + - vlq.v2n1.name + " to " + vlq.v2n2.name) + ' to ' + vlq.v1n2.name + ' ' + + 'while part ' + str(pn2 + 1) + ' moves from ' + + vlq.v2n1.name + ' to ' + vlq.v2n2.name) self._identifyBasedOnVLQ(score, partNum1, partNum2, dictKey, testFunction, textFunction, color, editorialDictKey='isImproperResolution', editorialValue=True, editorialMarkList=editorialMarkList) @@ -1344,14 +1344,14 @@ def identifyLeapNotSetWithStep(self, score, partNum1=None, partNum2=None, ''' testFunction = lambda vlq: vlq.leapNotSetWithStep() - textFunction = lambda vlq, pn1, pn2: ("Leap not set with step in measure " - + str(vlq.v1n1.measureNumber) + ": " - + "Part " + str(pn1 + 1) - + " moves from " + vlq.v1n1.name - + " to " + vlq.v1n2.name - + " while part " + str(pn2 + 1) - + " moves from " + vlq.v2n1.name - + " to " + vlq.v2n2.name) + textFunction = lambda vlq, pn1, pn2: ('Leap not set with step in measure ' + + str(vlq.v1n1.measureNumber) + ': ' + + 'Part ' + str(pn1 + 1) + + ' moves from ' + vlq.v1n1.name + + ' to ' + vlq.v1n2.name + + ' while part ' + str(pn2 + 1) + + ' moves from ' + vlq.v2n1.name + + ' to ' + vlq.v2n2.name) self._identifyBasedOnVLQ(score, partNum1, partNum2, dictKey, testFunction, textFunction, color) @@ -1387,7 +1387,7 @@ def identifyOpensIncorrectly(self, score, partNum1=None, partNum2=None, ''' testFunction = lambda vlq: vlq.opensIncorrectly() - textFunction = lambda vlq, pn1, pn2: "Opening harmony is not in style" + textFunction = lambda vlq, pn1, pn2: 'Opening harmony is not in style' self._identifyBasedOnVLQ(score, partNum1, partNum2, dictKey, testFunction, textFunction, color, startIndex = 0, endIndex = 1) @@ -1425,7 +1425,7 @@ def identifyClosesIncorrectly(self, score, partNum1=None, partNum2=None, color=N ''' testFunction = lambda vlq: vlq.closesIncorrectly() - textFunction = lambda vlq, pn1, pn2: "Closing harmony is not in style" + textFunction = lambda vlq, pn1, pn2: 'Closing harmony is not in style' self._identifyBasedOnVLQ(score, partNum1, partNum2, dictKey, testFunction, textFunction, color, startIndex=-1) @@ -1740,13 +1740,13 @@ def identifyDissonantHarmonicIntervals(self, score, partNum1=None, partNum2=None from F to B between part 1 and part 2' ''' testFunction = lambda hIntv: hIntv is not None and not hIntv.isConsonant() - textFunction = lambda hIntv, pn1, pn2: ("Dissonant harmonic interval in measure " - + str(hIntv.noteStart.measureNumber) + ": " - + str(hIntv.simpleNiceName) + " from " - + str(hIntv.noteStart.name) + " to " + textFunction = lambda hIntv, pn1, pn2: ('Dissonant harmonic interval in measure ' + + str(hIntv.noteStart.measureNumber) + ': ' + + str(hIntv.simpleNiceName) + ' from ' + + str(hIntv.noteStart.name) + ' to ' + str(hIntv.noteEnd.name) - + " between part " + str(pn1 + 1) - + " and part " + str(pn2 + 1)) + + ' between part ' + str(pn1 + 1) + + ' and part ' + str(pn2 + 1)) self._identifyBasedOnHarmonicInterval(score, partNum1, partNum2, color, dictKey, testFunction, textFunction) @@ -1813,12 +1813,12 @@ def identifyImproperDissonantIntervals(self, score, partNum1=None, partNum2=None intv = resultTheoryObject.intv tr = theoryResult.IntervalTheoryResult(intv) #tr.value = valueFunction(hIntv) - tr.text = ("Improper dissonant harmonic interval in measure " + - str(intv.noteStart.measureNumber) +": " + - str(intv.niceName) + " from " + str(intv.noteStart.name) + - " to " + str(intv.noteEnd.name) + - " between part " + str(partNum1 + 1) + - " and part " + str(partNum2 + 1)) + tr.text = ('Improper dissonant harmonic interval in measure ' + + str(intv.noteStart.measureNumber) +': ' + + str(intv.niceName) + ' from ' + str(intv.noteStart.name) + + ' to ' + str(intv.noteEnd.name) + + ' between part ' + str(partNum1 + 1) + + ' and part ' + str(partNum2 + 1)) if color is not None: tr.color(color) self._updateScoreResultDict(score, dictKey, tr) @@ -1861,11 +1861,11 @@ def identifyDissonantMelodicIntervals(self, score, partNum=None, color=None, ''' testFunction = lambda mIntv: mIntv is not None and mIntv.simpleName in [ - "A2", "A4", "d5", "m7", "M7"] - textFunction = lambda mIntv, pn: ("Dissonant melodic interval in part " + str(pn + 1) + - " measure " + str(mIntv.noteStart.measureNumber) +": " + - str(mIntv.simpleNiceName) + " from " + - str(mIntv.noteStart.name) + " to " + + 'A2', 'A4', 'd5', 'm7', 'M7'] + textFunction = lambda mIntv, pn: ('Dissonant melodic interval in part ' + str(pn + 1) + + ' measure ' + str(mIntv.noteStart.measureNumber) +': ' + + str(mIntv.simpleNiceName) + ' from ' + + str(mIntv.noteStart.name) + ' to ' + str(mIntv.noteEnd.name)) self._identifyBasedOnMelodicInterval(score, partNum, color, dictKey, testFunction, textFunction) @@ -1879,85 +1879,85 @@ def identifyDissonantMelodicIntervals(self, score, partNum=None, color=None, def identifyObliqueMotion(self, score, partNum1=None, partNum2=None, color=None): dictKey = 'obliqueMotion' testFunction = lambda vlq: vlq.obliqueMotion() - textFunction = lambda vlq, pn1, pn2: ("Oblique motion in measure " + - str(vlq.v1n1.measureNumber) +": " + - "Part " + str(pn1 + 1) + " moves from " + - vlq.v1n1.name + " to " + vlq.v1n2.name + " " + - "while part " + str(pn2 + 1) + " moves from " + - vlq.v2n1.name + " to " + vlq.v2n2.name) + textFunction = lambda vlq, pn1, pn2: ('Oblique motion in measure ' + + str(vlq.v1n1.measureNumber) +': ' + + 'Part ' + str(pn1 + 1) + ' moves from ' + + vlq.v1n1.name + ' to ' + vlq.v1n2.name + ' ' + + 'while part ' + str(pn2 + 1) + ' moves from ' + + vlq.v2n1.name + ' to ' + vlq.v2n2.name) self._identifyBasedOnVLQ(score, partNum1, partNum2, dictKey, testFunction, textFunction, color) def identifySimilarMotion(self, score, partNum1=None, partNum2=None, color=None): dictKey = 'similarMotion' testFunction = lambda vlq: vlq.similarMotion() - textFunction = lambda vlq, pn1, pn2: ("Similar motion in measure " + - str(vlq.v1n1.measureNumber) +": " + - "Part " + str(pn1 + 1) + " moves from " + - vlq.v1n1.name + " to " + vlq.v1n2.name + " " + - "while part " + str(pn2 + 1) + " moves from " + - vlq.v2n1.name+ " to " + vlq.v2n2.name) + textFunction = lambda vlq, pn1, pn2: ('Similar motion in measure ' + + str(vlq.v1n1.measureNumber) +': ' + + 'Part ' + str(pn1 + 1) + ' moves from ' + + vlq.v1n1.name + ' to ' + vlq.v1n2.name + ' ' + + 'while part ' + str(pn2 + 1) + ' moves from ' + + vlq.v2n1.name+ ' to ' + vlq.v2n2.name) self._identifyBasedOnVLQ(score, partNum1, partNum2, dictKey, testFunction, textFunction, color) def identifyParallelMotion(self, score, partNum1=None, partNum2=None, color= None): dictKey = 'parallelMotion' testFunction = lambda vlq: vlq.parallelMotion() - textFunction = lambda vlq, pn1, pn2: ("Parallel motion in measure " + - str(vlq.v1n1.measureNumber) +": " + - "Part " + str(pn1 + 1) + " moves from " + - vlq.v1n1.name + " to " + vlq.v1n2.name + " " + - "while part " + str(pn2 + 1) + " moves from " + - vlq.v2n1.name+ " to " + vlq.v2n2.name) + textFunction = lambda vlq, pn1, pn2: ('Parallel motion in measure ' + + str(vlq.v1n1.measureNumber) +': ' + + 'Part ' + str(pn1 + 1) + ' moves from ' + + vlq.v1n1.name + ' to ' + vlq.v1n2.name + ' ' + + 'while part ' + str(pn2 + 1) + ' moves from ' + + vlq.v2n1.name+ ' to ' + vlq.v2n2.name) self._identifyBasedOnVLQ(score, partNum1, partNum2, dictKey, testFunction, textFunction, color) def identifyContraryMotion(self, score, partNum1=None, partNum2=None, color=None): dictKey = 'contraryMotion' testFunction = lambda vlq: vlq.contraryMotion() - textFunction = lambda vlq, pn1, pn2: ("Contrary motion in measure " + - str(vlq.v1n1.measureNumber) + ": " + - "Part " + str(pn1 + 1) + " moves from " + - vlq.v1n1.name + " to " + vlq.v1n2.name + " " + - "while part " + str(pn2 + 1) + " moves from " + - vlq.v2n1.name+ " to " + vlq.v2n2.name) + textFunction = lambda vlq, pn1, pn2: ('Contrary motion in measure ' + + str(vlq.v1n1.measureNumber) + ': ' + + 'Part ' + str(pn1 + 1) + ' moves from ' + + vlq.v1n1.name + ' to ' + vlq.v1n2.name + ' ' + + 'while part ' + str(pn2 + 1) + ' moves from ' + + vlq.v2n1.name+ ' to ' + vlq.v2n2.name) self._identifyBasedOnVLQ(score, partNum1, partNum2, dictKey, testFunction, textFunction, color) def identifyOutwardContraryMotion(self, score, partNum1=None, partNum2=None, color=None): dictKey = 'outwardContraryMotion' testFunction = lambda vlq: vlq.outwardContraryMotion() - textFunction = lambda vlq, pn1, pn2: ("Outward contrary motion in measure " + - str(vlq.v1n1.measureNumber) + ": " + - "Part " + str(pn1 + 1) + " moves from " + - vlq.v1n1.name + " to " + - vlq.v1n2.name + " " + - "while part " + str(pn2 + 1) + " moves from " + - vlq.v2n1.name+ " to " + vlq.v2n2.name) + textFunction = lambda vlq, pn1, pn2: ('Outward contrary motion in measure ' + + str(vlq.v1n1.measureNumber) + ': ' + + 'Part ' + str(pn1 + 1) + ' moves from ' + + vlq.v1n1.name + ' to ' + + vlq.v1n2.name + ' ' + + 'while part ' + str(pn2 + 1) + ' moves from ' + + vlq.v2n1.name+ ' to ' + vlq.v2n2.name) self._identifyBasedOnVLQ(score, partNum1, partNum2, dictKey, testFunction, textFunction, color) def identifyInwardContraryMotion(self, score, partNum1=None, partNum2=None, color=None): dictKey = 'inwardContraryMotion' testFunction = lambda vlq: vlq.inwardContraryMotion() - textFunction = lambda vlq, pn1, pn2: ("Inward contrary motion in measure " + - str(vlq.v1n1.measureNumber) + ": " + - "Part " + str(pn1 + 1) + " moves from " + - vlq.v1n1.name + " to " + vlq.v1n2.name + " " + - "while part " + str(pn2 + 1) + " moves from " + - vlq.v2n1.name+ " to " + vlq.v2n2.name) + textFunction = lambda vlq, pn1, pn2: ('Inward contrary motion in measure ' + + str(vlq.v1n1.measureNumber) + ': ' + + 'Part ' + str(pn1 + 1) + ' moves from ' + + vlq.v1n1.name + ' to ' + vlq.v1n2.name + ' ' + + 'while part ' + str(pn2 + 1) + ' moves from ' + + vlq.v2n1.name+ ' to ' + vlq.v2n2.name) self._identifyBasedOnVLQ(score, partNum1, partNum2, color, dictKey, testFunction, textFunction) def identifyAntiParallelMotion(self, score, partNum1=None, partNum2=None, color=None): dictKey = 'antiParallelMotion' testFunction = lambda vlq: vlq.antiParallelMotion() - textFunction = lambda vlq, pn1, pn2: ("Anti-parallel motion in measure " + - str(vlq.v1n1.measureNumber) +": " + - "Part " + str(pn1 + 1) + " moves from " + - vlq.v1n1.name + " to " + vlq.v1n2.name + " " + - "while part " + str(pn2 + 1) + " moves from " + - vlq.v2n1.name+ " to " + vlq.v2n2.name) + textFunction = lambda vlq, pn1, pn2: ('Anti-parallel motion in measure ' + + str(vlq.v1n1.measureNumber) +': ' + + 'Part ' + str(pn1 + 1) + ' moves from ' + + vlq.v1n1.name + ' to ' + vlq.v1n2.name + ' ' + + 'while part ' + str(pn2 + 1) + ' moves from ' + + vlq.v2n1.name+ ' to ' + vlq.v2n2.name) self._identifyBasedOnVLQ(score, partNum1, partNum2, dictKey, testFunction, textFunction, color) @@ -2020,7 +2020,7 @@ def textFunction(vs, rn): for n in vs.getObjectsByClass('Note'): notes += n.name + ',' notes = notes[:-1] - return "Roman Numeral of " + notes + ' is ' + rn + return 'Roman Numeral of ' + notes + ' is ' + rn self._identifyBasedOnVerticality(score, color, dictKey, testFunction, textFunction, responseOffsetMap=responseOffsetMap) @@ -2108,7 +2108,7 @@ def identifyHarmonicIntervals(self, score, partNum1=None, partNum2=None, ''' testFunction = lambda hIntv: hIntv.generic.undirected if hIntv is not None else False - textFunction = lambda hIntv, pn1, pn2: ("harmonic interval between " + textFunction = lambda hIntv, pn1, pn2: ('harmonic interval between ' + hIntv.noteStart.name + ' and ' + hIntv.noteEnd.name + ' between parts ' + str(pn1 + 1) + ' and ' + str(pn2 + 1) + ' is a ' + str(hIntv.niceName)) @@ -2160,7 +2160,7 @@ def identifyScaleDegrees(self, score, partNum=None, color=None, dictKey='scaleDe testFunction = lambda sc, n: (str(self.getKeyAtMeasure(sc, n.measureNumber).getScale().getScaleDegreeFromPitch( n.pitch)) ) if n is not None else False - textFunction = lambda n, pn, scaleDegree: ("scale degree of " + n.name + ' in part ' + + textFunction = lambda n, pn, scaleDegree: ('scale degree of ' + n.name + ' in part ' + str(pn + 1) + ' is ' + str(scaleDegree)) self._identifyBasedOnNote(score, partNum, color, dictKey, testFunction, textFunction) @@ -2208,12 +2208,12 @@ def identifyMotionType(self, score, partNum1=None, partNum2=None, testFunction = lambda vlq: vlq.motionType().value textFunction = lambda vlq, pn1, pn2: (vlq.motionType().value + ' Motion in measure '+ - str(vlq.v1n1.measureNumber) + ": " + - "Part " + str(pn1 + 1) + " moves from " + - vlq.v1n1.name + " to " + vlq.v1n2.name + " " + - "while part " + str(pn2 + 1) + " moves from " + - vlq.v2n1.name+ " to " + vlq.v2n2.name) if ( - vlq.motionType() != "No Motion") else 'No motion' + str(vlq.v1n1.measureNumber) + ': ' + + 'Part ' + str(pn1 + 1) + ' moves from ' + + vlq.v1n1.name + ' to ' + vlq.v1n2.name + ' ' + + 'while part ' + str(pn2 + 1) + ' moves from ' + + vlq.v2n1.name+ ' to ' + vlq.v2n2.name) if ( + vlq.motionType() != 'No Motion') else 'No motion' self._identifyBasedOnVLQ(score, partNum1, partNum2, dictKey, testFunction, textFunction, color) @@ -2281,16 +2281,16 @@ def getResultsString(self, score, typeList=None): Hidden fifth in measure 1: Part 1 moves from C to D while part 2 moves from C to G Closing harmony is not in style ''' - resultStr = "" + resultStr = '' sid = score.id self.addAnalysisData(score) for resultType in self.store[sid]['ResultDict']: if typeList is None or resultType in typeList: - resultStr += resultType + ": \n" + resultStr += resultType + ': \n' for result in self.store[sid]['ResultDict'][resultType]: resultStr += result.text - resultStr += "\n" + resultStr += '\n' resultStr = resultStr[0:-1] #remove final new line character return resultStr @@ -2299,18 +2299,18 @@ def getHTMLResultsString(self, score, typeList=None): returns string of all results found by calling all identify methods on the TheoryAnalyzer score ''' - resultStr = "" + resultStr = '' sid = score.id self.addAnalysisData(score) for resultType in self.store[sid]['ResultDict']: if typeList is None or resultType in typeList: - resultStr += "" + resultType + ":

' return resultStr @@ -2519,6 +2519,6 @@ def removeNHTones(self): ads.removeNeighborTones(p) p.show() -if __name__ == "__main__": +if __name__ == '__main__': import music21 music21.mainTest(Test, 'moduleRelative') #, runTest='testFastVerticalityCheck') diff --git a/music21_tools/theoryAnalysis/theoryResult.py b/music21_tools/theoryAnalysis/theoryResult.py index 0d653e8..456ffb6 100644 --- a/music21_tools/theoryAnalysis/theoryResult.py +++ b/music21_tools/theoryAnalysis/theoryResult.py @@ -26,9 +26,9 @@ class TheoryResult: 'currentColor': 'The color of the entire theory result object', } def __init__(self): - self.text = "" - self.value = "" - self.currentColor = "" + self.text = '' + self.value = '' + self.currentColor = '' def color(self,color): ''' @@ -294,7 +294,7 @@ def demo(self): pass -if __name__ == "__main__": +if __name__ == '__main__': import music21 music21.mainTest(Test, 'moduleRelative') diff --git a/music21_tools/theoryAnalysis/wwnortonMGTA.py b/music21_tools/theoryAnalysis/wwnortonMGTA.py index 4406dd8..9364e3a 100644 --- a/music21_tools/theoryAnalysis/wwnortonMGTA.py +++ b/music21_tools/theoryAnalysis/wwnortonMGTA.py @@ -34,13 +34,13 @@ class wwnortonExercise: ''' def __init__(self): - self.xmlFileDirectory = "C:/Users/bhadley/Dropbox/Music21Theory/TestFiles/Exercises/" + self.xmlFileDirectory = 'C:/Users/bhadley/Dropbox/Music21Theory/TestFiles/Exercises/' #/xmlfiles/" - self.xmlFilename = "" + self.xmlFilename = '' self.originalExercise = stream.Stream() self.modifiedExercise = stream.Stream() self.studentExercise = stream.Stream() - self.textResultString = "" + self.textResultString = '' self.pn = {} self.ads = theoryAnalyzer.Analyzer() @@ -83,21 +83,21 @@ def _updatepn(self, newPartNum, direction): existingPartNum = self.pn[partName] if existingPartNum > newPartNum: shiftedPartNum = existingPartNum + 1 - elif existingPartNum == newPartNum and direction =="above": + elif existingPartNum == newPartNum and direction =='above': shiftedPartNum = existingPartNum + 1 else: shiftedPartNum = existingPartNum self.pn[partName] = shiftedPartNum - def addMarkerPartFromExisting(self, existingPartName, newPartName, newPartTitle="", - direction="below", rhythmType="copy", color=None): + def addMarkerPartFromExisting(self, existingPartName, newPartName, newPartTitle='', + direction='below', rhythmType='copy', color=None): partNum = self.pn[existingPartName] self._partOffsetsToPartIndecies() existingPart = self.modifiedExercise.parts[partNum] existingPartOffset = existingPart.offset - if rhythmType == "chordify": + if rhythmType == 'chordify': existingPart = self.originalExercise.chordify() newPart = copy.deepcopy(existingPart.getElementsByClass('Measure')) firstNote = True @@ -114,7 +114,7 @@ def addMarkerPartFromExisting(self, existingPartName, newPartName, newPartTitle= m.removeByClass(['Expression']) m.removeByClass(['KeySignature']) - if rhythmType == "quarterNotes": + if rhythmType == 'quarterNotes': for i in range(int(measureDuration)): markerNote = note.Note('c4') markerNote.notehead = 'x' @@ -142,13 +142,13 @@ def addMarkerPartFromExisting(self, existingPartName, newPartName, newPartTitle= for ks in newPart.flatten().getElementsByClass('KeySignature'): ks.sharps = 0 for c in newPart.flatten().getElementsByClass('Clef'): - c.sign = "C" + c.sign = 'C' c.line = 3 self._updatepn(partNum,direction=direction) - if direction == "above": + if direction == 'above': insertLoc = existingPartOffset - 0.5 self.pn[newPartName] = partNum - elif direction == "below" or direction is None: + elif direction == 'below' or direction is None: insertLoc = existingPartOffset + 0.5 self.pn[newPartName] = partNum + 1 self.modifiedExercise.insert(insertLoc,newPart) @@ -165,7 +165,7 @@ def compareMarkerLyricAnswer(self, score, taKey, markerPartName, offsetFunc, lyr correctLyric = lyricFunc(resultObj) markerNote = markerPart.flatten().getElementAtOrBefore(offset, classList=['Note']) if markerNote is None or markerNote.offset != offset: - print("No Marker") + print('No Marker') continue if markerNote.lyric != str(correctLyric): #markerNote.lyric = markerNote.lyric + "->" + str(correctLyric) @@ -194,18 +194,18 @@ def __init__(self): def addAuxillaryParts(self): self.addMarkerPartFromExisting('part1', newPartName='p1ScaleDegrees', - newPartTitle="1. Scale Degrees", - direction="above") + newPartTitle='1. Scale Degrees', + direction='above') self.addMarkerPartFromExisting('part1', newPartName='motionType', - newPartTitle="2. Motion Type", - rhythmType="quarterNotes", - direction="above") + newPartTitle='2. Motion Type', + rhythmType='quarterNotes', + direction='above') self.addMarkerPartFromExisting('part1', newPartName='harmIntervals', - newPartTitle="3. Harmonic Intervals", + newPartTitle='3. Harmonic Intervals', rhythmType='chordify', - direction="below") + direction='below') def checkExercise(self): self.ads.setKeyMeasureMap(self.studentExercise,{0:'F'}) @@ -258,8 +258,8 @@ def __init__(self): def addAuxillaryParts(self): self.addMarkerPartFromExisting('part2', newPartName='harmIntervals', - newPartTitle="1. Harmonic Intervals", - direction = "below") + newPartTitle='1. Harmonic Intervals', + direction = 'below') def checkExercise(self): self.ads.setKeyMeasureMap(self.studentExercise, {0:'G', 5:'D', 8:'F'}) @@ -303,7 +303,7 @@ def demo(self): ex.showStudentExercise() -if __name__ == "__main__": +if __name__ == '__main__': music21.mainTest(Test) #te = TestExternal() diff --git a/music21_tools/trecento/cadenceProbabilities.py b/music21_tools/trecento/cadenceProbabilities.py index 51d83f9..8a51c70 100644 --- a/music21_tools/trecento/cadenceProbabilities.py +++ b/music21_tools/trecento/cadenceProbabilities.py @@ -22,16 +22,16 @@ def getLandiniRandomStart(i): '''according to distribution of starting tenor notes of Landini cadences''' if i < 16: - return "A" + return 'A' if i < 35: - return "C" + return 'C' if i < 67: - return "D" + return 'D' if i < 69: - return "E" + return 'E' if i < 85: - return "F" - return "G" + return 'F' + return 'G' # def findsame(total=1000): # '''find out how often the first note and second note should be the same @@ -90,17 +90,17 @@ def countCadencePercentages(): firstNoteTotal[firstNote.name] += 1 lastNoteTotal[lastNote.name] += 1 - print("First note distribution:") + print('First note distribution:') for thisName in firstNoteTotal: print(thisName, firstNoteTotal[thisName] / totalPieces) - print("Last note distribution:") + print('Last note distribution:') for thisName in lastNoteTotal: print(thisName, lastNoteTotal[thisName] / totalPieces) -if __name__ == "__main__": +if __name__ == '__main__': countCadencePercentages() # ----------------------------------------------------------------------------- diff --git a/music21_tools/trecento/cadencebook.py b/music21_tools/trecento/cadencebook.py index a0c5a80..227a0e4 100644 --- a/music21_tools/trecento/cadencebook.py +++ b/music21_tools/trecento/cadencebook.py @@ -48,13 +48,13 @@ class TrecentoSheet: Kyrie rondello ''' - filename = "cadences.xls" - sheetname = "fischer_caccia" + filename = 'cadences.xls' + sheetname = 'fischer_caccia' def __init__(self, **keywords): self.iterIndex = 2 - if "filename" in keywords: - self.filename = keywords["filename"] + if 'filename' in keywords: + self.filename = keywords['filename'] if self.filename: try: xbook = xlrd.open_workbook(str(self.filename)) @@ -62,8 +62,8 @@ def __init__(self, **keywords): xbook = xlrd.open_workbook(os.path.join(_THIS_DIR, self.filename)) - if "sheetname" in keywords: - self.sheetname = keywords["sheetname"] + if 'sheetname' in keywords: + self.sheetname = keywords['sheetname'] self.sheet = xbook.sheet_by_name(self.sheetname) self.totalRows = self.sheet.nrows @@ -171,7 +171,7 @@ class CacciaSheet(TrecentoSheet): >>> cacciaSheet = CacciaSheet() ''' - sheetname = "fischer_caccia" + sheetname = 'fischer_caccia' class MadrigalSheet(TrecentoSheet): ''' @@ -183,7 +183,7 @@ class MadrigalSheet(TrecentoSheet): ''' - sheetname = "fischer_madr" + sheetname = 'fischer_madr' class BallataSheet(TrecentoSheet): ''' @@ -194,14 +194,14 @@ class BallataSheet(TrecentoSheet): ''' - sheetname = "fischer_ballata" + sheetname = 'fischer_ballata' def makeWork(self, rownumber=1): rowvalues = self.sheet.row_values(rownumber - 1) return Ballata(rowvalues, self.rowDescriptions) class KyrieSheet(TrecentoSheet): - sheetname = "kyrie" + sheetname = 'kyrie' class GloriaSheet(TrecentoSheet): @@ -252,18 +252,18 @@ class GloriaSheet(TrecentoSheet): ''' - sheetname = "gloria" + sheetname = 'gloria' def makeWork(self, rownumber=1): rowvalues = self.sheet.row_values(rownumber - 1) return Gloria(rowvalues, self.rowDescriptions) class CredoSheet(TrecentoSheet): - sheetname = "credo" + sheetname = 'credo' class SanctusSheet(TrecentoSheet): - sheetname = "sanctus" + sheetname = 'sanctus' class AgnusDeiSheet(TrecentoSheet): - sheetname = "agnus" + sheetname = 'agnus' class TrecentoCadenceWork: ''' @@ -306,12 +306,12 @@ class TrecentoCadenceWork: def __init__(self, rowvalues=None, rowDescriptions=None): if rowvalues is None: - rowvalues = ["", "", "", "", "", "", "", "", "", "", "", "", ""] + rowvalues = ['', '', '', '', '', '', '', '', '', '', '', '', ''] if rowDescriptions is None: - rowDescriptions = ["Catalog Number", "Title", "Composer", "EncodedVoices", - "PMFC/CMM Vol.", "PMFC Page Start", "PMFC Page End", - "Time Signature Beginning", "Incipit C", "Incipit T", - "Incipit Ct", "Incipit Type", "Notes"] + rowDescriptions = ['Catalog Number', 'Title', 'Composer', 'EncodedVoices', + 'PMFC/CMM Vol.', 'PMFC Page Start', 'PMFC Page End', + 'Time Signature Beginning', 'Incipit C', 'Incipit T', + 'Incipit Ct', 'Incipit Type', 'Notes'] self.rowvalues = rowvalues self.rowDescriptions = rowDescriptions self.fischerNum = rowvalues[0] @@ -348,7 +348,7 @@ def __init__(self, rowvalues=None, rowDescriptions=None): else: self.totalPmfcPage = None - if self.composer == ".": + if self.composer == '.': self.isAnonymous = True else: self.isAnonymous = False @@ -393,7 +393,7 @@ def asOpus(self): for partNumber, snippetPart in enumerate( thisSnippet.getElementsByClass('TrecentoCadenceStream')): - if thisSnippet.snippetName != "" and partNumber == self.totalVoices - 1: + if thisSnippet.snippetName != '' and partNumber == self.totalVoices - 1: textEx = expressions.TextExpression(thisSnippet.snippetName) textEx.style.absoluteY = 'below' if 'FrontPaddedSnippet' in thisSnippet.classes: @@ -458,7 +458,7 @@ def asScore(self): thisSnippet.contratenor is None): continue for partNumber, snippetPart in enumerate(thisSnippet.getElementsByClass('Stream')): - if thisSnippet.snippetName != "" and partNumber == self.totalVoices - 1: + if thisSnippet.snippetName != '' and partNumber == self.totalVoices - 1: textEx = expressions.TextExpression(thisSnippet.snippetName) textEx.style.absoluteY = 'below' if 'FrontPaddedSnippet' in thisSnippet.classes: @@ -505,7 +505,7 @@ def incipit(self): ''' rowBlock = self.rowvalues[8:12] rowBlock.append(self.rowvalues[7]) - if rowBlock[0] == "" or self.timeSigBegin == "": + if rowBlock[0] == '' or self.timeSigBegin == '': return None else: blockOut = self.convertBlockToStreams(rowBlock) @@ -535,14 +535,14 @@ def getOtherSnippets(self): for i in beginSnippetPositions: if i == beginSnippetPositions[0]: continue - thisSnippet = self.getSnippetAtPosition(i, snippetType="begin") + thisSnippet = self.getSnippetAtPosition(i, snippetType='begin') if thisSnippet is not None: thisSnippet.snippetName = self.rowDescriptions[i] thisSnippet.snippetName = re.sub(r'cad\b', 'cadence', thisSnippet.snippetName) thisSnippet.snippetName = re.sub(r'\s*C$', '', thisSnippet.snippetName) returnSnips.append(thisSnippet) for i in endSnippetPositions: - thisSnippet = self.getSnippetAtPosition(i, snippetType="end") + thisSnippet = self.getSnippetAtPosition(i, snippetType='end') if thisSnippet is not None: thisSnippet.snippetName = self.rowDescriptions[i] thisSnippet.snippetName = re.sub('cad ', 'cadence ', thisSnippet.snippetName) @@ -550,7 +550,7 @@ def getOtherSnippets(self): returnSnips.append(thisSnippet) return returnSnips - def getSnippetAtPosition(self, snippetPosition, snippetType="end"): + def getSnippetAtPosition(self, snippetPosition, snippetType='end'): ''' gets a "snippet" which is a collection of up to 3 lines of music, a timeSignature and a description of the cadence. @@ -562,10 +562,10 @@ def getSnippetAtPosition(self, snippetPosition, snippetType="end"): ''' - if self.rowvalues[snippetPosition].strip() != "": + if self.rowvalues[snippetPosition].strip() != '': thisBlock = self.rowvalues[snippetPosition:snippetPosition + 5] - if thisBlock[4].strip() == "": - if self.timeSigBegin == "": + if thisBlock[4].strip() == '': + if self.timeSigBegin == '': return None # need a timesig thisBlock[4] = self.timeSigBegin blockOut = self.convertBlockToStreams(thisBlock) @@ -615,10 +615,10 @@ def convertBlockToStreams(self, thisBlock): thisVoice = thisVoice.strip() if thisVoice: try: - returnBlock[i] = trecentoCadence.CadenceConverter(currentTimeSig + " " + + returnBlock[i] = trecentoCadence.CadenceConverter(currentTimeSig + ' ' + thisVoice).parse().stream except duration.DurationException as value: - raise duration.DurationException("Problems in line %s: specifically %s" % + raise duration.DurationException('Problems in line %s: specifically %s' % (thisVoice, value)) # except Exception, (value): # raise Exception("Unknown Problems in line %s: specifically %s" % @@ -646,7 +646,7 @@ def cadenceA(self): except IndexError: return None if fc is not None: - fc.snippetName = "A section cadence" + fc.snippetName = 'A section cadence' return fc @property @@ -660,7 +660,7 @@ def cadenceB(self): except IndexError: return None if fc is not None: - fc.snippetName = "B section cadence (1st or only ending)" + fc.snippetName = 'B section cadence (1st or only ending)' return fc @property @@ -673,7 +673,7 @@ def cadenceBClos(self): except IndexError: return None if fc is not None: - fc.snippetName = "B section cadence (2nd ending)" + fc.snippetName = 'B section cadence (2nd ending)' return fc def getAllStreams(self): @@ -713,9 +713,9 @@ def pmfcPageRange(self): ''' if self.pmfcPageStart != self.pmfcPageEnd: - return str("pp. " + str(self.pmfcPageStart) + "-" + str(self.pmfcPageEnd)) + return str('pp. ' + str(self.pmfcPageStart) + '-' + str(self.pmfcPageEnd)) else: - return str("p. " + str(self.pmfcPageStart)) + return str('p. ' + str(self.pmfcPageStart)) class Ballata(TrecentoCadenceWork): @@ -812,7 +812,7 @@ def xtestVirelais(self): ''' virelaisSheet = TrecentoSheet(sheetname='virelais') thisVirelai = virelaisSheet.makeWork(54) - if thisVirelai.title != "": + if thisVirelai.title != '': print(thisVirelai.title) thisVirelai.incipit.show('musicxml') @@ -822,7 +822,7 @@ def xtestRondeaux(self): ''' rondeauxSheet = TrecentoSheet(sheetname='rondeaux') thisRondeaux = rondeauxSheet.makeWork(41) - if thisRondeaux.title != "": + if thisRondeaux.title != '': print(thisRondeaux.title) thisRondeaux.incipit.show('musicxml') @@ -832,7 +832,7 @@ def xtestGloria(self): ''' gloriaS = GloriaSheet() thisGloria = gloriaS.makeWork(20) - if thisGloria.title != "": + if thisGloria.title != '': thisGloria.asScore().show() def xtestAsScore(self): @@ -845,7 +845,7 @@ def xtestAsScore(self): pass -if __name__ == "__main__": +if __name__ == '__main__': import music21 music21.mainTest(Test, 'importPlusRelative') # , TestExternal) diff --git a/music21_tools/trecento/findSevs.py b/music21_tools/trecento/findSevs.py index a55571e..b83fda0 100644 --- a/music21_tools/trecento/findSevs.py +++ b/music21_tools/trecento/findSevs.py @@ -46,7 +46,7 @@ def findInWork(work, searchInterval=7): # interval.note2.style.color = "blue" return containsInterval -if __name__ == "__main__": +if __name__ == '__main__': find(2, 459, ) # ----------------------------------------------------------------------------- diff --git a/music21_tools/trecento/findTrecentoFragments.py b/music21_tools/trecento/findTrecentoFragments.py index 78effe2..8cc2397 100644 --- a/music21_tools/trecento/findTrecentoFragments.py +++ b/music21_tools/trecento/findTrecentoFragments.py @@ -48,7 +48,7 @@ def compareToStream(self, cmpStream): else: for colorNote in range(i, i + self.intervalLength): # does not exactly work because of rests, oh well - cmpStream.notesAndRests[colorNote].style.color = "blue" + cmpStream.notesAndRests[colorNote].style.color = 'blue' return True return False @@ -74,7 +74,7 @@ def compareToStream(self, cmpStream): break else: # success! for colorNote in range(i, self.noteLength): - sN[colorNote].style.color = "blue" + sN[colorNote].style.color = 'blue' return True return False @@ -90,7 +90,7 @@ def searchForNotes(notesStr): noteObjArr = [] for tN in notesArr: tNName = tN[0] - if tNName.lower() != "r": + if tNName.lower() != 'r': tNObj = note.Note() tNObj.name = tN[0] tNObj.octave = int(tN[1]) @@ -112,19 +112,19 @@ def searchForNotes(notesStr): def colorFound(searcher1, thisCadence, streamOpus, thisWork, i): if searcher1.compareToStream(thisCadence.parts[i].flatten()) is True: - notesStr = "" + notesStr = '' for thisNote in thisCadence.parts[i].flatten().notesAndRests: # thisNote.style.color = "blue" if thisNote.isRest is False: - notesStr += thisNote.nameWithOctave + " " + notesStr += thisNote.nameWithOctave + ' ' else: - notesStr += "r " + notesStr += 'r ' streamOpus.insert(0, thisCadence) # streamLily += ("\\score {" + # "<< \\time " + str(thisCadence.timeSig) + # "\n \\new Staff {" + str(thisCadence.parts[i].lily) + "} >>" + # thisCadence.header() + "\n}\n") - print("In piece %r found in stream %d: %s" % (thisWork.title, i, notesStr)) + print('In piece %r found in stream %d: %s' % (thisWork.title, i, notesStr)) def searchForIntervals(notesStr): ''' @@ -163,14 +163,14 @@ def searchForIntervals(notesStr): streamOpus.show('lily.png') def findRandomVerona(): - searchForNotes("A4 F4 G4 E4 F4 G4") # p. 4 cadence 1 - searchForNotes("F4 G4 A4 G4 A4 F4 G4 A4") # p. 4 incipit 2 + searchForNotes('A4 F4 G4 E4 F4 G4') # p. 4 cadence 1 + searchForNotes('F4 G4 A4 G4 A4 F4 G4 A4') # p. 4 incipit 2 def findCasanatense522(): - searchForIntervals("D4 E4 D4 C4 D4 E4 F4") + searchForIntervals('D4 E4 D4 C4 D4 E4 F4') def findRavi3ORegina(): - searchForNotes("G16 G16 F8 E16") # should be cadence A, cantus + searchForNotes('G16 G16 F8 E16') # should be cadence A, cantus def searchForVat1969(): @@ -230,7 +230,7 @@ def audioVirelaiSearch(): virelaiCantuses = [] for i in range(2, 54): thisVirelai = virelaisSheet.makeWork(i) - if thisVirelai.title != "": + if thisVirelai.title != '': try: vc = thisVirelai.incipit.getElementsByClass('Part')[0] vc.insert(0, metadata.Metadata(title=thisVirelai.title)) @@ -263,7 +263,7 @@ def savedSearches(): # searchForNotes("G3 D3 R D3 D3 E3 F3") # Donna si to fallito TEST - last note = F# # searchForIntervals("F3 C3 C3 F3 G3") # Bologna Archivio: Per seguirla TEST # searchForNotes("F3 E3 F3 G3 F3 E3") # Mons archive fragment -- see FB Aetas Aurea post - searchForNotes("F4 G4 F4 B4 G4 A4 G4 F4 E4") # or B-4. Paris 25406 -- + searchForNotes('F4 G4 F4 B4 G4 A4 G4 F4 E4') # or B-4. Paris 25406 -- # Dominique Gatte pen tests # searchForNotes("D4 D4 C4 D4") # Fortuna Rira Seville 25 TEST! CANNOT FIND @@ -287,7 +287,7 @@ def savedSearches(): # -- possible contrafact -- no matches # searchForIntervals("F4 A4 F4 G4 F4 G4 A4") # Duke white notation manuscript -if __name__ == "__main__": +if __name__ == '__main__': savedSearches() # audioVirelaiSearch() diff --git a/music21_tools/trecento/find_vatican1790.py b/music21_tools/trecento/find_vatican1790.py index e722e2f..4ca2f5e 100644 --- a/music21_tools/trecento/find_vatican1790.py +++ b/music21_tools/trecento/find_vatican1790.py @@ -22,14 +22,14 @@ def find(): for ballata in ballatas: if i > 10: break - if ballata.timeSigBegin == "6/8" or ballata.timeSigBegin == "9/8": + if ballata.timeSigBegin == '6/8' or ballata.timeSigBegin == '9/8': incipit = ballata.incipit if incipit is not None: i += 1 opus.insert(0, incipit) opus.show('lily.pdf') -if __name__ == "__main__": +if __name__ == '__main__': find() # ----------------------------------------------------------------------------- diff --git a/music21_tools/trecento/largestAmbitus.py b/music21_tools/trecento/largestAmbitus.py index a05a814..3689926 100644 --- a/music21_tools/trecento/largestAmbitus.py +++ b/music21_tools/trecento/largestAmbitus.py @@ -31,7 +31,7 @@ def main(): ambi = p.analyze('ambitus') distance = ambi.diatonic.generic.undirected if distance >= 15: - print("************ GOT ONE!: {0} ************".format(ambi)) + print('************ GOT ONE!: {0} ************'.format(ambi)) elif distance >= 9: print(ambi) else: @@ -42,7 +42,7 @@ def main(): _DOC_ORDER = [] -if __name__ == "__main__": +if __name__ == '__main__': main() # ----------------------------------------------------------------------------- diff --git a/music21_tools/trecento/medren.py b/music21_tools/trecento/medren.py index c6b513b..2100332 100644 --- a/music21_tools/trecento/medren.py +++ b/music21_tools/trecento/medren.py @@ -1783,9 +1783,9 @@ def isHigherInhierarchy(l, u): if uclass0 is None: - raise MedRenException("Cannot find class in our hierarchy of streams: %s" % (u)) + raise MedRenException('Cannot find class in our hierarchy of streams: %s' % (u)) if lclass0 is None: - raise MedRenException("Cannot find class in our hierarchy of streams: %s" % (l)) + raise MedRenException('Cannot find class in our hierarchy of streams: %s' % (l)) if hierarchy.index(uclass0) == 0: return False @@ -1957,7 +1957,7 @@ def transferTies(score, *, inPlace=False): if tupAct != 0: # error... tempTuplet = duration.Tuplet(tupAct, tupNorm, copy.deepcopy(tempDuration.components[0])) - tempTuplet.tupletActualShow = "none" + tempTuplet.tupletActualShow = 'none' tempTuplet.bracket = False tieBeneficiary.duration = tempDuration tieBeneficiary.duration.tuplets = (tempTuplet,) @@ -2051,10 +2051,10 @@ def cummingSchubertStrettoFuga(score): if score.title: print(score.title) - print("intv.\tcount\tpercent") + print('intv.\tcount\tpercent') for l in sorted(strettoKeys): - print("%2d\t%3d\t%2d%%" % (l, strettoKeys[l], strettoKeys[l] * 100 / len(sn) - 1)) - print("\n") + print('%2d\t%3d\t%2d%%' % (l, strettoKeys[l], strettoKeys[l] * 100 / len(sn) - 1)) + print('\n') class MedRenException(exceptions21.Music21Exception): pass @@ -2119,12 +2119,12 @@ def testHouseStyle(self): def testStretto(): from music21 import converter - salve = converter.parse("A4 A G A D A G F E F G F E D", '4/4') # salveRegina liber p. 276 - adTe = converter.parse("D4 F A G G F A E G F E D G C D E D G F E D", '4/4') # ad te clamamus - etJesum = converter.parse("D4 AA C D D D E E D D C G F E D G F E D C D", '4/4') - salve.title = "Salve Regina (opening)LU p. 276" - adTe.title = "...ad te clamamus" - etJesum.title = "...et Jesum" + salve = converter.parse('A4 A G A D A G F E F G F E D', '4/4') # salveRegina liber p. 276 + adTe = converter.parse('D4 F A G G F A E G F E D G C D E D G F E D', '4/4') # ad te clamamus + etJesum = converter.parse('D4 AA C D D D E E D D C G F E D G F E D C D', '4/4') + salve.title = 'Salve Regina (opening)LU p. 276' + adTe.title = '...ad te clamamus' + etJesum.title = '...et Jesum' for piece in [salve, adTe, etJesum]: cummingSchubertStrettoFuga(piece) diff --git a/music21_tools/trecento/notation.py b/music21_tools/trecento/notation.py index 199d1b3..42069f3 100644 --- a/music21_tools/trecento/notation.py +++ b/music21_tools/trecento/notation.py @@ -32,7 +32,7 @@ from music21 import tie from music21 import tinyNotation from music21 import environment -_MOD = "trecento/notation.py" +_MOD = 'trecento/notation.py' environLocal = environment.Environment(_MOD) from . import medren @@ -375,7 +375,7 @@ class TrecentoTinyConverter(tinyNotation.Converter): 'quad': tinyNotation.QuadrupletState, 'lig': LigatureState } - def __init__(self, stringRep=""): + def __init__(self, stringRep=''): super().__init__(stringRep) self.tokenMap = [ (r'(\$[A-Z]\d?)', ClefToken), @@ -2040,27 +2040,27 @@ def processStream(mStream, pitches, lengths, downStems=None): SePerDureca.append(upper) SePerDureca.append(lower) - upperString = (".p. $C1 g(B) g(M) f e g f e p g(SB) f(SM) e d e(M) f p " + - "e(SB) e(SM) f e d(M) c p d(SB) r e p f(M) e d e d c p " + - "d(SB) c(M) d c d p e(SB) r(M) g f e p g(SB) a(SM) g f e(M) " + - "d p e(SB) f(SM) e d c(M) d e(L) a(SB) a p b(M) a g a g f p g " + - "f e f e f p g(SB) g(SM) a g f e d p e(SB) r(M) f(SM) e d e(M) " + - "p d(SB) r e(M) f p g(SB) d r(SM) e p f e d e d c p d(SB) d(M) " + + upperString = ('.p. $C1 g(B) g(M) f e g f e p g(SB) f(SM) e d e(M) f p ' + + 'e(SB) e(SM) f e d(M) c p d(SB) r e p f(M) e d e d c p ' + + 'd(SB) c(M) d c d p e(SB) r(M) g f e p g(SB) a(SM) g f e(M) ' + + 'd p e(SB) f(SM) e d c(M) d e(L) a(SB) a p b(M) a g a g f p g ' + + 'f e f e f p g(SB) g(SM) a g f e d p e(SB) r(M) f(SM) e d e(M) ' + + 'p d(SB) r e(M) f p g(SB) d r(SM) e p f e d e d c p d(SB) d(M) ' + "e(SB) c(M) p d(SB) c(M) d c B c(L) c'(SB)[D] c' p c'(SM) b a " + "b(M) c' b c' p b(SM) a g a(M) b a b p g(SB) g(SM) a g f e d p " + - "e(SB) r e(M) f p g f e f e f p g(SB) r g(M) f p g(SB) f(SM) e " + + 'e(SB) r e(M) f p g f e f e f p g(SB) r g(M) f p g(SB) f(SM) e ' + "d e(M) f e(L) a(M) b a b g(SB) p c'(M) b a c' b a p b c' b a " + "g a p b(SB) c'(SM) b a g(M) f p a(SB) a(M) g(SB) f(M) p e(SB) r " + - "g(M) f p g f e f e d p c(SB) d r p a g(SM) a g f e d p e(SB) r " + - "f(SM) e d e(SB) d(Mx)") - lowerString = (".p. $C3 c(L) G(B) A(SB) B c p d c r p A B c p d c B p " + - "lig{A[DL] G} A c B A(L) A(SB) A p G A B p c c(M) B(SB) " + - "A(M) p G(SB) G p A B c p d A r p G[D] A p B B(M) c(SB) c(M) " + - "p d(SB) d(M) A(SB) A(M) p G(SB) A B C(L) c(SB)[D] c e(B) d c(SB) " + - "c d p e d r p c c(M) d(SB) d(M) p c(SB) r r p c d c(M) d " + - "e(L) d(SB)[D] e p c[D] d p e e(M) d(SB) c(M) p B(SB) A B(M) " + - "c p d(SB) d(M) c(SB) d(M) p e(SB) d r p c c c(M) A(SB) B(M) p " + - "c(SB) B B p A B[D] p A B c d(Mx)") + 'g(M) f p g f e f e d p c(SB) d r p a g(SM) a g f e d p e(SB) r ' + + 'f(SM) e d e(SB) d(Mx)') + lowerString = ('.p. $C3 c(L) G(B) A(SB) B c p d c r p A B c p d c B p ' + + 'lig{A[DL] G} A c B A(L) A(SB) A p G A B p c c(M) B(SB) ' + + 'A(M) p G(SB) G p A B c p d A r p G[D] A p B B(M) c(SB) c(M) ' + + 'p d(SB) d(M) A(SB) A(M) p G(SB) A B C(L) c(SB)[D] c e(B) d c(SB) ' + + 'c d p e d r p c c(M) d(SB) d(M) p c(SB) r r p c d c(M) d ' + + 'e(L) d(SB)[D] e p c[D] d p e e(M) d(SB) c(M) p B(SB) A B(M) ' + + 'c p d(SB) d(M) c(SB) d(M) p e(SB) d r p c c c(M) A(SB) B(M) p ' + + 'c(SB) B B p A B[D] p A B c d(Mx)') upperConverted = TrecentoTinyConverter(upperString).parse( ).stream.flatten().getElementsNotOfClass('Barline') diff --git a/music21_tools/trecento/polyphonicSnippet.py b/music21_tools/trecento/polyphonicSnippet.py index f134ffd..f1ee0ce 100644 --- a/music21_tools/trecento/polyphonicSnippet.py +++ b/music21_tools/trecento/polyphonicSnippet.py @@ -68,7 +68,7 @@ class PolyphonicSnippet(stream.Score): >>> dummy2.elements () ''' - snippetName = "" + snippetName = '' def __init__(self, fiveExcelCells=None, parentPiece=None): super().__init__() @@ -76,7 +76,7 @@ def __init__(self, fiveExcelCells=None, parentPiece=None): fiveExcelCells = [] if fiveExcelCells != []: if len(fiveExcelCells) != 5: - raise Exception("Need five Excel Cells to make a PolyphonicSnippet object") + raise Exception('Need five Excel Cells to make a PolyphonicSnippet object') self.cadenceType = fiveExcelCells[3] self.timeSig = meter.TimeSignature(fiveExcelCells[4]) @@ -87,16 +87,16 @@ def __init__(self, fiveExcelCells=None, parentPiece=None): self.longestLineLength = 0 - if self.contratenor == "" or self.contratenor is None: + if self.contratenor == '' or self.contratenor is None: self.contratenor = None else: self.contratenor.id = 'Ct' - if self.tenor == "" or self.tenor is None: + if self.tenor == '' or self.tenor is None: self.tenor = None else: self.tenor.id = 'T' - if self.cantus == "" or self.cantus is None: + if self.cantus == '' or self.cantus is None: self.cantus = None else: self.cantus.id = 'C' @@ -136,23 +136,23 @@ def _padParts(self): def header(self): '''returns a string that prints an appropriate header for this cadence''' - if self.snippetName == "": + if self.snippetName == '': if (self.parentPiece is not None): - headOut = "" + headOut = '' parentPiece = self.parentPiece if (parentPiece.fischerNum): - headOut += str(parentPiece.fischerNum) + ". " + headOut += str(parentPiece.fischerNum) + '. ' if parentPiece.title: headOut += parentPiece.title if (parentPiece.pmfcVol and parentPiece.pmfcPageRange()): - headOut += " PMFC " + str(parentPiece.pmfcVol) + " " + headOut += ' PMFC ' + str(parentPiece.pmfcVol) + ' ' headOut += parentPiece.pmfcPageRange() return headOut else: - return "" + return '' else: if (self.parentPiece is not None): - headOut = self.parentPiece.title + " -- " + self.snippetName + headOut = self.parentPiece.title + ' -- ' + self.snippetName else: return self.snippetName @@ -210,7 +210,7 @@ def measuresShort(self, thisStream): class Incipit(PolyphonicSnippet): - snippetName = "" + snippetName = '' def backPadLine(self, thisStream): ''' @@ -277,7 +277,7 @@ def backPadLine(self, thisStream): class FrontPaddedSnippet(PolyphonicSnippet): - snippetName = "" + snippetName = '' def frontPadLine(self, thisStream): '''Pads a line with a bunch of rests at the @@ -392,12 +392,12 @@ def testLily(self): from . import trecentoCadence, cadencebook cantus = trecentoCadence.CadenceConverter( "6/8 c'2. d'8 c'4 a8 f4 f8 a4 c'4 c'8").parse().stream - tenor = trecentoCadence.CadenceConverter("6/8 F1. f2. e4. d").parse().stream - ps = PolyphonicSnippet([cantus, tenor, None, "8-8", "6/8"], + tenor = trecentoCadence.CadenceConverter('6/8 F1. f2. e4. d').parse().stream + ps = PolyphonicSnippet([cantus, tenor, None, '8-8', '6/8'], parentPiece=cadencebook.BallataSheet().makeWork(3)) ps.show('musicxml.png') -if __name__ == "__main__": +if __name__ == '__main__': import music21 music21.mainTest(Test, TestExternal, 'importPlusRelative') diff --git a/music21_tools/trecento/quodJactatur.py b/music21_tools/trecento/quodJactatur.py index dc09ebe..7b564d8 100644 --- a/music21_tools/trecento/quodJactatur.py +++ b/music21_tools/trecento/quodJactatur.py @@ -193,9 +193,9 @@ def getQJ(): ''' - qj = corpus.parse("ciconia/quod_jactatur") + qj = corpus.parse('ciconia/quod_jactatur') qjPart = qj.getElementsByClass(stream.Part)[0] - qjPart.transpose("P-8", inPlace=True) + qjPart.transpose('P-8', inPlace=True) qjPart.replace(qjPart.flatten().getElementsByClass(clef.Clef)[0], clef.BassClef()) cachedParts['1-0-False-False'] = copy.deepcopy(qjPart) return qjPart @@ -256,20 +256,20 @@ def findRetrogradeVoices(show=True): qj.show() else: if invert: - invStr = "Invert" + invStr = 'Invert' else: - invStr = " " - print(str(transpose) + " " + invStr + " " + str(finalScore)) + invStr = ' ' + print(str(transpose) + ' ' + invStr + ' ' + str(finalScore)) def prepareSolution(triplumTup, ctTup, tenorTup): qjSolved = stream.Score() for transpose, delay, invert, retro in [triplumTup, ctTup, tenorTup]: - idString = "%d-%d-%s-%s" % (transpose, delay, invert, retro) + idString = '%d-%d-%s-%s' % (transpose, delay, invert, retro) if idString in cachedParts: qjPart = copy.deepcopy(cachedParts[idString]) else: - qjPart = copy.deepcopy(cachedParts["1-0-False-False"]) + qjPart = copy.deepcopy(cachedParts['1-0-False-False']) if retro is True: qjPart = reverse(qjPart, makeNotation = False) if invert is True: @@ -466,13 +466,13 @@ def multipleSolve(): lowestRetro, avgScore) if avgScore > 0: - print("") + print('') if avgScore > maxScore: maxScore = avgScore - print("***** ", end="") + print('***** ', end='') print(writeLine) else: - print(str(i) + " ", end="") + print(str(i) + ' ', end='') csvFile.writerow(writeLine) class QuodJactaturException(exceptions21.Music21Exception): @@ -485,7 +485,7 @@ def runTest(self): -if __name__ == "__main__": +if __name__ == '__main__': import music21 music21.mainTest('importPlusRelative') # bentWolfSolution() diff --git a/music21_tools/trecento/runTrecentoCadence.py b/music21_tools/trecento/runTrecentoCadence.py index c74ffff..7e9238c 100644 --- a/music21_tools/trecento/runTrecentoCadence.py +++ b/music21_tools/trecento/runTrecentoCadence.py @@ -26,7 +26,7 @@ def countTimeSig(): for trecentoWork in ballataObj: thisTime = trecentoWork.timeSigBegin thisTime = thisTime.strip() # remove leading and trailing whitespace - if (thisTime == ""): + if (thisTime == ''): pass else: totalPieces += 1 @@ -36,8 +36,8 @@ def countTimeSig(): timeSigCounter[thisTime] = 1 for thisKey in sorted(timeSigCounter): - print(thisKey, ":", timeSigCounter[thisKey], - str(int(timeSigCounter[thisKey] * 100 / totalPieces)) + "%") + print(thisKey, ':', timeSigCounter[thisKey], + str(int(timeSigCounter[thisKey] * 100 / totalPieces)) + '%') def sortByPMFC(work): ''' @@ -120,7 +120,7 @@ def makePDFfromPiecesWithCapua(start=2, finish=3): if randomPiece.incipit: retrievedPieces.append(randomPiece) except: - raise Exception("Ugg " + str(i)) + raise Exception('Ugg ' + str(i)) # lilyString = "" # retrievedPieces.sort(key=sortByPMFC) @@ -163,7 +163,7 @@ def checkValidity(): try: unused_incipitStreams = randomPiece.incipitStreams() except music21.tinyNotation.TinyNotationException as inst: - raise Exception(randomPiece.title + " had problem " + inst.args) + raise Exception(randomPiece.title + ' had problem ' + inst.args) # temporarily commenting out for adding standard test approach @@ -181,7 +181,7 @@ def runTest(self): def testA(self): self.assertEqual(5, 5) ## something really wrong!?? -if __name__ == "__main__": +if __name__ == '__main__': #makePDFfromPiecesWithCapua() import music21 music21.mainTest(Test, 'moduleRelative') diff --git a/music21_tools/trecento/tonality.py b/music21_tools/trecento/tonality.py index e31e8ea..912b2cc 100644 --- a/music21_tools/trecento/tonality.py +++ b/music21_tools/trecento/tonality.py @@ -74,17 +74,17 @@ class TonalityCounter: ''' - def __init__(self, worksList, streamName="T", cadenceName="A"): + def __init__(self, worksList, streamName='T', cadenceName='A'): self.worksList = worksList self.streamName = streamName self.cadenceName = cadenceName - self.output = "" + self.output = '' self.displayStream = None self.storedDict = None def run(self): from music21 import stream - output = "" + output = '' streamName = self.streamName allScores = stream.Opus() @@ -95,9 +95,9 @@ def run(self): for thisWork in self.worksList: incip = thisWork.incipit - if self.cadenceName == "A": + if self.cadenceName == 'A': cadence = thisWork.cadenceA - elif self.cadenceName == "B": + elif self.cadenceName == 'B': cadence = thisWork.cadenceBclos try: if (cadence is None or cadence.parts[streamName] is None): @@ -110,7 +110,7 @@ def run(self): except IndexError: continue else: - raise Exception("Cannot deal with cadence type %s" % self.cadenceName) + raise Exception('Cannot deal with cadence type %s' % self.cadenceName) if incip is None or cadence is None: continue @@ -124,14 +124,14 @@ def run(self): firstNote = incipSN.pitches[0] cadenceNote = cadenceSN.pitches[-1] except IndexError: - output += thisWork.title + "\n" + output += thisWork.title + '\n' continue myDict[firstNote.step][cadenceNote.step] += 1 if firstNote.step == cadenceNote.step: allScores.insert(0, incip) allScores.insert(0, cadence) - output += "%30s %4s %4s\n" % (thisWork.title[0:30], firstNote.name, cadenceNote.name) + output += '%30s %4s %4s\n' % (thisWork.title[0:30], firstNote.name, cadenceNote.name) bigTotalSame = 0 bigTotalDiff = 0 @@ -139,17 +139,17 @@ def run(self): outKeyDiffTotal = 0 for inKey in sorted(myDict[outKey]): if outKey == inKey: - output += "**** " + output += '**** ' bigTotalSame += myDict[outKey][inKey] else: - output += " " + output += ' ' outKeyDiffTotal += myDict[outKey][inKey] bigTotalDiff += myDict[outKey][inKey] - output += "%4s %4s %4d\n" % (outKey, inKey, myDict[outKey][inKey]) - output += " %4s diff %4d\n" % (outKey, outKeyDiffTotal) - output += "Total Same %4d %3.1f%%\n" % (bigTotalSame, + output += '%4s %4s %4d\n' % (outKey, inKey, myDict[outKey][inKey]) + output += ' %4s diff %4d\n' % (outKey, outKeyDiffTotal) + output += 'Total Same %4d %3.1f%%\n' % (bigTotalSame, (bigTotalSame * 100.0) / (bigTotalSame + bigTotalDiff)) - output += "Total Diff %4d %3.1f%%\n" % (bigTotalDiff, + output += 'Total Diff %4d %3.1f%%\n' % (bigTotalDiff, (bigTotalDiff * 100.0) / (bigTotalSame + bigTotalDiff)) self.storedDict = myDict self.displayStream = allScores @@ -166,9 +166,9 @@ def landiniTonality(show=True): ballataObj = cadencebook.BallataSheet() worksList = [] for thisWork in ballataObj: - if thisWork.composer == "Landini": + if thisWork.composer == 'Landini': worksList.append(thisWork) - tCounter = TonalityCounter(worksList, streamName = "T", cadenceName = "A") + tCounter = TonalityCounter(worksList, streamName = 'T', cadenceName = 'A') tCounter.run() if show is True: print(tCounter.output) @@ -271,9 +271,9 @@ def nonLandiniTonality(show=True): for thisWork in ballataObj: if show: print(thisWork.title) - if thisWork.composer != "Landini" and thisWork.composer != ".": + if thisWork.composer != 'Landini' and thisWork.composer != '.': worksList.append(thisWork) - tCounter = TonalityCounter(worksList, streamName = "T", cadenceName = "A") + tCounter = TonalityCounter(worksList, streamName = 'T', cadenceName = 'A') tCounter.run() if show is True: print(tCounter.output) @@ -289,15 +289,15 @@ def anonBallataTonality(show=True): ballataObj = cadencebook.BallataSheet() worksList = [] for thisWork in ballataObj: - if thisWork.composer == ".": + if thisWork.composer == '.': worksList.append(thisWork) - tCounter = TonalityCounter(worksList, streamName = "T", cadenceName = "A") + tCounter = TonalityCounter(worksList, streamName = 'T', cadenceName = 'A') tCounter.run() if show is True: print(tCounter.output) - print("Generating Lilypond PNG of all pieces where the first note of " + - "the tenor is the same pitchclass as the last note of Cadence A") - print("It might take a while, esp. on the first Lilypond run...") + print('Generating Lilypond PNG of all pieces where the first note of ' + + 'the tenor is the same pitchclass as the last note of Cadence A') + print('It might take a while, esp. on the first Lilypond run...') tCounter.displayStream.show('lily.png') def sacredTonality(show=True): @@ -321,7 +321,7 @@ def sacredTonality(show=True): sanctusObj.makeWork(2), agnusObj.makeWork(2) ] - tCounter = TonalityCounter(worksList, streamName = "T", cadenceName = -1) + tCounter = TonalityCounter(worksList, streamName = 'T', cadenceName = -1) tCounter.run() if show is True: print(tCounter.output) @@ -346,7 +346,7 @@ class TestExternal(unittest.TestCase): # pragma: no cover def runTest(self): testAll(show=True, fast=False) -if __name__ == "__main__": +if __name__ == '__main__': import music21 music21.mainTest(Test, 'importPlusRelative') #External) diff --git a/music21_tools/trecento/trecentoCadence.py b/music21_tools/trecento/trecentoCadence.py index 429b5f5..783b0a0 100644 --- a/music21_tools/trecento/trecentoCadence.py +++ b/music21_tools/trecento/trecentoCadence.py @@ -58,7 +58,7 @@ class CadenceConverter(tinyNotation.Converter): , ) ''' - def __init__(self, stringRep=""): + def __init__(self, stringRep=''): super().__init__(stringRep) self.tokenMap = [ (r'(\d+\/\d+)', tinyNotation.TimeSignatureToken), @@ -117,7 +117,7 @@ def testTrecentoLine(self): self.assertAlmostEqual(st.duration.quarterLength, 6.0) st.show() -if __name__ == "__main__": +if __name__ == '__main__': import music21 music21.mainTest(Test, 'importPlusRelative') diff --git a/pyproject.toml b/pyproject.toml index 585c27d..a7709fe 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,7 +52,29 @@ Homepage = "https://github.com/cuthbertLab/music21-tools" default-groups = ["dev"] [tool.hatch.build.targets.wheel] -packages = ["music21_tools"] +packages = ['music21_tools'] [tool.pytest.ini_options] -doctest_optionflags = "NORMALIZE_WHITESPACE ELLIPSIS" +doctest_optionflags = ['NORMALIZE_WHITESPACE', 'ELLIPSIS'] + +[tool.ruff] +line-length = 100 + +[tool.ruff.lint] +# Flake8, pycodestyle, flake8-quotes + pyflakes (mirrors music21's house style) +select = ['E', 'W', 'Q', 'F', 'B'] +dummy-variable-rgx = '^(_.*|unused.*|i|j|counter|junk|dummy)' +ignore = [ + 'E227', # space around | -- nice to omit in int|str + 'E301', # 0 blank lines + 'E302', # blank lines -- expected 2 blank lines + 'E303', # too many blank lines + 'E731', # assignment to lambda + 'B904', # raise-from + 'B905', # zip without strict= +] + +[tool.ruff.lint.flake8-quotes] +inline-quotes = 'single' +multiline-quotes = 'single' +docstring-quotes = 'single' diff --git a/tools/exceldiff.py b/tools/exceldiff.py index e478992..9a6c03f 100755 --- a/tools/exceldiff.py +++ b/tools/exceldiff.py @@ -23,14 +23,14 @@ def main(argv: list[str]) -> None: if len(argv) != 3: - raise SystemExit("Usage: exceldiff.py file1.xls:sheet1 file2.xls:sheet2") + raise SystemExit('Usage: exceldiff.py file1.xls:sheet1 file2.xls:sheet2') if argv[1].count(':') == 1: (book1name, sheetname1) = argv[1].split(':') if book1name.count('.xls') == 0: - book1name += ".xls" + book1name += '.xls' else: - raise SystemExit("First name must be in form filename:sheetname") + raise SystemExit('First name must be in form filename:sheetname') if argv[2].count(':') == 1: (book2name, sheetname2) = argv[2].split(':') @@ -38,7 +38,7 @@ def main(argv: list[str]) -> None: (book2name, sheetname2) = (argv[2], sheetname1) if book2name.count('.xls') == 0: - book2name += ".xls" + book2name += '.xls' book1 = xlrd.open_workbook(book1name) book2 = xlrd.open_workbook(book2name) @@ -81,26 +81,26 @@ def main(argv: list[str]) -> None: minCells = totalCells1 # doesnt matter which for j in range(minCells): if rowvalues1[j] != rowvalues2[j]: - print("%3d,%2s--%34s : %34s" % (i + 1, xlrd.colname(j), + print('%3d,%2s--%34s : %34s' % (i + 1, xlrd.colname(j), (rowvalues1[j]).encode('utf-8')[:34], (rowvalues2[j]).encode('utf-8')[:34])) if extraCells > 0: - print("%3d extra cells in row %3d in" % (extraCells, i + 1), end='') + print('%3d extra cells in row %3d in' % (extraCells, i + 1), end='') if longrow == 1: - print(book1name + ":" + sheetname1) + print(book1name + ':' + sheetname1) elif longrow == 2: - print(book2name + ":" + sheetname2) + print(book2name + ':' + sheetname2) else: - raise Exception("What? longrow was not set!") + raise Exception('What? longrow was not set!') if extraRows > 0: - print("%3d extra rows in" % extraRows,) + print('%3d extra rows in' % extraRows,) if longsheet == 1: - print(book1name + ":" + sheetname1) + print(book1name + ':' + sheetname1) elif longsheet == 2: - print(book2name + ":" + sheetname2) + print(book2name + ':' + sheetname2) else: - raise Exception("What? longsheet was not set!") + raise Exception('What? longsheet was not set!') if __name__ == '__main__': From 54a607251d310c5c4c45a7d4314d95bae382d494 Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 13:34:04 -1000 Subject: [PATCH 02/28] Adopt music21 style configs and apply ruff safe autofixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Copies .editorconfig and .pylintrc verbatim from music21base. Applies ruff check --fix (27 fixes across 7 files: bare except, not-in operator, dict.get fallthrough, etc.). Restores `harmony` and `meter` imports in theoryAnalyzer.py that ruff stripped as unused — they're used in doctests, which ruff can't see. Co-Authored-By: Claude Opus 4.7 (1M context) --- .editorconfig | 20 + .pylintrc | 383 ++++++++++++++++++ music21_tools/bhadley/nips2011.py | 2 +- music21_tools/choraleTools/mnum_fixer.py | 26 +- music21_tools/featureExtraction/ismir2011.py | 7 +- music21_tools/misc/gatherAccidentals.py | 2 +- .../theoryAnalysis/theoryAnalyzer.py | 7 +- music21_tools/trecento/medren.py | 2 +- music21_tools/trecento/notation.py | 2 +- music21_tools/trecento/quodJactatur.py | 2 +- 10 files changed, 428 insertions(+), 25 deletions(-) create mode 100644 .editorconfig create mode 100644 .pylintrc diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..d68a9b9 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,20 @@ +# For details see http://EditorConfig.org + +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +insert_final_newline = true + +# Matches multiple files with brace expansion notation +# Set default charset +[*.{js,py}] +charset = utf-8 + +# 4 space indentation +[*.py] +indent_style = space +indent_size = 4 +trim_trailing_whitespace = true diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 0000000..fb79747 --- /dev/null +++ b/.pylintrc @@ -0,0 +1,383 @@ +[MASTER] + +# Specify a configuration file. +# rcfile= + +# Python code to execute, usually for sys.path manipulation such as +# pygtk.require(). +# init-hook= + +# Add files or directories to the blacklist. They should be base names, not +# paths. +ignore=CVS + +# Pickle collected data for later comparisons. +persistent=yes + +# List of plugins (as comma separated values of python modules names) to load, +# usually to register additional checkers. +load-plugins= + +## Use multiple processes to speed up Pylint. +## jobs=1 + +# Allow loading of arbitrary C extensions. Extensions are imported into the +# active Python interpreter and may run arbitrary code. +unsafe-load-any-extension=no + +# A comma-separated list of package or module names from where C extensions may +# be loaded. Extensions are loading into the active Python interpreter and may +# run arbitrary code +extension-pkg-whitelist= + + +[MESSAGES CONTROL] + +# Only show warnings with the listed confidence levels. Leave empty to show +# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED +confidence= + +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time. See also the "--disable" option for examples. +#enable= + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once).You can also use "--disable=all" to +# disable everything first and then re-enable specific checks. For example, if +# you want to run only the similarities checker, you can use "--disable=all +# --enable=similarities". If you want to run only the classes checker, but have +# no Warning level messages displayed, use"--disable=all --enable=classes +# --disable=W" + +# anything changed here, also change in test/testLint.py for now + +disable= + cyclic-import, # we use these inside functions when there's a deep problem. + unnecessary-pass, # not really a problem.. + locally-disabled, # test for this later, but hopefully will know what we're doing + duplicate-code, # needs to ignore strings -- keeps getting doctests... + fixme, # obviously known + superfluous-parens, # nope -- if they make things clearer... + too-many-statements, # someday + too-many-arguments, # definitely! but takes too long to get a fix now... + too-many-public-methods, # maybe... + too-many-branches, # yes, someday + too-many-locals, # no + too-many-lines, # yes, someday + too-many-return-statements, # we'll see + too-many-instance-attributes, # maybe later + too-many-positional-arguments, # try to get down to 6 first... + # no-self-use, # moved to optional extension. + invalid-name, # these are good music21 names; fix the regexp instead... + too-few-public-methods, # never remove or set to 1 + trailing-whitespace, # should ignore blank lines with tabs + missing-docstring, # gets too many well-documented properties + protected-access, # this is an important one, but see below... + unused-argument, + import-self, # fix is either to get rid of it or move away many tests... + wrong-import-position, + no-else-return, + too-many-ancestors, + inconsistent-return-statements, + keyword-arg-before-vararg, + consider-using-get, + chained-comparison, + import-outside-toplevel, + trailing-newlines, # is this really the worst thing in the world? + no-else-continue, # not so bad... + no-else-break, # same... + consider-using-enumerate, # sometimes parallelism is better than enumerate. + consider-using-dict-items, # readability improvement depends on excellent variable names + arguments-differ, # we are not purists. + arguments-renamed, # same + simplifiable-if-statement, # simpler to a computer maybe... + unsubscriptable-object, # too many errors + import-outside-toplevel, # allow for import music21, etc. + not-callable, # false positives, for instance on x.next() + raise-missing-from, # want to do this eventually, but adding 1000 msgs not helpful + consider-using-f-string, # future? + unnecessary-lambda-assignment, # opinionated + consider-using-generator, # generators are less performant for small container sizes, like most of ours + not-an-iterable, # false positives on RecursiveIterator in recent pylint versions. + unpacking-non-sequence, # also getting false positives. +# 'protected-access', # this is an important one, but for now we do a lot of +# # x = copy.deepcopy(self); x._volume = ... which is not a problem... + + +[REPORTS] + +# Set the output format. Available formats are text, parseable, colorized, msvs +# (visual studio) and html. You can also give a reporter class, eg +# mypackage.mymodule.MyReporterClass. +output-format=text +msg-template="{path}:{line}: [{msg_id}({symbol}), {obj}] {msg}" + +# Tells whether to display a full report or only the messages +reports=no + +# Python expression which should return a note less than 10 (10 is the highest +# note). You have access to the variables errors warning, statement which +# respectively contain the number of errors / warnings messages and the total +# number of statements analyzed. This is used by the global evaluation report +# (RP0004). +evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) + +# Add a comment according to your evaluation note. This is used by the global +# evaluation report (RP0004). +# comment=no + +# Template used to display messages. This is a python new-style format string +# used to format the message information. See doc for all details +#msg-template= + + +[BASIC] + +# Required attributes for module, separated by a comma +# required-attributes= + +# Good variable names which should always be accepted, separated by a comma +good-names=i,j,k,ex,Run,_ + +# Bad variable names which should always be refused, separated by a comma +bad-names=foo,baz,toto,tutu,tata,shit,fuck,stuff + +# Colon-delimited sets of names that determine each other's naming style when +# the name regexes allow several styles. +name-group= + +# Include a hint for the correct naming format with invalid-name +include-naming-hint=no + +# Regular expression matching correct function names +function-rgx=[a-z_][A-Za-z0-9_]{2,30}$ + +# Regular expression matching correct variable names +variable-rgx=[a-z_][A-Za-z0-9_]{2,30}$ + +# Regular expression matching correct constant names +const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ + +# Regular expression matching correct attribute names +attr-rgx=[a-z_][A-Za-z0-9_]{2,30}$ + +# Regular expression matching correct argument names +argument-rgx=[a-z_][A-Za-z0-9_]{2,30}$ + +# Regular expression matching correct class attribute names +class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ + +# Regular expression matching correct inline iteration names +inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ + +# Regular expression matching correct class names +class-rgx=[A-Z_][a-zA-Z0-9]+$ + +# Regular expression matching correct module names +module-rgx=(([a-z_][a-zA-Z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ + +# Regular expression matching correct method names +method-rgx=[a-z_][a-zA-Z0-9_]{2,30}$ + +# Regular expression which should only match function or class names that do +# not require a docstring. +no-docstring-rgx=__.*__ + +# Minimum line length for functions/classes that require docstrings, shorter +# ones are exempt. +docstring-min-length=-3 + + +[FORMAT] + +# Maximum number of characters on a single line. +max-line-length=100 + +# Regexp for a line that is allowed to be longer than the limit. +ignore-long-lines=^\s*(# )??$|converter\.parse + +# Allow the body of an if to be on the same line as the test if there is no +# else. +single-line-if-stmt=no + +# Maximum number of lines in a module +max-module-lines=1000 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' + +# Number of spaces of indent required inside a hanging or continued line. +indent-after-paren=4 + +# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. +expected-line-ending-format= + + +[LOGGING] + +# Logging modules to check that the string format arguments are in logging +# function parameter format +logging-modules=logging + + +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=FIXME,XXX,TODO + + +[SIMILARITIES] + +# Minimum lines number of a similarity. +min-similarity-lines=8 + +# Ignore comments when computing similarities. +ignore-comments=yes + +# Ignore docstrings when computing similarities. +ignore-docstrings=yes + +# Ignore imports when computing similarities. +ignore-imports=yes + + +[SPELLING] + +# Spelling dictionary name. Available dictionaries: none. To make it working +# install python-enchant package. +spelling-dict= + +# List of comma separated words that should not be checked. +spelling-ignore-words= + +# A path to a file that contains private dictionary; one word per line. +spelling-private-dict-file= + +# Tells whether to store unknown words to indicated private dictionary in +# --spelling-private-dict-file option instead of raising a message. +spelling-store-unknown-words=no + + +[TYPECHECK] + +# Tells whether missing members accessed in mixin class should be ignored. A +# mixin class is detected if its name ends with "mixin" (case insensitive). +ignore-mixin-members=yes + +# List of module names for which member attributes should not be checked +# (useful for modules/projects where namespaces are manipulated during runtime +# and thus existing member attributes cannot be deduced by static analysis +ignored-modules= + +# List of classes names for which member attributes should not be checked +# (useful for classes with attributes dynamically set). +ignored-classes=StreamCore + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E0201 when accessed. Python regular +# expressions are accepted. +generated-members=REQUEST,acl_users,aq_parent + + +[VARIABLES] + +# Tells whether we should check for unused import in __init__ files. +init-import=no + +# A regular expression matching the name of dummy variables (i.e. expectedly +# not used). +dummy-variables-rgx=_|dummy|unused|i$|j$|junk|counter + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid to define new builtins when possible. +additional-builtins= + +# List of strings which can identify a callback function by name. A callback +# name must start or end with one of those strings. +callbacks=cb_,_cb + + +[CLASSES] + +# List of interface methods to ignore, separated by a comma. This is used for +# instance to not check methods defines in Zope's Interface base class. +# ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__,__new__,setUp,setup,run + +# List of valid names for the first argument in a class method. +valid-classmethod-first-arg=cls + +# List of valid names for the first argument in a metaclass class method. +valid-metaclass-classmethod-first-arg=mcs + +# List of member names, which should be excluded from the protected access +# warning. +exclude-protected=_asdict,_fields,_replace,_source,_make + + +[DESIGN] + +# Maximum number of arguments for function / method +max-args=5 + +# maximum boolean expressions in a line (too-many-boolean-expressions) +max-bool-expr=10 + +# Argument names that match this expression will be ignored. Default to name +# with leading underscore +ignored-argument-names=_.* + +# Maximum number of locals for function / method body +max-locals=15 + +# Maximum number of return / yield for function / method body +max-returns=6 + +# Maximum number of branch for function / method body +max-branches=20 + +# Maximum number of statements in function / method body +max-statements=100 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of attributes for a class (see R0902). +max-attributes=20 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=40 + + +[IMPORTS] + +# Deprecated modules which should not be used, separated by a comma +deprecated-modules=regsub,TERMIOS,Bastion,rexec + +# Create a graph of every (i.e. internal and external) dependencies in the +# given file (report RP0402 must not be disabled) +import-graph= + +# Create a graph of external dependencies in the given file (report RP0402 must +# not be disabled) +ext-import-graph= + +# Create a graph of internal dependencies in the given file (report RP0402 must +# not be disabled) +int-import-graph= + + +[EXCEPTIONS] + +# Exceptions that will emit a warning when being caught. Defaults to +# "Exception" +# overgeneral-exceptions=Exception diff --git a/music21_tools/bhadley/nips2011.py b/music21_tools/bhadley/nips2011.py index 9a7c053..0d161bb 100644 --- a/music21_tools/bhadley/nips2011.py +++ b/music21_tools/bhadley/nips2011.py @@ -58,7 +58,7 @@ def nipsBuild(useOurExtractors=True, buildSet=1, evaluationMethod='coarse'): entryDict = {} for d in entries: - sid = d.keys()[0]; + sid = d.keys()[0] entryDict[int(sid)] = d[sid] diff --git a/music21_tools/choraleTools/mnum_fixer.py b/music21_tools/choraleTools/mnum_fixer.py index 86f7601..d58aadf 100644 --- a/music21_tools/choraleTools/mnum_fixer.py +++ b/music21_tools/choraleTools/mnum_fixer.py @@ -14,7 +14,7 @@ p = Path('/Users/Cuthbert/Desktop/Norman_Schmidt_Chorales') pOut = p.parent / 'Out_Chorales' -def run(): +def run(): files = list(p.iterdir()) filenames = [fp.name for fp in files] pos = 0 @@ -29,7 +29,7 @@ def run(): continue pos += 1 runOne(c, cName) - + def runOne(c, cName): pName = p / cName newScore = converter.parse(pName) @@ -77,7 +77,7 @@ def runOne(c, cName): m.number = mn - measureNumberShift m.numberSuffix = ms partNumSuffix.append((mn - measureNumberShift, ms)) - + elif perfect: priorMeasureWasIncomplete = False priorMeasureDuration = mQl @@ -102,7 +102,7 @@ def runOne(c, cName): ms = ms + 'x' m.number = mn - measureNumberShift m.numberSuffix = ms - partNumSuffix.append((mn - measureNumberShift, ms)) + partNumSuffix.append((mn - measureNumberShift, ms)) elif truncated: priorMeasureWasIncomplete = True m.paddingRight = short @@ -141,11 +141,11 @@ def runOne(c, cName): measureNumberShift += 1 m.number = mn - measureNumberShift partNumSuffix.append((mn - measureNumberShift, ms)) - + partSuffixesTuple = tuple(partNumSuffix) allSuffixesByPart.add(partSuffixesTuple) - - + + if len(allSuffixesByPart) != 1: print('Multiple conflicting measures!', cName) print(cName, allSuffixesByPart) @@ -157,14 +157,14 @@ def runOne(c, cName): sKNew = str(kNew) if kOrig.sharps != kNew.sharps: print('Key changed from', kOrig, kNew) - + if sKNew != sKOrig: kNew.activeSite.replace(kNew, kOrig) analysisKey = newScore.analyze('key') print('Mode would have been changed from ', sKOrig, sKNew) if str(analysisKey) != sKOrig: print('Key mismatch: ', sKOrig, sKNew, str(analysisKey)) - + except IndexError: print('no key in ', cName) @@ -177,10 +177,10 @@ def runOne(c, cName): # if not expander.isExpandable(): # #print('incoherent repeats', cName) # try: -# pOrig = expander.process() +# pOrig = expander.process() # except Exception: # pass -# +# # pNew = newScore.parts[i] # expander = repeat.Expander(pNew) # if not expander.isExpandable(): @@ -189,7 +189,7 @@ def runOne(c, cName): # pNew = expander.process() # except Exception: # pass -# +# # origPitches = tuple([p.nameWithOctave for p in pOrig.pitches]) # newPitches = tuple([p.nameWithOctave for p in pNew.pitches]) # if origPitches != newPitches: @@ -202,7 +202,7 @@ def runOne(c, cName): # continue # if thisP != newP: # print(i, thisP, newP) - + if __name__ == '__main__': run() diff --git a/music21_tools/featureExtraction/ismir2011.py b/music21_tools/featureExtraction/ismir2011.py index 1756552..4943419 100644 --- a/music21_tools/featureExtraction/ismir2011.py +++ b/music21_tools/featureExtraction/ismir2011.py @@ -124,7 +124,8 @@ def prepareChinaEurope2(): ds2.write('d:/desktop/folkTest.tab') def testChinaEuropeFull(): - import orange, orngTree + import orange + import orngTree data1 = orange.ExampleTable('d:/desktop/1.tab') data2 = orange.ExampleTable('d:/desktop/2.tab') @@ -152,7 +153,7 @@ def testChinaEuropeFull(): # this test requires orange and related files def xtestChinaEuropeSimpler(): - import orange, orngTree # @UnusedImport @UnresolvedImport + import orange trainData = orange.ExampleTable('ismir2011_fb_folkTrain.tab') testData = orange.ExampleTable('ismir2011_fb_folkTest.tab') @@ -210,7 +211,7 @@ def prepareTrecentoCadences(): def testTrecentoSimpler(): - import orange, orngTree # @UnusedImport @UnresolvedImport + import orange trainData = orange.ExampleTable('d:/desktop/trecento2.tab') testData = orange.ExampleTable('d:/desktop/trecento1.tab') diff --git a/music21_tools/misc/gatherAccidentals.py b/music21_tools/misc/gatherAccidentals.py index aced1a8..4d99e6b 100644 --- a/music21_tools/misc/gatherAccidentals.py +++ b/music21_tools/misc/gatherAccidentals.py @@ -204,7 +204,7 @@ def _deleteZeros(tally, excludeZeros): ''' if excludeZeros: for k in list(tally.keys()): - if tally[k] is 0: + if tally[k] == 0: del tally[k] return tally diff --git a/music21_tools/theoryAnalysis/theoryAnalyzer.py b/music21_tools/theoryAnalysis/theoryAnalyzer.py index ff4fe9e..8dfec42 100644 --- a/music21_tools/theoryAnalysis/theoryAnalyzer.py +++ b/music21_tools/theoryAnalysis/theoryAnalyzer.py @@ -161,10 +161,10 @@ from music21 import corpus from music21 import duration from music21 import exceptions21 -from music21 import harmony +from music21 import harmony # used in doctests from music21 import interval from music21 import key -from music21 import meter +from music21 import meter # used in doctests from music21 import note from music21 import roman from music21 import stream @@ -2006,7 +2006,7 @@ def identifyTonicAndDominant(self, score, color=None, def testFunction(vs, score): noteList = vs.getObjectsByClass('Note') - if not None in noteList: + if None not in noteList: inChord = chord.Chord(noteList) inKey = self.getKeyAtMeasure(score, noteList[0].measureNumber) chordBass = noteList[-1] @@ -2471,7 +2471,6 @@ def testChordMotionExample(self): # self.assertEqual(averageMotion, 4) # def testFastVerticalityCheck(self): - from music21 import stream sc = stream.Score() part0 = stream.Part() p0measure1 = stream.Measure(number=1) diff --git a/music21_tools/trecento/medren.py b/music21_tools/trecento/medren.py index 2100332..281bc4d 100644 --- a/music21_tools/trecento/medren.py +++ b/music21_tools/trecento/medren.py @@ -662,7 +662,7 @@ def __init__(self, *arguments, **keywords): note.Note.__init__(self, arguments[0], **keywords) # do not replace with super else: note.Note.__init__(self, **keywords) # do not replace with super - + GeneralMensuralNote.__init__(self) # due to different arguments, keywords self._gettingDuration = False self._mensuralType = 'brevis' diff --git a/music21_tools/trecento/notation.py b/music21_tools/trecento/notation.py index 42069f3..29b1a3d 100644 --- a/music21_tools/trecento/notation.py +++ b/music21_tools/trecento/notation.py @@ -866,7 +866,7 @@ def getBreveStrength(self, lengths): for i, item in enumerate(self.brevisLength): if (isinstance(item, medren.MensuralNote) and - (not 'down' in item.getStems()) and + ('down' not in item.getStems()) and (lengths[i] > lastSBLen)): strength = 0 diff --git a/music21_tools/trecento/quodJactatur.py b/music21_tools/trecento/quodJactatur.py index 7b564d8..e0564e2 100644 --- a/music21_tools/trecento/quodJactatur.py +++ b/music21_tools/trecento/quodJactatur.py @@ -292,7 +292,7 @@ def prepareSolution(triplumTup, ctTup, tenorTup): startCounting = False for n in qjChords.flatten().notes: - if not 'Chord' in n.classes: + if 'Chord' not in n.classes: continue if (startCounting is False or n.offset >= 70) and len(n.pitches) < 2: continue From 80115e94de1f9f72cd6ddc4dbc11f4c6db35712b Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 13:44:49 -1000 Subject: [PATCH 03/28] Apply ruff operator-spacing fixes (E225, E226, E228, E231) 211 fixes across 12 files, all autofixable in preview mode. No test regressions (127 passing / 22 failing, unchanged). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../graphicalInterfaceGame.py | 2 +- .../audioSearchDemos/graphicalInterfaceSF.py | 2 +- music21_tools/audioSearchDemos/omrfollow.py | 4 +- music21_tools/bhadley/nips2011.py | 26 ++++----- music21_tools/choraleTools/mnum_fixer.py | 2 +- music21_tools/composition/fadeChord1.py | 12 ++-- music21_tools/composition/phasing.py | 4 +- music21_tools/composition/seeger.py | 2 +- music21_tools/contour/contour.py | 16 +++--- music21_tools/counterpoint/species.py | 6 +- music21_tools/featureExtraction/ismir2011.py | 4 +- music21_tools/misc/eschbeg.py | 2 +- music21_tools/misc/gatherAccidentals.py | 2 +- music21_tools/misc/monteverdi.py | 8 +-- music21_tools/theory/mgtaPart1.py | 24 ++++---- .../theoryAnalysis/theoryAnalyzer.py | 42 +++++++------- music21_tools/theoryAnalysis/theoryResult.py | 6 +- music21_tools/theoryAnalysis/wwnortonMGTA.py | 22 ++++---- .../trecento/cadenceProbabilities.py | 4 +- music21_tools/trecento/cadencebook.py | 2 +- music21_tools/trecento/medren.py | 10 ++-- music21_tools/trecento/notation.py | 56 +++++++++---------- music21_tools/trecento/polyphonicSnippet.py | 2 +- music21_tools/trecento/quodJactatur.py | 4 +- music21_tools/trecento/runTrecentoCadence.py | 2 +- music21_tools/trecento/tonality.py | 8 +-- 26 files changed, 137 insertions(+), 137 deletions(-) diff --git a/music21_tools/audioSearchDemos/graphicalInterfaceGame.py b/music21_tools/audioSearchDemos/graphicalInterfaceGame.py index 70a0a07..f05ca44 100644 --- a/music21_tools/audioSearchDemos/graphicalInterfaceGame.py +++ b/music21_tools/audioSearchDemos/graphicalInterfaceGame.py @@ -72,7 +72,7 @@ def callback(self): self.boxName4.grid(row=2, column=2) self.textRound = tkinter.StringVar() - self.boxName5 = tkinter.Label(master, width=2*self.sizeButton, textvariable=self.textRound) + self.boxName5 = tkinter.Label(master, width=2 * self.sizeButton, textvariable=self.textRound) self.textRound.set('Round') self.boxName5.grid(row=2, column=1) diff --git a/music21_tools/audioSearchDemos/graphicalInterfaceSF.py b/music21_tools/audioSearchDemos/graphicalInterfaceSF.py index 0949f31..462b959 100644 --- a/music21_tools/audioSearchDemos/graphicalInterfaceSF.py +++ b/music21_tools/audioSearchDemos/graphicalInterfaceSF.py @@ -170,7 +170,7 @@ def cropBorder(self, img, minColor=240, maxColor=256): topCut = 0 bottomCut = 0 rightCut = 0 - numberPixels = int(math.sqrt(len(data)/3000000)*4) + numberPixels = int(math.sqrt(len(data) / 3000000) * 4) #Find top for i in range(0, len(data), numberPixels + int(resX / 10)): diff --git a/music21_tools/audioSearchDemos/omrfollow.py b/music21_tools/audioSearchDemos/omrfollow.py index 8c0e053..2085c09 100644 --- a/music21_tools/audioSearchDemos/omrfollow.py +++ b/music21_tools/audioSearchDemos/omrfollow.py @@ -92,10 +92,10 @@ def recognizeScore(scorePart, pageMeasureNumbers, iterations=1): for i in range(8): # top 8 searches topStream = l[i] scorePage = topStream.pageNumber - 1 - scores[scorePage] += (topStream.matchProbability / (i + 1.5))*10 + scores[scorePage] += (topStream.matchProbability / (i + 1.5)) * 10 print('\nBest guesses (pg#, starting measure, probability)') - for i,st in enumerate(l): + for i, st in enumerate(l): print(st.pageNumber, st.startMeasure, st.matchProbability) if i >= 7: break diff --git a/music21_tools/bhadley/nips2011.py b/music21_tools/bhadley/nips2011.py index 0d161bb..bc3f595 100644 --- a/music21_tools/bhadley/nips2011.py +++ b/music21_tools/bhadley/nips2011.py @@ -203,7 +203,7 @@ def getLeadsheetDatesFromBillboard(): UPPERLIMIT = 2011 dates = range(LOWERLIMIT, UPPERLIMIT) for i in dates: - if i !=2008 and i != 2009: + if i != 2008 and i != 2009: address = 'http://www.jamrockentertainment.com/billboard-music-top-100-songs-listed-by-year/top-100-songs-%s.html' % i url = urlopen(address) html = url.read() @@ -217,7 +217,7 @@ def getLeadsheetDatesFromBillboard(): words.pop(0) for a in words: a.strip() - pretty = pretty +' '+ a + pretty = pretty + ' ' + a if song == True: try: j = float(x) @@ -336,7 +336,7 @@ def getLeadsheetDatesFromBillboard(): outputjson = outputjson + '{"%s":[%s,%s]}, ' % (i, date, rank) if (i % 500) == 0: j = ((i - 1000) / (11938.00)) * 100.00 - print ('%s %%' %round(j, 2)) + print ('%s %%' % round(j, 2)) print (outputjson) @@ -410,33 +410,33 @@ def getPFromExperiment(): elif len(guessesNew) > NUM_NEW_PIECES: guess = old if answer == guess: - numCorrect +=1 + numCorrect += 1 avg += numCorrect / TOTAL_TRIALS p = avg / 10000.0 return p - def BinomialCoefficient(n,k): + def BinomialCoefficient(n, k): if n > k: - b = factorial(n) / (factorial(k)*factorial(n-k)) + b = factorial(n) / (factorial(k) * factorial(n - k)) return b - def BinomialProbability(n,k,p,q): - nchoosek = BinomialCoefficient(n,k) - ptothek = pow(p,k) - qtothenminusk = pow(q, (n-k) ) + def BinomialProbability(n, k, p, q): + nchoosek = BinomialCoefficient(n, k) + ptothek = pow(p, k) + qtothenminusk = pow(q, (n - k) ) return nchoosek * ptothek * qtothenminusk k = 148 #number of times music21 found correct date (successes) n = TOTAL_TRIALS #total number of trials p = getPFromExperiment() print ('The probability of a successful guess, as calculated by previous experiment', p) - q = 1-p + q = 1 - p prob = 0.0 #Probability of getting 148 or more correct (sum #the probabilty as k increses from 148 to 214) - for k in range(k,TOTAL_TRIALS): - prob = prob + BinomialProbability(n,k,p,q) + for k in range(k, TOTAL_TRIALS): + prob = prob + BinomialProbability(n, k, p, q) print ('The probability that the computer would guess correctly 69% or more of the time', prob) diff --git a/music21_tools/choraleTools/mnum_fixer.py b/music21_tools/choraleTools/mnum_fixer.py index d58aadf..723499b 100644 --- a/music21_tools/choraleTools/mnum_fixer.py +++ b/music21_tools/choraleTools/mnum_fixer.py @@ -58,7 +58,7 @@ def runOne(c, cName): truncated = True if not perfect and short < (barQl / 2) else False half = True if not perfect and short == (barQl / 2) else False - if half and priorMeasureWasIncomplete==False: + if half and priorMeasureWasIncomplete == False: priorMeasureWasIncomplete = True priorMeasureDuration = mQl priorMeasure = m diff --git a/music21_tools/composition/fadeChord1.py b/music21_tools/composition/fadeChord1.py index 9c628c5..661fc91 100644 --- a/music21_tools/composition/fadeChord1.py +++ b/music21_tools/composition/fadeChord1.py @@ -21,9 +21,9 @@ def smooth01(steps): # f(x) = arcsin(2x-1)/pi+1/2 out = [] - for i in range(1, steps+1): - frac = i/steps - out.append(math.asin(2*frac-1)/math.pi + 1/2) + for i in range(1, steps + 1): + frac = i / steps + out.append(math.asin(2 * frac - 1) / math.pi + 1 / 2) return out # return [0] + [math.asin(2*(i/steps)+1)/math.pi + 1/2 for i in range(1, steps-1)] + [1] @@ -78,16 +78,16 @@ def fade_note( ): reps = end_rep - start_rep smooths = smooth01(reps) - positions = [(1-s) * pos_offset_at_zero for s in smooths] + positions = [(1 - s) * pos_offset_at_zero for s in smooths] if fade_out: - smooths = [1-s for s in smooths] + smooths = [1 - s for s in smooths] m: stream.Measure for i, m in enumerate(part.getElementsByClass('Measure')): if i < start_rep: continue found = m.getElementsByClass(note.Note).getElementsByGroup(group_name) - index_in_smooths = i-start_rep if i < end_rep else end_rep-1-start_rep + index_in_smooths = i - start_rep if i < end_rep else end_rep - 1 - start_rep # print(index_in_smooths, smooths) for n in found: n.volume.velocityScalar = smooths[index_in_smooths] diff --git a/music21_tools/composition/phasing.py b/music21_tools/composition/phasing.py index 0858f38..11a6346 100644 --- a/music21_tools/composition/phasing.py +++ b/music21_tools/composition/phasing.py @@ -112,7 +112,7 @@ def pendulumMusic(show=True, elif ps < 36: active = 3 - jQuant = round(j*8)/8.0 + jQuant = round(j * 8) / 8.0 establishedChords = parts[active].getElementsByOffset(jQuant) if len(establishedChords) == 0: @@ -123,7 +123,7 @@ def pendulumMusic(show=True, c = establishedChords[0] c.append(p) - j += loopLength/(maxNotesPerLoop - totalParts + i) + j += loopLength / (maxNotesPerLoop - totalParts + i) # j += (8+(8-i))/8.0 p = octo.next(p, stepSize=scaleStepSize) diff --git a/music21_tools/composition/seeger.py b/music21_tools/composition/seeger.py index b382a30..4a2c914 100644 --- a/music21_tools/composition/seeger.py +++ b/music21_tools/composition/seeger.py @@ -76,7 +76,7 @@ def lowerLines(): # retrograde totalNotes = len(myRow) for i in range(2, totalNotes + 1): # skip last note - el = myRow[totalNotes-i] + el = myRow[totalNotes - i] if 'Note' in el.classes: elNote = el.transpose('A1') elNote.pitch.simplifyEnharmonic(inPlace=True) diff --git a/music21_tools/contour/contour.py b/music21_tools/contour/contour.py index 84b40d8..0bfb49c 100644 --- a/music21_tools/contour/contour.py +++ b/music21_tools/contour/contour.py @@ -273,7 +273,7 @@ def _normalizeContour(self, contourDict, maxKey): myKeys.sort() numKeys = len(myKeys) - spacing = (maxKey)/(numKeys-1.0) + spacing = (maxKey) / (numKeys - 1.0) res = {} i = 0.0 @@ -363,14 +363,14 @@ def _calcGenericMetric(self, inpStream, chordMetric): ''' score = 0 - n=0 + n = 0 for measure in inpStream: if 'Measure' in measure.classes: for chord in measure: if 'Chord' in chord.classes: dur = chord.duration.quarterLength - score += chordMetric(chord)*dur + score += chordMetric(chord) * dur n += dur if n != 0: @@ -395,7 +395,7 @@ def dissonanceMetric(self, inpStream): True ''' - return self._calcGenericMetric(inpStream, lambda x: 1-x.isConsonant() ) + return self._calcGenericMetric(inpStream, lambda x: 1 - x.isConsonant() ) def spacingMetric(self, inpStream): ''' @@ -416,8 +416,8 @@ def spacingForChord(chord): return (pitches[1] - pitches[0]) else: res += (pitches[1] - pitches[0]) ** (0.7) - for i in range(1, len(pitches)-1): - res += (pitches[i + 1]-pitches[i]) ** (1.5) + for i in range(1, len(pitches) - 1): + res += (pitches[i + 1] - pitches[i]) ** (1.5) return res return self._calcGenericMetric(inpStream, spacingForChord) @@ -733,7 +733,7 @@ def _runExperiment(): print(currentNum) - currentNum +=1 + currentNum += 1 # ''' # if chorale == 'bach/bwv277': @@ -759,7 +759,7 @@ def _runExperiment(): # print("too long") # continue # ''' - cf= ContourFinder(chorale) + cf = ContourFinder(chorale) ac.addPieceToContour(cf, 'dissonance') ac.addPieceToContour(cf, 'tonality') ac.addPieceToContour(cf, 'spacing') diff --git a/music21_tools/counterpoint/species.py b/music21_tools/counterpoint/species.py index 6eb06ac..bac2f91 100644 --- a/music21_tools/counterpoint/species.py +++ b/music21_tools/counterpoint/species.py @@ -125,7 +125,7 @@ def findHiddenFifths(self, stream1, stream2): 2 ''' numHiddenFifths = 0 - for i in range(len(stream1.notes)-1): + for i in range(len(stream1.notes) - 1): note1 = stream1.notes[i] note2 = stream1.getElementAfterElement(note1, [Note]) note3 = stream2.playingWhenAttacked(note1) @@ -300,7 +300,7 @@ def findHiddenOctaves(self, stream1, stream2): ''' numHiddenOctaves = 0 - for i in range(len(stream1.notes)-1): + for i in range(len(stream1.notes) - 1): note1 = stream1.notes[i] note2 = stream1.getElementAfterElement(note1, [Note]) note3 = stream2.playingWhenAttacked(note1) @@ -750,7 +750,7 @@ def countBadSteps(self, stream1): ''' numBadSteps = 0 sn = stream1.notes - for i in range(len(sn)-1): + for i in range(len(sn) - 1): note1 = sn[i] note2 = sn[i + 1] if note2 is not None: diff --git a/music21_tools/featureExtraction/ismir2011.py b/music21_tools/featureExtraction/ismir2011.py index 4943419..a5b0833 100644 --- a/music21_tools/featureExtraction/ismir2011.py +++ b/music21_tools/featureExtraction/ismir2011.py @@ -174,7 +174,7 @@ def xtestChinaEuropeSimpler(): knnWrong += 1 total = float(len(testData)) - print (majWrong/total, knnWrong/total) + print (majWrong / total, knnWrong / total) def prepareTrecentoCadences(): @@ -232,7 +232,7 @@ def testTrecentoSimpler(): knnWrong += 1 total = float(len(testData)) - print (majWrong/total, knnWrong/total) + print (majWrong / total, knnWrong / total) def wekaCommands(): ''' diff --git a/music21_tools/misc/eschbeg.py b/music21_tools/misc/eschbeg.py index 5c90fe9..f5ccc73 100644 --- a/music21_tools/misc/eschbeg.py +++ b/music21_tools/misc/eschbeg.py @@ -222,7 +222,7 @@ def findEmbeddedChords(testSet='0234589', cardinality=3, skipInverse=False): for myPitch in myPitches: myInverse.append(11 - myPitch) myInverseMin = min(myInverse) - for i,p in enumerate(myInverse): + for i, p in enumerate(myInverse): myInverse[i] = p - myInverseMin myInverse = sorted(myInverse) myInverseString = ''.join([str(p) for p in myInverse]) diff --git a/music21_tools/misc/gatherAccidentals.py b/music21_tools/misc/gatherAccidentals.py index 4d99e6b..fef8681 100644 --- a/music21_tools/misc/gatherAccidentals.py +++ b/music21_tools/misc/gatherAccidentals.py @@ -122,7 +122,7 @@ def getAccidentalCount(score, includeNonAccidentals=False, excludeZeros=True): accidental = p.accidental if accidental is None: if includeNonAccidentals: - tally['natural'] +=1 + tally['natural'] += 1 continue tally[accidental.name] += 1 return _deleteZeros(tally, excludeZeros) diff --git a/music21_tools/misc/monteverdi.py b/music21_tools/misc/monteverdi.py index f7650ea..30e8415 100644 --- a/music21_tools/misc/monteverdi.py +++ b/music21_tools/misc/monteverdi.py @@ -58,11 +58,11 @@ def analyzeBooks(books=(3,), start=1, end=20, show=False, strict=False): filename = 'monteverdi/madrigal.%s.%s.rntxt' % (book, i) if strict == True: analysis = corpus.parse(filename) - print(book,i) + print(book, i) else: try: analysis = corpus.parse(filename) - print(book,i) + print(book, i) except Exception: print('Cannot parse %s, maybe it does not exist...' % (filename)) continue @@ -193,11 +193,11 @@ def monteverdiParallels(books=(3,), start=1, end=20, show=True, strict=False): filename = 'monteverdi/madrigal.%s.%s.xml' % (book, i) if strict == True: c = corpus.parse(filename) - print (book,i) + print (book, i) else: try: c = corpus.parse(filename) - print (book,i) + print (book, i) except: print ('Cannot parse %s, maybe it does not exist...' % (filename)) continue diff --git a/music21_tools/theory/mgtaPart1.py b/music21_tools/theory/mgtaPart1.py index a7c5ccf..482c5cd 100644 --- a/music21_tools/theory/mgtaPart1.py +++ b/music21_tools/theory/mgtaPart1.py @@ -62,7 +62,7 @@ def ch1_basic_I_B(show=True, *arguments, **keywords): ''' pitches = [('a#', 'b'), ('b-', 'c#'), ('g-', 'a'), ('d-', 'c##'), ('f', 'e'), ('f#', 'e')] - for i,j in pitches: + for i, j in pitches: n1 = note.Note(i) n2 = note.Note(j) i1 = interval.notesToInterval(n1, n2) @@ -550,10 +550,10 @@ def ch2_basic_I_A_1(show=True, *arguments, **keywords): ex = stream.Stream() ex.insert(key.KeySignature(1)) - data = [[('d6',1.5)], - [('d6',1.5)], - [('d6',.5),('c6',.5),('b5',.5)], - [('rest',.5),('b5',.25),('c6',.25),('d6',.5)], + data = [[('d6', 1.5)], + [('d6', 1.5)], + [('d6', .5), ('c6', .5), ('b5', .5)], + [('rest', .5), ('b5', .25), ('c6', .25), ('d6', .5)], ] for mData in data: @@ -924,7 +924,7 @@ def ch2_writing_III_B(src): group.append(n) else: # end of tied notes group.append(n) - ql= sum([x.quarterLength for x in group]) + ql = sum([x.quarterLength for x in group]) for i in range(len(group)): if i == 0: # keep first, extend dur group[i].quarterLength = ql @@ -1589,12 +1589,12 @@ def ch5_writing_IV_A(show=True, *arguments, **keywords): ex.insert(meter.TimeSignature('6/4')) ex.insert(key.KeySignature(3)) - for p, d in [(None,1), ('f#3',1),('g#3',1),('a3',4), - ('g#3',.5),('a#3',.5),('b3',2), - ('a#3',.5),('g#3',.5),('a#3',.5),('b#3',.5), - ('c#4',1.5),('b3',.5),('a3',.5),('c#4',.5),('b3',.5),('a3',.5), - ('g#3',2),('f#3',3), (None,.5), ('c#4',.5),('c#4',.5), - ('b3',.5),('b3',.5),('a#3',.5)]: + for p, d in [(None, 1), ('f#3', 1), ('g#3', 1), ('a3', 4), + ('g#3', .5), ('a#3', .5), ('b3', 2), + ('a#3', .5), ('g#3', .5), ('a#3', .5), ('b#3', .5), + ('c#4', 1.5), ('b3', .5), ('a3', .5), ('c#4', .5), ('b3', .5), ('a3', .5), + ('g#3', 2), ('f#3', 3), (None, .5), ('c#4', .5), ('c#4', .5), + ('b3', .5), ('b3', .5), ('a#3', .5)]: if p == None: n = note.Rest() else: diff --git a/music21_tools/theoryAnalysis/theoryAnalyzer.py b/music21_tools/theoryAnalysis/theoryAnalyzer.py index 8dfec42..879db10 100644 --- a/music21_tools/theoryAnalysis/theoryAnalyzer.py +++ b/music21_tools/theoryAnalysis/theoryAnalyzer.py @@ -326,7 +326,7 @@ def getVerticalities(self, score, classFilterList=('Note', 'Chord', 'Harmony', ' # 'Note', 'Rest', 'Chord', 'Harmony']) for el in elementStream.elements: contentDict[partNum].append(el) - partNum +=1 + partNum += 1 else: elementStream = score.flatten().getElementsByOffset(c.offset, mustBeginInSpan=False, @@ -650,7 +650,7 @@ def getMelodicIntervals(self, score, partNum): ''' mInvList = [] noteList = score.parts[partNum].flatten().getElementsByClass(['Note', 'Rest']) - for (i,n1) in enumerate(noteList[:-1]): + for (i, n1) in enumerate(noteList[:-1]): n2 = noteList[i + 1] if 'Note' in n1.classes and 'Note' in n2.classes: @@ -774,7 +774,7 @@ def _identifyBasedOnVLQ(self, score, partNum1, partNum2, dictKey, else: vlqList = self.getVLQs(score, partNum1, partNum2) - if endIndex is None and startIndex >=0: + if endIndex is None and startIndex >= 0: endIndex = len(vlqList) for vlq in vlqList[startIndex:endIndex]: @@ -1201,7 +1201,7 @@ def identifyHiddenFifths(self, score, partNum1=None, partNum2=None, testFunction = lambda vlq: vlq.hiddenFifth() textFunction = lambda vlq, pn1, pn2: ('Hidden fifth in measure ' - + str(vlq.v1n1.measureNumber) +': ' + + str(vlq.v1n1.measureNumber) + ': ' + 'Part ' + str(pn1 + 1) + ' moves from ' + vlq.v1n1.name + ' to ' + vlq.v1n2.name @@ -1697,7 +1697,7 @@ def identifyNeighborTones(self, score, partNumToIdentify=None, color=None, dictK ' identified as a neighbor tone in part ' + str(pn + 1)) self._identifyBasedOnVerticalityNTuplet(score, partNumToIdentify, dictKey, testFunction, textFunction, color, editorialDictKey, editorialValue, - editorialMarkDict={1:[partNumToIdentify]}, nTupletNum=3) + editorialMarkDict={1: [partNumToIdentify]}, nTupletNum=3) def identifyDissonantHarmonicIntervals(self, score, partNum1=None, partNum2=None, color=None, dictKey='dissonantHarmonicIntervals'): @@ -1814,7 +1814,7 @@ def identifyImproperDissonantIntervals(self, score, partNum1=None, partNum2=None tr = theoryResult.IntervalTheoryResult(intv) #tr.value = valueFunction(hIntv) tr.text = ('Improper dissonant harmonic interval in measure ' + - str(intv.noteStart.measureNumber) +': ' + + str(intv.noteStart.measureNumber) + ': ' + str(intv.niceName) + ' from ' + str(intv.noteStart.name) + ' to ' + str(intv.noteEnd.name) + ' between part ' + str(partNum1 + 1) + @@ -1863,7 +1863,7 @@ def identifyDissonantMelodicIntervals(self, score, partNum=None, color=None, testFunction = lambda mIntv: mIntv is not None and mIntv.simpleName in [ 'A2', 'A4', 'd5', 'm7', 'M7'] textFunction = lambda mIntv, pn: ('Dissonant melodic interval in part ' + str(pn + 1) + - ' measure ' + str(mIntv.noteStart.measureNumber) +': ' + + ' measure ' + str(mIntv.noteStart.measureNumber) + ': ' + str(mIntv.simpleNiceName) + ' from ' + str(mIntv.noteStart.name) + ' to ' + str(mIntv.noteEnd.name)) @@ -1880,7 +1880,7 @@ def identifyObliqueMotion(self, score, partNum1=None, partNum2=None, color=None) dictKey = 'obliqueMotion' testFunction = lambda vlq: vlq.obliqueMotion() textFunction = lambda vlq, pn1, pn2: ('Oblique motion in measure ' + - str(vlq.v1n1.measureNumber) +': ' + + str(vlq.v1n1.measureNumber) + ': ' + 'Part ' + str(pn1 + 1) + ' moves from ' + vlq.v1n1.name + ' to ' + vlq.v1n2.name + ' ' + 'while part ' + str(pn2 + 1) + ' moves from ' + @@ -1892,11 +1892,11 @@ def identifySimilarMotion(self, score, partNum1=None, partNum2=None, color=None) dictKey = 'similarMotion' testFunction = lambda vlq: vlq.similarMotion() textFunction = lambda vlq, pn1, pn2: ('Similar motion in measure ' + - str(vlq.v1n1.measureNumber) +': ' + + str(vlq.v1n1.measureNumber) + ': ' + 'Part ' + str(pn1 + 1) + ' moves from ' + vlq.v1n1.name + ' to ' + vlq.v1n2.name + ' ' + 'while part ' + str(pn2 + 1) + ' moves from ' + - vlq.v2n1.name+ ' to ' + vlq.v2n2.name) + vlq.v2n1.name + ' to ' + vlq.v2n2.name) self._identifyBasedOnVLQ(score, partNum1, partNum2, dictKey, testFunction, textFunction, color) @@ -1904,11 +1904,11 @@ def identifyParallelMotion(self, score, partNum1=None, partNum2=None, color= Non dictKey = 'parallelMotion' testFunction = lambda vlq: vlq.parallelMotion() textFunction = lambda vlq, pn1, pn2: ('Parallel motion in measure ' + - str(vlq.v1n1.measureNumber) +': ' + + str(vlq.v1n1.measureNumber) + ': ' + 'Part ' + str(pn1 + 1) + ' moves from ' + vlq.v1n1.name + ' to ' + vlq.v1n2.name + ' ' + 'while part ' + str(pn2 + 1) + ' moves from ' + - vlq.v2n1.name+ ' to ' + vlq.v2n2.name) + vlq.v2n1.name + ' to ' + vlq.v2n2.name) self._identifyBasedOnVLQ(score, partNum1, partNum2, dictKey, testFunction, textFunction, color) @@ -1920,7 +1920,7 @@ def identifyContraryMotion(self, score, partNum1=None, partNum2=None, color=None 'Part ' + str(pn1 + 1) + ' moves from ' + vlq.v1n1.name + ' to ' + vlq.v1n2.name + ' ' + 'while part ' + str(pn2 + 1) + ' moves from ' + - vlq.v2n1.name+ ' to ' + vlq.v2n2.name) + vlq.v2n1.name + ' to ' + vlq.v2n2.name) self._identifyBasedOnVLQ(score, partNum1, partNum2, dictKey, testFunction, textFunction, color) @@ -1933,7 +1933,7 @@ def identifyOutwardContraryMotion(self, score, partNum1=None, partNum2=None, col vlq.v1n1.name + ' to ' + vlq.v1n2.name + ' ' + 'while part ' + str(pn2 + 1) + ' moves from ' + - vlq.v2n1.name+ ' to ' + vlq.v2n2.name) + vlq.v2n1.name + ' to ' + vlq.v2n2.name) self._identifyBasedOnVLQ(score, partNum1, partNum2, dictKey, testFunction, textFunction, color) @@ -1945,7 +1945,7 @@ def identifyInwardContraryMotion(self, score, partNum1=None, partNum2=None, colo 'Part ' + str(pn1 + 1) + ' moves from ' + vlq.v1n1.name + ' to ' + vlq.v1n2.name + ' ' + 'while part ' + str(pn2 + 1) + ' moves from ' + - vlq.v2n1.name+ ' to ' + vlq.v2n2.name) + vlq.v2n1.name + ' to ' + vlq.v2n2.name) self._identifyBasedOnVLQ(score, partNum1, partNum2, color, dictKey, testFunction, textFunction) @@ -1953,11 +1953,11 @@ def identifyAntiParallelMotion(self, score, partNum1=None, partNum2=None, color= dictKey = 'antiParallelMotion' testFunction = lambda vlq: vlq.antiParallelMotion() textFunction = lambda vlq, pn1, pn2: ('Anti-parallel motion in measure ' + - str(vlq.v1n1.measureNumber) +': ' + + str(vlq.v1n1.measureNumber) + ': ' + 'Part ' + str(pn1 + 1) + ' moves from ' + vlq.v1n1.name + ' to ' + vlq.v1n2.name + ' ' + 'while part ' + str(pn2 + 1) + ' moves from ' + - vlq.v2n1.name+ ' to ' + vlq.v2n2.name) + vlq.v2n1.name + ' to ' + vlq.v2n2.name) self._identifyBasedOnVLQ(score, partNum1, partNum2, dictKey, testFunction, textFunction, color) @@ -2207,12 +2207,12 @@ def identifyMotionType(self, score, partNum1=None, partNum2=None, ''' testFunction = lambda vlq: vlq.motionType().value - textFunction = lambda vlq, pn1, pn2: (vlq.motionType().value + ' Motion in measure '+ + textFunction = lambda vlq, pn1, pn2: (vlq.motionType().value + ' Motion in measure ' + str(vlq.v1n1.measureNumber) + ': ' + 'Part ' + str(pn1 + 1) + ' moves from ' + vlq.v1n1.name + ' to ' + vlq.v1n2.name + ' ' + 'while part ' + str(pn2 + 1) + ' moves from ' + - vlq.v2n1.name+ ' to ' + vlq.v2n2.name) if ( + vlq.v2n1.name + ' to ' + vlq.v2n2.name) if ( vlq.motionType() != 'No Motion') else 'No motion' self._identifyBasedOnVLQ(score, partNum1, partNum2, dictKey, testFunction, textFunction, color) @@ -2241,7 +2241,7 @@ def identifyCommonPracticeErrors(self, score, partNum1=None, partNum2=None, #self.identifyLeapNotSetWithStep(score, partNum1, partNum2, 'white', dictKey) self.identifyImproperDissonantIntervals(score, partNum1, partNum2, 'white', dictKey, unaccentedOnly = True) - self.identifyDissonantMelodicIntervals(score, partNum1,'cyan', dictKey) + self.identifyDissonantMelodicIntervals(score, partNum1, 'cyan', dictKey) self.identifyOpensIncorrectly(score, partNum1, partNum2, 'brown', dictKey) self.identifyClosesIncorrectly(score, partNum1, partNum2, 'gray', dictKey) @@ -2308,7 +2308,7 @@ def getHTMLResultsString(self, score, typeList=None): resultStr += '' + resultType + ':
    ' for result in self.store[sid]['ResultDict'][resultType]: resultStr += ("
  • " + - result.text.sub(':',":") + + result.text.sub(':', ":") + '
  • ') resultStr += '

' diff --git a/music21_tools/theoryAnalysis/theoryResult.py b/music21_tools/theoryAnalysis/theoryResult.py index 456ffb6..a15e4e7 100644 --- a/music21_tools/theoryAnalysis/theoryResult.py +++ b/music21_tools/theoryAnalysis/theoryResult.py @@ -30,7 +30,7 @@ def __init__(self): self.value = '' self.currentColor = '' - def color(self,color): + def color(self, color): ''' Bass-class method to color the individual elements in the theory result object. Polymorphically colors the theory result objects based on the type of object. @@ -260,7 +260,7 @@ def color(self, color ='red', partNum=None, noteList=None): self.vsnt.tnlsDict.keys()) if self.vsnt.nTupletNum == 3: self.vsnt.tnlsDict[partNum].color(color) - elif self.partNumIdentified !=None: + elif self.partNumIdentified != None: if self.vsnt.nTupletNum == 3: self.vsnt.tnlsDict[self.partNumIdentified].color(color, [2] ) @@ -273,7 +273,7 @@ def markNoteEditorial(self, editorialDictKey, editorialValue, editorialMarkDict= Default editorialMarkDict = {2:[1]} ''' if editorialMarkDict is None: - editorialMarkDict = {2:[1]} + editorialMarkDict = {2: [1]} for vsNum, partNumList in editorialMarkDict.items(): for unused_counter_partNum in partNumList: self.vsnt.verticalities[vsNum].getObjectsByPart(0, diff --git a/music21_tools/theoryAnalysis/wwnortonMGTA.py b/music21_tools/theoryAnalysis/wwnortonMGTA.py index 9364e3a..61ca0db 100644 --- a/music21_tools/theoryAnalysis/wwnortonMGTA.py +++ b/music21_tools/theoryAnalysis/wwnortonMGTA.py @@ -55,12 +55,12 @@ def loadOriginalExercise(self): self.modifiedExercise = copy.deepcopy(self.originalExercise) self.addAuxillaryParts() - def manuallyLoadOriginalExercise(self,sc): + def manuallyLoadOriginalExercise(self, sc): self.originalExercise = sc self.modifiedExercise = copy.deepcopy(self.originalExercise) self.addAuxillaryParts() - def loadStudentExercise(self,sc): + def loadStudentExercise(self, sc): for n in sc.flatten().getElementsByClass('Note'): n.color = 'black' self.studentExercise = sc @@ -69,12 +69,12 @@ def getBlankExercise(self): return self.blankExercise def _partOffsetsToPartIndecies(self): - for (i,el) in enumerate(self.modifiedExercise.elements): + for (i, el) in enumerate(self.modifiedExercise.elements): el.offset = i #self.modifiedExercise.show('text') def _partOffsetsToZero(self): - for (i,el) in enumerate(self.modifiedExercise.elements): + for (i, el) in enumerate(self.modifiedExercise.elements): el.offset = 0 #self.modifiedExercise.show('text') @@ -83,7 +83,7 @@ def _updatepn(self, newPartNum, direction): existingPartNum = self.pn[partName] if existingPartNum > newPartNum: shiftedPartNum = existingPartNum + 1 - elif existingPartNum == newPartNum and direction =='above': + elif existingPartNum == newPartNum and direction == 'above': shiftedPartNum = existingPartNum + 1 else: shiftedPartNum = existingPartNum @@ -144,14 +144,14 @@ def addMarkerPartFromExisting(self, existingPartName, newPartName, newPartTitle= for c in newPart.flatten().getElementsByClass('Clef'): c.sign = 'C' c.line = 3 - self._updatepn(partNum,direction=direction) + self._updatepn(partNum, direction=direction) if direction == 'above': insertLoc = existingPartOffset - 0.5 self.pn[newPartName] = partNum elif direction == 'below' or direction is None: insertLoc = existingPartOffset + 0.5 self.pn[newPartName] = partNum + 1 - self.modifiedExercise.insert(insertLoc,newPart) + self.modifiedExercise.insert(insertLoc, newPart) #self.modifiedExercise.show('text') # Somehow needed for sorting... self.modifiedExercise._reprText() @@ -208,13 +208,13 @@ def addAuxillaryParts(self): direction='below') def checkExercise(self): - self.ads.setKeyMeasureMap(self.studentExercise,{0:'F'}) + self.ads.setKeyMeasureMap(self.studentExercise, {0: 'F'}) self.ads.identifyMotionType(self.studentExercise, self.pn['part1'], - self.pn['part2'],dictKey='motionType') + self.pn['part2'], dictKey='motionType') self.ads.identifyScaleDegrees(self.studentExercise, self.pn['part1'], dictKey='p1ScaleDegrees') self.ads.identifyHarmonicIntervals(self.studentExercise, self.pn['part1'], - self.pn['part2'],dictKey='harmIntervals') + self.pn['part2'], dictKey='harmIntervals') scaleDegreeOffsetFunc = lambda resultObj: resultObj.n.offset scaleDegreeLyricTextFunc = lambda resultObj: resultObj.value @@ -262,7 +262,7 @@ def addAuxillaryParts(self): direction = 'below') def checkExercise(self): - self.ads.setKeyMeasureMap(self.studentExercise, {0:'G', 5:'D', 8:'F'}) + self.ads.setKeyMeasureMap(self.studentExercise, {0: 'G', 5: 'D', 8: 'F'}) self.ads.identifyHarmonicIntervals(self.studentExercise, self.pn['part1'], self.pn['part2'], dictKey='harmIntervals') self.ads.identifyCommonPracticeErrors(self.studentExercise, self.pn['part1'], diff --git a/music21_tools/trecento/cadenceProbabilities.py b/music21_tools/trecento/cadenceProbabilities.py index 8a51c70..4a4d557 100644 --- a/music21_tools/trecento/cadenceProbabilities.py +++ b/music21_tools/trecento/cadenceProbabilities.py @@ -58,8 +58,8 @@ def getLandiniRandomStart(i): def countCadencePercentages(): ballatas = cadencebook.BallataSheet() totalPieces = 0.0 - firstNoteTotal = defaultdict(lambda:0) - lastNoteTotal = defaultdict(lambda:0) + firstNoteTotal = defaultdict(lambda: 0) + lastNoteTotal = defaultdict(lambda: 0) for thisWork in ballatas: incipit = thisWork.incipit diff --git a/music21_tools/trecento/cadencebook.py b/music21_tools/trecento/cadencebook.py index 227a0e4..3a33fb1 100644 --- a/music21_tools/trecento/cadencebook.py +++ b/music21_tools/trecento/cadencebook.py @@ -530,7 +530,7 @@ def getOtherSnippets(self): beginSnippetPositions = self.beginSnippetPositions endSnippetPositions = self.endSnippetPositions # overridden in class Ballata if not endSnippetPositions: - endSnippetPositions = range(12, len(self.rowvalues)-1, 5) + endSnippetPositions = range(12, len(self.rowvalues) - 1, 5) returnSnips = [] for i in beginSnippetPositions: if i == beginSnippetPositions[0]: diff --git a/music21_tools/trecento/medren.py b/music21_tools/trecento/medren.py index 281bc4d..a92a705 100644 --- a/music21_tools/trecento/medren.py +++ b/music21_tools/trecento/medren.py @@ -68,7 +68,7 @@ (4, False)], } -_validMensuralTypes = [None,'maxima', 'longa', 'brevis', 'semibrevis', 'minima', 'semiminima'] +_validMensuralTypes = [None, 'maxima', 'longa', 'brevis', 'semibrevis', 'minima', 'semiminima'] _validMensuralAbbr = [None, 'Mx', 'L', 'B', 'SB', 'M', 'SM'] @@ -1479,11 +1479,11 @@ def setStem(self, index, direction, orientation): self.stems[index] = (direction, orientation) elif orientation in ['left', 'right']: if index == 0: - prevStem = (None,None) + prevStem = (None, None) nextStem = self.getStem(1) elif index == self._ligatureLength() - 1: prevStem = self.getStem(self._ligatureLength() - 2) - nextStem = (None,None) + nextStem = (None, None) else: prevStem = self.getStem(index - 1) nextStem = self.getStem(index + 1) @@ -1514,11 +1514,11 @@ def setStem(self, index, direction, orientation): else: raise MedRenException( 'a stem with orientation "%s" not permitted at index %d' % - (orientation,index)) + (orientation, index)) else: raise MedRenException( 'direction "%s" and orientation "%s" not supported for ligatures' % - (direction,orientation)) + (direction, orientation)) self._notes = [] def isReversed(self, index): diff --git a/music21_tools/trecento/notation.py b/music21_tools/trecento/notation.py index 29b1a3d..8a8ba72 100644 --- a/music21_tools/trecento/notation.py +++ b/music21_tools/trecento/notation.py @@ -118,8 +118,8 @@ def postParse(self, n): class FlagsModifier(tinyNotation.Modifier): def postParse(self, m21Obj): - direction = {'': None, 'S': 'side', 'D': 'down', 'U':'up'} - orientation = {'': None,'L': 'left', 'R': 'right'} + direction = {'': None, 'S': 'side', 'D': 'down', 'U': 'up'} + orientation = {'': None, 'L': 'left', 'R': 'right'} for flag in self.modifierData.split('/'): if len(flag) > 1 and (flag[0] in direction) and (flag[1] in orientation): m21Obj.setFlag(direction[flag[0]], orientation[flag[1]]) @@ -129,7 +129,7 @@ def postParse(self, m21Obj): class StemsModifier(tinyNotation.Modifier): def postParse(self, m21Obj): - direction = {'': None, 'S': 'side', 'D': 'down', 'U':'up'} + direction = {'': None, 'S': 'side', 'D': 'down', 'U': 'up'} orientation = {'L': 'left', 'R': 'right'} if '/' in self.modifierData or len(self.modifierData) == 1: for stem in self.modifierData.split('/'): @@ -680,7 +680,7 @@ def convertBrevisLength(brevisLength, convertedStream, inpDiv=None, measureNumOf m.append(startNote) measureList.append(m) - for dummy in range(int(lenList[0]/div.minimaPerBrevis) - 2): + for dummy in range(int(lenList[0] / div.minimaPerBrevis) - 2): measureNumOffset += 1 tempMeasure = stream.Measure(number=brevisLength.number + measureNumOffset) @@ -705,7 +705,7 @@ def convertBrevisLength(brevisLength, convertedStream, inpDiv=None, measureNumOf elif 'MensuralNote' in mList[i].classes: n = note.Note(mList[i].pitch) - dur = lenList[i]*mDur + dur = lenList[i] * mDur if (rem - dur) > -0.0001: #Fits w/i measure up to rounding error n.duration = duration.Duration(dur) @@ -764,11 +764,11 @@ def __init__(self, divisione=None, BL=None, pDS=False): self.brevisLength = BL self.unchangeableNoteLengthsList = [] - self.unknownLengthsDict = {'semibrevis':[], - 'semibrevis_downstem':[], - 'semiminima_right_flag':[], - 'seminima_left_flag':[], - 'semiminima_rest':[] + self.unknownLengthsDict = {'semibrevis': [], + 'semibrevis_downstem': [], + 'semiminima_right_flag': [], + 'seminima_left_flag': [], + 'semiminima_rest': [] } self.knownLengthsList = [] @@ -817,7 +817,7 @@ def getBreveStrength(self, lengths): ''' div = self.div BL = self.brevisLength - typeStrength = {'semibrevis': 1.0, 'minima': 0.5, 'semiminima':0.25} + typeStrength = {'semibrevis': 1.0, 'minima': 0.5, 'semiminima': 0.25} beatStrength = 0 strength = 0 @@ -830,9 +830,9 @@ def getBreveStrength(self, lengths): if math.isclose(curBeat % 3, 0): beatStrength = 1.0 elif curBeat % 3 - 1 or i % 3 == 2: - beatStrength = 1/3 + beatStrength = 1 / 3 else: - beatStrength = 1/9 + beatStrength = 1 / 9 elif div.standardSymbol in ['.q.', '.o.', '.d.']: if curBeat % 4 == 0: beatStrength = 1.0 @@ -1095,11 +1095,11 @@ def classifyUnknownNotesByType(self, unchangeableNoteLengthsList): if 'MensuralRest' in obj.classes: semiminima_rest_list.append(i) - retDict = {'semibrevis':semibrevis_list, - 'semibrevis_downstem':semibrevis_downstem, - 'semiminima_right_flag':semiminima_right_flag_list, - 'semiminima_left_flag':semiminima_left_flag_list, - 'semiminima_rest':semiminima_rest_list, + retDict = {'semibrevis': semibrevis_list, + 'semibrevis_downstem': semibrevis_downstem, + 'semiminima_right_flag': semiminima_right_flag_list, + 'semiminima_left_flag': semiminima_left_flag_list, + 'semiminima_rest': semiminima_rest_list, } self.numberOfSemibreves = len(retDict['semibrevis']) @@ -1188,13 +1188,13 @@ def translateDivI(self, unchangeableNoteLengthsList=None, unknownLengthsDict=Non knownLengthsList = unchangeableNoteLengthsList[:] if self.numberOfSemibreves > 0: - avgSBLength = minRem/self.numberOfSemibreves + avgSBLength = minRem / self.numberOfSemibreves for ind in semibrevis_list: if avgSBLength == 2: knownLengthsList[ind] = 2.0 minRem -= 2.0 elif (2 < avgSBLength) and (avgSBLength < 3): - if (ind < (len(self.brevisLength)-1) and + if (ind < (len(self.brevisLength) - 1) and self.brevisLength[ind + 1].mensuralType == 'minima'): knownLengthsList[ind] = 2.0 minRem -= 2.0 @@ -1316,7 +1316,7 @@ def translateDivN(self, unchangeableNoteLengthsList=None, unknownLengthsDict=Non knownLengthsList[semibrevis_list[-1]] = max(minRem, 3.0) minRem -= knownLengthsList[-1] - extend_num = min(knownLengthsList[-1]- 3, len(extend_list)) + extend_num = min(knownLengthsList[-1] - 3, len(extend_list)) shrink_tup += -1, elif self.numberOfSemibreves > 0: #SBs, but no last SB @@ -1468,7 +1468,7 @@ def translateDivPQ(self, unchangeableNoteLengthsList=None, diff_tup = () shrink_tup = () - lengths = [(0.5, 0.5), (2/3, 0.5), (0.5, 2/3), (2/3, 2/3)] + lengths = [(0.5, 0.5), (2 / 3, 0.5), (0.5, 2 / 3), (2 / 3, 2 / 3)] for (left_length, right_length) in lengths: for ind in semiminima_left_flag_list: @@ -1556,7 +1556,7 @@ def translateDivPQ(self, unchangeableNoteLengthsList=None, knownLengthsList_changeable[semibrevis_downstem_index] = max( minRem_changeable, 2.0) - extend_num = min(6*minRem_changeable - 15.0, len(extend_list)) + extend_num = min(6 * minRem_changeable - 15.0, len(extend_list)) minRem_changeable -= knownLengthsList_changeable[semibrevis_downstem_index] shrink_tup += (semibrevis_downstem_index,) @@ -1566,7 +1566,7 @@ def translateDivPQ(self, unchangeableNoteLengthsList=None, knownLengthsList_changeable[semibrevis_list[-1]] = max( minRem_changeable, 2.0) - extend_num = min(6*minRem_changeable - 12.0, len(extend_list)) + extend_num = min(6 * minRem_changeable - 12.0, len(extend_list)) minRem_changeable -= max(minRem_changeable, 2.0) shrink_tup += -1, @@ -1578,7 +1578,7 @@ def translateDivPQ(self, unchangeableNoteLengthsList=None, change_tup += (extend_list,) num_tup += (extend_num,) - diff_tup += (1/6,) + diff_tup += (1 / 6,) if minRem_changeable > -0.0001: knownLengthsList_changeable, minRem_changeable = ( @@ -1731,7 +1731,7 @@ def translateDivOD(self, unchangeableNoteLengthsList=None, else: - lengths = [(0.5, 0.5), (2/3, 0.5), (0.5, 2/3), (2/3, 2/3)] + lengths = [(0.5, 0.5), (2 / 3, 0.5), (0.5, 2 / 3), (2 / 3, 2 / 3)] strength = 0 for (left_length, right_length) in lengths: @@ -1845,7 +1845,7 @@ def translateDivOD(self, unchangeableNoteLengthsList=None, change_tup += extend_list_1, extend_list_2 num_tup += extend_num_1, extend_num_2 - diff_tup += (2.0, 1/6) + diff_tup += (2.0, 1 / 6) if minRem_changeable > -0.0001: knownLengthsList_changeable, minRem_changeable = ( @@ -1887,7 +1887,7 @@ def _allCombinations(combinationList, num): if num > 0: for i in range(len(combinationList)): comb = [combinationList[i]] - for c in _allCombinations(combinationList[(i + 1):], num-1): + for c in _allCombinations(combinationList[(i + 1):], num - 1): combs.append(comb + c) combs.reverse() combs.insert(0, []) diff --git a/music21_tools/trecento/polyphonicSnippet.py b/music21_tools/trecento/polyphonicSnippet.py index f1ee0ce..5b4805d 100644 --- a/music21_tools/trecento/polyphonicSnippet.py +++ b/music21_tools/trecento/polyphonicSnippet.py @@ -204,7 +204,7 @@ def measuresShort(self, thisStream): timeSigLength = self.timeSig.barDuration.quarterLength thisStreamLength = thisStream.duration.quarterLength shortness = self.findLongestCadence() - thisStreamLength - shortmeasures = shortness/timeSigLength + shortmeasures = shortness / timeSigLength return shortmeasures diff --git a/music21_tools/trecento/quodJactatur.py b/music21_tools/trecento/quodJactatur.py index e0564e2..f7f4764 100644 --- a/music21_tools/trecento/quodJactatur.py +++ b/music21_tools/trecento/quodJactatur.py @@ -246,7 +246,7 @@ def findRetrogradeVoices(show=True): totIntervals += 1 n.lyric = str(thisScore) - finalScore = int(100*(consScore + 0.0)/totIntervals) + finalScore = int(100 * (consScore + 0.0) / totIntervals) qj.insert(0, qjChords.flatten()) qj2.flatten().notesAndRests[0].addLyric('Trans: ' + str(transpose)) qj2.flatten().notesAndRests[0].addLyric('Invert: ' + str(invert)) @@ -309,7 +309,7 @@ def prepareSolution(triplumTup, ctTup, tenorTup): totIntervals += 1 n.lyric = str(thisScore) - return (qjChords, (consScore/(totIntervals + 0.0)), qjSolved) + return (qjChords, (consScore / (totIntervals + 0.0)), qjSolved) def getStrengthForNote(n): ''' diff --git a/music21_tools/trecento/runTrecentoCadence.py b/music21_tools/trecento/runTrecentoCadence.py index 7e9238c..8cde6f6 100644 --- a/music21_tools/trecento/runTrecentoCadence.py +++ b/music21_tools/trecento/runTrecentoCadence.py @@ -158,7 +158,7 @@ def makePDFfromPiecesWithCapua(start=2, finish=3): def checkValidity(): ballataObj = cadencebook.BallataSheet() - for i in range(1,378): + for i in range(1, 378): randomPiece = ballataObj.makeWork(i) #random.randint(231, 312) try: unused_incipitStreams = randomPiece.incipitStreams() diff --git a/music21_tools/trecento/tonality.py b/music21_tools/trecento/tonality.py index 912b2cc..beeb570 100644 --- a/music21_tools/trecento/tonality.py +++ b/music21_tools/trecento/tonality.py @@ -88,10 +88,10 @@ def run(self): streamName = self.streamName allScores = stream.Opus() - myDict = {'A': defaultdict(lambda:False), 'B': defaultdict(lambda:False), - 'C': defaultdict(lambda:False), 'D': defaultdict(lambda:False), - 'E': defaultdict(lambda:False), 'F': defaultdict(lambda:False), - 'G': defaultdict(lambda:False)} + myDict = {'A': defaultdict(lambda: False), 'B': defaultdict(lambda: False), + 'C': defaultdict(lambda: False), 'D': defaultdict(lambda: False), + 'E': defaultdict(lambda: False), 'F': defaultdict(lambda: False), + 'G': defaultdict(lambda: False)} for thisWork in self.worksList: incip = thisWork.incipit From 368da8e290649c52fa0dfddf5a05e0a54159e474 Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 14:01:00 -1000 Subject: [PATCH 04/28] lint style --- .../audioSearchDemos/humanVScomputer.py | 4 - .../audioSearchDemos/repetitionGame.py | 5 +- music21_tools/bhadley/__init__.py | 6 - music21_tools/bhadley/nips2011.py | 16 +- music21_tools/chant/chant.py | 4 - music21_tools/composition/__init__.py | 6 - music21_tools/composition/aug30.py | 4 - music21_tools/composition/phasing.py | 7 - music21_tools/counterpoint/__init__.py | 3 - music21_tools/counterpoint/species.py | 260 ++++++++---------- music21_tools/featureExtraction/ismir2011.py | 26 +- music21_tools/misc/monteverdi.py | 16 +- music21_tools/theory/mgtaPart1.py | 4 - music21_tools/theoryAnalysis/__init__.py | 4 - .../theoryAnalysis/theoryAnalyzer.py | 122 ++++---- music21_tools/trecento/__init__.py | 9 - .../trecento/cadenceProbabilities.py | 4 - music21_tools/trecento/cadencebook.py | 5 - music21_tools/trecento/findSevs.py | 4 - .../trecento/findTrecentoFragments.py | 6 - music21_tools/trecento/find_vatican1790.py | 4 - music21_tools/trecento/largestAmbitus.py | 4 - music21_tools/trecento/medren.py | 6 +- music21_tools/trecento/polyphonicSnippet.py | 4 - music21_tools/trecento/quodJactatur.py | 10 +- music21_tools/trecento/runTrecentoCadence.py | 4 - music21_tools/trecento/tonality.py | 5 - music21_tools/trecento/trecentoCadence.py | 4 - publications/icmc2010.py | 3 - 29 files changed, 204 insertions(+), 355 deletions(-) diff --git a/music21_tools/audioSearchDemos/humanVScomputer.py b/music21_tools/audioSearchDemos/humanVScomputer.py index be3333d..ab57323 100644 --- a/music21_tools/audioSearchDemos/humanVScomputer.py +++ b/music21_tools/audioSearchDemos/humanVScomputer.py @@ -70,7 +70,3 @@ def runGame(): if __name__ == '__main__': runGame() - - -# ----------------------------------------------------------------------------- -# eof diff --git a/music21_tools/audioSearchDemos/repetitionGame.py b/music21_tools/audioSearchDemos/repetitionGame.py index c0378bd..0df9de7 100644 --- a/music21_tools/audioSearchDemos/repetitionGame.py +++ b/music21_tools/audioSearchDemos/repetitionGame.py @@ -82,8 +82,5 @@ def game(self): if __name__ == '__main__': rG = repetitionGame() good = True - while good == True: + while good: good = rG.game() - -# ----------------------------------------------------------------------------- -# eof diff --git a/music21_tools/bhadley/__init__.py b/music21_tools/bhadley/__init__.py index a4af8a7..e69de29 100644 --- a/music21_tools/bhadley/__init__.py +++ b/music21_tools/bhadley/__init__.py @@ -1,6 +0,0 @@ - - - -# ----------------------------------------------------------------------------- -# eof - diff --git a/music21_tools/bhadley/nips2011.py b/music21_tools/bhadley/nips2011.py index bc3f595..0606db3 100644 --- a/music21_tools/bhadley/nips2011.py +++ b/music21_tools/bhadley/nips2011.py @@ -87,7 +87,7 @@ def nipsBuild(useOurExtractors=True, buildSet=1, evaluationMethod='coarse'): ## ignore 1960s and 1970s pieces... if year < 1961 or year >= 1981: fn = leadsheetDir + str(wf) + '.mxl' - print (fn, year, entryDict[wf][1]) + print(fn, year, entryDict[wf][1]) s = converter.parse(fn) title_id = s.metadata.title #cv = year # if not using coarse but instead using the exact year as the class value @@ -312,7 +312,7 @@ def getLeadsheetDatesFromBillboard(): fn = fn.replace(' ', '0') dst = os.path.join(DIR, fn) dates = [] - print (dst) + print(dst) if os.path.exists(dst): piece = converter.parse(dst) for year in DICT: @@ -336,15 +336,15 @@ def getLeadsheetDatesFromBillboard(): outputjson = outputjson + '{"%s":[%s,%s]}, ' % (i, date, rank) if (i % 500) == 0: j = ((i - 1000) / (11938.00)) * 100.00 - print ('%s %%' % round(j, 2)) - print (outputjson) + print('%s %%' % round(j, 2)) + print(outputjson) foo = len(outputjson) - 2 outputjson = outputjson[0:foo] + "]'" - print (outputjson) - print ('FINISHED! Found this many matches: ', matches) + print(outputjson) + print('FINISHED! Found this many matches: ', matches) def probabilityOfChance(): ''' @@ -430,7 +430,7 @@ def BinomialProbability(n, k, p, q): k = 148 #number of times music21 found correct date (successes) n = TOTAL_TRIALS #total number of trials p = getPFromExperiment() - print ('The probability of a successful guess, as calculated by previous experiment', p) + print('The probability of a successful guess, as calculated by previous experiment', p) q = 1 - p prob = 0.0 #Probability of getting 148 or more correct (sum @@ -438,7 +438,7 @@ def BinomialProbability(n, k, p, q): for k in range(k, TOTAL_TRIALS): prob = prob + BinomialProbability(n, k, p, q) - print ('The probability that the computer would guess correctly 69% or more of the time', prob) + print('The probability that the computer would guess correctly 69% or more of the time', prob) if __name__ == '__main__': #nipsBuild() diff --git a/music21_tools/chant/chant.py b/music21_tools/chant/chant.py index a29f877..7669a57 100644 --- a/music21_tools/chant/chant.py +++ b/music21_tools/chant/chant.py @@ -28,7 +28,6 @@ _MOD = 'chant.py' environLocal = environment.Environment(_MOD) - def fromStream(inputStream): if inputStream.metadata is not None: incipit = inputStream.metadata.title @@ -574,6 +573,3 @@ def testSimpleFile(self): if __name__ == '__main__': import music21 music21.mainTest(Test, 'moduleRelative') - -# ----------------------------------------------------------------------------- -# eof diff --git a/music21_tools/composition/__init__.py b/music21_tools/composition/__init__.py index 4c670d8..9c58ecf 100644 --- a/music21_tools/composition/__init__.py +++ b/music21_tools/composition/__init__.py @@ -8,9 +8,3 @@ from . import arvo from . import phasing from . import seeger - -# ----------------------------------------------------------------------------- -# eof - - - diff --git a/music21_tools/composition/aug30.py b/music21_tools/composition/aug30.py index 41d1a8c..5d4e1c8 100644 --- a/music21_tools/composition/aug30.py +++ b/music21_tools/composition/aug30.py @@ -133,7 +133,3 @@ def test(): if __name__ == '__main__': test() - -# ----------------------------------------------------------------------------- -# eof - diff --git a/music21_tools/composition/phasing.py b/music21_tools/composition/phasing.py index 11a6346..3e8350f 100644 --- a/music21_tools/composition/phasing.py +++ b/music21_tools/composition/phasing.py @@ -196,10 +196,3 @@ def xtestPendulumMusic(self, show=True): elif len(sys.argv) > 1: t = Test() t.testBasic(cycles=None, show=True) - - - - -# ----------------------------------------------------------------------------- -# eof - diff --git a/music21_tools/counterpoint/__init__.py b/music21_tools/counterpoint/__init__.py index 944f43d..645f4a0 100644 --- a/music21_tools/counterpoint/__init__.py +++ b/music21_tools/counterpoint/__init__.py @@ -2,6 +2,3 @@ __all__ = ['species'] from . import species -# ----------------------------------------------------------------------------- -# eof - diff --git a/music21_tools/counterpoint/species.py b/music21_tools/counterpoint/species.py index bac2f91..f9cff38 100644 --- a/music21_tools/counterpoint/species.py +++ b/music21_tools/counterpoint/species.py @@ -56,7 +56,7 @@ def findParallelFifths(self, srcStream, cmpStream): any note that has harmonic interval of a fifth and is preceded by a harmonic interval of a fifth. - >>> from music21 import note, stream + >>> from music21 import * >>> n1 = note.Note('G3') >>> n2 = note.Note('A3') >>> n3 = note.Note('B3') @@ -103,7 +103,7 @@ def findHiddenFifths(self, stream1, stream2): where the two streams reach a fifth through parallel motion, but is not a parallel fifth. - >>> from music21 import note, stream + >>> from music21 import * >>> n1 = note.Note('G3') >>> n2 = note.Note('A3') >>> n3 = note.Note('B3') @@ -143,8 +143,7 @@ def isParallelFifth(self, note11, note12, note21, note22): (i.e. argument order is isParallelFifth(v1n1, v1n2, v2n1, v2n2)), returns True if the two harmonic intervals are P5 and False otherwise. - >>> from music21 import note, stream - + >>> from music21 import * >>> n1 = note.Note('G3') >>> n2 = note.Note('B-3') >>> m1 = note.Note('D4') @@ -173,8 +172,7 @@ def isHiddenFifth(self, note11, note12, note21, note22): is isHiddenFifth(v1n1, v1n2, v2n1, v2n2)), returns True if there is a hidden fifth and false otherwise. - >>> from music21 import note, stream - + >>> from music21 import * >>> n1 = note.Note('G3') >>> n2 = note.Note('B-3') >>> m1 = note.Note('E4') @@ -216,8 +214,7 @@ def findParallelOctaves(self, stream1, stream2): any note that has harmonic interval of an octave and is preceded by a harmonic interval of an octave. - >>> from music21 import note, stream - + >>> from music21 import * >>> n1 = note.Note('G3') >>> n2 = note.Note('A3') >>> n3 = note.Note('B3') @@ -270,9 +267,7 @@ def findHiddenOctaves(self, stream1, stream2): anything where the two streams reach an octave through parallel motion, but is not a parallel octave. - - >>> from music21 import note, stream - + >>> from music21 import * >>> n1 = note.Note('F3') >>> n2 = note.Note('A3') >>> n3 = note.Note('A3') @@ -318,9 +313,7 @@ def isParallelOctave(self, note11, note12, note21, note22): isParallelOctave(v1n1, v1n2, v2n1, v2n2)), returns True if the two harmonic intervals are P8 and False otherwise. - >>> from music21 import note, stream - - + >>> from music21 import * >>> n1 = note.Note('A3') >>> n2 = note.Note('B-3') >>> m1 = note.Note('A4') @@ -338,12 +331,12 @@ def isParallelOctave(self, note11, note12, note21, note22): ''' vlq = voiceLeading.VoiceLeadingQuartet(note11, note12, note21, note22) return vlq.parallelOctave() -## interval1 = interval.notesToInterval(note11, note21) -## interval2 = interval.notesToInterval(note12, note22) -## if interval1.semiSimpleName == interval2.semiSimpleName == "P8": -## return True -## else: -## return False + # interval1 = interval.notesToInterval(note11, note21) + # interval2 = interval.notesToInterval(note12, note22) + # if interval1.semiSimpleName == interval2.semiSimpleName == "P8": + # return True + # else: + # return False def isHiddenOctave(self, note11, note12, note21, note22): '''Given four notes, assuming the first pair is from one part and @@ -351,26 +344,24 @@ def isHiddenOctave(self, note11, note12, note21, note22): (i.e. argument order is isHiddenOctave(v1n1, v1n2, v2n1, v2n2)) returns True if there is a hidden octave and false otherwise. - - >>> from music21 import note, stream - + >>> from music21 import * >>> n1 = note.Note('A3') >>> n2 = note.Note('B-3') >>> m1 = note.Note('F4') >>> m2 = note.Note('B-4') >>> cp = ModalCounterpoint() - >>> cp.isHiddenOctave(n1, m1, n2, m2) #(n1, n2) and (m1, m2) are chords + >>> cp.isHiddenOctave(n1, m1, n2, m2) # (n1, n2) and (m1, m2) are chords False - >>> cp.isHiddenOctave(n1, n2, m1, m2) #(n1, m1) and (n2, m2) are chords + >>> cp.isHiddenOctave(n1, n2, m1, m2) # (n1, m1) and (n2, m2) are chords True >>> m1.octave = 5 >>> m2.octave = 5 >>> cp.isHiddenOctave(n1, n2, m1, m2) True - ''' vlq = voiceLeading.VoiceLeadingQuartet(note11, note12, note21, note22) return vlq.hiddenOctave() + # interval1 = interval.notesToInterval(note11, note21) # interval2 = interval.notesToInterval(note12, note22) # interval3 = interval.notesToInterval(note11, note12) @@ -393,7 +384,7 @@ def findParallelUnisons(self, stream1, stream2): assigns a flag under note.editorial["parallelUnison"] for any note that has harmonic interval of P1 and is preceded by a P1. - >>> from music21 import note, stream + >>> from music21 import * >>> n1 = note.Note('G4') >>> n2 = note.Note('A4') >>> n3 = note.Note('B4') @@ -413,7 +404,6 @@ def findParallelUnisons(self, stream1, stream2): True >>> cp.findParallelUnisons(cp.stream2, cp.stream1) 3 - ''' stream1.attachIntervalsBetweenStreams(stream2) stream2.attachIntervalsBetweenStreams(stream1) @@ -440,8 +430,7 @@ def isParallelUnison(self, note11, note12, note21, note22): isParallelFifth(v1n1, v1n2, v2n1, v2n2)) returns True if the two harmonic intervals are P1 and False otherwise. - >>> from music21 import note, stream - + >>> from music21 import * >>> n1 = note.Note('A3') >>> n2 = note.Note('B-3') >>> m1 = note.Note('A3') @@ -455,24 +444,24 @@ def isParallelUnison(self, note11, note12, note21, note22): >>> m2.octave = 4 >>> cp.isParallelUnison(n1, n2, m1, m2) #parallel octaves, not unison False - ''' vlq = voiceLeading.VoiceLeadingQuartet(note11, note12, note21, note22) return vlq.parallelUnison() -## interval1 = interval.notesToInterval(note11, note21) -## interval2 = interval.notesToInterval(note12, note22) -## if interval1.name == interval2.name == "P1": -## return True -## else: -## return False + # interval1 = interval.notesToInterval(note11, note21) + # interval2 = interval.notesToInterval(note12, note22) + # if interval1.name == interval2.name == "P1": + # return True + # else: + # return False def isValidHarmony(self, note11, note21): - '''Determines if the harmonic interval between two given notes is + ''' + Determines if the harmonic interval between two given notes is "legal" according to 21M.301 rules of counterpoint. Legal harmonic intervals include 'P1', 'P5', 'P8', 'm3', 'M3', 'm6', and 'M6'. - >>> from music21 import note, stream + >>> from music21 import * >>> c = note.Note('C4') >>> d = note.Note('D4') >>> e = note.Note('E4') @@ -499,8 +488,7 @@ def isValidMiddleHarmony(self, note11, note21): 'm6', and 'M6', from before. 'P4' is now included because it is legal for middle harmonies. - >>> from music21 import note, stream - + >>> from music21 import * >>> c = note.Note('C4') >>> d = note.Note('D4') >>> e = note.Note('E4') @@ -528,8 +516,7 @@ def allValidHarmony(self, stream1, stream2): include 'P1', 'P5', 'P8', 'm3', 'M3', 'm6', and 'M6'. Also assumes that final interval must be a perfect unison or octave. - >>> from music21 import note, stream - + >>> from music21 import * >>> n1 = note.Note('G4') >>> n2 = note.Note('A4') >>> n3 = note.Note('D4') @@ -586,8 +573,7 @@ def allValidHarmonyMiddleVoices(self, stream1, stream2): middle voices, 'P4' is also allowed and the final interval is allowed to be a fifth. - >>> from music21 import note, stream - + >>> from music21 import * >>> n1 = note.Note('G4') >>> n2 = note.Note('A4') >>> n3 = note.Note('B4') @@ -628,9 +614,7 @@ def countBadHarmonies(self, stream1, stream2): '''Given two simultaneous streams, counts the number of notes (in the first stream given) that create illegal harmonies when attacked. - >>> from music21 import note, stream - - + >>> from music21 import * >>> n1 = note.Note('G4') >>> n2 = note.Note('A4') >>> n3 = note.Note('B4') @@ -664,9 +648,8 @@ def isValidStep(self, note11, note12): include 'P4', 'P5', 'P8', 'm2', 'M2', 'm3', 'M3', and 'm6'. SHOULD BE RENAMED isValidMelody? - - >>> from music21 import note, stream + >>> from music21 import * >>> c = note.Note('C4') >>> d = note.Note('D4') >>> e = note.Note('E#4') @@ -692,8 +675,7 @@ def isValidMelody(self, stream1): SHOULD BE RENAMED allValidMelody? - >>> from music21 import note, stream - + >>> from music21 import * >>> n1 = note.Note('G-4') >>> n2 = note.Note('A4') >>> n3 = note.Note('B4') @@ -721,13 +703,13 @@ def isValidMelody(self, stream1): return False def countBadSteps(self, stream1): - '''Given a single stream, returns the number of illegal melodic + ''' + Given a single stream, returns the number of illegal melodic intervals. SHOULD BE RENAMED countBadMelodies? - >>> from music21 import note, stream - + >>> from music21 import * >>> n1 = note.Note('G-4') >>> n2 = note.Note('A4') >>> n3 = note.Note('B4') @@ -764,8 +746,7 @@ def findAllBadFifths(self, stream1, stream2): and also puts the appropriate tags in note.editorial under `.parallelFifth` and `.hiddenFifth`. - >>> from music21 import note, stream - + >>> from music21 import * >>> n1 = note.Note('C4') >>> n2 = note.Note('D4') >>> n3 = note.Note('E4') @@ -787,12 +768,12 @@ def findAllBadFifths(self, stream1, stream2): return parallel + hidden def findAllBadOctaves(self, stream1, stream2): - '''Given two streams, returns the total parallel and hidden octaves, + ''' + Given two streams, returns the total parallel and hidden octaves, and also puts the appropriate tags in note.editorial under `.parallelOctave` and `.hiddenOctave`. - >>> from music21 import note, stream - + >>> from music21 import * >>> n1 = note.Note('C4') >>> n2 = note.Note('D4') >>> n3 = note.Note('E4') @@ -808,7 +789,6 @@ def findAllBadOctaves(self, stream1, stream2): >>> cp = ModalCounterpoint(s1, s2) >>> cp.findAllBadOctaves(cp.stream1, cp.stream2) 2 - ''' parallel = self.findParallelOctaves(stream1, stream2) hidden = self.findHiddenOctaves(stream1, stream2) @@ -819,7 +799,7 @@ def tooManyThirds(self, stream1, stream2, limit=3): number of consecutive harmonic thirds exceeds the limit and False otherwise. - >>> from music21 import note, stream + >>> from music21 import * >>> n1 = note.Note('E4') >>> n2 = note.Note('F4') >>> n3 = note.Note('G4') @@ -853,42 +833,43 @@ def tooManyThirds(self, stream1, stream2, limit=3): thirds = 0 return False -## def thirdCounter(self, intervalList, numThirds): -## '''Recursive helper function for tooManyThirds that returns the number -## of consecutive thirds in a stream, given a corresponding list of -## interval names. -## -## -## -## >>> cp = ModalCounterpoint() -## >>> iList1 = ['m3', 'M3', 'm6'] -## >>> cp.thirdCounter(iList1, 0) -## 2 -## >>> cp.thirdCounter(iList1, 2) -## 4 -## >>> iList2 = ['m2', 'M3', 'P1'] -## >>> cp.thirdCounter(iList2, 0) -## 0 -## >>> iList3 = [] -## >>> cp.thirdCounter(iList3, 52) -## 52 -## -## ''' -## if len(intervalList) == 0: -## return numThirds -## if intervalList[0] != "M3" and intervalList[0] != "m3": -## return numThirds -## else: -## numThirds += 1 -## newList = intervalList[1:] -## return self.thirdCounter(newList, numThirds) + # def thirdCounter(self, intervalList, numThirds): + # '''Recursive helper function for tooManyThirds that returns the number + # of consecutive thirds in a stream, given a corresponding list of + # interval names. + # + # + # + # >>> cp = ModalCounterpoint() + # >>> iList1 = ['m3', 'M3', 'm6'] + # >>> cp.thirdCounter(iList1, 0) + # 2 + # >>> cp.thirdCounter(iList1, 2) + # 4 + # >>> iList2 = ['m2', 'M3', 'P1'] + # >>> cp.thirdCounter(iList2, 0) + # 0 + # >>> iList3 = [] + # >>> cp.thirdCounter(iList3, 52) + # 52 + # + # ''' + # if len(intervalList) == 0: + # return numThirds + # if intervalList[0] != "M3" and intervalList[0] != "m3": + # return numThirds + # else: + # numThirds += 1 + # newList = intervalList[1:] + # return self.thirdCounter(newList, numThirds) def tooManySixths(self, stream1, stream2, limit=3): - '''Given two consecutive streams and a limit, returns True if the + ''' + Given two consecutive streams and a limit, returns True if the number of consecutive harmonic sixths exceeds the limit and False otherwise. - >>> from music21 import note, stream + >>> from music21 import * >>> n1 = note.Note('E4') >>> n2 = note.Note('F4') >>> n3 = note.Note('G4') @@ -923,43 +904,41 @@ def tooManySixths(self, stream1, stream2, limit=3): sixths = 0 return False -## def sixthCounter(self, intervalList, numSixths): -## '''Recursive helper function for tooManySixths that returns the number -## of consecutive thirds in a stream, given a corresponding list of -## interval names. -## -## -## -## >>> cp = ModalCounterpoint() -## >>> iList1 = ['m6', 'M6', 'm3'] -## >>> cp.sixthCounter(iList1, 0) -## 2 -## >>> cp.sixthCounter(iList1, 2) -## 4 -## >>> iList2 = ['m2', 'M6', 'P1'] -## >>> cp.sixthCounter(iList2, 0) -## 0 -## >>> iList3 = [] -## >>> cp.sixthCounter(iList3, 52) -## 52 -## -## ''' -## if len(intervalList) == 0: -## return numSixths -## if intervalList[0] != "M6" and intervalList[0] != "m6": -## return numSixths -## else: -## numSixths += 1 -## newList = intervalList[1:] -## return self.sixthCounter(newList, numSixths) + # def sixthCounter(self, intervalList, numSixths): + # ''' + # Recursive helper function for tooManySixths that returns the number + # of consecutive thirds in a stream, given a corresponding list of + # interval names. + # + # >>> cp = ModalCounterpoint() + # >>> iList1 = ['m6', 'M6', 'm3'] + # >>> cp.sixthCounter(iList1, 0) + # 2 + # >>> cp.sixthCounter(iList1, 2) + # 4 + # >>> iList2 = ['m2', 'M6', 'P1'] + # >>> cp.sixthCounter(iList2, 0) + # 0 + # >>> iList3 = [] + # >>> cp.sixthCounter(iList3, 52) + # 52 + # ''' + # if len(intervalList) == 0: + # return numSixths + # if intervalList[0] != "M6" and intervalList[0] != "m6": + # return numSixths + # else: + # numSixths += 1 + # newList = intervalList[1:] + # return self.sixthCounter(newList, numSixths) def raiseLeadingTone(self, stream1, minorScale): - '''Given a stream of notes and a minor scale object, returns a new + ''' + Given a stream of notes and a minor scale object, returns a new stream that raises all the leading tones of the original stream. Also raises the sixth if applicable to avoid augmented intervals. - >>> from music21 import note, stream - + >>> from music21 import * >>> n1 = note.Note('C4') >>> n2 = note.Note('G4') >>> n3 = note.Note('A4') @@ -1635,8 +1614,6 @@ def getRandomCF(mode=None): representing the name of the related scale's tonic, which can be made into a note and a scale object. - - >>> cf = getRandomCF() >>> sorted(list(cf.keys())) ['mode', 'notes'] @@ -1644,7 +1621,6 @@ def getRandomCF(mode=None): True >>> isinstance(cf['mode'], str) True - ''' if mode is not None: raise Exception('Cantus firmus selection by mode does not yet exist') @@ -1679,47 +1655,35 @@ def testGenerateFirstSpecies(self): score.insert(0, meter.TimeSignature('4/4')) score.insert(0, top) score.insert(0, cantusFirmus) -# score.show('text') -# score.show('musicxml') + # score.show('text') + # score.show('musicxml') score.show('midi') score.show('lily.png') def xtestGenerateFirstSpeciesThreeVoices(self): ''' A First Species, Three-Voice Counterpoint Generator by Jackie Rogoff (MIT 2010) - written as continuation of - a UROP (Undergraduate Research Opportunities Program) project at M.I.T. summer 2010. + written as continuation of a UROP (Undergraduate Research + Opportunities Program) project at M.I.T. summer 2010. ''' - counterpoint1 = ModalCounterpoint() - - cf = cantusFirmi[0]# getRandomCF() + cf = cantusFirmi[0] # getRandomCF() environLocal.printDebug(['Using: ', cf['notes']]) - cantusFirmus = stream.Part(converter.parse(cf['notes'], '4/4').notes) - + cantusFirmus = stream.Part(converter.parse('tinynotation: 4/4 ' + cf['notes']).notes) baseNote = Note(cf['mode']) thisScale = scale.MinorScale(baseNote) - (middleVoice, topVoice) = counterpoint1.generateFirstSpeciesThreeVoices( cantusFirmus, thisScale, 'random') - score = stream.Score() score.insert(0, meter.TimeSignature('4/4')) score.insert(0, topVoice) score.insert(0, middleVoice) score.insert(0, cantusFirmus) -# score.show('text') -# score.show('musicxml') + # score.show('text') + # score.show('musicxml') score.show('midi') score.show('lily.png') - - if __name__ == '__main__': import music21 music21.mainTest(Test, 'moduleRelative') - - -# ----------------------------------------------------------------------------- -# eof - diff --git a/music21_tools/featureExtraction/ismir2011.py b/music21_tools/featureExtraction/ismir2011.py index a5b0833..42d056c 100644 --- a/music21_tools/featureExtraction/ismir2011.py +++ b/music21_tools/featureExtraction/ismir2011.py @@ -43,10 +43,10 @@ def _process(self): def testFictaFeature(): luca = corpus.parse('luca/gloria.mxl') fe = MusicaFictaFeature(luca) - print (fe.extract().vector) + print(fe.extract().vector) mv = corpus.parse('monteverdi/madrigal.3.1.xml') fe.setData(mv) - print (fe.extract().vector) + print(fe.extract().vector) def testDataSet(): fes = features.extractorsById(['ql1', 'ql2', 'ql3']) @@ -61,11 +61,11 @@ def testDataSet(): classValue='Handel') ds.addData('http://www.midiworld.com/midis/other/handel/gfh-jm01.mid') ds.process() - print (ds.getAttributeLabels()) + print(ds.getAttributeLabels()) ds.write('d:/desktop/baroqueQLs.csv') fList = ds.getFeaturesAsList() - print (fList[0]) - print (features.outputFormats.OutputTabOrange(ds).getString()) + print(fList[0]) + print(features.outputFormats.OutputTabOrange(ds).getString()) for i in range(len(fList)): # display scores as pngs generated by Lilypond # if the most common note is an eighth note (0.5) @@ -174,7 +174,7 @@ def xtestChinaEuropeSimpler(): knnWrong += 1 total = float(len(testData)) - print (majWrong / total, knnWrong / total) + print(majWrong / total, knnWrong / total) def prepareTrecentoCadences(): @@ -202,7 +202,7 @@ def prepareTrecentoCadences(): ds.addData(s, classValue = thisBallata.composer, id=str(i)) else: ds2.addData(s, classValue = thisBallata.composer, id=str(i)) - print (i, thisBallata.title, thisBallata.composer) + print(i, thisBallata.title, thisBallata.composer) ds.process() ds2.process() @@ -232,7 +232,7 @@ def testTrecentoSimpler(): knnWrong += 1 total = float(len(testData)) - print (majWrong / total, knnWrong / total) + print(majWrong / total, knnWrong / total) def wekaCommands(): ''' @@ -302,7 +302,7 @@ def tinyNotationBass(): def figuredBassScale(): fbScale1 = figuredBass.realizerScale.FiguredBassScale('D', 'major') - print (fbScale1.getSamplePitches('E3', '6')) + print(fbScale1.getSamplePitches('E3', '6')) def exampleD(): @@ -314,7 +314,7 @@ def exampleD(): def fbFeatureExtraction(): exampleFB = converter.parse('ismir2011_fb_example1b.xml') fe1 = features.jSymbolic.PitchClassDistributionFeature(exampleFB) - print (fe1.extract().vector) + print(fe1.extract().vector) # [0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.6666666666666666, 0.0, 0.0, 1.0, 0.0, 0.0] n1 = exampleFB.parts[0][1][5] n1.expressions.append(expressions.Turn()) @@ -338,7 +338,7 @@ def fbFeatureExtraction(): exampleFBOut.insert(0, sol1.parts[1]) fe1.setData(exampleFBOut) - print (fe1.extract().vector) + print(fe1.extract().vector) #[0.0, 0.5, 1.0, 0.0, 0.6000000000000001, 0.0, 0.4, 0.2, 0.0, 0.7000000000000001, 0.0, 0.1] # exampleFBOut.show() @@ -354,7 +354,3 @@ def fbFeatureExtraction(): #testDataSet() #testFictaFeature() #example2() - - -# ----------------------------------------------------------------------------- -# eof diff --git a/music21_tools/misc/monteverdi.py b/music21_tools/misc/monteverdi.py index 30e8415..55da7dd 100644 --- a/music21_tools/misc/monteverdi.py +++ b/music21_tools/misc/monteverdi.py @@ -33,7 +33,7 @@ def spliceAnalysis(book=3, madrigal=1): for myN in aMeasures.flatten().notesAndRests: myN.style.hideObjectOnPrint = True x = aMeasures.write() - print (x) + print(x) #excerpt.insert(0, aMeasures) #excerpt.show() @@ -43,8 +43,8 @@ def showAnalysis(book=3, madrigal= 3): analysis = corpus.parse(filename) #analysis.show() (major, minor) = iqSemitonesAndPercentage(analysis) - print (major) - print (minor) + print(major) + print(minor) def analyzeBooks(books=(3,), start=1, end=20, show=False, strict=False): majorFig = '' @@ -193,13 +193,13 @@ def monteverdiParallels(books=(3,), start=1, end=20, show=True, strict=False): filename = 'monteverdi/madrigal.%s.%s.xml' % (book, i) if strict == True: c = corpus.parse(filename) - print (book, i) + print(book, i) else: try: c = corpus.parse(filename) - print (book, i) + print(book, i) except: - print ('Cannot parse %s, maybe it does not exist...' % (filename)) + print('Cannot parse %s, maybe it does not exist...' % (filename)) continue displayMe = False for i in range(len(c.parts) - 1): @@ -304,10 +304,10 @@ def findPhraseBoundaries(book=4, madrigal=12): for thisOffset in sorted(phraseScoresByOffset.keys()): psbo = phraseScoresByOffset[thisOffset] if psbo > 0: - print (thisOffset, psbo) + print(thisOffset, psbo) relevantNote = flattenedBass.getElementAtOrBefore(thisOffset - 0.1) if hasattr(relevantNote, 'score'): - print ('adjusting score from %d to %d for note in measure %d' % ( + print('adjusting score from %d to %d for note in measure %d' % ( relevantNote.score, relevantNote.score + psbo, relevantNote.measureNumber)) relevantNote.score += psbo else: diff --git a/music21_tools/theory/mgtaPart1.py b/music21_tools/theory/mgtaPart1.py index 482c5cd..84b4554 100644 --- a/music21_tools/theory/mgtaPart1.py +++ b/music21_tools/theory/mgtaPart1.py @@ -1875,7 +1875,3 @@ def testBasic(self): #ch2_writing_V_A(show=True) #ch2_writing_III_B_1() - -# ----------------------------------------------------------------------------- -# eof - diff --git a/music21_tools/theoryAnalysis/__init__.py b/music21_tools/theoryAnalysis/__init__.py index b4ff03a..24b2308 100644 --- a/music21_tools/theoryAnalysis/__init__.py +++ b/music21_tools/theoryAnalysis/__init__.py @@ -1,6 +1,2 @@ __all__ = ['theoryAnalyzer', 'theoryResult', 'wwnortonMGTA'] - - -# ----------------------------------------------------------------------------- -# eof diff --git a/music21_tools/theoryAnalysis/theoryAnalyzer.py b/music21_tools/theoryAnalysis/theoryAnalyzer.py index 879db10..b001596 100644 --- a/music21_tools/theoryAnalysis/theoryAnalyzer.py +++ b/music21_tools/theoryAnalysis/theoryAnalyzer.py @@ -46,9 +46,9 @@ * :meth:`~Analyzer.getMelodicIntervals` You can then iterate through these objects and access the attributes directly. Here is an example -of this that will analyze the root motion in a score: - +of this that will analyze the root motion in a score:: + >>> from music21 import harmony >>> p = corpus.parse('leadsheet').flatten().getElementsByClass('Harmony').stream() >>> p = harmony.realizeChordSymbolDurations(p) >>> averageMotion = 0 @@ -122,19 +122,18 @@ 7. if all checks are true, the passingTone or neighborTone is removed from the score (because the whole point of parsing the score into voiceLeadingObjects was to maintain a direct pointer to the original object in the score.) -8. the gap created by the deletion is filled in by extending the duration of the previous note - +8. the gap created by the deletion is filled in by extending the duration of the previous note:: ->>> p = corpus.parse('bwv6.6').measures(0, 20) ->>> #_DOCS_SHOW p.show() - .. image:: images/completebach.* - :width: 500 + >>> p = corpus.parse('bwv6.6').measures(0, 20) + >>> #_DOCS_SHOW p.show() + .. image:: images/completebach.* + :width: 500 ->>> ads.removePassingTones(p) ->>> ads.removeNeighborTones(p) ->>> #_DOCS_SHOW p.show() - .. image:: images/bachnononharm.* - :width: 500 + >>> ads.removePassingTones(p) + >>> ads.removeNeighborTones(p) + >>> #_DOCS_SHOW p.show() + .. image:: images/bachnononharm.* + :width: 500 =========================================== Detailed Method Documentation @@ -161,10 +160,8 @@ from music21 import corpus from music21 import duration from music21 import exceptions21 -from music21 import harmony # used in doctests from music21 import interval from music21 import key -from music21 import meter # used in doctests from music21 import note from music21 import roman from music21 import stream @@ -178,29 +175,29 @@ class Analyzer: _DOC_ORDER = ['getVerticalities', 'getVLQs', 'getThreeNoteLinearSegments', - 'getLinearSegments', 'getVerticalityNTuplets', 'getHarmonicIntervals', - 'getMelodicIntervals', 'getParallelFifths', 'getPassingTones', - 'getNeighborTones', 'getParallelOctaves', 'identifyParallelFifths', - 'identifyParallelOctaves', 'identifyParallelUnisons', - 'identifyHiddenFifths', 'identifyHiddenOctaves', 'identifyImproperResolutions', - 'identifyLeapNotSetWithStep', 'identifyOpensIncorrectly', - 'identifyClosesIncorrectly', - 'identifyPassingTones', 'removePassingTones', 'identifyNeighborTones', - 'removeNeighborTones', 'identifyDissonantHarmonicIntervals', - 'identifyImproperDissonantIntervals', - 'identifyDissonantMelodicIntervals', 'identifyObliqueMotion', - 'identifySimilarMotion', - 'identifyParallelMotion', - 'identifyContraryMotion', 'identifyOutwardContraryMotion', - 'identifyInwardContraryMotion', 'identifyAntiParallelMotion', - 'identifyTonicAndDominant', 'identifyHarmonicIntervals', - 'identifyScaleDegrees', 'identifyMotionType', - 'identifyCommonPracticeErrors', - 'addAnalysisData', 'removeFromAnalysisData', 'setKeyMeasureMap', - 'getKeyMeasureMap', 'getKeyAtMeasure', - 'getResultsString', 'colorResults', 'getHTMLResultsString', - 'getAllPartNumPairs', 'getNotes' - ] + 'getLinearSegments', 'getVerticalityNTuplets', 'getHarmonicIntervals', + 'getMelodicIntervals', 'getParallelFifths', 'getPassingTones', + 'getNeighborTones', 'getParallelOctaves', 'identifyParallelFifths', + 'identifyParallelOctaves', 'identifyParallelUnisons', + 'identifyHiddenFifths', 'identifyHiddenOctaves', 'identifyImproperResolutions', + 'identifyLeapNotSetWithStep', 'identifyOpensIncorrectly', + 'identifyClosesIncorrectly', + 'identifyPassingTones', 'removePassingTones', 'identifyNeighborTones', + 'removeNeighborTones', 'identifyDissonantHarmonicIntervals', + 'identifyImproperDissonantIntervals', + 'identifyDissonantMelodicIntervals', 'identifyObliqueMotion', + 'identifySimilarMotion', + 'identifyParallelMotion', + 'identifyContraryMotion', 'identifyOutwardContraryMotion', + 'identifyInwardContraryMotion', 'identifyAntiParallelMotion', + 'identifyTonicAndDominant', 'identifyHarmonicIntervals', + 'identifyScaleDegrees', 'identifyMotionType', + 'identifyCommonPracticeErrors', + 'addAnalysisData', 'removeFromAnalysisData', 'setKeyMeasureMap', + 'getKeyMeasureMap', 'getKeyAtMeasure', + 'getResultsString', 'colorResults', 'getHTMLResultsString', + 'getAllPartNumPairs', 'getNotes', + ] def __init__(self): @@ -234,8 +231,6 @@ def addAnalysisData(self, score): dd['ResultDict'] = defaultdict(dict) self.store[p.id] = dd - - # -------------------------------------------------------------------------------------- # Methods to split the score up into little pieces for analysis # The little pieces are all from voiceLeading.py, such as @@ -285,6 +280,7 @@ def getVerticalities(self, score, classFilterList=('Note', 'Chord', 'Harmony', ' , {0: []})>] + >>> from music21 import harmony >>> sc3 = stream.Score() >>> p1 = stream.Part() >>> p1.append(harmony.ChordSymbol('C', quarterLength = 1)) @@ -479,6 +475,7 @@ def getLinearSegments(self, score, partNum, lengthLinearSegment, classFilterList + >>> from music21 import * >>> sc3 = stream.Score() >>> part2 = stream.Part() >>> part2.append(harmony.ChordSymbol('D-', quarterLength=1)) @@ -522,7 +519,7 @@ def _getTypeOfAllObjects(self, objectList): setList = [] for obj in objectList: if obj != None: - setList.append(set (obj.classes) ) + setList.append(set(obj.classes) ) if setList: lastSet = setList[0] @@ -1445,6 +1442,7 @@ def identifyPassingTones(self, score, partNumToIdentify=None, color=None, dictKe :class:`~music21.editorial.NoteEditorial` value of editorialValue at ``note.editorial.[editorialDictKey]`` + >>> from music21 import * >>> sc = stream.Score() >>> sc.insert(0, meter.TimeSignature('2/4')) >>> part0 = stream.Part() @@ -1485,8 +1483,7 @@ def getPassingTones(self, score, dictKey=None, partNumToIdentify=None, unaccente returns a list of all passing tones present in the score, as identified by :meth:`~music21.voiceLeading.VerticalityTriplet.hasPassingTone` - - + >>> from music21 import * >>> sc = stream.Score() >>> sc.insert(0, meter.TimeSignature('2/4')) >>> part0 = stream.Part() @@ -1526,8 +1523,7 @@ def getNeighborTones(self, score, dictKey=None, partNumToIdentify=None, unaccent returns a list of all passing tones present in the score, as identified by :meth:`~music21.voiceLeading.VerticalityTriplet.hasNeighborTone` - - + >>> from music21 import * >>> sc = stream.Score() >>> sc.insert(0, meter.TimeSignature('2/4')) >>> part0 = stream.Part() @@ -1568,7 +1564,7 @@ def removePassingTones(self, score, dictKey='unaccentedPassingTones'): extending note duraitons (method under development) - + >>> from music21 import * >>> sc = stream.Score() >>> sc.insert(0, meter.TimeSignature('2/4')) >>> part0 = stream.Part() @@ -1613,6 +1609,7 @@ def removeNeighborTones(self, score, dictKey='unaccentedNeighborTones'): extending note duraitons (method under development) + >>> from music21 import * >>> sc = stream.Score() >>> sc.insert(0, meter.TimeSignature('2/4')) >>> part0 = stream.Part() @@ -1662,8 +1659,7 @@ def identifyNeighborTones(self, score, partNumToIdentify=None, color=None, dictK on weak beats). unaccentedOnly by default set to True - - + >>> from music21 import * >>> sc = stream.Score() >>> sc.insert(0, meter.TimeSignature('2/4')) >>> part0 = stream.Part() @@ -2459,17 +2455,17 @@ class TheoryAnalyzerException(exceptions21.Music21Exception): class Test(unittest.TestCase): def testChordMotionExample(self): - pass # in doctest -# from music21 import harmony, theoryAnalysis -# p = corpus.parse('leadsheet').flatten().getElementsByClass('Harmony') -# harmony.realizeChordSymbolDurations(p) -# averageMotion = 0 -# l = ads.getLinearSegments(p, 0, 2, ['Harmony']) -# for x in l: -# averageMotion += abs(x.rootInterval().intervalClass) -# averageMotion = averageMotion // len(l) -# self.assertEqual(averageMotion, 4) -# + pass # in doctest + # from music21 import harmony, theoryAnalysis + # p = corpus.parse('leadsheet').flatten().getElementsByClass('Harmony') + # harmony.realizeChordSymbolDurations(p) + # averageMotion = 0 + # l = ads.getLinearSegments(p, 0, 2, ['Harmony']) + # for x in l: + # averageMotion += abs(x.rootInterval().intervalClass) + # averageMotion = averageMotion // len(l) + # self.assertEqual(averageMotion, 4) + def testFastVerticalityCheck(self): sc = stream.Score() part0 = stream.Part() @@ -2496,8 +2492,7 @@ def testFastVerticalityCheck(self): 'Roman Numeral of B-,G is I') -class TestExternal(unittest.TestCase): # pragma: no cover - +class TestExternal(unittest.TestCase): # pragma: no cover def runTest(self): pass @@ -2507,12 +2502,11 @@ def demo(self): '/Users/bhadley/Dropbox/Music21Theory/TestFiles/TheoryAnalyzer/TATest.xml') ads = Analyzer() ads.identifyCommonPracticeErrors(sc) + # sc.show() - #sc.show() def removeNHTones(self): p = corpus.parse('bwv6.6').measures(0, 20) p.show() - ads = Analyzer() ads.removePassingTones(p) ads.removeNeighborTones(p) @@ -2520,4 +2514,4 @@ def removeNHTones(self): if __name__ == '__main__': import music21 - music21.mainTest(Test, 'moduleRelative') #, runTest='testFastVerticalityCheck') + music21.mainTest(Test, 'moduleRelative') diff --git a/music21_tools/trecento/__init__.py b/music21_tools/trecento/__init__.py index c22b22c..94ed108 100644 --- a/music21_tools/trecento/__init__.py +++ b/music21_tools/trecento/__init__.py @@ -1,16 +1,7 @@ __all__ = ['cadencebook', 'capua', 'findTrecentoFragments', 'notation', 'tonality'] -# this is necessary to get these names available with a -# from music21 import * import statement -import sys - from . import cadencebook from . import capua from . import findTrecentoFragments from . import notation from . import tonality - -#from music21.trecento import * - -# ----------------------------------------------------------------------------- -# eof diff --git a/music21_tools/trecento/cadenceProbabilities.py b/music21_tools/trecento/cadenceProbabilities.py index 4a4d557..05373da 100644 --- a/music21_tools/trecento/cadenceProbabilities.py +++ b/music21_tools/trecento/cadenceProbabilities.py @@ -102,7 +102,3 @@ def countCadencePercentages(): if __name__ == '__main__': countCadencePercentages() - -# ----------------------------------------------------------------------------- -# eof - diff --git a/music21_tools/trecento/cadencebook.py b/music21_tools/trecento/cadencebook.py index 3a33fb1..c8d2fd9 100644 --- a/music21_tools/trecento/cadencebook.py +++ b/music21_tools/trecento/cadencebook.py @@ -848,8 +848,3 @@ def xtestAsScore(self): if __name__ == '__main__': import music21 music21.mainTest(Test, 'importPlusRelative') # , TestExternal) - - -# ----------------------------------------------------------------------------- -# eof - diff --git a/music21_tools/trecento/findSevs.py b/music21_tools/trecento/findSevs.py index b83fda0..81f4431 100644 --- a/music21_tools/trecento/findSevs.py +++ b/music21_tools/trecento/findSevs.py @@ -48,7 +48,3 @@ def findInWork(work, searchInterval=7): if __name__ == '__main__': find(2, 459, ) - -# ----------------------------------------------------------------------------- -# eof - diff --git a/music21_tools/trecento/findTrecentoFragments.py b/music21_tools/trecento/findTrecentoFragments.py index 8cc2397..795b4b0 100644 --- a/music21_tools/trecento/findTrecentoFragments.py +++ b/music21_tools/trecento/findTrecentoFragments.py @@ -290,9 +290,3 @@ def savedSearches(): if __name__ == '__main__': savedSearches() # audioVirelaiSearch() - - - -# ----------------------------------------------------------------------------- -# eof - diff --git a/music21_tools/trecento/find_vatican1790.py b/music21_tools/trecento/find_vatican1790.py index 4ca2f5e..e3abcf7 100644 --- a/music21_tools/trecento/find_vatican1790.py +++ b/music21_tools/trecento/find_vatican1790.py @@ -31,7 +31,3 @@ def find(): if __name__ == '__main__': find() - -# ----------------------------------------------------------------------------- -# eof - diff --git a/music21_tools/trecento/largestAmbitus.py b/music21_tools/trecento/largestAmbitus.py index 3689926..1de0cc8 100644 --- a/music21_tools/trecento/largestAmbitus.py +++ b/music21_tools/trecento/largestAmbitus.py @@ -44,7 +44,3 @@ def main(): if __name__ == '__main__': main() - -# ----------------------------------------------------------------------------- -# eof - diff --git a/music21_tools/trecento/medren.py b/music21_tools/trecento/medren.py index a92a705..a0191c2 100644 --- a/music21_tools/trecento/medren.py +++ b/music21_tools/trecento/medren.py @@ -262,7 +262,7 @@ def __eq__(self, other): mensural type is tested rather than equality of duration >>> from music21 import stream - + >>> m = GeneralMensuralNote('minima') >>> n = GeneralMensuralNote('brevis') >>> m == n @@ -431,7 +431,7 @@ def _determineMensurationOrDivisione(self): If no context is present, returns None. >>> from music21_tools import trecento - + >>> gmn = GeneralMensuralNote('longa') >>> gmn._determineMensurationOrDivisione() >>> @@ -2132,7 +2132,7 @@ def testStretto(): import music21 music21.mainTest(Test, 'importPlusRelative') # TestExternal) # music21.testConvertMensuralMeasure() - # almaRedemptoris = converter.parse("C4 E F G A G G G A B c G", '4/4') #liber 277 (pdf401) + # almaRedemptoris = converter.parse("C4 E F G A G G G A B c G", '4/4') # Liber 277 (pdf 401) # puer = converter.parse('G4 d d d e d c c d c e d d', '4/4') # puer natus est 408 (pdf 554) # almaRedemptoris.title = "Alma Redemptoris Mater LU p. 277" # puer.title = "Puer Natus Est Nobis" diff --git a/music21_tools/trecento/polyphonicSnippet.py b/music21_tools/trecento/polyphonicSnippet.py index 5b4805d..6cc333b 100644 --- a/music21_tools/trecento/polyphonicSnippet.py +++ b/music21_tools/trecento/polyphonicSnippet.py @@ -400,7 +400,3 @@ def testLily(self): if __name__ == '__main__': import music21 music21.mainTest(Test, TestExternal, 'importPlusRelative') - -# ----------------------------------------------------------------------------- -# eof - diff --git a/music21_tools/trecento/quodJactatur.py b/music21_tools/trecento/quodJactatur.py index f7f4764..cca070e 100644 --- a/music21_tools/trecento/quodJactatur.py +++ b/music21_tools/trecento/quodJactatur.py @@ -484,14 +484,10 @@ def runTest(self): pass - if __name__ == '__main__': import music21 music21.mainTest('importPlusRelative') -# bentWolfSolution() -# possibleSolution() -# findRetrogradeVoices() + # bentWolfSolution() + # possibleSolution() + # findRetrogradeVoices() pass -# ----------------------------------------------------------------------------- -# eof - diff --git a/music21_tools/trecento/runTrecentoCadence.py b/music21_tools/trecento/runTrecentoCadence.py index 8cde6f6..11bbc68 100644 --- a/music21_tools/trecento/runTrecentoCadence.py +++ b/music21_tools/trecento/runTrecentoCadence.py @@ -185,7 +185,3 @@ def testA(self): #makePDFfromPiecesWithCapua() import music21 music21.mainTest(Test, 'moduleRelative') - - -# ----------------------------------------------------------------------------- -# eof diff --git a/music21_tools/trecento/tonality.py b/music21_tools/trecento/tonality.py index beeb570..3f0a696 100644 --- a/music21_tools/trecento/tonality.py +++ b/music21_tools/trecento/tonality.py @@ -349,8 +349,3 @@ def runTest(self): if __name__ == '__main__': import music21 music21.mainTest(Test, 'importPlusRelative') #External) - - -# ----------------------------------------------------------------------------- -# eof - diff --git a/music21_tools/trecento/trecentoCadence.py b/music21_tools/trecento/trecentoCadence.py index 783b0a0..ce60f2f 100644 --- a/music21_tools/trecento/trecentoCadence.py +++ b/music21_tools/trecento/trecentoCadence.py @@ -120,7 +120,3 @@ def testTrecentoLine(self): if __name__ == '__main__': import music21 music21.mainTest(Test, 'importPlusRelative') - -# ----------------------------------------------------------------------------- -# eof - diff --git a/publications/icmc2010.py b/publications/icmc2010.py index f49a2bc..daf312f 100644 --- a/publications/icmc2010.py +++ b/publications/icmc2010.py @@ -185,6 +185,3 @@ def testBasic(self): # bergEx01() music21.mainTest(Test) -# ----------------------------------------------------------------------------- -# eof - From b868f34c54cda1c88cbff5ed8e5e99f1f032664f Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 14:02:50 -1000 Subject: [PATCH 05/28] fix reprs --- music21_tools/trecento/cadencebook.py | 8 ++++---- music21_tools/trecento/polyphonicSnippet.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/music21_tools/trecento/cadencebook.py b/music21_tools/trecento/cadencebook.py index c8d2fd9..a9a108c 100644 --- a/music21_tools/trecento/cadencebook.py +++ b/music21_tools/trecento/cadencebook.py @@ -501,7 +501,7 @@ def incipit(self): >>> accur = bs.makeWork(2) >>> accurIncipit = accur.incipit >>> print(accurIncipit) - + ''' rowBlock = self.rowvalues[8:12] rowBlock.append(self.rowvalues[7]) @@ -523,8 +523,8 @@ def getOtherSnippets(self): >>> accurSnippets = accur.getOtherSnippets() >>> for thisSnip in accurSnippets: ... print(thisSnip) - - + + ''' beginSnippetPositions = self.beginSnippetPositions @@ -559,7 +559,7 @@ def getSnippetAtPosition(self, snippetPosition, snippetType='end'): >>> bs = BallataSheet() >>> accur = bs.makeWork(2) >>> print(accur.getSnippetAtPosition(12)) - + ''' if self.rowvalues[snippetPosition].strip() != '': diff --git a/music21_tools/trecento/polyphonicSnippet.py b/music21_tools/trecento/polyphonicSnippet.py index 6cc333b..ca40cc1 100644 --- a/music21_tools/trecento/polyphonicSnippet.py +++ b/music21_tools/trecento/polyphonicSnippet.py @@ -54,11 +54,11 @@ class PolyphonicSnippet(stream.Score): >>> dumClass = dummy.__class__ >>> dumClass - + >>> dumdum = dumClass() >>> dumdum.__class__ - + >>> ps2 = ps.__class__() >>> ps2.elements From c81893b1a8277554fdf667c9f92f2e030082bc76 Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 14:08:32 -1000 Subject: [PATCH 06/28] =?UTF-8?q?Apply=20E712=20fixes=20(=3D=3D=20True=20/?= =?UTF-8?q?=20=3D=3D=20False=20=E2=86=92=20bool-direct)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 33 fixes via ruff --unsafe-fixes across 9 files; transforms `x == True` → `x` and `x == False` → `not x`. No regressions. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../graphicalInterfaceGame.py | 2 +- .../audioSearchDemos/graphicalInterfaceSF.py | 20 +++++++++---------- .../audioSearchDemos/humanVScomputer.py | 8 ++++---- .../audioSearchDemos/repetitionGame.py | 6 +++--- music21_tools/bhadley/nips2011.py | 4 ++-- music21_tools/chant/chant.py | 10 +++++----- music21_tools/choraleTools/mnum_fixer.py | 2 +- music21_tools/misc/monteverdi.py | 10 +++++----- music21_tools/trecento/medren.py | 4 ++-- 9 files changed, 33 insertions(+), 33 deletions(-) diff --git a/music21_tools/audioSearchDemos/graphicalInterfaceGame.py b/music21_tools/audioSearchDemos/graphicalInterfaceGame.py index f05ca44..6e14abc 100644 --- a/music21_tools/audioSearchDemos/graphicalInterfaceGame.py +++ b/music21_tools/audioSearchDemos/graphicalInterfaceGame.py @@ -108,7 +108,7 @@ def mainLoop(self): #master = self.master - if self.good == True: + if self.good: print('rounddddddddddddasdasdadsadad', self.rG.round) self.textRound.set('Round %d' % (self.rG.round + 1)) self.counter = math.pow(-1, self.rG.round) diff --git a/music21_tools/audioSearchDemos/graphicalInterfaceSF.py b/music21_tools/audioSearchDemos/graphicalInterfaceSF.py index 462b959..fbdfb49 100644 --- a/music21_tools/audioSearchDemos/graphicalInterfaceSF.py +++ b/music21_tools/audioSearchDemos/graphicalInterfaceSF.py @@ -203,7 +203,7 @@ def cropBorder(self, img, minColor=240, maxColor=256): break comprovation = False - while comprovation == False: + while not comprovation: bad = False for yPos in range(0, resY, int(resY / resY)): pixelPosition = yPos * resX + leftCut - numberPixels @@ -213,7 +213,7 @@ def cropBorder(self, img, minColor=240, maxColor=256): or data[pixelPosition][1] not in colorRange or data[pixelPosition][2] not in colorRange): bad = True - if bad == False: + if not bad: comprovation = True else: leftCut = leftCut - numberPixels @@ -233,7 +233,7 @@ def cropBorder(self, img, minColor=240, maxColor=256): break comprovation = False - while comprovation == False: + while not comprovation: bad = False for yPos in range(0, resY, int(resY / resY)): pixelPosition = yPos * resX + resX - (rightCut - numberPixels) @@ -243,7 +243,7 @@ def cropBorder(self, img, minColor=240, maxColor=256): and data[pixelPosition][1] not in colorRange and data[pixelPosition][2] not in colorRange): bad = True - if bad == False: + if not bad: comprovation = True else: rightCut = rightCut - numberPixels @@ -343,7 +343,7 @@ def initializeGraphicInterface(self): self.textVar3.set('That is a good song! :)') - if self.firstTime == True: + if self.firstTime: self.button2 = tkinter.Button(master, text='START SF', width=self.sizeButton, @@ -547,7 +547,7 @@ def continueScoreFollower(self): environLocal.printDebug('continueScoreFollower starting') self.ScF = self.scoreFollower self.timeStart = time.time() - if self.stop == False and (self.firstTimeSF == True or self.rt.resultInThread == False): + if not self.stop and (self.firstTimeSF or not self.rt.resultInThread): environLocal.printDebug('firstTimeSF == True or resultInThread') self.lastNoteString = 'Note: %d, Measure: %d, Countdown:%d, Page:%d' % ( @@ -555,7 +555,7 @@ def continueScoreFollower(self): self.ScF.scoreStream[self.ScF.lastNotePosition].measureNumber, self.ScF.countdown, self.currentLeftPage) - if self.firstTimeSF == False: + if not self.firstTimeSF: self.textVarComments.set('1st meas: %d, last meas: %d' % ( self.ScF.scoreStream[self.ScF.firstNotePage].measureNumber, self.ScF.scoreStream[self.ScF.lastNotePage].measureNumber)) @@ -608,7 +608,7 @@ def analyzeRecording(self): # case in which the musician plays a note of a not displayed page pageNumber = 0 final = False - while final == False: + while not final: if (pageNumber < self.totalPagesScore and self.ScF.lastNotePosition >= self.beginningPages[pageNumber]): pageNumber += 1 @@ -631,7 +631,7 @@ def analyzeRecording(self): elif (self.ScF.lastNotePosition >= self.middlePages[self.currentLeftPage] - and self.isMoving == False): #50% case + and not self.isMoving): #50% case self.isMoving = True environLocal.printDebug('moving right page to left') self.moving() @@ -646,7 +646,7 @@ def analyzeRecording(self): 'page: hits=%d' % self.hits) if self.hits == 2: self.hits = 0 - if self.isMoving == False: + if not self.isMoving: self.isMoving = True environLocal.printDebug('moving for hits') self.moving() diff --git a/music21_tools/audioSearchDemos/humanVScomputer.py b/music21_tools/audioSearchDemos/humanVScomputer.py index ab57323..17652b5 100644 --- a/music21_tools/audioSearchDemos/humanVScomputer.py +++ b/music21_tools/audioSearchDemos/humanVScomputer.py @@ -31,7 +31,7 @@ def runGame(): time.sleep(2) print('3, 2, 1 GO!') nameNotes = ['A', 'B', 'C', 'D', 'E', 'F', 'G'] - while(good == True): + while(good): randomNumber = random.randint(0, 6) octaveNumber = 4 # I can put a random number here... fullNameNote = '%s%d' % (nameNotes[randomNumber], octaveNumber) @@ -51,7 +51,7 @@ def runGame(): (notesList, unused_durationList) = base.joinConsecutiveIdenticalPitches(detectedPitchObjects) j = 0 i = 0 - while i < len(notesList) and j < len(gameNotes) and good == True: + while i < len(notesList) and j < len(gameNotes) and good: if notesList[i].name == 'rest': i = i + 1 elif notesList[i].name == gameNotes[j].name: @@ -61,11 +61,11 @@ def runGame(): print('WRONG NOTE! You played', notesList[i].fullName, 'and should have been', gameNotes[j].fullName) good = False - if good == True and j != len(gameNotes): + if good and j != len(gameNotes): good = False print('YOU ARE VERY SLOW!!! PLAY FASTER NEXT TIME!') - if good == False: + if not good: print('GAME OVER! TOTAL ROUNDS: %d' % roundNumber) if __name__ == '__main__': diff --git a/music21_tools/audioSearchDemos/repetitionGame.py b/music21_tools/audioSearchDemos/repetitionGame.py index 0df9de7..dcf5542 100644 --- a/music21_tools/audioSearchDemos/repetitionGame.py +++ b/music21_tools/audioSearchDemos/repetitionGame.py @@ -49,7 +49,7 @@ def game(self): unused_durationList) = base.joinConsecutiveIdenticalPitches(detectedPitchObjects) j = 0 i = 0 - while i < len(notesList) and j < len(self.gameNotes) and self.good == True: + while i < len(notesList) and j < len(self.gameNotes) and self.good: if notesList[i].name == 'rest': i = i + 1 elif notesList[i].name == self.gameNotes[j].name: @@ -60,11 +60,11 @@ def game(self): 'and should have been', self.gameNotes[j].fullName) self.good = False - if self.good == True and j != len(self.gameNotes): + if self.good and j != len(self.gameNotes): self.good = False print('YOU ARE VERY SLOW!!! PLAY FASTER NEXT TIME!') - if self.good == False: + if not self.good: print('YOU LOSE!! HAHAHAHA') else: diff --git a/music21_tools/bhadley/nips2011.py b/music21_tools/bhadley/nips2011.py index 0606db3..840b452 100644 --- a/music21_tools/bhadley/nips2011.py +++ b/music21_tools/bhadley/nips2011.py @@ -218,7 +218,7 @@ def getLeadsheetDatesFromBillboard(): for a in words: a.strip() pretty = pretty + ' ' + a - if song == True: + if song: try: j = float(x) continue @@ -226,7 +226,7 @@ def getLeadsheetDatesFromBillboard(): song = False y = pretty continue - if song == False: + if not song: t = y, pretty tempList.append( t ) song = True diff --git a/music21_tools/chant/chant.py b/music21_tools/chant/chant.py index 7669a57..0865ad5 100644 --- a/music21_tools/chant/chant.py +++ b/music21_tools/chant/chant.py @@ -161,7 +161,7 @@ def toGABC(self, useClef=None, nextNote=None): letter += 'w' elif self.stropha: letter += 's' - if self.liquescent != False: + if self.liquescent: #if nextNote is not None: # if nextNote.diatonicNoteNum > self.diatonicNoteNum: # letter += '<' @@ -173,24 +173,24 @@ def toGABC(self, useClef=None, nextNote=None): letter += '<' else: letter += '~' - if self.punctumMora != False: + if self.punctumMora: if self.punctumMora == 1: letter += '.' elif self.punctumMora == 2: letter += '..' else: raise ChantException('unable to do punctumMora with more than two notes') - if self.episema != False: + if self.episema: if self.episema == 'vertical': letter += "'" elif self.episema == 'below': letter += '_0' else: letter += '_' - if self.breakNeume != False: + if self.breakNeume: letter += '!' - if self.choralSign != False: + if self.choralSign: letter += '[cs:' + self.choralSign + ']' if self.polyphonic: diff --git a/music21_tools/choraleTools/mnum_fixer.py b/music21_tools/choraleTools/mnum_fixer.py index 723499b..e028204 100644 --- a/music21_tools/choraleTools/mnum_fixer.py +++ b/music21_tools/choraleTools/mnum_fixer.py @@ -58,7 +58,7 @@ def runOne(c, cName): truncated = True if not perfect and short < (barQl / 2) else False half = True if not perfect and short == (barQl / 2) else False - if half and priorMeasureWasIncomplete == False: + if half and not priorMeasureWasIncomplete: priorMeasureWasIncomplete = True priorMeasureDuration = mQl priorMeasure = m diff --git a/music21_tools/misc/monteverdi.py b/music21_tools/misc/monteverdi.py index 55da7dd..d0aa11f 100644 --- a/music21_tools/misc/monteverdi.py +++ b/music21_tools/misc/monteverdi.py @@ -56,7 +56,7 @@ def analyzeBooks(books=(3,), start=1, end=20, show=False, strict=False): for book in books: for i in range(start, end + 1): filename = 'monteverdi/madrigal.%s.%s.rntxt' % (book, i) - if strict == True: + if strict: analysis = corpus.parse(filename) print(book, i) else: @@ -66,7 +66,7 @@ def analyzeBooks(books=(3,), start=1, end=20, show=False, strict=False): except Exception: print('Cannot parse %s, maybe it does not exist...' % (filename)) continue - if show == True: + if show: analysis.show() (MF, mF) = iqChordsAndPercentage(analysis) (MSt, mSt) = iqSemitonesAndPercentage(analysis) @@ -191,7 +191,7 @@ def monteverdiParallels(books=(3,), start=1, end=20, show=True, strict=False): for book in books: for i in range(start, end + 1): filename = 'monteverdi/madrigal.%s.%s.xml' % (book, i) - if strict == True: + if strict: c = corpus.parse(filename) print(book, i) else: @@ -267,10 +267,10 @@ def findPhraseBoundaries(book=4, madrigal=12): phraseScoresByOffset[phraseOffset] = 0 existingScore = 0 - if thisNote.isRest == True: + if thisNote.isRest: continue - if nextNote.isRest == True: + if nextNote.isRest: thisScore = thisScore + 10 else: intervalToNextNote = interval.notesToInterval(thisNote.pitches[0], diff --git a/music21_tools/trecento/medren.py b/music21_tools/trecento/medren.py index a0191c2..23be6df 100644 --- a/music21_tools/trecento/medren.py +++ b/music21_tools/trecento/medren.py @@ -1886,13 +1886,13 @@ def setBarlineStyle(score, newStyle, oldStyle='regular', *, inPlace=False): barline.style = newStyle return score -def scaleDurations(score, scalingNum=1, *, inPlace=False, scaleUnlinked=True): +def scaleDurations(score, scalingNum: int|float = 1, *, inPlace=False, scaleUnlinked=True): ''' scale all notes and TimeSignatures by the scaling amount. returns the Score object ''' - if inPlace is False: + if not inPlace: score = copy.deepcopy(score) for el in score.recurse(): From 9270d634c3040aefa615e51984eb20b3855ac7fb Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 14:11:35 -1000 Subject: [PATCH 07/28] Soften user-facing text: de-shout and remove mockery MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces ALL-CAPS shouting in print statements and tkinter UI labels with normal sentence case across audioSearchDemos and a few stragglers. Rewrites lines that mocked or laughed at the user — "YOU LOSE!! HAHAHAHA", "YOU ARE VERY SLOW!!! PLAY FASTER NEXT TIME!", "LOSER", etc. — into neutral phrasing. MIDI constants (NOTE_ON, END_OF_TRACK) and template tokens (SCOREGOESHERE) left alone. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../audioSearchDemos/graphicalInterfaceGame.py | 12 ++++++------ .../audioSearchDemos/graphicalInterfaceSF.py | 12 ++++++------ music21_tools/audioSearchDemos/humanVScomputer.py | 10 +++++----- music21_tools/audioSearchDemos/repetitionGame.py | 12 ++++++------ music21_tools/bhadley/nips2011.py | 2 +- music21_tools/counterpoint/species.py | 2 +- music21_tools/trecento/runTrecentoCadence.py | 2 +- 7 files changed, 26 insertions(+), 26 deletions(-) diff --git a/music21_tools/audioSearchDemos/graphicalInterfaceGame.py b/music21_tools/audioSearchDemos/graphicalInterfaceGame.py index 6e14abc..8bf2925 100644 --- a/music21_tools/audioSearchDemos/graphicalInterfaceGame.py +++ b/music21_tools/audioSearchDemos/graphicalInterfaceGame.py @@ -96,11 +96,11 @@ def callback(self): def startGame(self): #master = self.master self.good = True - self.textFinal.set('WAIT...') + self.textFinal.set('Wait...') #self.boxName6.grid(row=4, column=0, columnspan=3) self.rG = repetitionGame.repetitionGame() self.good = True - self.textFinal.set('GO!') + self.textFinal.set('Go!') self.master.after(0, self.mainLoop) @@ -131,9 +131,9 @@ def mainLoop(self): self.master.after(10, self.mainLoop) else: if self.counter == -1: - self.textP1Result.set('WINNER!') + self.textP1Result.set('Winner!') #boxName.grid(row=2, column=0) - self.textP2Result.set('LOSER') + self.textP2Result.set('Second place') #boxName.grid(row=2, column=2) self.canvas1.create_oval(1, 1, 40, 40, fill='yellow') self.canvas1.grid(row=1, column=0) @@ -141,8 +141,8 @@ def mainLoop(self): self.canvas2.create_oval(1, 1, 40, 40, fill='grey') self.canvas2.grid(row=1, column=2) else: - self.textP1Result.set('LOSER') - self.textP2Result.set('WINNER!') + self.textP1Result.set('Second place') + self.textP2Result.set('Winner!') self.canvas1.create_oval(1, 1, 40, 40, fill='grey') self.canvas1.grid(row=1, column=0) diff --git a/music21_tools/audioSearchDemos/graphicalInterfaceSF.py b/music21_tools/audioSearchDemos/graphicalInterfaceSF.py index fbdfb49..784981d 100644 --- a/music21_tools/audioSearchDemos/graphicalInterfaceSF.py +++ b/music21_tools/audioSearchDemos/graphicalInterfaceSF.py @@ -345,7 +345,7 @@ def initializeGraphicInterface(self): if self.firstTime: self.button2 = tkinter.Button(master, - text='START SF', + text='Start SF', width=self.sizeButton, command=self.startScoreFollower, bg='green') @@ -369,11 +369,11 @@ def initializeGraphicInterface(self): width=self.sizeButton, command=self.pageBackward) self.button7.grid(row=3, column=3) - self.button5 = tkinter.Button(master, text='MOVE', + self.button5 = tkinter.Button(master, text='Move', width=self.sizeButton, command=self.moving, bg='beige') self.button5.grid(row=2, column=3) - self.button6 = tkinter.Button(master, text='STOP SF', + self.button6 = tkinter.Button(master, text='Stop SF', width=self.sizeButton, command=self.stopScoreFollower, bg='red') self.button6.grid(row=5, column=4) @@ -512,7 +512,7 @@ def goToLastPage(self): def startScoreFollower(self): environLocal.printDebug('startScoreFollower starting') - self.button2 = tkinter.Button(self.master, text='START SF', width=self.sizeButton, + self.button2 = tkinter.Button(self.master, text='Start SF', width=self.sizeButton, command=self.startScoreFollower, state='disable', bg='green') self.button2.grid(row=5, column=3) scNotes = self.scorePart.flatten().notesAndRests @@ -586,10 +586,10 @@ def continueScoreFollower(self): environLocal.printDebug('stopped...') self.button2.destroy() - self.button2 = tkinter.Button(self.master, text='START SF', width=self.sizeButton, + self.button2 = tkinter.Button(self.master, text='Start SF', width=self.sizeButton, command=self.startScoreFollower, bg='green') self.button2.grid(row=5, column=3) - self.textVarComments.set('END!! %s' % (self.rt.resultInThread)) + self.textVarComments.set('Done. %s' % (self.rt.resultInThread)) def analyzeRecording(self): diff --git a/music21_tools/audioSearchDemos/humanVScomputer.py b/music21_tools/audioSearchDemos/humanVScomputer.py index 17652b5..c4cd77f 100644 --- a/music21_tools/audioSearchDemos/humanVScomputer.py +++ b/music21_tools/audioSearchDemos/humanVScomputer.py @@ -38,8 +38,8 @@ def runGame(): gameNotes.append(note.Note(fullNameNote)) roundNumber = roundNumber + 1 - print('ROUND %d' % roundNumber) - print('NOTES UNTIL NOW: (this will not be shown in the final version)') + print('Round %d' % roundNumber) + print('Notes so far (debug-only, will not appear in the final version):') for k in range(len(gameNotes)): print(gameNotes[k].fullName) @@ -58,15 +58,15 @@ def runGame(): i = i + 1 j = j + 1 else: - print('WRONG NOTE! You played', notesList[i].fullName, 'and should have been', gameNotes[j].fullName) + print('Wrong note. You played', notesList[i].fullName, 'and it should have been', gameNotes[j].fullName) good = False if good and j != len(gameNotes): good = False - print('YOU ARE VERY SLOW!!! PLAY FASTER NEXT TIME!') + print("Time's up — try a faster pace next round.") if not good: - print('GAME OVER! TOTAL ROUNDS: %d' % roundNumber) + print('Game over. Total rounds: %d' % roundNumber) if __name__ == '__main__': runGame() diff --git a/music21_tools/audioSearchDemos/repetitionGame.py b/music21_tools/audioSearchDemos/repetitionGame.py index dcf5542..7096010 100644 --- a/music21_tools/audioSearchDemos/repetitionGame.py +++ b/music21_tools/audioSearchDemos/repetitionGame.py @@ -56,25 +56,25 @@ def game(self): i = i + 1 j = j + 1 else: - print('WRONG NOTE! You played', notesList[i].fullName, - 'and should have been', self.gameNotes[j].fullName) + print('Wrong note. You played', notesList[i].fullName, + 'and it should have been', self.gameNotes[j].fullName) self.good = False if self.good and j != len(self.gameNotes): self.good = False - print('YOU ARE VERY SLOW!!! PLAY FASTER NEXT TIME!') + print("Time's up — try a faster pace next round.") if not self.good: - print('YOU LOSE!! HAHAHAHA') + print('Game over.') else: while i < len(notesList) and notesList[i].name == 'rest': i = i + 1 if i < len(notesList): self.gameNotes.append(notesList[i]) #add a new note - print('WELL DONE!') + print('Well done!') else: - print('YOU HAVE NOT ADDED A NEW NOTE! REPEAT AGAIN NOW') + print('No new note added — please add one before repeating.') self.round = self.round - 1 return self.good diff --git a/music21_tools/bhadley/nips2011.py b/music21_tools/bhadley/nips2011.py index 840b452..71bd7c3 100644 --- a/music21_tools/bhadley/nips2011.py +++ b/music21_tools/bhadley/nips2011.py @@ -344,7 +344,7 @@ def getLeadsheetDatesFromBillboard(): foo = len(outputjson) - 2 outputjson = outputjson[0:foo] + "]'" print(outputjson) - print('FINISHED! Found this many matches: ', matches) + print('Finished. Found this many matches: ', matches) def probabilityOfChance(): ''' diff --git a/music21_tools/counterpoint/species.py b/music21_tools/counterpoint/species.py index f9cff38..35d4d26 100644 --- a/music21_tools/counterpoint/species.py +++ b/music21_tools/counterpoint/species.py @@ -1002,7 +1002,7 @@ def generateFirstSpecies(self, cantusFirmus, minorScale, choice='random'): while (not goodHarmony or not goodMelody or not thirdsGood or not sixthsGood): environLocal.printDebug(['']) environLocal.printDebug(['-------------------------------------']) - environLocal.printDebug(['STARTING OVER NOW']) + environLocal.printDebug(['starting over']) try: top = self.getValidSecondVoice(cantusFirmus, minorScale, 'random') top = self.raiseLeadingTone(top, minorScale) diff --git a/music21_tools/trecento/runTrecentoCadence.py b/music21_tools/trecento/runTrecentoCadence.py index 11bbc68..bf8aa75 100644 --- a/music21_tools/trecento/runTrecentoCadence.py +++ b/music21_tools/trecento/runTrecentoCadence.py @@ -120,7 +120,7 @@ def makePDFfromPiecesWithCapua(start=2, finish=3): if randomPiece.incipit: retrievedPieces.append(randomPiece) except: - raise Exception('Ugg ' + str(i)) + raise Exception('Could not retrieve random piece at index ' + str(i)) # lilyString = "" # retrievedPieces.sort(key=sortByPMFC) From cc78910d814027d0d49160f11b1a8b125946f493 Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 14:14:30 -1000 Subject: [PATCH 08/28] fix MensuralRest construction --- music21_tools/trecento/medren.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/music21_tools/trecento/medren.py b/music21_tools/trecento/medren.py index 23be6df..68b0525 100644 --- a/music21_tools/trecento/medren.py +++ b/music21_tools/trecento/medren.py @@ -574,20 +574,23 @@ class MensuralRest(GeneralMensuralNote, note.Rest): ''' # scaling? - def __init__(self, *arguments, **keywords): - note.Rest.__init__(self, *arguments, **keywords) # do not replace with super + def __init__(self, mensuralTypeOrAbbr: str = 'brevis', **keywords): + # Do not forward the mensural-type string to note.Rest: in music21 v10 + # the first positional arg is `length` (a Duration type or quarterLength), + # and a mensural abbreviation like 'SB' would raise DurationException. + note.Rest.__init__(self, **keywords) # do not replace with super GeneralMensuralNote.__init__(self) # due to different keywords... self._gettingDuration = False self._mensuralType = 'brevis' - if arguments: - tOrA = arguments[0] - if tOrA in _validMensuralTypes: - self._mensuralType = tOrA - elif tOrA in _validMensuralAbbr: - self._mensuralType = _validMensuralTypes[_validMensuralAbbr.index(tOrA)] else: - raise MedRenException('%s is not a valid mensural type or abbreviation' % tOrA) + tOrA = mensuralTypeOrAbbr + if tOrA in _validMensuralTypes: + self._mensuralType = tOrA + elif tOrA in _validMensuralAbbr: + self._mensuralType = _validMensuralTypes[_validMensuralAbbr.index(tOrA)] + else: + raise MedRenException('%s is not a valid mensural type or abbreviation' % tOrA) self._duration = None self._fontString = '' From 74c02dd69600d85cae249b72592da8a72a516d6e Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 14:14:58 -1000 Subject: [PATCH 09/28] missed a line --- music21_tools/trecento/medren.py | 1 - 1 file changed, 1 deletion(-) diff --git a/music21_tools/trecento/medren.py b/music21_tools/trecento/medren.py index 68b0525..512df33 100644 --- a/music21_tools/trecento/medren.py +++ b/music21_tools/trecento/medren.py @@ -583,7 +583,6 @@ def __init__(self, mensuralTypeOrAbbr: str = 'brevis', **keywords): self._gettingDuration = False self._mensuralType = 'brevis' - else: tOrA = mensuralTypeOrAbbr if tOrA in _validMensuralTypes: self._mensuralType = tOrA From 5c86f79e4dac55e91eb8a9afd5d4719049a88353 Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 14:16:04 -1000 Subject: [PATCH 10/28] fix short/confusing variable names --- music21_tools/audioSearchDemos/omrfollow.py | 6 ++-- music21_tools/bhadley/harmonyRealizer.py | 10 +++---- music21_tools/chant/chant.py | 6 ++-- .../trecento/findTrecentoFragments.py | 8 ++--- music21_tools/trecento/medren.py | 30 +++++++++---------- music21_tools/trecento/notation.py | 6 ++-- 6 files changed, 33 insertions(+), 33 deletions(-) diff --git a/music21_tools/audioSearchDemos/omrfollow.py b/music21_tools/audioSearchDemos/omrfollow.py index 2085c09..8d76091 100644 --- a/music21_tools/audioSearchDemos/omrfollow.py +++ b/music21_tools/audioSearchDemos/omrfollow.py @@ -86,16 +86,16 @@ def recognizeScore(scorePart, pageMeasureNumbers, iterations=1): time.sleep(3) searchScore = audioSearch.transcriber.runTranscribe(show=False, plot=False, seconds=15.0, saveFile=False) - l = search.approximateNoteSearch(searchScore, allStreams) + matches = search.approximateNoteSearch(searchScore, allStreams) scores = [0 for j in range(len(pages))] for i in range(8): # top 8 searches - topStream = l[i] + topStream = matches[i] scorePage = topStream.pageNumber - 1 scores[scorePage] += (topStream.matchProbability / (i + 1.5)) * 10 print('\nBest guesses (pg#, starting measure, probability)') - for i, st in enumerate(l): + for i, st in enumerate(matches): print(st.pageNumber, st.startMeasure, st.matchProbability) if i >= 7: break diff --git a/music21_tools/bhadley/harmonyRealizer.py b/music21_tools/bhadley/harmonyRealizer.py index bf34b5e..d7d5ac9 100644 --- a/music21_tools/bhadley/harmonyRealizer.py +++ b/music21_tools/bhadley/harmonyRealizer.py @@ -91,13 +91,13 @@ def generateSmoothBassLine(harmonyObjects): octavePlus = interval.Interval(lastBass, copy.deepcopy(cs.bass())) cs.bass().octave = cs.bass().octave - 2 octaveMinus = interval.Interval(lastBass, copy.deepcopy(cs.bass())) - l = [sameOctave, octavePlus, octaveMinus] + candidates = [sameOctave, octavePlus, octaveMinus] minimum = sameOctave.generic.undirected ret = sameOctave - for i in l: - if i.generic.undirected < minimum: - minimum = i.generic.undirected - ret = i + for candidate in candidates: + if candidate.generic.undirected < minimum: + minimum = candidate.generic.undirected + ret = candidate if ret.noteEnd.octave > 3 or ret.noteEnd.octave < 1: ret.noteEnd.octave = lastBass.octave diff --git a/music21_tools/chant/chant.py b/music21_tools/chant/chant.py index 0865ad5..8afe655 100644 --- a/music21_tools/chant/chant.py +++ b/music21_tools/chant/chant.py @@ -530,9 +530,9 @@ def testSimpleFile(self): s.append(clef.AltoClef()) n = GregorianNote('C4') - l = note.Lyric('Po') - l.syllabic = 'begin' - n.lyrics.append(l) + lyric = note.Lyric('Po') + lyric.syllabic = 'begin' + n.lyrics.append(lyric) n.oriscus = True s.append(n) n2 = GregorianNote('D4') diff --git a/music21_tools/trecento/findTrecentoFragments.py b/music21_tools/trecento/findTrecentoFragments.py index 795b4b0..cf3e0f9 100644 --- a/music21_tools/trecento/findTrecentoFragments.py +++ b/music21_tools/trecento/findTrecentoFragments.py @@ -241,10 +241,10 @@ def audioVirelaiSearch(): # from music21 import converter # searchScore = converter.parse("c'4 a8 a4 g8 b4. d'4. c8 b a g f4", '6/8') # searchScore.show() - l = search.approximateNoteSearch(searchScore, virelaiCantuses) - for i in l: - print(i.metadata.title, i.matchProbability) - l[0].show() + matches = search.approximateNoteSearch(searchScore, virelaiCantuses) + for match in matches: + print(match.metadata.title, match.matchProbability) + matches[0].show() def findSimilarGloriaParts(): ''' diff --git a/music21_tools/trecento/medren.py b/music21_tools/trecento/medren.py index 512df33..18fcf63 100644 --- a/music21_tools/trecento/medren.py +++ b/music21_tools/trecento/medren.py @@ -1769,30 +1769,30 @@ def breakMensuralStreamIntoBrevisLengths(inpStream, inpMOrD=None, printUpdates=F inpStream_copy = copy.deepcopy(inpStream) # Preserve your input newStream = inpStream.__class__() - def isHigherInhierarchy(l, u): + def isHigherInhierarchy(lower, upper): hierarchy = ['Stream', 'Score', 'Part', 'Measure'] - uclass0 = None - for tryClass in u.classes: + upperClass = None + for tryClass in upper.classes: if tryClass in hierarchy: - uclass0 = tryClass + upperClass = tryClass break - lclass0 = None - for tryClass in l.classes: + lowerClass = None + for tryClass in lower.classes: if tryClass in hierarchy: - lclass0 = tryClass + lowerClass = tryClass break - if uclass0 is None: - raise MedRenException('Cannot find class in our hierarchy of streams: %s' % (u)) - if lclass0 is None: - raise MedRenException('Cannot find class in our hierarchy of streams: %s' % (l)) + if upperClass is None: + raise MedRenException('Cannot find class in our hierarchy of streams: %s' % (upper)) + if lowerClass is None: + raise MedRenException('Cannot find class in our hierarchy of streams: %s' % (lower)) - if hierarchy.index(uclass0) == 0: + if hierarchy.index(upperClass) == 0: return False else: - return hierarchy.index(lclass0) <= hierarchy.index(uclass0) + return hierarchy.index(lowerClass) <= hierarchy.index(upperClass) tempStream_1, tempStream_2 = inpStream_copy.splitByClass(None, lambda x: x.isStream) if tempStream_1: @@ -2054,8 +2054,8 @@ def cummingSchubertStrettoFuga(score): print(score.title) print('intv.\tcount\tpercent') - for l in sorted(strettoKeys): - print('%2d\t%3d\t%2d%%' % (l, strettoKeys[l], strettoKeys[l] * 100 / len(sn) - 1)) + for intv in sorted(strettoKeys): + print('%2d\t%3d\t%2d%%' % (intv, strettoKeys[intv], strettoKeys[intv] * 100 / len(sn) - 1)) print('\n') class MedRenException(exceptions21.Music21Exception): diff --git a/music21_tools/trecento/notation.py b/music21_tools/trecento/notation.py index 8a8ba72..3e972b3 100644 --- a/music21_tools/trecento/notation.py +++ b/music21_tools/trecento/notation.py @@ -925,8 +925,8 @@ def determineStrongestMeasureLengths(self, remain = lenRem lenRem_final = lenRem - for l in _allCombinations(change, change_num): - for i in l: + for combo in _allCombinations(change, change_num): + for i in combo: lengths_changeable[i] += diff if release is not None: lengths_changeable[release] -= diff @@ -1155,7 +1155,7 @@ def translate(self): except TypeError: raise TypeError('ml is screwed up! %s' % ml) - return [float(l) for l in knownLengthsList] + return [float(length) for length in knownLengthsList] def translateDivI(self, unchangeableNoteLengthsList=None, unknownLengthsDict=None, minRem=None): ''' From 5e710ad9344077e15dba11a10379a04024b8aba9 Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 14:46:52 -1000 Subject: [PATCH 11/28] fix comment spacing --- .../graphicalInterfaceGame.py | 19 +++--- .../audioSearchDemos/graphicalInterfaceSF.py | 30 ++++----- music21_tools/audioSearchDemos/omrfollow.py | 2 +- .../audioSearchDemos/repetitionGame.py | 2 +- music21_tools/bhadley/harmonyRealizer.py | 63 +++++++++---------- music21_tools/bhadley/nips2011.py | 58 +++++++++-------- music21_tools/chant/chant.py | 20 +++--- music21_tools/choraleTools/mnum_fixer.py | 4 +- music21_tools/composition/phasing.py | 2 +- music21_tools/counterpoint/species.py | 16 ++--- music21_tools/featureExtraction/ismir2011.py | 32 +++++----- music21_tools/josquin/label_intervals.py | 9 ++- music21_tools/misc/eschbeg.py | 16 ++--- music21_tools/misc/monteverdi.py | 28 ++++----- music21_tools/theory/mgtaPart1.py | 48 +++++++------- music21_tools/theory/mgtaPart2.py | 2 +- .../theoryAnalysis/theoryAnalyzer.py | 32 +++++----- music21_tools/theoryAnalysis/theoryResult.py | 6 +- music21_tools/theoryAnalysis/wwnortonMGTA.py | 14 ++--- music21_tools/trecento/cadencebook.py | 2 +- music21_tools/trecento/capua.py | 12 ++-- .../trecento/findTrecentoFragments.py | 2 +- music21_tools/trecento/polyphonicSnippet.py | 2 +- music21_tools/trecento/quodJactatur.py | 10 +-- music21_tools/trecento/runTrecentoCadence.py | 16 ++--- music21_tools/trecento/tonality.py | 2 +- music21_tools/trecento/trecentoCadence.py | 1 - publications/icmc2011.py | 8 +-- publications/ismir2010.py | 6 +- publications/seaverOct2009.py | 6 +- publications/seaver_presentation_2008.py | 4 +- publications/smt2010.py | 4 +- 32 files changed, 231 insertions(+), 247 deletions(-) diff --git a/music21_tools/audioSearchDemos/graphicalInterfaceGame.py b/music21_tools/audioSearchDemos/graphicalInterfaceGame.py index 8bf2925..8be3dee 100644 --- a/music21_tools/audioSearchDemos/graphicalInterfaceGame.py +++ b/music21_tools/audioSearchDemos/graphicalInterfaceGame.py @@ -13,15 +13,14 @@ import math from . import repetitionGame -import tkinter # @UnresolvedImport @Reimport - +import tkinter class SFApp(): def __init__(self, master): self.master = master self.frame = tkinter.Frame(master) - #self.frame.pack() + # self.frame.pack() self.master.wm_title('Repetition game') self.sizeButton = 11 @@ -94,10 +93,10 @@ def callback(self): self.buttonStart.grid(row=3, column=0, columnspan=3) def startGame(self): - #master = self.master + # master = self.master self.good = True self.textFinal.set('Wait...') - #self.boxName6.grid(row=4, column=0, columnspan=3) + # self.boxName6.grid(row=4, column=0, columnspan=3) self.rG = repetitionGame.repetitionGame() self.good = True self.textFinal.set('Go!') @@ -105,14 +104,14 @@ def startGame(self): def mainLoop(self): - #master = self.master + # master = self.master if self.good: print('rounddddddddddddasdasdadsadad', self.rG.round) self.textRound.set('Round %d' % (self.rG.round + 1)) self.counter = math.pow(-1, self.rG.round) - if self.counter == 1: #player 1 + if self.counter == 1: # player 1 self.canvas1.create_oval(1, 1, 40, 40, fill='green') self.canvas1.grid(row=1, column=0) @@ -132,9 +131,9 @@ def mainLoop(self): else: if self.counter == -1: self.textP1Result.set('Winner!') - #boxName.grid(row=2, column=0) + # boxName.grid(row=2, column=0) self.textP2Result.set('Second place') - #boxName.grid(row=2, column=2) + # boxName.grid(row=2, column=2) self.canvas1.create_oval(1, 1, 40, 40, fill='yellow') self.canvas1.grid(row=1, column=0) @@ -146,7 +145,7 @@ def mainLoop(self): self.canvas1.create_oval(1, 1, 40, 40, fill='grey') self.canvas1.grid(row=1, column=0) - #self.canvas2.destroy() + # self.canvas2.destroy() self.canvas2.create_oval(1, 1, 40, 40, fill='yellow') self.canvas2.grid(row=1, column=2) diff --git a/music21_tools/audioSearchDemos/graphicalInterfaceSF.py b/music21_tools/audioSearchDemos/graphicalInterfaceSF.py index 784981d..27e9219 100644 --- a/music21_tools/audioSearchDemos/graphicalInterfaceSF.py +++ b/music21_tools/audioSearchDemos/graphicalInterfaceSF.py @@ -34,7 +34,7 @@ _MOD = 'audioSearch/graphicalInterfaceSF.py' environLocal = environment.Environment(_MOD) -from music21.audioSearch import * #@UnusedWildImport +from music21.audioSearch import * #from music21.audioSearch import recording from music21 import scale @@ -61,8 +61,8 @@ def __init__(self, master): self.master.wm_title('Score follower - music21') self.scoreNameSong = 'scores/d luca gloria_Page_' - #'/Users/cuthbert/Desktop/scores/Saint-Saens-Clarinet-Sonata/Saint-Saens-Clarinet-Sonata_Page_' - #C:\Users\Jordi\Desktop\m21\Saint-Saens-Clarinet-Sonata\Saint-Saens-Clarinet-Sonata\Saint-Saens-Clarinet-Sonata_Page_' + # '/Users/cuthbert/Desktop/scores/Saint-Saens-Clarinet-Sonata/Saint-Saens-Clarinet-Sonata_Page_' + # C:\Users\Jordi\Desktop\m21\Saint-Saens-Clarinet-Sonata\Saint-Saens-Clarinet-Sonata\Saint-Saens-Clarinet-Sonata_Page_' #'scores/d luca gloria_Page_' #'scores/d luca gloria_Page_' self.format = 'tiff'#'jpg' @@ -86,7 +86,7 @@ def __init__(self, master): try: # for windows unused_user32 = ctypes.windll.user32 # test for error... self.screenResolution = [1024, 600] - #self.screenResolution = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1) + # self.screenResolution = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1) environLocal.printDebug('screen resolution (windows) %d x %d' % (self.screenResolution[0], self.screenResolution[1])) self.resolution = True except: # mac and linux @@ -172,7 +172,7 @@ def cropBorder(self, img, minColor=240, maxColor=256): rightCut = 0 numberPixels = int(math.sqrt(len(data) / 3000000) * 4) - #Find top + # Find top for i in range(0, len(data), numberPixels + int(resX / 10)): if (data[i][0] not in colorRange and data[i][1] not in colorRange @@ -180,7 +180,7 @@ def cropBorder(self, img, minColor=240, maxColor=256): topCut = int(i / resX) break - #Find bottom + # Find bottom for i in range(len(data) - 1, 0, -1 * numberPixels - int(resX / 10)): if (data[i][0] not in colorRange and data[i][1] not in colorRange @@ -188,7 +188,7 @@ def cropBorder(self, img, minColor=240, maxColor=256): bottomCut = int((len(data) - i) / resX) break - #Find left + # Find left stop = False for xPos in range(0, resX, numberPixels): # check every 4th pixel for yPos in range(xPos, resY, int(resY / 15)): @@ -218,7 +218,7 @@ def cropBorder(self, img, minColor=240, maxColor=256): else: leftCut = leftCut - numberPixels - #Find right + # Find right stop = False for xPos in range(resX - 1, 0, -numberPixels): # check every 4th pixel for yPos in range(resX - xPos, resY, int(resY / 15)): @@ -262,7 +262,7 @@ def cropBorder(self, img, minColor=240, maxColor=256): bottomCut = 0 if rightCut < 0: rightCut = 0 - #print (leftCut, topCut, rightCut, bottomCut) + # print(leftCut, topCut, rightCut, bottomCut) img = img.crop((leftCut, topCut, resX - rightCut, resY - bottomCut)) return img @@ -487,7 +487,7 @@ def goTo1stPage(self): image=self.phimage[0], tag='leftImage') self.textVar1.set('Left page: %d/%d' % (1, self.totalPagesScore)) - if self.totalPagesScore > 1: #there is more than 1 page + if self.totalPagesScore > 1: # there is more than 1 page self.canvas1.delete('rightImage') self.canvas1.create_image(self.positionxRight, self.positionyRight, image=self.phimage[1], tag='rightImage') @@ -502,7 +502,7 @@ def goToLastPage(self): image=self.phimage[self.totalPagesScore - 1], tag='leftImage') self.textVar1.set('Left page: %d/%d' % (self.totalPagesScore, self.totalPagesScore)) - if self.totalPagesScore > 1: #there is more than 1 page + if self.totalPagesScore > 1: # there is more than 1 page self.canvas1.delete('rightImage') self.textVar2.set('Right page: -/-') @@ -534,7 +534,7 @@ def startScoreFollower(self): self.textVar3.set('Start playing!') self.scoreFollower = ScF - #parameters for the thread 2 + # parameters for the thread 2 self.dummyQueue = queue.Queue() self.sampleQueue = queue.Queue() self.dummyQueue2 = queue.Queue() @@ -631,11 +631,11 @@ def analyzeRecording(self): elif (self.ScF.lastNotePosition >= self.middlePages[self.currentLeftPage] - and not self.isMoving): #50% case + and not self.isMoving): # 50% case self.isMoving = True environLocal.printDebug('moving right page to left') self.moving() - #self.isMoving = False + # self.isMoving = False environLocal.printDebug('playing a note of the second half part of the right page') elif (self.ScF.lastNotePosition >= self.beginningPages[self.currentLeftPage] @@ -650,7 +650,7 @@ def analyzeRecording(self): self.isMoving = True environLocal.printDebug('moving for hits') self.moving() - #self.isMoving = False + # self.isMoving = False else: self.hits = 0 environLocal.printDebug('playing a note of the left page') diff --git a/music21_tools/audioSearchDemos/omrfollow.py b/music21_tools/audioSearchDemos/omrfollow.py index 8d76091..8463995 100644 --- a/music21_tools/audioSearchDemos/omrfollow.py +++ b/music21_tools/audioSearchDemos/omrfollow.py @@ -53,7 +53,7 @@ def recognizeKuhlau(): Only does the first couple of pages ''' pageMeasureNumbers = [1, 73, 151, 217, 268, 313, 366, - 437, 506, 555, 614, 662, 702, 737, 764] #764 is end of document + 437, 506, 555, 614, 662, 702, 737, 764] # 764 is end of document kuhlau = converter.parse('kuhlau_op81_fl2.xml') recognizeScore(kuhlau, pageMeasureNumbers, iterations=3) diff --git a/music21_tools/audioSearchDemos/repetitionGame.py b/music21_tools/audioSearchDemos/repetitionGame.py index 7096010..692f641 100644 --- a/music21_tools/audioSearchDemos/repetitionGame.py +++ b/music21_tools/audioSearchDemos/repetitionGame.py @@ -71,7 +71,7 @@ def game(self): while i < len(notesList) and notesList[i].name == 'rest': i = i + 1 if i < len(notesList): - self.gameNotes.append(notesList[i]) #add a new note + self.gameNotes.append(notesList[i]) # add a new note print('Well done!') else: print('No new note added — please add one before repeating.') diff --git a/music21_tools/bhadley/harmonyRealizer.py b/music21_tools/bhadley/harmonyRealizer.py index d7d5ac9..6975ea1 100644 --- a/music21_tools/bhadley/harmonyRealizer.py +++ b/music21_tools/bhadley/harmonyRealizer.py @@ -52,7 +52,7 @@ def generateContrapuntalBassLine(harmonyObject, fbRules): fbLine.addElement(o) allSols = fbLine.realize(fbRules) - #print allSols.getNumSolutions() + # print(allSols.getNumSolutions()) return allSols.generateRandomRealizations(1) def generateSmoothBassLine(harmonyObjects): @@ -118,30 +118,29 @@ def generatePopSongRules(): ''' fbRules = rules.Rules() - #Single Possibility rules - fbRules.forbidIncompletePossibilities = True #True - fbRules.upperPartsMaxSemitoneSeparation = 12 #12 - fbRules.forbidVoiceCrossing = True #True - - #Consecutive Possibility rules - fbRules.forbidParallelFifths = True #True - fbRules.forbidParallelOctaves = True #True - fbRules.forbidHiddenFifths = True #True - fbRules.forbidHiddenOctaves = True #True - fbRules.forbidVoiceOverlap = True #True - fbRules.partMovementLimits = [] #[] - - #Special resolution rules - fbRules.resolveDominantSeventhProperly = False #True - fbRules.resolveDiminishedSeventhProperly = False #True - fbRules.resolveAugmentedSixthProperly = False #True - fbRules.doubledRootInDim7 = False #False - fbRules.applySinglePossibRulesToResolution = False #False - fbRules.applyConsecutivePossibRulesToResolution = False #False - fbRules.restrictDoublingsInItalianA6Resolution = True #True - - fbRules._upperPartsRemainSame = False #False - + # Single Possibility rules + fbRules.forbidIncompletePossibilities = True + fbRules.upperPartsMaxSemitoneSeparation = 12 + fbRules.forbidVoiceCrossing = True + + # Consecutive Possibility rules + fbRules.forbidParallelFifths = True + fbRules.forbidParallelOctaves = True + fbRules.forbidHiddenFifths = True + fbRules.forbidHiddenOctaves = True + fbRules.forbidVoiceOverlap = True + fbRules.partMovementLimits = [] + + # Special resolution rules + fbRules.resolveDominantSeventhProperly = False # def: True + fbRules.resolveDiminishedSeventhProperly = False # def: True + fbRules.resolveAugmentedSixthProperly = False # def: True + fbRules.doubledRootInDim7 = False + fbRules.applySinglePossibRulesToResolution = False + fbRules.applyConsecutivePossibRulesToResolution = False + fbRules.restrictDoublingsInItalianA6Resolution = True + + fbRules._upperPartsRemainSame = False fbRules.partMovementLimits.append((1, 5)) return fbRules @@ -224,12 +223,12 @@ def xtestRealizeLeadsheet(self, music21Stream): from music21 import base base.mainTest(Test, TestExternal) - #from music21 import corpus - #from music21.demos.bhadley import HarmonyRealizer - #test = HarmonyRealizer.TestExternal() + # from music21 import corpus + # from music21.demos.bhadley import HarmonyRealizer + # test = HarmonyRealizer.TestExternal() - #test.leadsheetEx1() - #sc = converter.parse('https://github.com/cuthbertLab/music21/raw/master/music21/corpus/leadSheet/fosterBrownHair.mxl') # Jeannie Light Brown Hair + # test.leadsheetEx1() + # sc = converter.parse('https://github.com/cuthbertLab/music21/raw/master/music21/corpus/leadSheet/fosterBrownHair.mxl') # Jeannie Light Brown Hair @@ -240,7 +239,7 @@ def xtestRealizeLeadsheet(self, music21Stream): Vr: $VP I IV | I | $VP I IV | V | $VP I IV | I | IV V | I IV | IV V | [2/4] I | [4/4] IV V | I IV | IV V | I | S: [D] $In $Vr $Vr $Vr ''' - #test.realizeclercqTemperleyEx(testfile1) + # test.realizeclercqTemperleyEx(testfile1) testfile2 = ''' % Brown-Eyed Girl @@ -253,7 +252,7 @@ def xtestRealizeLeadsheet(self, music21Stream): S: [G] $In $Vr*2 $Ext $Ch $Brk $Vr $Ext $Ch $A ''' - #test.realizeclercqTemperleyEx(testfile2) + # test.realizeclercqTemperleyEx(testfile2) diff --git a/music21_tools/bhadley/nips2011.py b/music21_tools/bhadley/nips2011.py index 71bd7c3..b841aa6 100644 --- a/music21_tools/bhadley/nips2011.py +++ b/music21_tools/bhadley/nips2011.py @@ -84,16 +84,16 @@ def nipsBuild(useOurExtractors=True, buildSet=1, evaluationMethod='coarse'): for wf in halfOfData: # taking half the data here.... to get the other set do [198:] year = entryDict[wf][0] - ## ignore 1960s and 1970s pieces... + # ignore 1960s and 1970s pieces... if year < 1961 or year >= 1981: fn = leadsheetDir + str(wf) + '.mxl' print(fn, year, entryDict[wf][1]) s = converter.parse(fn) title_id = s.metadata.title - #cv = year # if not using coarse but instead using the exact year as the class value + # cv = year # if not using coarse but instead using the exact year as the class value if evaluationMethod == 'coarse': - #coarse evaluation (only "old" or "new") + # coarse evaluation (only "old" or "new") if year < 1961: cv = 'old' else: @@ -149,8 +149,8 @@ def nipsEvalCoarse(): data1 = orange.data.table.Table('d:/docs/research/music21/nips-2011/year5-ourExtractors-1.tab') data2 = orange.data.table.Table('d:/docs/research/music21/nips-2011/year6-ourExtractors-2.tab') - #data1 = orange.ExampleTable('d:/docs/research/music21/nips-2011/year7-midi-only-1.tab') - #data2 = orange.ExampleTable('d:/docs/research/music21/nips-2011/year8-midi-only-2.tab') + # data1 = orange.ExampleTable('d:/docs/research/music21/nips-2011/year7-midi-only-1.tab') + # data2 = orange.ExampleTable('d:/docs/research/music21/nips-2011/year8-midi-only-2.tab') learners = {} @@ -266,7 +266,7 @@ def getLeadsheetDatesFromBillboard(): group = group.replace('?', 'H') t = title, group tempList.append( t ) - else: #i=2009 + else: # i=2009 address = 'http://www.jamrockentertainment.com/billboard-music-top-100-songs-lististed-by-year/top-100-songs-%s.html' % i url = urlopen(address) html = url.read() @@ -295,9 +295,7 @@ def getLeadsheetDatesFromBillboard(): DICT[str(i)] = copy.deepcopy(tempList) tempList = [] - #print DICT - - + # print(DICT) LOWERLIMIT = 1000 UPPERLIMIT = 12938 indexValues = range(LOWERLIMIT, UPPERLIMIT) @@ -317,21 +315,21 @@ def getLeadsheetDatesFromBillboard(): piece = converter.parse(dst) for year in DICT: for title, group in DICT[year]: - if piece.metadata.movementName.lower() == str(title).lower() : #or piece.metadata.composer == str(a): - #print "FOUND by title! Name", piece.metadata.movementName, "Composer", piece.metadata.composer, str(year) - #print dst + if piece.metadata.movementName.lower() == str(title).lower(): # or piece.metadata.composer == str(a): + # print("Found by title! Name", piece.metadata.movementName, "Composer", piece.metadata.composer, str(year)) + # print(dst) dates.append(int(year)) if len(dates) > 0: - date = min(dates) #date of entry + date = min(dates) # date of entry tempList = DICT[str(date)] for x in tempList: for e in x: if e.lower() == piece.metadata.movementName.lower(): - rank = (tempList.index(x) + 1 ) #position on Billboard 100 + rank = (tempList.index(x) + 1 ) # position on Billboard 100 - #print "Title:", piece.metadata.movementName, " Composer:", piece.metadata.composer, " Date:", date, " Position on Billboard:", rank - #print "Title:", piece.metadata.movementName, " Date:", date + # print "Title:", piece.metadata.movementName, " Composer:", piece.metadata.composer, " Date:", date, " Position on Billboard:", rank + # print "Title:", piece.metadata.movementName, " Date:", date matches = matches + 1 outputjson = outputjson + '{"%s":[%s,%s]}, ' % (i, date, rank) if (i % 500) == 0: @@ -380,7 +378,7 @@ def getPFromExperiment(): new = 1 avg = 0.0 for unused_trials in range(10000): - #generating the answerKey + # generating the answerKey answerKey = [] for i in range(NUM_OLD_PIECES): answerKey.append(old) @@ -388,19 +386,19 @@ def getPFromExperiment(): answerKey.append(new) random.shuffle(answerKey) - #generating the answers, then comparing them - #to answerKey and calculating the percentage - #guessed correctly + # generating the answers, then comparing them + # to answerKey and calculating the percentage + # guessed correctly numCorrect = 0.0 guessesOld = [] guessesNew = [] for answer in answerKey: guess = random.randint(0, 1) - #the algorithm is smart - it knows - #there is a maximum number of times it - #can guess old vs. new, and if it - #has reached that maximum, - #it won't guess that value + # the algorithm is smart - it knows + # there is a maximum number of times it + # can guess old vs. new, and if it + # has reached that maximum, + # it won't guess that value if guess == 0: guessesOld.append(guess) else: @@ -427,19 +425,19 @@ def BinomialProbability(n, k, p, q): qtothenminusk = pow(q, (n - k) ) return nchoosek * ptothek * qtothenminusk - k = 148 #number of times music21 found correct date (successes) - n = TOTAL_TRIALS #total number of trials + k = 148 # number of times music21 found correct date (successes) + n = TOTAL_TRIALS # total number of trials p = getPFromExperiment() print('The probability of a successful guess, as calculated by previous experiment', p) q = 1 - p prob = 0.0 - #Probability of getting 148 or more correct (sum - #the probabilty as k increses from 148 to 214) + # Probability of getting 148 or more correct (sum + # the probabilty as k increses from 148 to 214) for k in range(k, TOTAL_TRIALS): prob = prob + BinomialProbability(n, k, p, q) print('The probability that the computer would guess correctly 69% or more of the time', prob) if __name__ == '__main__': - #nipsBuild() + # nipsBuild() nipsEvalCoarse() diff --git a/music21_tools/chant/chant.py b/music21_tools/chant/chant.py index 8afe655..4b21b84 100644 --- a/music21_tools/chant/chant.py +++ b/music21_tools/chant/chant.py @@ -162,11 +162,11 @@ def toGABC(self, useClef=None, nextNote=None): elif self.stropha: letter += 's' if self.liquescent: - #if nextNote is not None: - # if nextNote.diatonicNoteNum > self.diatonicNoteNum: - # letter += '<' - # else: - # letter += '>' + # if nextNote is not None: + # if nextNote.diatonicNoteNum > self.diatonicNoteNum: + # letter += '<' + # else: + # letter += '>' if self.liquescent == 'ascending': letter += '<' elif self.liquescent == 'descending': @@ -332,8 +332,8 @@ def writeFile(self, text=None): >>> bsc = BaseScoreConverter() >>> filePath = bsc.writeFile('hello') - >>> assert(str(filePath).endswith('.gabc')) #_DOCS_HIDE - >>> filePath = '/var/folders/k9/T/music21/tmpekHFCr.gabc' #_DOCS_HIDE + >>> assert(str(filePath).endswith('.gabc')) # _DOCS_HIDE + >>> filePath = '/var/folders/k9/T/music21/tmpekHFCr.gabc' # _DOCS_HIDE >>> filePath '/var/folders/k9/T/music21/tmpekHFCr.gabc' @@ -355,9 +355,9 @@ def launchGregorio(self, fp=None): >>> bsc = BaseScoreConverter() >>> fn = '~cuthbert/Library/Gregorio/examples/Populas.gabc' - >>> #_DOCS_SHOW newFp = bsc.launchGregorio(fn) - >>> #_DOCS_SHOW bsc.gregorioCommand - >>> 'open -a"/usr/local/bin/gregorio" ' + fn #_DOCS_HIDE + >>> # _DOCS_SHOW newFp = bsc.launchGregorio(fn) + >>> # _DOCS_SHOW bsc.gregorioCommand + >>> 'open -a"/usr/local/bin/gregorio" ' + fn # _DOCS_HIDE 'open -a"/usr/local/bin/gregorio" ~cuthbert/Library/Gregorio/examples/Populas.gabc' diff --git a/music21_tools/choraleTools/mnum_fixer.py b/music21_tools/choraleTools/mnum_fixer.py index e028204..8d8aae6 100644 --- a/music21_tools/choraleTools/mnum_fixer.py +++ b/music21_tools/choraleTools/mnum_fixer.py @@ -175,7 +175,7 @@ def runOne(c, cName): # for i, pOrig in enumerate(c.parts): # expander = repeat.Expander(pOrig) # if not expander.isExpandable(): -# #print('incoherent repeats', cName) +# # print('incoherent repeats', cName) # try: # pOrig = expander.process() # except Exception: @@ -184,7 +184,7 @@ def runOne(c, cName): # pNew = newScore.parts[i] # expander = repeat.Expander(pNew) # if not expander.isExpandable(): -# #print('incoherent repeats', cName) +# # print('incoherent repeats', cName) # try: # pNew = expander.process() # except Exception: diff --git a/music21_tools/composition/phasing.py b/music21_tools/composition/phasing.py index 3e8350f..414a78d 100644 --- a/music21_tools/composition/phasing.py +++ b/music21_tools/composition/phasing.py @@ -33,7 +33,7 @@ def pitchedPhase(cycles=None, show=False): The source code describes how this works. - >>> #_DOCS_SHOW composition.phasing.pitchedPhase(cycles=4, show=True) + >>> # _DOCS_SHOW composition.phasing.pitchedPhase(cycles=4, show=True) .. image:: images/phasingDemo.* :width: 576 diff --git a/music21_tools/counterpoint/species.py b/music21_tools/counterpoint/species.py index 35d4d26..446ffc3 100644 --- a/music21_tools/counterpoint/species.py +++ b/music21_tools/counterpoint/species.py @@ -75,7 +75,7 @@ def findParallelFifths(self, srcStream, cmpStream): 3 >>> n1.editorial.harmonicInterval.name 'P5' - >>> m4.octave = 5 #checking for 12ths as well + >>> m4.octave = 5 # checking for 12ths as well >>> cp.findParallelFifths(cp.stream1, cp.stream2) 3 ''' @@ -154,7 +154,7 @@ def isParallelFifth(self, note11, note12, note21, note22): >>> cp.isParallelFifth(n1, n2, m1, m2) #(n1, m1) and (n2, m2) are chords True >>> m1.octave = 5 - >>> m2.octave = 5 #test parallel 12ths + >>> m2.octave = 5 # test parallel 12ths >>> cp.isParallelFifth(n1, n2, m1, m2) True @@ -235,7 +235,7 @@ def findParallelOctaves(self, stream1, stream2): >>> cp.findParallelOctaves(cp.stream2, cp.stream1) 3 >>> m3.octave = 5 - >>> m4.octave = 6 #check for parallel 17ths + >>> m4.octave = 6 # check for parallel 17ths >>> cp.findParallelOctaves(cp.stream2, cp.stream1) 3 @@ -442,7 +442,7 @@ def isParallelUnison(self, note11, note12, note21, note22): True >>> m1.octave = 4 >>> m2.octave = 4 - >>> cp.isParallelUnison(n1, n2, m1, m2) #parallel octaves, not unison + >>> cp.isParallelUnison(n1, n2, m1, m2) # parallel octaves, not unison False ''' vlq = voiceLeading.VoiceLeadingQuartet(note11, note12, note21, note22) @@ -1133,7 +1133,7 @@ def generateValidNotes(self, prevFirmus, currFirmus, prevNote, afterLeap, minorS possibleNotes.extend(goingUp) possibleNotes.extend(goingDown) - #favor contrary motion + # favor contrary motion if bottomInt.direction < 0: possibleNotes.extend(goingUp) else: @@ -1215,7 +1215,7 @@ def generateValidLastNotes(self, prevFirmus, currFirmus, prevNote, afterLeap, mi possibleNotes.extend(goingUp) possibleNotes.extend(goingDown) - #favor contrary motion + # favor contrary motion if bottomInt.direction < 0: possibleNotes.extend(goingUp) else: @@ -1294,8 +1294,8 @@ class Test(unittest.TestCase): # # counterpoint1 = ModalCounterpoint(stream1, stream2) # -# # GGBC -# # CDFF +# # GGBC +# # CDFF # findPar5 = counterpoint1.findParallelFifths(stream1, stream2) # print(findPar5) # diff --git a/music21_tools/featureExtraction/ismir2011.py b/music21_tools/featureExtraction/ismir2011.py index 42d056c..49f0bf0 100644 --- a/music21_tools/featureExtraction/ismir2011.py +++ b/music21_tools/featureExtraction/ismir2011.py @@ -81,7 +81,7 @@ def prepareChinaEurope1(): featureExtractors = features.extractorsById(['r31', 'r32', 'r33', 'r34', 'r35', 'p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8', 'p9', 'p10', 'p11', 'p12', 'p13', 'p14', 'p15', 'p16', 'p19', 'p20', 'p21']) - #featureExtractors = features.extractorsById('all') + # featureExtractors = features.extractorsById('all') oChina1 = corpus.parse('essenFolksong/han1') oCEurope1 = corpus.parse('essenFolksong/boehme10') @@ -291,12 +291,10 @@ def wekaCommands(): pass - -### FIGURED BASS PAPER ### - +# FIGURED BASS PAPER def tinyNotationBass(): bass1 = converter.parse('tinyNotation: 4/4 C4 D8_6 E8_6 F4 G4_7 c1', makeNotation=False) - #bass1.show('lily.png') + # bass1.show('lily.png') fbLine1 = figuredBass.realizer.figuredBassFromStream(bass1) fbLine1.showAllRealizations() @@ -329,7 +327,7 @@ def fbFeatureExtraction(): exampleFB.parts[0][2].append(y) fb1 = figuredBass.realizer.figuredBassFromStream(exampleFB.parts[1]) - #realization = fb1.realize() + # realization = fb1.realize() sol1 = fb1.generateRandomRealization() exampleFBOut = stream.Score() @@ -339,18 +337,18 @@ def fbFeatureExtraction(): fe1.setData(exampleFBOut) print(fe1.extract().vector) - #[0.0, 0.5, 1.0, 0.0, 0.6000000000000001, 0.0, 0.4, 0.2, 0.0, 0.7000000000000001, 0.0, 0.1] + # [0.0, 0.5, 1.0, 0.0, 0.6000000000000001, 0.0, 0.4, 0.2, 0.0, 0.7000000000000001, 0.0, 0.1] # exampleFBOut.show() if __name__ == '__main__': pass - #testTrecentoSimpler() - #prepareTrecentoCadences() - #figuredBassScale() - #fbFeatureExtraction() - #testChinaEuropeSimpler() - - #prepareChinaEurope2() - #testDataSet() - #testFictaFeature() - #example2() + # testTrecentoSimpler() + # prepareTrecentoCadences() + # figuredBassScale() + # fbFeatureExtraction() + # testChinaEuropeSimpler() + + # prepareChinaEurope2() + # testDataSet() + # testFictaFeature() + # example2() diff --git a/music21_tools/josquin/label_intervals.py b/music21_tools/josquin/label_intervals.py index f8e62d6..e43e593 100644 --- a/music21_tools/josquin/label_intervals.py +++ b/music21_tools/josquin/label_intervals.py @@ -17,7 +17,7 @@ def displayIntervals(file): (after chordification). ''' sJosquinPiece = converter.parse(file) - #dissonant_intervals = ['m2', 'M2', 'M7', 'd5', 'm7', 'A4', 'P4'] + # dissonant_intervals = ['m2', 'M2', 'M7', 'd5', 'm7', 'A4', 'P4'] rJosquinPiece = sJosquinPiece.chordify() for c in rJosquinPiece.flatten().getElementsByClass('Chord'): if len(c.pitches) == 1: @@ -35,14 +35,13 @@ def displayIntervals(file): sJosquinPiece.insert(0, rJosquinPiece) sJosquinPiece.show() -##################################################################################### - +# ----------------------------------------------- if __name__ == '__main__': import os import sys - basedir = '' # "/Users/Victoria/Desktop/" - filename = '1202a-Missa_Sine_nomine-Kyrie.xml' #argv[1] + basedir = '' # "/Users/Victoria/Desktop/" + filename = '1202a-Missa_Sine_nomine-Kyrie.xml' # argv[1] if os.path.isfile(filename): displayIntervals(filename) elif os.path.isfile(basedir + filename): diff --git a/music21_tools/misc/eschbeg.py b/music21_tools/misc/eschbeg.py index f5ccc73..0c2e660 100644 --- a/music21_tools/misc/eschbeg.py +++ b/music21_tools/misc/eschbeg.py @@ -55,12 +55,12 @@ def generateToneRows(numberToGenerate=1000, cardinality=12): ''' generates a list of random 12-tone rows. - >>> #_DOCS_SHOW generateToneRows(4) + >>> # _DOCS_SHOW generateToneRows(4) ['T310762985E4', '9E036T472158', '5879E3T12064', '417T26E95038'] generate random 3-note sets: - >>> #_DOCS_SHOW generateToneRows(4, 3) + >>> # _DOCS_SHOW generateToneRows(4, 3) ['840', 'T61', 'T10', '173'] ''' allNotes = '0123456789TE' @@ -76,7 +76,7 @@ def generateRandomRows(numberToGenerate=1000): generates random rows which might have the same note twice, but never twice in a row. - >>> #_DOCS_SHOW generateRandomRows(4) + >>> # _DOCS_SHOW generateRandomRows(4) ['67051534121', '05874071696', 'E082T6569674', '4E8383E4E395'] ''' returnRows = [] @@ -308,7 +308,7 @@ def uniquenessOfEschbeg(cardinality=7, searchCardinality=3, skipInverse=False, s for i in range(1, len(allHeptachords)): thisHeptachord = allHeptachords[i][0] thisHeptachordString = ''.join([numberToLetter(p) for p in thisHeptachord]) - #print thisHeptachordString + # print(thisHeptachordString) foundTrichords = findEmbeddedChords(thisHeptachordString, cardinality = searchCardinality, skipInverse = skipInverse) @@ -326,11 +326,3 @@ def uniquenessOfEschbeg(cardinality=7, searchCardinality=3, skipInverse=False, s if __name__ == '__main__': import music21 music21.mainTest('moduleRelative') - - #print findEmbeddedChords(cardinality=5) - #p, t = priorProbability(100000, enforce12Tone=False) - #print p - #print t - -#------------------------------ -#eof diff --git a/music21_tools/misc/monteverdi.py b/music21_tools/misc/monteverdi.py index d0aa11f..991b0c5 100644 --- a/music21_tools/misc/monteverdi.py +++ b/music21_tools/misc/monteverdi.py @@ -21,11 +21,11 @@ def spliceAnalysis(book=3, madrigal=1): ''' splice an analysis of the madrigal under the analysis itself ''' - #mad = corpus.parse('monteverdi/madrigal.%s.%s.xml' % (book, madrigal)) + # mad = corpus.parse('monteverdi/madrigal.%s.%s.xml' % (book, madrigal)) analysis = corpus.parse('monteverdi/madrigal.%s.%s.rntxt' % (book, madrigal)) # these are multiple parts in a score stream - #excerpt = mad.measures(1, 20) + # excerpt = mad.measures(1, 20) # get from first part aMeasures = analysis.parts[0].measures(1, 20) @@ -34,14 +34,14 @@ def spliceAnalysis(book=3, madrigal=1): myN.style.hideObjectOnPrint = True x = aMeasures.write() print(x) - #excerpt.insert(0, aMeasures) - #excerpt.show() + # excerpt.insert(0, aMeasures) + # excerpt.show() def showAnalysis(book=3, madrigal= 3): - #analysis = converter.parse('d:/docs/research/music21/dmitri_analyses/Mozart Piano Sonatas/k331.rntxt') + # analysis = converter.parse('d:/docs/research/music21/dmitri_analyses/Mozart Piano Sonatas/k331.rntxt') filename = 'monteverdi/madrigal.%s.%s.rntxt' % (book, madrigal) analysis = corpus.parse(filename) - #analysis.show() + # analysis.show() (major, minor) = iqSemitonesAndPercentage(analysis) print(major) print(minor) @@ -152,11 +152,11 @@ def iqRootsAndPercentage(analysisStream): active = 'minor' for element in romMerged: if 'RomanNumeral' in element.classes: - #distanceToTonicInSemis = int((element.root().ps - + # distanceToTonicInSemis = int((element.root().ps - # pitch.Pitch(element.scale.tonic).ps) % 12) elementLetter = str(element.root().name) - ## leave El + # # leave El if element.quality == 'minor' or element.quality == 'diminished': elementLetter = elementLetter.lower() elif element.quality == 'other': @@ -203,7 +203,7 @@ def monteverdiParallels(books=(3,), start=1, end=20, show=True, strict=False): continue displayMe = False for i in range(len(c.parts) - 1): - #iName = c.parts[i].id + # iName = c.parts[i].id ifn = c.parts[i].flatten().notesAndRests.stream() omi = ifn.offsetMap() for j in range(i + 1, len(c.parts)): @@ -251,7 +251,7 @@ def findPhraseBoundaries(book=4, madrigal=12): for p in sc.parts: partNotes = p.flatten().stripTies(matchByPitch=True).notesAndRests - #thisPartPhraseScores = [] # keeps track of the likelihood that a phrase boundary is after note i + # thisPartPhraseScores = [] # keeps track of the likelihood that a phrase boundary is after note i for i in range(2, len(partNotes) - 2): # start on the third note and stop searching on the third to last note... thisScore = 0 twoNotesBack = partNotes[i - 2] @@ -320,8 +320,8 @@ def findPhraseBoundaries(book=4, madrigal=12): if __name__ == '__main__': - #spliceAnalysis() - #analyzeBooks(books=[3, 4, 5]) - #analyzeBooks(books=[4], start=10, end=10, show=True, strict=True) + # spliceAnalysis() + # analyzeBooks(books=[3, 4, 5]) + # analyzeBooks(books=[4], start=10, end=10, show=True, strict=True) findPhraseBoundaries(book=4, madrigal=12) - #monteverdiParallels(books=[3], start=1, end=1, show=True, strict=True) + # monteverdiParallels(books=[3], start=1, end=1, show=True, strict=True) diff --git a/music21_tools/theory/mgtaPart1.py b/music21_tools/theory/mgtaPart1.py index 84b4554..2ccf600 100644 --- a/music21_tools/theory/mgtaPart1.py +++ b/music21_tools/theory/mgtaPart1.py @@ -46,7 +46,7 @@ def ch1_basic_I_A(show=True, *arguments, **keywords): # get direction of enharmonic move? # a move upward goes from f to g-, then a--- - #n.pitch.getEnharmonic(1) + # n.pitch.getEnharmonic(1) found.append(None) if show: for i in range(len(pitches)): @@ -158,7 +158,7 @@ def ch1_basic_II_A_1(show=True, *arguments, **keywords): *- ''' exercise = converter.parseData(humdata) - #exercise = music21.parseData("ch1_basic_II_A_1.xml") + # exercise = music21.parseData("ch1_basic_II_A_1.xml") for n in exercise.flatten().notes: # have to use flat here n.lyric = n.nameWithOctave if show: @@ -918,7 +918,7 @@ def ch2_writing_III_B(src): # note that ending ties are not given with tiny notation group = [] for n in s2.notesAndRests: - #environLocal.printDebug([n, n.tie]) + # environLocal.printDebug([n, n.tie]) if n.tie != None or len(group) > 0: if n.tie != None and n.tie.type != 'stop': group.append(n) @@ -1839,39 +1839,39 @@ def testBasic(self): # ------------------------------------------------------------------------------ if __name__ == '__main__': - #ch2_writing_III_A_1(show=True) + # ch2_writing_III_A_1(show=True) if len(sys.argv) == 1: music21.mainTest(Test) else: pass - #b = TestExternal() - #b.testBasic() + # b = TestExternal() + # b.testBasic() - #ch1_writing_I_B_1(show=True) - #ch1_writing_I_B_2(show=True) - #ch1_writing_I_B_3(show=True) - #ch1_basic_II_C_2(show=True) + # ch1_writing_I_B_1(show=True) + # ch1_writing_I_B_2(show=True) + # ch1_writing_I_B_3(show=True) + # ch1_basic_II_C_2(show=True) - #ch5_writing_IV_A(show=True) + # ch5_writing_IV_A(show=True) - #ch2_basic_I_A_1(show=True) + # ch2_basic_I_A_1(show=True) - #ch2_writing_III_A_1(show=True) - #ch2_writing_III_A_2(show=True) - #ch2_writing_III_A_3(show=True) + # ch2_writing_III_A_1(show=True) + # ch2_writing_III_A_2(show=True) + # ch2_writing_III_A_3(show=True) - #ch2_writing_III_B_3(show=True) + # ch2_writing_III_B_3(show=True) - #ch2_writing_I_A_1(show=True) - #ch2_writing_I_A_2(show=True) - #ch2_writing_I_A_3(show=True) - #ch2_writing_I_A_4(show=True) - #ch2_writing_I_A_5(show=True) + # ch2_writing_I_A_1(show=True) + # ch2_writing_I_A_2(show=True) + # ch2_writing_I_A_3(show=True) + # ch2_writing_I_A_4(show=True) + # ch2_writing_I_A_5(show=True) - #ch2_writing_IV_B(show=True) - #ch2_writing_V_A(show=True) + # ch2_writing_IV_B(show=True) + # ch2_writing_V_A(show=True) - #ch2_writing_III_B_1() + # ch2_writing_III_B_1() diff --git a/music21_tools/theory/mgtaPart2.py b/music21_tools/theory/mgtaPart2.py index a2a8301..73e5888 100755 --- a/music21_tools/theory/mgtaPart2.py +++ b/music21_tools/theory/mgtaPart2.py @@ -207,7 +207,7 @@ def test_Ch6_basic_II_B(self, *arguments, **keywords): elif len(sys.argv) > 1: t = Test() - #t.test_Ch6_basic_II_A(show=True) + # t.test_Ch6_basic_II_A(show=True) diff --git a/music21_tools/theoryAnalysis/theoryAnalyzer.py b/music21_tools/theoryAnalysis/theoryAnalyzer.py index b001596..0c6782e 100644 --- a/music21_tools/theoryAnalysis/theoryAnalyzer.py +++ b/music21_tools/theoryAnalysis/theoryAnalyzer.py @@ -58,9 +58,9 @@ >>> # gets a list of tuples, adjacent chord symbol objects in the score >>> for x in l: ... averageMotion += abs(x.rootInterval().intervalClass) - >>> #rootInterval() returns the interval between the roots of the first chordSymbol and second + >>> # rootInterval() returns the interval between the roots of the first chordSymbol and second >>> averageMotion = averageMotion // len(l) - >>> averageMotion #average intervalClass in this piece is about 4 + >>> averageMotion # average intervalClass in this piece is about 4 4 **get only interesting music theory voiceLeading objects from a score** @@ -379,7 +379,7 @@ def getVLQs(self, score, partNum1, partNum2): defaultKey = score.analyze('key') newKey = defaultKey vlq.key = newKey - #vlq.key = getKeyAtMeasure(score, vlq.v1n1.measureNumber) + # vlq.key = getKeyAtMeasure(score, vlq.v1n1.measureNumber) allVLQs.extend(vlqs) return allVLQs @@ -492,14 +492,14 @@ def getLinearSegments(self, score, partNum, lengthLinearSegment, classFilterList ''' linearSegments = [] - #no caching here - possibly implement later on... + # no caching here - possibly implement later on... verticalities = self.getVerticalities(score) for i in range(len(verticalities) - lengthLinearSegment + 1): objects = [] for n in range(lengthLinearSegment): objects.append(verticalities[i + n].getObjectsByPart(partNum, classFilterList)) - #print objects + # print objects if (lengthLinearSegment == 3 and 'Note' in self._getTypeOfAllObjects(objects)): tnls = voiceLeading.ThreeNoteLinearSegment(objects[0], objects[1], objects[2]) @@ -1290,7 +1290,7 @@ def identifyImproperResolutions(self, score, partNum1=None, partNum2=None, color ''' if editorialMarkList is None: editorialMarkList = [] - #TODO: incorporate Jose's resolution rules into this method (italian6, etc.) + # TODO: incorporate Jose's resolution rules into this method (italian6, etc.) testFunction = lambda vlq: not vlq.isProperResolution() textFunction = lambda vlq, pn1, pn2: ('Improper resolution of ' + vlq.vIntervals[0].simpleNiceName + @@ -1593,7 +1593,7 @@ def removePassingTones(self, score, dictKey='unaccentedPassingTones'): sid = score.id self.getPassingTones(score, dictKey=dictKey) for tr in self.store[sid]['ResultDict'][dictKey]: - a = tr.vsnt.tnlsDict[tr.partNumIdentified] #identifiedThreeNoteLinearSegment + a = tr.vsnt.tnlsDict[tr.partNumIdentified] # identifiedThreeNoteLinearSegment durationNewTone = a.n1.duration.quarterLength + a.n2.duration.quarterLength for obj in score.recurse(): if obj.id == a.n2.id: @@ -1638,7 +1638,7 @@ def removeNeighborTones(self, score, dictKey='unaccentedNeighborTones'): sid = score.id self.getNeighborTones(score, dictKey=dictKey) for tr in self.store[sid]['ResultDict'][dictKey]: - a = tr.vsnt.tnlsDict[tr.partNumIdentified] #identifiedThreeNoteLinearSegment + a = tr.vsnt.tnlsDict[tr.partNumIdentified] # identifiedThreeNoteLinearSegment durationNewTone = a.n1.duration.quarterLength + a.n2.duration.quarterLength for obj in score.recurse(): if obj.id == a.n2.id: @@ -1646,7 +1646,7 @@ def removeNeighborTones(self, score, dictKey='unaccentedNeighborTones'): break a.n1.duration = duration.Duration(durationNewTone) score.stripTies(inPlace=True, matchByPitch=True) - #a.n1.color = 'red' + # a.n1.color = 'red' self.store[sid]['Verticalities'] = None def identifyNeighborTones(self, score, partNumToIdentify=None, color=None, dictKey=None, @@ -1808,7 +1808,7 @@ def identifyImproperDissonantIntervals(self, score, partNum1=None, partNum2=None else: intv = resultTheoryObject.intv tr = theoryResult.IntervalTheoryResult(intv) - #tr.value = valueFunction(hIntv) + # tr.value = valueFunction(hIntv) tr.text = ('Improper dissonant harmonic interval in measure ' + str(intv.noteStart.measureNumber) + ': ' + str(intv.niceName) + ' from ' + str(intv.noteStart.name) + @@ -2027,7 +2027,7 @@ def textFunction(vs, rn): # homework assignments # - #def identifyRomanNumerals(self, score, color=None, + # def identifyRomanNumerals(self, score, color=None, # dictKey='romanNumerals', responseOffsetMap = []): # ''' # Identifies the roman numerals in the piece by iterating through @@ -2234,7 +2234,7 @@ def identifyCommonPracticeErrors(self, score, partNum1=None, partNum2=None, self.identifyHiddenOctaves(score, partNum1, partNum2, 'green', dictKey) self.identifyParallelUnisons(score, partNum1, partNum2, 'blue', dictKey) self.identifyImproperResolutions(score, partNum1, partNum2, 'purple', dictKey) - #self.identifyLeapNotSetWithStep(score, partNum1, partNum2, 'white', dictKey) + # self.identifyLeapNotSetWithStep(score, partNum1, partNum2, 'white', dictKey) self.identifyImproperDissonantIntervals(score, partNum1, partNum2, 'white', dictKey, unaccentedOnly = True) self.identifyDissonantMelodicIntervals(score, partNum1, 'cyan', dictKey) @@ -2287,7 +2287,7 @@ def getResultsString(self, score, typeList=None): for result in self.store[sid]['ResultDict'][resultType]: resultStr += result.text resultStr += '\n' - resultStr = resultStr[0:-1] #remove final new line character + resultStr = resultStr[0:-1] # remove final new line character return resultStr def getHTMLResultsString(self, score, typeList=None): @@ -2355,14 +2355,14 @@ def removeFromAnalysisData(self, score, dictKeys): del self.store[sid]['ResultDict'][dictKey] except Exception: pass - #raise TheoryAnalyzerException('got a dictKey to remove from + # raise TheoryAnalyzerException('got a dictKey to remove from # resultDictionary that wasnt in the dictionary: %s', dictKey) else: try: del self.store[sid]['ResultDict'][dictKeys] except Exception: pass - #raise TheoryAnalyzerException('got a dictKey to remove from resultDictionary + # raise TheoryAnalyzerException('got a dictKey to remove from resultDictionary # that wasn''t in the dictionary: %s', dictKeys) # def getKeyMeasureMap(self, score): @@ -2439,7 +2439,7 @@ def getKeyAtMeasure(self, score, measureNumber): return key.Key(kName) else: return keyMeasureMap[dictKey] - if measureNumber == 0: #just in case of a pickup measure + if measureNumber == 0: # just in case of a pickup measure if 1 in keyMeasureMap: return key.Key(key.convertKeyStringToMusic21KeyString(keyMeasureMap[1])) else: diff --git a/music21_tools/theoryAnalysis/theoryResult.py b/music21_tools/theoryAnalysis/theoryResult.py index a15e4e7..c7fc450 100644 --- a/music21_tools/theoryAnalysis/theoryResult.py +++ b/music21_tools/theoryAnalysis/theoryResult.py @@ -246,7 +246,7 @@ class VerticalityNTupletTheoryResult(TheoryResult): def __init__(self, vsnt, partNumIdentified=None): super().__init__() - self.vsnt = vsnt #vertical slice ntuplet + self.vsnt = vsnt # vertical slice ntuplet self.partNumIdentified = partNumIdentified def color(self, color ='red', partNum=None, noteList=None): @@ -298,5 +298,5 @@ def demo(self): import music21 music21.mainTest(Test, 'moduleRelative') - #te = TestExternal() - #te.demo() + # te = TestExternal() + # te.demo() diff --git a/music21_tools/theoryAnalysis/wwnortonMGTA.py b/music21_tools/theoryAnalysis/wwnortonMGTA.py index 61ca0db..3e18bde 100644 --- a/music21_tools/theoryAnalysis/wwnortonMGTA.py +++ b/music21_tools/theoryAnalysis/wwnortonMGTA.py @@ -35,7 +35,7 @@ class wwnortonExercise: ''' def __init__(self): self.xmlFileDirectory = 'C:/Users/bhadley/Dropbox/Music21Theory/TestFiles/Exercises/' - #/xmlfiles/" + # /xmlfiles/" self.xmlFilename = '' self.originalExercise = stream.Stream() self.modifiedExercise = stream.Stream() @@ -71,12 +71,12 @@ def getBlankExercise(self): def _partOffsetsToPartIndecies(self): for (i, el) in enumerate(self.modifiedExercise.elements): el.offset = i - #self.modifiedExercise.show('text') + # self.modifiedExercise.show('text') def _partOffsetsToZero(self): for (i, el) in enumerate(self.modifiedExercise.elements): el.offset = 0 - #self.modifiedExercise.show('text') + # self.modifiedExercise.show('text') def _updatepn(self, newPartNum, direction): for partName in self.pn: @@ -152,7 +152,7 @@ def addMarkerPartFromExisting(self, existingPartName, newPartName, newPartTitle= insertLoc = existingPartOffset + 0.5 self.pn[newPartName] = partNum + 1 self.modifiedExercise.insert(insertLoc, newPart) - #self.modifiedExercise.show('text') + # self.modifiedExercise.show('text') # Somehow needed for sorting... self.modifiedExercise._reprText() self._partOffsetsToZero() @@ -168,7 +168,7 @@ def compareMarkerLyricAnswer(self, score, taKey, markerPartName, offsetFunc, lyr print('No Marker') continue if markerNote.lyric != str(correctLyric): - #markerNote.lyric = markerNote.lyric + "->" + str(correctLyric) + # markerNote.lyric = markerNote.lyric + "->" + str(correctLyric) markerNote.color = 'red' def showStudentExercise(self): @@ -306,6 +306,6 @@ def demo(self): if __name__ == '__main__': music21.mainTest(Test) - #te = TestExternal() - #te.demo() + # te = TestExternal() + # te.demo() diff --git a/music21_tools/trecento/cadencebook.py b/music21_tools/trecento/cadencebook.py index a9a108c..5781e34 100644 --- a/music21_tools/trecento/cadencebook.py +++ b/music21_tools/trecento/cadencebook.py @@ -437,7 +437,7 @@ def asScore(self): Changes made to a snippet are reflected in the asScore() score object: - >>> deduto.snippets[0].parts[0].flatten().notes[0].name = "C###" + >>> deduto.snippets[0].parts[0].flatten().notes[0].name = 'C###' >>> deduto.asScore().parts[0].flatten().notes[0].name 'C###' ''' diff --git a/music21_tools/trecento/capua.py b/music21_tools/trecento/capua.py index 3356580..7c22d03 100644 --- a/music21_tools/trecento/capua.py +++ b/music21_tools/trecento/capua.py @@ -821,9 +821,9 @@ def findCorrections(correctionType='Maj3', startPiece=2, endPiece=459): # 'pmfcAlt': 4, 'pmfcNotCapua': 1, 'totalNotes': 82} # >>> foundPieceOpus.show('lily.pdf') -# >>> #_DOCS_SHOW (totalDict, foundPieceOpus) = correctedMin6() -# >>> totalDict = {'potentialChange': 82, 'capuaAlt': 30, 'pmfcAndCapua': 3, #_DOCS_HIDE -# ... 'capuaNotPmfc': 27, 'pmfcAlt': 4, 'pmfcNotCapua': 1, 'totalNotes': 82} #_DOCS_HIDE +# >>> # _DOCS_SHOW (totalDict, foundPieceOpus) = correctedMin6() +# >>> totalDict = {'potentialChange': 82, 'capuaAlt': 30, 'pmfcAndCapua': 3, # _DOCS_HIDE +# ... 'capuaNotPmfc': 27, 'pmfcAlt': 4, 'pmfcNotCapua': 1, 'totalNotes': 82} # _DOCS_HIDE # >>> pp(totalDict) # {'alterAll': 82, 'capuaAlt': 30, 'pmfcAndCapua': 3, 'capuaNotPmfc': 27, # 'pmfcAlt': 4, 'pmfcNotCapua': 1, 'totalNotes': 82} @@ -933,9 +933,9 @@ def improvedHarmony(startPiece=2, endPiece=459): Returns a dict showing the results - >>> #_DOCS_SHOW improvedHarmony() - >>> print("{'imperfCapua': 22, 'imperfIgnored': 155, " + #_DOCS_HIDE - ... "'perfCapua': 194, 'perfIgnored': 4057}") #_DOCS_HIDE + >>> # _DOCS_SHOW improvedHarmony() + >>> print("{'imperfCapua': 22, 'imperfIgnored': 155, " + # _DOCS_HIDE + ... "'perfCapua': 194, 'perfIgnored': 4057}") # _DOCS_HIDE {'imperfCapua': 22, 'imperfIgnored': 155, 'perfCapua': 194, 'perfIgnored': 4057} ''' diff --git a/music21_tools/trecento/findTrecentoFragments.py b/music21_tools/trecento/findTrecentoFragments.py index cf3e0f9..9633b78 100644 --- a/music21_tools/trecento/findTrecentoFragments.py +++ b/music21_tools/trecento/findTrecentoFragments.py @@ -264,7 +264,7 @@ def savedSearches(): # searchForIntervals("F3 C3 C3 F3 G3") # Bologna Archivio: Per seguirla TEST # searchForNotes("F3 E3 F3 G3 F3 E3") # Mons archive fragment -- see FB Aetas Aurea post searchForNotes('F4 G4 F4 B4 G4 A4 G4 F4 E4') # or B-4. Paris 25406 -- - # Dominique Gatte pen tests + # Dominique Gatte pen tests # searchForNotes("D4 D4 C4 D4") # Fortuna Rira Seville 25 TEST! CANNOT FIND # searchForNotes("D4 C4 B3 A3 G3") # Tenor de monaco so tucto Seville 25 diff --git a/music21_tools/trecento/polyphonicSnippet.py b/music21_tools/trecento/polyphonicSnippet.py index ca40cc1..7a923bf 100644 --- a/music21_tools/trecento/polyphonicSnippet.py +++ b/music21_tools/trecento/polyphonicSnippet.py @@ -375,7 +375,7 @@ def testCopyAndDeepcopy(self): elif part in ['Test', 'TestExternal']: continue elif callable(part): - #environLocal.printDebug(['testing copying on', part]) + # environLocal.printDebug(['testing copying on', part]) obj = getattr([self.__module__, part])() a = copy.copy(obj) b = copy.deepcopy(obj) diff --git a/music21_tools/trecento/quodJactatur.py b/music21_tools/trecento/quodJactatur.py index cca070e..61ce68a 100644 --- a/music21_tools/trecento/quodJactatur.py +++ b/music21_tools/trecento/quodJactatur.py @@ -231,7 +231,7 @@ def findRetrogradeVoices(show=True): thisScore = strength else: int1 = interval.Interval(n.pitches[0], n.pitches[1]) - #print int1.generic.simpleUndirected + # print int1.generic.simpleUndirected if int1.generic.simpleUndirected in [1, 3, 4, 5]: thisScore = strength elif int1.generic.simpleUndirected == 6: # less good @@ -281,8 +281,8 @@ def prepareSolution(triplumTup, ctTup, tenorTup): cachedParts[idString] = copy.deepcopy(qjPart) qjSolved.insert(0, qjPart.flatten()) - #DOESN'T WORK -- am I doing something wrong? - #for tp in qjSolved.parts: + # DOESN'T WORK -- am I doing something wrong? + # for tp in qjSolved.parts: # tp.makeMeasures(inPlace=True) qjChords = qjSolved.chordify() @@ -362,7 +362,7 @@ def possibleSolution(): # qjSolved.insert(0, stream.Part()) # qjSolved.insert(0, qjChords) qjSolved.show('musicxml') - #qjChords.show('musicxml') + # qjChords.show('musicxml') def multipleSolve(): # this is ridiculous... @@ -448,7 +448,7 @@ def multipleSolve(): unused_fullScore) = prepareSolution(triplum, ct, tenor) - #writeLine = (tripT, ctT, tenT, tripDelay, + # writeLine = (tripT, ctT, tenT, tripDelay, # ctDelay, tenDelay, tripInvert, ctInvert, # tenInvert, tripRetro, ctRetro, tenRetro, # avgScore) diff --git a/music21_tools/trecento/runTrecentoCadence.py b/music21_tools/trecento/runTrecentoCadence.py index bf8aa75..bab2e9b 100644 --- a/music21_tools/trecento/runTrecentoCadence.py +++ b/music21_tools/trecento/runTrecentoCadence.py @@ -74,7 +74,7 @@ def makePDFfromPieces(start=1, finish=2): ballataObj = cadencebook.BallataSheet() retrievedPieces = [] - for i in range(start, finish): ## some random pieces + for i in range(start, finish): # some random pieces randomPiece = ballataObj.makeWork( i ) # if randomPiece.incipit is not None: retrievedPieces.append(randomPiece) @@ -82,7 +82,7 @@ def makePDFfromPieces(start=1, finish=2): opus = stream.Opus() retrievedPieces.sort(key=sortByPMFC) for randomPiece in retrievedPieces: - #print(randomPiece.title.encode('utf-8')) + # print(randomPiece.title.encode('utf-8')) randomOpus = randomPiece.asOpus() for s in randomOpus.scores: opus.insert(0, s) @@ -93,7 +93,7 @@ def makePDFfromPieces(start=1, finish=2): # randomIncipit = randomPiece.incipitClass() # lilyString += randomIncipit.lily() # randomCadA = randomPiece.cadenceAClass() -## randomCadA.header = randomIncipit.header ## use its header however +# randomCadA.header = randomIncipit.header # use its header however # lilyString += randomCadA.lily() # randomCadB1 = randomPiece.cadenceB1Class() # if randomCadB1 is not None: @@ -114,7 +114,7 @@ def makePDFfromPiecesWithCapua(start=2, finish=3): ballataObj = cadencebook.BallataSheet() retrievedPieces = [] - for i in range(start, finish): ## some random pieces + for i in range(start, finish): # some random pieces try: randomPiece = ballataObj.makeWork( i ) # if randomPiece.incipit: @@ -133,7 +133,7 @@ def makePDFfromPiecesWithCapua(start=2, finish=3): # lilyString += randomIncipit.lily() # # randomCadA = randomPiece.cadenceAClass() -## randomCadA.header = randomIncipit.header ## use its header however +# randomCadA.header = randomIncipit.header # use its header however # for thisStream in randomCadA.streams: # capua.runRulesOnStream(thisStream) # @@ -159,7 +159,7 @@ def checkValidity(): ballataObj = cadencebook.BallataSheet() for i in range(1, 378): - randomPiece = ballataObj.makeWork(i) #random.randint(231, 312) + randomPiece = ballataObj.makeWork(i) # random.randint(231, 312) try: unused_incipitStreams = randomPiece.incipitStreams() except music21.tinyNotation.TinyNotationException as inst: @@ -179,9 +179,9 @@ def runTest(self): pass def testA(self): - self.assertEqual(5, 5) ## something really wrong!?? + self.assertEqual(5, 5) # something really wrong!?? if __name__ == '__main__': - #makePDFfromPiecesWithCapua() + # makePDFfromPiecesWithCapua() import music21 music21.mainTest(Test, 'moduleRelative') diff --git a/music21_tools/trecento/tonality.py b/music21_tools/trecento/tonality.py index 3f0a696..946fbed 100644 --- a/music21_tools/trecento/tonality.py +++ b/music21_tools/trecento/tonality.py @@ -348,4 +348,4 @@ def runTest(self): if __name__ == '__main__': import music21 - music21.mainTest(Test, 'importPlusRelative') #External) + music21.mainTest(Test, 'importPlusRelative') diff --git a/music21_tools/trecento/trecentoCadence.py b/music21_tools/trecento/trecentoCadence.py index ce60f2f..de748d5 100644 --- a/music21_tools/trecento/trecentoCadence.py +++ b/music21_tools/trecento/trecentoCadence.py @@ -66,7 +66,6 @@ def __init__(self, stringRep=''): (r'(\S*)', CadenceNoteToken), # last ] -###### test routines class Test(unittest.TestCase): diff --git a/publications/icmc2011.py b/publications/icmc2011.py index 9aae61a..93c4ac1 100644 --- a/publications/icmc2011.py +++ b/publications/icmc2011.py @@ -552,10 +552,10 @@ def testScalesPy06(self): # def testScalesPy10(self): # # look through s = corpus.parse('bwv1080/06') - # #part = corpus.parse('bwv1080/03').measures(24, 29).parts[0] - # #part = corpus.parse('bwv1080/03').parts[0] + # # part = corpus.parse('bwv1080/03').measures(24, 29).parts[0] + # # part = corpus.parse('bwv1080/03').parts[0] # - # #from music21 import corpus, scale, note + # # from music21 import corpus, scale, note # from music21 import analysis # # scDMelodicMinor = scale.MelodicMinorScale('d4') @@ -644,7 +644,7 @@ def testEx01(self): # # Labeling a vocal part based on scale degrees derived # # from key signature and from a specified target key. # - # s = corpus.parse('hwv56/movement3-03.md')#.measures(1, 7) + # s = corpus.parse('hwv56/movement3-03.md') # .measures(1, 7) # basso = s.parts['basso'] # s.remove(basso) # diff --git a/publications/ismir2010.py b/publications/ismir2010.py index 8c0aae0..233ba4e 100644 --- a/publications/ismir2010.py +++ b/publications/ismir2010.py @@ -91,8 +91,8 @@ def newDomSev(show=True): firstNote = thisMeasure.notesAndRests[0] firstNote.lyric = primeForm - # Thus we append the chord in closed position and then - # the measure containing the chord. + # Thus we append the chord in closed position and then + # the measure containing the chord. chordMeasure = stream.Measure() chordMeasure.append( @@ -513,7 +513,7 @@ def demoBachSearch(): import random fpList = list(corpus.search('bach').search('.xml')) - + random.shuffle(fpList) results = stream.Stream() diff --git a/publications/seaverOct2009.py b/publications/seaverOct2009.py index 66c8d09..a0571d9 100644 --- a/publications/seaverOct2009.py +++ b/publications/seaverOct2009.py @@ -44,7 +44,7 @@ def lsort(keyname): defaultPitch = music21.pitch.Pitch("C3") - # semiFlat lets me get all Measures no matter where they reside in the tree structure + # semiFlat lets me get all Measures no matter where they reside in the tree structure measureStream = converter.parse(humdrum.testFiles.mazurka6 ).flatten(retainContainers=True).getElementsByClass('Measure') rhythmicHash = defaultdict(list) @@ -93,7 +93,7 @@ def lsort(keyname): def displayChopinRhythms(): defaultPitch = music21.pitch.Pitch("C3") - # semiFlat lets me get all Measures no matter where they reside in the tree structure + # semiFlat lets me get all Measures no matter where they reside in the tree structure measureStream = converter.parse(humdrum.testFiles.mazurka6 ).flatten(retainContainers=True).getElementsByClass('Measure') rhythmicHash = {} @@ -394,7 +394,7 @@ def januaryThankYou(): # single labeled chord can be difficult. The first and second should be # extremely easy. The third and fifth should be easy to construct in # such a way that it doesn't miss anything but it might give some -# results that are "false positives". #4 will be the hardest to +# results that are "false positives". No. 4 will be the hardest to # construct, since a half cadence is something that's not determined so # much by the cadence chord and the chords directly preceding but more # from a larger sense of tonal listening which is of course harder to diff --git a/publications/seaver_presentation_2008.py b/publications/seaver_presentation_2008.py index 5624f0f..04616e3 100644 --- a/publications/seaver_presentation_2008.py +++ b/publications/seaver_presentation_2008.py @@ -23,8 +23,8 @@ def createEasyScale(): s1 = converter.parse("tinynotation: 3/4 d8 e f g a b") -# s1.timeSignature = time1 -# s1.showTimeSignature = True + # s1.timeSignature = time1 + # s1.showTimeSignature = True s1.show('lily.png') def createSleep(): diff --git a/publications/smt2010.py b/publications/smt2010.py index b8ae710..ff0ce60 100644 --- a/publications/smt2010.py +++ b/publications/smt2010.py @@ -184,8 +184,8 @@ def ex1_revised(show=True, *arguments, **keywords): else: beethovenScore = corpus.parse('opus133.xml') # load a MusicXML file - violin2 = beethovenScore[1] # most programming languages start counting from 0, - # so part 0 = violin 1, part 1 = violin 2, etc. + violin2 = beethovenScore[1] # most programming languages start counting from 0, + # so part 0 = violin 1, part 1 = violin 2, etc. display = stream.Stream() # an empty container for filling with found notes for thisMeasure in violin2.getElementsByClass('Measure'): notes = thisMeasure.findConsecutiveNotes(skipUnisons=True, From d5649f42a94d0cf5129a7bb65b545fd85b1fa2f7 Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 14:47:03 -1000 Subject: [PATCH 12/28] fix tests --- music21_tools/contour/contour.py | 102 +++++++++++++------------ music21_tools/trecento/_base.py | 21 ++++++ music21_tools/trecento/medren.py | 117 +++++++++++++---------------- music21_tools/trecento/notation.py | 66 ++++++++-------- 4 files changed, 160 insertions(+), 146 deletions(-) create mode 100644 music21_tools/trecento/_base.py diff --git a/music21_tools/contour/contour.py b/music21_tools/contour/contour.py index 0bfb49c..e24c472 100644 --- a/music21_tools/contour/contour.py +++ b/music21_tools/contour/contour.py @@ -23,7 +23,7 @@ _MOD = 'contour.py' environLocal = environment.Environment(_MOD) -#--------------------------------------------------- +# --------------------------------------------------- class ContourException(exceptions21.Music21Exception): pass @@ -65,19 +65,23 @@ class ContourFinder: >>> s = corpus.parse('bwv29.8') - >>> ContourFinder(s).plot('tonality') + >>> tonalContour = ContourFinder(s).getContour('tonality') + >>> isinstance(tonalContour, dict) + True + + To render visually, call ``.plot('tonality')`` instead of ``.getContour(...)``. TODO: image here... ''' def __init__(self, s=None): - self.s = s # a stream.Score object - self.sChords = None #lazy evaluation... + self.s = s # a stream.Score object + self.sChords = None # lazy evaluation... self.key = None - self._contours = { } #A dictionary mapping a contour type to a normalized contour dictionary + self._contours = { } # A dictionary mapping a contour type to a normalized contour dictionary - #self.metrics contains a dictionary mapping the name of a metric to a tuple (x,y) + # self.metrics contains a dictionary mapping the name of a metric to a tuple (x,y) # where x=metric function and y=needsChordify self._metrics = {'dissonance': (self.dissonanceMetric, True), @@ -122,8 +126,8 @@ def getContourValuesForMetric(self, metric, window=1, slide=1, needChordified=Fa OMIT_FROM_DOCS - >>> #set([1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21]).issubset(set(res.keys())) + set([1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21]).issubset(set(res.keys())) ''' res = {} @@ -141,19 +145,18 @@ def getContourValuesForMetric(self, metric, window=1, slide=1, needChordified=Fa numMeasures = len(mOffsets) - hasPickup - for i in range(1, numMeasures + 1, slide): #or numMeasures-window + 1 + for i in range(1, numMeasures + 1, slide): # or numMeasures-window + 1 fragment = s.measures(i, i + window - 1) - #TODO: maybe check that i+window-1 is less than numMeasures + window / 2 - + # TODO: maybe check that i+window-1 is less than numMeasures + window / 2 resValue = metric(fragment) res[i] = resValue return res - #TODO: tests that use simple 4-bar pieces that we have to create... - #ALSO: Need pictures or something! Need a clear demonstration! + # TODO: tests that use simple 4-bar pieces that we have to create... + # also: Need pictures or something! Need a clear demonstration! def getContour(self, cType, window=None, slide=None, overwrite=False, metric=None, needsChordify=False, normalized=False): ''' @@ -193,8 +196,7 @@ def getContour(self, cType, window=None, slide=None, overwrite=False, >>> mycontour = cf.getContour('spacing', metric = lambda x: 2, overwrite=False) Traceback (most recent call last): - OverwriteException: Attempted to overwrite 'spacing' metric but did - not specify overwrite=True + contour.OverwriteException: Attempted to overwrite 'spacing' metric but did not specify overwrite=True >>> mycontour = cf.getContour('spacing', slide=3, metric = lambda x: 2.0, overwrite=True) >>> [mycontour[x] for x in sorted(mycontour.keys())] @@ -284,7 +286,7 @@ def _normalizeContour(self, contourDict, maxKey): return res - #TODO: give same args as getContour, maybe? Also, test this. + # TODO: give same args as getContour, maybe? Also, test this. def plot(self, cType, contourIn=None, regression=True, order=4, title='Contour Plot', fileName=None): (plt, numpy) = _getExtendedModules() @@ -309,12 +311,12 @@ def plot(self, cType, contourIn=None, regression=True, order=4, - plt.plot(t, p(t), 'o-', label='estimate', markersize=1) #probably change label + plt.plot(t, p(t), 'o-', label='estimate', markersize=1) # probably change label plt.xlabel('Time (arbitrary units)') plt.ylabel('Value for %s metric' % cType) - plt.title(title) #say for which piece - #plt.savefig(filename + '.png') + plt.title(title) # say for which piece + # plt.savefig(filename + '.png') if fileName is not None: plt.savefig(fileName + '.png') @@ -353,7 +355,7 @@ def randomize(self, contourDict): return res - #--- code for the metrics + # --- code for the metrics def _calcGenericMetric(self, inpStream, chordMetric): ''' Helper function which, given a metric value for a chord, calculates a metric @@ -399,12 +401,10 @@ def dissonanceMetric(self, inpStream): def spacingMetric(self, inpStream): ''' - Defines a metric which takes a music21 stream containng measures and no parts. + Defines a metric which takes a music21 stream containing measures and no parts. This metric measures how spaced out notes in a piece are. - ''' - - #TODO: FIGURE OUT IF THIS IS REASONABLE! MIGHT WANT TO JUST DO: sqrt( sum(dist^2) ) + # TODO: Figure out if this is reasonable. Might want to just do: sqrt( sum(dist^2) ) def spacingForChord(chord): pitches = [ x.ps for x in chord.pitches ] pitches.sort() @@ -428,14 +428,23 @@ def tonalDistanceMetric(self, inpStream): ''' Returns a number between 0.0 and 1.0 that is a measure of how far away the key of inpStream is from the key of ContourFinder's internal stream. + + Music21 v10's discrete analyzer now strictly raises + :class:`~music21.analysis.discrete.DiscreteAnalysisException` when a + fragment has too few pitches for Krumhansl-Schmuckler analysis to find any + candidate keys; in that case this method returns 0.5 (neutral). ''' + from music21.analysis.discrete import DiscreteAnalysisException if self.key is None: self.key = self.s.analyze('key') - guessedKey = inpStream.analyze('key') + try: + guessedKey = inpStream.analyze('key') + except DiscreteAnalysisException: + return 0.5 - certainty = -2 #should be replaced by a value between -1 and 1 + certainty = -2 # should be replaced by a value between -1 and 1 if guessedKey == self.key: certainty = guessedKey.correlationCoefficient @@ -521,7 +530,7 @@ def addPieceToContour(self, piece, cType, metric=None, window=1, - def getCombinedContour(self, cType): #, metric=None, window=1, slide=1, order=8): + def getCombinedContour(self, cType): # , metric=None, window=1, slide=1, order=8): ''' Returns the combined contour of the type specified by cType. Instead of a dictionary, this contour is just a list of ordered pairs (tuples) with the @@ -565,11 +574,9 @@ def getCombinedContourPoly(self, cType, order=8): def plot(self, cType, showPoints=True, comparisonContour=None, regression=True, order=6): - - #TODO: maybe have an option of specifying a different - # color thing for each individual contour... - - if cType not in self.aggContours: #['dissonance', 'tonality', 'distance']: + # TODO: maybe have an option of specifying a different + # color thing for each individual contour... + if cType not in self.aggContours: # ['dissonance', 'tonality', 'distance']: return None else: contour = self.getCombinedContour(cType) @@ -581,7 +588,7 @@ def plot(self, cType, showPoints=True, comparisonContour=None, regression=True, # else: # contour = self._aggContoursAsList[cType] # - (plt, numpy) = _getExtendedModules() #@UnusedVariable + (plt, numpy) = _getExtendedModules() x, y = zip(*contour) @@ -593,17 +600,17 @@ def plot(self, cType, showPoints=True, comparisonContour=None, regression=True, y = [comparisonContour[i] for i in x] plt.plot(x, y, '.', label='compContour', markersize=8) - #p = numpy.poly1d( numpy.polyfit(x, y, order)) + # p = numpy.poly1d( numpy.polyfit(x, y, order)) p = self.getCombinedContourPoly(cType) if regression: t = numpy.linspace(0, max(x), max(x) + 1) - plt.plot(t, p(t), 'o-', label='estimate', markersize=1) #probably change label + plt.plot(t, p(t), 'o-', label='estimate', markersize=1) # probably change label plt.xlabel('Time (percentage of piece)') - plt.ylabel('Value') #change this - plt.title('title') #say for which piece - #plt.savefig(filename + '.png') + plt.ylabel('Value') # change this + plt.title('title') # say for which piece + # plt.savefig(filename + '.png') plt.show() plt.clf() @@ -651,10 +658,9 @@ def _getOutliers(): def _runExperiment(): - #get chorale iterator, initialize ac - + # get chorale iterator, initialize ac ac = AggregateContour() - #unresolved problem numbers: 88 (repeatFinder fails!) + # unresolved problem numbers: 88 (repeatFinder fails!) goodChorales = ['bach/bwv330', 'bach/bwv245.22', 'bach/bwv431', 'bach/bwv324', 'bach/bwv384', 'bach/bwv379', 'bach/bwv365', @@ -726,9 +732,9 @@ def _runExperiment(): 'bach/bwv343', 'bach/bwv311'] currentNum = 1 - #BCI = corpus.chorales.Iterator(1, 371, returnType='filename') #highest number is 371 - #highestNum = BCI.highestNumber - #currentNum = BCI.currentNumber + # BCI = corpus.chorales.Iterator(1, 371, returnType='filename') # highest number is 371 + # highestNum = BCI.highestNumber + # currentNum = BCI.currentNumber for chorale in goodChorales: print(currentNum) @@ -737,8 +743,8 @@ def _runExperiment(): # ''' # if chorale == 'bach/bwv277': -# continue #this chorale here has an added measure -# # container randomly in the middle which breaks things. +# continue # this chorale here has an added measure +# # container randomly in the middle which breaks things. # ''' chorale = corpus.parse(chorale) @@ -790,10 +796,10 @@ def _runExperiment(): if successes > 50: totalSuccesses += 1 - #print "GREAT SUCCESS!" + # print "GREAT SUCCESS!" else: totalFailures += 1 - print('failure: chorale ' + goodChorales[j]) #index ", str(i) + print('failure: chorale ' + goodChorales[j]) # index ", str(i) print(cType, ': totalSuccesses =', str(totalSuccesses), 'totalFailures =', str(totalFailures)) @@ -805,7 +811,7 @@ def _plotChoraleContours(): cf = ContourFinder(s) chorale = chorale[5:] print(chorale) - #cf.plot('dissonance', fileName= chorale + 'dissonance', regression=False) + # cf.plot('dissonance', fileName= chorale + 'dissonance', regression=False) try: cf.plot('tonality', fileName= chorale + 'tonality', regression=False) except exceptions21.Music21Exception: diff --git a/music21_tools/trecento/_base.py b/music21_tools/trecento/_base.py new file mode 100644 index 0000000..099a9ec --- /dev/null +++ b/music21_tools/trecento/_base.py @@ -0,0 +1,21 @@ +# ------------------------------------------------------------------------------ +# Name: music21_tools/trecento/_base.py +# Purpose: Shared base classes for the trecento subpackage +# +# Authors: Michael Scott Asato Cuthbert +# +# Copyright: Copyright © 2026 Michael Scott Asato Cuthbert +# License: BSD, see license.txt +# ------------------------------------------------------------------------------ +''' +Shared ancestors used elsewhere in the trecento subpackage. Avoids circular imports. +''' +from music21 import meter + + +class MedievalMeter(meter.TimeSignature): + ''' + Common base class for medieval/Renaissance Meter markers + (:class:`~music21_tools.trecento.medren.Mensuration` and + :class:`~music21_tools.trecento.notation.Divisione`), for `getContextByClass` + ''' diff --git a/music21_tools/trecento/medren.py b/music21_tools/trecento/medren.py index 18fcf63..5db0729 100644 --- a/music21_tools/trecento/medren.py +++ b/music21_tools/trecento/medren.py @@ -32,6 +32,7 @@ from music21.duration import Duration from . import notation +from ._base import MedievalMeter environLocal = environment.Environment('medren') @@ -118,7 +119,7 @@ def fontString(self): return self._fontString -class Mensuration(meter.TimeSignature): +class Mensuration(MedievalMeter): ''' An object representing a mensuration sign found in French notation. Takes four optional arguments: tempus, prolation, mode, and maximode. @@ -316,7 +317,7 @@ def _setMensuralType(self, mensuralTypeOrAbbr): 'semibrevis' >>> gmn_2 = GeneralMensuralNote('blah') Traceback (most recent call last): - MedRenException: blah is not a valid + music21_tools.trecento.medren.MedRenException: blah is not a valid mensural type or abbreviation ''') @@ -381,6 +382,11 @@ def updateDurationFromMensuration(self, mensuration=None, surroundingStream=None else: mOrD = mensuration + if mOrD is None: + # No mensuration or divisione in context — duration cannot be inferred. + self.duration = duration.Duration(0.0) + return + index = self._getTranslator(mensurationOrDivisione=mOrD, surroundingStream=surroundingStream) @@ -406,7 +412,7 @@ def _getTranslator(self, mensurationOrDivisione=None, surroundingStream=None): activeSite=surroundingStream) self._gettingDuration = True - if measure and 'Divisione' in mOrD.classes: + if measure and mOrD is not None and 'Divisione' in mOrD.classes: if index == 0: self.lenList = notation.BrevisLengthTranslator( mOrD, measure).getKnownLengths() @@ -446,20 +452,19 @@ def _determineMensurationOrDivisione(self): >>> gmn._determineMensurationOrDivisione() ''' - # mOrD = _getTargetBeforeOrAtObj(self, - # [Mensuration, trecento.notation.Divisione]) - searchClasses = (Mensuration, notation.Divisione) - mOrD = self.getContextByClass(searchClasses) + # In music21 v10, getContextByClass takes a single class only, so we + # search for the common parent of Mensuration and Divisione. + mOrD = self.getContextByClass(MedievalMeter) if mOrD is not None: return mOrD else: return None -# if len(mOrD)> 0: -# mOrD = mOrD[0] #Gets most recent M or D -# else: -# mOrD = None #TODO: try to determine mensuration for French Notation -# -# return mOrD + # if len(mOrD)> 0: + # mOrD = mOrD[0] # Gets most recent M or D + # else: + # mOrD = None # TODO: try to determine mensuration for French Notation + # + # return mOrD def _getSurroundingMeasure(self, mensurationOrDivisione=None, activeSite=None): ''' @@ -502,7 +507,6 @@ def _getSurroundingMeasure(self, mensurationOrDivisione=None, activeSite=None): , ], 2) ''' - mOrD = mensurationOrDivisione if mOrD is None: mOrD = self._determineMensurationOrDivisione() @@ -538,8 +542,9 @@ def _getSurroundingMeasure(self, mensurationOrDivisione=None, activeSite=None): break elif 'GeneralMensuralNote' in tempList[i].classes: # In Italian notation, brevis, longa, and maxima indicate a new measure - if (('Divisione' in mOrD.classes) and - (tempList[i].mensuralType in ['brevis', 'longa', 'maxima'])): + if (mOrD is not None + and 'Divisione' in mOrD.classes + and tempList[i].mensuralType in ['brevis', 'longa', 'maxima']): indOffset = i + 1 break else: @@ -554,8 +559,9 @@ def _getSurroundingMeasure(self, mensurationOrDivisione=None, activeSite=None): ('Ligature' in tempList[j].classes)): break if 'GeneralMensuralNote' in tempList[j].classes: - if (('Divisione' in mOrD.classes) and - (tempList[j].mensuralType in ['brevis', 'longa', 'maxima'])): + if (mOrD is not None + and 'Divisione' in mOrD.classes + and tempList[j].mensuralType in ['brevis', 'longa', 'maxima']): break else: mList.insert(j, tempList[j]) @@ -573,23 +579,13 @@ class MensuralRest(GeneralMensuralNote, note.Rest): :class:`music21.GeneralMensuralNote`. ''' - # scaling? def __init__(self, mensuralTypeOrAbbr: str = 'brevis', **keywords): # Do not forward the mensural-type string to note.Rest: in music21 v10 # the first positional arg is `length` (a Duration type or quarterLength), # and a mensural abbreviation like 'SB' would raise DurationException. note.Rest.__init__(self, **keywords) # do not replace with super - GeneralMensuralNote.__init__(self) # due to different keywords... - self._gettingDuration = False - self._mensuralType = 'brevis' - - tOrA = mensuralTypeOrAbbr - if tOrA in _validMensuralTypes: - self._mensuralType = tOrA - elif tOrA in _validMensuralAbbr: - self._mensuralType = _validMensuralTypes[_validMensuralAbbr.index(tOrA)] - else: - raise MedRenException('%s is not a valid mensural type or abbreviation' % tOrA) + # GeneralMensuralNote owns the mensural-type parsing and validation: + GeneralMensuralNote.__init__(self, mensuralTypeOrAbbr) self._duration = None self._fontString = '' @@ -658,25 +654,14 @@ class MensuralNote(GeneralMensuralNote, note.Note): :class:`music21.GeneralMensuralNote`. ''' - # scaling? - def __init__(self, *arguments, **keywords): - if arguments: - note.Note.__init__(self, arguments[0], **keywords) # do not replace with super + def __init__(self, pitch=None, mensuralTypeOrAbbr: str = 'brevis', **keywords): + if pitch is not None: + note.Note.__init__(self, pitch, **keywords) # do not replace with super else: note.Note.__init__(self, **keywords) # do not replace with super - GeneralMensuralNote.__init__(self) # due to different arguments, keywords - self._gettingDuration = False - self._mensuralType = 'brevis' - - if len(arguments) > 1: - tOrA = arguments[1] - if tOrA in _validMensuralTypes: - self._mensuralType = tOrA - elif tOrA in _validMensuralAbbr: - self._mensuralType = _validMensuralTypes[_validMensuralAbbr.index(tOrA)] - else: - raise MedRenException('%s is not a valid mensural type or abbreviation' % tOrA) + # GeneralMensuralNote owns the mensural-type parsing and validation: + GeneralMensuralNote.__init__(self, mensuralTypeOrAbbr) if self.mensuralType in ['minima', 'semiminima']: self.stems = ['up'] @@ -846,7 +831,7 @@ def setStem(self, direction): >>> r_1 = MensuralNote('A', 'brevis') >>> r_1.setStem('down') Traceback (most recent call last): - MedRenException: A note of type brevis cannot be equipped with a stem + music21_tools.trecento.medren.MedRenException: A note of type brevis cannot be equipped with a stem >>> r_2 = MensuralNote('A', 'semibrevis') >>> r_2.setStem('down') @@ -860,7 +845,7 @@ def setStem(self, direction): >>> r_3.setStem('down') Traceback (most recent call last): - MedRenException: This note already has the maximum number of stems + music21_tools.trecento.medren.MedRenException: This note already has the maximum number of stems >>> r_3.setStem(None) >>> r_3.getStems() @@ -928,7 +913,7 @@ def setFlag(self, stemDirection, orientation): >>> r_1 = MensuralNote('A', 'minima') >>> r_1.setFlag('up', 'right') Traceback (most recent call last): - MedRenException: a flag may not be added + music21_tools.trecento.medren.MedRenException: a flag may not be added to an upstem of note type minima >>> r_1.setStem('down') @@ -947,7 +932,7 @@ def setFlag(self, stemDirection, orientation): >>> r_3.setStem('side') >>> r_3.setFlag('side', 'left') Traceback (most recent call last): - MedRenException: a flag cannot be added to a stem with direction side + music21_tools.trecento.medren.MedRenException: a flag cannot be added to a stem with direction side ''' if stemDirection == 'up': @@ -1302,15 +1287,15 @@ def makeOblique(self, startIndex): 'oblique' >>> l.makeOblique(0) Traceback (most recent call last): - MedRenException: cannot start oblique notehead at index 0 + music21_tools.trecento.medren.MedRenException: cannot start oblique notehead at index 0 >>> l.makeOblique(2) Traceback (most recent call last): - MedRenException: cannot start oblique notehead at index 2 + music21_tools.trecento.medren.MedRenException: cannot start oblique notehead at index 2 >>> l.makeOblique(3) Traceback (most recent call last): - MedRenException: no note exists at index 4 + music21_tools.trecento.medren.MedRenException: no note exists at index 4 ''' if startIndex < self._ligatureLength() - 1: currentShape = self.noteheadShape[startIndex] @@ -1385,11 +1370,11 @@ def setMaxima(self, index, value): >>> l.setMaxima(1, True) Traceback (most recent call last): - MedRenException: cannot make note at index 1 a maxima + music21_tools.trecento.medren.MedRenException: cannot make note at index 1 a maxima >>> l.setMaxima(0, True) Traceback (most recent call last): - MedRenException: cannot make note at index 0 a maxima + music21_tools.trecento.medren.MedRenException: cannot make note at index 0 a maxima >>> l.setMaxima(2, False) >>> l.isMaxima(2) @@ -1447,7 +1432,7 @@ def setStem(self, index, direction, orientation): >>> l = Ligature(['A4', 'C5', 'B4', 'A4', 'B4']) >>> l.setStem(0, 'none', 'left') Traceback (most recent call last): - MedRenException: direction "None" and orientation "left" + music21_tools.trecento.medren.MedRenException: direction "None" and orientation "left" not supported for ligatures >>> l.setStem(1, 'up', 'left') @@ -1456,16 +1441,16 @@ def setStem(self, index, direction, orientation): >>> l.setStem(2, 'down', 'right') Traceback (most recent call last): - MedRenException: a stem with direction "down" not permitted at index 2 + music21_tools.trecento.medren.MedRenException: a stem with direction "down" not permitted at index 2 >>> l.setMaxima(4, True) >>> l.setStem(4, 'up', 'left') Traceback (most recent call last): - MedRenException: cannot place stem at index 4 + music21_tools.trecento.medren.MedRenException: cannot place stem at index 4 >>> l.setStem(3, 'up', 'left') Traceback (most recent call last): - MedRenException: a stem with direction "up" not permitted at index 3 + music21_tools.trecento.medren.MedRenException: a stem with direction "up" not permitted at index 3 ''' if direction == 'None' or direction == 'none': direction = None @@ -1559,12 +1544,12 @@ def setReverse(self, endIndex, value): >>> l.setReverse(2, True) Traceback (most recent call last): - MedRenException: the note at index 2 + music21_tools.trecento.medren.MedRenException: the note at index 2 cannot be given reverse value True >>> l.setReverse(3, True) Traceback (most recent call last): - MedRenException: the note at index 3 + music21_tools.trecento.medren.MedRenException: the note at index 3 cannot be given reverse value True ''' if value == 'True' or value == 'true': @@ -1709,7 +1694,7 @@ def breakMensuralStreamIntoBrevisLengths(inpStream, inpMOrD=None, printUpdates=F >>> s.append(GeneralMensuralNote('B')) >>> breakMensuralStreamIntoBrevisLengths(s) Traceback (most recent call last): - MedRenException: cannot combine objects + music21_tools.trecento.medren.MedRenException: cannot combine objects of type , within stream @@ -1717,7 +1702,7 @@ def breakMensuralStreamIntoBrevisLengths(inpStream, inpMOrD=None, printUpdates=F >>> p.append(s) >>> breakMensuralStreamIntoBrevisLengths(p) Traceback (most recent call last): - MedRenException: Hierarchy of + music21_tools.trecento.medren.MedRenException: Hierarchy of violated by >>> from music21_tools.trecento import notation @@ -1734,7 +1719,7 @@ def breakMensuralStreamIntoBrevisLengths(inpStream, inpMOrD=None, printUpdates=F >>> s.append(m) >>> breakMensuralStreamIntoBrevisLengths(s, printUpdates = True) Traceback (most recent call last): - MedRenException: Mensuration or divisione + music21_tools.trecento.medren.MedRenException: Mensuration or divisione <...Divisione .q.> not consistent within hierarchy >>> s = stream.Stream() @@ -2001,7 +1986,7 @@ def convertHouseStyle(score, durationScale=2, barlineStyle='tick', >>> from music21 import corpus >>> gloria = corpus.parse('luca/gloria') - >>> #_DOCS_HIDE gloria.show() + >>> # _DOCS_HIDE gloria.show() .. image:: images/medren_convertHouseStyle_1.* @@ -2009,7 +1994,7 @@ def convertHouseStyle(score, durationScale=2, barlineStyle='tick', >>> newGloria = convertHouseStyle(gloria, durationScale=2, ... barlineStyle='tick', tieTransfer=True) - >>> #_DOCS_HIDE newGloria.show() + >>> # _DOCS_HIDE newGloria.show() .. image:: images/medren_convertHouseStyle_2.* :width: 600 diff --git a/music21_tools/trecento/notation.py b/music21_tools/trecento/notation.py index 3e972b3..c87b5b5 100644 --- a/music21_tools/trecento/notation.py +++ b/music21_tools/trecento/notation.py @@ -27,6 +27,8 @@ from music21 import duration from music21 import exceptions21 from music21 import meter + +from ._base import MedievalMeter from music21 import note from music21 import stream from music21 import tie @@ -430,7 +432,7 @@ def fontString(self): '''The utf-8 code corresponding the punctus in Cicionia font''' return self._fontString -class Divisione(meter.TimeSignature): +class Divisione(MedievalMeter): ''' An object representing a divisione found in Trecento Notation. Takes one argument, nameOrSymbol. This is the name of the divisione, or @@ -597,7 +599,7 @@ def convertTrecentoStream(inpStream, inpDiv=None): for e in measuredStream: - if ('Metadata' in e.classes) or ('TextBox' in e.classes): #Formatting + if ('Metadata' in e.classes) or ('TextBox' in e.classes): # Formatting convertedStream.append(e) elif 'MensuralClef' in e.classes: @@ -673,7 +675,7 @@ def convertBrevisLength(brevisLength, convertedStream, inpDiv=None, measureNumOf else: raise TrecentoNotationException('Cannot find or determine or divisione') - if lenList[0] > div.minimaPerBrevis: #Longa, Maxima + if lenList[0] > div.minimaPerBrevis: # Longa, Maxima startNote = note.Note(mList[0].pitch) startNote.duration = div.barDuration startNote.tie = tie.Tie('start') @@ -707,11 +709,11 @@ def convertBrevisLength(brevisLength, convertedStream, inpDiv=None, measureNumOf dur = lenList[i] * mDur - if (rem - dur) > -0.0001: #Fits w/i measure up to rounding error + if (rem - dur) > -0.0001: # Fits w/i measure up to rounding error n.duration = duration.Duration(dur) m.append(n) rem -= dur - else: #Syncopated across barline + else: # Syncopated across barline n.duration = duration.Duration(rem) n.tie = tie.Tie('start') m.append(n) @@ -823,7 +825,7 @@ def getBreveStrength(self, lengths): strength = 0 curBeat = 0 for i in range(len(lengths)): - if math.isclose(curBeat - round(curBeat), 0): #Rounding error + if math.isclose(curBeat - round(curBeat), 0): # Rounding error curBeat = round(curBeat) if div.standardSymbol in ['.i.', '.n.']: @@ -988,9 +990,9 @@ def getUnchangeableNoteLengths(self): unchangeableNoteLengthsList = [] for obj in self.brevisLength: minimaLength = None - #If its duration is set, doesn't need to be determined + # If its duration is set, doesn't need to be determined - #Gets rid of everything known + # Gets rid of everything known if obj.mensuralType == 'maxima': minimaLength = 4.0 * self.div.minimaPerBrevis elif obj.mensuralType == 'longa': @@ -1001,7 +1003,7 @@ def getUnchangeableNoteLengths(self): objC = obj.classes if 'GeneralMensuralNote' not in objC: continue - #Dep on div + # Dep on div if obj.mensuralType == 'semibrevis': if 'MensuralRest' in obj.classes: if self.div.standardSymbol in ['.q.', '.i.']: @@ -1053,8 +1055,8 @@ def classifyUnknownNotesByType(self, unchangeableNoteLengthsList): semiminima_left_flag_list = [] semiminima_rest_list = [] - #Don't need these yet - #=================================================================== + # Don't need these yet + # =================================================================== # dragmas_no_flag = [] # dragmas_RNo_flag = [] # dragmas_LNo_flag = [] @@ -1063,7 +1065,7 @@ def classifyUnknownNotesByType(self, unchangeableNoteLengthsList): # dragmas_RL_flag = [] # dragmas_LR_flag = [] # dragmas_LL_flag = [] - #=================================================================== + # =================================================================== for i in range(len(self.brevisLength)): obj = self.brevisLength[i] @@ -1126,7 +1128,7 @@ def translate(self): self.minimaRemaining -= kl if None in self.unchangeableNoteLengthsList: - #Process everything else + # Process everything else if self.div.standardSymbol == '.i.': knownLengthsList = self.translateDivI() elif self.div.standardSymbol == '.n.': @@ -1274,10 +1276,10 @@ def translateDivN(self, unchangeableNoteLengthsList=None, unknownLengthsDict=Non semibrevis_downstem_index = None if self.numberOfDownstems > 0: - semibrevis_downstem_index = semibrevis_downstem[0] #Only room for one downstem + semibrevis_downstem_index = semibrevis_downstem[0] # Only room for one downstem knownLengthsList = unchangeableNoteLengthsList[:] - extend_list = [] #brevises able to be lengthened + extend_list = [] # brevises able to be lengthened extend_num = 0 if self.numberOfSemibreves > 0: @@ -1310,7 +1312,7 @@ def translateDivN(self, unchangeableNoteLengthsList=None, unknownLengthsDict=Non extend_num = min(knownLengthsList[semibrevis_downstem_index] - 3, len(extend_list)) shrink_tup += (semibrevis_downstem_index,) - else: #no downstems + else: # no downstems if self.hasLastSB: knownLengthsList[semibrevis_list[-1]] = max(minRem, 3.0) @@ -1319,7 +1321,7 @@ def translateDivN(self, unchangeableNoteLengthsList=None, unknownLengthsDict=Non extend_num = min(knownLengthsList[-1] - 3, len(extend_list)) shrink_tup += -1, - elif self.numberOfSemibreves > 0: #SBs, but no last SB + elif self.numberOfSemibreves > 0: # SBs, but no last SB if (self.brevisLength[semibrevis_list[-1] + 1].mensuralType == 'minima'): knownLengthsList[semibrevis_list[-1]] = 2.0 minRem -= 2.0 @@ -1430,7 +1432,7 @@ def translateDivPQ(self, unchangeableNoteLengthsList=None, extend_num = 0 semibrevis_downstem_index = None - if self.numberOfDownstems > 0: #Only room for one downstem per brevis length + if self.numberOfDownstems > 0: # Only room for one downstem per brevis length semibrevis_downstem_index = semibrevis_downstem[0] for ind in semibrevis_list[:-1]: @@ -1494,18 +1496,18 @@ def translateDivPQ(self, unchangeableNoteLengthsList=None, minRem_changeable) minRem_changeable -= knownLengthsList_changeable[semibrevis_downstem_index] - else: #no downstems + else: # no downstems if self.hasLastSB: knownLengthsList_changeable[semibrevis_list[-1]] = max(2.0, minRem_changeable) minRem_changeable -= knownLengthsList_changeable[semibrevis_list[-1]] - elif self.numberOfSemibreves > 0: #semibreves, but no ending SB + elif self.numberOfSemibreves > 0: # semibreves, but no ending SB knownLengthsList_changeable[semibrevis_list[-1]] = 2.0 minRem_changeable -= 2.0 - else: #left_length != right_length + else: # left_length != right_length master_list = (semiminima_left_flag_list + semiminima_right_flag_list + @@ -1541,7 +1543,7 @@ def translateDivPQ(self, unchangeableNoteLengthsList=None, knownLengthsList_changeable[ind] = right_length minRem_changeable -= right_length - #Otherwise, we don't know. Append SM Rest to extend list. + # Otherwise, we don't know. Append SM Rest to extend list. else: knownLengthsList_changeable[ind] = 0.5 extend_list.append(ind) @@ -1561,7 +1563,7 @@ def translateDivPQ(self, unchangeableNoteLengthsList=None, shrink_tup += (semibrevis_downstem_index,) - else: #No downstems + else: # No downstems if self.hasLastSB: knownLengthsList_changeable[semibrevis_list[-1]] = max( @@ -1571,7 +1573,7 @@ def translateDivPQ(self, unchangeableNoteLengthsList=None, shrink_tup += -1, - elif self.numberOfSemibreves > 0: #SBs, but no last SB + elif self.numberOfSemibreves > 0: # SBs, but no last SB knownLengthsList_changeable[semibrevis_list[-1]] = 2.0 minRem_changeable -= 2.0 extend_num = len(extend_list) @@ -1593,7 +1595,7 @@ def translateDivPQ(self, unchangeableNoteLengthsList=None, self.minimaRemaining = minRem_changeable if (tempStrength > strength) and (minRem_changeable > -0.0001): - #Technically, >= 0, but rounding error occurs. + # Technically, >= 0, but rounding error occurs. knownLengthsList = knownLengthsList_changeable[:] minRem = minRem_changeable strength = tempStrength @@ -1754,7 +1756,7 @@ def translateDivOD(self, unchangeableNoteLengthsList=None, knownLengthsList_changeable[ind] = left_length minRem_changeable -= left_length - else: #left_length != right_length + else: # left_length != right_length master_list = (semiminima_left_flag_list + semiminima_right_flag_list + @@ -1783,8 +1785,8 @@ def translateDivOD(self, unchangeableNoteLengthsList=None, else: knownLengthsList_changeable[ind] = 0.5 - #extend_list.append(ind) ### BUG: extend_list does not exist - #extend_list = _removeRepeatedElements(extend_list_2) + # extend_list.append(ind) # BUG: extend_list does not exist + # extend_list = _removeRepeatedElements(extend_list_2) if self.numberOfDownstems > 0: @@ -1808,7 +1810,7 @@ def translateDivOD(self, unchangeableNoteLengthsList=None, if extend_list_2: shrink_tup += (semibrevis_downstem_index,) - else: #downstems >= 2 + else: # downstems >= 2 newMensuralBL = [medren.MensuralNote('A', 'SB') for i in range(len(semibrevis_downstem))] @@ -1821,7 +1823,7 @@ def translateDivOD(self, unchangeableNoteLengthsList=None, for i, ind in enumerate(semibrevis_downstem): knownLengthsList_changeable[ind] = dSLengthList[i] - #Don't need shrink_tup. There is no room to extend anything. + # Don't need shrink_tup. There is no room to extend anything. elif self.numberOfSemibreves > 0: # no downstems if self.hasLastSB: @@ -1893,7 +1895,7 @@ def _allCombinations(combinationList, num): combs.insert(0, []) return combs -def _removeRepeatedElements(listOrTup): #So I don't have to use set +def _removeRepeatedElements(listOrTup): # So I don't have to use set newListOrTup = [] for item in listOrTup: @@ -2085,7 +2087,7 @@ def processStream(mStream, pitches, lengths, downStems=None): print('norm only: %s' % SePerDureca[i + 1][j]) print('') - #TinySePerDureca.show('text') + # TinySePerDureca.show('text') class Test(unittest.TestCase): From 5af58229348fea68b5f33026185cb200600311f0 Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 14:56:59 -1000 Subject: [PATCH 13/28] More comment linting --- .../audioSearchDemos/graphicalInterfaceSF.py | 28 ++++----- .../audioSearchDemos/humanVScomputer.py | 2 +- music21_tools/audioSearchDemos/omrfollow.py | 2 +- music21_tools/bhadley/harmonyRealizer.py | 4 +- music21_tools/chant/chant.py | 2 +- music21_tools/composition/seeger.py | 2 +- music21_tools/contour/contour.py | 2 +- music21_tools/counterpoint/species.py | 8 +-- music21_tools/midi/build_melody.py | 2 +- music21_tools/misc/eschbeg.py | 4 +- music21_tools/misc/gatherAccidentals.py | 6 +- music21_tools/misc/monteverdi.py | 6 +- music21_tools/theory/mgtaPart1.py | 40 ++++++------- music21_tools/theory/mgtaPart2.py | 4 +- .../theoryAnalysis/theoryAnalyzer.py | 8 +-- music21_tools/theoryAnalysis/theoryResult.py | 2 +- music21_tools/theoryAnalysis/wwnortonMGTA.py | 6 +- music21_tools/trecento/capua.py | 4 +- .../trecento/findTrecentoFragments.py | 8 +-- music21_tools/trecento/medren.py | 4 +- music21_tools/trecento/notation.py | 59 +++++++++---------- music21_tools/trecento/polyphonicSnippet.py | 2 +- music21_tools/trecento/quodJactatur.py | 8 +-- music21_tools/trecento/runTrecentoCadence.py | 4 +- music21_tools/trecento/tonality.py | 2 +- music21_tools/trecento/trecentoCadence.py | 4 +- publications/icmc2010.py | 1 - publications/icmc2011.py | 1 - publications/ismir2010.py | 6 +- publications/misc2010.py | 1 - publications/seaverOct2009.py | 8 --- publications/seaver_presentation_2008.py | 1 - publications/smt2010.py | 5 -- publications/smt2011.py | 3 +- 34 files changed, 112 insertions(+), 137 deletions(-) diff --git a/music21_tools/audioSearchDemos/graphicalInterfaceSF.py b/music21_tools/audioSearchDemos/graphicalInterfaceSF.py index 27e9219..2e0f410 100644 --- a/music21_tools/audioSearchDemos/graphicalInterfaceSF.py +++ b/music21_tools/audioSearchDemos/graphicalInterfaceSF.py @@ -35,7 +35,7 @@ environLocal = environment.Environment(_MOD) from music21.audioSearch import * -#from music21.audioSearch import recording +# from music21.audioSearch import recording from music21 import scale try: @@ -67,9 +67,9 @@ def __init__(self, master): #'scores/d luca gloria_Page_' self.format = 'tiff'#'jpg' self.nameRecordedSong = 'luca/gloria' - #'/Users/cuthbert/Desktop/scores/Saint-Saens-Clarinet-Sonata/saint-saens.xml' - #'C:\Users\Jordi\Desktop\m21\Saint-Saens-Clarinet-Sonata\Saint-Saens-Clarinet-Sonata\saint-saens.xml' - self.pageMeasureNumbers = [] # get directly from score - the last one is the last note of the score + # '/Users/cuthbert/Desktop/scores/Saint-Saens-Clarinet-Sonata/saint-saens.xml' + # 'C:\Users\Jordi\Desktop\m21\Saint-Saens-Clarinet-Sonata\Saint-Saens-Clarinet-Sonata\saint-saens.xml' + self.pageMeasureNumbers = [] # get directly from score - the last one is the last note of the score self.totalPagesScore = 1 self.currentLeftPage = 1 self.pagesScore = [] @@ -83,13 +83,13 @@ def __init__(self, master): self.sizeButton = 11 - try: # for windows + try: # for windows unused_user32 = ctypes.windll.user32 # test for error... self.screenResolution = [1024, 600] # self.screenResolution = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1) environLocal.printDebug('screen resolution (windows) %d x %d' % (self.screenResolution[0], self.screenResolution[1])) self.resolution = True - except: # mac and linux + except: # mac and linux try: for screen in AppKit.NSScreen.screens(): # @UndefinedVariable self.screenResolution = [int(screen.frame().size.width), int(screen.frame().size.height)] @@ -101,8 +101,8 @@ def __init__(self, master): self.resolution = False self.y = int(self.screenResolution[1] / 1.25) - self.x = int(self.y / 1.29)# 1.29 = side relation of letter paper - if self.x > self.screenResolution[0] / 2.6: # 2.6 is a factor to scale canvas + self.x = int(self.y / 1.29) # 1.29 = side relation of letter paper + if self.x > self.screenResolution[0] / 2.6: # 2.6 is a factor to scale canvas self.x = int(self.screenResolution[0] / 2.6) self.y = int(self.x * 1.29) environLocal.printDebug('resized! too big') @@ -152,12 +152,12 @@ def initializeName(self): str(i + 1).zfill(numberLength), self.format) self.listNamePages.append(namePage) - pilPage = PILImage.open(namePage) # @UndefinedVariable + pilPage = PILImage.open(namePage) if pilPage.mode != 'RGB': pilPage = pilPage.convert('RGB') pilPage = self.cropBorder(pilPage) - self.pagesScore.append(pilPage.resize(self.newSize, PILImage.ANTIALIAS)) # @UndefinedVariable - self.phimage.append(PILImageTk.PhotoImage(self.pagesScore[i])) # @UndefinedVariable + self.pagesScore.append(pilPage.resize(self.newSize, PILImage.ANTIALIAS)) + self.phimage.append(PILImageTk.PhotoImage(self.pagesScore[i])) environLocal.printDebug('initializeName finished') @@ -248,7 +248,7 @@ def cropBorder(self, img, minColor=240, maxColor=256): else: rightCut = rightCut - numberPixels - margin = int(resX * 0.03) # leave border 3% of the size + margin = int(resX * 0.03) # leave border 3% of the size leftCut = leftCut - margin topCut = topCut - margin @@ -578,7 +578,7 @@ def continueScoreFollower(self): self.rt = RecordThread(self.dummyQueue, self.sampleQueue, self.ScF) self.rt.daemon = True environLocal.printDebug('2nd thread about to start') - self.rt.start() # the 2nd thread starts here + self.rt.start() # the 2nd thread starts here self.dummyQueue.put('Start') environLocal.printDebug('about to put analyzeRecording into master...') self.master.after(7000, self.analyzeRecording) @@ -667,7 +667,7 @@ def stopScoreFollower(self): # # -#class External(): +# class External(): # # def __init__(self, newcoords, positionxLeft, positionxRight, speed, positionyRight, # canvas,currentLeftPage,totalPagesScore,newcoords3rd, diff --git a/music21_tools/audioSearchDemos/humanVScomputer.py b/music21_tools/audioSearchDemos/humanVScomputer.py index c4cd77f..cfd601a 100644 --- a/music21_tools/audioSearchDemos/humanVScomputer.py +++ b/music21_tools/audioSearchDemos/humanVScomputer.py @@ -12,7 +12,7 @@ from music21 import scale, note from music21 import audioSearch as base -#from music21.audioSearch import * +# from music21.audioSearch import * import time import random diff --git a/music21_tools/audioSearchDemos/omrfollow.py b/music21_tools/audioSearchDemos/omrfollow.py index 8463995..5cf4b13 100644 --- a/music21_tools/audioSearchDemos/omrfollow.py +++ b/music21_tools/audioSearchDemos/omrfollow.py @@ -89,7 +89,7 @@ def recognizeScore(scorePart, pageMeasureNumbers, iterations=1): matches = search.approximateNoteSearch(searchScore, allStreams) scores = [0 for j in range(len(pages))] - for i in range(8): # top 8 searches + for i in range(8): # top 8 searches topStream = matches[i] scorePage = topStream.pageNumber - 1 scores[scorePage] += (topStream.matchProbability / (i + 1.5)) * 10 diff --git a/music21_tools/bhadley/harmonyRealizer.py b/music21_tools/bhadley/harmonyRealizer.py index 6975ea1..f8ef7bd 100644 --- a/music21_tools/bhadley/harmonyRealizer.py +++ b/music21_tools/bhadley/harmonyRealizer.py @@ -173,7 +173,7 @@ class Test(unittest.TestCase): def runTest(self): pass -class TestExternal(unittest.TestCase): # pragma: no cover +class TestExternal(unittest.TestCase): # pragma: no cover def runTest(self): pass @@ -228,7 +228,7 @@ def xtestRealizeLeadsheet(self, music21Stream): # test = HarmonyRealizer.TestExternal() # test.leadsheetEx1() - # sc = converter.parse('https://github.com/cuthbertLab/music21/raw/master/music21/corpus/leadSheet/fosterBrownHair.mxl') # Jeannie Light Brown Hair + # sc = converter.parse('https://github.com/cuthbertLab/music21/raw/master/music21/corpus/leadSheet/fosterBrownHair.mxl') # Jeannie Light Brown Hair diff --git a/music21_tools/chant/chant.py b/music21_tools/chant/chant.py index 4b21b84..a936e0d 100644 --- a/music21_tools/chant/chant.py +++ b/music21_tools/chant/chant.py @@ -519,7 +519,7 @@ class Test(unittest.TestCase): def runTest(self): pass -class TestExternal(unittest.TestCase): # pragma: no cover +class TestExternal(unittest.TestCase): # pragma: no cover pass def runTest(self): diff --git a/music21_tools/composition/seeger.py b/music21_tools/composition/seeger.py index 4a2c914..c069e0d 100644 --- a/music21_tools/composition/seeger.py +++ b/music21_tools/composition/seeger.py @@ -40,7 +40,7 @@ def lowerLines(): appendNote = copy.deepcopy(rowNotes[currentNote % 10]) else: # second set of rotations is up a step: appendNote = rowNotes[currentNote % 10].transpose(2) - # if phraseNumber == 8 and addNote == 9: # mistaken transpositions by RCS + # if phraseNumber == 8 and addNote == 9: # mistaken transpositions by RCS # appendNote = appendNote.transpose(-1) # appendNote.lyrics.append(note.Lyric(text="*", number=3)) # diff --git a/music21_tools/contour/contour.py b/music21_tools/contour/contour.py index e24c472..ce2c9aa 100644 --- a/music21_tools/contour/contour.py +++ b/music21_tools/contour/contour.py @@ -576,7 +576,7 @@ def getCombinedContourPoly(self, cType, order=8): def plot(self, cType, showPoints=True, comparisonContour=None, regression=True, order=6): # TODO: maybe have an option of specifying a different # color thing for each individual contour... - if cType not in self.aggContours: # ['dissonance', 'tonality', 'distance']: + if cType not in self.aggContours: # ['dissonance', 'tonality', 'distance']: return None else: contour = self.getCombinedContour(cType) diff --git a/music21_tools/counterpoint/species.py b/music21_tools/counterpoint/species.py index 446ffc3..05c77eb 100644 --- a/music21_tools/counterpoint/species.py +++ b/music21_tools/counterpoint/species.py @@ -350,9 +350,9 @@ def isHiddenOctave(self, note11, note12, note21, note22): >>> m1 = note.Note('F4') >>> m2 = note.Note('B-4') >>> cp = ModalCounterpoint() - >>> cp.isHiddenOctave(n1, m1, n2, m2) # (n1, n2) and (m1, m2) are chords + >>> cp.isHiddenOctave(n1, m1, n2, m2) # (n1, n2) and (m1, m2) are chords False - >>> cp.isHiddenOctave(n1, n2, m1, m2) # (n1, m1) and (n2, m2) are chords + >>> cp.isHiddenOctave(n1, n2, m1, m2) # (n1, m1) and (n2, m2) are chords True >>> m1.octave = 5 >>> m2.octave = 5 @@ -1083,7 +1083,7 @@ def getValidSecondVoice(self, stream1, minorScale, choice='random'): elif choice == 'last': newNote = choices[-1] else: - newNote = random.choice(choices) # if choice flag not recognized, go with random + newNote = random.choice(choices) # if choice flag not recognized, go with random newNote.duration = currFirmus.duration stream2.append(newNote) int1 = interval.notesToInterval(prevNote, newNote) @@ -1628,7 +1628,7 @@ def getRandomCF(mode=None): # ------------------------------------------------------------------------------ -class TestExternal(unittest.TestCase): # pragma: no cover +class TestExternal(unittest.TestCase): # pragma: no cover def runTest(self): pass diff --git a/music21_tools/midi/build_melody.py b/music21_tools/midi/build_melody.py index 60e864e..b4ba06a 100644 --- a/music21_tools/midi/build_melody.py +++ b/music21_tools/midi/build_melody.py @@ -69,7 +69,7 @@ def main(): mt = midi.MidiTrack(1) # duration, pitch, velocity - data = [] # one start note + data = [] # one start note beats_per_measure = 4 measures = 16 diff --git a/music21_tools/misc/eschbeg.py b/music21_tools/misc/eschbeg.py index 0c2e660..9b9b6cc 100644 --- a/music21_tools/misc/eschbeg.py +++ b/music21_tools/misc/eschbeg.py @@ -226,7 +226,7 @@ def findEmbeddedChords(testSet='0234589', cardinality=3, skipInverse=False): myInverse[i] = p - myInverseMin myInverse = sorted(myInverse) myInverseString = ''.join([str(p) for p in myInverse]) - if myInverseString != myPitchString: # some are symmetric + if myInverseString != myPitchString: # some are symmetric ret += '\n[' + myInverseString + ']: ' for i in range(12): notFound = False @@ -318,7 +318,7 @@ def uniquenessOfEschbeg(cardinality=7, searchCardinality=3, skipInverse=False, s if '(' not in trichordInfo: noneMissing = False break - if noneMissing == showMatching: # default True + if noneMissing == showMatching: # default True allHeptachordList.append(thisHeptachordString) return allHeptachordList diff --git a/music21_tools/misc/gatherAccidentals.py b/music21_tools/misc/gatherAccidentals.py index fef8681..9aa694d 100644 --- a/music21_tools/misc/gatherAccidentals.py +++ b/music21_tools/misc/gatherAccidentals.py @@ -222,12 +222,12 @@ def runTest(self): def testGetAccidentalCountBasic(self): s = stream.Stream() - self.assertEqual(len(s.flatten().notes), 0) # the stream should be empty + self.assertEqual(len(s.flatten().notes), 0) # the stream should be empty self.assertEqual(getAccidentalCount(s), {}) def testGetAccidentalCountIntermediate(self): s = stream.Stream() - s.append(note.Note('C4')) # no accidental + s.append(note.Note('C4')) # no accidental s.append(note.Note('C#4')) # sharp s.append(note.Note('D-4')) # flat self.assertEqual(getAccidentalCount(s), {'flat': 1, 'sharp': 1}) @@ -282,5 +282,5 @@ def testAccidentalCountBachChorales(self): if __name__ == '__main__': import music21 - music21.mainTest(Test, 'moduleRelative') # replace 'Test' with 'TestSlow' to test it on all 371 Bach Chorales. + music21.mainTest(Test, 'moduleRelative') # replace 'Test' with 'TestSlow' to test it on all 371 Bach Chorales. diff --git a/music21_tools/misc/monteverdi.py b/music21_tools/misc/monteverdi.py index 991b0c5..6291e45 100644 --- a/music21_tools/misc/monteverdi.py +++ b/music21_tools/misc/monteverdi.py @@ -251,8 +251,8 @@ def findPhraseBoundaries(book=4, madrigal=12): for p in sc.parts: partNotes = p.flatten().stripTies(matchByPitch=True).notesAndRests - # thisPartPhraseScores = [] # keeps track of the likelihood that a phrase boundary is after note i - for i in range(2, len(partNotes) - 2): # start on the third note and stop searching on the third to last note... + # thisPartPhraseScores = [] # keeps track of the likelihood that a phrase boundary is after note i + for i in range(2, len(partNotes) - 2): # start on the third note and stop searching on the third to last note... thisScore = 0 twoNotesBack = partNotes[i - 2] previousNote = partNotes[i - 1] @@ -275,7 +275,7 @@ def findPhraseBoundaries(book=4, madrigal=12): else: intervalToNextNote = interval.notesToInterval(thisNote.pitches[0], nextNote.pitches[0]) - if intervalToNextNote.chromatic.undirected >= 6: # a tritone or bigger + if intervalToNextNote.chromatic.undirected >= 6: # a tritone or bigger thisScore = thisScore + 10 if ((thisNote.quarterLength > previousNote.quarterLength) and (thisNote.quarterLength > nextNote.quarterLength)): diff --git a/music21_tools/theory/mgtaPart1.py b/music21_tools/theory/mgtaPart1.py index 2ccf600..75f4eb5 100644 --- a/music21_tools/theory/mgtaPart1.py +++ b/music21_tools/theory/mgtaPart1.py @@ -66,7 +66,7 @@ def ch1_basic_I_B(show=True, *arguments, **keywords): n1 = note.Note(i) n2 = note.Note(j) i1 = interval.notesToInterval(n1, n2) - if i1.intervalClass == 1: # by interval class + if i1.intervalClass == 1: # by interval class unused_mark = 'H' elif i1.intervalClass == 2: unused_mark = 'W' @@ -159,7 +159,7 @@ def ch1_basic_II_A_1(show=True, *arguments, **keywords): ''' exercise = converter.parseData(humdata) # exercise = music21.parseData("ch1_basic_II_A_1.xml") - for n in exercise.flatten().notes: # have to use flat here + for n in exercise.flatten().notes: # have to use flat here n.lyric = n.nameWithOctave if show: exercise.show() @@ -188,10 +188,10 @@ def ch1_basic_II_A_2(show=True, *arguments, **keywords): *- ''' exercise = converter.parseData(humdata) - for n in exercise.flatten().notes: # have to use flat here + for n in exercise.flatten().notes: # have to use flat here n.lyric = n.nameWithOctave exercise.insert(0, clef.BassClef()) - exercise = exercise.sorted # need sorted to get clef + exercise = exercise.sorted # need sorted to get clef if show: exercise.show() @@ -212,7 +212,7 @@ def ch1_basic_II_B_1(show=True, *arguments, **keywords): *- ''' exercise = converter.parseData(humdata) - for n in exercise.flatten().notes: # have to use flat here + for n in exercise.flatten().notes: # have to use flat here n.lyric = n.nameWithOctave exercise.insert(0, clef.AltoClef()) if show: @@ -226,7 +226,7 @@ def ch1_basic_II_B_2(show=True, *arguments, **keywords): ''' humdata = '**kern\n1F#1e-\n1B\n1D-\n1c\n*-' exercise = converter.parseData(humdata) - for n in exercise.flatten().notes: # have to use flat here + for n in exercise.flatten().notes: # have to use flat here n.lyric = n.nameWithOctave exercise.insert(0, clef.TenorClef()) if show: @@ -245,7 +245,7 @@ def ch1_basic_II_C(data, intervalShift): n1 = note.Note(e) n1.quarterLength = 4 n2 = n1.transpose(intervalShift) - m.append(chord.Chord([n1, n2])) # chord to show both + m.append(chord.Chord([n1, n2])) # chord to show both else: m.append(e) m.timeSignature = m.bestTimeSignature() @@ -331,7 +331,7 @@ def ch1_writing_I_A_1(show=True, *arguments, **keywords): ''' ex = converter.parseData(humdata) ex = ex.transpose('p8') - ex.insert(0, clef.BassClef()) # maintain clef + ex.insert(0, clef.BassClef()) # maintain clef if show: ex.show() @@ -354,7 +354,7 @@ def ch1_writing_I_A_2(show=True, *arguments, **keywords): # this notation excerpt is incomplete ex = converter.parseData(humdata) ex = ex.transpose('p8') - ex.insert(0, clef.TrebleClef()) # maintain clef + ex.insert(0, clef.TrebleClef()) # maintain clef if show: ex.show() @@ -366,7 +366,7 @@ def ch1_writing_I_B_1(show=True, *arguments, **keywords): ''' # camptown races ex = converter.parse('tinynotation: 2/4 g8 g e g', makeNotation=False) - ex.insert(0, clef.AltoClef()) # maintain clef + ex.insert(0, clef.AltoClef()) # maintain clef if show: ex.show() @@ -456,7 +456,7 @@ def ch1_writing_II_A(show=True, *arguments, **keywords): import random from music21 import stream, expressions, pitch - dirWeight = [-1, 1] # start with an even distribution + dirWeight = [-1, 1] # start with an even distribution s = stream.Stream() nStart = note.Note('g4') @@ -471,7 +471,7 @@ def ch1_writing_II_A(show=True, *arguments, **keywords): if len(s) > 4 and n.pitch.pitchClass == nStart.pitch.pitchClass: n.expressions.append(expressions.Fermata()) break - if len(s) > 30: # emergency break in case the piece is too long + if len(s) > 30: # emergency break in case the piece is too long break direction = random.choice(dirWeight) if direction == 1: @@ -484,9 +484,9 @@ def ch1_writing_II_A(show=True, *arguments, **keywords): break # end b/c our transposition have exceeded accidental range iSpread = interval.notesToInterval(nStart, n) - if iSpread.direction == -1: # we are below our target, favor upward + if iSpread.direction == -1: # we are below our target, favor upward dirWeight = [-1, 1, 1] - if iSpread.direction == 1: # we are above our target, favor down + if iSpread.direction == 1: # we are above our target, favor down dirWeight = [-1, -1, 1] if show: @@ -711,7 +711,7 @@ def ch2_writing_I_A(tsStr, barGroups): for b in barGroups: summation = 0 for ql in b: - if ql > 0: # quick encoding: negative values for rests + if ql > 0: # quick encoding: negative values for rests n = note.Note() else: n = note.Rest() @@ -922,16 +922,16 @@ def ch2_writing_III_B(src): if n.tie != None or len(group) > 0: if n.tie != None and n.tie.type != 'stop': group.append(n) - else: # end of tied notes + else: # end of tied notes group.append(n) ql = sum([x.quarterLength for x in group]) for i in range(len(group)): - if i == 0: # keep first, extend dur + if i == 0: # keep first, extend dur group[i].quarterLength = ql group[i].tie = None # remove tie - else: # remove from source + else: # remove from source s2.remove(group[i]) - group = [] # reset + group = [] # reset environLocal.printDebug(['post editing']) @@ -1817,7 +1817,7 @@ def ch5_analysis_C(show=True, *arguments, **keywords): ] -class TestExternal(unittest.TestCase): # pragma: no cover +class TestExternal(unittest.TestCase): # pragma: no cover def runTest(self): pass diff --git a/music21_tools/theory/mgtaPart2.py b/music21_tools/theory/mgtaPart2.py index 73e5888..3ff19be 100755 --- a/music21_tools/theory/mgtaPart2.py +++ b/music21_tools/theory/mgtaPart2.py @@ -71,7 +71,7 @@ def test_Ch6_basic_II_A(self, *arguments, **keywords): if i == len(pitches1): s.append(clef.BassClef()) - p = pitch.Pitch(p) # convert string to obj + p = pitch.Pitch(p) # convert string to obj iObj = interval.Interval(intervals[i]) c = chord.Chord([p, p.transpose(iObj)], type='whole') s.append(c) @@ -201,7 +201,7 @@ def test_Ch6_basic_II_B(self, *arguments, **keywords): import music21 import sys - if len(sys.argv) == 1: # normal conditions + if len(sys.argv) == 1: # normal conditions music21.mainTest(Test) elif len(sys.argv) > 1: diff --git a/music21_tools/theoryAnalysis/theoryAnalyzer.py b/music21_tools/theoryAnalysis/theoryAnalyzer.py index 0c6782e..8af335f 100644 --- a/music21_tools/theoryAnalysis/theoryAnalyzer.py +++ b/music21_tools/theoryAnalysis/theoryAnalyzer.py @@ -776,7 +776,7 @@ def _identifyBasedOnVLQ(self, score, partNum1, partNum2, dictKey, for vlq in vlqList[startIndex:endIndex]: - if testFunction(vlq) is not False: # True or value + if testFunction(vlq) is not False: # True or value tr = theoryResult.VLQTheoryResult(vlq) tr.value = testFunction(vlq) if textFunction is None: @@ -804,7 +804,7 @@ def _identifyBasedOnHarmonicInterval(self, score, partNum1, partNum2, color, dic hIntvList = self.getHarmonicIntervals(score, partNum1, partNum2) for hIntv in hIntvList: - if testFunction(hIntv) is not False: # True or value + if testFunction(hIntv) is not False: # True or value tr = theoryResult.IntervalTheoryResult(hIntv) tr.value = valueFunction(hIntv) @@ -825,7 +825,7 @@ def _identifyBasedOnMelodicInterval(self, score, partNum, mIntvList = self.getMelodicIntervals(score, partNum) for mIntv in mIntvList: - if testFunction(mIntv) is not False: # True or value + if testFunction(mIntv) is not False: # True or value tr = theoryResult.IntervalTheoryResult(mIntv) tr.value = testFunction(mIntv) tr.text = textFunction(mIntv, partNum) @@ -845,7 +845,7 @@ def _identifyBasedOnNote(self, score, partNum, color, dictKey, testFunction, tex nList = self.getNotes(score, partNum) for n in nList: - if testFunction(score, n) is not False: # True or value + if testFunction(score, n) is not False: # True or value tr = theoryResult.NoteTheoryResult(n) tr.value = testFunction(score, n) diff --git a/music21_tools/theoryAnalysis/theoryResult.py b/music21_tools/theoryAnalysis/theoryResult.py index c7fc450..98b1489 100644 --- a/music21_tools/theoryAnalysis/theoryResult.py +++ b/music21_tools/theoryAnalysis/theoryResult.py @@ -285,7 +285,7 @@ class Test(unittest.TestCase): def runTest(self): pass -class TestExternal(unittest.TestCase): # pragma: no cover +class TestExternal(unittest.TestCase): # pragma: no cover def runTest(self): pass diff --git a/music21_tools/theoryAnalysis/wwnortonMGTA.py b/music21_tools/theoryAnalysis/wwnortonMGTA.py index 3e18bde..59a863b 100644 --- a/music21_tools/theoryAnalysis/wwnortonMGTA.py +++ b/music21_tools/theoryAnalysis/wwnortonMGTA.py @@ -107,9 +107,9 @@ def addMarkerPartFromExisting(self, existingPartName, newPartName, newPartTitle= previousNotRestContents = copy.deepcopy(m.getElementsByClass('NotRest')) measureDuration = m.duration.quarterLength - m.removeByClass(['GeneralNote']) # includes rests + m.removeByClass(['GeneralNote']) # includes rests m.removeByClass(['Dynamic']) - m.removeByClass(['Stream']) # get voices or sub-streams + m.removeByClass(['Stream']) # get voices or sub-streams m.removeByClass(['Dynamic']) m.removeByClass(['Expression']) m.removeByClass(['KeySignature']) @@ -289,7 +289,7 @@ class Test(unittest.TestCase): def runTest(self): pass -class TestExternal(unittest.TestCase): # pragma: no cover +class TestExternal(unittest.TestCase): # pragma: no cover def runTest(self): pass diff --git a/music21_tools/trecento/capua.py b/music21_tools/trecento/capua.py index 7c22d03..270a7a2 100644 --- a/music21_tools/trecento/capua.py +++ b/music21_tools/trecento/capua.py @@ -61,7 +61,7 @@ def applyCapuaToCadencebookWork(thisWork): >>> import copy - >>> b = cadencebook.BallataSheet().makeWork(331) # Francesco, Non Creder Donna + >>> b = cadencebook.BallataSheet().makeWork(331) # Francesco, Non Creder Donna >>> bOrig = copy.deepcopy(b) >>> applyCapuaToCadencebookWork(b) >>> bFN = b.asScore().flatten().notes @@ -1144,7 +1144,7 @@ def testRunNonCrederDonna(self): def testShowFourA(self): ballataObj = cadencebook.BallataSheet() showStream = stream.Opus() - for i in range(2, 45): # 459): # all ballate + for i in range(2, 45): # 459): # all ballate pieceObj = ballataObj.makeWork(i) # N.B. -- we now use Excel column numbers theseSnippets = pieceObj.snippets for thisSnippet in theseSnippets: diff --git a/music21_tools/trecento/findTrecentoFragments.py b/music21_tools/trecento/findTrecentoFragments.py index 9633b78..cd54295 100644 --- a/music21_tools/trecento/findTrecentoFragments.py +++ b/music21_tools/trecento/findTrecentoFragments.py @@ -275,17 +275,17 @@ def savedSearches(): # searchForIntervals("C4 B3 A3 A3 G3 G3 A3") # London 29987 88v T # searchForNotes("G3 E3 F3 G3 F3 E3 D3 C3") # probable French piece, # # Nuremberg 9, but worth a check - # searchForIntervals("A4 A4 G4 G4 F4 E4") # Nuremberg 9a, staff 6 probable French Piece + # searchForIntervals("A4 A4 G4 G4 F4 E4") # Nuremberg 9a, staff 6 probable French Piece # findCasanatense522() # findRandomVerona() # findRavi3ORegina() # searchForIntervals("D4 B4 D4 C4 D4") # cadence formula from 15th c. that # Lisa Colton was searching for in earlier sources -- none found - # searchForIntervals("G4 A4 G4 F4 E4 F4 G4 E4") # Prague XVII.J.17-14_1r piece 1 + # searchForIntervals("G4 A4 G4 F4 E4 F4 G4 E4") # Prague XVII.J.17-14_1r piece 1 # -- possible contrafact -- no correct matches - # searchForIntervals("G4 A4 B4 G4 F4 G4 F4 E4") # Prague XVII.J.17-14_1r piece 2 + # searchForIntervals("G4 A4 B4 G4 F4 G4 F4 E4") # Prague XVII.J.17-14_1r piece 2 # -- possible contrafact -- no matches - # searchForIntervals("F4 A4 F4 G4 F4 G4 A4") # Duke white notation manuscript + # searchForIntervals("F4 A4 F4 G4 F4 G4 A4") # Duke white notation manuscript if __name__ == '__main__': savedSearches() diff --git a/music21_tools/trecento/medren.py b/music21_tools/trecento/medren.py index 5db0729..4364a5d 100644 --- a/music21_tools/trecento/medren.py +++ b/music21_tools/trecento/medren.py @@ -2119,7 +2119,7 @@ def testStretto(): import music21 music21.mainTest(Test, 'importPlusRelative') # TestExternal) # music21.testConvertMensuralMeasure() - # almaRedemptoris = converter.parse("C4 E F G A G G G A B c G", '4/4') # Liber 277 (pdf 401) - # puer = converter.parse('G4 d d d e d c c d c e d d', '4/4') # puer natus est 408 (pdf 554) + # almaRedemptoris = converter.parse("C4 E F G A G G G A B c G", '4/4') # Liber 277 (pdf 401) + # puer = converter.parse('G4 d d d e d c c d c e d d', '4/4') # puer natus est 408 (pdf 554) # almaRedemptoris.title = "Alma Redemptoris Mater LU p. 277" # puer.title = "Puer Natus Est Nobis" diff --git a/music21_tools/trecento/notation.py b/music21_tools/trecento/notation.py index c87b5b5..2a91c0e 100644 --- a/music21_tools/trecento/notation.py +++ b/music21_tools/trecento/notation.py @@ -377,6 +377,7 @@ class TrecentoTinyConverter(tinyNotation.Converter): 'quad': tinyNotation.QuadrupletState, 'lig': LigatureState } + def __init__(self, stringRep=''): super().__init__(stringRep) self.tokenMap = [ @@ -390,12 +391,12 @@ def __init__(self, stringRep=''): self.modifierUnderscore = FlagsModifier self.modifierAngle = LigatureNoteheadModifier self.modifierParens = MensuralTypeModifier - self.modifierSquare = StemsModifier # or LigatureStemsModifier -# self.modifierMap = [ -# (r'\[([A-Z]?(\/[A-Z])*)\]', StemsModifier), -# (r'\[([A-Z][A-Z])\]', LigatureStemsModifier), -# (r'(\/R)', LigatureReverseModifier), -# ] + self.modifierSquare = StemsModifier # or LigatureStemsModifier + # self.modifierMap = [ + # (r'\[([A-Z]?(\/[A-Z])*)\]', StemsModifier), + # (r'\[([A-Z][A-Z])\]', LigatureStemsModifier), + # (r'(\/R)', LigatureReverseModifier), + # ] self.stateDict['lastDuration'] = 0.0 self.stateDict['previousMensuralType'] = None @@ -406,6 +407,7 @@ def parse(self, parent=None): if parent: r.mensuralType = parent.stateDict['previousMensuralType'] + class TrecentoNoteToken(tinyNotation.NoteToken): ''' For documentation please see :class:`music21.TrecentoTinyConverter`. @@ -456,7 +458,6 @@ class Divisione(MedievalMeter): >>> d = Divisione('q') >>> d.standardSymbol '.q.' - ''' def __init__(self, nameOrSymbol='.p.'): self.name = None @@ -584,7 +585,7 @@ def convertTrecentoStream(inpStream, inpDiv=None): offset = 0 # hierarchy = ['measure', 'part', 'score'] - convertedStream = None + convertedStream: stream.Stream if 'measure' in inpStream.classes: convertedStream = stream.Measure() elif 'part' in inpStream.classes: @@ -747,16 +748,16 @@ class BrevisLengthTranslator: This acts a helper class to improve the efficiency of :class:`music21.convertBrevisLength`. -# >>> names = ['SM', 'SM', 'SM', 'SM', 'SB', 'SB', 'SB', 'SB', 'SB', 'SM', 'SM', 'SM'] -# >>> BL = [medren.MensuralNote('A', n) for n in names] -# >>> BL[3] = medren.MensuralRest('SM') -# >>> for mn in BL[-3:]: -# ... mn.setFlag('up', 'left') -# >>> for mn in BL[4:9]: -# ... mn.setStem('down') -# >>> TBL = BrevisLengthTranslator(div, BL) -# >>> TBL.getKnownLengths() -# [0.5, 0.5, 0.5, 0.5, 4.0, 4.0, 4.0, 4.0, 4.0, 0.666..., 0.666..., 0.666...] + # >>> names = ['SM', 'SM', 'SM', 'SM', 'SB', 'SB', 'SB', 'SB', 'SB', 'SM', 'SM', 'SM'] + # >>> BL = [medren.MensuralNote('A', n) for n in names] + # >>> BL[3] = medren.MensuralRest('SM') + # >>> for mn in BL[-3:]: + # ... mn.setFlag('up', 'left') + # >>> for mn in BL[4:9]: + # ... mn.setStem('down') + # >>> TBL = BrevisLengthTranslator(div, BL) + # >>> TBL.getKnownLengths() + # [0.5, 0.5, 0.5, 0.5, 4.0, 4.0, 4.0, 4.0, 4.0, 0.666..., 0.666..., 0.666...] ''' def __init__(self, divisione=None, BL=None, pDS=False): @@ -1010,12 +1011,12 @@ def getUnchangeableNoteLengths(self): minimaLength = self.div.minimaPerBrevis / 2.0 elif self.div.standardSymbol in ['.p.', '.n.']: minimaLength = self.div.minimaPerBrevis / 3.0 - else: # we don't know it... + else: # we don't know it... pass else: - if 'side' in obj.getStems(): # oblique-stemmed semibreve + if 'side' in obj.getStems(): # oblique-stemmed semibreve minimaLength = 3.0 - else: # WHO THe heck knows a semibreve's length!!! :-) + else: # Who the heck knows a semibreve's length!!! :-) pass elif obj.mensuralType == 'minima': if 'MensuralNote' in obj.classes and 'down' in obj.stems: @@ -1079,7 +1080,7 @@ def classifyUnknownNotesByType(self, unchangeableNoteLengthsList): semibrevis_list.append(i) else: if 'side' in obj.getStems(): - pass # shouldnt happen since length is known... + pass # shouldnt happen since length is known... elif 'down' in obj.getStems(): semibrevis_downstem.append(i) else: @@ -1146,8 +1147,8 @@ def translate(self): newDiv = Divisione(self.div.standardSymbol) newDiv.minimaPerBrevis = 2 * self.div.minimaPerBrevis return self.brevisLength -# tempTBL = BrevisLengthTranslator(newDiv, self.brevisLength[:]) -# knownLengthsList = tempTBL.getKnownLengths() + # tempTBL = BrevisLengthTranslator(newDiv, self.brevisLength[:]) + # knownLengthsList = tempTBL.getKnownLengths() for i in range(len(knownLengthsList)): # Float errors ml = knownLengthsList[i] @@ -1255,7 +1256,6 @@ def translateDivN(self, unchangeableNoteLengthsList=None, unknownLengthsDict=Non >>> unkldict = TBL.classifyUnknownNotesByType(unchlist) >>> TBL.translateDivN(unchlist, unkldict, 8.0) [5.0, 1.0, 3.0] - ''' if unchangeableNoteLengthsList is None: @@ -1289,7 +1289,7 @@ def translateDivN(self, unchangeableNoteLengthsList=None, unknownLengthsDict=Non knownLengthsList[ind] = 2.0 minRem -= 2.0 extend_list.append(ind) - else: # if not followed by minima -- make 3.0 + else: # if not followed by minima -- make 3.0 knownLengthsList[ind] = 3.0 minRem -= 3.0 @@ -1404,7 +1404,6 @@ def translateDivPQ(self, unchangeableNoteLengthsList=None, >>> unkldict = TBL.classifyUnknownNotesByType(unchlist) >>> TBL.translateDivPQ(unchlist, unkldict, 6.0) [0.666..., 0.666..., 0.666..., 0.5, 0.5, 0.5, 0.5, 2.0] - ''' if unchangeableNoteLengthsList is None: @@ -1825,7 +1824,7 @@ def translateDivOD(self, unchangeableNoteLengthsList=None, knownLengthsList_changeable[ind] = dSLengthList[i] # Don't need shrink_tup. There is no room to extend anything. - elif self.numberOfSemibreves > 0: # no downstems + elif self.numberOfSemibreves > 0: # no downstems if self.hasLastSB: maxVal = max(minRem_changeable, 2.0) knownLengthsList_changeable[semibrevis_list[-1]] = maxVal @@ -1882,9 +1881,7 @@ def _allCombinations(combinationList, num): >>> _allCombinations(['a', 'b', 'c'], 2) [[], ['c'], ['b', 'c'], ['b'], ['a', 'b'], ['a', 'c'], ['a']] - ''' - combs = [] if num > 0: for i in range(len(combinationList)): @@ -1912,7 +1909,7 @@ class TrecentoNotationException(exceptions21.Music21Exception): pass # ------------------------------------------------------------------------------------- -class TestExternal(unittest.TestCase): # pragma: no cover +class TestExternal(unittest.TestCase): # pragma: no cover def testTinyTrecentoStream(self): from music21 import text diff --git a/music21_tools/trecento/polyphonicSnippet.py b/music21_tools/trecento/polyphonicSnippet.py index 7a923bf..e42dc20 100644 --- a/music21_tools/trecento/polyphonicSnippet.py +++ b/music21_tools/trecento/polyphonicSnippet.py @@ -383,7 +383,7 @@ def testCopyAndDeepcopy(self): self.assertNotEqual(b, obj) -class TestExternal(unittest.TestCase): # pragma: no cover +class TestExternal(unittest.TestCase): # pragma: no cover pass def runTest(self): diff --git a/music21_tools/trecento/quodJactatur.py b/music21_tools/trecento/quodJactatur.py index 61ce68a..08cd605 100644 --- a/music21_tools/trecento/quodJactatur.py +++ b/music21_tools/trecento/quodJactatur.py @@ -45,7 +45,7 @@ from music21 import clef -#from music21 import common +# from music21 import common from music21 import corpus from music21 import exceptions21 from music21 import instrument @@ -234,7 +234,7 @@ def findRetrogradeVoices(show=True): # print int1.generic.simpleUndirected if int1.generic.simpleUndirected in [1, 3, 4, 5]: thisScore = strength - elif int1.generic.simpleUndirected == 6: # less good + elif int1.generic.simpleUndirected == 6: # less good thisScore = strength / 2.0 else: thisScore = -2 * strength @@ -322,9 +322,9 @@ def getStrengthForNote(n): solutions should use n.beat ''' - if (n.offset / 2.0) == int(n.offset / 2.0): # downbeat + if (n.offset / 2.0) == int(n.offset / 2.0): # downbeat strength = 4 - elif (n.offset) == int(n.offset): # strong beat + elif (n.offset) == int(n.offset): # strong beat strength = 2 else: strength = 0.5 diff --git a/music21_tools/trecento/runTrecentoCadence.py b/music21_tools/trecento/runTrecentoCadence.py index bab2e9b..fd206d8 100644 --- a/music21_tools/trecento/runTrecentoCadence.py +++ b/music21_tools/trecento/runTrecentoCadence.py @@ -25,8 +25,8 @@ def countTimeSig(): for trecentoWork in ballataObj: thisTime = trecentoWork.timeSigBegin - thisTime = thisTime.strip() # remove leading and trailing whitespace - if (thisTime == ''): + thisTime = thisTime.strip() # remove leading and trailing whitespace + if thisTime == '': pass else: totalPieces += 1 diff --git a/music21_tools/trecento/tonality.py b/music21_tools/trecento/tonality.py index 946fbed..0aeae5d 100644 --- a/music21_tools/trecento/tonality.py +++ b/music21_tools/trecento/tonality.py @@ -340,7 +340,7 @@ class Test(unittest.TestCase): def runTest(self): testAll(show=False, fast=True) -class TestExternal(unittest.TestCase): # pragma: no cover +class TestExternal(unittest.TestCase): # pragma: no cover pass def runTest(self): diff --git a/music21_tools/trecento/trecentoCadence.py b/music21_tools/trecento/trecentoCadence.py index de748d5..c2c9fa4 100644 --- a/music21_tools/trecento/trecentoCadence.py +++ b/music21_tools/trecento/trecentoCadence.py @@ -94,14 +94,14 @@ def testDotGroups(self): cn = CadenceConverter('c#2..') cn.parse() - a = cn.stream.flatten().notes[0] # returns the stored music21 note. + a = cn.stream.flatten().notes[0] # returns the stored music21 note. self.assertEqual(a.name, 'C#') self.assertEqual(a.duration.type, 'half') self.assertEqual(a.duration.dotGroups, (1, 1)) self.assertEqual(a.duration.quarterLength, 4.5) -class TestExternal(unittest.TestCase): # pragma: no cover +class TestExternal(unittest.TestCase): # pragma: no cover ''' These objects generate PNGs, etc. ''' diff --git a/publications/icmc2010.py b/publications/icmc2010.py index daf312f..09a00b3 100644 --- a/publications/icmc2010.py +++ b/publications/icmc2010.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # ------------------------------------------------------------------------------ # Name: icmc2010.py # Purpose: icmc2010.py diff --git a/publications/icmc2011.py b/publications/icmc2011.py index 93c4ac1..dd04ff0 100644 --- a/publications/icmc2011.py +++ b/publications/icmc2011.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # ------------------------------------------------------------------------------ # Name: icmc2011.py # Purpose: Demonstrations for the ICMC 2011 poster session diff --git a/publications/ismir2010.py b/publications/ismir2010.py index 233ba4e..5b9898a 100644 --- a/publications/ismir2010.py +++ b/publications/ismir2010.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # ------------------------------------------------------------------------------ # Name: ismir2010.py # Purpose: Examples for ISMIR 2010 paper @@ -326,7 +325,7 @@ def demoBasic(): len(soprano.getElementsByClass('Measure')) _mRange = soprano.measures(14, 16) # mRange.show() - # mRange.sorted.show('text') # here we can see this + # mRange.sorted.show('text') # here we can see this @@ -656,6 +655,3 @@ def testBasic(self): # demoGraphMessiaenBrief() # demoGraphMessiaen() -# ----------------------------------------------------------------------------- -# eof - diff --git a/publications/misc2010.py b/publications/misc2010.py index 4102199..9b7a4a1 100644 --- a/publications/misc2010.py +++ b/publications/misc2010.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # ------------------------------------------------------------------------------ # Name: misc2010.py # Purpose: demos from 2010 diff --git a/publications/seaverOct2009.py b/publications/seaverOct2009.py index a0571d9..3651294 100644 --- a/publications/seaverOct2009.py +++ b/publications/seaverOct2009.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from music21 import stream from music21 import clef from music21 import converter, corpus, instrument, graph, note, meter, humdrum @@ -526,10 +525,3 @@ def xtestBasic(self): # js_q1() music21.mainTest(Test) # music21.mainTest(TestExternal) - - - - -# ----------------------------------------------------------------------------- -# eof - diff --git a/publications/seaver_presentation_2008.py b/publications/seaver_presentation_2008.py index 04616e3..b3913b1 100644 --- a/publications/seaver_presentation_2008.py +++ b/publications/seaver_presentation_2008.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # ------------------------------------------------------------------------------ # Name: demos/seaver_presentation_2008.py # Purpose: Demonstrations for the Seaver 2008 demo diff --git a/publications/smt2010.py b/publications/smt2010.py index ff0ce60..dad8f13 100644 --- a/publications/smt2010.py +++ b/publications/smt2010.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # ------------------------------------------------------------------------------ # Name: smt2010.py # Purpose: Demonstrations for the SMT 2010 poster session @@ -489,7 +488,3 @@ def testBasic(self): # chordifyAnalysisBrief() # corpusMelodicIntervalSearchBrief() chordifyAnalysisBrief() - -# ----------------------------------------------------------------------------- -# eof - diff --git a/publications/smt2011.py b/publications/smt2011.py index 880296c..0876c99 100644 --- a/publications/smt2011.py +++ b/publications/smt2011.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # ------------------------------------------------------------------------------ # Name: smt2011.py # Purpose: Demonstrations for the SMT 2011 demo @@ -147,7 +146,7 @@ def demoMakeChords(): c = src.flattenParts().makeChords(minimumWindowSize=3) print(c.write()) c.show() - + src = corpus.parse('opus18no1/movement3.xml').measures(0, 10) src.chordify().show() From 72bed206201c186f3c1e15b9e04263e32cdf1371 Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 15:04:13 -1000 Subject: [PATCH 14/28] lint (even comments) --- music21_tools/audioSearchDemos/graphicalInterfaceSF.py | 8 ++++---- music21_tools/audioSearchDemos/humanVScomputer.py | 2 +- music21_tools/audioSearchDemos/repetitionGame.py | 6 +++--- music21_tools/bhadley/nips2011.py | 4 ++-- music21_tools/contour/contour.py | 4 ++-- music21_tools/counterpoint/species.py | 8 ++++---- music21_tools/featureExtraction/ismir2011.py | 4 ++-- music21_tools/trecento/capua.py | 2 +- music21_tools/trecento/notation.py | 2 +- music21_tools/trecento/polyphonicSnippet.py | 10 +++++----- music21_tools/trecento/quodJactatur.py | 4 ++-- music21_tools/trecento/runTrecentoCadence.py | 6 +++--- music21_tools/trecento/tonality.py | 2 +- publications/icmc2011.py | 6 +++--- publications/misc2010.py | 4 ++-- publications/smt2010.py | 4 ++-- 16 files changed, 38 insertions(+), 38 deletions(-) diff --git a/music21_tools/audioSearchDemos/graphicalInterfaceSF.py b/music21_tools/audioSearchDemos/graphicalInterfaceSF.py index 2e0f410..a4f42b7 100644 --- a/music21_tools/audioSearchDemos/graphicalInterfaceSF.py +++ b/music21_tools/audioSearchDemos/graphicalInterfaceSF.py @@ -619,16 +619,16 @@ def analyzeRecording(self): totalPagesToMove = 0 else: totalPagesToMove = pageNumber - self.currentLeftPage - # print "TOTAL PAGES TO MOVE", totalPagesToMove, pageNumber, self.currentLeftPage + # print('Total pages to move', totalPagesToMove, + # pageNumber, self.currentLeftPage) if totalPagesToMove > 0: for i in range(totalPagesToMove): self.pageForward() - # print "has played a note not shown in the score (forward)" + # print('has played a note not shown in the score (forward)') elif totalPagesToMove < 0: for i in range(int(math.fabs(totalPagesToMove))): self.pageBackward() - # print "has played a note not shown in the score (backward)" - + # print('has played a note not shown in the score (backward)') elif (self.ScF.lastNotePosition >= self.middlePages[self.currentLeftPage] and not self.isMoving): # 50% case diff --git a/music21_tools/audioSearchDemos/humanVScomputer.py b/music21_tools/audioSearchDemos/humanVScomputer.py index cfd601a..33dbf83 100644 --- a/music21_tools/audioSearchDemos/humanVScomputer.py +++ b/music21_tools/audioSearchDemos/humanVScomputer.py @@ -31,7 +31,7 @@ def runGame(): time.sleep(2) print('3, 2, 1 GO!') nameNotes = ['A', 'B', 'C', 'D', 'E', 'F', 'G'] - while(good): + while good: randomNumber = random.randint(0, 6) octaveNumber = 4 # I can put a random number here... fullNameNote = '%s%d' % (nameNotes[randomNumber], octaveNumber) diff --git a/music21_tools/audioSearchDemos/repetitionGame.py b/music21_tools/audioSearchDemos/repetitionGame.py index 692f641..409eaaa 100644 --- a/music21_tools/audioSearchDemos/repetitionGame.py +++ b/music21_tools/audioSearchDemos/repetitionGame.py @@ -35,9 +35,9 @@ def game(self): self.round = self.round + 1 print('self.round %d' % self.round) - # print "NOTES UNTIL NOW: (this will not be shown in the final version)" - # for k in range(len(self.gameNotes)): - # print self.gameNotes[k].fullName + # print('Notes until now: (this will not be shown in the final version)') + # for k in range(len(self.gameNotes)): + # print(self.gameNotes[k].fullName) seconds = 2 + self.round freqFromAQList = base.getFrequenciesFromMicrophone(length=seconds, storeWaveFilename=None) diff --git a/music21_tools/bhadley/nips2011.py b/music21_tools/bhadley/nips2011.py index b841aa6..0106bf3 100644 --- a/music21_tools/bhadley/nips2011.py +++ b/music21_tools/bhadley/nips2011.py @@ -328,8 +328,8 @@ def getLeadsheetDatesFromBillboard(): if e.lower() == piece.metadata.movementName.lower(): rank = (tempList.index(x) + 1 ) # position on Billboard 100 - # print "Title:", piece.metadata.movementName, " Composer:", piece.metadata.composer, " Date:", date, " Position on Billboard:", rank - # print "Title:", piece.metadata.movementName, " Date:", date + # print('Title:', piece.metadata.movementName, ' Composer:', piece.metadata.composer, ' Date:', date, ' Position on Billboard:', rank) + # print('Title:', piece.metadata.movementName, ' Date:', date) matches = matches + 1 outputjson = outputjson + '{"%s":[%s,%s]}, ' % (i, date, rank) if (i % 500) == 0: diff --git a/music21_tools/contour/contour.py b/music21_tools/contour/contour.py index ce2c9aa..63c91aa 100644 --- a/music21_tools/contour/contour.py +++ b/music21_tools/contour/contour.py @@ -796,7 +796,7 @@ def _runExperiment(): if successes > 50: totalSuccesses += 1 - # print "GREAT SUCCESS!" + # print('Great success!') else: totalFailures += 1 print('failure: chorale ' + goodChorales[j]) # index ", str(i) @@ -821,7 +821,7 @@ def _plotChoraleContours(): pass -#------------------------ +# ------------------------ class Test(unittest.TestCase): def runTest(self): diff --git a/music21_tools/counterpoint/species.py b/music21_tools/counterpoint/species.py index 05c77eb..d041ca5 100644 --- a/music21_tools/counterpoint/species.py +++ b/music21_tools/counterpoint/species.py @@ -976,12 +976,12 @@ def raiseLeadingTone(self, stream1, minorScale): maxNote = len(s1notes) for i in range(maxNote): note1 = s1notes[i] - if (note1.name == sixth and i < maxNote - 2): + if note1.name == sixth and i < maxNote - 2 note2 = s1notes[i + 1] note3 = s1notes[i + 2] - if (note2.name == seventh and note3.name == tonic): + if note2.name == seventh and note3.name == tonic note1 = note1.transpose('A1') - elif (note1.name == seventh and i < maxNote - 1): + elif note1.name == seventh and i < maxNote - 1 note2 = s1notes[i + 1] if note2.name == tonic: note1 = note1.transpose('A1') @@ -999,7 +999,7 @@ def generateFirstSpecies(self, cantusFirmus, minorScale, choice='random'): thirdsGood = False sixthsGood = False - while (not goodHarmony or not goodMelody or not thirdsGood or not sixthsGood): + while not goodHarmony or not goodMelody or not thirdsGood or not sixthsGood environLocal.printDebug(['']) environLocal.printDebug(['-------------------------------------']) environLocal.printDebug(['starting over']) diff --git a/music21_tools/featureExtraction/ismir2011.py b/music21_tools/featureExtraction/ismir2011.py index 49f0bf0..bdf6a64 100644 --- a/music21_tools/featureExtraction/ismir2011.py +++ b/music21_tools/featureExtraction/ismir2011.py @@ -17,13 +17,13 @@ # def example2(): # handel = corpus.parse('hwv56/movement3-05.md') # fe = features.jSymbolic.TripleMeterFeature(handel) -# print (fe.extract().vector) +# print(fe.extract().vector) # # # no longer works... # soft = converter.parse("https://github.com/cuthbertLab/music21/raw/master/music21/" + # "corpus/leadSheet/fosterBrownHair.mxl") # fe.setData(soft) -# print (fe.extract().vector) +# print(fe.extract().vector) class MusicaFictaFeature(features.FeatureExtractor): name = 'Musica Ficta' diff --git a/music21_tools/trecento/capua.py b/music21_tools/trecento/capua.py index 270a7a2..a0551e8 100644 --- a/music21_tools/trecento/capua.py +++ b/music21_tools/trecento/capua.py @@ -1219,7 +1219,7 @@ def testRuleFrequency(self): # runPiece(267) # (totalDict, foundPieceOpus) = findCorrections(correctionType='min6', # startPiece=21, endPiece=22) - # print totalDict + # print(totalDict) # if len(foundPieceOpus) > 0: # foundPieceOpus.show('lily.png') import music21 diff --git a/music21_tools/trecento/notation.py b/music21_tools/trecento/notation.py index 2a91c0e..756f3c5 100644 --- a/music21_tools/trecento/notation.py +++ b/music21_tools/trecento/notation.py @@ -1322,7 +1322,7 @@ def translateDivN(self, unchangeableNoteLengthsList=None, unknownLengthsDict=Non shrink_tup += -1, elif self.numberOfSemibreves > 0: # SBs, but no last SB - if (self.brevisLength[semibrevis_list[-1] + 1].mensuralType == 'minima'): + if self.brevisLength[semibrevis_list[-1] + 1].mensuralType == 'minima' knownLengthsList[semibrevis_list[-1]] = 2.0 minRem -= 2.0 extend_list.append(semibrevis_list[-1]) diff --git a/music21_tools/trecento/polyphonicSnippet.py b/music21_tools/trecento/polyphonicSnippet.py index e42dc20..55aa51f 100644 --- a/music21_tools/trecento/polyphonicSnippet.py +++ b/music21_tools/trecento/polyphonicSnippet.py @@ -137,10 +137,10 @@ def _padParts(self): def header(self): '''returns a string that prints an appropriate header for this cadence''' if self.snippetName == '': - if (self.parentPiece is not None): + if self.parentPiece is not None headOut = '' parentPiece = self.parentPiece - if (parentPiece.fischerNum): + if parentPiece.fischerNum headOut += str(parentPiece.fischerNum) + '. ' if parentPiece.title: headOut += parentPiece.title @@ -151,7 +151,7 @@ def header(self): else: return '' else: - if (self.parentPiece is not None): + if self.parentPiece is not None headOut = self.parentPiece.title + ' -- ' + self.snippetName else: return self.snippetName @@ -244,7 +244,7 @@ def backPadLine(self, thisStream): ''' shortMeasures = int(self.measuresShort(thisStream)) - if (shortMeasures > 0): + if shortMeasures > 0 shortDuration = self.timeSig.barDuration hasMeasures = thisStream.hasMeasures() if hasMeasures: @@ -310,7 +310,7 @@ def frontPadLine(self, thisStream): ''' shortMeasures = int(self.measuresShort(thisStream)) - if (shortMeasures > 0): + if shortMeasures > 0 shortDuration = self.timeSig.barDuration offsetShift = shortDuration.quarterLength * shortMeasures hasMeasures = thisStream.hasMeasures() diff --git a/music21_tools/trecento/quodJactatur.py b/music21_tools/trecento/quodJactatur.py index 08cd605..909038b 100644 --- a/music21_tools/trecento/quodJactatur.py +++ b/music21_tools/trecento/quodJactatur.py @@ -231,7 +231,7 @@ def findRetrogradeVoices(show=True): thisScore = strength else: int1 = interval.Interval(n.pitches[0], n.pitches[1]) - # print int1.generic.simpleUndirected + # print(int1.generic.simpleUndirected) if int1.generic.simpleUndirected in [1, 3, 4, 5]: thisScore = strength elif int1.generic.simpleUndirected == 6: # less good @@ -429,7 +429,7 @@ def multipleSolve(): continue # same as lowestInvert == True and # middleInvert == False - if (transLowest == 1 and transMiddle == 1): + if transLowest == 1 and transMiddle == 1 continue # if transHighest == 4 then it's the same # as (-4, -4, 1) except for a few tritones diff --git a/music21_tools/trecento/runTrecentoCadence.py b/music21_tools/trecento/runTrecentoCadence.py index fd206d8..5f330b9 100644 --- a/music21_tools/trecento/runTrecentoCadence.py +++ b/music21_tools/trecento/runTrecentoCadence.py @@ -30,7 +30,7 @@ def countTimeSig(): pass else: totalPieces += 1 - if (thisTime in timeSigCounter): + if thisTime in timeSigCounter timeSigCounter[thisTime] += 1 else: timeSigCounter[thisTime] = 1 @@ -167,8 +167,8 @@ def checkValidity(): # temporarily commenting out for adding standard test approach -# if (__name__ == "__main__"): -# # countTimeSig() +# if __name__ == "__main__" +# # countTimeSig() # makePDFfromPiecesWithCapua() diff --git a/music21_tools/trecento/tonality.py b/music21_tools/trecento/tonality.py index 0aeae5d..d55e933 100644 --- a/music21_tools/trecento/tonality.py +++ b/music21_tools/trecento/tonality.py @@ -100,7 +100,7 @@ def run(self): elif self.cadenceName == 'B': cadence = thisWork.cadenceBclos try: - if (cadence is None or cadence.parts[streamName] is None): + if cadence is None or cadence.parts[streamName] is None cadence = thisWork.cadenceB except KeyError: cadence = thisWork.cadenceB diff --git a/publications/icmc2011.py b/publications/icmc2011.py index dd04ff0..3976972 100644 --- a/publications/icmc2011.py +++ b/publications/icmc2011.py @@ -240,7 +240,7 @@ def testStreams01(self): # Non-Hierarchical Object Associations # oldIds = [] # for idKey in n1.sites.siteDict: - # print (idKey, n1.sites.siteDict[idKey].isDead) + # print(idKey, n1.sites.siteDict[idKey].isDead) # oldIds.append(idKey) # print("-------") @@ -252,7 +252,7 @@ def testStreams01(self): # print(id(sp1), id(sp1.spannerStorage), n1.sites.siteDict[id(sp1.spannerStorage)].isDead) # if id(sp1.spannerStorage) in oldIds: - # print ("******!!!!!!!!!*******") + # print("******!!!!!!!!!*******") # Elements can report on what Spanner they belong to ss1 = n1.getSpannerSites() @@ -619,7 +619,7 @@ def testEx01(self): sc2 = scale.WholeToneScale('f#') # get pitches from any range of this scale - # print str(sc2.getPitches('g2', 'c4')) + # print(str(sc2.getPitches('g2', 'c4'))) self.assertEqual(common.pitchList(sc2.getPitches('g2', 'c4')), '[A-2, B-2, C3, D3, F-3, G-3, A-3, B-3, C4]') diff --git a/publications/misc2010.py b/publications/misc2010.py index 9b7a4a1..d27efbb 100644 --- a/publications/misc2010.py +++ b/publications/misc2010.py @@ -107,7 +107,7 @@ def towersOfHanoi(show=False, numParts=6, transpose=False): descendingPitches = [medPitch, lowPitch, highPitch] ascendingPitches = [lowPitch, medPitch, highPitch] - if (numParts/2.0) == int(numParts/2.0): + if (numParts / 2.0) == numParts // 2: oddPitches = descendingPitches evenPitches = ascendingPitches else: @@ -119,7 +119,7 @@ def towersOfHanoi(show=False, numParts=6, transpose=False): firstNote = note.Note("E5") firstNote.quarterLength = baseQuarterLength - if (i / 2.0) == int(i / 2.0): + if (i / 2.0) == i // 2: pitchCycle = copy.deepcopy(evenPitches) else: pitchCycle = copy.deepcopy(oddPitches) diff --git a/publications/smt2010.py b/publications/smt2010.py index dad8f13..1356047 100644 --- a/publications/smt2010.py +++ b/publications/smt2010.py @@ -293,8 +293,8 @@ def corpusMelodicIntervalSearch(show=True): msg.append( 'locale: %s: found %s percent melodic sevenths, out of %s intervals in %s works' % ( name, pcentSevenths, intervalCount, workCount)) -# for key in sorted(intervalDict.keys()): -# print intervalDict[key] + # for key in sorted(intervalDict.keys()): + # print(intervalDict[key]) for sub in msg: if show: From b8361a0251c80f0cc19230986c8b05fe50038dac Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 15:07:21 -1000 Subject: [PATCH 15/28] fix syntax errors. --- music21_tools/trecento/polyphonicSnippet.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/music21_tools/trecento/polyphonicSnippet.py b/music21_tools/trecento/polyphonicSnippet.py index 55aa51f..5131a33 100644 --- a/music21_tools/trecento/polyphonicSnippet.py +++ b/music21_tools/trecento/polyphonicSnippet.py @@ -137,10 +137,10 @@ def _padParts(self): def header(self): '''returns a string that prints an appropriate header for this cadence''' if self.snippetName == '': - if self.parentPiece is not None + if self.parentPiece is not None: headOut = '' parentPiece = self.parentPiece - if parentPiece.fischerNum + if parentPiece.fischerNum: headOut += str(parentPiece.fischerNum) + '. ' if parentPiece.title: headOut += parentPiece.title @@ -151,7 +151,7 @@ def header(self): else: return '' else: - if self.parentPiece is not None + if self.parentPiece is not None: headOut = self.parentPiece.title + ' -- ' + self.snippetName else: return self.snippetName @@ -244,7 +244,7 @@ def backPadLine(self, thisStream): ''' shortMeasures = int(self.measuresShort(thisStream)) - if shortMeasures > 0 + if shortMeasures: shortDuration = self.timeSig.barDuration hasMeasures = thisStream.hasMeasures() if hasMeasures: @@ -310,7 +310,7 @@ def frontPadLine(self, thisStream): ''' shortMeasures = int(self.measuresShort(thisStream)) - if shortMeasures > 0 + if shortMeasures: shortDuration = self.timeSig.barDuration offsetShift = shortDuration.quarterLength * shortMeasures hasMeasures = thisStream.hasMeasures() From 1cd178523e2ddffdf38e4a78d75b6ba379fa2ac5 Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 15:07:40 -1000 Subject: [PATCH 16/28] fix syntax errors --- music21_tools/trecento/notation.py | 2 +- music21_tools/trecento/quodJactatur.py | 2 +- music21_tools/trecento/runTrecentoCadence.py | 2 +- music21_tools/trecento/tonality.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/music21_tools/trecento/notation.py b/music21_tools/trecento/notation.py index 756f3c5..05f41c8 100644 --- a/music21_tools/trecento/notation.py +++ b/music21_tools/trecento/notation.py @@ -1322,7 +1322,7 @@ def translateDivN(self, unchangeableNoteLengthsList=None, unknownLengthsDict=Non shrink_tup += -1, elif self.numberOfSemibreves > 0: # SBs, but no last SB - if self.brevisLength[semibrevis_list[-1] + 1].mensuralType == 'minima' + if self.brevisLength[semibrevis_list[-1] + 1].mensuralType == 'minima': knownLengthsList[semibrevis_list[-1]] = 2.0 minRem -= 2.0 extend_list.append(semibrevis_list[-1]) diff --git a/music21_tools/trecento/quodJactatur.py b/music21_tools/trecento/quodJactatur.py index 909038b..df4fb72 100644 --- a/music21_tools/trecento/quodJactatur.py +++ b/music21_tools/trecento/quodJactatur.py @@ -429,7 +429,7 @@ def multipleSolve(): continue # same as lowestInvert == True and # middleInvert == False - if transLowest == 1 and transMiddle == 1 + if transLowest == 1 and transMiddle == 1: continue # if transHighest == 4 then it's the same # as (-4, -4, 1) except for a few tritones diff --git a/music21_tools/trecento/runTrecentoCadence.py b/music21_tools/trecento/runTrecentoCadence.py index 5f330b9..8f323ca 100644 --- a/music21_tools/trecento/runTrecentoCadence.py +++ b/music21_tools/trecento/runTrecentoCadence.py @@ -30,7 +30,7 @@ def countTimeSig(): pass else: totalPieces += 1 - if thisTime in timeSigCounter + if thisTime in timeSigCounter: timeSigCounter[thisTime] += 1 else: timeSigCounter[thisTime] = 1 diff --git a/music21_tools/trecento/tonality.py b/music21_tools/trecento/tonality.py index d55e933..4932644 100644 --- a/music21_tools/trecento/tonality.py +++ b/music21_tools/trecento/tonality.py @@ -100,7 +100,7 @@ def run(self): elif self.cadenceName == 'B': cadence = thisWork.cadenceBclos try: - if cadence is None or cadence.parts[streamName] is None + if cadence is None or cadence.parts[streamName] is None: cadence = thisWork.cadenceB except KeyError: cadence = thisWork.cadenceB From 61ce64b71eb6902958c2a2736755039672fde77a Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 15:10:34 -1000 Subject: [PATCH 17/28] more syntax errors --- music21_tools/counterpoint/species.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/music21_tools/counterpoint/species.py b/music21_tools/counterpoint/species.py index d041ca5..342690e 100644 --- a/music21_tools/counterpoint/species.py +++ b/music21_tools/counterpoint/species.py @@ -976,12 +976,12 @@ def raiseLeadingTone(self, stream1, minorScale): maxNote = len(s1notes) for i in range(maxNote): note1 = s1notes[i] - if note1.name == sixth and i < maxNote - 2 + if note1.name == sixth and i < maxNote - 2: note2 = s1notes[i + 1] note3 = s1notes[i + 2] - if note2.name == seventh and note3.name == tonic + if note2.name == seventh and note3.name == tonic: note1 = note1.transpose('A1') - elif note1.name == seventh and i < maxNote - 1 + elif note1.name == seventh and i < maxNote - 1: note2 = s1notes[i + 1] if note2.name == tonic: note1 = note1.transpose('A1') @@ -999,7 +999,7 @@ def generateFirstSpecies(self, cantusFirmus, minorScale, choice='random'): thirdsGood = False sixthsGood = False - while not goodHarmony or not goodMelody or not thirdsGood or not sixthsGood + while not goodHarmony or not goodMelody or not thirdsGood or not sixthsGood: environLocal.printDebug(['']) environLocal.printDebug(['-------------------------------------']) environLocal.printDebug(['starting over']) From dceeea69c00b80ce881e722cfbb1a3bdfaa9ce04 Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 16:44:37 -1000 Subject: [PATCH 18/28] doctests -- import own files --- music21_tools/chant/chant.py | 10 +- music21_tools/contour/contour.py | 25 +- music21_tools/counterpoint/species.py | 23 ++ .../theoryAnalysis/theoryAnalyzer.py | 41 +++- music21_tools/trecento/__init__.py | 3 +- music21_tools/trecento/cadencebook.py | 39 ++- music21_tools/trecento/capua.py | 10 +- music21_tools/trecento/medren.py | 207 +++++++++------- music21_tools/trecento/notation.py | 231 ++++++++++-------- music21_tools/trecento/polyphonicSnippet.py | 38 ++- music21_tools/trecento/runTrecentoCadence.py | 1 - music21_tools/trecento/tonality.py | 22 +- music21_tools/trecento/trecentoCadence.py | 2 +- 13 files changed, 372 insertions(+), 280 deletions(-) diff --git a/music21_tools/chant/chant.py b/music21_tools/chant/chant.py index a936e0d..5cd135a 100644 --- a/music21_tools/chant/chant.py +++ b/music21_tools/chant/chant.py @@ -81,6 +81,7 @@ def toGABCText(self): def clefToGABC(self, clefIn): ''' + >>> from music21_tools.chant.chant import GregorianStream >>> s = GregorianStream() >>> c = clef.AltoClef() >>> s.clefToGABC(c) @@ -95,13 +96,11 @@ class GregorianNote(note.Note): contains extra attributes which represent the interpretation or graphical representation of the note. - Most of the attributes default to False. Exceptions are noted below. - Example: a very special note. - + >>> from music21_tools.chant.chant import GregorianNote >>> n = GregorianNote("C4") >>> n.liquescent = True >>> n.quilisma = True @@ -204,6 +203,7 @@ def toBasicGABC(self, useClef=None): see http://home.gna.org/gregorio/gabc/ for more details. 'd' = lowest line + >>> from music21_tools.chant.chant import GregorianNote >>> n = GregorianNote("C4") >>> c = clef.AltoClef() >>> n.toBasicGABC(c) @@ -330,6 +330,7 @@ def __init__(self): def writeFile(self, text=None): ''' + >>> from music21_tools.chant.chant import BaseScoreConverter >>> bsc = BaseScoreConverter() >>> filePath = bsc.writeFile('hello') >>> assert(str(filePath).endswith('.gabc')) # _DOCS_HIDE @@ -353,6 +354,7 @@ def launchGregorio(self, fp=None): converts a .gabc file to LaTeX using the gregorio converter. Returns the filename with .tex substituted for .gabc + >>> from music21_tools.chant.chant import BaseScoreConverter >>> bsc = BaseScoreConverter() >>> fn = '~cuthbert/Library/Gregorio/examples/Populas.gabc' >>> # _DOCS_SHOW newFp = bsc.launchGregorio(fn) @@ -465,7 +467,7 @@ def substituteInfo(self, converter): r''' Puts the correct information into the TeXWrapper for the document - + >>> from music21_tools.chant.chant import DefaultTeXWrapper >>> wrapper = DefaultTeXWrapper() >>> class Converter(): ... score = r'\note{C}' + "\n" + r'\endgregorioscore %' + "\n" + r'\endinput %' diff --git a/music21_tools/contour/contour.py b/music21_tools/contour/contour.py index 63c91aa..fb5fa6a 100644 --- a/music21_tools/contour/contour.py +++ b/music21_tools/contour/contour.py @@ -14,7 +14,7 @@ import random import unittest -from music21 import base # for _missingImport testing. +from music21 import base # for _missingImport testing. from music21 import repeat from music21 import exceptions21 from music21 import corpus @@ -64,6 +64,7 @@ class ContourFinder: M and n are specified by 'window' and 'slide', which are both 1 by default. + >>> from music21_tools.contour.contour import ContourFinder >>> s = corpus.parse('bwv29.8') >>> tonalContour = ContourFinder(s).getContour('tonality') >>> isinstance(tonalContour, dict) @@ -79,14 +80,15 @@ def __init__(self, s=None): self.sChords = None # lazy evaluation... self.key = None - self._contours = { } # A dictionary mapping a contour type to a normalized contour dictionary + # A dictionary mapping a contour type to a normalized contour dictionary + self._contours = {} # self.metrics contains a dictionary mapping the name of a metric to a tuple (x,y) # where x=metric function and y=needsChordify self._metrics = {'dissonance': (self.dissonanceMetric, True), 'spacing': (self.spacingMetric, True), - 'tonality': (self.tonalDistanceMetric, False) } + 'tonality': (self.tonalDistanceMetric, False) } self.isContourFinder = True @@ -94,7 +96,6 @@ def setKey(self, key): ''' Sets the key of ContourFinder's internal stream. If not set manually, self.key will be determined by self.s.analyze('key'). - ''' self.key = key @@ -114,6 +115,7 @@ def getContourValuesForMetric(self, metric, window=1, slide=1, needChordified=Fa measures 3-6: f(measures 3-6), measures 5-8: f( measures5-8), ...} + >>> from music21_tools.contour.contour import ContourFinder >>> metric = lambda s: len(s.measureOffsetMap()) >>> c = corpus.parse('bwv10.7') >>> res = ContourFinder(c).getContourValuesForMetric(metric, 3, 2, False) @@ -184,6 +186,7 @@ def getContour(self, cType, window=None, slide=None, overwrite=False, use normalized=False (the default), but to get a contour which evenly divides time between 1.0 and 100.0, use normalized=True + >>> from music21_tools.contour.contour import ContourFinder >>> cf = ContourFinder( corpus.parse('bwv10.7')) >>> mycontour = cf.getContour('dissonance') >>> [mycontour[x] for x in sorted(mycontour.keys())] # doctest: +NORMALIZE_WHITESPACE @@ -196,7 +199,7 @@ def getContour(self, cType, window=None, slide=None, overwrite=False, >>> mycontour = cf.getContour('spacing', metric = lambda x: 2, overwrite=False) Traceback (most recent call last): - contour.OverwriteException: Attempted to overwrite 'spacing' metric but did not specify overwrite=True + music21_tools.contour.contour.OverwriteException: Attempted to overwrite 'spacing' metric but did not specify overwrite=True >>> mycontour = cf.getContour('spacing', slide=3, metric = lambda x: 2.0, overwrite=True) >>> [mycontour[x] for x in sorted(mycontour.keys())] @@ -251,6 +254,7 @@ def _normalizeContour(self, contourDict, maxKey): ''' Normalize a contour dictionary so that the values of the keys range from 0.0 to length. + >>> from music21_tools.contour.contour import ContourFinder >>> mycontour = { 0.0: 1.0, 3.0: 0.5, 6.0: 0.8, 9.0: 0.3, 12.0: 0.15, ... 15.0: 0.13, 18.0: 0.4, 21.0: 0.6 } >>> res = ContourFinder()._normalizeContour(mycontour, 100) @@ -275,7 +279,7 @@ def _normalizeContour(self, contourDict, maxKey): myKeys.sort() numKeys = len(myKeys) - spacing = (maxKey) / (numKeys - 1.0) + spacing = maxKey / (numKeys - 1.0) res = {} i = 0.0 @@ -331,6 +335,7 @@ def randomize(self, contourDict): Returns a version of contourDict where the keys-to-values mapping is scrambled. + >>> from music21_tools.contour.contour import ContourFinder >>> myDict = {1:1, 2:2, 3:3, 4:4, 5:5, 6:6, 7:7, 8:8, 9:9, 10:10, 11:11, 12:12, 13:13, ... 14:14, 15:15, 16:16, 17:17, 18:18, 19:19, 20:20} >>> res = ContourFinder().randomize(myDict) @@ -388,6 +393,7 @@ def dissonanceMetric(self, inpStream): To work correctly, input must contain measures and no parts. + >>> from music21_tools.contour.contour import ContourFinder >>> c = corpus.parse('bwv102.7').chordify() >>> ContourFinder().dissonanceMetric( c.measures(1, 1) ) 0.25 @@ -423,16 +429,10 @@ def spacingForChord(chord): return self._calcGenericMetric(inpStream, spacingForChord) - def tonalDistanceMetric(self, inpStream): ''' Returns a number between 0.0 and 1.0 that is a measure of how far away the key of inpStream is from the key of ContourFinder's internal stream. - - Music21 v10's discrete analyzer now strictly raises - :class:`~music21.analysis.discrete.DiscreteAnalysisException` when a - fragment has too few pitches for Krumhansl-Schmuckler analysis to find any - candidate keys; in that case this method returns 0.5 (neutral). ''' from music21.analysis.discrete import DiscreteAnalysisException @@ -442,6 +442,7 @@ def tonalDistanceMetric(self, inpStream): try: guessedKey = inpStream.analyze('key') except DiscreteAnalysisException: + # music21 raises exception when stream has no notes. return 0.5 certainty = -2 # should be replaced by a value between -1 and 1 diff --git a/music21_tools/counterpoint/species.py b/music21_tools/counterpoint/species.py index 342690e..bc111fe 100644 --- a/music21_tools/counterpoint/species.py +++ b/music21_tools/counterpoint/species.py @@ -56,6 +56,7 @@ def findParallelFifths(self, srcStream, cmpStream): any note that has harmonic interval of a fifth and is preceded by a harmonic interval of a fifth. + >>> from music21_tools.counterpoint.species import ModalCounterpoint >>> from music21 import * >>> n1 = note.Note('G3') >>> n2 = note.Note('A3') @@ -103,6 +104,7 @@ def findHiddenFifths(self, stream1, stream2): where the two streams reach a fifth through parallel motion, but is not a parallel fifth. + >>> from music21_tools.counterpoint.species import ModalCounterpoint >>> from music21 import * >>> n1 = note.Note('G3') >>> n2 = note.Note('A3') @@ -143,6 +145,7 @@ def isParallelFifth(self, note11, note12, note21, note22): (i.e. argument order is isParallelFifth(v1n1, v1n2, v2n1, v2n2)), returns True if the two harmonic intervals are P5 and False otherwise. + >>> from music21_tools.counterpoint.species import ModalCounterpoint >>> from music21 import * >>> n1 = note.Note('G3') >>> n2 = note.Note('B-3') @@ -172,6 +175,7 @@ def isHiddenFifth(self, note11, note12, note21, note22): is isHiddenFifth(v1n1, v1n2, v2n1, v2n2)), returns True if there is a hidden fifth and false otherwise. + >>> from music21_tools.counterpoint.species import ModalCounterpoint >>> from music21 import * >>> n1 = note.Note('G3') >>> n2 = note.Note('B-3') @@ -214,6 +218,7 @@ def findParallelOctaves(self, stream1, stream2): any note that has harmonic interval of an octave and is preceded by a harmonic interval of an octave. + >>> from music21_tools.counterpoint.species import ModalCounterpoint >>> from music21 import * >>> n1 = note.Note('G3') >>> n2 = note.Note('A3') @@ -267,6 +272,7 @@ def findHiddenOctaves(self, stream1, stream2): anything where the two streams reach an octave through parallel motion, but is not a parallel octave. + >>> from music21_tools.counterpoint.species import ModalCounterpoint >>> from music21 import * >>> n1 = note.Note('F3') >>> n2 = note.Note('A3') @@ -313,6 +319,7 @@ def isParallelOctave(self, note11, note12, note21, note22): isParallelOctave(v1n1, v1n2, v2n1, v2n2)), returns True if the two harmonic intervals are P8 and False otherwise. + >>> from music21_tools.counterpoint.species import ModalCounterpoint >>> from music21 import * >>> n1 = note.Note('A3') >>> n2 = note.Note('B-3') @@ -344,6 +351,7 @@ def isHiddenOctave(self, note11, note12, note21, note22): (i.e. argument order is isHiddenOctave(v1n1, v1n2, v2n1, v2n2)) returns True if there is a hidden octave and false otherwise. + >>> from music21_tools.counterpoint.species import ModalCounterpoint >>> from music21 import * >>> n1 = note.Note('A3') >>> n2 = note.Note('B-3') @@ -384,6 +392,7 @@ def findParallelUnisons(self, stream1, stream2): assigns a flag under note.editorial["parallelUnison"] for any note that has harmonic interval of P1 and is preceded by a P1. + >>> from music21_tools.counterpoint.species import ModalCounterpoint >>> from music21 import * >>> n1 = note.Note('G4') >>> n2 = note.Note('A4') @@ -430,6 +439,7 @@ def isParallelUnison(self, note11, note12, note21, note22): isParallelFifth(v1n1, v1n2, v2n1, v2n2)) returns True if the two harmonic intervals are P1 and False otherwise. + >>> from music21_tools.counterpoint.species import ModalCounterpoint >>> from music21 import * >>> n1 = note.Note('A3') >>> n2 = note.Note('B-3') @@ -461,6 +471,7 @@ def isValidHarmony(self, note11, note21): "legal" according to 21M.301 rules of counterpoint. Legal harmonic intervals include 'P1', 'P5', 'P8', 'm3', 'M3', 'm6', and 'M6'. + >>> from music21_tools.counterpoint.species import ModalCounterpoint >>> from music21 import * >>> c = note.Note('C4') >>> d = note.Note('D4') @@ -488,6 +499,7 @@ def isValidMiddleHarmony(self, note11, note21): 'm6', and 'M6', from before. 'P4' is now included because it is legal for middle harmonies. + >>> from music21_tools.counterpoint.species import ModalCounterpoint >>> from music21 import * >>> c = note.Note('C4') >>> d = note.Note('D4') @@ -516,6 +528,7 @@ def allValidHarmony(self, stream1, stream2): include 'P1', 'P5', 'P8', 'm3', 'M3', 'm6', and 'M6'. Also assumes that final interval must be a perfect unison or octave. + >>> from music21_tools.counterpoint.species import ModalCounterpoint >>> from music21 import * >>> n1 = note.Note('G4') >>> n2 = note.Note('A4') @@ -573,6 +586,7 @@ def allValidHarmonyMiddleVoices(self, stream1, stream2): middle voices, 'P4' is also allowed and the final interval is allowed to be a fifth. + >>> from music21_tools.counterpoint.species import ModalCounterpoint >>> from music21 import * >>> n1 = note.Note('G4') >>> n2 = note.Note('A4') @@ -614,6 +628,7 @@ def countBadHarmonies(self, stream1, stream2): '''Given two simultaneous streams, counts the number of notes (in the first stream given) that create illegal harmonies when attacked. + >>> from music21_tools.counterpoint.species import ModalCounterpoint >>> from music21 import * >>> n1 = note.Note('G4') >>> n2 = note.Note('A4') @@ -649,6 +664,7 @@ def isValidStep(self, note11, note12): SHOULD BE RENAMED isValidMelody? + >>> from music21_tools.counterpoint.species import ModalCounterpoint >>> from music21 import * >>> c = note.Note('C4') >>> d = note.Note('D4') @@ -675,6 +691,7 @@ def isValidMelody(self, stream1): SHOULD BE RENAMED allValidMelody? + >>> from music21_tools.counterpoint.species import ModalCounterpoint >>> from music21 import * >>> n1 = note.Note('G-4') >>> n2 = note.Note('A4') @@ -709,6 +726,7 @@ def countBadSteps(self, stream1): SHOULD BE RENAMED countBadMelodies? + >>> from music21_tools.counterpoint.species import ModalCounterpoint >>> from music21 import * >>> n1 = note.Note('G-4') >>> n2 = note.Note('A4') @@ -746,6 +764,7 @@ def findAllBadFifths(self, stream1, stream2): and also puts the appropriate tags in note.editorial under `.parallelFifth` and `.hiddenFifth`. + >>> from music21_tools.counterpoint.species import ModalCounterpoint >>> from music21 import * >>> n1 = note.Note('C4') >>> n2 = note.Note('D4') @@ -773,6 +792,7 @@ def findAllBadOctaves(self, stream1, stream2): and also puts the appropriate tags in note.editorial under `.parallelOctave` and `.hiddenOctave`. + >>> from music21_tools.counterpoint.species import ModalCounterpoint >>> from music21 import * >>> n1 = note.Note('C4') >>> n2 = note.Note('D4') @@ -799,6 +819,7 @@ def tooManyThirds(self, stream1, stream2, limit=3): number of consecutive harmonic thirds exceeds the limit and False otherwise. + >>> from music21_tools.counterpoint.species import ModalCounterpoint >>> from music21 import * >>> n1 = note.Note('E4') >>> n2 = note.Note('F4') @@ -869,6 +890,7 @@ def tooManySixths(self, stream1, stream2, limit=3): number of consecutive harmonic sixths exceeds the limit and False otherwise. + >>> from music21_tools.counterpoint.species import ModalCounterpoint >>> from music21 import * >>> n1 = note.Note('E4') >>> n2 = note.Note('F4') @@ -938,6 +960,7 @@ def raiseLeadingTone(self, stream1, minorScale): stream that raises all the leading tones of the original stream. Also raises the sixth if applicable to avoid augmented intervals. + >>> from music21_tools.counterpoint.species import ModalCounterpoint >>> from music21 import * >>> n1 = note.Note('C4') >>> n2 = note.Note('G4') diff --git a/music21_tools/theoryAnalysis/theoryAnalyzer.py b/music21_tools/theoryAnalysis/theoryAnalyzer.py index 8af335f..13d3c4f 100644 --- a/music21_tools/theoryAnalysis/theoryAnalyzer.py +++ b/music21_tools/theoryAnalysis/theoryAnalyzer.py @@ -48,6 +48,7 @@ You can then iterate through these objects and access the attributes directly. Here is an example of this that will analyze the root motion in a score:: + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> from music21 import harmony >>> p = corpus.parse('leadsheet').flatten().getElementsByClass('Harmony').stream() >>> p = harmony.realizeChordSymbolDurations(p) @@ -209,6 +210,7 @@ def addAnalysisData(self, score): also adds to any embedded Streams... + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> p = stream.Part() >>> s = stream.Score() >>> s.insert(0, p) @@ -243,6 +245,7 @@ def getVerticalities(self, score, classFilterList=('Note', 'Chord', 'Harmony', ' to determine what vertical slices to take. Default is to return only objects of type Note, Chord, Harmony, and Rest. + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> n1 = note.Note('c5') >>> n1.quarterLength = 4 >>> n2 = note.Note('f4') @@ -345,6 +348,7 @@ def getVLQs(self, score, partNum1, partNum2): extracts and returns a list of the :class:`~music21.voiceLeading.VoiceLeadingQuartet` objects present between partNum1 and partNum2 in the score + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> part0 = stream.Part() >>> part0.append(note.Note('c4')) @@ -389,6 +393,7 @@ def getThreeNoteLinearSegments(self, score, partNum): objects present in partNum in the score (three note linear segments are made up of ONLY three notes) + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> part0 = stream.Part() >>> part0.append(note.Note('c4')) @@ -436,6 +441,7 @@ def getLinearSegments(self, score, partNum, lengthLinearSegment, classFilterList + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> part0 = stream.Part() >>> part0.append(note.Note('c4')) @@ -538,6 +544,7 @@ def getVerticalityNTuplets(self, score, ntupletNum): :class:`~music21.voiceLeading.VerticalityNTuplet` or the corresponding subclass (currently only supports triplets) + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> part0 = stream.Part() >>> part1 = stream.Part() @@ -591,6 +598,7 @@ def getHarmonicIntervals(self, score, partNum1, partNum2): returns a list of all the harmonic intervals (:class:`~music21.interval.Interval` ) occurring between the two specified parts. + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> part0 = stream.Part() >>> part0.append(note.Note('e4')) @@ -630,6 +638,7 @@ def getMelodicIntervals(self, score, partNum): returns a list of all the melodic intervals (:class:`~music21.interval.Interval`) in the specified part. + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> part0 = stream.Part() >>> part0.append(note.Note('c4')) @@ -664,6 +673,7 @@ def getNotes(self, score, partNum): returns a list of notes present in the score. If Rests are present, appends None to the list + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> p = stream.Part() >>> p.repeatAppend(note.Note('C'), 3) @@ -695,6 +705,7 @@ def getAllPartNumPairs(self, score): Gets a list of all possible pairs of partNumbers: tuples (partNum1, partNum2) where 0 <= partNum1 < partnum2 < numParts + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> part0 = stream.Part() >>> part0.append(note.Note('c5')) @@ -946,6 +957,7 @@ def identifyParallelFifths(self, score, partNum1=None, partNum2=None, color=None + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> part0 = stream.Part() >>> p0measure1 = stream.Measure(number=1) @@ -992,6 +1004,7 @@ def getParallelFifths(self, score, partNum1=None, partNum2=None): + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> part0 = stream.Part() >>> p0measure1 = stream.Measure(number=1) @@ -1040,6 +1053,7 @@ def identifyParallelOctaves(self, score, partNum1=None, partNum2=None, + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> part0 = stream.Part() >>> p0measure1 = stream.Measure(number=1) @@ -1082,6 +1096,7 @@ def getParallelOctaves(self, score, partNum1=None, partNum2=None): + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> part0 = stream.Part() >>> p0measure1 = stream.Measure(number=1) @@ -1122,6 +1137,7 @@ def identifyParallelUnisons(self, score, partNum1=None, partNum2=None, color=Non + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> part0 = stream.Part() >>> p0measure1 = stream.Measure(number=1) @@ -1174,6 +1190,7 @@ def identifyHiddenFifths(self, score, partNum1=None, partNum2=None, + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> part0 = stream.Part() >>> p0measure1 = stream.Measure(number=1) @@ -1221,6 +1238,7 @@ def identifyHiddenOctaves(self, score, partNum1=None, partNum2=None, color=None, + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> part0 = stream.Part() >>> p0measure1 = stream.Measure(number=1) @@ -1268,6 +1286,7 @@ def identifyImproperResolutions(self, score, partNum1=None, partNum2=None, color + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> part0 = stream.Part() >>> p0measure1 = stream.Measure(number=1) @@ -1317,6 +1336,7 @@ def identifyLeapNotSetWithStep(self, score, partNum1=None, partNum2=None, + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> part0 = stream.Part() >>> p0measure1 = stream.Measure(number=1) @@ -1360,6 +1380,7 @@ def identifyOpensIncorrectly(self, score, partNum1=None, partNum2=None, + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> part0 = stream.Part() >>> p0measure1 = stream.Measure(number=1) @@ -1396,6 +1417,7 @@ def identifyClosesIncorrectly(self, score, partNum1=None, partNum2=None, color=N + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> part0 = stream.Part() >>> p0measure1 = stream.Measure(number=1) @@ -1442,6 +1464,7 @@ def identifyPassingTones(self, score, partNumToIdentify=None, color=None, dictKe :class:`~music21.editorial.NoteEditorial` value of editorialValue at ``note.editorial.[editorialDictKey]`` + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> from music21 import * >>> sc = stream.Score() >>> sc.insert(0, meter.TimeSignature('2/4')) @@ -1483,6 +1506,7 @@ def getPassingTones(self, score, dictKey=None, partNumToIdentify=None, unaccente returns a list of all passing tones present in the score, as identified by :meth:`~music21.voiceLeading.VerticalityTriplet.hasPassingTone` + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> from music21 import * >>> sc = stream.Score() >>> sc.insert(0, meter.TimeSignature('2/4')) @@ -1523,6 +1547,7 @@ def getNeighborTones(self, score, dictKey=None, partNumToIdentify=None, unaccent returns a list of all passing tones present in the score, as identified by :meth:`~music21.voiceLeading.VerticalityTriplet.hasNeighborTone` + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> from music21 import * >>> sc = stream.Score() >>> sc.insert(0, meter.TimeSignature('2/4')) @@ -1564,6 +1589,7 @@ def removePassingTones(self, score, dictKey='unaccentedPassingTones'): extending note duraitons (method under development) + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> from music21 import * >>> sc = stream.Score() >>> sc.insert(0, meter.TimeSignature('2/4')) @@ -1609,6 +1635,7 @@ def removeNeighborTones(self, score, dictKey='unaccentedNeighborTones'): extending note duraitons (method under development) + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> from music21 import * >>> sc = stream.Score() >>> sc.insert(0, meter.TimeSignature('2/4')) @@ -1659,6 +1686,7 @@ def identifyNeighborTones(self, score, partNumToIdentify=None, color=None, dictK on weak beats). unaccentedOnly by default set to True + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> from music21 import * >>> sc = stream.Score() >>> sc.insert(0, meter.TimeSignature('2/4')) @@ -1709,6 +1737,7 @@ def identifyDissonantHarmonicIntervals(self, score, partNum1=None, partNum2=None + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> part0 = stream.Part() >>> p0measure1 = stream.Measure(number=1) @@ -1756,6 +1785,7 @@ def identifyImproperDissonantIntervals(self, score, partNum1=None, partNum2=None + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> part0 = stream.Part() >>> p0measure1 = stream.Measure(number=1) @@ -1832,6 +1862,7 @@ def identifyDissonantMelodicIntervals(self, score, partNum=None, color=None, + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> part0 = stream.Part() >>> p0measure1 = stream.Measure(number=1) @@ -1972,6 +2003,7 @@ def identifyTonicAndDominant(self, score, color=None, slice at offset 0, 6, and 7 in the piece, pass ``responseOffsetMap=[0, 6, 7]`` + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> part0 = stream.Part() >>> p0measure1 = stream.Measure(number=1) @@ -2075,6 +2107,7 @@ def identifyHarmonicIntervals(self, score, partNum1=None, partNum2=None, created with ``.value`` set to the string most commonly used to identify the interval (0 through 9, with A4 and d5) + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> part0 = stream.Part() >>> p0measure1 = stream.Measure(number=1) @@ -2124,6 +2157,7 @@ def identifyScaleDegrees(self, score, partNum=None, color=None, dictKey='scaleDe ''' identify all the scale degrees in the score in partNum, or if not specified ALL partNums + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> part0 = stream.Part() >>> p0measure1 = stream.Measure(number=1) @@ -2174,6 +2208,7 @@ def identifyMotionType(self, score, partNum1=None, partNum2=None, + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> part0 = stream.Part() >>> p0measure1 = stream.Measure(number=1) @@ -2250,6 +2285,7 @@ def getResultsString(self, score, typeList=None): returns string of all results found by calling all identify methods on the TheoryAnalyzer score + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> part0 = stream.Part() >>> p0measure1 = stream.Measure(number=1) @@ -2330,6 +2366,7 @@ def removeFromAnalysisData(self, score, dictKeys): you'd like removed. Pass in a list of dictKeys or just a single dictionary key. + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> sc = stream.Score() >>> ads = Analyzer() >>> ads.addAnalysisData(sc) @@ -2337,7 +2374,7 @@ def removeFromAnalysisData(self, score, dictKeys): ... 'h1':'another sample response', '5':'third sample response'} >>> ads.removeFromAnalysisData(sc, 'sampleDictKey') >>> for k in sorted(list(ads.store[sc.id]['ResultDict'].keys())): - ... print("{0}\t{1}".format(k, ads.store[sc.id]['ResultDict'][k])) + ... print("{0} {1}".format(k, ads.store[sc.id]['ResultDict'][k])) 5 third sample response h1 another sample response @@ -2386,6 +2423,7 @@ def setKeyMeasureMap(self, score, keyMeasureMap): for analysis purposes only - no key object is actually added to the score. Check the music xml to verify measure numbers; pickup measures are usually 0. + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> n1 = note.Note('c5') >>> n1.quarterLength = 4 >>> n2 = note.Note('f4') @@ -2418,6 +2456,7 @@ def getKeyAtMeasure(self, score, measureNumber): uses keyMeasureMap to return music21 key object. If keyMeasureMap not specified, returns key analysis of theory score as a whole. + >>> from music21_tools.theoryAnalysis.theoryAnalyzer import Analyzer >>> s = stream.Score() >>> ads = Analyzer() diff --git a/music21_tools/trecento/__init__.py b/music21_tools/trecento/__init__.py index 94ed108..143a0df 100644 --- a/music21_tools/trecento/__init__.py +++ b/music21_tools/trecento/__init__.py @@ -1,7 +1,8 @@ -__all__ = ['cadencebook', 'capua', 'findTrecentoFragments', 'notation', 'tonality'] +__all__ = ['cadencebook', 'capua', 'findTrecentoFragments', 'medren', 'notation', 'tonality'] from . import cadencebook from . import capua from . import findTrecentoFragments +from . import medren from . import notation from . import tonality diff --git a/music21_tools/trecento/cadencebook.py b/music21_tools/trecento/cadencebook.py index 5781e34..7d43a1a 100644 --- a/music21_tools/trecento/cadencebook.py +++ b/music21_tools/trecento/cadencebook.py @@ -40,6 +40,7 @@ class TrecentoSheet: See the specialized subclasses below, esp. BallataSheet for more details. + >>> from music21_tools.trecento.cadencebook import TrecentoSheet >>> kyrieSheet = TrecentoSheet(sheetname='kyrie') >>> for thisKyrie in kyrieSheet: ... print(thisKyrie.title) @@ -113,7 +114,7 @@ def makeWork(self, rownumber=2): Row 1 is a header, so makeWork(2) gives the first piece. - + >>> from music21_tools.trecento.cadencebook import BallataSheet >>> ballataSheet = BallataSheet() >>> b = ballataSheet.makeWork(3) >>> print(b.title) @@ -126,7 +127,7 @@ def workByTitle(self, title): ''' return the first work with TITLE in the work's title. Case insensitive - + >>> from music21_tools.trecento.cadencebook import BallataSheet >>> ballataSheet = BallataSheet() >>> farina = ballataSheet.workByTitle('farina') >>> print(farina.title) @@ -163,24 +164,18 @@ class CacciaSheet(TrecentoSheet): ''' shortcut to a worksheet containing all the caccia cadences encoded - 2011-May: none encoded. - - + >>> from music21_tools.trecento.cadencebook import CacciaSheet >>> cacciaSheet = CacciaSheet() ''' - sheetname = 'fischer_caccia' class MadrigalSheet(TrecentoSheet): ''' shortcut to a worksheet containing all the madrigal cadences encoded - 2011-May: none encoded. - - ''' sheetname = 'fischer_madr' @@ -189,11 +184,8 @@ class BallataSheet(TrecentoSheet): ''' shortcut to a worksheet containing all the ballata cadences encoded. - 2011-May: over 400 of 460 encoded; unencoded pieces are mostly fragmentary. - ''' - sheetname = 'fischer_ballata' def makeWork(self, rownumber=1): @@ -210,9 +202,9 @@ class GloriaSheet(TrecentoSheet): French, Spanish, and Italian Gloria's openings of the Et in Terra, Dominus Deus, Qui Tollis, encoded along with the ends of the Cum Sancto and Amen. - 2011-August: all encoded except some very fragmentary pieces. + >>> from music21_tools.trecento.cadencebook import GloriaSheet >>> cadenceSpreadSheet = GloriaSheet() >>> gloriaNo20 = cadenceSpreadSheet.makeWork(20) >>> incipit = gloriaNo20.incipit @@ -249,9 +241,7 @@ class GloriaSheet(TrecentoSheet): {16.0} {0.0} {2.0} - ''' - sheetname = 'gloria' def makeWork(self, rownumber=1): @@ -298,7 +288,7 @@ class TrecentoCadenceWork: test just creating an empty TrecentoCadenceWork: - + >>> from music21_tools.trecento.cadencebook import TrecentoCadenceWork >>> tcw = TrecentoCadenceWork() ''' beginSnippetPositions = [8] @@ -365,13 +355,14 @@ def asOpus(self): ''' returns all snippets as a :class:`~music21.stream.Opus` object + >>> from music21_tools.trecento.cadencebook import BallataSheet >>> deduto = BallataSheet().workByTitle('deduto') >>> deduto.title 'Deduto sey a quel' >>> dedutoScore = deduto.asOpus() >>> dedutoScore - >>> #_DOCS_SHOW dedutoScore.show('lily.png') + >>> # _DOCS_SHOW dedutoScore.show('lily.png') ''' o = stream.Opus() md = metadata.Metadata() @@ -426,7 +417,7 @@ def asScore(self): ''' returns all snippets as a score chunk - + >>> from music21_tools.trecento.cadencebook import BallataSheet >>> deduto = BallataSheet().workByTitle('deduto') >>> deduto.title 'Deduto sey a quel' @@ -497,6 +488,7 @@ def incipit(self): Returns None if the piece or timeSignature is undefined + >>> from music21_tools.trecento.cadencebook import BallataSheet >>> bs = BallataSheet() >>> accur = bs.makeWork(2) >>> accurIncipit = accur.incipit @@ -516,8 +508,7 @@ def getOtherSnippets(self): returns a list of bits of music notation that are not the actual incipits of the piece. - - + >>> from music21_tools.trecento.cadencebook import BallataSheet >>> bs = BallataSheet() >>> accur = bs.makeWork(2) >>> accurSnippets = accur.getOtherSnippets() @@ -555,7 +546,7 @@ def getSnippetAtPosition(self, snippetPosition, snippetType='end'): gets a "snippet" which is a collection of up to 3 lines of music, a timeSignature and a description of the cadence. - + >>> from music21_tools.trecento.cadencebook import BallataSheet >>> bs = BallataSheet() >>> accur = bs.makeWork(2) >>> print(accur.getSnippetAtPosition(12)) @@ -580,8 +571,7 @@ def convertBlockToStreams(self, thisBlock): :class:`~trecentoCadence.TrecentoCadenceStream` notation) and returns a list of Streams and other information - - + >>> from music21_tools.trecento.cadencebook import BallataSheet >>> block1 = ['e4 f g a', 'g4 a b cc', '', 'no-cadence', '2/4'] >>> bs = BallataSheet() >>> dummyPiece = bs.makeWork(2) @@ -681,7 +671,7 @@ def getAllStreams(self): Get all streams in the work as a List, losing association with the other polyphonic units. - + >>> from music21_tools.trecento.cadencebook import BallataSheet >>> b = BallataSheet().makeWork(20) >>> sList = b.getAllStreams() >>> sList @@ -702,6 +692,7 @@ def pmfcPageRange(self): returns a nicely formatted string giving the page numbers in PMFC where the piece can be found + >>> from music21_tools.trecento.cadencebook import BallataSheet >>> bs = BallataSheet() >>> altroCheSospirar = bs.makeWork(4) >>> altroCheSospirar.title diff --git a/music21_tools/trecento/capua.py b/music21_tools/trecento/capua.py index a0551e8..27c7ae6 100644 --- a/music21_tools/trecento/capua.py +++ b/music21_tools/trecento/capua.py @@ -59,9 +59,11 @@ def applyCapuaToCadencebookWork(thisWork): :class:`~music21.alpha.trecento.polyphonicSnippet.PolyphonicSnippet` objects (a Score subclass) + >>> from music21_tools.trecento.capua import applyCapuaToCadencebookWork, capuaFictaToAccidental + >>> from music21_tools.trecento.cadencebook import BallataSheet >>> import copy - >>> b = cadencebook.BallataSheet().makeWork(331) # Francesco, Non Creder Donna + >>> b = BallataSheet().makeWork(331) # Francesco, Non Creder Donna >>> bOrig = copy.deepcopy(b) >>> applyCapuaToCadencebookWork(b) >>> bFN = b.asScore().flatten().notes @@ -573,8 +575,10 @@ def compareThreeFictas(srcStream1, srcStream2): srcStream1 and srcStream2 should be .flatten().notesAndRests - >>> b = cadencebook.BallataSheet().makeWork(331).asScore() - >>> #_DOCS_SHOW b.show() + >>> from music21_tools.trecento.capua import applyCapuaToStream, compareThreeFictas + >>> from music21_tools.trecento.cadencebook import BallataSheet + >>> b = BallataSheet().makeWork(331).asScore() + >>> # _DOCS_SHOW b.show() >>> b0n = b.parts[0].flatten().notesAndRests.stream() >>> b1n = b.parts[1].flatten().notesAndRests.stream() >>> applyCapuaToStream(b0n) diff --git a/music21_tools/trecento/medren.py b/music21_tools/trecento/medren.py index 4364a5d..94dc21e 100644 --- a/music21_tools/trecento/medren.py +++ b/music21_tools/trecento/medren.py @@ -14,6 +14,7 @@ ''' import copy import unittest +from typing import Literal from music21 import bar from music21 import base @@ -78,6 +79,7 @@ class MensuralClef(clef.Clef): ''' An object representing a mensural clef found in medieval and Renaissance music. + >>> from music21_tools.trecento.medren import MensuralClef >>> fclef = MensuralClef('F') >>> fclef.line 3 @@ -128,6 +130,7 @@ class Mensuration(MedievalMeter): Valid values for tempus and mode are 'perfect' and 'imperfect'. Valid values for prolation and maximode are 'major' and 'minor'. + >>> from music21_tools.trecento.medren import Mensuration >>> ODot = Mensuration(tempus='perfect', prolation='major') >>> ODot.standardSymbol 'O-dot' @@ -204,6 +207,7 @@ def fontString(self): TODO: Convert to SMuFL + >>> from music21_tools.trecento.medren import Mensuration >>> O = Mensuration('imperfect', 'major') >>> O.fontString '0x4f' @@ -262,6 +266,7 @@ def __eq__(self, other): Essentially the same as music21.base.Music21Object.__eq__, but equality of mensural type is tested rather than equality of duration + >>> from music21_tools.trecento.medren import GeneralMensuralNote >>> from music21 import stream >>> m = GeneralMensuralNote('minima') @@ -279,7 +284,6 @@ def __eq__(self, other): >>> m == n True ''' - eq = hasattr(other, 'mensuralType') if eq: eq = eq and (self.mensuralType == other.mensuralType) @@ -293,10 +297,28 @@ def __eq__(self, other): eq = eq and (self.offset == other.offset) return eq - def _getMensuralType(self): + @property + def mensuralType(self): + ''' + Name of the mensural length of the general mensural note + (brevis, longa, etc.): + + >>> from music21_tools.trecento.medren import GeneralMensuralNote + >>> gmn = GeneralMensuralNote('maxima') + >>> gmn.mensuralType + 'maxima' + >>> gmn_1 = GeneralMensuralNote('SB') + >>> gmn_1.mensuralType + 'semibrevis' + >>> gmn_2 = GeneralMensuralNote('blah') + Traceback (most recent call last): + music21_tools.trecento.medren.MedRenException: blah is not a valid + mensural type or abbreviation + ''' return self._mensuralType - def _setMensuralType(self, mensuralTypeOrAbbr): + @mensuralType.setter + def mensuralType(self, mensuralTypeOrAbbr): if mensuralTypeOrAbbr in _validMensuralTypes: self._mensuralType = mensuralTypeOrAbbr elif mensuralTypeOrAbbr in _validMensuralAbbr: @@ -305,22 +327,6 @@ def _setMensuralType(self, mensuralTypeOrAbbr): raise MedRenException('%s is not a valid mensural type or abbreviation' % mensuralTypeOrAbbr) - mensuralType = property(_getMensuralType, _setMensuralType, - doc='''Name of the mensural length of the general mensural note - (brevis, longa, etc.): - - >>> gmn = GeneralMensuralNote('maxima') - >>> gmn.mensuralType - 'maxima' - >>> gmn_1 = GeneralMensuralNote('SB') - >>> gmn_1.mensuralType - 'semibrevis' - >>> gmn_2 = GeneralMensuralNote('blah') - Traceback (most recent call last): - music21_tools.trecento.medren.MedRenException: blah is not a valid - mensural type or abbreviation - ''') - def updateDurationFromMensuration(self, mensuration=None, surroundingStream=None): ''' The duration of a :class:`GeneralMensuralNote` object can be accessed @@ -338,6 +344,9 @@ def updateDurationFromMensuration(self, mensuration=None, surroundingStream=None Every time a duration is changed, the method :meth:`GeneralMensuralNote.updateDurationFromMensuration`` should be called. + >>> from music21_tools.trecento.notation import Divisione, Punctus + >>> from music21_tools.trecento import notation + >>> from music21_tools.trecento.medren import GeneralMensuralNote, MensuralNote >>> mn = GeneralMensuralNote('B') >>> mn.duration.quarterLength 0.0 @@ -348,16 +357,14 @@ def updateDurationFromMensuration(self, mensuration=None, surroundingStream=None However, if subclass is given, context (a stream) is given, and a mensuration or divisione is given, duration can be determined. - >>> from music21_tools import trecento - >>> s = stream.Stream() - >>> s.append(notation.Divisione('.p.')) + >>> s.append(Divisione('.p.')) >>> for i in range(3): ... s.append(MensuralNote('A', 'SB')) - >>> s.append(trecento.notation.Punctus()) + >>> s.append(Punctus()) >>> s.append(MensuralNote('B', 'SB')) >>> s.append(MensuralNote('B', 'SB')) - >>> s.append(trecento.notation.Punctus()) + >>> s.append(Punctus()) >>> s.append(MensuralNote('A', 'B')) >>> for mn in s: ... if isinstance(mn, GeneralMensuralNote): @@ -412,7 +419,7 @@ def _getTranslator(self, mensurationOrDivisione=None, surroundingStream=None): activeSite=surroundingStream) self._gettingDuration = True - if measure and mOrD is not None and 'Divisione' in mOrD.classes: + if measure and mOrD is not None and isinstance(mOrD, notation.Divisione): if index == 0: self.lenList = notation.BrevisLengthTranslator( mOrD, measure).getKnownLengths() @@ -436,8 +443,9 @@ def _determineMensurationOrDivisione(self): If no context is present, returns None. - >>> from music21_tools import trecento - + >>> from music21_tools.trecento.medren import Mensuration + >>> from music21_tools.trecento.notation import Divisione + >>> from music21_tools.trecento.medren import GeneralMensuralNote >>> gmn = GeneralMensuralNote('longa') >>> gmn._determineMensurationOrDivisione() >>> @@ -445,7 +453,7 @@ def _determineMensurationOrDivisione(self): >>> s_2 = stream.Stream() >>> s_3 = stream.Stream() >>> s_3.insert(3, gmn) - >>> s_2.insert(1, trecento.notation.Divisione('.q.')) + >>> s_2.insert(1, Divisione('.q.')) >>> s_1.insert(2, Mensuration('perfect', 'major')) >>> s_2.insert(2, s_3) >>> s_1.insert(3, s_2) @@ -474,10 +482,10 @@ def _getSurroundingMeasure(self, mensurationOrDivisione=None, activeSite=None): If the general mensural note has more than one context, only the surrounding measure of the first context is returned. - >>> from music21_tools import trecento - + >>> from music21_tools.trecento.medren import GeneralMensuralNote, Ligature, MensuralNote + >>> from music21_tools.trecento.notation import Divisione, Punctus >>> s_1 = stream.Stream() - >>> s_1.append(trecento.notation.Divisione('.p.')) + >>> s_1.append(Divisione('.p.')) >>> l = MensuralNote('A', 'longa') >>> s_1.append(l) >>> for i in range(4): @@ -485,7 +493,7 @@ def _getSurroundingMeasure(self, mensurationOrDivisione=None, activeSite=None): >>> gmn_1 = GeneralMensuralNote('minima') >>> s_1.append(gmn_1) >>> s_1.append(MensuralNote('C', 'minima')) - >>> s_1.append(trecento.notation.Punctus()) + >>> s_1.append(Punctus()) >>> gmn_1._getSurroundingMeasure(activeSite=s_1) ([, , @@ -495,8 +503,8 @@ def _getSurroundingMeasure(self, mensurationOrDivisione=None, activeSite=None): ], 4) >>> s_2 = stream.Stream() - >>> s_2.append(trecento.notation.Divisione('.p.')) - >>> s_2.append(trecento.notation.Punctus()) + >>> s_2.append(Divisione('.p.')) + >>> s_2.append(Punctus()) >>> s_2.append(MensuralNote('A', 'semibrevis')) >>> s_2.append(MensuralNote('B', 'semibrevis')) >>> gmn_2 = GeneralMensuralNote('semibrevis') @@ -536,14 +544,14 @@ def _getSurroundingMeasure(self, mensurationOrDivisione=None, activeSite=None): for i in range(currentIndex - 1, -1, -1): # Punctus and ligature marks indicate a new measure - if (('Punctus' in tempList[i].classes) or - ('Ligature' in tempList[i].classes)): + if ((isinstance(tempList[i], notation.Punctus)) or + (isinstance(tempList[i], Ligature))): indOffset = i + 1 break - elif 'GeneralMensuralNote' in tempList[i].classes: + elif isinstance(tempList[i], GeneralMensuralNote): # In Italian notation, brevis, longa, and maxima indicate a new measure if (mOrD is not None - and 'Divisione' in mOrD.classes + and isinstance(mOrD, notation.Divisione) and tempList[i].mensuralType in ['brevis', 'longa', 'maxima']): indOffset = i + 1 break @@ -555,12 +563,12 @@ def _getSurroundingMeasure(self, mensurationOrDivisione=None, activeSite=None): mList.reverse() mList.insert(currentIndex, self) for j in range(currentIndex + 1, len(tempList), 1): - if (('Punctus' in tempList[j].classes) or - ('Ligature' in tempList[j].classes)): + if ((isinstance(tempList[j], notation.Punctus)) or + (isinstance(tempList[j], Ligature))): break - if 'GeneralMensuralNote' in tempList[j].classes: + if isinstance(tempList[j], GeneralMensuralNote): if (mOrD is not None - and 'Divisione' in mOrD.classes + and isinstance(mOrD, notation.Divisione) and tempList[j].mensuralType in ['brevis', 'longa', 'maxima']): break else: @@ -620,6 +628,7 @@ def fontString(self): TODO: Replace w/ SMuFL + >>> from music21_tools.trecento.medren import MensuralRest >>> mr = MensuralRest('SB') >>> mr.fontString '0x32' @@ -687,6 +696,10 @@ def __eq__(self, other): Only pitch is shown as a test. For other cases, please see the docs for :meth:``music21.GeneralMensuralNote.__eq__`` + >>> from music21_tools import trecento + >>> from music21_tools.trecento.medren import MensuralNote + >>> from music21_tools.trecento.notation import Divisione + >>> from music21_tools.trecento import notation >>> m = MensuralNote('A', 'minima') >>> n = MensuralNote('B', 'minima') >>> m == n @@ -726,6 +739,7 @@ def fontString(self): TODO: Replace with SMuFL + >>> from music21_tools.trecento.medren import MensuralNote >>> mn = MensuralNote('A', 'M') >>> mn.setStem('down') >>> mn.fontString @@ -786,9 +800,9 @@ def fontString(self): return self._fontString - - def _setMensuralType(self, mensuralTypeOrAbbr): - GeneralMensuralNote._setMensuralType(self, mensuralTypeOrAbbr) + @GeneralMensuralNote.mensuralType.setter + def mensuralType(self, mensuralTypeOrAbbr): + GeneralMensuralNote.mensuralType.fset(self, mensuralTypeOrAbbr) if self.mensuralType in ['minima', 'semiminima']: self.stems = ['up'] @@ -799,10 +813,6 @@ def _setMensuralType(self, mensuralTypeOrAbbr): if self._mensuralType == 'semiminima': self.flags['up'] = 'right' - mensuralType = property(GeneralMensuralNote._getMensuralType, _setMensuralType, - doc=''' See documentation in `music21.GeneralMensuralType`''') - - def getNumDots(self): ''' Used for French notation. Not yet implemented @@ -828,6 +838,7 @@ def setStem(self, direction): have a side stem, and vice versa). Setting stem direction to None removes all but the default number of stems. + >>> from music21_tools.trecento.medren import MensuralNote >>> r_1 = MensuralNote('A', 'brevis') >>> r_1.setStem('down') Traceback (most recent call last): @@ -910,6 +921,7 @@ def setFlag(self, stemDirection, orientation): but may be set to 'left'. Any note with a downstem may also have a flag on that stem. + >>> from music21_tools.trecento.medren import MensuralNote >>> r_1 = MensuralNote('A', 'minima') >>> r_1.setFlag('up', 'right') Traceback (most recent call last): @@ -934,7 +946,6 @@ def setFlag(self, stemDirection, orientation): Traceback (most recent call last): music21_tools.trecento.medren.MedRenException: a flag cannot be added to a stem with direction side ''' - if stemDirection == 'up': if self.mensuralType != 'semiminima': raise MedRenException('a flag may not be added to an upstem of note type %s' % @@ -1029,6 +1040,7 @@ class Ligature(base.Music21Object): The ligatures outlined in blue would be constructed as follows: + >>> from music21_tools.trecento.medren import Ligature >>> l1 = Ligature(['A4', 'F4', 'G4', 'A4', 'B-4']) >>> l1.makeOblique(0) >>> l1.setStem(0, 'down', 'left') @@ -1044,7 +1056,6 @@ class Ligature(base.Music21Object): Note that ligatures cannot be displayed yet. ''' - def __init__(self, pitches=None, color='black', filled='yes'): super().__init__() self.noteheadShape = None @@ -1085,6 +1096,7 @@ def notes(self): ''' Returns the ligature as a list of mensural notes + >>> from music21_tools.trecento.medren import Ligature >>> l = Ligature(['A4', 'B4']) >>> print([n.mensuralType for n in l.notes]) ['brevis', 'brevis'] @@ -1174,6 +1186,7 @@ def setColor(self, value, index=None): Sets the color of note at index to value. If no index is specified, or index is set to None, every note in the ligature is given value as a color. + >>> from music21_tools.trecento.medren import Ligature >>> l = Ligature(['A4', 'C5', 'B4']) >>> l.setColor('red') >>> l.getColor() @@ -1227,6 +1240,7 @@ def setFillStatus(self, value, index=None): To set a notehead as filled, value should be 'yes' or 'filled'. To set a notehead as empty, value should be 'no' or 'empty' . + >>> from music21_tools.trecento.medren import Ligature >>> l = Ligature(['A4', 'C5', 'B4']) >>> l.setFillStatus('filled') >>> l.getFillStatus() @@ -1279,6 +1293,7 @@ def makeOblique(self, startIndex): Note that an oblique notehead cannot start on the last note of a ligature. Also, a note that is a maxima cannot be the start or end of an oblique notehead. + >>> from music21_tools.trecento.medren import Ligature >>> l = Ligature(['A4', 'C5', 'B4', 'A4']) >>> l.makeOblique(1) >>> l.getNoteheadShape(1) @@ -1319,6 +1334,7 @@ def makeSquare(self, index): If the note at index is part of an oblique notehead, all other notes that are part of that notehead are also set to have square noteheads. + >>> from music21_tools.trecento.medren import Ligature >>> l = Ligature(['A4', 'C5', 'B4', 'A4']) >>> l.makeOblique(1) >>> l.makeSquare(2) @@ -1362,6 +1378,8 @@ def setMaxima(self, index, value): A note cannot be a maxima if that note has a stem. A note cannot be a maxima if the previous note has an up-stem. + >>> from music21_tools import trecento + >>> from music21_tools.trecento.medren import Ligature >>> l = Ligature(['A4', 'C5', 'B4']) >>> l.setStem(0, 'up', 'left') >>> l.setMaxima(2, True) @@ -1429,6 +1447,7 @@ def setStem(self, index, direction, orientation): Finally, a stem cannot be set on a note that is a maxima. An up-stem cannot be set on a note preceding a maxima. + >>> from music21_tools.trecento.medren import Ligature >>> l = Ligature(['A4', 'C5', 'B4', 'A4', 'B4']) >>> l.setStem(0, 'none', 'left') Traceback (most recent call last): @@ -1534,6 +1553,7 @@ def setReverse(self, endIndex, value): A reversed note is displayed directly on top of the preceeding note in the ligature. + >>> from music21_tools.trecento.medren import Ligature >>> l = Ligature(['A4', 'C5', 'F5', 'F#5']) >>> l.setStem(1, 'down', 'left') >>> l.setStem(2, 'down', 'left') @@ -1687,6 +1707,9 @@ def breakMensuralStreamIntoBrevisLengths(inpStream, inpMOrD=None, printUpdates=F Otherwise, this causes a inconsistency when converting the stream. + >>> from music21_tools.trecento.medren import ( + ... GeneralMensuralNote, MensuralNote, breakMensuralStreamIntoBrevisLengths) + >>> from music21_tools.trecento.notation import Divisione, Punctus >>> s = stream.Score() >>> p = stream.Part() >>> m = stream.Measure() @@ -1694,36 +1717,35 @@ def breakMensuralStreamIntoBrevisLengths(inpStream, inpMOrD=None, printUpdates=F >>> s.append(GeneralMensuralNote('B')) >>> breakMensuralStreamIntoBrevisLengths(s) Traceback (most recent call last): - music21_tools.trecento.medren.MedRenException: cannot combine objects - of type , - within stream + music21_tools.trecento.medren.MedRenException: + cannot combine objects of type , + within stream >>> s = stream.Score() >>> p.append(s) >>> breakMensuralStreamIntoBrevisLengths(p) Traceback (most recent call last): - music21_tools.trecento.medren.MedRenException: Hierarchy of - violated by + music21_tools.trecento.medren.MedRenException: + Hierarchy of + violated by - >>> from music21_tools.trecento import notation >>> p = stream.Part() >>> m.append(MensuralNote('G', 'B')) - >>> p.append(notation.Divisione('.q.')) + >>> p.append(Divisione('.q.')) >>> p.repeatAppend(MensuralNote('A', 'SB'),2) - >>> p.append(notation.Punctus()) + >>> p.append(Punctus()) >>> p.repeatAppend(MensuralNote('B', 'M'),4) - >>> p.append(notation.Punctus()) + >>> p.append(Punctus()) >>> p.append(MensuralNote('C', 'B')) - >>> s.append(notation.Divisione('.p.')) + >>> s.append(Divisione('.p.')) >>> s.append(p) >>> s.append(m) >>> breakMensuralStreamIntoBrevisLengths(s, printUpdates = True) Traceback (most recent call last): - music21_tools.trecento.medren.MedRenException: Mensuration or divisione - <...Divisione .q.> not consistent within hierarchy + music21_tools.trecento.medren.MedRenException: Mensuration or divisione <...Divisione .q.> not consistent within hierarchy >>> s = stream.Stream() - >>> s.append(notation.Divisione('.q.')) + >>> s.append(Divisione('.q.')) >>> s.append(p) >>> s.append(m) >>> t = breakMensuralStreamIntoBrevisLengths(s, printUpdates = True) @@ -1745,7 +1767,6 @@ def breakMensuralStreamIntoBrevisLengths(inpStream, inpMOrD=None, printUpdates=F {0.0} {0.0} <...MensuralNote brevis G> ''' - mOrD = inpMOrD mOrDInAsNone = True if mOrD is not None: @@ -1754,7 +1775,7 @@ def breakMensuralStreamIntoBrevisLengths(inpStream, inpMOrD=None, printUpdates=F inpStream_copy = copy.deepcopy(inpStream) # Preserve your input newStream = inpStream.__class__() - def isHigherInhierarchy(lower, upper): + def isHigherInHierarchy(lower, upper): hierarchy = ['Stream', 'Score', 'Part', 'Measure'] upperClass = None for tryClass in upper.classes: @@ -1768,7 +1789,6 @@ def isHigherInhierarchy(lower, upper): lowerClass = tryClass break - if upperClass is None: raise MedRenException('Cannot find class in our hierarchy of streams: %s' % (upper)) if lowerClass is None: @@ -1789,7 +1809,7 @@ def isHigherInhierarchy(lower, upper): for item in tempStream_2: newStream.append(item) - if ('Mensuration' in item.classes) or ('Divisione' in item.classes): + if isinstance(item, (Mensuration, notation.Divisione)): if mOrDInAsNone: # If first case or changed mOrD mOrD = item elif mOrD.standardSymbol != item.standardSymbol: @@ -1799,7 +1819,7 @@ def isHigherInhierarchy(lower, upper): tempStream_1_1, tempStream_1_2 = tempStream_1.splitByClass( None, - lambda x: isHigherInhierarchy(x, tempStream_1)) + lambda x: isHigherInHierarchy(x, tempStream_1)) if tempStream_1_1: raise MedRenException('Hierarchy of %s violated by %s' % (tempStream_1.__class__, tempStream_1_1[0].__class__)) @@ -1818,22 +1838,22 @@ def isHigherInhierarchy(lower, upper): for e in inpStream_copy: - if 'MensuralClef' in e.classes: + if isinstance(e, MensuralClef): newStream.append(e) - elif ('Mensuration' in e.classes) or ('Divisione' in e.classes): + elif isinstance(e, (Mensuration, notation.Divisione)): if mOrDInAsNone: # If first case or changed mOrD mOrD = e newStream.append(e) elif mOrD.standardSymbol != e.standardSymbol: # If higher, different mOrD found raise MedRenException( 'Mensuration or divisione %s not consistent within hierarchy' % e) - elif 'Ligature' in e.classes: + elif isinstance(e, Ligature): tempStream = stream.Stream() for mn in e.notes: tempStream.append(mn) for m in breakMensuralStreamIntoBrevisLengths(tempStream, printUpdates): newStream.append(m) - elif ('GeneralMensuralNote' in e.classes) and (e not in mensuralMeasure): + elif (isinstance(e, GeneralMensuralNote)) and (e not in mensuralMeasure): m = stream.Measure(number=measureNum) if printUpdates is True: print('Getting measure %s...' % measureNum) @@ -1859,11 +1879,11 @@ def setBarlineStyle(score, newStyle, oldStyle='regular', *, inPlace=False): returns the Score object. ''' - if inPlace is False: + if not inPlace: score = copy.deepcopy(score) oldStyle = oldStyle.lower() - for m in score.semiFlat: + for m in score.flatten(retainContainers=True): if isinstance(m, stream.Measure): barline = m.rightBarline if barline is None: @@ -1890,7 +1910,7 @@ def scaleDurations(score, scalingNum: int|float = 1, *, inPlace=False, scaleUnli el.duration.linked is False and scaleUnlinked is True): raise MedRenException('scale unlinked is not yet supported') - if isinstance(el, tempo.MetronomeMark): + if isinstance(el, tempo.MetronomeMark) and el.number is not None: el.number = el.number * scalingNum elif isinstance(el, meter.TimeSignature): newNum = el.numerator @@ -1904,7 +1924,7 @@ def scaleDurations(score, scalingNum: int|float = 1, *, inPlace=False, scaleUnli raise MedRenException( 'cannot create a scaling of the TimeSignature for this ratio') newDem = int(newDem) - el.loadRatio(newNum, newDem) + el.load(f'{newNum}/{newDem}') for p in score.parts: p.makeBeams(inPlace=True) @@ -1954,19 +1974,19 @@ def transferTies(score, *, inPlace=False): tiedEl.style.hideObjectOnPrint = True tiedNotes = [] - if inPlace is False: + if not inPlace: return score -def convertHouseStyle(score, durationScale=2, barlineStyle='tick', - tieTransfer=True, inPlace=False): +def convertHouseStyle(score, + durationScale: int|float|Literal[False] = 2, + barlineStyle: str|Literal[False] = 'tick', + tieTransfer: bool = True, + inPlace: bool = False): ''' The method :meth:`convertHouseStyle` takes a score, durationScale, barlineStyle, tieTransfer, and inPlace as arguments. Of these, only score is not optional. - Default values for durationScale, barlineStyle, tieTransfer, and inPlace are - 2, 'tick', True, and False respectively. - Changing :attr:`convertHouseStyle.barlineStyle` changes how the barlines are displayed within the piece. @@ -1983,12 +2003,11 @@ def convertHouseStyle(score, durationScale=2, barlineStyle='tick', and with the barline style set to 'tick'. The circled area shows a space left blank due to tieTransfer being True. - + >>> from music21_tools.trecento.medren import convertHouseStyle >>> from music21 import corpus >>> gloria = corpus.parse('luca/gloria') >>> # _DOCS_HIDE gloria.show() - .. image:: images/medren_convertHouseStyle_1.* :width: 600 @@ -1999,14 +2018,13 @@ def convertHouseStyle(score, durationScale=2, barlineStyle='tick', .. image:: images/medren_convertHouseStyle_2.* :width: 600 ''' - - if inPlace is False: + if not inPlace: score = copy.deepcopy(score) if durationScale is not False: scaleDurations(score, durationScale, inPlace=True) if barlineStyle is not False: setBarlineStyle(score, barlineStyle, inPlace=True) - if tieTransfer is not False: + if tieTransfer: transferTies(score, inPlace=True) return score @@ -2024,7 +2042,7 @@ def cummingSchubertStrettoFuga(score): thisGeneric = thisInt.generic.directed for strettoType in [8, -8, 5, -5, 4, -4]: strettoAllowed = [x[0] for x in allowableStrettoIntervals[strettoType]] - # inefficent but who cares + # inefficient repeatAllowed = [x[1] for x in allowableStrettoIntervals[strettoType]] for j in range(len(strettoAllowed)): thisStrettoAllowed = strettoAllowed[j] @@ -2047,7 +2065,6 @@ class MedRenException(exceptions21.Music21Exception): pass class Test(unittest.TestCase): - def runTest(self): pass @@ -2083,7 +2100,7 @@ def xtestUnlinked(self): n1.duration.quarterLength = 2.0 s.append([n1, n2]) - def xtestPythagSharps(self): + def xtestPythagoreanSharps(self): from music21 import corpus, midi gloria = corpus.parse('luca/gloria') p = gloria.parts[0].flatten() @@ -2106,9 +2123,11 @@ def testHouseStyle(self): def testStretto(): from music21 import converter - salve = converter.parse('A4 A G A D A G F E F G F E D', '4/4') # salveRegina liber p. 276 - adTe = converter.parse('D4 F A G G F A E G F E D G C D E D G F E D', '4/4') # ad te clamamus - etJesum = converter.parse('D4 AA C D D D E E D D C G F E D G F E D C D', '4/4') + # salveRegina liber p. 276 + salve = converter.parse('tinyNotation: 4/4 A4 A G A D A G F E F G F E D') + # ad te clamamus + adTe = converter.parse('tinyNotation: 4/4 D4 F A G G F A E G F E D G C D E D G F E D') + etJesum = converter.parse('tinyNotation: 4/4 D4 AA C D D D E E D D C G F E D G F E D C D') salve.title = 'Salve Regina (opening)LU p. 276' adTe.title = '...ad te clamamus' etJesum.title = '...et Jesum' diff --git a/music21_tools/trecento/notation.py b/music21_tools/trecento/notation.py index 05f41c8..7f09302 100644 --- a/music21_tools/trecento/notation.py +++ b/music21_tools/trecento/notation.py @@ -26,7 +26,9 @@ from music21 import common from music21 import duration from music21 import exceptions21 +from music21 import metadata from music21 import meter +from music21 import text from ._base import MedievalMeter from music21 import note @@ -243,6 +245,8 @@ class TrecentoTinyConverter(tinyNotation.Converter): If no mensural type is specified, it is assumed to be the same as the previous note. I.e., c(SB) B c d is a string of semibreves. + >>> from music21_tools.trecento.medren import Ligature + >>> from music21_tools.trecento.notation import TrecentoTinyConverter >>> tTNN = TrecentoTinyConverter('a(M)').parse().stream.flatten().notes[0] >>> tTNN.pitch @@ -258,11 +262,11 @@ class TrecentoTinyConverter(tinyNotation.Converter): :meth:`music21.medren.MensuralNote.setStem()`. >>> tTNN = TrecentoTinyConverter( - ... 'a(SB)[S]').parse().stream.flatten().notes[0] + ... 'a(SB)[S]').parse().stream.recurse().notes.first >>> tTNN.getStems() ['side'] - >>> tTNN = TrecentoTinyConverter('a(M)[D]').parse().stream.flatten().notes[0] + >>> tTNN = TrecentoTinyConverter('a(M)[D]').parse().stream.recurse().notes.first >>> tTNN.getStems() ['up', 'down'] @@ -274,7 +278,7 @@ class TrecentoTinyConverter(tinyNotation.Converter): follow the rules outlined in :meth:`music21.medren.MensuralNote.setFlag()`. >>> tTNN = TrecentoTinyConverter( - ... 'a(SM)_UL').parse().stream.flatten().notes[0] + ... 'a(SM)_UL').parse().stream.recurse().notes.first >>> tTNN.getStems() ['up'] @@ -288,7 +292,7 @@ class TrecentoTinyConverter(tinyNotation.Converter): direction-orientation pairs, as shown in the following complex example: >>> tTNN = TrecentoTinyConverter( - ... 'a(SM)[D]_UL/DR').parse().stream.flatten().notes[0] + ... 'a(SM)[D]_UL/DR').parse().stream.recurse().notes.first >>> tTNN.pitch >>> tTNN.getStems() @@ -312,11 +316,11 @@ class TrecentoTinyConverter(tinyNotation.Converter): {0.0} {0.0} {0.0} - {0.0} + {0.0} {0.0} - >>> tTNN = ts.flatten().getElementsByClass('Ligature')[0] + >>> tTNN = ts[Ligature].first >>> tTNN - + >>> [str(p) for p in tTNN.pitches] ['F4', 'G4', 'A4', 'G4', 'F4', 'C4'] @@ -333,7 +337,7 @@ class TrecentoTinyConverter(tinyNotation.Converter): Examples: >>> ts = TrecentoTinyConverter(r'lig{f a[DL]=R}').parse().stream - >>> tTNN = ts.flatten().getElementsByClass('Ligature')[0] + >>> tTNN = ts[Ligature].first >>> tTNN.getStem(1) ('down', 'left') @@ -342,7 +346,7 @@ class TrecentoTinyConverter(tinyNotation.Converter): >>> tTNN = TrecentoTinyConverter( - ... 'lig{f g a[UR] g f(Mx)}').parse().stream.flatten().getElementsByClass('Ligature')[0] + ... 'lig{f g a[UR] g f(Mx)}').parse().stream[Ligature].first >>> print([n.mensuralType for n in tTNN.notes]) ['longa', 'brevis', 'semibrevis', 'semibrevis', 'maxima'] @@ -363,7 +367,7 @@ class TrecentoTinyConverter(tinyNotation.Converter): ... '$C3 .p. c(SB) d e p d(B) lig{e d c}').parse().stream.flatten() >>> tTNS.show('text') {0.0} - {0.0} + {0.0} <...MensuralClef> {0.0} <...Divisione .p.> {0.0} <...medren.MensuralNote semibrevis C> {0.0} <...medren.MensuralNote semibrevis D> @@ -447,6 +451,7 @@ class Divisione(MedievalMeter): The corresponding symbols are '.q.', '.i.', '.p.', '.n.', '.o.', and '.d.'. + >>> from music21_tools.trecento.notation import Divisione >>> d = Divisione('senaria imperfecta') >>> d.standardSymbol '.i.' @@ -540,6 +545,8 @@ def convertTrecentoStream(inpStream, inpDiv=None): Anonymous, Se per dureça. Padua, Biblioteca Universitaria, MS 1115. Folio Ar. + >>> from music21 import stream + >>> from music21_tools.trecento.notation import TrecentoTinyConverter, convertTrecentoStream >>> upperString = ".p. $C1 g(B) g(M) f e g f e p g(SB) f(SM) e d e(M) f p " >>> upperString += "e(SB) e(SM) f e d(M) c p " >>> upperString += "d(SB) r e p f(M) e d e d c p d(SB) c(M) d c d p e(SB) r(M) " @@ -581,49 +588,44 @@ def convertTrecentoStream(inpStream, inpDiv=None): :width: 600 ''' - div = inpDiv - offset = 0 - # hierarchy = ['measure', 'part', 'score'] - - convertedStream: stream.Stream - if 'measure' in inpStream.classes: - convertedStream = stream.Measure() - elif 'part' in inpStream.classes: + # Find a divisione (recursively if needed); fail loudly if none exists. + div = inpDiv or inpStream[Divisione].first() + if div is None: + raise TrecentoNotationException( + f'No divisione found in {inpStream}; cannot convert to modern notation.') + + # Mirror the type of the input where possible (Measure/Part/Score), + # otherwise produce a plain Stream. + if isinstance(inpStream, stream.Measure): + convertedStream: stream.Stream = stream.Measure() + elif isinstance(inpStream, stream.Part): convertedStream = stream.Part() - elif 'score' in inpStream.classes: - convertedStream = stream.Measure() + elif isinstance(inpStream, stream.Score): + convertedStream = stream.Score() else: convertedStream = stream.Stream() - measuredStream = medren.breakMensuralStreamIntoBrevisLengths(inpStream, inpDiv) + measuredStream = medren.breakMensuralStreamIntoBrevisLengths(inpStream, div) print('') - for e in measuredStream: - - if ('Metadata' in e.classes) or ('TextBox' in e.classes): # Formatting - convertedStream.append(e) - - elif 'MensuralClef' in e.classes: - pass - - elif 'Divisione' in e.classes: - div = e - - elif e.isMeasure: - print(' Converting measure %s' % e.number) - measureList = convertBrevisLength(e, convertedStream, - inpDiv=div, measureNumOffset=offset) - for m in measureList: - convertedStream.append(m) - - elif e.isStream: - print('Converting stream %s' % e) - convertedPart = convertTrecentoStream(e, inpDiv = div) - convertedStream.insert(0, convertedPart) - - else: - raise medren.MedRenException( - 'Object %s cannot be processed as part of a trecento stream' % e) + # Preserve formatting elements. + for fmt_el in measuredStream[metadata.Metadata]: + convertedStream.append(fmt_el) + for fmt_el in measuredStream[text.TextBox]: + convertedStream.append(fmt_el) + + # Convert measures (one or more modern Measures per mensural brevis-length). + for measureEl in measuredStream.getElementsByClass(stream.Measure): + print(f' Converting measure {measureEl.number}') + for m in convertBrevisLength(measureEl, convertedStream, + inpDiv=div, measureNumOffset=0): + convertedStream.append(m) + + # Recurse on nested non-Measure streams (Parts, sub-Scores, etc). + for subStream in measuredStream: + if isinstance(subStream, stream.Stream) and not isinstance(subStream, stream.Measure): + print(f'Converting stream {subStream}') + convertedStream.insert(0, convertTrecentoStream(subStream, inpDiv=div)) return convertedStream @@ -646,21 +648,26 @@ def convertBrevisLength(brevisLength, convertedStream, inpDiv=None, measureNumOf rem = None measureList = [] - mList = list(brevisLength.recurse())[1:] + # .recurse() does not include the host stream (skipSelf default flipped + # to True in music21 v5.5), so a `[1:]` here would silently drop a real + # element (typically the first note). Take the recurse output as-is. + mList = list(brevisLength.recurse()) + + # Resolve the Divisione for this measure. Only one source is allowed: + # either the enclosing context (inpDiv) OR an in-measure Divisione, not both. + divs = list(brevisLength[Divisione]) + if len(divs) > 1 or (divs and inpDiv is not None): + offending = divs[0] if inpDiv is None else inpDiv + raise TrecentoNotationException( + f'divisione {offending} not consistent within hierarchy') + # Should already be caught by medren.breakMensuralStreamIntoBrevisLengths, + # but just in case... + if div is None and divs: + div = divs[0] tempTBL = BrevisLengthTranslator(div, mList) lenList = tempTBL.getKnownLengths() - - for item in mList: - if 'Divisione' in item.classes: - if div is None: - div = item - else: - raise TrecentoNotationException( - 'divisione %s not consistent within heirarchy' % item) - # Should already be caught by medren.breakMensuralStreamIntoBrevisLengths, - # but just in case... mDur = 0 if div is not None: rem = div.barDuration.quarterLength @@ -676,6 +683,11 @@ def convertBrevisLength(brevisLength, convertedStream, inpDiv=None, measureNumOf else: raise TrecentoNotationException('Cannot find or determine or divisione') + if not lenList: + # Empty measure (e.g. one that contained only a Divisione/Clef and no + # mensural notes); nothing to convert. + return measureList + if lenList[0] > div.minimaPerBrevis: # Longa, Maxima startNote = note.Note(mList[0].pitch) startNote.duration = div.barDuration @@ -703,9 +715,9 @@ def convertBrevisLength(brevisLength, convertedStream, inpDiv=None, measureNumOf else: for i in range(len(mList)): - if 'MensuralRest' in mList[i].classes: + if isinstance(mList[i], medren.MensuralRest): n = note.Rest() - elif 'MensuralNote' in mList[i].classes: + elif isinstance(mList[i], medren.MensuralNote): n = note.Note(mList[i].pitch) dur = lenList[i] * mDur @@ -789,7 +801,7 @@ def __init__(self, divisione=None, BL=None, pDS=False): self.hasLastSB = None def getKnownLengths(self): - if 'Divisione' in self.div.classes: + if isinstance(self.div, Divisione): self.knownLengthsList = self.translate() else: raise TrecentoNotationException('%s not recognized as divisione' % self.div) @@ -808,15 +820,16 @@ def getBreveStrength(self, lengths): and see that the second is more logical. Note that the strength itself is meaningless except when compared to other possible lengths for the same notes. + >>> from music21_tools.trecento.medren import MensuralNote + >>> from music21_tools.trecento.notation import BrevisLengthTranslator, Divisione >>> div = Divisione('.n.') >>> names = ['SB', 'M', 'M', 'M', 'SB'] - >>> BL = [medren.MensuralNote('A', n) for n in names] + >>> BL = [MensuralNote('A', n) for n in names] >>> TBL = BrevisLengthTranslator(div, BL) >>> TBL.getBreveStrength([2.0, 1.0, 1.0, 1.0, 4.0]) 2.0555... >>> TBL.getBreveStrength([3.0, 1.0, 1.0, 1.0, 3.0]) 2.8333... - ''' div = self.div BL = self.brevisLength @@ -898,14 +911,18 @@ def determineStrongestMeasureLengths(self, :param shrinkable_indices: tuple of indices of elements able to take up slack (i.e. ending SB, or downstem SB) + >>> from music21_tools.trecento.medren import MensuralNote + >>> from music21_tools.trecento.notation import BrevisLengthTranslator, Divisione >>> div = Divisione('.n.') >>> names = ['SB', 'M', 'M', 'M', 'SB'] - >>> BL = [medren.MensuralNote('A', n) for n in names] + >>> BL = [MensuralNote('A', n) for n in names] >>> TBL = BrevisLengthTranslator(div, BL) - >>> TBL.determineStrongestMeasureLengths([2.0, 1.0, 1.0, 1.0, 4.0], - ... ([0],), (1,), (1.0,), 0.0, shrinkable_indices=(-1,)) + >>> TBL.determineStrongestMeasureLengths( + ... [2.0, 1.0, 1.0, 1.0, 4.0], + ... ([0],), (1,), (1.0,), + ... 0.0, + ... shrinkable_indices=(-1,)) ([3.0, 1.0, 1.0, 1.0, 3.0], 0.0) - ''' if not (len(change_tup) == len(num_tup)) and (len(change_tup) == len(diff_tup)): raise Exception( @@ -954,7 +971,6 @@ def determineStrongestMeasureLengths(self, remain = lenRem return lengths, lenRem_final - def getUnchangeableNoteLengths(self): ''' takes the music in self.brevisLength and returns a list where element i in this list @@ -962,31 +978,32 @@ def getUnchangeableNoteLengths(self): cannot be determined without taking into account the context (e.g., semiminims, semibreves) then None is placed in that list. + >>> from music21_tools.trecento.medren import MensuralNote + >>> from music21_tools.trecento.notation import BrevisLengthTranslator, Divisione >>> div = Divisione('.i.') >>> names = ['SB', 'M', 'SB'] - >>> BL = [medren.MensuralNote('A', n) for n in names] + >>> BL = [MensuralNote('A', n) for n in names] >>> TBL = BrevisLengthTranslator(div, BL) >>> TBL.getUnchangeableNoteLengths() [None, 1.0, None] >>> names = ['B'] - >>> BL = [medren.MensuralNote('A', n) for n in names] + >>> BL = [MensuralNote('A', n) for n in names] >>> TBL = BrevisLengthTranslator(div, BL) >>> TBL.getUnchangeableNoteLengths() [6.0] >>> names = ['L'] - >>> BL = [medren.MensuralNote('A', n) for n in names] + >>> BL = [MensuralNote('A', n) for n in names] >>> TBL = BrevisLengthTranslator(div, BL) >>> TBL.getUnchangeableNoteLengths() [12.0] >>> names = ['Mx'] - >>> BL = [medren.MensuralNote('A', n) for n in names] + >>> BL = [MensuralNote('A', n) for n in names] >>> TBL = BrevisLengthTranslator(div, BL) >>> TBL.getUnchangeableNoteLengths() [24.0] - ''' unchangeableNoteLengthsList = [] for obj in self.brevisLength: @@ -1001,12 +1018,11 @@ def getUnchangeableNoteLengths(self): elif obj.mensuralType == 'brevis': minimaLength = float(self.div.minimaPerBrevis) else: - objC = obj.classes - if 'GeneralMensuralNote' not in objC: + if not isinstance(obj, medren.GeneralMensuralNote): continue # Dep on div if obj.mensuralType == 'semibrevis': - if 'MensuralRest' in obj.classes: + if isinstance(obj, medren.MensuralRest): if self.div.standardSymbol in ['.q.', '.i.']: minimaLength = self.div.minimaPerBrevis / 2.0 elif self.div.standardSymbol in ['.p.', '.n.']: @@ -1019,9 +1035,9 @@ def getUnchangeableNoteLengths(self): else: # Who the heck knows a semibreve's length!!! :-) pass elif obj.mensuralType == 'minima': - if 'MensuralNote' in obj.classes and 'down' in obj.stems: + if isinstance(obj, medren.MensuralNote) and 'down' in obj.stems: raise TrecentoNotationException('Dragmas currently not supported') - elif 'MensuralNote' in obj.classes and 'side' in obj.stems: + elif isinstance(obj, medren.MensuralNote) and 'side' in obj.stems: minimaLength = 1.5 else: minimaLength = 1.0 @@ -1037,9 +1053,11 @@ def classifyUnknownNotesByType(self, unchangeableNoteLengthsList): and the values are a list of indices in self.brevisLength (and unchangeableNoteLengthsList) which are those types... + >>> from music21_tools.trecento.medren import MensuralNote + >>> from music21_tools.trecento.notation import BrevisLengthTranslator, Divisione >>> div = Divisione('.n.') >>> names = ['SB', 'M', 'M', 'M', 'SB', 'M'] - >>> BL = [medren.MensuralNote('A', n) for n in names] + >>> BL = [MensuralNote('A', n) for n in names] >>> TBL = BrevisLengthTranslator(div, BL) >>> unchangeableNoteLengths = TBL.getUnchangeableNoteLengths() >>> kldict = TBL.classifyUnknownNotesByType(unchangeableNoteLengths) @@ -1075,7 +1093,7 @@ def classifyUnknownNotesByType(self, unchangeableNoteLengthsList): continue if obj.mensuralType == 'semibrevis': - if 'MensuralRest' in obj.classes: + if isinstance(obj, medren.MensuralRest): if self.div.standardSymbol not in ['.q.', '.i.', '.p.', '.n.']: semibrevis_list.append(i) else: @@ -1088,14 +1106,14 @@ def classifyUnknownNotesByType(self, unchangeableNoteLengthsList): elif obj.mensuralType == 'minima': pass elif obj.mensuralType == 'semiminima': - if 'MensuralNote' in obj.classes: + if isinstance(obj, medren.MensuralNote): if 'down' in obj.getStems(): raise TrecentoNotationException('Dragmas currently not supported') elif obj.getFlags()['up'] == 'right': semiminima_right_flag_list.append(i) elif obj.getFlags()['up'] == 'left': semiminima_left_flag_list.append(i) - if 'MensuralRest' in obj.classes: + if isinstance(obj, medren.MensuralRest): semiminima_rest_list.append(i) retDict = {'semibrevis': semibrevis_list, @@ -1162,9 +1180,11 @@ def translate(self): def translateDivI(self, unchangeableNoteLengthsList=None, unknownLengthsDict=None, minRem=None): ''' + >>> from music21_tools.trecento.medren import MensuralNote + >>> from music21_tools.trecento.notation import BrevisLengthTranslator, Divisione >>> div = Divisione('.i.') >>> names = ['SB', 'M', 'SB'] - >>> BL = [medren.MensuralNote('A', n) for n in names] + >>> BL = [MensuralNote('A', n) for n in names] >>> TBL = BrevisLengthTranslator(div, BL) >>> unchlist = TBL.getUnchangeableNoteLengths() >>> unchlist @@ -1218,9 +1238,11 @@ def translateDivN(self, unchangeableNoteLengthsList=None, unknownLengthsDict=Non ''' Translate the Novanaria (9) Divisio; returns the number of minims for each note. + >>> from music21_tools.trecento.medren import MensuralNote + >>> from music21_tools.trecento.notation import BrevisLengthTranslator, Divisione >>> div = Divisione('.n.') >>> names = ['SB', 'M', 'M', 'M', 'SB', 'M'] - >>> BL = [medren.MensuralNote('A', n) for n in names] + >>> BL = [MensuralNote('A', n) for n in names] >>> TBL = BrevisLengthTranslator(div, BL) >>> unchlist = TBL.getUnchangeableNoteLengths() >>> unkldict = TBL.classifyUnknownNotesByType(unchlist) @@ -1234,16 +1256,15 @@ def translateDivN(self, unchangeableNoteLengthsList=None, unknownLengthsDict=Non [2.0, 1.0, 1.0, 1.0, 3.0, 1.0] >>> names = ['SB', 'M', 'M', 'M', 'SB'] - >>> BL = [medren.MensuralNote('A', n) for n in names] + >>> BL = [MensuralNote('A', n) for n in names] >>> TBL = BrevisLengthTranslator(div, BL) >>> unchlist = TBL.getUnchangeableNoteLengths() >>> unkldict = TBL.classifyUnknownNotesByType(unchlist) >>> TBL.translateDivN(unchlist, unkldict, 6.0) [3.0, 1.0, 1.0, 1.0, 3.0] - >>> names = ['SB', 'M', 'SB'] - >>> BL = [medren.MensuralNote('A', n) for n in names] + >>> BL = [MensuralNote('A', n) for n in names] >>> TBL = BrevisLengthTranslator(div, BL) >>> unchlist = TBL.getUnchangeableNoteLengths() >>> unkldict = TBL.classifyUnknownNotesByType(unchlist) @@ -1257,7 +1278,6 @@ def translateDivN(self, unchangeableNoteLengthsList=None, unknownLengthsDict=Non >>> TBL.translateDivN(unchlist, unkldict, 8.0) [5.0, 1.0, 3.0] ''' - if unchangeableNoteLengthsList is None: unchangeableNoteLengthsList = self.unchangeableNoteLengthsList else: @@ -1356,9 +1376,11 @@ def translateDivPQ(self, unchangeableNoteLengthsList=None, ''' Translates P and Q (6 and 4) + >>> from music21_tools.trecento.medren import MensuralNote, MensuralRest + >>> from music21_tools.trecento.notation import BrevisLengthTranslator, Divisione >>> div = Divisione('.q.') >>> names = ['SB', 'SB'] - >>> BL = [medren.MensuralNote('A', n) for n in names] + >>> BL = [MensuralNote('A', n) for n in names] >>> TBL = BrevisLengthTranslator(div, BL) >>> unchlist = TBL.getUnchangeableNoteLengths() >>> unkldict = TBL.classifyUnknownNotesByType(unchlist) @@ -1366,8 +1388,8 @@ def translateDivPQ(self, unchangeableNoteLengthsList=None, [2.0, 2.0] >>> names = ['M', 'SM', 'SM', 'SM', 'SM', 'SM'] - >>> BL = [medren.MensuralNote('A', n) for n in names] - >>> BL[4] = medren.MensuralRest('SM') + >>> BL = [MensuralNote('A', n) for n in names] + >>> BL[4] = MensuralRest('SM') >>> BL[1].setFlag('up', 'left') >>> BL[2].setFlag('up', 'left') >>> TBL = BrevisLengthTranslator(div, BL) @@ -1378,7 +1400,7 @@ def translateDivPQ(self, unchangeableNoteLengthsList=None, >>> div = Divisione('.p.') >>> names = ['SB', 'SB', 'SB'] - >>> BL = [medren.MensuralNote('A', n) for n in names] + >>> BL = [MensuralNote('A', n) for n in names] >>> TBL = BrevisLengthTranslator(div, BL) >>> unchlist = TBL.getUnchangeableNoteLengths() >>> unkldict = TBL.classifyUnknownNotesByType(unchlist) @@ -1386,7 +1408,7 @@ def translateDivPQ(self, unchangeableNoteLengthsList=None, [2.0, 2.0, 2.0] >>> names = ['M', 'SB', 'SM', 'SM'] - >>> BL = [medren.MensuralNote('A', n) for n in names] + >>> BL = [MensuralNote('A', n) for n in names] >>> BL[1].setStem('down') >>> TBL = BrevisLengthTranslator(div, BL) >>> unchlist = TBL.getUnchangeableNoteLengths() @@ -1395,8 +1417,8 @@ def translateDivPQ(self, unchangeableNoteLengthsList=None, [1.0, 4.0, 0.5, 0.5] >>> names = ['SM', 'SM', 'SM', 'SM', 'SM', 'SM', 'SM', 'SB'] - >>> BL = [medren.MensuralNote('A', n) for n in names] - >>> BL[3] = medren.MensuralRest('SM') + >>> BL = [MensuralNote('A', n) for n in names] + >>> BL[3] = MensuralRest('SM') >>> for mn in BL[:3]: ... mn.setFlag('up', 'left') >>> TBL = BrevisLengthTranslator(div, BL) @@ -1405,7 +1427,6 @@ def translateDivPQ(self, unchangeableNoteLengthsList=None, >>> TBL.translateDivPQ(unchlist, unkldict, 6.0) [0.666..., 0.666..., 0.666..., 0.5, 0.5, 0.5, 0.5, 2.0] ''' - if unchangeableNoteLengthsList is None: unchangeableNoteLengthsList = self.unchangeableNoteLengthsList else: @@ -1613,9 +1634,11 @@ def translateDivOD(self, unchangeableNoteLengthsList=None, ''' Translates the octonaria and duodenaria divisions + >>> from music21_tools.trecento.medren import MensuralNote + >>> from music21_tools.trecento.notation import BrevisLengthTranslator, Divisione >>> divO = Divisione('.o.') >>> names = ['SB', 'SB', 'SB'] - >>> BL = [medren.MensuralNote('A', n) for n in names] + >>> BL = [MensuralNote('A', n) for n in names] >>> BL[1].setStem('down') >>> TBL = BrevisLengthTranslator(divO, BL) >>> unchlist = TBL.getUnchangeableNoteLengths() @@ -1624,7 +1647,7 @@ def translateDivOD(self, unchangeableNoteLengthsList=None, [2.0, 4.0, 2.0] >>> names = ['SM', 'SM', 'SM', 'SB', 'SB'] - >>> BL = [medren.MensuralNote('A', n) for n in names] + >>> BL = [MensuralNote('A', n) for n in names] >>> TBL = BrevisLengthTranslator(divO, BL) >>> unchlist = TBL.getUnchangeableNoteLengths() >>> unkldict = TBL.classifyUnknownNotesByType(unchlist) @@ -1633,7 +1656,7 @@ def translateDivOD(self, unchangeableNoteLengthsList=None, >>> divD = Divisione('.d.') >>> names = ['SB', 'SB'] - >>> BL = [medren.MensuralNote('A', n) for n in names] + >>> BL = [MensuralNote('A', n) for n in names] >>> TBL = BrevisLengthTranslator(divD, BL) >>> unchlist = TBL.getUnchangeableNoteLengths() >>> unkldict = TBL.classifyUnknownNotesByType(unchlist) @@ -1641,7 +1664,7 @@ def translateDivOD(self, unchangeableNoteLengthsList=None, [4.0, 8.0] >>> names = ['SB', 'SB', 'SB'] - >>> BL = [medren.MensuralNote('A', n) for n in names] + >>> BL = [MensuralNote('A', n) for n in names] >>> TBL = BrevisLengthTranslator(divD, BL) >>> unchlist = TBL.getUnchangeableNoteLengths() >>> unkldict = TBL.classifyUnknownNotesByType(unchlist) @@ -1649,7 +1672,7 @@ def translateDivOD(self, unchangeableNoteLengthsList=None, [4.0, 4.0, 4.0] >>> names = ['SB', 'SB', 'SB', 'SB'] - >>> BL = [medren.MensuralNote('A', n) for n in names] + >>> BL = [MensuralNote('A', n) for n in names] >>> TBL = BrevisLengthTranslator(divD, BL) >>> unchlist = TBL.getUnchangeableNoteLengths() >>> unkldict = TBL.classifyUnknownNotesByType(unchlist) @@ -1667,7 +1690,7 @@ def translateDivOD(self, unchangeableNoteLengthsList=None, [2.0, 4.0, 4.0, 2.0] >>> names = ['SB', 'SB', 'SM', 'SM', 'SM', 'SM', 'SB', 'SB'] - >>> BL = [medren.MensuralNote('A', n) for n in names] + >>> BL = [MensuralNote('A', n) for n in names] >>> TBL = BrevisLengthTranslator(divD, BL) >>> unchlist = TBL.getUnchangeableNoteLengths() >>> unkldict = TBL.classifyUnknownNotesByType(unchlist) @@ -2062,9 +2085,9 @@ def processStream(mStream, pitches, lengths, downStems=None): 'c(SB) B B p A B[D] p A B c d(Mx)') upperConverted = TrecentoTinyConverter(upperString).parse( - ).stream.flatten().getElementsNotOfClass('Barline') + ).stream.flatten().getElementsNotOfClass('Barline').stream() lowerConverted = TrecentoTinyConverter(lowerString).parse( - ).stream.flatten().getElementsNotOfClass('Barline') + ).stream.flatten().getElementsNotOfClass('Barline').stream() TinySePerDureca.append(upperConverted) TinySePerDureca.append(lowerConverted) diff --git a/music21_tools/trecento/polyphonicSnippet.py b/music21_tools/trecento/polyphonicSnippet.py index 5131a33..4b7701c 100644 --- a/music21_tools/trecento/polyphonicSnippet.py +++ b/music21_tools/trecento/polyphonicSnippet.py @@ -27,14 +27,15 @@ class PolyphonicSnippet(stream.Score): The fourth is the cadence type (optional), the fifth is the time signature if not the same as the time signature of the parentPiece. - >>> from . import trecentoCadence - >>> cantus = trecentoCadence.CadenceConverter( + >>> from music21_tools.trecento.cadencebook import BallataSheet + >>> from music21_tools.trecento.polyphonicSnippet import PolyphonicSnippet + >>> from music21_tools.trecento.trecentoCadence import CadenceConverter + >>> cantus = CadenceConverter( ... "6/8 c'2. d'8 c'4 a8 f4 f8 a4 c'4 c'8").parse().stream - >>> tenor = trecentoCadence.CadenceConverter("6/8 F1. f2. e4. d").parse().stream - >>> from . import cadencebook + >>> tenor = CadenceConverter("6/8 F1. f2. e4. d").parse().stream >>> ps = PolyphonicSnippet( ... [cantus, tenor, None, "8-8", "6/8"], - ... parentPiece=cadencebook.BallataSheet().makeWork(3)) + ... parentPiece=BallataSheet().makeWork(3)) >>> ps.elements (, , ) @@ -64,6 +65,7 @@ class PolyphonicSnippet(stream.Score): >>> ps2.elements () + >>> from music21_tools.trecento.polyphonicSnippet import Incipit >>> dummy2 = Incipit() >>> dummy2.elements () @@ -161,7 +163,7 @@ def findLongestCadence(self): returns the length. (in quarterLengths) for the longest line in the parts - + >>> from music21_tools.trecento.polyphonicSnippet import PolyphonicSnippet >>> s1 = stream.Part([note.Note(type='whole')]) >>> s2 = stream.Part([note.Note(type='half')]) >>> s3 = stream.Part([note.Note(type='quarter')]) @@ -169,7 +171,6 @@ def findLongestCadence(self): >>> ps = PolyphonicSnippet(fiveExcelRows) >>> ps.findLongestCadence() 4.0 - ''' longestLineLength = 0 for thisStream in self.parts: @@ -185,6 +186,7 @@ def measuresShort(self, thisStream): ''' returns the number of measures short that each stream is compared to the longest stream. + >>> from music21_tools.trecento.polyphonicSnippet import PolyphonicSnippet >>> s1 = stream.Part([note.Note(type='whole')]) >>> s2 = stream.Part([note.Note(type='half')]) >>> s3 = stream.Part([note.Note(type='quarter')]) @@ -199,8 +201,6 @@ def measuresShort(self, thisStream): >>> ps.measuresShort(s1) 0.0 ''' - - timeSigLength = self.timeSig.barDuration.quarterLength thisStreamLength = thisStream.duration.quarterLength shortness = self.findLongestCadence() - thisStreamLength @@ -208,7 +208,6 @@ def measuresShort(self, thisStream): return shortmeasures - class Incipit(PolyphonicSnippet): snippetName = '' @@ -217,7 +216,7 @@ def backPadLine(self, thisStream): Pads a Stream with a bunch of rests at the end to make it the same length as the longest line - + >>> from music21_tools.trecento.polyphonicSnippet import Incipit >>> ts = meter.TimeSignature('1/4') >>> s1 = stream.Part([ts]) >>> s1.repeatAppend(note.Note(type='quarter'), 4) @@ -240,7 +239,6 @@ def backPadLine(self, thisStream): {3.0} {0.0} {1.0} - ''' shortMeasures = int(self.measuresShort(thisStream)) @@ -275,15 +273,15 @@ def backPadLine(self, thisStream): lastMeasure.rightBarline = oldRightBarline - class FrontPaddedSnippet(PolyphonicSnippet): snippetName = '' def frontPadLine(self, thisStream): - '''Pads a line with a bunch of rests at the + ''' + Pads a line with a bunch of rests at the front to make it the same length as the longest line - + >>> from music21_tools.trecento.polyphonicSnippet import FrontPaddedSnippet >>> ts = meter.TimeSignature('1/4') >>> s1 = stream.Part([ts]) >>> s1.repeatAppend(note.Note(type='quarter'), 4) @@ -306,7 +304,6 @@ def frontPadLine(self, thisStream): {3.0} {0.0} {1.0} - ''' shortMeasures = int(self.measuresShort(thisStream)) @@ -326,7 +323,6 @@ def frontPadLine(self, thisStream): for thisNote in thisStream.iter.notesAndRests: thisNote.setOffsetBySite(thisStream, thisStream.elementOffset(m) + offsetShift) - for i in range(shortMeasures): newRest = note.Rest() newRest.duration = copy.deepcopy(shortDuration) @@ -355,10 +351,6 @@ def frontPadLine(self, thisStream): newFirstM.insert(nOffset, n) - - - - class Test(unittest.TestCase): pass @@ -366,7 +358,8 @@ def runTest(self): pass def testCopyAndDeepcopy(self): - '''Test copying all objects defined in this module + ''' + Test copying all objects defined in this module ''' import sys for part in sys.modules[self.__module__].__dict__: @@ -388,6 +381,7 @@ class TestExternal(unittest.TestCase): # pragma: no cover def runTest(self): pass + def testLily(self): from . import trecentoCadence, cadencebook cantus = trecentoCadence.CadenceConverter( diff --git a/music21_tools/trecento/runTrecentoCadence.py b/music21_tools/trecento/runTrecentoCadence.py index 8f323ca..2603b26 100644 --- a/music21_tools/trecento/runTrecentoCadence.py +++ b/music21_tools/trecento/runTrecentoCadence.py @@ -10,7 +10,6 @@ ''' Python script to find out certain statistics about the trecento cadences ''' - import unittest from . import cadencebook diff --git a/music21_tools/trecento/tonality.py b/music21_tools/trecento/tonality.py index 4932644..efb739d 100644 --- a/music21_tools/trecento/tonality.py +++ b/music21_tools/trecento/tonality.py @@ -28,15 +28,13 @@ class TonalityCounter: ''' The TonalityCounter object takes a list of Trecento Works - (defined in music21.trecento.cadencebook) and when run() + (defined in music21_tools.trecento.cadencebook) and when run() is called, stores a set of information about the cadence tonalities of the works. - streamName can be "C" (cantus), "T" (tenor, default), or "Ct" (contratenor), or very rarely "4" (fourth voice). - cadenceName can be "A" or "B" (which by default uses the second ending of cadence B if there are two endings) or an integer specifying which cadence to consult (-1 being @@ -44,15 +42,14 @@ class TonalityCounter: want the Amen no matter how many internal cadences there are). - This example takes three ballata and how that all three of them cadence on a different note than they began on. All three cadence on D despite beginning on C, A, and B (or B - flat) repsectively. + flat) respectively. - - >>> from music21_tools.trecento import cadencebook - >>> threeBallata = cadencebook.BallataSheet()[15:18] + >>> from music21_tools.trecento.cadencebook import BallataSheet + >>> from music21_tools.trecento.tonality import TonalityCounter + >>> threeBallata = BallataSheet()[15:18] >>> tc1 = TonalityCounter(threeBallata) >>> tc1.run() >>> print(tc1.output) @@ -160,17 +157,15 @@ def landiniTonality(show=True): generates information about the tonality of Landini's ballate using the tenor (streamName = "T") and the A cadence (which we would believe would end the piece) - ''' - - ballataObj = cadencebook.BallataSheet() + ballataObj = cadencebook.BallataSheet() worksList = [] for thisWork in ballataObj: if thisWork.composer == 'Landini': worksList.append(thisWork) - tCounter = TonalityCounter(worksList, streamName = 'T', cadenceName = 'A') + tCounter = TonalityCounter(worksList, streamName='T', cadenceName='A') tCounter.run() - if show is True: + if show: print(tCounter.output) def nonLandiniTonality(show=True): @@ -181,6 +176,7 @@ def nonLandiniTonality(show=True): would end the piece) + >>> from music21_tools import trecento >>> #_DOCS_SHOW trecento.tonality.nonLandiniTonality(show=True) diff --git a/music21_tools/trecento/trecentoCadence.py b/music21_tools/trecento/trecentoCadence.py index c2c9fa4..518c250 100644 --- a/music21_tools/trecento/trecentoCadence.py +++ b/music21_tools/trecento/trecentoCadence.py @@ -49,7 +49,7 @@ class CadenceConverter(tinyNotation.Converter): ''' Subclass of Tiny Notation that calls these tokens instead of the defaults - + >>> from music21_tools.trecento.trecentoCadence import CadenceConverter >>> dLucaGloriaIncipit = CadenceConverter( ... "6/8 c'2. d'8 c'4 a8 f4 f8 a4 c'4 c'8").parse().stream >>> dLucaGloriaIncipit.rightBarline = 'final' From bc704c7318519ef92c7772147f5a9f95f3aa3721 Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 17:01:30 -1000 Subject: [PATCH 19/28] more tests updated --- music21_tools/bhadley/harmonyRealizer.py | 8 - music21_tools/chant/chant.py | 19 --- music21_tools/composition/phasing.py | 10 -- music21_tools/contour/contour.py | 17 +-- music21_tools/counterpoint/species.py | 6 - music21_tools/misc/gatherAccidentals.py | 8 - music21_tools/theory/mgtaPart1.py | 6 - music21_tools/theory/mgtaPart2.py | 140 +----------------- .../theoryAnalysis/theoryAnalyzer.py | 3 - music21_tools/theoryAnalysis/theoryResult.py | 24 --- music21_tools/theoryAnalysis/wwnortonMGTA.py | 33 ----- music21_tools/trecento/cadencebook.py | 7 - music21_tools/trecento/capua.py | 11 -- music21_tools/trecento/medren.py | 110 +++++++------- music21_tools/trecento/notation.py | 51 ++++--- music21_tools/trecento/polyphonicSnippet.py | 10 -- music21_tools/trecento/quodJactatur.py | 18 --- music21_tools/trecento/runTrecentoCadence.py | 23 +-- music21_tools/trecento/tonality.py | 4 - music21_tools/trecento/trecentoCadence.py | 8 - publications/icmc2010.py | 8 - publications/icmc2011.py | 5 - publications/ismir2010.py | 8 - publications/seaverOct2009.py | 10 -- publications/smt2010.py | 9 -- 25 files changed, 97 insertions(+), 459 deletions(-) diff --git a/music21_tools/bhadley/harmonyRealizer.py b/music21_tools/bhadley/harmonyRealizer.py index f8ef7bd..0600d72 100644 --- a/music21_tools/bhadley/harmonyRealizer.py +++ b/music21_tools/bhadley/harmonyRealizer.py @@ -168,15 +168,7 @@ def mergeLeadSheetAndBassLine(leadsheet, bassLine): return s # ------------------------------------------------------------------------------ -class Test(unittest.TestCase): - - def runTest(self): - pass - class TestExternal(unittest.TestCase): # pragma: no cover - def runTest(self): - pass - def realizeclercqTemperleyEx(self, testfile): ''' Example realization (using fbRealizer - romanNumerals flavor) of any clercqTemperley file. diff --git a/music21_tools/chant/chant.py b/music21_tools/chant/chant.py index 5cd135a..45bd6e4 100644 --- a/music21_tools/chant/chant.py +++ b/music21_tools/chant/chant.py @@ -513,20 +513,7 @@ def substituteInfo(self, converter): class ChantException(exceptions21.Music21Exception): pass - - -class Test(unittest.TestCase): - pass - - def runTest(self): - pass - class TestExternal(unittest.TestCase): # pragma: no cover - pass - - def runTest(self): - pass - def testSimpleFile(self): s = GregorianStream() s.append(clef.AltoClef()) @@ -566,12 +553,6 @@ def testSimpleFile(self): os.system('open %s' % pdffn) - # ------------------------------------------------------------------------------ # define presented order in documentation _DOC_ORDER = [] - - -if __name__ == '__main__': - import music21 - music21.mainTest(Test, 'moduleRelative') diff --git a/music21_tools/composition/phasing.py b/music21_tools/composition/phasing.py index 414a78d..88c8218 100644 --- a/music21_tools/composition/phasing.py +++ b/music21_tools/composition/phasing.py @@ -143,21 +143,11 @@ def pendulumMusic(show=True, # ------------------------------------------------------------------------------ class Test(unittest.TestCase): - - def runTest(self): - pass - - def testBasic(self, cycles=4, show=False): # run a reduced version pitchedPhase(cycles=cycles, show=show) class TestExternal(unittest.TestCase): # pragma: no cover - - def runTest(self): - pass - - def testBasic(self, cycles=8, show=True): # run a reduced version pitchedPhase(cycles=cycles, show=show) diff --git a/music21_tools/contour/contour.py b/music21_tools/contour/contour.py index fb5fa6a..fbbf316 100644 --- a/music21_tools/contour/contour.py +++ b/music21_tools/contour/contour.py @@ -12,7 +12,6 @@ This module defines the ContourFinder and AggregateContour objects. ''' import random -import unittest from music21 import base # for _missingImport testing. from music21 import repeat @@ -442,7 +441,7 @@ def tonalDistanceMetric(self, inpStream): try: guessedKey = inpStream.analyze('key') except DiscreteAnalysisException: - # music21 raises exception when stream has no notes. + # music21 raises exception when stream has no notes. return 0.5 certainty = -2 # should be replaced by a value between -1 and 1 @@ -814,21 +813,9 @@ def _plotChoraleContours(): print(chorale) # cf.plot('dissonance', fileName= chorale + 'dissonance', regression=False) try: - cf.plot('tonality', fileName= chorale + 'tonality', regression=False) + cf.plot('tonality', fileName=chorale + 'tonality', regression=False) except exceptions21.Music21Exception: print(chorale) s.show() break pass - - -# ------------------------ -class Test(unittest.TestCase): - - def runTest(self): - pass - -if __name__ == '__main__': - import music21 - music21.mainTest(Test, 'moduleRelative') - diff --git a/music21_tools/counterpoint/species.py b/music21_tools/counterpoint/species.py index bc111fe..0a7c585 100644 --- a/music21_tools/counterpoint/species.py +++ b/music21_tools/counterpoint/species.py @@ -1652,17 +1652,11 @@ def getRandomCF(mode=None): # ------------------------------------------------------------------------------ class TestExternal(unittest.TestCase): # pragma: no cover - - def runTest(self): - pass - - def testGenerateFirstSpecies(self): ''' A First Species Counterpoint Generator by Jackie Rogoff (MIT 2010) written as part of an UROP (Undergraduate Research Opportunities Program) project at M.I.T. 2008. ''' - counterpoint1 = ModalCounterpoint() cf = getRandomCF() diff --git a/music21_tools/misc/gatherAccidentals.py b/music21_tools/misc/gatherAccidentals.py index 9aa694d..357b036 100644 --- a/music21_tools/misc/gatherAccidentals.py +++ b/music21_tools/misc/gatherAccidentals.py @@ -216,10 +216,6 @@ class GatherAccidentalsException(exceptions21.Music21Exception): # ------------------------------------------------------- class Test(unittest.TestCase): - - def runTest(self): - pass - def testGetAccidentalCountBasic(self): s = stream.Stream() self.assertEqual(len(s.flatten().notes), 0) # the stream should be empty @@ -269,10 +265,6 @@ def testGetAccidentalCountSumAdvanced(self): class TestSlow(unittest.TestCase): - - def runTest(self): - pass - def testAccidentalCountBachChorales(self): # the total number of accidentals in the Bach Chorales chorales = list( corpus.chorales.Iterator() ) diff --git a/music21_tools/theory/mgtaPart1.py b/music21_tools/theory/mgtaPart1.py index 75f4eb5..f4a98ee 100644 --- a/music21_tools/theory/mgtaPart1.py +++ b/music21_tools/theory/mgtaPart1.py @@ -1818,18 +1818,12 @@ def ch5_analysis_C(show=True, *arguments, **keywords): ] class TestExternal(unittest.TestCase): # pragma: no cover - def runTest(self): - pass - def testBasic(self): for func in FUNCTIONS: func(show=True, play=False) class Test(unittest.TestCase): - def runTest(self): - pass - def testBasic(self): for func in FUNCTIONS: func(show=False, play=False) diff --git a/music21_tools/theory/mgtaPart2.py b/music21_tools/theory/mgtaPart2.py index 3ff19be..10a5c1f 100755 --- a/music21_tools/theory/mgtaPart2.py +++ b/music21_tools/theory/mgtaPart2.py @@ -23,18 +23,12 @@ # ------------------------------------------------------------------------------ # all are tests class Test(unittest.TestCase): - - def runTest(self): - pass - -# ------------------------------------------------------------------------------ -# CHAPTER 6 -# ------------------------------------------------------------------------------ -# Basic Elements -# ------------------------------------------------------------------------------ -# I. Writing generic intervals (melodic) - - + # ------------------------------------------------------------------------------ + # CHAPTER 6 + # ------------------------------------------------------------------------------ + # Basic Elements + # ------------------------------------------------------------------------------ + # I. Writing generic intervals (melodic) def xtest_Ch6_basic_I_A(self, *arguments, **keywords): '''p55 Write a whole note on the specified generic interval. Do not add sharps or flats. @@ -43,12 +37,8 @@ def xtest_Ch6_basic_I_A(self, *arguments, **keywords): ''' pass - - - -# ------------------------------------------------------------------------------ -# II. Writing major and perfect pitch intervals - + # ------------------------------------------------------------------------------ + # II. Writing major and perfect pitch intervals def test_Ch6_basic_II_A(self, *arguments, **keywords): '''p. 55 Write the specified melodic interval above the given note. @@ -86,117 +76,6 @@ def test_Ch6_basic_II_A(self, *arguments, **keywords): self.assertEqual(match, ['C5', 'C#5', 'C5', 'C#5', 'B-4', 'E3', 'B-2', 'B-2', 'A-3', 'B-2']) - def test_Ch6_basic_II_B(self, *arguments, **keywords): - pass - -# ------------------------------------------------------------------------------ -# III. Writing major, minor, and perfect pitch intervals - - -# ------------------------------------------------------------------------------ -# IV. Writing diminished and augmented pitch intervals - -# ------------------------------------------------------------------------------ -# V. Enharmonically equivalent intervals - - -# ------------------------------------------------------------------------------ -# VI. Interval inversion - - -# ------------------------------------------------------------------------------ -# VII. Interval class - - - -# ------------------------------------------------------------------------------ -# VII. Interval class - - - -# ------------------------------------------------------------------------------ -# Writing Exercises -# ------------------------------------------------------------------------------ -# Writing intervals - - -# ------------------------------------------------------------------------------ -# Analysis -# ------------------------------------------------------------------------------ -# I. Harmonic and melodic intervals - - - -# ------------------------------------------------------------------------------ -# II. Melodic intervals, compound intervals, and interval class - - - - - -# ------------------------------------------------------------------------------ -# CHAPTER 7: Triads and Seventh Chords -# ------------------------------------------------------------------------------ -# Basic Elements -# ------------------------------------------------------------------------------ -# I. Building triads above a scale - - - -# ------------------------------------------------------------------------------ -# II. Spelling isolated triads - - -# ------------------------------------------------------------------------------ -# III. Scale-degree triads - - -# ------------------------------------------------------------------------------ -# IV. Building seventh chords above a scale - - -# ------------------------------------------------------------------------------ -# V. Spelling isolated seventh chords - - - -# ------------------------------------------------------------------------------ -# VI. Scale-degree triads and seventh chords in inversion - - -# ------------------------------------------------------------------------------ -# Analysis -# ------------------------------------------------------------------------------ -# I. Brief analysis - - -# ------------------------------------------------------------------------------ -# II. Examining a lead sheet - - - - - - - -# ------------------------------------------------------------------------------ -# CHAPTER 8: Intervals in Action -# ------------------------------------------------------------------------------ -# Basic Elements -# ------------------------------------------------------------------------------ -# I. Opening and closing patterns in note-against-note counterpoint - - - - - - - - - - - - if __name__ == '__main__': import music21 import sys @@ -208,6 +87,3 @@ def test_Ch6_basic_II_B(self, *arguments, **keywords): t = Test() # t.test_Ch6_basic_II_A(show=True) - - - diff --git a/music21_tools/theoryAnalysis/theoryAnalyzer.py b/music21_tools/theoryAnalysis/theoryAnalyzer.py index 13d3c4f..7daae34 100644 --- a/music21_tools/theoryAnalysis/theoryAnalyzer.py +++ b/music21_tools/theoryAnalysis/theoryAnalyzer.py @@ -2532,9 +2532,6 @@ def testFastVerticalityCheck(self): class TestExternal(unittest.TestCase): # pragma: no cover - def runTest(self): - pass - def demo(self): from music21 import converter sc = converter.parse( diff --git a/music21_tools/theoryAnalysis/theoryResult.py b/music21_tools/theoryAnalysis/theoryResult.py index 98b1489..15360d0 100644 --- a/music21_tools/theoryAnalysis/theoryResult.py +++ b/music21_tools/theoryAnalysis/theoryResult.py @@ -9,8 +9,6 @@ # Copyright: Copyright © 2009-2026 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ -import unittest - class TheoryResult: ''' A TheoryResult object is used to store information about the results @@ -278,25 +276,3 @@ def markNoteEditorial(self, editorialDictKey, editorialValue, editorialMarkDict= for unused_counter_partNum in partNumList: self.vsnt.verticalities[vsNum].getObjectsByPart(0, classFilterList=['Note']).editorial[editorialDictKey] = editorialValue - - -class Test(unittest.TestCase): - - def runTest(self): - pass - -class TestExternal(unittest.TestCase): # pragma: no cover - - def runTest(self): - pass - - def demo(self): - pass - - -if __name__ == '__main__': - import music21 - music21.mainTest(Test, 'moduleRelative') - - # te = TestExternal() - # te.demo() diff --git a/music21_tools/theoryAnalysis/wwnortonMGTA.py b/music21_tools/theoryAnalysis/wwnortonMGTA.py index 59a863b..975abdb 100644 --- a/music21_tools/theoryAnalysis/wwnortonMGTA.py +++ b/music21_tools/theoryAnalysis/wwnortonMGTA.py @@ -12,10 +12,6 @@ _DOC_IGNORE_MODULE_OR_PACKAGE = True import copy -import unittest - -import music21 - from music21 import converter from music21 import stream from music21 import instrument @@ -280,32 +276,3 @@ def checkExercise(self): offsetFunc=harmonicIntervalOffsetFunc, lyricFunc=harmonicIntervalTextFunc) - - -# ------------------------------------------------------------ - -class Test(unittest.TestCase): - - def runTest(self): - pass - -class TestExternal(unittest.TestCase): # pragma: no cover - - def runTest(self): - pass - - def demo(self): - ex = ex11_1_I() - sc = converter.parse('C:/Users/bhadley/Dropbox/Music21Theory/TestFiles/' + - 'SampleStudentResponses/S11_1_IA_completed.xml') - ex.loadStudentExercise(sc) - ex.checkExercise() - ex.showStudentExercise() - - -if __name__ == '__main__': - music21.mainTest(Test) - - # te = TestExternal() - # te.demo() - diff --git a/music21_tools/trecento/cadencebook.py b/music21_tools/trecento/cadencebook.py index 7d43a1a..d38c5c5 100644 --- a/music21_tools/trecento/cadencebook.py +++ b/music21_tools/trecento/cadencebook.py @@ -730,9 +730,6 @@ class Gloria(TrecentoCadenceWork): class Test(unittest.TestCase): - def runTest(self): - pass - def testTrecentoCadenceWorkCopying(self): w = TrecentoCadenceWork() _w1 = copy.copy(w) @@ -760,14 +757,10 @@ def testConvertBlockToStreams(self): class TestExternal(unittest.TestCase): # pragma: no cover - def runTest(self): - pass - def testCredo(self): ''' testing a Credo in and Lilypond out ''' - cs1 = CredoSheet() # filename = r'd:\docs\trecento\fischer\cadences.xls') # cs1 = BallataSheet() credo1 = cs1.makeWork(2) diff --git a/music21_tools/trecento/capua.py b/music21_tools/trecento/capua.py index 27c7ae6..5287bc3 100644 --- a/music21_tools/trecento/capua.py +++ b/music21_tools/trecento/capua.py @@ -1042,10 +1042,6 @@ def ruleFrequency(startNumber=2, endNumber=459): class Test(unittest.TestCase): - - def runTest(self): - pass - def testRunNonCrederDonna(self): pieceNum = 331 # Francesco, PMFC 4 6-7: Non creder, donna ballataObj = cadencebook.BallataSheet() @@ -1137,9 +1133,6 @@ def testColorCapuaFicta(self): class TestExternal(unittest.TestCase): # pragma: no cover - def runTest(self): - pass - def testRunNonCrederDonna(self): t = Test() pObj = t.testRunNonCrederDonna() @@ -1166,10 +1159,6 @@ def testShowFourA(self): class TestSlow(unittest.TestCase): - - def runTest(self): - pass - def testCompare1(self): ballataObj = cadencebook.BallataSheet() totalDict = { diff --git a/music21_tools/trecento/medren.py b/music21_tools/trecento/medren.py index 94dc21e..1d70f2a 100644 --- a/music21_tools/trecento/medren.py +++ b/music21_tools/trecento/medren.py @@ -1729,43 +1729,46 @@ def breakMensuralStreamIntoBrevisLengths(inpStream, inpMOrD=None, printUpdates=F Hierarchy of violated by + The normal case: a single flat ``Part`` carrying a Divisione at its head, + followed by mensural notes and Puncti. The function returns a ``Part`` + of ``Measure`` objects grouped by brevis-length, with the Divisione placed + as the first element of the first Measure. + >>> p = stream.Part() - >>> m.append(MensuralNote('G', 'B')) >>> p.append(Divisione('.q.')) - >>> p.repeatAppend(MensuralNote('A', 'SB'),2) + >>> p.repeatAppend(MensuralNote('A', 'SB'), 2) >>> p.append(Punctus()) - >>> p.repeatAppend(MensuralNote('B', 'M'),4) + >>> p.repeatAppend(MensuralNote('B', 'M'), 4) >>> p.append(Punctus()) >>> p.append(MensuralNote('C', 'B')) - >>> s.append(Divisione('.p.')) - >>> s.append(p) - >>> s.append(m) - >>> breakMensuralStreamIntoBrevisLengths(s, printUpdates = True) - Traceback (most recent call last): - music21_tools.trecento.medren.MedRenException: Mensuration or divisione <...Divisione .q.> not consistent within hierarchy - - >>> s = stream.Stream() - >>> s.append(Divisione('.q.')) - >>> s.append(p) - >>> s.append(m) - >>> t = breakMensuralStreamIntoBrevisLengths(s, printUpdates = True) + >>> t = breakMensuralStreamIntoBrevisLengths(p, printUpdates=True) Getting measure 0... ... >>> t.show('text') - {0.0} <...Divisione .q.> - {0.0} - {0.0} - {0.0} <...MensuralNote semibrevis A> - {0.0} <...MensuralNote semibrevis A> - {0.0} - {0.0} <...MensuralNote minima B> - {0.0} <...MensuralNote minima B> - {0.0} <...MensuralNote minima B> - {0.0} <...MensuralNote minima B> - {0.0} - {0.0} <...MensuralNote brevis C> - {0.0} - {0.0} <...MensuralNote brevis G> + {0.0} + {0.0} + {0.0} <...MensuralNote semibrevis A> + {0.0} <...MensuralNote semibrevis A> + {0.0} + {0.0} <...MensuralNote minima B> + {0.0} <...MensuralNote minima B> + {0.0} <...MensuralNote minima B> + {0.0} <...MensuralNote minima B> + {0.0} + {0.0} <...MensuralNote brevis C> + + >>> first = t.getElementsByClass(stream.Measure).first() + >>> isinstance(first[0], Divisione) + True + + Now insert a second, conflicting Divisione mid-Part — the function refuses + because trecento divisione changes are only allowed at the highest stream + level, not within a single voice. + + >>> p.insert(5, Divisione('.p.')) + >>> breakMensuralStreamIntoBrevisLengths(p) + Traceback (most recent call last): + music21_tools.trecento.medren.MedRenException: Mensuration or divisione not consistent within hierarchy ''' mOrD = inpMOrD mOrDInAsNone = True @@ -1835,18 +1838,27 @@ def isHigherInHierarchy(lower, upper): else: measureNum = 0 mensuralMeasure = [] + # Hold clef/divisione/mensuration until the first Measure is built, then + # prepend them inside it — that matches the natural music21 layout + # (TimeSignature/Clef live inside their first Measure, not as siblings + # of it). + pendingFirstMeasureItems = [] for e in inpStream_copy: if isinstance(e, MensuralClef): - newStream.append(e) + pendingFirstMeasureItems.append(e) elif isinstance(e, (Mensuration, notation.Divisione)): - if mOrDInAsNone: # If first case or changed mOrD + if mOrD is None: mOrD = e - newStream.append(e) - elif mOrD.standardSymbol != e.standardSymbol: # If higher, different mOrD found + pendingFirstMeasureItems.append(e) + elif mOrD.standardSymbol != e.standardSymbol: + # A second, different divisione in the same flat stream — + # not allowed (divisione changes must happen at a higher + # hierarchy level). raise MedRenException( - 'Mensuration or divisione %s not consistent within hierarchy' % e) + f'Mensuration or divisione {e} not consistent within hierarchy') + # else: same divisione repeated, ignore silently elif isinstance(e, Ligature): tempStream = stream.Stream() for mn in e.notes: @@ -1856,15 +1868,25 @@ def isHigherInHierarchy(lower, upper): elif (isinstance(e, GeneralMensuralNote)) and (e not in mensuralMeasure): m = stream.Measure(number=measureNum) if printUpdates is True: - print('Getting measure %s...' % measureNum) + print(f'Getting measure {measureNum}...') mensuralMeasure = e._getSurroundingMeasure(mOrD, inpStream_copy)[0] if printUpdates is True: - print('mensuralMeasure %s' % mensuralMeasure) + print(f'mensuralMeasure {mensuralMeasure}') + # Place clef/divisione (collected so far) at the front of the + # very first Measure; subsequent Measures get only their notes. + for item in pendingFirstMeasureItems: + m.append(item) + pendingFirstMeasureItems = [] for item in mensuralMeasure: m.append(item) newStream.append(m) measureNum += 1 + # If the input was just metadata (clef/divisione) with no notes, place + # those items at the top of newStream so they aren't lost. + for item in pendingFirstMeasureItems: + newStream.append(item) + return newStream # ----------------------------------------------------------- @@ -2064,14 +2086,7 @@ def cummingSchubertStrettoFuga(score): class MedRenException(exceptions21.Music21Exception): pass -class Test(unittest.TestCase): - def runTest(self): - pass - class TestExternal(unittest.TestCase): # pragma: no cover - def runTest(self): - pass - def xtestBarlineConvert(self): from music21 import corpus testPiece = corpus.parse('luca/gloria') @@ -2133,12 +2148,3 @@ def testStretto(): etJesum.title = '...et Jesum' for piece in [salve, adTe, etJesum]: cummingSchubertStrettoFuga(piece) - -if __name__ == '__main__': - import music21 - music21.mainTest(Test, 'importPlusRelative') # TestExternal) - # music21.testConvertMensuralMeasure() - # almaRedemptoris = converter.parse("C4 E F G A G G G A B c G", '4/4') # Liber 277 (pdf 401) - # puer = converter.parse('G4 d d d e d c c d c e d d', '4/4') # puer natus est 408 (pdf 554) - # almaRedemptoris.title = "Alma Redemptoris Mater LU p. 277" - # puer.title = "Puer Natus Est Nobis" diff --git a/music21_tools/trecento/notation.py b/music21_tools/trecento/notation.py index 7f09302..74c3672 100644 --- a/music21_tools/trecento/notation.py +++ b/music21_tools/trecento/notation.py @@ -262,11 +262,11 @@ class TrecentoTinyConverter(tinyNotation.Converter): :meth:`music21.medren.MensuralNote.setStem()`. >>> tTNN = TrecentoTinyConverter( - ... 'a(SB)[S]').parse().stream.recurse().notes.first + ... 'a(SB)[S]').parse().stream.recurse().notes.first() >>> tTNN.getStems() ['side'] - >>> tTNN = TrecentoTinyConverter('a(M)[D]').parse().stream.recurse().notes.first + >>> tTNN = TrecentoTinyConverter('a(M)[D]').parse().stream.recurse().notes.first() >>> tTNN.getStems() ['up', 'down'] @@ -278,7 +278,7 @@ class TrecentoTinyConverter(tinyNotation.Converter): follow the rules outlined in :meth:`music21.medren.MensuralNote.setFlag()`. >>> tTNN = TrecentoTinyConverter( - ... 'a(SM)_UL').parse().stream.recurse().notes.first + ... 'a(SM)_UL').parse().stream.recurse().notes.first() >>> tTNN.getStems() ['up'] @@ -292,7 +292,7 @@ class TrecentoTinyConverter(tinyNotation.Converter): direction-orientation pairs, as shown in the following complex example: >>> tTNN = TrecentoTinyConverter( - ... 'a(SM)[D]_UL/DR').parse().stream.recurse().notes.first + ... 'a(SM)[D]_UL/DR').parse().stream.recurse().notes.first() >>> tTNN.pitch >>> tTNN.getStems() @@ -318,7 +318,7 @@ class TrecentoTinyConverter(tinyNotation.Converter): {0.0} {0.0} {0.0} - >>> tTNN = ts[Ligature].first + >>> tTNN = ts[Ligature].first() >>> tTNN >>> [str(p) for p in tTNN.pitches] @@ -337,7 +337,7 @@ class TrecentoTinyConverter(tinyNotation.Converter): Examples: >>> ts = TrecentoTinyConverter(r'lig{f a[DL]=R}').parse().stream - >>> tTNN = ts[Ligature].first + >>> tTNN = ts[Ligature].first() >>> tTNN.getStem(1) ('down', 'left') @@ -346,7 +346,7 @@ class TrecentoTinyConverter(tinyNotation.Converter): >>> tTNN = TrecentoTinyConverter( - ... 'lig{f g a[UR] g f(Mx)}').parse().stream[Ligature].first + ... 'lig{f g a[UR] g f(Mx)}').parse().stream[Ligature].first() >>> print([n.mensuralType for n in tTNN.notes]) ['longa', 'brevis', 'semibrevis', 'semibrevis', 'maxima'] @@ -650,8 +650,11 @@ def convertBrevisLength(brevisLength, convertedStream, inpDiv=None, measureNumOf # .recurse() does not include the host stream (skipSelf default flipped # to True in music21 v5.5), so a `[1:]` here would silently drop a real - # element (typically the first note). Take the recurse output as-is. - mList = list(brevisLength.recurse()) + # element (typically the first note). Pull only mensural objects — the + # surrounding Clef/Divisione/Punctus ride along inside the Measure but + # contribute no note-length and would confuse BrevisLengthTranslator. + mList = [el for el in brevisLength.recurse() + if isinstance(el, medren.GeneralMensuralNote)] # Resolve the Divisione for this measure. Only one source is allowed: # either the enclosing context (inpDiv) OR an in-measure Divisione, not both. @@ -1008,20 +1011,24 @@ def getUnchangeableNoteLengths(self): unchangeableNoteLengthsList = [] for obj in self.brevisLength: minimaLength = None - # If its duration is set, doesn't need to be determined + # Non-mensural items (Clef, Divisione, Punctus, …) can legitimately + # sit inside the Measure but contribute no note-length. Skip them + # by entering None to keep the list aligned with self.brevisLength. + mensuralType = getattr(obj, 'mensuralType', None) # Gets rid of everything known - if obj.mensuralType == 'maxima': + if mensuralType == 'maxima': minimaLength = 4.0 * self.div.minimaPerBrevis - elif obj.mensuralType == 'longa': + elif mensuralType == 'longa': minimaLength = 2.0 * self.div.minimaPerBrevis - elif obj.mensuralType == 'brevis': + elif mensuralType == 'brevis': minimaLength = float(self.div.minimaPerBrevis) else: if not isinstance(obj, medren.GeneralMensuralNote): + unchangeableNoteLengthsList.append(None) continue # Dep on div - if obj.mensuralType == 'semibrevis': + if mensuralType == 'semibrevis': if isinstance(obj, medren.MensuralRest): if self.div.standardSymbol in ['.q.', '.i.']: minimaLength = self.div.minimaPerBrevis / 2.0 @@ -1034,14 +1041,14 @@ def getUnchangeableNoteLengths(self): minimaLength = 3.0 else: # Who the heck knows a semibreve's length!!! :-) pass - elif obj.mensuralType == 'minima': + elif mensuralType == 'minima': if isinstance(obj, medren.MensuralNote) and 'down' in obj.stems: raise TrecentoNotationException('Dragmas currently not supported') elif isinstance(obj, medren.MensuralNote) and 'side' in obj.stems: minimaLength = 1.5 else: minimaLength = 1.0 - elif obj.mensuralType == 'semiminima': + elif mensuralType == 'semiminima': pass unchangeableNoteLengthsList.append(minimaLength) return unchangeableNoteLengthsList @@ -1091,6 +1098,10 @@ def classifyUnknownNotesByType(self, unchangeableNoteLengthsList): knownLength = unchangeableNoteLengths[i] if knownLength is not None: continue + # Skip non-mensural items (Clef, Divisione, Punctus, ...) that + # ride along inside the Measure. + if not isinstance(obj, medren.GeneralMensuralNote): + continue if obj.mensuralType == 'semibrevis': if isinstance(obj, medren.MensuralRest): @@ -2106,14 +2117,8 @@ def processStream(mStream, pitches, lengths, downStems=None): else: print('norm only: %s' % SePerDureca[i + 1][j]) print('') - # TinySePerDureca.show('text') -class Test(unittest.TestCase): - - def runTest(self): - pass - if __name__ == '__main__': import music21 - music21.mainTest(Test, TestExternal, 'importPlusRelative') + music21.mainTest(TestExternal, 'importPlusRelative') diff --git a/music21_tools/trecento/polyphonicSnippet.py b/music21_tools/trecento/polyphonicSnippet.py index 4b7701c..9b8d6ea 100644 --- a/music21_tools/trecento/polyphonicSnippet.py +++ b/music21_tools/trecento/polyphonicSnippet.py @@ -352,11 +352,6 @@ def frontPadLine(self, thisStream): class Test(unittest.TestCase): - pass - - def runTest(self): - pass - def testCopyAndDeepcopy(self): ''' Test copying all objects defined in this module @@ -377,11 +372,6 @@ def testCopyAndDeepcopy(self): class TestExternal(unittest.TestCase): # pragma: no cover - pass - - def runTest(self): - pass - def testLily(self): from . import trecentoCadence, cadencebook cantus = trecentoCadence.CadenceConverter( diff --git a/music21_tools/trecento/quodJactatur.py b/music21_tools/trecento/quodJactatur.py index df4fb72..a07f8ab 100644 --- a/music21_tools/trecento/quodJactatur.py +++ b/music21_tools/trecento/quodJactatur.py @@ -39,13 +39,9 @@ without any problems. Working on this problem also gave a great test of music21's ability to manipulate diatonic Streams. ''' - import copy -import unittest - from music21 import clef -# from music21 import common from music21 import corpus from music21 import exceptions21 from music21 import instrument @@ -477,17 +473,3 @@ def multipleSolve(): class QuodJactaturException(exceptions21.Music21Exception): pass - -class Test(unittest.TestCase): - - def runTest(self): - pass - - -if __name__ == '__main__': - import music21 - music21.mainTest('importPlusRelative') - # bentWolfSolution() - # possibleSolution() - # findRetrogradeVoices() - pass diff --git a/music21_tools/trecento/runTrecentoCadence.py b/music21_tools/trecento/runTrecentoCadence.py index 2603b26..4e3d15d 100644 --- a/music21_tools/trecento/runTrecentoCadence.py +++ b/music21_tools/trecento/runTrecentoCadence.py @@ -10,7 +10,7 @@ ''' Python script to find out certain statistics about the trecento cadences ''' -import unittest +import music21 from . import cadencebook def countTimeSig(): @@ -163,24 +163,3 @@ def checkValidity(): unused_incipitStreams = randomPiece.incipitStreams() except music21.tinyNotation.TinyNotationException as inst: raise Exception(randomPiece.title + ' had problem ' + inst.args) - - -# temporarily commenting out for adding standard test approach -# if __name__ == "__main__" -# # countTimeSig() -# makePDFfromPiecesWithCapua() - - -# ------------------------------------------------------------------------------ -class Test(unittest.TestCase): - - def runTest(self): - pass - - def testA(self): - self.assertEqual(5, 5) # something really wrong!?? - -if __name__ == '__main__': - # makePDFfromPiecesWithCapua() - import music21 - music21.mainTest(Test, 'moduleRelative') diff --git a/music21_tools/trecento/tonality.py b/music21_tools/trecento/tonality.py index efb739d..98ae428 100644 --- a/music21_tools/trecento/tonality.py +++ b/music21_tools/trecento/tonality.py @@ -331,14 +331,10 @@ def testAll(show=True, fast=False): landiniTonality(show) class Test(unittest.TestCase): - pass - def runTest(self): testAll(show=False, fast=True) class TestExternal(unittest.TestCase): # pragma: no cover - pass - def runTest(self): testAll(show=True, fast=False) diff --git a/music21_tools/trecento/trecentoCadence.py b/music21_tools/trecento/trecentoCadence.py index 518c250..cf3e3ea 100644 --- a/music21_tools/trecento/trecentoCadence.py +++ b/music21_tools/trecento/trecentoCadence.py @@ -68,10 +68,6 @@ def __init__(self, stringRep=''): class Test(unittest.TestCase): - - def runTest(self): - pass - def testCopyAndDeepcopy(self): '''Test copying all objects defined in this module ''' @@ -89,7 +85,6 @@ def testCopyAndDeepcopy(self): self.assertNotEqual(a, obj) self.assertNotEqual(b, obj) - def testDotGroups(self): cn = CadenceConverter('c#2..') cn.parse() @@ -105,9 +100,6 @@ class TestExternal(unittest.TestCase): # pragma: no cover ''' These objects generate PNGs, etc. ''' - def runTest(self): - pass - def testTrecentoLine(self): ''' should display a 6 beat long line with some triplets diff --git a/publications/icmc2010.py b/publications/icmc2010.py index 09a00b3..9a77029 100644 --- a/publications/icmc2010.py +++ b/publications/icmc2010.py @@ -156,10 +156,6 @@ def oldAccent(show=True): class Test(unittest.TestCase): - - def runTest(self): - pass - def testBasic(self): '''icmc2010: Test non-showing functions ''' @@ -167,10 +163,6 @@ def testBasic(self): func(show=False) class TestExternal(unittest.TestCase): # pragma: no cover - - def runTest(self): - pass - def testBasic(self): '''Test showing functions ''' diff --git a/publications/icmc2011.py b/publications/icmc2011.py index 3976972..25b1d69 100644 --- a/publications/icmc2011.py +++ b/publications/icmc2011.py @@ -22,11 +22,6 @@ # ------------------------------------------------------------------------------ class Test(unittest.TestCase): - - def runTest(self): - pass - - def testStreams01(self): ''' Basic stream issues diff --git a/publications/ismir2010.py b/publications/ismir2010.py index 5b9898a..e1a6a52 100644 --- a/publications/ismir2010.py +++ b/publications/ismir2010.py @@ -606,10 +606,6 @@ def demoBachSearchBrief(): class Test(unittest.TestCase): - - def runTest(self): - pass - def testBasic(self): '''ismir2010: Test non-showing functions @@ -619,10 +615,6 @@ def testBasic(self): func(show=False) class TestExternal(unittest.TestCase): # pragma: no cover - - def runTest(self): - pass - def testBasic(self): for func in funcList: func(show=True) diff --git a/publications/seaverOct2009.py b/publications/seaverOct2009.py index 3651294..a41aaf6 100644 --- a/publications/seaverOct2009.py +++ b/publications/seaverOct2009.py @@ -492,10 +492,6 @@ def js_q5(): tests = [simple4a, simple4b, simple4c, simple4e, simple4f] class TestExternal(unittest.TestCase): # pragma: no cover - - def runTest(self): - pass - def testBasic(self): '''Test showing functions ''' @@ -509,18 +505,12 @@ def testSimple3(self): class Test(unittest.TestCase): - - def runTest(self): - pass - - def xtestBasic(self): '''seaverOct2009: Test non-showing functions ''' for func in tests: func(show=False) - if __name__ == "__main__": # js_q1() music21.mainTest(Test) diff --git a/publications/smt2010.py b/publications/smt2010.py index 1356047..da20146 100644 --- a/publications/smt2010.py +++ b/publications/smt2010.py @@ -8,16 +8,12 @@ # Copyright: Copyright © 2009-14 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ - - import unittest from music21 import corpus, converter, note, chord, stream, environment, graph, interval, meter _MOD = 'demo/smt2010.py' environLocal = environment.Environment(_MOD) - - def ex01(show=True, *arguments, **keywords): ''' This example extracts first a part, then a measure from a complete score. @@ -444,10 +440,6 @@ def chordifyAnalysisBrief(): # ------------------------------------------------------------------------------ class Test(unittest.TestCase): - - def runTest(self): - pass - def testBasic(self): ''' smt2010: Test non-showing functions @@ -459,7 +451,6 @@ def testBasic(self): # for func in [findPotentialPassingTones]: for func in [findHighestNotes, demoJesse, corpusMelodicIntervalSearchBrief, findPotentialPassingTones]: - # func(show=False, op133=sStream) func(show=False) From 30a57f9c84a3b69928ba61db584834ac32dd12e0 Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 17:03:18 -1000 Subject: [PATCH 20/28] wording --- music21_tools/trecento/medren.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/music21_tools/trecento/medren.py b/music21_tools/trecento/medren.py index 1d70f2a..3e5dcf1 100644 --- a/music21_tools/trecento/medren.py +++ b/music21_tools/trecento/medren.py @@ -1730,7 +1730,7 @@ def breakMensuralStreamIntoBrevisLengths(inpStream, inpMOrD=None, printUpdates=F violated by The normal case: a single flat ``Part`` carrying a Divisione at its head, - followed by mensural notes and Puncti. The function returns a ``Part`` + followed by mensural notes and puncti. The function returns a ``Part`` of ``Measure`` objects grouped by brevis-length, with the Divisione placed as the first element of the first Measure. @@ -1765,10 +1765,11 @@ def breakMensuralStreamIntoBrevisLengths(inpStream, inpMOrD=None, printUpdates=F because trecento divisione changes are only allowed at the highest stream level, not within a single voice. - >>> p.insert(5, Divisione('.p.')) + >>> p.insert(5.0, Divisione('.p.')) >>> breakMensuralStreamIntoBrevisLengths(p) Traceback (most recent call last): - music21_tools.trecento.medren.MedRenException: Mensuration or divisione not consistent within hierarchy + music21_tools.trecento.medren.MedRenException: Mensuration or + divisione not consistent within hierarchy ''' mOrD = inpMOrD mOrDInAsNone = True From fe24559d49f2cd8c238cf568fd337a07f989fab1 Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 17:04:33 -1000 Subject: [PATCH 21/28] efficiency warnings --- music21_tools/theoryAnalysis/theoryAnalyzer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/music21_tools/theoryAnalysis/theoryAnalyzer.py b/music21_tools/theoryAnalysis/theoryAnalyzer.py index 7daae34..8eb5ade 100644 --- a/music21_tools/theoryAnalysis/theoryAnalyzer.py +++ b/music21_tools/theoryAnalysis/theoryAnalyzer.py @@ -323,7 +323,7 @@ def getVerticalities(self, score, classFilterList=('Note', 'Chord', 'Harmony', ' classList=classFilterList) # el = part.flatten().getElementAtOrBefore(c.offset,classList=[ # 'Note', 'Rest', 'Chord', 'Harmony']) - for el in elementStream.elements: + for el in elementStream: contentDict[partNum].append(el) partNum += 1 else: @@ -332,7 +332,7 @@ def getVerticalities(self, score, classFilterList=('Note', 'Chord', 'Harmony', ' classList=classFilterList) # el = part.flatten().getElementAtOrBefore(c.offset, # classList=['Note', 'Rest', 'Chord', 'Harmony']) - for el in elementStream.elements: + for el in elementStream: contentDict[partNum].append(el) partNum += 1 From a8a64ced019b259288ea85bf9b91448a2760f0b0 Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 17:08:30 -1000 Subject: [PATCH 22/28] ruff and version bump --- music21_tools/audioSearchDemos/graphicalInterfaceSF.py | 2 +- music21_tools/bhadley/harmonyRealizer.py | 2 +- music21_tools/bhadley/nips2011.py | 6 +++--- music21_tools/composition/fadeChord1.py | 3 +-- music21_tools/misc/eschbeg.py | 9 ++++++--- music21_tools/theory/mgtaPart1.py | 6 +++--- pyproject.toml | 2 +- uv.lock | 2 +- 8 files changed, 17 insertions(+), 15 deletions(-) diff --git a/music21_tools/audioSearchDemos/graphicalInterfaceSF.py b/music21_tools/audioSearchDemos/graphicalInterfaceSF.py index a4f42b7..c2c6218 100644 --- a/music21_tools/audioSearchDemos/graphicalInterfaceSF.py +++ b/music21_tools/audioSearchDemos/graphicalInterfaceSF.py @@ -395,7 +395,7 @@ def moving(self): image=self.phimage[self.currentLeftPage + 1], tag='3rdImage') self.refreshTime = 40 - if self.ScF != None: + if self.ScF is not None: if self.ScF.scoreStream[self.ScF.lastNotePosition].measureNumber < ( self.pageMeasureNumbers[self.currentLeftPage + 1] + self.pageMeasureNumbers[self.currentLeftPage]) / 2.0: diff --git a/music21_tools/bhadley/harmonyRealizer.py b/music21_tools/bhadley/harmonyRealizer.py index 0600d72..275d21f 100644 --- a/music21_tools/bhadley/harmonyRealizer.py +++ b/music21_tools/bhadley/harmonyRealizer.py @@ -213,7 +213,7 @@ def xtestRealizeLeadsheet(self, music21Stream): if __name__ == '__main__': from music21 import base - base.mainTest(Test, TestExternal) + base.mainTest(TestExternal) # from music21 import corpus # from music21.demos.bhadley import HarmonyRealizer diff --git a/music21_tools/bhadley/nips2011.py b/music21_tools/bhadley/nips2011.py index 0106bf3..0f7119d 100644 --- a/music21_tools/bhadley/nips2011.py +++ b/music21_tools/bhadley/nips2011.py @@ -314,7 +314,7 @@ def getLeadsheetDatesFromBillboard(): if os.path.exists(dst): piece = converter.parse(dst) for year in DICT: - for title, group in DICT[year]: + for title, _group in DICT[year]: if piece.metadata.movementName.lower() == str(title).lower(): # or piece.metadata.composer == str(a): # print("Found by title! Name", piece.metadata.movementName, "Composer", piece.metadata.composer, str(year)) # print(dst) @@ -433,8 +433,8 @@ def BinomialProbability(n, k, p, q): prob = 0.0 # Probability of getting 148 or more correct (sum # the probabilty as k increses from 148 to 214) - for k in range(k, TOTAL_TRIALS): - prob = prob + BinomialProbability(n, k, p, q) + for ki in range(k, TOTAL_TRIALS): + prob = prob + BinomialProbability(n, ki, p, q) print('The probability that the computer would guess correctly 69% or more of the time', prob) diff --git a/music21_tools/composition/fadeChord1.py b/music21_tools/composition/fadeChord1.py index 661fc91..943a7e4 100644 --- a/music21_tools/composition/fadeChord1.py +++ b/music21_tools/composition/fadeChord1.py @@ -36,7 +36,6 @@ def main(): basis = cast(stream.Measure, converter.parse("tinynotation: 2/4 c16 d e f g a c' b") .getElementsByClass('Measure').first()) vols = [[1, 0, 1, 0, 1, 0, 1, 0] * reps] - smooths = smooth01(reps) for i, n in enumerate(basis.notes): n.volume.velocityScalar = vols[0][i] notes = basis[note.Note] @@ -51,7 +50,7 @@ def main(): notes[7].groups.append('B') part = stream.Part() - for rep_n in range(reps): + for _ in range(reps): new_measure = deepcopy(basis) part.append(new_measure) diff --git a/music21_tools/misc/eschbeg.py b/music21_tools/misc/eschbeg.py index 9b9b6cc..16dfe3d 100644 --- a/music21_tools/misc/eschbeg.py +++ b/music21_tools/misc/eschbeg.py @@ -22,9 +22,12 @@ eschbeg = '30ET47' def letterToNumber(letter): - if letter == 'E': number = 11 - elif letter == 'T': number = 10 - else: number = int(letter) + if letter == 'E': + number = 11 + elif letter == 'T': + number = 10 + else: + number = int(letter) return number def numberToLetter(number): diff --git a/music21_tools/theory/mgtaPart1.py b/music21_tools/theory/mgtaPart1.py index f4a98ee..50dfd1b 100644 --- a/music21_tools/theory/mgtaPart1.py +++ b/music21_tools/theory/mgtaPart1.py @@ -919,8 +919,8 @@ def ch2_writing_III_B(src): group = [] for n in s2.notesAndRests: # environLocal.printDebug([n, n.tie]) - if n.tie != None or len(group) > 0: - if n.tie != None and n.tie.type != 'stop': + if n.tie is not None or len(group) > 0: + if n.tie is not None and n.tie.type != 'stop': group.append(n) else: # end of tied notes group.append(n) @@ -1595,7 +1595,7 @@ def ch5_writing_IV_A(show=True, *arguments, **keywords): ('c#4', 1.5), ('b3', .5), ('a3', .5), ('c#4', .5), ('b3', .5), ('a3', .5), ('g#3', 2), ('f#3', 3), (None, .5), ('c#4', .5), ('c#4', .5), ('b3', .5), ('b3', .5), ('a#3', .5)]: - if p == None: + if p is None: n = note.Rest() else: n = note.Note(p) diff --git a/pyproject.toml b/pyproject.toml index a7709fe..45e97ec 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "hatchling.build" [project] name = "music21-tools" -version = "10.1.2" +version = "10.2.0" description = "Demonstrations and tools for music21." readme = "README.md" license = "BSD-3-Clause" diff --git a/uv.lock b/uv.lock index 214cc53..be76ce6 100644 --- a/uv.lock +++ b/uv.lock @@ -522,7 +522,7 @@ wheels = [ [[package]] name = "music21-tools" -version = "10.1.2" +version = "10.2.0" source = { editable = "." } dependencies = [ { name = "music21" }, From 0f77037356e6af52aa606ddd6906ffc335ce0349 Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 17:16:55 -1000 Subject: [PATCH 23/28] more ruff --- .../graphicalInterfaceGame.py | 6 ++-- .../audioSearchDemos/graphicalInterfaceSF.py | 33 +++++++++---------- .../audioSearchDemos/humanVScomputer.py | 7 ++-- .../audioSearchDemos/repetitionGame.py | 5 ++- music21_tools/bhadley/nips2011.py | 9 +++-- music21_tools/choraleTools/mnum_fixer.py | 2 +- music21_tools/composition/fadeChord1.py | 2 +- music21_tools/misc/monteverdi.py | 4 +-- .../theoryAnalysis/theoryAnalyzer.py | 8 ++--- music21_tools/theoryAnalysis/theoryResult.py | 4 +-- music21_tools/theoryAnalysis/wwnortonMGTA.py | 4 +-- music21_tools/trecento/cadencebook.py | 4 +-- music21_tools/trecento/notation.py | 9 ++--- music21_tools/trecento/runTrecentoCadence.py | 4 +-- 14 files changed, 50 insertions(+), 51 deletions(-) diff --git a/music21_tools/audioSearchDemos/graphicalInterfaceGame.py b/music21_tools/audioSearchDemos/graphicalInterfaceGame.py index 8be3dee..90c1b0d 100644 --- a/music21_tools/audioSearchDemos/graphicalInterfaceGame.py +++ b/music21_tools/audioSearchDemos/graphicalInterfaceGame.py @@ -8,12 +8,12 @@ # Copyright: Copyright © 2011-2026 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ -_DOC_IGNORE_MODULE_OR_PACKAGE = True - import math +import tkinter + from . import repetitionGame -import tkinter +_DOC_IGNORE_MODULE_OR_PACKAGE = True class SFApp(): diff --git a/music21_tools/audioSearchDemos/graphicalInterfaceSF.py b/music21_tools/audioSearchDemos/graphicalInterfaceSF.py index c2c6218..7455bff 100644 --- a/music21_tools/audioSearchDemos/graphicalInterfaceSF.py +++ b/music21_tools/audioSearchDemos/graphicalInterfaceSF.py @@ -8,16 +8,19 @@ # Copyright: Copyright © 2011-2026 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ -_DOC_IGNORE_MODULE_OR_PACKAGE = True +import math +import queue +import threading +import time +import tkinter from music21 import corpus from music21 import converter +from music21 import environment from music21 import exceptions21 -import threading -import queue -import tkinter -import time -import math +from music21 import scale +from music21.audioSearch import scoreFollower +# from music21.audioSearch import recording _missingImport = [] try: @@ -30,22 +33,18 @@ except ImportError: _missingImport.append('PIL') -from music21 import environment -_MOD = 'audioSearch/graphicalInterfaceSF.py' -environLocal = environment.Environment(_MOD) - -from music21.audioSearch import * -# from music21.audioSearch import recording -from music21 import scale - try: import AppKit except ImportError: try: import ctypes - except: + except ImportError: pass +_DOC_IGNORE_MODULE_OR_PACKAGE = True +_MOD = 'audioSearch/graphicalInterfaceSF.py' +environLocal = environment.Environment(_MOD) + # TO DO # the same name for the score and the song!!!! @@ -89,13 +88,13 @@ def __init__(self, master): # self.screenResolution = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1) environLocal.printDebug('screen resolution (windows) %d x %d' % (self.screenResolution[0], self.screenResolution[1])) self.resolution = True - except: # mac and linux + except Exception: # mac and linux try: for screen in AppKit.NSScreen.screens(): # @UndefinedVariable self.screenResolution = [int(screen.frame().size.width), int(screen.frame().size.height)] environLocal.printDebug('screen resolution (MAC or linux) %d x %d' % (self.screenResolution[0], self.screenResolution[1])) self.resolution = True - except: + except Exception: self.screenResolution = [1024, 600] environLocal.printDebug('screen resolution not detected') self.resolution = False diff --git a/music21_tools/audioSearchDemos/humanVScomputer.py b/music21_tools/audioSearchDemos/humanVScomputer.py index 33dbf83..eb8b145 100644 --- a/music21_tools/audioSearchDemos/humanVScomputer.py +++ b/music21_tools/audioSearchDemos/humanVScomputer.py @@ -8,13 +8,14 @@ # Copyright: Copyright © 2011-2026 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ -_DOC_IGNORE_MODULE_OR_PACKAGE = True +import time +import random from music21 import scale, note from music21 import audioSearch as base # from music21.audioSearch import * -import time -import random + +_DOC_IGNORE_MODULE_OR_PACKAGE = True diff --git a/music21_tools/audioSearchDemos/repetitionGame.py b/music21_tools/audioSearchDemos/repetitionGame.py index 409eaaa..9258769 100644 --- a/music21_tools/audioSearchDemos/repetitionGame.py +++ b/music21_tools/audioSearchDemos/repetitionGame.py @@ -8,12 +8,11 @@ # Copyright: Copyright © 2011-2026 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ -_DOC_IGNORE_MODULE_OR_PACKAGE = True - - from music21 import scale from music21 import audioSearch as base +_DOC_IGNORE_MODULE_OR_PACKAGE = True + class repetitionGame(): diff --git a/music21_tools/bhadley/nips2011.py b/music21_tools/bhadley/nips2011.py index 0f7119d..2102cfa 100644 --- a/music21_tools/bhadley/nips2011.py +++ b/music21_tools/bhadley/nips2011.py @@ -33,10 +33,9 @@ orngTree = None try: - import BeautifulSoup - from BeautifulSoup import * + from BeautifulSoup import BeautifulSoup except ImportError: - pass + BeautifulSoup = None from music21 import common from music21 import features @@ -222,7 +221,7 @@ def getLeadsheetDatesFromBillboard(): try: j = float(x) continue - except: + except (ValueError, TypeError): song = False y = pretty continue @@ -281,7 +280,7 @@ def getLeadsheetDatesFromBillboard(): try: j = float(x) continue - except: + except (ValueError, TypeError): if cnt < 100: groups.append(str(x)) else: diff --git a/music21_tools/choraleTools/mnum_fixer.py b/music21_tools/choraleTools/mnum_fixer.py index 8d8aae6..63d3793 100644 --- a/music21_tools/choraleTools/mnum_fixer.py +++ b/music21_tools/choraleTools/mnum_fixer.py @@ -9,7 +9,7 @@ # ------------------------------------------------------------------------------ from pathlib import Path -from music21 import * +from music21 import converter, corpus, musicxml p = Path('/Users/Cuthbert/Desktop/Norman_Schmidt_Chorales') pOut = p.parent / 'Out_Chorales' diff --git a/music21_tools/composition/fadeChord1.py b/music21_tools/composition/fadeChord1.py index 943a7e4..725aa41 100644 --- a/music21_tools/composition/fadeChord1.py +++ b/music21_tools/composition/fadeChord1.py @@ -15,7 +15,7 @@ import math -from music21 import * +from music21 import converter, note, stream def smooth01(steps): diff --git a/music21_tools/misc/monteverdi.py b/music21_tools/misc/monteverdi.py index 6291e45..3f1deed 100644 --- a/music21_tools/misc/monteverdi.py +++ b/music21_tools/misc/monteverdi.py @@ -198,8 +198,8 @@ def monteverdiParallels(books=(3,), start=1, end=20, show=True, strict=False): try: c = corpus.parse(filename) print(book, i) - except: - print('Cannot parse %s, maybe it does not exist...' % (filename)) + except Exception: + print(f'Cannot parse {filename}, maybe it does not exist...') continue displayMe = False for i in range(len(c.parts) - 1): diff --git a/music21_tools/theoryAnalysis/theoryAnalyzer.py b/music21_tools/theoryAnalysis/theoryAnalyzer.py index 8eb5ade..255bf81 100644 --- a/music21_tools/theoryAnalysis/theoryAnalyzer.py +++ b/music21_tools/theoryAnalysis/theoryAnalyzer.py @@ -303,7 +303,7 @@ def getVerticalities(self, score, classFilterList=('Note', 'Chord', 'Harmony', ' sid = score.id self.addAnalysisData(score) if ('Verticalities' in self.store[sid] - and self.store[sid]['Verticalities'] != None): + and self.store[sid]['Verticalities'] is not None): return self.store[sid]['Verticalities'] # if elements exist at same offset, return both @@ -524,7 +524,7 @@ def getLinearSegments(self, score, partNum, lengthLinearSegment, classFilterList def _getTypeOfAllObjects(self, objectList): setList = [] for obj in objectList: - if obj != None: + if obj is not None: setList.append(set(obj.classes) ) if setList: @@ -794,7 +794,7 @@ def _identifyBasedOnVLQ(self, score, partNum1, partNum2, dictKey, tr.text = tr.value else: tr.text = textFunction(vlq, partNum1, partNum2) - if editorialDictKey != None: + if editorialDictKey is not None: tr.markNoteEditorial(editorialDictKey, editorialValue, editorialMarkList) if color is not None: tr.color(color) @@ -908,7 +908,7 @@ def _identifyBasedOnVerticalityNTuplet(self, score, partNumToIdentify, dictKey, for vsnt in self.getVerticalityNTuplets(score, nTupletNum): if testFunction(vsnt, partNumToIdentify) is not False: tr = theoryResult.VerticalityNTupletTheoryResult(vsnt, partNumToIdentify) - if editorialDictKey != None: + if editorialDictKey is not None: tr.markNoteEditorial(editorialDictKey, editorialValue, editorialMarkDict) if textFunction is not None: tr.text = textFunction(vsnt, partNumToIdentify) diff --git a/music21_tools/theoryAnalysis/theoryResult.py b/music21_tools/theoryAnalysis/theoryResult.py index 15360d0..b3e0ad8 100644 --- a/music21_tools/theoryAnalysis/theoryResult.py +++ b/music21_tools/theoryAnalysis/theoryResult.py @@ -253,12 +253,12 @@ def color(self, color ='red', partNum=None, noteList=None): ''' if noteList is None: noteList = [] - if partNum != None: + if partNum is not None: print('color...', partNum, self.partNumIdentified, self.vsnt.nTupletNum, self.vsnt.tnlsDict.keys()) if self.vsnt.nTupletNum == 3: self.vsnt.tnlsDict[partNum].color(color) - elif self.partNumIdentified != None: + elif self.partNumIdentified is not None: if self.vsnt.nTupletNum == 3: self.vsnt.tnlsDict[self.partNumIdentified].color(color, [2] ) diff --git a/music21_tools/theoryAnalysis/wwnortonMGTA.py b/music21_tools/theoryAnalysis/wwnortonMGTA.py index 975abdb..03aad5e 100644 --- a/music21_tools/theoryAnalysis/wwnortonMGTA.py +++ b/music21_tools/theoryAnalysis/wwnortonMGTA.py @@ -9,8 +9,6 @@ # Copyright: Copyright © 2009-2026 Michael Scott Asato Cuthbert # License: BSD, see license.txt # ------------------------------------------------------------------------------ -_DOC_IGNORE_MODULE_OR_PACKAGE = True - import copy from music21 import converter from music21 import stream @@ -18,6 +16,8 @@ from music21 import note from . import theoryAnalyzer +_DOC_IGNORE_MODULE_OR_PACKAGE = True + class wwnortonExercise: ''' diff --git a/music21_tools/trecento/cadencebook.py b/music21_tools/trecento/cadencebook.py index d38c5c5..85b5a9a 100644 --- a/music21_tools/trecento/cadencebook.py +++ b/music21_tools/trecento/cadencebook.py @@ -21,8 +21,6 @@ import xlrd -_THIS_DIR = os.path.dirname(os.path.abspath(__file__)) - from music21 import duration from music21 import expressions from music21 import metadata @@ -31,6 +29,8 @@ from . import trecentoCadence from . import polyphonicSnippet +_THIS_DIR = os.path.dirname(os.path.abspath(__file__)) + class TrecentoSheet: ''' A TrecentoSheet represents a single worksheet of an Excel spreadsheet diff --git a/music21_tools/trecento/notation.py b/music21_tools/trecento/notation.py index 74c3672..b62c718 100644 --- a/music21_tools/trecento/notation.py +++ b/music21_tools/trecento/notation.py @@ -30,16 +30,17 @@ from music21 import meter from music21 import text -from ._base import MedievalMeter +from music21 import environment from music21 import note from music21 import stream from music21 import tie from music21 import tinyNotation -from music21 import environment -_MOD = 'trecento/notation.py' -environLocal = environment.Environment(_MOD) from . import medren +from ._base import MedievalMeter + +_MOD = 'trecento/notation.py' +environLocal = environment.Environment(_MOD) _validDivisiones = { (None, None): 0, diff --git a/music21_tools/trecento/runTrecentoCadence.py b/music21_tools/trecento/runTrecentoCadence.py index 4e3d15d..a56aaf8 100644 --- a/music21_tools/trecento/runTrecentoCadence.py +++ b/music21_tools/trecento/runTrecentoCadence.py @@ -118,8 +118,8 @@ def makePDFfromPiecesWithCapua(start=2, finish=3): randomPiece = ballataObj.makeWork( i ) # if randomPiece.incipit: retrievedPieces.append(randomPiece) - except: - raise Exception('Could not retrieve random piece at index ' + str(i)) + except Exception as exc: + raise Exception(f'Could not retrieve random piece at index {i}') from exc # lilyString = "" # retrievedPieces.sort(key=sortByPMFC) From 6eaa879c13d05e4aa9437db38cf41624fde322ea Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 21:36:09 -1000 Subject: [PATCH 24/28] set line widths --- .../graphicalInterfaceGame.py | 3 +- .../audioSearchDemos/graphicalInterfaceSF.py | 24 ++++++---- .../audioSearchDemos/humanVScomputer.py | 9 ++-- music21_tools/bhadley/harmonyRealizer.py | 13 +++--- music21_tools/bhadley/nips2011.py | 43 ++++++++++++------ music21_tools/chant/chant.py | 3 +- music21_tools/contour/contour.py | 3 +- music21_tools/featureExtraction/ismir2011.py | 8 +++- music21_tools/misc/gatherAccidentals.py | 3 +- music21_tools/misc/monteverdi.py | 9 ++-- music21_tools/theory/mgtaPart1.py | 44 ++++++++++++++----- music21_tools/theory/mgtaPart2.py | 3 +- .../theoryAnalysis/theoryAnalyzer.py | 11 +++-- music21_tools/trecento/capua.py | 3 +- music21_tools/trecento/medren.py | 15 ++++--- pyproject.toml | 7 +++ 16 files changed, 139 insertions(+), 62 deletions(-) diff --git a/music21_tools/audioSearchDemos/graphicalInterfaceGame.py b/music21_tools/audioSearchDemos/graphicalInterfaceGame.py index 90c1b0d..af7c770 100644 --- a/music21_tools/audioSearchDemos/graphicalInterfaceGame.py +++ b/music21_tools/audioSearchDemos/graphicalInterfaceGame.py @@ -71,7 +71,8 @@ def callback(self): self.boxName4.grid(row=2, column=2) self.textRound = tkinter.StringVar() - self.boxName5 = tkinter.Label(master, width=2 * self.sizeButton, textvariable=self.textRound) + self.boxName5 = tkinter.Label(master, width=2 * self.sizeButton, + textvariable=self.textRound) self.textRound.set('Round') self.boxName5.grid(row=2, column=1) diff --git a/music21_tools/audioSearchDemos/graphicalInterfaceSF.py b/music21_tools/audioSearchDemos/graphicalInterfaceSF.py index 7455bff..0bf0bb3 100644 --- a/music21_tools/audioSearchDemos/graphicalInterfaceSF.py +++ b/music21_tools/audioSearchDemos/graphicalInterfaceSF.py @@ -60,15 +60,19 @@ def __init__(self, master): self.master.wm_title('Score follower - music21') self.scoreNameSong = 'scores/d luca gloria_Page_' - # '/Users/cuthbert/Desktop/scores/Saint-Saens-Clarinet-Sonata/Saint-Saens-Clarinet-Sonata_Page_' - # C:\Users\Jordi\Desktop\m21\Saint-Saens-Clarinet-Sonata\Saint-Saens-Clarinet-Sonata\Saint-Saens-Clarinet-Sonata_Page_' + # '/Users/cuthbert/Desktop/scores/Saint-Saens-Clarinet-Sonata/' + # 'Saint-Saens-Clarinet-Sonata_Page_' + # C:\Users\Jordi\Desktop\m21\Saint-Saens-Clarinet-Sonata\ + # Saint-Saens-Clarinet-Sonata\Saint-Saens-Clarinet-Sonata_Page_' #'scores/d luca gloria_Page_' #'scores/d luca gloria_Page_' self.format = 'tiff'#'jpg' self.nameRecordedSong = 'luca/gloria' # '/Users/cuthbert/Desktop/scores/Saint-Saens-Clarinet-Sonata/saint-saens.xml' - # 'C:\Users\Jordi\Desktop\m21\Saint-Saens-Clarinet-Sonata\Saint-Saens-Clarinet-Sonata\saint-saens.xml' - self.pageMeasureNumbers = [] # get directly from score - the last one is the last note of the score + # 'C:\Users\Jordi\Desktop\m21\Saint-Saens-Clarinet-Sonata\ + # Saint-Saens-Clarinet-Sonata\saint-saens.xml' + # get directly from score — the last entry is the last note + self.pageMeasureNumbers = [] self.totalPagesScore = 1 self.currentLeftPage = 1 self.pagesScore = [] @@ -86,13 +90,16 @@ def __init__(self, master): unused_user32 = ctypes.windll.user32 # test for error... self.screenResolution = [1024, 600] # self.screenResolution = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1) - environLocal.printDebug('screen resolution (windows) %d x %d' % (self.screenResolution[0], self.screenResolution[1])) + environLocal.printDebug('screen resolution (windows) %d x %d' + % (self.screenResolution[0], self.screenResolution[1])) self.resolution = True except Exception: # mac and linux try: for screen in AppKit.NSScreen.screens(): # @UndefinedVariable - self.screenResolution = [int(screen.frame().size.width), int(screen.frame().size.height)] - environLocal.printDebug('screen resolution (MAC or linux) %d x %d' % (self.screenResolution[0], self.screenResolution[1])) + self.screenResolution = [int(screen.frame().size.width), + int(screen.frame().size.height)] + environLocal.printDebug('screen resolution (MAC or linux) %d x %d' + % (self.screenResolution[0], self.screenResolution[1])) self.resolution = True except Exception: self.screenResolution = [1024, 600] @@ -477,7 +484,8 @@ def pageBackward(self): self.canvas1.grid(row=1, column=0, columnspan=3, rowspan=7) self.currentLeftPage -= 1 - environLocal.printDebug('page Backward %d %d' % (self.currentLeftPage, self.totalPagesScore)) + environLocal.printDebug('page Backward %d %d' + % (self.currentLeftPage, self.totalPagesScore)) def goTo1stPage(self): self.currentLeftPage = 1 diff --git a/music21_tools/audioSearchDemos/humanVScomputer.py b/music21_tools/audioSearchDemos/humanVScomputer.py index eb8b145..9e77d63 100644 --- a/music21_tools/audioSearchDemos/humanVScomputer.py +++ b/music21_tools/audioSearchDemos/humanVScomputer.py @@ -48,8 +48,10 @@ def runGame(): freqFromAQList = base.getFrequenciesFromMicrophone(length=seconds, storeWaveFilename=None) detectedPitchesFreq = base.detectPitchFrequencies(freqFromAQList, useScale) detectedPitchesFreq = base.smoothFrequencies(detectedPitchesFreq) - (detectedPitchObjects, unused_listplot) = base.pitchFrequenciesToObjects(detectedPitchesFreq, useScale) - (notesList, unused_durationList) = base.joinConsecutiveIdenticalPitches(detectedPitchObjects) + (detectedPitchObjects, + unused_listplot) = base.pitchFrequenciesToObjects(detectedPitchesFreq, useScale) + (notesList, + unused_durationList) = base.joinConsecutiveIdenticalPitches(detectedPitchObjects) j = 0 i = 0 while i < len(notesList) and j < len(gameNotes) and good: @@ -59,7 +61,8 @@ def runGame(): i = i + 1 j = j + 1 else: - print('Wrong note. You played', notesList[i].fullName, 'and it should have been', gameNotes[j].fullName) + print('Wrong note. You played', notesList[i].fullName, + 'and it should have been', gameNotes[j].fullName) good = False if good and j != len(gameNotes): diff --git a/music21_tools/bhadley/harmonyRealizer.py b/music21_tools/bhadley/harmonyRealizer.py index 275d21f..7b9948f 100644 --- a/music21_tools/bhadley/harmonyRealizer.py +++ b/music21_tools/bhadley/harmonyRealizer.py @@ -178,7 +178,8 @@ def realizeclercqTemperleyEx(self, testfile): testFile1 = s.toScore() testFile = harmony.realizeChordSymbolDurations(testFile1) - smoothBassRN = generateSmoothBassLine(testFile.flatten().getElementsByClass(roman.RomanNumeral)) + smoothBassRN = generateSmoothBassLine( + testFile.flatten().getElementsByClass(roman.RomanNumeral)) output = generateContrapuntalBassLine(smoothBassRN, generateBaroqueRules()) output.insert(metadata.Metadata()) @@ -194,7 +195,8 @@ def testLeadsheetEx1(self): testFile1.insert(metadata.Metadata()) testFile1.metadata.title = 'Jeanie With The Light Brown Hair' testFile = harmony.realizeChordSymbolDurations(testFile1) - smoothBassCS = generateSmoothBassLine(testFile.flatten().getElementsByClass(harmony.ChordSymbol)) + smoothBassCS = generateSmoothBassLine( + testFile.flatten().getElementsByClass(harmony.ChordSymbol)) output = generateContrapuntalBassLine(smoothBassCS, generatePopSongRules()) mergeLeadSheetAndBassLine(testFile1, output).show() @@ -206,7 +208,8 @@ def xtestRealizeLeadsheet(self, music21Stream): ''' testFile = harmony.realizeChordSymbolDurations(music21Stream) - smoothBassCS = generateSmoothBassLine(testFile.flatten().getElementsByClass(harmony.ChordSymbol)) + smoothBassCS = generateSmoothBassLine( + testFile.flatten().getElementsByClass(harmony.ChordSymbol)) output = generateContrapuntalBassLine(smoothBassCS, generatePopSongRules()) mergeLeadSheetAndBassLine(music21Stream, output).show() @@ -220,9 +223,7 @@ def xtestRealizeLeadsheet(self, music21Stream): # test = HarmonyRealizer.TestExternal() # test.leadsheetEx1() - # sc = converter.parse('https://github.com/cuthbertLab/music21/raw/master/music21/corpus/leadSheet/fosterBrownHair.mxl') # Jeannie Light Brown Hair - - + # sc = corpus.parse('leadSheet/fosterBrownHair') # Jeannie Light Brown Hair testfile1 = ''' % Dylan - Blowin' in the Wind diff --git a/music21_tools/bhadley/nips2011.py b/music21_tools/bhadley/nips2011.py index 2102cfa..2b3204d 100644 --- a/music21_tools/bhadley/nips2011.py +++ b/music21_tools/bhadley/nips2011.py @@ -53,7 +53,7 @@ def nipsBuild(useOurExtractors=True, buildSet=1, evaluationMethod='coarse'): # here are all the pieces by id and their year and billboard chart number (not used) # this data found by Beth Hadley - entries = json.loads('''[{"1024":[2009,48]}, {"1028":[1961,56]}, {"1034":[1986,9]}, {"1054":[1971,12]}, {"1070":[1982,34]}, {"1081":[2006,55]}, {"1099":[1973,11]}, {"1105":[1952,13]}, {"1347":[2003,30]}, {"1384":[1993,27]}, {"1402":[2009,50]}, {"1459":[1969,2]}, {"1722":[1982,2]}, {"1742":[1959,3]}, {"1904":[1964,9]}, {"1905":[1967,18]}, {"1906":[1967,20]}, {"1907":[1964,8]}, {"1912":[1977,44]}, {"1922":[1954,94]}, {"1930":[1999,6]}, {"1934":[1985,10]}, {"1940":[1970,3]}, {"2045":[1961,7]}, {"2049":[1961,12]}, {"2125":[1959,19]}, {"2167":[1965,88]}, {"2170":[1957,68]}, {"2374":[1963,14]}, {"2387":[1950,4]}, {"2405":[1974,2]}, {"2431":[1985,15]}, {"2447":[1960,3]}, {"2448":[1982,28]}, {"2462":[1951,33]}, {"2519":[1965,7]}, {"2521":[1978,23]}, {"2523":[1955,16]}, {"2533":[1976,52]}, {"2546":[1952,50]}, {"2665":[2004,2]}, {"2688":[1973,45]}, {"2709":[2009,5]}, {"2729":[2004,2]}, {"2735":[2009,60]}, {"2742":[1970,98]}, {"2774":[1967,10]}, {"2776":[1952,46]}, {"2777":[1969,47]}, {"2833":[1957,34]}, {"2834":[1957,37]}, {"2838":[1956,8]}, {"2967":[1973,31]}, {"2984":[1987,14]}, {"2985":[1977,41]}, {"2994":[1967,76]}, {"3012":[1963,28]}, {"3153":[1963,5]}, {"3154":[1963,5]}, {"3155":[1965,9]}, {"3157":[1978,36]}, {"3195":[1975,65]}, {"3218":[1992,6]}, {"3226":[1963,58]}, {"3229":[1958,42]}, {"3232":[1979,10]}, {"3241":[1972,3]}, {"3242":[1977,12]}, {"3243":[1970,45]}, {"3275":[1965,8]}, {"3281":[1954,28]}, {"3282":[1991,15]}, {"3285":[1974,33]}, {"3299":[1956,57]}, {"3300":[1953,8]}, {"3301":[1957,47]}, {"3311":[1954,9]}, {"3323":[1954,28]}, {"3324":[1987,14]}, {"3379":[1962,25]}, {"3402":[1961,2]}, {"3409":[1972,12]}, {"3420":[1954,78]}, {"3452":[1971,85]}, {"3466":[1962,46]}, {"3477":[1960,13]}, {"3484":[1983,59]}, {"3532":[1961,15]}, {"3548":[1970,20]}, {"3554":[1981,53]}, {"3558":[1981,62]}, {"3668":[1953,73]}, {"3681":[1954,2]}, {"3687":[1957,11]}, {"3688":[1957,11]}, {"3689":[1962,15]}, {"3690":[1955,17]}, {"3717":[1955,5]}, {"3718":[1962,4]}, {"3719":[1958,48]}, {"3732":[1954,95]}, {"3749":[1953,3]}, {"3755":[1970,93]}, {"3764":[1958,44]}, {"3765":[1974,94]}, {"3772":[1973,71]}, {"3784":[1961,95]}, {"3785":[1950,17]}, {"3786":[1951,15]}, {"3821":[1954,66]}, {"3834":[1963,3]}, {"3845":[1985,65]}, {"3866":[1957,48]}, {"3871":[1950,82]}, {"3911":[1967,23]}, {"3928":[1959,52]}, {"3979":[1989,70]}, {"3980":[1963,10]}, {"4016":[1951,34]}, {"4022":[1956,98]}, {"4044":[1952,54]}, {"4051":[1984,56]}, {"4073":[1980,90]}, {"4117":[1976,1]}, {"4139":[1951,5]}, {"4252":[1950,14]}, {"4286":[1959,12]}, {"4288":[1965,43]}, {"4294":[1961,75]}, {"4318":[1960,10]}, {"4320":[1961,5]}, {"4335":[1966,62]}, {"4341":[1970,41]}, {"4343":[1964,2]}, {"4353":[1961,55]}, {"4354":[1962,21]}, {"4356":[1955,4]}, {"4357":[1966,23]}, {"4400":[1967,52]}, {"4438":[1965,71]}, {"4439":[1951,9]}, {"4462":[1968,42]}, {"4464":[1964,27]}, {"4470":[1987,38]}, {"4492":[1961,31]}, {"4494":[1952,65]}, {"4503":[1953,91]}, {"4504":[1953,35]}, {"4505":[1953,35]}, {"4514":[1970,51]}, {"4537":[1954,21]}, {"4538":[1956,4]}, {"4567":[1962,93]}, {"4575":[1960,19]}, {"4576":[1962,27]}, {"4618":[1998,13]}, {"4621":[1954,67]}, {"4643":[1970,2]}, {"4645":[1966,44]}, {"4649":[1953,40]}, {"4656":[1974,86]}, {"4657":[1984,25]}, {"4679":[1966,33]}, {"4728":[1974,56]}, {"4732":[2005,43]}, {"4740":[1964,33]}, {"4741":[1963,24]}, {"4742":[1970,18]}, {"4750":[1968,2]}, {"4773":[1971,98]}, {"4791":[1966,28]}, {"4795":[1983,96]}, {"4807":[1956,81]}, {"4837":[1950,5]}, {"4889":[1967,84]}, {"4897":[1957,67]}, {"4963":[1991,58]}, {"4978":[1959,51]}, {"4979":[1956,49]}, {"5002":[1956,3]}, {"5023":[1974,60]}, {"5025":[1977,22]}, {"5195":[1954,1]}, {"5228":[1963,65]}, {"5280":[1970,64]}, {"5296":[1955,62]}, {"5300":[1952,43]}, {"5346":[1955,52]}, {"5356":[1981,29]}, {"5367":[1964,54]}, {"5376":[1970,48]}, {"5391":[1982,31]}, {"5394":[1976,30]}, {"5431":[1974,8]}, {"5432":[1962,6]}, {"5480":[1971,49]}, {"5489":[1969,85]}, {"5506":[1960,98]}, {"5522":[1968,50]}, {"5541":[1972,90]}, {"5544":[2001,92]}, {"5547":[1975,70]}, {"5551":[1975,67]}, {"5556":[1999,29]}, {"5567":[1970,80]}, {"5579":[1981,8]}, {"5615":[1972,15]}, {"5631":[1954,81]}, {"5648":[1953,2]}, {"5652":[1950,63]}, {"5653":[1957,98]}, {"5702":[1959,81]}, {"5766":[1956,21]}, {"5768":[1959,47]}, {"5790":[1959,96]}, {"5794":[1957,3]}, {"5798":[1958,94]}, {"5805":[1979,63]}, {"5808":[1958,14]}, {"5810":[2001,5]}, {"5816":[1958,31]}, {"5825":[1959,61]}, {"5837":[1980,5]}, {"5838":[1995,34]}, {"5840":[1974,41]}, {"5841":[1973,35]}, {"5844":[1973,78]}, {"5882":[1954,90]}, {"5883":[1961,63]}, {"5893":[1981,31]}, {"5894":[1981,31]}, {"5936":[1981,30]}, {"5957":[1970,42]}, {"5976":[1992,41]}, {"5983":[1969,21]}, {"5987":[1970,90]}, {"5989":[1975,48]}, {"5990":[1978,37]}, {"6001":[1966,37]}, {"6002":[1969,92]}, {"6022":[1982,77]}, {"6023":[1988,39]}, {"6024":[1977,1]}, {"6042":[1981,2]}, {"6049":[1977,99]}, {"6050":[1956,10]}, {"6052":[1962,77]}, {"6053":[1964,29]}, {"6063":[1957,65]}, {"6065":[1956,15]}, {"6067":[1966,91]}, {"6069":[1987,69]}, {"6073":[1983,53]}, {"6091":[1950,95]}, {"6135":[1962,82]}, {"6151":[1978,18]}, {"6156":[1961,6]}, {"6164":[1954,60]}, {"6169":[1959,54]}, {"6185":[1958,25]}, {"6191":[2005,86]}, {"6239":[1970,24]}, {"6294":[1994,30]}, {"6301":[1952,17]}, {"6354":[2003,3]}, {"6370":[1987,55]}, {"6389":[1961,32]}, {"6398":[1965,15]}, {"6404":[1961,1]}, {"6426":[1992,100]}, {"6430":[1993,32]}, {"6444":[2010,32]}, {"6448":[1958,74]}, {"6476":[1955,12]}, {"6493":[1992,64]}, {"6523":[2007,76]}, {"6528":[1981,18]}, {"6563":[1960,12]}, {"6592":[1998,60]}, {"6689":[1960,20]}, {"6703":[1968,75]}, {"6722":[1955,12]}, {"6773":[1953,100]}, {"6903":[1958,24]}, {"6910":[1962,61]}, {"6961":[1981,35]}, {"6975":[1964,14]}, {"7030":[1958,34]}, {"7038":[1979,26]}, {"7083":[1970,91]}, {"7123":[1957,83]}, {"7228":[1971,2]}, {"7268":[1984,22]}, {"7409":[1994,96]}, {"7418":[1959,98]}, {"7660":[1950,80]}, {"7742":[1999,59]}, {"7790":[1956,14]}, {"7818":[1966,2]}, {"7837":[1972,42]}, {"7838":[1984,15]}, {"7914":[1960,29]}, {"7923":[1950,74]}, {"7925":[1993,87]}, {"7961":[1952,53]}, {"7965":[1959,87]}, {"8006":[1951,4]}, {"8016":[1997,75]}, {"8045":[1987,6]}, {"8103":[2010,74]}, {"8145":[1986,4]}, {"8192":[1970,67]}, {"8216":[1974,35]}, {"8243":[2008,98]}, {"8328":[1976,15]}, {"8364":[1970,65]}, {"8441":[1961,14]}, {"8448":[1962,90]}, {"8557":[1958,48]}, {"8678":[1967,74]}, {"8763":[1955,12]}, {"8855":[1962,74]}, {"8862":[1978,9]}, {"8884":[2009,2]}, {"8887":[2010,18]}, {"8915":[1974,74]}, {"8967":[1974,74]}, {"8999":[1963,3]}, {"9025":[1972,84]}, {"9026":[1971,78]}, {"9177":[1966,50]}, {"9192":[1961,2]}, {"9203":[1960,85]}, {"9224":[1970,69]}, {"9254":[1976,55]}, {"9264":[1973,95]}, {"9266":[1974,31]}, {"9294":[1994,2]}, {"9298":[1969,23]}, {"9322":[1952,81]}, {"9369":[1958,1]}, {"9618":[2007,25]}, {"9652":[2009,63]}, {"9673":[1965,64]}, {"9699":[1987,10]}, {"9883":[1973,67]}, {"9914":[1991,58]}, {"9918":[2010,6]}, {"9945":[1997,32]}, {"9954":[1959,80]}, {"9969":[1966,65]}, {"9983":[1987,14]}, {"9999":[1999,59]}, {"10052":[1969,64]}, {"10075":[1967,49]}, {"10118":[1961,18]}, {"10226":[2009,11]}, {"10234":[1979,14]}, {"10247":[1987,74]}, {"10260":[1970,82]}, {"10265":[1961,7]}, {"10269":[1989,39]}, {"10318":[1978,20]}, {"10320":[1970,35]}, {"10321":[1971,2]}, {"10395":[1968,33]}, {"10466":[1970,12]}, {"10571":[1985,84]}, {"10602":[1963,28]}, {"10604":[1965,25]}, {"10636":[1951,15]}, {"10656":[2010,42]}, {"10663":[1962,1]}, {"10703":[1969,25]}, {"10767":[1959,3]}, {"11007":[1994,31]}, {"11050":[1971,51]}, {"11103":[1986,39]}, {"11150":[1970,36]}, {"11158":[1961,14]}, {"11281":[2009,7]}, {"11284":[1967,41]}, {"11604":[2003,92]}, {"11665":[1992,64]}, {"11667":[1993,18]}, {"11733":[1964,41]}, {"11756":[1951,25]}, {"11767":[1973,66]}, {"11781":[1965,62]}, {"11785":[1979,20]}, {"11807":[1958,26]}, {"11857":[1958,22]}, {"12187":[2009,60]}, {"12275":[1959,98]}, {"12514":[2007,76]}, {"12899":[1958,2]}]''') + entries = json.loads('''[{"1024":[2009,48]}, {"1028":[1961,56]}, {"1034":[1986,9]}, {"1054":[1971,12]}, {"1070":[1982,34]}, {"1081":[2006,55]}, {"1099":[1973,11]}, {"1105":[1952,13]}, {"1347":[2003,30]}, {"1384":[1993,27]}, {"1402":[2009,50]}, {"1459":[1969,2]}, {"1722":[1982,2]}, {"1742":[1959,3]}, {"1904":[1964,9]}, {"1905":[1967,18]}, {"1906":[1967,20]}, {"1907":[1964,8]}, {"1912":[1977,44]}, {"1922":[1954,94]}, {"1930":[1999,6]}, {"1934":[1985,10]}, {"1940":[1970,3]}, {"2045":[1961,7]}, {"2049":[1961,12]}, {"2125":[1959,19]}, {"2167":[1965,88]}, {"2170":[1957,68]}, {"2374":[1963,14]}, {"2387":[1950,4]}, {"2405":[1974,2]}, {"2431":[1985,15]}, {"2447":[1960,3]}, {"2448":[1982,28]}, {"2462":[1951,33]}, {"2519":[1965,7]}, {"2521":[1978,23]}, {"2523":[1955,16]}, {"2533":[1976,52]}, {"2546":[1952,50]}, {"2665":[2004,2]}, {"2688":[1973,45]}, {"2709":[2009,5]}, {"2729":[2004,2]}, {"2735":[2009,60]}, {"2742":[1970,98]}, {"2774":[1967,10]}, {"2776":[1952,46]}, {"2777":[1969,47]}, {"2833":[1957,34]}, {"2834":[1957,37]}, {"2838":[1956,8]}, {"2967":[1973,31]}, {"2984":[1987,14]}, {"2985":[1977,41]}, {"2994":[1967,76]}, {"3012":[1963,28]}, {"3153":[1963,5]}, {"3154":[1963,5]}, {"3155":[1965,9]}, {"3157":[1978,36]}, {"3195":[1975,65]}, {"3218":[1992,6]}, {"3226":[1963,58]}, {"3229":[1958,42]}, {"3232":[1979,10]}, {"3241":[1972,3]}, {"3242":[1977,12]}, {"3243":[1970,45]}, {"3275":[1965,8]}, {"3281":[1954,28]}, {"3282":[1991,15]}, {"3285":[1974,33]}, {"3299":[1956,57]}, {"3300":[1953,8]}, {"3301":[1957,47]}, {"3311":[1954,9]}, {"3323":[1954,28]}, {"3324":[1987,14]}, {"3379":[1962,25]}, {"3402":[1961,2]}, {"3409":[1972,12]}, {"3420":[1954,78]}, {"3452":[1971,85]}, {"3466":[1962,46]}, {"3477":[1960,13]}, {"3484":[1983,59]}, {"3532":[1961,15]}, {"3548":[1970,20]}, {"3554":[1981,53]}, {"3558":[1981,62]}, {"3668":[1953,73]}, {"3681":[1954,2]}, {"3687":[1957,11]}, {"3688":[1957,11]}, {"3689":[1962,15]}, {"3690":[1955,17]}, {"3717":[1955,5]}, {"3718":[1962,4]}, {"3719":[1958,48]}, {"3732":[1954,95]}, {"3749":[1953,3]}, {"3755":[1970,93]}, {"3764":[1958,44]}, {"3765":[1974,94]}, {"3772":[1973,71]}, {"3784":[1961,95]}, {"3785":[1950,17]}, {"3786":[1951,15]}, {"3821":[1954,66]}, {"3834":[1963,3]}, {"3845":[1985,65]}, {"3866":[1957,48]}, {"3871":[1950,82]}, {"3911":[1967,23]}, {"3928":[1959,52]}, {"3979":[1989,70]}, {"3980":[1963,10]}, {"4016":[1951,34]}, {"4022":[1956,98]}, {"4044":[1952,54]}, {"4051":[1984,56]}, {"4073":[1980,90]}, {"4117":[1976,1]}, {"4139":[1951,5]}, {"4252":[1950,14]}, {"4286":[1959,12]}, {"4288":[1965,43]}, {"4294":[1961,75]}, {"4318":[1960,10]}, {"4320":[1961,5]}, {"4335":[1966,62]}, {"4341":[1970,41]}, {"4343":[1964,2]}, {"4353":[1961,55]}, {"4354":[1962,21]}, {"4356":[1955,4]}, {"4357":[1966,23]}, {"4400":[1967,52]}, {"4438":[1965,71]}, {"4439":[1951,9]}, {"4462":[1968,42]}, {"4464":[1964,27]}, {"4470":[1987,38]}, {"4492":[1961,31]}, {"4494":[1952,65]}, {"4503":[1953,91]}, {"4504":[1953,35]}, {"4505":[1953,35]}, {"4514":[1970,51]}, {"4537":[1954,21]}, {"4538":[1956,4]}, {"4567":[1962,93]}, {"4575":[1960,19]}, {"4576":[1962,27]}, {"4618":[1998,13]}, {"4621":[1954,67]}, {"4643":[1970,2]}, {"4645":[1966,44]}, {"4649":[1953,40]}, {"4656":[1974,86]}, {"4657":[1984,25]}, {"4679":[1966,33]}, {"4728":[1974,56]}, {"4732":[2005,43]}, {"4740":[1964,33]}, {"4741":[1963,24]}, {"4742":[1970,18]}, {"4750":[1968,2]}, {"4773":[1971,98]}, {"4791":[1966,28]}, {"4795":[1983,96]}, {"4807":[1956,81]}, {"4837":[1950,5]}, {"4889":[1967,84]}, {"4897":[1957,67]}, {"4963":[1991,58]}, {"4978":[1959,51]}, {"4979":[1956,49]}, {"5002":[1956,3]}, {"5023":[1974,60]}, {"5025":[1977,22]}, {"5195":[1954,1]}, {"5228":[1963,65]}, {"5280":[1970,64]}, {"5296":[1955,62]}, {"5300":[1952,43]}, {"5346":[1955,52]}, {"5356":[1981,29]}, {"5367":[1964,54]}, {"5376":[1970,48]}, {"5391":[1982,31]}, {"5394":[1976,30]}, {"5431":[1974,8]}, {"5432":[1962,6]}, {"5480":[1971,49]}, {"5489":[1969,85]}, {"5506":[1960,98]}, {"5522":[1968,50]}, {"5541":[1972,90]}, {"5544":[2001,92]}, {"5547":[1975,70]}, {"5551":[1975,67]}, {"5556":[1999,29]}, {"5567":[1970,80]}, {"5579":[1981,8]}, {"5615":[1972,15]}, {"5631":[1954,81]}, {"5648":[1953,2]}, {"5652":[1950,63]}, {"5653":[1957,98]}, {"5702":[1959,81]}, {"5766":[1956,21]}, {"5768":[1959,47]}, {"5790":[1959,96]}, {"5794":[1957,3]}, {"5798":[1958,94]}, {"5805":[1979,63]}, {"5808":[1958,14]}, {"5810":[2001,5]}, {"5816":[1958,31]}, {"5825":[1959,61]}, {"5837":[1980,5]}, {"5838":[1995,34]}, {"5840":[1974,41]}, {"5841":[1973,35]}, {"5844":[1973,78]}, {"5882":[1954,90]}, {"5883":[1961,63]}, {"5893":[1981,31]}, {"5894":[1981,31]}, {"5936":[1981,30]}, {"5957":[1970,42]}, {"5976":[1992,41]}, {"5983":[1969,21]}, {"5987":[1970,90]}, {"5989":[1975,48]}, {"5990":[1978,37]}, {"6001":[1966,37]}, {"6002":[1969,92]}, {"6022":[1982,77]}, {"6023":[1988,39]}, {"6024":[1977,1]}, {"6042":[1981,2]}, {"6049":[1977,99]}, {"6050":[1956,10]}, {"6052":[1962,77]}, {"6053":[1964,29]}, {"6063":[1957,65]}, {"6065":[1956,15]}, {"6067":[1966,91]}, {"6069":[1987,69]}, {"6073":[1983,53]}, {"6091":[1950,95]}, {"6135":[1962,82]}, {"6151":[1978,18]}, {"6156":[1961,6]}, {"6164":[1954,60]}, {"6169":[1959,54]}, {"6185":[1958,25]}, {"6191":[2005,86]}, {"6239":[1970,24]}, {"6294":[1994,30]}, {"6301":[1952,17]}, {"6354":[2003,3]}, {"6370":[1987,55]}, {"6389":[1961,32]}, {"6398":[1965,15]}, {"6404":[1961,1]}, {"6426":[1992,100]}, {"6430":[1993,32]}, {"6444":[2010,32]}, {"6448":[1958,74]}, {"6476":[1955,12]}, {"6493":[1992,64]}, {"6523":[2007,76]}, {"6528":[1981,18]}, {"6563":[1960,12]}, {"6592":[1998,60]}, {"6689":[1960,20]}, {"6703":[1968,75]}, {"6722":[1955,12]}, {"6773":[1953,100]}, {"6903":[1958,24]}, {"6910":[1962,61]}, {"6961":[1981,35]}, {"6975":[1964,14]}, {"7030":[1958,34]}, {"7038":[1979,26]}, {"7083":[1970,91]}, {"7123":[1957,83]}, {"7228":[1971,2]}, {"7268":[1984,22]}, {"7409":[1994,96]}, {"7418":[1959,98]}, {"7660":[1950,80]}, {"7742":[1999,59]}, {"7790":[1956,14]}, {"7818":[1966,2]}, {"7837":[1972,42]}, {"7838":[1984,15]}, {"7914":[1960,29]}, {"7923":[1950,74]}, {"7925":[1993,87]}, {"7961":[1952,53]}, {"7965":[1959,87]}, {"8006":[1951,4]}, {"8016":[1997,75]}, {"8045":[1987,6]}, {"8103":[2010,74]}, {"8145":[1986,4]}, {"8192":[1970,67]}, {"8216":[1974,35]}, {"8243":[2008,98]}, {"8328":[1976,15]}, {"8364":[1970,65]}, {"8441":[1961,14]}, {"8448":[1962,90]}, {"8557":[1958,48]}, {"8678":[1967,74]}, {"8763":[1955,12]}, {"8855":[1962,74]}, {"8862":[1978,9]}, {"8884":[2009,2]}, {"8887":[2010,18]}, {"8915":[1974,74]}, {"8967":[1974,74]}, {"8999":[1963,3]}, {"9025":[1972,84]}, {"9026":[1971,78]}, {"9177":[1966,50]}, {"9192":[1961,2]}, {"9203":[1960,85]}, {"9224":[1970,69]}, {"9254":[1976,55]}, {"9264":[1973,95]}, {"9266":[1974,31]}, {"9294":[1994,2]}, {"9298":[1969,23]}, {"9322":[1952,81]}, {"9369":[1958,1]}, {"9618":[2007,25]}, {"9652":[2009,63]}, {"9673":[1965,64]}, {"9699":[1987,10]}, {"9883":[1973,67]}, {"9914":[1991,58]}, {"9918":[2010,6]}, {"9945":[1997,32]}, {"9954":[1959,80]}, {"9969":[1966,65]}, {"9983":[1987,14]}, {"9999":[1999,59]}, {"10052":[1969,64]}, {"10075":[1967,49]}, {"10118":[1961,18]}, {"10226":[2009,11]}, {"10234":[1979,14]}, {"10247":[1987,74]}, {"10260":[1970,82]}, {"10265":[1961,7]}, {"10269":[1989,39]}, {"10318":[1978,20]}, {"10320":[1970,35]}, {"10321":[1971,2]}, {"10395":[1968,33]}, {"10466":[1970,12]}, {"10571":[1985,84]}, {"10602":[1963,28]}, {"10604":[1965,25]}, {"10636":[1951,15]}, {"10656":[2010,42]}, {"10663":[1962,1]}, {"10703":[1969,25]}, {"10767":[1959,3]}, {"11007":[1994,31]}, {"11050":[1971,51]}, {"11103":[1986,39]}, {"11150":[1970,36]}, {"11158":[1961,14]}, {"11281":[2009,7]}, {"11284":[1967,41]}, {"11604":[2003,92]}, {"11665":[1992,64]}, {"11667":[1993,18]}, {"11733":[1964,41]}, {"11756":[1951,25]}, {"11767":[1973,66]}, {"11781":[1965,62]}, {"11785":[1979,20]}, {"11807":[1958,26]}, {"11857":[1958,22]}, {"12187":[2009,60]}, {"12275":[1959,98]}, {"12514":[2007,76]}, {"12899":[1958,2]}]''') # noqa: E501 entryDict = {} for d in entries: @@ -171,16 +171,19 @@ def nipsEvalCoarse(): c = classifier(matchData[i]) if c != matchData[i].getclass(): mismatch += 1 - print('%s %s: misclassified %s/%s of %s' % (cStr, cName, mismatch, len(matchData), matchStr)) + print('%s %s: misclassified %s/%s of %s' + % (cStr, cName, mismatch, len(matchData), matchStr)) def getLeadsheetDatesFromBillboard(): ''' - script to generate a json list matching leadsheet files to their dates. script compiles list of Billboard + script to generate a json list matching leadsheet files to their dates. + Compiles list of Billboard top 100 songs from jamrockentertainment.com, then uses this dictionary to match up titles from leadsheet file. Last updated: 10/6/2011, Beth Hadley - Both the dictionary generated by scraping the website and the json output has been copied into a text file - and saved so this script shouldn't need to be re-run unless a change has been made. See text file. + Both the dictionary generated by scraping the website and the json output + has been copied into a text file and saved so this script shouldn't need to be + re-run unless a change has been made. See text file. ''' import os try: @@ -193,8 +196,10 @@ def getLeadsheetDatesFromBillboard(): # Code below scrapes this website: http://www.jamrockentertainment.com/billboard-music-top-100-songs-listed-by-year.html # for their listing of the Billboard 100 songs from 1950 to 2010. # -# Generates an unordered dictionary with the corresponding data: each key in the dictionary is the year, each value is a list -# of tuples, each tuple includes the song title at index 0 and group/artist at index 1. The list is ordered starting at +# Generates an unordered dictionary with the corresponding data: each key in +# the dictionary is the year, each value is a list of tuples, each tuple +# includes the song title at index 0 and group/artist at index 1. +# The list is ordered starting at # element 0 by rank, starting with number 1. DICT = {} tempList = [] @@ -203,7 +208,9 @@ def getLeadsheetDatesFromBillboard(): dates = range(LOWERLIMIT, UPPERLIMIT) for i in dates: if i != 2008 and i != 2009: - address = 'http://www.jamrockentertainment.com/billboard-music-top-100-songs-listed-by-year/top-100-songs-%s.html' % i + address = ('http://www.jamrockentertainment.com/' + 'billboard-music-top-100-songs-listed-by-year/' + 'top-100-songs-%s.html' % i) url = urlopen(address) html = url.read() soup = BeautifulSoup(html, convertEntities=BeautifulSoup.HTML_ENTITIES) @@ -230,7 +237,9 @@ def getLeadsheetDatesFromBillboard(): tempList.append( t ) song = True elif i == 2008: - address = 'http://www.jamrockentertainment.com/billboard-music-top-100-songs-listed-by-year/top-100-songs-%s.html' % i + address = ('http://www.jamrockentertainment.com/' + 'billboard-music-top-100-songs-listed-by-year/' + 'top-100-songs-%s.html' % i) url = urlopen(address) html = url.read() soup = BeautifulSoup(html) @@ -266,7 +275,9 @@ def getLeadsheetDatesFromBillboard(): t = title, group tempList.append( t ) else: # i=2009 - address = 'http://www.jamrockentertainment.com/billboard-music-top-100-songs-lististed-by-year/top-100-songs-%s.html' % i + address = ('http://www.jamrockentertainment.com/' + 'billboard-music-top-100-songs-lististed-by-year/' + 'top-100-songs-%s.html' % i) url = urlopen(address) html = url.read() soup = BeautifulSoup(html, convertEntities=BeautifulSoup.HTML_ENTITIES) @@ -314,8 +325,11 @@ def getLeadsheetDatesFromBillboard(): piece = converter.parse(dst) for year in DICT: for title, _group in DICT[year]: - if piece.metadata.movementName.lower() == str(title).lower(): # or piece.metadata.composer == str(a): - # print("Found by title! Name", piece.metadata.movementName, "Composer", piece.metadata.composer, str(year)) + # or piece.metadata.composer == str(a): + if piece.metadata.movementName.lower() == str(title).lower(): + # print("Found by title! Name", + # piece.metadata.movementName, + # "Composer", piece.metadata.composer, str(year)) # print(dst) dates.append(int(year)) @@ -327,7 +341,10 @@ def getLeadsheetDatesFromBillboard(): if e.lower() == piece.metadata.movementName.lower(): rank = (tempList.index(x) + 1 ) # position on Billboard 100 - # print('Title:', piece.metadata.movementName, ' Composer:', piece.metadata.composer, ' Date:', date, ' Position on Billboard:', rank) + # print('Title:', piece.metadata.movementName, + # ' Composer:', piece.metadata.composer, + # ' Date:', date, + # ' Position on Billboard:', rank) # print('Title:', piece.metadata.movementName, ' Date:', date) matches = matches + 1 outputjson = outputjson + '{"%s":[%s,%s]}, ' % (i, date, rank) diff --git a/music21_tools/chant/chant.py b/music21_tools/chant/chant.py index 45bd6e4..5405b46 100644 --- a/music21_tools/chant/chant.py +++ b/music21_tools/chant/chant.py @@ -431,7 +431,8 @@ def __init__(self): % If you use usual TeX fonts, here is a starting point: \\usepackage{times} -% to change the font to something better, you can install the kpfonts package (if not already installed). To do so +% to change the font to something better, you can install the kpfonts package + % (if not already installed). To do so % go open the "TeX Live Manager" in the Menu Start->All Programs->TeX Live 2010 % here we begin the document diff --git a/music21_tools/contour/contour.py b/music21_tools/contour/contour.py index fbbf316..eb8c300 100644 --- a/music21_tools/contour/contour.py +++ b/music21_tools/contour/contour.py @@ -198,7 +198,8 @@ def getContour(self, cType, window=None, slide=None, overwrite=False, >>> mycontour = cf.getContour('spacing', metric = lambda x: 2, overwrite=False) Traceback (most recent call last): - music21_tools.contour.contour.OverwriteException: Attempted to overwrite 'spacing' metric but did not specify overwrite=True + music21_tools.contour.contour.OverwriteException: Attempted to overwrite + 'spacing' metric but did not specify overwrite=True >>> mycontour = cf.getContour('spacing', slide=3, metric = lambda x: 2.0, overwrite=True) >>> [mycontour[x] for x in sorted(mycontour.keys())] diff --git a/music21_tools/featureExtraction/ismir2011.py b/music21_tools/featureExtraction/ismir2011.py index bdf6a64..acefdc7 100644 --- a/music21_tools/featureExtraction/ismir2011.py +++ b/music21_tools/featureExtraction/ismir2011.py @@ -103,7 +103,10 @@ def prepareChinaEurope1(): def prepareChinaEurope2(): - featureExtractors = features.extractorsById(['r31', 'r32', 'r33', 'r34', 'r35', 'p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8', 'p9', 'p10', 'p11', 'p12', 'p13', 'p14', 'p15', 'p16', 'p19', 'p20', 'p21']) + featureExtractors = features.extractorsById( + ['r31', 'r32', 'r33', 'r34', 'r35', + 'p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8', 'p9', 'p10', + 'p11', 'p12', 'p13', 'p14', 'p15', 'p16', 'p19', 'p20', 'p21']) oChina2 = corpus.parse('essenFolksong/han2') oCEurope2 = corpus.parse('essenFolksong/boehme20') @@ -148,7 +151,8 @@ def testChinaEuropeFull(): c = classifier(matchData[i]) if c != matchData[i].getclass(): mismatch += 1 - print('%s %s: misclassified %s/%s of %s' % (cStr, cName, mismatch, len(matchData), matchStr)) + print('%s %s: misclassified %s/%s of %s' + % (cStr, cName, mismatch, len(matchData), matchStr)) # this test requires orange and related files diff --git a/music21_tools/misc/gatherAccidentals.py b/music21_tools/misc/gatherAccidentals.py index 357b036..3d436aa 100644 --- a/music21_tools/misc/gatherAccidentals.py +++ b/music21_tools/misc/gatherAccidentals.py @@ -274,5 +274,6 @@ def testAccidentalCountBachChorales(self): if __name__ == '__main__': import music21 - music21.mainTest(Test, 'moduleRelative') # replace 'Test' with 'TestSlow' to test it on all 371 Bach Chorales. + # replace 'Test' with 'TestSlow' to test it on all 371 Bach Chorales. + music21.mainTest(Test, 'moduleRelative') diff --git a/music21_tools/misc/monteverdi.py b/music21_tools/misc/monteverdi.py index 3f1deed..fde8675 100644 --- a/music21_tools/misc/monteverdi.py +++ b/music21_tools/misc/monteverdi.py @@ -38,7 +38,8 @@ def spliceAnalysis(book=3, madrigal=1): # excerpt.show() def showAnalysis(book=3, madrigal= 3): - # analysis = converter.parse('d:/docs/research/music21/dmitri_analyses/Mozart Piano Sonatas/k331.rntxt') + # analysis = converter.parse( + # 'd:/docs/research/music21/dmitri_analyses/Mozart Piano Sonatas/k331.rntxt') filename = 'monteverdi/madrigal.%s.%s.rntxt' % (book, madrigal) analysis = corpus.parse(filename) # analysis.show() @@ -251,8 +252,10 @@ def findPhraseBoundaries(book=4, madrigal=12): for p in sc.parts: partNotes = p.flatten().stripTies(matchByPitch=True).notesAndRests - # thisPartPhraseScores = [] # keeps track of the likelihood that a phrase boundary is after note i - for i in range(2, len(partNotes) - 2): # start on the third note and stop searching on the third to last note... + # thisPartPhraseScores = [] # keeps track of the likelihood that + # a phrase boundary is after note i + # start on the third note and stop searching on the third-to-last note + for i in range(2, len(partNotes) - 2): thisScore = 0 twoNotesBack = partNotes[i - 2] previousNote = partNotes[i - 1] diff --git a/music21_tools/theory/mgtaPart1.py b/music21_tools/theory/mgtaPart1.py index 50dfd1b..e866b74 100644 --- a/music21_tools/theory/mgtaPart1.py +++ b/music21_tools/theory/mgtaPart1.py @@ -200,7 +200,9 @@ def ch1_basic_II_A_2(show=True, *arguments, **keywords): def ch1_basic_II_B_1(show=True, *arguments, **keywords): ''' p4. - For each of the five trebleclef pitches on the left, write the alto-clef equivalent on the right. Then label each pitch with the correct name and octave designation. + For each of the five trebleclef pitches on the left, write the alto-clef + equivalent on the right. Then label each pitch with the correct name and + octave designation. ''' humdata = ''' **kern @@ -222,7 +224,9 @@ def ch1_basic_II_B_1(show=True, *arguments, **keywords): def ch1_basic_II_B_2(show=True, *arguments, **keywords): ''' p4. - For each of the five bass clef pitches on the left, write the tenor-clef equivalent on the right. Then label each pitch with the correct name and octave designation. + For each of the five bass clef pitches on the left, write the tenor-clef + equivalent on the right. Then label each pitch with the correct name and + octave designation. ''' humdata = '**kern\n1F#1e-\n1B\n1D-\n1c\n*-' exercise = converter.parseData(humdata) @@ -608,13 +612,16 @@ def ch2_basic_I_B(show=True, *arguments, **keywords): (Given meter type and one of meter, beat unit, beat division, full bar divisions, provide the other data) ''' - # a brute force way to do this might have a function in meter.py that returns a number of candidates for a given meter type and some other parameter (bar duration). then, these values can be tested for match. + # a brute force way to do this might have a function in meter.py that returns + # a number of candidates for a given meter type and some other parameter + # (bar duration). then, these values can be tested for match. pass def ch2_basic_I_C(show=True, *arguments, **keywords): '''p. 13 - Complete the chart below. (For a given meter, provide meter type, beat unit, beat division, and beat subdivision.) + Complete the chart below. (For a given meter, provide meter type, beat unit, + beat division, and beat subdivision.) ''' from music21 import meter, stream @@ -729,7 +736,8 @@ def ch2_writing_I_A(tsStr, barGroups): def ch2_writing_I_A_1(show=True, *arguments, **keywords): '''p. 14 - Complete the rhythms below by adding one note value that completes any measure with too few beats. + Complete the rhythms below by adding one note value that completes any + measure with too few beats. ''' barGroups = ([.5], [.75, .25], [.5, .75], [.25, .25, .25, .25], [.5], []) ex = ch2_writing_I_A('3/8', barGroups) @@ -742,7 +750,9 @@ def ch2_writing_I_A_1(show=True, *arguments, **keywords): def ch2_writing_I_A_2(show=True, *arguments, **keywords): '''p. 14 ''' - barGroups = ([.75, .25, .25, .25, .25, .25, 1.5], [.25, .25, .5, -.5, .5], [2, .25, .25, .25, .25, .25, .25], [3]) + barGroups = ([.75, .25, .25, .25, .25, .25, 1.5], + [.25, .25, .5, -.5, .5], + [2, .25, .25, .25, .25, .25, .25], [3]) ex = ch2_writing_I_A('4/4', barGroups) if show: ex.show() @@ -752,7 +762,8 @@ def ch2_writing_I_A_2(show=True, *arguments, **keywords): def ch2_writing_I_A_3(show=True, *arguments, **keywords): '''p. 14 ''' - barGroups = ([2, 1.5, .5, .5, .5, .5], [-.5, .5, .5, .5, 1, 1, 1], [4, 1.5], [.5, .5, .5, .5, .5, 1, .5]) + barGroups = ([2, 1.5, .5, .5, .5, .5], [-.5, .5, .5, .5, 1, 1, 1], + [4, 1.5], [.5, .5, .5, .5, .5, 1, .5]) ex = ch2_writing_I_A('3/2', barGroups) if show: ex.show() @@ -815,7 +826,9 @@ def ch2_writing_I_B_5(show=True, *arguments, **keywords): def ch2_writing_II_A(show=True, *arguments, **keywords): '''p. 15 - Each of these pieces begins with an anacrusis. What note value (or note value plus rest) could the composer use to fill the last measure of the compositions correctly. + Each of these pieces begins with an anacrusis. What note value (or note value + plus rest) could the composer use to fill the last measure of the compositions + correctly. ''' pass @@ -955,7 +968,8 @@ def ch2_writing_III_B_1(show=True, *arguments, **keywords): def ch2_writing_III_B_2(show=True, *arguments, **keywords): '''p. 17 ''' - ex = converter.parse('tinynotation: 4/4 c4~ c8 c16 c c8 c~ c c c2~ c4 c8 c8 c8~ c16 c c8~ c16 c c2') + ex = converter.parse( + 'tinynotation: 4/4 c4~ c8 c16 c c8 c~ c c c2~ c4 c8 c8 c8~ c16 c c8~ c16 c c2') ex = ch2_writing_III_B(ex) if show: @@ -993,7 +1007,9 @@ def ch2_writing_IV_A(show=True, *arguments, **keywords): def ch2_writing_IV_B(show=True, *arguments, **keywords): '''p. 18 ''' - ex = converter.parse("tinynotation: 2/4 c8. c16 e8 g c'4. r8 a8. a16 c'8 a g4. e16 f g8 g8 e16 e g16 g a8 g8 e4 d8 e16 f e d8 d16 c4.") + ex = converter.parse( + "tinynotation: 2/4 c8. c16 e8 g c'4. r8 a8. a16 c'8 a g4. e16 f g8 g8" + ' e16 e g16 g a8 g8 e4 d8 e16 f e d8 d16 c4.') ex = ex.makeMeasures() ex.makeBeams(inPlace=True) @@ -1015,7 +1031,9 @@ def ch2_writing_V_A(show=True, *arguments, **keywords): from music21 import key # note: tiny is not encoding C#s for c'#4 properly (it seems) - ex = converter.parse("tinynotation: 3/2 g#1 f#4 g#4 a1 g#2 f#1 g#4. en8 g#2 f#4 r4 f#4 d#8 B8 e2 r4 e4 a4. a8 a2 g#4 g# b4. e8 a2~ a4 a4 d'n4. d'8 d'n2 c'#4 c'# c'# c'#") + ex = converter.parse( + 'tinynotation: 3/2 g#1 f#4 g#4 a1 g#2 f#1 g#4. en8 g#2 f#4 r4 f#4 d#8 B8' + " e2 r4 e4 a4. a8 a2 g#4 g# b4. e8 a2~ a4 a4 d'n4. d'8 d'n2 c'#4 c'# c'# c'#") ex.insert(0, key.KeySignature(4)) # presently, this only works if makeAccidentals is called before make measures @@ -1295,7 +1313,9 @@ def ch3_analysis_II_B(show=True, *arguments, **keywords): def ch4_basic_I_A(show=True, *arguments, **keywords): '''p. 33 - For each major key, write out the scale. Circle degree 6. Write out a new scale that begins ont he pitch class you circled. Write the name of this relative-minor scale on the line indicated. + For each major key, write out the scale. Circle degree 6. Write out a new + scale that begins ont he pitch class you circled. Write the name of this + relative-minor scale on the line indicated. ''' pass diff --git a/music21_tools/theory/mgtaPart2.py b/music21_tools/theory/mgtaPart2.py index 10a5c1f..2f077e1 100755 --- a/music21_tools/theory/mgtaPart2.py +++ b/music21_tools/theory/mgtaPart2.py @@ -33,7 +33,8 @@ def xtest_Ch6_basic_I_A(self, *arguments, **keywords): '''p55 Write a whole note on the specified generic interval. Do not add sharps or flats. - MSC: 2013 Oct -- No longer works now that convertGenericToSemitone() [buggy] has been removed. + MSC: 2013 Oct -- No longer works now that convertGenericToSemitone() + [buggy] has been removed. ''' pass diff --git a/music21_tools/theoryAnalysis/theoryAnalyzer.py b/music21_tools/theoryAnalysis/theoryAnalyzer.py index 255bf81..456877a 100644 --- a/music21_tools/theoryAnalysis/theoryAnalyzer.py +++ b/music21_tools/theoryAnalysis/theoryAnalyzer.py @@ -562,9 +562,11 @@ def getVerticalityNTuplets(self, score, ntupletNum): >>> ads = Analyzer() >>> len(ads.getVerticalityNTuplets(sc, 3)) 2 - >>> ads.getVerticalityNTuplets(sc, 3)[1] - , - , ]> + >>> triplet = ads.getVerticalityNTuplets(sc, 3)[1] + >>> triplet.__class__.__name__ + 'VerticalityTriplet' + >>> len(triplet.verticalities) + 3 ''' verticalityNTuplets = [] sid = score.id @@ -1809,7 +1811,8 @@ def identifyImproperDissonantIntervals(self, score, partNum1=None, partNum2=None >>> len(ads.store[sc.id]['ResultDict']['improperDissonantIntervals']) 1 >>> ads.store[sc.id]['ResultDict']['improperDissonantIntervals'][0].text - 'Improper dissonant harmonic interval in measure 1: Perfect Fourth from B to E between part 1 and part 2' + 'Improper dissonant harmonic interval in measure 1: + Perfect Fourth from B to E between part 1 and part 2' ''' sid = score.id diff --git a/music21_tools/trecento/capua.py b/music21_tools/trecento/capua.py index 5287bc3..c4691b9 100644 --- a/music21_tools/trecento/capua.py +++ b/music21_tools/trecento/capua.py @@ -967,7 +967,8 @@ def improvedHarmony(startPiece=2, endPiece=459): if len(thisSnippetParts) < 2: continue srcStream1 = thisSnippetParts['C'].flatten().notesAndRests - srcStream2 = thisSnippetParts['T'].flatten().notesAndRests # ignore 3rd voice for now... + # ignore 3rd voice for now... + srcStream2 = thisSnippetParts['T'].flatten().notesAndRests srcStream1.attachIntervalsBetweenStreams(srcStream2) # srcStream2.attachIntervalsBetweenStreams(srcStream1) applyCapuaToStream(srcStream1) diff --git a/music21_tools/trecento/medren.py b/music21_tools/trecento/medren.py index 3e5dcf1..99bb01e 100644 --- a/music21_tools/trecento/medren.py +++ b/music21_tools/trecento/medren.py @@ -842,7 +842,8 @@ def setStem(self, direction): >>> r_1 = MensuralNote('A', 'brevis') >>> r_1.setStem('down') Traceback (most recent call last): - music21_tools.trecento.medren.MedRenException: A note of type brevis cannot be equipped with a stem + music21_tools.trecento.medren.MedRenException: A note of type brevis + cannot be equipped with a stem >>> r_2 = MensuralNote('A', 'semibrevis') >>> r_2.setStem('down') @@ -856,7 +857,8 @@ def setStem(self, direction): >>> r_3.setStem('down') Traceback (most recent call last): - music21_tools.trecento.medren.MedRenException: This note already has the maximum number of stems + music21_tools.trecento.medren.MedRenException: This note already has + the maximum number of stems >>> r_3.setStem(None) >>> r_3.getStems() @@ -944,7 +946,8 @@ def setFlag(self, stemDirection, orientation): >>> r_3.setStem('side') >>> r_3.setFlag('side', 'left') Traceback (most recent call last): - music21_tools.trecento.medren.MedRenException: a flag cannot be added to a stem with direction side + music21_tools.trecento.medren.MedRenException: a flag cannot be added + to a stem with direction side ''' if stemDirection == 'up': if self.mensuralType != 'semiminima': @@ -1460,7 +1463,8 @@ def setStem(self, index, direction, orientation): >>> l.setStem(2, 'down', 'right') Traceback (most recent call last): - music21_tools.trecento.medren.MedRenException: a stem with direction "down" not permitted at index 2 + music21_tools.trecento.medren.MedRenException: a stem with direction + "down" not permitted at index 2 >>> l.setMaxima(4, True) >>> l.setStem(4, 'up', 'left') @@ -1469,7 +1473,8 @@ def setStem(self, index, direction, orientation): >>> l.setStem(3, 'up', 'left') Traceback (most recent call last): - music21_tools.trecento.medren.MedRenException: a stem with direction "up" not permitted at index 3 + music21_tools.trecento.medren.MedRenException: a stem with direction + "up" not permitted at index 3 ''' if direction == 'None' or direction == 'none': direction = None diff --git a/pyproject.toml b/pyproject.toml index 45e97ec..e616a09 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -78,3 +78,10 @@ ignore = [ inline-quotes = 'single' multiline-quotes = 'single' docstring-quotes = 'single' + +[tool.ruff.lint.per-file-ignores] +# clercqTemperley example contains a real chord progression on a single line +# (musical content; not wrappable). +'music21_tools/bhadley/harmonyRealizer.py' = ['E501'] +# Gregorio .gabc → LaTeX template strings; line breaks would break the template. +'music21_tools/chant/chant.py' = ['E501'] From dcbf17638af3591750f8e0639a3f600165a36d9b Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 22:22:07 -1000 Subject: [PATCH 25/28] Add CI workflow + unittest discovery via conftest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - .github/workflows/ci.yml runs ruff + pytest on Python 3.11-3.14 for pushes/PRs to master. - conftest.py filters TestExternal/TestSlow classes during pytest collection (matches music21's pytest plugin convention). - pyproject.toml bakes --doctest-modules, python_files='*.py', and testpaths='music21_tools' into pytest config so `uv run pytest` alone does the full sweep. - Renamed module-level testFoo helpers that weren't actually tests (demo*, runAll); aug30.py's test() → demo() + new TestExternal wrapper so the .show() call doesn't fire during routine collection. - README's "Running the tests" section trimmed to the essentials. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/ci.yml | 35 ++++++++++++++++++++ README.md | 19 ++++++----- conftest.py | 28 ++++++++++++++++ music21_tools/composition/aug30.py | 16 ++++++--- music21_tools/featureExtraction/ismir2011.py | 14 ++++---- music21_tools/trecento/capua.py | 2 +- music21_tools/trecento/medren.py | 2 +- music21_tools/trecento/tonality.py | 6 ++-- pyproject.toml | 5 +++ 9 files changed, 102 insertions(+), 25 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 conftest.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..2521263 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,35 @@ +name: CI + +on: + push: + branches: [master] + pull_request: + branches: [master] + +jobs: + test: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ['3.11', '3.12', '3.13', '3.14'] + + steps: + - uses: actions/checkout@v4 + + - name: Install uv + uses: astral-sh/setup-uv@v4 + with: + enable-cache: true + + - name: Set up Python ${{ matrix.python-version }} + run: uv python install ${{ matrix.python-version }} + + - name: Install dependencies + run: uv sync --python ${{ matrix.python-version }} + + - name: Lint with ruff + run: uv run --python ${{ matrix.python-version }} ruff check music21_tools/ tools/ + + - name: Run tests + run: uv run --python ${{ matrix.python-version }} pytest diff --git a/README.md b/README.md index 24dbcde..f9fbd4d 100644 --- a/README.md +++ b/README.md @@ -42,21 +42,22 @@ under `webapps/`. The project is described in: ## Running the tests -This project uses [`uv`](https://docs.astral.sh/uv/) and `pytest`. From the -repository root: - ```sh -# install (creates .venv/ with music21 >= 10 and dev dependencies) -uv sync +uv sync # one-time: install music21 >= 10 + dev deps +uv run pytest # full sweep (doctests + Test classes) +``` -# run the full test + doctest suite -uv run pytest --doctest-modules music21_tools/ +A single module: + +```sh +uv run pytest music21_tools/theoryAnalysis/theoryAnalyzer.py ``` -To test a single module: +`TestExternal` (interactive / display) and `TestSlow` (full-corpus) classes are +skipped by default. Run them one method at a time via `unittest`: ```sh -uv run pytest --doctest-modules music21_tools/theoryAnalysis/theoryAnalyzer.py +uv run python -m unittest music21_tools.chant.chant.TestExternal.testSimpleFile ``` diff --git a/conftest.py b/conftest.py new file mode 100644 index 0000000..3fc9d16 --- /dev/null +++ b/conftest.py @@ -0,0 +1,28 @@ +''' +Pytest configuration for music21-tools. + +Skip ``TestExternal`` and ``TestSlow`` classes during automated collection. + +By music21 convention: + +* ``TestExternal`` methods open files on the local machine, play sounds, render + with LilyPond, or otherwise need a person at the console. Run them + individually when verifying a behavior, never in CI. +* ``TestSlow`` methods are long-running (full corpus walks, etc.) and are not + meant for the default test sweep. + +Only ``Test`` classes — plain unit tests — survive collection. +''' +from unittest import TestCase + + +def pytest_collection_modifyitems(config, items): + kept = [] + for item in items: + parent = getattr(item, 'parent', None) + cls = getattr(parent, 'cls', None) + if cls is not None and issubclass(cls, TestCase) and cls.__name__ != 'Test': + # filter out TestSlow, TestExternal, etc. + continue + kept.append(item) + items[:] = kept diff --git a/music21_tools/composition/aug30.py b/music21_tools/composition/aug30.py index 5d4e1c8..f468764 100644 --- a/music21_tools/composition/aug30.py +++ b/music21_tools/composition/aug30.py @@ -13,14 +13,16 @@ written on August 30, 2008 converted to new system on Dec. 26, 2010 ''' +import copy +import random +import unittest + from music21 import articulations from music21 import duration from music21 import meter from music21 import note from music21 import tempo from music21 import stream -import copy -import random def rhythmLine(baseNote=None, minLength=8.0, maxProbability=0.5): if baseNote is None: @@ -110,7 +112,7 @@ def addPart(minLength=80, maxProbability=0.7, instrument=None): return s1 -def test(): +def demo(): from music21 import instrument as j sc1 = stream.Score() # instruments = [Piccolo(), Glockenspiel(), 72, 69, 41, 27, 47, 1, 1, 1, 1, 34] @@ -131,5 +133,11 @@ def test(): sc1.insert(0, part) sc1.show() + +class TestExternal(unittest.TestCase): # pragma: no cover + def testDemo(self): + demo() + + if __name__ == '__main__': - test() + demo() diff --git a/music21_tools/featureExtraction/ismir2011.py b/music21_tools/featureExtraction/ismir2011.py index acefdc7..8505e38 100644 --- a/music21_tools/featureExtraction/ismir2011.py +++ b/music21_tools/featureExtraction/ismir2011.py @@ -40,7 +40,7 @@ def _process(self): fictaPitches += 1 self._feature.vector[0] = fictaPitches / len(allPitches) -def testFictaFeature(): +def demoFictaFeature(): luca = corpus.parse('luca/gloria.mxl') fe = MusicaFictaFeature(luca) print(fe.extract().vector) @@ -48,7 +48,7 @@ def testFictaFeature(): fe.setData(mv) print(fe.extract().vector) -def testDataSet(): +def demoDataSet(): fes = features.extractorsById(['ql1', 'ql2', 'ql3']) ds = features.DataSet(classLabel='Composer') ds.addFeatureExtractors(fes) @@ -126,7 +126,7 @@ def prepareChinaEurope2(): ds2.process() ds2.write('d:/desktop/folkTest.tab') -def testChinaEuropeFull(): +def demoChinaEuropeFull(): import orange import orngTree data1 = orange.ExampleTable('d:/desktop/1.tab') @@ -214,7 +214,7 @@ def prepareTrecentoCadences(): ds2.write('d:/desktop/trecento2.tab') -def testTrecentoSimpler(): +def demoTrecentoSimpler(): import orange trainData = orange.ExampleTable('d:/desktop/trecento2.tab') @@ -346,13 +346,13 @@ def fbFeatureExtraction(): if __name__ == '__main__': pass - # testTrecentoSimpler() + # demoTrecentoSimpler() # prepareTrecentoCadences() # figuredBassScale() # fbFeatureExtraction() # testChinaEuropeSimpler() # prepareChinaEurope2() - # testDataSet() - # testFictaFeature() + # demoDataSet() + # demoFictaFeature() # example2() diff --git a/music21_tools/trecento/capua.py b/music21_tools/trecento/capua.py index c4691b9..50b3ee8 100644 --- a/music21_tools/trecento/capua.py +++ b/music21_tools/trecento/capua.py @@ -1071,7 +1071,7 @@ def testRunNonCrederDonna(self): [ ['A', 'P5', None], ['A', 'M6', None], ['G', 'P5', None], ['G', 'm6', None], - ['A', 'm7', None], ['F', 'd5', ''], + ['A', 'm7', None], ['F', 'd5', ''], ['G', 'm6', None], ['A', 'P1', None], ['B', 'M6', None], ['A', 'P5', None], ['G', 'm7', None], ['G', 'm6', None], diff --git a/music21_tools/trecento/medren.py b/music21_tools/trecento/medren.py index 99bb01e..74c1b1a 100644 --- a/music21_tools/trecento/medren.py +++ b/music21_tools/trecento/medren.py @@ -2142,7 +2142,7 @@ def testHouseStyle(self): gloriaNew = convertHouseStyle(gloria) gloriaNew.show() -def testStretto(): +def demoStretto(): from music21 import converter # salveRegina liber p. 276 salve = converter.parse('tinyNotation: 4/4 A4 A G A D A G F E F G F E D') diff --git a/music21_tools/trecento/tonality.py b/music21_tools/trecento/tonality.py index 98ae428..8112ba3 100644 --- a/music21_tools/trecento/tonality.py +++ b/music21_tools/trecento/tonality.py @@ -323,7 +323,7 @@ def sacredTonality(show=True): print(tCounter.output) tCounter.displayStream.show('lily.png') -def testAll(show=True, fast=False): +def runAll(show=True, fast=False): sacredTonality(show) if fast is False: nonLandiniTonality(show) @@ -332,11 +332,11 @@ def testAll(show=True, fast=False): class Test(unittest.TestCase): def runTest(self): - testAll(show=False, fast=True) + runAll(show=False, fast=True) class TestExternal(unittest.TestCase): # pragma: no cover def runTest(self): - testAll(show=True, fast=False) + runAll(show=True, fast=False) if __name__ == '__main__': import music21 diff --git a/pyproject.toml b/pyproject.toml index e616a09..3202f1d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,7 +55,12 @@ default-groups = ["dev"] packages = ['music21_tools'] [tool.pytest.ini_options] +# `uv run pytest` is equivalent to: +# pytest --doctest-modules -o python_files='*.py' music21_tools/ +addopts = ['--doctest-modules'] doctest_optionflags = ['NORMALIZE_WHITESPACE', 'ELLIPSIS'] +python_files = ['*.py'] +testpaths = ['music21_tools'] [tool.ruff] line-length = 100 From 91559759689118f47dd1dc2aea8cd53436d78700 Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 22:26:39 -1000 Subject: [PATCH 26/28] Tighten CI workflow and medren isinstance checks - ci.yml: trigger on PRs only (no push), and use actions/setup-python@v5 to provide the interpreter instead of `uv python install` so uv reuses GitHub's cached Python toolchain. - medren.py: collapse `isinstance(x, (Mensuration, notation.Divisione))` to `isinstance(x, MedievalMeter)` (their shared parent) in the two spots where both subclasses were checked together. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/ci.yml | 16 ++++++++-------- music21_tools/trecento/medren.py | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2521263..494b51e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,8 +1,6 @@ name: CI on: - push: - branches: [master] pull_request: branches: [master] @@ -17,19 +15,21 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install uv uses: astral-sh/setup-uv@v4 with: enable-cache: true - - name: Set up Python ${{ matrix.python-version }} - run: uv python install ${{ matrix.python-version }} - - name: Install dependencies - run: uv sync --python ${{ matrix.python-version }} + run: uv sync - name: Lint with ruff - run: uv run --python ${{ matrix.python-version }} ruff check music21_tools/ tools/ + run: uv run ruff check music21_tools/ tools/ - name: Run tests - run: uv run --python ${{ matrix.python-version }} pytest + run: uv run pytest diff --git a/music21_tools/trecento/medren.py b/music21_tools/trecento/medren.py index 74c1b1a..fc4f29a 100644 --- a/music21_tools/trecento/medren.py +++ b/music21_tools/trecento/medren.py @@ -1818,7 +1818,7 @@ def isHigherInHierarchy(lower, upper): for item in tempStream_2: newStream.append(item) - if isinstance(item, (Mensuration, notation.Divisione)): + if isinstance(item, MedievalMeter): if mOrDInAsNone: # If first case or changed mOrD mOrD = item elif mOrD.standardSymbol != item.standardSymbol: @@ -1854,7 +1854,7 @@ def isHigherInHierarchy(lower, upper): if isinstance(e, MensuralClef): pendingFirstMeasureItems.append(e) - elif isinstance(e, (Mensuration, notation.Divisione)): + elif isinstance(e, MedievalMeter): if mOrD is None: mOrD = e pendingFirstMeasureItems.append(e) From e4d85ded0dbffd9b0860e4ee085f8cf596424edb Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 22:30:10 -1000 Subject: [PATCH 27/28] returning a value from a Test is deprecated Therefore Capua's test needs to be split. --- music21_tools/trecento/capua.py | 62 ++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/music21_tools/trecento/capua.py b/music21_tools/trecento/capua.py index 50b3ee8..16df3f1 100644 --- a/music21_tools/trecento/capua.py +++ b/music21_tools/trecento/capua.py @@ -1044,29 +1044,7 @@ def ruleFrequency(startNumber=2, endNumber=459): class Test(unittest.TestCase): def testRunNonCrederDonna(self): - pieceNum = 331 # Francesco, PMFC 4 6-7: Non creder, donna - ballataObj = cadencebook.BallataSheet() - pieceObj = ballataObj.makeWork(pieceNum) - - applyCapuaToCadencebookWork(pieceObj) - srcStream = pieceObj.snippets[0].parts[0].flatten().notesAndRests.stream() - cmpStream = pieceObj.snippets[0].parts[1].flatten().notesAndRests.stream() - # ignore 3rd voice for now... - srcStream.attachIntervalsBetweenStreams(cmpStream) - cmpStream.attachIntervalsBetweenStreams(srcStream) - - # colorCapuaFicta(srcStream, cmpStream, 'both') - - outList = [] - for n in srcStream: - if n.editorial.harmonicInterval is not None: - outSublist = [n.name, n.editorial.harmonicInterval.simpleName] - if 'capuaFicta' in n.editorial: - outSublist.append(repr(n.editorial.capuaFicta)) - else: - outSublist.append(None) - outList.append(outSublist) - + _pieceObj, outList = _analyzeNonCrederDonna() self.assertEqual(outList, [ ['A', 'P5', None], ['A', 'M6', None], @@ -1078,9 +1056,6 @@ def testRunNonCrederDonna(self): ['F', 'd5', None], ['E', 'M3', None], ['D', 'P1', None] ]) - # pieceObj.asOpus().show('lily.pdf') - - return pieceObj def testRun1(self): ballataSht = cadencebook.BallataSheet() @@ -1133,10 +1108,41 @@ def testColorCapuaFicta(self): # assert n13.style.color == 'green' +def _analyzeNonCrederDonna(): + ''' + Run Capua on Francesco, "Non creder, donna" (PMFC 4 6-7, BallataSheet + row 331). Returns ``(pieceObj, outList)`` so both ``Test`` (which only + asserts on ``outList``) and ``TestExternal`` (which renders ``pieceObj`` + with LilyPond) can share the analysis without a test method returning a + value (deprecated in unittest). + ''' + pieceNum = 331 # Francesco, PMFC 4 6-7: Non creder, donna + ballataObj = cadencebook.BallataSheet() + pieceObj = ballataObj.makeWork(pieceNum) + + applyCapuaToCadencebookWork(pieceObj) + srcStream = pieceObj.snippets[0].parts[0].flatten().notesAndRests.stream() + cmpStream = pieceObj.snippets[0].parts[1].flatten().notesAndRests.stream() + # ignore 3rd voice for now... + srcStream.attachIntervalsBetweenStreams(cmpStream) + cmpStream.attachIntervalsBetweenStreams(srcStream) + + outList = [] + for n in srcStream: + if n.editorial.harmonicInterval is not None: + outSublist = [n.name, n.editorial.harmonicInterval.simpleName] + if 'capuaFicta' in n.editorial: + outSublist.append(repr(n.editorial.capuaFicta)) + else: + outSublist.append(None) + outList.append(outSublist) + + return pieceObj, outList + + class TestExternal(unittest.TestCase): # pragma: no cover def testRunNonCrederDonna(self): - t = Test() - pObj = t.testRunNonCrederDonna() + pObj, _outList = _analyzeNonCrederDonna() pObj.asOpus().show('lily.png') def testShowFourA(self): From 787f8c55874cbd7cad3bca4ac3692cc71c59da25 Mon Sep 17 00:00:00 2001 From: Michael Scott Asato Cuthbert Date: Mon, 25 May 2026 22:32:34 -1000 Subject: [PATCH 28/28] Standardize copyright --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 5a9925a..ed34bbd 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2007-2018, Michael Scott Asato Cuthbert and cuthbertLab +Copyright (c) 2004-2026, Michael Scott Asato Cuthbert All rights reserved. Redistribution and use in source and binary forms, with or without