From d0e129ce3ebad6555e3ea0f9d3e439ee195c4a69 Mon Sep 17 00:00:00 2001 From: McJones Date: Tue, 11 Dec 2018 11:41:10 +1100 Subject: [PATCH 1/3] Replaced raw_input. Cleaned up unsued variables --- Field_D_SupportingClasses.py | 90 +++++++++++++++++------------------- 1 file changed, 42 insertions(+), 48 deletions(-) diff --git a/Field_D_SupportingClasses.py b/Field_D_SupportingClasses.py index f89690e..e0b186d 100644 --- a/Field_D_SupportingClasses.py +++ b/Field_D_SupportingClasses.py @@ -5,6 +5,7 @@ # check out www.github.com/dan-field/Text2SATB for info and rights # #################################################################### +import prompt class DF_Syllables: def __init__(self): @@ -45,8 +46,7 @@ def b(self, word): adjusted_ending = self.breakDownFromBack(rest, ending) adjusted_endLength = 0 for syllable in adjusted_ending: - for letter in syllable: - adjusted_endLength += 1 + adjusted_endLength = len(syllable) if adjusted_endLength > endLength: rest = rest[:len(rest)+endLength-adjusted_endLength] restBrokenDown = self.r(rest) @@ -149,7 +149,7 @@ def breakDownFromBack(self, word, suffix): # now check for 'e' endings (on the whole word, or the word with suffix removed, as applicable) if w[-1] == "e": # last letter is 'e' if w[-2] not in self.vowels and w[-3] in self.vowels_y: # second-last is consonant and third-last is vowel - ending = word[-3]+word[-2]+word[-1] # this is a Vowel-Consonant-e ending + if w[-4] not in self.vowels and len(w) == 4: # it's cons-vowel-cons-'e' so it's a single syllable (note the 'le' ending has already been dealt with in the 'searchSuffix' function) if suffix == "": return [word] @@ -456,15 +456,15 @@ def __init__(self): lineText = [] inputText = [] infile = None - usrFileName = raw_input("please enter the filename of the text input file, e.g. 'mypoem.txt'\n: ") + usrFileName = prompt.string("please enter the filename of the text input file, e.g. 'mypoem.txt': ") try: infile = open(usrFileName, "r") except (OSError, IOError): infile = None - print "\nThere was an issue attempting to open the file." - print "Please double-check your filename; "+usrFileName+"\n" - print "Note your input text file must be in the same" - print "folder as the Python files." + print("\nThere was an issue attempting to open the file.") + print("Please double-check your filename; "+usrFileName+"\n") + print("Note your input text file must be in the same") + print("folder as the Python files.") return if infile is not None: for line in infile.readlines(): @@ -526,11 +526,11 @@ def __init__(self): syllables[-1] = syllables[-1]+punctuation # add the punctuation back on where it came from if punctuation in ".;:!?*": # these punctuation marks will create new lines self.lastWord = True # this will be the last word in this line - positions = range(len(syllables)) # start an 'empty' list with as many members as there are syllables in the word + positions = list(range(len(syllables))) # start an 'empty' list with as many members as there are syllables in the word if len(positions) == 1: # this means there's only one syllable in the word positions[0] = "single" # this follows the MusicXML 'syllabic' convention else: # there are two or more syllables in the word - for index, position in enumerate(positions): + for index, _ in enumerate(positions): if index == 0: # first syllable positions[index] = "begin" elif index == len(positions)-1: # last syllable @@ -553,13 +553,13 @@ def provideScrabbleScores(self): return self.scrabbleScores def provideTitle(self): - usrTitle = raw_input("please enter a Title for the work\n: ") + usrTitle = prompt.string("please enter a Title for the work: ") if usrTitle == "": usrTitle = None return usrTitle def provideLyricist(self): - usrLyricist = raw_input("please enter the Lyricist's name\n: ") + usrLyricist = prompt.string("please enter the Lyricist's name: ") if usrLyricist == "": usrLyricist = None return usrLyricist @@ -627,7 +627,7 @@ def __init__(self, verses, positions, scores): def planHarmonicStructure(self): # looks at the incoming verse structure and generates a chord sequence # Try to keep the chord references numeric/relative for easy adaptation - key = 0 # number zero will represent the 'home' key + verseKey = 0 verseKeys = [] lineKey = 0 @@ -646,7 +646,7 @@ def planHarmonicStructure(self): # but if there are more than 240 syllables, it goes back to zero and starts over again verseKey += keyshift verseKeys.append(verseKey) - for i, line in enumerate(verse): # similarly, we might change key from line to line using the same sort of logic + for i, _ in enumerate(verse): # similarly, we might change key from line to line using the same sort of logic if i == 0: # first line lineKey = verseKey # first line of each verse is in the verse's key elif index == len(self.verses)-1 and i == len(self.verses[index])-1: # this is the last line of the last verse @@ -671,7 +671,7 @@ def determineChordSequence(self): for i, line in enumerate(verse): chordBase[index].append([]) chordType[index].append([]) - for j, syllable in enumerate(line): + for j, _ in enumerate(line): cycleMove = 0 chordComplexity = 0 # we want to set a chord degree and type that reflects the Scrabble score of the word @@ -811,7 +811,7 @@ def getBassPart(self, homeKey): count = 0 barNo = -1 for i, line in enumerate(verse): - for j, syllable in enumerate(line): + for j, _ in enumerate(line): keyRef = self.chordPlan[index][i] chordDegree = self.chordBase[index][i][j] # this is just the step number - it needs to be converted to a chromatic degree number chordDegree = self.convertChordDegree(chordDegree) @@ -828,7 +828,7 @@ def getBassPart(self, homeKey): differences = [abs(loose_target - float(note)) for note in bassTargets] closest = differences.index(min(differences)) thisNote = bassTargets[closest] # pick the bass note that is closest to the comfortable mid point - thisDuration = 4 + # we have all the info we need to start assembling the Bass part if count%16 == 0: # the previous bar is full bassNotes[index].append([]) @@ -842,7 +842,6 @@ def getBassPart(self, homeKey): bassPositions[index][barNo].append(self.positions[index][i][j]) if len(self.durations[index][i][j]) == 1: # the note does not cross a barline L = self.durations[index][i][j][0] - R = self.sylRests[index][i][j][0] bassRhythms[index][barNo].append(L) bassTies[index][barNo].append(None) count += L @@ -895,7 +894,7 @@ def getTenorPart(self, homeKey): count = 0 barNo = -1 for i, line in enumerate(verse): - for j, syllable in enumerate(line): + for j, _ in enumerate(line): keyRef = self.chordPlan[index][i] chordDegree = self.chordBase[index][i][j] # this is just the step number - it needs to be converted to a chromatic degree number chordDegree = self.convertChordDegree(chordDegree) @@ -914,7 +913,7 @@ def getTenorPart(self, homeKey): differences = [abs(loose_target - float(note)) for note in tenTargets] closest = differences.index(min(differences)) thisNote = tenTargets[closest] # pick the tenor note that is closest to the comfortable mid point - thisDuration = 4 + # we have all the info we need to start assembling the Tenor part if count%16 == 0: # the previous bar is full tenNotes[index].append([]) @@ -1030,7 +1029,7 @@ def getAltoPart(self, homeKey): count = 0 barNo = -1 for i, line in enumerate(verse): - for j, syllable in enumerate(line): + for j, _ in enumerate(line): keyRef = self.chordPlan[index][i] chordDegree = self.chordBase[index][i][j] # this is just the step number - it needs to be converted to a chromatic degree number chordDegree = self.convertChordDegree(chordDegree) @@ -1049,7 +1048,7 @@ def getAltoPart(self, homeKey): differences = [abs(loose_target - float(note)) for note in altoTargets] closest = differences.index(min(differences)) thisNote = altoTargets[closest] # pick the alto note that is closest to the comfortable mid point - thisDuration = 4 + # we have all the info we need to start assembling the Alto part if count%16 == 0: # the previous bar is full altoNotes[index].append([]) @@ -1189,9 +1188,7 @@ def getSopPart(self, homeKey): shiftedScale = [] for note in scale: shiftedScale.append(homeKey+keyRef+note) - sopScaleTargets = self.buildFullRange(shiftedScale, self.rangeSop[0], self.rangeSop[1]) - if i == len(verse)-1 and j == len(line)-1: - sopScaleTargets = sopChordTargets + # LOOSE TARGET needs to be modified so that it's a melody note ------------------------------- loose_target = 70.4 # seek out a comfortable mid-point in the soprano range if chordType == 0: @@ -1201,7 +1198,7 @@ def getSopPart(self, homeKey): differences = [abs(loose_target - float(note)) for note in sopChordTargets] closest = differences.index(min(differences)) thisNote = sopChordTargets[closest] # pick the soprano note that is closest to the comfortable mid point - thisDuration = 4 + # we have all the info we need to start assembling the Soprano part if count%16 == 0: # the previous bar is full sopNotes[index].append([]) @@ -1268,7 +1265,6 @@ def getSopPart(self, homeKey): self.sopLatestNote = thisNote else: L = self.durations[index][i][j][0] - R = self.sylRests[index][i][j][0] sopRhythms[index][barNo].append(L) sopTies[index][barNo].append(None) sopNotes[index][barNo].append(thisNote) @@ -1324,9 +1320,7 @@ def getLinesAndSyllables(self, verses): for verse in verses: resultVerse = [] for line in verse: - syllableCount = 0 - for syllable in line: - syllableCount += 1 + syllableCount = len(line) resultVerse.append(syllableCount) resultSong.append(resultVerse) return resultSong @@ -1587,17 +1581,17 @@ def __init__(self, usrTitle=None, progID=None, usrAuthor=None): self.measureNo = 0 self.voice = 1 # 1 Soprano, 2 Alto, 3 Tenor, 4 Bass self.flats = True # assumes black notes should be written as flats - will need to be updated once a 'key' functionality is added - usrFileName = raw_input("please enter a name for the output file\n: ") + usrFileName = prompt.string("please enter a name for the output file: ") self.fileName = usrFileName+".musicxml" try: self.file = open(self.fileName, "w") except (OSError, IOError): self.file = None - print "\nThere was an issue with the file operation." - print "Please double-check your filename.\n" - print "Note the MusicXML file will attempt to save in the" - print "same folder as the Python files; please ensure you" - print "have write permission for that folder." + print("\nThere was an issue with the file operation.") + print("Please double-check your filename.\n") + print("Note the MusicXML file will attempt to save in the") + print("same folder as the Python files; please ensure you") + print("have write permission for that folder.") return self.file.write('\n') self.file.write(' Date: Tue, 11 Dec 2018 18:27:19 +1100 Subject: [PATCH 2/3] replaced hand crafted XML with lxml --- Field_D_SupportingClasses.py | 488 +++++++++++++++++------------------ 1 file changed, 230 insertions(+), 258 deletions(-) diff --git a/Field_D_SupportingClasses.py b/Field_D_SupportingClasses.py index e0b186d..29a2de9 100644 --- a/Field_D_SupportingClasses.py +++ b/Field_D_SupportingClasses.py @@ -6,6 +6,7 @@ #################################################################### import prompt +import lxml.etree as tree class DF_Syllables: def __init__(self): @@ -456,20 +457,24 @@ def __init__(self): lineText = [] inputText = [] infile = None - usrFileName = prompt.string("please enter the filename of the text input file, e.g. 'mypoem.txt': ") - try: - infile = open(usrFileName, "r") - except (OSError, IOError): - infile = None - print("\nThere was an issue attempting to open the file.") - print("Please double-check your filename; "+usrFileName+"\n") - print("Note your input text file must be in the same") - print("folder as the Python files.") - return + + while infile is None: + usrFileName = prompt.string("please enter the filename of the text input file, e.g. 'mypoem.txt': ") + + try: + infile = open(usrFileName, "r") + except (OSError, IOError): + infile = None + print("\nThere was an issue attempting to open the file.") + print("Please double-check your filename; "+usrFileName+"\n") + print("Note your input text file must be in the same") + print("folder as the Python files.") + if infile is not None: for line in infile.readlines(): inputText.append(line) infile.close() + # The input file has been read, and all of the text is in 'inputText' lineText.append("---BREAK---") # this will be used to signify a new verse noted = True # this is a flag to avoid multiple 'new verse' indications in a row @@ -1583,323 +1588,290 @@ def __init__(self, usrTitle=None, progID=None, usrAuthor=None): self.flats = True # assumes black notes should be written as flats - will need to be updated once a 'key' functionality is added usrFileName = prompt.string("please enter a name for the output file: ") self.fileName = usrFileName+".musicxml" - try: - self.file = open(self.fileName, "w") - except (OSError, IOError): - self.file = None - print("\nThere was an issue with the file operation.") - print("Please double-check your filename.\n") - print("Note the MusicXML file will attempt to save in the") - print("same folder as the Python files; please ensure you") - print("have write permission for that folder.") - return - self.file.write('\n') - self.file.write('\n') - self.file.write('\n') - self.file.write(' \n') - self.file.write(' '+str(self.Title)+'\n') - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' '+str(self.progID)+'\n') - self.file.write(' '+str(self.Author)+'\n') - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' Soprano\n') - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' Alto\n') - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' Tenor\n') - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' Bass\n') - self.file.write(' \n') - self.file.write(' \n') + + # building up the xml tree + self.root = tree.Element('score-partwise', attrib={'version':'3.1'}) + work = tree.SubElement(self.root, 'work') + tree.SubElement(work, 'work-title').text = self.Title + + # author + ident = tree.SubElement(self.root,'identification') + tree.SubElement(ident, 'creator', attrib={'type':'composer'}).text = self.progID + tree.SubElement(ident, 'creator', attrib={'type':'lyricist'}).text = self.Author + + # part list + part_list = tree.SubElement(self.root, 'part-list') + score_info = {'P1':'Soprano', 'P2':'Alto', 'P3':'Tenor', 'P4':'Bass'}.items() + for score_id, score_type in score_info: + score_part = tree.SubElement(part_list, 'score-part', attrib={'id': score_id}) + tree.SubElement(score_part, 'part-name').text = score_type + + # this writes a section + # returns a tuple with the part and the current measure + def startSection(self, section): + if self.root is not None: + + part_id = str(section['part_id']) + clef_sign = str(section['clef_sign']) + clef_line = str(section['clef_line']) + + part = tree.SubElement(self.root, 'part', attrib={'id': part_id}) + measure = tree.SubElement(part, 'measure', attrib={'number': str(self.measureNo)}) + attributes = tree.SubElement(measure, 'attributes') + tree.SubElement(attributes, 'divisions').text = str(self.DIVISIONS) + + key = tree.SubElement(attributes, 'key') + tree.SubElement(key, 'fifths').text = '-3' + + time = tree.SubElement(attributes, 'time') + tree.SubElement(time, 'beats').text = '4' + tree.SubElement(time, 'beat-type').text = '4' + + clef = tree.SubElement(attributes, 'clef', attrib= {'number': '1'}) + tree.SubElement(clef, 'sign').text = clef_sign + tree.SubElement(clef, 'line').text = clef_line + + # tenors get an octave change? + if part_id == 'P3': + tree.SubElement(clef, 'clef-octave-change').text = '-1' + + return (part, measure) def startSoprano(self): - if self.file is not None: - self.measureNo = 0 - self.voice = 1 - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' '+str(self.DIVISIONS)+'\n') - self.file.write(' \n') - self.file.write(' -3\n') - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' G\n') - self.file.write(' 2\n') - self.file.write(' \n') - self.file.write(' \n') + self.measureNo = 0 + self.voice = 1 + + # writing the soprano elements to the xml tree + section = {} + section['part_id'] = 'P1' + section['clef_sign'] = 'G' + section['clef_line'] = '2' + return self.startSection(section) + def startAlto(self): - if self.file is not None: - self.measureNo = 0 - self.voice = 2 - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' '+str(self.DIVISIONS)+'\n') - self.file.write(' \n') - self.file.write(' -3\n') - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' G\n') - self.file.write(' 2\n') - self.file.write(' \n') - self.file.write(' \n') + self.measureNo = 0 + self.voice = 2 + + # writing the alto elements to the xml tree + section = {} + section['part_id'] = 'P2' + section['clef_sign'] = 'G' + section['clef_line'] = '2' + return self.startSection(section) def startTenor(self): - if self.file is not None: - self.measureNo = 0 - self.voice = 3 - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' '+str(self.DIVISIONS)+'\n') - self.file.write(' \n') - self.file.write(' -3\n') - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' G\n') - self.file.write(' 2\n') - self.file.write(' -1\n') - self.file.write(' \n') - self.file.write(' \n') + self.measureNo = 0 + self.voice = 3 + + # writing the tenor elements to the xml tree + section = {} + section['part_id'] = 'P3' + section['clef_sign'] = 'G' + section['clef_line'] = '2' + return self.startSection(section) def startBass(self): - if self.file is not None: - self.measureNo = 0 - self.voice = 4 - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' '+str(self.DIVISIONS)+'\n') - self.file.write(' \n') - self.file.write(' -3\n') - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' F\n') - self.file.write(' 4\n') - self.file.write(' \n') - self.file.write(' \n') - - def endPart(self): - if self.file is not None: - self.file.write(' \n') - self.file.write(' light-heavy\n') - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' \n') + self.measureNo = 0 + self.voice = 4 + + # writing the bass elements to the xml tree + section = {} + section['part_id'] = 'P4' + section['clef_sign'] = 'F' + section['clef_line'] = '4' + return self.startSection(section) + + def endPart(self, measure): + barline = tree.SubElement(measure, 'barline', attrib={'location': 'right'}) + tree.SubElement(barline, 'bar-style').text = 'light-heavy' def endXMLFile(self): - if self.file is not None: - self.file.write('\n') - self.file.close() - - def addMeasure(self): - if self.file is not None: - self.file.write(' \n') - self.measureNo += 1 - self.file.write(' \n') - - def addMeasureDbl(self): - if self.file is not None: - self.file.write(' \n') - self.measureNo += 1 - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' light-light\n') - self.file.write(' \n') - - def addMeasureKeyChange(self, newKey): - if self.file is not None: - self.file.write(' \n') - self.measureNo += 1 - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' light-light\n') - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' '+str(newKey)+'\n') - self.file.write(' \n') - self.file.write(' \n') - - def addNote(self, MIDI_No, duration=None, lyric=None, position=None, tie=None): # duration: 4 = crotchet, 16 = semi-breve - if self.file is not None: - if duration is None: - duration = 4 # default to a crotchet - if lyric is None: - lyric = "" # default to no text - note_type, dotted, tiedToMinim = self.MIDI.Duration2Type(duration) - self.file.write(' \n') + string = tree.tostring(self.root, encoding = 'UTF-8', pretty_print = True, standalone = False, doctype = '') + + try: + with open(self.fileName, "wb") as text_file: + text_file.write(string) + except (OSError, IOError): + print("\nThere was an issue with the file operation.") + print("Please double-check your filename and folder permissions.\n") + + + # takes in the current part + # returns the new measure + def addMeasure(self, part): + self.measureNo += 1 + measure = tree.SubElement(part, 'measure', attrib={'number':str(self.measureNo)}) + return measure + + # takes in the current part + # returns the new measure + def addMeasureDbl(self, part): + self.measureNo += 1 + measure = tree.SubElement(part, 'measure',attrib={'number': str(self.measureNo)}) + barline = tree.SubElement(measure, 'barline', attrib={'location':'left'}) + tree.SubElement(barline, 'bar-style').text = 'light-light' + + return measure + + def addNote(self, measure, MIDI_No, duration=None, lyric=None, position=None, tie=None): # duration: 4 = crotchet, 16 = semi-breve + if duration is None: + duration = 4 # default to a crotchet + if lyric is None: + lyric = "" # default to no text + note_type, dotted, tiedToMinim = self.MIDI.Duration2Type(duration) + + note = tree.SubElement(measure, 'note') + + if MIDI_No != "RRR": + octave, step, alter = self.MIDI.MIDI2Note(MIDI_No, self.flats) + + pitch = tree.SubElement(note, 'pitch') + tree.SubElement(pitch, 'step').text = str(step) + + if alter != 0: + tree.SubElement(pitch, 'alter').text = str(alter) + + tree.SubElement(pitch, 'octave').text = str(octave) + else: + tree.SubElement(note, 'rest') + + if tiedToMinim is False: + tree.SubElement(note, 'duration').text = str(duration) + else: + tree.SubElement(note, 'duration').text = str(duration - 8) + + tree.SubElement(note, 'voice').text = str(self.voice) + tree.SubElement(note, 'type').text = note_type + + if dotted is True: + tree.SubElement(note, 'dot') + + if tie is not None and tiedToMinim is False: + notations = tree.SubElement(note, 'notations') + tree.SubElement(notations, 'tied', attrib={'type': str(tie)}) + + if tiedToMinim is True: + notations = tree.SubElement(note, 'notations') + + if tie == "stop": + tree.SubElement(notations, 'tied', attrib={'type': 'stop'}) + + tree.SubElement(notations, 'tied', attrib={'type': 'start'}) + + lyric_node = tree.SubElement(note, 'lyric') + + if position is not None: + tree.SubElement(lyric_node, 'syllabic').text = str(position) + + tree.SubElement(lyric_node, 'text').text = lyric + + if tiedToMinim is True: + note = tree.SubElement(measure, 'note') if MIDI_No != "RRR": - octave, step, alter = self.MIDI.MIDI2Note(MIDI_No, self.flats) - self.file.write(' \n') - self.file.write(' '+str(step)+'\n') + + pitch = tree.SubElement(note, 'pitch') + tree.SubElement(pitch, 'step').text = str(step) + if alter != 0: - self.file.write(' '+str(alter)+'\n') - self.file.write(' '+str(octave)+'\n') - self.file.write(' \n') - else: - self.file.write(' \n') - if tiedToMinim is False: - self.file.write(' '+str(duration)+'\n') + tree.SubElement(pitch, 'alter').text = str(alter) + + tree.SubElement(pitch, 'octave').text = str(octave) else: - self.file.write(' '+str(duration-8)+'\n') - self.file.write(' '+str(self.voice)+'\n') - self.file.write(' '+str(note_type)+'\n') - if dotted is True: - self.file.write(' \n') - if tie is not None and tiedToMinim is False: - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' \n') - if tiedToMinim is True: - self.file.write(' \n') - if tie == "stop": - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' \n') - if position is not None: - self.file.write(' '+str(position)+'\n') - self.file.write(' '+str(lyric)+'\n') - self.file.write(' \n') - self.file.write(' \n') - if tiedToMinim is True: - self.file.write(' \n') - if MIDI_No != "RRR": - self.file.write(' \n') - self.file.write(' '+str(step)+'\n') - if alter != 0: - self.file.write(' '+str(alter)+'\n') - self.file.write(' '+str(octave)+'\n') - self.file.write(' \n') - else: - self.file.write(' \n') - self.file.write(' 8\n') - self.file.write(' '+str(self.voice)+'\n') - self.file.write(' half\n') - self.file.write(' \n') - self.file.write(' \n') - if tie == "start": - self.file.write(' \n') - self.file.write(' \n') - self.file.write(' \n') - - - def backOneBar(self): - if self.file is not None: - self.file.write(' \n') - self.file.write(' '+str(int(self.DIVISIONS*4))+'\n') - self.file.write(' \n') + tree.SubElement(note, 'rest') + + tree.SubElement(note, 'duration').text = '8' + tree.SubElement(note, 'voice').text = str(self.voice) + tree.SubElement(note, 'type').text = 'half' + + notations = tree.SubElement(note, 'notations') + tree.SubElement(notations, 'tied', attrib={'type':'stop'}) + if tie == "start": + tree.SubElement(notations, 'tied', attrib={'tied':'start'}) def writeSop(self, notes, durations, lyrics=None, positions=None, ties=None): - self.startSoprano() + part, measure = self.startSoprano() for Vindex, verse in enumerate(notes): for Bindex, bar in enumerate(verse): if Bindex == len(verse)-1 and Vindex != len(notes)-1: # it's the last bar of the verse but not the last verse - self.addMeasureDbl() + measure = self.addMeasureDbl(part) elif Bindex == len(verse)-1 and Vindex == len(notes)-1: # this is the very last bar; don't add a new bar pass elif Bindex != 0: - self.addMeasure() + measure = self.addMeasure(part) if lyrics is not None and positions is not None and ties is not None: for Nindex, _ in enumerate(bar): - self.addNote(bar[Nindex], durations[Vindex][Bindex][Nindex], lyrics[Vindex][Bindex][Nindex], positions[Vindex][Bindex][Nindex], ties[Vindex][Bindex][Nindex]) + self.addNote(measure, bar[Nindex], durations[Vindex][Bindex][Nindex], lyrics[Vindex][Bindex][Nindex], positions[Vindex][Bindex][Nindex], ties[Vindex][Bindex][Nindex]) elif lyrics is not None: for Nindex, _ in enumerate(bar): - self.addNote(bar[Nindex], durations[Vindex][Bindex][Nindex], lyrics[Vindex][Bindex][Nindex]) + self.addNote(measure, bar[Nindex], durations[Vindex][Bindex][Nindex], lyrics[Vindex][Bindex][Nindex]) else: for Nindex, _ in enumerate(bar): - self.addNote(bar[Nindex], durations[Vindex][Bindex][Nindex]) - self.endPart() + self.addNote(measure, bar[Nindex], durations[Vindex][Bindex][Nindex]) + self.endPart(measure) def writeAlto(self, notes, durations, lyrics=None, positions=None, ties=None): - self.startAlto() + part, measure = self.startAlto() for Vindex, verse in enumerate(notes): for Bindex, bar in enumerate(verse): if Bindex == len(verse)-1 and Vindex != len(notes)-1: # it's the last bar of the verse but not the last verse - self.addMeasureDbl() + measure = self.addMeasureDbl(part) elif Bindex == len(verse)-1 and Vindex == len(notes)-1: # this is the very last bar; don't add a new bar pass elif Bindex != 0: - self.addMeasure() + measure = self.addMeasure(part) if lyrics is not None and positions is not None and ties is not None: for Nindex, _ in enumerate(bar): - self.addNote(bar[Nindex], durations[Vindex][Bindex][Nindex], lyrics[Vindex][Bindex][Nindex], positions[Vindex][Bindex][Nindex], ties[Vindex][Bindex][Nindex]) + self.addNote(measure, bar[Nindex], durations[Vindex][Bindex][Nindex], lyrics[Vindex][Bindex][Nindex], positions[Vindex][Bindex][Nindex], ties[Vindex][Bindex][Nindex]) elif lyrics is not None: for Nindex, _ in enumerate(bar): - self.addNote(bar[Nindex], durations[Vindex][Bindex][Nindex], lyrics[Vindex][Bindex][Nindex]) + self.addNote(measure, bar[Nindex], durations[Vindex][Bindex][Nindex], lyrics[Vindex][Bindex][Nindex]) else: for Nindex, _ in enumerate(bar): - self.addNote(bar[Nindex], durations[Vindex][Bindex][Nindex]) - self.endPart() + self.addNote(measure, bar[Nindex], durations[Vindex][Bindex][Nindex]) + self.endPart(measure) def writeTenor(self, notes, durations, lyrics=None, positions=None, ties=None): - self.startTenor() + part, measure = self.startTenor() for Vindex, verse in enumerate(notes): for Bindex, bar in enumerate(verse): if Bindex == len(verse)-1 and Vindex != len(notes)-1: # it's the last bar of the verse but not the last verse - self.addMeasureDbl() + measure = self.addMeasureDbl(part) elif Bindex == len(verse)-1 and Vindex == len(notes)-1: # this is the very last bar; don't add a new bar pass elif Bindex != 0: - self.addMeasure() + measure = self.addMeasure(part) if lyrics is not None and positions is not None and ties is not None: for Nindex, _ in enumerate(bar): - self.addNote(bar[Nindex], durations[Vindex][Bindex][Nindex], lyrics[Vindex][Bindex][Nindex], positions[Vindex][Bindex][Nindex], ties[Vindex][Bindex][Nindex]) + self.addNote(measure, bar[Nindex], durations[Vindex][Bindex][Nindex], lyrics[Vindex][Bindex][Nindex], positions[Vindex][Bindex][Nindex], ties[Vindex][Bindex][Nindex]) elif lyrics is not None: for Nindex, _ in enumerate(bar): - self.addNote(bar[Nindex], durations[Vindex][Bindex][Nindex], lyrics[Vindex][Bindex][Nindex]) + self.addNote(measure, bar[Nindex], durations[Vindex][Bindex][Nindex], lyrics[Vindex][Bindex][Nindex]) else: for Nindex, _ in enumerate(bar): - self.addNote(bar[Nindex], durations[Vindex][Bindex][Nindex]) - self.endPart() + self.addNote(measure, bar[Nindex], durations[Vindex][Bindex][Nindex]) + self.endPart(measure) def writeBass(self, notes, durations, lyrics=None, positions=None, ties=None): - self.startBass() + part, measure = self.startBass() for Vindex, verse in enumerate(notes): for Bindex, bar in enumerate(verse): if Bindex == len(verse)-1 and Vindex != len(notes)-1: # it's the last bar of the verse but not the last verse - self.addMeasureDbl() + measure = self.addMeasureDbl(part) elif Bindex == len(verse)-1 and Vindex == len(notes)-1: # this is the very last bar; don't add a new bar pass elif Bindex != 0: - self.addMeasure() + measure = self.addMeasure(part) if lyrics is not None and positions is not None and ties is not None: for Nindex, _ in enumerate(bar): - self.addNote(bar[Nindex], durations[Vindex][Bindex][Nindex], lyrics[Vindex][Bindex][Nindex], positions[Vindex][Bindex][Nindex], ties[Vindex][Bindex][Nindex]) + self.addNote(measure, bar[Nindex], durations[Vindex][Bindex][Nindex], lyrics[Vindex][Bindex][Nindex], positions[Vindex][Bindex][Nindex], ties[Vindex][Bindex][Nindex]) elif lyrics is not None: for Nindex, _ in enumerate(bar): - self.addNote(bar[Nindex], durations[Vindex][Bindex][Nindex], lyrics[Vindex][Bindex][Nindex]) + self.addNote(measure, bar[Nindex], durations[Vindex][Bindex][Nindex], lyrics[Vindex][Bindex][Nindex]) else: for Nindex, _ in enumerate(bar): - self.addNote(bar[Nindex], durations[Vindex][Bindex][Nindex]) - self.endPart() + self.addNote(measure, bar[Nindex], durations[Vindex][Bindex][Nindex]) + self.endPart(measure) def MIDI2Fifths(self, MIDI_Key): MIDI_Key = int(MIDI_Key) From f4172aa7b113cd6ed0d610ced5de51c6381fe23d Mon Sep 17 00:00:00 2001 From: McJones Date: Wed, 12 Dec 2018 10:30:26 +1100 Subject: [PATCH 3/3] cleaned up some duplicated code --- Field_D_SupportingClasses.py | 64 +++++------------------------------- 1 file changed, 8 insertions(+), 56 deletions(-) diff --git a/Field_D_SupportingClasses.py b/Field_D_SupportingClasses.py index 29a2de9..08b86eb 100644 --- a/Field_D_SupportingClasses.py +++ b/Field_D_SupportingClasses.py @@ -1789,8 +1789,7 @@ def addNote(self, measure, MIDI_No, duration=None, lyric=None, position=None, ti if tie == "start": tree.SubElement(notations, 'tied', attrib={'tied':'start'}) - def writeSop(self, notes, durations, lyrics=None, positions=None, ties=None): - part, measure = self.startSoprano() + def writeSection(self, part, measure, notes, durations, lyrics=None, positions=None, ties=None): for Vindex, verse in enumerate(notes): for Bindex, bar in enumerate(verse): if Bindex == len(verse)-1 and Vindex != len(notes)-1: # it's the last bar of the verse but not the last verse @@ -1810,68 +1809,21 @@ def writeSop(self, notes, durations, lyrics=None, positions=None, ties=None): self.addNote(measure, bar[Nindex], durations[Vindex][Bindex][Nindex]) self.endPart(measure) + def writeSop(self, notes, durations, lyrics=None, positions=None, ties=None): + part, measure = self.startSoprano() + self.writeSection(part, measure, notes, durations, lyrics, positions, ties) + def writeAlto(self, notes, durations, lyrics=None, positions=None, ties=None): part, measure = self.startAlto() - for Vindex, verse in enumerate(notes): - for Bindex, bar in enumerate(verse): - if Bindex == len(verse)-1 and Vindex != len(notes)-1: # it's the last bar of the verse but not the last verse - measure = self.addMeasureDbl(part) - elif Bindex == len(verse)-1 and Vindex == len(notes)-1: # this is the very last bar; don't add a new bar - pass - elif Bindex != 0: - measure = self.addMeasure(part) - if lyrics is not None and positions is not None and ties is not None: - for Nindex, _ in enumerate(bar): - self.addNote(measure, bar[Nindex], durations[Vindex][Bindex][Nindex], lyrics[Vindex][Bindex][Nindex], positions[Vindex][Bindex][Nindex], ties[Vindex][Bindex][Nindex]) - elif lyrics is not None: - for Nindex, _ in enumerate(bar): - self.addNote(measure, bar[Nindex], durations[Vindex][Bindex][Nindex], lyrics[Vindex][Bindex][Nindex]) - else: - for Nindex, _ in enumerate(bar): - self.addNote(measure, bar[Nindex], durations[Vindex][Bindex][Nindex]) - self.endPart(measure) + self.writeSection(part, measure, notes, durations, lyrics, positions, ties) def writeTenor(self, notes, durations, lyrics=None, positions=None, ties=None): part, measure = self.startTenor() - for Vindex, verse in enumerate(notes): - for Bindex, bar in enumerate(verse): - if Bindex == len(verse)-1 and Vindex != len(notes)-1: # it's the last bar of the verse but not the last verse - measure = self.addMeasureDbl(part) - elif Bindex == len(verse)-1 and Vindex == len(notes)-1: # this is the very last bar; don't add a new bar - pass - elif Bindex != 0: - measure = self.addMeasure(part) - if lyrics is not None and positions is not None and ties is not None: - for Nindex, _ in enumerate(bar): - self.addNote(measure, bar[Nindex], durations[Vindex][Bindex][Nindex], lyrics[Vindex][Bindex][Nindex], positions[Vindex][Bindex][Nindex], ties[Vindex][Bindex][Nindex]) - elif lyrics is not None: - for Nindex, _ in enumerate(bar): - self.addNote(measure, bar[Nindex], durations[Vindex][Bindex][Nindex], lyrics[Vindex][Bindex][Nindex]) - else: - for Nindex, _ in enumerate(bar): - self.addNote(measure, bar[Nindex], durations[Vindex][Bindex][Nindex]) - self.endPart(measure) + self.writeSection(part, measure, notes, durations, lyrics, positions, ties) def writeBass(self, notes, durations, lyrics=None, positions=None, ties=None): part, measure = self.startBass() - for Vindex, verse in enumerate(notes): - for Bindex, bar in enumerate(verse): - if Bindex == len(verse)-1 and Vindex != len(notes)-1: # it's the last bar of the verse but not the last verse - measure = self.addMeasureDbl(part) - elif Bindex == len(verse)-1 and Vindex == len(notes)-1: # this is the very last bar; don't add a new bar - pass - elif Bindex != 0: - measure = self.addMeasure(part) - if lyrics is not None and positions is not None and ties is not None: - for Nindex, _ in enumerate(bar): - self.addNote(measure, bar[Nindex], durations[Vindex][Bindex][Nindex], lyrics[Vindex][Bindex][Nindex], positions[Vindex][Bindex][Nindex], ties[Vindex][Bindex][Nindex]) - elif lyrics is not None: - for Nindex, _ in enumerate(bar): - self.addNote(measure, bar[Nindex], durations[Vindex][Bindex][Nindex], lyrics[Vindex][Bindex][Nindex]) - else: - for Nindex, _ in enumerate(bar): - self.addNote(measure, bar[Nindex], durations[Vindex][Bindex][Nindex]) - self.endPart(measure) + self.writeSection(part, measure, notes, durations, lyrics, positions, ties) def MIDI2Fifths(self, MIDI_Key): MIDI_Key = int(MIDI_Key)