Script

In MADS, calculations are performed and reports produced for a given Plan . Calculations corresponding to a Commodity or a Herd within a plan are predefined. By defining scripts, additional variables can be specified and assigned values through user-defined calculations – that can make use of commodity or herd results or other variables within a given plan.

A script item can also be a command to display results or to export results to external files.

A Script would be executed for a given Plan by adding it to its list of components.

A script is defined by a unique ID, a label, an optional unit, and a list of script items. A script item can be a command, a variable declaration or an instruction.

Script editor template

script ID = ‹label› ; //, unit = ‹unit› ;
// script items
end;

Specifying results

The syntax is the same as the one for specifying table items. A reference to a results entity can be:

A tilde is the ~ character, used as a separator between IDs and attributes.

The result-type attribute for a commodity can be consQ, prodQ, availQ, balQ, consV, prodV, availV ,balV , where the suffixes Q and V stand for Quantities and Values, and cons, prod, avail and bal stand respectively for consumed, produced, available and balance.

The aggregated-result-attribute for a Herd can take some fifty one different values. They are detailed in the corresponding Herd Results section of the herd reference page.

The detailed-by-Class result-attribute for a Herd can take four possible values: avgSize, deathRate, offtakeRate, intakeRate.

Script commands

There are five possible output commands, to display either a qualified commodity, a qualified herd result, a table or a variable. The item reference is picked from a list when using a template. The item ID is optionally followed by a label, as shown below by the following templates :

print comm_Riz~consQ as ‹label›? ;
print herd_FamilyHerd~nbrMJ as ‹label›? ;
print herdClass_FamilyHerd~avgSize~AdultMales as ‹label›? ;
print table T as ‹label›? ;
print var_A as ‹label›? ;

If a label is not defined by the print command (it is optional) then the label of the data item will be used instead. Depending on the value of the «Results as» attribute in the headers, the output will be sent to an editor either in plain text or in web format (html). The normal commands of the editor can be used to save and / or print the results.

There are two data-export commands, one to specify external file names (that can also be defined in the headers section) and the other for actual export, as detailed in the Data import-export section, and as shown below by the following templates :

fileSpec ID = ‹fileSpec› ;
export var_A into ‹data› in ‹Sheet_A› in ID ;
export comm_Riz~consQ into ‹data› in ‹SheetName› in ID ;

Script variables

A script item can define a variable in two different ways, namely either a free standing variable declaration or a variable declaration combined with an assignment. An assignment assigns to a variable, with the = sign, the result of evaluating an expression. An expression can also be assigned to an already defined variable. Depending on the expression, the result to be assigned to a variable as its value could be either a time series of values (TS) or a single number, in which case (single number) the result will be transformed into a TS with constant values.

When a variable is declared, it can be specified as local to the script, in which case it will not be possible to use it in an other script or in a table definition.

A variable is thus defined by the optional keyword ‹local› followed by the keyword ‹var›, by a unique ID and a label, and optionally by an assignment, as shown by the following template :

local? var ID = ‹label› // ; or = expression ;

Script expressions

An expression combines numbers, time series of values (TS), references to a variable, commodity results, herd results, and/or functions using operators ( + - / * ^ ) and/or parenthesis.

References use the ID of the entity, duly qualified as detailed above (Specifying results ). Available attributes for each type of entity are also detailed in the corresponding reference sections.

When evaluating an expression, operators precedence follows standard rules : power (^) is evaluated first, then multipliers (* or /) and finally adders (+ or -). Parenthesis can be used to clarify or override this order; they can be nested.

Example :
var Amenagement = ‹Aménagement› = (comm_Reseau~balV * (1 + Taux_imprevus/100) + var_Fonc + var_Resid) * var_FC_Réseau ;

Script functions

MADS predefines a number of functions, all on the same pattern : keyword ( comma-separated list of parameters ). The type AtomID is used for parameters to represent a reference to a variable, a commodity result or a herd result.

Functions return a TS when evaluated. When the function is said to return a single value (e.g. the Sum function), it means that that single value is assigned to all periods of a TS.

If Plus and If Minus functions

Templates :
A = ifPlus (AtomID);
A = ifMinus (AtomID);

Returns a TS. ifPlus keeps positive values and sets negative ones to zero and ifMinus keep negative values and sets positive ones to zero. As an example of use, let us assume an activity that consumes Labor at the level [100 120 140], whereas labor available from the family is [ 120 ]. The balance is thus [20 0 -20]. The surplus in year one has no value. The years with negative values are «extracted» with the ifMinus function to give the deficit :
HiredLaborCost = ifMinus (LaborBalance) * (-1) * HiredLaborPrice;

Price Contingencies function

Template :
A = priceCont (item = AtomID, inflation = VarRef);

Returns a TS with price contingency amounts corresponding to values in ‹item› given ‹inflation› rates over time. Used in project costing. If item is an investment over two years, say item = [100 200 0], and inflation is projected to be 5% in year 1 and 4% thereafter, (inflation = [5 4]), then price contingencies will be:

Deflating function

Template :
A = deflated (item = AtomID, inflation = VarRef);

Returns a TS with deflated amounts corresponding to values in ‹item› given ‹inflation› rates over time. Used in cash-flow analysis to reflect real impact on debt repayment under fixed interest rate and inflation. The compound rate calculations are similar to the Price Contingencies example above: amounts in year 1 would be divided by 1.05 and amounts in year 2 by 1.092.

Sum function

Template :
A = sum (AtomID);

