Discussion:
[Tutor] Equivalent of a Subroutine in Python?
Seelinger, Bruce
2001-01-31 22:12:29 UTC
Permalink
Hello,

Another question from someone totally new to Python. Is there an equivalent
in Python to a sub-routine, (e.g. gosub and return). I want to create a
modular program with sub-routines to perform distinct tasks wihin the
program for organizational and debugging purposes, etc. Is the only (or
best) way to do this is with modules? A function works but the values
obtained within the function do not appear to be valid outside of that
function. I guess I am looking for the best approach to create the
subroutines for execution from the main flow of the program.

Thanks for any assistance!

Regards,

Bruce Seelinger
Kalle Svensson
2001-02-01 18:51:36 UTC
Permalink
Post by Seelinger, Bruce
Another question from someone totally new to Python. Is there an equivalent
in Python to a sub-routine, (e.g. gosub and return). I want to create a
A function.

[snip]
Post by Seelinger, Bruce
best) way to do this is with modules? A function works but the values
obtained within the function do not appear to be valid outside of that
function. I guess I am looking for the best approach to create the
No. That's a feature. Global variables are often a bad idea and make
programs more difficult to understand, especially when they grow larger.
Use class instance methods and variables or plain old return values.
Post by Seelinger, Bruce
a = 0
... global a
... a = val
...
Post by Seelinger, Bruce
print a
0
Post by Seelinger, Bruce
f(12)
print a
12
But don't blame me if you don't understand your own programs three months
from now... <wink>

I suggest you read
http://www.crosswinds.net/~agauld/
http://www.ibiblio.org/obp/thinkCSpy/
http://www.python.org/doc/current/tut/

Especially the parts about functions, modules, classes and object oriented
programming.

HTH,
Kalle
--
Email: ***@gnupung.net | You can tune a filesystem, but you
Web: http://www.gnupung.net/ | can't tune a fish. -- man tunefs(8)
PGP fingerprint: 0C56 B171 8159 327F 1824 F5DE 74D7 80D7 BF3B B1DD
Deirdre Saoirse
2001-02-01 17:54:04 UTC
Permalink
Post by Seelinger, Bruce
Another question from someone totally new to Python. Is there an
equivalent in Python to a sub-routine, (e.g. gosub and return).
There are functions.
Post by Seelinger, Bruce
I want to create a modular program with sub-routines to perform
distinct tasks wihin the program for organizational and debugging
purposes, etc. Is the only (or best) way to do this is with modules?
No. As I said, there are also functions.
Post by Seelinger, Bruce
A function works but the values obtained within the function do not
appear to be valid outside of that function. I guess I am looking for
the best approach to create the subroutines for execution from the
main flow of the program.
Good coding design says that that's the way it should be. Functions should
only change what's inside them, not stuff that may have Unintended
Consequences (tm).

