-1

我制作了我的第一个 MLM 软件,我想我设法编写了如何从下线获取积分的代码,即使这是一个递归问题,我没有使用递归,如果看起来更好,我可能会重构为递归版本。使用我们的系统,分销商的级别以银子的数量来衡量,并且对于每个售出的产品,促销/奖金/分数/积分都是在线进行的,因此如果 Bob 是 Alice 的赞助商并且 Alice 进行了购买,那么 Bob 将获得积分以那次购买的银子数量来衡量。我在我的用户类中添加了一个业务功能:

def this_month_non_manager_silver(self):
    silver = 0 
    today = date.today()
    timeline = date(today.year, today.month, 1) 
    downline = User.query(User.sponsor
            == self._key).fetch()
    distributor = self
    while distributor.has_downline():
        downline = User.query(User.sponsor == distributor.key).fetch()
        for person in downline:  
            orders = model.Order.all().filter('buyer_id =' , person.key.id()).filter('created >' , timeline).filter('status =', 'PAID').fetch(999999)
            for order in orders:
                for idx,item in enumerate(order.items):
                    purchase = model.Item.get_by_id(long(item.id()))
                    amount = int(order.amounts[idx])
                    silver = silver + amount*purchase.silver/1000.000 
            distributor = person
    return silver

现在可能要做的只是根据订单的深度对白银进行 %。该代码实际上为订单下线输出了正确的结果,但我尚未对其进行广泛测试,我想知道您是否认为代码看起来很奇怪,以及我是否考虑过所有问题,因为模型有些复杂/高级。用户类来自 webapp2,我可以使用子类,但我没有时间这样做,所以我只是将方法放入那里的用户类,现在我可以从 Jinja2 调用它{{user.this_month_non_manager_silver}}

递归可能是做到这一点的正确方法,但我的解决方案不是还可以吗?我可以继续前进并暂时保留此代码,还是您认为它不可接受?

感谢任何建设性的批评。

4

1 回答 1

2

我在这里看到的主要问题是您实际上是在尝试进行广度优先搜索(您查看位于分销商下方的所有用户,然后查看位于这些分销商下方的所有用户等),但每个在 while 循环循环时,您只查看最后一个分配器下方的用户。

如果我们把重要的部分分解成类似 python 的东西,你会得到:

distributor=self
while distributor.has_downline():
    for person in distributor.downline:
        distributor = person

可以看到,访问第一组下线后distributor的值就是用户下线中的最后一个distributor。然后下一次运行for循环时,您只查看最后一个分销商的下线。

传统上,tree-walking 算法要么是递归的,要么是基于循环的,带有堆栈。通常,您将根据内存限制选择其中一种。为了保持解决方案的迭代,您需要像这样重写上面的 python-ish 代码:

downlinestack = []
distributor=self
downlinestack += distributor.downline
while downlinestack:
    downline = downlinestack.pop()
    for person in downline:
        downlinestack.append(person.downline)
于 2012-02-02T06:52:57.153 回答