# 1. Print out data in columns
height = [134, 138, 142, 146, 150, 154, 158, 162, 166, 170, 174, 178]
fev = [1.7, 1.9, 2., 2.1, 2.2, 2.5, 2.7, 3.,3.1, 3.4, 3.8, 3.9]
n_height = len(height)
print(f"HEIGHT FEV")
# you need to add an appropriate for loop here and modify the next print statement so that you can print out all heights and FEVs
for num in range (0,n_height):
print(f" {height[num]} {fev[num]}")

# 2. Import libraries - NumPy and matplotlib
import numpy as np
import matplotlib.pyplot as plt

# 3. Plot the data; add labels to axes and plot title
plt.scatter (height, fev)
plt.xlabel("Height (cm)")
plt.ylabel("fev")
plt.title("Height vs. fev in boys 10-15 years old")

# 4. Input functions to find interpolating polynomial
def compute_int_coeff(n, x, y):
coeff = [] # initialize list
for i in range(0, n+1): # loop to calculate n+1 coefficients
numerator = y[i]
denominator = 1. # because denominator is a product we must initialize to 1
for j in range(0, n+1):
if (i != j): # denominator is product of all terms except
# when x_i=x_j which would give 0
denominator = denominator * (x[i] - x[j])
coeff.append(numerator / denominator) # add term to list
return coeff
def eval_int_polynomial(n, x, x_eval, coeff):
my_sum = 0. # formula is sum of n+1 terms so initialize
for i in range(0, n+1): # loop to form sum of terms
product = 1. # initialize product in numerator of L_i
for j in range(0, n+1): # loop to form product of terms in numerator
if (i != j): # include all terms except when i = j
product = product * (x_eval - x[j])
# when this j loop is complete we have the numerator of L_i for one term
yi_times_Li = product * coeff[i] # multiplies numerator times C_i (y_i/ product)
my_sum = my_sum + yi_times_Li # keeps running tally of sum of terms
return my_sum

# 5. Plot the interpolating polynomial from a height of 134 cm to 178 cm
n = len(height) - 1
coeff = compute_int_coeff(n, height, fev)
x_eval = np.linspace(134, 178)
y_plt = []
for i in range(0,len(x_eval)):
polynomial = eval_int_polynomial(n, height, x_eval[i], coeff)
y_plt.append(polynomial)
plt.scatter (height, fev)
plt.xlabel("Height (cm)")
plt.ylabel("fev")
plt.plot(x_eval, y_plt, 'r')
plt.title("Interpolating Polynomial for Boys Aged 10-15")

# 6. Use the polynomial to predict the FEV for a height of 165 cm and of 175 cm.
# Which do you think is a better prediction?
print(f"Predicted fev based on height of 165 cm is {eval_int_polynomial(n, height, 165, coeff)}")
print(f"Predicted fev based on height of 175 cm is {eval_int_polynomial(n, height, 175, coeff)}")
print("********************************************************************************************************************")
print(f"The better prediciton is for 165 cm because it is on-trend with the graph, while 175 cm has a large dip in readings")

#Import libraries
import matplotlib.pyplot as plt
import numpy as np

#Plot piecewise linear interpolating polynomial and data; use data from Part 1
plt.plot(height, fev,'r')
plt.xlabel("Height")
plt.ylabel("fev")
plt.scatter(height, fev)
plt.title("Piecewise Linear Interpolating Polynomial")

# Use the piecewise polynomial to predict the FEV for a height of 165 cm and of 176 cm.
# How does this compare with 11th degree polynomial which predicted 3.104 for 165 cm and
# 2.697 for 176 cm
#The previous part asks to solve for a height of 175 cm, which resulted in a predicted fev of 3.349
print(f"The fev prediction based on a height of 165 cm is {np.interp(165, height, fev)}")
print(f"The fev prediction based on a height of 176 cm is {np.interp(176, height, fev)}")
print("*******************************************************************************************************************************")
print(f"The fev prediction from the 11th degree polynomial for 165 cm in height was 3.104 vs the result of this graph, which was 3.075")
print(f"The fev prediction from the 11th degree polynomial for 175 cm in height was 3.349 vs the result of this graph (for 176 cm), which was 3.849")