473,322 Members | 1,232 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,322 software developers and data experts.

idiom for debug code?

Is there a mechanism or an idiom for adding code for debugging so that it
can easily be removed in the production code? I am thinking of something
similar to the C/C++ preprocessor statements with which you can compile an
application with the debug code or without it (the default).

Dan
Jul 18 '05 #1
9 2006
Dan Perl wrote:
Is there a mechanism or an idiom for adding code for debugging so that it
can easily be removed in the production code? I am thinking of something
similar to the C/C++ preprocessor statements with which you can compile an
application with the debug code or without it (the default).

Dan

Personally I think you should consider NOT removing the debugging code.
It never ceases to amaze me how many times I must have a client run
the application with debug set so that the program logs details about
the running process and intermediate results. The output logfile can
then be easily emailed, faxed, etc. to me so that I can determine what
is REALLY the problem. The overhead of these if _debug: "type"
statements seems incredibly low compared to the ability to get this
information when needed. Just some thoughts based on my experience
of the last 30+ years.

Larry Bates
Syscon, Inc.
Jul 18 '05 #2
I was not thinking of actually removing code. The analogy to C++
preprocessing was just an example. I am looking at something that can be
determined at run-time, not compile-time.

And you're right, I'm not really concerned about the overhead of an "if"
because I will not use this extensively anyway. This problem occurred to me
when I decided to add an import for win32traceutil. I'm looking for a way
to have that permanently in the code and enabling/disabling it only at
run-time.

I have thought of alternatives like an environment variable or a
configuration parameter, but I was looking for other ideas. I thought this
should be a common issue and that there could be an idiom for it.

Dan

PS: in the case of importing win32traceutil, I guess that checking the
environment would be necessary anyway, or the import should be in a try
statement, ignoring the exceptions.

"Larry Bates" <lb****@syscononline.com> wrote in message
news:wf********************@comcast.com...
Dan Perl wrote:
Is there a mechanism or an idiom for adding code for debugging so that it
can easily be removed in the production code? I am thinking of something
similar to the C/C++ preprocessor statements with which you can compile
an application with the debug code or without it (the default).

Dan

Personally I think you should consider NOT removing the debugging code.
It never ceases to amaze me how many times I must have a client run
the application with debug set so that the program logs details about
the running process and intermediate results. The output logfile can
then be easily emailed, faxed, etc. to me so that I can determine what
is REALLY the problem. The overhead of these if _debug: "type"
statements seems incredibly low compared to the ability to get this
information when needed. Just some thoughts based on my experience
of the last 30+ years.

Larry Bates
Syscon, Inc.

Jul 18 '05 #3
[Dan Perl]:

Is there a mechanism or an idiom for adding code for debugging so that it
can easily be removed in the production code? I am thinking of something
similar to the C/C++ preprocessor statements with which you can compile an
application with the debug code or without it (the default).


assert is nice, but it's not really what I call debug code -- that's
code which should stay.

for "true" debug code, use the logging module and emit debug messages
with logging.debug("..."). you can raise the debug level if you don't
need them.

or define your own debug() function. to disable debug, simply bind a
null function to that name. this rebinding can be done dynamically,
of course. (this is what the logging module does with unwanted log
levels.)

in either case, you may want to avoid code like:

debug("Mother's smell is %s, number of taunts %d" % (fruit, count))

since Python won't be smart enough to skip the string interpolation.
instead, write it as

debug("Mother's smell is %s, number of taunts %d", fruit, count)

and do the interpolation inside the debug function.
--
Kjetil T.
Jul 18 '05 #4
In message <6t********************@rogers.com>, Dan Perl
<da*****@rogers.com> writes
I was not thinking of actually removing code. The analogy to C++
preprocessing was just an example. I am looking at something that can be
determined at run-time, not compile-time.

And you're right, I'm not really concerned about the overhead of an "if"
because I will not use this extensively anyway. This problem occurred to me
when I decided to add an import for win32traceutil. I'm looking for a way
to have that permanently in the code and enabling/disabling it only at
run-time.

I have thought of alternatives like an environment variable or a
configuration parameter, but I was looking for other ideas. I thought this
should be a common issue and that there could be an idiom for it.

Dan

PS: in the case of importing win32traceutil, I guess that checking the
environment would be necessary anyway, or the import should be in a try
statement, ignoring the exceptions.

"Larry Bates" <lb****@syscononline.com> wrote in message
news:wf********************@comcast.com...
Dan Perl wrote:
Is there a mechanism or an idiom for adding code for debugging so that it
can easily be removed in the production code? I am thinking of something
similar to the C/C++ preprocessor statements with which you can compile
an application with the debug code or without it (the default).

