Alex Rivera | Logout

Python: if more than one of three things is true, return false

Asked 2011-07-14T01:37:40.613
12

I'm writing a django model that allows my site to have coupons.

Coupons can have three types: lifetime account voucher, certain period of months voucher, certain number of dollars voucher.

To keep things simple, I'm only allowing coupons to have one of the three possible values (i.e. a voucher can't be for $10 and 5 months). But I want to check when a coupon is being saved to ensure this rule is true.

Currently I have:

true_count = 0
if self.months:
    true_count += 1
if self.dollars:
    true_count += 1
if self.lifetime:
    true_count += 1    

if true_count > 1:
    raise ValueError("Coupon can be valid for only one of: months, lifetime, or dollars")  

I know there's a better way to do this, but I'm not seeing it (call it coder's block).

Help is much appreciated.

In case it maters, the three types are int, int, and bool

months = models.IntegerField(default=0)
cents = models.IntegerField(default=0)
#dollars = models.FloatField(default=0.00)
#dollars replaced with integer cents per advice of group
lifetime = models.BooleanField(default=False)
Edit
Report

1 Answer

0

Even better solution than before, with combinations, any, and all. Assuming you have all the attributes you want to test in a sequence called attributes:

from itertools import combinations
any(map(all, combinations(attributes, 2)))

In english, it reads

Are any length-2 combinations of the attributes all true?

This solution works for an arbitrary number of attributes, and can be modified to test for an arbitrary number of them being true.

Although admittedly it's very inefficient, I'd say it's pretty cute and readable.

answered 2011-07-14T02:39:43.390

Your Answer