by RetroSonic » Thu Jan 10, 2013 12:30 pm
MusicBrainz NGS fan wrote:I have also problem with Overflow expcetion on line 4176 and I found that there is problem with decimal separator if your default locale is not en-US. I'm using sk-SK and decimal separator for this culture is comma. then munkresme.xml looks like:
Code: Select all
<matrix><row><col>0,166666666666667</col></row></matrix>
and when munkres.exe is trying to proceed this xml, is throwing an error:
Code: Select all
ValueError: invalid literal for float(): 0,166666666666667
in this case, munkresindexes.xml stays empty and this causes error mentioned in previous post.
Code: Select all
Set objMunkresIndexes = objMunkresXML.selectNodes("/matrix/index")
this line returns empty array and next if statement will be true. foreach loop inside will be never executed and cost and i variables will stay initialized to zero.
logme call on line 4176 throws an exception because it tries to divide by zero:
Code: Select all
logme "cost: " & Round(cost / i, 6)
to fix this I made some changes to the function order_items (marked as CUSTOM CODE)
Code: Select all
Function order_items(items, trackinfo):
'"""Orders the items based on how they match some canonical track
'information. Returns a list of Items whose length is equal to the
'length of ``trackinfo``. This always produces a result if the
'numbers of items is at most the number of TrackInfo objects
'(otherwise, returns None). In the case of a partial match, the
'returned list may contain None in some positions.
'"""
'# Make sure lengths match: If there is less items, it might just be that
'# there is some tracks missing.
If items.Count > trackinfo.Count Then
Set order_items = Nothing
MunkresCost = 200
Exit Function
End If
'to compare the dicts in case of issues:
' For j = 0 To items.Count - 1
' logme items.Item(j).Title & " - " & items.Item(j).TrackOrderStr
' Next
'
' For j = 0 To trackinfo.Count - 1
' logme trackinfo.Item(j).Title & " - " & trackinfo.Item(j).TrackOrderStr
' Next
'CUSTOM CODE START
Dim locale
locale = GetLocale
SetLocale("en-US")
'CUSTOM CODE END
'# Construct the cost matrix.
j = 0
Dim costs : Set costs = CreateObject("Scripting.Dictionary")
xml = "<matrix>"
For j = 0 To items.Count - 1
Set cur_item = items.Item(j)
'Set cur_item = items.Item(key)
xml = xml & "<row>"
For i = 0 To trackinfo.Count - 1
'For i, canon_item in enumerate(trackinfo):
xml = xml & "<col>" & track_distance(cur_item, trackinfo.Item(i), trackinfo.Item(i).TrackOrderStr, False) & "</col>"
SDB.ProcessMessages
'row.append(track_distance(cur_item, canon_item, i+1))
Next
'costs.append(row)
xml = xml & "</row>"
Next
xml = xml & "</matrix>"
Dim objFSO, logf
Set objFSO = CreateObject("Scripting.FileSystemObject")
Dim tmpXMLPath: tmpXMLPath = SDB.ScriptsPath & sScriptDir & "munkresme.xml"
Set logf = objFSO.OpenTextFile(tmpXMLPath, 2, True)
logf.WriteLine xml
logf.Close
Set logf = Nothing
Set objFSO = Nothing
'# Find a minimum-cost bipartite matching.
'matching = Munkres().compute(costs)
Set objMunkresXML = Munkres()
'# Order items based on the matching.
'ordered_items = [None]*len(trackinfo)
'for cur_idx, canon_idx in matching:
' ordered_items[canon_idx] = items[cur_idx]
'return ordered_items
Set objMunkresIndexes = objMunkresXML.selectNodes("/matrix/index")
If Not objMunkresIndexes Is Nothing Then
'create a blank dict with the correct size
Dim ordered_items : Set ordered_items = CreateObject("Scripting.Dictionary")
For i = 0 To trackinfo.Count
Set objTemp = Nothing
ordered_items.Add i, objTemp
Next
cost = 0.0
i = 0
For Each mindex in objMunkresIndexes
i = i +1
Set nodeRow = mindex.selectSingleNode("row")
Set nodeCol = mindex.selectSingleNode("col")
Set nodeCost = mindex.selectSingleNode("cost")
rowindex = CInt(nodeRow.Text)
colindex = CInt(nodeCol.Text)
'logme nodeCost.Text
cost = cost + nodeCost.Text
'Set ordered_items.Item(colindex) = items.Item(rowindex) 'rowindex = index in NewTracks? colindex= index in mbitems?
ordered_items.Item(rowindex) = colindex
'logme mindex.selectSingleNode("row").Text & ", " & mindex.selectSingleNode("col").Text
Next
'CUSTOM CODE START
If i > 0 Then
logme "cost: " & Round(cost / i, 6)
MunkresCost = Round(cost / i, 4)
SetLocale(locale)
Set order_items = ordered_items
Else
MunkresCost = 100
SetLocale(locale)
Set order_items = Nothing
End If
'CUSTOM CODE END
Else
MunkresCost = 100
'CUSTOM CODE START
SetLocale(locale)
'CUSTOM CODE END
Set order_items = Nothing
End If
End Function
hope it helps.
Many thanks for this. It works like a charm...
[quote="MusicBrainz NGS fan"]I have also problem with Overflow expcetion on line 4176 and I found that there is problem with decimal separator if your default locale is not en-US. I'm using sk-SK and decimal separator for this culture is comma. then munkresme.xml looks like:
[code]
<matrix><row><col>0,166666666666667</col></row></matrix>
[/code]
and when munkres.exe is trying to proceed this xml, is throwing an error:
[code]
ValueError: invalid literal for float(): 0,166666666666667
[/code]
in this case, munkresindexes.xml stays empty and this causes error mentioned in previous post.
[code]
Set objMunkresIndexes = objMunkresXML.selectNodes("/matrix/index")
[/code]
this line returns empty array and next if statement will be true. foreach loop inside will be never executed and cost and i variables will stay initialized to zero.
logme call on line 4176 throws an exception because it tries to divide by zero:
[code]
logme "cost: " & Round(cost / i, 6)
[/code]
to fix this I made some changes to the function order_items (marked as CUSTOM CODE)
[code]
Function order_items(items, trackinfo):
'"""Orders the items based on how they match some canonical track
'information. Returns a list of Items whose length is equal to the
'length of ``trackinfo``. This always produces a result if the
'numbers of items is at most the number of TrackInfo objects
'(otherwise, returns None). In the case of a partial match, the
'returned list may contain None in some positions.
'"""
'# Make sure lengths match: If there is less items, it might just be that
'# there is some tracks missing.
If items.Count > trackinfo.Count Then
Set order_items = Nothing
MunkresCost = 200
Exit Function
End If
'to compare the dicts in case of issues:
' For j = 0 To items.Count - 1
' logme items.Item(j).Title & " - " & items.Item(j).TrackOrderStr
' Next
'
' For j = 0 To trackinfo.Count - 1
' logme trackinfo.Item(j).Title & " - " & trackinfo.Item(j).TrackOrderStr
' Next
'CUSTOM CODE START
Dim locale
locale = GetLocale
SetLocale("en-US")
'CUSTOM CODE END
'# Construct the cost matrix.
j = 0
Dim costs : Set costs = CreateObject("Scripting.Dictionary")
xml = "<matrix>"
For j = 0 To items.Count - 1
Set cur_item = items.Item(j)
'Set cur_item = items.Item(key)
xml = xml & "<row>"
For i = 0 To trackinfo.Count - 1
'For i, canon_item in enumerate(trackinfo):
xml = xml & "<col>" & track_distance(cur_item, trackinfo.Item(i), trackinfo.Item(i).TrackOrderStr, False) & "</col>"
SDB.ProcessMessages
'row.append(track_distance(cur_item, canon_item, i+1))
Next
'costs.append(row)
xml = xml & "</row>"
Next
xml = xml & "</matrix>"
Dim objFSO, logf
Set objFSO = CreateObject("Scripting.FileSystemObject")
Dim tmpXMLPath: tmpXMLPath = SDB.ScriptsPath & sScriptDir & "munkresme.xml"
Set logf = objFSO.OpenTextFile(tmpXMLPath, 2, True)
logf.WriteLine xml
logf.Close
Set logf = Nothing
Set objFSO = Nothing
'# Find a minimum-cost bipartite matching.
'matching = Munkres().compute(costs)
Set objMunkresXML = Munkres()
'# Order items based on the matching.
'ordered_items = [None]*len(trackinfo)
'for cur_idx, canon_idx in matching:
' ordered_items[canon_idx] = items[cur_idx]
'return ordered_items
Set objMunkresIndexes = objMunkresXML.selectNodes("/matrix/index")
If Not objMunkresIndexes Is Nothing Then
'create a blank dict with the correct size
Dim ordered_items : Set ordered_items = CreateObject("Scripting.Dictionary")
For i = 0 To trackinfo.Count
Set objTemp = Nothing
ordered_items.Add i, objTemp
Next
cost = 0.0
i = 0
For Each mindex in objMunkresIndexes
i = i +1
Set nodeRow = mindex.selectSingleNode("row")
Set nodeCol = mindex.selectSingleNode("col")
Set nodeCost = mindex.selectSingleNode("cost")
rowindex = CInt(nodeRow.Text)
colindex = CInt(nodeCol.Text)
'logme nodeCost.Text
cost = cost + nodeCost.Text
'Set ordered_items.Item(colindex) = items.Item(rowindex) 'rowindex = index in NewTracks? colindex= index in mbitems?
ordered_items.Item(rowindex) = colindex
'logme mindex.selectSingleNode("row").Text & ", " & mindex.selectSingleNode("col").Text
Next
'CUSTOM CODE START
If i > 0 Then
logme "cost: " & Round(cost / i, 6)
MunkresCost = Round(cost / i, 4)
SetLocale(locale)
Set order_items = ordered_items
Else
MunkresCost = 100
SetLocale(locale)
Set order_items = Nothing
End If
'CUSTOM CODE END
Else
MunkresCost = 100
'CUSTOM CODE START
SetLocale(locale)
'CUSTOM CODE END
Set order_items = Nothing
End If
End Function
[/code]
hope it helps.[/quote]
Many thanks for this. It works like a charm...