Coverage for jstark / grocery / average_purchase_cycle.py: 100%

17 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-03-23 22:34 +0000

1"""AvgPurchaseCycle feature""" 

2 

3import pyspark.sql.functions as f 

4from pyspark.sql import Column 

5 

6from jstark.features.feature import DerivedFeature 

7from jstark.features.earliest_purchase_date import EarliestPurchaseDate 

8from jstark.features.most_recent_purchase_date import MostRecentPurchaseDate 

9from .basket_count import BasketCount 

10 

11 

12class AvgPurchaseCycle(DerivedFeature): 

13 def column_expression(self) -> Column: 

14 return f.try_divide( 

15 f.datediff( 

16 MostRecentPurchaseDate( 

17 self.as_at, 

18 self.feature_period, 

19 first_day_of_week=self._first_day_of_week, 

20 ).column, 

21 EarliestPurchaseDate( 

22 self.as_at, 

23 self.feature_period, 

24 first_day_of_week=self._first_day_of_week, 

25 ).column, 

26 ), 

27 BasketCount( 

28 self.as_at, 

29 self.feature_period, 

30 first_day_of_week=self._first_day_of_week, 

31 ).column, 

32 ) 

33 

34 @property 

35 def description_subject(self) -> str: 

36 return "Average purchase cycle" 

37 

38 @property 

39 def commentary(self) -> str: 

40 return ( 

41 "How often (measured in days) is a purchase made. This " 

42 + "is very useful to determine how often a customer buys " 

43 + "a particular product" 

44 ) 

45 

46 def default_value(self) -> Column: 

47 return f.lit(None)