code: def before_and_after(predicate, it):
      """A variant of :func:`takewhile` that allows complete access to the
      remainder of the iterator.
  
           >>> it = iter('ABCdEfGhI')
           >>> all_upper, remainder = before_and_after(str.isupper, it)
           >>> ''.join(all_upper)
           'ABC'
           >>> ''.join(remainder) # takewhile() would lose the 'd'
           'dEfGhI'
  
      Note that the first iterator must be fully consumed before the second
      iterator can generate valid results.
      """
      it = iter(it)
      transition = []
  
      def true_iterator():
          for elem in it:
              if predicate(elem):
                  yield elem
              else:
                  transition.append(elem)
                  return
  
      # Note: this is different from itertools recipes to allow nesting
      # before_and_after remainders into before_and_after again. See tests
      # for an example.
      remainder_iterator = chain(transition, it)
  
      return true_iterator(), remainder_iterator
  
imports: import math
  import operator
  from collections import deque
  from collections.abc import Sized
  from functools import partial, reduce
  from itertools import chain, combinations, compress, count, cycle, groupby, islice, product, repeat, starmap, tee, zip_longest
  from random import randrange, sample, choice
label_desc: Use image node_id 31 for calling a global function with example usage: before_and_after(predicate, it) and returns: true_iterator,  remainder_iterator