[Chicago-talk] Decision tree code

Richard Reina richard at rushlogistics.com
Wed Feb 10 14:50:44 PST 2021


	


I looked at the suggested links and I believe they are more complicated than I need. I am pretty sure that all potential answers that I will be working with will always have the same outcome/action skip to quest n, nm "notify manager and end survey", or 'c' continue to next question. Accordingly, what about just designing similar to the following:

use strict;
use warnings;

 my %question = (

    1 => 'Have you traveled to foolandia in three years?|bol|Y,N|Y:c,N:3',
    2 => 'Were you there for more than a week?',
    3 => 'Are you currenly employed with bar company?|bol|Y,N|Y:c,N:nm',
    4 => 'Enter date you first heard of foo and bar?|date|YYYY-MM-DD',
    5 => 'Have you ever failed to file a required foo bar form?|bol|Y,N|Y:NM,N:c',
    
    );

my $total_qs = 5; # total number of questions
my $cq = 1;   # current question

while ($cq < $total_qs) {

    my @ask = split(/\|/, $question{$cq});
    my @ans = split(/,/, $ask[2]);
    print $cq . ') ' . $ask[0] . " @ans \n";
    chomp(my $ans = <STDIN>);
    $ans =~ tr/a-z/A-Z/;
  
    my @actions = split(/,/, $ask[3]);

    if ($ask[1] eq 'bol') {

    while(not $ans ~~ @ans ) {
        
        print "print Your Answer: $ans is not a valid answer. Please try again.\n";
        chomp($ans = <STDIN>);
        $ans =~ tr/a-z/A-Z/;
        
    }
    
    foreach my $pa (@actions) {
        
        if ($ans eq substr($pa, 0, 1)) {
        
        my ($ansr, $action) = split(/:/, $pa);
            
            if ($action eq 'c') {
            
            # continue to next question
            $cq++;
            
            } elsif ($action eq 'nm') {
            
            # notify a manager and end survey
            $cq = $total_qs;
            last;
            
            } elsif ($action =~ /^[+-]?\d+$/) {
            
            # action for this answer is an interger, skip to it
            $cq = $action;
            }
        
        }
        
    } # end of foreach

    }  elsif ($ask[1] eq 'date') {
    
    # validate date
    $cq++;
    
    }
    
} # end of while
           
   
print "Thank you for answering some questions. Have a great day!\n";
 
 



On Sat, 6 Feb 2021 14:47:30 -0600, Richard Reina <gatorreina at gmail.com> wrote:
 
Alan, thank you for the insight. I will look into this.
 

Richard

 


El sáb, 6 feb 2021 a las 14:06, Alan Mead (<amead2 at alanmead.org>) escribió:


Maybe I'm stating the obvious, but if you don't want to change the code, then you need to define the branching logic and questions/answers as data and write an "engine" that processes the data and decides what question is next based on the current state (e.g., the answer to the current question, and possibly other information relevant to your application). You should beware that this could become icky. For example, it may be possible to create bugs in the branching logic.

I don't know what the context is, but I believe what you're describing is called "skip logic" and "branching" in the survey industry and it's implemented in packages like LimeSurvey:  https://www.limesurvey.org/blog/20-blog/129-skip-logic-and-branching-equip-your-survey-structure-with-intelligent-paths

Even if you cannot use Lime Survey, you might look at how they implement the rules and think about how you would build an engine to implement this yourself. I think in essence, each question has an ID and the survey has a sequence. Each item either has skip logic, or doesn't. If skip logic exists for a question, then each response to the question needs a ID to branch to. If not, the next question in the survey sequence is chosen. It wouldn't be a monumental task to write this kind of simple engine. I guess implicit in this is that you should be reading your questions and answers from some kind of human- and machine-readable format like YAML or JSON. This file is where you would insert the skip logic in a format you devise. I found references to XPDL in googling as described below. You should define as much complexity as you need. I had a student who couldn't use SurveyMonkey because he wanted to administer a six-item depression survey, score it, and then branch based on whether the score indicated depression or not. At the time, scoring survey questions and adding them up was beyond what SM could do. He found that Qualtrics did have a feature to do this.

Implicit in my description above is that the main purpose is to collect and store survey responses. If your goal is more like reaching a decision (e.g., "Based on your responses, an adjustable-rate mortgage would best suit your needs...") then the questions AND the ending decisions have to be part of the data and perhaps the logic isn't as simple as above (maybe there is no sequence and every question needs a branch, or there are sections of questions that go together and branch between sections). It looks like XPDL is an industry standard (in the workflow industry)  for representing this.

If you google "decision tree" you get a bunch of hits for machine learning. I googled "Perl decision process tree" and that lead me to potentially useful articles like the one below, in which someone wants to create flexible rules about "workflow" (how how tickets are routed in a ticketing app): https://www.perlmonks.org/?node_id=222257

This is also similar to the way web frameworks work. But I think there you'd be writing code to perform each step, so that's probably not helpful.

I am continually amazed by what's on CPAN but I doubt you will find a module for anything like skip logic/workflow in abstract. I think it's more likely to be embedded in a context, like the ticketing app, a survey, or a web frame work. But it looks like there are some Perl modules for implementing workfows.

-Alan

 
On 2/6/2021 8:53 AM, Richard Reina wrote:


I am trying to write code that would guide a user through a series of questions and depending on their answers given ask them different questions. I can of course do this with procedural code but it has occured to me that it might begin to get messy especially when exceptions mount. For example, if the answer to the third question is no, then skip to question 8. So I am looking for a way to structure such code to make it cleaner and perhaps easier to maintain, Does anyone know of any examples of similar projects that I can reference?
 

Thanks,

 

Richard 

 

 

_______________________________________________
Chicago-talk mailing list
Chicago-talk at pm.org
https://mail.pm.org/mailman/listinfo/chicago-talk


 

-- 

Alan D. Mead, Ph.D.
President, Talent Algorithms Inc.

science + technology = better workers

http://www.alanmead.org

The irony of this ... is that the Internet is
both almost-infinitely expandable, while at the
same time constrained within its own pre-defined
box. And if that makes no sense to you, just
reflect on the existence of Facebook. We have
the vastness of the internet and yet billions
of people decided to spend most of them time
within a horribly designed, fake-news emporium
of a website that sucks every possible piece of
personal information out of you so it can sell it
to others. And they see nothing wrong with that.

-- Kieren McCarthy, commenting on why we are not 
                    all using IPv6


_______________________________________________
Chicago-talk mailing list
Chicago-talk at pm.org
https://mail.pm.org/mailman/listinfo/chicago-talk

_______________________________________________
Chicago-talk mailing list
Chicago-talk at pm.org
https://mail.pm.org/mailman/listinfo/chicago-talk



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.pm.org/pipermail/chicago-talk/attachments/20210210/fd540f91/attachment.html>


More information about the Chicago-talk mailing list