Clearly, you learned Basic first and early versions of Basic (sorry, I
haven't used the language in 26 years...) didn't have local scoping as
that was difficult to implement and its advantages were not yet
appreciated. I believe Pascal was the first widely-used language to use
local scoping.

_Deirdre
Michael P. Reilly
2001-02-01 18:15:20 UTC
Permalink
This message is in MIME format. Since your mail reader does not understand
this format, some or all of this message may not be legible.
------_=_NextPart_001_01C08BD2.E6AD3D40
Content-Type: text/plain;
charset="iso-8859-1"
Hello,
Another question from someone totally new to Python. Is there an equivalent
in Python to a sub-routine, (e.g. gosub and return). I want to create a
modular program with sub-routines to perform distinct tasks wihin the
program for organizational and debugging purposes, etc. Is the only (or
best) way to do this is with modules? A function works but the values
obtained within the function do not appear to be valid outside of that
function. I guess I am looking for the best approach to create the
subroutines for execution from the main flow of the program.
There sure are. You would either use the "def" statement or the
"lambda" expression to create a subroutine/procedure/function.
... print name, 'said', repr(message)
...
WhatsMyLine('Arcege', "Spam, Spam, Eggs and Spam")
Arcege said 'Spam, Spam, Eggs and Spam'
is_odd = lambda n: (n % 2) == 1
is_odd(3)
1
is_odd(4), is_odd(5)
(0, 1)
I would suggest that you read the Python tutorial; it could help you a
lot with your questions.
<URL: http://www.python.org/doc/current/tut/tut.html>

-Arcege

--
------------------------------------------------------------------------
| Michael P. Reilly, Release Manager | Email: ***@shore.net |
| Salem, Mass. USA 01970 | |
------------------------------------------------------------------------
Bruce Sass
2001-02-01 18:34:13 UTC
Permalink
Post by Seelinger, Bruce
Another question from someone totally new to Python. Is there an equivalent
in Python to a sub-routine, (e.g. gosub and return). I want to create a
function - subroutine - procedure... they are all the same basic idea
Post by Seelinger, Bruce
modular program with sub-routines to perform distinct tasks wihin the
program for organizational and debugging purposes, etc. Is the only (or
best) way to do this is with modules? A function works but the values
obtained within the function do not appear to be valid outside of that
You should send along an example... it is probably just a problem with
Python's scope rules, or maybe that the code is passing a reference when
you are thinking value, or maybe you are expecting a default parameter's
value to be evaluated everytime the function is used when it is actually
only evaluated once... hard to say without seeing any code.
Post by Seelinger, Bruce
function. I guess I am looking for the best approach to create the
subroutines for execution from the main flow of the program.
later,

Bruce
Deirdre Saoirse
2001-02-01 19:15:35 UTC
Permalink
As this is really a tutor question, I'm cutting the extra parts and
re-posting the meat to the Tutor list (list mom's prerogative):

(And yes, I'd rather responses went to the list; others are struggling
with the same kinds of things and NOT posting...)
I wanted to use values obtained in subroutines or functions as you are
allowed in DCL. For example, one subroutine determines the hardware
type of unit based on data imported from a file. Once that subroutine
determines the hardware type, it is assigned to a variable (hw_type)
and is used by other subroutines for purposes unique to that hardware
type. I think the underlying issue is the my logic and design will
need to be modified to adhere to Python's rules.
In calling a function, you can pass one or more parameters to it. Unlike
may other languages, you can also return multiple parameters.

def readFile(fname):
... do some stuff...
hw_type = (something from the file)
hw_info = (something else from the file)
return hw_type, hw_info

def main():
hw_type, hw_info = readFile("foo")

There's also more complex structures; see:
http://www.python.org/doc/current/tut/node7.html#SECTION007400000000000000000

_Deirdre
D-Man
2001-02-01 22:18:14 UTC
Permalink
Except for some minor philosophical issues,

subroutine is function is method is procedure is subprogram

Different communities have different names for the same concept.
Functions are what you want here. The problem you are running into is
Python's scope and namespace rules.
... """ this function will give a new value for s """
... s = s + "Hello World"
...
s = "Foo "
mutate( )
print s
Foo
What happened here? The value didn't change. There are 2 reasons for
that. First, the function body has a local namespace. Those names
don't exist outside of the function. Assignment, in Python, is
different than in most languages. In, say, C/C++ assignment will
modify the value of the memory that the variable name refers to (is
bound to). In Python, assignment is simply a rebinding. Everything
in Python is a reference. If a name doesn't yet exist, the
"assignment" will create the name, *in the local namespace*. Ok,
knowing this, I'll try my above example again.
... global s
... s = s + "Hello World"
...
s = "Foo "
mutate( )
print s
Foo Hello World
This is closer to what you are looking for, I think. The 'global'
keyword notifies the interpreter that you want to use a variable from
outside the local namespace. This isn't necessary for reading a
variable, but to assign to it (rebind it) it is necessary. Without
the global statement, I would have created a new binding in the
function's local namespace, and the effects would not be visible
outside of the function.


There is another issue to consider when trying to modify variables.
Some variables are immutable, while other are mutable. Immutable
variables can't have their /value/ changed, but can still be rebound
to a new object (value). Strings, integers, and tuples are some of
the immutable types in python. Lists and classes are mutable. An
... s = s + "Hello World"
...
a_string = "Foo "
mutate( a_string )
print a_string
Foo
The argument 's' was rebound /inside/ the function to point to a new
string whose value was "Foo Hello World". The a_string variable is
still bound to the original string whose value is still "Foo".

Now I'll try with a list, since lists are mutable.
... """ try mutating a list """
... l = l + [ 3 , 4 , 5 ]
...
a_list = [ 1 , 2 ]
mutate( a_list )
print a_list
[1, 2]
The problem here is the namespace the new list is bound in. The
operator "+" on a list doesn't modify the list, but instead returns a
new list that is the concatenation of the operands.
... l += [ 3 , 4 , 5 ]
...
a_list = [ 1 , 2 ]
mutate( a_list )
print a_list
[1, 2, 3, 4, 5]
Version 2.0 of the interpreter added augmented assignment. For
immutable objects, the value isn't changed and the new object is bound
to the left hand side. (It is just a shorthand notation) For mutable
objects it will modify the object, /and/ return a refernce to the
object. The return is necessary otherwise your identifier won't refer
to any objects anymore.

In older versions as well as newer versions of the interpreter, the
... l.extend( [ 3 , 4 , 5 ] )
...
a_list = [ 1 , 2 ]
mutate( a_list )
print a_list
[1, 2, 3, 4, 5]
What kind of background are you coming from? If I remember correctly,
gosub is from BASIC (but I haven't done any BASIC programming).

If you can provide some examples of what you are trying to do (the
python code you have that isn't working right) we can help you to see
how python's semantics are working and how to modify it to give you
the semantics you want.


You can start out using stand-alone functions, but I much prefer using
classes for (most) of my work. (there are situations where a
stand-alone function is a better choice though) Simply put, a class
is a set of data and a set of functions that operate on that data.
You can create multiple instances of a class and each will have its
own set of that data.

HTH,
-D


On Wed, Jan 31, 2001 at 05:12:29PM -0500, Seelinger, Bruce wrote:
| Hello,
|
| Another question from someone totally new to Python. Is there an equivalent
| in Python to a sub-routine, (e.g. gosub and return). I want to create a
| modular program with sub-routines to perform distinct tasks wihin the
| program for organizational and debugging purposes, etc. Is the only (or
| best) way to do this is with modules? A function works but the values
| obtained within the function do not appear to be valid outside of that
| function. I guess I am looking for the best approach to create the
| subroutines for execution from the main flow of the program.
|
| Thanks for any assistance!
|
| Regards,
|
| Bruce Seelinger
David Porter
2001-02-02 00:55:58 UTC
Permalink
Post by Seelinger, Bruce
Another question from someone totally new to Python. Is there an equivalent
in Python to a sub-routine, (e.g. gosub and return). I want to create a
modular program with sub-routines to perform distinct tasks wihin the
program for organizational and debugging purposes, etc. Is the only (or
best) way to do this is with modules?
What about functions?

According to http://foldoc.doc.ic.ac.uk/foldoc/foldoc.cgi?query=subroutine

"A function is often very similar to a subroutine, the main difference
being that it is called chiefly for its return value, rather than for any
side effects."
Post by Seelinger, Bruce
A function works but the values obtained within the function do not appear
to be valid outside of that function.
That is because they are local to the function's namespace. If you want them
to be global, then you must declare them so:

def fun():
global x
x = 11

fun()
print x


Or you could use a standard function with return value:

def fun2():
return 11

x = fun2()
print x


David

Loading...