2017년 4월 2일 일요일

List of Lists as a Text String


See my list below 

How can I write this as a ONE TEXT string attached to "list from csv table" block. 

I looked around but did not find anything specific : may be something as simple as \n or maybe blank space but having no luck today. 


--
yes exactly, just use \n to get a new line

1A1,1A2,1A3\n1G1,1B2,1B3\n etc.

--
Thanks .

How do I do with three levels of list of list as in example 

1. First level is defined by "comma"
2. Second level defined by new line \n
3. what about third level 
or even fourth 

--
a csv table only can have 2 dimensions, but you can do something like this

--
@Taifun .... great graphic ...should be in your web page hints.

--

if i understand correctly this might work as well 

for three dimension - list from csv row and then list from csv tabel

for fourth - list from csv table - list from csv table 

--
thank you @SteveJG
@Richard: just try something and prepare a screenshot of your blocks incl. Do it result
this also can help others with the same problem. Thank you.

-- 
I will post blocks tonight

I think we can put multilevel csv in a single Text box. 

--
If you want to extend into higher dimensions,
you could store things sparsely in TinyDB with
tags of the form 
"i1,i2,i3,i4..."
where the length of the key list is your number of dimensions.

I have no data on performance, but
you might get  reduced block complexity.

--
Did your blocks works?
If it worked, do you mind attach the screenshot on :
1. how the blocks build to read csv?
2. how should i write the format in the csv file?

because i used the "∖n" but nothing happened as i want it to.

--
I was thinking that I will use list of csv block attach to list of table block -- that did not work after several hours of work. 

I think, Only way to this ( 4 level list of list in one text string) will be using :  " " the parse those out before calling list from csv row.  I did not proceed further as I used tinyTB to share my list between the screens. may be someone want to try out

--

is in list error


I am trying to import data from a file. When I get data, I convert it to a list. then I check if the first item in the first list in a list of lists. I get that its "b15". then I check if it's already on the list,  but it says false, although it is there. I tried with and without the trim, but it doesn't work. I have to prevent duplicate entries. Any ideas?

Edit: Now I checked the length of the two "b15" and one seems to be four letters. What could be the extra letter even when I check it with trim?



--
how do the data in the file look like? can you provide an example?
currently you convert the data using the list from csv table block and assign it to variable geciciname?
unfortunately the Do it result hides most of your blocks...

-- 
Perhaps change all \n to a zero length string to filter out invisible NL characters?

-- 
Well, the data is just like this, from the csv I import:
b15,1,2013075,name1
b15,2,2013053,name2
b15,3,2014029,name3
b15,4,2014067,name4

and so on.. I convert it using the list from csv table. interestingly, it shows only the first b15 item as four digits. the others are three digits. I checked the csv file time and again, but the raw data there does not have any spaces before or after.

Is the ∖n a character? can it be removed with a block combo?

--
just update your file (to remove the strange b15) and upload it again to App Inventor
\n is a new line character, but this does not seem to be the issue here

-- 
Ok. I did this once more with some other input, and saved it as csv. Nothing looks odd in MsExcel or Notepad. But I still get duplicate entries. And the reason for that seems to be the strange character MS-DOS type command showed me. As you can see in the attached photo, there is a strange character before the class name b54. the other lines don't have this, so this is what causes the duplicate. Does anyone know what this character is? Is there a way to get rid of it? Can I build a check block to get rid of it? I'll ask my users to input csv files. If this keeps happening, I'm in trouble.


--
does this happen in Excel only or also if you create the csv file with Notepad?
you can try Notepad and save the file in UTF-8 format, see also https://puravidaapps.com/snippets.php#2webget


-- 
This looks like a three byte BOM.

It would always have the same value if it's there, 
hex EF BB BF, so test for it at the front of the file 
and chop it off if it's there.

You can generate this 3-byte sequence at run time using the
Web1.HTML_Text_Decode block and the right inputs.

Attached is a sample that generates a 2-byte BOM.
Extend it to get your 3 byte BOM.
It also shows how to see what kind of unreadable characters you have.


--
When I copy cells from excel to notepad and save it as csv there, the odd character is still there. And now I tried to create a csv just by typing in to a notepad and saving it as a csv file, it's still there.

