Simple addition and database

461 views
Skip to first unread message

Dan Flemming

unread,
Nov 16, 2017, 4:36:49 PM11/16/17
to DroidScript
I've got an app I'd like to build, but my programming language is vlisp (write automated drafting that runs inside AutoCAD).

I want to have 9 entries (numbering 1 thru 9), 9 times.
And an average for each set of 9 entries (these "sets" should hide until a button opens them for viewing).
The "sets" should have the date, then average displayed (upon user picking that data, it should open to show the 9 entries of 9 times).

Also a progressive overall average "of averages" (that always displays in the top-right corner).

Hope you can help...

EGM

unread,
Nov 16, 2017, 6:46:05 PM11/16/17
to DroidScript
I have way too many questions to be of help, like "why not use Excel, it rocks at rows of numbers and averages?", "can the output be an HTML table?", "where does 'database' fit into all this?" just to name a few.

If you can break it down for me I'd be happy to provide whatever insight I possess.

Dan Flemming

unread,
Nov 16, 2017, 10:59:28 PM11/16/17
to DroidScript
I'm going to enter a number of 1 thru 9, 9 separate times.

Example:
1) I would normally create a drop down list numbering 1,2,3,4,5,6,7,8,9.
So the user could select the number they wanted to use.

2) This number would be saved in a list.
After 9 numbers are selected and saved into that "list", I want the list saved.
2 items need to mark the meaning of the list.
A) Average
B) Date

And call that 1 entry.

Sample of 9 number list:
Average,3,5,7,3,5,2,4,8,4,date

Where the average of this list is 1st data in the list, and date is last.

An average in top right corner of the app would always reflect the list's average (the calculation gets the 1st data, or average, and averages the 5 data sets below. Then updates top right corner number with NEW average.

Let's say I've entered data 5 different times, the running average of the 1st data (or average) would show in top right corner.

I can write the whole thing in vlisp, create the dialog and database fairly quick.
Then create a video of what I want if that helps...

EGM

unread,
Nov 17, 2017, 4:48:40 PM11/17/17
to DroidScript
Okay, I understand enough to start. I can put together a basic app for you to tweak, after I take my dog to the park (he has waited all day for me to get home.)

Dan Flemming

unread,
Nov 17, 2017, 5:03:04 PM11/17/17
to DroidScript
I have been busy building my app.

I've figured out how to use an image as a background, and size it to my prefered orientation.

Then create a drop down list with the data I needed, and then figured out how to update a createtextedit with the results.

I also figured out how to have "text to speech" read the results...

I still want to create an sql database with the results, AND average the results (to be continuously displayed).

I very impressed with droid script!
Wow...

Easy peasy so far.
But now I'm getting over my head with the methods needed to complete my app.

Dan

EGM

unread,
Nov 17, 2017, 7:35:38 PM11/17/17
to DroidScript
Have you taken a look at the SQL database example within the app?

If you can post the code you have a question about someone will point you in the right direction. (Or post the Lisp, I can figure out an equivalent.)

Dan Flemming

unread,
Nov 18, 2017, 4:20:48 PM11/18/17
to DroidScript
I have looked at the example sql database code.

Looks like what I need, but not sure enough how to code this language to empliment it correctly.

The visable running average needs to read the "average" (or 1st data on each db entry) to display the average.

Dan Flemming

unread,
Nov 18, 2017, 4:47:24 PM11/18/17
to DroidScript
As a drop-down number is selected I would also like to have text to speech comment on numbers 0 - 9.

Each selection needs to compare the number with a conditional statement to give the responce.

Example:
A zero is selected...
"Wow! That sucks! Shurly you can do better than that!"

A five is selected...
"Now your starting to get somewhere! Come on, I know you can do better!"

A nine is selected...
"Wow! Way to go! They can't touch that!"

Or what ever I decide to use for each number.

1) I'm not sure how to read the db lines to average them.
2) I'm still unclear how to rotate my text after I used "landscape" as the orientation.
3) Placing the drop-down and 2 other texts in the exact position I want them is beyond me too.

Dan Flemming

unread,
Nov 19, 2017, 7:57:58 AM11/19/17
to DroidScript
Here's the code I have so far:

I'll post it them try and explain what I would like to do with it.

