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

前端 未结 11 2542
温柔的废话
温柔的废话 2021-02-14 01:33

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 numb

相关标签:
11条回答
  • 2021-02-14 01:53

    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!

    0 讨论(0)
  • 2021-02-14 01:54

    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.

    0 讨论(0)
  • 2021-02-14 01:56

    I don't know if this is better for you, but doing it this way would work:

    if (self.months && self.dollars) || (self.months && self.lifetime) || (self.dollars && self.lifetime):
       raise ValueError("Coupon can be valid for only one of: months, lifetime, or dollars") 
    
    0 讨论(0)
  • 2021-02-14 02:01

    Keep the quantity in a single field, and have the type be a separate field that uses choices.

    0 讨论(0)
  • 2021-02-14 02:02

    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()
    
    0 讨论(0)
提交回复
热议问题