I must avoid entering letters on my digipas - javascript

I have a small problem. When I enter a new transfert of 269 euros with the account bank number BE072750044-35066. I have to introduce a code of confirmation. The code is 350269.
The figures 350 are the last 5 figures of the bank account number -> BE072750044-35066.
And the 269 represents the amount for the new transfert.
Another example, if the new transfert was of 350 euros. We will have 350350.
Now my problem, if I have an account bank with a letter at the end. FR5940802053780006178110K61.
The problem is that I retrieve 10K269, but the user must enter only numbers on the digipas.
How to avoid this problem for the user, please?
getTokenTwoAdd(nt) {
var partOne, partTwo, absoluteAmount;
partOne = (nt.iban.substr(nt.iban.length - 5)).substring(0, 3);
absoluteAmount = Math.abs(nt.amount);
absoluteAmount = parseInt(absoluteAmount);
partTwo = ((absoluteAmount < 100) ? this.helpers.addLeadingZeroesLeft(absoluteAmount, 3) : absoluteAmount) + "";
partTwo = partTwo.substring(0, 3);
console.log("Iban number, slice => " + partOne);
console.log("Iban number => " + nt.iban);
console.log("Amount => " + absoluteAmount);
return partOne + partTwo;
}
The variable partOne represents the account bank number with the slice
The variable nt.iban is the accout bank number
The variable absoluteAmount is the amount for the new transfert

To get rid of any characters that are not digits, you could use
partOne = nt.iban.replace(/\D+/g, '').substr(-5, 3);
where \D+ matches one or more non-digit characters.

Related

Random number generator for my discord bot in discord.js

else if (parts[0] === Prefix + 'number') {
message.channel.send(message.author.username + ' What is the minimum number');
if (parts[0] === Math.int) {
var MinNum = (Discord.Message);
console.log("minimum number is " + MinNum);
message.channel.send(message.author.username + ' what is the maximum number');
} if (parts[0] === Math.int) {
var MaxNum = (Discord.Message);
console.log("Maximum number is " + MaxNum);
const RandomNum = Random.int(MinNum, MaxNum);
message.channel.send(Message.author.username + " number is " + RandomNum);
} else if (parts[0] === Math.int == false) {
message.channel.send("Sorry " + message.author.username + " that is an invalid number");
}
}
So this is some code for a random number generator, when someone says -number, my bot asks the user what is the minimun number, when the user puts a number that number is set to the MinNum variable, and the minimun number is logged in my console. After this, it asks the user what is the maximum number, next it is suppose to do the same thing but with the maximum number, after the user inputs the maximum number the random number generator spits out a random number between those two values, and if the user does not put a number my bot says sorry (username) that is an invalid number.
I'm not sure what Math.int is, and why you think that if (parts[0] === Prefix + 'number') it will also be (parts[0] === Math.int). Unfortunately, it won't work like this. You can't accept a command and accept any follow-up messages as a response to your bot's question.
However, this is a nice use case for message collectors. First, you can send the first question and ask for the first limit. Once this message is sent, you can set up a message collector in the channel using channel.createMessageCollector.
It accepts a filter and an options object. With the filter you can check if the incoming message is from the author who typed the command and if their response is a valid number.
createMessageCollector returns a MessageCollector, so you can subscribe to the collect and end events.
The collect event is emitted whenever a message is collected. If this is the first response, you can store it in an array (limits) and send a new message asking for the maximum.
Once the user sends a second valid number, the end event fires, so you can generate a random number and send it to the user. The end event also fires when the max time is reached, so you can check if the reason is the timeout and if it is, send an error message.
You could also create a helper function to generate a random integer between two numbers:
function randomInt([min, max]) {
if (min > max) {
[min, max] = [max, min];
}
return Math.floor(Math.random() * (max - min + 1) + min);
}
And here is the full code:
if (command === 'number') {
const embedMin = new MessageEmbed()
.setTitle(`🎲 Get a random number 🎲`)
.setColor('GREEN')
.setDescription('What is the minimum number?');
await message.channel.send(embedMin);
// filter checks if the response is from the author who typed the command
// and if the response is a valid number
const filter = (response) =>
response.author.id === message.author.id && !isNaN(response.content.trim());
const collector = message.channel.createMessageCollector(filter, {
// set up the max wait time the collector runs
time: 60000, // ms
// set up the max responses to collect
max: 2,
});
// it stores the user responses
const limits = [];
collector.on('collect', async (response) => {
const num = parseInt(response.content.trim(), 10);
limits.push(num);
// if this is the first number sent
if (limits.length === 1) {
const embedMax = new MessageEmbed()
.setTitle(`🎲 Get a random number 🎲`)
.setColor('GREEN')
.addField('Minimum', limits[0])
.setDescription('What is the maximum number?');
// send the next question
message.channel.send(embedMax);
}
});
// runs when either the max limit is reached or the max time
collector.on('end', (collected, reason) => {
console.log({ collected });
if (reason === 'time') {
const embedTimeout = new MessageEmbed()
.setTitle(`🎲 Get a random number 🎲`)
.setColor('RED')
.setDescription(
`I'm sorry, I haven't received a response in a minute, so I'm off now. If you need a new random number again, type \`${prefix}number\``,
);
message.channel.send(embedTimeout);
}
if (limits.length === 2) {
// get a random number
const embedRandom = new MessageEmbed()
.setTitle(`🎲 Get a random number 🎲`)
.setColor('GREEN')
.addField('Minimum', limits[0], true)
.addField('Maximum', limits[1], true)
.setDescription(`Your random number is: ${randomInt(limits)}`);
message.channel.send(embedRandom);
}
});
}

