def add_node_list(self, node_list): ''' Add a list of nodes to the block. These nodes must already be successive to each other. Also, one of the following conditions must be true: 1. The first node in the list is a child of the last node in the block. 2. The last node in the list is the parent of the first node in the block. ''' assert self.alive if not node_list: return if len(node_list) == 1: self.append_node(node_list[0]) return if not logic_tools.all_equal((node.step_profile for node in node_list)): raise BlockError('''Tried to add node list that doesn't share the \ same step options profile.''') sample_step_profile = node_list[0].step_profile if self.__node_list and \ sample_step_profile != self.get_step_profile(): raise BlockError('''Tried to add nodelist which contains node \ that has a different step_profile.''') # We now make sure the node_list is successive, untouched, and has no # unwanted children. for i in xrange(len(node_list)): if (i >= 1) and (node_list[i].parent != node_list[i-1]): raise BlockError('Tried to add non-consecutive nodes to block.') if (len(node_list) - i >= 2) and (len(node_list[i].children) != 1): raise BlockError('''Tried to add to the block a node which \ doesn't have exactly one child, and not as the last node in the block.''') if node_list[i].touched: raise BlockError("Tried to add touched nodes to block.") if not self.__node_list: # If the node list is empty, our job is simple. self.__node_list = list(node_list) for node in node_list: node.block = self return if node_list[0].parent == self.__node_list[-1]: self.__node_list = self.__node_list + node_list elif self.__node_list[0].parent == node_list[-1]: self.__node_list = node_list + self.__node_list else: raise BlockError('List of nodes is not adjacent to existing nodes.') for node in node_list: node.block = self
def call_and_check_if_profiled(f): '''Call the function `f` and return whether it profiled itself.''' with OutputCapturer() as output_capturer: f() output = output_capturer.output segments_found = [(segment in output) for segment in segments] if not logic_tools.all_equal(segments_found): raise Exception("Some segments were found, but some weren't; can't " "know if this was a profiled call or not. Possibly " "some of our segments are wrong.") return segments_found[0]
def test_node_selection_and_range(): '''Test `node_selection` and `node_range`.''' root_state = life.State.create_root(2, 2) project = garlicsim.Project(life) tree = project.tree root = project.root_this_state(root_state) leaf1 = project.simulate(root, 10) temp_path = root.make_containing_path() middle_node = temp_path[5] leaf2 = project.simulate(middle_node, 10) # Now we have a tree with a fork in it, in `middle_node` path1 = leaf1.make_containing_path() # creating only after leaf2 path2 = leaf2.make_containing_path() range1 = ds.NodeRange(root, leaf1) assert path1 == range1.make_path() range2 = ds.NodeRange(root, leaf2) assert path2 == range2.make_path() ns1 = ds.NodeSelection([range1, range2]) ns2 = ns1.copy() assert ns1 == ns2 ns2.compact() assert ns1 == ns2 range1blocky = ds.NodeRange(root, leaf1.block) range2blocky = ds.NodeRange(root, leaf2.block) ns3 = ds.NodeSelection([range1blocky, range2blocky]) ns4 = ns3.copy() ns4.compact() logic_tools.all_equal((ns1, ns2, ns3, ns4), exhaustive=True) all_ranges = sum((ns.ranges for ns in (ns1, ns2, ns3, ns4)), []) for range in all_ranges: assert range == range.clone_with_blocks_dissolved() assert len(tree.nodes) == 21 ##################### alt_tree, alt_ns1 = copy.deepcopy((tree, ns1)) alt_tree.delete_node_selection(alt_ns1) assert len(alt_tree.nodes) == 0 assert len(alt_tree.roots) == 0 ##################### assert len(tree.nodes) == 21 middle_node_grandparent = middle_node.parent.parent middle_node_grandchild_1 = path1.next_node(path1.next_node(middle_node)) middle_node_grandchild_2 = path2.next_node(path2.next_node(middle_node)) assert middle_node_grandchild_1 is not middle_node_grandchild_2 small_range_1 = ds.NodeRange(middle_node_grandparent, middle_node_grandchild_1) small_range_2 = ds.NodeRange(middle_node_grandparent, middle_node_grandchild_2) assert small_range_1 != small_range_2 small_ns = ds.NodeSelection((small_range_1, small_range_2)) ##################### alt_tree, alt_small_range_1 = copy.deepcopy((tree, small_range_1)) alt_tree.delete_node_range(alt_small_range_1) assert len(alt_tree.roots) == 3 assert len(alt_tree.nodes) == 16 ##################### ##################### alt_tree, alt_small_range_2 = copy.deepcopy((tree, small_range_2)) alt_tree.delete_node_range(alt_small_range_2) assert len(alt_tree.roots) == 3 assert len(alt_tree.nodes) == 16 ##################### ##################### alt_tree, alt_small_ns = copy.deepcopy((tree, small_ns)) alt_tree.delete_node_selection(alt_small_ns) assert len(alt_tree.roots) == 3 assert len(alt_tree.nodes) == 14 ##################### assert len(tree.nodes) == 21
def assert_same_signature(*callables): '''Assert that all the `callables` have the same function signature.''' arg_specs = [cute_inspect.getargspec(callable_) for callable_ in callables] if not logic_tools.all_equal(arg_specs, exhaustive=True): raise Failure('Not all the callables have the same signature.')
import psyco psyco.full() from garlicsim.general_misc.logic_tools import all_equal stuff = [[1, 'meow'] for i in range(10)] print all_equal(stuff)
def add_node_list(self, node_list): ''' Add a list of nodes to the block. These nodes must already be successive to each other. Also, one of the following conditions must be true: 1. The first node in the list is a child of the last node in the block. 2. The last node in the list is the parent of the first node in the block. ''' assert self.alive if not node_list: return if len(node_list) == 1: self.append_node(node_list[0]) return if not logic_tools.all_equal((node.step_profile for node in node_list)): raise BlockError("Tried to add node list that doesn't share the " "same step profile.") sample_step_profile = node_list[0].step_profile if self.__node_list and \ sample_step_profile != self.step_profile: raise BlockError('Tried to add node list which contains node that ' 'has a different step profile.') # We now make sure the node_list is successive, untouched, and has no # unwanted children. for i in xrange(len(node_list)): if (i >= 1) and (node_list[i].parent != node_list[i-1]): raise BlockError('Tried to add non-consecutive nodes to block.') if (len(node_list) - i >= 2) and (len(node_list[i].children) != 1): raise BlockError("Tried to add to the block a node which " "doesn't have exactly one child, and not as " "the last node in the block.") if node_list[i].touched: raise BlockError('Tried to add touched nodes to block.') if not self.__node_list: # If the node list is empty, our job is simple. self.__node_list = list(node_list) for node in node_list: node.block = self self.step_profile = sample_step_profile return if node_list[0].parent == self.__node_list[-1]: self.__node_list = self.__node_list + node_list elif self.__node_list[0].parent == node_list[-1]: self.__node_list = node_list + self.__node_list else: raise BlockError('List of nodes is not adjacent to existing nodes.') for node in node_list: node.block = self