[Python][Maya Script] Script WIP. question on how to extract a tuple out of a string

Howdy guys i’m currently working on a python script and was wondering if you guys could take a look! I am still running into a few problems but here it is


import maya.cmds as cmds
def findAllCameras():                  #function
	Listcamnew = []                    # main list that needs to be filled
	listofCamerasWShapes = cmds.ls(cameras = 1)   #lists all the cameras
	CameraPar = cmds.listRelatives(listofCamerasWShapes, parent=1)  # lists all cameras
	DefaultCam = (u'front', u'persp', u'side', u'top') #list all cameras that i don't want
    	for callcam in CameraPar: 
    		if DefaultCam in CameraPar:           #if its a default camera it removes it
        		str_list.remove(DefaultCam)
        		return CameraPar
        	camname = callcam.name                #creates name to go into ListcameraNew
        	Cameragetval = cmds.getAttr(('callcam') + '.translate')  #XYZ camera loc
        	Cameraxyz(a,b,c) = [callcam[0] (a, b, c)] #Clean Val into cameraxyz
        	StackingValuesofCamera = [camname, Cameraxyz]        #stack together  
        	Listcamnew.append(StackingValuesofCamera)        
    	return CameraPar

one of the few problems i’m running into is the function getAttr from maya’s cmds. the result it gives me is [(2.3, 44, 54)] which is a tuple within a list. I was hoping to find a way to extract the tuple out of the list but seems like it doesn’t run correctly by doing Cameraxyz(a,b,c) = [callcam[0] (a, b, c)]

I think there may be a few more problems with the script and its not so called “pythonic” however babysteps first =D,

thank you for the look and thank you doubly for some pointers or advice!

Hi, I haven’t had much time to look at this and I’m very new to Python myself but I’ve got one suggestion.

xform could be used here instead of getAttr, if that helps. You could use cameraPos = cmds.xform (query=True, translate=True, ws=True) to get the world space translate values - that might make your code cleaner, as it will condense it into a list minus the tuple and you can use indexes to get the values. (If that’s what you’re trying to do).

Hope this maybe helps?

Okay, I had a closer look at the script. Not sure what you’re trying to achieve. Looks like to me you want to pass out a list containing the name of the any cameras that aren’t default (as a string), and the world space position of those cameras. Correct?


import maya.cmds as cmds
def findAllCameras():                  #function
    listOfCameras = []                    # main list that needs to be fille
    listofCamerasWShapes = cmds.ls(cameras = 1)   #lists all the camera
    CameraPar = cmds.listRelatives(listofCamerasWShapes, parent=1)  # lists all cameras
    DefaultCam = ['front','persp','side','top'] #list all cameras that i don't want
    for callcam in DefaultCam: # remove default cameras in the scene from CameraPar
        CameraPar.remove(callcam)
        #error check
        if CameraPar == []:
            cmds.error("Empty list. No other cameras in scene")
    for c in CameraPar: #getting remaining cameras in scene
        Cameraxyz = cmds.xform(c, q=True, ws=True, t=True)
        StackingValuesofCamera = (c, Cameraxyz)        #create a tuple with camera name and world space Pos  
        listOfCameras.append(StackingValuesofCamera)   #append to a list to pass out
    return listOfCameras

This is what I noticed.

  1. You declare DefaultCamera as a tuple with unicode strings in it. This is probably not what you want, so I changed it to a defined list of strings with the known camera names. This means it’s easier to iterate through.
  2. You use for x in y, but don’t actually use x - meaning this part of the code doesn’t really do what it’s meant to do, which is iterate through values in a list.
  3. I put in an error check to break the code if the list, once the cameras are removed, is returned as an empty list.
  4. There are things I removed and cleaned up, because I didn’t understand what they were doing to be honest! Haha! I’m really new at Python too (only a couple of weeks experience) so I don’t know if what I’m doing is right either.

Apologies if this isn’t what you wanted. If it’s not, please say what the script is for and I’ll have another look.

Hope I helped!

Well firstly,

Cameraxyz(a,b,c) = [callcam[0] (a, b, c)]

is incorrect. To python you’re mapping a function to something completely random.

If callcam is [(2.3, 44, 54)], then you can simply run

cameraXYZ = callcam[0]

