UPDATE: I figured out my issue
gram = notesNumbers[i:(i+1)];
When I print gram
it prints it as an array with only 1 value. For example it would print [55]
. Later in my code im referencing gram, however its using the whole array instead of the one value inside of it. To make it work I had to do gram[0]
But a much easier approach was to just rewrite the above code to:
gram = notesNumbers[i]
Now when I print gram
it give me a value ex) 55
In my code
I understand people have had similar issues, but in my context how do I fix this!
Im trying to do some prediction based on markov chains.
I have a very simple program. I have used the library mido to get music notes. I have parsed it and have all the notes in an array called notesNumbers
the notesNumbers
array output looks like this
[55, 62, 67, 74, 55, 62, 67, 74, 55, 62, 67, 74, 55, 62, 67, 74, 55, 62, 67, 74, 55, 62, 67, 74, 55, 62, 67, 74, 55, 48, 52, 55, 59, 67, 71, 67, 71, 67, 71, 59, 67, 71]
I then created a new empty dictionary called ngrams
I have set a starting point for the markovchain as 88 noted by the variable currentGram
what I then proceed to do is to create the markov transition 'matrix'. I use my dictionary to create a key with a number, then for the value I create an array which holds every possible "next number" that occurs in the given notesNumber
What I should be seeing if I print ngrams
would be something like this (example):
{'88': ['45', '55', '67', '45', '45', '33', '77', '90'], '32': ['44', '76', '77'}
however when trying to add to my dictionary by iterating I get the error TypeError: unhashable type: 'list' python
I get the error in the line that contains
if not gram in ngrams:
Code is below:
from midiutil.MidiFile import MIDIFile
import random
import mido
from mido import MidiFile
from mido import MidiTrack
#ignore midi stuff
mid = MidiFile()
track = MidiTrack()
mid.tracks.append(track)
notesNumbers = []
#notesNumbers = notesNumbers2
ngrams= {}
#Parsing message to get the notes to be played
for msg in MidiFile('song.mid'):
if (not msg.is_meta):
if (msg.type == 'note_on'):
notesNumbers.append(msg.note)
#print(notesNumbers)
#starting number I picked
currentGram = 88
#print notesNumbers
#myOtherString = "".join(str(elm) for elm in notesNumbers)
#print notesNumbers2
#currentGram = random.choice(myOtherString)
ngrams= {}
#print currentGram
print(len(notesNumbers))
#creating markov transition matrix without directly doing probabilty
#Creating a dictionary, getting each number and the frequency of the following number
for i in range(len(notesNumbers)):
print("about to iterate")
gram = notesNumbers[i:(i+1)];
print(gram)
print("finish iterate")
lessthan = len(notesNumbers) - 1
if not gram in ngrams:
ngrams[gram] = []
else:
if (i < lessthan):
nextgram = notesNumbers[i+1]
ngrams[gram].append(nextgram)
print(ngrams)
result = []
result.append(currentGram)
#getting next state
for i in range(len(notesNumbers)):
possibilites = ngrams[currentGram]
#print possibilites
nextChoice = random.choice(possibilites)
#print nextChoice
result.append(nextChoice)
currentGram = nextChoice
print("Restult")
print result