Using REPT() with Decimals - javascript

I was wondering about being able to use/make a function like REPT() to display partial repetitions with decimal numbers. My formula, as it stands, works fine for integers. If I wanted to give 3 stars, I just use =REPT(CHAR(9733), 3) and that prints 3 black stars.
Let's say I wanted to give something 4.2 stars. Is there a way to do something like this? I've been trying to figure out a way to do it with App Script, but I'm not sure how to proceed. Everything I've researched online is geared towards making a clickable rating system with HTML/CSS/JavaScript. But I'd be looking more for something like an average rating on Amazon or something.
This is what I have with App Script so far:
function starRating() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('test');
var cell = sheet.getRange(2,1); // Sets a test cell
// Create a concatenated string of 5 blank stars
var blankStars = "";
for (let i = 0; i < 5; i++) {
blankStars = blankStars.concat(String.fromCharCode(9734));
}
// Create a concatenated string of 5 black stars
var blackStars = "";
for (let i = 0; i < 5; i++) {
blackStars = blackStars.concat(String.fromCharCode(9733));
}
cell.setValue(blankStars);
cell.setHorizontalAlignment("center")
cell.setFontSize(18);
var rating = sheet.getRange(1,1).getValue(); // Raw Rating (e.g. 4.3)
var amount = Math.max(0, (Math.min(5, rating))) * 20; // Gets percent out of 100, also ensures rating is from 0-5
/*
Maybe find a way to overlay the blackStar on top of blankStar?
Use amount as a way of only showing percent of blackStar?
*/
}
As I put in the comment, my thought was to overlay a percent of the blackStar string on top of the blankStar string, but 1. I don't know how to do that and 2. I don't know how that could be put into the cell.

This is fairly close and a lot easier
function stars(n = 9) {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet0");
const style = SpreadsheetApp.newTextStyle().setForegroundColor("#000000").setFontSize(16).build();
let s = "";
Array.from(new Array(10).keys()).forEach(x => s = s.concat(String.fromCharCode(x < n ? 9733 : 9734)));
sh.getRange(3, 1).setValue(s).setTextStyle(style);
}

Related

How to write a script, which when ran increments the number by 1?

I am looking to write a script in windows which when the user clicks on it increments the count by 1.
The script has a variable integer 000000
Another variable string number
When the user clicks on the script from their desktop it increments the integer to 000001 and appendes in front of number so it becomes number000001 and when user next clicks it increases to number000002 and so on.
I am sure it's a simple script but I am not sure where to begin or which language to use, it'll be great if someone can help me out
I think it would be something along the lines of, but not really sure what I am doing, how to save the increment from last run, how to run trigger the script when the icon is clicked from desktop.
Integer = 000000
String = "Number"
Integer++
IntegerString = Number+Integer
Thanks.
did you need this 00000 before 1,2,3 and etc?
try this one:
let i = 0;
const s = 'Number';
const intString = s + format(i++);
and formatter for number:
function format(num) {
let strNum = num.toString();
const numSize = strNum.length;
for(i = numSize; i < 6; i++) {
strNum = 0 + strNum;
}
}
Take a look at this probably solves your problem
let dv = "000000";
document.querySelector('button').addEventListener('click', () => {
let increment = ++dv;
increment = ("000000" + increment).slice(-6);
document.querySelector('span').innerText = increment
})
<button>increment</button>
<h1>number<span>000000</span></h1>

Google Apps Script random string generating

i am new to Google apps script, i want to create string of random characters in the code given below in variable body2.
function myfunction() {
var files = DriveApp.getFiles();
while (files.hasNext(`enter code here`)) {
Logger.log(files.next().getName());
}
var recipient = Session.getActiveUser().getEmail();
var subject = 'A list of files in your Google Drive';
var body1 = Logger.getLog();
var body2;
for(var i=0;i<6;i++)
{
body2[i]=BigNumber.tostring("Math.floor(Math.random()*11)");
}
body=body1+body2;
MailApp.sendEmail(recipient, subject, body);
};
but when i run this function, it says "TypeError: Cannot find function tostring in object 0. (line 12, file "Code") " i can't understand how to solve this error?
Why we have to multiply random by 11 , can it be multiplied with any integer number?
what if i want that string in only capital letters.!
Some other question
1) i don't have enough knowledge of JavaScript, is it good to learn GAS directly?
2) i can't find proper written material or documentation for GAS , the material available at Google's official site is seems to be updating time by time , what to do then ? any link to material would help me .!
I guess I just figured
function randomStr(m) {
var m = m || 15; s = '', r = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (var i=0; i < m; i++) { s += r.charAt(Math.floor(Math.random()*r.length)); }
return s;
};
Hope someone finds it helpful.
As for a random string use this its better:
Math.random().toString(36). 36 is the base thus will use letters and numbers in the string.
As for gas documentation, the official page is pretty complete. It changes because it constantly improves and adds new services.
I have this charIdGeneration() in my GAS library
function charIdGenerator()
{
var charId ="";
for (var i = 1; i < 10 ; i++)
{
charId += String.fromCharCode(97 + Math.random()*10);
}
//Logger.log(charId)
return charId;
}

