<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Explanation of python code
Dear Yordan, 
Kindly find attached a folder containing python code for the toy model in the stock flow presentation. The coding of system wide stress simulation is part of my deliverables. In addition, I thought it may be useful for you to have an object orientated programming framework in python because it is associated with agent based modelling.  In object-oriented programming languages, data and programming methods or functions are “embedded” in objects that can manipulate their own data and interact with other programming objects.  This makes real-world entities such as households or banks easy  to be represented. For example, in this model a natural starting point is to define an object/class called “Dealer banks”. I specified information dealers would need to have and rules for how they interact with each other and their environment. Another feature of object-oriented programming that is good for ABM development is inheritance. An instantiated object, e.g. commercial bank, can ‘inherit’ some characteristics from a ‘parent class’ but still behave in different ways. 
However, the obvious downside is that Python coding is definitely harder than Matlab. For example, there is no interface to click on a variable set(not that I"m aware of anyway), you have to save the variables in a dataframe (by writing a function in the  code) and then write the  dataframe to a csv file. On the upside, it’s possible to automate the update state easily and add heterogenous behavior for same-type like institutions. Another feature is that 
How to run the model
Running python 
Step1:  In the beginning we need to instantiate two objects in the main file to run the program  -
from src.environment import Environment
    from src.runner import Runner
the Environment and the Runner class. The code for those classes are stored in the folder src and the name of the classes are Environment and Runner (not surprising).
* The runner has two main purposes - it just handles the time steps and writes the output to csv. 
* The environment has the purpose of reading all the configuration files,  instantiating the agents and saving the agents in lists to access them in the actual modelling part. So whenever you want to access a variable for an agent in the updater (for example a cash position of a hedgefund), you need to write 
ruby 
for hr in environment.hedgefunds
Step2:  Those type "  " names later become dictionaries for the instantiated agent object. So the hedge fund has 
a dictionary (a data structure that saves stuff) with the name stock_variable = {Cash
Step3:  Here you can change the initital interest rates and prices for the marketable assets and also the shocks. It's possible to assign them to other variables and change them later in the updater. It's also possible to not read them in at all (just delete the lines) and define those in the updater script, but in the current setup they get read into the dictionary in the environment, environment.exogenous variables = {price_GB 
<ASSISTANT_TASK:>
Python Code:
# %load sflow.py
# [SublimeLinter pep8-max-line-length:300]
# -*- coding: utf-8 -*-
# -------------------------------------------------------------------------
#
#  MAIN
#
# -------------------------------------------------------------------------
if __name__ == '__main__':
    from src.environment import Environment
    from src.runner import Runner
# We have to pass in the path of the environment xml as args[0] 
# the  name of the environment xml as args[1] here:
# and the scenario name as args[2] here:
    args = ["configs/environment/", "environment_config", "benchmark"]
#
# INITIALIZATION
#
    environment_directory = str(args[0])
    identifier = str(args[1])
    scenario = str(args[2])
    environment = Environment(environment_directory, identifier)
    runner = Runner(environment, scenario)
#
# UPDATE STEP
#
    for i in range(int(environment.static_parameters['num_simulations'])):
        environment.initialize(environment_directory, identifier)
        runner.initialize(environment, scenario)
        # do the run
        runner.do_run(environment, scenario)
Explanation: Explanation of python code
Dear Yordan, 
Kindly find attached a folder containing python code for the toy model in the stock flow presentation. The coding of system wide stress simulation is part of my deliverables. In addition, I thought it may be useful for you to have an object orientated programming framework in python because it is associated with agent based modelling.  In object-oriented programming languages, data and programming methods or functions are “embedded” in objects that can manipulate their own data and interact with other programming objects.  This makes real-world entities such as households or banks easy  to be represented. For example, in this model a natural starting point is to define an object/class called “Dealer banks”. I specified information dealers would need to have and rules for how they interact with each other and their environment. Another feature of object-oriented programming that is good for ABM development is inheritance. An instantiated object, e.g. commercial bank, can ‘inherit’ some characteristics from a ‘parent class’ but still behave in different ways. 
However, the obvious downside is that Python coding is definitely harder than Matlab. For example, there is no interface to click on a variable set(not that I"m aware of anyway), you have to save the variables in a dataframe (by writing a function in the  code) and then write the  dataframe to a csv file. On the upside, it’s possible to automate the update state easily and add heterogenous behavior for same-type like institutions. Another feature is that 
How to run the model
Running python :
    For python code to be executed the computer needs 
    to have python 2 or python 3 installed (via https://www.python.org) 
    A nice coding editor like Sublime Text 3, Atom or pycharm. The good thing about pycharm is that you can run the 
    code in the editor without installing additional packages. On my mac, I actually run the code in the terminal 
    (also called bash). I think in Windows, the equivalent is the shell. The program is run via command line codes. So 
    I go to the path of where the folders are stored and type.
ruby  
python sflow.py
Alternatively, for example in pycharm, you can open the slfow.py program and then run it. 
This executes the whole program and writes a csv file with the output in the main folder stockflow. 
If you want to change things in this model, the main files you will be working on are the agent scripts 
in src/institution, the updater.py and the configuration files in /configs/.  
So let's start by looking at the main file: 
Sflow.py
End of explanation
# %load configs/agents/hf/hf.xml
<agent identifier="HF">
<parameter type="stock_variables" name="GB" value="40"></parameter>
<parameter type="stock_variables" name="CB" value="20"></parameter>
 <parameter type="stock_variables" name="Cash" value="10"></parameter>
 <parameter type="stock_variables" name="does_repo" value="yes"></parameter>
</agent>
<!-- <parameter type="parameters" name="leverage" value="13.0780116888061"></parameter> -->
Explanation: In the beginning we need to instantiate two objects in the main file to run the program  -
from src.environment import Environment
    from src.runner import Runner
the Environment and the Runner class. The code for those classes are stored in the folder src and the name of the classes are Environment and Runner (not surprising).
* The runner has two main purposes - it just handles the time steps and writes the output to csv. 
* The environment has the purpose of reading all the configuration files,  instantiating the agents and saving the agents in lists to access them in the actual modelling part. So whenever you want to access a variable for an agent in the updater (for example a cash position of a hedgefund), you need to write 
ruby 
for hr in environment.hedgefunds:
    print hr.Cash
The instantiation of the agents takes up quite a bit of code in the environment file. The code reads the data for the agents from configuration files you find in /configs. A configuration file for the agents is stored in an agent folder because python iterates through the folder to look for all config files for a specific agent. It's possible to store them all in one place but then the automation code of the instantiation has to be changed. 
An agent config file looks like this:
End of explanation
# %load configs/environment/environment_config.xml
<environment identifier='toy_test'>
<!-- simulation parameters -->
  <parameter type='static' name='num_sweeps' value='10'></parameter>
  <parameter type='static' name='num_simulations' value='1'></parameter>
  <parameter type='static' name='cbank_directory' value='configs/agents/cbank/'></parameter>
  <parameter type='static' name='dealer_directory' value='configs/agents/dealer/'></parameter>
  <parameter type='static' name='hf_directory' value='configs/agents/hf/'></parameter>
  <parameter type='static' name='pf_directory' value='configs/agents/pf/'></parameter>
  <parameter type='static' name='ic_directory' value='configs/agents/ic/'></parameter>
  <parameter type='static' name='mmf_directory' value='configs/agents/mmf/'></parameter>
  <parameter type='static' name='if_directory' value='configs/agents/if/'></parameter>
  <parameter type='exogenous' name='price_GB' value="1.0"></parameter>
    <parameter type='exogenous' name='price_CB' value="1.0"></parameter>
    <parameter type='exogenous' name='haircut' value="0.05"></parameter>
      <parameter type='exogenous' name='interest_GB' value="0.02"></parameter>
      <parameter type='exogenous' name='interest_CB' value="0.04"></parameter>
      <parameter type='exogenous' name='interest_repo' value="0.02"></parameter>
      <parameter type='exogenous' name='interest_loans' value="0.02"></parameter>
      <parameter type='exogenous' name='interest_deposits' value="0.02"></parameter>
      <parameter type='exogenous' name='GB_shock' value="-0.1"></parameter>
      <parameter type='exogenous' name='CB_shock' value="-0.1"></parameter>
      <parameter type='exogenous' name='Redemption' value="-0.1"></parameter>
</environment>
Explanation: Those type "  " names later become dictionaries for the instantiated agent object. So the hedge fund has 
a dictionary (a data structure that saves stuff) with the name stock_variable = {Cash: 20, GB: 40, CB: 20, does_repo = 'yes'} When I write the results to csv, I iterate over those variables.
You can define additional variables (e.g. leverage) by adding a line. But for now I commented that out. 
Agents' configuration files all look similar to that one. 
The environment config file looks a bit different:
End of explanation
# -*- coding: utf-8 -*-
# -------------------------------------------------------------------------
#  class Updater
# -------------------------------------------------------------------------
import numpy as np
class Updater():
    #
    #
    # METHODS
    #
    def get_identifier(self):
        return self.identifier
    # -------------------------------------------------------------------------
    # __init__
    # -------------------------------------------------------------------------
    def __init__(self, environment, runner):
        self.environment = environment
        self.runner = runner
        self.results_df = 0
        self.prices = np.array([])
        self.rates={}
        self.system_equity = 0
        self.system_assets = 0
        self.delta_pGB = 0
        self.delta_pGB = 0
    # -------------------------------------------------------------------------
    # -------------------------------------------------------------------------
    # do_update
    # -------------------------------------------------------------------------
    def do_update_benchmark(self, environment, current_step, scenario):
        import pandas as pd
        if current_step < 1:
            self.add_rates(environment)
            self.initialize_prices(environment, current_step)
            print "***In t=:", current_step , " This is the price matrix***\n", self.prices, "\n",
            self.initialize_assets_all_agents(current_step, environment)
            self.profit_all_agents(environment, current_step)
        else:
            self.update_all_agents_balance_sheets(environment, current_step, scenario)
Explanation: Here you can change the initital interest rates and prices for the marketable assets and also the shocks. It's possible to assign them to other variables and change them later in the updater. It's also possible to not read them in at all (just delete the lines) and define those in the updater script, but in the current setup they get read into the dictionary in the environment, environment.exogenous variables = {price_GB : 1.0, ... }. 
What's the difference between num_simulations and num_sweeps? For the time iterations current_step it's more convenient to use num_sweeps rather than num_simulations for now. num_sweeps are the time steps for the model algorithm.  With num_simulations, one can  initiate a different environment with different classes, so for now it's better to stick with num_sweeps to handle the time steps in the model. 
Once all the agents' objects and configuration files are instantiated, the code moves on to the actual model algorithm which is stored in the updater class under \src\
    updater.py
The updater can be thought as the class that handels the transition.  
Updater.py
Here 
We take over the initial prices and interest rates given by the enviroment config and save them in updater specific    dictionaries (updater.prices and updater.rates by using the method def add_rates(self, environment):
def initialize_prices and def updade_prices
The really important method is the one below: 
```ruby 
def do_update_benchmark(self, environment, current_step, scenario):
    import pandas as pd
if current_step &lt; 1:
    self.add_rates(environment)
    self.initialize_prices(environment, current_step)
    print "***In t=:", current_step , " This is the price matrix***\n", self.prices, "\n",
    self.initialize_assets_all_agents(current_step, environment)
    self.profit_all_agents(environment, current_step)
else:
    self.update_all_agents_balance_sheets(environment, current_step, scenario)```
def write_to_csv  puts the output in to a result dataframe self.results_df.
End of explanation
<END_TASK>