Operators as Strings

operators as strings

The way I see it, you have two options - use an expression evaluator or construct, compile
and run C# code on the fly.

I would go with an expression evaluator library, as you do not have to worry about any security issues. That is, you might not be able to use code generation in medium trust environments, such as most shared hosting servers.

Here is an example for generating code to evaluate expressions:
http://www.vbforums.com/showthread.php?t=397264

Compare two strings with ' ' and ' ' operators in JavaScript

As said above, the formal specification is in the standard: http://www.ecma-international.org/ecma-262/7.0/#sec-abstract-relational-comparison , in layman's terms the logic is like this:

1) String vs String

Split both strings into 16-bit code units and compare them numerically. Note that code units != characters, e.g. "cafè" < "cafè" is true (really).

2) String vs other primitive

Convert both to numbers. If one of them is NaN, return false, otherwise compare numerically. +0 and -0 are considered equal, +/-Infinity is bigger/smaller than anything else.

3) String vs Object

Try to convert the object to a primitive, attempting, in order, [Symbol.toPrimitive]("number"), valueOf and toString. If we've got string, proceed to 1), otherwise proceed to 2). For arrays specifically, this will invoke toString which is the same as join.

Turn string into operator

Use a lookup table:

import operator
ops = { "+": operator.add, "-": operator.sub } # etc.

print(ops["+"](1,1)) # prints 2

python is operator behaviour with string

One important thing about this behavior is that Python caches some, mostly, short strings (usually less than 20 characters but not for every combination of them) so that they become quickly accessible. One important reason for that is that strings are widely used in Python's source code and it's an internal optimization to cache some special sorts of strings. Dictionaries are one of the generally used data structures in Python's source code that are used for preserving the variables, attributes, and namespaces in general, plus for some other purposes, and they all use strings as the object names. This is to say that every time you try to access an object attribute or have access to a variable (local or global) there's a dictionary lookup firing up internally.

Now, the reason that you got such bizarre behavior is that Python (CPython implementation) treats differently with strings in terms of interning. In Python's source code, there is a intern_string_constants function that gives strings the validation to be interned which you can check for more details. Or check this comprehensive article http://guilload.com/python-string-interning/.

It's also noteworthy that Python has an intern() function in the sys module that you can use to intern strings manually.

In [52]: b = sys.intern('a,,')

In [53]: c = sys.intern('a,,')

In [54]: b is c
Out[54]: True

You can use this function either when you want to fasten the dictionary lookups or when you're ought to use a particular string object frequently in your code.

Another point that you should not confuse with string interning is that when you do a == b, you're creating two references to the same object which is obvious for those keywords to have the same id.

Regarding punctuations, it seems that if they are one character they get interned if their length is more than one. If the length is more than one they won't get cached. As mentioned in the comments, one reason for that might be because it's less likely for keywords and dictionary keys to have punctuations in them.

In [28]: a = ','

In [29]: ',' is a
Out[29]: True

In [30]: a = 'abc,'

In [31]: 'abc,' is a
Out[31]: False

In [34]: a = ',,'

In [35]: ',,' is a
Out[35]: False

# Or

In [36]: a = '^'

In [37]: '^' is a
Out[37]: True

In [38]: a = '^%'

In [39]: '^%' is a
Out[39]: False

But still, these are just some speculations that you cannot rely on in your code.

How to compare strings with logical operators to a list of strings?

Despite being valid Python code, what you've written is semantically very far away from what you're trying to achieve. This is due to some incorrect assumptions about how the language behaves, or can be made to behave.

First of all, your "list of logical operators" looks and behaves nothing like what you're expecting. This:

["abc" or "def" and "ghi"]

Is a list literal, which will evaluate to a list containing a single string item thanks to short-circuit evaluation:

["abc"]

The expression "abc" or "def" and "ghi" will evaluate down to a single object, in this case "abc". Non-empty strings are considered "truthy", and the binary or operator only needs one of its operands to be true/truthy in order for the whole expression to evaluate as true/truthy.

Second, this:

if "abd" and "def" in a:

Must be parsed as:

if ("abd") and ("def" in a):

Again, when evaluated as a distinct boolean-expression, the string "abd" is non-empty, and therefore truthy. This is similar to saying:

if True and "def" in a:

or simply:

if "def" in a:

There are different ways to solve the issue, but perhaps the simplest solution you're looking for is:

if ("abc" in a) or ("def" in a and "ghi" in a):

Just because the code you've written reads like an English sentence to you, doesn't mean that this is how Python will interpret it.

Difference between usage of in operator in strings and list containing strings in python

For strings, the in operator returns true if the left-hand-side is a substring of the right-hand-side.

So "yo" in "without you" asks: Does the substring "yo" appear anywhere in the string "without you"? Yes.


For sequences (like lists), the in operator returns true if the left-hand-side is equal to any element in the right-hand-side.

"without you".split() will return ["without", "you"].

So "yo" in ["without", "you"] asks: Does"yo" equal one of those two strings? No.


See also

  • Membership test details (docs.python.org)
  • __contains__

Plus operator on strings in c++

The associativity of operator+ is left-to-right. Then "Hello" + ", world" + exclam is interpreted as ("Hello" + ", world") + exclam while "Hello" + ", world" is invalid. "Hello" and ", world" are const char[]s and could decay to pointer as const char* which can't be added.

Using std::string instead of c-style string, or changing the code to "Hello" + (", world" + exclam) works because there's operator+ for std::string which could accept two std::strings or a std::string and a c-style string (as either the 1st or 2nd operand), and it returns std::string which could be added further.

Perform arithmetic operations from operators defined as strings

Starting from JDK1.6 you can use built-in Javascript engine to evaluate this expression for you .

import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;

public class Main {
public static void main(String[] args) throws Exception{
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
String expression = "100+200/100*2";
System.out.println(engine.eval(expression));
}
}

So you can use it to calculate the expression according to operators precedence rules.

Also If you need just the count of solutions , it might be easier to use TreeSet then print the size of the set at the end.

Here is a full explanation :

public class Main {

public static void main(String[] args) {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("JavaScript");
int a = 100;
int b = 200;
int c = 300;
int d = 100;
String[] chars = {"+", "-", "*", "/"};
try {
TreeSet<String> set = new TreeSet<>();
for (int i=0; i<chars.length; i++){
for (int j=0; j<chars.length; j++){
for (int k=0; k<chars.length; k++){
String expression = a+chars[i]+b+chars[j]+c+chars[k]+d;
set.add(String.valueOf(engine.eval(expression)));
}
}
}
System.out.println(set.size());
} catch (ScriptException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
}


Related Topics



Leave a reply



Submit