Assigning an array to a variable

Hi,

How do you assign an array of values to an indexed variable, where the form is currently created within Excel?

For example variable_name = [1025, 1026, 1035, 1050]

Thank you,

Are you talking about ODK Collect or the new 2.0 tools?

I don't know what you mean by 'indexed variable'

In ODK Collect, the user's chosen options for a multiple-choice field are
represented as a space-separated string of choice values.

You can then use the selected(${fieldname}, 'value') to test whether
'value' is among the selected options or use selected-at(${fieldname},1) to
get the first such choice, etc.

··· On Fri, Aug 14, 2015 at 10:09 AM, wrote:

Hi,

How do you assign an array of values to an indexed variable, where the
form is currently created within Excel?

For example variable_name = [1025, 1026, 1035, 1050]

Thank you,

--

Post: opendatakit@googlegroups.com
Unsubscribe: opendatakit+unsubscribe@googlegroups.com
Options: http://groups.google.com/group/opendatakit?hl=en


You received this message because you are subscribed to the Google Groups
"ODK Community" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to opendatakit+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--
Mitch Sundt
Software Engineer
University of Washington
mitchellsundt@gmail.com

Hi Mitch,

Thank you for your reply.

I refer to ODK Collect.

What I did was to allow the device-user to assign values to a variable within a repeat group for a fixed number of times.
Say the variable is called key_ID_number, the repeat group is named Idrecord_Group and the repeat_count = 3.

Now the device user can type in:
key_ID_number(1) = 1025
key_ID_number(2) = 1026
key_ID_number(3) = 1035

Henceforth, depending on the iteration number, the respective value of key_ID_number are re-called and used in a second repeat group.
The syntax used to re-call:

indexed-repeat(${Key_ID_number}, ${Idrecord_Group}, position(..))

It works fine.

However, the difficulty I face is that:

  1. Key_ID_number is completely irrelevant to the device user. Hence, I do not want the device-user to type in or select values regarding key_ID_number. These values are to be automatically assigned to key_ID_number within the form itself, in order to be recalled within a repeat group when needed.
    My question is, can it be done and if so, how?

  2. If it is possible to assign more than one value to key_ID_name outside a repeat-group, how will I re-call the respective values of key_ID_number with the syntax: indexed-repeat()?
    Will it be possible just to leave the group-name out and use the syntax:
    indexed-repeat(${Key_ID_number},position(..))?

Thank you for your help,

Peter

··· On Friday, August 14, 2015 at 7:09:07 PM UTC+2, toffie...@gmail.com wrote: > Hi, > > How do you assign an array of values to an indexed variable, where the form is currently created within Excel? > > For example variable_name = [1025, 1026, 1035, 1050] > > Thank you,

Wow Mitch! Thank you for your thorough reply. Much appreciated.

Attached is the excel-file with which I am busy with, as well as its related .csv-file that pre-load certain values.

Basically what it does, is that the device-user needs to provide a temperature. The form then determines and notify the colour range to which the provided temperature relates to: Green, Yellow or Red.
The parameter ranges of the respective colours are contained within the .csv-file. There is 3 parameter ranges with its unique key, each representing a colour. The keys are 3001 for Green, 3002 for Yellow and 3003 for Red.

Taken into account to convert multiple-select values into a set of string values: How is that being performed? I assumed most of the advice provided is from the perspective of hard-coding XML?

I am happy about the fact of your mentioning to work with an initial value and dynamically assign/determine the rest. All of the unique-keys are consecutive numbers, as already mentioned: 3001, 3002 and 3003, which indicates that it can automatically be determined.

Hence forth, can a value be assigned to the variable, as would occur in a typical for-statement?

For example:

initial_value = 3001;
monRecordID = ${initial_value};
for i = 1 to 3:
pulldata(...monRecordID) // values of either monRecordID 3001, 3002 or 3003 being pre-loaded//
monRecordID = monRecordID + 1; //monRecordID change from 3001 to 3002 and finally to 3003//
end;
(*Please note the above is my own version of writing to portray the concept and is not associated to a specific coding).

I this possible in Excel or at least in XML?

Thank you,

Test_Ranges.csv (79 Bytes)

Temperature_status.xlsx (11.5 KB)

··· On Friday, August 14, 2015 at 7:09:07 PM UTC+2, toffie...@gmail.com wrote: > Hi, > > How do you assign an array of values to an indexed variable, where the form is currently created within Excel? > > For example variable_name = [1025, 1026, 1035, 1050] > > Thank you,

From my attached example, it will be seen that in order to pre-load the unique keys, the user must select all of them. However, this will not make sense at all to the device-user and I try to avoid it by having the unique keys pre-set within the form. Yet, I do not know how.