//Called when application is started.
function OnStart()
{
    //app.SetOrientation( "Landscape" );
 //Create a layout with objects vertically centered.
 lay = app.CreateLayout( "linear", "VCenter,FillXY" );
 
 //Create a blank image.
 img = app.CreateImage( null, 0.2, 0.2 );
 lay.AddChild( img );
 //Add layout to app. 
 app.AddLayout( lay );
{
   
   
    ////Create a text label and add it to layout.
    txt1 = app.CreateText( "Average Here", 0.3,0.08 );
 txt1.SetTextColor( "#ff0000" );
    txt1.SetBackColor( "#f2eaea" );
 txt1.SetTextSize( 12 );
 lay.AddChild( txt1 );
 
 //Create some text.
    txt = app.CreateText( "Average\nSystem", 0.8, 0.2, "Multiline");
    txt.SetTextSize( 22 );
    txt.SetTextColor( "#ff0000" );
    lay.AddChild( txt );
}
 //Create spinner.
    spin = app.CreateSpinner( "0,1,2,3,4,5,6,7,8,9" );
    spin.SetTextColor( "#ff0000" );
    spin.SetBackColor( "#f2eaea" );
    spin.SetTextSize( 22 );
    spin.SetOnTouch( spin_OnChange );
    lay.AddChild( spin );
 
 //Add layout to app. 
 app.AddLayout( lay );
}
//Called when user changes the selection.
function spin_OnChange( item )
{
    //app.ShowPopup( "Set = " + item );
    txt1.SetText( "Average = " + item );
   
    //Speak the text at default pitch and speed.
 var pitch = 1.0, speed = 1.0;
 app.TextToSpeech( txt1.GetText(), pitch, speed );
 
 ////Not sure how to save each item into a list
 ////This shows the number saved in "SetList"
 //app.ShowPopup( item );
 //app.SaveNumber( "SetList", item );
}


I've looked at some of the code required to implement most of what I need, but still don't understand it enough to complete the task.

1) The multi-line is just some text that don't require anything done to it.
2) Spin is what I want the user to select (also what I want to track, so this needs to be saved as a LIST).
a) Each time the Spin number is selected, it should be "added" to the LIST.
b) A count needs to make sure the list doesn't go over 9 numbers (when 9 numbers have been entered, that is a complete data-set to be stored in the database. And the Spin LIST is started over).
c) Txt1 is where the "running" average of the Spin is shown (each time Spin is selected the average is displayed in txt1)
Also I'd like to have a separate function that checks each Spin and gives a verbal reply to the number selected (like my previous post's "sayings")
3) Another text var needs to read the current database, get the 1st data from each line in the database and display the average of them all.
I don't have this text in the app yet.

That is near enough to completion.
I have a background I'll put in it, and maybe a few other small images later.

Thanks!
Dan

Dave Smart

unread,
Nov 19, 2017, 1:21:11 PM11/19/17
to DroidScript
Hi Dan,

I think a full blown relational database is a bit 'overkill' for this little task (unless you have some particular reason for using one).  It would be simpler to save and load your data to JSON files.  You can use a JavaScript array (or array of objects) to store and process your data in memory and simply save out the results to a JSON file when you are done.... then load it back in again when you need it on another occasion.

Dan Flemming

unread,
Nov 20, 2017, 9:23:01 AM11/20/17
to DroidScript
Don't really know what I need to store the data, and have no idea what JSON files are.
I would speculate they are internal files that I can read/write to store the data in, which is ok with me.

I'm using a JavaScript tutorial to try and learn more about what I'm doing, and it will be a "hit & miss" process.

What I'm learning so far...
I need a var to store array data in.
When my spin gets the number from the user, it's added to the var (which is the array).
After 9 elements are added, the var is saved to a file (the file would have all the other arrays in it).

Then I can open & read the file (getting only the 1st element in each "line" of data, to process for a total average of all prior entries.

Simple enough for a seasoned code of this language, but for a newbie, it's a little perplexing.

Can someone help me understand a couple of things.
My understanding my not be the correct way, but it's what I understand at this time:

1) I set a var = setlist1( "" ).  It's empty so I can add my data to it.
2) I count the length of var setlist1 with setlist1.length
3) I use an if statement to let my app know the max input was reached (know sure the coding for this process).
When done I can append the array to a file.

If I can understand this process, I can slowly process to the file system.

D

EGM

unread,
Nov 20, 2017, 4:27:54 PM11/20/17
to DroidScript
Do you want to save one number, one set of numbers, or an unlimited set of numbers? Then you can decide how you want to save it. :-)

I tweaked your code a bit (but tried to leave explanations why.)


/* Globally scoped objects (everything is an object)
are available everywhere, as opposed to
function-scope objects which are only available within
that function. */

