Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #46708 > unrolled thread

PyWart: The problem with "print"

Started byRick Johnson <rantingrickjohnson@gmail.com>
First post2013-06-02 10:04 -0700
Last post2013-06-03 15:11 -0400
Articles 20 on this page of 109 — 26 participants

Back to article view | Back to comp.lang.python


Contents

  PyWart: The problem with "print" Rick Johnson <rantingrickjohnson@gmail.com> - 2013-06-02 10:04 -0700
    Re: PyWart: The problem with "print" Chris Angelico <rosuav@gmail.com> - 2013-06-03 03:20 +1000
      Re: PyWart: The problem with "print" Dan Sommers <dan@tombstonezero.net> - 2013-06-02 17:49 +0000
        Re: PyWart: The problem with "print" Rick Johnson <rantingrickjohnson@gmail.com> - 2013-06-02 11:18 -0700
          Re: PyWart: The problem with "print" Ned Batchelder <ned@nedbatchelder.com> - 2013-06-02 16:45 -0400
          Re: PyWart: The problem with "print" Michael Torrie <torriem@gmail.com> - 2013-06-02 23:49 -0600
          Re: PyWart: The problem with "print" Chris Angelico <rosuav@gmail.com> - 2013-06-03 17:17 +1000
            Re: PyWart: The problem with "print" Alister <alister.ware@ntlworld.com> - 2013-06-03 08:01 +0000
      Re: PyWart: The problem with "print" Rick Johnson <rantingrickjohnson@gmail.com> - 2013-06-02 11:09 -0700
        Re: PyWart: The problem with "print" Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-06-02 19:03 +0000
        Re: PyWart: The problem with "print" Chris Angelico <rosuav@gmail.com> - 2013-06-03 06:21 +1000
        Re: PyWart: The problem with "print" jmfauth <wxjmfauth@gmail.com> - 2013-06-04 05:23 -0700
          Re: PyWart: The problem with "print" rusi <rustompmody@gmail.com> - 2013-06-04 06:29 -0700
            Re: PyWart: The problem with "print" Mark Lawrence <breamoreboy@yahoo.co.uk> - 2013-06-04 14:35 +0100
          Re: PyWart: The problem with "print" Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-06-05 05:03 +0000
    Re: PyWart: The problem with "print" Andrew Berg <robotsondrugs@gmail.com> - 2013-06-02 12:30 -0500
    Re: PyWart: The problem with "print" Chris Angelico <rosuav@gmail.com> - 2013-06-03 03:34 +1000
    Re: PyWart: The problem with "print" Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-06-02 18:58 +0000
      Re: PyWart: The problem with "print" Chris Angelico <rosuav@gmail.com> - 2013-06-03 06:28 +1000
      Re: PyWart: The problem with "print" Rick Johnson <rantingrickjohnson@gmail.com> - 2013-06-03 18:37 -0700
        Re: PyWart: The problem with "print" Vito De Tullio <vito.detullio@gmail.com> - 2013-06-04 05:16 +0200
          Re: PyWart: The problem with "print" Rick Johnson <rantingrickjohnson@gmail.com> - 2013-06-03 20:53 -0700
          Re: PyWart: The problem with "print" Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-06-04 04:30 +0000
        Bools and explicitness [was Re: PyWart: The problem with "print"] Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-06-04 05:39 +0000
          Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Rick Johnson <rantingrickjohnson@gmail.com> - 2013-06-04 08:44 -0700
            Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Chris Angelico <rosuav@gmail.com> - 2013-06-05 02:00 +1000
              Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Rick Johnson <rantingrickjohnson@gmail.com> - 2013-06-04 09:19 -0700
                Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Chris Angelico <rosuav@gmail.com> - 2013-06-05 02:27 +1000
                  Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-06-05 05:28 +0000
                    Re: Bools and explicitness [was Re: PyWart: The problem with "print"] alex23 <wuwei23@gmail.com> - 2013-06-04 22:31 -0700
                Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Ned Batchelder <ned@nedbatchelder.com> - 2013-06-04 13:25 -0400
            Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Rick Johnson <rantingrickjohnson@gmail.com> - 2013-06-04 09:09 -0700
              Re: Bools and explicitness [was Re: PyWart: The problem with "print"] alex23 <wuwei23@gmail.com> - 2013-06-04 18:31 -0700
            Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Fábio Santos <fabiosantosart@gmail.com> - 2013-06-04 17:10 +0100
            Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Jason Swails <jason.swails@gmail.com> - 2013-06-04 13:32 -0400
            Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Ian Kelly <ian.g.kelly@gmail.com> - 2013-06-04 11:42 -0600
              Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Rick Johnson <rantingrickjohnson@gmail.com> - 2013-06-04 16:21 -0700
                Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Mark Lawrence <breamoreboy@yahoo.co.uk> - 2013-06-05 00:37 +0100
                Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Michael Torrie <torriem@gmail.com> - 2013-06-04 23:28 -0600
            Re: Bools and explicitness [was Re: PyWart: The problem with "print"] "Russ P." <Russ.Paielli@gmail.com> - 2013-06-04 23:11 -0700
              Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Chris Angelico <rosuav@gmail.com> - 2013-06-05 17:15 +1000
                Re: Bools and explicitness [was Re: PyWart: The problem with "print"] "Russ P." <Russ.Paielli@gmail.com> - 2013-06-05 00:47 -0700
                Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Rick Johnson <rantingrickjohnson@gmail.com> - 2013-06-06 09:49 -0700
                  Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Chris Angelico <rosuav@gmail.com> - 2013-06-07 02:59 +1000
                  Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Dan Stromberg <drsalists@gmail.com> - 2013-06-06 18:26 -0700
              Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Mark Lawrence <breamoreboy@yahoo.co.uk> - 2013-06-05 09:59 +0100
                Re: Bools and explicitness [was Re: PyWart: The problem with "print"] "Russ P." <Russ.Paielli@gmail.com> - 2013-06-05 09:15 -0700
                  Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Chris Angelico <rosuav@gmail.com> - 2013-06-06 02:59 +1000
                    Re: Bools and explicitness [was Re: PyWart: The problem with "print"] "Russ P." <Russ.Paielli@gmail.com> - 2013-06-05 14:59 -0700
                      Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-06-06 01:56 +0000
                        Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Chris Angelico <rosuav@gmail.com> - 2013-06-06 12:29 +1000
                          Re: Bools and explicitness [was Re: PyWart: The problem with "print"] "Russ P." <Russ.Paielli@gmail.com> - 2013-06-05 21:25 -0700
                            Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Ian Kelly <ian.g.kelly@gmail.com> - 2013-06-06 00:06 -0600
                          Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-06-06 09:29 +0000
                            Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Chris Angelico <rosuav@gmail.com> - 2013-06-06 19:45 +1000
                            Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Serhiy Storchaka <storchaka@gmail.com> - 2013-06-06 14:12 +0300
                            Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Robert Kern <robert.kern@gmail.com> - 2013-06-06 16:35 +0100
                            Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Chris Angelico <rosuav@gmail.com> - 2013-06-07 01:41 +1000
                            Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Robert Kern <robert.kern@gmail.com> - 2013-06-06 17:08 +0100
                              Re: Bools and explicitness [was Re: PyWart: The problem with "print"] rusi <rustompmody@gmail.com> - 2013-06-06 10:27 -0700
                                Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Devin Jeanpierre <jeanpierreda@gmail.com> - 2013-06-06 14:44 -0400
                            Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Mark Janssen <dreamingforward@gmail.com> - 2013-06-06 10:59 -0700
                              Re: Bools and explicitness [was Re: PyWart: The problem with "print"] alex23 <wuwei23@gmail.com> - 2013-06-06 17:53 -0700
                                Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Mark Janssen <dreamingforward@gmail.com> - 2013-06-06 18:44 -0700
                                  Re: Bools and explicitness [was Re: PyWart: The problem with "print"] alex23 <wuwei23@gmail.com> - 2013-06-06 19:03 -0700
                                    Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Mark Janssen <dreamingforward@gmail.com> - 2013-06-06 22:01 -0700
                                  Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-06-07 02:29 +0000
                                    Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Mark Janssen <dreamingforward@gmail.com> - 2013-06-06 20:14 -0700
                                      Re: Bools and explicitness [was Re: PyWart: The problem with "print"] rusi <rustompmody@gmail.com> - 2013-06-06 20:24 -0700
                                        Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Mark Janssen <dreamingforward@gmail.com> - 2013-06-06 20:30 -0700
                                        Re: Bools and explicitness [was Re: PyWart: The problem with "print"] rusi <rustompmody@gmail.com> - 2013-06-06 20:43 -0700
                            Re: Bools and explicitness [was Re: PyWart: The problem with "print"] "Russ P." <Russ.Paielli@gmail.com> - 2013-06-06 11:08 -0700
                    Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Rick Johnson <rantingrickjohnson@gmail.com> - 2013-06-06 08:49 -0700
                      Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Chris Angelico <rosuav@gmail.com> - 2013-06-07 02:00 +1000
                        Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Grant Edwards <invalid@invalid.invalid> - 2013-06-06 17:32 +0000
                  Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-06-06 01:37 +0000
                    Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Chris Angelico <rosuav@gmail.com> - 2013-06-06 11:45 +1000
                      Re: Bools and explicitness [was Re: PyWart: The problem with "print"] rusi <rustompmody@gmail.com> - 2013-06-06 07:09 -0700
                        Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Chris Angelico <rosuav@gmail.com> - 2013-06-07 01:26 +1000
                          Re: Bools and explicitness [was Re: PyWart: The problem with "print"] rusi <rustompmody@gmail.com> - 2013-06-06 08:36 -0700
                            Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Chris Angelico <rosuav@gmail.com> - 2013-06-07 01:46 +1000
                    Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Rick Johnson <rantingrickjohnson@gmail.com> - 2013-06-06 11:03 -0700
                      Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Rick Johnson <rantingrickjohnson@gmail.com> - 2013-06-06 11:11 -0700
              Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Terry Jan Reedy <tjreedy@udel.edu> - 2013-06-05 12:10 -0400
              Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Michael Torrie <torriem@gmail.com> - 2013-06-05 17:18 -0600
                Re: Bools and explicitness [was Re: PyWart: The problem with "print"] "Russ P." <Russ.Paielli@gmail.com> - 2013-06-05 16:52 -0700
                  Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Michael Torrie <torriem@gmail.com> - 2013-06-05 19:20 -0600
                Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Rick Johnson <rantingrickjohnson@gmail.com> - 2013-06-06 09:24 -0700
                  Re: Bools and explicitness [was Re: PyWart: The problem with "print"] Devin Jeanpierre <jeanpierreda@gmail.com> - 2013-06-06 12:39 -0400
                    Re: Bools and explicitness [was Re: PyWart: The problem with "print"] alex23 <wuwei23@gmail.com> - 2013-06-06 17:55 -0700
        Re: PyWart: The problem with "print" Chris Angelico <rosuav@gmail.com> - 2013-06-04 17:30 +1000
    Re: PyWart: The problem with "print" Jason Swails <jason.swails@gmail.com> - 2013-06-02 20:16 -0400
      Re: PyWart: The problem with "print" Dan Sommers <dan@tombstonezero.net> - 2013-06-03 03:10 +0000
        Re: PyWart: The problem with "print" Jason Swails <jason.swails@gmail.com> - 2013-06-02 23:23 -0400
          Re: PyWart: The problem with "print" Dan Sommers <dan@tombstonezero.net> - 2013-06-03 04:20 +0000
            Re: PyWart: The problem with "print" Robert Kern <robert.kern@gmail.com> - 2013-06-03 11:52 +0100
        Re: PyWart: The problem with "print" Tim Delaney <timothy.c.delaney@gmail.com> - 2013-06-03 13:37 +1000
          Python Heisenbugs?  (was: Re: PyWart: The problem with "print") Dan Sommers <dan@tombstonezero.net> - 2013-06-03 04:34 +0000
            Re: Python Heisenbugs? (was: Re: PyWart: The problem with "print") Chris Angelico <rosuav@gmail.com> - 2013-06-03 15:05 +1000
            Re: Python Heisenbugs? (was: Re: PyWart: The problem with "print") Devin Jeanpierre <jeanpierreda@gmail.com> - 2013-06-03 03:06 -0400
        Re: PyWart: The problem with "print" Mark Lawrence <breamoreboy@yahoo.co.uk> - 2013-06-03 09:49 +0100
        Re: PyWart: The problem with "print" Dave Angel <davea@davea.name> - 2013-06-03 08:56 -0400
    Re: PyWart: The problem with "print" Chris Angelico <rosuav@gmail.com> - 2013-06-03 12:02 +1000
    Re: PyWart: The problem with "print" Ian Kelly <ian.g.kelly@gmail.com> - 2013-06-03 11:12 -0600
    Re: PyWart: The problem with "print" Jason Swails <jason.swails@gmail.com> - 2013-06-03 15:09 -0400
      Re: PyWart: The problem with "print" Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-06-03 20:31 +0000
        Re: PyWart: The problem with "print" Chris Angelico <rosuav@gmail.com> - 2013-06-04 06:44 +1000
    Re: PyWart: The problem with "print" Jason Swails <jason.swails@gmail.com> - 2013-06-03 15:10 -0400
    Re: PyWart: The problem with "print" Jason Swails <jason.swails@gmail.com> - 2013-06-03 15:11 -0400

