'counter' versioning for object renaming not working

57 views
Skip to first unread message

likage

unread,
Aug 22, 2016, 8:58:29 PM8/22/16
to Python Programming for Autodesk Maya
I am trying to do some grouping with the usage of counters, such that it will increment accordingly.. I apologize if my title gives the wrong impression but...

Anyway, when I have 2 or more selections and as I execute my code, instead of seeing groups with naming such as - TEST_1_GRP, TEST_2_GRP, TEST_3_GRP etc., I am getting TEST_1_GRP, TEST_1_GRP1, TEST_1_GRP2 as my results...

I tried placing some of the line for the counter portion around (like within/ before the for sentence), I am getting nowhere..

Below is my code:
def fix_shapes():
    all_geos
= cmds.ls(sl = True)
   
for geo in all_geos:
        shapes
= cmds.listRelatives(geo, fullPath=True, shapes=True)
       
       
if len(shapes) == 1:
           
continue
       
        new_listing
= []
        listing
.append(shapes[:1])
       
# pop out the first shape, since we don't have to fix it
        multi_shapes
= shapes[1:]
       
for multi_shape in multi_shapes:
            new_transform
= cmds.duplicate(multi_shape, parentOnly=True)
            new_geos
= cmds.parent(multi_shape, new_transform, addObject=True, shape=True)
            listing
.append(new_geos)


           
# remove the shape from its original transform
            cmds
.parent(multi_shape, removeObject=True, shape=True)
       
       
# counter to 'version' up new_geos group naming
        counter
= 0
        new_group_name
= cmds.group(em=True, name = 'TEST_' + str(counter + 1) + '_GRP')
       
       
for item in new_listing:
            counter
= counter + 1
            new_geos_parent_name
= cmds.listRelatives(item, parent = True)
            cmds
.parent(new_geos_parent_name, new_group_name)

Greatly appreciate for any advice..


test.ma

likage

unread,
Aug 22, 2016, 9:03:18 PM8/22/16
to Python Programming for Autodesk Maya
Just a little bit more information.. If I change the latter portion of my code to:
        counter = 0
       
for item in listing:

            counter
= counter + 1
            new_geos_parent_name
= cmds.listRelatives(item, parent = True)

            new_group_name
= cmds.group(em = True, name = 'TEST_' + str(counter) + '_GRP')
            cmds
.parent(new_geos_parent_name, new_group_name)

I will get 3 different groups created, each with an individual geometry within them..

Justin Israel

unread,
Aug 22, 2016, 10:16:44 PM8/22/16
to python_in...@googlegroups.com
The problem that I see is that you are doing your counter on the inner loop. This means you will end up getting name clashes for each "geo" in "all_geos". That is, your defined naming pattern is:  TEST_<NUM>_GRP
While you are making sure to increment the name for each inner loopitem, you will start over at the next geo and then Maya's own unique naming logic is helping you out by appending a number to the name. If you were to use a unique counter for the outer loop (at the start of your function), this would end up with a different outcome.

Futhermore, since you are doing your own internal counter, this does not prevent you from still having that number added to the end when you run this script more than once, since you are likely to clash again with groups from the previous run.

If you really want to be able to have custom naming with a custom number increment, then you may want to try your own unique naming function. Something like this?

def uniqueNamePattern(base="object"):
    i = 1
    customRepl = base.format('x') != base  

    if customRepl:
        name = base.format() 
    else:
        name = base 

    while cmds.objExists(name):
        i += 1
        if customRepl:
            name = base.format() 
        else:
            name = "{0}{1}".format(base, i) 

    return name 

cmds.group(name=uniqueNamePattern("test_{0}_GRP"))

Justin

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/fde473f3-2f99-459c-82dc-f92061d65f4f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

likage

unread,
Aug 23, 2016, 2:40:05 AM8/23/16
to Python Programming for Autodesk Maya
Hi, was wondering if you could explain more on 'base='object' as I am not really understanding it... Not to mention about the base.format that you have used.

Correct me if I am wrong but is that suppose to be the name of object?

Alok Gandhi

unread,
Aug 23, 2016, 3:01:01 AM8/23/16
to python_in...@googlegroups.com
@Justin : Might I suggest a minor change to your example function : using the format code in the default argument would make it more readable (especially in absence of any example usage)

so the signature becomes:
def uniqueNamePattern(base="whatever_{0}_whatever")