Returns a single value (that single value is assigned to all periods of A), which is the sum of all values in the input. Note that if project life is set to 20 years, and B = [12 15 25] then sum(B) is equal to 12 15 25 * 18 (the last value gets repeated).

Single value function

Template :
A = singleVal (AtomID, index);

Returns a single value (that single value is assigned to all periods of A), which is the one at year ‹index›. Assumes index=1 if index < 1 and index=life if index > life.

Shift function

Template :
A = shift (delay , AtomID);

Returns a TS. Values are shifted to the right, i.e. delayed, if delay is positive, and shifted to left if delay is negative.

If delay >= ProjectLife (i.e to 20) then all values are set to 0.
If delay <= -ProjectLife (i.e than -20) then all values set to year 20 value.

Read function

Template :
A = read (ID in ‹Table› from F1)

Returns a TS with values read from an external spreadsheet, as detailed in the Data import-export section. F1 is the reference to a file defined in a filespec command.

Purchase function

Template :
A = purchase (consumed = itemConsRef , produced = itemProdRef);

Returns a TS. Given two references of type AtomID corresponding to the production and consumption of a certain product, the purchase function calculates the quantity to purchase when there is a deficit after carrying over to the following year a surplus from the previous year, for example in the case of a product that can be retained on a farm. This is equivalent to :
Purchase = (itemCons – itemProd) + shift(1 , ifMinus(itemCons – itemProd))

Residual value function

Template :
A = resVal (investment = AtomID , life = life yrs, resValRate = rate % ) ;

Returns a TS. Given a reference of type AtomID corresponding to investment costs, the investment life and a percentage for residual value, resVal calculates the residual value of the investment either at the end of its life or at the end of the project, using linear depreciation.

Assuming Project life = 20, Investment life = 6 and Residual Value Rate = 10 %, an investment of 100 in year 1 will produce a residual value of 10 in year 7. An investment of 100 in year 17 will have been used for 4 years at the of year 20, its value in year 20 will be: 100 * (0.1 + (1 - 0.1) * ((6 – 4) / 6) ) = 40 .

Operating cost function

Template :
A = opCost (investment = AtomID, life = life yrs, rate = rate %, delay=delay yrs);

Returns a TS. Given a reference of type AtomID corresponding to investment costs, the investment life, a percentage for operating costs, and an initial no-maintenance period, opCost will return the operating costs over the life of the investment (e.g. a building will cost nothing for three years and then 6 % of its initial cost for operation and/or maintenance).

Debt Service function

Template :
A = debtServ (loan=loanRef, separate? loanEndYr? , rate=rate %, duration=duration, grace=grace, grace on int=graceOnInt?);

Returns a TS. Given a reference of type AtomID corresponding to loan amounts, loan interest rate and duration and grace period, the function will return the debt repayment schedule, on the basis of constant installments.

The calculations can be affected by the following options:

Outstanding function

Template :
A = debtServ (loan=loanRef, rate=rate %, loanEndYr?, debt service=debtServRef ;

Returns a TS. Typically used in accounting models in conjunction with the Debt Service function above. Given a TS with loan amounts and the corresponding repayment schedule for a given interest rate, the function will return a TS with the outstanding debt (principal).

By default, loan amounts are assumed to be given at the beginning of a year and repaid at the end of the year, a repayment after one year will thus show up in the same year as the disbursement. When the optional parameter ‹loanEndYr› is used, loan amounts will be assumed to be given at the end of a year, meaning that repayments will be shifted right by a year, thus affecting the results of this function. It is up to the user to make sure that the interest rate and the loanEndYr parameter are the same as in the debt service calculations.

Rate of return function

Template :
A = irr (
// comma-separated list of weighted variables
, as ‹label› (export into tableID in fileRef)? ) ;

weighted variable template : AtomID * Value?,

A weighted variable is a reference of type AtomID optionally multiplied or divided by a value. The result of the function depends on the number of such variables in the list:

The export section within parenthesis is optional, it would send copy of the function’s output to an ODF spreadsheet file, as detailed in the Data import-export section.

The internal rate of return of Y is the value of the discount rate R that solves the equation:

Present value = 0,
where Present value = Sum Y[I] / (I + R) ^ I
with I = 1 to Life (^ stands for power)

The equation can have up to Life roots, some are real numbers and others are complex numbers. The function will produce a result only if there is one and only one real-number root.

The switching value of a variable is the percentage of change to be applied to this variable, all the others being unchanged, in order for the IRR to be equal to OCC (the discount rate given in the headers used to calculate present values). It shows the sensitivity of the IRR to variations of the component variables.

The example below is reproduced from the Plaine de Daye example.

Script instruction :
local var TIR = irr ( Riz_eco, Maïs_eco, Amenagement, Intrants_eco, Encadrement_eco, Pompage_eco, Travail_eco, as «Analyse de rentabilité économique de l'aménagement») ;

Output :

Mali – Plaine de Daye
Current plan: Périmètre de la Plaine de Daye
Analyse de rentabilité économique de l’aménagement
Rate of return = 14,32%

Present and switching values
(Opportunity cost of capital = 12,00%)
Present ValuesSwitching Values
Per cent
Riz (éco)1 243 909,54-12,42
Maïs (éco) 334 749,96 -46,16
Aménagement -1 028 126,84 15,03
Intrants (éco) -148 019,95 104,39
Encadrement (éco) -29 877,77 517,18
Pompage (éco) -59 328,52 260,45
Travail (éco) -158 785,01 97,31
Net Balance 154 521,39--