0

I'm working on a project where my code is spread across different files; for instance, in convex.py, I invoke methods I've written in rings.py by calling from rings import * at the top. In rings I define a constant p using mpmath which is used in the various functions of rings, so it depends on the precision I've hand-written into rings (e.g. via mpmath.mp.dps = 40). However, when using convex I may later on want p to have higher precision. Is there a way to make rings take in some input when I import it into convex? e.g. maybe I want 50 decimal digits of precision once, and 100 the next use, so a perfect solution would be to let rings take in an input D and set mpmath.mp.dps = D there, and in convex maybe have

D = 50
from rings[D] import *

(and then use D elsewhere in the file, and where I can also freely change D (along with whatever else I'd like to change in convex, without needing to go back into rings each time)). (The proposed notation above is to sort of view rings as a function of D.)

The only concrete workaround I see would be to modify each of my rings methods to take inputs as all of the precision-dependent constants which I've defined in rings, redefine them in convex, and then pass them as arguments; but this seems like a clunky and overall bad solution.

Let me know if I can clarify any of this. Thanks in advance.

EDIT: Sample code

# rings.py
import mpmath as mp
from mpmath import sqrt
mp.mp.dps = 40
p = sqrt(2)
def f(x):
    return p*x
# convex.py
import mpmath as mp
from mpmath import sqrt
from rings import *
D = 50 # or 100
mp.mp.dps = D
q = sqrt(3)
print D+f(q)
zjs
  • 327
  • 1
  • 9
  • I'm trying to understand your problem setup - maybe adding minimal code snippets would help. From what I've understood, if you want to change the value `D` when running `convex.py`, did you think about writing a class in `rings.py` and instantiating it in `convex.py` by setting the desired `D` value? Or maybe to keep a separate config file that can access in one of those scripts? – akilat90 Jun 04 '21 at 18:33
  • @akilat90 I've added simplified sample snippets in the main post. The main use of the constant-dependent code would be as functions, so I'm not certain making it into classes is optimal (though I'm also relatively new to classes so could be mistaken). How would I go about setting up this config file that you mention? – zjs Jun 04 '21 at 18:42
  • IIUC, you need to use the same (and arbitrary) `dps` value for all the calculations in both `convex.py` and `rings.py`. Since `mp.mps.dps` is a global variable, wouldn't it be sufficient to set that to an arbitrary value in `convex.py` itself (like you're already doing)? [How to read config files](https://stackoverflow.com/questions/19379120/how-to-read-a-config-file-using-python), but it seems irrelevant. – akilat90 Jun 04 '21 at 19:46
  • @akilat90 To make sure I'm understanding correctly: globalness implies that if I compile `convex` with `mp.mp.dps = 50`, then this will supersede `mp.mp.dps = 40` in `rings` at time of compilation, including in the evaluation of `p`? – zjs Jun 04 '21 at 21:13
  • (I've just put together toy files and it confirms that the answer to the above question is yes) – zjs Jun 04 '21 at 21:42

1 Answers1

1

The most straightforward solution in my head would be to declare a class, which allows to update the value D.

rings.py

import mpmath as mp
from mpmath import sqrt

class Ring:
    def __init__(self, D=40):
        mp.mp.dps = D

    def set_d(self, D):
        mp.mp.dps = D

    def f(self, x):
        p = sqrt(2)
        return p * x

convex.py

import mpmath as mp
from mpmath import sqrt
from rings import Ring

D = 50
ring = Ring(D)
q = sqrt(3)
print(D + ring.f(q))

I hope I understood your question correctly. Let me know if that helps.

schilli
  • 1,700
  • 1
  • 9
  • 17
  • I think this does accomplish it, thank you. To double-check: one could move `p = sqrt(2)` into `__init__` in order for it to be used in another method of `Ring`, and it could then be accessed in `convex` as `ring.p`? – zjs Jun 04 '21 at 21:15
  • 1
    Yes. Exactly. Classes and object are worth reading into if you are not that familiar yet. You will definitely find a lot of good guides online. – schilli Jun 05 '21 at 09:51