Constraint 'not equal' not working

Hi all,

I am trying to build in a warning based on a ‘not equal’ constraint (row 16 in the excel). However, the warning keeps popping up, even when the constraint is not valid (so in case both values ARE equal). Any advise how I can make this work? Thanks!

ODK forum_not_equal.xlsx (17.2 KB)

Put a note question before row 16 that outputs the two values in the label so you can confirm if they are equal or not. I put the quotes there so you can see if there might be trailing spaces.

debug: '${calculate_total_species}' '${tree_number}'

The other potential issue might be data types. In the constraint, try casting both values.

number(${calculate_total_species}) != number(${tree_number})

Hi @yanokwa ,

I tried both options. Even if the output results are the same, the note in row 16 is still activated. Also casting to a number data type does not help.

(I'm guessing column types as the extract doesn't include them, pretty sure they're right from context)

calculate_total_nr_per_species is the sum of all the repeat elements for 'how many trees of species x'
calculate_total_species takes the above and converts it to an integer (so the values for these two fields should be the same), could be done in one step, but also shouldn't be required.

warning_misalignment_total_nr_species is a note with a constraint ${calculate_total_species} != ${tree_number} and relevance of selected(${confirm_nr_trees_per_species}, 'yes'). I don't think a constraint can do anything on a note as it is acting on the user input value of the field.

So, no matter if calculate_total_species = tree_number or not, the note will still show if selected(${confirm_nr_trees_per_species}, 'yes') is true and the constraint will not do anything.

It seems the note should have relevance of ${calculate_total_species} != ${tree_number} and selected(${confirm_nr_trees_per_species}, 'yes') so it will only appear when these are both true, and also have a required of yes, which will prevent continuing (as you can't enter anything to a note, but it's required so this is effectively a block) until values are changed to make the note not relevant.

BUT - If there are x 'other' species', the number planted of these are excluded from the sum and the form will prevent the user from continuing as the sum of planted selected species will be < total trees planted which also includes the number of non-selected species planted. You could:

  • modify the question from "Can you specify the number of trees planted for each species?" to "Can you specify the number of trees planted for all selected species?", or
  • include logic to add an element to the repeat to capture the total # of all trees of all non-selected species together, or
  • change the relevance test to check that the sum is (!= if other species is blank) and (< if not blank). But this is imperfect as the entered totals could be net incorrect on the low side and form still be valid.), or
  • add another repeat that asks for each nonselectable species and the # planted then add the sum of these to the existing sum of those planted for selectable species and test that sum-selected + sum-nonselected = total planted for relevance, or
  • completely rework the structure to something like
    • INT: How many trees in total were planted? (required = yes)
    • start repeat:
      • SELECT_ONE: select a planted species, or select 'other' if not listed (required = yes) (constraint to prevent already selected species / choice filter to remove already selected option)
      • TEXT: enter the non listed species name (relevant if above is 'other') (required = yes) (constraint to prevent already entered species)
      • CALCULATE: coalesce(select , text)
    • end repeat
    • SELECT_ONE: Can you specify the number of trees planted for all species? (required = yes)
    • start repeat (relevant if above is yes)
      • similar repeat as existing but use the coalesced value in the label via indexed-repeat or position logic
      • INT: How many of coalesced value were planted? (required = yes)
    • end repeat
    • CALCULATE: sum of above # per species
    • NOTE: Error, mismatch, go back and check your inputs (relevant if total planted != sum species planted AND can you specify = yes) (required = yes)

Alternatively, use "can you specify the number of trees planted for any species", make the # planted in the repeat optional, and make the relevant on the note (if total planted < sum species planted AND can you specify = yes) (required = yes), which isn't perfect but prevents the sum of each species planted > total planted but could net underreport values for species planted.

You might also be able to ask "do you know how many of 'species' were planted" in the first repeat and then capture the value if 'yes', and at the end check that (total planted) < sum (species # planted) and do away with the second repeat entirely. Still has the possibility to individually over&underreport with a net underreport as above. (eg total = 100, first species don't know (actual = 10), second do know, 40 (actual = 45), third species do know 50 (actual = 45). sum is 90, second is wrongly low, third is wrongly high but form valid)

Example form with the relevance/required parts fixed up:

constraint_issue.xlsx (561.9 KB)

2 Likes

Yes, the issue is constraint never makes sense for a note. (@LN to confirm?)

Hint: Using an acknowledge type instead of the (required) note, might offer an advantage:

  • allowing a non-equal (if possible rare case)
  • registering the “OK” of the respondent
  • allowing to add a required comment
  • not blocking to submit the case.
1 Like

@ahblake,

Many thanks for this extensive answer! What solved the issue was putting the constraint in the relevance column (not in the constraint colom). I added the excel to show the working result. I also took into account your comment on the ‘other’ tree species. Good point! Thanks again for your help.

solution.xlsx (15.3 KB)

1 Like

It's technically valid but I agree I can't think of a good use for it. I could imagine maybe having a note with an explanation of pass/fail conditions that's always shown and then using a constraint on that note to draw attention to it if the fail condition is reached? It feels like a bit of a stretch and I think @ahblake's suggestions are great!