2014-02-14 79 views
0

另一個Python浮點問題。我正在創建一個應用程序來幫助我們的培訓部門。這個應用程序的一部分是處理類的評估。評估包括一類設備,書面測試分數,操作測試分數和操作測試時間。這個承諾會很長。返回浮點數的Python方法爲相同的原始數據返回不同的值

有一個公式計算得分:眼下的界面允許用戶輸入測試分數和分和秒爲道路試驗

score = written_test + operational - best_decimal_time + decimal_time 
percentage = score/best score 

。從理論上講,最佳時間的得分爲:

written_test + operational 

因爲小數點會抵消。

注意,written_test是使用Django一個評估模型定義是的Evaluation

student屬性的屬性:

class Evaluation(models.Model): 
    student = models.ForeignKey(StudentRegistration) 
    machine_class = models.ForeignKey(MachineClass) 
    operational = models.IntegerField() 
    minutes = models.IntegerField(null=True, blank=True, default=0) 
    seconds = models.IntegerField(null=True, blank=True, default=0) 
    raw_time = models.CharField(max_length=5, null=True, blank=True, default=0) 
    decimal_time = models.DecimalField(max_digits=15, decimal_places=3, default=0, null=True, blank=True) 
    score = models.DecimalField(max_digits=15, decimal_places=2, default=0, null=True, blank=True) 
    percent = models.DecimalField(max_digits=15, decimal_places=2, default=0, null=True, blank=True) 
    evaluator = models.ForeignKey(Instructor, null=True, blank=True, default=None) 

的保存方法的評價是:

def save(self, *args, **kwargs): 
    """Sets the raw_time and decimal_time from the minutes and seconds and saves the object.""" 
    self.raw_time = self.get_raw_time() 
    self.decimal_time = self.get_decimal_time() 
    self.score = self.get_score() 
    super(Evaluation, self).save(*args, **kwargs) 

get_raw_time方法:

def get_raw_time(self): 
    """Formats the minutes and seconds into a time string d:dd and returns the formatted time.""" 
    s = '0' 
    if self.seconds < 10: 
     s = s + str(self.seconds) 
    else: 
     s = self.seconds 
    return '%s:%s' % (self.minutes, s) 

的get_decimal_time方法:

def get_decimal_time(self): 
    return '%.3f' % ((self.minutes) + (self.seconds/60.0)) 

的get_best_time方法:

def get_best_time(self): 
    reg_ary = [] 
    s_class = self.student.scheduled_class_id 
    registrations = StudentRegistration.objects.filter(scheduled_class_id=s_class).values('id') 
    for r in registrations: 
     reg_ary.append(r['id']) 
    evaluations = Evaluation.objects.filter(student_id__in=reg_ary).order_by('decimal_time') 
    for e in evaluations: 
     if e.machine_class == self.machine_class: 
      if e.decimal_time < self.get_decimal_time(): 
       return '%.3f' % round(e.decimal_time, 4) 
      else: 
       return '%.3f' % round(self.get_decimal_time(), 4) 
    return self.get_decimal_time() 

最後get_score方法:

def get_score(self): 
    return '%.2f' % (Decimal(self.student.written_test) + Decimal(self.operational) - 
      Decimal(self.get_decimal_time()) + Decimal(self.get_best_time())) 

這裏是數字:

written_test = 21 
operational = 96 
minutes = 3 
seconds = 1 

這是表格的第一個入口,所以它是最好的時間,所以當計算得分時應該是21 + 96 = 117

當我輸入這些號碼是我得到:

117 written to the database # correct maybe, I think it should be 117.00 but not huge. 
raw_time = 3:01 # correct 
decimal_time = 3.017 # correct 
best_decimal_time = 3.017 # correct 
score = 117.00 # correct 

當我更改記錄爲2秒,我得到:

116.98 written to the database # incorrect, should still be 117 
raw_time = 3:02 # correct 
decimal_time = 3.033 # correct 
best_decimal_time = 3.033 # correct 
score = 117.00 # correct 

當我刪除的記錄,並使用分鐘後重新啓動= 3和秒= 2 I得到:

117 written to the database # correct mostly 
raw_time = 3:02 # correct 
decimal_time = 3.033 # correct 
best_decimal_time = 3.033 # correct 
score = 117.00 # correct 

最後,當我更改記錄到1秒我得到:

117.02 written to the database # incorrect, should still be 117 
raw_time = 3:01 # correct 
decimal_time = 3.017 # correct 
best_decimal_time = 3.017 # correct 
score = 117.00 # correct 

這也正是每個值都來自:

I looked in the database for the value written there 
raw_time = self.raw_time 
decimal_time = self.decimal_time 
best_decimal_time = self.get_best_time() 
score = self.get_score() 

我懷疑這是用浮漂的二進制表示的問題,但似乎無法弄清楚如何解決它。我曾嘗試投入到十進制,有些東西只是在某個地方,我的大腦傷害了一點。我知道這很長,但我想確保提供儘可能多的相關信息。難道是時間到了三位數的精度,而得分不是?

是困惑我的部分是數據庫越來越的get_score()的結果被寫入到數據庫中的值,但什麼是顯示在界面是不同的。

對此提出建議?

+1

差異0.02看起來比二進制浮點表示問題通常要大。 – Messa

+0

這就是我最初想到的,但我無法得出更好的理由,爲什麼'get_score()'方法在編輯時只返回兩個不同的值......等等,它只是在編輯上,所以什麼是導致數據庫中的值更改時出現問題。可能會成爲某事..... – Tony

回答

0

好吧,我非常迷戀那些浮現的東西,我錯過了實際的問題。問題是我需要檢查數據庫中的最佳時間是否屬於當前評估,如果是,則使用self而不是數據庫值。

+1給Messa讓我思考。

相關問題