JavaScript loops to store data in an array - javascript

I have a friend who has an assignment on arrays and because I lack experience in Javascript and she just needs some real quick help understanding how to implement a Javascript loop to store data in an array which converts a letter grade to a number. Can someone just guide her in a general direction?
https://docs.google.com/fileview?id=16uNNiooLalkm1QlszrqEPr2qqMGLjhrtQx7qCLw-7d2ftygre8GM6hyceJHj&hl=en\
Update: She states that she doesn't understand how to make it prompt again after the first time while storing data. Can someone just write a translation for a C++ code for do {}?

Here's a more or less complete solution - but it doesn't output the results to the HTML page but outputs it with the alert boxes.
var done = false,
classes = [],
total_credits = 0,
avg = 0;
while(!done){
var class_name = prompt("Enter class name"),
letter_grade = prompt("Enter letter grade for "+class_name),
credit_hours = prompt("Enter credit hours for "+class_name),
number_grade = {"A":4,"B":3,"C":2,"D":1,"F":0}[letter_grade];
if(class_name && letter_grade && credit_hours){
classes.push({
class_name: class_name,
letter_grade: letter_grade,
number_grade: number_grade,
credit_hours: credit_hours
});
total_credits += parseInt(credit_hours,10);
avg += number_grade*credit_hours;
}else
done = true;
}
avg = avg/total_credits;
for(var i=0; i<classes.length; i++){
alert(classes[i].class_name + " | " +
classes[i].letter_grade + " | " +
classes[i].credit_hours);
}
alert("Total credits: " + total_credits);
alert("GPA: " + avg.toFixed(2));

Basically, she should use a while loop.
in (mostly) pseudocode:
more_entries = true;
while(more_entries)
{
response = prompt("Question for the user","");
if (response == null)
{
more_entries = false;
}
else
{
// store value somewhere
}
}
Of course, this needs to be expanded to multiple prompts.

Related

convert array.push.(prompt()) into a number

when i run the program the browser tell me moy is NaN yet I took care to use .map(Number) to convert the array into a number . I need some help please.
var score = [];
var i = 0;
var choice = 0;
while(choice != null){
i++;
score.push(prompt("put the score number "+i));
score = score.map(Number);
choice = prompt("to continue click on ok to cancel click on cancel");
}
var sum = 0,moy;
for(a=0;a<=i;a++) {
sum = sum+score[a];
moy = sum/i;
}
document.write("you put "+i+" score(s) <br>and the average is"+moy);
you have syntax error in this line
for(a=0;a<=i;a++) {
define a variable like this
for(var a=0;a<=i;a++)

How to get and set values in different tabs of a google sheet?

I have a sheet with TAB A and TAB B.
I want to loop through TAB A and get a matrix of values which I want to paste in TAB B.
It is throwing Errors, "Cannot read property 1, etc
function getValuesFromModal(form) {
var IdeasCounter = 0;
const IDEA = 10,
PROD = 26,
PROM = 20,
CLIENT = 4,
ORANGE = "#e69138",
GREEN = "#6aa84f",
RED = "#e06666";
var rangeSource = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Records").getRange("A2:V").getValues();
var rangeDest = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Board").getRange("A2:E");
for (i in rangeSource) {
if (rangeSource[i][0] == "Ideas" && (!isNaN(parseInt(rangeSource[i][17])))) {
rangeDest[IdeasCounter][0].setValue("( " + rangeSource[i][2] + " )" + "\n" + rangeSource[i][3] + "\n\n" + "[ " + rangeSource[i][17] + " ]");
switch (rangeSource[i][17]) {
case rangeSource[i][17] < (IDEA - 2):
rangeDest[IdeasCounter][0].setBackground(GREEN);
break;
case rangeSource[i][17] > (IDEA):
rangeDest[IdeasCounter][0].setBackground(RED);
break;
case rangeSource[i][17] < (IDEA):
rangeDest[IdeasCounter][0].setBackground(ORANGE);
break;
}
IdeasCounter++;
}
}
}
I found a few issues with your script, and have modified it accordingly:
I renamed rangeSource as you were pulling the values, not the actual range.
I then created new arrays for the destination values and the cell backgrounds. This is necessary so that, on running the script, previously existing values and background colors will not be overwritten. Also, iterating through an array of a range's values is much faster than iterating through the range.
You were using a for..in loop, but you shouldn't do that here. Instead, use a sequential for loop. Please take a look at this great answer to understand why. (Also, you can't loop through a Google Range class using the Array [][] notation. You would have to use the very slow getCell() method on the range, but it is vveeerrryyy ssssllooowwww.)
I saved sourceValues[i][17] to its own variable, but you should, ideally, do so for the other sourceValues[i][*] values as it will be easier to read and maintain.
The switch statement is incorrect as it is not really meant to handle </> comparisons. Again, someone else's explanation on both how you could do it, and why you should not do it is better than mine; you can read it here.
I then used batch operations as they're much faster, to write the destination values and set the cell background colors.
After modification, this is what resulted:
function getValuesFromModal(form) {
var IdeasCounter = 0;
const IDEA = 10,
PROD = 26,
PROM = 20,
CLIENT = 4,
ORANGE = "#e69138",
GREEN = "#6aa84f",
RED = "#e06666";
var sourceValues = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Records").getRange("A2:V").getValues();
var destRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Board").getRange("A2:A"); // Looked like you were only writing to column A
var destNewValues = destRange.getValues();
var destBackgrounds = destRange.getBackgrounds();
for (var i=0; i<sourceValues.length; i++) {
var ideaValue = sourceValues[i][17];
if (sourceValues[i][0] == "Ideas" && (!isNaN(parseInt(ideaValue)))) {
var destValue = "( " + sourceValues[i][2] + " )\n" + sourceValues[i][3] + "\n\n[ " + ideaValue + " ]";
destNewValues[i][0] = destValue;
if (ideaValue < (IDEA - 2)) { // Right now excluding ideaValue == 10
destBackgrounds[i] = [GREEN];
} else if (ideaValue > IDEA) {
destBackgrounds[i] = [RED];
} else if (ideaValue < IDEA) {
destBackgrounds[i] = [ORANGE];
}
}
}
destRange.setValues(destNewValues).setBackgrounds(destBackgrounds);
}

Treating numbers as strings

