3

I'm fairly new to programming and I've been working with Python for a few months now. I'm trying to get a concept to work with Stackless, but just can't figure out how (though I've written other test scripts that work with Stackless).

Anywho, as a boiled down example consider the following code that runs through a list and finds all permutations (edit: n-dimensional cartesian products) of it by calling the same function recursively.

def traverseList(theList,temp,solutions,level=1):
    if level != len(theList):
        for x in theList:
            temp.append(x)
            traverseList(theList,temp,solutions,level+1)
            temp.pop()
    else:
        for x in theList:
            temp.append(x)
            solutions.append(temp[:])
            temp.pop()

myList = ["a",None,2,"gamma",8] #the list doesn't always have just numbers
solutionList = []
tempList = []

traverseList(myList,tempList,solutionList)
print("%s... %s" %(solutionList[0], solutionList[-1]))

which yields:

['a', 'a', 'a', 'a', 'a']... [8, 8, 8, 8, 8]

So far it seems that the only examples I find with Stackless and recursion have the function sending information out at the end of the function after it's all done. Never in the middle of a for loop, as would be necessary in the above.

How the heck would I do this? How would I turn this into a script that would run with tasklets rather than recursive functions? (This version is the best I can come up with, but it fails no matter how I arrange it. This is one of many tries, I may as well throw spaghetti up against a wall at this point.)

Bonus e-cookie for a way to do it without a bounceBack function - I haven't yet been able to find a way to have a single tasklet pass information to itself multiple times without one.

Thanks for your time!

Mike Pennington
  • 41,899
  • 19
  • 136
  • 174
squid808
  • 1,430
  • 2
  • 14
  • 31
  • 2
    I know literally nothing about Stackless Python, but I feel I should make a couple of minor notes. First, I'd advise against using `main` as a variable name. Second, this doesn't compute permutations, it computes the n-dimensional cartesian product of an n-element list. (There are only 120 permutations of a 5-element list.) Third, [recursion](http://en.wikipedia.org/wiki/Recursion_(computer_science)) and [concurrency](http://en.wikipedia.org/wiki/Concurrency_(computer_science)) are not at all the same. Sorry I can't help with the main problem you're having! – senderle Jun 10 '11 at 03:44
  • 1
    For using 'main', that makes sense, I'll keep it in mind. As to the cartesian product... I can't promise I'll remember the word, but I'll try to remember the difference. Same for the differences between recursion and concurrency. It's tough to get all the words right when teaching one's self, but I'll do my best. Thanks! – squid808 Jun 10 '11 at 12:13

2 Answers2

1

I think you want to research "generators" (i.e. "yield" python keyword). Basically a generator lets you pause in the middle of a function call and sort of return the result. When the function is "called" again it resumes at the line just after the "yield". When you finally "return" you are done.

Here's some example code for you:

def myGen(*x):
  for elem in x:
    print "in myGen"
    yield elem

def myFn(*x):
  ret = []
  for elem in x:
    print "in myFn"
    ret.append(x)
  return x


for e in myGen(1,2,3,4,5):
  print e

for e in myFn(1,2,3,4,5):
  print e

The output is below. Notice in the generator case (myGen), the "in myGen" is printed alternating with the print of the list. But in the myFn of course "in myFn" is printed out first.

in myGen
1
in myGen
2
in myGen
3
in myGen
4
in myGen
5
in myFn
in myFn
in myFn
in myFn
in myFn
1
2
3
4
5
AndrewStone
  • 517
  • 4
  • 14
  • I've used generators and yields, but I don't see how this would help me. Yes, a generator can pause after a yield until called again, but that would be part of the problem. In order for Stackless to call on the same tasklet again, the tasklet needs to be in a free and listening position. The generator would just be paused, and not really accepting new input. – squid808 Jun 21 '11 at 14:43
0

If I've understood your question right and since you already have your method in place, plugging this in would work

import stackless as s
channel = s.channel()
s.tasklet(traverseList)(myList,tempList,solutionList)
s.run()
print("%s... %s" %(solutionList[0], solutionList[-1]))

Alternatively you could use *args / **kwargs in the parameters list to the tasklet

techiev2
  • 298
  • 1
  • 8