Insert commas into string number - string

I have this code, and I want to put commas.
I've seen many examples, but I dont now were put the code.
This is my AS3 code:
calccn.addEventListener(MouseEvent.CLICK,result1);
function result1(e:MouseEvent)
{
var vev: Number = (Number(vev.text));
var cn1: Number = (Number(3/100));
var result1f: Number = (Number(vev*cn1));
var round;
round=result1f.toFixed(0);
v3.text = String(round);
}
Example
If the result give me 1528000,32
I want that the result is 1.528.000 or 1 528 000

I didn't know (live and learn, eh), but there's actually a dedicated class: NumberFormatter.
If you want to do the thing on a regular basis, you might want a method to call:
// Implementation.
import flash.globalization.NumberFormatter;
// The default separator is comma.
function formattedNumber(value:Number, separator:String = ","):String
{
var NF:NumberFormatter;
NF = new NumberFormatter("en_US");
// Enforce the use of the given separator.
NF.groupingSeparator = separator;
// Ignore the fraction part.
NF.fractionalDigits = 0;
return NF.formatNumber(value);
}
// Usage.
//Format the given number with spaces for separator.
trace(formattedNumber(1528000.32, " ")); // 1 528 000
//Format the given number with the default separator.
trace(formattedNumber(1528000.32)); // 1,528,000
But if you want just a simple one-timer, and don't really care if it is commas or spaces as long as they present you may just condense in into a single expression:
calccn.addEventListener(MouseEvent.CLICK, result1);
function result1(e:MouseEvent):void
{
// Declaring variables with the same names as
// other entities is a generally bad idea.
var input:Number = Number(vev.text);
var cn1:Number = 3.0 / 100.0;
// Keep in mind that I used int() here as
// a simple tool to remove the fraction part.
v3.text = (new NumberFormatter("en_US")).formatNumber(int(input * cn1));
}

Related

How can I switch from operator to another operator?

