HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Is it possible to optimize the following boolean checks?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thebooleanchecksfollowingpossibleoptimize

Problem

The following code works and it prints out only True as it is supposed to, for all the different cases:

class User(object):
  def __init__(self, key):
    self.key = key

def is_ok(user_dbs, self_db):
  count = len(user_dbs)
  if not self_db:
    return not count
  return (count != 1 or self_db.key == user_dbs[0].key) and count != 2

print 'Should print only True:'
print is_ok([],                 None)    is True   # found nothing and no self
print is_ok([],                 User(1)) is True   # found nothing and self
print is_ok([User(1)],          None)    is False  # found one and no self
print is_ok([User(1)],          User(1)) is True   # found one and it is you
print is_ok([User(2)],          User(1)) is False  # found one and it is not you
print is_ok([User(1), User(2)], None)    is False  # found two and no self
print is_ok([User(1), User(2)], User(1)) is False  # found two and one of them is you
print is_ok([User(2), User(1)], User(1)) is False  # found two and one of them is you
print is_ok([User(2), User(3)], User(1)) is False  # found two and none of them is you


The whole thing is to check if the username is available for a new user or when an existing user is updating his current username.

The user_dbs can have maximum 2 records as it has a limit in the actual query. So here is the breakdown:

  • If there are 2 records then we know for sure that the particular username is not available.



  • If there are 0 records then we know for sure that this username is available.



  • If there is 1 record then:



  • If it's a new user then the username is not available



  • If it's an existing user and that user is yourself then the username is available, otherwise not.



So can we optimize somehow the is_ok function above?

Try it live: repl.it/XHC

Solution

I came up with a different solution by utilizing Python's magic method for == which is __eq__(self, other).

I define it in the User class like so:

class User(object):
    def __init__(self, key):
        self.key = key
    def __eq__(self, other):
        return self.key == other.key if isinstance(other, User) else False


This allows you to do the obvious User(1) == User(2) testing but also this allows you to test membership in a collection using the in keyword:

User(1) in [User(1)] # This will return True
User(1) in [User(2)] # This will return False


We can then change the condition slightly to make the is_ok function like this:

def is_ok(user_dbs, self_db):
    count = len(user_dbs)
    if not self_db:
        return not count
    return count == 1 and self_db in user_dbs or count == 0


This has the advantage of being a bit more readable, and hence Pythonic. This might come in handy elsewhere as well.

Another minor point is that if you ever rename key to something else or change the structure of your User class, this code will still work (remember to update __eq__!), while most of the alternatives will break.

Code Snippets

class User(object):
    def __init__(self, key):
        self.key = key
    def __eq__(self, other):
        return self.key == other.key if isinstance(other, User) else False
User(1) in [User(1)] # This will return True
User(1) in [User(2)] # This will return False
def is_ok(user_dbs, self_db):
    count = len(user_dbs)
    if not self_db:
        return not count
    return count == 1 and self_db in user_dbs or count == 0

Context

StackExchange Code Review Q#60510, answer score: 6

Revisions (0)

No revisions yet.