Opposite of optional argument?

This is the place for queries that don't fit in any of the other categories.

Opposite of optional argument?

Postby hrs » Sat Jan 04, 2014 1:25 pm

An optional argument is when a function may use more than the positional arguments but this left to the caller. But what I want is the caller somewhere in the middle of the call chain not to know or care about the optional arguments.

I have a function that solves equations of a certain form without needing to know all about it in an attempt to keep it generic. This can be achieved by requiring all equations that need solving to specify args even if they don't use it, but I think this is a bit hacky. Is there a better way to handle this?

Code: Select all
def dif_eq1(x, y, args):
    ''' We need to specify args even if we don't use it '''
    return - 2 * y + x + 4

def dif_eq2(x, y, args):
    a, b = args
    return - 2 * y + x * a + 4 / b

def RK4(dydx, dx, x, y, args):
    ''' Arguments: (function to solve,
                    initial x value,
                    initial y value,
                    arguments required by function to solve)
        This function should not have to know what args is '''

    x = [x]
    y = [y]

    steps = 100
    h = dx / steps

    for n in xrange(steps):
        k1 = h * dydx(x[n], y[n], args)
        k2 = h * dydx(x[n] + h/2, y[n] + k1/2, args)
        k3 = h * dydx(x[n] + h/2, y[n] + k2/2, args)
        k4 = h * dydx(x[n] + h, y[n] + k3, args)

        k = (k1 + 2 * k2 + 2 * k3 + k4) / 6

        x.append(x[n] + h)
        y.append(y[n] + k)

    return x, y

''' Here we do need to know what args is '''
x1, y1 = RK4(dif_eq1, 2., 0, 1, None)
x2, y2 = RK4(dif_eq2, 2.5, 0, 1, (2, 3))
hrs
 
Posts: 86
Joined: Thu Feb 07, 2013 9:26 pm

Re: Opposite of optional argument?

Postby metulburr » Sat Jan 04, 2014 1:42 pm

But what I want is the caller somewhere in the middle of the call chain not to know or care about the optional arguments.

the optional args are called keyword arguments

the order that they must appear in a func call/header:
positional args (value), keyword args (key=value), *sequnece form, followed by **dict form

You cannot re-arrange this order. If there are positional args, they must appear first, if there are postiitonal args, keyword args must appear after all the positional args, etc.

EDIT:
after re-reading, the above ^ has nothing to do with the question. Leaving it though for completeness

This can be achieved by requiring all equations that need solving to specify args even if they don't use it, but I think this is a bit hacky. Is there a better way to handle this?

the only other way is to set args to a keyword arg:
Code: Select all
...
def RK4(dydx, dx, x, y, args=None):
...

and call it with args only when you need args
Code: Select all
...
x1, y1 = RK4(dif_eq1, 2., 0, 1)
x2, y2 = RK4(dif_eq2, 2.5, 0, 1, (2, 3))
...

However i think a class would better organize this code, so your not passing around x, y , or args
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1313
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: Opposite of optional argument?

Postby hrs » Sat Jan 04, 2014 2:13 pm

metulburr wrote:the only other way is to set args to a keyword arg:
Code: Select all
...
def RK4(dydx, dx, x, y, args=None):
...

and call it with args only when you need args
Code: Select all
...
x1, y1 = RK4(dif_eq1, 2., 0, 1)
x2, y2 = RK4(dif_eq2, 2.5, 0, 1, (2, 3))
...

Ah, yes, that's better thanks. However, it doesn't allow me to write
Code: Select all
def dif_eq1(x, y):
    return - 2 * y + x + 4

def dif_eq2(x, y, args):
    a, b = args
    return - 2 * y + x * a + 4 / b

and I still need to put a dummy argument in dif_eq1 which is the part that's bothering me.
hrs
 
Posts: 86
Joined: Thu Feb 07, 2013 9:26 pm

Re: Opposite of optional argument?

Postby metulburr » Sat Jan 04, 2014 2:36 pm

you cant remove an argument from a function and then call that function with that argument that you just removed.
Code: Select all
...
    for n in xrange(steps):
        if args:
            k1 = h * dydx(x[n], y[n], args)
            k2 = h * dydx(x[n] + h/2, y[n] + k1/2, args)
            k3 = h * dydx(x[n] + h/2, y[n] + k2/2, args)
            k4 = h * dydx(x[n] + h, y[n] + k3, args)
        else:
            k1 = h * dydx(x[n], y[n])
            k2 = h * dydx(x[n] + h/2, y[n] + k1/2)
            k3 = h * dydx(x[n] + h/2, y[n] + k2/2)
            k4 = h * dydx(x[n] + h, y[n] + k3)
...


I still think though that a class would clean this code up. Make it easier to read, write, and maintain later on. Plus your non-meaningful variable names makes it hard to read.
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1313
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: Opposite of optional argument?

Postby hrs » Sat Jan 04, 2014 3:52 pm

Yes, later figured too to just check args and pass it or not depending on the test result, but I don't think the code duplication is worth it.
I still think though that a class would clean this code up.

I will consider this option and see if I can do it in a way that makes sense.
Plus your non-meaningful variable names makes it hard to read.

Yes you are right, but these are the typical variable names you see everywhere in Runge-Kutta descriptions and implementations and I'm not sure what else to call them. This is only for a first order differential equation, for a second order DE it's even worse ...

Anyway, thanks for your help. I have some options to consider now.
hrs
 
Posts: 86
Joined: Thu Feb 07, 2013 9:26 pm


Return to General Coding Help

Who is online

Users browsing this forum: No registered users and 4 guests