scan string operators - javascript - string

In a calculator I own 4 input type ="number" in particular:
<input type = "number" id ="mol" min="1" max="4">
<input type = "number" id ="div" min="1" max="4">
<input type = "number" id ="add" min="1" max="4">
<input type = "number" id ="min" min="1" max="4">
In a textbox, I insert the mathematical expression for extended.
<input type = "text" id = "exp" readonly>
The numerical values ​​and the operators have gone through the normal buttons.
So, for example, the expression inserted in the textbox is this: 8*5-9/2+3
Now I would want that when I press the equal key, based on the priority that the customer has given to the operands, the expression result changed.
multiplication: 1
division: 4
subtraction: 2
addition: 3
-> 40 - 9 / 2 + 3
-> 31 / 2 + 3
-> 31 / 5
-> = 6.2
I think this is very difficult to achieve.
Get the value of the textbox and evaluate the result based on the priority of the operands is really extreme. What do you propose?

Try using the split method: http://msdn.microsoft.com/en-us/library/t5az126b(v=vs.94).aspx
Split on the operator with the first priority first, then split each group by the second operator, then for each subgroup split by the third operator, and for each of those sub-subgroups split by the fourth. Then apply the operator to the groups moving upward.
Conceptual example (not the full code you'll need, but should give an idea):
var expression = "8*5-9/2+3"; // Get this from the data
var operator1Groups = expression.split("*"); // Instead of hardcoding this, retrieve which operator has highest priority from the data
for (var i in operator1Groups) {
var operator2Groups = operator1Groups[i].split("+"); // Similarly, don't hardcode the operator
// And so on...
// Once you get to the lowest operator, start applying the operator to each group
}

The way to do this is with an Operator Precedence Parser. They are commonly implemented using Djikstra's Shunting-yard Algorithm. You could specify the precedence by loading the operators and precedences into a list and then running the algorithm:
function parse(inputExpression, operators) {
// Strip out anything that isn't a number or a math operator
var tokens = inputExpression
.replace(/[^0-9+\-*\/()]/g, '')
.split(/([+\-*\/()])/)
.filter(function(x) { return x != ""; });
var outputQ = []; // push = push, pop = pop
var operStk = []; // enqueue = push, dequeue = shift
function top(stack) { return stack[stack.length-1]; }
while(tokens.length !== 0) {
var token = tokens.shift();
if(!isNaN(Number(token))) {
outputQ.push(token);
} else if (operators.hasOwnProperty(token)) {
while(operators[token] >= operators[top(operStk)])
outputQ.push(operStk.pop());
operStk.push(token);
} else if (token == '(') {
operStk.push(token);
} else if (token == ')') {
while(top(operStk) != '(' && operStk.length != 0)
outputQ.push(operStk.pop());
if(operStk.length == 0)
return null;
operStk.pop(); // Get rid of the l-paren
} else {
console.log("Bad token '" + token + "'");
return null;
}
}
while(operStk.length > 0)
outputQ.push(operStk.pop());
return outputQ;
}
function evaluate(parseResult) {
if (parseResult === null) return null;
var valueStack = [];
while(parseResult.length !== 0) {
var op = parseResult.shift();
if(!isNaN(Number(op)))
valueStack.push(Number(op));
else {
var val2 = valueStack.pop();
var val1 = valueStack.pop();
if(op == '+') {
valueStack.push(val1 + val2);
} else if(op == '-') {
valueStack.push(val1 - val2);
} else if(op == '*') {
valueStack.push(val1 * val2);
} else if(op == '/') {
valueStack.push(val1 / val2);
} else {
console.log("Invalid operator '" + op + "'");
return null;
}
}
}
if(valueStack.length !== 1) {
console.log("Invalid stack. Remaining: " + valueStack);
return null;
}
return valueStack.pop();
}
Usage:
var operators = {
"+": 3,
"-": 2,
"*": 1,
"/": 4
};
evaluate(parse("40 - 9 / 2 + 3", operators)); // == 6.2
Note that this will not handle unary minus, because it's difficult to do with Shunting-yard, and because you aren't asking for a precedence for it. On the bright side, it does support parenthesis.
Hope this helps!
Alex

Related

How to construct a binary tree from a infix string with brackets?

A non-empty tree is defined as {L,a,R}, L is left subtree, and R is Right subtree. {} for subtree is empty.
for example, {{{{},3,{}},2,{{},1,{}}},4,{{{},5,{}},6,{}}} constructs an binary tree like the picture.tree constructed from the string
I have found a question for constructs an binary tree from a prefix expression with brackets, but I still have no idea for how to doing this.
I did not get a reply on which data structure or language you expect to use, but here is an implementation of a recursive parser in JavaScript.
It uses a regular expression to tokenise the input into braces and data.
From those tokens it creates instances of a typical Node class.
Finally it outputs that structured tree in a simple, rotated view:
class Node {
constructor(left, value, right) {
this.left = left;
this.value = value;
this.right = right;
}
toString() {
return (this.right ? this.right.toString().replace(/^/gm, " ") + "\n" : "")
+ this.value
+ (this.left ? "\n" + this.left.toString().replace(/^/gm, " ") : "");
}
}
function createTree(s) {
const tokens = s.matchAll(/,([^{},]+),|[{}]|(.)/g);
function getToken(expect) {
let [all, value, error] = tokens.next().value;
value ||= all;
if (error || expect && !expect.includes(all)) throw "Unexpected '" + all + "'";
return value;
}
function dfs(readOpening) {
if (readOpening) getToken("{");
if (getToken("{}") == "}") return null;
const node = new Node(dfs(), getToken(), dfs(true));
getToken("}");
return node;
}
return dfs(true);
}
// Demo
const s = "{{{{},3,{}},2,{{},1,{}}},4,{{{},5,{}},6,{}}}";
const root = createTree(s);
console.log(root.toString()); // rotated view, with root at the left
Thanks for answerign my question. I finally came up with an naive method by myself. I used recursive function to deal with token and create nodes. It used a counter to judge whether brackets is closed. Here is my code in C++.
createTree(string inp){
int leftBracket = 0,rightBracket = 0;
if (inp.length() <= 2) {
return nullptr;
}
else {
for (int i = 1;;i++) {
if (leftBracket == rightBracket && inp[i] >= '0' && inp[i] <= '9') {
treeNode* newNode = new treeNode(inp[i]-'0', createTree(inp.substr(1, i - 2)), createTree(inp.substr(i + 2, inp.length() - i - 3)));
nodeCounter++;
return newNode;
}
else {
if (inp[i] == '{') {
leftBracket++;
}
else if (inp[i] == '}') {
rightBracket++;
}
}
}
}
}

I would like my bot to delete the message that contains a keyword or that contains similar characters

in my bot I have implemented a keyword filter that the bot reviews in each message that is written in the chat, until now it works, but I want to improve it, for reasons of respect I will not put words here, so I will put some others example,
The bot detects if you write for example "vulgar", "badword", "hello"
But what I want to achieve is to detect if they write "hellooo", "vuulgarr", vulg4rr"
This is my base where I have the words stored:
badwords.js
var words = ["vulgar", "vulg4r", "hello", "badword4", "badword5"]
module.exports = words;
This is my function that checks if a bad word comes on the way, split any words and then deletes the message if it finds a result, with indexOf()
index.js
const _ = require('lodash');
const badwords = require('./badwords');
/**
* Functions
*/
// compares every word to badWords array from badWords.js
function checkWord(word) {
return badwords.indexOf(word) > -1;
}
/**
* Main Module
*/
module.exports = function (self, nick, channel, message) {
'use strict';
message = message.toLowerCase();
message = message.split(' ');
nick = nick;
channel = channel.toLowerCase();
for (var i = 0, len = message.length; i < len; i++) {
if (checkWord(message[i])) {
self.send('.ban', channel, nick);
}
}
}
Any idea to improve it?, thank's
A more complicated method
We can have two pointers on both strings to compare, but skipping offsets upon duplicates:
function checkString(message, keyword) {
while(message.length > 0) {
if(checkPrefix(message, keyword)) return true
message = message.substr(1)
}
}
function checkPrefix(message, keyword) { // keyword is one of the keywords
let om = 0, ok = 0
while (true) {
if (ok >= keyword.length)
return true // we have finished reading keyword, and everything matched
if(om >= message.length)
return false // message is shorter than keyword
while (om + 1 < message.length && message.charAt(om) === message.charAt(om + 1))
om++ // skip consecutive repetitions in message
while (ok + 1 < keyword.length && keyword.charAt(ok) === keyword.charAt(ok + 1))
ok++ // skip consecutive repetitions in keyword
if (message.charAt(om) !== message.charAt(ok)) return false // encountered an inconsistent character
}
}
A simpler method
Just scan the repetitions in a string and delete them first.
function removeDuplicates(string) {
for (let i = 0; i < string.length - 1; ) {
if (string.charAt(i) === string.charAt(i + 1)) {
string = string.substr(0, i) + string.substr(i + 1) // skip string[i]
} else {
i++ // not duplicate, proceed to next pair
}
}
}
Then you can compare directly:
removeDuplicates(message).indexOf(removeDuplicates(keyword)) !== -1
You can apply it like this:
for (const part in message.split(" ")) {
for (word in words) {
if (removeDuplicates(part).indexOf(removeDuplicates(word)) !== -1)
self.send(".ban", ...)
break
}
}

stored exponential value in mongodb [duplicate]

I'm looking for a good JavaScript equivalent of the C/PHP printf() or for C#/Java programmers, String.Format() (IFormatProvider for .NET).
My basic requirement is a thousand separator format for numbers for now, but something that handles lots of combinations (including dates) would be good.
I realize Microsoft's Ajax library provides a version of String.Format(), but we don't want the entire overhead of that framework.
Current JavaScript
From ES6 on you could use template strings:
let soMany = 10;
console.log(`This is ${soMany} times easier!`);
// "This is 10 times easier!"
See Kim's answer below for details.
Older answer
Try sprintf() for JavaScript.
If you really want to do a simple format method on your own, don’t do the replacements successively but do them simultaneously.
Because most of the other proposals that are mentioned fail when a replace string of previous replacement does also contain a format sequence like this:
"{0}{1}".format("{1}", "{0}")
Normally you would expect the output to be {1}{0} but the actual output is {1}{1}. So do a simultaneous replacement instead like in fearphage’s suggestion.
Building on the previously suggested solutions:
// First, checks if it isn't implemented yet.
if (!String.prototype.format) {
String.prototype.format = function() {
var args = arguments;
return this.replace(/{(\d+)}/g, function(match, number) {
return typeof args[number] != 'undefined'
? args[number]
: match
;
});
};
}
"{0} is dead, but {1} is alive! {0} {2}".format("ASP", "ASP.NET")
outputs
ASP is dead, but ASP.NET is alive! ASP {2}
If you prefer not to modify String's prototype:
if (!String.format) {
String.format = function(format) {
var args = Array.prototype.slice.call(arguments, 1);
return format.replace(/{(\d+)}/g, function(match, number) {
return typeof args[number] != 'undefined'
? args[number]
: match
;
});
};
}
Gives you the much more familiar:
String.format('{0} is dead, but {1} is alive! {0} {2}', 'ASP', 'ASP.NET');
with the same result:
ASP is dead, but ASP.NET is alive! ASP {2}
It's funny because Stack Overflow actually has their own formatting function for the String prototype called formatUnicorn. Try it! Go into the console and type something like:
"Hello, {name}, are you feeling {adjective}?".formatUnicorn({name:"Gabriel", adjective: "OK"});
You get this output:
Hello, Gabriel, are you feeling OK?
You can use objects, arrays, and strings as arguments! I got its code and reworked it to produce a new version of String.prototype.format:
String.prototype.formatUnicorn = String.prototype.formatUnicorn ||
function () {
"use strict";
var str = this.toString();
if (arguments.length) {
var t = typeof arguments[0];
var key;
var args = ("string" === t || "number" === t) ?
Array.prototype.slice.call(arguments)
: arguments[0];
for (key in args) {
str = str.replace(new RegExp("\\{" + key + "\\}", "gi"), args[key]);
}
}
return str;
};
Note the clever Array.prototype.slice.call(arguments) call -- that means if you throw in arguments that are strings or numbers, not a single JSON-style object, you get C#'s String.Format behavior almost exactly.
"a{0}bcd{1}ef".formatUnicorn("FOO", "BAR"); // yields "aFOObcdBARef"
That's because Array's slice will force whatever's in arguments into an Array, whether it was originally or not, and the key will be the index (0, 1, 2...) of each array element coerced into a string (eg, "0", so "\\{0\\}" for your first regexp pattern).
Neat.
Number Formatting in JavaScript
I got to this question page hoping to find how to format numbers in JavaScript, without introducing yet another library. Here's what I've found:
Rounding floating-point numbers
The equivalent of sprintf("%.2f", num) in JavaScript seems to be num.toFixed(2), which formats num to 2 decimal places, with rounding (but see #ars265's comment about Math.round below).
(12.345).toFixed(2); // returns "12.35" (rounding!)
(12.3).toFixed(2); // returns "12.30" (zero padding)
Exponential form
The equivalent of sprintf("%.2e", num) is num.toExponential(2).
(33333).toExponential(2); // "3.33e+4"
Hexadecimal and other bases
To print numbers in base B, try num.toString(B). JavaScript supports automatic conversion to and from bases 2 through 36 (in addition, some browsers have limited support for base64 encoding).
(3735928559).toString(16); // to base 16: "deadbeef"
parseInt("deadbeef", 16); // from base 16: 3735928559
Reference Pages
Quick tutorial on JS number formatting
Mozilla reference page for toFixed() (with links to toPrecision(), toExponential(), toLocaleString(), ...)
From ES6 on you could use template strings:
let soMany = 10;
console.log(`This is ${soMany} times easier!`);
// "This is 10 times easier!"
Be aware that template strings are surrounded by backticks ` instead of (single) quotes.
For further information:
https://developers.google.com/web/updates/2015/01/ES6-Template-Strings
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings
Note:
Check the mozilla-site to find a list of supported browsers.
jsxt, Zippo
This option fits better.
String.prototype.format = function() {
var formatted = this;
for (var i = 0; i < arguments.length; i++) {
var regexp = new RegExp('\\{'+i+'\\}', 'gi');
formatted = formatted.replace(regexp, arguments[i]);
}
return formatted;
};
With this option I can replace strings like these:
'The {0} is dead. Don\'t code {0}. Code {1} that is open source!'.format('ASP', 'PHP');
With your code the second {0} wouldn't be replaced. ;)
I use this simple function:
String.prototype.format = function() {
var formatted = this;
for( var arg in arguments ) {
formatted = formatted.replace("{" + arg + "}", arguments[arg]);
}
return formatted;
};
That's very similar to string.format:
"{0} is dead, but {1} is alive!".format("ASP", "ASP.NET")
For Node.js users there is util.format which has printf-like functionality:
util.format("%s world", "Hello")
I'm surprised no one used reduce, this is a native concise and powerful JavaScript function.
ES6 (EcmaScript2015)
String.prototype.format = function() {
return [...arguments].reduce((p,c) => p.replace(/%s/,c), this);
};
console.log('Is that a %s or a %s?... No, it\'s %s!'.format('plane', 'bird', 'SOman'));
< ES6
function interpolate(theString, argumentArray) {
var regex = /%s/;
var _r=function(p,c){return p.replace(regex,c);}
return argumentArray.reduce(_r, theString);
}
interpolate("%s, %s and %s", ["Me", "myself", "I"]); // "Me, myself and I"
How it works:
reduce applies a function against an accumulator and each element in the array (from left to right) to reduce it to a single value.
var _r= function(p,c){return p.replace(/%s/,c)};
console.log(
["a", "b", "c"].reduce(_r, "[%s], [%s] and [%s]") + '\n',
[1, 2, 3].reduce(_r, "%s+%s=%s") + '\n',
["cool", 1337, "stuff"].reduce(_r, "%s %s %s")
);
Here's a minimal implementation of sprintf in JavaScript: it only does "%s" and "%d", but I have left space for it to be extended. It is useless to the OP, but other people who stumble across this thread coming from Google might benefit from it.
function sprintf() {
var args = arguments,
string = args[0],
i = 1;
return string.replace(/%((%)|s|d)/g, function (m) {
// m is the matched format, e.g. %s, %d
var val = null;
if (m[2]) {
val = m[2];
} else {
val = args[i];
// A switch statement so that the formatter can be extended. Default is %s
switch (m) {
case '%d':
val = parseFloat(val);
if (isNaN(val)) {
val = 0;
}
break;
}
i++;
}
return val;
});
}
Example:
alert(sprintf('Latitude: %s, Longitude: %s, Count: %d', 41.847, -87.661, 'two'));
// Expected output: Latitude: 41.847, Longitude: -87.661, Count: 0
In contrast with similar solutions in previous replies, this one does all substitutions in one go, so it will not replace parts of previously replaced values.
3 different ways to format javascript string
There are 3 different ways to format a string by replacing placeholders with the variable value.
Using template literal (backticks ``)
let name = 'John';
let age = 30;
// using backticks
console.log(`${name} is ${age} years old.`);
// John is 30 years old.
Using concatenation
let name = 'John';
let age = 30;
// using concatenation
console.log(name + ' is ' + age + ' years old.');
// John is 30 years old.
Creating own format function
String.prototype.format = function () {
var args = arguments;
return this.replace(/{([0-9]+)}/g, function (match, index) {
// check if the argument is there
return typeof args[index] == 'undefined' ? match : args[index];
});
};
console.log('{0} is {1} years old.'.format('John', 30));
JavaScript programmers can use String.prototype.sprintf at https://github.com/ildar-shaimordanov/jsxt/blob/master/js/String.js. Below is example:
var d = new Date();
var dateStr = '%02d:%02d:%02d'.sprintf(
d.getHours(),
d.getMinutes(),
d.getSeconds());
I want to share my solution for the 'problem'. I haven't re-invented the wheel but tries to find a solution based on what JavaScript already does. The advantage is, that you get all implicit conversions for free. Setting the prototype property $ of String gives a very nice and compact syntax (see examples below). It is maybe not the most efficient way, but in most cases dealing with output it does not have to be super optimized.
String.form = function(str, arr) {
var i = -1;
function callback(exp, p0, p1, p2, p3, p4) {
if (exp=='%%') return '%';
if (arr[++i]===undefined) return undefined;
exp = p2 ? parseInt(p2.substr(1)) : undefined;
var base = p3 ? parseInt(p3.substr(1)) : undefined;
var val;
switch (p4) {
case 's': val = arr[i]; break;
case 'c': val = arr[i][0]; break;
case 'f': val = parseFloat(arr[i]).toFixed(exp); break;
case 'p': val = parseFloat(arr[i]).toPrecision(exp); break;
case 'e': val = parseFloat(arr[i]).toExponential(exp); break;
case 'x': val = parseInt(arr[i]).toString(base?base:16); break;
case 'd': val = parseFloat(parseInt(arr[i], base?base:10).toPrecision(exp)).toFixed(0); break;
}
val = typeof(val)=='object' ? JSON.stringify(val) : val.toString(base);
var sz = parseInt(p1); /* padding size */
var ch = p1 && p1[0]=='0' ? '0' : ' '; /* isnull? */
while (val.length<sz) val = p0 !== undefined ? val+ch : ch+val; /* isminus? */
return val;
}
var regex = /%(-)?(0?[0-9]+)?([.][0-9]+)?([#][0-9]+)?([scfpexd%])/g;
return str.replace(regex, callback);
}
String.prototype.$ = function() {
return String.form(this, Array.prototype.slice.call(arguments));
}
Here are a few examples:
String.format("%s %s", [ "This is a string", 11 ])
console.log("%s %s".$("This is a string", 11))
var arr = [ "12.3", 13.6 ]; console.log("Array: %s".$(arr));
var obj = { test:"test", id:12 }; console.log("Object: %s".$(obj));
console.log("%c", "Test");
console.log("%5d".$(12)); // ' 12'
console.log("%05d".$(12)); // '00012'
console.log("%-5d".$(12)); // '12 '
console.log("%5.2d".$(123)); // ' 120'
console.log("%5.2f".$(1.1)); // ' 1.10'
console.log("%10.2e".$(1.1)); // ' 1.10e+0'
console.log("%5.3p".$(1.12345)); // ' 1.12'
console.log("%5x".$(45054)); // ' affe'
console.log("%20#2x".$("45054")); // ' 1010111111111110'
console.log("%6#2d".$("111")); // ' 7'
console.log("%6#16d".$("affe")); // ' 45054'
Adding to zippoxer's answer, I use this function:
String.prototype.format = function () {
var a = this, b;
for (b in arguments) {
a = a.replace(/%[a-z]/, arguments[b]);
}
return a; // Make chainable
};
var s = 'Hello %s The magic number is %d.';
s.format('world!', 12); // Hello World! The magic number is 12.
I also have a non-prototype version which I use more often for its Java-like syntax:
function format() {
var a, b, c;
a = arguments[0];
b = [];
for(c = 1; c < arguments.length; c++){
b.push(arguments[c]);
}
for (c in b) {
a = a.replace(/%[a-z]/, b[c]);
}
return a;
}
format('%d ducks, 55 %s', 12, 'cats'); // 12 ducks, 55 cats
ES 2015 update
All the cool new stuff in ES 2015 makes this a lot easier:
function format(fmt, ...args){
return fmt
.split("%%")
.reduce((aggregate, chunk, i) =>
aggregate + chunk + (args[i] || ""), "");
}
format("Hello %%! I ate %% apples today.", "World", 44);
// "Hello World, I ate 44 apples today."
I figured that since this, like the older ones, doesn't actually parse the letters, it might as well just use a single token %%. This has the benefit of being obvious and not making it difficult to use a single %. However, if you need %% for some reason, you would need to replace it with itself:
format("I love percentage signs! %%", "%%");
// "I love percentage signs! %%"
+1 Zippo with the exception that the function body needs to be as below or otherwise it appends the current string on every iteration:
String.prototype.format = function() {
var formatted = this;
for (var arg in arguments) {
formatted = formatted.replace("{" + arg + "}", arguments[arg]);
}
return formatted;
};
I use a small library called String.format for JavaScript which supports most of the format string capabilities (including format of numbers and dates), and uses the .NET syntax. The script itself is smaller than 4 kB, so it doesn't create much of overhead.
I'll add my own discoveries which I've found since I asked:
number_format (for thousand separator/currency formatting)
sprintf (same author as above)
Sadly it seems sprintf doesn't handle thousand separator formatting like .NET's string format.
If you are looking to handle the thousands separator, you should really use toLocaleString() from the JavaScript Number class since it will format the string for the user's region.
The JavaScript Date class can format localized dates and times.
Very elegant:
String.prototype.format = function (){
var args = arguments;
return this.replace(/\{\{|\}\}|\{(\d+)\}/g, function (curlyBrack, index) {
return ((curlyBrack == "{{") ? "{" : ((curlyBrack == "}}") ? "}" : args[index]));
});
};
// Usage:
"{0}{1}".format("{1}", "{0}")
Credit goes to (broken link) https://gist.github.com/0i0/1519811
There is "sprintf" for JavaScript which you can find at http://www.webtoolkit.info/javascript-sprintf.html.
The PHPJS project has written JavaScript implementations for many of PHP's functions. Since PHP's sprintf() function is basically the same as C's printf(), their JavaScript implementation of it should satisfy your needs.
I use this one:
String.prototype.format = function() {
var newStr = this, i = 0;
while (/%s/.test(newStr))
newStr = newStr.replace("%s", arguments[i++])
return newStr;
}
Then I call it:
"<h1>%s</h1><p>%s</p>".format("Header", "Just a test!");
I have a solution very close to Peter's, but it deals with number and object case.
if (!String.prototype.format) {
String.prototype.format = function() {
var args;
args = arguments;
if (args.length === 1 && args[0] !== null && typeof args[0] === 'object') {
args = args[0];
}
return this.replace(/{([^}]*)}/g, function(match, key) {
return (typeof args[key] !== "undefined" ? args[key] : match);
});
};
}
Maybe it could be even better to deal with the all deeps cases, but for my needs this is just fine.
"This is an example from {name}".format({name:"Blaine"});
"This is an example from {0}".format("Blaine");
PS: This function is very cool if you are using translations in templates frameworks like AngularJS:
<h1> {{('hello-message'|translate).format(user)}} <h1>
<h1> {{('hello-by-name'|translate).format( user ? user.name : 'You' )}} <h1>
Where the en.json is something like
{
"hello-message": "Hello {name}, welcome.",
"hello-by-name": "Hello {0}, welcome."
}
One very slightly different version, the one I prefer (this one uses {xxx} tokens rather than {0} numbered arguments, this is much more self-documenting and suits localization much better):
String.prototype.format = function(tokens) {
var formatted = this;
for (var token in tokens)
if (tokens.hasOwnProperty(token))
formatted = formatted.replace(RegExp("{" + token + "}", "g"), tokens[token]);
return formatted;
};
A variation would be:
var formatted = l(this);
that calls an l() localization function first.
For basic formatting:
var template = jQuery.validator.format("{0} is not a valid value");
var result = template("abc");
We can use a simple lightweight String.Format string operation library for Typescript.
String.Format():
var id = image.GetId()
String.Format("image_{0}.jpg", id)
output: "image_2db5da20-1c5d-4f1a-8fd4-b41e34c8c5b5.jpg";
String Format for specifiers:
var value = String.Format("{0:L}", "APPLE"); //output "apple"
value = String.Format("{0:U}", "apple"); // output "APPLE"
value = String.Format("{0:d}", "2017-01-23 00:00"); //output "23.01.2017"
value = String.Format("{0:s}", "21.03.2017 22:15:01") //output "2017-03-21T22:15:01"
value = String.Format("{0:n}", 1000000);
//output "1.000.000"
value = String.Format("{0:00}", 1);
//output "01"
String Format for Objects including specifiers:
var fruit = new Fruit();
fruit.type = "apple";
fruit.color = "RED";
fruit.shippingDate = new Date(2018, 1, 1);
fruit.amount = 10000;
String.Format("the {type:U} is {color:L} shipped on {shippingDate:s} with an amount of {amount:n}", fruit);
// output: the APPLE is red shipped on 2018-01-01 with an amount of 10.000
Just in case someone needs a function to prevent polluting global scope, here is the function that does the same:
function _format (str, arr) {
return str.replace(/{(\d+)}/g, function (match, number) {
return typeof arr[number] != 'undefined' ? arr[number] : match;
});
};
For those who like Node.JS and its util.format feature, I've just extracted it out into its vanilla JavaScript form (with only functions that util.format uses):
exports = {};
function isString(arg) {
return typeof arg === 'string';
}
function isNull(arg) {
return arg === null;
}
function isObject(arg) {
return typeof arg === 'object' && arg !== null;
}
function isBoolean(arg) {
return typeof arg === 'boolean';
}
function isUndefined(arg) {
return arg === void 0;
}
function stylizeNoColor(str, styleType) {
return str;
}
function stylizeWithColor(str, styleType) {
var style = inspect.styles[styleType];
if (style) {
return '\u001b[' + inspect.colors[style][0] + 'm' + str +
'\u001b[' + inspect.colors[style][3] + 'm';
} else {
return str;
}
}
function isFunction(arg) {
return typeof arg === 'function';
}
function isNumber(arg) {
return typeof arg === 'number';
}
function isSymbol(arg) {
return typeof arg === 'symbol';
}
function formatPrimitive(ctx, value) {
if (isUndefined(value))
return ctx.stylize('undefined', 'undefined');
if (isString(value)) {
var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
.replace(/'/g, "\\'")
.replace(/\\"/g, '"') + '\'';
return ctx.stylize(simple, 'string');
}
if (isNumber(value)) {
// Format -0 as '-0'. Strict equality won't distinguish 0 from -0,
// so instead we use the fact that 1 / -0 < 0 whereas 1 / 0 > 0 .
if (value === 0 && 1 / value < 0)
return ctx.stylize('-0', 'number');
return ctx.stylize('' + value, 'number');
}
if (isBoolean(value))
return ctx.stylize('' + value, 'boolean');
// For some reason typeof null is "object", so special case here.
if (isNull(value))
return ctx.stylize('null', 'null');
// es6 symbol primitive
if (isSymbol(value))
return ctx.stylize(value.toString(), 'symbol');
}
function arrayToHash(array) {
var hash = {};
array.forEach(function (val, idx) {
hash[val] = true;
});
return hash;
}
function objectToString(o) {
return Object.prototype.toString.call(o);
}
function isDate(d) {
return isObject(d) && objectToString(d) === '[object Date]';
}
function isError(e) {
return isObject(e) &&
(objectToString(e) === '[object Error]' || e instanceof Error);
}
function isRegExp(re) {
return isObject(re) && objectToString(re) === '[object RegExp]';
}
function formatError(value) {
return '[' + Error.prototype.toString.call(value) + ']';
}
function formatPrimitiveNoColor(ctx, value) {
var stylize = ctx.stylize;
ctx.stylize = stylizeNoColor;
var str = formatPrimitive(ctx, value);
ctx.stylize = stylize;
return str;
}
function isArray(ar) {
return Array.isArray(ar);
}
function hasOwnProperty(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
var name, str, desc;
desc = Object.getOwnPropertyDescriptor(value, key) || {value: value[key]};
if (desc.get) {
if (desc.set) {
str = ctx.stylize('[Getter/Setter]', 'special');
} else {
str = ctx.stylize('[Getter]', 'special');
}
} else {
if (desc.set) {
str = ctx.stylize('[Setter]', 'special');
}
}
if (!hasOwnProperty(visibleKeys, key)) {
name = '[' + key + ']';
}
if (!str) {
if (ctx.seen.indexOf(desc.value) < 0) {
if (isNull(recurseTimes)) {
str = formatValue(ctx, desc.value, null);
} else {
str = formatValue(ctx, desc.value, recurseTimes - 1);
}
if (str.indexOf('\n') > -1) {
if (array) {
str = str.split('\n').map(function (line) {
return ' ' + line;
}).join('\n').substr(2);
} else {
str = '\n' + str.split('\n').map(function (line) {
return ' ' + line;
}).join('\n');
}
}
} else {
str = ctx.stylize('[Circular]', 'special');
}
}
if (isUndefined(name)) {
if (array && key.match(/^\d+$/)) {
return str;
}
name = JSON.stringify('' + key);
if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
name = name.substr(1, name.length - 2);
name = ctx.stylize(name, 'name');
} else {
name = name.replace(/'/g, "\\'")
.replace(/\\"/g, '"')
.replace(/(^"|"$)/g, "'")
.replace(/\\\\/g, '\\');
name = ctx.stylize(name, 'string');
}
}
return name + ': ' + str;
}
function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
var output = [];
for (var i = 0, l = value.length; i < l; ++i) {
if (hasOwnProperty(value, String(i))) {
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
String(i), true));
} else {
output.push('');
}
}
keys.forEach(function (key) {
if (!key.match(/^\d+$/)) {
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
key, true));
}
});
return output;
}
function reduceToSingleString(output, base, braces) {
var length = output.reduce(function (prev, cur) {
return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
}, 0);
if (length > 60) {
return braces[0] +
(base === '' ? '' : base + '\n ') +
' ' +
output.join(',\n ') +
' ' +
braces[1];
}
return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
}
function formatValue(ctx, value, recurseTimes) {
// Provide a hook for user-specified inspect functions.
// Check that value is an object with an inspect function on it
if (ctx.customInspect &&
value &&
isFunction(value.inspect) &&
// Filter out the util module, it's inspect function is special
value.inspect !== exports.inspect &&
// Also filter out any prototype objects using the circular check.
!(value.constructor && value.constructor.prototype === value)) {
var ret = value.inspect(recurseTimes, ctx);
if (!isString(ret)) {
ret = formatValue(ctx, ret, recurseTimes);
}
return ret;
}
// Primitive types cannot have properties
var primitive = formatPrimitive(ctx, value);
if (primitive) {
return primitive;
}
// Look up the keys of the object.
var keys = Object.keys(value);
var visibleKeys = arrayToHash(keys);
if (ctx.showHidden) {
keys = Object.getOwnPropertyNames(value);
}
// This could be a boxed primitive (new String(), etc.), check valueOf()
// NOTE: Avoid calling `valueOf` on `Date` instance because it will return
// a number which, when object has some additional user-stored `keys`,
// will be printed out.
var formatted;
var raw = value;
try {
// the .valueOf() call can fail for a multitude of reasons
if (!isDate(value))
raw = value.valueOf();
} catch (e) {
// ignore...
}
if (isString(raw)) {
// for boxed Strings, we have to remove the 0-n indexed entries,
// since they just noisey up the output and are redundant
keys = keys.filter(function (key) {
return !(key >= 0 && key < raw.length);
});
}
// Some type of object without properties can be shortcutted.
if (keys.length === 0) {
if (isFunction(value)) {
var name = value.name ? ': ' + value.name : '';
return ctx.stylize('[Function' + name + ']', 'special');
}
if (isRegExp(value)) {
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
}
if (isDate(value)) {
return ctx.stylize(Date.prototype.toString.call(value), 'date');
}
if (isError(value)) {
return formatError(value);
}
// now check the `raw` value to handle boxed primitives
if (isString(raw)) {
formatted = formatPrimitiveNoColor(ctx, raw);
return ctx.stylize('[String: ' + formatted + ']', 'string');
}
if (isNumber(raw)) {
formatted = formatPrimitiveNoColor(ctx, raw);
return ctx.stylize('[Number: ' + formatted + ']', 'number');
}
if (isBoolean(raw)) {
formatted = formatPrimitiveNoColor(ctx, raw);
return ctx.stylize('[Boolean: ' + formatted + ']', 'boolean');
}
}
var base = '', array = false, braces = ['{', '}'];
// Make Array say that they are Array
if (isArray(value)) {
array = true;
braces = ['[', ']'];
}
// Make functions say that they are functions
if (isFunction(value)) {
var n = value.name ? ': ' + value.name : '';
base = ' [Function' + n + ']';
}
// Make RegExps say that they are RegExps
if (isRegExp(value)) {
base = ' ' + RegExp.prototype.toString.call(value);
}
// Make dates with properties first say the date
if (isDate(value)) {
base = ' ' + Date.prototype.toUTCString.call(value);
}
// Make error with message first say the error
if (isError(value)) {
base = ' ' + formatError(value);
}
// Make boxed primitive Strings look like such
if (isString(raw)) {
formatted = formatPrimitiveNoColor(ctx, raw);
base = ' ' + '[String: ' + formatted + ']';
}
// Make boxed primitive Numbers look like such
if (isNumber(raw)) {
formatted = formatPrimitiveNoColor(ctx, raw);
base = ' ' + '[Number: ' + formatted + ']';
}
// Make boxed primitive Booleans look like such
if (isBoolean(raw)) {
formatted = formatPrimitiveNoColor(ctx, raw);
base = ' ' + '[Boolean: ' + formatted + ']';
}
if (keys.length === 0 && (!array || value.length === 0)) {
return braces[0] + base + braces[1];
}
if (recurseTimes < 0) {
if (isRegExp(value)) {
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
} else {
return ctx.stylize('[Object]', 'special');
}
}
ctx.seen.push(value);
var output;
if (array) {
output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
} else {
output = keys.map(function (key) {
return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
});
}
ctx.seen.pop();
return reduceToSingleString(output, base, braces);
}
function inspect(obj, opts) {
// default options
var ctx = {
seen: [],
stylize: stylizeNoColor
};
// legacy...
if (arguments.length >= 3) ctx.depth = arguments[2];
if (arguments.length >= 4) ctx.colors = arguments[3];
if (isBoolean(opts)) {
// legacy...
ctx.showHidden = opts;
} else if (opts) {
// got an "options" object
exports._extend(ctx, opts);
}
// set default options
if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
if (isUndefined(ctx.depth)) ctx.depth = 2;
if (isUndefined(ctx.colors)) ctx.colors = false;
if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
if (ctx.colors) ctx.stylize = stylizeWithColor;
return formatValue(ctx, obj, ctx.depth);
}
exports.inspect = inspect;
// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
inspect.colors = {
'bold': [1, 22],
'italic': [3, 23],
'underline': [4, 24],
'inverse': [7, 27],
'white': [37, 39],
'grey': [90, 39],
'black': [30, 39],
'blue': [34, 39],
'cyan': [36, 39],
'green': [32, 39],
'magenta': [35, 39],
'red': [31, 39],
'yellow': [33, 39]
};
// Don't use 'blue' not visible on cmd.exe
inspect.styles = {
'special': 'cyan',
'number': 'yellow',
'boolean': 'yellow',
'undefined': 'grey',
'null': 'bold',
'string': 'green',
'symbol': 'green',
'date': 'magenta',
// "name": intentionally not styling
'regexp': 'red'
};
var formatRegExp = /%[sdj%]/g;
exports.format = function (f) {
if (!isString(f)) {
var objects = [];
for (var j = 0; j < arguments.length; j++) {
objects.push(inspect(arguments[j]));
}
return objects.join(' ');
}
var i = 1;
var args = arguments;
var len = args.length;
var str = String(f).replace(formatRegExp, function (x) {
if (x === '%%') return '%';
if (i >= len) return x;
switch (x) {
case '%s':
return String(args[i++]);
case '%d':
return Number(args[i++]);
case '%j':
try {
return JSON.stringify(args[i++]);
} catch (_) {
return '[Circular]';
}
default:
return x;
}
});
for (var x = args[i]; i < len; x = args[++i]) {
if (isNull(x) || !isObject(x)) {
str += ' ' + x;
} else {
str += ' ' + inspect(x);
}
}
return str;
};
Harvested from: https://github.com/joyent/node/blob/master/lib/util.js
I have a slightly longer formatter for JavaScript here...
You can do formatting several ways:
String.format(input, args0, arg1, ...)
String.format(input, obj)
"literal".format(arg0, arg1, ...)
"literal".format(obj)
Also, if you have say a ObjectBase.prototype.format (such as with DateJS) it will use that.
Examples...
var input = "numbered args ({0}-{1}-{2}-{3})";
console.log(String.format(input, "first", 2, new Date()));
//Outputs "numbered args (first-2-Thu May 31 2012...Time)-{3})"
console.log(input.format("first", 2, new Date()));
//Outputs "numbered args(first-2-Thu May 31 2012...Time)-{3})"
console.log(input.format(
"object properties ({first}-{second}-{third:yyyy-MM-dd}-{fourth})"
,{
'first':'first'
,'second':2
,'third':new Date() //assumes Date.prototype.format method
}
));
//Outputs "object properties (first-2-2012-05-31-{3})"
I've also aliased with .asFormat and have some detection in place in case there's already a string.format (such as with MS Ajax Toolkit (I hate that library).
Using Lodash you can get template functionality:
Use the ES template literal delimiter as an "interpolate" delimiter.
Disable support by replacing the "interpolate" delimiter.
var compiled = _.template('hello ${ user }!');
compiled({ 'user': 'pebbles' });
// => 'hello pebbles!

PEGjs: Fallback (backtrack?) to string if floating point rule fail

I have an atom rule that tries to parse everything as either a number or a quoted string first, if that fails, then treat the thing as a string.
Everything parses fine except one particular case that is this very specific string:
DUD 123abc
Which fails to parse with Expected " ", "." or [0-9] but "a" found. error.
What I expect: it should parse successfully and return string "123abc" as a string atom. You can see several of my unsuccessful attempts commented out in the grammar content below.
Any help/tips/pointers/suggestions appreciated!
You can try the grammar on the online PEG.js version. I'm using node v0.8.23 and pegjs 0.7.0
Numbers that parses correctly:
`123
`0
`0.
`1.
`.23
`0.23
`1.23
`0.000
. <--- as string, not number and not error
I want 123abc to be parsed as a string, is this possible?
This is my entire grammar file:
start = lines:line+ { return lines; }
// --------------------- LINE STRUCTURE
line = command:command eol { return command; }
command = action:atom args:(sep atom)*
{
var i = 0, len = 0;
for (var i = 0, len = args.length; i < len; i++) {
// discard parsed separator tokens
args[i] = args[i][1];
}
return [action, args];
}
sep = ' '+
eol = "\r" / "\n" / "\r\n"
atom = num:number { return num; }
/ str:string_quoted { return str; }
/ str:string { return str; }
// --------------------- COMMANDS
// TODO:
// --------------------- STRINGS
string = chars:([^" \r\n]+) { return chars.join(''); }
string_quoted = '"' chars:quoted_chars* '"' { return chars.join(''); }
quoted_chars = '\\"' { return '"'; }
/ char:[^"\r\n] { return char; }
// --------------------- NUMBERS
number = integral:('0' / [1-9][0-9]*) fraction:("." [0-9]*)?
{
if (fraction && fraction.length) {
fraction = fraction[0] + fraction[1].join('');
} else {
fraction = '';
}
integral = integral instanceof Array ?
integral[0] + integral[1].join('') :
'0';
return parseFloat(integral + fraction);
}
/ ("." / "0.") fraction:[0-9]+
{
return parseFloat("0." + fraction.join(''));
}
/*
float = integral:integer? fraction:fraction { return integral + fraction; }
fraction = '.' digits:[0-9]* { return parseFloat('0.' + digits.join('')); }
integer = digits:('0' / [1-9][0-9]*)
{
if (digits === '0') return 0;
return parseInt(digits[0] + digits[1].join(''), 10);
}
*/
Solved this by adding !([0-9\.]+[^0-9\.]) which is sort of a look-ahead infront of the number rule.
I know that the atom rule will match so what it effectively does is making the number rule fails a bit sooner. Hopefully this can helps someone with ambiguous cases in the future.
So the number rule now becomes:
number = !([0-9\.]+[^0-9\.]) integral:('0' / [1-9][0-9]*) fraction:("." [0-9]*)?
I think that checking that the character trailing number is a number-separator (not an alphanum) would have also worked, and more cheaply.
number = integral:('0' / [1-9][0-9]*) fraction:("." [0-9]*)? !([0-9A-Za-z])

if/else and if/elseif

If I have a statement block like this:
if (/*condition here*/){ }
else{ }
or like this:
if (/*condition here*/)
else if (/*condition here*/) {}
else if (/*condition here*/) {}
What is the difference?
It seems that with if/else, if part is for true state and the else part is for all other possible options (false). An else-if would be useful for a number of conditions. This is my understanding, is there anything more I should be aware of?
Without "elseif" syntax you would have to write chain if-statements for processing one of several possible outcomes this way:
if( str == "string1" ) {
//handle first case
} else {
if( str == "string2" ) {
//handle second case
} else {
if( str == "string3" ) {
//handle third case
} else {
//default case
}
}
}
instead you can write
if( str == "string1" ) {
//handle first case
} else if( str == "string2" ) {
//handle second case
} else if( str == "string3" ) {
//handle third case
} else {
//default case
}
which is completely the same as the previous one, but looks much nicer and is much easier to read.
Situation a:
if( condition )
{
}
else
{
}
When the condition in the above statement is false, then the statements in the else block will always be executed.
Situation b:
if( condition )
{
}
else if( condition2 )
{
}
else
{
}
When 'condition' is false, then the statements in the else if block will only be executed when condition2 is true.
The statements in the else block will be executed when condition2 is false.
Many languages have a grammer like this (here: ECMAScript Language Specification, so JavaScript):
IfStatement :
    if ( Expression ) Statement else Statement
    if ( Expression ) Statement
Statement :
    Block
    VariableStatement
    EmptyStatement
    ExpressionStatement
    IfStatement
    IterationStatement
    ContinueStatement
    BreakStatement
    ReturnStatement
    WithStatement
    LabelledStatement
    SwitchStatement
    ThrowStatement
    TryStatement
Block :
    { StatementListopt }
StatementList :
    Statement
    StatementList Statement
So the branches of an ifStatement may contain a block of statements (Block) or one of the other statements (other than Block). That means this is valid:
if (expr)
someStatement;
else
otherStatement;
And as StatementList may just contain a single statement, these examples are equivalent to the previous:
if (expr) {
someStatement;
} else {
otherStatement;
}
if (expr)
someStatement;
else {
otherStatement;
}
if (expr) {
someStatement;
} else
otherStatement;
And when we replace otherStatement by an additional IfStatement, we get this:
if (expr) {
someStatement;
} else
if (expr) {
someOtherStatement;
}
The rest is just code formatting:
if (expr) {
someStatement;
} else if (expr) {
someOtherStatement;
}
Emphasizing what Gumbo said.
Also, if a language has a real elif / elsif / elseif (say, a "real" else-if instruction, instead of a kind of nested chaining hidden away by formatting), then the compiler can easly emit a single node in an Abstract Syntax Tree (or similar, see http://en.wikipedia.org/wiki/Abstract_syntax_tree) instead of nesting them.
To give an example:
Say in C/C++ you have:
if (a) {
X
} else if (b) {
Y
} else if (c) {
Z
} else {
0
}
Then the compiler will build an AST-node like this:
a
/ \
X b
/ \
Y c
/ \
Z 0
But if the language of choice has a real if-else:
if (a) {
X
} elif (b) {
Y
} elif (c) {
Z
} else {
0
}
Then the AST could more easily look like this:
(a--b--c)
/ / / \
X Y Z 0
In such a language, an "if else" would only be possible if braces are not mandatory:
if (a) {
X
} elif (b) {
Y
} else if (c) { // syntax error "missing braces" if braces mandatory
Z
} else {
0
}
Corresponding AST (if braces are not mandatory):
(a--b)
/ / \
X Y c
/ \
Z 0
This could make CFG-Analysis (http://en.wikipedia.org/wiki/Control_flow_graph) easier to implement (though there might be no actual optimization benefit; so imho it'd just benefit the lazy programmer :D).
else if basically means the else part of if is another if statement.
**if/else**
if(condition)
statement;
else
statement;
if/ else if /else
if(condition)
{
if(condition)
statement;
else
statement;
}
else if(condition)
{
if(condition)
statement;
else
statement;
}
else
statement;
if/else and if/else if used also like this
Given a single variable, you will use the simple if-else structure. When there are multiple variables and you have a different path to execute for the different possibilities, you will use if-else if-...-else. Note, that the latter also ends with an else statement.
You already gave the answer yourself. if/else is for true/false result, like is an int=2 or any other possible int value, and if/elseif is for more than 2 results, like an int=2, and int=3 and so on.
Also it groups the context of a variable. You could check every single result like
if (a == 2) { do one thing };
if (a == 3) { do another thing };
...
if (a != 2 && a != 3 ...) { do something else };
With if/else/elseif it's better readable.
if you want to check more condition we can use if..elseif. single condition then we can use if or if...else.
Here I can't able to upload the full explanation with example so please go through the following links.
if..else statement details
http://allinworld99.blogspot.in/2016/02/ifelse-flow-chart-with-easy-example.html
if...elseif details
http://allinworld99.blogspot.in/2016/02/flow-chart-with-example-for-if-then.html
import java.util.*;
public class JavaApplication21 {
public static void main(String[] args) {
Scanner obj = new Scanner(System.in);
System.out.println("You are watching an example of if & else if statements");
int choice, a, b, c, d;
System.out.println(" Enter 1-Addition & 2-Substraction");
int option = obj.nextInt();
switch (option) {
case (1):
System.out.println("how many numbers you want to add.... it can add up to 3 numbers only");
choice = obj.nextInt();
if (choice == 2) {
System.out.println("Enter 1st number");
a = obj.nextInt();
System.out.println("Enter 2nd number");
b = obj.nextInt();
c = a + b;
System.out.println("Answer of adding " + a + " & " + b + " is= " + c);
} else if (choice == 3) {
System.out.println("Enter 1st number");
a = obj.nextInt();
System.out.println("Enter 2nd number");
b = obj.nextInt();
System.out.println("Enter 3rd number");
c = obj.nextInt();
d = a + b + c;
System.out.println("Answer of adding " + a + " , " + b + " & " + c + " is= " + d);
}
case (2):
System.out.println("how many numbers you want to substract.... it can substract up to 3 numbers only");
choice = obj.nextInt();
if (choice == 2) {
System.out.println("Enter 1st number");
a = obj.nextInt();
System.out.println("Enter 2nd number");
b = obj.nextInt();
c = a - b;
System.out.println("Answer of substracting " + a + " & " + b + " is= " + c);
} else if (choice == 3) {
System.out.println("Enter 1st number");
a = obj.nextInt();
System.out.println("Enter 2nd number");
b = obj.nextInt();
System.out.println("Enter 3rd number");
c = obj.nextInt();
d = a - b - c;
System.out.println("Answer of substracting " + a + " , " + b + " & " + c + " is= " + d);
}
default:
System.out.println("no option you have chosen" + option);
}
}
}
// simple if-else statement
if(condition)
{
statement;
}
else
{
statement;
}

Resources