1
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())

With this function, I created a list of list containing field.name and getattr(loan2.request.customer_product, field.name). For example,

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

The problem is I prefer something like

+----------------------------------------------------+-----------------+
| 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 fact, those values are the same when I query the database with something like

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

I would like the returning value from the interactive shell. Could anyone help me with this issue? What could I modify in the code?

Thanks!

P.S. Please let me know if the question is unclear.

  • The values are the same. The difference is that the interavtive shell is printing the `repr` of the value. – cco Mar 05 '17 at 05:15
  • @cco Yes ok, but with this code, I'd like to print the repr. Are you able to modify the code to allow such thing? –  Mar 05 '17 at 05:21
  • It's hard to know what to suggest without knowing anything about `Texttable`, but i'd think that using `mylist.append([field.name, repr(getattr(loan2.request.customer_product, field.name))])` might do the trick. – cco Mar 05 '17 at 05:25
  • @cco You are almost right, but it didn't show up all the decimals. with this new structure, it appended `Decimal('...')` and `u'...'`, but it didn't show up all the appropriate decimal. The purpose of that is I want to use the assertEqual function in unit-tests. So I need the exact value in argument. For instance, `self.assertEqual(loaner.request.customer.sum_new_pmt, 56.000)` is wrong while `self.assertEqual(loaner.request.customer.sum_new_pmt, 56.000121522936645)` is right –  Mar 05 '17 at 05:42
  • I think the sanest way to do the comparison would be to round floats (both expected and computed) to a particular precision before comparing them. – cco Mar 05 '17 at 05:55
  • Could you explain what do you mean in using the instance I use in my last comment? –  Mar 05 '17 at 05:57

2 Answers2

0

As per TextTable source code here https://github.com/foutaise/texttable/blob/master/texttable.py#L304 It seems you should be using something like this

....
table = Texttable(max_width = 6000)
table.set_precision(20)
....
jperelli
  • 6,988
  • 5
  • 50
  • 85
0

(Expanding on my comments)
First, I'd suggest not print your test results the way you show. There are several test modules for Python; my choice would be Pytest.

Since conversion from strings to float doesn't always give the exact value corresponding to the string (because binary floating point can't represent the value exactly), when comparing floating-point numbers it is best to avoid comparing for equality, but to allow some wiggle room. My suggestion was to use round (or equivalently, string formatting to a particular precision) for this - e.g. assert round(139.908, 3) == round(computed_value, 3).

What is the best way to compare floats for almost-equality in Python? is a good explanation of the issues, with some useful code.

Community
  • 1
  • 1
cco
  • 5,873
  • 1
  • 16
  • 21