@@ -1566,17 +1566,55 @@ class truth:
15661566
15671567 If '/', or '%' are inconvenient, you can change them by passing the
15681568 *slash* and *interpolate* arguments to truth().
1569+
1570+ By default *bool*() is used to determine whether the value is true or false.
1571+ However you can override this behavior by passing a value to *is_true*. It
1572+ may be a simple value or it may be a callable that accepts the given value
1573+ as its only argument.
1574+
1575+ The formatter may contain a third section, which if present is taken to be a
1576+ format specification that is applied to value before it is interpolated into
1577+ the output.
1578+
1579+ As an example of these features, consider this example:
1580+
1581+ >>> contestants = [
1582+ ... dict(name="Elinor", index=27, wins="car" ),
1583+ ... dict(name="Vernon", index=130, wins="phone"),
1584+ ... dict(name="Lee", index=0),
1585+ ... dict(name="Lita", comment='disqualified'),
1586+ ... ]
1587+
1588+ >>> for contestant in contestants:
1589+ ... name = contestant.get('name')
1590+ ... index = contestant.get('index')
1591+ ... index = truth(index, is_true=index is not None)
1592+ ... wins = truth(contestant.get('wins'))
1593+ ... comment = truth(contestant.get('comment'))
1594+ ... print(f"{index:%/ ✗/>3}: {name}{wins: wins a %/ loses}{comment: (%)/}")
1595+ 27: Elinor wins a car
1596+ 130: Vernon wins a phone
1597+ 0: Lee loses
1598+ ✗: Lita loses (disqualified)
1599+
15691600 """
15701601
1571- def __init__ (self , value , formatter = None , * , interpolate = '%' , slash = '/' ):
1602+ def __init__ (self , value , formatter = None , * , is_true = None , interpolate = '%' , slash = '/' ):
15721603 self .value = value
1604+ if is_true is None :
1605+ self .is_true = bool (value )
1606+ elif callable (is_true ):
1607+ self .is_true = is_true (value )
1608+ else :
1609+ self .is_true = bool (is_true )
15731610 self .interpolate = interpolate
15741611 self .slash = slash
15751612 if formatter :
1576- use_if_true , _ , use_if_false = formatter .partition (self .slash )
1577- self .defaults = use_if_true , use_if_false
1613+ use_if_true , _ , rest = formatter .partition (self .slash )
1614+ use_if_false , _ , preformatter = rest .partition (self .slash )
1615+ self .defaults = use_if_true , use_if_false , preformatter
15781616 else :
1579- self .defaults = 'yes' , 'no'
1617+ self .defaults = 'yes' , 'no' , ''
15801618
15811619 def format (self , formatter = None ):
15821620 """Expand truth to a string.
@@ -1593,19 +1631,22 @@ def format(self, formatter=None):
15931631 return self .__format__ (formatter )
15941632
15951633 def __format__ (self , formatter ):
1596- value = self .value
15971634 if formatter :
1598- use_if_true , _ , use_if_false = formatter .partition (self .slash )
1635+ use_if_true , _ , rest = formatter .partition (self .slash )
1636+ use_if_false , _ , preformatter = rest .partition (self .slash )
15991637 else :
1600- use_if_true , use_if_false = self .defaults
1601- out = use_if_true if bool (value ) else use_if_false
1602- return out .replace (self .interpolate , str (value ))
1638+ use_if_true , use_if_false , preformatter = self .defaults
1639+ out = use_if_true if self .is_true else use_if_false
1640+ value = str (self .value )
1641+ if preformatter and self .interpolate in out :
1642+ value = f"{ self .value :{preformatter }} "
1643+ return out .replace (self .interpolate , value )
16031644
16041645 def __str__ (self ):
1605- return self .defaults [0 ] if self .value else self .defaults [1 ]
1646+ return self .defaults [0 ] if self .is_true else self .defaults [1 ]
16061647
16071648 def __bool__ (self ):
1608- return bool ( self .value )
1649+ return self .is_true
16091650
16101651 def __repr__ (self ):
16111652 return f"{ self .__class__ .__name__ } ({ bool (self .value )} )"
0 commit comments