<jupyter_start><jupyter_text>Get corpus and parse to pieces<jupyter_code>coreCorpus = corpus.corpora.CoreCorpus()
sixEight = corpus.search('6/8')

bachCorpusScores = []
for c in sixEight:
    score = c.parse()
    bachCorpusScores.append(score)<jupyter_output><empty_output><jupyter_text>Collect notes from a single piece<jupyter_code>sBach = corpus.parse('bach/bwv57.8')
len(sBach.getElementsByClass(stream.Part))

measures = len(sBach.getElementsByClass(stream.Part)[0].getElementsByClass(stream.Measure))
# Get a part of the piece
noteIterator = sBach.parts[0].getElementsByClass(stream.Measure).flat.getElementsByClass('Note')
allNotes = []

for el in noteIterator:
    if('-' in el.nameWithOctave):
        noteName = el.pitch.getEnharmonic().nameWithOctave
        allNotes.append(noteName)
    else:
        noteName = el.nameWithOctave
        allNotes.append(noteName)<jupyter_output><empty_output><jupyter_text>Collect notes from a corpus<jupyter_code>possibleNotes = set() # set containing all possible notes for matrix creation
allNotesPerPiece = [] # Multidimensional array of all notes per piece
for p in bachCorpusScores:
    currNotes = []
    measures = len(p.getElementsByClass(stream.Part)[0].getElementsByClass(stream.Measure))
    # Get a part of the piece
    noteIterator = p.parts[0].getElementsByClass(stream.Measure).flat.getElementsByClass('Note')
    if(len(noteIterator) == 0):
        continue
    for el in noteIterator:
        pitchName = el.nameWithOctave
        if('-' in pitchName or '##' in pitchName):
            noteName = el.pitch.getEnharmonic().nameWithOctave
            possibleNotes.add(noteName)
            currNotes.append(noteName)
        else:
            noteName = el.nameWithOctave
            possibleNotes.add(noteName)
            currNotes.append(noteName)
            
    allNotesPerPiece.append(currNotes)
flatten = lambda l: [item for sublist in l for item in sublist]
flatten(allNotesPerPiece)
# Get frequency array
counter = collections.Counter(flatten(allNotesPerPiece))

# Check if no empty pieces
print(len(allNotesPerPiece))
print(len(list(filter(lambda x: x > 0, map(len, allNotesPerPiece)))))<jupyter_output><empty_output><jupyter_text>Create frequency matrix<jupyter_code># Get frequency array
counter = collections.Counter(flatten(allNotesPerPiece))
# Initial note counter
counter[' '] = len(allNotesPerPiece)

noteRows = possibleNotes.add(' ')

zeros = np.full((len(possibleNotes), len(possibleNotes)), 0)
matrix = pd.DataFrame(zeros, index=possibleNotes, columns=possibleNotes)
matrix = matrix.astype(float)

for allNotes in allNotesPerPiece:
    # Fill transition matrix frequencies
    for i in range(len(allNotes)+1):
        # First note
        if(i == 0):
            matrix[' '][allNotes[i]] = matrix[' '][allNotes[i]] + 1
            continue
        # Last note
        if(i == len(allNotes)):
            matrix[allNotes[i-1]][' '] = matrix[allNotes[i-1]][' '] + 1
            continue

        currNote = allNotes[i-1]
        nextNote = allNotes[i]

        matrix[currNote][nextNote] = matrix[currNote][nextNote] + 1

### Divide each row to get probabilistic model
for i in possibleNotes:
    for j in possibleNotes:
        matrix[j][i] = matrix[j][i] / counter[j]
tr = matrix[' ']
tr
# Check if p sum up to one
matrix.sum(0)
def getRandomTransition(matrix, startNote):
    rng = random.random()
    transitions = []
    if(startNote is None):
        transitions = matrix[' ']
    else:
        transitions = matrix[startNote]
    pSum = 0.0
    for k,v in transitions.iteritems():
        if rng > pSum and rng < pSum + v:
            return k
        else:
            pSum += v
        
    print(f'P of {startNote} does not add up to 1.0')
    print(f'Sum = {pSum}')
    print(f'Rng = {rng}')        
populationSize = 10
iterations = 1
measureLength = 8

population = []

for i in range(populationSize): 
    individual = []
    for j in range(measureLength):
        random.random()
        while(len(individual) < measureLength):
            nextNote = None
            if(len(individual) == 0):
                # Add durations
                nextNote = getRandomTransition(matrix, None)
            else:
                # Add durations
                nextNote = getRandomTransition(matrix, individual[-1])
            individual.append(nextNote)
    print(individual)
    population.append(individual)



# Map note strings to music21 notes
notes = list(map(lambda x: list(map(lambda y: note.Note(y), x)), population))
s = stream.Score(id='mainScore')
part = stream.Part(id='part0')
measures = []
for i in range(notes):
    m = stream.Measure(i+1)
    notesInMeasure = notes[i]
    m.extend(notesInMeasure)
    part.append(m)
    
part
# Export to csv
matrix.to_csv(path_or_buf="./transition-matrix.csv")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11644260599793174, 'fraction_numerical': 0.007238883143743537, 'mean_word_length': 3.279646017699115, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '555160', 'license': 'MIT', 'n_tokens_mistral': 1603, 'n_tokens_neox': 1505, 'n_words': 346, 'path': 'EvoMusicCompanion/jupyter/model-building.ipynb', 'repo_name': 'Jerryhu1/MasterThesis', 'size': '4835'}