//Empty array to hold number list.
var list = [];

//See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
//and: https://medium.freecodecamp.org/reduce-f47a7da511a9
function listAvg() { return list.reduce( function(total, amount, index, array) {
total += amount;
if( index === array.length-1) {
return total/array.length;
} else {
return total;
}
});}

//Layout objects scoped globally so they can be
// accessed by event handlers:

var txt1; //Displays the average, updated in spin_OnChange function.
var spin; //Updated in spin_OnChange
var img; //Useless placeholder right now, could be part of awesome image carousel tomorrow.

//Called when application is started.
function OnStart()
{
//app.SetOrientation( "Landscape" );
//Create a layout with objects vertically centered.

var lay = app.CreateLayout( "linear", "VCenter,FillXY" );



//Create a blank image.
img = app.CreateImage( null, 0.2, 0.2 );
lay.AddChild( img );
//Add layout to app.
app.AddLayout( lay );

//Create a text label and add it to layout.


txt1 = app.CreateText( "Average Here", 0.3,0.08 );
txt1.SetTextColor( "#ff0000" );
txt1.SetBackColor( "#f2eaea" );
txt1.SetTextSize( 12 );
lay.AddChild( txt1 );

//Create some text.

var txt = app.CreateText( "Average\nSystem", 0.8, 0.2, "Multiline");


txt.SetTextSize( 22 );
txt.SetTextColor( "#ff0000" );
lay.AddChild( txt );

//Create spinner.
spin = app.CreateSpinner( "Pick:,0,1,2,3,4,5,6,7,8,9" );


spin.SetTextColor( "#ff0000" );
spin.SetBackColor( "#f2eaea" );
spin.SetTextSize( 22 );
spin.SetOnTouch( spin_OnChange );
lay.AddChild( spin );

//Add layout to app.
app.AddLayout( lay );
}
//Called when user changes the selection.
function spin_OnChange( item )
{

//Convert selected item from string to integer,
// and insert it and end of list.
list.push( parseInt( item ));



//app.ShowPopup( "Set = " + item );

txt1.SetText( "Average = " + listAvg() );



//Speak the text at default pitch and speed.
var pitch = 1.0, speed = 1.0;
app.TextToSpeech( txt1.GetText(), pitch, speed );

////Not sure how to save each item into a list
////This shows the number saved in "SetList"
//app.ShowPopup( item );
//app.SaveNumber( "SetList", item );

/* Since the handler only activates when the item
changes (hence 'OnChange'), set spinner back to
the item you don't want selected. */
spin.SelectItem( "Pick:" );
}

Dan Flemming

unread,
Nov 21, 2017, 8:59:05 AM11/21/17
to DroidScript
I made a video of the application inside AutoCAD in the language I understand.
This dialog won't let me upload it.

I will place it on my website (when time permits), then you can fully understand what I'm wanting in this app.

Thanks,
D

Dan Flemming

unread,
Nov 21, 2017, 5:57:12 PM11/21/17
to DroidScript
I'm uploading it to my website now.


This should explain what I want...

Dan Flemming

unread,
Nov 21, 2017, 6:05:06 PM11/21/17
to DroidScript
Thanks EMG!

I see the array you built but don't understand a few items in the coding (but I'm working on it).
Yes I think that will work, averaging the numbers like you did (I like this simplified method you showed me).

If you would watch the .avi video I made, I think it will show you what I trying to do.

Thanks a lot...
D

Dan Flemming

unread,
Nov 21, 2017, 6:15:51 PM11/21/17
to DroidScript
EGM,

I ran your tweaked code.
Works nicely.
The average always needs to be rounded (up or down depending on remainder) to a single digit.

Right track!


D

EGM

unread,
Nov 21, 2017, 10:03:45 PM11/21/17
to DroidScript
change the line that reads:

   
return total/array.length;

to:

 return Math.round(total/array.length);


EGM

unread,
Nov 21, 2017, 10:15:41 PM11/21/17
to DroidScript
Wait... did you mean a single digit AFTER the decimal point? That would be:

return Math.round(total/array.length*10)/10;


alex.symbroson

unread,
Nov 22, 2017, 5:16:45 AM11/22/17
to DroidScript
No you need floor. Or to fixed:

return Math.floor(total/array.length*10)/10;

return 1*(total/array.length).toFixed(1);

EGM

unread,
Nov 22, 2017, 8:42:03 AM11/22/17
to DroidScript
Math.floor() always rounds down, Math.ceil() always rounds up.

