[Tutor] Question about calling functions

Alan Gauld alan.gauld at btinternet.com
Mon Aug 27 01:57:46 CEST 2007


"Ara Kooser" <ghashsnaga at gmail.com> wrote

> a character works except for one part. You have a choice of 
> excepting
> a set of numbers. If you choose n then the program dumps you into:
> def navy() instead of going back to def upp().
>
> print upp()
> print """You have a chance to reroll if needed."""
> reroll()
> navy()

When you exit reroll() you always go into navy()

> I see that after reroll() it goes to navy(). What I don't understand
> is why when you have a choose n it  won't go back to upp(). Thanks.

Because you have nothing to stop it going into reroll().
Thee is no if statement, it will always, without fail exit reroll
and go into navy. (It may call upp() in between times but it
will nonetheless go into navy after reroll finishes.)

> strength = 0
> dexterity = 0
> endurance = 0
> intelligence = 0
> education = 0
> social = 0
>
> def upp():
>   global strength
>   global dexterity
>   global endurance
>   global intelligence
>   global education
>   global social
>
>   strength = random.randrange(2,12)
>   dexterity = random.randrange(2,12)
>   endurance = random.randrange(2,12)
>   intelligence = random.randrange(2,12)
>   education = random.randrange(2,12)
>   social = random.randrange(2,12)
>
>   return strength, dexterity, endurance, intelligence, education, 
> social

You don't really need to return therse since they are the
global values initialised at the top of the code.

> def reroll():
>   a = raw_input("Are you satisfied with your UPP? Choose yes or 
> no.").lower()
>   try:
>       if a[0] == "y":
>           career()
>       elif a[0] == "n":
>           upp()
>       else:
>           print "Please choose a valid option."
>           print
>           out = reroll()
>
>   except:
>       print "Please choose a valid option."
>       print
>       out = reroll()

You don't need the try/except since the is/elif/else will catch all 
possible
cases. BUT you are assigning out to the return value of reroll() but 
reroll()
never returns a value. So out will always equal None. This isn't much
of a problem since you never use out anyway! You don't really need 
this
function you could replace it with a while loop at the top level.

Your use of nested calls is what is giving your odd behaviouir.

You call upp()
Then you call reroll()
Inside reroll() you either call career() or call upp() again or call 
reroll() again
If you call career() then, when it exits, you will exit reroll() and 
then call navy().
If you call upp() then, when it exits, you will exit reroll() and then 
call navy().
If you call reroll() then, when it exits, you will exit the outer 
reroll() and then call navy().

So whatever happens in reroll() you eventually wind up calling navy()

>   return

This does nothing.

> def career():
>   b = raw_input("Navy, Marines, Army, Scouts, Merchants").lower()
>   try:
>       if b[0] == "navy":
>           out = navy()

b[0] will be a character. You are comparing a character to a string.
It will never equate.

>       elif b[0] == "marines":
>       elif b[0] == "army":
>       elif b[0] == "scouts":
>       elif b[0] == "merchants":

Same for these

>   except:
>      print "Please choose a valid option."
>      print
>      career()

The except will never get called(unl;ess one of the called
functions raises an exception, which is fairly unlikely.

>   return

Again, this does nothing

> def navy():
>   global strength
>   global dexterity
>   global endurance
>   global intelligence
>   global education
>   global social
>
>   print """You have selected a naval career."""
>   c = raw_input("How many terms of service do you want? 1,2,3,4,5")
>
>   enlist = int(c)
>   count = 0
>
>   rank = 0
>   age = 18
>   benefits = []
>   cash = []
>   skills = []
>   commission = False
>
>   while count<enlist:
>      age=age+4
>      count=count+1
>
>      if commission == False:
>         comm = random.randrange(2,12)
>         if comm>=10:
>            commission = True
>            print "You made commission"
>         else:
>            print "You did not make comission"
>
>
>      if commission == True:
>         prom = random.randrange(2,12)
>         if prom>=8:
>            rank=rank+1
>            print "Your rank is now"
>            print rank

You could simplify that to one line with:

>            print "Your rank is now", rank

Or if you really want a separate line:

>            print "Your rank is now\n", rank

>         else:
>            print "You did not make promotion"
>
>
>      pskill = random.randrange(1,6)
>      if pskill == 1:
>         strength=strength+1
>
>      elif pskill == 2:
>         dexterity=dexterity+1
>
>      elif pskill == 3:
>         endurance=endurance+1
>
>      elif pskill == 4:
>         intelligence=intelligence+1
>
>      elif pskill == 5:
>         education=education+1
>
>      elif pskill == 6:
>         social=social+1
>
>
>      sskill = random.randrange(1,6)
>      if sskill == 1:
>         skills[1:1]=['Ships Boat']

This is an unusual way of inserting entries to a list. It would be 
more
common to use append or insert, as in:
   skills.append('Ships Boat')

>      elif sskill == 2:
>      elif sskill == 3:
>      elif sskill == 4:
>      elif sskill == 5:
>      elif sskill == 6:
>      if education<8:
>         aeskill = random.randrange(1,6)
>         if aeskill == 1:
>         elif aeskill == 2:
>         elif aeskill == 3:
>         elif aeskill == 4:
>         elif aeskill == 5:
>         elif aeskill == 6:
>
>      if education>=8:
>         ae8skill = random.randrange(1,6)
>         if ae8skill == 1:
>         elif ae8skill == 2:
>         elif ae8skill == 3:
>         elif ae8skill == 4:
>         elif ae8skill == 5:
>         elif ae8skill == 6:

You can almost certainly tidy this lot up using better data structures
then it becomes a case of indexing into the data rather than all the
if/elif steps.

>   print"#################################"
>   print "# Your UPP is:",strength, dexterity, endurance,
> intelligence, education, social
>   print "# Your current rank is now:",rank
>   print "# Your current age is now:",age
>   print "#",skills
>   print"#################################"
>
>   return
>
>
> ###############################################################################
> # start program here
> ###############################################################################
> print """Welcome to the Classic Traveller character generator.
>        Written in Python"""
> print """Press return to generate a character"""
> raw_input()
>
>
> print upp()
> print """You have a chance to reroll if needed."""
>
> reroll()
> navy()


In general you will find life easier if you start with a simpler 
version of your
program (only two or three characeristics/skills etc) and get the 
overall
structure right. Its easier to debug and less code to write. Once its 
basically
working adding extra features is easy.

HTH,

-- 
Alan Gauld
Author of the Learn to Program web site
http://www.freenetpages.co.uk/hp/alan.gauld 




More information about the Tutor mailing list