Flat-schmat! [was Re: Python syntax in Lisp and Scheme]

Bengt Richter bokr at oz.net
Sun Oct 5 19:41:25 EDT 2003


On Sun, 05 Oct 2003 12:27:47 GMT, Kenny Tilton <ktilton at nyc.rr.com> wrote:

>
>
>Andrew Dalke wrote:
>
>> Still have only made slight headway into learning Lisp since the
>> last discussion, so I've been staying out of this one.  But
>> 
>> Kenny Tilton:
>> 
>>>Take a look at the quadratic formula. Is that flat? Not. Of course
>>>Python allows nested math (hey, how come!), but non-mathematical
>>>computations are usually trees, too.
>> 
>> 
>> Since the quadratic formula yields two results, ...
>
>I started this analogy, didn't I? <g>
>
>I expect most
>> people write it more like
>> 
>> droot = sqrt(b*b-4*a*c)  # square root of the discriminate
>> x_plus   = (-b + droot) / (4*a*c)
>> x_minus = (-b - droot) / (4*a*c)
>
>Not?:
>
>(defun quadratic (a b c)
>   (let ((rad (sqrt (- (* b b) (* 4 a c)))))
>     (mapcar (lambda (plus-or-minus)
>               (/ (funcall plus-or-minus (- b) rad) (+ a a)))
>       '(+ -))))
>	
>:)
>
So cluttered ;-)
(and you evaluate a+a twice, why not (two-a (+ a a)) in the let ;-)

JFTHOI, a one-liner:

def quadr(a,b,c): return [op(-b, r)/d for r,d in [(sqrt(b*b-4*a*c),a+a)] for op in (add,sub)]

But that aside, don't you think the following 3 lines are more readable than your 5 above?

    def quadratic(a,b,c):
        rad = sqrt(b*b-4*a*c); den =a+a
        return (-b+rad)/den, (-b-rad)/den

(Not tested byond what you see below ;-)

====< quadratic.py >=========================================================
from operator import add,sub
from math import sqrt
def quadr(a,b,c): return [op(-b, r)/d for r,d in [(sqrt(b*b-4*a*c),a+a)] for op in (add,sub)]

def quadratic(a,b,c):
    rad = sqrt(b*b-4*a*c); den =a+a
    return (-b+rad)/den, (-b-rad)/den
    
def funs(a,b,c,q):
    def y(x): return a*x*x+b*x+c
    def invy(y): return a and q(a,b,c-y) or [(y-c)/b, None]
    return y,invy

def test():
    for q in (quadr, quadratic):
        for coeffs in [(1,2,3), (1,0,0),(0,5,0)]:
            print '\n    ff(x)=%s*x*x + %s*x + %s, and inverse is using %s:'%(coeffs+(q.__name__,))
            ff,fi = funs(*(coeffs+(q,)))
            for x in range(-3,4):
                ffx = 'ff(%s)'%x; sy='%s, '%ff(x); fiy='fi(%s)'%(ffx)
                print '%8s => %6s %11s => %s'%(ffx,sy,fiy, fi(ff(x)))

if __name__ == '__main__':
    test()
=============================================================================

test result:

[16:51] C:\pywk\clp>quadratic.py

    ff(x)=1*x*x + 2*x + 3, and inverse is using quadr:
  ff(-3) =>    6,   fi(ff(-3)) => [1.0, -3.0]
  ff(-2) =>    3,   fi(ff(-2)) => [0.0, -2.0]
  ff(-1) =>    2,   fi(ff(-1)) => [-1.0, -1.0]
   ff(0) =>    3,    fi(ff(0)) => [0.0, -2.0]
   ff(1) =>    6,    fi(ff(1)) => [1.0, -3.0]
   ff(2) =>   11,    fi(ff(2)) => [2.0, -4.0]
   ff(3) =>   18,    fi(ff(3)) => [3.0, -5.0]

    ff(x)=1*x*x + 0*x + 0, and inverse is using quadr:
  ff(-3) =>    9,   fi(ff(-3)) => [3.0, -3.0]
  ff(-2) =>    4,   fi(ff(-2)) => [2.0, -2.0]
  ff(-1) =>    1,   fi(ff(-1)) => [1.0, -1.0]
   ff(0) =>    0,    fi(ff(0)) => [0.0, 0.0]
   ff(1) =>    1,    fi(ff(1)) => [1.0, -1.0]
   ff(2) =>    4,    fi(ff(2)) => [2.0, -2.0]
   ff(3) =>    9,    fi(ff(3)) => [3.0, -3.0]

    ff(x)=0*x*x + 5*x + 0, and inverse is using quadr:
  ff(-3) =>  -15,   fi(ff(-3)) => [-3, None]
  ff(-2) =>  -10,   fi(ff(-2)) => [-2, None]
  ff(-1) =>   -5,   fi(ff(-1)) => [-1, None]
   ff(0) =>    0,    fi(ff(0)) => [0, None]
   ff(1) =>    5,    fi(ff(1)) => [1, None]
   ff(2) =>   10,    fi(ff(2)) => [2, None]
   ff(3) =>   15,    fi(ff(3)) => [3, None]

    ff(x)=1*x*x + 2*x + 3, and inverse is using quadratic:
  ff(-3) =>    6,   fi(ff(-3)) => (1.0, -3.0)
  ff(-2) =>    3,   fi(ff(-2)) => (0.0, -2.0)
  ff(-1) =>    2,   fi(ff(-1)) => (-1.0, -1.0)
   ff(0) =>    3,    fi(ff(0)) => (0.0, -2.0)
   ff(1) =>    6,    fi(ff(1)) => (1.0, -3.0)
   ff(2) =>   11,    fi(ff(2)) => (2.0, -4.0)
   ff(3) =>   18,    fi(ff(3)) => (3.0, -5.0)

    ff(x)=1*x*x + 0*x + 0, and inverse is using quadratic:
  ff(-3) =>    9,   fi(ff(-3)) => (3.0, -3.0)
  ff(-2) =>    4,   fi(ff(-2)) => (2.0, -2.0)
  ff(-1) =>    1,   fi(ff(-1)) => (1.0, -1.0)
   ff(0) =>    0,    fi(ff(0)) => (0.0, 0.0)
   ff(1) =>    1,    fi(ff(1)) => (1.0, -1.0)
   ff(2) =>    4,    fi(ff(2)) => (2.0, -2.0)
   ff(3) =>    9,    fi(ff(3)) => (3.0, -3.0)

    ff(x)=0*x*x + 5*x + 0, and inverse is using quadratic:
  ff(-3) =>  -15,   fi(ff(-3)) => [-3, None]
  ff(-2) =>  -10,   fi(ff(-2)) => [-2, None]
  ff(-1) =>   -5,   fi(ff(-1)) => [-1, None]
   ff(0) =>    0,    fi(ff(0)) => [0, None]
   ff(1) =>    5,    fi(ff(1)) => [1, None]
   ff(2) =>   10,    fi(ff(2)) => [2, None]
   ff(3) =>   15,    fi(ff(3)) => [3, None]

Regards,
Bengt Richter




More information about the Python-list mailing list