toFixed() might work better because it takes an optional number of decimals.

return Math.round(total/array.length*10)/10;

becomes...

return (total/array.length).toString(1);

Dan Flemming

unread,
Nov 22, 2017, 3:36:23 PM11/22/17
to DroidScript

Dan Flemming

unread,
Nov 23, 2017, 6:49:25 AM11/23/17
to DroidScript
EGM,

I emailed a video to you.
It should explain what I'd like to accomplish with this app.

I changed the return to... returm.Math.round(total.array.length); And it works just fine.
I added another text (text2) to see what was being save in the list (just to see the results in action) and //'d it out.
I'm learning...

Thanks for the help.

Dan Flemming

unread,
Nov 23, 2017, 6:56:39 AM11/23/17
to DroidScript
I do have more questions about image rotation & exact text placement, but the can wait until a working program is nearly complete.
In the meantime I'll go back to w3schools.com and learn about the language.

I'm thinking if this program catches on with people, I might need a database that can be accessed globally.
Where a person would log-in, use the app, as see how others are doing (like a leader-board), to get an idea of their ability.
But that just fantasy so far...

Thanks,
Dan

EGM

unread,
Nov 23, 2017, 9:24:01 AM11/23/17
to DroidScript
Dan, I threw together a working example at https://www.dropbox.com/s/13s5s7660l1jz7m/Average-Sets-DS.spk?dl=0

It doesn't average the database numbers yet, and seriously needs documentation, but I wanted your take on it.

EGM

unread,
Nov 23, 2017, 12:17:42 PM11/23/17
to DroidScript
Added documentation, still have a "save" method and now an "undo" method to write. Also tweaked button style.

/**
* Average-Sets-DS
* Displays the average of 1-9 numbers,
* pushing the set of 9 numbers to storage
* when a new set of 9 is entered.
*/

/* ToDo:
* 1. Test app across different events such as OnPause, OnResume.
* 2. Write undo feature.
* 3. Write method to persist data to storage.
*/
// Displays the average of 9 numbers.
var numbersAverage = createText();
// Displays the average of averages.
var databaseAverage = createText();
// Doohicky to visually signify how many left to go.
var progressMeter = createProgressMeter();
// Displays numbers entered.
var numbersEntered = app.CreateText( "", 0.8 );
// Counts numbers in set.
var counter = 0;
// Array (set) of 9 numbers.
var numbersList = [];
// Array (set) of number lists, along with date and average.
var dataSets = [];

/*
Uses Array.reduce() method to sum all the elements
in an array, but on the last element divide the sum by
the length of the array.
See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
and: https://medium.freecodecamp.org/reduce-f47a7da511a9
*/
function average( numbersArray ) { return numbersArray.reduce( function(total, amount, index, array) {

total += amount;
if( index === array.length-1) {

return (total/array.length).toFixed(1);
} else {
return total;
}
});}

/*
'app.Create*()' functions wrapped to create a single
location to adjust look and behavior; changing the look
of the wrapped button changes the look of all of
them. Returns control object.
*/
function createButton( text ) {
var button = app.CreateButton( text, 0.3, 0.1, "FontAwesome, Custom" );
button.SetStyle( "#0099cc","#33b5e5",20);
button.SetOnTouch( OnTouch );
return button;
}
/* Wired to variable to allow updating. */
function createText() {
var text = app.CreateText( "", 0.2 );
text.SetTextSize( 22 );
return text;
}
/* 'Throw-away' texts used as labels. */
function createLabel( text ) {
var label = app.CreateText( text )
label.SetTextSize( 20 );
return label;
}
/* Places an array of controls onto a horizontal layout. */
function createRow( controls ) {
var row = app.CreateLayout( "Linear", "Horizontal,FillX" );
controls.forEach( function( control ) { row.AddChild( control ) } );
return row;
}
/*
'Throw-away' texts used as vertical spacers.
Setting margins on all the controls would achieve
the same thing, but this was easier for the purpose
its used for.
*/
function createSpacer( height ) {
var spacer = app.CreateText( "", -1, height );
return spacer;
}
/*
Although the SeekBar is a user interface control, we
can use it as a progress display by using its SetValue
method, and prevent it from causing side effects by
not setting its SetOnClick method.
*/
function createProgressMeter() {
var meter = app.CreateSeekBar( 0.8 );
meter.IsEnabled( false );
meter.SetRange( 0.9 );
meter.SetValue( 0.0 );
return meter;
}

