Source code for utils.helper_methods

"""
Helper Methods used in the AGE-ABM Visual Interface Backend
@Author Matthew Fleischman
@Co-Authors Meghan Ireland and Max Hall

"""

[docs] def get_data_types(agent): """ This function takes a agent as a parameter and gets its valid_plot_types. Parameters ---------- agent : AgentOfInterest agent to be checked. Returns ------- valid_plot_data_types : list[str] | Returns the valid_plot_data_types for the given agent. """ valid_plot_data_types = [] if agent.get_count(): valid_plot_data_types.append("count") if agent.get_individual(): valid_plot_data_types.append("individual") if agent.get_mean_val(): valid_plot_data_types.append("mean_val") if agent.get_median_val(): valid_plot_data_types.append("median_val") if agent.get_total_val(): valid_plot_data_types.append("total_val") if agent.get_min_val(): valid_plot_data_types.append("min_val") if agent.get_max_val(): valid_plot_data_types.append("max_val") if agent.get_variance(): valid_plot_data_types.append("variance_val") if agent.get_std_dev(): valid_plot_data_types.append("std_dev_val") return valid_plot_data_types
[docs] def valid_plot_data_type(plot_data_type : str): """ This function takes a plot_data_type as a parameter and ensures that it is a valid plot_data_type. Parameters ---------- plot_data_type : str plot_data_type to be checked. Returns ------- plot_data_type : str | Returns the plot_data_type if valid. | Returns 1 if not valid """ valid_plot_data_types = ["count", "individual", "mean_val", "median_val", "total_val" , "min_val", "max_val", "variance_val", "std_dev_val"] if plot_data_type in valid_plot_data_types: return plot_data_type return 1
[docs] def valid_plot_type(plot_type : str): """ This function takes a plot_type as a parameter and ensures that it is a valid plot_type. Parameters ---------- plot_type : str plot_type to be checked. Returns ------- plot_type : str | Returns valid plot type on success | Returns 1 if plot type invalid """ valid_plot_types = ["plot", "bar", "scatter"] if plot_type in valid_plot_types: return plot_type return 1
[docs] def adding_name_checker(name : str, list_to_go_in : list, is_attribute : bool = False): """ This function takes a name as a parameter and ensures that it is a valid python class name as well as is not an existing name already. Parameters ---------- name : str name to be checked. list_to_go_in : list[str] list it will be put into Returns ------- error term : str | Returns formatted name on success | Returns 1 if name already in use | Returns 2 if name uses invalid characters """ # Gets the whole list in lowercase lowercase_list = [word.lower() for word in list_to_go_in] # Constructing a Valid Name return_name = "" name = (name.strip().replace("_", " ")) parts_of_name = [word.strip().capitalize() for word in name.split(" ")] for word in parts_of_name: if parts_of_name.index(word) == 0: return_name += word else: return_name += "_" + word # Checking if this name already in use lowercase_name = return_name.lower() for exist_name in lowercase_list: # Checks if name already in use if lowercase_name == exist_name: return 1 # Name already in use # Checks if any non-permitted char's used if name_validator(return_name) != 0: return 2 # Name invalid # Valid name returned if is_attribute: return return_name.lower() return return_name
[docs] def getting_name_checker(name : str, list_to_come_from : list, is_attribute : bool = False): """ This function takes a name as a parameter and ensures that it is a valid python class name as well as is not an existing name already. Parameters ---------- name : str name to be checked. list_to_come_from : list[str] list it will be taken from Returns ------- error term : str | Returns formatted name on success | Returns 1 if name isn't already in list | Returns 2 if name uses invalid characters """ # Gets the whole list in lowercase lowercase_list = [word.lower() for word in list_to_come_from] # Constructing a Valid Name return_name = "" name = (name.strip().replace("_", " ")) parts_of_name = [word.strip().capitalize() for word in name.split(" ")] for word in parts_of_name: if parts_of_name.index(word) == 0: return_name += word else: return_name += "_" + word # Checking if this name already in use lowercase_name = return_name.lower() not_in = True for exist_name in lowercase_list: # Checks if name already in use if lowercase_name == exist_name: not_in = False if not_in: return 1 # Name isn't in list # Checks if any non-permitted char's used if name_validator(return_name) != 0: return 2 # Name invalid # Valid name returned if is_attribute: return return_name.lower() return return_name
[docs] def name_validator(name : str): """ This function takes a name as a parameter and ensures that it is a valid python class name. Parameters ---------- name : str name to be checked. Returns ------- error term : int | Returns 0 on success | Returns 1 if invalid chars used """ # Checks if name has a length if len(name) == 0: return 1 # Checks first char is a number if 48 <= ord(name[0]) <= 57: return 1 # Ensures only valid characters are used for i in name: char = ord(i) if char < 48 or 57 < char < 65 or 90 < char < 95 or 95 < char < 97 or 122 < char: return 1 # Confirms name is valid return 0
[docs] def plotting_string(indent : str, agent : str, attr : str, interest : str, plot_type : str , title : str, xlabel : str, ylabel : str, compare_agents : list[str]): """Method to help write plots to the visualisation ouptut file. Parameters ---------- indent : str Indentation for the plotting code. agent : str Name of the agent whos data is being plotted. attr : str Attribute data being plotted. interest : str Data interests for the attribute being plotted. plot_type : str Type of plot (line graph, scatter plot, bar graph). title : str Title of the plot. xlabel : str Label of x-axis. ylabel : str Label of y-axis. compare_agents : list[str] List of agents to compare to the current agent whos data is being plotted. Returns ------- plotter : str | Returns the compiled string to be written to the visualisation output file. """ # Comment and create new plot plotter = f"{indent}# Plotting data for the {interest} values of the {attr} attribute\n" plotter += f"{indent}fig, ax = plt.subplots()\n" # Collect data from records # Get valus of attributes length_compare_agents = len(compare_agents) if attr != "": # Get final data of individual values if interest == "individual": plotter += f"{indent}y_vals = {agent}_records['{attr}']['{interest}'][-1]\n" for i in range(length_compare_agents): plotter += f"{indent}y_vals{str(i+1)} = {compare_agents[i]}_records['{attr}']" plotter += f"['{interest}'][-1]\n" # Get other data types else: plotter += f"{indent}y_vals = {agent}_records['{attr}']['{interest}']\n" for i in range(length_compare_agents): plotter += f"{indent}y_vals{str(i+1)} = {compare_agents[i]}_records['{attr}']" plotter += f"['{interest}']\n" # Get agent count else: plotter += f"{indent}y_vals = {agent}_records['count']\n" for i in range(length_compare_agents): plotter += f"{indent}y_vals{str(i+1)} = {compare_agents[i]}_records['count']\n" # Create x-axis plotter += f"{indent}x_vals = list(range(len(y_vals)))\n" # Plot data and comparing agents plotter += f"{indent}ax.{plot_type}(x_vals, y_vals, label='{agent}')\n" for i in range(length_compare_agents): plotter += f"{indent}ax.{plot_type}(x_vals, y_vals{str(i+1)}" plotter += f", label='{compare_agents[i]}')\n" # Give title and axis labels plotter += f"{indent}ax.set_title('{title}')\n" plotter += f"{indent}ax.set_xlabel('{xlabel}')\n" plotter += f"{indent}ax.set_ylabel('{ylabel}')\n" # Provides legend plotter += f"{indent}ax.legend()\n" plotter += f"{indent}return fig\n\n" return plotter