How to do parellel arrays with following information

For this question, it might be a little vague, because i just dont understand it at all, its probably the wording.. from what i learn in class it seems a lot harder. So im lost as to where to begin.. if someone can help walk me through it easier i would appreciate it!
Question: Design a Program that will read the same parts inventory file described in the problem 6. the parts are: (Record code, part number, part description, and inventory balance) validate the record code and part number on each record, and print the details of all valid records whose part numbers fall within the value AA3000 and AA3999 inclusive. Also print a count of these selected records at the end of the parts listing.
Now, i hope you can understand what its asking because i sure dont. Any help or a small walk through would be awesome. This is the code i am supposed to start out from that was given to me.
var Rec_Code = new Array(11,11,11,12,11,12,11,13,11,14);
var Numer = new Array(2000,3000,3003,3008,3999,2000,1090,3678,3777,3543);
var Alpha = new Array("AA","AA","AX","AA","AA","AA","AB","AA","AN","AA");
var Desc = new Array("X","L","S","F","R","U","T","N","Q","Y");
var Inv_Bal = new Array(12,13,14,23,34,56,32,45,67,77);
also, this was given to me, which is basically what i have to do, but dont know how to completely do it.
use the vars that I provided to create 5 parallel arrays, RecCode, AlphaPart of part number, Numeric part of the part number,Description and Inventory. You need to search the first 3 arrays for:
RecCode of 11
AlphaCode of 'AA':
Numeric Code betweewn 3000 - 3999 inclusive
when you find a match increment a count and display the Description and Inventory.
Assuming that all arrays are the same length and sorted appropriately, you can loop over one and display the information you need:
var count = 0;
for(var i = 0; i < Rec_Code.length; i++)
{
if(Rec_Code[i] == 11 && Alpha[i] == 'AA' && (Numer[i] >= 3000 && Numer[i] <= 3999))
{
console.log(Desc[i]);
console.log(Inv_Bal[i]);
count++;
}
}
var Rec_Code = new Array(11,11,11,12,11,12,11,13,11,14);
var Numer = new Array(2000,3000,3003,3008,3999,2000,1090,3678,3777,3543);
var Alpha = new Array("AA","AA","AX","AA","AA","AA","AB","AA","AN","AA");
var Desc = new Array("X","L","S","F","R","U","T","N","Q","Y");
var Inv_Bal = new Array(12,13,14,23,34,56,32,45,67,77);
var count = 0;
for(var i = 0; i < Rec_Code.length; i++)
{
if(Rec_Code[i] == 11 && Alpha[i] == 'AA' && (Numer[i] >= 3000 && Numer[i] <= 3999))
{
console.log(Desc[i]);
console.log(Inv_Bal[i]);
count++;
}
}

Improving speed and data efficiency with javascript calculator.

