Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

python

django

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)
like image 960
Ted Avatar asked Jul 14 '11 01:07

Ted


People also ask

How do you check if 3 numbers are the same in Python?

a() == b() == c() is functionally equivalent to a() == b() and b() == c() whenever consecutive calls to b return the same value and have the same aggregate side effects as a single call to b .

How do I return a true or false function in Python?

bool() in Python. Python bool() function is used to return or convert a value to a Boolean value i.e., True or False, using the standard truth testing procedure.

Why is True 2 in Python?

Because Boolean in Python is a subtype of integers.

How do I check if a condition is true in Python?

You can check if a value is either truthy or falsy with the built-in bool() function. According to the Python Documentation, this function: Returns a Boolean value, i.e. one of True or False .


2 Answers

One thing I've done in similar situations is this:

coupon_types = (self.months, self.dollars, self.lifetime,)

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

It's now much easier to add new coupon types to check for in the future!

like image 166
randlet Avatar answered Oct 16 '22 08:10

randlet


You could also use a list comp to filter false values:

if len([x for x in [self.months, self.dollars, self.lifetime] if x]) > 1:
    raise ValueError()

Or building off MRAB's answer:

if sum(map(bool, [self.months, self.dollars, self.lifetime])) > 1:
    raise ValueErrro()
like image 5
zeekay Avatar answered Oct 16 '22 07:10

zeekay