I am trying to port some Python code and I am a little lost on small issue which I would appreciate some advice.
I understand the in operator but I am a little unclear on what the : operator does in this example.
if foo in bar[i][:2]:
# do something
In http://docs.python.org/tutorial/introduction.html#strings it states that the : operator makes the first two characters only if this is a string. However when used with a list like this is that what will happen as well? So does this just mean the first 2 characters of the string in th
This is called list slicing, you already link to the proper part of the documentation in your question. If you find documentation confusing, there is a video tutorial for that:
http://www.youtube.com/watch?v=iD6a0G8MnjA
The behaviour of the operator doesn't depend on where its operands come from - it doesn't matter whether it was a literal, a variable, or a complex expression. The operator does its thing because its operand is a string, not because it was computed in a particular way.
Related
The literal 3e4 represents the float 30000 in python (3.8 at least).
>>> print(3e4)
30000.0
The syntax of the following code is clearly invalid:
x=4
3ex
3ex is not a valid expression, but the example helps me ask my question:
Clearly, the expression 3*10**4 represents the same number, but my question here is purely related to the scientific notation literals. Just for my curiosity, is there a way to use the same syntax with a variable power, better than:
x=4
eval(f"1e{x}")
One subtle difference between 3e4 and 3*10**4 is the type (float and int respectively).
Is there also a difference in execution time perhaps in calculating these two expressions?
To your first question: No, the documentation does not suggest you can.
Is there a way to use the same syntax with a variable power?
When float is instantiated from a string, it calls out to a CPython C library PyOS_string_to_double to which handles making the str locale-aware (. vs ,) before passing the string directly to the C function strtod doc.
Meanwhile the documentation for PyOS_string_to_double does not mention of any special way to configure the exponent.
To your second question about performance, this is easily benchmarked. But, we do not have a candidate to benchmark against. So, this is a moot question.
Is there also a difference in execution time perhaps?
I hope this satiates your curiosity. If not, feel free to dig into the C code that I linked.
Is it possible to do the opposite of eval() in python which treats inputs as literal strings? For example f(Node(2)) -> 'Node(2)' or if there's some kind of higher-order operator that stops interpreting the input like lisp's quote() operator.
The answer to does Python have quote is no, Python does not have quote. There's no homoiconicity, and no native infrastructure to represent the languages own source code.
Now for what is the opposite of eval: you seem to be missing some part the picture here. Python's eval is not the opposite of quote. There's three types values can be represented as: as unparsed strings, as expressions, and as values (of any type).
quote and LISP-style "eval" convert between expressions and values.
Parsing and pretty printing form another pair between expressions and strings.
Python's actual eval goes directly from strings to values, and repr goes back (in the sense of printing a parsable value1).
Since SO does not support drawing diagrams:
So if you are looking for the opposite of eval, it's either trivially repr, but that might not really help you, or it would be the composition of quote and pretty priniting, if there were quoting in Python.
This composition with string functions a bit cumbersome, which is why LISPs let the reader deal with parsing once and for all, and from that point on only go between expressions and values. I don't know any language that has such a "quote + print" function, actually (C#'s nameof comes close, but is restricted to names).
Some caveats about the diagram:
It does not commute: you have deal with pure values or disregard side effects, for one, and most importantly quote is not really a function in some sense, of course. It's a special form. That's why repr(x) is not the same as prettyprint(quote(x)), in general.
It's not depicting pairs of isomorphisms. Multiple expressions can eval to the same value etc.
1That's not always the case in reality, but that's what it's suppsedly there for.
I have an xpath in the following format
xpath='//*[#id="peoplegrid"]/div[5]/div[1]/a'
I want to pass a string to the first div in the x path in the following manner
x=[1,2,3,4,5]
for i in x:
xpath='//*[#id="peoplegrid"]/div[',+str(i),']/div[1]/a'
print(xpath)
However when I run this, it states that bad operand type for unary +: 'str'
How can I pass a string to this xpath
Following is the full piece of code I am working on
x=[1,2,3,4]
for i in x:
python_button=driver.find_element_by_xpath('//*[#id="peoplegrid"]/div,'+[str(x)]+'/div[1]/a')
python_button.click()
driver.execute_script("window.history.go(-1)")
You're missing the second +. Try something like this.
xpath='//*[#id="peoplegrid"]/div['+str(i)+']/div[1]/a'
I cannot update #Steven's answer with such a subtle (less than 6 character) change, so I've created my own answer.
What you need is the following:
xpath='//*[#id="peoplegrid"]/div['+str(i)+']/div[1]/a'
As you can tell, between my answer and #Steven's answer, mine does not include the commas within the first div portion of the XPATH. For your purposes, it is unnecessary and invalid to place the commas in the string. Commas are typically used in print statements to prevent newlines from being appended to the output.
EDIT: In regards to the change to the original post and the comments therein, concatenating a list to a string is also invalid. Merely use an interpreter and try compiling the code, and a TypeError: must be str, not list will be thrown. This makes sense, since you cannot append a list directly to a str; however, if the contents of the list are strings, or can be converted to strings, then you can concatenate these. See here for an explanation of string concatentation in Python.
It's best to avoid constructing the XPath expression by string concatenation. Disadvantages:
(a) you need to worry about escaping strings that contain special characters
(b) you need to REALLY worry about it if there's any possibility of people inserting bad strings maliciously (XPath injection attacks)
(c) you have to compile the expression each time it's used.
I don't know the Python API you are using, but most XPath APIs allow you to compile an expression containing variables (eg. '//[#id="peoplegrid"]/div[$param]/div[1]/a') and then bind a value to the variable separately. If you can do this then it's much preferable and avoids the above disadvantages.
I want users to input math formula in my system. How can convert case1 formula to case2 formula using Python? In another word, I would like to change math order specifically for double asterisks.
#case1
3*2**3**2*5
>>>7680
#case2
3*(2**3)**2*5
>>>960
Not only is this not something that Python supports, but really, why would you want to? Modifying BIDMAS or PEMDAS (depending on your location), would not only give you incorrect answers, but also confuse the hell out of any devs looking at the code.
Just use brackets like in Case 2, it's what they're for.
If users are supposed to enter formulas into your program, I would suggest keeping it as is. The reason is that exponentiation in mathematics is right-associative, meaning the execution goes from the top level down. For example: a**b**c = a**(b**c), by convention.
There are some programs that use bottom-up resolution of the stacked exponentiation -- MS Excel and LibreOffice are some of them, however, it is against the regular convention, and always confused the hell out of me.
If you would like to override this behavior, and still be mathematically correct, you have to use brackets.
You can always declare your own power method that would resolve the way you want it -- something like numpy.pow(). You could overload the built-in, but that's too much hastle.
Read this
Below is the example to achieve this using re as:
expression = '3*2**3**2*5'
asterisk_exprs = re.findall(r"\d+\*\*\d+", expression) # List of all expressions matching the criterion
for expr in asterisk_exprs:
expression = expression.replace(expr, "({})".format(expr)) # Replace the expression with required expression
# Value of variable 'expression': '3*(2**3)**2*5'
In order to evaluate the mathematical value of str expression, use eval as:
>>> eval(expression)
960
How can I allow users to execute mathematical expressions in a safe way?
Do I need to write a full parser?
Is there something like ast.literal_eval(), but for expressions?
The examples provided with Pyparsing include several expression parsers:
https://github.com/pyparsing/pyparsing/blob/master/examples/fourFn.py is a conventional arithmetic infix notation parser/evaluator implementation using pyparsing. (Despite its name, this actually does 5-function arithmetic, plus several trig functions.)
https://github.com/pyparsing/pyparsing/blob/master/examples/simpleBool.py is a boolean infix notation parser/evaluator, using a pyparsing helper method operatorPrecedence, which simplifies the definition of infix operator notations.
https://github.com/pyparsing/pyparsing/blob/master/examples/simpleArith.py and https://github.com/pyparsing/pyparsing/blob/master/examples/eval_arith.py recast fourFn.py using operatorPrecedence. The first just parses and returns a parse tree; the second adds evaluation logic.
If you want a more pre-packaged solution, look at plusminus, a pyparsing-based extensible arithmetic parsing package.
What sort of expressions do you want? Variable assignment? Function evaluation?
SymPy aims to become a full-fledged Python CAS.
Few weeks ago I did similar thing, but for logical expressions (or, and, not, comparisons, parentheses etc.). I did this using Ply parser. I have created simple lexer and parser. Parser generated AST tree that was later use to perform calculations. Doing this in that way allow you to fully control what user enter, because only expressions that are compatible with grammar will be parsed.
Yes. Even if there were an equivalent of ast.literal_eval() for expressions, a Python expression can be lots of things other than just a pure mathematical expression, for example an arbitrary function call.
It wouldn't surprise me if there's already a good mathematical expression parser/evaluator available out there in some open-source module, but if not, it's pretty easy to write one of your own.
maths functions will consist of numeric and punctuation characters, possible 'E' or 'e' if you allow scientific notation for rational numbers, and the only (other) legal use of alpha characters will be if you allow/provide specific maths functions (e.g. stddev). So, should be trivial to run along the string for alpha characters and check the next little bit isn't suspicious, then simply eval the string in a try/except block.
Re the comments this reply has received... I agree this approach is playing with fire. Still, that doesn't mean it can't be done safely. I'm new to python (< 2 months), so may not know the workarounds to which this is vulnerable (and of course a new Python version could always render the code unsafe in the future), but - for what little it's worth (mainly my own amusement) - here's my crack at it:
def evalMaths(s):
i = 0
while i < len(s):
while s[i].isalpha() and i < len(s):
idn += s[i]
i += 1
if (idn and idn != 'e' and idn != 'abs' and idn != 'round'):
raise Exception("you naughty boy: don't " + repr(idn))
else:
i += 1
return eval(s)
I would be very interested to hear if/how it can be circumvented... (^_^) BTW / I know you can call functions like abs2783 or _983 - if they existed, but they won't. I mean something practical.
In fact, if anyone can do so, I'll create a question with 200 bounty and accept their answer.