Slow execution of a loop in Apps Script - javascript

Basically what I am looking for is any recommendations you can provide me to make this piece of code to execute faster.
The intention of this piece of code its basically by testing some conditions obtain a score and the questions related for each profile selected, and print those scores in the "Results Sheet" and print the questions in Sheets assigned with the name of the profile.
Through some quick and basic testing I discovered whenever the loop starts to print either the results or the questions its where the slow execute starts.
Sorry for the mess on the code I just started programming in Apps
Script several weeks ago.
EDIT
To be quite more specific Im trying to find out if there is any work around to print the questions in the different sheets and values of the profiles. I took a look at the similar question and he addresses a loop using for..in, Im still trying to find out if there is any other logical process I can do to get those values.
var iGrade1 = 0;
var iGrade2 = 0.5;
var iGrade3 = 1;
var resultsSheet = SpreadsheetApp.getActive().getSheetByName('Results');
var iStartingColumn = 5;
var iCellD = 'D';
var iCellE = 'E';
var iTotCounter = 2;
var amountProfiles = profileSheet.getRange
(2, perfilSheet.getLastColumn()).getValue();
var iTotPerf = 0;
var iPT = 1;
var aResizeP = 1;
for( i = 2; i< questionsSheet.getLastRow() ; i++ ){
//Range
sBI = 'B' + i;
sDI = 'D' + i;
//Copies values like 1|2|3|4|, 3|4|, 2|3|, etc.
profileCodes = questionsSheet.getRange(sDI).getValue();
for(j = 0; j < amountProfiles; j++){
//There is a checkbox where user selects if he wants that profile or not
if(profileSheet.getRange(1,iStartingColumn).getValue()
=== 'Yes'){
var sheetProfile = SpreadsheetApp.getActive().getSheetByName
(profileSheet.getRange(3, iStartingColumn).getValue());
var totProfile = profileSheet.getRange(perfilSheet.getLastRow(), iStartingColumn).getValue();
//User can select in a checkbox between 'Bad' 'Regular' and 'Good'
if( ( questionsSheet.getRange( sBI ).getValue() === '× Bad' ) ){
if(profileCodes.split("|").indexOf( String( perfilSheet.getRange(2, iStartingColumn).getValue() ) ) > -1 ){
iTotPerf = iTotPerf + iGrade1; }
}
else if( ( questionsSheet.getRange( sBI ).getValue() === ' ± Regular' ) ){
if( profileCodes.split("|").indexOf( String( perfilSheet.getRange(2, iStartingColumn).getValue() ) ) > -1 ){
iTotPerf = iTotPerf + iGrade2; }
}
else if( ( questionsSheet.getRange( sBI ).getValue() === '✓ Good' ) ){
if(profileCodes.split("|").indexOf( String( perfilSheet.getRange(2, iStartingColumn).getValue() ) ) > -1 ){
iTotPerf = iTotPerf + iGrade3; }
}
if ( profileCodes.split('|').indexOf(String
(perfilSheet.getRange(2, iStartingColumn).getValue()))
> -1){
questionsSheet.getRange('A' + i + ':' + 'C' + i)
.copyTo(sheetProfile.getRange('A' + iPT),SpreadsheetApp
.CopyPasteType.PASTE_NORMAL,false);
sheetProfile.autoResizeColumn(aResizeP);
}
if(iTotPerf != 0){
resultadosSheet.getRange(iCellD + iTotCounter).setValue(resultadosSheet.getRange(iCellD + iTotCounter).getValue() + iTotPerf);
resultsSheet.getRange(iCellE + iTotCounter).setValue( ( (resultsSheet.getRange(iCellD + iTotCounter).getValue() * 100)/ totPerfil )/ 100);
}
}
iTotPerf = 0;
iTotCounter++;
iStartingColumn++;
}
iPT += 1;
iTotCounter = 2;
iStartingColumn = 5;
}

Related

Different ways of counting characters in Indesign using javascript