Dan

Personally I think you should consider NOT removing the debugging code.
It never ceases to amaze me how many times I must have a client run
the application with debug set so that the program logs details about
the running process and intermediate results. The output logfile can
then be easily emailed, faxed, etc. to me so that I can determine what
is REALLY the problem. The overhead of these if _debug: "type"
statements seems incredibly low compared to the ability to get this
information when needed. Just some thoughts based on my experience
of the last 30+ years.

Larry Bates
Syscon, Inc.



I' use the following technique. I originally wrote it four years or so
ago, so I'm sure it could be much improved. In fact looking at it now,
I ma deeply embarrassed to post it, and know it could be dramatically
improved both by using more modern features of Python, by better coding
and by some comprehension of design.

I have a utility.py module which contains my common functions and I
import this in every module, plus a wrapper for the debug function:

import utility

debug = 0

def dprint( *args):
"""
print function toggled on or off by module debug variable
"""
global debug
if debug:
apply(utility._dprint,args)
This allows me to scatter dprint functions throughout the module instead
of print statements, and enable or suppress them by setting the global
'debug', e.g.

def func(x):
global total
total += x
dprint("total is currently",total)

to get an output of something like:
! module.py:83 in func: total is currently 10
The relevant code from my utility.py is attached.
I would welcome rewrites of this code, of course.

Regards

Ian
--
Ian Parker

Jul 18 '05 #5
Ian Parker wrote:

[...]
I have a utility.py module which contains my common functions and I
import this in every module, plus a wrapper for the debug function:

import utility

debug = 0

def dprint( *args):
"""
print function toggled on or off by module debug variable
"""
global debug
if debug:
apply(utility._dprint,args)
This allows me to scatter dprint functions throughout the module instead
of print statements, and enable or suppress them by setting the global
'debug', e.g.

def func(x):
global total
total += x
dprint("total is currently",total)

to get an output of something like:
! module.py:83 in func: total is currently 10


Well, I don't do anything as sophisticated as dprint on the output side,
and might consider lifting it. But in terms of selecting which debug
code gets executed I often use something like

if 3 in debug:

because this makes it easy to selectively turn different bits of debug
code on or off. Of course the test takes a little longer, but when not
debugging it doesn't take long to check whether an integer is in an
empty list.

regards
Steve
Jul 18 '05 #6
Thanks, Ian. It's late Saturday for me now so I will look more at the code
later, but so far what I get from what you sent is only dprint and that is a
logging utility. That's not what I was looking for. OTOH, I see that your
posting was probably only a first installment, so I am looking forward to
more details, including more parts from your utility module.

The solution that you are using for the dprint utility involves a global
variable. How do you change its value? Is that still by making a change in
the code, even if the change is only one place? I would like a solution
that does not involve any change in the code and is determined strictly at
run-time. I was thinking of something like an environment variable or a
configuration attribute. Of course, your solution can be adapted to set the
global variable based on an environment variable or based on configuration.

As for rewriting your code, did you take a look at the newsgroup thread
about the new logging utility?

Dan

"Ian Parker" <pa****@hiredatum.demon.co.uk> wrote in message
news:0D**************@hiredatum.demon.co.uk...
In message <6t********************@rogers.com>, Dan Perl
<da*****@rogers.com> writes
I was not thinking of actually removing code. The analogy to C++
preprocessing was just an example. I am looking at something that can be
determined at run-time, not compile-time.

And you're right, I'm not really concerned about the overhead of an "if"
because I will not use this extensively anyway. This problem occurred to
me
when I decided to add an import for win32traceutil. I'm looking for a way
to have that permanently in the code and enabling/disabling it only at
run-time.

I have thought of alternatives like an environment variable or a
configuration parameter, but I was looking for other ideas. I thought
this
should be a common issue and that there could be an idiom for it.

Dan

PS: in the case of importing win32traceutil, I guess that checking the
environment would be necessary anyway, or the import should be in a try
statement, ignoring the exceptions.

"Larry Bates" <lb****@syscononline.com> wrote in message
news:wf********************@comcast.com...
Dan Perl wrote:
Is there a mechanism or an idiom for adding code for debugging so that
it
can easily be removed in the production code? I am thinking of
something
similar to the C/C++ preprocessor statements with which you can compile
an application with the debug code or without it (the default).

Dan
Personally I think you should consider NOT removing the debugging code.
It never ceases to amaze me how many times I must have a client run
the application with debug set so that the program logs details about
the running process and intermediate results. The output logfile can
then be easily emailed, faxed, etc. to me so that I can determine what
is REALLY the problem. The overhead of these if _debug: "type"
statements seems incredibly low compared to the ability to get this
information when needed. Just some thoughts based on my experience
of the last 30+ years.

