# HG changeset patch # User Jeff Hammel # Date 1409889696 25200 # Node ID 7517682843cb86d6bced5cb579233fe0d5ea32f8 # Parent 6906e5fc6dfd04eaa3460220f78c1cd7b99b87c7 CLI diff -r 6906e5fc6dfd -r 7517682843cb numerics/interpolation.py --- a/numerics/interpolation.py Thu Sep 04 20:57:10 2014 -0700 +++ b/numerics/interpolation.py Thu Sep 04 21:01:36 2014 -0700 @@ -5,7 +5,7 @@ interpolation """ -__all__ = ['neighbors', 'linear_interpolation'] +__all__ = ['neighbors', 'linear_interpolation', 'InterpolateParser'] def neighbors(start, finish): """ @@ -65,4 +65,68 @@ retval.append(ratio*data[right][1] + (1.-ratio)*data[left][1]) return retval +class InterpolateParser(argparse.ArgumentParser): + """CLI option parser""" + def __init__(self, **kwargs): + kwargs.setdefault('description', __doc__) + argparse.ArgumentParser.__init__(self, **kwargs) + self.add_argument('input', nargs='?', + type=argparse.FileType('r'), default=sys.stdin, + help='input file, or read from stdin if ommitted') + self.add_argument('-o', '--output', dest='output', + type=argparse.FileType('w'), default=sys.stdout, + help="output file, or stdout if ommitted") + self.add_argument('--points', '--print-points', dest='print_points', + action='store_true', default=False, + help="print the points to interpolate to and exit") + self.options = None + + def parse_args(self, *args, **kw): + options = argparse.ArgumentParser.parse_args(self, *args, **kw) + self.validate(options) + self.options = options + return options + + def validate(self, options): + """validate options""" + +def main(args=sys.argv[1:]): + """CLI""" + + # parse command line options + parser = InterpolateParser() + options = parser.parse_args(args) + + # read the CSV + reader = csv.reader(options.input) + data = [[float(col) for col in row] for row in reader] + ncols = set([len(row) for row in data]) + assert len(ncols) == 1 + ncols = ncols.pop() + assert ncols > 1 + + # get `x` values + data = sorted(data, key=lambda x: x[0]) + x = [row[0] for row in data] + xmin = int(x[0]) + 1 + xmax = int(x[-1]) + points = range(xmin, xmax+1) + if options.print_points: + print ('\n'.join([str(point) for point in points])) + return + + # make into x,y series + series = [[(row[0], row[col]) for row in data] + for col in range(1,ncols)] + + # interpolate + interpolated = [linear_interpolation(s, points) for s in series] + + # output interpolated data + writer = csv.writer(options.output) + for row in zip(points, *interpolated): + writer.writerow(row) + +if __name__ == '__main__': + main()