Ibrahim Yaacob
Ibrahim Yaacob

Reputation: 91

Cleaner way to do if else on multiple variables in Python

i have 4 variables here that needs to check whether its true or false. together will all the combinations.. 4 true, 3 true 1 false, 2 true 2 false, 1 true 3 false and all false.. in total this will make like 10++ condition (a bit lazy to count).

    if game and owner and platform and is_new and for_sale:
        game_copy = GameCopy.objects.all()
    elif game:
        game_copy = GameCopy.objects.filter(game=game)
    elif platform:
        game_copy = GameCopy.objects.filter(platform=platform)
    elif owner:
        game_copy = GameCopy.objects.filter(user=owner)
    elif is_new:
        game_copy = GameCopy.objects.filter(is_new=is_new)
    elif for_sale:
        game_copy = GameCopy.objects.filter(for_sale=for_sale)
    else:
        game_copy = GameCopy.objects.all()
    return game_copy

im looking for a leaner approach for this condition.. hopefully ended with something with 5 to 10 lines

Upvotes: 1

Views: 753

Answers (2)

pho
pho

Reputation: 25489

You could add everything that's truthy to a dictionary and then pass those to the function by unpacking keyword arguments.

args = { "game": game, "owner": owner, "platform": platform, "is_new": is_new, "for_sale": for_sale }

# check if all args are truthy
all_args = all(v for v in args.values())

# filter out only the truthy args
filtered_args = {k: v for k, v in args.items() if v}

if all_args or not filtered_args:
    # if all_args is true or filtered_args is empty
    game_copy = GameCopy.objects.all()
else:
    # Unpack filtered_args into filter()
    game_copy = GameCopy.objects.filter(**filtered_args)

Upvotes: 5

dspr
dspr

Reputation: 2423

You could change your variable to a set of flags (bits set in a unique integer)

GAME     = 1 << 0 # 1
OWNER    = 1 << 1 # 2
PLATFORM = 1 << 2 # 4
IS_NEW   = 1 << 3 # 8
FOR_SALE = 1 << 4 # 16

# for instance flags = GAME
# or           flags = OWNER | IS_NEW

# ensures that there is only one flag set and pass it to you filter
if (flags & (flags-1) == 0) and flags != 0: 
    game_copy = GameCopy.objects.filter(flags)

# Otherwise
else: game_copy = GameCopy.objects.all()
return game_copy

Upvotes: 1

Related Questions