Количество нижестоящих распределений MLM - PullRequest
0 голосов
/ 02 февраля 2012

Я делаю свое первое программное обеспечение MLM и думаю, что мне удалось написать код, как получить баллы из нижестоящего уровня, хотя это рекурсивная проблема, я не использовал рекурсию и мог бы реорганизовать рекурсивную версию, если это кажется лучше. В нашей системе уровень дистрибьютора измеряется количеством серебряных монет, и за каждый проданный продукт акция / бонус / балл / баллы работает вверх, поэтому, если Боб является спонсором Алисы, а Алиса совершает покупку, тогда Боб получает очки измеряется в количестве серебра для этой покупки. Я добавил бизнес-функцию в свой класс пользователя:

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}}

Рекурсия может быть правильным способом сделать это, но разве мое решение все еще не в порядке, и я могу сейчас перейти и сохранить этот код или вы думаете, что он неприемлем?

Спасибо за любую конструктивную критику.

1 Ответ

2 голосов
/ 02 февраля 2012

Основная проблема, которую я вижу здесь, заключается в том, что вы, по сути, пытаетесь выполнить поиск в ширину (вы смотрите на всех пользователей, которые находятся ниже дистрибьютора, а затем на всех пользователей ниже этих дистрибьюторов и т. Д. И т. Д.), но каждый раз при выполнении цикла while вы смотрите только на пользователей ниже последнего распространителя.

Если мы разбиваем важные части на что-то python-ish, вы получите следующее:

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

Как видите, значение распространителя после получения первого набора нисходящих линий является последним распределителем в нисходящем канале пользователя.Затем в следующий раз при запуске цикла for вы будете смотреть только на нижестоящую структуру последнего дистрибьютора.

Традиционно алгоритм обхода дерева либо рекурсивный, либо основан на цикле со стеком.Как правило, вы выбираете один или другой на основе ограничений памяти.Чтобы решение оставалось итеративным, вам нужно переписать приведенный выше код python-ish:

downlinestack = []
distributor=self
downlinestack += distributor.downline
while downlinestack:
    downline = downlinestack.pop()
    for person in downline:
        downlinestack.append(person.downline)
...