how do I keep my input at the same screen location? - python

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.)

Related

What is it called when a program takes control over a console, and how can one do that in python?

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.

Alternate ways to stop print() in python

I have to get user input from the console. Using python input() statement only stops and returns the input when the user clicks "ENTER". But I want it to also happen with "TAB".
Is there a way that python input() can respond to both "ENTER" and "TAB" and return the user input?
I have tried different modules like msvcrt, keyboard, pynput, etc., But they simply read characters one by one. I had to deal with the below items:
Shift + ch (for uppercase)
Inserting characters in between (using right/left arrows)
Copy and Paste
Insert, etc
So I don't want to manually code for all these and many unknowns may raise in the future. These are all already taken care by python input(). I just need to stop it and return the output for "TAB" as well.
Please let me know if there is a way to achieve this.
It might be helpful to a lot of users.

Keeping the user's input intact when outputing to terminal at the same time

To simplify, let's say I'm trying to write a command line two-way chat in Python. I would like the user to input his message with input() at the command prompt, but a listening thread could print a message at any moment. By default, this would "break" the user's input. Visually something like this:
userB>Stop interuserA wrote:Hey check this out!
rupting me!
The closest I was able to find was this answer here which is almost, but not exactly, what I'm looking for, but it did point me towards the blessings package which seems to be what I need (although I'm happy with an answer for any package, or even pure ANSII).
What I'm trying to achieve is to print incoming output from a Thread above the user's input, so that his text doesn't break. Let's say the user is typing:
userB>Stop inter
Suddenly a message comes in from the thread, but our user's input doesn't brake:
userA says: Ok I won't interrupt you
userB>Stop inter
What should my threads theoretical print_incoming_message() method look like to achieve this?
NB: I'm using Linux and am not interested in cross-platform compatibility.
There are two ways of doing this.
One is to use ncurses. There are python bindings for this. With ncurses, the terminal screen is under your complete control, and you can print characters at any point.
Without ncurses, you can't write above the current line. What you can do, however, is print a \r character and go back to the beginning of the line.
If you save the user's input (say he wrote foo), and you want to print the line bar above that, you can output:
\rbar\nfoo
This will overwrite the current line, and introduce a newline, moving the user's input down. The effect is similar, but it won't be as tamper-proof as ncurses.

Python Console with Logging

I'm in the process of rewriting a server program, and I want to add into it a simple console input.
At the moment, it just serves data and prints out one or two lines for each thing it does, as a descriptive measure for anyone watching/debugging.
What I want is to have a "sticky" input bar that is always at the bottom, above which my debug prints appear, so that I can enter commands at any point while the program is printing. This would look a bit like:
...
[88.88.88.88] Handling Connection on Port 11452
[12.12.12.12] Received Data
[44.44.44.44] Sending Disconnect Sequence
>>>Enter Data Here at Any Time
Ideally, this would be done without curses as this would complicate matters. I feel like I must be missing a simple solution.
Thanks in Advance,
Freddy.
If you're looking for a slightly higher-level library than curses, there are a few, like urwid (although of course they don't come with Python, and have to be installed).
If you really want to avoid a windowing library, I suppose you could run the server under screen, configured with an input bar and a rest-of-the-window, and give the server the two virtual TTYs instead of normal input… but that would be a lot more work, not less.
If you want to go lower level, you can always use termios, search termcap, and manually write control sequences to manually take care of scrolling everything but the last line, moving the input cursor, and so on. But that's going to be even more work.
And of course there's always the super-hacky possibility: For every output, and after every input, "redraw" the whole screen by spamming a few hundred blank lines, re-writing the output, and writing the input line. This will look terrible, and not work in a variety of edge cases, but it does avoid any kind of windowing.
However, I think there's a much better way to solve this problem.
You've already got a server. Why not just serve the console API on another "control" port (maybe just on localhost) instead of on the stdin/stdout/tty? That will work even if the server is, e.g., running as a daemon. And it means you can use your favorite fancy Telnet or similar client as a console, instead of having to write something from scratch.

Code to check a scripts activity (python)

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 ".".

Categories

Resources