Flip a boolean value without referencing it twice - python

I am looking for a short syntax that would look somewhat like x *= -1 where x is a number, but for booleans, if it even exists. It should behave like b = not(b). The interested of this is being able to flip a boolean in a single line when the variable name is very long.
For example, if you have a program where you can turn on|off lamps in a house, you want to avoid writing the full thing:
self.lamps_dict["kitchen"][1] = not self.lamps_dict["kitchen"][1]

You can use xor operator (^):
x = True
x ^= True
print(x) # False
x ^= True
print(x) # True
Edit: As suggested by Guimoute in the comments, you can even shorten this by using x ^= 1 but it will change the type of x to an integer which might not be what you are looking for, although it will work without any problem where you use it as a condition directly, if x: or while x: etc.

Related

Python code mistake resulting in no return(pitagorean set problem)

I am just starting out with programming in python and programming in general.
I've made this code:
for a in range(1,1001):
for b in range(1,1001):
c2=(a**2)+(b**2)
c=c2**0.5
if type(c) == int and a+b+c == 1000:
print(a*b*c)
To find a pitagorean set with a+b+c=1000, but had no return. Code runs but doesn't print out anything and ends.
This is a euler9 problem, and I know I can find solutions on the internet but i really want to understand why this particular one that I came up with doesn't work. In my understanding it should check every pair of a and b in range of 1000 and check if for any "a^2+b^2=c^2", square root of c is an integer and a+b+c=1000.
Thanks for help
A couple of things to note:
1) The type of c will always be a float. So, type(c) == int will always evaluate to False, and your print statement will never be hit. The reason for this is because your power is a float. In general, square roots are only sanely represented as floats.
2) You almost never want to check the type of a variable in Python, and your case is no exception. What you want to do is check whether or not c has a value that is an integer, not if the type of c is an integer. To do that, use the built-in is_integer. Here's an example:
>>> x = 1 ** .5
>>> x
1.0
>>> x.is_integer()
True
>>> y = 2 ** .5
>>> y
1.4142135623730951
>>> y.is_integer()
False
>>> (4**.5).is_integer()
True
>>> (19**.5).is_integer()
False
>>> (25**.5).is_integer()
True
HTH, good luck solving the problem.
P.S. It's Pythagorean, not Pitagorean.
Try to set c as a result of 1000-a-b this should be an integer.Than compare power of c with a^2 + b^2. As you are trying to make a square root in general it doesn't give an integer so the type of this is always float. If you remove comparing c type with int your code should work.
If you want to check if the value is an integer you should try build in function is_integer().
c.is_integer()

How to stop short circuiting in Python?

Python short circuits the logical operators.
for eg:
if False and Condition2:
#condition2 won't even be checked because the first condition is already false.
Is there a way to stop this behavior. I want it to check both the conditions and then perform the and operation(as done in c, c++ etc). It's useful when we are performing some operation along with the condition. e.g.:
if a < p.pop() and b < p.pop():
One way can be checking the conditions before and then comparing the Boolean values. But that would be wastage of memory.
if all([a < p.pop(), b < p.pop()])
This creates a list, which will be evaluated in its entirety, and then uses all to confirm that both values are truthy. But this is somewhat obscure and I'd rather suggest you write plain, easy to understand code:
a_within_limit = a < p.pop()
b_within_limit = b < p.pop()
if a_within_limit and b_within_limit:
If the conditions are booleans, as they are in your example, you could use & instead:
>>> a, b, p = 1, 1, [0, 0]
>>> (a < p.pop()) & (b < p.pop())
False
>>> p
[]
You can use the all() and any() built-in functions to somehow emulate the and and or operators. Both take an iterable of boolean-likes values as parameter. If you give it a literal tuple or list, all members will be fully evaluated:
# all emulates the and operator
if all((False, Condition2)):
do_stuff()
# any emulates the or operator
if any((False, Condition2)):
do_stuff()
Short answer: No, you cannot stop it to do this.
For example:
av = p.pop()
bv = p.pop()
if a < av and b < bv:
pass
Or:
av, bv = p.pop(), p.pop()
if a < av and b < bv:
pass
Also, there is no waste of memory in these examples. In Python, almost everything is done by reference. The value object being popped already exists somewhere. Even the scalars like strings, ints, etc are objects (some of them are slightly optimized). The only memory changes here are (1) the creation of a new variable that refers to the same existing object, and (2) removal of the record in the dict at the same time (which referred to that object before popping). They are of the similar scale.

How to decrement a variable while printing in Python?

