def _generate_computation_node(interaction: Dict, graph: GraphRLang, g_inputs: Dict[str, DataFrameGraph]) -> Node: if interaction['labels'] == ["EQUAL"]: r_from, c_from, inp_id = interaction['from'][0].split(':') return g_inputs[inp_id].get_node_xy(int(r_from), int(c_from)) from_nodes = [ _generate_computation_node(t, graph, g_inputs) for t in interaction['from'] ] interm_node = graph.create_intermediate_node(interaction['value']) labels = interaction['labels'] if len(labels) == 1 and len(from_nodes) > 1: labels = [labels[0]] * len(from_nodes) for label, node in zip(labels, from_nodes): graph.add_edge(Edge(node, interm_node, getattr(ELabel, label))) return interm_node
def process_ui_interaction( self, inputs: Dict[str, Any], interactions: List[Dict]) -> Tuple[Any, Graph, Dict[str, Graph]]: value_interactions = [ interaction for interaction in interactions if interaction['to'] != "" ] output_cells = [[int(r), int(c)] for r, c, _ in (interaction['to'].split(':') for interaction in value_interactions)] if len(output_cells) > 0: row_nums, col_nums = list(zip(*output_cells)) else: row_nums = [] col_nums = [] min_r, max_r = min([i for i in row_nums if i >= 0] + [0]), max([i for i in row_nums if i >= 0] + [0]) min_c, max_c = min(col_nums, default=0), max(col_nums, default=0) num_rows = max_r - min_r + 1 num_cols = max_c - min_c + 1 output = pd.DataFrame([[f"_CELL_{r}_{c}" for c in range(num_cols)] for r in range(num_rows)], columns=[f"_COL_{c}" for c in range(num_cols)]) columns = list(output.columns) for interaction in value_interactions: value = interaction['value'] r, c, _ = interaction['to'].split(':') r = int(r) c = int(c) if r == -1: columns[c - min_c] = value else: output.iloc[r - min_r, c - min_c] = value output.columns = columns graph = GraphRLang() g_inputs: Dict[str, DataFrameGraph] = { key: DataFrameGraph(inp) for key, inp in inputs.items() } g_output = DataFrameGraph(output) for g_inp in g_inputs.values(): graph.merge(g_inp) graph.merge(g_output) for interaction in interactions: if interaction["labels"] == ["DELETE"]: node_to = g_output.deletion_node for r_from, c_from, inp_id in (i.split(':') for i in interaction['from']): node_from = g_inputs[inp_id].get_node_xy( int(r_from), int(c_from)) graph.add_edge(Edge(node_from, node_to, ELabel.DELETE)) continue value = interaction['value'] r_to, c_to, _ = interaction['to'].split(':') r_to = int(r_to) c_to = int(c_to) if r_to >= 0: r_to -= min_r c_to -= min_c if r_to == -1: actual_value = output.columns[c_to] else: actual_value = output.iloc[r_to, c_to] if _not_equal(actual_value, value): continue node_to = g_output.get_node_xy(r_to, c_to) node_from = _generate_computation_node(interaction, graph, g_inputs) graph.add_edge(Edge(node_from, node_to, ELabel.EQUAL)) return output, graph, g_inputs