From Stackoverflow:
In particular, Microsoft compilers and interpreters, ... will add a BOM to the start when saving text as UTF-8. 
I believe that's the whole case.  ABG, you suggest a solution which will be a new chapter for me. I have no idea how to deal with encoding decoding things. So, I'll take the shortcut. Now the easiest way for me would be to tell the users to create a line of headings for the data below, and tell the app to ignore the first item in list.

--
Sneaky!
I love it!

--

Build Your Own DB - Part 1


How to Build Your Own Data Base using Blocks  - Part 1
Abe Getzler
7/6/2014

Motivation



App Inventor 2 does not provide access to any kind of local SQL database.  It offers TinyDB, a key/data local store, and Fusion Tables blocks, for SQL access to Google’s Web based relational data base.  The Fusion Tables interface requires you to remember your column names, and to understand and follow SQL syntax to build queries.


In this paper, we will work our way up to relational data base concepts by building on the list facilities of App Inventor.  We start with some familiarity with simple lists, and work our way up to tables.


Prerequisite reading





Some Sample Data





Here’s part of a conversion table, done as a list of lists, also known as a table.  


To read this, we go row by row.  The first row says that to work with lengths, we can convert feet to inches by multiplying by 12. Likewise, the second row says that to work with lengths, we can convert miles to feet by multiplying by 5280.


I threw in a few time conversions also following the same pattern.  Each column serves a single purpose:


  1. The Dimension: type of units being converted (length, time, weight, etc.)
  2. The measure being converted From
  3. The measure being converted To
  4. What Factor we must multiply by to do the conversion.


I’ve done this as a screenshot to show the structure and how you can nest lists inside lists.  I’ve used the right-click “Inline Inputs” and “External Inputs” Block Editor options to get this rows and columns effect.  You can also type data into a spreadsheet program and export the data as a CSV  table:


I’m going to cheat and use the App Inventor emulator, right-click-DoIt,  and one of the table blocks to extract the data in CSV table format, in case you want to copy my data...




"length","feet","inches","12"
"length","miles","feet","5280"
"length","inches","cm","2.54"
"time","hours","minutes","60"
"time","minutes","seconds","60"
"time","seconds","milliseconds","1000"
"time","milliseconds","seconds","0.001"


Slicing and Dicing



Data Analysts use a cooking analogy for the act of chopping up a table by row and by column.
One way to slice up a table is to pick only those rows that have a particular value in one column.
In SQL this is specified with a WHERE clause, so let’s name our procedures using the word WHERE…


WHERE_EQ



This is a result procedure that accepts a table (a list of lists) and returns a smaller table containing the same columns, but only the rows where a particular column (specified by column number) equals a particular value.

WHERE_EQ.jpg



Because App Inventor has two different kinds of comparison blocks, one for numbers and another for text, we decide early on which comparison we will use rather than deciding on a row by row basis.  People usually store either numbers or text in any one table column, and never mix them.


WHERE_EQ_NUMBER



WHERE_EQ_NUMBER.jpg


WHERE_EQ_TEXT



WHERE_EQ_TEXT.jpg
Notice that these two return procedures differ only in the type of block used for the comparison in the inner if-then block.


For convenience, we only need to remember to use the WHERE_EQ procedure …


Here’s a sample application of WHERE_EQ, using a spinner selection of “length” for column 1 of our data table, to give us just the rows for length conversions …


Screenshot 2014-07-22 16.18.28.png


Because WHERE_EQ is a return procedure it can be combined with other return procedure calls.  If we want to return just the rows from our sample data with a Dimension (column 1) value of “length” and a From value of “feet” we nest the calls …


Screenshot 2014-07-22 16.40.23.png


If we want to test for other conditions such as “less than”, “greater than”, etc., we can duplicate our WHERE_EQ procedures, and change the names and test criteria, such as WHERE_LT, WHERE_GT, etc.


DISTINCT



If you want to filter your table data by particular column values, you need a procedure that will return a list of distinct values from one particular table column.  This can be used to prime the Elements list of a List Picker, List View, or a Spinner.


DISTINCT.jpg


This builds and returns a result list by starting with an empty list, running through the input table, and checking each value in the requested column number against the result list before adding it.


This is an example of the expression you would use to feed the Elements of a Spinner or List Picker to decide which dimension (length or time) to use to filter our conversion table...


Screenshot 2014-07-22 17.41.45.png


SELECT