I'm writing a javascript program to handle each character intо Indesign document.
To begin with, I wrote two different ways of counting characters, which for some reason give different results for large documents. Why?
var
myDocument, docStories, docCharacters,
docFootnotesCharacters, docTablesCharacters;
myDocument = app.activeDocument;
var TotalChars = 0;
// Fisrt way
docStories = myDocument.stories.everyItem();
docCharacters = docStories.characters.length;
docFootnotesCharacters = docStories.footnotes.everyItem().characters.length;
docTablesCharacters = docStories.tables.everyItem().cells.everyItem().characters.length;
statReport = [];
// Second way
for ( j = 0; j < myDocument.stories.length; j++ ) {
myStory = myDocument.stories.item(j);
var Frames = myStory.textContainers;
for ( i = 0; i < Frames.length; i++ ) {
var Frame = Frames[i];
for (var TextCnt = 0; TextCnt < Frame.texts.length; TextCnt++) {
CurrentText = Frame.texts.item(TextCnt);
TotalChars += CurrentText.characters.length;
}
for (var TableCnt = 0; TableCnt < Frame.tables.length; TableCnt++) {
var CurrentTable = Frame.tables.item(0);
for ( var CellCnt = 0; CellCnt < CurrentTable.cells.length; CellCnt++ ) {
var CurrentCell = CurrentTable.cells.item(CellCnt);
TotalChars += CurrentCell.characters.length;
}
}
for (var FootNoteCnt = 0; FootNoteCnt < Frame.footnotes.length; FootNoteCnt++) {
var CurrentFootNote = Frame.footnotes.item(0);
TotalChars += CurrentFootNote.characters.length;
}
}
}
statReport.push ( "Characters: " + ( docCharacters + docFootnotesCharacters + docTablesCharacters ) );
statReport.push ( "TotalChars: " + TotalChars );
alert ( statReport.join ( "\r" ), "Document Text Statistic" );
In the second method, you're counting all the characters inside text frames in the story. But stories can be overset (the text overflows). The first method will count overset text (because you're counting the characters in a story, but the second method will ignore those, because it's only counting characters in story frames.

Using a for loop to insert javascript variable into json encoded php variable

