Home > database >  How to write Python class to solve for any missing variable given an equation and values for the oth
How to write Python class to solve for any missing variable given an equation and values for the oth

Time:09-28

I am trying to write a Python class that, when given an equation (or set of equations, eventually) with n variables and values for any n-1 of the variables, will solve for the remaining undefined variable.

For example, if I currently wanted a class for simple conversion between Celsius and Farenheit in either direction, currently I would write it as such:

class TempConversion():
    def __init__(self, temp, unit): 
        self.unit = unit 

        if self.unit == "C":
            self.celsius = temp
        elif self.unit == "F":
            self.farenheit = temp

    def convert_temps(self):
        if self.unit == "C":
            self.farenheit = 9/5 * self.celsius   32
        elif self.unit == "F":
            self.celsius = ( self.farenheit - 32 ) * 5/9

Even in this simple example, I currently have to write the equation twice under the .convert_temps() method. In a real simulation program that involves several dozen equations involving several variables each, this could potential require writing dozens of lines of highly redundant code, prone to arithmetic errors in implementation and messy to read.

I suspect that there is a common way to write this efficiently/flexibly, either with native Python or with a particular package, such that each equation only needs to be 'written once.' I cannot seem to find the right search terms on SO, however.

It seems like SymPy might be an option from python solving equations for unknown variable but that SymPy would require me to define whichever variable was missing as a Symbol(), which would presumably still mean writing a lot of conditional statements etc.

CodePudding user response:

Since you asked to make an example:

  1. sympy uses symbols and does symbolic computation, not numeric calculations.
  2. For each each unknown in your equation you would need a symbol. Luckily developers were wise enough to add some sort of symbol where you do not need to name specifically. (Dummy)
  3. Use one of conversation formulas and rearrange it to be in first order equation with two unknowns format. (ax by c = 0)
  4. Use the passed value as one of unknowns and solve the equation for the other one.

Dummy symbols:

Normally sympy requires you to create symbols and those symbols must have different names.

In your example you would need two symbols as below:

c = sp.Symbol("C")
f = sp.Symbol("F")

or

c, f = sp.symbols("C F")

However in your case you might not know how many unknown are there so you can use Dummy. It takes no required argument and creates symbols.

c = sp.Dummy()
f = sp.Dummy()

Rearranging the formula

Here you can use of conversion formulas. Let us use C2F.

F = 9 / 5 * C   32

Becomes:

9 / 5 * C   32 - F = 0

Where F is temperature in Fahreneit and C is temperature in Celius.

Now the code would be something like:

import sympy as sp


class TempConversion:
    def __init__(self, temp: float, unit: str) -> None:
        self.unit = unit
        self.temp = temp
        self.f, self.c = sp.Dummy(), sp.Dummy()
        self.equation = 9 / 5 * self.c   32 - self.f

    def convert(self) -> list:
        if "CELSIUS".startswith(self.unit.upper()):
            reduced = self.equation.subs(self.c, self.temp)
            return sp.solve(reduced, self.f)
        elif "FAHRENHEIT".startswith(self.unit.upper()):
            reduced = self.equation.subs(self.f, self.temp)
            return sp.solve(reduced, self.c)
        else:
            raise ValueError("Unknown Temperature Unit")


if __name__ == '__main__':
    t = TempConversion(22.75, "F")
    print(t.convert())

Please notice in this example there were 2 unknowns and one was provided by user. In other examples you might need parse the given equation or create an equation builder class. Create a list of dummy symbols and do other clever things.

  • Related