【问题标题】:Same value from the interactive shell来自交互式 shell 的相同值
【发布时间】:2017-03-04 23:08:18
【问题描述】:
def unittest(execute=False):
                with timetravel(datetime(2017,03,01)) as now:
                    loan2 = compute_loan(user, {'product_id': 1,
                                       'frequency': '1week',
                                       'first_debit_date': now })

            if not execute:
                print('You are wrong')
                pass
            else:
                field_list = CustomerProduct._meta.get_fields()
                mylist = []
                exclude = ['id','contract', 'actor_actions',
                        'locked', 'description', 'target_actions',
                        'action_object_actions', 'created', 'modified',
                        'request', 'withdrawal_first_date', 'deposit_date']
                table = Texttable(max_width = 6000)
                for field in field_list:
                    if field.name not in exclude:
                        mylist.append([field.name, getattr(loan2.request.customer_product, field.name)])
                table.add_rows(mylist)
                print(table.draw())

通过这个函数,我创建了一个包含field.namegetattr(loan2.request.customer_product, field.name) 的列表。例如,

+----------------------------------------------------+---------+
| debit_frequency                                    | 1week   |
+----------------------------------------------------+---------+
| broker_pmt                                         | 17.865  |
+----------------------------------------------------+---------+
| broker_pre_withdrawal_daily_interest_rate          | 0.001   |
+----------------------------------------------------+---------+
| broker_total_post_pre_withdrawal_interest_amount   | 139.908 |
+----------------------------------------------------+---------+

问题是我更喜欢类似的东西

+----------------------------------------------------+-----------------+
| debit_frequency                                    | u'1week'        |
+----------------------------------------------------+-----------------+
| broker_pmt                                         | 17.865903434    |
+----------------------------------------------------+-----------------+
| broker_pre_withdrawal_daily_interest_rate          | 0.0014348934    |
+----------------------------------------------------+-----------------+
| broker_total_post_pre_withdrawal_interest_amount   | 139.9083498304  |
+----------------------------------------------------+-----------------+

事实上,当我用类似的方式查询数据库时,这些值是相同的

In [7]: loaner.request.customer.sum_new_pmt
Out[7]: 56.000121522936645

我想要交互式 shell 的返回值。谁能帮我解决这个问题?我可以在代码中修改什么?

谢谢!

P.S.如果问题不清楚,请告诉我。

【问题讨论】:

  • 值相同。不同之处在于 interavtive shell 正在打印值的repr
  • @cco 是的,但是使用此代码,我想打印代表。你能修改代码来允许这样的事情吗?
  • 如果不了解Texttable,很难知道建议什么,但我认为使用mylist.append([field.name, repr(getattr(loan2.request.customer_product, field.name))]) 可能会成功。
  • @cco 你几乎是对的,但它没有显示所有小数。有了这个新结构,它附加了Decimal('...')u'...',但它没有显示所有适当的小数。这样做的目的是我想在单元测试中使用 assertEqual 函数。所以我需要参数中的确切值。例如,self.assertEqual(loaner.request.customer.sum_new_pmt, 56.000) 是错误的,而 self.assertEqual(loaner.request.customer.sum_new_pmt, 56.000121522936645) 是正确的
  • 我认为进行比较的最明智的方法是将浮点数(预期的和计算的)舍入到特定的精度,然后再进行比较。

标签: python django interactive


【解决方案1】:

(在我的 cmets 上展开)
首先,我建议不要按照您显示的方式打印您的测试结果。 Python有几个测试模块;我的选择是Pytest

由于从字符串到浮点数的转换并不总是给出与字符串对应的确切值(因为二进制浮点数不能准确表示该值),所以在比较浮点数时最好避免比较是否相等,但要留出一些回旋余地。我的建议是为此使用round(或等效地,将字符串格式化为特定精度) - 例如assert round(139.908, 3) == round(computed_value, 3).

What is the best way to compare floats for almost-equality in Python? 很好地解释了这些问题,并提供了一些有用的代码。

【讨论】:

  • 是的,但目前 Django 使用 assertEqual
【解决方案2】:

根据此处的TextTable源代码https://github.com/foutaise/texttable/blob/master/texttable.py#L304看来你应该使用这样的东西

....
table = Texttable(max_width = 6000)
table.set_precision(20)
....

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-12
    • 1970-01-01
    • 2013-04-16
    • 2017-07-15
    • 2021-07-14
    • 1970-01-01
    • 2016-02-17
    相关资源
    最近更新 更多