Arcade expression evaluating multiple field values to calculate value

2926
4
Jump to solution
04-08-2019 06:56 PM
JoeBryant1
Occasional Contributor II

Hi,

I'm creating a Scavenger Hunt for Collector use and want to be able to quickly grade the results in a Dashboard on ArcGIS Online. Contestants will be supplied a guide with question IDs and multiple choice answers. They will select the question ID and their multiple choice answer for each feature they record.

I have all of the features, fields and domains created along with some test answers. I'm trying to use the calculate value function for a hosted feature service in ArcGIS Online to add a "Y" or "N" value to a new 'Corrected' field to indicate if they got they answer right or wrong. (This field will be hidden from them in the Collector web map)

My logic is that I want any collected feature (row) whose QuestionID == "1" AND MultChoice == "A" to get a "Y" assigned to the new 'Corrected' field. I will list all of the correct combinations of Question IDs and Multiple Choice answers in this manner. Else, all other values will be assigned "N".

I've been experimenting with the Arcade Expression builder box in ArcGIS Online, but it seems to be lacking in its syntax troubleshooting capabilities and I'm not getting anywhere. It doesn't seem I can evaluate a compound expression. I'm thinking I need to create a variable based on a filter (the easiest way would be all questions with Multiple Choice == "A" become variable 'MultiA', "B" becomes 'MultiB", etc.), and then evaluate an IIF statement for each of those variables.

Any Arcade wizards out there care to enlighten me?

0 Kudos
1 Solution

Accepted Solutions
XanderBakker
Esri Esteemed Contributor

What you can do is this:

// create a disctionary with the correct answer for each question ID
var answers = {"1": "A", "2": "C", 
               "3": "B", "4": "A",
               "5": "D", "6": "D"
}

// read the fields that contain the question ID and user answer
var QuestionID = $feature.QuestionID1;
var UserAnswer = $feature.Answer1;

// validate the answer
if (HasKey(answers, QuestionID)) {
    var CorrectAnswer = answers[QuestionID];
    if (UserAnswer == CorrectAnswer) {
        return "Y";
    } else {
        return "N";
    }
} else {
    return "?";
}

  • On the first rows you can create a dictionary that holds all the question IDs together with the correct answer (lines 2 - 5).
  • Line 7 and 8 will read the fields that hold the ID and answer of the user
  • lines 12 to 21 will validate if the ID is in the dictionary and if so, extract the correct answer for the ID and validate is it matches the answer provided by the user and assign a Y or N (or ?).

You could also extract multiple answers and calculate the score in %.

View solution in original post

4 Replies
XanderBakker
Esri Esteemed Contributor

What you can do is this:

// create a disctionary with the correct answer for each question ID
var answers = {"1": "A", "2": "C", 
               "3": "B", "4": "A",
               "5": "D", "6": "D"
}

// read the fields that contain the question ID and user answer
var QuestionID = $feature.QuestionID1;
var UserAnswer = $feature.Answer1;

// validate the answer
if (HasKey(answers, QuestionID)) {
    var CorrectAnswer = answers[QuestionID];
    if (UserAnswer == CorrectAnswer) {
        return "Y";
    } else {
        return "N";
    }
} else {
    return "?";
}

  • On the first rows you can create a dictionary that holds all the question IDs together with the correct answer (lines 2 - 5).
  • Line 7 and 8 will read the fields that hold the ID and answer of the user
  • lines 12 to 21 will validate if the ID is in the dictionary and if so, extract the correct answer for the ID and validate is it matches the answer provided by the user and assign a Y or N (or ?).

You could also extract multiple answers and calculate the score in %.

JoeBryant1
Occasional Contributor II

Xander, you're awesome! This is exactly what I needed.

I hadn't thought of creating a dictionary for the correct answers. Very clean.

I have not used the "HasKey" function before. This seems to be the essential piece of this script. When I read it and try to understand the logic, my head still turns in circles. I think it's going to take me a while to master that one.

Hopefully others find this post and can benefit. Thanks again; you saved my bacon! 

XanderBakker
Esri Esteemed Contributor

Hi Joe Bryant ,

I'm glad it worked for you. As you probably noticed the dictionary consists of key: value pairs. So "1" is the key (the QuestionID) and "A" is the value (the correct answer for question with ID "1"). When using the HasKey function you are checking is the key (question ID) exists in the dictionary. If it doesn't we skip directly to the part where "?" is returned. If the key (question ID) exists in the dictionary we extract the correct answer. This is done by DictionaryName[QuestionID]. The reason is used is to avoid that an error is triggered when we try to use a key that does not exist in the dictionary. I hope this makes it a bit easier to understand.

0 Kudos
JoeBryant1
Occasional Contributor II

Yes, that does clarify it. I had not grasped that the dictionary is more than a list; it is a list of key:value pairs. And you can return the value by using the key with the expression “DictionaryName[key]”.

Joe Bryant

GIS Coordinator

WEST YOST ASSOCIATES

direct 530.761.0226