I was wondering how I would go about converting Sympy's "Mod()" to Python's default syntax of the percent sign (%). I cannot find any "built-in" function (in the Sympy package). I could write one myself, except I want the result to be simplified. In the function that I would create, I've realized that I don't know how to avoid adding extra parentheses. Since I want it in its most simplified form, I would need to use Sympy's simplification. And that would then undo the conversion of "Mod()" to "%". So if there isn't an easy way to convert Sympy's Mod to Python's "%", please tell me there's a way in Sympy to simplify only parentheses. I've looked, and I haven't been able to find that either. I at least want a way to remove redundant parentheses without converting "%" back to "Mod".
Edit:
Here's an example, I want:
Mod(x + 1, 3)
to become:
(x+1)%3
But I don't want:
Mod(x, 3)
to be:
(x)%3
I want it to be:
x%3
Now that I have done a bit of looking into sympy's options for custom printing it looks like it is quite easy to implement:
from sympy.printing.precedence import precedence
from sympy.printing.str import StrPrinter
class MyPrinter(StrPrinter):
def _print_Mod(self,expr):
own_level = precedence(expr)
args = (self.parenthesize(arg, own_level) for arg in expr.args)
return "{} % {}".format(*args)
The printer's method parenthesize takes an expression and a "level" where the level represents the precedence threshold that causes it to actually add brackets around the argument, so it will only put parentheses around operations that need them:
from sympy.abc import x
printer = MyPrinter()
def test(expr):
print(printer.doprint(expr))
>>> test(x%3)
x % 3
>>> test((x+1)%3)
(x + 1) % 3
From my (extremely limited) testing seems to suggest this works fine, also see the note below about own_level.
as shown in the documentation for overriding printing, you can just override Basic.__str__ to use your custom printer when just printing out expressions:
from sympy import Basic
Basic.__str__ = lambda expr, printer=MyPrinter(): printer.doprint(expr)
>>> print(x%3)
x % 3
as a side note - the reason Mod doesn't / can't do this by default is because it apparently inherits from Function:
>>> issubclass(sympy.Mod, sympy.Function)
True
This is why it displays as a function call in pretty much every printing method there is, this also means that modulus has the same precedence as functions:
>>> precedence(x%3)
70
>>> f = sympy.Function("f")
>>> precedence(f(x))
70
>>> print( f(x)%x ) #so it thinks f(x) needs parens here
(f(x)) % x
if you find an appropriate precedence to use for own_level please share it with me as I would love to update my answer.
Related
I have a function that computes a large expression based on Sympy symbols passed as arguments. A very simplified version for readability is:
def expr(a):
return (1+a)/a
This generally works but if the passed argument is the infinity symbol then this becomes a NaN, whereas I'd prefer the result to be somehow evaluated as a limit and return 1 (in this simplified case).
Since in my actual code there are many arguments which could be infinite and the expression is quite large, I'd rather avoid an if-else sequence covering every possible combination of infinite-valued arguments.
I've tried using unevaluated expressions but that doesn't seem to work either. Is there a good workaround for this?
You could write the expression as a limit:
from sympy import oo, limit
from sympy.abc import a, x
def expr(a):
return limit((1 + x) / x, x, a)
print(expr(oo)) # 1
so I am having issues trying to do basic math in Python. I can do basic math, but when I add in exponents, square roots, etc, I have errors with the IDE. How do I do this?
Here are a few of my problems that I am having issues with:
(n(n-1))/2)
(4)* pi * r ** 2=
(r(cos(a)**2) + r(sin(b))**2)**(.5)
((y**2) - (y**1))/((x**2) - (x**1))=
(n*(n-1))/2 should work if you have already given n a numeric value (e.g. n=2 or something). Your original expression has unbalanced parentheses (three closing parens and only two opening parens) and it is missing the multiplication sign (*) which is necessary in python, otherwise n(n-1) would be interpreted as the function n supplied with the input n-1, in which case you get a message like "TypeError: 'int' object is not callable", assuming you had previously defined n=2 or the like. It's telling you that the integer n cannot be called like a function, which is how it interprets n().
To get pi (3.14159...) in python, you should import the math package and then use math.pi like this:
import math
r = 2
x = 4*math.pi*r**2
You don't need parentheses around the 4. Parentheses are used for grouping, when you need operations to be done in a different order than the standard order of operations. You don't need the trailing equal sign (that's a syntax error).
In the third expression you are using implicit multiplication notation which is fine for pencil and paper but in python you need to use * every time you multiply. Also, you need to import the math package and then use math.sin and math.cos.
import math
a = 90
b = 45
x = (r*(math.cos(a)**2) + r*(math.sin(b))**2)**(.5)
There doesn't appear to be anything wrong with the last expression except the trailing = sign which should be removed. Store the result of this expression in a variable if you want to keep it for future use:
z = ((y**2) - (y**1))/((x**2) - (x**1))
If you just type the expression at the command line it will print the result immediately:
x = 3
y = 2
((y**2) - (y**1))/((x**2) - (x**1))
but if you are using this expression in a script you want to save the result in a variable so you can use it later or print it out or something:
z = ((y**2) - (y**1))/((x**2) - (x**1))
As was previously pointed out in the comments, x**1 is the same, mathematically, as x so it's not clear why you would want to write it this way, but it's not wrong.
You can use math.pow() or the simpler ** syntax:
There are two ways to complete basic maths equations in python either:
use the ** syntax. e.g:
>>> 2 ** 4
16
>>> 3 ** 3
27
or use math.pow(). e.g:
>>> import math
>>> math.pow(5, 2)
25.0
>>> math.pow(36, 0.5)
6.0
As you can see, with both of these functions you can use any real power so negative for inverse or decimals for roots.
In general, for these types of equations, you want to look into the math module. It has lost of useful functions and defined constants that you may find useful. In particular for your specific problems: math.pi and these trig. functions.
I hope these examples and the links I made are useful for you :)
I think if I'd know the math behind it I might have figured it out by myself.
When I call math.log10(0.0000000000001) I get -13. But how do I convert this back into 0.0000000000001? and how i'd handle it when using math.log(0.0000000000001)?
Both ways, the fundamental, arithmetic one and the one using a built-in python function would interest me.
a = math.log10(0.0000000000001)
b = 10 ** a
math.log() takes two parameter, a number and a base. Default value is e (mathematical constant), a special constant which tends to 2.71828.
You can get the number by evaluating base to the power log_value
>>> a = math.log(10)
>>> a
2.302585092994046
>>> 2.71828**a
9.999984511610785
If I would take e's value with higher precision, I can get the result close to 10.
Or, you can use math.exp()
>>>math.exp(a)
10.000000000000002
You can also use math.pow()
>>> math.pow(2.71828,a)
9.999984511610785
I tried to work out a python-like language which combined with the feature of MACRO(weird, but just for fun..), for example, the codes to calculate fibonacci seq analyticly is like this:
from math import *
def analytic_fibonacci(n):
sqrt_5 = sqrt(5);
p = (1 + sqrt_5) / 2;
q = 1/p;
return int( (p**n + q**n) / sqrt_5 + 0.5 )
print analytic_fibonacci(10),
And I can rewrite it in the python-like-with-MACRO language like this:
from math import sqrt
sqrt
def analytic_fibonacci(n):
_2(5)
(1+_1)/2
1/_1
return int((_2**n+_1**n)/_3+0.5)
print analytic_fibonacci(10)
The idea is to use line number to expand the expression so that no explicit assignment is needed. The _2 means to replace it with the expression appeared 2 lines smaller than the current line, so the _2 in the 4th line becomes the expression in the 2nd line, which is sqrt, and _2(5) is expanded to sqrt(5). (Lines before current line starts with _, after current line starts with |)
The example above is simple. When I tried to rewrite a more complex example, I encountered problem:
def fibIter(n):
if n < 2:
return n
fibPrev = 1
fib = 1
for num in xrange(2, n):
fibPrev, fib = fib, fib + fibPrev
return fib
I don't know how to use the line-number-based MACRO to express fibPrev, fib = fib, fib + fibPrev. I think some features is missing in this "MACRO langugage" , and fibPrev, fib = fib, fib+fibPrev is expressible if I fixed it.. (I heard that the MACRO in Lisp is Turing Complete so I think the example above should be expressed by MACRO) Does anyone have ideas about this?
I see two ways to interpret your language. Neither is very powerful.
The first way is to literally expand the macros to expressions, rather than values. Then analytic_fibonacci expands to
def analytic_fibonacci(n):
return int(((1+sqrt(5))/2**n+1/(1+sqrt(5))/2**n)/sqrt(5)+0.5)
You probably want some parentheses in there; depending on how you define the language, those may or may not be added for you.
This is pretty useless. Multiple-evaluation problems abound (where a function is reexecuted every time a macro refers to it), and it only lets you do things you could have done with ordinary expressions.
The second interpretation is that every statement consisting of a Python expression implicitly assigns that expression to a variable. This is also pretty useless, because only one statement can assign to any of these implicit variables. There's no way to do
x = 0
for i in range(5):
x += i
because you can't have the equivalent of x refer to either _2 or _0 depending on where the last assignment came from. Also, this really isn't a macro system at all.
Using the second interpretation, we can add a new operator to bring back the power of ordinary variable assignments. We'll call this the merge operator.
merge(_1, _2)
evaluates to either _1 or _2, depending on which was evaluated most recently. If one of the arguments hasn't yet been evaluated, it defaults to the other. fibIter then becomes
def fibIter(n):
if n < 2:
return n
1 # fibPrev
1 # fib
for num in xrange(2, n):
merge(_2, _-1) # temp
merge(_4, _-1) + merge(_3, _0) # fib
_2 # fibPrev
return merge(_2, _5)
This is quite awkward; essentially, we have to replace every use of a variable like x by a merge of every location it could have been assigned. It also requires awkward line counting, making it hard to tell which "variable" is which, and it doesn't handle multiple assignments, for loop targets, etc. I had to use negative indices to refer to future lines, because we need some way to refer to things assigned later.
Lisp macros are more powerful than your language because they let you apply arbitrary Lisp code to your Lisp code. Your language only allows a macro to expand to fixed expressions. A Lisp macro can take arbitrary code as arguments, cut it up, rearrange it, replace parts of it with different things depending on conditionals, recurse, etc. Your macros can't even take arguments.
Generally speaking, what should the unary + do in Python?
I'm asking because, so far, I have never seen a situation like this:
+obj != obj
Where obj is a generic object implementing __pos__().
So I'm wondering: why do + and __pos__() exist? Can you provide a real-world example where the expression above evaluates to True?
Here's a "real-world" example from the decimal package:
>>> from decimal import Decimal
>>> obj = Decimal('3.1415926535897932384626433832795028841971')
>>> +obj != obj # The __pos__ function rounds back to normal precision
True
>>> obj
Decimal('3.1415926535897932384626433832795028841971')
>>> +obj
Decimal('3.141592653589793238462643383')
In Python 3.3 and above, collections.Counter uses the + operator to remove non-positive counts.
>>> from collections import Counter
>>> fruits = Counter({'apples': 0, 'pears': 4, 'oranges': -89})
>>> fruits
Counter({'pears': 4, 'apples': 0, 'oranges': -89})
>>> +fruits
Counter({'pears': 4})
So if you have negative or zero counts in a Counter, you have a situation where +obj != obj.
>>> obj = Counter({'a': 0})
>>> +obj != obj
True
I believe that Python operators where inspired by C, where the + operator was introduced for symmetry (and also some useful hacks, see comments).
In weakly typed languages such as PHP or Javascript, + tells the runtime to coerce the value of the variable into a number. For example, in Javascript:
+"2" + 1
=> 3
"2" + 1
=> '21'
Python is strongly typed, so strings don't work as numbers, and, as such, don't implement an unary plus operator.
It is certainly possible to implement an object for which +obj != obj :
>>> class Foo(object):
... def __pos__(self):
... return "bar"
...
>>> +Foo()
'bar'
>>> obj = Foo()
>>> +"a"
As for an example for which it actually makes sense, check out the
surreal numbers. They are a superset of the reals which includes
infinitesimal values (+ epsilon, - epsilon), where epsilon is
a positive value which is smaller than any other positive number, but
greater than 0; and infinite ones (+ infinity, - infinity).
You could define epsilon = +0, and -epsilon = -0.
While 1/0 is still undefined, 1/epsilon = 1/+0 is +infinity, and 1/-epsilon = -infinity. It is
nothing more than taking limits of 1/x as x aproaches 0 from the right (+) or from the left (-).
As 0 and +0 behave differently, it makes sense that 0 != +0.
A lot of examples here look more like bugs. This one is actually a feature, though:
The + operator implies a copy.
This is extremely useful when writing generic code for scalars and arrays.
For example:
def f(x, y):
z = +x
z += y
return z
This function works on both scalars and NumPy arrays without making extra copies and without changing the type of the object and without requiring any external dependencies!
If you used numpy.positive or something like that, you would introduce a NumPy dependency, and you would force numbers to NumPy types, which can be undesired by the caller.
If you did z = x + y, your result would no longer necessarily be the same type as x. In many cases that's fine, but when it's not, it's not an option.
If you did z = --x, you would create an unnecessary copy, which is slow.
If you did z = 1 * x, you'd perform an unnecessary multiplication, which is also slow.
If you did copy.copy... I guess that'd work, but it's pretty cumbersome.
Unary + is a really great option for this.
For symmetry, because unary minus is an operator, unary plus must be too. In most arithmetic situations, it doesn't do anything, but keep in mind that users can define arbitrary classes and use these operators for anything they want, even if it isn't strictly algebraic.
I know it's an old thread, but I wanted to extend the existing answers to provide a broader set of examples:
+ could assert for positivity and throw exception if it's not - very useful to detect corner cases.
The object may be multivalued (think ±sqrt(z) as a single object -- for solving quadratic equations, for multibranched analytical functions, anything where you can "collapse" a twovalued function into one branch with a sign. This includes the ±0 case mentioned by vlopez.
If you do lazy evaluation, this may create a function object that adds something to whatever it is applied to something else. For instance, if you are parsing arithmetics incrementally.
As an identity function to pass as an argument to some functional.
For algebraic structures where sign accumulates -- ladder operators and such. Sure, it could be done with other functions, but one could conceivably see something like y=+++---+++x. Even more, they don't have to commute. This constructs a free group of plus and minuses which could be useful. Even in formal grammar implementations.
Wild usage: it could "mark" a step in the calculation as "active" in some sense. reap/sow system -- every plus remembers the value and at the end, you can gather the collected intermediates... because why not?
That, plus all the typecasting reasons mentioned by others.
And after all... it's nice to have one more operator in case you need it.
__pos__() exists in Python to give programmers similar possibilities as in C++ language — to overload operators, in this case the unary operator +.
(Overloading operators means give them a different meaning for different objects, e. g. binary + behaves differently for numbers and for strings — numbers are added while strings are concatenated.)
Objects may implement (beside others) these emulating numeric types functions (methods):
__pos__(self) # called for unary +
__neg__(self) # called for unary -
__invert__(self) # called for unary ~
So +object means the same as object.__pos__() — they are interchangeable.
However, +object is more easy on the eye.
Creator of a particular object has free hands to implement these functions as he wants — as other people showed in their real world's examples.
And my contribution — as a joke: ++i != +i in C/C++.
Unary + is actually the fastest way to see if a value is numeric or not (and raise an exception if it isn't)! It's a single instruction in bytecode, where something like isinstance(i, int) actually looks up and calls the isinstance function!