from time import sleep
for i in range(7200, -1 , -1):
print(f"{i}", end="\r")
sleep(1)
When I run the above python script, it counts down and replaces the old number with the current number so it all stays on the same line. However, per the below image, the CLI cursor (not sure if that's what it's called, I'm still fairly new to programming) overlaps the numbers. I'm not quite sure how to rectify this so the cursor doesn't do that. I'd prefer it to go to the next line, but if that isn't possible then go to the end of the printed number.
screenshot of issue
This happens both in VS Code and the mac terminal.
I wasn't able to find anything regarding this, but that's probably because I just don't know what terms to exactly use. I tried putting \r and \n in different places, but most of my attempts just kept printing to a new line.
Related
I am planning to make a python program which displays some sequential info in the console without adding newlines, i.e. similarly to what man does - the console is taken over by the program and all the input goes to the program, and the program is able to update text in place rather than having to print on a newline every time. I don't know what is the proper term for this, which makes for a "problem of unknown terminology" (which I'm sure has a proper name as well, but ironically I do not know it either), and thus makes it near impossible for me to search for the answer myself.
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.
My current input method is a for loop. I input an integer it gets added to a list then it goes around to the next input. This produces a new line each time it goes around. I would like to keep the input entries at the same location. I'm new to Python and programming in general so I have no clue where to start. My input statement is in this form:
var= input(" message: ")
Thank You
If you are working with UNIX or Windows terminals, you can add an ASCI escape ("\033[A") to move the cursor one line up to ask for input again, as shown in the example here, so in this way, you can get your input message at the same position by "overwriting" the previous input message.
tl;dr: there's a reason most simple applications don't do this: it's a lot of work for not very much payoff.
If you're talking about making sure that the "message: " line always appears in the same place in the window, then you can't do it with plain input: it doesn't take an "end of line" argument and actually the newline happens before input gets a hold of the input string. (I.e. when the user hits RETURN.)
You can do it, especially if you don't care about Windows, using getch mode, which basically says that the terminal passes characters to you, not whole lines, and you need to decide how to interpret them. The getch package seems like it might be able to help here, it even supports Windows!
Another option (probably not as effective or a nuclear bomb when what you need is a scalpel) would be to use something like curses or blessings' terminal.location abilities. And blessings, I believe, incorporates ANSI escape chars. (As mentioned in the other answer to this question, it's probably the right way to go.)
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 .
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 ".".