#!/usr/bin/env python

import numpy as np
import timeit

def line2array0(line, field_len):
    nums = []
    i = 0
    while i < len(line):
        nums.append(float(line[i:i+field_len]))
        i += field_len
    return np.array(nums)

def line2array1(line, field_len):
    return np.array(map(float, [line[i*field_len:(i+1)*field_len] for i in range(len(line)/field_len)]))

def line2array2(line, field_len):
    return np.array(tuple(line), dtype = 'S1').view(dtype='S%i'%field_len).astype(np.float)

def line2array3(line, field_len):
    return np.array((line,)).view(dtype='S%i'%field_len).astype(np.float)

def line2array4(line, field_len):
    return np.array(line, dtype='c').view(dtype='S%i'%field_len).astype(np.float)

def line2array5(line, field_len):
    return np.fromstring(line, dtype='c').view(dtype='S%i'%field_len).astype(np.float)



def build_test_line(num_fields):
    import random
    line  = []
    for i in range(num_fields):
        num = random.uniform(-1e10, 1e10)
        s = "%13.7g"%num
        if len(s) != 13:
            print "error", num, s
        line.append(s)
    return "".join(line)

line = build_test_line(100)

## assume the first method is correct!
solution = line2array1(line, field_len=13)
for i, f in enumerate([line2array0,
                       line2array1,
                       line2array2,
                       line2array3,
                       line2array4,
                       line2array5,
                       ]):
    print "testing method:", i
    if any(f(line, field_len=13) != solution):
        print "***\nError in method %i\n***"%i 
           
setup = """import numpy as np
field_len = 13
line = "-1.000000E+00-1.000000E+00-1.000000E+00-1.000000E+00 1.250000E+00 1.250000E+00-1.000000E+00-1.000000E+00-1.000000E+00-1.000000E+00 1.250000E+00 1.250000E+00-1.000000E+00-1.000000E+00-1.000000E+00-1.000000E+00 1.250000E+00 1.250000E+00-1.000000E+00-1.000000E+00-1.000000E+00-1.000000E+00 1.250000E+00 1.250000E+00-1.000000E+00-1.000000E+00-1.000000E+00-1.000000E+00 1.250000E+00 1.250000E+00-1.000000E+00-1.000000E+00-1.000000E+00-1.000000E+00 1.250000E+00 1.250000E+00-1.000000E+00-1.000000E+00-1.000000E+00-1.000000E+00 1.250000E+00 1.250000E+00-1.000000E+00-1.000000E+00-1.000000E+00-1.000000E+00 1.250000E+00 1.250000E+00-1.000000E+00-1.000000E+00-1.000000E+00-1.000000E+00 1.250000E+00 1.250000E+00-1.000000E+00-1.000000E+00-1.000000E+00-1.000000E+00 1.250000E+00 1.250000E+00-1.000000E+00-1.000000E+00-1.000000E+00-1.000000E+00 1.250000E+00 1.250000E+00"
"""
                      
print "Timing:"

print "List comp:", timeit.Timer("np.array(map(float, [line[i*field_len:(i+1)*field_len] for i in range(len(line)/field_len)]))",
                              setup ).timeit()

print "convert to tuple:", timeit.Timer("np.array(tuple(line), dtype = 'S1').view(dtype='S%i'%field_len).astype(np.float)",
                                 setup ).timeit()

print "auto convert:", timeit.Timer("np.array((line,)).view(dtype='S%i'%field_len).astype(np.float)",
                                 setup ).timeit()

print "char type:", timeit.Timer("np.array(line, dtype='c').view(dtype='S%i'%field_len).astype(np.float)",
                                 setup ).timeit()

print "fromstring:", timeit.Timer("np.fromstring(line, dtype='c').view(dtype='S%i'%field_len).astype(np.float)",
                                  setup ).timeit()

print "without float conversion:", timeit.Timer("np.fromstring(line, dtype='c').view(dtype='S%i'%field_len)",
                                                setup ).timeit()



