calling functions

A

anthonyberet

This is the first time I have tried out functions (is that the main way
of making subroutines in Python?)

Anyway, my function, mutate, below

#make a child string by randomly changing one character of the parent

Def mutate():
newnum=random.randrange(27)
if newnum==0:
gene=' '
else:
gene=chr(newnum+96)
position=random.randrange(len(target))
child=parent[:position-1]+gene+parent[position+1:]

mutate()


The trouble is when I later (as in further down the code) attempt to
retrieve the value of gene I get an error saying that gene is undefined.
It works fine when I don't have the routine defined as a function. - the
IF- Else structure means gene must have a value of ' ' or 'a' to 'z'.

It seems that the line:

mutate()

is not invoking the function, but why not?

Thanks again - this group is great. I despair of ever being able to
contribute though :-(
 
J

jepler

Without a 'global' statement, all variables which are assigned in the body of a
function are local to that function.

Here is an example showing that f() does not create a module-level variable,
but g() does.
... z = 3
... ... global z
... z = 3
... Traceback (most recent call last):
Traceback (most recent call last):
3

You also have a fencepost error in your slicing. You want to write
child = parent[:position] + gene + parent[position+1]
otherwise you end up including too few characters in child, and if
position is 0 you get an even more unexpected result.

However, instead of using 'global' you should just have mutate() return
the new child. Here's a version of mutate() that I wrote:
import string, random
valid = string.lowercase + " "

def mutate(parent):
position = random.randrange(len(parent))
newgene = random.choice(valid)
return parent[:position] + newgene + parent[position+1:]
My mutate() returns the new string after it is mutated, so there's no
need to use 'global'

Here, I repeatedly mutate child to give a new child:... child = mutate(child)
... print child
...
forest of grays
forqst of grays
fooqst of grays
zooqst of grays
zooqst of brays

Here, I find many mutations of parent:... child = mutate(parent)
... print child
...
foresf of grass
forestsof grass
forest ofpgrass
forest oj grass
forest cf grass

If you have a fitness function f() which returns a higher number the
more fit a string is, and you're using Python 2.4, here is some code to
order several mutations of parent according to fitness:
children = sorted((mutate(parent) for i in range(5)), key=f, reverse=True)
fittest_child = children[0]

Here's a stupid fitness function:
def f(s): return f.count(" ")

And it's fairly successful at breeding a string with lots of spaces:... children = (mutate(child) for j in range(100))
... child = sorted(children, key=f, reverse=True)[0]
... print child
...
f rest of grass
f rest of g ass
f rest yf g ass
f rest y g ass
f rest y g a s
t rest y g a s
t rest y g a
t re t y g a
t e t y g a
t e y g a

Over 10 generations, the most fit of 100 mutations is used as the basis for the
next generation.

Jeff

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)

iD8DBQFC7rk0Jd01MZaTXX0RAjrAAJ9+oThJyQqcqAUWmDet08s8dY2dzQCfdyqm
X/ln9AWpvfTHc9hgvNP8JWI=
=EyqV
-----END PGP SIGNATURE-----
 
B

bruno modulix

anthonyberet said:
This is the first time I have tried out functions (is that the main way
of making subroutines in Python?)

A function is allowed to change it's arguments and to return None, so
yes, you can consider it as a 'subroutine'.
Anyway, my function, mutate, below

#make a child string by randomly changing one character of the parent

Def mutate():
s/Def/def/

<meta>
please copy-paste code - retyping it increases the risk of typos.
newnum=random.randrange(27)
if newnum==0:
gene=' '
else:
gene=chr(newnum+96)
position=random.randrange(len(target))
child=parent[:position-1]+gene+parent[position+1:]

Where does this 'gene' come from ?-)
mutate()


The trouble is when I later (as in further down the code) attempt to
retrieve the value of gene I get an error saying that gene is undefined.

Of course it is.
It works fine when I don't have the routine defined as a function. - the
IF- Else structure means gene must have a value of ' ' or 'a' to 'z'.

This 'gene' only lives in the function body - as with almost any other
programming language.
It seems that the line:

mutate()

is not invoking the function,

It is. But this function does not return anything (well, it returns
None, which is the Python representation of exactly nothing) - and you'd
loose it if it did anyway.

<non-pythonic-explanation>
A variable created in a function is local to the function. It disappears
as soon as the function returns - unless you keep a reference to it one
way or another. The usual way to do so is to return the variable to the
caller :
</non-pythonic-explanation>


def mutate():
newnum = random.randrange(27)
if newnum == 0:
gene=' '
else:
gene = chr(newnum + 96)
return gene

gene = mutate()
# target and parent where undefined...
# please post working code
parent = "0123456789"
#position = random.randrange(len(target))
position = random.randrange(len(parent))
child=parent[:position-1]+gene+parent[position+1:]

Now you may want to check your algorithm, since it doesn't perform as
described - but this is another problem !-)

hints:
import string
string.ascii_lowercase
help(random.choice)

astring = "abcd"
alist = list(astring)
alist[0] = 'z'
astring2 = ''.join(alist)

Also note that a function can take arguments:
def fun_with_args(arg1, arg2):
print "in func_with_name : arg1 = %s - arg2 = %s" % (arg1, arg2)

fun_with_args('toto', 'titi')

so you can have the whole algorithm in the function body:

def createChild(parent):
# code here to create child
return child

parent = "0123456789"
child = createChild(parent)
print "parent : %s\nchild : %s" % (parent, child)
Thanks again - this group is great. I despair of ever being able to
contribute though :-(

You did. There would be no answer if there were no questions !-)
BTW, may I suggest you to spend some time on a good Python tutorial ?
(there are many good ones freely available on the net).

HTH
 

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

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top