Page 1 of 6  [1] 2 3 4 5 6  Next page →


#46708 — PyWart: The problem with "print"

FromRick Johnson <rantingrickjohnson@gmail.com>
Date2013-06-02 10:04 -0700
SubjectPyWart: The problem with "print"
Message-ID<687dea63-84da-4c45-9366-cb5a10665d1f@googlegroups.com>
Note to those of you who may be new to Python: I will refer to "print" as a function -- just be aware that "print" was a statement before Python3000 was introduced.

------------------------------------------------------------
 Introduction:
------------------------------------------------------------
Many languages provide a function, method, or statement by which users can write easily to stdout, and Python is no exception with it's own "print" function. However, whilst writing to stdout via "print" is slightly less verbose than calling the "write" method of "sys.stdout", we don't really gain much from this function except a few keystrokes... is this ALL print should be? A mere syntactical sugar? For me, i think the "print" function CAN and SHOULD be so much more!

------------------------------------------------------------
 Print's Role in Debugging:
------------------------------------------------------------
A print function can be helpful in many ways, and one very important role print plays is to inform the programmer of internal states of objects via debug messages written to stdout.

Sure, there are fancy debuggers by which internal state and object identity can be inspected on the fly, however, "print" is always going to be there no matter what libraries or add-on you have available. And let's face it folks, print is the most simplistic and intuitive interface you'll ever find for debugging purposes. Sure, "print" may not be the most productive for large scale debugging, but for the majority of debugging tasks, it's a good fit.

I know some of you will cringe at the idea of using print for debugging, however, i will argue that using a debugger can weaken your detective skills. If an exception message and trackback are not giving you enough information to find the bug, well then, the language OR the code you've written is not worth a monkey's toss! 

I've found that many subtle bugs are caused by not limiting the inputs to sane values (or types). And with Python's duct typing and implicit casting to Boolean, you end up with all sorts of misleading things happening! Maybe you're testing for truth values and get a string instead; which screws everything up!!! 

