How to accept an input in the console from the user (JS)? - javascript

I tried to create a JavaScript program that outputs the binary format of an English letter on input. I had to put the value in the code. How can the value be entered in the console when the program runs?
function returnBinaryLetter(char) {
return ((/^[a-z]$/).test(char)) ? char.charCodeAt(0).toString(2).padStart(8, '0') : 'Sorry, that is not a letter.'
}
// Something like:
// const input = consoleInputFunction('Enter a number.');
// console.log(returnBinaryLetter(input.toLowerCase()));
EDIT 1: This is not for a webpage. This is a JS program which I will run using Node.js. I require a solution with just JS, not with some framework (if that is even possible, mentioning just to be specific).
EDIT 2: I have made the code better after suggestions in Endothermic Dragon's answer.

To directly answer your question, you would use prompt to get a user input in this case.
However, you don't need all of that code. Try this:
function returnBinaryLetter(char) {
if ((/^[a-z]$/).test(char)) {
return char.charCodeAt(0).toString(2).padStart(8, '0')
} else {
return 'Sorry, that is not a letter.'
}
}
var input = prompt('Enter letter to be converted to binary:').toLowerCase();
console.log(returnBinaryLetter(input))
While it may seem a bit intimidating, here's the whole thing broken down:
Ask for an input using prompt, and convert it to lowercase.
Pass the character to the function returnBinaryLetter, and log the output.
Now for the function returnBinaryLetter:
Check if it is a single lowercase letter, using some RegEx.
If it is, return binary. Otherwise, return an error with a description.
Hmm, but how does the binary conversion work?
First, take the character and get its character code.
Next, convert that code to binary.
Finally, pad the start so it is an 8-bit number. If it is not 8 digits, add on 0s at the beginning until it is.
Here, you can see that a more dynamic conversion looks much shorter, and cleaner as well, compared to manually entering about 28 lines of code.
Bonus:
Surprise, surprise! You can further shorten it. Using a ternary operator, you can skip the if-else statement.
function returnBinaryLetter(char) {
return ((/^[a-z]$/).test(char)) ? char.charCodeAt(0).toString(2).padStart(8, '0') : 'Sorry, that is not a letter.'
}
var input = prompt('Enter letter to be converted to binary:').toLowerCase();
console.log(returnBinaryLetter(input))
Now, it's a one-liner!
A ternary operator is usually used within variables when you want to assign its value based on a condition. The ternary operator first checks if the condition inside the brackets is true, and if it is, it returns the first statement (between ? and :), and if not, it returns the second statement (after the :). Pairing this with the return statement of a function, you get a one-liner function!
Feedback:
Since it seems that you are following CamelCase, I thought I would mention that function names should always start with a capital letter, along with each word after that also starting with a capital letter. Variables are different however - for variables, you do make the first letter lowercase, but make all the other words uppercase. In addition, the function name returnBinaryLetter might seem intuitive to you, but not for anyone looking at the code. A more intuitive name that exactly describes its function would be LowercaseLetterToBinary.

For NodeJS, You can use inquirer, which provides different kinds of prompts for the command line (such as text, list, checkbox etc).
Prerequistes:
Install it with npm install inquirer
Example
const { prompt } = require("inquirer");
async main() {
const binaryLetter = await prompt({
type: 'input',
name: 'letter',
message: `What's your name >>`
})
.then(answer => returnBinaryLetter(answer['letter']));
}
main();

Related

Regex for js variable end with semicolon

