number of arguments a function takes

E

Elaine Jackson

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
 
A

Aahz

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 ([email protected]) <*> 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
 
D

Duncan Booth

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.
 
E

Elaine Jackson

Exactly what I was looking for. Thank you very much.

| |
| > 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.
|
| >>>
 
C

Corey Coughlin

Elaine Jackson said:
Exactly what I was looking for. Thank you very much.

| |
| > 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!
 
E

Elaine Jackson

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)


| > Exactly what I was looking for. Thank you very much.
| >
| > | > | | > |
| > | > 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!
 
C

Corey Coughlin

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.
:)
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,176
Messages
2,570,947
Members
47,501
Latest member
Ledmyplace

Latest Threads

Top