Larry Bates
Syscon, Inc.


I' use the following technique. I originally wrote it four years or so
ago, so I'm sure it could be much improved. In fact looking at it now,
I ma deeply embarrassed to post it, and know it could be dramatically
improved both by using more modern features of Python, by better coding
and by some comprehension of design.

I have a utility.py module which contains my common functions and I
import this in every module, plus a wrapper for the debug function:

import utility

debug = 0

def dprint( *args):
"""
print function toggled on or off by module debug variable
"""
global debug
if debug:
apply(utility._dprint,args)
This allows me to scatter dprint functions throughout the module instead
of print statements, and enable or suppress them by setting the global
'debug', e.g.

def func(x):
global total
total += x
dprint("total is currently",total)

to get an output of something like:
! module.py:83 in func: total is currently 10
The relevant code from my utility.py is attached.

--------------------------------------------------------------------------------


I would welcome rewrites of this code, of course.

Regards

Ian
--
Ian Parker

Jul 18 '05 #7

"Dan Perl" <da*****@rogers.com> wrote in message
news:ye********************@rogers.com...
Thanks, Ian. It's late Saturday for me now so I will look more at the
code later, but so far what I get from what you sent is only dprint and
that is a logging utility. That's not what I was looking for. OTOH, I
see that your posting was probably only a first installment, so I am
looking forward to more details, including more parts from your utility
module.
I just realized that maybe you meant that posting to be the only one and not
an installment, hence the one of ONE ([1/1]). Too bad. Could you post also
the rest of your utility script? Or would that break some copyright (do you
own it?)?
The solution that you are using for the dprint utility involves a global
variable. How do you change its value? Is that still by making a change
in the code, even if the change is only one place? I would like a
solution that does not involve any change in the code and is determined
strictly at run-time. I was thinking of something like an environment
variable or a configuration attribute. Of course, your solution can be
adapted to set the global variable based on an environment variable or
based on configuration.

As for rewriting your code, did you take a look at the newsgroup thread
about the new logging utility?

Dan

Jul 18 '05 #8
In message <HzJ7d.288401$4o.8905@fed1read01>, Steve Holden
<st***@holdenweb.com> writes
Ian Parker wrote:

[...]
I have a utility.py module which contains my common functions and I
import this in every module, plus a wrapper for the debug function:
import utility
debug = 0
def dprint( *args):
"""
print function toggled on or off by module debug variable
"""
global debug
if debug:
apply(utility._dprint,args)
This allows me to scatter dprint functions throughout the module
instead
of print statements, and enable or suppress them by setting the global
'debug', e.g.
def func(x):
global total
total += x
dprint("total is currently",total)
to get an output of something like:
! module.py:83 in func: total is currently 10


Well, I don't do anything as sophisticated as dprint on the output
side, and might consider lifting it. But in terms of selecting which
debug code gets executed I often use something like

if 3 in debug:

because this makes it easy to selectively turn different bits of debug
code on or off. Of course the test takes a little longer, but when not
debugging it doesn't take long to check whether an integer is in an
empty list.

regards
Steve


I like that - it does give a flexibility that my dprint lacks. I do
tend to find that, although I may enable my dprint only for a function
or method, I still comment out some of the dprint calls.

Regards

Ian

--
Ian Parker
Jul 18 '05 #9
In message <ye********************@rogers.com>, Dan Perl
<da*****@rogers.com> writes
Thanks, Ian. It's late Saturday for me now so I will look more at the code
later, but so far what I get from what you sent is only dprint and that is a
logging utility. That's not what I was looking for. OTOH, I see that your
posting was probably only a first installment, so I am looking forward to
more details, including more parts from your utility module.

The solution that you are using for the dprint utility involves a global
variable. How do you change its value? Is that still by making a change in
the code, even if the change is only one place? I would like a solution
that does not involve any change in the code and is determined strictly at
run-time. I was thinking of something like an environment variable or a
configuration attribute. Of course, your solution can be adapted to set the
global variable based on an environment variable or based on configuration.

As for rewriting your code, did you take a look at the newsgroup thread
about the new logging utility?

Dan

"Ian Parker" <pa****@hiredatum.demon.co.uk> wrote in message
news:0D**************@hiredatum.demon.co.uk...
In message <6t********************@rogers.com>, Dan Perl
<da*****@rogers.com> writes
I was not thinking of actually removing code. The analogy to C++
preprocessing was just an example. I am looking at something that can be
determined at run-time, not compile-time.

