2012-02-02 5 views
-1

나는 나의 첫 번째 MLM 소프트웨어를 만든다. 그리고 내가 재귀 적 문제는 아니지만 재귀를 사용하지 않았고 재귀 적 버전으로 리팩토링 할 수도 있지만, 그게 더 좋아 보인다. 우리 시스템에서는 배급사의 수준이 실바의 수로 측정되며 판매 된 각 제품에 대해 승진/보너스/점수/포인트가 올라가서 밥이 앨리스의 스폰서이고 앨리스가 구매 한 다음 밥이 포인트를 얻으면 그 구매에 대한 은도계 수로 측정됩니다. 내 사용자 클래스에 비즈니스 기능을 추가 : 할 수 있습니다 무엇MLM downline distribution count

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에서 호출 할 수 있습니다

재귀 이 작업을 수행하는 올바른 방법 일지 모르지만 여전히 내 솔루션이 OK가 아니며이 코드를 계속 사용하거나 계속 유지하거나 수용 할 수 없다고 생각합니까?

건설적인 비판에 감사드립니다.

답변

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

답장을 보내 주셔서 감사합니다. 이 경우 재귀 적 솔루션이 더 적절한지 궁금합니다. –

+0

재귀 솔루션은 스택 오버 플로우 상황에 처하게 될 것이라고 생각하지 않는 한 괜찮습니다 (즉, 자신이 너무 자주 전화해야하는 번거 로움). 그들은 일반적으로 읽고 이해하기가 더 쉽습니다. – Xentac