I am trying to find and extract an assignment of a property of the product_image object from Javascript code, extracted with BeautifulSoup. I have tried following
re.findall(r"product_images\['top_lg'] = .*;", txt)
Unfortunately it does not extract anything from my text below.
product_images['top_lg'] = {
"tn": '//image.test.com/media/cache/04/0a/040a1e61f5edc387d8c8e40d3ea0e0ca.jpg',
"md": '//image.test.com/media/cache/b7/f3/b7f3cb1da267d7e8ac0412bdc522c862.jpg',
"lg": '//image.test.com/media/shape_images/011f7f24ae4cbbef191cff1a711df9e1_a3c9ca71b7d85d87085955f8d1c4bfc3_0_.jpg',
"alt": 'test ',
"data-zoomable": 'True',
"text_line": 'teest'
};
The scripts that I am parsing are taken from https://www.brilliantearth.com/Petite-Twisted-Vine-Diamond-Ring-White-Gold-BE1D54-3821855/
If, like me, you find regex flags confusing and hard to remember, use
"not semicolon" expressions instead of dot
re.findall(r"product_images\['top_lg'] = [^;]*;", txt)
Note. Otherwise you can add a flag as Thierry suggests, though you would need also add a 'non-gready modifier' ? after * to indicate that you are interested in the first semicolon rather that the last.

What is the regex of 'if'?

I am working on a project that needs to check if the user has written a good condition on a textfield. So I'd like to know if one of you knows the regex of a 'if'. For example, if the user writes if ((k <= 5 && k>0)|| x>8) I will return true.
Keith's reference looks good (pegjs.org). You're not looking for a regex (albeit possible to do with such) by a lexer + yacc combo (see flex and bison). Note that what you are really looking for is the "expression" parser. A "simple calculator" expression.
One way to test would be to use the "eval()" function. However, it is considered to be a dangerous function. Yet, in your case you let the end user enter an expression and then execute that expression. If they write dangerous stuff, they probably know what they are doing and they will be doing it to themselves.
There is documentation about it:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
In your case you would do something like the following with a try/catch to know whether it is valid:
var valid = true;
try
{
// where input.val would reference your if() expression
eval(input.val);
}
catch(e)
{
valid = false;
}
Note that's a poor man solution since it won't tell you whether other code is included in the expression. There are probably some solution to that such as adding some string at the start such as:
eval("ignore = (1 + " + input.val + ")");
Now input.val pretty much has to be an expression. You'll have to test and see whether that's acceptable or not.

Greek language support for lunr.js

