essay on programming languages, computer science, information techonlogies and all.

Saturday, May 28, 2016

Fluent for educated

Recently came across a book named 'Fluent Python' and being inspired to make my python code fluent and concise.

First there is no need to read each line and parse and put to a list like below.
def LoadTrainingExamples( file, separator ) :
    examples = []
    for line in open( file ) :
        examples.append( [ float(e) for e in line.rstrip().split(separator) ] )
    return examples

>>> Examples = LoadTrainingExamples( 'faults.txt', '\t' )
You just need to call loadtxt() like below
>>> Examples = np.loadtxt( 'faults.txt' )


Next, I used array index as in implicit index for storing min, max. It is a sore to eyes but have to show you again.
>>> minmax = np.vstack( (A.min(0),A.max(0)) ); 
>>> A = Normalize( A, minmax,[-1,1] );
There is 'namedtuple' to make a C structure like class in a line.
>>> import collections
>>> Limit = collections.namedtuple( 'Limit', ['Upper','Lower']) 
>>> limits = [Limit(min(aj),max(aj)) for c in A.T]   # A.T because min, max across column vector. Also named aj instead of ai 
>>> A = Normalize( A, limits, Limit(-1,1)) 


Then Normalize function that is another pain to read.
def Normalize( A, minmax, interval ) :
    N = []
    scale = math.fabs( interval[1] - interval[0] )
    offset = interval[0]
    for i in range(A.shape[1]) :
        minv = minmax[0,i]
        maxv = minmax[1,i]
        N.append( [ (((float(a)-minv)/(maxv-minv))*scale + offset)
                    for a in A[:,i] ] )
    return np.matrix( N ).getT()
With 'Limit' namedtuple and numpy.matrix 's operator overloading of + and *, the code can be written as below.
def Normalize( A, Limits, interval ) :
    N = np.matrix([ (aj-li.Lower)/(li.Upper-li.Lower) 
        for aj,li in zip(A.T, Limits) ])                         # convert to [0:1] 
    N = N * (interval.Upper - interval.Lower) + interval.Lower   # scale and offset
    return N.getT() 

    References
  • Fluent Python, Luciano Ramalho

No comments: