Hello so I am trying to work on this code for my Java Script class and I am stuck on how to proceed. The instructions for the problem we were given were as follows:
Create a simple self-checkout system. Prompt for the prices and quantities of three items. Calculate the subtotal of the items. Then calculate the tax using a tax rate of 5%. Print out the line items with the quantity and total, and then print out the subtotal, tax amount, and total.
Here is my code so far:
// Make a function for a simple self-checkout system.
// prompt the user for quantity of the items
// Prompt the user for the prices of the items
function self_Checkout () {
var prices = [x, y, z,];
var x = prompt('Enter value');
var quantity_x = prompt('Enter value for quantity of item 1');
return x * quantity_x;}
{ if
var y = prompt('Enter value');
var quantity_y = prompt('Enter value for quantity of item 2');
return y * quantity_y;
{ if
var z = prompt('Enter value');
var quantity_z = prompt('Enter value for quantity of item 3');
return z * quantity_y;
// Multiply entire total by a tax rate of 5%
// Return value of total of all items + tax to user
// Use console.log or document.write?
}
Now the assignment also mentions how we are supposed to use loops objects and arrays also in this problem. I have attempted to add a array in the code. Some help on how to proceed in my code would be much appreciated, hopefully i explained it well enough to get some help.
Here is working code that is all dynamic and not limited to 3 items
<!DOCTYPE html>
<html>
<head>
<script>
function getit(){
var result = document.getElementById('demo');
var allitems = 0;
var itemCount = prompt("how many items do you need?");
var items = {};
for (i = 0; i < itemCount; i++) {
items[i] = {
name : prompt("Product Name"),
price : prompt("Product Price"),
qty : prompt("Product qty")
}
}
for (i = 0; i < itemCount; i++) {
var subtotal = 0;
var total = 0;
subtotal = items[i].price * items[i].qty;
total = subtotal * 1.05;
allitems = allitems + subtotal;
result.innerHTML += "Product: " + items[i].name + "<br/>";
result.innerHTML += "Total Qty: " +items[i].qty + "<br/>";
result.innerHTML += "Sub total: " + subtotal + "<br/>";
result.innerHTML += "Sub total: " + total + "<br/>";
if(i == (itemCount - 1)){result.innerHTML += "Sub total for all items: " + allitems + "<br/>";}
}
}
</script>
</head>
<body>
<button onclick="getit()">Shop</button>
<p id="result">Creating a JavaScript Object.</p>
</body>
</html>
Related
I am working with automation in Google sheet. Can you help me?
This problem is for sending surveys to 46 people. Each people needs to rate 5 people from those 46 people.
Requirements:
1. 1 rater, for 5 uniques ratees
2. No duplicate name per row (it should be 6 unique names in a row)
3. No duplicate name per column (it should be 46 unique names per column)
Expected output is for us to create 46x6 random names with no duplicates in row and columns.
-
-
Flow:
If a unique matrix across and below can be created, then it's values can be used as keys to the actual name array.
Create a 2D number array with length = number of rows
Loop through required number of columns and rows
Create a temporary array (tempCol) to store current column data
Fill the array with random numbers
Use indexOf to figure out if any random numbers are already present in the currentrow/ current column, if so, get a new random number.
In random cases, where it's impossible to fill up the temporary column with unique random numbers across and below, delete the temporary column and redo this iteration.
Snippet:
function getRandUniqMatrix(numCols, numRows) {
var maxIter = 1000; //Worst case number of iterations, after which the loop and tempCol resets
var output = Array.apply(null, Array(numRows)).map(function(_, i) {
return [i++]; //[[0],[1],[2],...]
});
var currRandNum;
var getRandom = function() {
currRandNum = Math.floor(Math.random() * numRows);
}; //get random number within numRows
while (numCols--) {//loop through columns
getRandom();
for (
var row = 0, tempCol = [], iter = 0;
row < numRows;
++row, getRandom()
) {//loop through rows
if (//unique condition check
!~output[row].indexOf(currRandNum) &&
!~tempCol.indexOf(currRandNum)
) {
tempCol.push(currRandNum);
} else {
--row;
++iter;
if (iter > maxIter) {//reset loop
iter = 0;
tempCol = [];
row = -1;
}
}
}
output.forEach(function(e, i) {//push tempCol to output
e.push(tempCol[i]);
});
}
return output;
}
console.info(getRandUniqMatrix(6, 46));
var data1d = data.map(function(e){return e[0]});
var finalArr = getRandUniqMatrix(6, 46).map(function(row){return row.map(function(col){return data1d[col]})});
destSheet.getRange(1,1,finalArr.length, finalArr[0].length).setValues(finalArr);
The OP wants to create a review matrix in which the names of the reviewed employees are chosen at random, the reviewer cannot review themselves, and the matrix is completed for 46 employees.
Based on previous code, this version builds an array of employee names for each row, in which the name of the reviewer is not included in the array. Five names are chosen at random and applied to the reviewer. The loop then repeats through each of the 46 employees.
For example, in the first round of reviews, "name01" is omitted from the array of employees from which the "reviewees" are randomly chosen. In the second round, "name01" is included, but "name02" is excluded from the array of employees. And so on, such that in each case, the array of employees used for the random selection of five reviews is always 45 names in length, and excludes the name of the reviewer.
The random selection of names to be rated does not ensure an equal and even distribution of reviews among employees. Though each employee will conduct 5 reviews, some employees are reviewed more than 5 times, some less than 5 times, and (depending on the alignment of the sun, the moon and the stars) it is possible that some may not be selected for review.
function s05648755803(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetname = "Sheet3";
var sheet = ss.getSheetByName(sheetname);
// some variables
var randomcount = 30; // how many random names
var rowstart = 7; // ignore row 1 - the header row
var width = 5; // how many names in each row - 1/rater plus 5/ratee
var thelastrow = sheet.getLastRow();
//Logger.log("DEBUG:last row = "+thelastrow)
// get the employee names
var employeecount = thelastrow-rowstart+1;
//Logger.log("DEBUG: employee count = "+employeecount);//DEBUG
// get the data
var datarange = sheet.getRange(rowstart, 1, thelastrow - rowstart+1);
//Logger.log("DEBUG: range = "+datarange.getA1Notation());//DEBUG
var data = datarange.getValues();
//Logger.log("data length = "+data.length);
//Logger.log(data);
var counter = 0;
var newarray = [];
for (c = 0;c<46;c++){
counter = c;
for (i=0;i<data.length;i++){
if(i!=counter){
newarray.push(data[i]);
}
}
//Logger.log(newarray);
var rowdata = [];
var results = selectRandomElements(newarray, 5);
Logger.log(results)
rowdata.push(results);
var newrange = sheet.getRange(rowstart+c, 3, 1, 5);
newrange.setValues(rowdata);
// clear the arrays for the next loop
var newarray=[];
var rowdata = []
}
}
/*
// selectRandomElements and getRandomInt
// Credit: Vidar S. Ramdal
// https://webapps.stackexchange.com/a/102666/196152
*/
function selectRandomElements(fromValueRows, count) {
var pickedRows = []; // This will hold the selected rows
for (var i = 0; i < count && fromValueRows.length > 0; i++) {
var pickedIndex = getRandomInt(0, fromValueRows.length);
// Pick the element at position pickedIndex, and remove it from fromValueRows. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice
var pickedRow = fromValueRows.splice(pickedIndex, 1)[0];
// Add the selected row to our result array
pickedRows.push(pickedRow);
}
return pickedRows;
}
function getRandomInt(min,
max) { // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
}
Screenshot#1
Screenshot#2
Try this. Satisfies all the three requirements.
HTML/JS:
<html>
<title>Unique Employees</title>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
</head>
<table id="survey_table" border="1" width="85%" cellspacing="0">
<thead>
<th>Rater</th>
<th>Ratee1</th>
<th>Ratee2</th>
<th>Ratee3</th>
<th>Ratee4</th>
<th>Ratee5</th>
</thead>
<tbody id="table_body">
</tbody>
</table>
<script type="text/javascript">
function arrayRemove(arr, value) {
return arr.filter(function(ele) {
return ele != value;
});
}
function getRandomInt(rm_row, rm_col) {
var temp_arr = [];
for (var k = 1; k <= 46; k++) {
temp_arr.push(k);
}
for (var k = 0; k < rm_row.length; k++) {
temp_arr = arrayRemove(temp_arr, rm_row[k]);
}
for (var k = 0; k < rm_col.length; k++) {
temp_arr = arrayRemove(temp_arr, rm_col[k]);
}
var rand = temp_arr[Math.floor(Math.random() * temp_arr.length)];
return rand;
}
function exclude_num(row_unq, col_unq) {
var rand_int = getRandomInt(row_unq, col_unq);
if (!row_unq.includes(rand_int) && !col_unq.includes(rand_int)) {
arr_row.push(rand_int);
return rand_int;
} else {
return exclude_num(arr_row, arr_cols);
}
}
for (var i = 1; i <= 46; i++) {
var arr_row = [];
arr_row.push(i);
var table_html = '<tr id="Row' + i + '">';
for (var j = 1; j <= 6; j++)
{
if (j == 1) {
table_html += '<td class="Column' + j + ' cells_unq">' + i + '</td>';
} else {
var arr_cols = []
$('.Column' + j).each(function() {
arr_cols.push(Number($(this).text()));
});
var num = exclude_num(arr_row, arr_cols);
table_html += '<td class="Column' + j + ' cells_unq">' + num + '</td>';
}
}
table_html += '</tr>';
var row_html = $('#table_body').html();
$('#table_body').html(row_html + table_html);
}
$('.cells_unq').each(function() {
temp_text = $(this).text();
$(this).text('Name' + temp_text);
});
</script>
<style type="text/css">
td {
text-align: center;
}
</style>
</html>
Can you help point out what is wrong with my code here:
The goal is to to compute the total amount spent by a diner party of 3 people, each ordering 2 dishes.
I know there are other ways to do this using 'this' and 'new' in a more oop manner, but I think my approach here is more readable..if I can make it work. The code works fine if each patron only orders 1 dish so there is something wrong with the way I have been trying to access the JS dictionary.
Sorry about the newbie question. Any help is appreciate!
var diners=[
{name:'adam', entree1:'ramen', price1:11.5, entree2: 'miso', price2 : 3},
{name:'bobby', entree1: 'udon', price1 :10.69, entree2: 'gyoza', price2 :4.5},
{name:'carly', entree1: 'teriyaki chicken', price1:12, entree2: 'miso', price2 : 3},
];
var entrees1_total=0;
for (var d in diners){
entrees1_total += diners[d].price1; //total expense of entree1 for all diners
diners[d].tax1 = diners[d].price1*0.082; // method for sales tax
entrees1_total += diners[d].tax1; //total entree1 price including sales tax
}
var entrees2_total=0;
for (var d in diners){
entrees2_total += diners[d].price2;
diners[d].tax2 = diners[d] * price2 * 0.082;
entrees2_total += diners[d].tax2;
}
var total = entree1_total + entree2_total;
var total_bill = total*1.2; //tips
console.log("total is: " + total_bill.toString());
for (var d in diners) {
console.log(diners[d].name + " spends " + (diners[d].price1 + diners[d].tax1)+(diners[d].price2 + diners[d].tax2));
} // print out total spent for each patron
You can just use .reduce() to iterate the array and keep a running total:
var rawTotal = diners.reduce(function(cum, obj) {
return cum + obj.price1 + obj.price2;
}, 0);
// add in tax and tip
var tax = rawTotal * 0.082;
var tip = rawTotal * 0.2; // assumes you don't include taxes in tip calculation
var finalTotal = rawTotal + tax + tip;
Working demo: https://jsfiddle.net/jfriend00/ure3r2jg/
A few notes about your code:
You should never use for/in to iterate an array. for/in iterates all properties of the object which includes array elements, but can also include other enumerable properties (if any have been added to the object). Instead, use .forEach(), .map(), .reduce() or a regular for (var i = 0; i < array.length; i++) loop or in ES6, for/of.
Your sales tax calculation is not correct. You are multiplying each sub-total value which means the early values get multiplied by the sales tax value multiple times. It is simplest to just accumulate the regular total and then apply the sales tax at the end. Or, multiple the sales tax only by each new price, not by the accumulated total.
You have to decide if tip is calculated before or after taxes. This is matter of preference, but I've shown it where tip is calculated before taxes.
This statement looks incorrect
diners[d].tax2 = diners[d] * price2 * 0.082;
I guess you meant "diners[d].price2"
First off - your diners variable is not a dictionary but an array of anonymous objects. Therefore you can not index the array by objects diners[1] but only by the ordinal number of the objetc in array. For that you use for cycle.
Also you had other typos in your code.
Find fixed and working code below:
var diners=[
{name:'adam', entree1:'ramen', price1:11.5, entree2: 'miso', price2 : 3},
{name:'bobby', entree1: 'udon', price1 :10.69, entree2: 'gyoza', price2 :4.5},
{name:'carly', entree1: 'teriyaki chicken', price1:12, entree2: 'miso', price2 : 3},
];
var entrees1_total=0;
for (d=0; d < diners.length; d++){
entrees1_total += diners[d].price1; //total expense of entree1 for all diners
diners[d].tax1 = diners[d].price1 * 0.082; // method for sales tax
entrees1_total += diners[d].tax1; //total entree1 price including sales tax
}
var entrees2_total=0;
for (d=0; d < diners.length; d++){
entrees2_total += diners[d].price2;
diners[d].tax2 = diners[d].price2 * 0.082;
entrees2_total += diners[d].tax2;
}
var total = entrees1_total + entrees2_total;
var total_bill = total*1.2; //tips
console.log("total is: " + total_bill.toString());
for (var d in diners) {
console.log(diners[d].name + " spends " + (diners[d].price1 + diners[d].tax1)+(diners[d].price2 + diners[d].tax2));
} // print out total spent for each patron
You made few mistakes in second loop and you result in console.log worked like string. Not a number. So the working code is
var diners=[
{name:'adam', entree1:'ramen', price1:11.5, entree2: 'miso', price2 : 3},
{name:'bobby', entree1: 'udon', price1 :10.69, entree2: 'gyoza', price2 :4.5},
{name:'carly', entree1: 'teriyaki chicken', price1:12, entree2: 'miso', price2 : 3},
];
var entrees1_total=0;
for (var d in diners){
entrees1_total += +diners[d].price1; //total expense of entree1 for all diners
diners[d].tax1 = diners[d].price1*0.082; // method for sales tax
entrees1_total += +diners[d].tax1; //total entree1 price including sales tax
}
var entrees2_total=0;
for (var d in diners){
entrees2_total += +diners[d].price2;
diners[d].tax2 = diners[d].price2 * 0.082;
entrees2_total += +diners[d].tax2;
}
var total = entrees1_total + entrees2_total;
var total_bill = total*1.2; //tips
console.log("total is: " + total_bill.toString());
for (var d in diners) {
console.log(diners[d].name + " spends " + (diners[d].price1 +diners[d].tax1 + diners[d].price2 + diners[d].tax2));
}
:
I am trying to calculate the average of 3 values (each numbered from 1-10) that are selected by the user and then pass the results to an text input (for display as a graph).
It should be updating the new average every time one of the values is changed, but the averaging is not working correctly at all. I think that the loop is not resetting the values every time it runs- it's adding up the sum each time it runs, but not sure how to fix it.
Here is my code:
var sliders = $("#health1,#health2,#health3");
var elmt = [];
$(sliders).each(function () {
elmt.push($(this).attr('value'));
$("#health1,#health2,#health3").change(function () {
var sum = 0;
averageRisk();
});
});
function averageRisk() {
var sum = 0;
for (var i = 0; i < elmt.length; i++) {
sum += parseInt(elmt[i], 10);
}
var avg = sum / elmt.length;
document.getElementById('healthLevel').value = +avg;
elmt.push($(sliders).attr('value'));
$('#healthLevel').val(avg).trigger('change');
console.log("Sum: " + sum);
console.log("Average: " + avg);
}
Here is an example:
http://jsfiddle.net/pixelmix/783cfmnv/
Not sure but seems like a lot of extra work going. Main issue was you were building array of initial values and not getting the values each time they changed. That first .each got all the slider values and added them to elmt and continued to push new values on to after every change instead of just getting the current values every time. Did you want to accumulate all values over time?
Fiddle: http://jsfiddle.net/AtheistP3ace/783cfmnv/6/
$("#health1,#health2,#health3").on('change', function () {
averageRisk();
});
function averageRisk() {
var sum = 0;
var elmt = $("#health1,#health2,#health3");
for (var i = 0; i < elmt.length; i++) {
sum += parseInt(elmt[i].value, 10); //don't forget to add the base
}
var avg = sum / elmt.length;
document.getElementById('healthLevel').value = +avg;
$('#healthLevel').val(avg).trigger('change');
console.log("Sum: " + sum);
console.log("Average: " + avg);
}
And as pointed out if you want to ignore updating things when the sum is NaN you can do this:
function averageRisk() {
var sum = 0;
var elmt = $("#health1,#health2,#health3");
for (var i = 0; i < elmt.length; i++) {
sum += parseInt(elmt[i].value, 10); //don't forget to add the base
}
if (isNaN(sum)) {
return false;
}
var avg = sum / elmt.length;
document.getElementById('healthLevel').value = +avg;
$('#healthLevel').val(avg).trigger('change');
console.log("Sum: " + sum);
console.log("Average: " + avg);
}
The problem is that you fill the elmt array at page loading.
When user changes the values, you do not refresh the elmt array. So the array used to compute the average is always the same, empty.
You have to recover the input values each time they are modified.
function averageRisk() {
var sum = 0;
// Re make the loop for getting all inputs values
$(sliders).each(function() {
var value = parseInt($(this).val(), 10);
sum += value;
});
var avg = sum/$(sliders).length;
$('#healthLevel').val(avg);
}
Working example : http://jsfiddle.net/783cfmnv/7/
PS : You can use the css class healthInput to select your inputs. If you add later other fields, you will not have to add the new input id to your jQuery selector.
I did this work, check it .
http://jsfiddle.net/783cfmnv/10/
$("#health1,#health2,#health3").change(function() {
var val1 = +slider1.val();
var val2 = +slider2.val();
var val3 = +slider3.val();
var avg = (val1 + val2 + val3) /3;
$("#healthLevel").val(avg);
});
I am having the
table which contains the table like
items price quantity total
apple 100 2 200
orange 200 2 600
grand total=600.
item fields are dropdown when drop down changes the price will be changed and total value and grandtotal also changed. My problem is when selecting apple and orange again go to apple change the item my grand total is not changing.
My Javascript code:
function totalprice(element, price) {
var elementid = element.id;
var expr = elementid.substring(elementid.indexOf(":") + 1, elementid.length);
var quantity = document.getElementById("quantity:" + expr).value;
var price = document.getElementById("price:" + expr).value;
if (quantity > 0) {
document.getElementById("total:" + expr).value = (parseInt(quantity)) * (parseInt(price));
var grandtotal = document.getElementById("total:" + expr).value;
var gtot = 0;
var amount = 0;
for (var i = 0; i <= expr; i++) {
//document.getElementById("total").value="";
gtot = document.getElementById("total:" + expr).value;
amount = parseInt(gtot) + parseInt(amount);
}
document.getElementById("total").value = amount;
}
return true;
}
I know the mistake is in for loop only it is simple one but i dont know how to solve.
I got the solution for this using table rows length and use that length to my for loop now my code is like
function totalprice(element,price)
{
var elementid=element.id;
var expr = elementid.substring(elementid.indexOf(":") + 1, elementid.length);
var quantity = document.getElementById("quantity:"+expr).value;
var price = document.getElementById("price:" + expr).value;
if(quantity >0)
{
document.getElementById("total:"+ expr ).value= (parseInt(quantity))*(parseInt(price));
//var grandtotal =document.getElementById("total:"+expr).value;
//var grandtotal = document.getElementsByClassName("total"+expr);
var rowcount = document.getElementById('table').rows.length;
var grandtotal = 0;
var finalamount = 0;
for(var i=1; i<rowcount; i++)
{
grandtotal=document.getElementById("total:"+i).value;
finalamount = parseInt(grandtotal) + parseInt(finalamount);
}
document.getElementById("total").value=finalamount;
}
return true;
}
Here is code what you need:
Java Script:
<script>
function getVal(e){
// for text
alert(e.options[e.selectedIndex].innerHTML);
// for value
alert(e.options[e.selectedIndex].value);
}
</script>
HTML:
<select name="sel" id="sel" onchange='getVal(this);'>
<option value="1">Apple</option>
<option value="2">Banana</option>
<option value="3">Cat</option>
</select>
I see two errors in your for loop, first you forgot to use i in your getElement so you're only going through the same field multiple times, second, you're only looping through the inputs previous to the field that was updated (i<=expr), when you actually want to go through all the "total" fields to get the grand total, I would suggest giving a class to all your total fields and then use this code for your loop
var total_fields = document.getElementsByClassName('total');
for (var i = 0; i < total_fields.length; i++) {
gtot = total_fields[i].value;
amount+= parseInt(gtot);
}
document.getElementById("total").value = amount;
I think the problem relies here:
"My problem is when selecting apple and orange again"
Because I don't see in your code that you are actually updating the elements id when you calculate the total.
So... If you do:
gtot = document.getElementById("total:" + expr).value;
First time will work, because expr var is the original one, then, gtot is the right element id
but...
...when you do a second change, that var has a different value now... and gtot will not match your element id to recalculate the new value. (or in worst case, will match another and update the wrong one)
I am writing a simple cart that to handle user input before arriving at a sum that I pass off to my payment processor. I have code that works, but I'm not sure if it's the most efficient way of calculating the total. Secondly, I would like to add the possibility for a percentage discount when three of the categories are selected. I originally had a way that did a lot of checking through IF statements, but that was inefficient and there was also an unresolved issue with it. How would I go about applying a percentage discount to my preexisting code (if three of four of the item categories are >0)?
var subtotal = 0;
var veu4 = 0;
var veo4 = 0;
var vres = 0;
var vcvl = 0;
var vedb = 0;
function update_price(pin) {
quantity = parseFloat(pin.value);
var callname = pin.name;
if (callname == "item1"){
price = quantity * 50;
subtotal -= vcvl * 50;
vcvl = quantity;
}
else if (callname == "item2"){
price = quantity * 50;
subtotal -= vres * 50;
vres = quantity;
}
else if (callname == "item3"){
price = quantity * 99;
subtotal -= veu4 * 99;
veu4 = quantity;
}
else if (callname == "item4"){
price = quantity * 129;
subtotal -= veo4 * 129;
veo4 = quantity;
}
else{
//commented out irrelevant
}
subtotal += price;
passtotal = document.getElementById("ftotal");
total = document.getElementById("ptotal");
total.innerHTML = subtotal;
passtotal.value = subtotal;
passtotal.innerHTML = subtotal;
}
}
Your help is greatly appreciated!
Many ways to do this, but this would be a bit more DRY.
var items = {
item1: 50,
item2: 50,
item3: 99,
item4: 129
};
var cart = {};
function update_price(pin) {
quantity = parseFloat(pin.value);
var callname = pin.name;
// Get the total for this item with quantity
price = quantity * items[callname];
// Update quantity in cart
cart[callname] = {quantity: quantity, subtotal: price};
passtotal = document.getElementById("ftotal");
total = document.getElementById("ptotal");
total.innerHTML = price;
passtotal.value = price;
passtotal.innerHTML = price;
}
I think your concept of totals/subtotals is weird. It seems like your total/subtotal will always be equal to your last calculation of price * quantity. Maybe your code generated is wrong. As such mine will be slightly wrong too. To fix it, make the total equal to all of the subtotals in the cart.
As for passing this data to your server, you should pass the items that will be purchased and the quantity. On the server-sider, the subtotals and totals should be recalculated. I added your cart variable to help with this. Just serialize this data and send it over to your server processing. Do not take the value of ftotal or ptotal to be accurate when you actually charge the user.