另一个Python浮点问题。我正在创建一个应用程序来帮助我们的培训部门。该应用程序的一部分是处理类评估。评估包括一类设备,书面测试分数,操作测试分数和操作测试时间。这很有希望。
有一个计算得分的公式:
score = written_test + operational - best_decimal_time + decimal_time
percentage = score / best score
现在,界面允许用户输入测试分数以及道路测试的分钟和秒数。从理论上讲,最佳时间的分数是:
written_test + operational
因为小数时间会偏移。
请注意,written_test
是student
Evaluation
属性的属性
使用Django评估的模型定义是:
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
当我删除记录并使用minute = 3和seconds = 2重新开始时,我得到:
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()
结果,但界面中显示的内容不同。
建议?
答案 0 :(得分:0)
self
而不是数据库值。
+1让Messa让我思考。