And you're right, I'm not really concerned about the overhead of an "if"
because I will not use this extensively anyway. This problem occurred to
me
when I decided to add an import for win32traceutil. I'm looking for a way
to have that permanently in the code and enabling/disabling it only at
run-time.

I have thought of alternatives like an environment variable or a
configuration parameter, but I was looking for other ideas. I thought
this
should be a common issue and that there could be an idiom for it.

Dan

PS: in the case of importing win32traceutil, I guess that checking the
environment would be necessary anyway, or the import should be in a try
statement, ignoring the exceptions.

"Larry Bates" <lb****@syscononline.com> wrote in message
news:wf********************@comcast.com...
Dan Perl wrote:
> Is there a mechanism or an idiom for adding code for debugging so that
> it
> can easily be removed in the production code? I am thinking of
> something
> similar to the C/C++ preprocessor statements with which you can compile
> an application with the debug code or without it (the default).
>
> Dan
Personally I think you should consider NOT removing the debugging code.
It never ceases to amaze me how many times I must have a client run
the application with debug set so that the program logs details about
the running process and intermediate results. The output logfile can
then be easily emailed, faxed, etc. to me so that I can determine what
is REALLY the problem. The overhead of these if _debug: "type"
statements seems incredibly low compared to the ability to get this
information when needed. Just some thoughts based on my experience
of the last 30+ years.

Larry Bates
Syscon, Inc.


I' use the following technique. I originally wrote it four years or so
ago, so I'm sure it could be much improved. In fact looking at it now,
I ma deeply embarrassed to post it, and know it could be dramatically
improved both by using more modern features of Python, by better coding
and by some comprehension of design.

I have a utility.py module which contains my common functions and I
import this in every module, plus a wrapper for the debug function:

import utility

debug = 0

def dprint( *args):
"""
print function toggled on or off by module debug variable
"""
global debug
if debug:
apply(utility._dprint,args)
This allows me to scatter dprint functions throughout the module instead
of print statements, and enable or suppress them by setting the global
'debug', e.g.

def func(x):
global total
total += x
dprint("total is currently",total)

to get an output of something like:
! module.py:83 in func: total is currently 10
The relevant code from my utility.py is attached.

--------------------------------------------------------------------------------


I would welcome rewrites of this code, of course.

Regards

Ian
--
Ian Parker



That was indeed the only instalment. Yes, thinking about it now, dprint
is simply a logging system, so I really should look at the logging
module -(which didn't exist when I wrote dprint). Feel free to lift the
code - I certainly lifted chunks of it from other examples I find on
this newsgroup.

Yes, 'debug' is a global variable. The reason for the inclusion of the
dprint wrapper in each module is to make use of the module 'debug' to
give a little more granularity. Two points:

In a function, I frequently do what feels like a very clumsy hack:

def func(x,y):
global debug ; olddebug = debug
# debug = 1
Jul 18 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: David Morgenthaler | last post by:
In many of my scripts I've used the following idiom for accessing data files placed nearby: BASEDIR = os.path.dirname(__file__) .. .. .. fp = file(os.path.join(BASEDIR,"somefile.txt")) .. ..
28
by: Fábio Mendes | last post by:
I'm sorry if it's an replicate. Either my e-mail program is messing with things or the python-list sent my msg to /dev/null. I couldn't find anything related in previous PEP's, so here it goes a...
1
by: Pekka Niiranen | last post by:
Hi there, after reading TkInter/thread -recipe: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/82965 I wondered if it was possible to avoid using threads for the following problem: ...
12
by: Frans Englich | last post by:
Hello, Since Python doesn't have static typing, how is the same result as traditional function overloads results in acheived? With function overloads the "selection of code path depending on...
7
by: Icosahedron | last post by:
I've been going through some old code trying to clean it up and rearchitect it based on more modern C++ idioms. In the old code I often used the Pimpl idiom on a class by class basis, creating...
12
by: Siemel Naran | last post by:
What is a good idiom for handling a lazy object? I see 2 good possibilities. Any more, any comments? Which way do people here use? (1) class Thing { public: Thing(double x, double y) :...
7
by: Mikhail N. Kupchik | last post by:
Hi All. I have a question regarding Herb Sutter's idiom of implementation of operator= via nonthrowing swap() member function, to guarantee strict exception safety. The idea of the idiom is...
6
by: Gareth Stockwell | last post by:
I've been using an technique whereby a tag used as a parameter to a template class C determines which of several potential base classes (A,B) C inherits from. What I want to know is whether there...
14
by: Daniel Lidström | last post by:
Hello! I have just discovered a way to use the private implementation idiom (pimpl), without the overhead of dynamic memory allocation. For those of you who don't know what this is, Wikipedia...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.