def crossover(parent1, parent2, maxDepth, terms):
     child1 = parent1.copy()
     child2 = parent2.copy()
     randomNodeIndexParent1 = random.randint(0, parent1.nodeCount()-2) + 1
     randomNodeIndexParent2 = random.randint(0, parent2.nodeCount()-2) + 1
     randomNodeParent1 = parent1.subProgramAt(randomNodeIndexParent1)[0]
     randomNodeParent2 = parent2.subProgramAt(randomNodeIndexParent2)[0]
     child2.replaceAt(randomNodeIndexParent2, randomNodeParent1)
     child1.replaceAt(randomNodeIndexParent1, randomNodeParent2)
     return Program.prune(child1, 4, terms), Program.prune(child2, 4, terms)
 def mutate(parent, maxDepth, functions, terms):
     randomProgram = Program.random(int(maxDepth/2), functions, terms, [-5,5])
     randomNodeIndex = random.randint(0, randomProgram.nodeCount()-1)
     child = parent.copy()
     child.replaceAt(randomNodeIndex, randomProgram.subProgramAt(randomNodeIndex)[0])
     return Program.prune(parent, maxDepth, terms)