This improves readability for `base.format` used later.

- Alok




On Tue, Aug 23, 2016 at 2:40 PM, likage <dissid...@gmail.com> wrote:
Hi, was wondering if you could explain more on 'base='object' as I am not really understanding it... Not to mention about the base.format that you have used.

Correct me if I am wrong but is that suppose to be the name of object?
--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/75146519-887f-492b-89c5-0a3eba98d3b4%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--

Justin Israel

unread,
Aug 23, 2016, 7:09:38 AM8/23/16
to python_in...@googlegroups.com
Sorry, I wrote this pretty quickly and didn't do any docstrings. Also realized I had bugs from when I had to retype it from my internal network into our public network :-) 
Updated here:

@likage
Hopefully the new comments help. But basically you pass the function the name you want to start with. If you dont pass it anything, it will start with the name "object".
Then it will keep checking and updating the name with the counter until it finds a free name. 
The usage of the format() method is just basic python str.format():

@alok
I guess I could have made the default base use the pattern that likage had specified, but I was really just making it generic and then the usage of it could specify that custom format. Maybe my docstrings clarified the usage though?

Justin


On Tue, Aug 23, 2016 at 7:00 PM Alok Gandhi <alok.ga...@gmail.com> wrote:
@Justin : Might I suggest a minor change to your example function : using the format code in the default argument would make it more readable (especially in absence of any example usage)

so the signature becomes:
def uniqueNamePattern(base="whatever_{0}_whatever")

This improves readability for `base.format` used later.

- Alok



On Tue, Aug 23, 2016 at 2:40 PM, likage <dissid...@gmail.com> wrote:
Hi, was wondering if you could explain more on 'base='object' as I am not really understanding it... Not to mention about the base.format that you have used.

Correct me if I am wrong but is that suppose to be the name of object?

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.



--

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/CAPaTLMSwuY%3D6_YeJeF05nz%3Dd7cJ2PEO50eW7FsD2iHgGYzp2-g%40mail.gmail.com.

Alok Gandhi

unread,
Aug 24, 2016, 2:05:55 AM8/24/16
to python_in...@googlegroups.com

@alok
I guess I could have made the default base use the pattern that likage had specified, but I was really just making it generic and then the usage of it could specify that custom format. Maybe my docstrings clarified the usage though?

Justin

It sure did. I would still maintain that in this particular case having a format code laid out in the default arguments definitely improves readability. Default arguments bound to get most focus, more than docstrings in case of functions/methods that are sometimes for no-good reason considered trivial. In my personal opinion, nothing is trivial in code, if it is don't write it.

Of course, ideally, whenever there is a docstring, it is for a reason and meant to be READ and should be READ. Another point is most IDEs (and some text editors as well), auto-fill the default arguments as a part of code-completion feature, thereby increasing the importance of well-formed, informative and aptly named defaults.
-- 

likage

unread,
Aug 24, 2016, 1:09:57 PM8/24/16
to Python Programming for Autodesk Maya
@Justin
Thank you so much. The doc string certainly helps as I am able to comprehend what is going on :)
I did not know of such a way to do this 'counter' as I am having difficulties trying to implement the 'counter-conditional' that I have seen in c++ into pythonic forms, which of course failed miserably..

@Alok
I will try using the format that you have suggested as that could have made my code in a more consistent form since I already have/ specifying a certain naming. 


likage

unread,
Sep 7, 2016, 2:54:12 PM9/7/16
to Python Programming for Autodesk Maya
I tried to tweak the code a bit so that it will register version padding - eg. abc_001, abc_002 where in my code I am using something like uniqueNamePattern("abc_{0}{0}{0}")

While it seems to work in a sense, I got abc_111, abc_222 instead... Also I tried something like uniqueNamePattern("abc_00{0}")
However, say if I have 12 of the same items and as I execute the code, instead of getting abc_010 or abc_011, I got abc_0010, abc_0011

Can someone shed some light to me?

Justin Israel

unread,
Sep 7, 2016, 3:24:56 PM9/7/16
to Python Programming for Autodesk Maya
Your approaches have tried to format either 3 independent counter numbers into the string (the same number 3 times) or uses 2 fixed 0 characters that never change

If you are using my custom counter suggestion, try updating the format string like this

uniqueNamePattern("abc_{0:0>3}")

That says to pad the number with 0, right aligned, with a width of 3

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.

likage

