2012-02-02 15 views
-1

我做我的第一個傳銷軟件,我想我設法編碼如何從下線獲得點,即使它是遞歸問題我沒有使用遞歸,我可能會重構爲遞歸版本if這似乎更好。在我們的系統中,分銷商的水平是衡量我的銀牌數和每個銷售的產品的促銷/獎金/分數/積分上線,所以如果鮑勃是愛麗絲的贊助商,愛麗絲購買,那麼鮑勃將獲得積分以購買的銀飾數量來衡量。我添加了一個業務功能,以我的用戶等級:傳銷下線分佈計數

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

遞歸可能是正確的方式來做到這一點,但不是我的解決方案仍然可以,我可以繼續前進,並保留此代碼,或者你認爲這是不可接受的?

感謝您的任何建設性的批評。

回答

2

主要的問題我在這裏看到的是,你基本上試圖做一個廣度優先搜索(你看所有誰是分銷商下面的用戶,再看看那些經銷商,等等等等以下用戶),但每當while循環循環時,您只查看最後一個分發服務器下方的用戶。

如果我們打破的重要組成部分弄成蟒蛇十歲上下,你會得到這樣的:

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) 
+0

謝謝你的回答。如果在這種情況下更合適,我想知道遞歸解決方案。 – 2012-02-02 20:56:17

+0

只要你不認爲你會遇到堆棧溢出的情況(即你最終不得不自稱太多次),遞歸解決方案就沒有問題。儘管如此,他們通常更容易閱讀和理解。 – Xentac 2012-02-17 06:31:38