Anyhoo, i digress...

------------------------------------------------------------
 Inadequacies of "print" Debugging.
------------------------------------------------------------
In it's current implementation, print is helpful, but in many ways, print is lacking it's true potential. Many of the problems that propagate up when using print as a debugger focus on the fact that you cannot easily switch the debug messages "on" or "off".

Sure, you can comment-out all calls to print, but if you need to see the messages again you will be forced to uncomment all the lines again... hey that's no fun! 

A "wise programmer" may think he's solved the problem by writing a function called "debugprint" that looks like this:

    def debugprint(*args):
        if DEBUG == True:
            print(*args)

However that solution is at best woefully inadequate and at worse a cycle burner!

 * Woefully inadequate because: Switching on or off the debug
   messages is only valid in the current module that the
   function was imported. What if you want to kill all
   debugprint messages EVERYWHERE? Do you really want to edit
   "debug = BOOLEAN" in every source file OR do something
   stupid like import debugprint and edit the DEBUG constant
   OR even dumber, edit the debugprint source code? GAWD NO!

 * But even if you are willing to cope with all the "switch-
   on-and-off" nonsense, are you willing to have you code
   slowed by numerous calls to a dead function containing a
   comparison that will always be false?

    ## START INTERACTIVE SESSION ##
    py> from __future__ import print_function
    py> DEBUG = True
    py> def debugprint(*args):
    ...     if not DEBUG:
    ...         return
    ...     print(*args)
    py> debugprint("foo", "bar")
    foo bar
    py> DEBUG = False
    py> code = compile('debugprint("foo", "bar")', '<string>', 'exec')
    py> import dis
    py> dis.disassemble(code)
      1           0 LOAD_NAME                0 (debugprint)
                  3 LOAD_CONST               0 ('foo')
                  6 LOAD_CONST               1 ('bar')
                  9 CALL_FUNCTION            2
                 12 POP_TOP
                 13 LOAD_CONST               2 (None)
                 16 RETURN_VALUE
   ## END INTERACTIVE SESSION ##
   After a few million executions of this superfluous
   comparison your cpu is losing faith in your ability to
   write logical code!

   py> function.call() + false_comparison() == 'cycle burner'
   "YOU BET YOU A$$ IT DOES!!"

------------------------------------------------------------
 Solution.
------------------------------------------------------------
This realization has brought me to the conclusion that Python (and other languages) need a "scoped print function". What is a "scoped print function" anyway?  Well what i am proposing is that Python include the following "debug switches" in the language:

  ------------------------------
   Switch: "__GLOBALDEBUG__"
  ------------------------------
  Global switching allows a programmer to instruct the
  interpreter to IGNORE all print functions or to EVALUATE
  all print functions by assigning a Boolean value of True
  or False respectively to the global switch (Note: global
  switch always defaults to True!).

  Any script that includes the assignment "__GLOBALDEBUG__ =
  False" will disable ALL debug print messages across the
  entire interpreter namespace. In effect, all print
  statements will be treated as comments and ignored by the
  interpreter. No dead functions will be called and no false
  comparisons will be made!

  (Note: __GLOBALDEBUG__ should not be available in any
  local namespace but accessed only form the topmost
  namespace. Something like: __main__.__GLOBALDEBUG__ =
  Boolean

  ------------------------------
   Switch: "__LOCALDEBUG__"
  ------------------------------
  Local switching allows a programmer to turn on (or off)
  debug messages in the module it was declared. Not sure if
  this should be more specific than modules; like classes,
  blocks, or functions??? Of course this declaration will
  be overridden by any global switch.

------------------------------------------------------------
 Concerns:
------------------------------------------------------------
My only concern is that some programmers may be confused why their print calls  are not working and may not have the capacity to resolve that function named "print" is tied to the global and local switches named "__GLOBAL_DEBUG__" and "__LOCAL_DEBUG__". To prevent any cognitive dissonance it may be desirable to introduce a new function called "debugprint".

*school-bell-rings*

[toc] | [next] | [standalone]


#46711

FromChris Angelico <rosuav@gmail.com>
Date2013-06-03 03:20 +1000
Message-ID<mailman.2551.1370193662.3114.python-list@python.org>
In reply to#46708
On Mon, Jun 3, 2013 at 3:04 AM, Rick Johnson
<rantingrickjohnson@gmail.com> wrote:
>  * Woefully inadequate because: Switching on or off the debug
>    messages is only valid in the current module that the
>    function was imported. What if you want to kill all
>    debugprint messages EVERYWHERE? Do you really want to edit
>    "debug = BOOLEAN" in every source file OR do something
>    stupid like import debugprint and edit the DEBUG constant
>    OR even dumber, edit the debugprint source code? GAWD NO!

Easy fix to this one. Instead of copying and pasting debugprint into
everything, have it in a module and import it everywhere. Then the
debug flag will be common to them all.

Oh, and you probably want to add **kwargs to debugprint, because the
print function does a lot more than sys.stdout.write does:

>>> print(1,2,3,4,sep='#')
1#2#3#4

>  * But even if you are willing to cope with all the "switch-
>    on-and-off" nonsense, are you willing to have you code
>    slowed by numerous calls to a dead function containing a
>    comparison that will always be false?

Hmm. Could be costly. Hey, you know, Python has something for testing that.

>>> timeit.timeit('debugprint("asdf")','def debugprint(*args):\n\tif not DEBUG: return\n\tprint(*args)\nDEBUG=False',number=1000000)
0.5838018519113444

That's roughly half a second for a million calls to debugprint().
That's a 580ns cost per call. Rather than fiddle with the language,
I'd rather just take this cost. Oh, and there's another way, too: If
you make the DEBUG flag have effect only on startup, you could write
your module thus:

if DEBUG:
  debugprint=print
else:
  def debugprint(*args,**kwargs):
    pass

So you can eliminate part of the cost there, if it matters to you. If
a half-microsecond cost is going to be significant to you, you
probably should be looking at improving other areas, maybe using
ctypes/cython, or possibly playing with the new preprocessor tricks
that have been being discussed recently. There's really no need to
change the language to solve one specific instance of this "problem".

ChrisA

[toc] | [prev] | [next] | [standalone]


#46717

FromDan Sommers <dan@tombstonezero.net>
Date2013-06-02 17:49 +0000
Message-ID<iALqt.35937$nm.1417@newsfe14.iad>
In reply to#46711
On Mon, 03 Jun 2013 03:20:52 +1000, Chris Angelico wrote:

> On Mon, Jun 3, 2013 at 3:04 AM, Rick Johnson
> <rantingrickjohnson@gmail.com> wrote:
>>  * Woefully inadequate because: Switching on or off the debug
>>    messages is only valid in the current module that the function was
>>    imported. What if you want to kill all debugprint messages
>>    EVERYWHERE? Do you really want to edit "debug = BOOLEAN" in every
>>    source file OR do something stupid like import debugprint and edit
>>    the DEBUG constant OR even dumber, edit the debugprint source
>>    code? GAWD NO!
> 
> Easy fix to this one. Instead of copying and pasting debugprint into
> everything, have it in a module and import it everywhere. Then the
> debug flag will be common to them all.

Or use the logging module.  It's easy to get going quickly (just call
logging.basicConfig at startup time), and with a little care and
feeding, you can control the output in more ways than can fit into the
margin.

Oh, yeah, I'm sure it introduces some overhead.  So does everything
else.

>>  * But even if you are willing to cope with all the "switch-
>>    on-and-off" nonsense, are you willing to have you code slowed by
>>    numerous calls to a dead function containing a comparison that
>>    will always be false?
> 
> Hmm. Could be costly ...

