def calculate_num_segments_range():

    for i in range(15, num_segments_max+1):
        n_diff = solve_for_n_diff(num_bp_per_segment*i)
        if n_diff/i <= 1:
            return [i, num_segments_max]

    print "problem computing min num segments, abort"
    return None
def factors(num):
    facts =  set(reduce(list.__add__, ([i, num//i] for i in range(1, int(num**0.5) + 1) if num % i == 0)))
    return list(facts)

for num_potential_strands in range(num_potential_strands_range[0], num_potential_strands_range[1]+1):
    min_num_segments = int(math.ceil(num_segments_range[0]/float(num_potential_strands))*num_potential_strands)
    for num_segments in range(min_num_segments, num_segments_range[1]+1, num_potential_strands):

        if num_segments % 3 != 0:
            continue
        if num_segments_min > num_segments:
            continue


        n = num_segments*num_bp_per_segment
        n_diff = solve_for_n_diff(n)

        num_segments_factors = factors(num_segments)
        for i, val in enumerate(num_segments_factors):
            remainder = n_diff/val - round(n_diff/val)
            if abs(remainder*val) < tolerance and (round(n_diff/val) in num_segments_factors):
                factor1 = val
                factor2 = round(n_diff/val)
                n_diff = factor1*factor2
                print_candidate(num_segments, n_diff, num_potential_strands, num_segments/max(factor1, factor2))


print "\n\n"
print "candidate with min theta error:"
print_candidate(min_theta_error_candidate["num_segments"], min_theta_error_candidate["n_diff"],
                min_theta_error_candidate["num_potential_strands"], min_theta_error_candidate["n_diff_period"])