How to print text behind an input in python 3.x - python-3.x

Sorry the title is confusing, but i'm not too sure how to word it appropriately.
My goal here is to have regular python input but for text for the input to be displayed to the right of where i'm typing.
For example what the user would see:
<- input your age
i'm looking for the cursor and where they type to be in that blank space, where the arrow is pointing.
Is this possible or am I being an idiot here?
Sorry if this is confusing or if I have worded this badly,
thankyou for your time.

The simplest way to achieve this is to use the carriage return (CR) ascii escape sequence. The "\r" character ill move the cursor t the beginning of the current line and begin taking input. Be careful with the amount of white space you have in the prompt since long names will begin to overwrite the prompt itself.
Note that as in #Carcigenicate's comment this will not work in every terminal or my behave differently.
name = input(" <- input your age\r")

Try the python-prompt-toolkit package.
In particular, the Adding a right prompt section.

Related

Is there an end= equivalent for inputs?

So as I'm sure you know there's a specific operator for print() functions called end.
#as an example
print('BOB', end='-')
#would output
BOB-
So is there something like this for inputs? For example, if I wanted to have an input that would look something like this:
Input here
►
-------------------------------------------------------
And have the input at the ► and be inside the dashes using something like
x = input('Input here\n►', end='-------')
Would there be some equivalent?
EDIT:
Just to be clear, everything will be printed at the same time. The input would just be on the line marked with the ►, and the ---- would be printed below it, but at the SAME time. This means that the input would be "enclosed" by the ---.
Also, there has been a comment about curses - can you please clarify on this?
Not exactly what you want, but if the --- (or ___) can also be on the same line, you could use an input prompt with \r:
input("__________\r> ")
This means: print 10 _, then go back \r to the beginning of the line, print > overwriting the first two _, then capture the input, overwriting more _. This shows the input prompt > ________. After typing some chars: > test____. Captured input: 'test'
For more complex input forms, you should consider using curses.
When using basic console IO, once a line has been ended with a newline, it's gone and can't be edited. You can't move the cursor up to do print anything above that last line, only add on a new line below.
That means that without using a specialized "console graphics" library like curses (as tobias_k suggests), you pretty much can't do what you're asking. You can mess around a little with the contents of the last line (overwriting text you've already written there), but you can't write to any line other than the last one.
To understand why console IO works this way, you should know that very early computers didn't have screens. Instead, their console output was directly printed out one line at a time on paper. While some line printers could print several characters on the same spot (to get effects line strikethrough or underline), you couldn't unprint anything once it was on the paper. Furthermore, the paper feed only worked in one direction. Once you had sent a newline character that told the printer to advance the paper, you couldn't go back to an old line again.
I believe this would solve your problem:
print(f">>> {input()} ------")
OR
print(f"{input(">>>")} ------")
F-strings are quite useful when it comes to printing text + variables.

Multiline input prompt indentation interfering with output indentation

I have a function that prints the number of pixels found in an image and then asks the user how they would like to proceed. As long as the interpreter hasn't moved on from the function I want all the output to be indented accordingly.
One such 'sub output' (the input prompt) needs to be multiple lines. So I kick off with the 3*quote (''') followed by two spaces to create the indentation. At the end of the question 'how would you like to proceed?' I use a hard return. An extra indentation is assumed by the text editor so I remove it causing the following list of suggestions to line up flush with the input variable command. Here's how it looks:
def returnColors():
#
# lots of code that does stuff...
#
print("The source image contains", lSize, "px.")
print("")
command=input(''' What would you like to do? You can say:
get all
get unique
''')
The problem with this is that the interpreter is acknowledging the indentation that separates the function body from the function statement as actual string contents, causing the output to look like this:
The source image contains 512 px.
What would you like to do? You can say...
get all
get unique
|
The only way to avoid this is by breaking indentation in the interpreter. Although I know it works, it doesn't look very good. So what options do I have?
EDIT: Just because I have the screenshot_
One thing that you should keep in mind is that once you have start a multiline string declaration, all the text until it is closed is taken as is and syntax (ie, indentation) is no longer considered.
You can start your multiline with an explicit new line so that everything in the multiline string can be indented together in code.
IE.
command=input('''
What would you like to do? You can say:
get all
get unique
''')
would print out the prompt with a new line on top, but the formatting of the text is more explicitly shown and should appear as seen.
OR you could use the \n for each new line in the string to get it formatted more correctly and remember to use a single \ after each new line. E.g.
instead of:
''' What would you like to do? You can say:
get all
get unique
'''
Try
' What would you like to do? You can say:\
\n\
\n get all\
\n get unique\
\n'
The indent won't matter, no matter where you use \n at the beginning of new line, the input() will output the same. This is will give the same input() string:
' What would you like to do? You can say:\
\n\
\n get all\
\n get unique\
\n'

How to make getch() accept taking an enter hit (\n)?

I made a touch typing console program in C++.
It reads the text from a file and load it to the screen.
User must enter the right letter in order for him to proceed to the next letter.
My only Problem is with the '\n',
so if I had something like this in the text file (the file I'm reading from):
"
hello
dude
Sup
"
After the user enters "hello",
he should press enter right?
But whenever he presses enter, getch() takes him back to the beginning for the current line.
How can I fix this?
I'm reading the whole file and storing it to a string, like this:
void getTextFromFile()
{
text.assign(istreambuf_iterator<char>(fin), istreambuf_iterator<char>());
}
First of all, getch() is deprecated (just an FYI if you start having more problems with it). From my understanding you're trying to accept character input 1 char at a time. If you're using getch() for the '\n' enter press you should be fine. If not please explain more.
I just tried a quick experiment. Apparently getch() (which, as reagan says, is deprecated; use _getch() instead) returns '\r', not '\n', when you press Enter.
With your current program, try typing Ctrl-J instead of Enter; that should give you a '\n' result from getch().
And for future reference, you should show us the actual code that calls getch(). I have no idea how the currentLetter = getch(); that you mentioned in a comment relates to the code in the question.

Remove Various Whitespaces While Editing in Vim

So oftentimes, while editing with Vim, I'll get into a variety of situations where whitespace gives me hassle. For example, say I have a comment like this:
#This program was featured on the Today show, it is an algorithm for promoting world peace in third-world countries
#given the name of that country and the name of a celebrity to endorse its cause
If I want to, for example, trim the lines so they go to X characters, I end up putting a newline somewhere in the middle of the top line to get this (after hitting the newline and auto-indenting):
#This program was featured on the Today show, it is an algorithm for promoting
world peace in third-world countries
#given the name of that country and the name of a celebrity to endorse its cause
I then add a # to the beginning of the line, and that's all well and good, but then I want that line to line up, too. To do so, I have to delete the newline, all the whitespace for the indent on the next line, and then the commenting # mark. It doesn't take an awfully long amount of time to do that, but this and similar situations all add up over a day's worth of coding.
Now the example above is pretty specific, but my question isn't. What's a good way in Vim to delete all whitespace INCLUDING NEWLINES up until the next non-whitespace character? If Vim already has movements that do that, that would be awesome, but if not, does anyone have a favorite Vim function they use to do the above that could be mapped to a key? At the very least, am I missing some Vim usage idiom that prevents me from even having to worry about this case?
EDIT: Formatting to width, while useful and applicable to the case above, isn't the focus of this question. I'm concerned more with whitespace removal that doesn't stop at the end of a line, but instead carries on to the first non-whitespace character of the next line.
You really just want to reformat that comment to fit the current 'textwidth'. If the comment is a paragraph (i.e., separated by a line of whitespace above and below), then you can just use gqip (gq is the reformat command, ip is the "inner-paragraph" text object) to reformat it. If it's not a standalone paragraph, you can visually select those lines and then use gq.
This likely also relies on having 'formatoptions' set correctly to make sure the comment characters are handled properly, but in many cases the ftplugin has already done that.
This is a while later, but I found that there is a command that does what I need to in 90% of circumstances:
J -- join line below to the current one
This command seems to work:
:.s/\W*$\n\W*//g
it uses a replace to remove whitespace up to end of line and the new line at the end.
In this example:
testting aad $
asdjkasdjsdaksddjk$
(to see meta characters in vim use the command :set list)
if you place the cursor on the first line and use the first command it will delete everything from aad to $ (not including aad but including $ and a newline.)
Also, note for what you are doing it is far more efficient to use an external program to format comments for you. In particular, par is a great small C program that edits text and wraps it to desired lengths.
If you have par in your path, to do what you are trying to do is as easy as selecting the block of comment with Shift+v and running the command
:!par 40pgr
where 40 is the desired width in columns.
If you are feeling hackish, write your own program in C/perl/C++/python that edits comments however you like, then put it in path and use the external filter command :! to process blocks of text through it.

Append general buffer to the end of every line in VI

I'm trying to add the contents of the general buffer to the end of every line. I'm sure this is fairly simple, however, an hour of google searches have lead me nowhere.
This is what my file looks like
::Things to bring camping
--matches
--tent
--sleeping bags
--inflatable bed
--firewood
--camping stove
--skillet
I want to add "::Things to bring camping" to the end of every line.
This is i have figured out so far.
/:: -> brings me to the line in question
Y -> yanks the entire line to the general buffer
I tried :%s/$/\p -> this added a "p" to the end of every line.
My problem is with step 3. How do I tell the "search and replace command" to used the "p" (the contents of the general buffer) instead of the "p" the character
Thank you so much for your help.
Just a suggestion: If you try doing it with a macro, you will be able to use 'p' to add the contents of the general buffer.
Sorry, I had to go into vim and find out.
The way to copy your entire line while in command mode, is:
^r "
(that's CTRL and r, then " )
That should paste the entire line you yanked into your search and replace command
For step three, instead of \p, you should use ctrl-R-a. Hold down the control key and type an uppercase "R", continue holding control, and type a lowercase "a".
For a line with multiple words, use ctrl-R-" instead.
I agree with using a macro - they're very powerful.
In this case I took your list example and positioned it at the first colon.
I used y$ to grab the remainder of the line in the buffer.
Then I recorded the macro - I chose 1.
q1
j$pq
Then you can call it for any number of rows in your list. E.g. 10#1
Learned something figuring this one out ...
:%s/$/\=getreg()/
The \= says that what follows is an expression to be evaluated, and the getreg() call gets the contents of the register, by default the "general buffer" as it used to be called by vi.

Resources