I'm making a program that can understands human words, and so far it's going great.
My current standpoint is understanding math equations. You can add, subtract, multiply and divide very easily with as many numbers as you'd like, but I'm wondering how I can do addition then multiply the result, like this:
const source = require("./source.js")
var main = source.interpret(
"add 4 and 4 multiply by 4",
)
source.output(main)
And it should output:
64
Yes I know that there is an easier way of doing this math equation, however in any calculator of any sort you should be able to this kind of switching in any context.
How can I accomplish this?
Here is the full source code;
index.js:
const source = require("./source.js")
var main = source.interpret(
"add 4 and 4 together then multiply the result by 4",
)
source.output(main)
source.js:
function output(main) {
console.log(main)
}
function interpret(str) {
const dl = str.split(' ');
const operator = dl.shift(x => x.includes("add", "subtract", "multiply", "divide"))
const numbers = dl.filter(x => Number(x))
switch (operator) {
case "add":
return numbers.reduce((a, b) => Number(a) + Number(b));
case "subtract":
return numbers.reduce((a, b) => Number(a) - Number(b));
case "multiply":
return numbers.reduce((a, b) => Number(a) * Number(b));
case "divide":
return numbers.reduce((a, b) => Number(a) / Number(b));
}
}
module.exports = {interpret, output}
The main problem with your interpret function is that after finding a single operator, it will perform that operation on all numbers and immediately return. We can’t simply reduce all the numbers using the first operation we find, because it’s possible that some numbers are related to other operations! In the expression add 2 and 2 multiply by 3, the 3 is related to the multiply operation!
This means that we can't process the entire input like that. An alternative is to iterate over the input, and depending on the operator we find, we perform the related action.
To simplify, let's consider that there's only the add operation. What are we expecting next? It could be [number] and [number], but also, it can be by [number]. The first one just adds the two numbers, but in the second, it should add the new number to the last operation.
A side note: your shift and filter functions are parsing the input, and the switch case is interpreting the parsed structure. Your “human language” is actually a programming language! add 2 and 2 is analogous to 2 + 2 in JavaScript, just different. With that, I will introduce you to some programming language theory terms, it can be easier to search for more help if you deep dive in the topic.
Considering the last paragraph, let's refactor interpret:
// from https://stackoverflow.com/questions/175739/how-can-i-check-if-a-string-is-a-valid-number
function isNumeric(str) {
if (typeof str != "string") return false
return !isNaN(str) && !isNaN(parseFloat(str))
}
function interpret(input) {
const tokens = input.split(' ') // in fancy programming language terms,
// this is a lexical analysis step
// note that we are not supporting things like
// double spaces, something to think about!
let state = 0 // we are keeping the results from our operation here
for (i = 0; i < tokens.length; i++) {
const t = tokens[i] // to keep things shorter
switch (t) {
case "add": // remember: there's two possible uses of this operator
const next = tokens[i + 1]
if (next == "by") {
// we should add the next token (hopefully a number!) to the state
state += parseFloat(tokens[i + 2])
i += 2 // very important! the two tokens we read should be skipped
// by the loop. they were "consumed".
continue // stop processing. we are done with this operation
}
if (isNumeric(next)) {
const a = tokens[i + 2] // this should be the "and"
if (a != "and") {
throw new Error(`expected "and" token, got: ${a}`)
}
const b = parseFloat(tokens[i + 3])
state = parseFloat(next) + b
i += 3 // in this case, we are consuming more tokens
continue
}
throw new Error(`unexpected token: ${next}`)
}
}
return state
}
const input = `add 2 and 2 add by 2 add by 5`
console.log(interpret(input))
There's a lot to improve from this code, but hopefully, you can get an idea or two. One thing to note is that all your operations are "binary operations": they always take two operands. So all that checking and extracting depending if it's by [number] or a [number] and [number] expression is not specific to add, but all operations. There's many ways to write this, you could have a binary_op function, I will go for possibly the least maintainable option:
// from https://stackoverflow.com/questions/175739/how-can-i-check-if-a-string-is-a-valid-number
function isNumeric(str) {
if (typeof str != "string") return false
return !isNaN(str) && !isNaN(parseFloat(str))
}
function isOperand(token) {
const ops = ["add", "multiply"]
if (ops.includes(token)) {
return true
}
return false
}
function interpret(input) {
const tokens = input.split(' ') // in fancy programming language terms,
// this is a lexical analysis step
// note that we are not supporting things like
// double spaces, something to think about!
let state = 0 // we are keeping the results from our operation here
for (i = 0; i < tokens.length; i++) {
const t = tokens[i] // to keep things shorter
if (!isOperand(t)) {
throw new Error(`expected operand token, got: ${t}`)
}
// all operators are binary, so these variables will hold the operands
// they may be two numbers, or a number and the internal state
let a, b;
const next = tokens[i + 1]
if (next == "by") {
// we should add the next token (hopefully a number!) to the state
a = state
b = parseFloat(tokens[i + 2])
i += 2 // very important! the two tokens we read should be skipped
// by the loop. they were "consumed".
}
else if (isNumeric(next)) {
const and = tokens[i + 2] // this should be the "and"
if (and != "and") {
throw new Error(`expected "and" token, got: ${and}`)
}
a = parseFloat(next)
b = parseFloat(tokens[i + 3])
i += 3 // in this case, we are consuming more tokens
} else {
throw new Error(`unexpected token: ${next}`)
}
switch (t) {
case "add":
state = a + b
break;
case "multiply":
state = a * b
}
}
return state
}
const input = `add 2 and 2 add by 1 multiply by 5`
console.log(interpret(input)) // should log 25
There's much more to explore. We are writing a "single-pass" interpreter, where the parsing and the interpreting are tied together. You can split these two, and have a parsing function that turns the input into a structure that you can then interpret. Another point is precedence, we are applying the operation in the order they appear in the expression, but in math, multiplication should be done first than addition. All of these problems are programming language problems.
If you are interested, I deeply recommend the book http://craftinginterpreters.com/ for a gentle introduction on writing programming languages, it will definitely help in your endeavor.

How do I generate a string that contains a keyword?

