Live data from Hacker News

Icecream: Never use print() to debug again in Python

github.com

221–230 of 271 posts

Re: Icecream: Never use print() to debug again in Python

#221
post #60

Earlier quoted context omitted.

Absolutely, I don't understand why using print() or its equivalent in other languages is looked down upon. It's quick way to narrow down the "area of search" before bringing in the big guns.

How is changing code simpler than literally clicking on the line number to set a breakpoint?

When I use a debugger I often feel like I'm looking through a soda straw. I can only see the state at that one instance in time. Just because I know the line of code where the exception occurred, doesn't tell me which data caused it, and breaking on exceptions is often too late. Instead I'm stuck hitting continue over and over until I finally see something out of place, realize I went to far and have to start over again. With logging, I have the entire history at my fingertips which I can skim or grep to quickly pinpoint the data that caused things to go wrong.

More fairly, it is a trade-off with the debugger giving wide visibility into state, but narrow visibility temporally, and logging giving narrow visibility into state (just what you logged), but broad temporal visibility. They both have their place, but I find that logging narrows things down more quickly, while the debugger helps me understand the problem by walking through step-by-step, assuming the problem isn't obvious once narrowed down.

Re: Icecream: Never use print() to debug again in Python

#222
post #66

Earlier quoted context omitted.

You can also use the breakpoint() introduced in py3.7 via PEP533 https://www.python.org/dev/peps/pep-0553/

Bump. This is the most correct way to debug python programs VS using print statement.

Most correct you say? Based on what? Mind you we're talking about code that will never even ship in the vast majority of cases. Ergo, do whatever works best for you.

Re: Icecream: Never use print() to debug again in Python

#223

I am always going to use print to debug in every programming language I can until the day I die.

It's a failure of debuggers that they haven't cleared the very low bar of obviousness and ease of use of print(). I'm very much a novice, but RStudio was the first environment that made debugging so easy I didn't feel the need to use print().

Re: Icecream: Never use print() to debug again in Python

#224
post #184

Earlier quoted context omitted.

Yes, print() and breakpoints are different tools with different uses and there's cases where one is superior to the other. This is why some tools now offer logpoints, which are basically print() inserted via a breakpoint UI rather than in your code where you can forget to remove them

Oh please tell me about those tools.

Visual studio does trace points [0]

[0] https://docs.microsoft.com/en-us/visualstudio/debugger/using...

Re: Icecream: Never use print() to debug again in Python

#225

You can do the same thing with Python 3.8+ by using f-strings and just appending "=" to the variable name: >>> print(f"{d['key'][1]=}") d['key'][1]='one'

Hey! I'm Ansgar. I wrote Icecream.

f-strings's `=` is awesome. I'm overjoyed it was added to Python. I use it all the time.

That said, IceCream does bring more to the table, like:

  - Stynax highlighting.
  - Pretty prints data structures.
  - Returns its value for nesting.
  - Integrates with logging via `ic.configureOutput()`.
etc

I hope that helps!

Re: Icecream: Never use print() to debug again in Python

#226
post #151

Earlier quoted context omitted.

I don't understand your wheel analogy, sorry. > You might not even know which wheel to jam the debugger stick into, if the behaviour is complex. If you don't know where to put a breakpoint, how do you know where to put a print statement?

Imagine putting breakpoints in multiple tight loops in the stage of narrowing the search space. Imagine how many times you need to click next. A conditional breakpoint will only help if you know the condition you're looking for, but there's stage before that of "Well, what looks strange during execution". Also for multithreaded code, stopping one thread dead for long enough for a human to investigate it can inadverte…

> Imagine putting breakpoints in multiple tight loops in the stage of narrowing the search space.

If you have enough loops to make breakpoints impossible to use, you've likely got enough log output that you're not going to be able to parse. You're almost certainly going to look for other ways of narrowing the search space.

> stopping one thread dead for long enough for a human to investigate it can inadvertently resolve all sorts of race conditions.

