问题:仅基于结构动态计算MLM中的状态。
它工作正常,但速度太慢了。只有测试处理大约需要20秒。我试图用生成器替换一些列表,但这是一个糟糕的解决方案,因为它们必须在运行时进行更改。我对增强没有更多的想法,但我确信代码是如此丑陋和可优化。主要逻辑在最后一个函数中。
@property
def consultants_at_first_two_lines(self):
return self.first_line.filter(consultant_experience=True) | self.second_line.filter(consultant_experience=True)
def golden_club_bonuses(self, start_date, end_date):
status = self.golden_club_status_on_date(date.today())
result = status.bonuses
if start_date:
result = filter(lambda x: x.bonus_date >= start_date, result)
if end_date:
result = filter(lambda x: x.bonus_date <= end_date, result)
return result
def executed_in_period(self, start_date=None, end_date=None):
result = TreeNode.objects.filter(executor=self).order_by('contract_date')
if start_date:
result = result.filter(contract_date__gte=start_date)
if end_date:
result = result.filter(contract_date__lte=end_date)
return result
def invited_in_period(self, start_date=None, end_date=None):
result = self.children.order_by('contract_date')
if start_date:
result = result.filter(contract_date__gte=start_date)
if end_date:
result = result.filter(contract_date__lte=end_date)
return result
def golden_club_status_on_date(self, status_date):
step = timedelta(days=1)
if self.invited_in_period():
enter_period_start = self.invited_in_period()[0].contract_date
else:
enter_period_start = None
if enter_period_start:
current_date = enter_period_start
else:
current_date = self.contract_date + step
prev_rank = None
current_rank = 0
next_rank = 0
invited = []
executed = []
rank_apply_date = None
bonuses = []
while current_date <= status_date:
if enter_period_start and enter_period_start + time_settings['golden_club_enter_period'] < current_date:
enter_period_start = None
if rank_apply_date == current_date:
if not self.consultant_experience and next_rank:
TreeNode.objects.filter(id=self.id).update(consultant_experience=True)
if current_rank == 1:
for newbie in executed:
bonus = GoldenClubBonus(executor=self,
executed=newbie,
total=golden_club_awards['consultant_executing'],
bonus_date=current_date)
bonuses.append(bonus)
elif current_rank == 2:
for newbie in invited:
bonuses.append(GoldenClubBonus(executor=self,
executed=newbie,
total=golden_club_awards['senior_consultant_executing'],
bonus_date=current_date))
my_consultants = self.consultants_at_first_two_lines.all()
grandsons = [child.executed_in_period(start_date=(current_date-timedelta(days=1)).replace(day=1),
end_date=current_date-timedelta(days=1)) for child in (cons for cons in list(self.consultants_at_first_two_lines)
if cons.golden_club_status_on_date(status_date=date.today()).prev_rank)]
for x in my_consultants:
if x.golden_club_status_on_date(current_date - step):
for grandson in x.executed_in_period(start_date=(current_date - step).replace(day=1),
end_date=current_date - step):
grandsons.append(grandson)
for grandson in grandsons:
bonuses.append(GoldenClubBonus(executor=self,
executed=grandson,
total=golden_club_awards['senior_consultants_son_executing'],
bonus_date=current_date))
prev_rank = current_rank
current_rank = next_rank
next_rank = current_rank - 1 if current_rank > 0 else 0
del invited[:]
del executed[:]
for x in self.invited_in_period(start_date=current_date, end_date=current_date):
if not (enter_period_start or current_rank or next_rank):
enter_period_start = current_date
invited.append(x)
for x in self.executed_in_period(start_date=current_date, end_date=current_date):
executed.append(x)
if current_rank == 0:
if next_rank == 0 and \
enter_period_start and \
len(self.invited_in_period(start_date=enter_period_start,
end_date=enter_period_start + time_settings['golden_club_enter_period'])) >= 10:
next_rank = 1
enter_period_start = None
elif current_rank == 1:
if next_rank == 0 and (len(invited) >= 5 or len(executed) >= 10):
next_rank = 1
if next_rank == 1 \
and (len(invited) >= 5 or len(executed) >= 20) \
and len(self.consultants_at_first_two_lines) >= 3:
next_rank = 2
elif current_rank == 2:
if next_rank == 1 and (len(invited) >= 5 or len(executed) >= 20):
next_rank = 2
rank_apply_date = next_nth_day_of_month(date1=current_date, n=1, include_today=False)
current_date += step
result = GoldenClubStatus(prev_rank=prev_rank,
current_rank=current_rank,
next_rank=next_rank,
bonuses=bonuses,
enter_period_start=enter_period_start,
rank_apply_date=rank_apply_date,
status_date=status_date,
invited=self.invited_in_period(),
executed=self.executed_in_period(),
owner=self)
return result发布于 2015-01-14 11:49:07
以下是两件小事:
if start_date:
result = filter(lambda x: x.bonus_date >= start_date, result)
if end_date:
result = filter(lambda x: x.bonus_date <= end_date, result)应该是
if start_date:
result = (x for x in result if x.bonus_date >= start_date)
if end_date:
result = (x for x in result if x.bonus_date <= end_date)另外,
grandsons = [child.executed_in_period(start_date=(current_date-timedelta(days=1)).replace(day=1),
end_date=current_date-timedelta(days=1))
for child in (cons for cons in list(self.consultants_at_first_two_lines)
if cons.golden_club_status_on_date(status_date=date.today()).prev_rank)]应该只是
day = timedelta(days=1)
today = date.today()
yesterday = current_date - day
yesterday_dayeq1 = yesterday.replace(day=1)
grandsons = [child.executed_in_period(start_date=yesterday_dayeq1, end_date=yesterday)
for child in self.consultants_at_first_two_lines
if child.golden_club_status_on_date(status_date=today).prev_rank]https://codereview.stackexchange.com/questions/77477
复制相似问题