Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #96502 > unrolled thread
| Started by | Azureaus <ltoshea@gmail.com> |
|---|---|
| First post | 2015-09-13 07:39 -0700 |
| Last post | 2015-09-13 23:57 +0000 |
| Articles | 5 — 5 participants |
Back to article view | Back to comp.lang.python
Phone Tree Azureaus <ltoshea@gmail.com> - 2015-09-13 07:39 -0700
Re: Phone Tree Chris Angelico <rosuav@gmail.com> - 2015-09-14 00:59 +1000
Re: Phone Tree Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2015-09-13 12:53 -0400
Re: Phone Tree Laura Creighton <lac@openend.se> - 2015-09-13 20:03 +0200
Re: Phone Tree Denis McMahon <denismfmcmahon@gmail.com> - 2015-09-13 23:57 +0000
| From | Azureaus <ltoshea@gmail.com> |
|---|---|
| Date | 2015-09-13 07:39 -0700 |
| Subject | Phone Tree |
| Message-ID | <6ae5c632-b061-4b86-87ae-24c50435445b@googlegroups.com> |
Hi, I'm helping out some teenagers (14yo ish) who have just started programming and are working on a 'call tree' program as part of some after school coding classes and I wanted to talk about potential solutions. The first task is to implement a 'troubleshooting program' similar to what a phone operator would have when you phone up with a problem. We all know the type when you phone up your ISP, 'have you turned it off and on again?', "have you changed your telephone filter' etc.. It states there should be at least 10 questions and that the user should reach a solution, e.g. 'replace your power cable'. There and my initial reaction was that this could be achieved by lots of if/else statements with each question running onto another one, ugly but it would certainly work. One of them pointed out how inefficient this was and asked if there was another way, they hated writing out tons of if/elif/else statements. Does anyone have any ideas for a more elegant solution? My thoughts are that I could use a tree data structure and hence make traversing the tree recursive based on yes or no answers. I'm happy to put the time in to explain these more complex ideas, I'm just hoping those with more expertise than myself could either help verify the idea or suggest alternatives. Thanks in advance!
[toc] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-09-14 00:59 +1000 |
| Message-ID | <mailman.475.1442156404.8327.python-list@python.org> |
| In reply to | #96502 |
On Mon, Sep 14, 2015 at 12:39 AM, Azureaus <ltoshea@gmail.com> wrote:
> The first task is to implement a 'troubleshooting program' similar to what a phone operator would have when you phone up with a problem. We all know the type when you phone up your ISP, 'have you turned it off and on again?', "have you changed your telephone filter' etc..
>
> It states there should be at least 10 questions and that the user should reach a solution, e.g. 'replace your power cable'. There and my initial reaction was that this could be achieved by lots of if/else statements with each question running onto another one, ugly but it would certainly work. One of them pointed out how inefficient this was and asked if there was another way, they hated writing out tons of if/elif/else statements.
>
> Does anyone have any ideas for a more elegant solution? My thoughts are that I could use a tree data structure and hence make traversing the tree recursive based on yes or no answers. I'm happy to put the time in to explain these more complex ideas, I'm just hoping those with more expertise than myself could either help verify the idea or suggest alternatives.
>
This sounds broadly similar to a Twenty Questions game. You may be
able to find some neat implementations of that, which could be
reworked into what you want.
A more cynical algorithm could be implemented as follows:
import random
questions = [
# The IT Crowd
"Hello, IT, have you tried turning it off and on again?",
# The Bastard Operator From Hell
"How long has this been happening?",
"Has anyone else had this problem?",
"Is it your floor that has the Gas Leak?",
# Standard ISP questions
"Have you tried disabling your antivirus?",
"Are we talking to the authorized account holder?",
# Add additional questions as required
]
random.shuffle(questions)
questions = questions[::2] # Ask about half of them
for q in questions:
response = input(q) # raw_input in Py2
# Utterly ignore the response
print("I'm sorry, nobody else has reported this problem, so it cannot
be a real problem.")
I may or may not be basing this on real life experience.
For something a bit more useful, though, what you might have is a
nested pile of tuples. For instance:
questions = (
# First the question
"Have you rebooted your computer?",
# Then the if-no response
"Please reboot your computer, then call back.",
# Finally the if-yes response
("Are you running Windows?",
("Are you using a Macintosh?",
"I'm sorry, we only support Windows and Mac OS.",
"Let me transfer you to our Macintosh support people.",
),
("Have you disabled your antivirus?",
"Please disable your AV and try again.",
("Is it your floor that has the gas leak?",
"I'm sorry, I can't help you.",
"Strike a match. All your problems will disappear.",
),
),
),
)
while isinstance(questions, tuple):
q, no, yes = questions
response = input(q)
if response == "yes": questions = yes
elif response == "no": questions = no
else: print("I'm sorry, I didn't understand that response.")
print(questions) # is now the solution
This is a data-driven algorithm. The code is extremely short, and is
fundamentally about the UI; you could change it completely (a GUI app,
text-to-speech and DTMF for IVR, etc, etc) without changing the
question structure at all.
Is this the kind of tree structure you had in mind?
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Dennis Lee Bieber <wlfraed@ix.netcom.com> |
|---|---|
| Date | 2015-09-13 12:53 -0400 |
| Message-ID | <mailman.484.1442163208.8327.python-list@python.org> |
| In reply to | #96502 |
On Sun, 13 Sep 2015 07:39:23 -0700 (PDT), Azureaus <ltoshea@gmail.com>
declaimed the following:
>It states there should be at least 10 questions and that the user should reach a solution, e.g. 'replace your power cable'. There and my initial reaction was that this could be achieved by lots of if/else statements with each question running onto another one, ugly but it would certainly work. One of them pointed out how inefficient this was and asked if there was another way, they hated writing out tons of if/elif/else statements.
>
Good for them... Separate the data from the algorithm/implementation.
>Does anyone have any ideas for a more elegant solution? My thoughts are that I could use a tree data structure and hence make traversing the tree recursive based on yes or no answers. I'm happy to put the time in to explain these more complex ideas, I'm just hoping those with more expertise than myself could either help verify the idea or suggest alternatives.
Classical 20 questions implementation
http://www.c-sharpcorner.com/uploadfile/4a950c/20-questions-guessing-game-using-binary-trees/
Even my college computer (late 70s) had a version. Most implementations
are designed to be self-learning -- that is, they start with only one
answer (or maybe even none) and if the guess is incorrect they ask the
player to provide a question that can be used to differentiate between the
its guess and the correct answer.
True -- the efficiency of the result depends on the order the inputs
are provided as a key difference may end up at the bottom of a chain of
failed guesses, all of which could have been avoided if it had been the
first item. "is it alive?" as a first question would wipe out all the
inanimate stuff... But if the system was taught in the order "is it an
element"/"is it a mineral"/"is it a rock"/"is it alive"...
>
>Thanks in advance!
--
Wulfraed Dennis Lee Bieber AF6VN
wlfraed@ix.netcom.com HTTP://wlfraed.home.netcom.com/
[toc] | [prev] | [next] | [standalone]
| From | Laura Creighton <lac@openend.se> |
|---|---|
| Date | 2015-09-13 20:03 +0200 |
| Message-ID | <mailman.485.1442167403.8327.python-list@python.org> |
| In reply to | #96502 |
Somewhere in there you may find that dictionary dispatching is
something worth doing. I don't know. This whole sort of problem
is sort of grating, in that it is trying to replicate one of the
most irritating user experiences on the planet ...
From python3: Patterns, Recipes and Idioms
http://www.google.se/url?sa=t&rct=j&q=&esrc=s&source=web&cd=5&ved=0CEUQFjAEahUKEwiJv4CtxPTHAhVqvnIKHY68Bec&url=http%3A%2F%2Fpython-3-patterns-idioms-test.readthedocs.org%2Fen%2Flatest%2FMultipleDispatching.html&usg=AFQjCNG0UFOKpxJNVDSCt9dtAJ55SC_zEA
The guts of the thing is a simple dictionary:
outcome = {
(Paper, Rock): Outcome.WIN,
(Paper, Scissors): Outcome.LOSE,
(Paper, Paper): Outcome.DRAW,
(Scissors, Paper): Outcome.WIN,
(Scissors, Rock): Outcome.LOSE,
(Scissors, Scissors): Outcome.DRAW,
(Rock, Scissors): Outcome.WIN,
(Rock, Paper): Outcome.LOSE,
(Rock, Rock): Outcome.DRAW,
}
Which, in this case, plays the child's game rock, paper, scissors with
2 players. But you could use a tuple with 10 values.
If a lot of your outcomes are going to arrive at the same answer 'Stick
the device in a box, print off this shipping label, and send it via
UPS to our repair service centre.' then this approach will have more
appeal.
Sometimes what you want is to dispatch on a set of functions with
arguments, and you can stick that in your dictionary as well.
outcomes = { (a,c,d) : (function1_name, (arg1, arg2, arg3))
(a, b, d) : (function2_name, (arg1,))}
But whether this is going to help or not really depends on your data.
If you find yourself itching for a case statement, then it probably
will. But I am not sure that this was your intent in the first place.
Laura
[toc] | [prev] | [next] | [standalone]
| From | Denis McMahon <denismfmcmahon@gmail.com> |
|---|---|
| Date | 2015-09-13 23:57 +0000 |
| Message-ID | <mt52hu$ji9$3@dont-email.me> |
| In reply to | #96502 |
On Sun, 13 Sep 2015 07:39:23 -0700, Azureaus wrote:
> Does anyone have any ideas for a more elegant solution? My thoughts are
> that I could use a tree data structure and hence make traversing the
> tree recursive based on yes or no answers. I'm happy to put the time in
> to explain these more complex ideas, I'm just hoping those with more
> expertise than myself could either help verify the idea or suggest
> alternatives.
The trick is to separate the data and the processing.
Each question has a yes, no answer, so start with a dictionary of data
tuples (you could use a list, but using a dictionary makes the
relationship slightly easier to walk through):
questions = {
1: (q1, response if yes, response if no),
2: (q2, response if yes, response if no) .... }
The responses can be either a number of another question, or a result
text.
Then your algorithm is broadly:
x = 1:
while x is numeric:
ask questions[x][0]
if answer is "yes":
x = questions[x][1]
if answer is "no":
x = questions[x][2]
answer is x
You can use a list instead of a dictionary, just remember 0 indexing when
you're working out which question leads to which next question.
This way also makes for an interesting talking point about separating
data and code, especially given the multiple if statements issue.
--
Denis McMahon, denismfmcmahon@gmail.com
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web