unread,
Sep 7, 2016, 6:19:00 PM9/7/16
to Python Programming for Autodesk Maya
I did not know that I can write it as {0:0>3}! Works like a charm!


On Wednesday, September 7, 2016 at 12:24:56 PM UTC-7, Justin Israel wrote:


On Thu, 8 Sep 2016, 6:54 AM likage <dissid...@gmail.com> wrote:
I tried to tweak the code a bit so that it will register version padding - eg. abc_001, abc_002 where in my code I am using something like uniqueNamePattern("abc_{0}{0}{0}")

While it seems to work in a sense, I got abc_111, abc_222 instead... Also I tried something like uniqueNamePattern("abc_00{0}")
However, say if I have 12 of the same items and as I execute the code, instead of getting abc_010 or abc_011, I got abc_0010, abc_0011

Can someone shed some light to me?

Your approaches have tried to format either 3 independent counter numbers into the string (the same number 3 times) or uses 2 fixed 0 characters that never change

If you are using my custom counter suggestion, try updating the format string like this

uniqueNamePattern("abc_{0:0>3}")

That says to pad the number with 0, right aligned, with a width of 3

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.

Justin Israel

unread,
Sep 7, 2016, 7:00:16 PM9/7/16
to python_in...@googlegroups.com
On Thu, Sep 8, 2016 at 10:19 AM likage <dissid...@gmail.com> wrote:
I did not know that I can write it as {0:0>3}! Works like a charm!

For completeness, the equivalent in using the older string formatting approach would be:

"abc_%03d" % number

But using the format() method is the newer preferred approach.

 

On Wednesday, September 7, 2016 at 12:24:56 PM UTC-7, Justin Israel wrote:


On Thu, 8 Sep 2016, 6:54 AM likage <dissid...@gmail.com> wrote:
I tried to tweak the code a bit so that it will register version padding - eg. abc_001, abc_002 where in my code I am using something like uniqueNamePattern("abc_{0}{0}{0}")

While it seems to work in a sense, I got abc_111, abc_222 instead... Also I tried something like uniqueNamePattern("abc_00{0}")
However, say if I have 12 of the same items and as I execute the code, instead of getting abc_010 or abc_011, I got abc_0010, abc_0011

Can someone shed some light to me?

Your approaches have tried to format either 3 independent counter numbers into the string (the same number 3 times) or uses 2 fixed 0 characters that never change

If you are using my custom counter suggestion, try updating the format string like this

uniqueNamePattern("abc_{0:0>3}")

That says to pad the number with 0, right aligned, with a width of 3

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/b9d86111-fcd6-4f78-910f-84ef12625a5b%40googlegroups.com.

yann19

unread,
Sep 13, 2016, 9:27:52 PM9/13/16
to Python Programming for Autodesk Maya
Just wondering though - is it not possible to implement the padding into Justin's code?
Would that not be cleaner? Assuming if thread starter simply wants the naming to be of version padding 3 throughout, rather than keep typing uniqueNamePattern("abc_{0:0>3}"), uniqueNamePattern("def_{0:0>3}") etc...


On Wednesday, September 7, 2016 at 4:00:16 PM UTC-7, Justin Israel wrote:
On Thu, Sep 8, 2016 at 10:19 AM likage <dissid...@gmail.com> wrote:
I did not know that I can write it as {0:0>3}! Works like a charm!

For completeness, the equivalent in using the older string formatting approach would be:

"abc_%03d" % number

But using the format() method is the newer preferred approach.

 

On Wednesday, September 7, 2016 at 12:24:56 PM UTC-7, Justin Israel wrote:


On Thu, 8 Sep 2016, 6:54 AM likage <dissid...@gmail.com> wrote:
I tried to tweak the code a bit so that it will register version padding - eg. abc_001, abc_002 where in my code I am using something like uniqueNamePattern("abc_{0}{0}{0}")

While it seems to work in a sense, I got abc_111, abc_222 instead... Also I tried something like uniqueNamePattern("abc_00{0}")
However, say if I have 12 of the same items and as I execute the code, instead of getting abc_010 or abc_011, I got abc_0010, abc_0011

Can someone shed some light to me?

Your approaches have tried to format either 3 independent counter numbers into the string (the same number 3 times) or uses 2 fixed 0 characters that never change

If you are using my custom counter suggestion, try updating the format string like this

uniqueNamePattern("abc_{0:0>3}")

