IMHO, parsing the string is just a matter of administrative logic and
should not be bothered with when focussing on the business logic (which, in
this case, is recreating the hierarchy).
Sure JSON, YAML, and XML(ugly) are a few options to choose from for parsing
the string. In the end, It is just a detail to get the data, nothing more,
nothing less.
What is important is how we deal with that data in the most efficient,
optimized and readable way.
So here is my implementation, parsing your original indented string. This
definitely covers your points 1 and 2. 3 is a matter of opinion and is
subjective.
Few things to note:
- Right in the beginning, we parse the string in a single line, keeping
the administrative logic out from the rest of our business code. You can
easily replace this single line with whatever parser you want.
- I am using `namedtuple` for readability they are lightweight and
require no more memory than regular tuples.
- `bisect` uses a basic bisection algorithm, an improvement over the
common approach for finding an insertion point in a sorted list without
having to sort it again.
- This completely eliminates multiple calls to parent() as in your
original implementation. For each line in the input string, we parent only
once, no need to go back up or down in the hierarchy with multiple
if-elif-else. This is more efficient and straight forward.
- Handles multiple hierarchies starting from the root (which your
version also covered I think)
- Space characters are not a problem on an empty line(In my example, I
have deliberate space chars to demonstrate that). On that note, please note
that I am using line.strip(' ') instead of line.strip(), the reason being
you can still parse escape characters like \r \t \n etc., strip() eats them
up as they are whitespaces as well.
----------------------------------------------------------
from collections import namedtuplefrom bisect import bisect_left
import pymel.core as pm
def hierarchy_from_string(hierarchy):
NodeInfo = namedtuple('NodeInfo', 'node indent')
nodeInfos = []
for nodeName, currIndent in ((line.strip(' '),
len(line) - len(line.lstrip(' ')))
for line in hierarchy.split("\n")
if line.strip()):
node = (pm.ls(nodeName)[0] if pm.ls(nodeName)
else pm.createNode('transform', name=nodeName))
parentIndex = bisect_left([nodeInfo.indent for nodeInfo in nodeInfos],
currIndent)
parentNode = (nodeInfos[parentIndex - 1].node
if parentIndex - 1 >= 0 else None)
nodeInfo = NodeInfo(node=node, indent=currIndent)
if parentIndex < len(nodeInfos):
nodeInfos[parentIndex] = nodeInfo
else:
nodeInfos.append(nodeInfo)
pm.parent(node, parentNode)
hierarchy_from_string("""\rig implementation geometry
skeleton interface controls previewfoo bar
baz alice bob""")
- Alok
--
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 [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/python_inside_maya/CAPaTLMTEP2TkYA18FFq9Wp2ea%2BFBW0ErTM6EVbg6O1dNVVa-jA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.