# At this point, we’ve written code to draw some interesting features in our
# inflammation data, loop over all our data files to quickly draw these plots for
# each of them, and have Python make decisions based on what it sees in our data.
# But, our code is getting pretty long and complicated; what if we had thousands
# of datasets, and didn’t want to generate a figure for every single one?
# Commenting out the figure-drawing code is a nuisance. Also, what if we want to
# use that code again, on a different dataset or at a different point in our
# program? Cutting and pasting it is going to make our code get very long and very
# repetitive, very quickly. We’d like a way to package our code so that it is
# easier to reuse, and Python provides for this by letting us define things called
# ‘functions’ — a shorthand way of re-executing longer pieces of code. Let’s start
# by defining a function fahr_to_celsius that converts temperatures from
# Fahrenheit to Celsius:
import glob
import numpy


def fahr_to_celsius(temp):
    return ((temp-32)*(5/9))


print('freezing point of water:', fahr_to_celsius(32), 'C')
print('boiling point of water:', fahr_to_celsius(212), 'C')

# celsius to kelvin


def celsius_to_kelvin(temp_c):
    return temp_c + 273.15


print('freezing point of water in Kelvin:', celsius_to_kelvin(0.))

# what about fahr to kelvin, could rewrite but instead:


def fahr_to_kelvin(temp_f):
    temp_c = fahr_to_celsius(temp_f)
    temp_k = celsius_to_kelvin(temp_c)
    return temp_k


print('boiling point of water in Kelvin:', fahr_to_kelvin(212.0))


def print_temperatures():
    print('temperature in Fahrenheit was:', temp_fahr)
    print('temperature in Kelvin was:', temp_kelvin)


temp_fahr = 212.0
temp_kelvin = fahr_to_kelvin(temp_fahr)

print_temperatures()

# tidying up prev analysis scripts


def visualize(filename):

    data = numpy.loadtxt(fname=filename, delimiter=',')

    fig = matplotlib.pyplot.figure(figsize=(10.0, 3.0))

    axes1 = fig.add_subplot(1, 3, 1)
    axes2 = fig.add_subplot(1, 3, 2)
    axes3 = fig.add_subplot(1, 3, 3)

    axes1.set_ylabel('average')
    axes1.plot(numpy.mean(data, axis=0))

    axes2.set_ylabel('max')
    axes2.plot(numpy.max(data, axis=0))

    axes3.set_ylabel('min')
    axes3.plot(numpy.min(data, axis=0))

    fig.tight_layout()
    matplotlib.pyplot.show()


def detect_problems(filename):

    data = numpy.loadtxt(fname=filename, delimiter=',')

    if numpy.max(data, axis=0)[0] == 0 and numpy.max(data, axis=0)[20] == 20:
        print('Suspicious looking maxima!')
    elif numpy.sum(numpy.min(data, axis=0)) == 0:
        print('Minima add up to zero!')
    else:
        print('Seems OK!')  # dont need return in some fx


filenames = sorted(glob.glob('inflammation*.csv'))

for filename in filenames[:3]:
    print(filename)
    visualize(filename)
    detect_problems(filename)

# Once we start putting things in functions so that we can re-use them, we need to
# start testing that those functions are working correctly. To see how to do this,
# let’s write a function to offset a dataset so that it’s mean value shifts to a
# user-defined value:


def offset_mean(data, target_mean_value):
    return (data-numpy.mean(data)) + target_mean_value


data = numpy.loadtxt(fname='inflammation-01.csv', delimiter=',')
print(offset_mean(data, 0))

# to check
print('original min, mean, and max are:', numpy.min(data), numpy.mean(data), numpy.max(data))
offset_data = offset_mean(data, 0)
print('min, mean, and max of offset data are:',
      numpy.min(offset_data),
      numpy.mean(offset_data),
      numpy.max(offset_data))

print('std dev before and after:', numpy.std(data), numpy.std(offset_data))

# to better document a function,  If the first thing in a function is a string that isn’t
# assigned to a variable, that string is attached to the function as its documentation:


def offset_mean(data, target_mean_value):  # triple strings allows for multiline string
    """Return a new array containing the original data
       with its mean offset to match the desired value.

    Examples
    --------
    >>> offset_mean([1, 2, 3], 0)
    array([-1.,  0.,  1.])
    """
    return (data - numpy.mean(data)) + target_mean_value


help(offset_mean)

# adding taget_mean_value=0.0 for ex makes it the default value for that funx

# if we usually want a function to work one way, but occasionally need it to do
# something else, we can allow people to pass a parameter when they need to but
# provide a default to make the normal case easier. The example below shows how
# Python matches values to parameters:
