I just learned there are truthy and falsy values in python which are different from the normal True and False.
Can someone please explain in depth what truthy and falsy values are? Where should I use them? What is the difference between truthy and True values and falsy and False values?
We use "truthy" and "falsy" to differentiate from the bool values True and False. A "truthy" value will satisfy the check performed by if or while statements. As explained in the documentation, all values are considered "truthy" except for the following, which are "falsy":
None
False
Numbers that are numerically equal to zero, including:
0
0.0
0j
decimal.Decimal(0)
fraction.Fraction(0, 1)
Empty sequences and collections, including:
[] - an empty list
{} - an empty dict
() - an empty tuple
set() - an empty set
'' - an empty str
b'' - an empty bytes
bytearray(b'') - an empty bytearray
memoryview(b'') - an empty memoryview
an empty range, like range(0)
objects for which
obj.__bool__() returns False
obj.__len__() returns 0, given that obj.__bool__ is undefined
As the comments described, it just refers to values which are evaluated to True or False.
For instance, to see if a list is not empty, instead of checking like this:
if len(my_list) != 0:
print("Not empty!")
You can simply do this:
if my_list:
print("Not empty!")
This is because some values, such as empty lists, are considered False when evaluated for a boolean value. Non-empty lists are True.
Similarly for the integer 0, the empty string "", and so on, for False, and non-zero integers, non-empty strings, and so on, for True.
The idea of terms like "truthy" and "falsy" simply refer to those values which are considered True in cases like those described above, and those which are considered False.
For example, an empty list ([]) is considered "falsy", and a non-empty list (for example, [1]) is considered "truthy".
See also this section of the documentation.
Python determines the truthiness by applying bool() to the type, which returns True or False which is used in an expression like if or while.
Here is an example for a custom class Vector2dand it's instance returning False when the magnitude (lenght of a vector) is 0, otherwise True.
import math
class Vector2d(object):
def __init__(self, x, y):
self.x = float(x)
self.y = float(y)
def __abs__(self):
return math.hypot(self.x, self.y)
def __bool__(self):
return bool(abs(self))
a = Vector2d(0,0)
print(bool(a)) #False
b = Vector2d(10,0)
print(bool(b)) #True
Note: If we wouldn't have defined __bool__ it would always return True, as instances of a user-defined class are considered truthy by default.
Example from the book: "Fluent in Python, clear, concise and effective programming"
Truthy values refer to the objects used in a boolean context and not so much the boolean value that returns true or false.Take these as an example:
>>> bool([])
False
>>> bool([1])
True
>>> bool('')
False
>>> bool('hello')
True
Where should you use Truthy or Falsy values ?
These are syntactic sugar, so you can always avoid them, but using them can make your code more readable and make you more efficient.
Moreover, you will find them in many code examples, whether in python or not, because it is considered good practice.
As mentioned in the other answers, you can use them in if tests and while loops. Here are two other examples in python 3 with default values combined with or, s being a string variable. You will extend to similar situations as well.
Without truthy
if len(s) > 0:
print(s)
else:
print('Default value')
with truthy it is more concise:
print(s or 'Default value')
In python 3.8, we can take advantage of the assignment expression :=
without truthy
if len(s) == 0:
s = 'Default value'
do_something(s)
with truthy it is shorter too
s or (s := 'Default value')
do_something(s)
or even shorter,
do_something(s or (s := 'Default value'))
Without the assignment expression, one can do
s = s or 'Default value'
do_something(s)
but not shorter. Some people find the s =... line unsatisfactory because it corresponds to
if len(s)>0:
s = s # HERE is an extra useless assignment
else:
s = "Default value"
nevertheless you can adhere to this coding style if you feel comfortable with it.
Any object in Python can be tested for its truth value. It can be used in an if or while condition or as operand of the Boolean operations.
The following values are considered False:
None
False
zero of any numeric type, for example, 0, 0L, 0.0, 0j.
any empty sequence, for example, '', (), [].
any empty mapping, for example, {}.
instances of user-defined classes, if the class defines a __nonzero__() or __len__() method, when that method returns the integer zero or bool value False.
All other values are considered True -- thus objects of many types are always true.
Operations and built-in functions that have a Boolean result always return 0 or False for false and 1 or True for true, unless otherwise stated.
In case of if (!id) {}
!expr returns false if its single operand can be converted to true; otherwise, returns true.
If a value can be converted to true, the value is so-called truthy. If a value can be converted to false, the value is so-called falsy.
Examples of expressions that can be converted to false are:
null;
NaN;
0;
empty string ("" or '' or ``);
undefined.
Even though the ! operator can be used with operands that are not Boolean values, it can still be considered a boolean operator since its return value can always be converted to a boolean primitive. To explicitly convert its return value (or any expression in general) to the corresponding boolean value, use a double NOT operator or the Boolean constructor.
Example:
n1 = !null // !t returns true
n2 = !NaN // !f returns true
n3 = !'' // !f returns true
n4 = !'Cat' // !t returns false
While in case of if (id != null) {} it will only check if the value in id is not equal to null
reference https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_NOT
Falsy means something empty like empty list,tuple, as any datatype having empty values or None.
Truthy means :
Except are Truthy
In pure Spock/Groovy I need two separate assertions to verify that list contains some element and nothing else:
def "list has single element"() {
given:
def list = ['x']
expect:
list.size() == 1
list.first() == 'x'
}
I can make this assertion single-line by using Guava dependency:
expect:
Iterables.getOnlyElement(list) == 'x'
Is there a way to do the same in single line in pure Groovy/Spock? I don't want to use Guava too much in my tests.
EDIT
Actually for such a simple example just list == ['x'] is enough. I'm looking for a non Guava solution for something more complex, when multiple assertions must be performed on this single element:
def "list has single element"() {
given:
def list = [5.0]
expect:
def bigDecimal = Iterables.getOnlyElement(list)
bigDecimal.scale() == 1
bigDecimal.precision() == 2
}
If creating a helper method is acceptable, one can use with():
def "list has single element"() {
given:
def list = [5.0]
expect:
with onlyElementOf(list), {
it.scale() == 1
it.precision() == 2
}
}
where onlyElementOf() is
static <T> T onlyElementOf(Iterable<T> iterable) {
Iterator iterator = iterable.iterator()
def first = iterator.next()
assert !iterator.hasNext(), "Iterable has more than 1 element"
return first
}
This makes the test pretty readable.
Why these two strings are not matching on neither one: .equals() OR .compareTo() OR == OR Objects.equals()? I believe it should match atleast at one comparions.
Process proc1 = 'cat /home/output.txt'.execute()
Process proc2 = 'grep -o -m 1 webServiceReturn'.execute()
Process all = proc1 | proc2
def log = all.text.toString()
String svc = "webServiceReturn";
println (log)
println (svc)
//if (svc.equals(log)) {
//if (svc.compareTo(log)) {
//if(svc == log) {
if (Objects.equals((svc),(log))) {
println "MATCHED" }
else {
println "NOT MATCHED" }
The result on all four comparison are:
webServiceReturn
webServiceReturn
NOT MATCHED
I was able to reproduce your issue and making one minor modification to trim the white space on the results allowed it to match.
Do a trim on your all.text to remove any extraneous white space.
def log = all.text.trim()
You don't need the .toString() call either.
I just learned from another StackOverflow answer that using equals(), .contains and in fail to see same contents of strings of different type.
Groovy different results on using equals() and == on a GStringImpl
According to an answer by #dunes in the above question, the Groovy comparison using == uses compareTo() opportunistically before equals(). (The == comparison in Groovy has a remarkable difference from Java where it compares references).
def expandedString = "${'test'}"
def simpleString = 'test'
println "Expansion: ${expandedString}"
println "equals 'test' ? ${expandedString.equals(simpleString)}"
println " == 'test' ? ${expandedString == simpleString}"
The above outputs the following,
Expansion: test
equals 'test' ? false
== 'test' ? true
The following excerpt from the Groovy documentation omits the compareTo() piece that makes == different from equals().
In Groovy, using == to test equality is different from using the same operator in Java. In Groovy, it is calling equals. If you want to compare reference equality, you should use is like in the following example:
def list1 = ['Groovy 1.8','Groovy 2.0','Groovy 2.3']
def list2 = ['Groovy 1.8','Groovy 2.0','Groovy 2.3']
assert list1 == list2
assert !list1.is(list2)
http://docs.groovy-lang.org/next/html/documentation/core-operators.html#_identity_operator
I am new to grails I found in many examples that a variable may end with question mark (?)
like this
boolean equals(other) {
if(other?.is(this))
return true
}
above code contains If condition in that other is ending with a ? so I want to know the meaning of that representation
?. is a null safe operator which is used to avoid unexpected NPE.
if ( a?.b ) { .. }
is same as
if ( a != null && a.b ) { .. }
But in this case is() is already null safe, so you would not need it
other.is( this )
should be good.
There is a subtlety of ?., the Safe navigation operator, not mentioned in #dmahapatro's answer.
Let me give an example:
def T = [test: true]
def F = [test: false]
def N = null
assert T?.test == true
assert F?.test == false
assert N?.test == null // not false!
In other words, a?.b is the same as a != null && a.b only when testing for a boolean value. The difference is that the first one can either evaluate to a.b or null, while the second one can only be a.b or false. This matters if the value of the expression is passed on to another expression.
im a newbie in groovy so i have a question, i have two lists, and i want to know if a value that exists in the first list also exists in the second list, and it must return true or false.
I tried to make a short test but it doesn't works... here is what i tried:
// List 1
def modes = ["custom","not_specified","me2"]
// List 2
def modesConf = ["me1", "me2"]
// Bool
def test = false
test = modesConf.any { it =~ modes }
print test
but if i change the value of "me2" in the first array to "mex2" it returns true when it must return false
Any idea?
Simplest I can think of is using intersect and let Groovy truth kick in.
def modes = ["custom","not_specified","me2"]
def modesConf = ["me1", "me2"]
def otherList = ["mex1"]
assert modesConf.intersect(modes) //["me2"]
assert !otherList.intersect(modes) //[]
assert modesConf.intersect(modes) == ["me2"]
In case the assertion passed, you can get the common elements out of the intersection without doing a second operation. :)
I believe you want:
// List 1
def modes = ["custom","not_specified","me2"]
// List 2
def modesConf = ["me1", "me2"]
def test = modesConf.any { modes.contains( it ) }
print test
This disjoint() method returns true if there's no item that is common to both lists. It sounds like you want the negation of that:
def modes = ["custom","not_specified","me2"]
def modesConf = ["me1", "me2"]
assert modes.disjoint(modesConf) == false
modesConf = ["me1", "mex2"]
assert modes.disjoint(modesConf) == true
You can use any of the disjoint()/intersect()/any({}) which will return true/false. Below given are the examples:
def list1=[1,2,3]
def list2=[3,4,5]
list1.disjoint(list2) // true means there is no common elements false means there is/are
list1.any{list2.contains(it)} //true means there are common elements
list1.intersect(list2) //[] empty list means there is no common element.
def missingItem = modesConf.find { !modes.contains(it) }
assert missingFile == "me1"
In such case, missingItem will contain a missing element which exists in modesConf but doesn't exist in modes. Or will be null if everything is fine.