I try to generate the encoding of the EAN13 barcode in order to obtain for the code 6181100327649 the following line 6BSLLAA*dchgej+
This to be able to use the EAN font and generate in my creative visuals.
Here is my code but it does not work :
function EAN(chaine) {
var i = 0;
var first = 0;
var checksum = 0;
var CodeBarre = "";
var tableA = 0;
if(chaine.match("/^\d{12}$/")){
for (i = 1; i < 12; i += 2)
{
chaine.substr(i, 1);
checksum += parseInt(chaine.substr(i, 1));
}
checksum *= 3;
for (i = 0; i < 12; i += 2)
{
checksum += parseInt(chaine.substr(i, 1));
}
chaine += (10 - checksum % 10) % 10;
CodeBarre = chaine.substr(0, 1) + (chaine.fromCharCode(65 + parseInt(chaine.substr(1, 1)) ));
first = parseInt(chaine.substr(0, 1));
for (i = 2; i <= 6; i++)
{
tableA = false;
switch (i)
{
case 2: if (first >= 0 && first <= 3) tableA = true; break;
case 3: if (first == 0 || first == 4 || first == 7 || first == 8) tableA = true; break;
case 4: if (first == 0 || first == 1 || first == 4 || first == 5 || first == 9) tableA = true; break;
case 5: if (first == 0 || first == 2 || first == 5 || first == 6 || first == 7) tableA = true; break;
case 6: if (first == 0 || first == 3 || first == 6 || first == 8 || first == 9) tableA = true; break;
}
if (tableA)
CodeBarre += (chaine.fromCharCode(65 + parseInt(chaine.substr(i, 1)) ));
else
CodeBarre += (chaine.fromCharCode(75 + parseInt(chaine.substr(i, 1)) ));
}
CodeBarre += "*";
for (i = 7; i <= 12; i++)
{
CodeBarre += (chaine.fromCharCode(97 + parseInt(chaine.substr(i, 1)) ));
}
CodeBarre += "+";
}
return CodeBarre;
}
document.getElementById("demo").innerHTML = EAN("618110032764");
There was mutliple issues here, but here is a working example for you
function getCharCode(chaine, index, position) {
return String.fromCharCode(position + parseInt(chaine.substr(index, 1)));
}
function EAN(chaine) {
var i = 0;
var first = 0;
var checksum = 0;
var CodeBarre = "";
var tableA = 0;
if (chaine.match(/^\d{12}$/)) {
for (i = 1; i < 12; i += 2) {
chaine.substr(i, 1);
checksum += parseInt(chaine.substr(i, 1));
}
checksum *= 3;
for (i = 0; i < 12; i += 2) {
checksum += parseInt(chaine.substr(i, 1));
}
chaine += (10 - checksum % 10) % 10;
CodeBarre = chaine.substr(0, 1) + getCharCode(chaine, 1, 65);
first = parseInt(chaine.substr(0, 1));
for (i = 2; i <= 6; i++) {
tableA = false;
switch (i) {
case 2:
if (first >= 0 && first <= 3) tableA = true;
break;
case 3:
if (first == 0 || first == 4 || first == 7 || first == 8) tableA = true;
break;
case 4:
if (first == 0 || first == 1 || first == 4 || first == 5 || first == 9) tableA = true;
break;
case 5:
if (first == 0 || first == 2 || first == 5 || first == 6 || first == 7) tableA = true;
break;
case 6:
if (first == 0 || first == 3 || first == 6 || first == 8 || first == 9) tableA = true;
break;
}
if (tableA)
CodeBarre += getCharCode(chaine, i, 65);
else
CodeBarre += getCharCode(chaine, i, 75);
}
CodeBarre += "*";
for (i = 7; i <= 12; i++) {
CodeBarre += getCharCode(chaine, i, 97);
}
CodeBarre += "+";
}
return CodeBarre;
}
document.getElementById("demo").innerHTML = EAN("618110032764");
Among those issues :
Regex shouldn't be a string so no "" surrounding the expression
fromCharCode is a static method, should be used with String.fromCharCode
You should access characters from the string with the index on the loop
Here is the working demo: https://jsfiddle.net/t6r15qbd/1/
Sorry to come back to this topic, but can you give me another hand?
I can't get the encoding in txt_encoding
please, can you complete your help and help me?
function getCharCode(chaine, index, position) {return String.fromCharCode(position + parseInt(chaine.substr(index, 1)));}
function EAN(chaine) {
var code_ean13_sivop = document.getElementById("txt_ean13_sivop");
var txt_ean = document.getElementById("txt_ean");
var txt_encodage = document.getElementById("txt_encodage");
txt_ean.value = code_ean13_sivop.options[code_ean13_sivop.selectedIndex].text.substr(0, 12);
var i = 0;
var first = 0;
var checksum = 0;
var CodeBarre = "";
var tableA = 0;
if (chaine.match(/^\d{12}$/)) {
for (i = 1; i < 12; i += 2) {chaine.substr(i, 1); checksum += parseInt(chaine.substr(i, 1));}
checksum *= 3;
for (i = 0; i < 12; i += 2) {checksum += parseInt(chaine.substr(i, 1));}
chaine += (10 - checksum % 10) % 10;
CodeBarre = chaine.substr(0, 1) + getCharCode(chaine, 1, 65);
first = parseInt(chaine.substr(0, 1));
for (i = 2; i <= 6; i++) {
tableA = false;
switch (i) {
case 2: if (first >= 0 && first <= 3) tableA = true; break;
case 3: if (first == 0 || first == 4 || first == 7 || first == 8) tableA = true; break;
case 4: if (first == 0 || first == 1 || first == 4 || first == 5 || first == 9) tableA = true; break;
case 5: if (first == 0 || first == 2 || first == 5 || first == 6 || first == 7) tableA = true; break;
case 6: if (first == 0 || first == 3 || first == 6 || first == 8 || first == 9) tableA = true; break;
}
if (tableA) CodeBarre += getCharCode(chaine, i, 65); else CodeBarre += getCharCode(chaine, i, 75);
}
CodeBarre += "*";
for (i = 7; i <= 12; i++) {CodeBarre += getCharCode(chaine, i, 97); }
CodeBarre += "+";
}
return CodeBarre;
txt_encodage.value = EAN(txt_ean.value);
}
<select class="form-control form-control-sm text-monospace" id="txt_ean13_sivop" name="txt_ean13_sivop" onChange="EAN();">
<option value="" selected></option>
<option value="6181100327847">6181100327847</option>
<option value="6181100327854">6181100327854</option>
<option value="6181100328080">6181100328080</option>
<option value="6181100328097">6181100328097</option>
</select>
<input type="text" class="form-control form-control-sm text-monospace" id="txt_ean" name="txt_ean">
<input type="text" class="form-control form-control-sm text-monospace" id="txt_encodage" name="txt_encodage">
Related
I am trying to display all non-divisibles by 3 and 7 with whitespace between each number.
However I am a bit struggling with the whitespaces. This is how my outcome should look like: "1 2 4 5 8 10"!
I appreciate your help!
let input = 10;
let i = " ";
for(var num = 1; num <= input; num++ ){
if(num % 3 != 0 && num % 7 != 0){
i = i + num;
}
}
console.log(i);
You need to add spaces while modifying i. Also, remember to remove trailing whitespace at the and of the resulting string using .trimEnd():
let input = 10;
let i = "";
for(var num = 1; num <= input; num++ ){
if(num % 3 != 0 && num % 7 != 0){
i = i + num + " "; // <-- here
}
}
i = i.trimEnd(); // <-- and here
console.log(i);
let input = 10;
let i = " ";
for(var num = 1; num <= input; num++ ){
if(num % 3 != 0 && num % 7 != 0){
i = i + num + " ";
}
}
console.log(i);
I'm trying to create a cs50 card validator with JavaScript. I'm having problems with the checksum counting. It should be sum % 10 === 0 //true.
let cards = [378282246310005, 371449635398431,
5555555555554444, 5105105105105100, 4012888888881881,
4012888888881880, 1234567890, 361049635398431], result = '';
cards.forEach( card => {
if (isCardValid(card)) {
result += card + ' = ';
checkBank(card);
}
});
document.getElementById('task6').innerHTML = result;
function checkBank(card) {
if ((card >= 340000000000000 && card < 350000000000000) || (card >= 370000000000000 && card < 380000000000000))
result += ("AMEX\n");
else if (card >= 5100000000000000 && card < 5600000000000000)
result += ("MASTERCARD\n");
else if ((card >= 4000000000000 && card < 5000000000000) || (card >= 4000000000000000 && card < 5000000000000000))
result += ("VISA\n");
else
result += ("INVALID\n");
}
function isCardValid(digits) {
let sum = 0;
for (let i = 0; i < digits.length; i++) {
let cardNum = parseInt(digits[i]);
if ((digits.length - i) % 2 === 0) {
cardNum = cardNum * 2;
if (cardNum > 9) {
cardNum = cardNum - 9;
}
}
sum += cardNum;
}
return sum % 10 === 0;
}
Here is some data to check validator work:
378282246310005 //AMEX
371449635398431 //AMEX
5555555555554444 //MASTERCARD
5105105105105100 //MASTERCARD
4012888888881881 //VISA
4012888888881880 //INVALID
1234567890 //INVALID
361049635398431 //INVALID
The main thing is, i can't use strings, arrays and any ready to use functions. Waiting for your help, thanks.
UPD
I solved the issue with an algorithm except for this card:
4012888888881880 //INVALID
My code thinks that this is a VISA card. Bank validation looks fine, so i don't know where to find the problem. Any suggestions where is problem?
UPD2
Final version
let cards = [378282246310005, 371449635398431,
5555555555554444, 5105105105105100, 4012888888881881,
4012888888881880, 1234567890, 361049635398431], result = '';
cards.forEach( card => {
if (isCardValid(card)) {
result += card + ' = ';
checkBank(card);
} else {
result += card + ' = INVALID Card\n'
}
});
document.getElementById('task6').innerHTML = result;
function checkBank(card) {
if ((card >= 340000000000000 && card < 350000000000000) || (card >= 370000000000000 && card < 380000000000000))
result += ("AMEX\n");
else if (card >= 5100000000000000 && card < 5600000000000000)
result += ("MASTERCARD\n");
else if ((card >= 4000000000000 && card < 5000000000000) || (card >= 4000000000000000 && card < 5000000000000000))
result += ("VISA\n");
else
result += ("INVALID Bank\n");
}
function isCardValid(card) {
let sum = 0, len, first = 0, second = 0;
for (len=0; card; Math.floor(card /= 10), ++len) {
let digit = Math.floor(card % 10);
second = first;
first = digit;
if (len & 1) {
digit += digit;
if (digit > 9) {
digit -= 9;
}
}
sum += digit;
}
return sum % 10 === 0;
}
<pre id="task6"></pre>
function numberToOrdinal(i) {
var j = i % 10,
k = i % 100;
if (j == 0 && k == 100) {
return '0th';
}
if (j == 1 && k != 11) {
return i + "st";
}
if (j == 2 && k != 12) {
return i + "nd";
}
if (j == 3 && k != 13) {
return i + "rd";
}
return i + "th";
}
It's not passing this test, what's wrong?
should handle single digits
expected '0th' to equal '0'
if you gonna devide a unknown input you wanna check if the input given might be zero. Else there might be an devisionbyzero exception thrown.
function numberToOrdinal(i) {
if(i === 0){ // since we devide i we wanna check if it might be zero.
return i ;
}
var j = i % 10,
k = i % 100;
//if (j == 0 && k == 100) { didnt seem to be doing anything
//return '0th';
//}
if (j == 1 && k != 11) {
return i + "st";
}
if (j == 2 && k != 12) {
return i + "nd";
}
if (j == 3 && k != 13) {
return i + "rd";
}
return i + "th";
}
console.log(numberToOrdinal(0));
you could just change these lines
if (j == 0 && k == 100) {
return '0th';
}
to be
if (i == 0) {
return i
}
If you want your function to return 0 when 0 is passed to the function, you will need to enter a condition to handle that, such as:
if (i === 0) {
return 0;
}
You have to enter another condition to handle it
function numberToOrdinal(i) {
var j = i % 10,
k = i % 100;
if (i === 0) {
return i;
}
if (j == 1 && k != 11) {
return `${i}st`;
}
if (j == 2 && k != 12) {
return `${i}nd`;
}
if (j == 3 && k != 13) {
return `${i}rd`;
}
return `${i}th`;
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I'm working through the intermediate algorithms in the FreeCodeCamp curriculum. One of them involves converting integers to roman numerals. My solution (presented below) works, however it is very much the "naive" approach, if you will. The task hints that array.splice(), array.indexOf(), and array.join() ought to be used. My implementation only uses array.join().
Edited question for precision: Will someone provide an implementation that makes use of all of the aforementioned methods?
Thanks.
My implementation:
function convertToRoman(num) {
var I = 1, V = 5, X = 10, L = 50, C = 100, D = 500, M = 1000;
var numerals = [];
var i;
if(num >= 1000){
var numMs = Math.floor(num / 1000);
for (i = 0; i < numMs; i++){
numerals.push('M');
}
num = num % 1000;
}
if(num >= 900){
numerals.push('CM');
num = num - 900;
}
if(num < 900){
if(num >= 500){
numerals.push('D');
num = num - 500;
}
if(num >= 400){
numerals.push('CD');
num = num - 400;
}
var numCs = Math.floor(num / 100);
for(i = 0; i < numCs; i++){
numerals.push('C');
}
num = num % 100;
}
if(num >= 90){
numerals.push('XC');
num = num - 90;
}
if(num < 90){
if(num >= 50){
numerals.push('L');
num = num - 50;
}
if(num >= 40){
numerals.push('XL');
num = num - 40;
}
var numXs = Math.floor(num / 10);
for(i = 0; i < numXs; i++){
numerals.push('X');
}
num = num % 10;
}
if(num == 9){
numerals.push('IX');
num = num - 9;
}
if(num < 9){
if(num >= 5){
numerals.push('V');
num = num - 5;
}
if(num >=4){
numerals.push('IV');
num = num - 4;
}
var numIs = Math.floor(num / 1);
for(i = 0; i < numIs; i++){
numerals.push('I');
}
}
var converted = numerals.join('');
return converted;
}
UPDATE: Another answer found here, but it does not use the methods I'm interested in using.
You may do as follows;
function toRoman(n){
var numerals = ["I","V","X","L","C","D","M"];
return n.toString()
.split("")
.reverse()
.reduce((p,c,i) => (c === "0" ? ""
: c < "4" ? numerals[2*i].repeat(c)
: c === "4" ? numerals[2*i] + numerals[2*i+1]
: c < "9" ? numerals[2*i+1] + numerals[2*i].repeat(c-5)
: numerals[2*i] + numerals[2*i+2]) + p,"");
}
console.log(toRoman(1453));
This is a proposal which use Array#reduce for any part of the number to convert.
function toRoman(i) {
return ('0000' + i).slice(-4).split('').map(Number).reduce(function (r, a, i) {
var value = 'MDCLXVI';
if (a === 4 || a === 9) {
r += value[i * 2];
a++;
}
if (a === 10) {
r += value[i * 2 - 2];
a -= 10;
}
if (a >= 5) {
r += value[i * 2 - 1];
a -= 5;
}
while (a) {
r += value[i * 2];
a--;
}
return r;
}, '');
}
var i;
for (i = 1; i <= 3000; i++) {
document.getElementById('tt').innerHTML += i + ' ' + toRoman(i) + `\n`;
}
<pre id="tt"></pre>
Trying to have a user input a number and if they type in a string I would like to prompt them to enter a number. Seems like I got that part right but how can I get the second prompt to keep popping up until the user enters a an actual number. As of now, once the user enters a string again nothing runs after that. Would appreciate any kind of suggestions.
Here is the code:
function enterNumber(n) {
n = parseInt(prompt("Please enter a number: "));
if (isNaN(n)) {
n = parseInt(prompt("You did not enter a number. Please enter a number: "));
for(var i = 1; i <= n; i++) {
if (i % 15 === 0) {
document.write("Fizz Buzz" + "<br>");
continue;
}
else if (i % 3 === 0){
document.write("Fizz" + "<br>");
continue;
} else if (i % 5 === 0) {
document.write("Buzz" + "<br>");
continue;
}
document.write(i + "<br>");
}
}
};
enterNumber();
Use while loop until the entered is number.
function enterNumber(n) {
while (isNaN(parseInt(n))) {
n = parseInt(prompt("Please enter a number: "));
}
for (var i = 1; i <= n; i++) {
if (i % 15 === 0) {
document.write("Fizz Buzz" + "<br>");
continue;
} else if (i % 3 === 0) {
document.write("Fizz" + "<br>");
continue;
} else if (i % 5 === 0) {
document.write("Buzz" + "<br>");
continue;
}
document.write(i + "<br>");
}
};
enterNumber();
You can also shorten you code using nested Ternary operators as follow.
function enterNumber(n) {
while (isNaN(parseInt(n))) {
n = parseInt(prompt("Please enter a number: "));
}
for (var i = 1; i <= n; i++) {
var title = i % 15 === 0 ? 'Fizz Buzz' : i % 3 === 0 ? 'Fizz' : i % 5 === 0 ? 'Buzz' : i;
document.write(title + "<br>");
}
};
enterNumber();
Try like this
function enterNumber(n) {
while (isNaN(n))
n = parseInt(prompt("You did not enter a number. Please enter a number: "));
for (var i = 1; i <= n; i++) {
if (i % 15 === 0) {
document.write("Fizz Buzz" + "<br>");
continue;
} else if (i % 3 === 0) {
document.write("Fizz" + "<br>");
continue;
} else if (i % 5 === 0) {
document.write("Buzz" + "<br>");
continue;
}
document.write(i + "<br>");
}
};
enterNumber();