# PymelTutorial02

## 02 - relatives of objects, history of objects

The previous section assumes that the objects you're selecting contain the attributes you want to change. But what if that's not true? What if you want to change something which is an input to your selection?

For example, you run the create -> polygon primitves -> sphere command twice. You'll end up with 2 spheres, each connected to their own polysphere node. If you select the transform, how do you change the radius?

This implies 2 questions:

```   given a transform, how do you get to the shape
given a shape, how do you get to its construction history
```

The 'listRelatives' command will list any child shapes for a transform. It can do more than that, but when called by itself, does what we need.

```from pymel.core import *
selection = ls(selection=True)
selection =  selection[0]     # lets just deal with one sphere for now

print 'the transform is: ',
print selection

"the transform is:  pSphere2"

myshape = selection.listRelatives()
print 'the shape is: ',
print myshape[0]

"the shape is:  pSphereShape2"
```

the 'listHistory' command lets you see all the inputs to a node. So in this case if we give it one of the shapes, it should return the polysphere command:

```myhistory = myshape[0].listHistory()
print 'the history is: ',
print myhistory

"the history is:  [nt.Mesh(u'pSphereShape2'), nt.PolySphere(u'polySphere2')]"
```

And once we have that, we can then get to the radius attribute of the polysphere command and change it:

```mypolysphere = myhistory[1]
```

so, if we wanted this to happen across lots of spheres at once, and list comprehend the shit outta this, we could do this:

```selection = ls(selection=True)
shapes = [ x.listRelatives()[0] for x in selection ]
spheres = [ x.listHistory()[1] for x in shapes ]
[ x.radius.set(0.5) for x in spheres]
```

Or as a horrible one-liner (which is actually what I'd do cos I'm lazy)

```[ x.listRelatives()[0].listHistory()[1].radius.set(2) for x in ls(selection=True)]
```

But wait! We can cheat even further!

I found out that listHistory doesn't need a shape fed into it. Give it a transform, and it will work out the shape first, then the history for the shape. Means you can skip a step:

```[ x.listHistory()[1].radius.set(1) for x in ls(selection=True)]
```

todo: given a construction history object, how do you get to the transform?