# "Natural sorting" of Pose Libs

I’ve done a really ugly script that sorts the poselib poses alphabetically.
The problem is the sorting method. This is a sorted example :
Pose1
Pose10
Pose11
Pose2
Pose3
Pose4

I’ve been told I need “natural sorting” algorithm, but I’m lost.
Currently the sorting part of my script is this:

``````import bpy
armaturename='armaturex'

def str_compare(a,b):
#a=b -&gt; 0
#a&lt;b -&gt; 1
#a&gt;b -&gt; -1
#if they are the same
if a==b:
#print("the same")
return 0 #returns 0

lena=len(a)
lenb=len(b)
count=0
for count in range(lena):
if count&gt;=lenb:
return -1
else:
if a[count]&gt;b[count]:
return -1
if a[count]&lt;b[count]:
return 1
return 1

def compara(a,b):
if str_compare(a.name.lower(),b.name.lower())==1:
name=a.name
frame=a.frame
a.name=b.name
a.frame=b.frame
b.name=name
b.frame=frame
return{'FINISHED'}

class OBJECT_OT_sortlibrary(bpy.types.Operator):
bl_idname="object.sortlibrary"
bl_label="Sort the pose library"

def execute(self,context):
import bpy
print("Initializing poses sorting")
#get the time range
range=bpy.data.actions[bpy.context.object.pose_library.name].frame_range
start=range[0]
end=range[1]
print("The range is from "+str(start )+ " to " +str(end))
#get pose markers
frames=[]
valores=[]
count=0
for pmark in bpy.data.actions[bpy.context.object.pose_library.name].pose_markers :
print ("Pose: "+str(pmark))
frames.append(pmark.frame)
valores.append(str(pmark))
print("Item " +str(count)+". Frame "+str(frames[count])+" es "+str(valores[count]))
for pmarkb in bpy.data.actions[bpy.context.object.pose_library.name].pose_markers :
if pmark!=pmarkb:
compara(pmark,pmarkb)
count =count+1

return {'FINISHED'}
``````

Note: this is not the full script because it is quite long, this is just the sorting related part. And sorry for the Spanish words in the code.
What should I change for getting a “natural sorting”?

Unfortunately, Python doesn’t have built-in natural sorting.

as it happens a while back i wrote little script that pads numbers with zeroes so you get 00001, 00002, 00030, 00400, 05000. which works great if you know in advance the largest number you might see. These of course do sort automatically in the correct order.

all you have to code is a script that looks at the string of the pose name, and starting from the last character stores all the characters that are of type integer when checked.

``````
# given
pose_list = "Pose1", "Pose10", "Pose11", "Pose2", "Pose3", "Pose4"

for pose in pose_list:
print(pose)

integers = True
num_string = ""
position = -1
while(integers):
character = pose[position]
if character.isdigit():
position -= 1
num_string = character + num_string
else:
integers = False

print(num_string)

``````

but it’s not very fast, you might use a match object instead, it keeps the code easier to read :

``````
import re

pose_list = "Pose1", "Pose10", "Pose11", "Pose2", "Pose3", "Pose4"
pattern = '\d+'  # one or more numerical characters

for pose in pose_list:
match = re.search(pattern, pose)
if match:
print(match.group())
else:
print("no numerical characters in pose name")

``````

this stuff works a treat if you have large sets of objects being created and named and you want them ordered nicely. but if you are simply dealing with a number of poses that you manually name, i’d suggest adding the padding-zeroes yourself. For example sometimes when i’m modeling something i save continuously using filename_001, filename_002…filename_010… etc that way when looking in the file/folders the .blends are in the correct order.

well, this bugged me and i remembered a bit of extra details on the sorted() method, which is you can define your own sort parameters. http://code.google.com/edu/languages/google-python-class/sorting.html

this works but not if your list is inconsistent and has names without numericals you will need additional error checking.

``````
import re

pose_list = "Pose1", "Pose10", "Pose11", "Pose2", "Pose3", "Pose4"
pattern = '\d+'  # one or more numerical characters

def MyFn(pose):
match = re.search(pattern, pose)
return int(match.group())

print(sorted(pose_list, key=MyFn))

&gt;&gt;&gt; ['Pose1', 'Pose2', 'Pose3', 'Pose4', 'Pose10', 'Pose11']

``````

Thank you guys. I’ll give it a new try and if I get something I’ll post it here.