I remember starting out to code.. npp was a breath of fresh air.. due to my line of work I now do everything in vim via prompt.. but npp is the first thing I open when I work in gui.. can't express how happy I am to see its still flourishing..
for poorly written python code that is just too large to add the many print statments.. I run it using trace and pipe to a log.. ofc pdb is awesome too.. provided it crashes so I can work in the stack trace..
for bash I do something similar by using set -x and a custom PS4 prompt that gives me file function and line number..
in my own code I have info, warn, error and debug log lines (for both bash and python).. so I rarely have to resort to enabling trace..
use proper logging with log levels.. just being able to switch on debug level and get a wealth of info is a big step in the right direction.. my debug lines have method names and line numbers.. I take this so seriously that I have my custom logging method for bash and python (I script a lot in both).. I drop a lot of info lines as I code and switch them debug once I'm finishing up..
confirming fundamentals is another tried and tested method..
other than logging and methodology, having the right tools is important.. I use pudb for my debugger in python.. and bash -xv for shell..
error reporting is also important.. I use 'trap' and set -E in bash to capture all errors, provide a lot of info and even email it to me..
in python I have exception hook.. I even monkey patched threading to report its uncatched errors to the main threads exception hook (I use python2.7 for work.. this is fixed in latest python3)
during my dev phase I always give more time to coming up with a solution vs with running with an idea.. this allows you to engineer a solution..
and lastly.. in my down time I think about the problems I couldn't solve at the desk.. this could be when I'm about to sleep.. when I'm playing pool.. etc.. I find that solutions come easier at these moments..