As the title reads, my javascript file won't append to a filtered list via a random generator function, for context it's being built in replit so perhaps its just a buggy bit of software on replits end, though I'm certain I've done something wrong and can't for the life of me figure out what. The main idea for this project is to have it randomly select an item from a list, append it to an empty list, then pass that string to an HTML textarea tag to be displayed as text.
Code in question:
var LowercaseList = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"];
var NumList = ["1","2","3","4","5","6","7","8","9","0"];
var SpecialCharList = ["`","~","!","#","$","%","^","&","*","_","-","+","=","<",">","?","/"];
// Letter list ID's since I couldn't figure out how to run this using a database
var LetterIDList = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26];
// Number list ID's since I couldn't figure out how to run this using a database
var NumIDList = [1,2,3,4,5,6,7,8,9,10];
// Special character list ID's since I couldn't figure out how to run this using a database
var SpecialID = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17];
// Filtered Lists
var UpperFiltered = [];
var LowerFiltered = [];
var NumFiltered = [];
var SpecialFiltered = [];
// Global declarations of random number variables to grab values from intial lists
var UpperGenVariable;
var LowerGenVariable;
var NumGenVariable;
var SpecialGenVariable;
// Creates a basic password with 2 of each kind of character
function Basic () {
for (var i = 1; i < 2; i++) {
UppercaseGenerate();
}
for (var i = 1; i < 2; i++) {
LowercaseGenerate();
}
for (var i = 1; i < 2; i++) {
NumGenerate();
}
for (var i = 1; i < 2; i++) {
SpecialGenerate();
}
};
let passwordGen = document.getElementById("PasswordDisplay")
function UppercaseGenerate () {
var UpperFiltered = [];
UpperGenVariable = Math.random(0, LetterIDList.length);
for (var i = 0; i < LetterIDList.length - 1; i++) {
if (LetterIDList[i] == UpperGenVariable) {
appendItem(UpperFiltered, UppercaseList[i]);
}
};
console.log(UpperFiltered);
passwordGen.value = UpperFiltered
};
HTML textarea code:
<label style = "color:white;" for="PasswordDisplay">Your generated password ----></label>
<textarea readonly id="PasswordDisplay" name="PasswordDisplay" rows="10" cols="50">
Please select a password complexity setting
</textarea>
I changed how you generate the random number.
Also added the UppercaseList, added i <= 2 rather then i < 2 in the cycles so the yould really run 2 times, added += to passwordGen.value += UpperFiltered so the value would add up.
I guess that is it.
var UppercaseList = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"];
var LowercaseList = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"];
var NumList = ["1","2","3","4","5","6","7","8","9","0"];
var SpecialCharList = ["`","~","!","#","$","%","^","&","*","_","-","+","=","<",">","?","/"];
// Letter list ID's since I couldn't figure out how to run this using a database
var LetterIDList = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26];
// Number list ID's since I couldn't figure out how to run this using a database
var NumIDList = [1,2,3,4,5,6,7,8,9,10];
// Special character list ID's since I couldn't figure out how to run this using a database
var SpecialID = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17];
// Filtered Lists
var UpperFiltered = [];
var LowerFiltered = [];
var NumFiltered = [];
var SpecialFiltered = [];
// Global declarations of random number variables to grab values from intial lists
var UpperGenVariable;
var LowerGenVariable;
var NumGenVariable;
var SpecialGenVariable;
// Creates a basic password with 2 of each kind of character
function Basic () {
for (var i = 1; i <= 2; i++) {
UppercaseGenerate();
}
for (var i = 1; i <= 2; i++) {
LowercaseGenerate();
}
for (var i = 1; i <= 2; i++) {
NumGenerate();
}
for (var i = 1; i <= 2; i++) {
SpecialGenerate();
}
};
let passwordGen = document.getElementById("PasswordDisplay")
function UppercaseGenerate() {
var UpperFiltered = [];
UpperGenVariable = Math.floor(Math.random() * LetterIDList.length);
for (var i = 0; i < LetterIDList.length; i++) {
if (LetterIDList[i] == UpperGenVariable) {
UpperFiltered.push(UppercaseList[i]);
}
};
passwordGen.value += UpperFiltered
};
I am using the below script to delete duplicate rows from the google spreadsheet. The script was working good but as the data in the spreadsheet is being added daily, now the script is throwing "Exceeded maximum execution time" error. As I am new to scripting I don't understand what is my problem.
Could someone help me in solving this problem of mine.
function Deleteduplicates() {
var SpreadSheetKey = "My key";
var sheetD = SpreadsheetApp.openById(SpreadSheetKey).getSheetByName("Daily");
var sheetW = SpreadsheetApp.openById(SpreadSheetKey).getSheetByName("Weekly");
var dataD = sheetD.getDataRange().getValues();
var dataW = sheetW.getDataRange().getValues();
//Daily
var newDataD = new Array();
for(i in dataD){
var row = dataD[i];
var duplicate = false;
for(j in newDataD){
if(row.join() == newDataD[j].join()){
duplicate = true;
}
}
if(!duplicate){
newDataD.push(row);
}
}
//weekly
var newDataW = new Array();
for(i in dataW){
var row = dataW[i];
var duplicate = false;
for(j in newDataW){
if(row.join() == newDataW[j].join()){
duplicate = true;
}
}
if(!duplicate){
newDataW.push(row);
}
}
sheetD.clearContents();
sheetW.clearContents();
sheetD.getRange(1, 1, newDataD.length, newDataD[0].length).setValues(newDataD);
sheetW.getRange(1, 1, newDataW.length, newDataW[0].length).setValues(newDataW);
}
Conceptually, this should be quite a bit faster. I have not tried it on a large data set. The first version will leave the rows sorted as they were originally. The second version will be faster but will leave the rows sorted according to the columns from first to last on first text.
function Deleteduplicates() {
var SpreadSheetKey = "My key";
var ss = SpreadsheetApp.openById(SpreadSheetKey);
var sheetD = ss.getSheetByName("Daily");
var sheetW = ss.getSheetByName("Weekly");
var sheets = [sheetD, sheetW];
var toSs = {};
for(s in sheets) {
var data = sheets[s].getDataRange().getValues();
for(i in data){
// EDIT: remove commas from join("") for blank test
data[i].unshift(data[i].join(""),(1000000 + i).toString());
}
data.sort();
// remove blank rows -- Edit
var blank = 0;
while(data[blank][0].trim().length == 0) {blank++};
if(blank > 0) data.splice(0, blank);
// end Edit
var len = data.length - 1;
for(var x = len; x > 0; x-- ) {
if(data[x][0] == data[x-1][0]) {
data.splice(x, 1);
};
};
for(i in data) {
data[i].splice( 0, 1);
};
data.sort();
for(i in data) {
data[i].splice(0, 1);
};
toSs[sheets[s].getSheetName()] = data;
};
for(s in sheets) {
var data = toSs[sheets[s].getSheetName()];
sheets[s].clearContents();
sheets[s].getRange(1, 1, data.length, data[0].length).setValues(data);
}
}
Faster leaving rows sorted by join() created to test for duplicates
function Deleteduplicates() {
var SpreadSheetKey = "My key";
var ss = SpreadsheetApp.openById(SpreadSheetKey);
var sheetD = ss.getSheetByName("Daily");
var sheetW = ss.getSheetByName("Weekly");
var sheets = [sheetD, sheetW];
var toSs = {};
for(s in sheets) {
var data = sheets[s].getDataRange().getValues();
for(i in data){
// EDIT: remove commas from join("") for blank test
data[i].unshift(data[i].join(""));
}
data.sort();
// remove blank rows -- Edit
var blank = 0;
while(data[blank][0].trim().length == 0) {blank++};
if(blank > 0) data.splice(0, blank);
// end Edit
var len = data.length - 1;
for(var x = len; x > 0; x-- ) {
if(data[x][0] == data[x-1][0]) {
data.splice(x, 1);
};
};
for(i in data) {
data[i].splice( 0, 1);
};
toSs[sheets[s].getSheetName()] = data;
};
for(s in sheets) {
var data = toSs[sheets[s].getSheetName()];
sheets[s].clearContents();
sheets[s].getRange(1, 1, data.length, data[0].length).setValues(data);
}
}
Edited per Henrique's comment.
Edited 5/8: Remove blank rows(2 edited areas marked)
There is no problem with your script. It is just exceeding the "maximum execution time" allowed for any script (which is currently 6 minutes).
To workaround this problem you'll have to split your problem into "less than 6 minutes" parts.
For example, in your code you're clearing duplicates from 2 sheets. Trying creating two functions, one for each, and run them separately.
Also, there could be some performance enhancements that could make the script run under 6 minutes. For example, I'm not sure joining each row is the best way (performance-wise) to do an array comparison.
Creating a new array to re-set the data might not be optimal either, I'd probably go with a map verification, which is constant-time, instead of O(n^2) double array checking you're doing.
Bottom line, this is a limitation you have to live with in Apps Script. And any solution anyone proposes is just a workaround, that will also eventually fail if your data gets overly big.
I have been using google scripts for a week, and I have searched as much as I could to get the answer. Can someone please help me? I wrote a simple script to evaluate if a course is online based on the last three digits of a course number(i.e PSY-250-400). The script works fine, and I pushed the result into the end of the array. I don't know how to write back to google sheets. Below is what I have. Currently it will set the values based on the first result(online course). So all values are set to online. I am running it on 7 rows right now, but will need to run it on 20,000.
function onlineonly(online){
var sheet = SpreadsheetApp.getActiveSheet();
var students = sheet.getRange('A2:D7').getValues();
var online = ["400","401","403","404","600"];
var m;
var section;
for(var i=0; i<students.length; ++i){
section = students[i][3].substring(8,13);
for(var j = 0;j<online.length; j++){
if(section===online[j]){
section = m;
}
}
if(section === m){
students[i].push("online");
} else {
students[i].push("not online");
}
var method = [];
for(var k = 0; k<students.length; k++){
if(students[i][4]=== "online"){
method = "online";
} else {
method = "in person";
}
sheet.getRange('c2:c7').setValue(method);
}
}
}
The important thing to remember is that the dimensions of the Range must equal the exact dimensions of the Array[][]. This array must be two-dimensional! Otherwise you'll get an error that setValues() method expects an Object[][], not an Array.
You're trying to set a simple array. Also, the method you'll use is setValues(), not setValue().
Your code is a little hard to understand, so this is an example of the pattern:
function writeOutValues() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var range = sheet.getRange("C2:C7");
var values = range.getValues();
//remember, a 2d array is a grid of values that corresponds to the grid of the range like so: values[row][column]
//so in this range, values[0][0] = C2, values[1][0] = C3, etc.
values[0][0] = "New Value";
values[1][0] = "Another one";
//to set value,
range.setValues(values);
}
just move inner for loop
for(var k = 0; k<students.length; k++) to outside the main for loop
and apply the technique as told by zbnrg
here is working code
function onlineonly()
{
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var students = sheet.getRange('A2:C4').getValues();
var online = ["400","401","403","404","600"];
var m;
var section;
for(var i=0; i<students.length; ++i)
{
section = students[i][1].slice(8,11);
for(var j = 0;j<online.length; j++)
{
if(section===online[j])
{
section = m;
}
}
if(section === m)
{
students[i].push("online");
}
else
{
students[i].push("not online");
}
}
var range = sheet.getActiveSheet().getRange("C2:C4");
var method = range.getValues();
for(var k = 0; k<students.length; k++)
method[k][0] = students[k][3]==="online"?"online":"in person";
Logger.log(method[0][0] +" "+method[1][0] +" "+ method[2][0])
range.setValues(method);
}
here is my spreadsheet https://docs.google.com/spreadsheets/d/1iA9v_3rPH9JAhAmt2EJTdbqTQkFEl7yewawPy3w4YIg/edit#gid=0