Yeah, all that time that I have left over and have to find something
else to do instead of debugging my program.  What a waste!  ;-)

Dan

[toc] | [prev] | [next] | [standalone]


#46719

FromRick Johnson <rantingrickjohnson@gmail.com>
Date2013-06-02 11:18 -0700
Message-ID<7fea8f79-830c-4d82-a899-eb2fcc1e6cdc@googlegroups.com>
In reply to#46717
On Sunday, June 2, 2013 12:49:02 PM UTC-5, Dan Sommers wrote:
> On Mon, 03 Jun 2013 03:20:52 +1000, Chris Angelico wrote:
> > On Mon, Jun 3, 2013 at 3:04 AM, Rick Johnson
> [...]
> Or use the logging module.  It's easy to get going quickly
> (just call logging.basicConfig at startup time), and with
> a little care and feeding, you can control the output in
> more ways than can fit into the margin. Oh, yeah, I'm sure
> it introduces some overhead.  So does everything else.

I hate log files, at least during development or testing. I prefer to debug on the command line or using my IDE. Log files are for release time, not development.

[toc] | [prev] | [next] | [standalone]


#46734

FromNed Batchelder <ned@nedbatchelder.com>
Date2013-06-02 16:45 -0400
Message-ID<mailman.2563.1370205952.3114.python-list@python.org>
In reply to#46719
On 6/2/2013 2:18 PM, Rick Johnson wrote:
> On Sunday, June 2, 2013 12:49:02 PM UTC-5, Dan Sommers wrote:
>> On Mon, 03 Jun 2013 03:20:52 +1000, Chris Angelico wrote:
>>> On Mon, Jun 3, 2013 at 3:04 AM, Rick Johnson
>> [...]
>> Or use the logging module.  It's easy to get going quickly
>> (just call logging.basicConfig at startup time), and with
>> a little care and feeding, you can control the output in
>> more ways than can fit into the margin. Oh, yeah, I'm sure
>> it introduces some overhead.  So does everything else.
> I hate log files, at least during development or testing. I prefer to debug on the command line or using my IDE. Log files are for release time, not development.
>
Rick, you should give the logging module a try.  The default 
configuration from basicConfig is that the messages all go to stderr, so 
no log files to deal with.  And it's configurable in the ways you want, 
plus a lot more.

--Ned.

[toc] | [prev] | [next] | [standalone]


#46770

FromMichael Torrie <torriem@gmail.com>
Date2013-06-02 23:49 -0600
Message-ID<mailman.2582.1370238575.3114.python-list@python.org>
In reply to#46719
On 06/02/2013 12:18 PM, Rick Johnson wrote:
> On Sunday, June 2, 2013 12:49:02 PM UTC-5, Dan Sommers wrote:
>> On Mon, 03 Jun 2013 03:20:52 +1000, Chris Angelico wrote:
>>> On Mon, Jun 3, 2013 at 3:04 AM, Rick Johnson
>> [...] Or use the logging module.  It's easy to get going quickly 
>> (just call logging.basicConfig at startup time), and with a little
>> care and feeding, you can control the output in more ways than can
>> fit into the margin. Oh, yeah, I'm sure it introduces some
>> overhead.  So does everything else.
> 
> I hate log files, at least during development or testing. I prefer to
> debug on the command line or using my IDE. Log files are for release
> time, not development.

Except that it's not.  Have you even looked at what the logging module
is?  It most certainly can log to stderr if you provide no logging
handler to write to a file.

[toc] | [prev] | [next] | [standalone]


#46774

FromChris Angelico <rosuav@gmail.com>
Date2013-06-03 17:17 +1000
Message-ID<mailman.2584.1370243836.3114.python-list@python.org>
In reply to#46719
On Mon, Jun 3, 2013 at 3:49 PM, Michael Torrie <torriem@gmail.com> wrote:
> On 06/02/2013 12:18 PM, Rick Johnson wrote:
>> On Sunday, June 2, 2013 12:49:02 PM UTC-5, Dan Sommers wrote:
>>> On Mon, 03 Jun 2013 03:20:52 +1000, Chris Angelico wrote:
>>>> On Mon, Jun 3, 2013 at 3:04 AM, Rick Johnson
>>> [...] Or use the logging module.  It's easy to get going quickly
>>> (just call logging.basicConfig at startup time), and with a little
>>> care and feeding, you can control the output in more ways than can
>>> fit into the margin. Oh, yeah, I'm sure it introduces some
>>> overhead.  So does everything else.
>>
>> I hate log files, at least during development or testing. I prefer to
>> debug on the command line or using my IDE. Log files are for release
>> time, not development.
>
> Except that it's not.  Have you even looked at what the logging module
> is?  It most certainly can log to stderr if you provide no logging
> handler to write to a file.

Plus, writing to a file actually makes a lot of sense for development
too. It's far easier to run the program the same way in dev and
release, which often means daemonized. I like to have Upstart manage
all my services, for instance.

ChrisA

[toc] | [prev] | [next] | [standalone]


#46777

FromAlister <alister.ware@ntlworld.com>
Date2013-06-03 08:01 +0000
Message-ID<S3Yqt.23009$ja6.6971@fx18.am4>
In reply to#46774
On Mon, 03 Jun 2013 17:17:12 +1000, Chris Angelico wrote:

> On Mon, Jun 3, 2013 at 3:49 PM, Michael Torrie <torriem@gmail.com>
> wrote:
>> On 06/02/2013 12:18 PM, Rick Johnson wrote:
>>> On Sunday, June 2, 2013 12:49:02 PM UTC-5, Dan Sommers wrote:
>>>> On Mon, 03 Jun 2013 03:20:52 +1000, Chris Angelico wrote:
>>>>> On Mon, Jun 3, 2013 at 3:04 AM, Rick Johnson
>>>> [...] Or use the logging module.  It's easy to get going quickly
>>>> (just call logging.basicConfig at startup time), and with a little
>>>> care and feeding, you can control the output in more ways than can
>>>> fit into the margin. Oh, yeah, I'm sure it introduces some overhead. 
>>>> So does everything else.
>>>
>>> I hate log files, at least during development or testing. I prefer to
>>> debug on the command line or using my IDE. Log files are for release
>>> time, not development.
>>
>> Except that it's not.  Have you even looked at what the logging module
>> is?  It most certainly can log to stderr if you provide no logging
>> handler to write to a file.
> 
> Plus, writing to a file actually makes a lot of sense for development
> too. It's far easier to run the program the same way in dev and release,
> which often means daemonized. I like to have Upstart manage all my
> services, for instance.
> 
> ChrisA

further point
the production logging code needs to be implemented and tested at 
development time anyway so why not make use of it instead of creating 
additional redundant code?



-- 
It is a lesson which all history teaches wise men, to put trust in ideas,
and not in circumstances.
		-- Emerson

[toc] | [prev] | [next] | [standalone]


#46718

FromRick Johnson <rantingrickjohnson@gmail.com>
Date2013-06-02 11:09 -0700
Message-ID<fadc8140-5276-41ff-9fcf-1c6ee1690809@v2g2000yqa.googlegroups.com>
In reply to#46711
On Jun 2, 12:20 pm, Chris Angelico <ros...@gmail.com> wrote:
> On Mon, Jun 3, 2013 at 3:04 AM, Rick Johnson
> >  * Woefully inadequate because: Switching on or off the debug
> >    messages is only valid in the current module that the
> >    function was imported. What if you want to kill all
> >    debugprint messages EVERYWHERE? Do you really want to edit
> >    "debug = BOOLEAN" in every source file OR do something
> >    stupid like import debugprint and edit the DEBUG constant
> >    OR even dumber, edit the debugprint source code? GAWD NO!
> Easy fix to this one. Instead of copying and pasting debugprint into
> everything, have it in a module and import it everywhere. Then the
> debug flag will be common to them all.