That says to pad the number with 0, right aligned, with a width of 3

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.

likage

unread,
Sep 14, 2016, 2:20:47 AM9/14/16
to Python Programming for Autodesk Maya
Prior to what yann19 has mentioned, having the padding incorporated into the function instead of writing it out, whenever I need to call it. I thought of changing the second last line of the function from

name = "{0}{1}".format(base, i)

into

name = "{0:<03}".format(i)

But as I tried to use uniqueNamePattern("test_{0}_GRP"), the padding revert back to a single digit unless I change {0} to {0:<03}

I apologize in advance that I have not done much testing before I type this out

Justin Israel

unread,
Sep 14, 2016, 6:42:28 AM9/14/16
to Python Programming for Autodesk Maya

Can you post a new version of the code you tried? I have a feeling you are trying to either update the default case but still passing in a customRepl solution (a string with a replacement pattern). Or you are changing the wrong part of the format string.
It should be possible to make the default case be padded to 3 places, if you don't pass in a string with your own pattern. Another approach would be to refactor the function to have a second param for the fill size and default it to 3. Then you would just fill the counter to that padding before formatting it into the base string.


--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/08b2f88c-1aa5-4b9c-948a-428081ae8498%40googlegroups.com.

likage

unread,
Sep 14, 2016, 5:55:44 PM9/14/16
to Python Programming for Autodesk Maya
I tried to use your case and did an update, and it failed badly...
Even so, my method was wrong to begin with, i think. It already fails if I am trying to do the counter in the middle of the naming

def uniqueNamePattern(base=""):

    i
= 1
    customRepl
= base.format('x') != base  


   
if customRepl:

        name
= base.format(i)

   
else:
        name
= base


   
while cmds.objExists(name):
        i
+= 1

       
base = base + "{0:0>3}".format(1)
       
if customRepl:
            name
= base
           
print "name1 : ", name
       
else:

            name
= "{0}{1}".format(base, i)

           
print "name2 : ", name


   
return name


cmds
.group(name=uniqueNamePattern("test_"))

Justin Israel

unread,
Sep 14, 2016, 6:29:50 PM9/14/16
to python_in...@googlegroups.com
Yea this isn't what you want. It has bugs. Firstly, you seem to be formatting the number 1 instead of the variable "i" :-)
You can't change the base variable at all. That needs to stay the original value so that you can use it as the base of building the next name to test.  

Here is an updated example of how you could make the padding amount an optional parameter:

Justin

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.

likage

unread,
Sep 19, 2016, 6:45:48 PM9/19/16
to Python Programming for Autodesk Maya
ah... I am still trying to get my head around this... 

Geordie Martinez

unread,
Sep 19, 2016, 7:17:10 PM9/19/16
to python_inside_maya

why don’t you just add a hash to the name which auto-numerates nodes without name collision?

import maya.cmds as mc
blah = mc.polyCube(n="someBaseName#")   # the hash inside the string is legal and will resolve to the next unique int

On Mon, Sep 19, 2016 at 3:45 PM, likage <dissid...@gmail.com> wrote:
ah... I am still trying to get my head around this... 

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/1088c21f-6557-4ea2-9904-dda0477ab32e%40googlegroups.com.

Justin Israel

unread,
Sep 19, 2016, 7:19:47 PM9/19/16
to python_in...@googlegroups.com
On Tue, Sep 20, 2016 at 11:17 AM Geordie Martinez <geordie...@gmail.com> wrote:

why don’t you just add a hash to the name which auto-numerates nodes without name collision?


Because the original request asked to have placeholders in a position other than the end of the name, and also with control over padding.
 
import maya.cmds as mc
blah = mc.polyCube(n="someBaseName#")   # the hash inside the string is legal and will resolve to the next unique int
On Mon, Sep 19, 2016 at 3:45 PM, likage <dissid...@gmail.com> wrote:
ah... I am still trying to get my head around this... 

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/CABPXW4g4ZVifT7iZXfF7dXb2440VP%3D49A4-Mpm1QibDVyvGA%2Bg%40mail.gmail.com.

Geordie Martinez

unread,
Sep 19, 2016, 11:12:59 PM9/19/16
to Python Programming for Autodesk Maya
ah yes. 
once I returned to having an internet connection from being trapped inside a concrete fortress,
the entire conversation revealed itself and my question seems now a bit late to the party. please disregard.
Reply all
Reply to author
Forward
0 new messages