Registering a new stemmer function in lunr for greek words doesn't work as expected. here is my code on codepen. I am not receiving any errors, the function stemWord() works fine when used separately but it fails to stem the words in lunr.
below is a sample of the code:
function stemWord(w) {
// code that returns the stemmed word
};
// create the new function
greekStemmer = function (token) {
return stemWord(token);
};
// register it with lunr.Pipeline, this allows you to still serialise the index
lunr.Pipeline.registerFunction(greekStemmer, 'greekStemmer')
var index = lunr(function () {
this.field('title', {boost: 10})
this.field('body')
this.ref('id')
this.pipeline.remove(lunr.trimmer) // it doesn't work well with non-latin characters
this.pipeline.add(greekStemmer)
})
index.add({
id: 1,
title: 'ΚΑΠΟΙΟΣ',
body: 'Foo foo foo!'
})
index.add({
id: 2,
title: 'ΚΑΠΟΙΕΣ',
body: 'Bar bar bar!'
})
index.add({
id: 3,
title: 'ΤΙΠΟΤΑ',
body: 'Bar bar bar!'
})
In lunr a stemmer is implemented as a pipeline function. A pipeline function is executed against each word in a document when indexing the document, and each word in a search query when searching.
For a function to work in a pipeline it has to implement a very simple interface. It needs to accept a single string as input, and it must respond with a string as its output.
So a very simple (and useless) pipeline function would look like the following:
var simplePipelineFunction = function (word) {
return word
}
To actually make use of this pipeline function we need to do two things:
Register it as a pipeline function, this allows lunr to correctly serialise and deserialise your pipeline.
Add it to your indexes pipeline.
That would look something like this:
// registering our pipeline function with the name 'simplePipelineFunction'
lunr.Pipeline.registerFunction(simplePipelineFunction, 'simplePipelineFunction')
var idx = lunr(function () {
// adding the pipeline function to our indexes pipeline
// when defining the pipeline
this.pipeline.add(simplePipelineFunction)
})
Now, you can take the above, and swap out the implementation of our pipeline function. So, instead of just returning the word unchanged, it could use the greek stemmer you have found to stem the word, maybe like this:
var myGreekStemmer = function (word) {
// I don't know how to use the greek stemmer, but I think
// its safe to assume it won't be that different than this
return greekStem(word)
}
Adapting lunr to work with a language other than English requires more than just adding your stemmer though. The default language of lunr is English, and so, by default, it includes pipeline functions that are specialised for English. English and Greek are different enough that you will probably run into issues trying to index Greek words with the English defaults, so we need to do the following:
Replace the default stemmer with our language specific stemmer
Remove the default trimmer which doesn't play so nice with non-latin characters
Replace/remove the default stop word filter, its unlikely to be much use on a language other than English.
The trimmer and stop word filter are implemented as pipeline functions, so implementing language specific ones would be similar for the stemmer.
So, to set up lunr for Greek you would have this:
var idx = lunr(function () {
this.pipeline.after(lunr.stemmer, greekStemmer)
this.pipeline.remove(lunr.stemmer)
this.pipeline.after(lunr.trimmer, greekTrimmer)
this.pipeline.remove(lunr.trimmer)
this.pipeline.after(lunr.stopWordFilter, greekStopWordFilter)
this.pipeline.remove(lunr.stopWordFilter)
// define the index as normal
this.ref('id')
this.field('title')
this.field('body')
})
For some more inspiration you can take a look at the excellent lunr-languages project, it has many examples of creating language extensions for lunr. You could even submit one for Greek!
EDIT Looks like I don't know the lunr.Pipeline API as well as I thought, there is no replace function, instead we just insert the replacement after the function to remove, and then remove it.
EDIT Adding this to help others in the future... It turns out the problem was down to the casing of the tokens within lunr. lunr wants to treat all tokens as lowercase, this is done, without any configurability, in the tokenizer. For most language processing functions this is not a problem, indeed, most assume words are lower cased. In this case, the Greek stemmer only stems uppercase words due to the complexity of stemming in Greek (I'm not a Greek speaker so can't comment on how much more complex that stemming is). A solution is to convert to upper case before calling the Greek stemmer, then convert back to lowercase before passing the tokens on to the rest of the pipeline.

Get the value of confused Javascript code