Using JS to sum a column of values from an external text file containing donation histories of a db of donors

I need some assistance figuring out how to sum a column of dynamic totals that could be a positive or negative dollar amount, or an indication of stock shares.
I have a tab-delimited text file of donor contributions for that I am matching up against a CSV file of other related customer data that I am using to create a statement letter which will show a "donation history" of a particular donor. Each donor has a different amount of donations, and to complicate things, the column of data for a particular donation record could show either "$1,000.00" or "($1,000.00)" or "2 Shares APPL". The number with the parentheticals is of course, representing a negative number.
At the end of this column, I need to show a string that will read either "Total: $1,000.00," or if any of the donation history contains a donation record that included shares of stock the returned string will simply read, "$1,000.00 & Stock."
I have been racking my brain trying to come up with the JS rule that can achieve this. I have the JS rule that is generating the donation history correctly, but summing the donation amount column is causing me to go crazy...
Here is the JS for generating my donation history list in the letter (this seems to be working fine):
var contributionList = new ExternalDataFileEx("/~wip/248839 Frontiers/Master Data/Double Data proof.txt", "\t");
var donor_id = Field("Supporter");
var lb = "<br>\n";
var matches = new Array();
for (var i = 0; i <= contributionList.recordCount; i++) {
var idVariable = contributionList.GetFieldValue(i, "Supporter");
var dateVariable = contributionList.GetFieldValue(i, "Donation Date");
var ministryVariable = contributionList.GetFieldValue(i, "Ministry Designation");
var giftVariable = contributionList.GetFieldValue(i, "Donation Amount");
var tsSettings = "<p tabstops=19550,Right,,;29600,Left,,;>";
var ts = "<t>";
if (donor_id == idVariable)
matches.push(tsSettings + dateVariable + ts + giftVariable + ts + ministryVariable);
}
//return matches;
return matches.join(lb);
Now here is the JS code that is not working just fine. I am trying to tally the donation amount column, it only returns "Total: $0.00 & Stock" every time (I have tried to explain my thought process via comments):
var contributionList = new ExternalDataFileEx("/~wip/248839 Frontiers/Master Data/Double Data proof.txt", "\t");
var donor_id = Field("Supporter");
for (var i = 0; i <= contributionList.recordCount; i++) {
var idVariable = contributionList.GetFieldValue(i, "Supporter");
var giftVariable = contributionList.GetFieldValue(i, "Donation Amount");
var sum = 0;
var shares = 0;
var tsSettings = "<p tabstops=19550,Right,,;29600,Left,,;>";
var ts = "<t>";
var totalStr = "Total ";
var stockStr = " & Stock";
var totalFormatted = FormatNumber("$#,###.00", Math.max(0, StringToNumber(sum)));
// Match data from linked file to current Supporter
if (donor_id == idVariable) {
// Look at current record and see if it contains the word "Share(s)"
// or not and act accordingly
if (giftVariable.match(/(^|\W)share($|\W)/i) || giftVariable.match(/(^|\W)shares($|\W)/i)) {
// Turn switch "on" if donation amount is a share or shares so
// we can have the " & Stock" appended to our string.
shares = 1;
// Because this donation is/are shares, we must "zero" this
// amount to make the math work when we sum everything up...
giftVariable = 0;
// This is where we are keeping our running total...
sum += giftVariable[i];
} else {
// This record was not a donation of share(s) so we now have to
// determine whether we are dealing with postive or negative numbers
// and then strip out all of the non-number characters, remove and
// replace the () whis just a "-," leaving us with a number we can
// work with...
// If number has parenthesis, then deal with it...
if (giftVariable.indexOf("(")) {
// Strip out all the ()$, characters...
giftVariable = giftVariable.replace(/[()$,]/g,"")
// Append the minus sign to the number...
giftVariable = "-" + giftVariable;
sum += giftVariable[i];
} else {
giftVariable = giftVariable.replace(/[$,]/g,"");
sum += giftVariable[i];
}
}
}
}
// Return Total...
if (shares == 1) {
return tsSettings + totalStr + ts + totalFormatted + stockStr;
} else {
return tsSettings + totalStr + ts + totalFormatted;
}
Any assistance would be greatly appreciated!
The problem (and code) needs to be broken into smaller, atomic steps. From your description it sounds like you should:
load a text file into memory
for each line in the file
extract: {
donor_id
charity
gift
and store the results in a contributions dictionary
for each item in the contributions dictionary
transform gift string into {
dollarAmount: float with a default of 0.0
stock: name with a default of ""
}
create an empty dictionary called totals
each item will have the shape {
id
dollarAmount as a float
stocks an an array
}
for each item in the contributions dictionary
lookup the id in the totals dictionary
if it exists
totals[id].dolarAmount += item.dollarAmount
totals[id].stocks.push(item.stock)
otherwise
totals[id].dollarAmount = item.dollarAmount
totals[id].stocks = [item.stock]
normalize your charities
for each item in totals dictionary
remove any empty strings from item.charities
create your report
for each item in totals dictionary
write`${item.id} donated `${item.dollarAmont}` ${item.stocks.length > 1 ? 'and stock' : ''
I believe you are trying to do too many things at once. Instead, the goal should be to normalize your data before you attempt to perform any calculations or aggrgrations, then normalize your aggregrations before writing your summaries or reports.
I would also stay away from using any direct string manipulation. You should have a dedicated function whose only purpose is to take a string like "($20.34) and 1 share of APPL" and return either 20.34, -20.34, or 0.0. And a different function whose only purpose is to take the same string and return either true or false is stock was present.

Regex to validate custom tracking information

I am working on a requirement to validate tracking information with the following restrictions:
Format: COPYYYY#####
COP is a fixed prefix of each tracking information
YYYY is a year in which the tracking information was submitted (valid years: 2015-2018)
##### is a randomly generated 5 digit number
Tracking information should only have 3 letter characters (COP prefix)
Tracking information should have exactly 9 numeric characters that follow the first 3 letter characters.
Tracking information should be exactly 12 characters long
Since regex is not great solution to validate number range, I decided to check year later once the format is valid.
COP followed by 9 digits (i.e COPXXXXXXXXX)
The regex below is always returning false, even for correct inputs.
/^COP\d{9}$/
Please suggest corrections to above regex and also share thoughts on validating year range in regex (if it is cleaner approach).
Use regex pattern \bCOP(201[5-8])(\d{5})\b
Test source code (JavaScript):
var re = /\bCOP(201[5-8])(\d{5})\b/g;
var s = 'To track your packages, enter COP201812345 and COP201867890 at www.example.org';
var m;
do {
m = re.exec(s);
if (m) {
var e = document.createElement('div');
e.innerHTML = 'Match: ' + m[0] + ' (Year: ' + m[1] + ', Id: ' + m[2] + ')';
document.getElementById("output").appendChild(e);
}
} while (m);
Test source code (Java):
String s = "To track your packages, enter COP201812345 and COP201867890 at www.example.org";
Matcher m = Pattern.compile("\\bCOP(201[5-8])(\\d{5})\\b").matcher(s);
while (m.find())
System.out.println(
"Match: " + m.group() +
" (Year: " + m.group(1) + ", Id: " + m.group(2) + ")");
}
Output:
Match: COP201812345 (Year: 2018, Id: 12345)
Match: COP201867890 (Year: 2018, Id: 67890)
Test it here (JavaScript) and here (Java).
Use the code below.
String value = "COP201812345";
Pattern p = Pattern.compile("^(COP)(201[5-8])(\\d{5})$");
Matcher m = p.matcher(value);
if (m.find()) {
System.out.println("Tracking number " + value + " is valid");
System.out.println("Tracking prefix: " + m.group(1));
System.out.println("Year between 2015 and 2018 is: " + m.group(2));
System.out.println("Random 5 digit number is: " + m.group(3));
}
else {
System.out.println("No match");
}
Output:
Tracking number COP201812345 is valid
Tracking prefix: COP
Year between 2015 and 2018 is: 2018
Random 5 digit number is: 12345

Building a Custom RNG

I am building an app for people who like to play the lottery. The app will take in data from the user such as birthdays, street addresses, license plates, lucky numbers, times, etc. The user will fill their number diary with whatever they want. I will concatenate these strings of numbers into a solo string for each user.
I then will run the following function to get the frequency of each digit 0 - 9 as it appears in the string.
var digitFreq= function(numString){
zeros = numString.split("0").length-1
ones = numString.split("1").length-1
twos = numString.split("2").length-1
threes = numString.split("3").length-1
fours = numString.split("4").length-1
fives = numString.split("5").length-1
sixes = numString.split("6").length-1
sevens = numString.split("7").length-1
eights = numString.split("8").length-1
nines = numString.split("9").length-1
numbers = numString.length;
zeroPrcnt = zeros/numbers
onePrcnt = ones/numbers
twoPrcnt = twos/numbers
threePrcnt = threes/numbers
fourPrcnt = fours/numbers
fivePrcnt = fives/numbers
sixPrcnt = sixes/numbers
sevPrcnt = sevens/numbers
eightPrcnt = eights/numbers
ninePrcnt = nines/numbers
}
This will return the frequency % of each digit in the number string. My question is how do I take these frequencies and dynamically build an RNG that uses each user's personal frequency percentages when drawing a three digit, four digit, or mega lottery number?
The user will use their RNG to generate lottery numbers to play.
You could just concatenate all entries in one string and then randomly choose a character from that string. Each number would have a probability related to the number of times it appears in the string.

Masking credit card number if a CC number entered

var cardNumber = '4761640026883566';
var cardNumberDashed = '4761-6400-1234-2345';
var cardNumberSpaced = '4761 6400 1234 3523';
var ensureOnlyNumbers = R.replace(/[^0-9]+/g, '');
var maskAllButLastFour = R.replace(/[0-9](?=([0-9]{4}))/g, '*');
var hashedCardNumber = R.compose(maskAllButLastFour, ensureOnlyNumbers);
document.body.innerHTML = hashedCardNumber(cardNumber) + '<br/>' +
hashedCardNumber(cardNumberDashed) + '<br/>' +
hashedCardNumber(cardNumberSpaced);
My situation is a bit complicated, I have a <textarea> that I use as a message field in a chat window. I want to mask all credit card numbers that was sent on this chat, but NOT every number, because I do need a membership numbers from clients which is 10-15 digits numbers.
<textarea id="postMessage"></textarea>
I followed the code in this jsfiddle: http://jsfiddle.net/7odv6kfk/ but it works only on input fields that have credit card numbers.
How can I do that?
Thank you!
http://jquerycreditcardvalidator.com/
this library may help you it can detects only credit card number and avoid other numbers
var result = $('#cardnumber').validateCreditCard({ accept: ['visa', 'mastercard'] })
Here you can find valid CC number formats and regular expressions matching them:
http://www.regular-expressions.info/creditcard.html
The problem is that old VISA cards have 13 digits, American Express have 15 digits and some JCB cards have 15 digits. This conflicts with your membership numbers. Do you need to support 16-digit CC numbers then?
The following code shows how to replace 16-digit CC numbers with asterisks:
var re = /\b(\d[ -]?){15}\d\b/g;
var text = "My CC number is 4761640026883566 (or 4761-6400-1234-2345, or 4761 6400 1234 3523). My membership number is 1234567890123."
document.body.innerHTML = text.replace(re, "****");
Output:
My CC number is **** (or ****, or ****). My membership number is 1234567890123.

Categories