I'm currently making a program with many functions that utilise Math.rand(). I'm trying to generate a string with a given keyword (in this case, lathe). I want the program to log a string that has "lathe" (or any version of it, with capitals or not), but everything I've tried has the program hit its call stack size limit (I understand exactly why, I want the program to generate a string with the word without it hitting its call stack size).
What I have tried:
function generateStringWithKeyword(randNum: number) {
const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/";
let result = "";
for(let i = 0; i < randNum; i++) {
result += chars[Math.floor(Math.random() * chars.length)];
if(result.includes("lathe")) {
continue;
} else {
generateStringWithKeyword(randNum);
}
}
console.log(result);
}
This is what I have now, after doing brief research on stackoverflow I learned that it might have been better to add the if/else block with a continue, rather than using
if(!result.includes("lathe")) return generateStringWithKeyword(randNum);
But both ways I had hit the call stack size limit.
A "correct" version of your algorithm, written as an iterative function instead of as a recursive one so as not to exceed stack depth, would look something like this:
function generateStringWithKeyword(randNum: number) {
const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/";
let result = "";
let attemptCnt = 0;
while (!result.toLowerCase().includes("lathe")) {
attemptCnt++;
result = "";
for (let i = 0; i < randNum; i++) {
result += chars[Math.floor(Math.random() * chars.length)];
}
if (attemptCnt > 1e6) {
console.log("I GIVE UP");
return;
}
}
console.log(result);
return result;
}
I don't like when my browser hangs because of a script that won't finish, so I put a maximum attempt count in there. A million chances seems reasonable. When you try it out, this happens:
generateStringWithKeyword(10); // I GIVE UP
Which makes sense; let's perform a rough back-of-the-envelope probability calculation to see how long we might expect this to take. The chance that "lathe" will appear in some case at position 1 of the word is (2/64)×(2/64)×(2×64)×(2/64)×(2/64) ("L" or "l" appears first, followed by "A" or "a", etc) which is approximately 3×10-8. For a word of length 10, "lathe" can appear starting at positions 1, 2, 3, 4, 5, or 6. While this isn't exactly correct, let's think of this as multiplying your chances by 6 of getting the word somewhere, so the actual chance of getting a valid result is somewhere around 1.8×10-7. So we can expect that you'd need to make approximately 1 ÷ 1.8×10-7 = 5.6 million chances to succeed.
Oh, darn, I only gave it a million. Let's up that to 10 million and try again:
generateStringWithKeyword(10); // "lATHELEYSc"
Great! Although, it does sometimes still give up. And really, an algorithm which needs millions of tries before it succeeds is very, very inefficient. You might want to read about bogosort, a sorting algorithm which works by randomly shuffling things and checking to see if they are sorted, and it keeps trying until it works. It's used for educational purposes to highlight how such techniques don't really perform well enough to be practical. Nobody would ever want to use such an algorithm for real.
So how would you do this "the right" way? Well, my suggestion here is to just build your result correctly the first time. If you have 10 characters and 5 of them need to be "lathe" in some case, then you will need 5 truly random characters. So randomly decide how many of those letters should be before "lathe". If you pick 2, for example, then put 2 random characters, plus "lathe" in a random case, plus 3 more random characters.
It could be something like this, where I mostly use your same style of for-loops and += string concatenation:
function generateStringWithKeyword(randNum: number) {
const keyword = "lathe";
if (randNum < keyword.length) throw new Error(
"This is not possible; \"" + keyword + "\" doesn't fit in " + randNum + " characters"
);
const actuallyRandNum = randNum - keyword.length;
const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/";
let result = "";
const kwInsertionPoint = Math.floor(Math.random() * (actuallyRandNum + 1));
for (let i = 0; i < kwInsertionPoint; i++) {
result += chars[Math.floor(Math.random() * chars.length)];
}
for (let i = 0; i < keyword.length; i++) {
result += Math.random() < 0.5 ? keyword[i].toLowerCase() : keyword[i].toUpperCase();
}
for (let i = kwInsertionPoint; i < actuallyRandNum; i++) {
result += chars[Math.floor(Math.random() * chars.length)];
}
return result;
}
If you run this, you will see that it is very efficient, and never gives up:
console.log(Array.from({ length: 4 }, () => generateStringWithKeyword(5)).join(" "));
// "lathE LaThe lATHe LatHe"
console.log(Array.from({ length: 4 }, () => generateStringWithKeyword(7)).join(" "));
// "p6lAtHe laThE01 nlaTheK lATHeRJ"
console.log(Array.from({ length: 4 }, () => generateStringWithKeyword(10)).join(" "));
// "giMqzLaTHe 5klAthegBo oVdLatHe0q twNlATheCr"
Playground link to code

dart efficient string processing techniques?

