Calculate maximum score and return the subject name

Hi @Kal_Lam and @stephanealoo,

I want to do a calculation in my form as follow:

Assume a project has got eight interventions, each intervention gets its score from different questions asked under each intervention. at the end of the form I have total score for each intervention, what i want to do is to calculate the maximum score and then return the name of that intervention i.e. Beneficiary A has been selected for Intervention one based on the highest score criteria

thank you in advance

Hello @danishjownaqibullah,

There is a max() function that you can use. If you are using calculations to create score for each part, I’m assuming you are familiar with more complex type of form building. If not, I’ll try to assist even further.

Best,

1 Like

@hakan_cetinkaya,

Thank you for the response. Yes, you are very right, max() function can be used to return maximum value, but I am interested in returning the label of maximum value. i.e. for the eight interventions, i have coded as intervention one, intervention two and …so on. So if i have max(), it will return maximum value but instead i want to return the maximum value question name, i mean the header, so that i understand for what intervention the beneficiary is selected. I am familiar with jr:choice-name, but that is used with questions having options, i guess.

thank you

@danishjownaqibullah Yeah you are absolutely right. max() will only provide the value.

I’m thinking about some if functions, like if(max(X) = ${Q1}, $Q1, max(X) = ${Q2}... what do you think?

1 Like

@hakan_cetinkaya,
Thank you for providing the suggestion. I used your idea to solve the issue, but instead of displaying the question, i displayed the intervention name such as ‘Intervention one’, ‘Intervention two’ and … Thank you so much for the support.

2 Likes

Glad to help @danishjownaqibullah :slight_smile:

1 Like

Yes you can accomplish something that will do this in the general case, but it does involve a little XPath ‘black magic’… (read on)

This is certainly a valid approach if you have a known (and limited) fixed number of repeat iterations. But it wont work in the general case because, obviously, you dont know how many checks to put in your nested if…

The following form should do the trick:

ayhPC3UN8rwAYvJ4qWiNob.xlsx (9.5 KB)

The repeat group collects the data - name and value. At the end of the repeat, the max() function is used to get the maximum of all the values entered in the repeat.

Next comes the Secret Sauce™ … :slightly_smiling_face:

${group}[value = ${max}][position() = 1]/name

This calculation treats the repeat group (in the form’s submission XML data) as an XML hierarchy, and ‘filters’ all the entries under the group based on the predicate [value = ${max}]. Basically, this extracts all those elements whose value equals the aforementioned computed max. This is then filtered again using [position() = 1] to only take the first matching max. Because you might have multiple entries with the same max value, the previous filter could return multiple matches. This is fine with Enketo - which will silently return only the first match - but the same calculation can cause problems with KoboCollect which will complain when more than one match is found. The [position() = 1] fixes it to worth as desired in KoboCollect.

Once we find the (first) repeat element with a matching maximum value, we can pull out the corresponding name from it.

As shown, this will identify the repeat iteration with the maximum value and show the corresponding name (or it could be any other computed identifier you want, if you stick it in your repeat group).

Have a play; you should see it recompute the maximum value and corresponding name as you change different values within the repeat. Behaves similarly under KoboCollect.

For those using the Kobo Formbuilder, this is what the form looks like:

2 Likes

Hi, I would like that your example is registered as a showcase (also for ODK), please.