How exactly do the shortcut operators work in python? - python

I started learning python and while i was checking some of the examples about shortcut operators I ran into this one
a = 6
b = 3
a /= 2 * b
print(a)
which print 1.0 as the result which i'm sure is wrong because it's supposed to be the simplified version of:
a = a / 2 * b
which gives 9.0 as the result and I think makes more sense acording to the order

a /= <anything here> computes all of the <anything here> first, and then does the division and assignment. So in your example, it is equivalent to a = a / (2 * b) (note parentheses).

Think about how the order of operations works:
a /= c
Is equivalent to
a = a / c
In a similar line,
a /= 2 * b
Is tantamount to
a = a / (2 * b)
Which equates to 6 / (2 * 3) which indeed equals 1.

a /= 2 * b
is in other words a = a / ( 2 * b)

This
a /= 2 * b
corresponds to
a = a / (2 * b)
and not to
a / 2 * b

Related

How to substitute partial powers?

I have an expression which contains terms like expr = a**m * b**n where a,b are symbols and m,n are integers. I want to use expr.subs(a**i * b**j, 0) to set the expression to zero if a**i * b**j is a factor of a**m * b**n (here i,j are integers too). This works in some cases, but not when only one of the symbols is used for the substitution:
>>> from sympy import symbols
>>> a, b = symbols('a b')
>>> (a**2 * b**3).subs(a**2 * b**2, 0) # (1) works
0
>>> (a**2 * b**3).subs(a * b**2, 0) # (2) works
0
>>> (a**2 * b**3).subs(b**2, 0) # (3) does not work
a**2*b**3
>>> (a**3).subs(a**2, 0) # (4) does not work
a**3
>>> (a**4).subs(a**2, 0) # (5) works
0
I would like this substitution to work in all of the above cases and logically it should (since for example a**2 * b**3 is equivalent to a**2 * b * (b**2) and thus the substitution (b**2, 0) should yield 0). However, if using a single symbol in the substitution, it seems to work only for those cases where the expression contains the subs-term raised to a power; for example:
>>> (a**2 * b**4).subs(b**2, 0) # (6) works
0
>>> (a**2 * b**4).subs(b**3, 0) # (7) does not work
a**2*b**4
This behavior seems a little odd since it works for b**1 and also when artificially augmenting both, the actual expression and the subs-term, with some other symbol:
>>> (a**2 * b**4).subs(b, 0) # (8) works
0
>>> c = symbols('c')
>>> (c * (a**2 * b**4)).subs(c * (b**3), 0) # (9) works
0
While I could use this last observation (augmenting expressions) as a workaround, it doesn't seem neither clear nor efficient.
Hence, is there another way to make the substitution work for all cases where the subs-term is contained in the actual expression?
>>> sympy.__version__
'1.10.1'
To check if something is a factor of a product you can use extract_multiplicatively:
>>> expr = a**3*b**3*c
>>> 0 if expr.extract_multiplicatively(a*b**2) else expr
0
You could also use the rem function to see if the remainder is 0:
>>> rem(expr, a*b**2)
0
If your expressions occur within a larger expression, then these could be incorporated into a replace call, expr.replace(...). If you are trying to ignore high-order terms in an expression you can just make a function to add the order of all symbol-based powers in a term:
>>> expr = expand((x + 1)**3*(y + 1)**2)
>>> def order(m):
... return sum([degree(m, x) for x in m.free_symbols])
...
>>> expr.replace(lambda x: not x.is_Add,
... lambda x: 0 if order(x)>2 else x)
3*x**2 + 6*x*y + 3*x + y**2 + 2*y + 1
works, because a2 = 0 is 0 * b3 what leads to 0
a = 0 means a**2 = 0 -> 0
b2 = 0 but b2 is not in b**3, so it does not work
same issue as 3
a4 is in a2 so 0
same as 5 but with b´s
same issue as 3
b is in b**4
c = c so it comes to 0 because only symbols get replaced
Everything works like intended

Python mathematical expression evaluation

