<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def generate_calculus_integrate_sample(vlist, ops, min_depth, max_depth, functions):
 """Randomly generate a symbolic integral dataset sample. Given an input expression, produce the indefinite integral. Args: vlist: Variable list. List of chars that can be used in the expression. ops: List of ExprOp instances. The allowed operators for the expression. min_depth: Expression trees will not have a smaller depth than this. 0 means there is just a variable. 1 means there is one operation. max_depth: Expression trees will not have a larger depth than this. To make all trees have the same depth, set this equal to `min_depth`. functions: Defines special functions. A dict mapping human readable string names, like "log", "exp", "sin", "cos", etc., to single chars. Each function gets a unique token, like "L" for "log". Returns: sample: String representation of the input. Will be of the form 'var:expression'. target: String representation of the solution. """

  var_index = random.randrange(len(vlist))
  var = vlist[var_index]
  consts = vlist[:var_index] + vlist[var_index + 1:]

  depth = random.randrange(min_depth, max_depth + 1)
  expr = random_expr_with_required_var(depth, var, consts, ops)

  expr_str = str(expr)
  sample = var + ":" + expr_str
  target = format_sympy_expr(
      sympy.integrate(expr_str, sympy.Symbol(var)), functions=functions)
  return sample, target