Thank you Mitch,

You were much helpful.

Kind regards,

··· On Friday, August 14, 2015 at 7:09:07 PM UTC+2, toffie...@gmail.com wrote: > Hi, > > How do you assign an array of values to an indexed variable, where the form is currently created within Excel? > > For example variable_name = [1025, 1026, 1035, 1050] > > Thank you,

First, there is no mechanism to assign values to fields within a repeat
group from outside a repeat group. At best, you can provide unchanging (not
calculated) default values for those fields, but you can't change what
those unchanging default values are -- they are specified in the form
definition.

You can define calculated fields within a repeat group, and those will be
re-evaluated as the values change for the fields that they depend upon.

Multiple-choice (select) fields are stored as space-separated list of the
choice values. If you want to dynamically initialize fields within a repeat
group, you could place the initial values for the repeat into a string
value, with each initial value being a string that does not contain any
spaces. Within the repeat group, you could then have a calculate
expression such as:
selected-at(${initial_value_string}, position(..)-1) to grab the value
out of that ${initial_value_string} field (defined and calculated before
you enter the repeat group) and place it into the data field within the
repeat group.

NOTE: assuming you need these values to be dynamically generated and
unique, you will want to wrap the computation for ${initial_value_string}
with a once(...) function, to ensure that it is only computed once and that
subsequent edits or traversals of the filled-in form do not change these
dynamically-generated values.

There is no alternative syntax for indexed-repeat(...). Note that
indexed-repeat(${fieldname},${mygroup},1) would get the value for fieldname
inside the mygroup's first repeat. Where you get the value 1 is up to you.
I.e., it doesn't have to be position(..), but can be the value from another
field in the form, etc.

In general, as you make more complex forms with repeat groups, it may
become necessary to set an upper limit to the number or repeats you allow
in your form. This would typically be required so that you can write the
formulas that would compute these initial value strings or assemble the
results from the first repeat group into the set of initial values for
subsequent repeat groups. Note that if you use the multiple-choice string
field mechanism described above, you have:

selected()
selected-at()
count-selected()

available to help you write your formulas.

At some point, the if-then-else nesting of these formulas will exceed the
memory capacity of the device. This happens very quickly for string
patterns (regex() function), but will also happen with complex expressions.

··· --------------

The indexed-repeat() function is an alternative to using XPath expressions
to refer to fields in your form. XPath expressions of any complexity can
be fiendishly difficult to write, and there are a number of quirks in
javarosa that make that even harder. In some cases, however, it may be
easier to specify what you want by using an XPath expression. The key
problem in javarosa is that some valid XPath expressions don't work:

/data/mygroup[1]/datavalue
/data/mygroup[position() = 1]/datavalue

don't work. You need to write:

/data/mygroup[position(.) = 1]/datavalue

On Fri, Aug 14, 2015 at 3:01 PM, toffiehosting@gmail.com wrote:

On Friday, August 14, 2015 at 7:09:07 PM UTC+2, toffie...@gmail.com wrote:

Hi,

How do you assign an array of values to an indexed variable, where the
form is currently created within Excel?

For example variable_name = [1025, 1026, 1035, 1050]

Thank you,

Hi Mitch,

Thank you for your reply.

I refer to ODK Collect.

What I did was to allow the device-user to assign values to a variable
within a repeat group for a fixed number of times.
Say the variable is called key_ID_number, the repeat group is named
Idrecord_Group and the repeat_count = 3.

Now the device user can type in:
key_ID_number(1) = 1025
key_ID_number(2) = 1026
key_ID_number(3) = 1035

Henceforth, depending on the iteration number, the respective value of
key_ID_number are re-called and used in a second repeat group.
The syntax used to re-call:

indexed-repeat(${Key_ID_number}, ${Idrecord_Group}, position(..))

It works fine.

However, the difficulty I face is that:

  1. Key_ID_number is completely irrelevant to the device user. Hence, I do
    not want the device-user to type in or select values regarding
    key_ID_number. These values are to be automatically assigned to
    key_ID_number within the form itself, in order to be recalled within a
    repeat group when needed.
    My question is, can it be done and if so, how?

  2. If it is possible to assign more than one value to key_ID_name outside
    a repeat-group, how will I re-call the respective values of key_ID_number
    with the syntax: indexed-repeat()?
    Will it be possible just to leave the group-name out and use the syntax:
    indexed-repeat(${Key_ID_number},position(..))?

Thank you for your help,

Peter

--