This is for when you want just some of the columns in a table, but all the rows…


from =  a table (list of lists) input
column_nos = a list of column numbers in the input table we want in the result
result =  a table with all from’s rows, but just the requested column numbers, slid down.


SELECT.jpg


A sample app - conversions



Screen shots - Designer



Designer_V1.jpg


Screenshot 2014-08-15 12.58.46.png


Screenshot 2014-08-15 13.03.09.pngScreenshot 2014-08-15 13.03.37.png


Screenshot 2014-08-15 13.04.01.png

TinyDB help please


Is there anyway to have data PRE STORED in a TinyDB when an application starts for first time?

The database held will be a list of names and stats for a baseball player. These do not change at any time.

i can write blocks so when a name is generate it is then saved in the TinyDB while the application is open but not so Data is already there when the application opens for the first time.

--
"Is there anyway to have data PRE STORED in a TinyDB when an application starts for first time?"   No.  Prefilling a TinyDB is not possible.   A predetermined csv file can contain the same information.       "Babe Ruth", 714,2873,2213,2.28         where    name,Hr,Hits,RBJI,ERA   is the sequence.     Access the info with the File component.

 Put the names and stats in a csv text file.  The csv can be hard coded using blocks or saved as a resourse in Media easily.  You can read the csv from the sdCard, however that is not what you want to do.   If the stats must be in the TinyDb, load the csv data to the TinyDB on first run of the app either with the File control or it might already be there if you load it as a resource.

Depending on what your app does, you could retrieve and store the stats in the csv file  instead of in the TinyDB.      

--
Second time writing this, lets see if it posts this time!!! :0

I did consider the CSV idea however the blocks is where i fell down and couldnt find a solution. 
The CSV was created in excel and has 10 columns and around 50 rows so far.

i can do the blocks to find the file and read it but then it breaks down and i get lost.
what i want it to do is as an example find the name in column one "babe ruth" and the then populate certain labels with data from his row

Make sense?

--
i can do the blocks to find the file and read it but then it breaks down and i get lost.
It would really help if you provided a screenshot of your relevant blocks, so we can see what you are trying to do, and where the problem may be.

you also might want to learn how to work with lists
⦁ How to work with Lists by Saj
⦁ How to work with Lists and Lists of lists (pdf) by appinventor.org

this also can help: how does a list of lists (2 dimensions) look like

--
i cleared the one i did previous so created quick one to show u the blocks i am up to and the details on side panel,

From my understanding them blocks tell on screen start up to change a text label to entry in the TDB and then to call the CSV file.
From here i am stuck...

-- 
as already recommended, learn how to work with lists, you will need it...


-- 
I understand how to create a list, how to use the spinner and seclection.

I understand the result command also that once it is read it will come back with a result,

What i dont get is the next step which is saving that result back as a table that is searchable.

-- 
ok i have now managed to get to here.

The csv is read and the result is added the the list. However not as i wanted.  i have added the Do it comment too.
It found right hook which is correct but when read the CSV also contains a description in the next column and a damage number.


-- 
what i want it to do is as an example find the name in column one "babe ruth" and the then populate certain labels with data from his row
after importing the csv table into a list of lists you will have to create 2 lists: a list which contains only the first column of the table and a list of lists, which contains all other information

Now you can use the index in list block to get the index of "babe ruth" from list1, then use the select list item block to select all the corresponding information from the list of lists

you might want to learn how to work with lists, then try something and if you get stuck, post again here with a screenshot of your relevant blocks

--
This example uses only csv files loaded to Media 9resources.)  It might provide you with some ideas.

The ListView has a search capability which unfortunately is BROKEN, so don't even try.   You can place all your player names in the list view.  Two ways of handling the data are shown.  Build the app and experiment and use the pieces you need.    



--
Thank you so much that was very very useful. I am trying to perfect this on the wrestling app i was working on at the moment and can now get to the point where reads the CSV files and is able to select a row based on index as number. Attached is the blocks and do it responses. i cannot see to get the last part working where it will display the reuslted rows as seperate entities.  ie pull first part of string in index 1 and change label to it, then index 2 and so forth. every permitation i have tried has failed.
Can you look at the attached and see how it looks to you. i have deleted the final blocks so i can add them.






--
Here's a doc with another example for you ...
Thank you for the link.

I have seen this doc before and still have trouble getting head around it.

--
What would help is to see what your csv file looks like  ..the rest of the block you are copying from...which you do not have in your code, displays the csv file.

I am going to guess part of your problem is that you do not have a space where the green circle is located ..perhaps you left it blank?     The second part is the issue could be how you made your csv file.   If the file comes from an Excel spreadsheet I have heard that Excell adds extra 'hidden' characters when it converts.   I do not have Excel so not the expert here; however, if your csv has extra hidden characters, that may be why the file is not displaying (the other reason is that you have to be connected to a device or an emulator for the DoIt to work.

--
The file was created in excel 2010.

The problem just to clarify is the  next step after where I am now (pics from last pos)

So far AI2:
- Finds both csv files.
- looks for as an example index 4 and pulls the row
- row is the placed in its own list
- the row displays on a label with open and close brackets.  There is 6 parts in the string and all are there.

What I need next is for the app to take that info and seperate the 6 onto individual labels

--
Wow you guys are good!! :D:D:D

it looks like it now working. i had missed the space but also hadnt got the split line in correctly. 

Will go from here and will post and let you know how i getting on.

--
The example shows how to separate into separate labels Gaz.    I think the problem is described here:  is in list error    but I do not know how someone gets rid of a BOM.     Sorry, I do not have excel ...I imagine you would use a fancy Notepad clone like Notepad ++   that can show hidden files and remove the BOM.

To get into labels, you probably need to fix the BOM issue   and then use the labe3 to label 7 part of the example code blocks (label8 outputs the info in a single string).

I would do this, redo the first two or three entries in you excel spread sheet, but make them in the form shown in the example... do not copy them, type them in Notepad.  Then, replace your current csv files with this shortened file and see what happens.

--

Spinner name selection


I have a spinner that will select a sound, displayed what was selected and play the selection.  The spinner list has the names of the sounds "alarm1.mp3, alarm2.mp3....."

I would like to see in the selection "Alarm 1, Alarm2...)  Is there a way to have the text replaced?  Say Alarm 1 = alarm1.mp2....



--
use a second list with the nice names and use that list for the spinner
then in the AfterSelection event select the corresponding item from the first list using the selection index

-- 
When the screen loads and or I select spinner I get an error (701 unable to load Sound X and unable to play Sound X)


--
Getting frustrated.  I have this now, when I select a sound from the spinner I get unable to load 2 and unable to play 2 (number based on what one I select)

I understand what the #2 represents (it is the selection index line.  how do I take that selection line 2 and get it to select line 2 in the list of sounds?



--
ok, stepped away for a moment and got it.  for anyone else looking here are the block to make this work. 

--

Problems with spinner


It seemed to be working properly until few day, but now when i use the spinner it looks like sometimes it work sometimes it doesn't.
The problem is that the function "after selection" doesn't work all the times, sometimes it seems like you havent selected anything. To fix it i have to select an other item and then select the first again.
To check it i used a notifier that After selection showed the selection. Sometimes the notifier pop up with the selection, sometimes it doesn't!

--
The spinner has been re-worked a bit.  Prior to this release, the spinner's AfterSelecting block was triggered as soon as the app loaded.  That caused problems.

Now, you have to select each spinner as they are not automatically chosen for you.  The AfterSelecting will ALWAYS fire if you make a different selection.  In other words, if you have 3 items on a list, "Select...", "1" and "2," Select will be the first one showing when the spinner loads, but it's not selected... it's just the top of the list.,  If you drop that list down and try to select the first one, "Select...," nothing will happen because it's already chosen but no selected.  The reason you load the spinner with that first "Select..." choice is because you than HAVE to make a choice to register an actual selection.  If you drop the spinner, and choose 1, the AfterSelecting block fires, as do all the rest.

--
Thanks for your reply. I understood the way it works but still can't make it work properly, e.g. my spinner is empty at beginning, i create a list and use it to set its elements, and i set a selection using the method .SelectionIndex or .Selection
Now, if i select a different item, it doesn't get triggered. I have to select a third one to be triggered.
E.g. my list is "choose", "1", "2". I set my spinner list using these three items, and select "choose". If then i select "1" or "2", the after selection doesn't work, if I select again it does.

Another issue is in the little program in the attachment. If i press twice The button and then select an item the .AftesSelection doesn't fire.

--
You have to make a physical selection with the spinner.  So when the spinner initializes, it will SHOW "Choose," but nothing has been selected yet.  If you drop the spinner and choose "Choose" it will NOT trigger.  You have to select 1 or 2.

You're trying to do the physical selection by code, and that's not possible I don't believe.  If you set a selection index programatically, it will NOT generate the AfterSelecting block.

--
Sorry for my english, maybe i didn't explain quite well :)
I just use the code to put the selector on "choose" but i don't really need to fire in that moment. Then i physically select a different option (eg. 1) and still doesn't fire. It I select again another item (choose or 2) then it fires.
Did you try the snipplet i posted? clicking twice on the button doesn't fire at the first selection either.
I can show you my complete code if this can help, but it's quite big.

--
I tried your snippet. What I see is that the event does not fire when you select the same thing as what you set the selection index to. I think that this is works as designed, because your selection does not change what was already selected.

-- 
Yes, Ghica's correct... One a selection is made, AfterSelecting will not fire if you select the same item again... it will only fire once you change the selection.

--
Actually, I think this is a bug. It cannot be true that if you try to select twice the same thing that the event would not fire.

-- 
Actually Ghica, it's part of the OS...

Here's a note I received from Jeff about this when I brought it up during the testing:

The issue here is that the low level Android control assumes that the first item is already selected. So selecting it does not generate an After Picking event. Indeed the work around is to make the first item a non-choice like "Select from below..." etc.


-Jeff

That also means that as part of the workaround you should reset the selection to the first item in the After Picking event, otherwise you will have no event firing if you choose twice the same thing.

-- 
That's correct... if you preset it, then you'd also have to set whatever would trigger on selecting when you assign the selectionindex.
Of course, the easy way to do that is to have what happens in AfterSelecting in a proc, and call the proc after the initial set, and also in AfterSelecting.

--

Spinner After Selecting


Good day Expert!
I just wanna ask if there is any way to fire an after selecting event if i choose the same value of the past selection.??
Please help if u got any idea :)