/* Creates main display, returning it as a layout object. */
function mainDisplay() {
var background = app.CreateLayout( "Linear", "FillXY" );
background.AddChild( createSpacer( 0.1 ) );
background.AddChild( createRow([createLabel("Average of Numbers: "), numbersAverage]) )
background.AddChild( createSpacer( 0.04 ) );
background.AddChild( createRow([createLabel("Average of Database: "), databaseAverage]) )
background.AddChild( createSpacer( 0.1 ) );
background.AddChild( createRow([createButton("7"),createButton("8"),createButton("9")]) )
background.AddChild( createRow([createButton("4"),createButton("5"),createButton("6")]) )
background.AddChild( createRow([createButton("1"),createButton("2"),createButton("3")]) )
background.AddChild( createRow([createButton("0"),createButton("[fa-undo]")]) )
background.AddChild( createSpacer( 0.1 ) );
background.AddChild( progressMeter );
background.AddChild( numbersEntered );
return background;
}

/* Display buttons handler. */
function OnTouch()
{
// Get the button object last pressed
var button = app.GetLastButton();
// Get the text of the button...
var text = button.GetText();
// Test to see if "undo" button was pressed by checking the Unicode value for [fa-undo].
if ( text === "\uf0e2" ) {
app.ShowPopup( "Undo not working (yet)" );
}
else {
// ...and also convert it to a number (we're going to be using both.)
var number = parseInt( text );
// Check the counter (numbersList.length would also work here.)
if (counter < 9) {
// Numbers list not yet full, so...
// numbersList[numbersList.length] = number should also work.
numbersList.push( number );
// Add the number to the display of numbers, update the progress meter, and display the average.
numbersEntered.SetText( numbersEntered.GetText() + " " + text );
progressMeter.SetValue( counter / 10 );
numbersAverage.SetText( average( numbersList ).toString() )
}
else {
// Numbers list was full, so push it to dataset list
var dataSet = {
avg: parseFloat( numbersAverage.GetText() ),
numbers: numbersList,
date: new Date(),
// Override Object.valueOf() method so it returns avg instead of [object object].
valueOf: function() { return this.avg; }
};
dataSets.push( dataSet );
//databaseAverage.SetText( averageDatasets( dataSets ))
databaseAverage.SetText( average( dataSets ))
//app.ShowPopup(JSON.stringify(averageDatasets( dataSets )))
numbersList = [ number ]
numbersEntered.SetText( text );
progressMeter.SetValue( 1 );
counter = 0;
}
counter++;
}
}

/* Back button handler. */
function OnBack() {
var dialog = app.CreateYesNoDialog( "Really quit?" )
dialog.SetOnTouch( OnDialog );
dialog.Show()
}
/* Quit dialog handler. */
function OnDialog( result ) {
if (result === "Yes") {
app.Exit();
}
}

//Called when application is started.

// This is the main routine so put settings that affect entire app here.
function OnStart()
{
app.EnableBackKey( false );
app.AddLayout( mainDisplay() );
}

Dan Flemming

unread,
Nov 24, 2017, 8:13:15 AM11/24/17
to DroidScript
EGM,
Not sure if you got the video I sent you.

I ran the code you posted above, Nice!
I studied the code a little yesterday because I want to understand the processing code involved.

I'm in the process of a javascript tutorial to help me understand the language.

Questions:
1) Inserting blank spaces divides the available space on the device with 1 real number (if you add y number also does it adds more space?)
2) Adding text, I know you can divide xy by percentage of space for text placement, but suppose I want exact placement of text, what syntax controls that?
3) Is there a way to push data to the beginning of an existing array?  I know push inserts at the end of the array. Can it be reversed, then use push to insert to end, then reverse again to get data at the beginning?   Not sure of the methods...
4) If I use a background image in an app that is default orientation, how do you get the image to rotate 90 degrees and fill the screen (tried but failed so far).

Rounding values I use Math.round(total/array.length)  I like the simplicity of this code with the built-in functions.
And overall reduces code size.
I have programs that use way over 5,000 lines of code to get the desired outcome (I leaned over time how to reduce the size and increase the quantity of programs used).

Thanks for the help...
Dan

EGM

unread,
Nov 24, 2017, 1:28:26 PM11/24/17
to DroidScript
1. Yes. In the function below, CreateText takes 4 parameters: text, width, height, and options.

function createSpacer( height ) {
var spacer = app.CreateText( "", -1, height );
return spacer;
}