I strings in the format of name:key:dataLength:data and these strings can often be chained together. for example "aNum:n:4:9879aBool:b:1:taString:s:2:Hi" this would map to an object something like:
{
aNum: 9879,
aBool: true,
aString: "Hi"
}
I have a method for parsing a string in this format but I'm not sure whether it's use of substring is the most efficient way of pprocessing the string, is there a more efficient way of processing strings in this fashion (repeatedly chopping off the front section):
Map<string, dynamic> fromString(String s){
Map<String, dynamic> _internal = new Map();
int start = 0;
while(start < s.length){
int end;
List<String> parts = new List<String>(); //0 is name, 1 is key, 2 is data length, 3 is data
for(var i = 0; i < 4; i++){
end = i < 3 ? s.indexOf(':') : num.parse(parts[2]);
parts[i] = s.substring(start, end);
start = i < 3 ? end + 1 : end;
}
var tranType = _tranTypesByKey[parts[1]]; //this is just a map to an object which has a function that can convert the data section of the string into an object
_internal[parts[0]] = tranType._fromStr(parts[3]);
}
return _internal;
}
I would try s.split(':') and process the resulting list.
If you do a lot of such operations you should consider creating benchmarks tests, try different techniques and compare them.
If you would still need this line
s = i < 3 ? s.substring(idx + 1) : s.substring(idx);
I would avoid creating a new substring in each iteration but instead just keep track of the next position.
You have to decide how important performance is relative to readability and maintainability of the code.
That said, you should not be cutting off the head of the string repeatedly. That is guaranteed to be inefficient - it'll take time that is quadratic in the number of records in your string, just creating those tail strings.
For parsing each field, you can avoid doing substrings on the length and type fields. For the length field, you can build the number yourself:
int index = ...;
// index points to first digit of length.
int length = 0;
int charCode = source.codeUnitAt(index++);
while (charCode != CHAR_COLON) {
length = 10 * length + charCode - 0x30;
charCode = source.codeUnitAt(index++);
}
// index points to the first character of content.
Since lengths are usually small integers (less than 2<<31), this is likely to be more efficient than creating a substring and calling int.parse.
The type field is a single ASCII character, so you could use codeUnitAt to get its ASCII value instead of creating a single-character string (and then your content interpretation lookup will need to switch on character code instead of character string).
For parsing content, you could pass the source string, start index and length instead of creating a substring. Then the boolean parser can also just read the code unit instead of the singleton character string, the string parser can just make the substring, and the number parser will likely have to make a substring too and call double.parse.
It would be convenient if Dart had a double.parseSubstring(source, [int from = 0, int to]) that could parse a substring as a double without creating the substring.

How to split a string without specifying any separator in asp.net with C#?

I have a string with 1000 length. I need to split it and assign it to different controls. I do not have any character separator.
Since each string that I am assigning to controls do not contain same length. As of now I am doing it using substring in which i am specifying the length. But its becoming hectic for me as the length is huge.
Please suggest me is there any way to split and assign in simpler way?
You can use this string constructor:
var input = "Some 1000 character long string ...";
var inputChars = input.ToCharArray();
control1.Value = new string(inputChars, 0, 100); // chars 0-100 of input
control2.Value = new string(inputChars, 100, 20); // chars 100-120 of input
control3.Value = new string(inputChars, 120, 50); // chars 120-170 of input
...
Or using Substring:
var input = "Some 1000 character long string ...";
control1.Value = input.Substring(0, 100); // chars 0-100 of input
control2.Value = input.Substring(100, 20); // chars 100-120 of input
control3.Value = input.Substring(120, 50); // chars 120-170 of input
You could also do this
var parts = new []
{
Tuple.Create(0, 100),
Tuple.Create(100, 20),
Tuple.Create(120, 50),
}
var inputParts = parts.Select(p => input.Substring(p.Item1, p.Item2))
.ToArray();
control1.Value = inputParts[0];
control2.Value = inputParts[1];
control3.Value = inputParts[3];
This makes it much easier to maintain as the number of controls grows larger. You can store this list of 'parts' statically, so it can be reused elsewhere in your application without duplicating the code.
If all the controls the same type, you can do this:
var parts = new []
{
new { control = control1, offset = 0, length = 100 },
new { control = control2, offset = 100, length = 20 },
new { control = control3, offset = 120, length = 50 },
}
foreach(var part in parts)
{
part.control.Value = new string(inputChars, part.offset, offset.length);
// or part.control.Value = input.Substring(part.offset, offset.length);
}
You won't get around specifying the information which control gets which part of the string. Once you have this information (let's say they are stored in a control array controls and int array length), you can just loop over the string and do a piecewise Substring:
var controls = { control1, control2, control3, ... };
var lengths = { 100, 20, 5, ... };
int offset = 0;
for (int i = 0; i < controls.length; i++) {
controls[i].Value = myLongString.Substring(offset, lengths[i]);
offset += lengths[i];
}
Obviously, this will fail horribly if myLongString is shorter than the sum of all lengths or the array length of lengths is shorter than the one of controls, but adding some checks for that and throwing a suitable error is left as an exercise to the reader. In addition, the controls must be compatible in the sense that they all derive from the same base class with a common Value property. If that is not the case, you might have to do a few type checks and casts inside the loop.