I got a piece of code like this:
var password = eval(function(p,a,c,k,e,d){e=function(c){return(c<a?"":e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1;};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p;}('9 5$=["\\8\\3\\4\\3\\2\\2\\1\\3\\2\\3\\3\\2\\2\\7\\3\\1\\4\\1\\3\\2\\1\\3\\1\\3\\2\\2\\2\\1\\3\\4\\1\\3\\2\\1\\4\\1\\3\\2\\1\\4\\1\\3\\2\\2\\1\\3\\4\\1\\3\\2\\1\\4\\1\\3\\2\\1\\4\\1\\3\\2\\1\\4\\1\\3\\2\\1\\4\\1\\3\\2\\1\\4\\1\\3\\2\\2\\1\\3\\1\\3\\2\\2"];6 c(){e["\\f\\g\\d\\a\\b"](5$[0])}',17,17,'|x2b|x5d|x5b|x21|_|function|x29|x28|var|x72|x74|O0|x65|window|x61|x6c'.split('|'),0,{}));
And I unpacked the following code(except 'var password = '):
eval(function(p,a,c,k,e,d){e=function(c){return(c<a?"":e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1;};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p;}('9 5$=["\\8\\3\\4\\3\\2\\2\\1\\3\\2\\3\\3\\2\\2\\7\\3\\1\\4\\1\\3\\2\\1\\3\\1\\3\\2\\2\\2\\1\\3\\4\\1\\3\\2\\1\\4\\1\\3\\2\\1\\4\\1\\3\\2\\2\\1\\3\\4\\1\\3\\2\\1\\4\\1\\3\\2\\1\\4\\1\\3\\2\\1\\4\\1\\3\\2\\1\\4\\1\\3\\2\\1\\4\\1\\3\\2\\2\\1\\3\\1\\3\\2\\2"];6 c(){e["\\f\\g\\d\\a\\b"](5$[0])}',17,17,'|x2b|x5d|x5b|x21|_|function|x29|x28|var|x72|x74|O0|x65|window|x61|x6c'.split('|'),0,{}));
Then I got:
var _$ = ["\x28\x5b\x21\x5b\x5d\x5d\x2b\x5b\x5d\x5b\x5b\x5d\x5d\x29\x5b\x2b\x21\x2b\x5b\x5d\x2b\x5b\x2b\x5b\x5d\x5d\x5d\x2b\x5b\x21\x2b\x5b\x5d\x2b\x21\x2b\x5b\x5d\x2b\x21\x2b\x5b\x5d\x5d\x2b\x5b\x21\x2b\x5b\x5d\x2b\x21\x2b\x5b\x5d\x2b\x21\x2b\x5b\x5d\x2b\x21\x2b\x5b\x5d\x2b\x21\x2b\x5b\x5d\x2b\x21\x2b\x5b\x5d\x5d\x2b\x5b\x2b\x5b\x5d\x5d"];
function O0() {
window["\x61\x6c\x65\x72\x74"](_$[0])
}
And after decoding:
var _$ = ["([![]]+[][[]])[+!+[]+[+[]]]+[!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[+[]]"];
function O0() {
window["alert"](_$[0])
}
Now I wonder how the codes execute and what is the value of password ?
Thanks so much.
The code is obfuscated and intended to permit execution of arbitrary code even if the script text is passed through filters.
The approach is often used for tracking, phishing and other undesirable activities, so I would suggest you don't try running it.
All you need to do is run this code -- not the 'window' stuff, but only the 'decode' part -- and you'll see the solution.
Here are some pointers on decoding:
the outer array brackets are a decoy
an empty array [] evaluates to 0 when used in a calculation such as +[]
!0 = 1
!+0 evaluates to true or 1, !+1 to false or 0 (this surely must be a loophole in Javascript)
.. so !+[] is simply 1.
[1]+[1] is not a valid math sum, so both arrays are converted to strings before being added up.
The above takes care of the numbers. Where does the first character come from? The first part ([![]]+[][[]]) evaluates directly to a string two constants, which add together as a string again, and the array index after it picks up a single character.

Regex: find whatever comes after one thing before another thing

I want to find anything that comes after s= and before & or the end of the string. For example, if the string is
t=qwerty&s=hello&p=3
I want to get hello. And if the string is
t=qwerty&s=hello
I also want to get hello
Thank you!
\bs=([^&]+) and grabbing $1should be good enough, no?
edit: added word anchor! Otherwise it would also match for herpies, dongles...
Why don't you try something that was generically aimed at parsing query strings? That way, you can assume you won't run into the obvious next hurdle while reinventing the wheel.
jQuery has the query object for that (see JavaScript query string)
Or you can google a bit:
function getQuerystring(key, default_)
{
if (default_==null) default_="";
key = key.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regex = new RegExp("[\\?&]"+key+"=([^&#]*)");
var qs = regex.exec(window.location.href);
if(qs == null)
return default_;
else
return qs[1];
}
looks useful; for example with
http://www.bloggingdeveloper.com?author=bloggingdeveloper
you want to get the "author" querystring's value:
var author_value = getQuerystring('author');
The simplest way to do this is with a selector s=([^&]*)&. The inside of the parentheses has [^&] to prevent it from grabbing hello&p=3 of there were another field after p.
You can also use the following expression, based on the solution provided here, which finds all characters between the two given strings:
(?<=s=)(.*)(?=&)
In your case you may need to slightly modify it to account for the "end of the string" option (there are several ways to do it, especially when you can use simple code manipulations such as manually adding a & character to the end of the string before running the regex).

Categories