I just noticed an odd behavior when using l (i.e. the list command) in ipdb. I think I have seen something similar with the Perl debugger in the past, but it still puzzles me.
The first time I inoke it shows corerectly ~10 lines of code around the current step (breakpoint). However, if I press it repeatedly, it does not show code around the current location anymore, but instead it shows code that comes below it.
Eventually list shows the final lines of the script, and if I press l again it doesn't show anything anymore.
Why is this, and how can I have it behave consistently as the first time I invoke it?
Many command line debuggers behave that way. (pdb, gdb, ipdb ...).
If you want display current line again, specify the line number.
l 42
If you don't know the current line number, issue where command.
The reason several list commands in most debuggers show different lines is for the simple reason that it doesn't make a lot of sense to show the same source code lines over and over. Presumably you can scroll back to see what you saw before.
That said, let me say that if you are willing to use the trepan debugger, it does have the ability to show the same source code lines for where you are currently stopped using "list .". To see lines before the last list, use "list -".
You can also set how many lines you want to list by default using "set listsize".
This command in pdb always shows the source text around the debugger's current line
(pdb) l .
Related
Say we get a massive and very messy script that contains many lines that aren't in use.
How can we find out which lines are in use?
If the script is very short we can go with debugger step by step and see what is used but this is impractical in most cases.
Is there any tool or trick to get the lines that are not in use?
IDEs mark variables not in use, but what about function definitions that are not executed at all?
Basically how to get the lines that weren't executed in a python script specific run?
Maybe something to plot a list of numbers of lines not in use
Disclaimer: Sorry if the question is stupid or repeated, I've tried to find similar ones that answer what I need to know but I couldn't. I've started to learn programming about 1 month ago and this is my second time on this website. Feel free to point out any errors or better ways to formulate my questions on stackoverflow, I'll be grateful.
Context:
I was trying to find out a way to print a string - in this case ' º ' - after my user's input - an angle -, on the same line.
I need an alternative way to do this, or help with the one I'm using.
What I got from my research is that, apparently, using the command os.system(cls) should erase the previous line, and putting \033[A before the string should move the cursor up one line. So using these two together should erase the previous line and then overwrite it.
Here's my try:
from os import system
cls = lambda: system('cls')
angle = float(input(f'Insert an angle:'))
cls()
print(f'\033[AInsert an angle:{angle}º')
Desired result on run:
Insert an angle: *60*º # being 60 the user's input
Actual result on pycharm:
Insert an angle:60
Insert an angle:60.0º # for some reason, you can't see it when paste it here, but there's a symbol of a crossed rectangle on the beginning of this line on Pycharm's run
How it looks on pycharm's run terminal
As you can see, the line isn't getting overwritten, only repeated.
What is weird is that when I run this program with Python 3.8 instead of Pycharm, it works as intended, but, on Pycharm, the line isn't overwritten. Instead, Pycharm just prints a crossed rectangle symbol.
Why does it work when executing the file with Python 3.8, but not when pressing "run" on pycharm?
Is there a way to avoid it?
Are there better alternatives to printing a string on the same line as an input?
In cases where I need special printing (ANSII escape codes, backspacing...), I use the actual Terminal, not the Python Console.
For whatever reason, interactive consoles, regardless of IDE, seem to have issues with handing specialties like that. With the normal Terminal, it works as expected:
I have never found a way of having the interactive console handle cases like this.
I'm sure someone has come across this before, but it was hard thinking of how to search for it.
Suppose I have a file generate_data.py and another plot_utils.py which contains a function for plotting this data.
Of note, generate_data.py takes a long time to run and I would like to only have to run it once. However, I haven't finished working out the kinks in plot_utils.py, so I have to run this a bunch of times.
It seems in spyder that when I run generate_data (be it in the current console or in a new dedicated python interpreter) that it doesn't allow me to modify plot_utils.py and call "from plot_utils import plotter" in the command line. -- I mean it doesn't have an error, but it's clear the changes haven't been made.
I guess I kind of want cell mode between different .py files.
EDIT: After being forced to formulate exactly what I want, I think I got around this by putting "from plot_utils import plotter" \n "plotter(foo)" inside a cell in generate_data.py. I am now wondering if there is a more elegant solution.
SECOND EDIT: actually the method mentioned above in the edit does not work as I said it did. Still looking for a method.
You need to reload it:
# Python 2.7
plotter = reload(plotter)
or
# Python 3.x
from imp import reload
plotter = reload(plotter)
I'm using python.el
If I choose 'debugger' from the menu, and enter 'python -m pdb myfile.py', gud starts, and in a split frame I see the (Pdb) prompt in one, and my python code in the other with a caret on the first line, indicating that it's ready to go. For example 'n' steps to the next line and the caret moves accordingly.
If instead I enter 'python -m ipdb myfile.py', the frame splits, and one split is labeled gud, but there's no ipdb console evident. In other words, this way of starting ipdb doesn't seem to work. Ipdb works just fine if I manually insert a breakpoint into my python code using ipdb.set_trace(), except that it does not use the gud interface. Is this intentional so that ipdb's stack trace will work nicely?
If so, that's fine, but is there a way to start ipdb from emacs without manually adding a set_trace() command?
The basic problem here is that gud is looking for a (Pdb) prompt and ipdb doesn't prompt this way. There are three ways to fix this: fix ipdb to give a (Pdb) prompt, fix gud not to need to look for (Pdb) or (my favorite) use something else either on the gud side or on the ipdb side.
The problem with fixing up gud is that it is rather old and to my mind a bit creaky using global variables and not making use of Emacs Lisp data structures available other than lists and cons cells. A total rewrite of gud is called realgud, it is currently in MELPA and ELPA. And ipdb is supported.
The last option is to use something else, so let me suggest the Python trepan debugger which is already integrated into realgud (but not gud since I consider that a dead end). Although the backtraces it gives are not exactly like ipdb's, it does colorize them and the source code.
And recent versions of trepan3k backtraces will even show, on demand, you where in the line you are. So if you had say two calls of a function, like fib() it would distinguish which of the calls function was the one in progress.
Simple question:
Is there some code or function I can add into most scripts that would let me know its "running"?
So after you execute foo.py most people would see a blinking cursor. I currently am running a new large script and it seems to be working, but I wont know until either an error is thrown or it finish(might not finish).
I assume you could put a simple print "foo-bar"at the end of each for loop in the script?
Any other neat visual read out tricks?
I like clint.progress.bar. For logging, you can check Lggr.
The print "foo-bar" trick is basically what people do for quick&dirty scripts. However, if you have lots and lots of loops, you don't want to print a line for each one. Besides the fact that it'll fill the scrollback buffer of your terminal, on many terminals it's hard to see whether anything is happening when all it's doing is printing the same line over and over. And if your loops are quick enough, it may even mean you're spending more time printing than doing the actual work.
So, there are some common variations to this trick:
Print characters or short words instead of full lines.
Print something that's constantly changing.
Only print every N times through the loop.
To print a word without a newline, you just print 'foo',. To print a character with neither a newline nor a space, you have to sys.stdout.write('.'). Either way, people can see the cursor zooming along horizontally, so it's obvious how fast the feedback is.
If you're got a for n in … loop, you can print n. Or, if you're progressively building something, you can print len(something), or outfile.ftell(), or whatever. Even if it's not objectively meaningful, the fact that it's constantly changing means you can tell what's going on.
The easiest way to not print all the time is to add a counter, and do something like counter += 1; if counter % 250 == 0: print 'foo'. Variations on this include checking the time, and printing only if it's been, say, 1 or more seconds since the last print, or breaking the task into subtasks and printing at the end of each subtask.
And obviously you can mix and match these.
But don't put too much effort into it. If this is anything but a quick&dirty aid to your own use, you probably want something that looks more professional. As long as you can expect to be on a reasonably usable terminal, you can print a \r without a \n and overwrite the line repeatedly, allowing you to draw nice progress bars or other feedback (ala curl, wget, scp, and other similar Unix tools). But of course you also need to detect when you're not on a terminal, or at least write this stuff to stderr instead of stdout, so if someone redirects or pipes your script they don't get a bunch of garbage. And you might want to try to detect the terminal width, and if you can detect it and it's >80, you can scale the progress bar or show more information. And so on.
This gets complicated, so you probably want to look for a library that does it for you. There are a bunch of choices out there, so look through PyPI and/or the ActiveState recipes.
You could log things to a file. You could print out dots, like print ".".