--
This is an Android thing and cannot be done.
It just means that you must do something else to find out the value of the spinner. Treat it like a value entered in a form and have a submit button to read the values.

--
Have you tried storing the prior selection in a global variable, for example named Prior_Selection?

--
My app in to send via sms the element selected in the spinner.. so whenever i want to resend ill just need to select again the item in spinner.. but unfortunately picking the same value does not trigger the after.selecting event.. Is there any way to force trigger even ig i choose same item..??

--
A submit button is your only option with a spinner, but maybe you could use a ListPicker? That one will fire after picking I think.

--

Order a Spinner values from TinywebDB


I try order a spinner values from my Custom TinywebDB. but i can not do it.
Please help me.

TAGVALUE SAVED
Motonaves        ["tai_splendor", "lowlands_brabo", "thor_thunder", "harvest_legend", "nomadic_milde", ""]

I need show names (values) list by "Date" or "last modified" ..( showing first, the last saved )
Now spinner show first line, the first saved.

--
your question is about how to order a list...
or find other solutions after doing a search in the forum

alternatively store your data in a fusiontable to be able to order your values easily
SELECT * FROM <tableid> ORDER BY Date
do the Pizza Party tutorial to learn how to work with fusiontables


-- 

Spliting text for spinner


I want to take text from text box insert it into TinyDB (I use text from textbox like a tag not like a value to store because that is better for me) and then I take text from DB and insert it into spinner. So but if I read data from DB it write it like "(1tag 2tag 3tag)" and more (tag1... is for exampe - if I write "Hi" into DB it give me back "(Hi)") so I use replace text to delete "()" Yeah that works but i want to split text to (for example) 1tag in 1st textbox... 2tag 3tag and here is the problem. When I do this DB give me back only "()".
Here is my blocks and screenshot:




--
I don't know what the heck you're doing there.

Tags get returned as a LIST, not as a text string.  All that silly replacement you're doing with parenthesis is ridiculous.

Set the ListPicker's Elements to the TinyDB's tags... That's it.

--
Thanks, I never do with tinyDB but i want to try it and you very help me. Thanks.

First of all, please keep the conversations here in the forum so other people can lean too.

I suggest you do some of the tutorials so you know how AI works. The tutorials are located here: http://appinventor.mit.edu/explore/ai2/tutorials

--