def test_while_is_not(self): it = iter(string.ascii_lowercase) self.assertEqual(['a'], list(iter_utils.while_is_not(it, 'a'))) it = iter(string.ascii_lowercase) self.assertEqual(['a', 'b'], list(iter_utils.while_is_not(it, 'b'))) self.assertEqual(list(string.ascii_lowercase[2:]), list(iter_utils.while_is_not(it, 'zzz'))) it = iter(string.ascii_lowercase) self.assertEqual(list(string.ascii_lowercase), list(iter_utils.while_is_not(it, '')))
def pformat(self, stringify_node=None, linesep=LINE_SEP, vertical_conn=VERTICAL_CONN, horizontal_conn=HORIZONTAL_CONN, empty_space=EMPTY_SPACE_SEP, starting_prefix=STARTING_PREFIX): """Formats this node + children into a nice string representation. **Example**:: >>> from taskflow.types import tree >>> yahoo = tree.Node("CEO") >>> yahoo.add(tree.Node("Infra")) >>> yahoo[0].add(tree.Node("Boss")) >>> yahoo[0][0].add(tree.Node("Me")) >>> yahoo.add(tree.Node("Mobile")) >>> yahoo.add(tree.Node("Mail")) >>> print(yahoo.pformat()) CEO |__Infra | |__Boss | |__Me |__Mobile |__Mail """ if stringify_node is None: # Default to making a unicode string out of the nodes item... stringify_node = lambda node: six.text_type(node.item) expected_lines = self.child_count(only_direct=False) + 1 buff = six.StringIO() conn = vertical_conn + horizontal_conn stop_at_parent = self for i, node in enumerate(self.dfs_iter(include_self=True), 1): prefix = [] connected_to_parent = False last_node = node # Walk through *most* of this nodes parents, and form the expected # prefix that each parent should require, repeat this until we # hit the root node (self) and use that as our nodes prefix # string... parent_node_it = iter_utils.while_is_not( node.path_iter(include_self=True), stop_at_parent) for j, parent_node in enumerate(parent_node_it): if parent_node is stop_at_parent: if j > 0: if not connected_to_parent: prefix.append(conn) connected_to_parent = True else: # If the node was connected already then it must # have had more than one parent, so we want to put # the right final starting prefix on (which may be # a empty space or another vertical connector)... last_node = self._children[-1] m = last_node.find_first_match(lambda n: n is node, include_self=False, only_direct=False) if m is not None: prefix.append(empty_space) else: prefix.append(vertical_conn) elif parent_node is node: # Skip ourself... (we only include ourself so that # we can use the 'j' variable to determine if the only # node requested is ourself in the first place); used # in the first conditional here... pass else: if not connected_to_parent: prefix.append(conn) spaces = len(horizontal_conn) connected_to_parent = True else: # If we have already been connected to our parent # then determine if this current node is the last # node of its parent (and in that case just put # on more spaces), otherwise put a vertical connector # on and less spaces... if parent_node[-1] is not last_node: prefix.append(vertical_conn) spaces = len(horizontal_conn) else: spaces = len(conn) prefix.append(empty_space * spaces) last_node = parent_node prefix.append(starting_prefix) for prefix_piece in reversed(prefix): buff.write(prefix_piece) buff.write(stringify_node(node)) if i != expected_lines: buff.write(linesep) return buff.getvalue()
def pformat( self, stringify_node=None, linesep=LINE_SEP, vertical_conn=VERTICAL_CONN, horizontal_conn=HORIZONTAL_CONN, empty_space=EMPTY_SPACE_SEP, starting_prefix=STARTING_PREFIX, ): """Formats this node + children into a nice string representation. **Example**:: >>> from taskflow.types import tree >>> yahoo = tree.Node("CEO") >>> yahoo.add(tree.Node("Infra")) >>> yahoo[0].add(tree.Node("Boss")) >>> yahoo[0][0].add(tree.Node("Me")) >>> yahoo.add(tree.Node("Mobile")) >>> yahoo.add(tree.Node("Mail")) >>> print(yahoo.pformat()) CEO |__Infra | |__Boss | |__Me |__Mobile |__Mail """ if stringify_node is None: # Default to making a unicode string out of the nodes item... stringify_node = lambda node: six.text_type(node.item) expected_lines = self.child_count(only_direct=False) + 1 buff = six.StringIO() conn = vertical_conn + horizontal_conn stop_at_parent = self for i, node in enumerate(self.dfs_iter(include_self=True), 1): prefix = [] connected_to_parent = False last_node = node # Walk through *most* of this nodes parents, and form the expected # prefix that each parent should require, repeat this until we # hit the root node (self) and use that as our nodes prefix # string... parent_node_it = iter_utils.while_is_not(node.path_iter(include_self=True), stop_at_parent) for j, parent_node in enumerate(parent_node_it): if parent_node is stop_at_parent: if j > 0: if not connected_to_parent: prefix.append(conn) connected_to_parent = True else: # If the node was connected already then it must # have had more than one parent, so we want to put # the right final starting prefix on (which may be # a empty space or another vertical connector)... last_node = self._children[-1] m = last_node.find_first_match(lambda n: n is node, include_self=False, only_direct=False) if m is not None: prefix.append(empty_space) else: prefix.append(vertical_conn) elif parent_node is node: # Skip ourself... (we only include ourself so that # we can use the 'j' variable to determine if the only # node requested is ourself in the first place); used # in the first conditional here... pass else: if not connected_to_parent: prefix.append(conn) spaces = len(horizontal_conn) connected_to_parent = True else: # If we have already been connected to our parent # then determine if this current node is the last # node of its parent (and in that case just put # on more spaces), otherwise put a vertical connector # on and less spaces... if parent_node[-1] is not last_node: prefix.append(vertical_conn) spaces = len(horizontal_conn) else: spaces = len(conn) prefix.append(empty_space * spaces) last_node = parent_node prefix.append(starting_prefix) for prefix_piece in reversed(prefix): buff.write(prefix_piece) buff.write(stringify_node(node)) if i != expected_lines: buff.write(linesep) return buff.getvalue()