コード例 #1
0
ファイル: HistoryFrequencyDB.py プロジェクト: alclass/cxlots
class HistFreqUpdater(object):
  '''
  '''
  def __init__(self): # concurso_range
    self.slider = ConcursoExt()
    self.histfreqdbslider = HistFreqDBSlider()
    self.update_db_if_needed()
    self.verify_histfreqs_consistency()

  def update_db_if_needed(self):
    self.total_concursos = self.slider.get_total_concursos()
    self.last_n_histfreq_updated = self.histfreqdbslider.get_total_histfreqs()
    n_missing_histfreqs = self.total_concursos - self.last_n_histfreq_updated 
    if n_missing_histfreqs < 0:
      error_msg = 'Inconsistent histfreqs size. It is greater than concursos.  Program execution cannot continue.'
      raise IndexError, error_msg
    elif n_missing_histfreqs == 0:
      # nothing to do! Sizes match.
      return
    print 'Need to update %d hist-freq concursos (from %d to %d)' %(n_missing_histfreqs, self.last_n_histfreq_updated, self.total_concursos)
    self.update_histfreqs_from_last_updated()
       
  def update_histfreqs_from_last_updated(self):
    histfreqdbs_to_update = []
    if self.last_n_histfreq_updated == 0:
      numpy_histfreq = numpy.zeros(60,int)
    else:
      numpy_histfreq = self.histfreqdbslider.get_histfreq_at(self.last_n_histfreq_updated)
    for nDoConc in range(self.last_n_histfreq_updated + 1, self.total_concursos + 1):
      jogo = self.slider.get_concurso_by_nDoConc(nDoConc)
      for dezena in jogo.get_dezenas():
        index = dezena - 1 
        numpy_histfreq[index] += 1 
      histfreqdb = HistFreqDB()
      histfreqdb.set_charfreqs(numpy_histfreq, nDoConc)
      histfreqdbs_to_update.append(histfreqdb)
    self.histfreqdbslider.update_histfreqs(histfreqdbs_to_update)

  def verify_histfreqs_consistency(self):
    print 'About to verify histfreqs consistency of %d concursos : Please, wait. ' %(self.total_concursos)  
    numpy_histfreq = numpy.array([0]*60)
    for nDoConc in range(1, self.total_concursos + 1):
      jogo = self.slider.get_concurso_by_nDoConc(nDoConc)
      for dezena in jogo.get_dezenas():
        index = dezena - 1 
        numpy_histfreq[index] += 1
      self.compare_calc_histfreq_with_db(nDoConc, numpy_histfreq)
    print 'Verified histfreqs consistency of %d concursos : ok! ' %(self.total_concursos)  
    
  def compare_calc_histfreq_with_db(self, nDoConc, numpy_histfreq):
    histfreqdb = self.histfreqdbslider.get_histfreq_at(nDoConc)
    bool_array = histfreqdb == numpy_histfreq
    # unfortunately, comparison of numpy arrays should compare element by element
    # old implementation 
    # one_to_one = zip(histfreqdb, numpy_histfreq)
    # for pair in one_to_one:
      # if pair[0] != pair[1]:
    if False in bool_array:
      error_msg = ' at nDoConc=%d histfreqdb != numpy_histfreq \n db = %s \n calculated = %s' %(nDoConc, histfreqdb, numpy_histfreq)
      raise ValueError, error_msg
