How do boolean operators work in 'if' conditions? - python

I am currently new to Python and am trying to run a few simple lines of code. I cannot understand how Python is evaluating this syntax after the if statement. Any explanations will be appreciated.
number = int(raw_input("Enter number : "))
if number == (1 or 2 or 3):
print "Match"
else:
print "No match"
Only the integer 1 yield a positive result and any other numbers including 2 and 3 go through the else branch. Can the conditions be stated as the following only?:
if number == 1 or number == 2 or number == 3:
Thank you.

You probably want:
if number in (1, 2, 3):

Python has boolean values, such as True and False, and it also has falsy values, such as any empty list, tuple, or dictionary, an empty string, 0, and None. Truthy values are the opposite of that, namely anything that's defined.
Python's or evaluates and short-circuts on the first element that returns a truthy value.
So, the expression (1 or 2 or 3) is going to return 1.
If you want to compare against all elements, then you're looking for the in keyword:
if number in (1, 2, 3):
# Do logic

The or operator takes two arguments, on its left and right sides, and performs the following logic:
Evaluate the stuff on the left-hand side.
If it is a truthy value (e.g, bool(x) is True, so it's not zero, an empty string, or None), return it and stop.
Otherwise, evaluate the stuff on the right-hand side and return that.
As such, 1 or 2 or 3 is simply 1, so your expression turns into:
if number == (1):
If you actually mean number == 1 or number == 2 or number == 3, or number in (1, 2, 3), you'll need to say that.
(Incidentally: The and operator works the same way, except step 2 returns if the left-hand-side is falsey.)

Related

Meaning of r[( s== 'even'::2) in python function

Question that asks:
"Create a function that returns the characters from a list or string r
on odd or even positions, depending on the specifier s. The specifier
will be "odd" for items on odd positions (1, 3, 5, ...) and "even" for
items on even positions (2, 4, 6, ...)."
E.g. char_at_pos([2, 4, 6, 8, 10], "even") ➞ [4, 8]
Have managed to solve, but saw a quicker way to solve would be to use:
def char_at_pos(r, s):
return r[s == 'even'::2]
am wondering how to interpret r[s == 'even'::2], is that adding a condition inside the index bracket before we pick the even index numbers in the list? How does it then also pick the odd numbers?
r[s == 'even'::2]
s == 'even' evaluates to 1 (which is the numerical equivalent for True) if s is 'even', otherwise it evaluates to zero (which is the numerical equivalent for False). Now lets break it down based on examples:
r[1:10] takes all items startig at 1 till item 10 (excluded).
r[1:] takes all items starting at 1 till the end.
r[1:10:2] takes every second item starting at 1 till item 10, and
r[1::2] correspondingly takes every second item starting at 1 till the end.
Adding to the #jim answer,
Booleans in Python are implemented as a subclass of integers.
>>> int(True)
1
>>> int(False)
0
>>> issubclass(type(True), int)
True
>>> issubclass(type(False), int)
True
When you call r[s == 'even'::2] python calls the __getitem__ method of the list object with the slice object slice(True, None, None) or slice(False, None, None)[Depends upon the result of s == 'even']. The PySlice_Unpack C API call will extract the start, stop, step data members from a slice object as C integers. So this is where the start(boolean object) argument is actually is converting to an int object making the expression to be evaluated as same as r[1::2] or r[0::2]

What is the star (*) doing in this FizzBuzz solution?

Learning programming in Python and I am doing some challenges. I've run into something I haven't learned yet and was curious what this code is doing.
So my challenge is called the "FizzBuzz" challenge. The instructions are simple:
Create a function that takes a number as an argument and returns
"Fizz", "Buzz" or "FizzBuzz".
If the number is a multiple of 3 the output should be "Fizz". If the
number given is a multiple of 5, the output should be "Buzz". If the
number given is a multiple of both 3 and 5, the output should be
"FizzBuzz". If the number is not a multiple of either 3 or 5, the
number should be output on its own.
I wrote this code to solve it (obviously it can be better):
def fizz_buzz(num):
if num % 3 == 0 and num % 5 == 0:
return 'FizzBuzz'
elif num % 3 == 0:
return 'Fizz'
elif num % 5 == 0:
return 'Buzz'
else:
return str(num)
But, once I submitted my solution I was able to see the top solution, which is:
def fizz_buzz(num):
return "Fizz"*(num%3==0) + "Buzz"*(num%5==0) or str(num)
My question is what is the * doing here? Can someone point me to documentation or resources that addresses what this persons code has done? I don't find it super readable but it is apparently the best solution to the problem.
bool in Python is a subclass of int; True has the value 1, False, 0.
Sequences (including str) in Python can be multiplied, to get the sequence repeated that many times, so:
"Fizz"*(num%3==0)
multiplies "Fizz" by 1 (numeric value of True) when num % 3 == 0, producing the original string, and by 0 (numeric value of False) otherwise, producing the empty string.
The same work is done with "Buzz" and concatenated. If both of them produced the empty string (which is falsy), then the or means str(num) is evaluated and returned (Python's or and and don't evaluate to strict True or False, they evaluate to the last item evaluated, and short-circuit, so or always evaluates to the first truthy item, or the last item in the or chain regardless of truthiness).
Firstly, shorter doesn't always mean better. In this case, your solution is fine, and the "top solution" is clever, but needlessly confusing, as you're aware :P
The star is doing string multiplication, and it's exploiting the fact that False == 0 and True == 1. So if num is divisible by 3, you get 'Fizz' once, and if num is divisible by 5, you get 'Buzz' once. Otherwise you get an empty string, '', and because an empty string is falsy, the or clause means it will be replaced by str(num).
The * is string multiplication as usual. It's just multiplying by 0 or 1 based on whether the condition to print the phrase is met. If neither condition is met, it defaults to returning the number, as it should.
I don't know about a resource, but I can tell you what it does. The phrase num%3==0 is a Boolean which is true if the number is divisible by 3. If that's the case, this phrase returns a 1 (or 0 if False). Same for num%5==0 and divisible by 5. This is then being multiplied by the string Fizz and/or Buzz and concatenated together, where multiplying by 1 returns the string and 0 nothing. If neither of those holds, it returns str(num).
I do not know the link to any documentation or resource about it, but I can explain it to you.
Firstly in python str can be multiplied by a number, for instance 'Fizz' * 3 will return 'FizzFizzFizz' or 'Fizz' * 0 will return '', an empty string.
Secondly bool in python can be also recognized as int, i.e. True is 1 and False is 0.
Thirdly in python strings can be added e.g. 'Fizz'+'Buzz' will return 'FizzBuzz'
What the best solution guy does is very simple by num%3==0 he gets bool and just multiplies the str 'Fizz' or 'Buzz' by it and returns.

printf-style string formatting with boolean condition in brackets string%d % (i condition)

I can't understand how this condition behind the % works
for i in range(1,6):
print "pet%d" % (i == 1 and 2 or 4)
this part (i == 1 and 2 or 4) is what I cant understand. As far as I understand it does the same as a
if i == 1:
i = 2
else:
i = 4
but how does the (i == 1 and 2 or 4) work especially with the %d % i formatting?
Read it as 2 if i == 1 else 4 using the python a if b else c or if i == 1 then 2 else 4
It gives 4 unless i == 1 returns true, then it gives 2:
pet2
pet4
pet4
pet4
pet4
This sort of boolean (ab)use is common in shell scripts:
Evaluating the boolean goes as follows:
If i == 1 is True, then we must test what is on the other side of the and. 2 is also true, so we exit early (as the or is already known to be true, returning the last value 2.
If i == 1 is False, we skip the other side of the and and evaluate the other side of the or, which is 4. 4 is true, so we return 4.
What you have is an example of short-circuiting with and and or.
We can add some parens to see how the expression is evaluated:
(((i == 1) and 2) or 4)
or: only evaluates the second argument if the first one is False
and: only evaluates the second argument if the first one is True
Which makes 2 the result of the evaluation when i is 1 (since 2 is truthy and the second operand of the or will not be evaluated), and 4 otherwise (since a False in the first operand of the and means the second operand of the or will be returned).
About conditional statement:
In Python, some values can be evaluated kinda like True and False even if they are not boolean values:
For instance:
if []:
print "this branch is never reached since it evaluates to False"
print "due to the empty list"
if 0:
print "same thing here"
(More info about how some data types are evaluated in a boolean expression here: http://getpython3.com/diveintopython3/native-datatypes.html#booleans)
Now, back to the following statement:
(i == 1 and 2 or 4)
Here we have a boolean expression as well. Dissecting the expression, we have the following:
(i == 1 and 2 or 4)
((i == 1) and 2) or (4) # This is the order of evaluation
Since 2 and 4 are not 0, they will always evaluate to True
Now, understanding the output: The output will be always 4 if i is different than 1.
The reason for this is because if i == 1 the returned value is 2. The value 2 is returned because it is not necessary to evaluate the whole expression 2 or 4 since the first part is evaluated to True.
On the other hand, if i is not 1, the value 4 has to be evaluated. Because 4 is not zero, it is evaluated to True.
This is why the output is always 4 if i is different than 1
About the "ternary" operator:
Python does not have a ternary operator like in Java/C/C++ (?:) but you have a similar effect using if-else:
# value a = <value if condition is true> if <condition> else <other value>
# Example
>>> a = 2 if 1 < 10 else 0
>>> a
2
Therefore, if you wanted to print values from the range function, you should use the following:
for i in range(1,6):
print "pet%d" % i
Or maybe, printing A for even numbers and B for odd numbers:
for i in range(1,6):
print "pet%s" % ("A" if i % 2 == 0 else "B")
I might be wrong, but I know in javaScript when you say i == 1 and 2 or 4 it evaluates from left to right.
Thus the computer will determine if i == 2, and if it does, it will have a temp val of bits set to 1, and take that flag and bitwise AND it with 2, resulting in the value 2. Since the next expression is an OR, it will not compute that since the condition is true regardless, and the "and" operator short circuits. Thus 2 will print.
However if i != 2, then the first part will evaluate to false, and have a temp val of all 0 bits. Then, the or with 4 will change the value to 4 (a bitwise 0 with 4 returns 4), and so 4 will print.
I hope this makes sense! Let me know if you have any other questions.

Count the number of times each element appears in a list. Then making a conditional statement from that

write a function that takes, as an argument, a list called aList. It returns a Boolean True if the list contains each of the integers between 1 and 6 exactly once, and False otherwise.
This is homework and I thought I had it right, but it is now telling me that it isn't right. Here is my code.
def isItAStraight(aList):
count = 0
for i in set(aList):
count += 1
return aList.count(i) == 1
for some reason even if a number appears more than once it still gives true and I can't figure out why it won't give me false unless the first or last number are changed.
Each number has to occur only one time otherwise it is false.
So like take [1,2,3,4,5,6]
would be true.
But [1,2,2,3,4,5]
would be false.
Also, I can't import things like Counter or collections (though it would be so much easier to do it isn't apart of the assignment.)
The list is randomly generated from 1 to 6.
With a return inside the loop, you are only checking one value. You need to check each value. Also, instead of looping through the items of the list, you should loop through the items you're actually looking for. It would also help to make sure there are the correct number of items in the list.
def isItAStraight(aList):
if len(aList) != 6:
return False
for i in range(1, 7):
if aList.count(i) != 1:
return False
return True
But the easiest way to do this is to simply sort the list and check if it's what you're looking for:
def isItAStraight(aList):
return sorted(aList) == list(range(1, 7))
You need to be careful about what's inside the list. What you've written is a basically the same as the pseudo-code below:
let count = 0
for every unique element in aList:
Add 1 to count
if count is now 1, return true.
This will always return true if there is at least one element in aList, since you're adding 1 to count and then returning immediately.
A couple approaches to consider:
Create a 6 element list of all zeros called flags. Iterate over aList and set the corresponding element in flags to 1. If flags is all ones, then you return true.
Sort the list, then check if the first six numbers are 1, 2, 3, 4, 5, 6.

How to check consecutive number in list?

This is my homework.
The problem is to find a way to check whether the items in a list are consecutive or not.
The following is code I've written:
def consecutive(var):
for x in range(2, len(var)):
forward = var[x] - var[x-1]
backward = var[x-1] - var[x-2]
if forward == backward:
return True
else:
return False
var = []
print 'Enter your number:'
while True:
num = raw_input()
if num == '':
break
var += [int(num)]
print consecutive(var)
If I input numbers like 1, 2, 3, 4, 5 then I will get True
If I input numbers like 2, 6, 3, 9, 7, 1, 4 then I'll get False
Here, I succeeded returning True or False values respectively.
But there're two questions that make me upset because if I use my code to solve the questions, I don't get the value that I want (it gives me an error)
First question: Is an empty list considered a consecutive list or not?
Second: Is a list that involves a single value considered a consecutive list or not?
Would you like to help me?
By mathematical convention as discussed in the comments, it would be standard to consider both an empty list and a list with a single element as consecutive, should it not be specified in your homework more precisely.
By the logic of vacuous truth, were a list to not have consecutive order it would require enough elements (2) to break this condition of ordering. To handle this in your existing code, you could simply perform a check before your main check to ensure the base cases of an empty list and a list with one element return True.

Categories