Variables and operations
Let's talk about how to retrieve and set variable values and execute operations using the Run adapter available with the JS libraries.
Python model example
Here is a simple Python model for a savings account simulation. It declares two variables, balance and interest_rate, and operations that update these variables.
import json
from epicenter import Epicenter
balance = 1000
interest_rate = .05
def transaction(amount):
global balance
balance = balance + amount # Update the balance
Epicenter.record("balance", balance) # Save the new balance to run state
def apply_interest():
global balance
global interest_rate
balance = balance * (1 + interest_rate)
Epicenter.record("balance", balance) # Save the new balance to run state
def set_interest_rate(new_val):
global interest_rate
if new_val <= 0:
print("Interest rate must be greater than 0!") # Raise error for invalid interest rate
return
interest_rate = new_val # Update the interest rate
Epicenter.record("interest_rate", interest_rate) # Save the new interest rate to run state
For Python models, it is a best practice to define operations that update variable values rather than set variables directly. This way, you can implement validation and save the new value as part of the run state.
Saving variables to database allows you to retrieve the values of a variable for all participants without loading all the runs into memory.
To display a variable value for all the participants of a model run, use the getVariables() function of the Run adapter.
Save state variables
Because Python models can save variables to databasee, you can enable your model to restore a run to memory from a snapshot.
Snapshot restore is recommended for Python models rather than run history replay. One reason for this is that a Python model can contain random values. In this case, an exact run replay would not work. For example, if a financial account simulation has a varying interest rate, the rate would be different with each replay.
Enable snapshot restore
To enable snapshot restore, you must add the names of the state variables to the restorations object in your model's context file.
Here is a sample context file for the savings account model:
{
"language": "python3",
"restorations": {
"assembly": [
{
"snapshot": {
"variables": [
"balance",
"interest_rate"
]
}
}
]
}
}
Retrieve variables
To display the current balance in the simulation UI, retrieve it using the getVariable() function of the Run adapter.
import { runAdapter } from 'epicenter-libs';
current_balance = await runAdapter.getVariable('0000019975d0aaebd160de2450566846su33', 'balance');
Execute operations
To execute the model's operations, use the operation() function of the Run adapter.
For example, to apply monthly interest to the current balance, execute the apply_interest() operation. This operation doesn't take any arguments, so all you need to pass to the runAdapter.operation() function are the run key and the operation name.
import { runAdapter } from 'epicenter-libs';
await runAdapter.operation(
'0000019975d0aaebd160de2450566846su33',
'apply_interest'
);
To run a transaction on the account, execute the transaction() operation. Pass the amount argument inside an array, as in the example below.
import { runAdapter } from 'epicenter-libs';
await runAdapter.operation(
'0000019975d0aaebd160de2450566846su33',
'transaction',
[500]
);
For more detail on using the Run adapter to execute operations, read about the operation() function.