I was trying to solve a random problem, I used a relation that I made, when I've come to implement it in python it give me different results than the one that I calculated, so I tried to change.
the thing is I don't get how does python see each one!!?
those two expressions here give different results sometimes:
((column+1)//2) * ((row+1)//2)
= (column+1)//2 * (row+1)//2
Here's an example:
rows, columns = 4, 4
for row in range(2, rows+1):
for column in range(1, columns+1):
print('*'*15)
result = ((column+1)//2) * ((row+1)//2)
f_result = (column+1)//2 * (row+1)//2
print('>> normal expression:', (column+1)//2, (row+1)//2)
print('>> second expression:', ((column+1)//2), ((row+1)//2))
print('>> row:', row)
print('>> column:', column)
print('>> Results:', result, f_result)
print()
The last two entries in the results:
***************
>> normal expression: 2 2
>> second expression: 2 2
>> row: 4
>> column: 3
>> Results: 4 5
***************
>> normal expression: 2 2
>> second expression: 2 2
>> row: 4
>> column: 4
>> Results: 4 5
You need to understand operator precedence first
Check out this link
Now for the expression
((col+1)//2) * ((row+1)//2) = (col+1)//2 * (row+1)//2
((col+1)//2) * ((row+1)//2) = ((4+1)//2) * ((4+1)//2)
= (5//2)*(5//2)
= 2 * 2
= 4
(col+1)//2 * (row+1)//2 = (4+1)//2 * (4+1)//2
= 5//2 * 5//2
= 2 * 5//2
= 10//2 (as * has higher precedence over //)
= 5

Simple addition of 1 to a large number does not work? (Python 3.9)

Note: I am not that experienced in Python, therefore my code may not be as good as it could/should be.
I am attempting to create a tool to facilitate calculating the algebraic factors of a certain form of number (see https://en.wikipedia.org/wiki/Aurifeuillean_factorization). This is mostly as a test/learning experience, however I have run into a problem when attempting to calculate the parameter "c", which is defined as 2^(2k+1)+1. The addition step does not work for me. I am simply getting the returned value as 2^129, instead of 2^129+1 as I am looking to get. Is this an issue with Python itself, or am I making some sort of mistake in this.
Code:
import math
def make_aurifeuille_factors(base, exponent):
if base == 2 and exponent % 4 == 2:
k = (exponent - 2) / 4
c = int(1 + 2 ** (2*k + 1))
d = int(2 ** (k + 1))
L = c + d
M = c - d
return int(k), int(c), int(d), int(L), int(M)
def gcd(a, b):
return int(math.gcd(a, b))
print(make_aurifeuille_factors(2, 258))
k = (exponent - 2) / 4 makes k a float, which means you potentially introduce numerical error in computations down the line. Use integer division to stay in int world from the start:
def make_aurifeuille_factors(base, exponent):
if base == 2 and exponent % 4 == 2:
k = (exponent - 2) // 4
c = 1 + 2 ** (2*k + 1)
d = 2 ** (k + 1)
L = c + d
M = c - d
return k, c, d, L, M

When I convert an expression using shortcut operators the output is wrong

I read that if I have the following expression:
variable = variable op expression
It can be simplified and shown as follows:
variable op= expression
For example: i = i + 2 * j --> i += 2 * j
However, I have used the previous example in a = a / 2 * b --> a /= 2 * b
Let a=6 and b=3. Using both values in a=a/2*b, the output is 9. However, in the case of a /= 2* b, the output is 1
This is because you are changing the order of operations.
a = a / 2 * b is interpreted as "Divide a by 2, then multiply by b, then store the result in a", or a = (a / 2) * b.
a /= 2 * b is interpreted as "Multiply 2 by b, then divide a by the result, and store the final result in a", or a = a / (2 * b).
I hope this helps.

How to enter a Googol in Python?

I've heard that Python does not have any upper limit with integers. So I wanted to give a try:
a = 1e100
b = 1
c = a + b + a
c - 2 * a
> 0.0
Unfortunately I realized that writing 1e2 returns a float while 100 returns an int.
I've then tested with long('1' + '0' * 100) which works.
a = long('1' + '0' * 100)
b = 1
c = a + b + a
c - 2 * a
> 1L
Is this solution the only way to affect a Googol to a variable?
Subsequent question:
How to avoid confusion between floating point and fixed point during computations?
You can get a Googol like so:
10**100
I dont really understand your question but i think you are asking is there only this way to manipulate googol variable .
i just tried this on my python idle and got this
>>> a = 10 ** 100
>>> b = 1
>>> c = a + b + a
>>> c - 2 *a
1
>>>
You could use the power operator:
base**times
so 123 googols would be 123*10**100

Categories

Resources