Feeding the Python a Different Input

Author: Guy Shepherd

Back in April I published a short series of articles outlining how Mo.net and Python could be used together to develop potentially useful applications of interest to actuaries and other user communities.  Following those articles, a number of clients have approached us with ideas of how those building blocks might be extended to provide even richer applications and with questions about how this might be accomplished.  Most of these ideas will require some enhancement to the interface between Mo.net and Python, which we will start to roll out in the next release, but one request was how to change the input data used by the Mo.net projection when being called from Python, which I’m going to cover here.

Unfortunately, the solution to the problem isn’t quite as simple as it might have been, due largely to the primitive data types that Python traditionally uses.  While Mo.net can accept an array of string-based inputs to override those baked-into the model, the closest thing that Python can offer us is a list.  Regrettably, a Python list is not compatible with a .NET array.  This means that our solution must be rather more creative, until such time as we provide additional interfaces to the model that will accept more primitive data types.

Python Script

Using the Python script covered in Part 3 of the series as a basis, I have added some additional code that captures the new series of inputs as a Python list, then exports this to a tab delimited file, and then passes this file into the Mo.net input table.  The complete script, including the additional code is shown below.

import sys
import clr
    
# define path to the Mo.net Linked DLL and add this to system path

assembly_path = r"C:\Mo.net Projects\LinkedFundsForPython\Linked_DLL"
sys.path.append(assembly_path)

# add Mo.net kernel assembly references to the CLR

clr.AddReference("Sal.CalculationEngine.GenCore")
clr.AddReference("Sal.CalculationEngine.GenDataAccess")
clr.AddReference("Sal.CalculationEngine.Interfaces.Entities")
clr.AddReference("Sal.CalculationEngine.ExcelReporting.TabularValues")

from GenDataAccess import DataRequest

# add Mo.net projection DLL reference to the CLR

clr_ref = clr.AddReference("Linked_Monet")
monet_type = clr_ref.GetType('Monet')

# invoke Mo.net interface methods

initCmdLine_method = monet_type.GetMethod('InitCommandLine')
initCmdLine_method.Invoke(None, [None])

init_method = monet_type.GetMethod('Initialise')
init_method.Invoke(None, [True])

initProj_method = monet_type.GetMethod('InitialiseProjections')
initProj_method.Invoke(None, [])

# obtain a reference to the projection inside the DLL

projections = monet_type.GetProperty('Projections')

# override the default value for the SterlInt projection parameter

linkedproj = projections.GetValue(None).Linked
linkedproj.SterlInt = 0.1

#   input array is really a two dimensional list (or a list of lists)

inputarray = [['PolNo', 'Sex1', 'AgeEnt1', 'PremFreq', 'FundType', 'SumAssured', 'PeriodIF', 'Term', 'PremInit'], 
['1', '1', '55', '4', 'Equity', '100,000', '0', '20', '0']]

# write the inputarray to a file

import csv

newfile = 'c:\\temp\\Linked_Inputs_TEST.txt'

with open(newfile, 'w') as file:

    for item1 in inputarray:
        for item2 in item1:
        # write each item on a new line
            file.write("%%s\t" %% item2)
        file.write("\n")
    print('Done')
         
#create an instance of the Mo.net DataRequest object using the input file created above#

from GenDataAccess import DataRequest
linkedproj.InputsTable = DataRequest('c:\\temp\\Linked_Inputs_TEST.txt', '\t', 'Uninitialised')

# run the projection

linkedproj.Run()

# show the inputs - to check they have been overridden

print(f'PolNo = {linkedproj.Record.PolNo}')
print(f'Sex1 = {linkedproj.Record.Sex1}')
print(f'AgeEnt1 = {linkedproj.Record.AgeEnt1}')


# show the sterling result at time=0 

print(f'SterlInt = {linkedproj.SterlInt}')
print(f'SterlRes(0) = {linkedproj.SterlRes(0)}')

Running this script will produce similar output to before, but now it’s using the input values contained in the list defined at line 45.  Changing these input values and rerunning the script will produce different answers

What’s Going On?

The key elements of the Python script are as follows.

Line NumberCommentary
45- 46This defines a new two-dimensional list of input values with headings called inputarray
50-52Create a new output file into which to insert the list of inputs
54-61Write each of the list elements out to the file using a tab delimited (as defined by the \t in line 59)
65-66Create an instance of the Mo.net DataRequest object and pass the new file created above into it.  This overrides the inputtable used by the projection with the values defined in the list and passed into the file.

It’s possible to create multiple rows of inputs in this way by simply extending the inputarray list to hold multiple row of inputs.

Conclusion

I hope this small extension to the original series is helpful.  We will return to the integration potential of Mo.net and other platforms in further blog articles shortly.

Contact Us

Need a Mo.net licence? Get in touch with us today to discuss your modelling requirements.

Was this article helpful?
YesNo

Comments are closed.