3.2 - Bag formula
GnrBag provides as built-in a particular resolver, called BagFormula, that allows the definition of particular expressions among the bag's items, as they were cells of a spreadsheet. The method formula() takes a formula as first parameter. A formula is a string that represents an expression in which all the variables are marked with the char '$. The method fomula() may also take some kwargs that specify the path of each variable.
mybag=Bag({'rect': Bag(), 'polygon': Bag()})
mybag.setBackRef()
mybag['rect.params.base']=20
mybag['rect.params.height']=10
mybag['rect.area']= mybag.formula('$w*$h', w ='params.base', h='params.height')
>>>print mybag['rect.area']
200
You can define some formulas and symbols if you plan to use them in several situations, in fact Bag has a register of all defined formula and symbols. With the method defineSymbol() it's possible define a variable and link it to a value at the specified path. With the method defineFormula() you can define a formula that uses defined symbols.
mybag.defineFormula(calculate_perimeter='2*($base + $height)' )
mybag.defineSymbol(base ='params.base', height='params.height')
mybag['rect.perimeter']= mybag.formula('calculate_perimeter')
>>>print mybag['rect.perimeter']
60
In the following examples is used a previously defined formula with the method defineFormula(), but its variables are directly bound to bag's element ad kwargs of the method formula().
mybag.defineFormula(calculate_hypotenuse= '(($side1**2)+ ($side2**2))**0.5')
mybag.triangle=Bag()
mybag['triangle.sides.short']=2
mybag['triangle.sides.long']=4
mybag['triangle.sides.hypotenuse']=mybag.formula('calculate_hypotenuse', side1='short', side2='long')
>>>print mybag['triangle.sides.hypotenuse']
resolving hypotenuse: <gnr.bag.gnrbag.BagFormula object at 0x101d910>
4.472135955
When a bag item is bound to the symbol of a formula we use a path. We can use two kinds of path, relative path is the default. By relative we mean that starts from from the point of view of the bag that contains the formula.
mybag['polygon.side_number']=5
mybag['polygon.params.side_length']=10
mybag['polygon.calculated.perimeter']= mybag.formula('$num*$length',
num='../side_number',
length='../params.side_length')
>>>print mybag['polygon.calculated.perimeter']
50
As perimeter is within the bag calculated, the relative paths to reach side_number and side_length must include a backward step until polygon level. Sometimes is simplier to use absolute path, to bound a variable to its value. As absolute path we mean that it starts from the point of view of the bag that calls the method formula(). An absolute path starts with the char '/'. Let's see the previous example with absolute paths.
mybag['polygon.side_number']=5
mybag['polygon.params.side_length']=10
mybag['polygon.calculated.perimeter']= mybag.formula('$num*$length',
num='/polygon/side_number',
length='/polygon.params.side_length')
>>>print mybag['polygon.calculated.perimeter']
50
Now it's necessary to specify with more accuracy how does BagFormula work. The bag that calls the methods defineFormula, defineSymbols and formula becomes a sort of namespace for our spreadsheet like system. It is the origin of the absolute paths and has two important properties that are the dictionary of the formulas and the one of the symbols.
Attachments
- formula.png (39.2 kB) - added by anonymous 2 years ago.
- BagFormula.py (1.8 kB) - added by anonymous 2 years ago.