Ignoring the fact that you have "import everywhere", what if you want
to stop ALL debug messages? If you "import everywhere" to get them,
you then have to "edit everywhere" to stop them.

> Oh, and you probably want to add **kwargs to debugprint, because the
> print function does a lot more than sys.stdout.write does:

The kwargs to print are not germane to the issue, however noobs may be
watching so glad you pointed that one out.

> [...]
> py> timeit.timeit('debugprint("asdf") [...]
> 0.5838018519113444
>
> That's roughly half a second for a million calls to debugprint().
> That's a 580ns cost per call. Rather than fiddle with the language,
> I'd rather just take this cost.

I never purposely inject ANY superfluous cycles in my code except in
the case of testing or development. To me it's about professionalism.
Let's consider a thought exercise shall we?

  Imagine your an auto mechanic. You customer brings in his
  car and asks you to make some repairs. You make the
  repairs but you also adjust the air/fuel ratio to run
  "rich" (meaning the vehicle will get less MPG). Do you
  still pat yourself on the back and consider you've done a
  professional job?

I would not! However, you're doing the same thing as the mechanic when
your code executes superflouos calls and burns cycles for no other
reason than pure laziness. CPU's are not immortal you know, they have
a lifetime. Maybe you don't care about destroying someone's CPU,
however, i do!

I just wonder how many of your "creations" (aka: monstrosities!) are
burning cycles this very minute!

> [...]
> So you can eliminate part of the cost there, if it matters to you. If
> a half-microsecond cost is going to be significant to you, you
> probably should be looking at improving other areas, maybe using
> ctypes/cython, or possibly playing with the new preprocessor tricks
> that have been being discussed recently. There's really no need to
> change the language to solve one specific instance of this "problem".

That's like suggesting to the poor fella who's MPG is suffering
(because of your incompetent adjustments!) to buy fuel additives to
compensate for the loss of MPG. Why should he incur costs because you
are incompetent?

[toc] | [prev] | [next] | [standalone]


#46723

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-06-02 19:03 +0000
Message-ID<51ab96f2$0$29966$c3e8da3$5496439d@news.astraweb.com>
In reply to#46718
On Sun, 02 Jun 2013 11:09:12 -0700, Rick Johnson wrote:

> Maybe you don't care about destroying someone's CPU, however, i do!

And yet here you are, destroying millions of people's CPUs by sending 
them email or usenet messages filled with garbage.


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#46731

FromChris Angelico <rosuav@gmail.com>
Date2013-06-03 06:21 +1000
Message-ID<mailman.2561.1370204475.3114.python-list@python.org>
In reply to#46718
On Mon, Jun 3, 2013 at 4:09 AM, Rick Johnson
<rantingrickjohnson@gmail.com> wrote:
> On Jun 2, 12:20 pm, Chris Angelico <ros...@gmail.com> wrote:
>> On Mon, Jun 3, 2013 at 3:04 AM, Rick Johnson
>> >  * Woefully inadequate because: Switching on or off the debug
>> >    messages is only valid in the current module that the
>> >    function was imported. What if you want to kill all
>> >    debugprint messages EVERYWHERE? Do you really want to edit
>> >    "debug = BOOLEAN" in every source file OR do something
>> >    stupid like import debugprint and edit the DEBUG constant
>> >    OR even dumber, edit the debugprint source code? GAWD NO!
>> Easy fix to this one. Instead of copying and pasting debugprint into
>> everything, have it in a module and import it everywhere. Then the
>> debug flag will be common to them all.
>
> Ignoring the fact that you have "import everywhere", what if you want
> to stop ALL debug messages? If you "import everywhere" to get them,
> you then have to "edit everywhere" to stop them.

Example:

## debugprint.py
DEBUG = True
def debugprint(*a,**kw):
  if DEBUG:
    return print(*a,**kw)

## every other module
from debugprint import debugprint
debugprint("I got imported!")
def foo():
  debugprint("I got foo'd!")

See how many places you need to edit to change the DEBUG flag? You can
even do it at run time with this version of the code:

## toggle debugging
import debugprint
debugprint.DEBUG = not debugprint.DEBUG

And, as several others have pointed out, this is kinda sorta what the
logging module does, only it does it better. Same method; you import
the same module everywhere. It is THE SAME module.

>> That's roughly half a second for a million calls to debugprint().
>> That's a 580ns cost per call. Rather than fiddle with the language,
>> I'd rather just take this cost.
>
> I never purposely inject ANY superfluous cycles in my code except in
> the case of testing or development. To me it's about professionalism.

Why do you use Python? Clearly the only professional option is to use
raw assembler. Or possibly you could justify C on the grounds of
portability.

> Let's consider a thought exercise shall we?
>
>   Imagine your an auto mechanic. You customer brings in his
>   car and asks you to make some repairs. You make the
>   repairs but you also adjust the air/fuel ratio to run
>   "rich" (meaning the vehicle will get less MPG). Do you
>   still pat yourself on the back and consider you've done a
>   professional job?
>
> I would not! However, you're doing the same thing as the mechanic when
> your code executes superflouos calls and burns cycles for no other
> reason than pure laziness. CPU's are not immortal you know, they have
> a lifetime. Maybe you don't care about destroying someone's CPU,
> however, i do!

Better analogy: When you build a car, you incorporate a whole bunch of
gauges and indicators. They clutter things up, and they're extra
weight to carry; wouldn't the car get more MPG (side point: can I have
my car get more OGG instead? I like open formats) if you omit them?

> I just wonder how many of your "creations" (aka: monstrosities!) are
> burning cycles this very minute!

Every one that's written in a high level language. So that's Yosemite,
Minstrel Hall, Tisroc, KokoD, RapidSend/RapidRecv, and Vizier. And
that's just the ones that I've personally created and that I *know*
are currently running (and that I can think of off-hand). They're
wasting CPU cycles dealing with stuff that I, the programmer, now
don't have to. Now let's see. According to my server, right now, load
average is 0.21 - of a single-core Intel processor that was mid-range
back in 2009. And that's somewhat higher-than-normal load, caused by
some sort of usage spike a few minutes ago (and is dropping);
normally, load average is below 0.10.

At what point would it be worth my effort to rewrite all that code to
eliminate waste? Considering that I could build a new server for a few
hundred (let's say $1000 to be generous, though the exact price will
depend on where you are), or rent one in a top-quality data center for
$40-$55/month and not have to pay for electricity or internet, any
rewrite would need to take less than two days of my time to be
worthwhile. Let 'em burn cycles; we can always get more.

>> So you can eliminate part of the cost there, if it matters to you. If
>> a half-microsecond cost is going to be significant to you, you
>> probably should be looking at improving other areas, maybe using
>> ctypes/cython, or possibly playing with the new preprocessor tricks
>> that have been being discussed recently. There's really no need to
>> change the language to solve one specific instance of this "problem".
>
> That's like suggesting to the poor fella who's MPG is suffering
> (because of your incompetent adjustments!) to buy fuel additives to
> compensate for the loss of MPG. Why should he incur costs because you
> are incompetent?

He's welcome to push a wheelbarrow if he doesn't want the overhead of
a car. The car offers convenience, but at a cost. This is an eternal
tradeoff.

ChrisA

[toc] | [prev] | [next] | [standalone]


#46885