I've got several items I'm trying to display within a canvas. I've json my php data to support doing this in javascript.
Now I'm trying to iterate the database names with a for loop so I don't have to write the code for each.
Here's what I've got so far:
for ((var i=2; i<=17; i++) && (var j=3; i<=18; j++)){
if((row.g1c[j]y + row.g1c[j]m != 0) && ((12*row.g1c[j]y + row.g1c[j]m) > (360 + (12*row.O1y + row.O1m)))){
var g1c[i]w = (360-(12*row.g1c[i]y + row.g1c[i]m)-(12*row.O1y + row.O1m));
} else if (row.g1c[j]y +row.g1c[j]m != 0){
var g1c[i]w = ((12*row.g1c[j]y + row.g1c[j]m)-(12*row.g1c[i]y + row.g1c[i]m));
} else {}
var g1c[i]x = ((12*row.g1c[i]y + row.g1c[i]m)-(12*row.O1y + row.O1m));
var lineHeight = 15;
var maxWidth = 2.5*(g1c[i]w);
var x = 80+(2.5*(g1c[i]x))+(maxWidth/2);
}
This isn't working and I'm 99.999% sure it has to do with the i and j syntax, but everything I've looked up and tried hasn't worked.
If someone would tell me where my screw-up is, I'd be eternally grateful.
Thanks in advance!
Decided do go down the PHP route vice Javascript to avoid having to redo my database...
I'm creating a for loop for each database column and row...
for ($j=3; $j<=$count; $j++){
$l = "g1c".$j."m";
$m = "g1c".$j."y";
I can then use php logic as needed for each row of data that needs to be assessed...
if(($row[$l] + $row[$m]) != 0){
.... do something
}
You can probably do this:
for (var i=2; i<=17; i++){
for (var j=3; i<=18; j++){
if((row.g1c[j]y + row.g1c[j]m != 0) && ((12*row.g1c[j]y + row.g1c[j]m) > (360 + (12*row.O1y + row.O1m)))){
var g1c[i]w = (360-(12*row.g1c[i]y + row.g1c[i]m)-(12*row.O1y + row.O1m));
} else if (row.g1c[j]y +row.g1c[j]m != 0){
var g1c[i]w = ((12*row.g1c[j]y + row.g1c[j]m)-(12*row.g1c[i]y + row.g1c[i]m));
} else {}
var g1c[i]x = ((12*row.g1c[i]y + row.g1c[i]m)-(12*row.O1y + row.O1m));
var lineHeight = 15;
var maxWidth = 2.5*(g1c[i]w);
var x = 80+(2.5*(g1c[i]x))+(maxWidth/2);
}
}

Javascript: Looping through an array

This is driving me crazy! I'm very new to javascript(can read it but not always write it) My problem is threefold.User needs to input(prompt) "tall single latte".
1. I want to ad an array to this problem to store a.) the coffee strings and b.) the coffee prices.
2. I want to use a for loop to output the total amount of coffee ordered so far.
3. My output should be in table format ex.
short single latte's price is R10
double tall coffee's price is R15
var coffee = [ ];
var price = [ ];
for (var i = 0; i < 2; i++) {
var coffee = prompt("What coffee do you want:", "");
// Size
if (coffee.indexOf('short') > -1) {
var size = 7;
}
if (coffee.indexOf('tall') > -1) {
var size = 9;
}
if (coffee.indexOf('grande') > -1) {
var size = 11;
}
// Shots
if (coffee.indexOf('single') > -1) {
var shots = 1;
}
if (coffee.indexOf('double') > -1) {
var shots = 2;
}
if (coffee.indexOf('triple') > -1) {
var shots = 3;
}
// Is cappuccino?
if (coffee.indexOf('cappuccino') > -1) {
var extra = 2;
} else {
var extra = 0;
}
var price = (size + (3 * shots) + extra);
console.log(coffee + "'s price is R" + price);
}
An example of what I want to achieve:
var coffee = [ ];
var price = [ ];
coffee.push("short single latte");
price.push(10);
coffee.push("double tall latte");
price.push(15);
var i;
for (i = 0; i < coffee.length ; i++)
{
console.log(coffee[i] + "'s price is R" + price[i]);
}
I based this answer on what appears that you want to achieve (your second code-block).
-1 (often returned by functions/methods whose valid output includes 0) is called a 'sentinel value' and in javascript one catches them using ~: everything that is not -1 will coerce to true.
Further explanations as comments in code:
(window.Orders=function(){ // our constructor function
this.clr(); // init by calling clr.
}).prototype={ // set inherited methods
clr: function(){ // clear
this.coffee=[]; // empty array of unknown length
this.price=[]; // empty array of unknown length
}
, add: function(){ // build orders list
var inp, size, shots, extra;
while((inp=prompt('What coffee do you want:')) !== null){
size=0; // Size
if( ~inp.indexOf('short' ) ) size= 7;
else if( ~inp.indexOf('tall' ) ) size= 9;
else if( ~inp.indexOf('grande') ) size= 11;
shots=0; // Shots
if( ~inp.indexOf('single') ) shots= 1;
else if( ~inp.indexOf('double') ) shots= 2;
else if( ~inp.indexOf('triple') ) shots= 3;
extra= ~inp.indexOf('cappuccino') ? 2 : 0; //cappuccino?
if( size && shots ){ //abuse price to check input
this.coffee.push(inp);
this.price.push(size + 3 * shots + extra);
} else alert('please enter valid order');
}
}
, get: function(EOL){ //output orders
var i=0, L=this.coffee.length, r=new Array(L);
for(; i<L; i++){ //using a for loop as you requested.
r[i]=this.coffee[i] + "'s price is R" + this.price[i];
}
return r.join(EOL || '<br>'); //return string using arg EOL or '<br>'
}
};
<!-- HTML AND *EXAMPLE* usage -->
<button onclick="
var orders=new Orders(); // Construct new var orders
orders.add(); // Start filling it
document.getElementById('out').innerHTML=orders.get(); //get output
//orders.clr() //clears orders if you want to reuse it without spawning a new
">get orders (cancel/escape to quit)</button>
<br>
Output: <div id="out"></div>
Now.. the real challenge is thinking up way's to parse the userinput strings, determining what is valid & complete and what not (thankfully you didn't ask for solutions to that problem). I checked if size and shots are set.
Hopefully this helps your learning experience.
Thank you guys, I think I figured it out.. know its probably the long way... but...
var coffeeName = new Array();
var priceSingle = new Array();
// Loop 2 times
for ( var i = 0; i < 2; i++){
// Prompt Coffee
coffee = prompt("What coffee do you want:", "");
// Size
if (coffee.indexOf('short') > -1) {
var size = 7;
}
if (coffee.indexOf('tall') > -1) {
var size = 9;
}
if (coffee.indexOf('grande') > -1) {
var size = 11;
}
// Shots
if (coffee.indexOf('single') > -1) {
var shots = 1;
}
if (coffee.indexOf('double') > -1) {
var shots = 2;
}
if (coffee.indexOf('triple') > -1) {
var shots = 3;
}
// Is cappuccino?
if (coffee.indexOf('cappuccino') > -1) {
var extra = 2;
} else {
var extra = 0;
}
// Work out Price
var price = (size + (3 * shots) + extra);
// Push coffee to coffeeNameArray
coffeeName.push(coffee);
// Push price to priceSingleArray
priceSingle.push(price);
}
// Loop coffeeName length - Output List
for (var i = 0; i < coffeeName.length; i++)
{
console.log(coffeeName[i]+"'s price is R"+priceSingle[i]);
}