I'm building a javascript calculator (with jquery mobile) for simplifying routine calculations in microscopy. I'm looking to create more efficient code and would love any input... I don't expect anyone to dig through the whole thing, but here is the link to the program for reference: http://www.iscopecalc.com
(the javascript for the calculator is at http://www.iscopecalc.com/js/calc.js )
The calculator basically consists of about 12 inputs that the user can set. Using the values received from these inputs, the calculator generates values for about 15 different parameters and outputs the results in the display. Currently, whenever the state of an input changes, I bind that change event to a quick function that writes the value for that input to a cookie. But the meat of the program comes with the "updateCalc()" function which reads the values from all of the inputs (from stored cookies) and then recalculates every one of the parameters to be displayed and outputs them. I've coped just that function here for ease of access:
function updateCalc(){
readValues(); //load current calculator state into cookies
var data = $.cookie(); //puts all cookie data into object
var fluorData = fluoroTable[data['fluorophore']]; //fluorophore data taken from table at the end of the file depending on chosen fluorophore
var fluorem = fluorData['fluorem'];
var fluorex = fluorData['fluorex'];
var cameraData = cameraTable[data['camera']]; //camera data taken from table at the end of the file depending on chosen camera
var campix = cameraData['campix'];
var chipWidth = cameraData['chipWidth'];
var chipHeight = cameraData['chipHeight'];
var chipHpix = cameraData['chipHpix'];
var chipVpix = cameraData['chipVpix'];
var RefInd = data['media']; //simple variables taken directly from calculator inputs
var NA = data['NAslider'];
var obj = data['objective'];
var cammag = data['cameraRelay'];
var CSUmag = data['CSUrelay'];
var bin = data['binning'];
var pinholeRad;
var FOVlimit;
var mode;
if (data['modality']=='widefield'){ //FOVlimit, pinholeRad, and CSU mag will all depend on which modality is chosen
FOVlimit = 28;
pinholeRad = NaN;
mode = 'Widefield';
CSUmag = 1;
}
else if (data['modality']=='confocal'){
if (data['CSUmodel']=='X1'){
pinholeRad = 25;
if(data['borealis']=='true'){
mode = "Borealis CSU-X1";
FOVlimit = 9;
}
else {
mode = "Yokogawa CSU-X1";
FOVlimit = 7;
CSUmag = 1;
}
}
else if (data['CSUmodel']=='W1'){
mode = "Yokogawa CSU-W1";
FOVlimit = 16;
pinholeRad = data['W1-disk']/2;
CSUmag = 1;
}
}
//These are main outputs and they depend on the input variables above
var latRes = 0.61 * fluorem / NA;
var axRes = 1.4 * fluorem * RefInd / (NA*NA);
var BPpinhole = 1000 * pinholeRad / (obj * CSUmag);
var AU = BPpinhole / latRes;
var totalMag = obj * cammag * CSUmag;
var BPpixel = 1000 * campix * bin / totalMag;
var samples = latRes / BPpixel;
var pixperpin = BPpinhole * 2 / BPpixel;
var sampLit = 1000 * FOVlimit / (obj * CSUmag);
var coverage = FOVlimit * cammag / chipHeight;
if (coverage < 1) {
chipUsed = coverage;
FOV = sampLit;
}
else {
chipUsed = 1;
FOV = sampLit * chipHeight / (FOVlimit * cammag);
}
var sampWaste = 1 - FOV / sampLit;
var imgpix = 1000 * FOV / (chipVpix / bin);
//function goes on to update display with calculated values...
}
It works ok and I'm generally pleased with the results but here's what I'd like advice on:
Each of the input variables only really affects a handful of the outputs (for instance, a change in input #3 would only really change the calculation for a few of the outputs... not all 15), however, my function recalculates ALL outputs everytime ANY of the inputs are changed, regardless of relevance... I've considered making a giant If-Then function that would selectively update only the outputs that would have changed based on the input that was changed. This would obviously take a larger amount of code, but I'm wondering if (once loaded) the code would be faster when using the calculator, of if it would just be a waste of my time and clutter up my code.
I'm also wondering if storing inputs in cookies and reading values back from cookies is a reasonable way to do things and if I should maybe make a global variable instead that stores the state of the calculator. (the cookies have the added benefit of storing the users calculator state for later visits).
I'm pretty new at this stuff, so any and all comments on how I might improve the efficiency of my code would be greatly appreciated (feel free to just link to a page that I should read, or a method I should be using for instance...)
if you've made it this far, thanks for your time!!

Split an IP address into Octets, then do some math on each of the Octets

I actually have this working, but its very ugly, and its keeping me awake at night trying to come up with an eloquent piece of code to accomplish it.
I need to take a series of strings representing IP Ranges and determine how many actual IP address that string would represent. My approach has been to split that into 4 octets, then attempt to split each octet and do the math from there.
e.g.: 1.2.3.4-6 represents 1.2.3.4, 1.2.3.5, and 1.2.3.6, thus I want to get the answer of 3 from this range.
To further complicate it, the string I'm starting with can be a list of such ranges from a text box, separated by newlines, so I need to look at each line individually, get the count of represented IP address, and finally, how many of the submitted ranges have this condition.
1.1.1.4-6 /* Represents 3 actual IP Addresses, need to know "3" */
2.2.3-10.255 /* Represents 8 actual IP Addresses, need to know "8" */
3.3.3.3 /* No ranges specified, skip this
4.4.4.4 /* No ranges specified, skip this
Net result is that I want to know is that 2 lines contained a "range", which represent 8 IP addresses (3+8)
Any eloquent solutions would be appreciated by my sleep schedule. :
)
There you go:
var ips = ["1.2.3.4", "2.3.4-6.7", "1.2.3.4-12"];
for(var i=0; i<ips.length; i++) {
var num = 1;
var ip = ips[i];
var parts = ip.split('.');
for(var j=0; j<parts.length; j++) {
var part = parts[j];
if(/-/.test(part)) {
var range = part.split('-');
num *= parseInt(range[1]) - parseInt(range[0]) + 1;
}
}
alert(ip + " has " + num + " ips.");
}​
This code also handles ranges like 1.2.3-4.0-255 correctly (i.e. 256*2=512 ips in that range). The list items that have no ranges yield a total of 1 ips, and you can ignore them based on the resulting num if you don't need them.
You'll probably need to slightly modify my example, but I'm confident you won't have any trouble in doing so.
Ok, this is how I would do it
var addr = '1.1.3-10.4-6';
function getNumAddresses(input) {
var chunks = input.split('.');
var result = 1;
for (var i = 0; i < 4; i++) {
if (chunks[i].indexOf('-') != -1) {
var range = chunks[i].split('-');
result *= parseInt(range[1]) - parseInt(range[0]) + 1;
}
}
return result;
}
alert(getNumAddresses(addr));

Categories