In JavaScript any parameter you leave out when you call a function gets passed as "undefined" instead of throwing an error. So I told it "Create a blank text, make it the correct width for the text, use the height passed in, and to heck with the options."

Steve Garman

unread,
Nov 24, 2017, 1:40:09 PM11/24/17
to DroidScript
For exact placement of controls, use a layout type "Absolute" and use txt.SetPosition

To add to and remove from arrays, take a look at the JavaScript documentation for
Pop, Push, Shift and Unshift

EGM

unread,
Nov 24, 2017, 2:06:46 PM11/24/17
to DroidScript
2. Control placement methods are in the Layouts section, because they're common to all controls.

For "Linear" layouts, to adjust spacing use:
SetPadding( left, top, right, bottom )
SetMargins( left, top, right, bottom )

Rarely used (because of taking into account all screen sizes might be different) the other option for placing controls is the "Absolute" layout:
SetPosition( left, top, width, height )
SetSize( width, height )

Also worth mentioning are the app methods:
GetDisplayWidth, GetScreenHeight, GetDisplayHeight, GetScreenHeight, and GetScreenDensity if you REALLY want to get technical about object placement. :-)

Dan Flemming

unread,
Dec 9, 2017, 12:11:00 PM12/9/17
to DroidScript
I've been working on my little project and I'm having 2 problems.

  I've got the data sets working as array's.
(finding the average and using unshift to set the average of a set of numbers as the 1st data in the array)

The problems:
1) After "> 1" set, I'm not sure how to get the 1st data of each array and average them.

2) JSon file.

