Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #16402 > unrolled thread
| Started by | Colin Higwell <colinh@somewhere.invalid> |
|---|---|
| First post | 2011-11-29 20:06 +0000 |
| Last post | 2011-11-30 09:36 -0200 |
| Articles | 8 — 7 participants |
Back to article view | Back to comp.lang.python
Total newbie question: Best practice Colin Higwell <colinh@somewhere.invalid> - 2011-11-29 20:06 +0000
Re: Total newbie question: Best practice Arnaud Delobelle <arnodel@gmail.com> - 2011-11-29 20:34 +0000
Re: Total newbie question: Best practice Neil Cerutti <neilc@norwich.edu> - 2011-11-29 21:12 +0000
Re: Total newbie question: Best practice Chris Angelico <rosuav@gmail.com> - 2011-11-30 07:36 +1100
Re: Total newbie question: Best practice Dave Angel <d@davea.name> - 2011-11-29 16:57 -0500
Re: Total newbie question: Best practice Colin Higwell <colinh@somewhere.invalid> - 2011-11-29 23:08 +0000
RE: Total newbie question: Best practice Shambhu Rajak <Shambhu.Rajak@kpitcummins.com> - 2011-11-30 08:50 +0000
Re: Total newbie question: Best practice "Pedro Henrique G. Souto" <pedro.h.souto@gmail.com> - 2011-11-30 09:36 -0200
| From | Colin Higwell <colinh@somewhere.invalid> |
|---|---|
| Date | 2011-11-29 20:06 +0000 |
| Subject | Total newbie question: Best practice |
| Message-ID | <jb3e06$37h$1@dont-email.me> |
Hi, I am just starting to learn Python (I have been at it only a few hours), so please bear with me. I have a few very small scripts (do you call them scripts or programs?) which work properly, and produce the results intended. However, they are monolithic in nature; i.e. they begin at the beginning and finish at the end. Having done a little reading, I note that it seems to be quite common to have a function main() at the start (which in turn calls other functions as appropriate), and then to call main() to do the work. Is that standard best practice? Thanks
[toc] | [next] | [standalone]
| From | Arnaud Delobelle <arnodel@gmail.com> |
|---|---|
| Date | 2011-11-29 20:34 +0000 |
| Message-ID | <mailman.3134.1322598844.27778.python-list@python.org> |
| In reply to | #16402 |
On 29 November 2011 20:06, Colin Higwell <colinh@somewhere.invalid> wrote:
> Hi,
Hi Colin, and welcome to Python :)
> I am just starting to learn Python (I have been at it only a few hours),
> so please bear with me. I have a few very small scripts (do you call them
> scripts or programs?) which work properly, and produce the results
> intended.
I think you can call them either.
> However, they are monolithic in nature; i.e. they begin at the beginning
> and finish at the end. Having done a little reading, I note that it seems
> to be quite common to have a function main() at the start (which in turn
> calls other functions as appropriate), and then to call main() to do the
> work.
>
> Is that standard best practice?
When code should be put in a function is a matter of judgement in the
end, so it's not an easy question. But roughly speaking:
- if you need to perform the same task at several points in you
program, then it's a good idea to put this in a function. It avoids
duplication of code, minimises the chances for bugs, makes the program
easier to read (provided you find a nice name for the function!) and
also improves testability.
- if there is a task that could be performed is several different ways
but with the same result, then it's good to put in a function. This
way when reading the program you can focus on the important thing,
which is the result of the process, without being distracted by the
details of how the result is arrived at. Moreover, it gives you added
flexibility as you can later try a different method for performing the
same task and very easily plug it into your existing program to see if
it improves performance for example.
- if you have a piece of code which is too long to be understood
easily, consider whether you could break it down into smaller bits,
each of which has some meaning of its own, and make each bit into a
function with a name that describes clearly what it does. Then
rewrite your big piece of code in terms of these functions. It will
make your program a lot easier to understand when you come back to it
in the future.
As for the main() function, I don't think it is standard practice in
Python. There is no requirement to have a main() function. You can
use the idiom:
if __name__ == "__main__":
...
which will execute if you call the file as a script (as opposed to
importing it as a module)
--
Arnaud
[toc] | [prev] | [next] | [standalone]
| From | Neil Cerutti <neilc@norwich.edu> |
|---|---|
| Date | 2011-11-29 21:12 +0000 |
| Message-ID | <9jl06gFg9oU1@mid.individual.net> |
| In reply to | #16403 |
On 2011-11-29, Arnaud Delobelle <arnodel@gmail.com> wrote: > As for the main() function, I don't think it is standard > practice in Python. There is no requirement to have a main() > function. You can use the idiom: I don't start off with a main function, but if my script gets long and complicated, or if global names have proliferated and have become confusing, I'll refactor the whole thing into functions, including a "main". With most globals moved into main's namespace, calling subroutines from main forces me to define the context that's actually necessary for each part of the program. The resultant refactored programs are much easier to test, read and maintain. TLDR: "Called-only-once" functions like main are useful as documentation, hooks for testing, and for unraveling a snarl of global variables. -- Neil Cerutti
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2011-11-30 07:36 +1100 |
| Message-ID | <mailman.3135.1322598998.27778.python-list@python.org> |
| In reply to | #16402 |
On Wed, Nov 30, 2011 at 7:06 AM, Colin Higwell <colinh@somewhere.invalid> wrote:
> However, they are monolithic in nature; i.e. they begin at the beginning
> and finish at the end. Having done a little reading, I note that it seems
> to be quite common to have a function main() at the start (which in turn
> calls other functions as appropriate), and then to call main() to do the
> work.
The reason for this practice is to allow your .py file to be either a
top-level program or an imported module.
if __name__ == "__main__":
main()
When you run a .py file directly, __name__ will be "__main__", and
it'll execute main(). (Some programs directly embed the main routine
in that if block - appropriate if main() would be very short, eg just
calling some other function.) But if you import it as a module in some
other program, that won't be the case; so instead, the module's
functions are made available to the calling program.
For simple scripts that don't have anything to offer as a module, it's
fine to not bother with this structure. Python doesn't demand
syntactic salt; that's one of its greatest features, IMHO.
Chris Angelico
[toc] | [prev] | [next] | [standalone]
| From | Dave Angel <d@davea.name> |
|---|---|
| Date | 2011-11-29 16:57 -0500 |
| Message-ID | <mailman.3136.1322603871.27778.python-list@python.org> |
| In reply to | #16402 |
On 11/29/2011 03:06 PM, Colin Higwell wrote:
> Hi,
>
> I am just starting to learn Python (I have been at it only a few hours),
> so please bear with me. I have a few very small scripts (do you call them
> scripts or programs?) which work properly, and produce the results
> intended.
>
> However, they are monolithic in nature; i.e. they begin at the beginning
> and finish at the end. Having done a little reading, I note that it seems
> to be quite common to have a function main() at the start (which in turn
> calls other functions as appropriate), and then to call main() to do the
> work.
>
> Is that standard best practice?
>
> Thanks
>
Welcome to Python, and to the comp.lang.python list. Is this your first
experience programming?
Yes, factoring your code from "monolithic" to "modular' (several
functions, or even functions and classes), is good practice.
That's not to say that some problems don't deserve a monolithic answer,
but if you're a beginner, i'd like to see you get into a modular habit.
You can use the words script and program pretty much interchangeably.
in some contexts, each has additional connotations. For example,
somebody used to a compiled language may refer to a python source file
as a script, implying it's not as sophisticated as his own product.
But, closer to home, we usually refer to the file you directly pass to
the interpreter as a script, and any added files that get imported, as
modules, or libraries.
Other times, people will refer to a simple program as a script, implying
that all it does is invoke some standard library functions, or even run
some external programs. But when it gets more complex, it gradually
turns into a "real program."
Why break up a monolith?
Several reasons. If you factor the code into independent functions, and
give them good names, then each piece of the program is easier to
understand. You will especially appreciate that if you come back to the
code after doing something else for two weeks. Similarly if somebody
else has to take over your code, or maybe adapt it to a slightly
different purpose.
Next, if it doesn't quite work, you can exercise the individual pieces
independently, and narrow down the problem more quickly.
Next, if the progfram is slow, usually you can narrow it down to a few
key functions that take most of the time. You can write two versions of
the same function, and do some careful timings to decide which one to use.
Next, some of those functions may be useful in the next program you
write. If you "reuse" the code by copy & paste, and find a problem in
the new one, it's quite possible that the same problem may exist in your
first program. it's easier to bring those changes back if they're in a
function than if they're in lines 14 through 71.
Finally, some of that reusable code may be worth moving to an external
file, called a module. Then the same copy can be literally shared
between multiple projects. This is how libraries were born, and you can
write your own, eventually.
there are many other reasons, but some of them might not make sense to
you yet.
How do you break it up?
First, separate the classic parts that most scripts will have. Put the
imports at the top, along with a comment describing the whole progfram's
purpose. Next put the global variables, which should be few. If there
are any constants, use all UPPERCASE for their names.
Next, put the function and class definitions. Notice that none of them
will be called yet, so the order of execution isn't important to the
compiler. Each function needs a name, and you should use a name that
makes sense to you. Try to write functions that work at a single level
of complexity, and do one complete operation. Try not to do
input/output in the same functions that do the computation.
And finally, put the actual mainline. It could be as simple as a call
to main(), but it may make more sense to you to put the calls to
argument processing here, rather than in a main function. By arguments
here, i'm referring to the stuff you typed on the command line when youi
invoked the script. This part of the code is where you do the magic
incantation:
if __name__ == "__main__":
main()
When the number of functions gets unwieldy, it's time to move some of
them to a new file. They should be related, and should work at the same
level of complexity. And the file name should remind you of their
purpose. At that point, you add an import of that file to your main
source script. Congratulations, you've created a module.
One catch with writing a lengthy reply is that others have already given
you good feedback. Hopefully, mine will complement theirs.
--
DaveA
[toc] | [prev] | [next] | [standalone]
| From | Colin Higwell <colinh@somewhere.invalid> |
|---|---|
| Date | 2011-11-29 23:08 +0000 |
| Message-ID | <jb3ole$euh$1@dont-email.me> |
| In reply to | #16406 |
On Tue, 29 Nov 2011 16:57:18 -0500, Dave Angel wrote: > On 11/29/2011 03:06 PM, Colin Higwell wrote: >> Hi, >> >> I am just starting to learn Python (I have been at it only a few >> hours), so please bear with me. I have a few very small scripts (do you >> call them scripts or programs?) which work properly, and produce the >> results intended. >> >> However, they are monolithic in nature; i.e. they begin at the >> beginning and finish at the end. Having done a little reading, I note >> that it seems to be quite common to have a function main() at the start >> (which in turn calls other functions as appropriate), and then to call >> main() to do the work. >> >> Is that standard best practice? >> >> Thanks >> > Welcome to Python, and to the comp.lang.python list. Is this your first > experience programming? > > Yes, factoring your code from "monolithic" to "modular' (several > functions, or even functions and classes), is good practice. > > That's not to say that some problems don't deserve a monolithic answer, > but if you're a beginner, i'd like to see you get into a modular habit. > > You can use the words script and program pretty much interchangeably. > in some contexts, each has additional connotations. For example, > somebody used to a compiled language may refer to a python source file > as a script, implying it's not as sophisticated as his own product. > But, closer to home, we usually refer to the file you directly pass to > the interpreter as a script, and any added files that get imported, as > modules, or libraries. > > Other times, people will refer to a simple program as a script, implying > that all it does is invoke some standard library functions, or even run > some external programs. But when it gets more complex, it gradually > turns into a "real program." > > > Why break up a monolith? > > Several reasons. If you factor the code into independent functions, and > give them good names, then each piece of the program is easier to > understand. You will especially appreciate that if you come back to the > code after doing something else for two weeks. Similarly if somebody > else has to take over your code, or maybe adapt it to a slightly > different purpose. > > Next, if it doesn't quite work, you can exercise the individual pieces > independently, and narrow down the problem more quickly. > > Next, if the progfram is slow, usually you can narrow it down to a few > key functions that take most of the time. You can write two versions of > the same function, and do some careful timings to decide which one to > use. > > Next, some of those functions may be useful in the next program you > write. If you "reuse" the code by copy & paste, and find a problem in > the new one, it's quite possible that the same problem may exist in your > first program. it's easier to bring those changes back if they're in a > function than if they're in lines 14 through 71. > > Finally, some of that reusable code may be worth moving to an external > file, called a module. Then the same copy can be literally shared > between multiple projects. This is how libraries were born, and you can > write your own, eventually. > > there are many other reasons, but some of them might not make sense to > you yet. > > > How do you break it up? > > First, separate the classic parts that most scripts will have. Put the > imports at the top, along with a comment describing the whole progfram's > purpose. Next put the global variables, which should be few. If there > are any constants, use all UPPERCASE for their names. > > Next, put the function and class definitions. Notice that none of them > will be called yet, so the order of execution isn't important to the > compiler. Each function needs a name, and you should use a name that > makes sense to you. Try to write functions that work at a single level > of complexity, and do one complete operation. Try not to do > input/output in the same functions that do the computation. > > And finally, put the actual mainline. It could be as simple as a call > to main(), but it may make more sense to you to put the calls to > argument processing here, rather than in a main function. By arguments > here, i'm referring to the stuff you typed on the command line when youi > invoked the script. This part of the code is where you do the magic > incantation: > > if __name__ == "__main__": > main() > > > > When the number of functions gets unwieldy, it's time to move some of > them to a new file. They should be related, and should work at the same > level of complexity. And the file name should remind you of their > purpose. At that point, you add an import of that file to your main > source script. Congratulations, you've created a module. > > One catch with writing a lengthy reply is that others have already given > you good feedback. Hopefully, mine will complement theirs. Thank you, and thanks also to all the other respondents. I have programmed before in a number of other languages, but there is still plenty in this thread for me to digest.
[toc] | [prev] | [next] | [standalone]
| From | Shambhu Rajak <Shambhu.Rajak@kpitcummins.com> |
|---|---|
| Date | 2011-11-30 08:50 +0000 |
| Message-ID | <mailman.3149.1322643933.27778.python-list@python.org> |
| In reply to | #16402 |
Collins Congratulations for your first step into Python Programming. You can call them script or programs(not necessarily but depends on what your coding for). Yaa..it's always a good practice to call it through main(), but it doesn't really matter you can call the method in way.... Regards, Shambhu -----Original Message----- From: Colin Higwell [mailto:colinh@somewhere.invalid] Sent: 30/11/2011 1:37 AM To: python-list@python.org Subject: Total newbie question: Best practice Hi, I am just starting to learn Python (I have been at it only a few hours), so please bear with me. I have a few very small scripts (do you call them scripts or programs?) which work properly, and produce the results intended. However, they are monolithic in nature; i.e. they begin at the beginning and finish at the end. Having done a little reading, I note that it seems to be quite common to have a function main() at the start (which in turn calls other functions as appropriate), and then to call main() to do the work. Is that standard best practice? Thanks
[toc] | [prev] | [next] | [standalone]
| From | "Pedro Henrique G. Souto" <pedro.h.souto@gmail.com> |
|---|---|
| Date | 2011-11-30 09:36 -0200 |
| Message-ID | <mailman.3153.1322653011.27778.python-list@python.org> |
| In reply to | #16402 |
On 30/11/2011 06:50, Shambhu Rajak wrote:
> Collins Congratulations for your first step into Python Programming.
> You can call them script or programs(not necessarily but depends on what your coding for).
> Yaa..it's always a good practice to call it through main(), but it doesn't really matter you
> can call the method in way....
>
> Regards,
> Shambhu
>
> -----Original Message-----
> From: Colin Higwell [mailto:colinh@somewhere.invalid]
> Sent: 30/11/2011 1:37 AM
> To: python-list@python.org
> Subject: Total newbie question: Best practice
>
> Hi,
>
> I am just starting to learn Python (I have been at it only a few hours),
> so please bear with me. I have a few very small scripts (do you call them
> scripts or programs?) which work properly, and produce the results
> intended.
>
> However, they are monolithic in nature; i.e. they begin at the beginning
> and finish at the end. Having done a little reading, I note that it seems
> to be quite common to have a function main() at the start (which in turn
> calls other functions as appropriate), and then to call main() to do the
> work.
>
> Is that standard best practice?
>
> Thanks
Congratulations on becoming a Pythonist!
Like Shambhu said, it doesn't matter where do you put the code, but is
interesting to have a main() function when you have a program, and you
want to differentiate if it is running directly (i.e. python program.py)
or if it is running as a module, imported by other program (i.e. import
program).
To do so, you do this:
main():
# blablabla
if __name__ == '__main__':
main()
If the program is running directly, the variable __name__ will be
'__main__', if not, __name__ will be the name of the module ('program',
in this case).
Att;
Pedro
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web