2

I'm new to Python/AnyTree and am trying to get a list of raw ingredients to make a bunch of Harburgers (Hamburgers at Point San Pablo Harbor near San Francisco - you need to check it out if you're in the area!! In fact, the winning answer here gets a free Harburger on me next time you're in town!) But I digress...

The question is how can I get access to the 'qty' and 'uom' fields in the tree?

from anytree import Node, RenderTree, PreOrderIter
Harburger=Node("Harburger", children=[
        Node("RoundRoll", qty=1, uom='ea'),
        Node("GriddleGhee", qty = 1, uom='gm'),
        Node("SmashedBurger", qty = 5, uom='oz')])

print(RenderTree(Harburger))

Node('/Harburger')
├── Node('/Harburger/RoundRoll', qty=1, uom='ea')
├── Node('/Harburger/GriddleGhee', qty=1, uom='gm')
└── Node('/Harburger/SmashedBurger', qty=5, uom='oz')

So far, so good. Now I can traverse the tree, like:

#print ingredients for 5 Harburgers
print([(node.name for node in PreOrderIter(Harburger)])

['Harburger', 'RoundRoll', 'GriddleGhee', 'SmashedBurger']

How can I modify this command to get qty and uom?

I've tried

print([(node.name, node.qty) for node in PreOrderIter(Harburger)])

only to get errors!

VortexProf
  • 117
  • 8
  • I suspect your list comprehension using attribute syntax fails because the root node doesn't have the attributes you're looking for. Since your tree only has two levels, maybe iterate over `Harburger.children` instead of doing a traversal? – Blckknght Mar 10 '19 at 00:19
  • You got it - when I added the qty and uom fields to the top record, it worked great. WooHoo! Add your answer and I will vote you up! – VortexProf Mar 10 '19 at 01:19

1 Answers1

2

The issue your code accessing the extra attributes has is that the top-level Node doesn't have the qty and uom attributes, so when it comes up first in the pre-order tree traversal, the code quits with an exception.

You can fix this in a few ways. One way, which you've commented has worked, is to add the attributes to the root node too.

Another option might be to test for the attributes before using them, with something like:

print([(node.name, node.qty) for node in PreOrderIter(Harburger) if hasattr(node, "qty")])

If you can rely upon your tree only having the two levels (the top-level root node and its children), you can iterate over just the child nodes instead of doing a full traversal. Just use Harburger.children rather than PreOrderIter(Harburger).

Blckknght
  • 100,903
  • 11
  • 120
  • 169