python - 为什么这个函数偶尔会返回错误的值
问题描述
我在 Phrancko.com 上经营一个针织毛衣图案制作网站,我对这个功能正在发生的事情感到困惑。
我使用此函数将用户的“neck_circumference”转换为“neck width”的调整值。
def calc_width_from_neck_size(circ):
with localcontext() as ctx:
ctx.prec = 3
if isinstance(circ, Decimal):
circ = float(circ)
diameter = (round((circ / pi) * 8) / 8) + 1.375 # 1 3/8" wider than circular neck
return Decimal(diameter)
它在大多数情况下始终如一地工作,但偶尔会返回错误的值。当用户在表格中输入颈围时,它只需调用此函数,然后将输入的值和此函数的结果都放入数据库中。中间没有其他处理发生。
例如,这里是为颈部宽度输入 15.5 的用户的所有结果:
id,create_date,neck_width,neck_circumference
80,"2019-08-30 22:23:00",6.250,15.500
81,"2019-08-31 01:54:43",6.250,15.500
111,"2019-11-02 00:33:28",6.250,15.500
238,"2020-03-15 18:36:45",6.250,15.500
258,"2020-05-02 19:02:29",6.250,15.500
289,"2020-07-04 23:56:56",6.750,15.500
321,"2020-09-25 21:47:36",6.250,15.500
323,"2020-09-25 21:56:35",6.250,15.500
330,"2020-10-15 18:47:38",6.250,15.500
350,"2020-10-28 19:33:49",6.250,15.500
352,"2020-11-10 03:16:36",6.250,15.500
360,"2021-01-03 04:31:41",6.250,15.500
385,"2021-02-01 20:25:46",6.250,15.500
397,"2021-02-15 19:28:29",6.250,15.500
426,"2021-03-07 16:52:23",6.250,15.500
469,"2021-05-01 15:21:06",6.250,15.500
478,"2021-05-02 12:53:39",6.250,15.500
502,"2021-05-16 04:51:40",6.250,15.500
515,"2021-05-24 01:10:13",6.250,15.500
534,"2021-06-09 19:59:43",6.250,15.500
547,"2021-06-14 10:24:39",6.250,15.500
请注意,大部分时间都存储了正确的值 6.25,但是对于 id 289,它存储了 6.75!
这不是唯一一次发生这种情况。有数百条这样的记录,只有大约 3 个错误值。它们都发生在不同的日期。如您所见,这是在 2020-07-04 上发布的。2021-05-22 生产了一个不同的版本。代码在这两个日期没有更改和更改回来。此代码在网站的整个生命周期中保持不变。我完全感到困惑。
这个函数怎么能在大多数时候完美地工作,但在极少数情况下会产生错误的值?
附加信息:
我无法提供 MRE,因为我无法生产。这是一些调用该函数一百万次并且不产生单个异常值的测试代码。
from decimal import *
from math import pi
def calc_width_from_neck_size(circ):
with localcontext() as ctx:
ctx.prec = 3
if isinstance(circ, Decimal):
circ = float(circ)
diameter = (round((circ / pi) * 8) / 8) + 1.375 # 1 3/8" wider than circular neck
return Decimal(diameter)
num_found = 0
for count in range(1, 1000000):
circ = float(Decimal('15.000'))
test = Decimal(6.125)
width = calc_width_from_neck_size(circ)
if width != test:
num_found += 1
print(f'WRONG: Count {count} Circ {circ} Width {width} round((circ / pi) * 8) {round((circ / pi) * 8)}')
print(f'Found {num_found} wrong ones.')
因此,我的注意力转向了如何设置输入值 (circ)。它在 Django 视图中运行,下面是调用它的单行代码:
sweater.neck_width = calc_width_from_neck_size(sweater.who_for.neck_circumference)
毛衣.who_for_neck_circumference 字段声明如下:
class Recipient(models.Model):
knitter = models.ForeignKey(User, on_delete=models.CASCADE)
recipient_name = models.CharField(max_length=30, verbose_name="Their name:")
chest_circumference = models.DecimalField(max_digits=5, decimal_places=3)
neck_circumference = models.DecimalField(max_digits=5, decimal_places=3)
shoulder_to_waist = models.DecimalField(max_digits=5, decimal_places=3)
该值在 Django 验证后直接从用户输入中提取到此字段中,然后直接传递给如上所示的函数。我不知道当用户输入 DecimalField 时 Django 的幕后会发生什么,但我知道当我提取它时,该值始终是一个有效的 Decimal 值,它直接传递给函数并存储结果在数据库的不同字段中。正如我在原始问题中指出的那样,我只能通过对所有应该相同的字段进行 SQL 显示来查看异常行为。
我明白为什么没有人能帮助我解决这个问题。我只是不知道还能做什么。我很感激任何关于如何阐明这一点的建议。
坦率
解决方案
推荐阅读
- unit-testing - 'meteor test' 没有接收到 *.test[s].js
- python - 熊猫数据框无法为切片子集赋值
- javascript - 在 Laravel 中使用 Ajax 在引导模式上显示数据库
- java - 使用 docx4j 将现有幻灯片插入新的 pptx 演示文稿
- c# - UWP - 通过 C# 中的 GPS 传感器显式获取位置坐标
- html - 在 Angular 6 中动态创建 html 导航选项卡
- c# - 如何处理文本并从哈希c#中获取文本
- android - Android 上的 OnOptionsItemSelected 无法在活动中工作
- sql-server - 无法将节点 js 连接到 SQL 服务器
- javascript - Handlebars helper 正则表达式用于标记多选输入框中的选择框