コード例 #2
0
ファイル: HistoryFrequency.py プロジェクト: alclass/cxlots
class HistFreq(object):
  '''
  A histfreq composes (ie, its attributes):
  --------------------
  + bottomconc = the lower concurso number in the range composing the frequency histogram
  + topconc = the upper concurso number in the range composing the frequency histogram
  + (private) dezenasfreqs = sorted list of each dezena's total occurrence (ie, its frequency) in the related range (bottomconc, topconc)  
  --------------------
  A histfreq does (ie, its methods):
  + mount_histfreq  
  '''
  def __init__(self): # concurso_range
    self.histfreqdbslider = HistFreqDBSlider()
    self.total_histfreqs  = self.histfreqdbslider.get_total_histfreqs()
    self.slider           = ConcursoExt()
    self.total_concursos  = self.slider.get_total_concursos()
    self.update_histfreq_if_needed()
    
  def reissueHistFreqUpdater(self):
    HistFreqUpdater()
    self.total_histfreqs  = self.histfreqdbslider.get_total_histfreqs()
        
  def update_histfreq_if_needed(self, secondTry=False):
    if self.total_histfreqs < self.total_concursos:
      self.reissueHistFreqUpdater()
      if not secondTry:
        return self.update_histfreq_if_needed(secondTry=True)
      else:
        error_msg = 'Failed to update histfreq array. It should have the same size (=%d) as "concursos (=%d)".' %(self.total_histfreqs, self.total_concursos)
        raise ValueError, error_msg

  def get_concurso_by_nDoConc(self, nDoConc):
    '''
    Just a "convenience" public method (not used internally by the class)
    '''
    return self.concursoSlider.get_concurso_by_nDoConc(nDoConc)

  def get_histfreq_at(self, nDoConc=None, secondTry=False):
    '''
    histfreq is a numpy array that contains frequencies of all dozens (ex., in Megasena it's a 60-number array)
    dozen 1 has its frequency at index 0, dozen 2, index 1, so on until dozen 60 at index 59
    '''
    if nDoConc == None:
      nDoConc = self.total_concursos # JogoSlider().get_total_jogos() # ie, number of last one
    elif nDoConc < 1 or nDoConc > self.total_concursos:
      error_msg = 'nº (=%d) do concurso fora da faixa válida (1, %d) ' %(nDoConc, self.total_concursos)
      raise ValueError, error_msg
    elif nDoConc > self.total_histfreqs:
      if secondTry:
        error_msg = 'There is a size different between total_jogo (=%d) and total_histfreqs (=%d) and nDoConc = %d. Program cannot continue until this is corrected.' %(self.total_jogos, self.total_histfreqs, nDoConc)
        raise ValueError, error_msg
      else:
        # this should be a very rare use case, ie, database has changed while this class is still instantiated and running :: try to update histfreqs so that total_histfreqs equals total_concursos
        self.reissueHistFreqUpdater()
        return self.get_concurso_by_nDoConc(nDoConc, secondTry=True)
    # it return as a numpy array object
    histfreq = self.histfreqdbslider.get_histfreq_at(nDoConc)
    if histfreq == None:
      error_msg = "histfreq for concurso %d was not found. It's missing in database." %nDoConc
      raise IndexError, error_msg
    return histfreq
    # index = nDoConc - 1
    # return self.allhistfreqs[index]

  def get_histfreq_tuplelike_at(self, nDoConc=None, secondTry=False):
    '''
    Same as get_histfreq_at(), the plus is that it zips range(1, 61) with histfreq
    '''
    total_dezenas = len(self.get_histfreq_at(nDoConc))
    dezenas = range(1, total_dezenas + 1)
    return zip(dezenas, self.get_histfreq_at(nDoConc))

  def get_freqstair_at(self, nDoConc=None):
    '''
    freqstair is an ordered array from minimum frequency (least occurred) to maximum frequency (most occurred) at nDoConc
    '''
    histstair = set ( self.get_histfreq_at(nDoConc) )
    histstair = list( histstair )
    histstair.sort()
    return histstair

  def get_freqstair_with_dozens_at(self, nDoConc=None):
    '''
    freqstair is an ordered array from minimum frequency (least occurred) to maximum frequency (most occurred) at nDoConc
    '''
    freqstair_with_dozens = []
    freqstair = self.get_freqstair_at(nDoConc)
    for freq in freqstair:
      subset_dezenas = []; offset = 0; histfreq = list( self.get_histfreq_at(nDoConc) ) 
      while 1:
        try:
          index = histfreq.index(freq)
          del histfreq[ : index + 1]
          dezena = offset + index + 1
          offset += index + 1
          subset_dezenas.append(dezena)
          # print 'dezena', dezena, 'freq', freq, freqstair
          # print histfreq, 'tam', len(histfreq) 
          if len(histfreq) == 0:
            break
        except ValueError:
          break
      freqstair_with_dozens.append( (freq, subset_dezenas) )
    return freqstair_with_dozens

  def get_histfreq_within_range(self, concurso_range=None):
    if concurso_range == None:
      return self.get_histfreq_at()
    bottomconc = concurso_range[0] 
    topconc    = concurso_range[1]
    if bottomconc == 1:
      return self.get_histfreq_at(topconc)
    return self.get_deltahistfreq(bottomconc, topconc)

  def get_deltahistfreq(self, bottomconc, topconc):
    if bottomconc == 1:
      return self.get_histfreq_at(topconc)
    bottomfreqhist = self.get_histfreq_at(bottomconc-1)
    topfreqhist    = self.get_histfreq_at(topconc)
    deltafreqhist  = topfreqhist - bottomfreqhist  # + self.numpy_ones
    # it return as a numpy array object 
    return deltafreqhist # no need to hardcopy this one, because it's computed here

  def get_histfreq_for_dezena_witin_range(self, dezena, concurso_range=None):
    histfreq = self.get_histfreq_within_range(concurso_range)
    if histfreq == None:
      return None
    if dezena < 1 or dezena > len(histfreq) + 1:
      error_msg = 'Dezena (=%d) fora da faixa válida (%d, %d)' %(dezena, 1, len(histfreq) + 1)
      raise ValueError, error_msg
    index = dezena - 1
    return histfreq[index]

  def __str__(self):
    return '<HistFreq self.total_histfreqs=%d>' %self.total_histfreqs