Fromjmfauth <wxjmfauth@gmail.com>
Date2013-06-04 05:23 -0700
Message-ID<a42a977e-66b3-42e0-97fd-be3ca821b836@w15g2000vbn.googlegroups.com>
In reply to#46718
On 2 juin, 20:09, Rick Johnson <rantingrickjohn...@gmail.com> wrote:

> >
> >
>
> I never purposely inject ANY superfluous cycles in my code except in
> the case of testing or development. To me it's about professionalism.
> Let's consider a thought exercise shall we?
>


--------


The flexible string representation is the perfect example
of this lack of professionalism.
Wrong by design, a non understanding of the mathematical logic,
of the coding of characters, of Unicode and of the usage of
characters (everything is tight together).

How is is possible to arrive to such a situation ?
The answer if far beyond my understanding (although
I have my opinion on the subject).

jmf

[toc] | [prev] | [next] | [standalone]


#46898

Fromrusi <rustompmody@gmail.com>
Date2013-06-04 06:29 -0700
Message-ID<1815a2d3-5d7f-401b-a320-6cc6c7fc2025@qn4g2000pbc.googlegroups.com>
In reply to#46885
On Jun 4, 5:23 pm, jmfauth <wxjmfa...@gmail.com> wrote:
> On 2 juin, 20:09, Rick Johnson <rantingrickjohn...@gmail.com> wrote:
>
>
>
> > I never purposely inject ANY superfluous cycles in my code except in
> > the case of testing or development. To me it's about professionalism.
> > Let's consider a thought exercise shall we?
>
> --------
>
> The flexible string representation is the perfect example
> of this lack of professionalism.
> Wrong by design, a non understanding of the mathematical logic,
> of the coding of characters, of Unicode and of the usage of
> characters (everything is tight together).
>
> How is is possible to arrive to such a situation ?
> The answer if far beyond my understanding (although
> I have my opinion on the subject).
>
> jmf

The Clash of the Titans

Lé jmf chârgeth with mightƴ might
And le Mond underneath trembleth
Now RR mounts his sturdy steed
And the windmill yonder turneth

[toc] | [prev] | [next] | [standalone]


#46901

FromMark Lawrence <breamoreboy@yahoo.co.uk>
Date2013-06-04 14:35 +0100
Message-ID<mailman.2647.1370352913.3114.python-list@python.org>
In reply to#46898
On 04/06/2013 14:29, rusi wrote:
> On Jun 4, 5:23 pm, jmfauth <wxjmfa...@gmail.com> wrote:
>> On 2 juin, 20:09, Rick Johnson <rantingrickjohn...@gmail.com> wrote:
>>
>>
>>
>>> I never purposely inject ANY superfluous cycles in my code except in
>>> the case of testing or development. To me it's about professionalism.
>>> Let's consider a thought exercise shall we?
>>
>> --------
>>
>> The flexible string representation is the perfect example
>> of this lack of professionalism.
>> Wrong by design, a non understanding of the mathematical logic,
>> of the coding of characters, of Unicode and of the usage of
>> characters (everything is tight together).
>>
>> How is is possible to arrive to such a situation ?
>> The answer if far beyond my understanding (although
>> I have my opinion on the subject).
>>
>> jmf
>
> The Clash of the Titans
>
> Lé jmf chârgeth with mightƴ might
> And le Mond underneath trembleth
> Now RR mounts his sturdy steed
> And the windmill yonder turneth
>

+1 funniest poem of the week :)

-- 
"Steve is going for the pink ball - and for those of you who are 
watching in black and white, the pink is next to the green." Snooker 
commentator 'Whispering' Ted Lowe.

Mark Lawrence

[toc] | [prev] | [next] | [standalone]


#47012

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-06-05 05:03 +0000
Message-ID<51aec6a7$0$11118$c3e8da3@news.astraweb.com>
In reply to#46885
On Tue, 04 Jun 2013 05:23:19 -0700, jmfauth wrote:

> How is is possible to arrive to such a situation ? The answer if far
> beyond my understanding

Truer words have never been spoken.


> (although I have my opinion on the subject).


http://en.wikipedia.org/wiki/Dunning–Kruger_effect



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#46714

FromAndrew Berg <robotsondrugs@gmail.com>
Date2013-06-02 12:30 -0500
Message-ID<mailman.2554.1370194233.3114.python-list@python.org>
In reply to#46708
I don't think you go far enough. Obviously we need way more flexibility. A simple on/off is okay for some things, but a finer granularity
would be really helpful because some things are more important than others. And why stop at stdout/stderr? We need to add a consistent way
to output these messages to files too in case we need to reference them again. The messages should have a consistent format as well. Why add
the same information to each message when it would be much simpler to simply define a default format and insert the real meat of the message
into it? It really seems like we should already have something like this. Hmm.....
-- 
CPython 3.3.2 | Windows NT 6.2.9200 / FreeBSD 9.1

[toc] | [prev] | [next] | [standalone]


#46716

FromChris Angelico <rosuav@gmail.com>
Date2013-06-03 03:34 +1000
Message-ID<mailman.2556.1370194494.3114.python-list@python.org>
In reply to#46708
On Mon, Jun 3, 2013 at 3:30 AM, Andrew Berg <robotsondrugs@gmail.com> wrote:
> I don't think you go far enough. Obviously we need way more flexibility. A simple on/off is okay for some things, but a finer granularity
> would be really helpful because some things are more important than others. And why stop at stdout/stderr? We need to add a consistent way
> to output these messages to files too in case we need to reference them again. The messages should have a consistent format as well. Why add
> the same information to each message when it would be much simpler to simply define a default format and insert the real meat of the message
> into it? It really seems like we should already have something like this. Hmm.....

You have a really good point there. I'm sure I could think of a really
good way to do all this, but I'm stuck... it's like there's a log jam
in my head...

(Okay, maybe I should go to bed now, my puns are getting worse.
Considering how late it is, I'll probably sleep like a log.)

ChrisA

[toc] | [prev] | [next] | [standalone]


#46722

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-06-02 18:58 +0000
Message-ID<51ab95d5$0$29966$c3e8da3$5496439d@news.astraweb.com>
In reply to#46708
On Sun, 02 Jun 2013 10:04:00 -0700, Rick Johnson wrote:

> Many
> languages provide a function, method, or statement by which users can
> write easily to stdout, and Python is no exception with it's own "print"
> function. However, whilst writing to stdout via "print" is slightly less
> verbose than calling the "write" method of "sys.stdout", we don't really
> gain much from this function except a few keystrokes... is this ALL
> print should be? A mere syntactical sugar?

Perhaps you should read the docs before asking rhetorical questions, 
because the actual answer is, No, print is not mere syntactical sugar 
saving a few keystrokes.


Help on built-in function print in module builtins:

print(...)
    print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)

    Prints the values to a stream, or to sys.stdout by default.
    Optional keyword arguments:
    file:  a file-like object (stream); defaults to the current
           sys.stdout.
    sep:   string inserted between values, default a space.
    end:   string appended after the last value, default a newline.
    flush: whether to forcibly flush the stream.


Still not powerful enough for you? Easily fixed:

import builtins

# The higher the verbosity, the more messages are printed.
verbosity = 2

def print(*args, level=1, **kwargs):
    if level >= verbosity:
        builtins.print(*args, **kwargs)


print("debug message", level=4)  # Only prints if verbosity >= 4
print("info message", level=3)
print("warning message", level=2)
print("critical message", level=1)  # Only prints if verbosity >= 1


Trivial enough to embed in each module that needs it, in which case each 
module can have its own verbosity global variable. Or you can put it in a 
helper module, with a single, application-wide global variable, and use 
it like this:

import verbose_print
print = verbose_print.print
verbose_print.verbosity = 3
print("some message", level=4)

Of course, in practice you would set the verbosity according to a command 
line switch, or an environment variable, or a config file, and not hard 
code it in your source code.


> I've found that many subtle bugs are caused by not limiting the inputs
> to sane values (or types). And with Python's duct typing 

Nothing worse than having pythons roaming through your ducts, eating your 
ducks.


> and implicit
> casting to Boolean, you end up with all sorts of misleading things
> happening! Maybe you're testing for truth values and get a string
> instead; which screws everything up!!!

Only if you're a lousy programmer who doesn't understand Python's truth 
model.


> A "wise programmer" may think he's solved the problem by writing a
> function called "debugprint" that looks like this:
> 
>     def debugprint(*args):
>         if DEBUG == True:
>             print(*args)

No no no, that's not how you do it. It should be:

    if DEBUG == True == True:

Wait, no, I got that wrong. It should be:

    if DEBUG == True == True == True:

Hang on, I've nearly got it!

    if DEBUG == True == True == True == True:

Or, you could program like a professional, and say:

    if DEBUG:

By the way, why is DEBUG a constant? Doesn't that defeat the purpose?


> However that solution is at best woefully inadequate and at worse a
> cycle burner!

Certainly you don't want to be burning cycles. Imagine the pollution from 
the burning rubber tyres!


>  * Woefully inadequate because: Switching on or off the debug
>    messages is only valid in the current module that the function was
>    imported. What if you want to kill all debugprint messages
>    EVERYWHERE? 

You start by learning how Python works, and not making woefully incorrect 
assumptions.


>    Do you really want to edit "debug = BOOLEAN" in every
>    source file 

Python does not work that way.


>    OR do something stupid like import debugprint and edit
>    the DEBUG constant 

Heaven forbid that people do something that actually works the way Python 
is designed to work.


>    OR even dumber, edit the debugprint source code?
>    GAWD NO!
>
>  * But even if you are willing to cope with all the "switch-
>    on-and-off" nonsense, are you willing to have you code slowed by
>    numerous calls to a dead function containing a comparison that will
>    always be false?

And of course you have profiled your application, and determined that the 
bottleneck in performance is the calls to debugprint, because otherwise 
you are wasting your time and ours with premature optimization.

Life is hard. Sometimes you have to choose between performance and 
debugging.


> This
> realization has brought me to the conclusion that Python (and other
> languages) need a "scoped print function". What is a "scoped print
> function" anyway?  Well what i am proposing is that Python include the
> following "debug switches" in the language:
> 
>   ------------------------------
>    Switch: "__GLOBALDEBUG__"
>   ------------------------------
>   Global switching allows a programmer to instruct the interpreter to
>   IGNORE all print functions or to EVALUATE all print functions by
>   assigning a Boolean value of True or False respectively to the global
>   switch (Note: global switch always defaults to True!).

If you really care about this premature optimization, you can do this:

if __debug__:
    print("whatever")


You then globally disable these print calls by running Python with the -O 
switch.


