How to trigger a "undo" for user input - python

I have the following user input statements that are part of a larger function. When prompted for user input it is the case that a user might fat finger the keyboard and continue with the following input prompts. The user input is arbitrary and it really depends on them if they plug in the correct information. However, it could be neat to go back to the previous input statement and continue from there by triggering a keybind (E.g crtl + b lets say) or something similar.
I understand that this could be refined by having explicit invalid inputs with a conditional statement. however, this wouldn't be the use case for my situation. I'm not sure how to go about this. Hoping someone can point me in the right direction.
whichDIMM = input("\nWhich DIMM needs to be replaced?: (ex. A4) \n")
dimmSize = input("\n64G/32G/16G memory?\n")
hostname = input("\nEnter hostname: \n"
Would it be possible to 'Undo' and go back to the previous prompt in case there are spelling mistakes? then continue as expected? otherwise, the user will need to re-run the entire program.
For example:
Which DIMM needs to be replaced?
*mistypes*
64G/32G/16G memory?
(trigger undo)
Which DIMM needs to be replaced?
DIMM_A4
64G/32G/16G memory?
64G
Enter hostname:
myhostname
...
continue with the rest of the script

You are basically trying to turn this into a form where you can move between fields and then submit the whole form. This has been written in many ways already so you could just use one such library. A simple one would be npyscreen for example.

Related

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.

Renpy pasteable input

A game I'm working on needs an input in which a special code can be pasted. The code is a random hash of 24 characters, which would be hard for players to write manually. I haven't found any good quality ways of implementing such an input.
Could this be even done? And if so, how?
I'm just started with Renpy not so long ago and my knowledge is currently scarce
It is mentioned in the documentation.
Input
Creates a text input area, which allows the user to enter text. When > the user presses return, the text will be returned by the interaction.
copypaste
If True, it becomes possible to copy and paste into this input. (By
default, disabled.)
Just set copypaste=True

When does python terminal automatically press enter when pasting something

Title really seems off the point, but what I am trying to ask is this:
For example, I have an input variable called answer
answ = input("> ")
Whenever I run the code and paste something into the input it automatically goes through and does not allow me to edit anything.
But, I also have another input variable that is not really different from the first one and that one allows me to edit out my input once I paste anything into
My question is, why are those 2 inputs different.
Please ask me in detail on what you didn't get about my question. I might be explaining very poorly

Stagged validation/parsing in Amazon Lex

I want to make a simple quote bot which needs to know about addresses and dimensions. Currently I have hacked one together with a python state machine and rasa NLU for the intent stuff, though the nature of the data means most of the entities are better extracted by hand.
For example, an opening sentence might be "i want to send 4 boxes from A postcodeA to B postcodeB they're 3 by 3 by 3m each". These addresses need to be validated, which may involve a back and forth (did you mean this postcode, or maybe that state? This isn't a valid match, please choose from this list, etc...).
Additionally, the order of the validation might be weird. For example, one could have a suburb, postcode, and is_valid slot. There are several possibilities: they could enter a valid S + P, just S, an invalid S alone, a valid S and P which are individually valid but not a match, etc. In some cases I want to defer validation to make use of other information, for example if an invalid suburb was given but a valid postcode, i would use the postcode to inform suggestions for the correct suburb. However, if an invalid suburb was given but no postcode, there is no point asking for a postcode because i would want to get a valid suburb first. In this way having a slot ordering of 'suburb', 'postcode', 'is_valid' doesn't quite cut it as far as i can tell.
I suppose the validation call for suburb and postcode can just have their own set of switch statements which look at the other slots which may have been filled at the same time? Seems a bit chicken and egg, as would need to wait for validation of those as well, and may end up requiring calling Lambda's from within Lambda's. For example, if the validation fails, the bot asks for more info, but the validation of that info may require a different process/lambda than the original input
It could also be they don't include any details about the object, in which case it needs to be prompted for later after the address stuff is all sorted out. For example, if they fail to include info about dimensions i want to ask 'what're the dimensions' and allow them to either include just measurements or weights and quantities as well - this i understand as standard slot filling.
So my question is: how difficult/reasonable is it to have validation calls in Lambdas actually lead to side-paths in the conversation? Previously i had done something like this in a slot-filling setting by having 'is_valid' slots all over the place (especially if I don't want to simply throw an 'isn't valid' error and robotically re-ask the original question'). Is there a better way?
Also, how would one manage 'interrupt' intents? That is, a set of intents which would trigger 'do you want to go restart?' kind of questions, which will return to the original state if the user replies 'no', and, ideally, if they say yes can return to a specific point in the conversation (which i imagine would be achieved by just resetting appropriate slots to empty)
Also, not wedded to the idea of Amazon Lex, any of the pre-canned cases which reduce amount of boiler plate code are good too.
Apologies for word vomit.
Wow, ok here's what I can offer:
1. Validation Difficulty
how difficult/reasonable is it to have validation calls in Lambdas actually lead to side-paths in the conversation?
Building a complex validation and conversation algorithm is standard practice for Lex Developers of service bots. So it is very reasonable to expect to have to do that yourself either in Lambda, or somewhere else and just use Lambda as a go-between. So the difficulty lies in your hands, and maybe you can find APIs that you can use to validate addresses and postal codes like Google Maps to make that part easier.
2. 'is_valid' Slots
Previously i had done something like this in a slot-filling setting by having 'is_valid' slots all over the place (especially if I don't want to simply throw an 'isn't valid' error and robotically re-ask the original question'). Is there a better way?
Lex does have a better way: sessionAttributes! A good practice is to only create slots for holding the values you need to fulfill each intent. For anything else, you can happily rely on sessionAttributes to keep track of the conversation path, slot validity, slot history, intent history, interruption intents, etc, etc, etc, as much as you can imagine. It's completely up to you how to organize your bot logic and keep track of current and past states of the convo there.
For example: You could have slot: postalCodeA
And in sessionAttributes also have: postalCodeA_valid, postalCodeA_confirmed, postalCodeA_attempts etc.
And use those sessionAttributes values to determine the conversation path in your logic. When you find a slot is invalid, you could save that value in an ..._attempts or ..._history list in sessionAttributes, then set ..._valid to false, and reset the slot to null, and re-elicit that slot with a message explaining why it was invalid, or try to elicit an address slot instead of a postal code slot.
3. Interrupt Intents
Also, how would one manage 'interrupt' intents? That is, a set of intents which would trigger 'do you want to go restart?' kind of questions
As I hinted at earlier, the answer to this is also sessionAttributes! When your user is inside of one intent (intentA), Lex will first attempt to fill the current elicit slot with their input, but if it doesn't match, Lex will also check if the input matches a different intent's utterances. So you could have an interrupt intent (intentB) with utterances like "let's start over", "nevermind", "back up", etc. Then in all of your normal intents, you keep a backup of that intent's slot values in sessionAttribtues, as well as something like last_intent to know where a user was previously in case it changes.
This would allow you to handle interrupt intents like this:
user enters intentA
intentA fills some slots, and backs them up in sessionAttributes
user says "lets start over" triggering intentB
intentB asks for confirmation of canceling intentA
(Yes) intentB fulfills the intent after erasing intentA values from sessionAttributes and returns user to start with elicitIntent and asks "how else may I help you?"
(No) intentB passes the user back to intentA (which you know because you kept track of sessionAttributes.last_intent) and send a confirmation of continuing with intentA with confirmIntent: "Alright, I still remember where we left off, would you like to continue {intentA action}?" (the response will be sent to intentA, where you can handle that).
(if user wants to continue with intentA) intentA fills the new empty slots from sessionAttributes and uses other sessionAttributes values to continue through your algorithm to the point where it left off, delivering the same elicit slot that it was last on, and the user is impressed with your bot's intelligence. =)

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

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

Categories

Resources