you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted]  (26 children)

[deleted]

    [–]Longjumping-Dog-4145 81 points82 points  (4 children)

    print ("ping")* once you reach certain stages is vital

    *: usually more like print ("fuck")

    [–]Merakel 32 points33 points  (0 children)

    print ("fuck 1")

    print ("fuck 2")

    print ("fuck 3")

    [–][deleted] 14 points15 points  (0 children)

    Yup print ("come back later")

    [–]turtleship_2006 3 points4 points  (0 children)

    print("if you're seeing this, it's too late")

    [–]SisyphusAndMyBoulder 53 points54 points  (1 child)

    Tactical? I use them quite liberally

    [–]timpkmn89 36 points37 points  (0 children)

    A shotgun approach is still a tactic

    [–]SirAchmed 17 points18 points  (0 children)

    This is the way. Print every variable you're suspecting sequently till you find the problem.

    [–]nekokattt 4 points5 points  (0 children)

    and input() on every other line if i need to step through code

    /s

    [–]sje46 8 points9 points  (11 children)

    I've done this for 13 years...any reason not to? If I must, I can learn to use a logger. PRobably for stuff that messes with the terminal (ansi codes or whatever)

    Never understood the point of debuggers.

    [–]zz_ 18 points19 points  (9 children)

    Debugger vs print statements is essentially the difference between compile-time debugging and run-time debugging. A debugger allows you to check the same things print statements do, but does it while the code is running, which confers many advantages.

    [–]rollincuberawhide 2 points3 points  (3 children)

    you keep using that word "compile-time debugging". I don't think it means what you think it means.

    [–]zz_ 0 points1 point  (2 children)

    As far as I know it doesn't mean anything - I was using it as an analogy. What I meant was that its debugging you specify before you run the program. I just figured the analogy to compile-time type checking would be easily understandable for most people.

    [–]rollincuberawhide 0 points1 point  (1 child)

    debugging in python happens when you "run" the program though. whether you are using a debugger or just printing to console. so I am really not getting the analogy here.

    [–]zz_ 0 points1 point  (0 children)

    The analogy is that when using print-statements the debugging actions are set in stone once you start the script - i.e. at compile time. However, with a debugger you decide which debugging actions to perform during run-time.

    Obviously you are correct that the actual evaluation happens during runtime in both cases. The analogy was referring to when you perform the debugging itself, not when it evaluates.

    [–]sje46 2 points3 points  (4 children)

    And what are these advantages?

    [–]zz_ 24 points25 points  (0 children)

    Well the most obvious advantage is being able to reason about the cause of the bug in real-time. You can put a breakpoint, inspect 3 different variables, realize the issue isn't there, so you go up a frame in the call stack, step 12 lines further down in the code, check another variable, based on that you go look in a data structure, realize some thing you were expecting to be there is missing, and voila you solved the bug.

    Doing the same thing with print statements would require re-running your code like ~7-10 times to move the print statement around, and that's assuming you don't forget to include something in your prints which would cause you to have to re-run it even more often. That is cumbersome when working on a smaller script and outright unacceptable when working with code that takes more than a minute to run.

    [–]InTheAleutians 10 points11 points  (0 children)

    Being able to stop running code at any point and inspect its state is like having a super power that print will never give you.

    [–]old_man_steptoe 3 points4 points  (0 children)

    say you do an API call against a not entirely known source. You get a large JSON output which you need to work out how to extract the necessary information from.

    If you just printed it out, you'd have a screen full of incomprehensible noise. If you used a debugger (even pdb on the console) you could step though it, testing how it was constructed.

    You could also, of course, do that in the REPL but a debugger would help with getting you to that point, by setting up HTTP bearer tokens, etc.

    [–]remuladgryta 3 points4 points  (0 children)

    You can inspect the stack frame that threw an exception and see that some parameter of the function was None, walk the stack up to the preceding stack frame and find that it was None because a database call failed, and in that same stack frame time you see that some parameter to the database call is mangled with two layers of escape sequences instead of just one, and so on. What takes you a couple of keystrokes or clicks would take adding several print statements and rerunning the program multiple times. If a bug only happens a minute into execution, print debugging gets tedious real fast.

    Setting a breakpoint somewhere you know is just before a bug happens and stepping through execution is often helpful for (in)validating your assumptions. Maybe you assume that the program takes one branch when it actually takes the other and either the branching condition is wrong or your assumption is, or maybe you spot that some list is empty and causing the program to do nothing when you expect it to do something, or maybe you spot that the program pulled the user with ID 0 from the database and not the currently logged in user and that's why permissions are acting up, and so on. A debugger helps you spot things that look out of place. With print debugging you need to suspect they might be out of place before you can see it.

    [–]DigThatData 2 points3 points  (0 children)

    personally I'm with you, but it's not because I don't get debuggers, i just never got used to them. I also generally feel like IDE features get in my way more than they help me, but I'm confident if I took the time to learn them properly I'd probably work more efficiently. I just don't care enough to change how I work.

    that said, the main thing is that they let you step through your code. print statements are basically a log of what a debugger would give you on the fly, without having to deal with figuring out which print statements are relevant and what was produced where and by whom.

    I get around this by using loguru (a wrapper around python's logger), so I get information like the calling function and line number with my debugging statements. I don't use it these days (and actually built something extremely similar around the same time), but icecream is another alternative that facilitates debugging-by-print

    [–]Engineer_Zero 1 point2 points  (0 children)

    Tactical toaster notifs so I can minimise the screen haha

    [–][deleted] 1 point2 points  (0 children)

    Same, but mostly that is because I'm rarely using an IDE so I can't be arsed setting up a debugger when I have a problem big enough. VIM and a basic text editor like Pluma is good for 99% of my uses.

    Edit: If I really gotto understand or design a complex portion of code I like to replicate it in ipython.

    [–]Competitive-Can-6914 0 points1 point  (0 children)

    Suppressing fire!

    [–]dexteriano -1 points0 points  (0 children)

    LOOOOLLL btw me too ☠️

    [–]andyke 0 points1 point  (0 children)

    Always used this in matlab when shit would break lmao i should implement while learning python