#!/usr/bin/env python3
from __future__ import print_function
import numpy as np
try:
    import pylab
except ImportError:
    pylab = None  # disable plotting


def get_stats(data):

    # simple pylab functions
    info = {
        "mean": np.mean(data),
        "q25": np.percentile(data, 25),
        "median": np.median(data),
        "q75": np.percentile(data, 75),
        "stddev": np.std(data),
    }

    # min/max
    data.sort()
    info["min"] = data[0]
    info["max"] = data[-1]

    # convert values to strings
    for key in info.keys():
        info[key] = str(info[key])
    return info


def print_table(info, labels):
    # determine field widths
    widths = {}
    for key in labels:
        widths[key] = max(len(key), len(info[key]))

    # generate a format string
    formatstr = '  '.join(['{:' + str(widths[key]) + '}' for key in labels])

    # print out the information
    print(formatstr.format(*tuple(labels)))
    print(formatstr.format(*tuple([info[key] for key in labels])))


def print_stats(info):
    print_table(info, ["min", "q25", "median", "q75", "max"])
    print_table(info, ["mean", "stddev"])


if __name__ == "__main__":
    # set up the command line parser
    import argparse
    parser = argparse.ArgumentParser(description='Calculate statistics on a' ' list of values')
    parser.add_argument('values', metavar='N', nargs='+', help='values to get statistics of')
    if pylab:
        parser.add_argument('--plot', action='store_true', help='Generate a box and whisker plot')
    args = parser.parse_args()

    # convert the data into something useful (like a list of floats)
    data = []
    for value in args.values:
        try:
            data.append(float(value))
        except ValueError:
            value = value.split(",")
            value = [float(a) for a in value if len(a) > 0]
            data.extend(value)
    print('data =', data)

    # print out the statistics
    stat_info = get_stats(data)
    print_stats(stat_info)

    # box and whisker plot
    if pylab and args.plot:
        pylab.boxplot(data)
        pylab.show()
