Python Forum
Adding Decimals to classes with OOP + rounding to significant digits (ATM demo)
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Adding Decimals to classes with OOP + rounding to significant digits (ATM demo)
#8
Hi @bowlofred, Thank you for your reply. I’ve done some more experimentation in my REPL based on your feedback. I tried the context manager and it turns out to behave as you predicted. It rounds up or down. Here it is:

$ bpython
bpython version 0.22.1 on top of Python 3.10.4 /usr/bin/python
>>> import decimal
>>> from decimal import Decimal
>>> ctx = decimal.getcontext()
>>> x = Decimal('2.35')
>>> y = Decimal('3.35')
>>> with decimal.localcontext() as ctx:
...     ctx.rounding = decimal.ROUND_HALF_UP
...     print(round(x,1))
...     print(round(y,1))
...     
2.4
3.4
>>> with decimal.localcontext() as ctx:
...     ctx.rounding = decimal.ROUND_DOWN
...     print(round(x,1))
...     print(round(y,1))
...     
2.3
3.3
But when we return to calling .getcontext that we were originally working with, it shows the change but Python is still rounding UP even after I tell Python to round DOWN. See here:

$ bpython
bpython version 0.22.1 on top of Python 3.10.4 /usr/bin/python
>>> import decimal
>>> from decimal import Decimal
>>> ctx = decimal.getcontext()
>>> ctx
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1
, clamp=0, flags=[], traps=[DivisionByZero, Overflow, InvalidOperation])
>>> ctx.rounding = decimal.ROUND_DOWN
>>> ctx
Context(prec=28, rounding=ROUND_DOWN, Emin=-999999, Emax=999999, capitals=1, cla
mp=0, flags=[], traps=[DivisionByZero, Overflow, InvalidOperation])
>>> x = Decimal('2.35')
>>> y = Decimal('3.35')
>>> print(round(x,1))
2.4
>>> ctx
Context(prec=28, rounding=ROUND_DOWN, Emin=-999999, Emax=999999, capitals=1, cla
mp=0, flags=[], traps=[DivisionByZero, Overflow, InvalidOperation])
>>> print(round(y,1))
3.4
>>> y
Decimal('3.35')
>>> 
So I whipped out the official python REPL and entered the same commands:

$ python
Python 3.10.4 (main, Mar 23 2022, 23:05:40) [GCC 11.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import decimal
>>> from decimal import Decimal
>>> ctx = decimal.getcontext()
>>> ctx
Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[DivisionByZero, Overflow, InvalidOperation])
>>> ctx.rounding = decimal.ROUND_DOWN
>>> ctx
Context(prec=28, rounding=ROUND_DOWN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[DivisionByZero, Overflow, InvalidOperation])
>>> x = Decimal('2.35')
>>> y = Decimal('3.35')
>>> print(round(x,1))
2.3
>>> ctx
Context(prec=28, rounding=ROUND_DOWN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[Inexact, Rounded], traps=[DivisionByZero, Overflow, InvalidOperation])
>>> print(round(y,1))
3.3
>>> y
Decimal('3.35')
>>> ctx.rounding = decimal.ROUND_UP
>>> ctx
Context(prec=28, rounding=ROUND_UP, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[Inexact, Rounded], traps=[DivisionByZero, Overflow, InvalidOperation])
>>> print(round(x,1))
2.4
>>> print(round(y,1))
3.4
>>> 
It’s working now. This proves @deanhystad’s suspicion that the problem is with the bpython REPL I am using. There seems to be a related known outstanding issue on the bpython project's GitHub repo with the decimal module. Lesson learned: Don’t trust bpython.

@deanhystad, Thank you for sharing the two specific quotes on docs.python.org. The official Python docs are vast and verbose. Even if I spent all weekend long reading the entire doc entry on the decimal package, it still probably wouldn’t have registered in my mind. So I appreciate you highlighting the specific passage relevant to my issue.

I personally find the Python docs to be written by programmers, for programmers, meaning they aren’t very helpful to novices like me. I prefer reading guides like on Geek for Geeks, Programiz, PythonTutorial.net, YouTube, and Python forums in general because in all of these locations on the web, I can find helpful guides and experienced programers who share specific practical examples written in language that is candid, approachable, and friendly rather the robotic and rigid docs.python.org.