I got bored and decided to make a script, but it isn't working. Instead of adding the numbers, it treats them as strings, ex. 0 + 42 + 0 + 17 would be 042017. Also, the while script goes on forever.
var money = 0;
var yn = false;
var bye = 0;
var add = window.prompt("How many dollars do you want?");
console.log("You got " + add + " dollars!");
parseFloat(add);
money += add;
add = 0;
console.log(money);
while (money < 1000000001 || bye == 1) {
yn = window.confirm("Do you want more money?");
if (yn) {
add = window.prompt("How many dollars do you want?");
console.log("You got " + add + " dollars!");
parseFloat(add);
money += add;
console.log(money);
} else {
console.log("Goodbye!");
bye = 1;
};
};
if (money > 999999999) {
console.log("You won the game with " + money + " dollars!");
};
When you do
parseFloat(add);
it converts add to a floating point value and returns it. Since you are ignoring it, add remains unchanged as a string. You might want to replace the new value in add, like this
add = parseFloat(add);
Also, you can just convert the result of window.prompt itself, like this
add = parseFloat(window.prompt(...));
Most likely the reason your while loop is going on forever is because of the bye variable. Your logic is broken.
If the user answers No to the prompt, bye will be set to 1 and never change back. The while loop will continue as long as bye is 1, so it will go on forever.
To fix this, you can use:
while (money < 1000000001 && bye !== 1) {
or
while (money < 1000000001 || bye === 0) {
However, to store an on/off flag, you should be using a boolean variable, not a number:
var bye = false;
// ....
while (money < 1000000001 && !bye) {
// ....
if (yn) {
// ....
} else {
// ....
bye = true;
}
}
Also note that you don't need (read: shouldn't use) a semicolon after if and while blocks.

Help with comparing to array values in JavaScript

I have developed this code with help from you guys here on stackoverflow. I have added an extra part to it where it compares two numbers from two different arrays, in this case offhire1 and pro2.
The problem is in my code where I have:
(offhire1[i].value > pro2[i].value)
It only allows me to contine if the numbers match i.e 100=100. But what I'm after is identifing any numbers that are greater than the value only 120 > 100. I have tested if the values are being passed and they are.
What is my mistake here can anyone suss it out.
function validateoffhire(form) {
var num1 = document.getElementById('num1');
var test2Regex = /^[0-9 ]+(([\,\.\- ][a-zA-Z ])?[a-zA-Z]*)*$/;
var accumulator = 0;
var num2 = num1.value;
var i=0;
var offhire1 = [];
var pro2 =[];
for(var i = 0; i < num2; i++) {
offhire1[i] = document.getElementById('offhire1' + i);
pro2[i] = document.getElementById('pro2' + i);
var offhire2 = offhire1[i].value;
// var pro3 = pro2[i].value;
if(!offhire2.match(test2Regex)){
inlineMsg('offhire1' + i,'This needs to be an integer',10);
return false;
}
else if (offhire1[i].value > pro2[i].value) {
alert("You entered: " + pro2[i].value)
inlineMsg('offhire1' + i,'You have off hired to many items',10);
return false;
}
else{
accumulator += parseInt(offhire2);
}
}
if(accumulator <= 0){
inlineMsg('num1' ,'You have not off Hired any items',10);
return false;
}
return true;
}
I'm not quite sure I follow you. If the numbers are the same, the statement won't match.
One issue in your code is that you're comparing strings, not numbers. You may want to change it to:
(parseInt(offhire1[i].value) > parseInt(pro2[i].value))

Converting VBScript to Javascript, What is the right way of parsing source code?

I was asked to convert some VB6/VBScript code to javascript so after googling it and not finding anything I can use,I wrote a small javascript function to help me do the conversion; it's so crude and only converts (some of) the synatx, but it worked for me for the job I had...now I'm thinking of improving it but the method I used is so primitive (Regular Expression matching and replacing).
So...my question is:
What is the proper way to parse source code? is there any (not so complicated) way of doing it? and I don't want to use Exe's, it must be done entirely in Javascript. I'm not searching for ready-to-use source code (I don't think it exists!) but I want to learn how to be able to start with source code and turn it into objects (the opposite of serialization, I think?).
//here is the code:
var strs=[];
function vbsTojs(vbs){
var s = vbs;
s = HideStrings(s);
//only function block
s = s.match(/Function[\w\W]+End\s+Function/gim)[0];
//line-continuation char
s = s.replace(/_\n/gm,"");
//replace ":" with CRLF
s = s.replace(/:/gm,"\n");
//move inline comment to its own line
s = s.replace(/^(.+)'(.*)$/gim,"'$2\n$1");
//single line if -> multiple line
s = s.replace(/\bthen\b[ \t](.+)/gi,"then\n$1\nEnd If");
//alert(s);
var Vars='';
var Fx='';
var FxHead='';
var Args = '';
a=s.split('\n');
//trim
for(i=0;i<a.length;i++){
a[i]=a[i].replace(/^\s+|\s+$/,"");
}
//remove empty items
a=a.filter(function(val) { return val !== ""; });
//alert(a.join('\n'));
//function
a[0]=a[0].replace(/function\s+/i,"");
Fx = a[0].match(/^\w+/)[0];
a[0]=a[0].replace(Fx,"").replace(/[\(\)]/g,"");
a[0]=a[0].replace(/\bbyval\b/gi,"").replace(/\bbyref\b/gi,"").replace(/\boptional\b/gi,"");
a[0]=a[0].replace(/\bas\s+\w+\b/gi,"");
a[0]=a[0].replace(/\s+/g,"");
a[0]=a[0].replace(/,/gi,", ");
FxHead = "function " + Fx+ " ("+ a[0] + "){";
a[0]="";
//end function
a.length = a.length-1;
for(i=1;i<a.length;i++){
//Vars
if(a[i].search(/^dim\s+/i)>-1){
a[i]=a[i].replace(/dim\s*/i,"");
Vars += a[i] + ",";
a[i]='';
//FOR
}else if(a[i].search(/^\bFOR\b\s+/i)>-1){
a[i]=a[i].replace(/^\bFOR\b\s+/i,"");
counter = a[i].match(/^\w+/)[0];
from = a[i].match(/=\s*[\w\(\)]+/)[0];
from=from.replace(/=/,"").replace(/\s+/g,"");
a[i]=a[i].replace(counter,"").replace(from,"").replace(/\bTO\b/i,"");
to = a[i].match(/\s*[\w\(\)]+\s*/)[0];
to=to.replace(/=/,"").replace(/\s+/g,"");
a[i] = "for(" + counter + "=" + from + "; " + counter + "<=" + to + "; " + counter + "++){"
//NEXT
}else if(a[i].search(/^NEXT\b/i)>-1){
a[i] = "}";
//EXIT FOR
}else if(a[i].search(/\bEXIT\b\s*\bFOR\b/i)>-1){
a[i] = "break";
//IF
}else if(a[i].search(/^\bIF\b\s+/i)>-1){
a[i]=a[i].replace(/^\bIF\b\s+/i,"");
a[i]=a[i].replace(/\bTHEN$\b/i,"");
a[i]=a[i].replace(/=/g,"==").replace(/<>/g,"!="); //TODO: it should not replace if inside a string! <---------------
a[i]=a[i].replace(/\bOR\b/gi,"||").replace(/\bAND\b/gi,"&&"); //TODO: it should not replace if inside a string! <---------------
a[i] = "if(" + a[i] + "){";
//ELSE
}else if(a[i].search(/^ELSE/i)>-1){
a[i] = "}else{";
//END IF
}else if(a[i].search(/^END\s*IF/i)>-1){
a[i] = "}";
//WHILE
}else if(a[i].search(/^WHILE\s/i)>-1){
a[i] = a[i].replace(/^WHILE(.+)/i,"while($1){");
//WEND
}else if(a[i].search(/^WEND/i)>-1){
a[i] = "}";
//DO WHILE
}else if(a[i].search(/^DO\s+WHILE\s/i)>-1){
a[i] = a[i].replace(/^DO\s+WHILE(.+)/i,"while($1){");
//LOOP
}else if(a[i].search(/^LOOP$/i)>-1){
a[i] = "}";
//EXIT FUNCTION
}else if(a[i].search(/\bEXIT\b\s*\bFUNCTION\b/i)>-1){
a[i] = "return";
//SELECT CASE
}else if(a[i].search(/^SELECT\s+CASE(.+$)/i)>-1){
a[i]=a[i].replace(/^SELECT\s+CASE(.+$)/i,"switch($1){");
}else if(a[i].search(/^END\s+SELECT/i)>-1){
a[i] = "}";
}else if(a[i].search(/^CASE\s+ELSE/i)>-1){
a[i] = "default:";
}else if(a[i].search(/^CASE[\w\W]+$/i)>-1){
a[i] = a[i] + ":" ;
}
//CONST
else if(a[i].search(/^CONST/i)>-1){
a[i] = a[i].replace(/^CONST/i,"const");
}
else{
//alert(a[i]);
}
//COMMENT
if(a[i].search(/^\'/)>-1){
a[i]=a[i].replace(/^\'/,"//");
}else if(a[i].search(/\'.*$/)>-1){
a[i]=a[i].replace(/\'(.*)$/,"//$1");
}
}
//alert(a.join("*"));
Vars = Vars.replace(/\s*AS\s+\w+\s*/gi,"");
if(Vars!="") Vars = "var " + Vars.replace(/,$/,";").replace(/,/g,", ");
FxHead + '\n' + Vars;
a=a.filter(function(val) { return val !== ""; }) //remove empty items
for(i=0;i<a.length;i++){
if (a[i].search(/[^}{:]$/)>-1) a[i]+=";";
}
ss = FxHead + '\n' + Vars + '\n' + a.join('\n') + '\n}';
ss = ss.replace(new RegExp(Fx+"\\s*=\\s*","gi"),"return ");
ss = UnHideStrings(ss);
return jsIndenter(ss);
}
//-----------------------------------------------------
function jsIndenter(js){
var a=js.split('\n');
var margin=0;
var s = '';
//trim
for(i=0;i<a.length;i++){ a[i]=a[i].replace(/^\s+|\s+$/,""); }
//remove empty items
a=a.filter(function(val) { return val !== ""; });
for(var i=1;i<a.length;i++){
if(a[i-1].indexOf("{")>-1) margin += 4 ;
if(a[i].indexOf("}")>-1) { margin -= 4; }
if(margin<0) margin = 0;
a[i] = StrFill(margin," ") + a[i] ;
}
return a.join('\n');
}
function StrFill(Count,StrToFill){
var objStr,idx;
if(StrToFill=="" || Count==0){
return "";
}
objStr="";
for(idx=1;idx<=Count;idx++){
objStr += StrToFill;
}
return objStr;
}
function HideStrings(text){
const x = String.fromCharCode(7);
const xxx = String.fromCharCode(8);
text = text.replace(/"""/gim, '"'+xxx); //hide 3 quotes " " "
var idx=0, f=0;
while(f>-1){
f = text.search(/".+?"/gim);
if(f>-1){
strs.push(text.match(/".+?"/)[0]);
//alert(strs[idx]);
text = text.replace(/".+?"/, x+idx+x);
idx++;
}
}
//alert(text);
return text;
}
function UnHideStrings(text){
for(var i=0; i<strs.length; i++){
text = text.replace(new RegExp("\\x07"+i+"\\x07"), strs[i]);
}
//Unhide 3 quotes " " " ***BUG: causes unterminated string if triple-quotes are at the end of the string
text = text.replace(/\x08/gim,'\\"');
text = text.replace(/""/gi,'\\"');
return text;
}
The proper way to parse source code for any programming language is to use a parser. Regular expressions are a useful part of (some) parsers, but a parser is a different sort of thing. There is quite a body of research and techniques in the Computer Science literature on the subject of parsing, and it's a fascinating pursuit to study.
"Converting" a bunch of Visual Basic code to Javascript is a project that seems inherently fraught with peril and mystery. A Visual Basic parser will be just the first significant hurdle to conquer. After that, you'll need to figure out how to semantically represent the Visual Basic operations in Javascript. Depending on the original context of the code, that could be somewhat weird. (You don't mention anything about where this code all runs.)
As enriching a learning experience as this might be, it's not unlikely that translating the code by hand will (in the end) take less time and produce better results. That's particularly true if you're just now finding out that there is such a thing as a "parser".
Nice job. Sounds like you did something that might not be perfect, but it did the job.
I'd recommend looking into parsers and grammars if you want to make it more sophisticated. There are lots of parser generators that would be able to help you. You'd have to come up with a grammar for the source language, generate the lexer/parser, and then use that to generate an abstract syntax tree (AST). Once you have that, you can walk the AST and ask it to emit any code you want.
It's doable but, as Oded says, it's not trivial.

Categories

Resources