2009-10-27 36 views
1

我正在寫一個遊戲網站,其中繪製是一系列四位數。例如1234在Django中,如何編寫一個查詢來選擇四個整數的所有可能的組合?

我試圖在django中寫一個查詢,它將根據輸入的四位數字選擇所有的獲勝者,winners是相同數字或相同組合的任意組合,1 2 3 4,2 3 1 4 4 1 3 2都是勝利者。

是怎麼寫這個查詢的最有效方法。

---------------------編輯,很抱歉不能提供模型樣本這裏有如下:-----------

class Draw(models.Model): 
    digit1 = models.PositiveSmallIntegerField(null=True,blank=True) 
    digit2 = models.PositiveSmallIntegerField(null=True,blank=True) 
    digit3 = models.PositiveSmallIntegerField(null=True,blank=True) 
    digit4 = models.PositiveSmallIntegerField(null=True,blank=True) 
    draw_date = models.DateTimeField() 
    closed = models.BooleanField() 
    winner = models.BooleanField() 

    def __unicode__(self): 
     return "Draw For Week Ending %s" %(self.draw_date) 

    def get_absolute_url(self): 
     return "/draw/%s/" % (self.draw_date) 

    def save(self, force_insert=False, force_update=False): 
     if self.digit1 and self.digit2 and self.digit3 and self.digit4: 
      #check if there are winners 
      try: 
       winners = Ticket.objects.filter(draw=self.id,digit1=self.digit1,digit2=self.digit2,digit3=self.digit3,digit4=self.digit4) 
       self.winner = True 
      except Ticket.DoesNotExist: 
       self.winner = False     
      #close & save draw/winners 
      self.closed = True 
      # Add new Draw for following week. 
      new_date = self.draw_date + datetime.timedelta(hours=168) 
      new_draw= Draw(draw_date=new_date) 
      new_draw.save() 
     super(Draw, self).save(force_insert, force_update) # Call the "real" save() method. 

class Serial(models.Model): 
    serial = models.CharField(max_length=4) 
    closed = models.BooleanField(unique=False) 

    def __unicode__(self): 
     return "%s" %(self.serial) 

    def get_absolute_url(self): 
     return "/draw/serial/%s/" % (self.serial)  

class Ticket(models.Model): 
    draw = models.ForeignKey(Draw) 
    digit1 = models.PositiveSmallIntegerField() 
    digit2 = models.PositiveSmallIntegerField() 
    digit3 = models.PositiveSmallIntegerField() 
    digit4 = models.PositiveSmallIntegerField() 
    date = models.DateField(auto_now_add=True,editable=False) 
    active = models.BooleanField(default=True) 
    serial_used = models.ForeignKey(Serial,related_name="ticket_serial_used") 

    def __unicode__(self): 
     return "#: %s - %s" %(self.id,self.draw) 

    def get_absolute_url(self): 
     return "/ticket/%s/" % (self.id)  

    def save(self, force_insert=False, force_update=False): 
     if self.serial_used: 
      serial = Serial.objects.get(pk=self.serial_used.id) 
      serial.closed = True 
      serial.save() 
     super(Ticket, self).save(force_insert, force_update) # Call the "real" save() method. 
+0

你的模型在存儲玩家選擇的數字方面是如何設置的? – lemonad 2009-10-27 15:04:46

+0

無法看到您的模型而無法回答。 – 2009-10-27 15:19:41

+0

看到上面的模型聲明,我試圖確定是否他們是贏家當Save方法被重寫在Draw模型 – Rasiel 2009-10-27 15:26:30

回答

5

我建議調整代碼以保存數字,以便他們按排序順序保存。例如。如果用戶輸入「5262」,則應該將其存儲爲「2256」。然後,當您選擇一組獲勝的數字時,您可以對這些數字進行排序,並通過簡單的等式進行過濾。這將比嘗試檢查所有可能的組合的表現要好很多。

如果您需要將未排序的選項用於其他目的,請在模型sortedDigits中添加一個新字段,以便您可以與之進行比較。

+0

這是否意味着我改變我的模型從4個獨立數字到1個合併數字的聲明? – Rasiel 2009-10-27 16:40:23

+0

我認爲這會更簡單。或者,您只需對數字進行排序,然後讓您的篩選器對勝利組合進行四次平等檢查,每位數字一次。無論哪種方式將工作。 – 2009-10-27 17:09:51

+0

這個工程謝謝!我只是做了四位數字和平等檢查每個數字 – Rasiel 2009-10-27 17:38:54

0

代碼:

from itertools import permutations 
winning_numbers = "1234" 
winning_combinations = map(lambda v: "".join(v), list(permutations(winning_numbers, 4))) 

winners = GamesPlayed.objects.filter(numbers__in=winning_combinations) 

假設GamesPlayed是所有玩過的遊戲的模型對象,文本字段的數字包含格式爲NNNN的四個選定數字。

如果你使用Python 2.5 itertools沒有permutations。該文檔有一個實現,您可以使用:http://docs.python.org/library/itertools.html#itertools.permutations

+0

這聽起來像它會工作..我把它做的(基於我上面的模型聲明?): 贏家= Ticket.objects.filter(digit1__in = winning_combinations,digit2__in = winning_combinations,digit3__in = winning_combinations,digit4__in = winning_combinations) – Rasiel 2009-10-27 15:25:15

+0

可以根據上述模型在上下文中顯示您的答案,我基本上有一個想法,在這裏做,但我不知道文字字段的數字,因爲你正在使用一個字符串,我使用4個不同的整數。 – Rasiel 2009-10-27 15:32:04

+0

我假設:贏得數字將變成: winning_numbers =「%s%s%s%s」%(self.digit1,self.digit2,self.digit3,self.digit4) – Rasiel 2009-10-27 15:41:11

0

數字的順序是重要的嗎?

如果沒有,你可以買票的數字排序,然後按升序平,然後用你的代碼

winners = Ticket.objects.filter(draw=self.id,digit1=self.digit1,digit2=self.digit2,digit3=self.digit3,digit4=self.digit4) 

順便說一句,你try ... except塊時不會趕上那裏的情況沒有贏家。由get方法(see docs)拋出DoesNotExist異常。

如果沒有中獎彩票,filter方法將返回一個空的查詢集,但不會引發錯誤。然後您可以檢查是否有贏家使用if語句。

if winners 
    # there are winners 
    self.winner = True 
else: 
    # there are not winners 
    self.winner = False 
+0

嗨,沒有數字的順序並不重要,勝利的組合是,但我不知道如何排序門票號碼,以及如何轉化爲選擇所有可能的組合數字的邏輯?你能澄清嗎? – Rasiel 2009-10-27 16:18:10

+0

感謝您注意Try除了Block,我沒有注意到它! – Rasiel 2009-10-27 17:39:30

+0

如果我說排序標籤_digits_而不是_numbers_,它可能會更清晰。在Python中對列表進行排序非常簡單。沒有必要計算所有組合,因爲所有組合都可以縮減到相同的排序列表。希望這是有道理的。 – Alasdair 2009-10-27 18:01:19

相關問題