That’ll give you the tuple from the list, because callcam[0] returns the first item which is the tuple.

also just modified your code a little so the function ends if no camera’s exist.


import maya.cmds as cmds
def findAllCameras():
    camList = []
    CameraPar=[cam for cam in cmds.listRelatives(cmds.ls(cameras=1),parent=1) if cam not in ['front','persp','side','top']]

    if CameraPar == []:
        cmds.error("Empty list. No other cameras in scene")
        return False

    for c in CameraPar:
        camTran = cmds.xform(c, q=True, ws=True, t=True)
        StackingValuesofCamera = (c, camTran) 
        camList.append(StackingValuesofCamera)
    return camList

That way the function ends processing if the CameraPar is empty. It’ll also let you use the function as an object in other functions:
eg


if findAllCamera()=False:
    do this....
else:
    do that

[QUOTE=dgovil;17143]


        cmds.error("Empty list. No other cameras in scene")
        return False

[/QUOTE]
Just wondering, why the need for ‘return False’ if cmds.error() terminates the code anyway?
Incase its caught?

[QUOTE=dgovil;17143]


if CameraPar == []:
    cmds.error("Empty list. No other cameras in scene")
    return False

[/QUOTE]
I assume this works for the given example (I haven’t run it), but Maya has a tendency to return either empty lists or None depending on which command you use. And sometimes, when you’re really lucky, it will return different ones for the same command under different conditions. As a rule of thumb, it’s probably better to just test the variable if it returns True.


if not CameraPar:
    cmds.error("Empty list. No other cameras in scene")
    return False

In python empty lists and None both evaluate to False, while lists with items in them will evaluate to True. So this is a more fail-proof way of using python with Maya.

Thanks for that clarification, assumptionsoup. :slight_smile: Nice bit of info to know. :smiley:

[QUOTE=ldunham1;17144]Just wondering, why the need for ‘return False’ if cmds.error() terminates the code anyway?
Incase its caught?[/QUOTE]

Does cmds.error terminate the script? I assumed it just printed an error to the script window, but kept the script running?

[QUOTE=assumptionsoup;17145]


if not CameraPar:
    cmds.error("Empty list. No other cameras in scene")
    return False

In python empty lists [] and None both evaluate to False, while lists with items in them will evaluate to True. So this is a more fail-proof way of using python with Maya.[/QUOTE]

Yeah you’re right. if not is a much better way to do it, and far more readable to boot.

[QUOTE=dgovil;17149]Does cmds.error terminate the script? I assumed it just printed an error to the script window, but kept the script running?
[/QUOTE]

error does terminate the script but your method is a lot more readable.

[QUOTE=Wuffles;17150]error does terminate the script but your method is a lot more readable.[/QUOTE]

No, it isn’t. Raise a damn exception. You’re writing python, use it!

Maya has a tendency to return either empty lists or None depending on which command you use

Yup, and what a cause for frustration. I now either use pymel (which has been pretty consistent) or do:

myvar = cmds.ls() or []
for o in myvar:
    ...

Have the “or ” means I don’t have to check if myvar evaluates to False, which means less nesting and nicer code. Just a suggestion to get around such a heinous ‘design’.

[QUOTE=Rob Galanakis;17194]No, it isn’t. Raise a damn exception. You’re writing python, use it![/QUOTE]

Sorry for digging up an older thread Rob but I just noticed this. What do you mean by this? Excuse my ignorance as I’m very new to all this. :o)

[QUOTE=Wuffles;17580]Sorry for digging up an older thread Rob but I just noticed this. What do you mean by this? Excuse my ignorance as I’m very new to all this. :o)[/QUOTE]

Hi. I’m also pretty new to all of this but I think he meant something along these lines:

def myFunction():
	try:
		print "test"
	except:
		sys.stderr.write("Error: Failed to execute myFunction #
")
		raise

Python can raise many different errors / exception , you can check the doc here

so for example raise RuntimeError (“blablablabla”)

(if i didnt miss any capital letters etc should run )

The thing i dont like in the latest versions of maya all those errors cmds.error ,raise etc dont show up red in the bottom line (sorry dont remember the name)
So what I ended up using was a quick call to the API with OpenMaya.MGlobal.displayError(“blablabla”) that shows up red