Here's the sample code I'm using to write a JSon file, and I'm not sure I'm writing this file (can't find it on my cell phone).

//Storing data:
        myObj = { "name":"Dan", "date":"2017-12-09", "data":"[5,1,2,3,4,5,6,7,8,9]", "city":"My City", "state":"My State" };
        myJSON =  JSON.stringify(myObj);
        localStorage.setItem("DansData.json", myJSON);

I know myObj is the data I want to save.
Then I stringify   myObj.

My confusion is do I need to "Hard Path" the file?
Example "/DansData.json"   Will this place the file in the directory created by DroidScript for the app?
(or add additional pathway perimeters)

Or
Do I leave off the extension?
Example "/DansData"

Just not sure if my code should be a function that called when I want to write or as I have shown.

Thanks,
Dan

Dan Flemming

unread,
Dec 9, 2017, 12:15:34 PM12/9/17
to DroidScript
Also,
If I successfully write my json file, how do I add other data?

This is what I'm thinking:

I write the file with the data I want.
When I want to add more data, I read the file then add more array's to it, then rewrite the file?

Or
Is there an append function that just adds arrays to the file?

Dan

Dave Smart

unread,
Dec 9, 2017, 2:54:03 PM12/9/17
to DroidScript
Hi Dan,

You can load the json data file as a string (which can contain arrays and objects, or arrays of objects etc) using app.ReadFile() and then use JSON.parse() to turn the data string into a JavaScript object (or array of objects), which you can use, search and modify at run time, then just save the data back again using JSON.stringify().  If your database is less than about 5 megs then this is a fast and efficient way of handling the data as it will all be held in RAM while you work on it.

Also, if you are writing out log files or continuously growing data files (probably not relevant to your project), you can use a 'psuedo json' file by writing out json objects to a file using the 'append' option and putting commas between each item.  Then when you want to load the log file and process it, you load it in as a string and just add "[" and "]" to the front and back of the string to make it a valid json array and use JSON.parse() on it to turn it into a JavaScript array.

Something like this:-

File contents:-

{ "time" : 32523353, "msg" : "App started", "count" : 4 },
{ "time" : 32523399, "msg" : "App connected", "count" : 3 },
{ "time" : .... etc



Read log file to array:-

var s = app.ReadFile( "/sdcard/log.txt" );
var log = JSON.parse( "[" + s + "]" );


for( var i=0; i<log.length; i++ )
{
   console
.log( log[i].msg + " " + log[i].count );
}

Regards
David

Dan Flemming

unread,
Dec 9, 2017, 5:02:16 PM12/9/17
to DroidScript
Hi David,

I studied what you wrote and understand reading the .txt and parsing the results into objects.

I'm not sure you answered my questions though.
In my example code (12:11 pm)...
was I correct in writing the json txt?
Which way is correct (if any in my example #2)?

I need to understand what I'm writing and HOW it works before I can write better code.

Thanks again,
Dan

Dave Smart

unread,
Dec 10, 2017, 5:27:55 AM12/10/17
to DroidScript
No, you were not really correct... close though :)

You made hard work for yourself as you don't need to quote everything up as the JSON.stringify function will do that for you.  You should work in JavaScript and let the JSON functions to the hard work for you.

You should have written something like this instead:-

 var myObj = { name:"Dan", date:new Date(), data:[5,1,2,3,4,5,6,7,8,9], city:"My City", state:"My State" };
 var myJSON =  JSON.stringify(myObj);
 app.MakeFolder( "/sdcard/Dan" );
 app.WriteFile( "/sdcard/Dan/DansData.json", myJSON );


You could also save it to private (and encrypted on non-rooted phones) data store which is removed when the app is removed, like this:-

var privDir = app.GetPrivateFolder( "Dan" );
app.WriteFile( privDir  + "/DansData.json", myJSON );




Dan Flemming

unread,
Dec 10, 2017, 11:49:43 AM12/10/17
to DroidScript
Dave,

I'm new to javascript & android app coding.
I'm trying to learn and I really appreciate your help!
I'm going through the w3schools javascript tutorials, but it's a little different than DroidScript...

Thanks for show me the makefolder & writefile commands, I've read about how to do this, but it was windows javascript and the commands were different that DroidScript.

I didn't understand the KEY should be un-quoted (as your example shows, letting stringify convert to it's format).
I knew about the date command and I would have used an array for the data (my bad example).

Thanks, this helps me understand what I need to do (and why).
Dan

Dan Flemming

unread,
Dec 10, 2017, 12:09:23 PM12/10/17
to DroidScript
Another question Dave,

Do I need to give the extension to the json file?
Or use .txt?

Thanks,
Dan

Steve Garman

unread,
Dec 10, 2017, 12:13:11 PM12/10/17
to DroidScript
From your code's perspective, you can use any extension or none.

You will get a plain text file anyway.

I usually use .json for self-documenting.

Dan Flemming

unread,
Dec 10, 2017, 12:29:56 PM12/10/17
to DroidScript
Thanks steve,

If I want to append more data to the same file, what is the command syntax?

Thanks,
Dan

Dan Flemming

unread,
Dec 10, 2017, 12:35:11 PM12/10/17
to DroidScript
I'll read the file, extract the data, add more data to existing data, then re-write the file.

Just not sure of the process...

Dan

Steve Garman

unread,
Dec 10, 2017, 3:32:07 PM12/10/17
to DroidScript

var myObj = { name:"Dan", date:new Date(), data:[5,1,2,3,4,5,6,7,8,9], city:"My City", state:"My State" };
//Make sure folder exists
app.MakeFolder( "/sdcard/Dan" );
//Read json data
var data = app.ReadFile( "/sdcard/Dan/DansData.json" );
//Make sure there is data
if(data=="")arr= [ ];
else arr = JSON.parse(data);
//add new data
arr.push(myObj);
//convert back to JSON
data = JSON.stringify(arr);
//Write alll data
app.WriteFile( "/sdcard/Dan/DansData.json", data );

Dan Flemming

unread,
Dec 11, 2017, 6:01:18 PM12/11/17
to DroidScript
Thanks Steve!

Not sure if I'd have figured it out (not!).

I didn't think about using push to append.
So I can also use unshift to add anything to the front end if needed...

Thanks,
This helps my understanding... Tutorials are a bit vague.

Dan
Message has been deleted

Dan Flemming

unread,
Dec 12, 2017, 11:14:24 PM12/12/17
to DroidScript
I found all the JavaScript references you guys have added to DroidScript.
(I didn't look thoroughly through DroidScript, just jumped in and tried to learn as I started developing my 1st app).
I've been wanting to learn how to write app's for many years now, and DroidScript was the key to success!

So far I have done quite a good job (for not knowing the language & syntax).
Mostly it's trial & error (sometimes builds a better understand of what works, but slow & frustrating...).

Thanks for such a GREAT app!
Glad I found it...

Very Thankful,
Dan

Dan Flemming

unread,
Dec 15, 2017, 8:06:49 AM12/15/17
to DroidScript
Another question please...

The icons that are used in either the tutorials or samples, are they system icons or is there somewhere I can find icons to use for myself?
I notice that some are 2 part names, or are in an array, just want to know where I can find them (or more app sized icons).

Thanks,
Dan

Dan Flemming

unread,
Dec 15, 2017, 10:20:51 AM12/15/17
to DroidScript
I found the Fontawesomepicker.js downloaded it and put it in Assets:Misc. (in the app where I want to use the picker until my app is finished, then delete it).
OR SHOULD THE PICKER BE A STAND-ALONE APP?   JUST TO GET THE NAMES OF ICONS I WANT TO USE?

I used the included code for creating the button and function.

When I pick the button the Layout appears.
But there's nothing there (no text & no icons), Just [], like the array is empty.
How do I call the All674FontAwesomeIcons.txt, to display the names & icons?

I assume I would create an array of the names, then add the array-name to the function as the argument?

Dan

Dan Flemming

unread,
Dec 15, 2017, 10:49:05 AM12/15/17
to DroidScript
Got Fontawesomepicker working!

Sorry, just learning how to make things work quickly...
Had to change path to file in .js

Dan

Netpower8

unread,
Dec 15, 2017, 7:03:01 PM12/15/17
to DroidScript
The fontawesome picker is only a guide to be able to know what icon you are looking for. If you know what you want you can simplly drop the picker and use the icon directly.

icn=app.CreateText('[fa-bars] [fa-paste]',-1,-1,'fontawesome');
lay.AddChild(icn);

Dan Flemming

unread,
Dec 16, 2017, 8:22:35 AM12/16/17
to DroidScript
Thanks Netpower8!

I appreciate your help...
I understand calling icons in font files better now.

I'm have a problem because I don't quite understand the HOW quite yet.
I'm calling a icons from a font file, but want to supplement an image in place of one of the icons.
I'm getting the resulting image, but the text don't align horizontally with the image.
I don't understand WHY it don't.
I think it may be the image is too wide, but not sure and I've worked on it trying different things without success.

Here's the code:
(I used an existing drawer code from the samples, but want to changes a few things to make it work for my needs)

I was hoping I could use my own image in place of the file's icon, but it don't work the way I wanted it to.
I don't understand why...  Is it because the image isn't the same size as the font file icon?
Or is it the method that used to call the image (I think the method the image is called places the image in vertical order of operations, but not positive).

I thought...  If the listitems was like an array, I could replace the icon name with my image name and it would replace the icon with my image.
It does replace the icon, but the alignment (both on the same line) isn't working.
Both images are on separate lines, then both text's on separate lines (that's 4 line instead of 2).

Is there another way I need to call the image ot get the alignment working the same?
Do I have to re-size the image to say... 50x50 or some other size to match the sizes of the icon file's icons?

//Add a second list to menu layout.
    shark = app.CreateImage( "Img/Shark2.png", 0.15, -1 );
    var shark1 = layMenu.AddChild( shark );
    finright = app.CreateImage( "Img/animated-shark-image-0006.gif", 0.2, -1 );
    var fin1 = layMenu.AddChild( finright );
    var listItems = "Ranking::[shark1],Search Players::[fin1],Settings::[fa-cog]";
    lstMenu2 = app.CreateList( listItems, drawerWidth, -1, "Menu,Expand" );
    lstMenu2.SetColumnWidths( -1, 0.35, 0.18 );
    lstMenu2.SetOnTouch( lstMenu_OnTouch );
    layMenu.AddChild( lstMenu2 );

I'm just learning the JavaScript/Droidscript language, but I know Visual-Lisp well.

Thanks,
Dan

Netpower8

unread,
Dec 17, 2017, 10:52:23 AM12/17/17
to DroidScript
the list file icon is FIXED and if you try to change the size of the font. the image dont change in size.

if you are picky and want it to be the same size with the font then maybe you should make your own list control (which is possible)

redefining the image size wont matter... it will display the same size on the list icon. even if the size is either big or small. the icon size on the list is fixed
the best way to get around this is to define you own list control ( this is doable.)

Dan Flemming

unread,
Dec 19, 2017, 2:54:50 PM12/19/17
to DroidScript
I'm having a hard time trying to place an image & text on the same horizontal line.
Kind of like icon fonts, but instead I want an image to be on the left of the text.
Tried different things for hours, searched for many more...  No luck.

Dan

Steve Garman

unread,
Dec 19, 2017, 3:01:59 PM12/19/17
to DroidScript
Dan,
I suggest you start a new topic with a meaningful subject. Hijacking threads, even ones you started yourself makes life difficult for other people.

You may find it useful to post code you have tried and explain what you are not happy about with the result.

Reply all
Reply to author
Forward
0 new messages