Replace List Item Appinventor - app-inventor

I have a TinyDB and in each tag of the TinyDB I have a list.
Each list has 3 items, each indexed as 1, 2 and 3.
I want to change the 3rd item, index 3.
So I have done the following
So I want to now save the change in the TinyDB
and have added a storeValue command as follows.
I figured out how to get the valuetoStore variable. As follows.
I had done this before, and thought it wrong because it still doesn't change the 3rd item in the list. But I've added a notifier to look at it and it's correct. So the "replace list item" isn't working how I thought it should. It isn't replacing the 3rd item with an "n."
Any ideas?
Thanks.

Your second try is almost correct. The only thing is, you should use the replace list item block together with the local variable name instead of retrieving the value again from TinyDB.
So what is the difference to your "solution"? Currently you assign the list to a local variable name. Then you use the replace list item block together with a list, you can't store somewhere (you are loading the list again from TinyDB). And in the end you store variable name (which doesn't have been modified at all) in TinyDB. Therefore the solution is to use the replace list item block together with the local variable name instead of retrieving the value again from TinyDB. Btw. a better name for the local variable name would be list.
Further tips
Also in the definition of the local variable name you should add a block, e.g. an empty string or 0
And if you want simplify a little bit, you can move the definition of the local variable name inside the for each loop. And alternatively of using the for each number loop, for list it's easier to use the for each item in list loop, see also the documentation. The list in your case is TinyDB1.GetTags.
As already said in the forum, generally I would use a list of lists and store it in only one tag in TinyDB
How to work with Lists by Saj
How to work with Lists and Lists of lists (pdf) by appinventor.org

Related

How to declare a set of parameters in omnetpp.ini