(Apr-29-2022, 02:40 PM)deanhystad Wrote:
Output:
The context for arithmetic is an environment specifying precision, rounding rules, limits on exponents, flags indicating the results of operations, and trap enablers which determine whether signals are treated as exceptions. Rounding options include ROUND_CEILING, ROUND_DOWN, ROUND_FLOOR, ROUND_HALF_DOWN, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_UP, and ROUND_05UP.
Output:
The usual start to using decimals is importing the module, viewing the current context with getcontext() and, if necessary, setting new values for precision, rounding, or enabled traps:

I think I am beginning to understand, although I still have a few points of clarification related to these two particular passages.

When getcontext() is called and the rounding=”ROUND_UP” argument is passed in, does this establish the behavior for all rounding operations for the entire script for as long as the script is running?

So in a sense, by analogy, does .getcontext work like an ‘environmental variable’? I have a little bit of experience with environmental variables in some Django projects I have been playing with on and off recently. With Django, the DEBUG setting applies to all web apps. In my local testing environment, DEBUG is set to True which helps the developer diagnose and identify bugs. But for production, DEBUG is set to False, preventing the exposure of sensitive information to public web site visitors.

So to compare, when a .getcontext argument is passed in such as ROUND_DOWN, does the ROUND_DOWN behavior then apply to the whole script at runtime when it is called, causing all round() methods to behave the same way?

For the purposes of my script in my original post (but also copied below), I’d like all my Decimals to ROUND_HALF_UP. So where in my script should I add it? Within the scope of the Account class? Embedded beneath the dunder __init__ method? Or outside all classes near the top when all the packages are imported and initialized?

Here is my original script:

import decimal
from decimal import Decimal
from random import randint
  
class Account:
  
   def __init__(self, first_name, last_name,starting_balance=0.00):
       self.first_name = first_name
       self.last_name = last_name
       self.balance = round(Decimal(starting_balance),2)
       self.transaction_id = randint(101,999)
  
   def deposit(self, amount):
       self.balance += round(Decimal(amount),2)
       self.transaction_id += randint(101,999) - randint(101,999)
       return f'D-{self.transaction_id}'
   
   def withdraw(self, amount):     	
       self.balance -= round(Decimal(amount),2)
       self.transaction_id += randint(101,999) - randint(101,999)
       return f'W-{self.transaction_id}'
So where should the following context declaration be placed in the above script?

ctx = decimal.getcontext()
ctx.rounding = decimal.ROUND_HALF_UP
Reply


Messages In This Thread
RE: Adding Decimals to classes with OOP + rounding to significant digits (ATM demo) - by Drone4four - May-04-2022, 06:15 AM

Possibly Related Threads…
Thread Author Replies Views Last Post
  Python won 't do decimals SomebodySmart 5 768 Jun-08-2023, 07:14 PM
Last Post: buran
  Get numpy ceil and floor value for nearest two decimals klllmmm 4 1,319 Jun-07-2023, 07:35 AM
Last Post: paul18fr
  need help rounding joseph202020 7 1,367 Feb-21-2023, 08:13 PM
Last Post: joseph202020
  from numpy array to csv - rounding SchroedingersLion 6 2,264 Nov-14-2022, 09:09 PM
Last Post: deanhystad
  floats 2 decimals rwahdan 3 1,659 Dec-19-2021, 10:30 PM
Last Post: snippsat
  Random data generation sum to 1 by rounding juniorcoder 9 3,515 Oct-20-2021, 03:36 PM
Last Post: deanhystad
  Rounding issue kmll 1 1,441 Oct-08-2021, 10:35 AM
Last Post: Yoriz
  Converting decimals stylingpat 3 2,154 Mar-27-2021, 02:32 PM
Last Post: deanhystad
  Not rounding to desired decimal places? pprod 2 2,586 Mar-05-2021, 11:11 AM
Last Post: pprod
  Decimal Rounding error project_science 4 2,795 Jan-06-2021, 03:14 PM
Last Post: project_science

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020