scalar vs array and program control

Steven D'Aprano steve at pearwood.info
Sun Jul 26 06:03:06 CEST 2015


On Sat, 25 Jul 2015 02:18 pm, Seb wrote:

> Hello,
> 
> I'm fairly new to Python, struggling to write in a more object-oriented,
> functional style.  I just wrote a function that takes two arrays 
> representing sine (y) and cosine (x) angle coordinates, and returns the
> angle in degrees.

Alas, your description is not entirely clear. I think you mean you take the
rectangular coordinates x and y, and return the angle of the line from the
origin to the point (x, y) in degrees. E.g. given x = y = 1, return 45.

Try this:

def angle_deg(x, y):
    return np.rad2deg(np.arctan(y/x))


And in action, it works with both scalars and arrays.

py> angle_deg(1, 2)
63.43494882292201

py> angle_deg(np.array([1, 2, 3, 4]), np.array([1, 3, 2, 0]))
array([ 45.        ,  56.30993247,  33.69006753,   0.        ])


An alternative would be this:


def angle_deg2(x, y):
    return np.rad2deg(np.arctan2(y, x))

py> angle_deg2(np.array([1, 2, 3, 4]), np.array([1, 3, 2, 0]))
array([ 45.        ,  56.30993247,  33.69006753,   0.        ])


There may be differences in results for points not in the first quadrant.

If you're only using numpy functions, or (most) operators like + - * etc,
they already work on both scalars and numpy arrays. If you write your own
functions using only those things, your functions will gain the same
ability. But if you find yourself needing to use functions which numpy
doesn't provide, you can emulate a similar style like this:


from number import Number

def my_function(arg):
    if isinstance(arg, Number):
        # code treating arg as a scalar
    else:
        # assume arg is a vector
        for x in arg:
            # code treating x as a scalar



You'll probably find duplicated code. You can remove that duplicated code
this way:


# note the leading underscore; that is the Python convention for "Private"
def _my_function(x):
    if isinstance(x, Number):
        # code treating x as a scalar
    else:
        raise TypeError("expected a number, got %s" % type(x).__name__)


def my_function(arg):
    if isinstance(arg, Number):
        return _my_function(arg)
    else:
        for x in arg:
            y = _my_function(x)
            # stick y in some sort of array
        # return the array of y values



-- 
Steven



More information about the Python-list mailing list