首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >动态计算MLM中的状态

动态计算MLM中的状态
EN

Code Review用户
提问于 2015-01-14 07:28:25
回答 1查看 183关注 0票数 0

问题:仅基于结构动态计算MLM中的状态。

它工作正常,但速度太慢了。只有测试处理大约需要20秒。我试图用生成器替换一些列表,但这是一个糟糕的解决方案,因为它们必须在运行时进行更改。我对增强没有更多的想法,但我确信代码是如此丑陋和可优化。主要逻辑在最后一个函数中。

代码语言:javascript
复制
@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
EN

回答 1

Code Review用户

回答已采纳

发布于 2015-01-14 11:49:07

以下是两件小事:

代码语言:javascript
复制
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)

应该是

代码语言:javascript
复制
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)

另外,

代码语言:javascript
复制
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)]

应该只是

代码语言:javascript
复制
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]
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/77477

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档