""" A model for capital structure. Places two groups of agents in the enviornment randomly and moves them around randomly. """ import copy import random from indra.agent import Agent from indra.composite import Composite from indra.display_methods import RED, BLUE from indra.env import Env from registry.registry import get_env, get_prop from registry.registry import user_tell from indra.space import DEF_HEIGHT, DEF_WIDTH from indra.utils import init_props MODEL_NAME = "capital" DEBUG = False # turns debugging code on or off DEBUG2 = False # turns deeper debugging code on or off DEF_NUM_ENTR = 10 DEF_NUM_RHOLDER = 10 DEF_TOTAL_RESOURCES_ENTR_WANT = 20000 DEF_TOTAL_RESOURCES_RHOLDER_HAVE = 30000 DEF_ENTR_CASH = 100000 DEF_RHOLDER_CASH = 0 DEF_K_PRICE = 1 DEF_RESOURCE_HOLD = {"land": 1000, "truck": 500, "building": 200} DEF_CAP_WANTED = {"land": 1000, "truck": 500, "building": 200} DEF_EACH_CAP_PRICE = {"land": DEF_K_PRICE, "truck": DEF_K_PRICE, "building": DEF_K_PRICE} resource_holders = None # list of resource holders entrepreneurs = None # list of entrepreneur def dict_to_string(dict): return " ".join(good + " {0:.2f}".format(amt) for good, amt in dict.items()) def entr_action(agent): if agent["cash"] > 0: nearby_rholder = get_env().get_neighbor_of_groupX(agent, resource_holders, hood_size=4) if nearby_rholder is not None: # try to buy a resource if you have cash for good in agent["wants"].keys(): price = nearby_rholder["price"][good] entr_max_buy = min(agent["cash"], agent["wants"][good] * price) # if find the resources entr want if good in nearby_rholder["resources"].keys(): trade_amt = min(entr_max_buy, nearby_rholder["resources"][good]) # update resources for the two groups if good not in agent["have"].keys(): agent["have"][good] = trade_amt agent["have"][good] += trade_amt agent["wants"][good] -= trade_amt nearby_rholder["resources"][good] -= trade_amt nearby_rholder["cash"] += trade_amt * price agent["cash"] -= trade_amt * price if agent["wants"][good] <= 0: agent["wants"].pop(good) if nearby_rholder["resources"][good] <= 0: nearby_rholder["resources"].pop(good) break if agent["wants"] and agent["have"]: user_tell("I'm " + agent.name + " and I will buy resources from " + str(nearby_rholder) + ". I have " + "{0:.2f}".format(agent["cash"]) + " dollars left." + " I want " + dict_to_string(agent["wants"]) + ", and I have " + dict_to_string(agent["have"]) + ".") elif agent["wants"]: user_tell("I'm " + agent.name + " and I will buy resources from " + str(nearby_rholder) + ". I have " + "{0:.2f}".format(agent["cash"]) + " dollars left." + " I want " + dict_to_string(agent["wants"]) + ", and I don't have any capital.") elif agent["have"]: user_tell("I'm " + agent.name + " and I will buy resources from " + str(nearby_rholder) + ". I have " + "{0:.2f}".format(agent["cash"]) + " dollars left." + " I got all I need, and I have " + dict_to_string(agent["have"]) + "!") return False # move to find resource holder else: user_tell("I'm " + agent.name + " and I'm broke!") else: user_tell("I'm " + agent.name + " and I can't find resources.") return True def rholder_action(agent): if agent["resources"]: get_env().user.tell("I'm " + agent.name + " and I've got resources. I have " + str(agent["cash"]) + " dollors now." + " I have " + str(agent["resources"]) + ".") else: get_env().user.tell("I'm " + agent.name + " and I've got resources. I have " + str(agent["cash"]) + " dollors now." + " I ran out of resources!") # resource holder dont move return True def create_entr(name, i, props=None): """ Create an agent. """ starting_cash = DEF_ENTR_CASH if props is not None: starting_cash = get_prop('entr_starting_cash', DEF_ENTR_CASH) resources = copy.deepcopy(DEF_CAP_WANTED) if props is not None: total_resources = get_prop('entr_want_resource_total', DEF_TOTAL_RESOURCES_ENTR_WANT) num_resources = len(resources) for k in resources.keys(): resources[k] = int((total_resources * 2) * (random.random() / num_resources)) return Agent(name + str(i), action=entr_action, attrs={"cash": starting_cash, "wants": resources, "have": {}}) def create_rholder(name, i, props=None): """ Create an agent. """ k_price = DEF_K_PRICE resources = copy.deepcopy(DEF_CAP_WANTED) num_resources = len(resources) price_list = copy.deepcopy(DEF_EACH_CAP_PRICE) if props is not None: k_price = props.get('cap_price', DEF_K_PRICE) for k in price_list.keys(): price_list[k] = float("{0:.2f}".format(float(k_price * random.uniform(0.5, 1.5)))) starting_cash = DEF_RHOLDER_CASH if props is not None: starting_cash = get_prop('rholder_starting_cash', DEF_RHOLDER_CASH) if props is not None: total_resources = get_prop('rholder_starting_resource_total', DEF_TOTAL_RESOURCES_RHOLDER_HAVE) for k in resources.keys(): resources[k] = int((total_resources * 2) * (random.random() / num_resources)) return Agent(name + str(i), action=rholder_action, attrs={"cash": starting_cash, "resources": resources, "price": price_list}) def set_up(props=None): """ A func to set up run that can also be used by test code. """ global resource_holders global entrepreneurs pa = init_props(MODEL_NAME, props, model_dir="capital") entrepreneurs = Composite("Entrepreneurs", {"color": BLUE}, member_creator=create_entr, props=pa, num_members=pa.get('num_entr', DEF_NUM_ENTR)) resource_holders = Composite("Resource_holders", {"color": RED}, member_creator=create_rholder, props=pa, num_members=pa.get('num_rholder', DEF_NUM_RHOLDER)) Env("neighborhood", height=get_prop('grid_height', DEF_HEIGHT), width=get_prop('grid_width', DEF_WIDTH), members=[resource_holders, entrepreneurs]) return resource_holders, entrepreneurs def main(): global resource_holders global entrepreneurs (blue_group, red_group) = set_up() if DEBUG2: get_env().user.tell(get_env().__repr__()) get_env()() return 0 if __name__ == "__main__": main()