• We are currently performing site maintenance, parts of civfanatics are currently offline, but will come back online in the coming days. For more updates please see here.

Making sorted() Python 2.3.5 compatible (for Mac)

Xyth

History Rewritten
Joined
Jul 14, 2004
Messages
4,106
Location
Aotearoa
I'm trying to get Culturally Linked Starts to work on Mac. Mac BTS uses Python 2.3.5, which lacks some of the sorting functionality/formatting of 2.4 and later versions, sorted() in particular. The line below in bold is the one throwing an error and I'm not sure how to fix it in this situation:

Code:
		def runAntColonyOptimization():
			# constants
			# NUM_RUNS = 50
			# NUM_ANTS = 250
			# NUM_BEST_ANTS = 5
			# PHEROMON_UPDATE = 0.025
			NUM_ANTS = iNumPlayers
			NUM_BEST_ANTS = int(iNumPlayers / 10)
			NUM_RUNS = iNumPlayers * 25
			PHEROMON_UPDATE = 0.34 / iNumPlayers
			# the best ant (permutation, error) we know
			TheBestAnt = (None, 'inf')
			# uniformly distributed pheromon at the beginning
			fPheromonMatrix = SquareMatrix(iNumPlayers, 1 / iNumPlayers)
			# the actual ACO:
			for iRun in xrange(NUM_RUNS):
				ants = {}
				# get some random ants:
				for i in xrange(NUM_ANTS):
					permutation = randomList(iPlayersList, fPheromonMatrix)
					error = evaluatePermutation(permutation)
					ants[error] = permutation
				bestants = []
				# get the x best ants (smallest error):
				[B]for error in sorted(ants)[:NUM_BEST_ANTS]:[/B]
					ant = (ants[error], error)
					bestants.append(ant)
				# check if we have a new TheBestAnt:
				if bestants[0][1] < TheBestAnt[1]:
					TheBestAnt = bestants[0]
					print "%s %.8f (%d)" % (TheBestAnt[0], TheBestAnt[1], iRun)
				# let the x best ants update the pheromon matrix:
				for i, pos in enumerate(fPheromonMatrix):
						for ant in bestants:
							value = ant[0][i]
							fPheromonMatrix[i][value] = pos[value] + PHEROMON_UPDATE
						# total probability for each pos has to be one:
						fPheromonMatrix[i] = ScaleList(fPheromonMatrix[i])
			return TheBestAnt

Anyone able to help me rewrite that line in a 2.3.5 compatible way? I've learned how to fix some of these issues myself (thanks to several people here!) but this one I'm at a bit of a loss on.
 
I remember having this problem. sorted() is new in Python 2.4, and creates a sorted copy of the iterable you apply it to. Python 2.3 has sort(), which only works on lists, and takes fewer parameters, but it sorts the list in-place.

As you don't use the extra parameters provided by sorted(), and assuming ants is a list, you should be able to do the equivalent to sorted() with Python 2.3 by making a copy of the list you want to sort, and then running sort() on it.
Code:
			# get the x best ants (smallest error):
				sortedAnts = ants
				sortedAnts.sort()
				for error in sortedAnts[:NUM_BEST_ANTS]:
					ant = (sortedAnts[error], error)
					bestants.append(ant)
[
This assumes you want the original ants list to remain unsorted. If you don't mind them being sorted, you don't need to copy it first.
 
Thanks Alan, that explanation makes sense. Unfortuantely though it didn't work, I get the following error:

Code:
AttributeError: 'dict' object has no attribute 'sort'

So I guess that means ants is a dictionary and not a list after all. Any idea how to sort a dictionary in a similar fashion to the original code?
 
I think you just need to use a sorted list of the dictionary's keys. I think that is what the sorted() function returns when run on a dictionary - just a list of the keys that has been sorted. The "ant" tuple is constructed by looking up the value (which is apparently a list) in the dictionary using key in the sorted order ("ants[error]").

Code:
				# get the x best ants (smallest error):
				sortedkeys = ants.keys()
				sortedkeys.sort()
				for error in sortedkeys[:NUM_BEST_ANTS]:
					ant = (ants[error], error)
					bestants.append(ant)
(Untested, of course.)
 
That did the trick, thank you!
 
Back
Top Bottom