-1

I am trying to check if 3 values are equal to None because I want to make error handling for my PyQT5 application. I have tried every possible way of checking if values are empty but still not the wanted result. At the moment I have 3 QLineEdit's that I need to check if they are empty but it always displays different information.

        self.name_edit = self.nameEdit.text()
        self.jobTitle_edit = self.jobTitleEdit.text()
        self.mob_edit = self.mobEdit.text()
        self.businessUnit = str(self.BusinessUnit.currentText())        

        check = [self.name_edit, self.jobTitle_edit, self.mob_edit]

        if check == None:
            data = "FailedNoInfo"
            self.windows2 = notifyWindow(data)
            print(self.nameEdit.text())
            print(self.mobEdit.text())
        else:
            ProcessData(data)
            print(self.nameEdit.text())
            print(self.mobEdit.text())
            print(self.jobTitleEdit.text())

This is the last way I checked if they were empty and this resulted in nothing. Does someone have an idea why this is going wrong with multiple values as this is working fine without any issues with 1 value.

Edit 1

Checking if the check is None is stupid because it is not it is an empty array but not None. But nothing seems to be working here been stuck on this for waaaay to long.

Blokhunt
  • 1
  • 1
  • 1
    The `text()` method will never return `None`. If you want to know if **all three** values are empty, you can do `if not any(check)`. If you want to know if **at least one** value is empty, you can do `if not all(check)`. – ekhumoro Aug 03 '21 at 19:42

2 Answers2

0

There are two misconceptions here:

  1. the text property of QLineEdit always returns a string, even if it's empty, and an empty string is "", not None:
value = self.lineEdit.text()
print(value == None) # this will return False
print(value is None) # same as above
if not value:
    print('Empty string')
else:
    print(value)

Note that the official Style Guide for Python Code (aka, PEP-8) suggest to always check with is or is not for singletons like None.

  1. a list is a list, it is not None, no matter if it's empty or if all of its items are None:
myList = [None, None]
print(myList is None) # this will return False
myList = []
print(myList is None) # this too will return False

The last is important: as said, even if it's empty, an empty list is still a list object, not None (see for example this question): None is not an abstract meaning, it is a very specific and peculiar object that fundamentally means: this is absolutely nothing, not "something empty", just nothing".
An empty box is not nothing, it is still a box, no matter its contents: in fact, you call it an empty box, not "nothing".

If you want to check if all items contain text, then you can use all:

check = [self.name_edit, self.jobTitle_edit, self.mob_edit]
if not all(check):
    # some items are empty, since "not all" of them have contents
else:
    # go on...

Alternatively, if you want to check if all strings are empty (but still check if at least any of them has contents), use any:

if not any(check):
    # all strings are empty
elif not all(check):
    # *some* strings are empty
else:
    # all strings have text
musicamante
  • 41,230
  • 6
  • 33
  • 58
  • Thank you for your answer! But this also still gives does not make a difference as it will always go to the true statement and never to the else statement if I try this – Blokhunt Aug 03 '21 at 19:51
  • @Blokhunt what do you mean by "it will always go to the true statement"? – musicamante Aug 03 '21 at 19:53
  • @musicmante At the moment I have this: check = [self.name_edit, self.jobTitle_edit, self.mob_edit] if all(check): print("All texts are empty") data = "FailedNoInfo" self.windows2 = notifyWindow(data) else: ProcessData(data) But it will always go to the else statement and create the object ProccessData(data) – Blokhunt Aug 03 '21 at 19:59
  • @Blokhunt Please read more carefully: the statement should be `if not all(check):`. You're missing the **`not`**. Python has always tried to focus on [English] language syntax: the concept here is that you need to check whether *not every field has content*, hence: `if not all`. If you do `if all`, it means "check if *all* fields have content". – musicamante Aug 03 '21 at 20:03
  • When I change it to "if not all(check)" it will always parse it to the "All strings are empty" outcome so really weird it is always eighter one or the other. – Blokhunt Aug 03 '21 at 20:10
  • @Blokhunt as explained in the last part of my question, if you want to know whether *some* items are empty or *all* items are empty, then you need to use `any` as shown in the example code. If you want to get which items are empty, then use a `for` or appropriate `if/elif/elif...` within a `not all` block. – musicamante Aug 03 '21 at 20:20
  • Done every possible way you have given to me but not working I am thinking about an other solution because think it is something else with my code thank you for your assistance – Blokhunt Aug 04 '21 at 15:05
  • @Blokhunt sorry but "it's not working" is pointless without knowing what you actually did. My code *does* work, that's basic python logic (and you can see that's exactly what others pointed out in answers and comments). I'd suggest you to **not** look for another solution, but to better investigate on this one, and get the occasion to better learn the logical patterns of if statements and builtin functions. Create a basic script (no interaction), with simple functions showing the results of those statements and a bunch of possible combinations of variables; see the results and *study* them. – musicamante Aug 04 '21 at 15:13
0

This is going wrong because you're comparing a list with a None value.

check = [1, 2, 3]
print(check == None)    # Outputs False

Therefore, your if statement will always enter in the else clause.


Note that a variable with a None value and a variable with an empty string value are different things:

var1 = None
var2 = ''
print(var1 == var2)    # Outputs False
  1. If you want to check whether all values are None, you can use
if all(value is None for value in (self.name_edit, self.jobTitle_edit, self.mob_edit)):
  1. If you want to check whether all values are empty strings, you can use
if all(not len(value) for value in (self.name_edit, self.jobTitle_edit, self.mob_edit)):
  1. If you want to check whether all values are None or empty strings, you can use
if not any((self.name_edit, self.jobTitle_edit, self.mob_edit)):
enzo
  • 9,861
  • 3
  • 15
  • 38
  • Note that the second point is unnecessarily verbose: there's no point in checking the length of a string to check if it has content, so it could just be `if all(not value for value in ...)` or even better `if not all(value for value in ...)`, since it doesn't need the added negation for each item. – musicamante Aug 03 '21 at 20:16
  • But `not value` would include `None` values as well, and the second point was meant to include only empty strings!!! I'm so sorry. – enzo Aug 03 '21 at 20:19
  • Noo problem thank you for your answer – Blokhunt Aug 03 '21 at 20:21
  • @enzo Sorry but your argument isn't valid, for two reasons: 1. the OP is getting those values from QLineEdit (which *always* returns a string), so that is not a problem. 2. in any case, even assuming that there could be `None` values in the list, your `not len(value)` would raise a TypeError exception, since `None` has no length. – musicamante Aug 03 '21 at 20:29
  • @musicamante 1. I don't know PyQt, but since the OP added the `None` check I assumed `text()` could return `None`. 2. The second point was added in case `text()` only returned strings, that's why I added the first and third points. – enzo Aug 03 '21 at 20:34
  • @enzo I didn't mean that your answer is wrong, just that the syntax for the second point is unnecessarily verbose: since your assumption (which is correct) is "in case text() only returned strings", there's no point in checking the length. *Yes*, the `not value` statement *could* include `None`, but since you said that in that case you assume `text()` only returns strings, there would be no `None` values at all there. What the OP cares about is whether the string has content or not, no matter its length, so `not value` will suffice, and it's also better for readability *and* performance-wise. – musicamante Aug 03 '21 at 20:49