Ogle this awesome snip of C++:
#define TRACE_(x) cout << #x ": " << x << endl
When you use that like this:
TRACE_(y + z);
TRACE_(strAnimals);
TRACE_(__LINE__);
the program emits this:
y + z: 12
strAnimals: Lemmings
__LINE__: 69
Mighty healthy and easy to write debug statements with, huh? Saves a lot of
keystrokes, huh?
How do I do that, just as easy to call, in Python?
--
Phlip phli...@my-deja.com
============ http://c2.com/cgi/wiki?PhlIp ============
-- In the beginning, God distinguished heaven and earth --
> Pythonographers:
>
> Ogle this awesome snip of C++:
>
> #define TRACE_(x) cout << #x ": " << x << endl
>
> When you use that like this:
>
> TRACE_(y + z);
> TRACE_(strAnimals);
> TRACE_(__LINE__);
>
> the program emits this:
>
> y + z: 12
> strAnimals: Lemmings
> __LINE__: 69
>
> Mighty healthy and easy to write debug statements with, huh? Saves a lot of
> keystrokes, huh?
>
> How do I do that, just as easy to call, in Python?
Try this:
def TRACE ( str ):
print "%s: %s" % ( str, eval(str) )
TRACE('y+z')
TRACE('strAnimals')
Sorry... you /do/ need to put the parameters in quotes, so Python doesnt
try to evaluate them before calling TRACE
And... not sure if there's a equivalent of __line__
("`-/")_.-'"``-._ Ch'marr, a.k.a.
. . `; -._ )-;-,_`) Chris Cogdon <chm...@furry.org.au>
(v_,)' _ )`-.\ ``-'
_.- _..-_/ / ((.' FC1.3: FFH3cmA+>++C++D++H++M++P++R++T+++WZ++Sm++
((,.-' ((,/ fL RLCT acl+++d++e+f+++h++i++++jp-sm++
That's a preprocessor trick, not a C++ trick. Replace <<
with printf, and it works just as fine under C.
(iirc, bjarne thinks that real C++ programmers shouldn't
use the preprocessor at all, but what does he know...)
> How do I do that, just as easy to call, in Python?
Run your Python code through C's preprocessor?
Or use something like this:
def trace(expr):
# evaluate expression in callers namespace
import sys
try:
raise None
except:
frame = sys.exc_info()[2].tb_frame.f_back
print expr, "=", eval(expr, frame.f_globals, frame.f_locals)
x = 10
y = 20
trace("x + y")
## prints:
## x + y = 30
Cheers /F
<!-- (the eff-bot guide to) the standard python library:
http://www.pythonware.com/people/fredrik/librarybook.htm
-->
> Pythonographers:
>
> Ogle this awesome snip of C++:
>
> #define TRACE_(x) cout << #x ": " << x << endl
You can do it in Python the other way around:
>>> def trace_(x):
... print x+":", eval(x)
...
>>> y = z = 6; animal='lemming'
>>> trace_('y+z')
y+z: 12
>>> trace_('animal')
animal: lemming
HIH!
--
Moshe Zadka <s...@zadka.site.co.il>
This is a signature anti-virus.
Please stop the spread of signature viruses!
Fingerprint: 4BD1 7705 EEC0 260A 7F21 4817 C7FC A636 46D0 1BD6
> And... not sure if there's a equivalent of __line__
Of more interest would be to be able to get a hold of execution stack
information, such as what method called this method (and maybe the
parameter values, such as 'self' of *that* method)
If it's called 'trace'? it'd be nice to trace back :)
This may be possible, I don't know how the Traceback works in Python; I
haven't explored it yet.
Take care,
--
Jay O'Connor
joco...@cybermesa.com
http://www.cybermesa.com/~joconnor
"God himself plays the bass strings first when He tunes the soul"
> (iirc, bjarne thinks that real C++ programmers shouldn't
> use the preprocessor at all, but what does he know...)
C++ features such as namespaces, templates, and const variables acting
as true constants generally render it unnecessary to use the
preprocessor to accomplish most tasks it was traditionally used for.
It's generally considered bad style to make excessive use of the
preprocessor in Standard C++.
--
Erik Max Francis / m...@alcyone.com / http://www.alcyone.com/max/
__ San Jose, CA, US / 37 20 N 121 53 W / ICQ16063900 / &tSftDotIotE
/ \ When one is in love, a cliff becomes a meadow.
\__/ (an Ethiopian saying)
Official Buh rules / http://www.alcyone.com/max/projects/cards/buh/
The official rules to the betting card game, Buh.
"The C preprocessor is a powerful but blunt tool, however, and macros are a
dangerous way to program because they change the lexical structure of the
program underfoot. Let the language proper do the work."
Kernighan & Pike, _The Practice of Programming_.
iirc, either K or R have mentioned they would have left macros out of the
language if they could have forseen the clever and wondrous uses that would
be found for them.
>Try this:
>
>def TRACE ( str ):
> print "%s: %s" % ( str, eval(str) )
>
>TRACE('y+z')
>TRACE('strAnimals')
>
>Sorry... you /do/ need to put the parameters in quotes, so Python doesnt
>try to evaluate them before calling TRACE
You also need to provide the TRACE function with the caller's local
namespace, or TRACE will, in general, get NameErrors.
def TRACE(str, locals):
print "%s: %s" % (str, eval(str, globals(), locals))
and call it like
TRACE('y+z', locals())
(I know I'm stomping on a predefined function name in TRACE, but I
have no problem with it in this case.)
--
Clarence Gardner
Software Engineer
NetLojix Communications
clar...@netlojix.com
>Try this:
>
>def TRACE ( str ):
> print "%s: %s" % ( str, eval(str) )
>
>TRACE('y+z')
>TRACE('strAnimals')
>
>Sorry... you /do/ need to put the parameters in quotes, so Python doesnt
>try to evaluate them before calling TRACE
You also need to provide the TRACE function with the caller's local
Note how Python lacks a preprocessor and macros :) People occasionally rally
for a macro preprocessor, but usually not of the C type. Being fairly
ignorant in languages featuring macros other than the C style, I can't
really say what they *are* rallying for, but apparently there are sane macro
preprocessors in existance, somewhere :)
--
Thomas Wouters <tho...@xs4all.net>
Hi! I'm a .signature virus! copy me into your .signature file to help me spread!
If I may humbly offer a small change which even handles
something like the original __LINE__ request, I believe:
def trace(expr = None):
# evaluate expression in callers namespace
import sys
try:
raise None
except:
frame = sys.exc_info()[2].tb_frame.f_back
if expr != None:
print expr, ":", eval(expr, frame.f_globals, frame.f_locals)
else:
print '__LINE__ :', frame.f_lineno
x = 10
y = 20
strAnimals = "Lemmings"
trace("x + y")
trace("strAnimals")
trace()
## prints:
## x + y : 30
## strAnimals : Lemmings
## __LINE__ : 19
> That's a preprocessor trick, not a C++ trick. Replace <<
> with printf, and it works just as fine under C.
Could'a mentioned that's where the trick started with me. Before the #
stringerizer operator got invented, too...
> (iirc, bjarne thinks that real C++ programmers shouldn't
> use the preprocessor at all, but what does he know...)
The exact rule is "Don't use a low-tech feature when a high-tech one will
do". You'l notice this rule explains why I'm deep in the coils of Python
these days...
One should not use the C preprocessor to perform simple administration,
such as declaring a constant. But only the preprocessor has the
stringerizer operator #; and it's a quite recent addition, based on bugs
exploited in earlier preprocessors to stringerize without it, so it
qualifies as high-tech.
> Run your Python code through C's preprocessor?
We are already deep in a stack of script, Perforce Jam, Python, SWIG and
C++ code; we don't need another operation on our source!
Thomas Wouters wrote:
> Note how Python lacks a preprocessor and macros :)
No, reaching down into the interpret's own pants and grabbing its nads with
lines like these will do nicely:
frame = sys.exc_info()[2].tb_frame.f_back
ch...@onca.catsden.net wrote:
> And... not sure if there's a equivalent of __line__
I just threw that one in worrying the first question might turn out too
easy...
Thanks to all the replies; I'l try the suggestions (and learn what
"trace()" does) as soon as I'm on the clock ;-)
--
Phlip phli...@my-deja.com
============ http://c2.com/cgi/wiki?PhlIp ============
-- Who needs a degree when we have Web e-search engines? --
Other than C, my exposure has been to various macro assemblers. With some
creativity, it is possible to write your own language to the extent the
underlying asm never surfaces. In fact, it isn't uncommon in embedded work
for people to use macros to write code for a PIC or AVR device almost
completely in '51 syntax.
I personally am uncomfortable when a language allows one to create a private
dialect; FORTH and many of the functional languages come to mind. Factoring
a problem into functions is one thing, but I prefer to see the bare metal of
the language and well known library calls rather than essentially having to
learn yet another language someone has lovingly handcrafted (and generally
not documented).
If I'm in a mood to annoy Guido, I propose hygienic(sp?) macros, like
in R5RS. These are things which are macros, but on the verge on being
functions: no accidental name collision, for one. Real macros work on
the parser level, not the tokenizer levels, so you can't do idiotic
stuff like
#define BEGIN {
#define END ;}
Or other shoot-on-sight offense.
Better make that 'except None'. Unqualified 'except' clauses are generally
a bad idea. In this case, you really don't want to catch 'MemoryError',
'KeyboardInterrupt', or 'ComputerExplodingError'.
--
Rainer Deyke (ro...@rainerdeyke.com)
Shareware computer games - http://rainerdeyke.com
"In ihren Reihen zu stehen heisst unter Feinden zu kaempfen" - Abigor
> Better make that 'except None'. Unqualified 'except' clauses are generally
> a bad idea. In this case, you really don't want to catch...'ComputerExplodingError'.
I hadn't seen that exception raised yet....is it new? What do you
usually do to handle it?
> Rainer Deyke wrote:
>
> > Better make that 'except None'. Unqualified 'except' clauses are
> > generally
> > a bad idea. In this case, you really don't want to
> > catch...'ComputerExplodingError'.
>
> I hadn't seen that exception raised yet....is it new? What do you
> usually do to handle it?
Right past you.
--
Erik Max Francis / m...@alcyone.com / http://www.alcyone.com/max/
__ San Jose, CA, US / 37 20 N 121 53 W / ICQ16063900 / &tSftDotIotE
/ \ It is much safer to obey than to rule.
\__/ Thomas a Kempis
7 sisters productions / http://www.7sisters.com/
Web design for the future.
ComputerExplodingError is one of the "hidden" exceptions of the Underground
of Pythonic Secrecy (UPS), created in response to the much cooler names of
rival groups Secret Pythonic Underground (SPU) amd Pythonic Secret
Underground (SPU). It is raised automatically when a computer "goes
postal". The proper response is to panic and scream a lot. This is done
automatically by the interpreter when stack unwinding is complete.
Obviously this requires that any 'except' clause that intercepts the
exception re-throws it.
>Jay O'Connor wrote:
>
>> Rainer Deyke wrote:
>> > catch...'ComputerExplodingError'.
>>
>> I hadn't seen that exception raised yet....is it new? What do you
>> usually do to handle it?
>
>Right past you.
Nope, just being silly :)
Take care,
"God himself plays on the bass strings first, when he tunes the soul"
And if you have sound support then the computer says
"I'm sorry %{USER}s, I can't do that right now" % os.environ
if os.environ.has_key("USER"), else it plays
"Daisy, Daisy, give me your answer true"
But I don't actually know this since I'm not a member of
So long as it goes via normal routes, there shouldn't be a problem. But know
that the Tristero network takse a dim view of transporting equipment for other
nonexistent organizations.
Don't ever antagonize the horn.
How do you make trace("a = 1") work ?
> "Phlip" <phli...@my-deja.com> wrote:
> Or use something like this:
>
> def trace(expr):
> # evaluate expression in callers namespace
> import sys
> try:
> raise None
> except:
> frame = sys.exc_info()[2].tb_frame.f_back
> print expr, "=", eval(expr, frame.f_globals, frame.f_locals)
>
> x = 10
> y = 20
> trace("x + y")
>
> ## prints:
> ## x + y = 30
>
> Cheers /F
>
> <!-- (the eff-bot guide to) the standard python library:
> http://www.pythonware.com/people/fredrik/librarybook.htm
> -->
>
>
Sent via Deja.com
http://www.deja.com/