Evaluating Formulas#
Unlike a program written in a programming language, a modelx Model does not have a single entry point, such as the main function in C. And modelx also differs from Excel, in a sence that modelx does not populate its Model with calculated values upon opening the Model. modelx evaluates a Formula when its value is requested by the user directly or indirectly through Formulas depending on the Fromula’s value.
The Fibo
Cells in the sample below is taken from the earlier section:
>>> Fibo.formula
def Fibo(n):
if n > 1:
return Fibo(n-1) + Fibo(n-2)
else:
return n
Initially, Fibo
does not have any values. You can check
Fibo
’s values by converting it to dict
:
>>> dict(Fibo)
{}
When you request the value of Fibo
for n=5
,
the values of Fibo
for n=0
through n=4
are also calculated:
>>> Fibo(5)
5
>>> dict(Fibo)
{1: 1, 0: 0, 2: 1, 3: 2, 4: 3, 5: 5}
Namespaces for Formulas#
Most Formulas need to reference values of other Cells
and References to calculate their own values.
Unlike Python functions,
the name binding for modelx Formulas is independent from
Python modules.
Each Space has its own namespace associated with itself,
and the names in the Formulas of child Cells in the Space
are bound in the namespace associated with the Space.
The names defined in the associated namespace are
the names of the child objects of the Space, such as
child Cells, Spaces and References. In addition to
the child objects’ names, global References,
special names and built-in names are defined in the associated
namespace.
The global References are the References defined at the containing Model level,
as attributes of the Model.
The special names are defiend by modelx,
and the names start with “_”.
Currently there is only one special name, _space
,
which refers to the Space itself.
The list below summarizes
the kind of names defined in the namespace associated with a UserSpace.
The child Cells, Spaces and References
The global References defined in the Model
The special names (
_space
)The Python built-in names
The sample code below is taken from
the mortgage loan example we have seen earlier.
The Balance
global variable
refers to a Cells object Balance
, but the name of the variable
does not need to be the same as the Cells’ name:
>>> Balance.formula
def Balance(t):
if t > 0:
return Balance(t-1) * (1+Rate) - Payment()
else:
return Principal
>>> Balance(30)
1.2096279533579946e-10
If Balance
was a Python function, then the names in
the Balance
definition, such as Balance
, Rate
,
Payment
, Principal
would refer to global variables
defined in the module that the function was defined in.
However, as explained above, the Formula of Balance
is evaluated
in the namespace associated with its parent Space Fixed
.
The Fixed
Space has child Cells, such as Payment
and
Balance
. It also has child References, such as
Principal
and Rate
. So, the names in the Balance
definition
refer to those child Cells and Referneces of the Fixed
Space.
To get all the names defined in the Fixed
name space,
use the Python built-in function dict
.
The code below assumes that the Fixed
variable refers to the Fixed
Space:
>>> dir(Fixed)
['Balance',
'Payment',
'Principal',
'Rate',
'Term',
'__builtins__',
'_self',
'_space']
(Note: _self
in the list above is deprecated and should not be used.)
Analyzing Formula dependency#
<<TODO>>