Program rule, assign value by summing boolean data elements

Hi all,
Apologies if this is documented somewhere else, but I’m having trouble. I have an event program on 2.31 and would like to autopopulate a data element by summing the number of “yes” responses in a particular section that contains 5 yes/no questions. I have done a program rule with assign value, and in the expression simply added up the data elements (since I was thinking that yes would evaluate to 1 and no to 0), but it’s blank. I’ve tried other d2 condition expressions as well. Does anyone have a quick recommendation for this?
Gratefully,
Natalie

3 Likes

I don’t think adding booleans is a good approach, and in fact, it will crash in Android due to the fact that the expressions are evaluated by the rule engine. My recommendation (which might not be the best and maybe someone from the backend can give a better one) would be:

  • Create 5 Program Rules variables
  • Create 5 Program Rules that evaluate your “YES/NO” questions by d2:hasValue(X) && X == "YES" assign 1 to the Program Rule variables created above
  • Add another Program Rule with higher priority that adds the 5 variables and assigns to the data element you wanted.

Thank you!! I’ve tried this but it’s still blank.

I created a program variable for the data element itself (the yes I want to count - “stigmatise les personnes”). Then I created another calculated program variable (stigmatize persons calculated value).
I created one program rule of priority 1 with the expression
d2:hasValue(#{stigmatise les personnes}) &&#{stigmatise les personnes} ==1
and the action “Assign value 1 to #{stigmatize persons calculated value}”.

I did the same thing for another yes/no response. Then created another program rule with priority 2 - Add the yes responses, with the action to assign value, expression d2:hasValue(#{Stigmatize persons calculated}) and expression to evaluate and assign, adding up the calculated values.

I think this is a good idea and should work, but the data element I am trying to populate with the sum just remains blank. Let me know if you see any issues!

Gratefully~

Hi @Natalie_Tibbels.

I have created a quick demo on the https://play.dhis2.org/2.34.0/ but I guess it will be deleted tonight; so I am adding a metadata package (remove the .pdf extension as it is a .zip)metadata.json.zip.pdf (3.3 KB) that you could import in the play server.

To be honest I was a bit more difficult that I initially thought because of the differences between the PR in Android and web.

The result in web|android is (what I think you wanted); note that I have added a “3” by default so it can be appreciated the changes.
vokoscreen-2020-05-09_10-55-40
vokoscreen-2020-05-09_10-59-37

You will need several Program Rules variable, in the form:
2 * (number of boolean fields)
Because you will need two program rules variables to assign either 0 or 1 according to the boolean state:
image

Then you will need the same amount of program rules pluse one, in the form:
2 * (number of boolean fields) + 1
image

Basically you are having two program rules per boolean to assign the number 0 or 1 so calculations can be made later:

PR1 condtion: !d2:hasValue(‘prv_boolean_one’) || !#{prv_boolean_one}
PR1 action: Assign value: “0” to field “#{prv_bool_one_to_number}”

PR2 condition: d2:hasValue(‘prv_boolean_one’) && #{prv_boolean_one}
PR2 action: Assign value: “1” to field “#{prv_bool_one_to_number}”

(repeat these two PR for every boolean)

Program rule to calculate (this is a bit tricky as we want it to be evaluated always so condition is true):

PR1 condtion: true
PR1 action: Assign value: “#{prv_bool_one_to_number} + #{prv_bool_two_to_number} + 3” to field “jb_test_boolean_calculation”

Please note that the program rules require to have priorities. The important thing is that the calculation is executed after the other ones. In the example I used Priority 1 for the assignations and 5 for the calculation.

Hope it helps.

2 Likes

This is amazing, thank you!

Hi again! Thanks so much for your help. I’ve made this whole thing work almost exactly as you said, except that I’ve been asked to include a couple of non-boolean data elements as well. Everything works except that the last program rule is adding integers together, not adding like a sum. So instead of 3+1+1 (where 3, 1, and 1 are calculated program rules based on answers in the form) = 5, it’s coming out to be 311. Any quick thoughts on what I might be doing wrong?

Also, I figured out the other value types, but not how to populate based on an option set. Thanks again!

This is probably because they are being treated like a string instead of a number. Is it happening only in web? Android? Both?

This is somehow known in Android (Home - DHIS2 Documentation).

Is there any chance you could provide access to the program with the program rules?

Just a remark, this is probably going to not be a problem soon when Android and Web share the same rule engine.

Best.

Thanks again! When will android and web share the same rule engine?

The program rules work just fine on the browser, but on android, every single one says “There is a configuration issue causing a loop in the rules.” If I click “accept,” The boolean calculation will work, but the option set or numeric rules will not.

For example, I have data elements for age (numeric) and sex (option set - male/female). I want to assign the value 3 for men 35 and older.

  1. I created the PRV ‘age’ (data element in current event) and PRV ‘sex’.
  2. Created a calculated PRV, ‘male_35plus’,
  3. Created a program rule to assign value, condition #{age} >=35 &&#{sex} ==‘01’ , with action assign value 3 to PRV ‘male_35plus’.
  4. male_35plus is then added to scores from other questions

Another example, I want to assign the value 3 if a person’s occupation is “seasonal worker” or “uniform” (option set code ‘sw’ or ‘un’), and 0 for all other options.

  1. Created PRV ‘occupation’ (DE in current event)
  2. Created PRV ‘occupation_calculated’ (calculated value)
  3. Created PR to assign value to occupation_calculated, expression=#{occupation} ==‘sw’, action= assign value: “3” to field #{occupation_calculated}.
  4. Created second PR for the other option code ‘un’

Those are all priority 1, and then the process of assigning sums of calculated value to an aggregate score is priority 5.

Let me know if you see anything wrong with this process for the way android evaluates! Or it may be part of what you the issues in the doc you posted (thank you).

Hello, am trying to do the same thing with a boolean field such that when i click Yes, it assigns value to another data element, but the assignment never happens. My program rule expression is :

The rule expression works if I display key:value pair but the same rule does not assign to data element

Hi @abdimohammed, just to understand properly the issue. Is this working in web but not in Android?

Hi? It occurs on both android and Web.

@jaime.bosque Can I give you credentials for my test server you try it out?? It would mean a lot if I can fix the problem.
Thanks

Thank you @jaime.bosque - for right now I think it seems to be working, apparently the problem was that I had value type text for the option set instead of number, which caused the score to concatenate. Field testing is ongoing and will keep you posted.

@abdimohammed Do you have both program rules, to assign 0 or 1 based on yes or no? I’m not sure it will help, but I was having trouble if only assigning for yes.

Hello all, the issue was that I was not generating resource table after making my changes.
Solution: Generate resource table

1 Like

Hello @jaime.bosque,
How Does the updates affect this part?? Do we need to change anything here?

Hi @abdimohammed. Not sure what you are referring to.

Hi,
Am refering to this answer here. I had set my program rules according to this answer. But the rules are not working after updating

error … This is an example you had given earlier. Does the update affect the rules above?

All rules configured as above works perfect in dhis2 web but the same rules not working on dhis2 android