#!/bin/python3

import math;

def mystery(x, N):
    """This mystery function outputs some value based on x and n.
    We assume that x is a real number, and n is a positive integer."""

    output = 0;

    for n in range(0, N + 1):
        print("Adding the term: (-1)^{} x^{} / ({})! = {} {} / {}".format(n, 2*n+1, 2*n+1, (-1)**n, x**(2*n+1), math.factorial(2*n+1)));
        output += ((-1)**n)*(x**(2*n+1))/(math.factorial(2*n+1));

    return output;

# Tasks from the Worksheet

# 1. Calculate some specific values of the function. 
#    For example, fill out the following table:
# 
#      |         | x = 0   | x = 1   | x = 2   | x = 3   |
#      |---------|---------|---------|---------|---------|
#      | N=1     |         |         |         |         |
#      | N=2     |         |         |         |         |
#      | N=3     |         |         |         |         |
#      | N=4     |         |         |         |         |

# In general, you can write a function `table(C,R)` which produces a similar
# table with columns x = 0, 1, 2, ..., C and rows N = 1, 2, ..., R.

def table(C, R):
    """ Produce a table of values for the mystery function. """
    # ADD CODE HERE (start)


    # ADD CODE HERE (end) 

# 2.  Create a new Python function `limit(x)` which calculates the limiting value of
# `mystery(x,N)` for each x. You will want to use the built-in Python function
# abs() to compute the absolute value.

def limit(x):
    """Output the limiting value of mystery(x,N) as a function of N.""" 
    # ADD CODE HERE (start)

    # ADD CODE HERE (end)


# 3. Approximate the smallest and biggest values of `mystery(x,N)` on the domain -3 <= x <= when N is big.
# To do so, calculate the value of `limit(x)` at a large number of points in the domain -3 <= x <= 3.

# Initialize the biggest and smallest possible values as floats.
# (These initial values feel "backwards". Why are they correct?)

SMALLEST = float('inf');
SMALLEST_sample_point = 0;

BIGGEST = float('-inf');
BIGGEST_sample_point = 0;

# Specify the number of sample points to check.
SAMPLES = 1000;

# ADD CODE HERE (start)

# ADD CODE HERE (end)

print("Smallest value is: limit({}) = {}".format(SMALLEST_sample_point, SMALLEST));
print("Biggest value is: limit({}) = {}".format(BIGGEST_sample_point, BIGGEST));


# 4. On paper: Write it out as a polynomial, for N = 3. 
# 5. In Desmos: Graph the function `mystery(x,N)` with a slider for N.