Grabbing text from webpage and storing as variable

On the webpage
http://services.runescape.com/m=itemdb_rs/Armadyl_chaps/viewitem.ws?obj=19463
It lists prices for a particular item in a game, I wanted to grab the "Current guide price:" of said item, and store it as a variable so I could output it in a google spreadsheet. I only want the number, currently it is "643.8k", but I am not sure how to grab specific text like that.
Since the number is in "k" form, that means I can't graph it, It would have to be something like 643,800 to make it graphable. I have a formula for it, and my second question would be to know if it's possible to use a formula on the number pulled, then store that as the final output?
-EDIT-
This is what I have so far and it's not working not sure why.
function pullRuneScape() {
var page = UrlFetchApp.fetch("http://services.runescape.com/m=itemdb_rs/Armadyl_chaps/viewitem.ws?obj=19463").getContentText();
var number = page.match(/Current guide price:<\/th>\n(\d*)/)[1];
SpreadsheetApp.getActive().getSheetByName('RuneScape').appendRow([new Date(), number]);
}
Your regex is wrong. I tested this one successfully:
var number = page.match(/Current guide price:<\/th>\s*<td>([^<]*)<\/td>/m)[1];
What it does:
Current guide price:<\/th> find Current guide price: and closing td tag
\s*<td> allow whitespace between tags, find opening td tag
([^<]*) build a group and match everything except this char <
<\/td> match the closing td tag
/m match multiline
Use UrlFetch to get the page [1]. That'll return an HTTPResponse that you can read with GetBlob [2]. Once you have the text you can use regular expressions. In this case just search for 'Current guide price:' and then read the next row. As to remove the 'k' you can just replace with reg ex like this:
'123k'.replace(/k/g,'')
Will return just '123'.
https://developers.google.com/apps-script/reference/url-fetch/
https://developers.google.com/apps-script/reference/url-fetch/http-response
Obviously, you are not getting anything because the regexp is wrong. I'm no regexp expert but I was able to extract the number using basic string manipulation
var page = UrlFetchApp.fetch("http://services.runescape.com/m=itemdb_rs/Armadyl_chaps/viewitem.ws?obj=19463").getContentText();
var TD = "<td>";
var start = page.indexOf('Current guide price');
start = page.indexOf(TD, start);
var end = page.indexOf('</td>',start);
var number = page.substring (start + TD.length , end);
Logger.log(number);
Then, I wrote a function to convert k,m etc. to the corresponding multiplying factors.
function getMultiplyingFactor(symbol){
switch(symbol){
case 'k':
case 'K':
return 1000;
case 'm':
case 'M':
return 1000 * 1000;
case 'g':
case 'G':
return 1000 * 1000 * 1000;
default:
return 1;
}
}
Finally, tie the two together
function pullRuneScape() {
var page = UrlFetchApp.fetch("http://services.runescape.com/m=itemdb_rs/Armadyl_chaps/viewitem.ws?obj=19463").getContentText();
var TD = "<td>";
var start = page.indexOf('Current guide price');
start = page.indexOf(TD, start);
var end = page.indexOf('</td>',start);
var number = page.substring (start + TD.length , end);
Logger.log(number);
var numericPart = number.substring(0, number.length -1);
var multiplierSymbol = number.substring(number.length -1 , number.length);
var multiplier = getMultiplyingFactor(multiplierSymbol);
var fullNumber = multiplier == 1 ? number : numericPart * multiplier;
Logger.log(fullNumber);
}
Certainly, not the optimal way of doing things but it works.
Basically I parse the html page as you did (with corrected regex) and split the string into number part and multiplicator (k = 1000). Finally I return the extracted number. This function can be used in Google Docs.
function pullRuneScape() {
var pageContent = UrlFetchApp.fetch("http://services.runescape.com/m=itemdb_rs/Armadyl_chaps/viewitem.ws?obj=19463").getContentText();
var matched = pageContent.match(/Current guide price:<.th>\n<td>(\d+\.*\d*)([k]{0,1})/);
var numberAsString = matched[1];
var multiplier = "";
if (matched.length == 3) {
multiplier = matched[2];
}
number = convertNumber(numberAsString, multiplier);
return number;
}
function convertNumber(numberAsString, multiplier) {
var number = Number(numberAsString);
if (multiplier == 'k') {
number *= 1000;
}
return number;
}

Resources