number of arguments a function takes

Discussion in 'Python' started by Elaine Jackson, Jan 29, 2004.

  1. Suppose one of the arguments of a function f_1 is another function f_2. Can f_1
    access the number of arguments taken by f_2? (I'm writing a little script to
    automate the construction of logical truth-tables.) Thanks.

    Peace
     
    Elaine Jackson, Jan 29, 2004
    #1
    1. Advertising

  2. Elaine Jackson

    Aahz Guest

    In article <CSaSb.329909$ts4.189798@pd7tw3no>,
    Elaine Jackson <> wrote:
    >
    >Suppose one of the arguments of a function f_1 is another function
    >f_2. Can f_1 access the number of arguments taken by f_2? (I'm writing
    >a little script to automate the construction of logical truth-tables.)


    In theory, yes (because of Python's introspection capabilities). In
    practice, you're likely to want to choose a different mechanism that
    doesn't require that information. If you tell us more about your actual
    problem, we may be able to point you in a better direction.
    --
    Aahz () <*> http://www.pythoncraft.com/

    "The joy of coding Python should be in seeing short, concise, readable
    classes that express a lot of action in a small amount of clear code --
    not in reams of trivial code that bores the reader to death." --GvR
     
    Aahz, Jan 29, 2004
    #2
    1. Advertising

  3. Elaine Jackson

    Duncan Booth Guest

    "Elaine Jackson" <> wrote in
    news:CSaSb.329909$ts4.189798@pd7tw3no:

    > Suppose one of the arguments of a function f_1 is another function
    > f_2. Can f_1 access the number of arguments taken by f_2? (I'm
    > writing a little script to automate the construction of logical
    > truth-tables.) Thanks.


    Look at the inspect module, in particular you probably want
    inspect.getargspec:

    >>> import inspect
    >>> def f(a,b): pass


    >>> inspect.getargspec(f)

    (['a', 'b'], None, None, None)
    >>> help(inspect.getargspec)

    Help on function getargspec in module inspect:

    getargspec(func)
    Get the names and default values of a function's arguments.

    A tuple of four things is returned: (args, varargs, varkw, defaults).
    'args' is a list of the argument names (it may contain nested lists).
    'varargs' and 'varkw' are the names of the * and ** arguments or None.
    'defaults' is an n-tuple of the default values of the last n arguments.

    >>>
     
    Duncan Booth, Jan 29, 2004
    #3
  4. Exactly what I was looking for. Thank you very much.

    "Duncan Booth" <> wrote in message
    news:Xns947FAE6461014duncanrcpcouk@127.0.0.1...
    | "Elaine Jackson" <> wrote in
    | news:CSaSb.329909$ts4.189798@pd7tw3no:
    |
    | > Suppose one of the arguments of a function f_1 is another function
    | > f_2. Can f_1 access the number of arguments taken by f_2? (I'm
    | > writing a little script to automate the construction of logical
    | > truth-tables.) Thanks.
    |
    | Look at the inspect module, in particular you probably want
    | inspect.getargspec:
    |
    | >>> import inspect
    | >>> def f(a,b): pass
    |
    | >>> inspect.getargspec(f)
    | (['a', 'b'], None, None, None)
    | >>> help(inspect.getargspec)
    | Help on function getargspec in module inspect:
    |
    | getargspec(func)
    | Get the names and default values of a function's arguments.
    |
    | A tuple of four things is returned: (args, varargs, varkw, defaults).
    | 'args' is a list of the argument names (it may contain nested lists).
    | 'varargs' and 'varkw' are the names of the * and ** arguments or None.
    | 'defaults' is an n-tuple of the default values of the last n arguments.
    |
    | >>>
     
    Elaine Jackson, Jan 29, 2004
    #4
  5. "Elaine Jackson" <> wrote in message news:<YVbSb.319671$JQ1.192347@pd7tw1no>...
    > Exactly what I was looking for. Thank you very much.
    >
    > "Duncan Booth" <> wrote in message
    > news:Xns947FAE6461014duncanrcpcouk@127.0.0.1...
    > | "Elaine Jackson" <> wrote in
    > | news:CSaSb.329909$ts4.189798@pd7tw3no:
    > |
    > | > Suppose one of the arguments of a function f_1 is another function
    > | > f_2. Can f_1 access the number of arguments taken by f_2? (I'm
    > | > writing a little script to automate the construction of logical
    > | > truth-tables.) Thanks.
    > |
    > | Look at the inspect module, in particular you probably want
    > | inspect.getargspec:
    > |
    > | >>> import inspect
    > | >>> def f(a,b): pass
    >
    > | >>> inspect.getargspec(f)
    > (['a', 'b'], None, None, None)
    > | >>> help(inspect.getargspec)
    > | Help on function getargspec in module inspect:
    > |
    > | getargspec(func)
    > | Get the names and default values of a function's arguments.
    > |
    > | A tuple of four things is returned: (args, varargs, varkw, defaults).
    > | 'args' is a list of the argument names (it may contain nested lists).
    > | 'varargs' and 'varkw' are the names of the * and ** arguments or None.
    > | 'defaults' is an n-tuple of the default values of the last n arguments.
    > |
    > | >>>


    So you're working on a truth table program? I have a truth table
    object I did for my own application, more focused on finding
    input/output transitions in arbitrary truth tables, but if you're
    interested, let me know. Regardless, are you working on something
    that will ultimately become public? If so, be sure to announce it
    when you're done, I'd love to have a look. Especially if you're doing
    anything with functional simplification, my object can return a simple
    SOP function for a table (reducing out unused inputs is also an
    option) but they can get kind of lengthy for complicated functions.
    And if you need any other help, be sure to let me know!
     
    Corey Coughlin, Jan 30, 2004
    #5
  6. I think you're expectations of this are a little high. It's just something I did
    for amusement while I was drinking my coffee this morning. Anyway, here it is.
    And yes, I'd be very interested to see your code.

    Peace (code follows)

    NEG = lambda A: not A
    CONJ = lambda *args: False not in args
    DISJ = lambda *args: True in args
    IMPL = lambda A,B: (not A) or B
    EQUIV = lambda A,B: (A and B) or (not A and not B)

    def truthTable(boolFunct):
    assignmentList = lambda numArgs: (numArgs==0 and [[]]) or \
    reduce(list.__add__,[[X+[False],X+[True]] for X in
    assignmentList(numArgs-1)])
    import inspect
    numArgs=len(inspect.getargspec(boolFunct)[0])
    for assignment in assignmentList(numArgs):
    print assignment," : ",boolFunct(*assignment)

    ## EXAMPLE:
    f = lambda x,y,z: DISJ(CONJ(x,y),NEG(z))
    truthTable(f)


    "Corey Coughlin" <> wrote in message
    news:...
    | "Elaine Jackson" <> wrote in message
    news:<YVbSb.319671$JQ1.192347@pd7tw1no>...
    | > Exactly what I was looking for. Thank you very much.
    | >
    | > "Duncan Booth" <> wrote in message
    | > news:Xns947FAE6461014duncanrcpcouk@127.0.0.1...
    | > | "Elaine Jackson" <> wrote in
    | > | news:CSaSb.329909$ts4.189798@pd7tw3no:
    | > |
    | > | > Suppose one of the arguments of a function f_1 is another function
    | > | > f_2. Can f_1 access the number of arguments taken by f_2? (I'm
    | > | > writing a little script to automate the construction of logical
    | > | > truth-tables.) Thanks.
    | > |
    | > | Look at the inspect module, in particular you probably want
    | > | inspect.getargspec:
    | > |
    | > | >>> import inspect
    | > | >>> def f(a,b): pass
    | >
    | > | >>> inspect.getargspec(f)
    | > (['a', 'b'], None, None, None)
    | > | >>> help(inspect.getargspec)
    | > | Help on function getargspec in module inspect:
    | > |
    | > | getargspec(func)
    | > | Get the names and default values of a function's arguments.
    | > |
    | > | A tuple of four things is returned: (args, varargs, varkw, defaults).
    | > | 'args' is a list of the argument names (it may contain nested lists).
    | > | 'varargs' and 'varkw' are the names of the * and ** arguments or None.
    | > | 'defaults' is an n-tuple of the default values of the last n
    arguments.
    | > |
    | > | >>>
    |
    | So you're working on a truth table program? I have a truth table
    | object I did for my own application, more focused on finding
    | input/output transitions in arbitrary truth tables, but if you're
    | interested, let me know. Regardless, are you working on something
    | that will ultimately become public? If so, be sure to announce it
    | when you're done, I'd love to have a look. Especially if you're doing
    | anything with functional simplification, my object can return a simple
    | SOP function for a table (reducing out unused inputs is also an
    | option) but they can get kind of lengthy for complicated functions.
    | And if you need any other help, be sure to let me know!
     
    Elaine Jackson, Jan 30, 2004
    #6
  7. OK, here's my object. Basically, you set up a truth table with the
    input and output pins, then you can add values to it usings
    dictionaries of the form { 'pin name': 0 or 1......} to represent each
    state. The point here is more to deduce the boolean functions of a
    table from data observed from black box boolean functions, very useful
    for my job in semiconductors. Keep in mind that I wasn't exactly
    trained in software, so my code is usually a little rough and brute
    force, which keeps it from being less elegant, but easy to understand.
    Anyway, if you have any questions, feel free to ask.

    class TruthTable(object):
    def __init__(self,iinputs= [], ioutputs=[]):
    self.ttab = {}
    self.inpindex = {}
    self.vcount = 0
    if iinputs and ioutputs:
    self.vcount = 2 ** len(iinputs)
    i = 1
    for input in iinputs:
    self.inpindex[input] = i
    i = i * 2
    for output in ioutputs:
    self.ttab[output] = [ None ] * self.vcount
    def reducetable(self):
    newinputs = []
    onegone = False
    for ipin in self.inpindex.keys():
    iused = False
    for opin in self.ttab.keys():
    iused = iused or self.findtransitions(ipin, opin)
    if iused:
    newinputs.append(ipin)
    else:
    onegone = True
    if not onegone:
    return None
    i = 1
    newindex = {}
    newttab = {}
    newcount = 2 ** len(newinputs)
    for ipin in newinputs:
    newindex[ipin] = i
    i = i * 2
    for opin in self.ttab.keys():
    newttab[opin] = [None] * newcount
    for i in range(newcount):
    curristate = {}
    for ipin, bplace in newindex.items():
    curristate[ipin] = ( i & bplace ) / bplace
    for j in range(self.vcount):
    oldstate = self.vec2output(j)
    matched = True
    for ipin in curristate:
    matched = matched and curristate[ipin] ==
    oldstate[ipin]
    if matched:
    for opin in newttab:
    newttab[opin] = oldstate[opin]
    self.ttab = newttab
    self.inpindex = newindex
    self.vcount = newcount
    def addvalues(self, ttentry):
    index = 0
    foundall = True
    for ipin in self.inpindex:
    if ipin not in ttentry:
    raise KeyError, 'Pin %s not in %s' % (ipin, ttentry)
    else:
    index = index + ttentry[ipin] * self.inpindex[ipin]
    for pin, value in ttentry.items():
    if pin in self.ttab:
    self.ttab[pin][index] = value
    def deloutput(self, outname):
    if self.ttab.has_key(outname):
    del self.ttab[outname]
    def vec2output(self, vec):
    outent = {}
    for input, binplace in self.inpindex.items():
    outent[input] = ( vec & binplace) / binplace
    for output, outvals in self.ttab.items():
    outent[output] = outvals[vec]
    return outent
    def getvalue(self, inpstate, opin):
    if opin not in self.ttab:
    raise IndexError, 'Incorrect output pin %s used in
    getvalue.' % opin
    stindex = 0
    for ipin in self.inpindex:
    if ipin not in inpstate:
    raise KeyError, 'Pin %s cannot be found in inpstate
    %s' % (ipin, inpstate)
    stindex = stindex + self.inpindex[ipin] * inpstate[ipin]
    return self.ttab[opin][stindex]
    def __str__(self):
    outs = ''
    allpins = self.inpindex.keys() + self.ttab.keys()
    maxname = 0
    for pin in allpins:
    if len(pin) > maxname:
    maxname = len(pin)
    if maxname < 5:
    maxname = 5
    indicies = self.inpindex.values()
    indicies.sort()
    indicies.reverse()
    indtoinp = {}
    inputs = []
    for input, index in self.inpindex.items():
    indtoinp[index] = input
    for i in indicies:
    outs = outs + '%s ' % stringfill(indtoinp, maxname)
    inputs.append(indtoinp)
    outs = outs + '| '
    outputs = self.ttab.keys()
    outputs.sort()
    for out in outputs:
    outs = outs + '%s ' % stringfill(out, maxname)
    outs = outs + '\n'
    for i in range(self.vcount):
    currvec = self.vec2output(i)
    for inp in inputs:
    outs = outs + '%s ' % stringfill(str(currvec[inp]),
    maxname)
    outs = outs + '| '
    for out in outputs:
    outs = outs + '%s ' % stringfill(str(currvec[out]),
    maxname)
    outs = outs + '\n'
    return outs
    def findtransitions(self, ipin, opin):
    indicies = range(self.vcount)
    binplace = self.inpindex[ipin]
    zerobits = filter(lambda x: x & binplace == 0, indicies)
    possibles = map(lambda x: ( x, x + binplace ), zerobits)
    foundtrans = []
    for lowbit, highbit in possibles:
    ovec = self.ttab[opin]
    if (ovec[lowbit] != ovec[highbit] and ovec[lowbit] in
    [0,1] and
    ovec[highbit] in [0,1]):
    foundtrans.append( (lowbit, highbit) )
    foundtrans = map(lambda x: ( self.vec2output(x[0]),
    self.vec2output(x[1]) ),
    foundtrans)
    return foundtrans
    def getoutfunc2(self, opin, notxwhens = []):
    if opin not in self.ttab:
    return '',''
    relpins = []
    for ipin in self.inpindex.keys():
    tranpairs = self.alltransitions(ipin)
    for lowst, highst in tranpairs:
    if lowst[opin] != highst[opin] and ipin not in
    relpins:
    relpins.append(ipin)
    if relpins == []:
    return '',''
    outhighs = []
    outx = []
    allone = True
    for vec in range(self.vcount):
    pvec = self.vec2output(vec)
    if pvec[opin] in [1, 'X']:
    saveout = pvec[opin]
    for pin in pvec.keys():
    a = pin in self.ttab
    b = pin not in relpins
    if a or b:
    del pvec[pin]
    if len(pvec) > 0:
    allone = False
    if saveout == 1 and pvec not in outhighs:
    outhighs.append(pvec)
    if saveout == 'X' and pvec not in outx:
    outx.append(pvec)
    outfunc = ''
    xfunc = ''
    if allone:
    return '1',''
    for cwhen in outhighs:
    pstring = WhenString(cwhen)
    if outfunc == '':
    outfunc = '(%s)' % pstring
    else:
    outfunc = '%s|(%s)' % (outfunc, pstring)
    if notxwhens:
    print 'finding badxwhens'
    badxwhens = []
    for cwhen in outx:
    for subwhen in notxwhens:
    if DictIn(cwhen,subwhen):
    badxwhens.append(cwhen)
    break
    for bwhen in badxwhens:
    outx.remove(bwhen)
    for cwhen in outx:
    pstring = WhenString(cwhen)
    if xfunc == '':
    xfunc = '(%s)' % pstring
    else:
    xfunc = '%s|(%s)' % (xfunc, pstring)
    return outfunc, xfunc
    def alltransitions(self, ipin):
    indicies = range(self.vcount)
    binplace = self.inpindex[ipin]
    zerobits = filter(lambda x: x & binplace == 0, indicies)
    possibles = map(lambda x: ( x, x + binplace ), zerobits)
    foundtrans = []
    foundtrans = map(lambda x: ( self.vec2output(x[0]),
    self.vec2output(x[1]) ),
    possibles)
    return foundtrans
    def getinputs(self):
    return self.inpindex.keys()
    def getoutputs(self):
    return self.ttab.keys()
    def __len__(self):
    return self.vcount

    Oh, and a function called WhenString is also called, here's that:

    def WhenString(statein):
    pstring = ''
    pinlist = statein.keys()
    pinlist.sort()
    for pin in pinlist:
    if pstring != '':
    pstring = '%s&' % pstring
    if statein[pin] == 0:
    pstring = '%s!' % pstring
    if statein[pin] in [0, 1]:
    pstring = '%s%s' % (pstring, pin)
    if pstring and pstring[-1] in ['&', '!']:
    pstring = pstring[:-1]
    return pstring

    I took out some comments and a couple of differential specific
    functions to clear things up, and it's a little cluttered up with code
    to check for 'X' states, but that's it. Let me know what you think.
    :)
     
    Corey Coughlin, Jan 30, 2004
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Neo
    Replies:
    10
    Views:
    674
    sushant
    Jan 20, 2005
  2. jmborr
    Replies:
    1
    Views:
    427
    Stargaming
    Nov 3, 2007
  3. sniffer
    Replies:
    4
    Views:
    322
    Lie Ryan
    Dec 8, 2008
  4. Replies:
    3
    Views:
    836
  5. oldyork90
    Replies:
    10
    Views:
    350
    Jorge
    Sep 27, 2008
Loading...

Share This Page