Stopping one thread for long enough to do console IO has the same effect. Especially if you're using python, you'll need a lock to synchronise the print statement across your threads!

Re: Icecream: Never use print() to debug again in Python

#227
post #83
post #60

Earlier quoted context omitted.

Absolutely, I don't understand why using print() or its equivalent in other languages is looked down upon. It's quick way to narrow down the "area of search" before bringing in the big guns.

> It's quick way to narrow down the "area of search" before bringing in the big guns. What are the big guns? with a debugger, I can stick a breakpoint and look at the entire state of everything. Given we're talking about Python, in pycharm [0] you can even execute your print statements in the debugger if you so wish. If you get the location wrong, or want to see what's going on elsewhere you can just continue executi…

> in pycharm [0] you can even execute your print statements in the debugger if you so wish

In my experience, debuggers are really good to expose hidden control flow. But usually, I know the flow, and using a debugger for human-in-the-middle print statements is just going to slow me down. Worse, those print statements are ephemeral, so I'm disinclined to write a nice formatter.

Print debugging leverages the language -- want to print in a certain condition? Easy. Have a recursive structure, an array, or a graph that you need to investigate? A naked print sucks, a custom formatter is great. Need to check some preconditions/postconditions? Do that in code. Don't try to check that stuff by hand in the debugger.

Speaking personally... the only thing I like about icecream is that ic(foo) both prints and returns foo, because you can inject it into code basically for free. But I already have a solution to that:

  def ic(x): print(x); return x

Re: Icecream: Never use print() to debug again in Python

#228
post #151

Earlier quoted context omitted.

Imagine putting breakpoints in multiple tight loops in the stage of narrowing the search space. Imagine how many times you need to click next. A conditional breakpoint will only help if you know the condition you're looking for, but there's stage before that of "Well, what looks strange during execution". Also for multithreaded code, stopping one thread dead for long enough for a human to investigate it can inadverte…

What I imagine Macha is arguing for is that the cost of using print is extremely small, smaller at least than breakpoints. No one is saying breakpoints are useless, sometimes printing is 'cheaper' in time and effort in order to locate the region code of code in which using breakpoints is cheaper.

> the cost of using print is extremely small, smaller at least than breakpoints.

I don't think it is, at all. The cost of using print is re-running your applciation with a code change, whereas the cost of a breakpoint is re-running your application with a breakpoint. Clicking in a gutter in an editor, pressing a keyboard shortcut, or typing "b " into your debugger is no more time or effort than adding a print statement, and re-running your program.

Re: Icecream: Never use print() to debug again in Python

#229

Earlier quoted context omitted.

Maybe C++ fixed type safety, but it introduced lot of complexity and bugs for no actual added value. For instance, because of stateful ios objects, it's close to impossible to write correct code outputing hex on first attempt. I'm sure that lot of C++ code outputing hex is just plain wrong. Given that C++ keeps getting more and more complex features, it is just amazing that C++ I/O is still so inconvenient, opaque an…

I mean it's not particularly pretty but what's so bad about this? std::cout

That construction is ok. But usually you want formatted output, let's say align to byte, and pad with zeroes. I've seen oftentimes (and did myself):

    std::cout 
This appears to work until someone change the alignment to left somewhere in the code. Hence the correct code is:

    // C++ type-safe equiv to printf("%-02x",my_int) - it's called progress
    std::cout 
Also, is it relevant to keep the final 'dec' when we assume we can't assert the ios left/right state, so why could we assert the hex/dec state? Or maybe was it a bug to change alignment to left, and not restore it to right afterwards? Or maybe should you restore ios state in some centrol place, and never pass your iostream to some external libs? Discussions and wars ahead. Note that the bug above is very nasty because it will change say "02" into "20", which looks perfectly valid.

Note: I just noticed that in C++20, there is new formatted string proposal. You can't stop progress, but neither can you speed it up it seems.

Note2: the 'std::' spam is yet another indication that C++ is lacking common sense and utterly broken.

Post reply on HN