>   Any script that includes the assignment "__GLOBALDEBUG__ = False" will
>   disable ALL debug print messages across the entire interpreter
>   namespace. In effect, all print statements will be treated as comments
>   and ignored by the interpreter. No dead functions will be called and
>   no false comparisons will be made!
> 
>   (Note: __GLOBALDEBUG__ should not be available in any local namespace
>   but accessed only form the topmost namespace. Something like:
>   __main__.__GLOBALDEBUG__ = Boolean

Python does not work like that. Perhaps you should learn how to program 
in Python before telling us how it should be improved?


>   ------------------------------
>    Switch: "__LOCALDEBUG__"
>   ------------------------------
>   Local switching allows a programmer to turn on (or off) debug messages
>   in the module it was declared. Not sure if this should be more
>   specific than modules; like classes, blocks, or functions??? Of course
>   this declaration will be overridden by any global switch.

So, it will be utterly useless then, since __LOCALDEBUG__ has no effect, 
and __GLOBALDEBUG__ overrides it. Great.


> My only
> concern is that some programmers may be confused why their print calls 
> are not working and may not have the capacity to resolve that function
> named "print" is tied to the global and local switches named
> "__GLOBAL_DEBUG__" and "__LOCAL_DEBUG__". To prevent any cognitive
> dissonance it may be desirable to introduce a new function called
> "debugprint".

That's not what cognitive dissonance means. The word you are looking for 
is "confusion".

Cognitive dissonance is the mental stress and anguish a person feels when 
deep down they know that they are the best, most intelligent, most expert 
Python programmer on the planet, better even than Python's creator, and 
yet every time they open their mouth to tell the world how Python gets it 
wrong and how to fix it, they just get shot down in flames.


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#46732

FromChris Angelico <rosuav@gmail.com>
Date2013-06-03 06:28 +1000
Message-ID<mailman.2562.1370204934.3114.python-list@python.org>
In reply to#46722
On Mon, Jun 3, 2013 at 4:58 AM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
>> I've found that many subtle bugs are caused by not limiting the inputs
>> to sane values (or types). And with Python's duct typing
>
> Nothing worse than having pythons roaming through your ducts, eating your
> ducks.

Steven, you misunderstand. It's more about using your ducts to type
code. Have you seen the Mythbusters episode where they're trying to
enter a building surreptitiously? ("Crimes and Mythdemeanors 1", I
think, if you want to look it up.) At one point, we can CLEARLY hear
one of the hosts, moving along a duct, *typing*. We can hear the
click-click-click of giant keys.

Hah. Knew I could trust Youtube. http://www.youtube.com/watch?v=5LovGVrrIuk

ChrisA

[toc] | [prev] | [next] | [standalone]


#46827

FromRick Johnson <rantingrickjohnson@gmail.com>
Date2013-06-03 18:37 -0700
Message-ID<a46a1835-9960-4cc3-b15e-7c027f054919@googlegroups.com>
In reply to#46722
On Sunday, June 2, 2013 1:58:30 PM UTC-5, Steven D'Aprano wrote:
> On Sun, 02 Jun 2013 10:04:00 -0700, Rick Johnson wrote:

Oh Steven, you've really outdone yourself this time with the
theatrics. I hope you scored some "cool points" with your
minions. Heck, you almost had me convinced until i slapped
myself and realized your whole argument is just pure BS. For
the sake of the lemmings, i must dissect your BS and expose
it's methane emitting innards for all to smell.

> > Many
> > languages provide a function, method, or statement by which users can
> > write easily to stdout, and Python is no exception with it's own "print"
> > function. However, whilst writing to stdout via "print" is slightly less
> > verbose than calling the "write" method of "sys.stdout", we don't really
> > gain much from this function except a few keystrokes... is this ALL
> > print should be? A mere syntactical sugar?
>
> Perhaps you should read the docs before asking rhetorical questions,
> because the actual answer is, No, print is not mere syntactical sugar
> saving a few keystrokes.
> [...]

And perhaps you should read a dictionary and obtain (at
minimum) a primary school level education in English before
making such foolish statements, because, OBVIOUSLY you don't
know the definition of "syntactical sugar"... shall i
educate you?


    ############################################################
    #               Wikipedia: "syntactic sugar"               #
    ############################################################
    # In computer science, syntactic sugar is syntax within a  #
    # programming language that is designed to make things     #
    # easier to read or to express. It makes the language      #
    # "sweeter" for human use: things can be expressed more    #
    # clearly, more concisely, or in an alternative style that #
    # some may prefer[...]                                     #
    ############################################################

The print function is the very definition of a "syntactic sugar".

For example:
    print("some sting")

is much more readable than:

    sys.stdout.write("some string"+"\n")

or:

    sys.stderr.write("some string"+"\n")

or:

    streamFoo.write("blah")

But wait, there's more!

    ############################################################
    #         Wikipedia: "syntactic sugar" (continued)         #
    ############################################################
    # [...]Specifically, a construct in a language is called   #
    # syntactic sugar if it can be removed from the language   #
    # without any effect on what the language can do:          #
    # functionality and expressive power will remain the same. #
    ############################################################

Again, the removal of a print function (or print statement)
will not prevent users from calling the write method on
sys.stdout or sys.stderr (or ANY "stream object" for that matter!)

The only mistake i made was to specify stdout.write
specifically instead of generally referring to the print
function as a sugar for "stream.write()".

> > I've found that many subtle bugs are caused by not limiting the inputs
> > to sane values (or types). And with Python's duct typing
> [...]
> > and implicit
> > casting to Boolean, you end up with all sorts of misleading things
> > happening! Maybe you're testing for truth values and get a string
> > instead; which screws everything up!!!
> Only if you're a lousy programmer who doesn't understand Python's truth
> model.

I understand the Python truth model quite well, i just don't
happen to like it. Implicit conversion to Boolean breaks the
law of "least astonishment".

Many times you'll get a result (or an input) that you expect
to be a Boolean, but instead is a string. A good example of
poor coding is "dialog box return values". Take your
standard yes/no/cancel dialog, i would expect it to return
True|False|None respectively, HOWEVER, some *idiot* decided
to return the strings 'yes'|'no'|'cancel'.

If you tried to "bool test" a string (In a properly designed
language that does NOT support implicit Boolean conversion)
you would get an error if you tried this:

  py> string = " "
  py> if string:
  ...     do_something()
  ERROR: Cannot convert string to Boolean!

However, with Python's implicit conversion to Boolean, the
same conditional will ALWAYS be True: because any string
that is not the null string is True (as far as Python is
concerned). This is an example of Python devs breaking TWO
Zens at once:

 "explicit is better than implicit"
 "errors should NEVER pass silently"

And even though Python does not raise an error, it should!

> > A "wise programmer" may think he's solved the problem by writing a
> > function called "debugprint" that looks like this:
> > >     def debugprint(*args):
> >         if DEBUG == True:
> >             print(*args)
> No no no, that's not how you do it. It should be:
>     if DEBUG == True == True:
> Wait, no, I got that wrong. It should be:
>     if DEBUG == True == True == True:
> Hang on, I've nearly got it!
>     if DEBUG == True == True == True == True:
> Or, you could program like a professional, and say:
>     if DEBUG:

Obviously you don't appreciate the value of "explicit enough".

  if VALUE:

is not explicit enough, however

  if bool(VALUE)

or at least:

  if VALUE == True

is "explicit enough". Whereas:

 if VALUE == True == True

is just superflous. But that's just one example. What about this:

  if lst:

I don't like that because it's too implict. What exactly
about the list are we wanting to test? Do we want to know if
we have list object or a None object, OR, do we want to know
if we have a list object AND the list has members? I prefer
to be explicit at the cost of a few keystrokes:

  if len(lst) > 0:

Covers the "has members" test and:

  if lst is not None

covers the "existence" test.

I know Python allows me to be implicit here, however, i am
choosing to be explicit for the sake of anyone who will read
my code in the future but also for myself, because being
explicit when testing for truth can catch subtle bugs.

Consider the following:

 What if the symbol `value` is expected to be a list,
 however, somehow it accidentally got reassigned to another
 type. If i choose to be implicit and use: "if value", the
 code could silently work for a type i did not intend,
 therefore the program could go on for quite some time before
 failing suddenly on attribute error, or whatever. 

However, if i choose to be explicit and use:

  "if len(VALUE) > 0:

then the code will fail when it should: at the comparison
line.  Because any object that does not provide a __len__
method would cause Python to raise NameError.

By being "explicit enough" i will inject readability and
safety into my code base. (that's twice you've been schooled
in one reply BTW!)

> By the way, why is DEBUG a constant? Doesn't that defeat the purpose?

Hmm, I agree!. You're actually correct here. We should not
be reassigning constants should we? (<--rhetorical) In
correcting me you've exposed yet another design flaw with
Python. Sadly Python DOES allow reassignment of CONSTANTS.

> >  * But even if you are willing to cope with all the "switch-
> >    on-and-off" nonsense, are you willing to have you code slowed by
> >    numerous calls to a dead function containing a comparison that will
> >    always be false?
> And of course you have profiled your application, and determined that the
> bottleneck in performance is the calls to debugprint, because otherwise
> you are wasting your time and ours with premature optimization.
> Life is hard. Sometimes you have to choose between performance and
> debugging.

Only if your language does not provide a proper debugprint
function or provide the tools to create a proper debug print
function. I detest true global variables, however, there are
some legitimate reasons for true globals in every language.
This "debugprint" problem is one of those reasons.

> > This
> > realization has brought me to the conclusion that Python (and other
> > languages) need a "scoped print function". What is a "scoped print
> > function" anyway?  Well what i am proposing is that Python include the
> > following "debug switches" in the language:
> > >   ------------------------------
> >    Switch: "__GLOBALDEBUG__"
> >   ------------------------------
> >   Global switching allows a programmer to instruct the interpreter to
> >   IGNORE all print functions or to EVALUATE all print functions by
> >   assigning a Boolean value of True or False respectively to the global
> >   switch (Note: global switch always defaults to True!).
> If you really care about this premature optimization, you can do this:
> if __debug__:
>     print("whatever")

That's hideous! Two lines of code to make a single debug
message, are you joking? I realize Python will allow me to
place the entire statement on one line, however i refuse to
do that also. I am very strict about my block structure and
styles, and even the consistent inconsistency of the great
GvR will not sway me away from adherence to my consistent
readable style.


> You then globally disable these print calls by running Python with the -O
> switch.
> >   Any script that includes the assignment "__GLOBALDEBUG__ = False" will
> >   disable ALL debug print messages across the entire interpreter
> >   namespace. In effect, all print statements will be treated as comments
> >   and ignored by the interpreter. No dead functions will be called and
> >   no false comparisons will be made!
> > >   (Note: __GLOBALDEBUG__ should not be available in any local namespace
> >   but accessed only form the topmost namespace. Something like:
> >   __main__.__GLOBALDEBUG__ = Boolean
> Python does not work like that. Perhaps you should learn how to program
> in Python before telling us how it should be improved?

And perhaps you should listen to diverse ideas and be open
to change instead of clinging to your guns and religion.

> >   ------------------------------
> >    Switch: "__LOCALDEBUG__"
> >   ------------------------------
> >   Local switching allows a programmer to turn on (or off) debug messages
> >   in the module it was declared. Not sure if this should be more
> >   specific than modules; like classes, blocks, or functions??? Of course
> >   this declaration will be overridden by any global switch.
> So, it will be utterly useless then, since __LOCALDEBUG__ has no effect,
> and __GLOBALDEBUG__ overrides it. Great.

Of course global debug overrides local debug, what's the
purpose of global switching if it cannot override local
switching? "__GLOBALDEBUG__ = False" would disables ALL
debug messages EVERYWHERE. Yes, you are correct on this
issue. It would be the same as setting a command line switch.
However, you misunderstand __LOCALDEBUG__. When global
debugging is "on" "__LOCALDEBUG__ = False" will disable
debug messages ONLY in the module for which it was declared.

[toc] | [prev] | [next] | [standalone]


Page 1 of 6  [1] 2 3 4 5 6  Next page →

Back to top | Article view | comp.lang.python


csiph-web