I have hosts of two types: wirelessHostA[0..N], wirelessHostB[0..N]. I want to declare each of hosts wirelessHostA[0..N] to send messages to respective wirelessHostB[0..N]. Example: A[0] sends to B[0], A[10] sends to B[10]. Expression-wise I have got something like this:
*.wirelessHostA[0..${N}].app[ * ].destAddresses = "wirelessHostB[0..${N}]"
although this one is not correct. I am a bit unsure about how to declare a variable that can be iterated during a run and not a value per run.
You should not see the lines in the INI file as assignments where you can create procedural constructs like loops etc. Instead think about them as pattern matching rules. When a module needs a parameter, it scans the INI file from start, line by line and tries to match the first part (i.e. the part before =) to the current module path. If it matches, it assigns the second part to the parameter. If not, in continues with the next line in the INI file.
So first, write a pattern rule, then a value that can be evaluated in that context. When you specify the value, you may refer to other parameters (that are available in the module's context) or you may refer to other extra contextual information, such as the matching submodule's index (if it is part of a vector). There are other functions to access the index of parent of etc.
In this case, we have a submodule vector of hosts where each one contains a submodule vector of apps. The index operator would return the index of the current context module (which is the position in the app vector), but we need actually the index of the parent of the app vector (which is the host vector). There is a NED function for this too, called parentIndex(). So the solution would look like this:
*.wirelessHostA[*].app[*].destAddresses = "wirelessHostB[" + string(parentIndex()) + "]"
See https://doc.omnetpp.org/omnetpp/manual/#sec:ned-functions:category-ned for more info.

Access to iterated controls in repeated sections in Orbeon

When setting repeated content in a section in Orbeon each control is repeated and the their names are the same. How do I access the the control from the first, second...etc instance of a control from each iterated section? I'm thinking along the lines of $control-name[instance#] or something similair.
The following works, given this form:
$name[2]: return the second value
string-join($name, ', '): join all values with commas
count($name): return the number of values
See also the relevant documentation.
To access this value in "bind" section, you can use a relative path , like ../name=''.
TO access this value in "body" section, then you can use context()/../name.
If you are trying to make anything different, be more specific and this answer can be edited to be according to what you want.

App Inventor TinyWebDB List Problems

I got a problem using the TinyWebDB in App Inventor 2. Here's a Screenshot of the blockcode.
The goal of this Screen is to store a list(array) of images and later query them with a button but my problem starts already earlier. First there is a variable initialized called fotoList and declared as an empty list.
When this Screen initializes (left block) I store the empty fotoList under the tag FotoListTag. Then if the image under the tag "SteckbriefFoto" is not in this list -> getValue with tag "FotoListTag". Then he jumps into the block on the right and adds the photo .. other stuff not important .. at the end I store the list again in the TinyWebDB (and also in the TinyDB) with the tag "FotoListTag". Then it goes back to the block on the left where at the end I want to set an image.picture to the photo I stored in variable fotoList.
When I compile the code there is an error opening the page that says
Select list item: List index too large
Select list item: Attempt to get item number 1 of a list of length 0:()
I just don't get the problem with this code and i hope someone can help me.
For lists, valueIfTagNotThere should be create empty list instead of an empty string
On first run of your app, TinyDB is empty, which means, for tag = FotoListTag you get no value back, therefore this should be an empty list in the beginning.
Later you are trying to select the first item from the list (zahl is 1). As you know, the list is empty in the beginning, so probably you should add an if statement to check, if the list is not empty and only then select the first item... same for tag = Schriftlist.
You also have a timing issue. in Screen.Initialize you are trying to get a value from TinyWebDB. This is an asynchronous call, you get the result back in TinyWebDB.GotResult event and this takes a little bit (let's say 500 milliseconds), but meanwhile the complete blocks of the Screen.Initialize event will be executed. Probably you are expecting, that meanwhile tag = FotolistTag is not empty anymore, but this is not the case.

Parsing one large array into several sub-arrays

I have a list of adjectives (found here), that I would like to be the basis for a "random_adjective(category)" method.
I'm really just taking a stab at this, as my first real attempt at a useful program.
Step 1: Open file, remove formatting. No problem.
list=File.read('adjectivelist')
list.gsub(/\n/, " ")
The next step is to break the string up by category..
list.split(" ")
Now I have an array of every word in the file. Neat. The ones with a tilde before them represent the category names.
Now I would like to break up this LARGE array into several smaller ones, based on category.
I need help with the syntax here, although the pseudocode for this would be something like
Scan the array for an element which begins with a tilde.
Now create a new array based on the name of that element sans the tilde, and ALSO place this "category name" into the "categories" array. Now pull all the elements from the main array, and pop them into the sub-array, until you meet another tilde. Then repeat the process until there are no more elements in the array.
Finally I would pull a random word from the category named in the parameter. If there was no category name matching the parameter, it would return false and exit (this is simply in case I want to add more categories later.)
Tips would be appreciated
You may want to go back and split first time around like this:
categories = list.split(" ~")
Then each list item will start with the category name. This will save you having to go back through your data structure as you suggest. Consider that a tip: sometimes it's better to re-think the start of a coding problem than to head inexorably forwards
The structure you are reaching towards is probably a Hash, where the keys are category names, and the values are arrays of all the matching adjectives. It might look like this:
{
'category' => [ 'word1', 'word2', 'word3' ]
}
So you might do this:
words_in_category = Hash.new
categories.each do |category_string|
cat_name, *words = category_string.split(" ")
words_in_category[cat_name] = words
end
Finally, to pick a random element from an array, Ruby provides a very useful method sample, so you can just do this
words_in_category[ chosen_category ].sample
. . . assuming chosen_category contains the string name of an actual category. I'll leave it to you to figure out how to put this all together and handle errors, bad input etc
Use slice_before:
categories = list.split(" ").slice_before(/~\w+/)
This will create an sub array for each word starting with ~, containing all words before the next matching word.
If this file format is your original and you have freedom to change it, then I recommend you save the data as yaml or json format and read it when needed. There are libraries to do this. That is all. No worry about the mess. Don't spend time reinventing the wheel.

In Yahoo! Pipes how can I return a single value from a loop that's built with values from every item?

For example, I have a list of items and each item has a name. I want to build a single string that contains a comma-separated list of all the names. In most programming languages, I would loop over the items and append to a value outside the list/array. But, I can't figure out any combination of Yahoo! Pipes modules to do it. Maybe I'm missing something obvious, but I also find nothing relevant from Google.
How do I append loop item values to a single value outside the loop?
Or how can I return a single value from a loop that's built with values from every item?
Or what is the correct method to accomplish this in Pipes if it's neither of those?
The best method I've come up with based on help from the Yahoo! group, is to use an Item Builder (item.string = default) --> Loop ( assign all to item.string ). Using another pipe inside the Loop to provide the values to concatenate was also very helpful.
Unfortunately the modules available with Yahoo Pipes alone cannot perform the task you are aiming at. The only solution available currently is to use "web service" module to call an externally hosted script (say in PHP)... the entire pipe content will be sent to the script as POST field "data". You can code the script such that it loops through all items to add the string to a single string and return it after processing.

Resources