Post: opendatakit@googlegroups.com
Unsubscribe: opendatakit+unsubscribe@googlegroups.com
Options: http://groups.google.com/group/opendatakit?hl=en


You received this message because you are subscribed to the Google Groups
"ODK Community" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to opendatakit+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--
Mitch Sundt
Software Engineer
University of Washington
mitchellsundt@gmail.com

No, there is no concept of re-assignment:

monRecordID = monRecordID + 1;

There is ONLY the concept of re-evaluation.

If you are a programmer, this is most similar to a logic programming
language.

The form definition is a declarative document.

It does not by itself describe program flow and, being declarative, does
not describe iteration.

Relevant conditions are just that -- preconditions for the inclusion of the
fields in the resulting document.

The way to do what you describe is:

monRecordIDSet = "3001 3002 3003" // declare the set of all ids
begin repeat (jr:count = 3) // require 3 repeats
monID = selected-at(${monRecordIDSet},position(..)-1)
pullData(..monID)
end repeat

Nothing here is iterative or algorithmic. It is declarative:

The assertion that monRecordIDSet contains set of all possible IDs
The requirement for 3 repeats of a group
The assertion that monID within the repeating group is chosen from among
the set of possible IDs by pulling out the Nth ID.
The assertion that the data within the repeating group is pulled from some
external data source.

When ODK Collect processes this declarative document, it proceeds to
evaluate, in-order, the preconditions for each question, and present them
to the user if that precondition is satisfied. From a declarative
standpoint, this imposes an artificial ordering on the survey, but it is
what we, as survey designers, expect. Internally, ever time you update a
value, all calculations and relevant conditions that depend upon that value
are evaluated (to maintain the declarative reality). When you finalize the
form, a final sweep through the form is made to ensure that all conditions
are still satisfied. If not, you are thrown back to the first field that is
now inconsistent.

··· On Sat, Aug 15, 2015 at 6:50 AM, wrote:

On Friday, August 14, 2015 at 7:09:07 PM UTC+2, toffie...@gmail.com wrote:

Hi,

How do you assign an array of values to an indexed variable, where the
form is currently created within Excel?

For example variable_name = [1025, 1026, 1035, 1050]

Thank you,

Wow Mitch! Thank you for your thorough reply. Much appreciated.

Attached is the excel-file with which I am busy with, as well as its
related .csv-file that pre-load certain values.

Basically what it does, is that the device-user needs to provide a
temperature. The form then determines and notify the colour range to which
the provided temperature relates to: Green, Yellow or Red.
The parameter ranges of the respective colours are contained within the
.csv-file. There is 3 parameter ranges with its unique key, each
representing a colour. The keys are 3001 for Green, 3002 for Yellow and
3003 for Red.

From my attached example, it will be seen that in order to pre-load the
unique keys, the user must select all of them. However, this will not make
sense at all to the device-user and I try to avoid it by having the unique
keys pre-set within the form. Yet, I do not know how.

Taken into account to convert multiple-select values into a set of string
values: How is that being performed? I assumed most of the advice provided
is from the perspective of hard-coding XML?

I am happy about the fact of your mentioning to work with an initial value
and dynamically assign/determine the rest. All of the unique-keys are
consecutive numbers, as already mentioned: 3001, 3002 and 3003, which
indicates that it can automatically be determined.

Hence forth, can a value be assigned to the variable, as would occur in a
typical for-statement?

For example:

initial_value = 3001;
monRecordID = ${initial_value};
for i = 1 to 3:
pulldata(...monRecordID) // values of either monRecordID 3001, 3002 or
3003 being pre-loaded//
monRecordID = monRecordID + 1; //monRecordID change from 3001 to 3002 and
finally to 3003//
end;
(*Please note the above is my own version of writing to portray the
concept and is not associated to a specific coding).

I this possible in Excel or at least in XML?

Thank you,

--

Post: opendatakit@googlegroups.com
Unsubscribe: opendatakit+unsubscribe@googlegroups.com
Options: http://groups.google.com/group/opendatakit?hl=en


You received this message because you are subscribed to the Google Groups
"ODK Community" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to opendatakit+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--
Mitch Sundt
Software Engineer
University of Washington
mitchellsundt@gmail.com

And you may also find

join(' ',${datavalue})

useful.