Some if and else's can be rewritten1 and shortened2 (codegolf-style) likewise, because booleans can act as integers in Python. For example if a<b:return a can be rewritten3 as return("",a)[a<b].
In this case (I simplified the condition for readability),
if a<b: print(a)
can be rewritten as both of the following:
print(("",a)[a<b])
(print(""),print(a))[a<b]
(if we ignore newlines, else end="" can be used).
I would like to decrement a variable n (the whole thing is in a while loop with n in its condition) when a<b is true on top of everything, eg.
if a<b:
print(a)
n-=1
while using the syntax trick above.
In C, (n/n--)-1 is not only equal to 0, but also substracts 1 from n. In Python, I haven't found a way to do this. Some invalid syntaxes I tried:
print(("",a+(n/n--)-1)[a<b])
(print(""),(print(a);n-=1))[a<b]
How to decrement the variable (and print a) when the condition is true using this "trick"?
1,2,3: these statements aren't always true
Python isn't C. For one thing, Python doesn't have a decrement operator, so print(n--) won't work. For another, assignments in Python are statements, not expressions, so print(n-=1) won't work.
If you truly wanted your print statement to have side effects, it could invoke a function:
def decrement():
global n
n -= 1
return n
print(decrement())
But don't. No one will expect that your print statement has side-effects, so everyone will be surprised when commenting out your print statement changes the program's result.
EDIT: I just noticed that this is a code golf question. In that case, my stylistic advice isn't really valid. Everyone expects golfed code to be weird.
Ps. If your goal is to change if statements into expressions, then play with and and or, which short circuit. For example:
a<b and (print(a), decrement())
Or use if ... else expressions
(print(a),decrement()) if a<b else None
n = 10
print(n // (n := n-1) - 1)
# (x := y) is the equivalent of x = y
#but you can use it inside expressions
#and it returns the new value of x
# finally a C simple assignment
a = (b := 1)
print(a, b)
gives
0
1 1

why comparative operation on set return False? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
I have problem with this code. i can't understand why this happened?
i am going to compare two set by >=< but all output are False !
>>> x=set([1,2,3])
>>> y=set([3])
>>> x<y
False
>>> x>y
False
>>> x==y
False
actually I want to know why it return False .
You've made a slight mistake:
>>> x = {1,2,3}
>>> y = {3}
>>> x > y
True
>>> x < y
False
>>> x == y
False
You tested x < y and y > x which gave you the same result. Now you can see that x > y.
However, there are sets for which all three comparisons are actually False:
>>> x = {1,2,3}
>>> y = {1,2,4}
>>> x > y
False
>>> x < y
False
>>> x == y
False
and this is due to the implementation of <=> for sets, which compares sets via subset logic (x < y asks if x is a strict subset of y).
You did x<y and y>x. These are the same. Probably you mean to do x<y and y<x.
x<y
is the same as
y>x
and sets are not the same sets so x == y gives False too.
The only route to altering the way built-in containers check equality is to make them contain as values, instead of the "originals", wrapped values (wrapped in a class that overrides __eq__ and __ne__). This is if you need to alter the way the containers themselves use equality checking, e.g. for the purpose of the in operator where the right-hand side operand is a list -- as well as in containers' method such as their own __eq__ (type(x).__eq__(y) is the typical way Python will perform internally what you code as x == y).
If what you're talking about is performing your own equality checks (without altering the checks performed internally by the containers themselves), then the only way is to change every cont1 == cont2 into (e.g.) same(cont1, cont2, value_same) where value_same is a function accepting two values and returning True or False like == would. That's probably too invasive WRT the criterion you specify.
If you can change the container themselves (i.e., the number of places where container objects are created is much smaller than the number of places where two containers are checked for equality), then using a container subclass which overrides __eq__ is best.
I can't replicate the results in your question
>>> x=set([1,2,3])
>>> y=set([3])
>>> x<y
False
>>> x>y
True
>>> x==y
False
If there is a version of Python that returns False for x>y it is a bug in the Python implementation.
I suspect you didn't copy and paste from your console, and retyped what you think it said.
From documentation -
In addition, both Set and ImmutableSet support set to set comparisons. Two sets are equal if and only if every element of each set is contained in the other (each is a subset of the other). A set is less than another set if and only if the first set is a proper subset of the second set (is a subset, but is not equal). A set is greater than another set if and only if the first set is a proper superset of the second set (is a superset, but is not equal).
So y is less than x . If you do y < x you will get true -
>>> x = set([1,2,3])
>>> y = set([3])
>>> x < y
False
>>> y < x
True
Your comparisons , were - x < y (x less than y , which is false) , y > x (y greather than x , which is same as previous one) , again false. And x == y which is also false (since both sets do not have equal elements).
Based on the screenshot you added, seems like x is {1} and y is {2} .
You can check the snippet from documentation I added above, in set , less than returns true only if the set on the left side is a subset of the set on the right side, in your case, both x and y are not subsets of each other, hence x is not less than y , and y is not less than y and they are not equal.
Example -
>>> x = {1}
>>> y = {2}
>>> x < y
False
>>> y < x
False

Compacting an if statement

I want to write this if statement as compact as possible (to avoid having duplicate code)
if length == 10 if boolean is False or length == 13 if boolean is True:
The part that PyCharm does not like is the
if boolean is True
It asks for a colon.
PyCharm does not allow me to run it. Does anyone have a nice compact solution to this if?
I think you meant
if (not boolean and length == 10) or (boolean and length == 13):
The parentheses aren't necessary, but I think they help readability. #jonsharpe's solution is even shorter and only has to evaluate boolean once, but it may be harder to read, especially if you're not familiar with Python's ternary expressions.
Never use is for equality comparison (that's what == is for), but boolean types should never be explicitly compared to True or False anyway.
You can use a conditional expression (also known as a "ternary") to write it out much more concisely:
if length == 13 if boolean else length == 10:
or, equivalently:
if length == (13 if boolean else 10):
Per the documentation:
The expression x if C else y first evaluates the condition, C (not x); if C is true, x is evaluated and its value is returned; otherwise, y is evaluated and its value is returned.

Categories