giving buttons in an array an own ID

I need help for a project I am doing for school. We need to make a booking system for a cinema. To generate the chairs I made an array but how do I give each button an own ID?
This is my code:
function chair(){
for( i = 1 ; i <= 10; i = i + 1 ){
if ( i > 3 && i < 8 ){
document.write("<button>button</button>");
}else{
document.write("<button>hi</button>");
}
}
}
Well, you could do this:
document.write("<button id=btn" + i + ">button</button>");
Side notes:
You're falling prey to The Horror of Implicit Globals — declare your i variable.
Normally barring a reason to do something else, in programming we start with 0 rather than 1:
for (i = 0; i < 10; i = i + 1)
You don't have to, but that's the normal thing to do.
i = i + 1 can be written ++i ("increment i"):
for (i = 0; i < 10; ++i)
Again you don't have to, but that (or its cousin i++) would be much more common than i = i + 1.
document.write is fine for small class assignments and such, but just FWIW, you probably wouldn't want to use it in the real world. Use the DOM instead:
var btn = document.createElement("button");
btn.id = "btn" + i;
document.body.appendChild(btn);
HTH, as you're learning...
function chair()
{
var ID = 0;
for( i = 1 ; i <= 10; i = i + 1 )
{
if ( i > 3 && i < 8 ){
document.write("<button id=btn"+id+">button</button>");
} else{
document.write("<button id=btn"+id+">hi</button>");
}
id++;
}
}
var id=0;
for( i = 1 ; i <= 10; i = i + 1 )
{
if ( i > 3 && i < 8 )
{
document.write("<button id="+id+">button</button>");
id++;
}
else
{
document.write("<button id="+id+">hi</button>");
id++;
}
}
I would advise against document.write. You can do this
function chair() {
for (var i = 0; i < 10; i++) {
var btn = document.createElement("button");
btn.id = "btn" + i; // set the id
btn.innerHTML = (i > 3 && i < 8) ? "Button" : "hi";
document.body.appendChild(btn);
}
}
P.S I've updated the answer to meet T.J.Crowder's suggestions in his side notes.

Generating Radio Button Result Depending On TextArea Value

A few days ago I did not manage to generate a result from my radio button, I managed to solve that problem now. My other problem is how do I generate ONLY few set of the radio button depending on TextArea value changes;
For Example in this code
<script language="javascript" type="text/javascript">
function generatetest() {
codeOne = document.docContainer.text1.value;
codeTwo = document.docContainer.number2.value;
function firstType(){
var codeFour = 0;
for( i = 0; i < document.docContainer.radio4.length; i++ )
{
if( document.docContainer.radio4[i].checked == true )
codeFour = document.docContainer.radio4[i].value;
}
var codeTen = 0;
for( i = 0; i < document.docContainer.radio10.length; i++ )
{
if( document.docContainer.radio10[i].checked == true )
codeTen = document.docContainer.radio10[i].value;
}
document.docContainer.textarea12.value = codeOne + codeTwo + codeFour + codeTen;
}
function secondType(){
var codeSix = 0;
for( i = 0; i < document.docContainer.radio6.length; i++ )
{
if( document.docContainer.radio6[i].checked == true )
codeFour = document.docContainer.radio6[i].value;
}
var codeEleven = 0;
for( i = 0; i < document.docContainer.radio11.length; i++ )
{
if( document.docContainer.radio11[i].checked == true )
codeTen = document.docContainer.radio11[i].value;
}
document.docContainer.textarea12.value = codeOne + codeTwo + codeSix + codeEleven
}
if (document.docContainer.number2.value="1")
{
firstType();
}
else if (document.docContainer.number2.value="2")
{
secondType();
}
}
</script>
The code is working, problem is, even though I insert the value on textarea "number2" as "2", the code still generate firstType() result
Am Im using wrong if-statement or what and how do I go around about this?
Your code could be more fun to read, but Putting quotes around your numbers is causing javascript to treat them like text. Is this what you want to be doing?

Categories