It that usage, you would have your repeat group with a datavalue calculated
field with some expression to calculate your unique key id (wrapped with once()
so it won't change). That key id would not contain any spaces.

Then after that repeat, you would have a calculated field with the above
expression.

And this would give you the set of key ids for all the repeats in that
repeat group.

You could then have a subsequent repeat group that iterated over those
values to collect additional info.

··· On Fri, Aug 14, 2015 at 3:54 PM, Mitch Sundt wrote:

First, there is no mechanism to assign values to fields within a repeat
group from outside a repeat group. At best, you can provide unchanging (not
calculated) default values for those fields, but you can't change what
those unchanging default values are -- they are specified in the form
definition.

You can define calculated fields within a repeat group, and those will be
re-evaluated as the values change for the fields that they depend upon.

Multiple-choice (select) fields are stored as space-separated list of the
choice values. If you want to dynamically initialize fields within a repeat
group, you could place the initial values for the repeat into a string
value, with each initial value being a string that does not contain any
spaces. Within the repeat group, you could then have a calculate
expression such as:
selected-at(${initial_value_string}, position(..)-1) to grab the value
out of that ${initial_value_string} field (defined and calculated before
you enter the repeat group) and place it into the data field within the
repeat group.

NOTE: assuming you need these values to be dynamically generated and
unique, you will want to wrap the computation for ${initial_value_string}
with a once(...) function, to ensure that it is only computed once and that
subsequent edits or traversals of the filled-in form do not change these
dynamically-generated values.

There is no alternative syntax for indexed-repeat(...). Note that
indexed-repeat(${fieldname},${mygroup},1) would get the value for fieldname
inside the mygroup's first repeat. Where you get the value 1 is up to you.
I.e., it doesn't have to be position(..), but can be the value from another
field in the form, etc.

In general, as you make more complex forms with repeat groups, it may
become necessary to set an upper limit to the number or repeats you allow
in your form. This would typically be required so that you can write the
formulas that would compute these initial value strings or assemble the
results from the first repeat group into the set of initial values for
subsequent repeat groups. Note that if you use the multiple-choice string
field mechanism described above, you have:

selected()
selected-at()
count-selected()

available to help you write your formulas.

At some point, the if-then-else nesting of these formulas will exceed the
memory capacity of the device. This happens very quickly for string
patterns (regex() function), but will also happen with complex expressions.


The indexed-repeat() function is an alternative to using XPath expressions
to refer to fields in your form. XPath expressions of any complexity can
be fiendishly difficult to write, and there are a number of quirks in
javarosa that make that even harder. In some cases, however, it may be
easier to specify what you want by using an XPath expression. The key
problem in javarosa is that some valid XPath expressions don't work:

/data/mygroup[1]/datavalue
/data/mygroup[position() = 1]/datavalue

don't work. You need to write:

/data/mygroup[position(.) = 1]/datavalue

On Fri, Aug 14, 2015 at 3:01 PM, toffiehosting@gmail.com wrote:

On Friday, August 14, 2015 at 7:09:07 PM UTC+2, toffie...@gmail.com wrote:

Hi,

How do you assign an array of values to an indexed variable, where the
form is currently created within Excel?

For example variable_name = [1025, 1026, 1035, 1050]

Thank you,

Hi Mitch,

Thank you for your reply.

I refer to ODK Collect.

What I did was to allow the device-user to assign values to a variable
within a repeat group for a fixed number of times.
Say the variable is called key_ID_number, the repeat group is named
Idrecord_Group and the repeat_count = 3.

Now the device user can type in:
key_ID_number(1) = 1025
key_ID_number(2) = 1026
key_ID_number(3) = 1035

Henceforth, depending on the iteration number, the respective value of
key_ID_number are re-called and used in a second repeat group.
The syntax used to re-call:

indexed-repeat(${Key_ID_number}, ${Idrecord_Group}, position(..))

It works fine.

However, the difficulty I face is that:

  1. Key_ID_number is completely irrelevant to the device user. Hence, I do
    not want the device-user to type in or select values regarding
    key_ID_number. These values are to be automatically assigned to
    key_ID_number within the form itself, in order to be recalled within a
    repeat group when needed.
    My question is, can it be done and if so, how?

  2. If it is possible to assign more than one value to key_ID_name outside
    a repeat-group, how will I re-call the respective values of key_ID_number
    with the syntax: indexed-repeat()?
    Will it be possible just to leave the group-name out and use the syntax:
    indexed-repeat(${Key_ID_number},position(..))?

Thank you for your help,

Peter

--

Post: opendatakit@googlegroups.com
Unsubscribe: opendatakit+unsubscribe@googlegroups.com
Options: http://groups.google.com/group/opendatakit?hl=en


You received this message because you are subscribed to the Google Groups
"ODK Community" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to opendatakit+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--
Mitch Sundt
Software Engineer
University of Washington
mitchellsundt@gmail.com

--
Mitch Sundt
Software Engineer
University of Washington
mitchellsundt@gmail.com