CITGuru / PyInquirer

A Python module for common interactive command line user interfaces
MIT License
1.91k stars 235 forks source link

[Want help] Can you provide an example that goes back to the previous step? #128

Open 625781186 opened 3 years ago

625781186 commented 3 years ago

Sometimes you type something wrong and you need to go back to the previous step. Thanks~

lazee commented 3 years ago

What step? Previous question?

625781186 commented 3 years ago

What step? Previous question?

yes . Add an action for each question that go back the Previous question , and show the answer to the previous question.

lazee commented 3 years ago

Ok. Your question is kind of outside the scope of what PyInquirer offers.

PyInquirer strives to be an easily embeddable and beautiful command line interface for Python.

Meaning that it offers (imho) a brilliant way to get input from the user. It does not offer the kind of logic you request. That is something you need to implement yourself (or with help from other frameworks). What you describe is some sort of wizard functionality, as far as I can tell, where the user will be given a choice of jumping back and forward between input options. That in itself introduces several problems/challenges:

State management

User input in sequence often results in some sort of state, where one choice affects the following choices (If selected A then do B, else C). All ending up in some sort of state. Eg: The user might have given a name, an address, a country and a region. If he has selected a region and then goes back to change the country, then you must make sure to remove the region from your state. This will very quickly turn into a huge mess where you end up with a state explosion.

You can use state machines for this. Actually you should use a state machine if you want to go down that road. But I really wouldn't recommend it.

Side Effects

Often there might be side effects involved during the lifecycle of a script. Let's imagine a scenario like this:

> python clean_db.py
Select db:
[*] db1
[] db2
Clean table rows (y/N) ? y

There is no way to recover from these side-effects by moving backwards. Hence there can be no general solution to this problem.

User interface

It is extremely hard to imagine how we could offer the user an intuitive interface on how to go back to the previous choice without buttons, links and so on. We are after all on the command line.

The common way to solve this

A very common way to solve your problem is by presenting a summary of the input that the user has provided, before acting upon it. And then let the user confirm.

Your name: George
Age: 12

-------------
Name: George
Age: 12
-------------
Is this correct (y/N)? 

If the user says 'no', then you will ask him to give it another shot or abort your script.

There are hundreds of ways this can be solved, but my general advice is to keep things very simple. Managing state is hard.

625781186 commented 3 years ago

@lazee I guess my question may not be asking about logic and state management, It's that I don't know how to add an action option after each question that goes back to the previous step.

Such as :

Select db:
[*] db1
[] db2
Next             # Press the space bar to trigger the operation .
Pre               # Press the space bar to trigger the operation .
# -------------------------
Input your Name:

Next             # Press the space bar to trigger the operation .
Pre               # Press the space bar to trigger the operation .

It looks a little bit like examples/when. py

lazee commented 3 years ago

That has everything to do with logic and state management :)

lazee commented 3 years ago

As far as I can tell the examples/when.py will have to deal with the exact same problems as I described. The when property takes a function that can introduce side effects it is impossible to recover from, the ui argument stands and the same goes for state management.

klize commented 3 years ago

I have the same requirement to go to back step without lambda statement or 'when'.

Since every questions can have predecessor with some depth, it may not be a good solution.

as I understood, prompt function gives your question flows within for statement, which means if we want to go back to previous step by giving a default menu .. or something, we need kind of goto keyword like C language. Or the for statement may need to be changed into while True so that we can handle an index of questions.

just let me know if I wrong, thanks.

625781186 commented 3 years ago

image

I plan to use prompt-toolkit for this function. The left side serves as the index for the questions, the middle side presents the questions for each step, the right side displays the answers to all the questions.