diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 3b75d50dcbeeb28bc9999213a16bd87130d1149b..8102a2ec2a38218db29f84bcf5e2afb677c2df72 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -3,7 +3,7 @@ stages:
   - deploy
 
 variables:
-  GIT_STRATEGY: fetch
+  GIT_STRATEGY: clone  # Ensure a fresh clone from the branch
   HTTP_PROXY: "http://webproxy.bs.ptb.de:8080"
   HTTPS_PROXY: "http://webproxy.bs.ptb.de:8080"
   NO_PROXY: "*.ptb.de"
@@ -11,11 +11,8 @@ variables:
 .test_template:
   stage: test
   before_script:
-    # Set proxy for apt-get
-    #- echo 'Acquire::http::Proxy "http://webproxy.bs.ptb.de:8080";' | tee /etc/apt/apt.conf.d/99proxy
-    # Update sources to a reliable mirror and install mono-devel
-    #- sed -i 's/http:\/\/deb.debian.org/http:\/\/ftp.de.debian.org/g' /etc/apt/sources.list
-    #- apt-get update && apt-get install -y mono-devel
+    # Ensure that the code is checked out from the current branch
+    - git checkout "$CI_COMMIT_REF_NAME"
   script:
     - pip install .[testing]
     - pytest --cov --cov-report term-missing --cov-report xml:coverage.xml --cov-report html:cov_html
@@ -25,6 +22,7 @@ variables:
     paths:
       - coverage.xml
       - cov_html/
+    when: always  # Ensure artifacts are saved even if the job fails
     reports:
       coverage_report:
         coverage_format: cobertura
@@ -33,37 +31,15 @@ test:python_3.0:
   extends: .test_template
   image: python:3.0
 
-test:python_3.1:
-  extends: .test_template
-  image: python:3.1
-
-test:python_3.2:
-  extends: .test_template
-  image: python:3.2
-
-test:python_3.3:
-  extends: .test_template
-  image: python:3.3
-
-test:python_3.4:
-  extends: .test_template
-  image: python:3.4
-
-test:python_3.5:
-  extends: .test_template
-  image: python:3.5
-
-test:python_3.6:
-  extends: .test_template
-  image: python:3.6
+# Define jobs for each Python version from 3.7 to 3.12
 
 test:python_3.7:
   extends: .test_template
-  image: python:3.7
+  image: python:3.7.17
 
 test:python_3.8:
   extends: .test_template
-  image: python:3.8
+  image: python:3.8.20
 
 test:python_3.9:
   extends: .test_template
@@ -80,19 +56,3 @@ test:python_3.11:
 test:python_3.12:
   extends: .test_template
   image: python:3.12
-
-commit_and_push_coverage:
-  stage: deploy
-  image: alpine/git
-  script:
-    - git config --global user.email "gitlab@runner"
-    - git config --global user.name  "Git Lab Runner"
-    - git fetch --all
-    - git checkout -b coverage-report || git checkout coverage-report
-    - rm -rf *  # Clear the branch (optional: handle with care)
-    - cp -r cov_html/* .
-    - git add .
-    - git commit -m "Update coverage report" || echo "No changes to commit"
-    - git push --set-upstream origin coverage-report
-  only:
-    - master
diff --git a/pyproject.toml b/pyproject.toml
index 58ffad30ab5ced13b75a88774279d794f7ec8b30..26bff3b7f8179230f9bd3bd74b97b5d2b817c576 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
 
 [project]
 name = "dsiunits"  # Ensure this is correctly specified
-version = "2.3.2"
+version = "2.4.0"
 description = "This is a Python module for handling the SI units as objects in Python, parsing them from strings and converting them to Latex and Unicode, as well as performing math operations and calculating scale factors."
 authors = [
     { name="Benedikt Seeger", email="benedikt.seeger@ptb.de" },
@@ -12,7 +12,7 @@ authors = [
 ]
 license = { file="LICENSE" }
 readme = "README.md"
-requires-python = ">=3.10"
+requires-python = ">=3.7"
 classifiers=[
     "Programming Language :: Python :: 3",
     "License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
diff --git a/setup.cfg b/setup.cfg
index c90da9993be9973f403d785722da24bf531421c2..ed5564fcd28318bd1d0224b136f74075a42bc6b0 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,11 +1,11 @@
 [metadata]
 name = dsiUnits
-version = 2.3.2
+version = 2.4.0
 description = This is a Python module for handling the SI units as objects in Python, parsing them from strings and converting them to Latex and Unicode, as well as performing math operations and calculating scale factors.
 long_description = file: README.md
 
 [options]
-python_requires = >=3.10
+python_requires = >=3.7
 
 [options.extras_require]
 testing =
diff --git a/src/dsiUnitNode.py b/src/dsiUnitNode.py
index 2f1857d2457add9009d9d10d4b1d39dd8bd700e6..e2371fcb97a13b59eeb795a600dd4c13a2fa5f70 100644
--- a/src/dsiUnitNode.py
+++ b/src/dsiUnitNode.py
@@ -1,57 +1,75 @@
 # This file is part of dsiUnits (https://gitlab1.ptb.de/digitaldynamicmeasurement/dsiUnits/)
 # Copyright 2024 [Benedikt Seeger(PTB), Vanessa Stehr(PTB)]
-#This library is free software; you can redistribute it and/or
-#modify it under the terms of the GNU Lesser General Public
-#License as published by the Free Software Foundation; either
-#version 2.1 of the License, or (at your option) any later version.
-
-#This library is distributed in the hope that it will be useful,
-#but WITHOUT ANY WARRANTY; without even the implied warranty of
-#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#Lesser General Public License for more details.
-
-#You should have received a copy of the GNU Lesser General Public
-#License along with this library; if not, write to the Free Software
-#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 import warnings
 from typing import List
 import math
 from fractions import Fraction
 
-from unitStrings import _dsiPrefixesLatex, _dsiPrefixesScales, _dsiUnitsLatex, _derivedToBaseUnits, _additionalConversions
+from unitStrings import (
+    _dsiPrefixesLatex,
+    _dsiPrefixesScales,
+    _dsiUnitsLatex,
+    _derivedToBaseUnits,
+    _additionalConversions,
+)
 
 
 class dsiUnitNode:
-    """one node of the D-SI tree, containing prefix, unit, power
-    """
-    dsiPaserInstance = None  #this class variable will stort the dsiPaserInstance optained from the singelton constructed
-                            # by the initialize_parser() class method by lazy loading so the instance is created when
-                            # the first node is created and not before dsiPaser is fully defined
+    """one node of the D-SI tree, containing prefix, unit, power"""
+
+    dsiParserInstance = None  # this class variable will stored the dsiParserInstance obtained from the singleton constructed
+    # by the initialize_parser() class method by lazy loading so the instance is created when
+    # the first node is created and not before dsiParser is fully defined
 
     @classmethod
     def initialize_parser(cls):
         from dsiParser import dsiParser
-        cls.dsiPaserInstance = dsiParser()
-        
-    def __init__(self, prefix: str,unit: str,exponent: Fraction=Fraction(1), valid:bool=True,scaleFactor: float = 1.0  ):# Adding scale factor with default value 1.0
-        if dsiUnitNode.dsiPaserInstance is None:
+
+        cls.dsiParserInstance = dsiParser()
+
+    def __init__(
+        self,
+        prefix: str,
+        unit: str,
+        exponent: Fraction = Fraction(1),
+        valid: bool = True,
+        scaleFactor: float = 1.0,
+    ):  # Adding scale factor with default value 1.0
+        if dsiUnitNode.dsiParserInstance is None:
             dsiUnitNode.initialize_parser()
-        self.prefix=prefix
-        self.unit=unit
-        self.valid=valid
-        if isinstance(exponent,Fraction) or isinstance(exponent,int):
-            self.exponent=Fraction(exponent)
-        if isinstance(exponent,str):
-            if exponent== '':
-                exponent= Fraction(1)
+        self.prefix = prefix
+        self.unit = unit
+        self.valid = valid
+        if isinstance(exponent, Fraction) or isinstance(exponent, int):
+            self.exponent = Fraction(exponent)
+        if isinstance(exponent, str):
+            if exponent == "":
+                exponent = Fraction(1)
             else:
                 try:
-                    exponent = Fraction(exponent).limit_denominator(self.dsiPaserInstance.maxDenominator)
+                    exponent = Fraction(exponent).limit_denominator(
+                        self.dsiParserInstance.maxDenominator
+                    )
                 except ValueError:
-                    exponent=exponent
-                    warnings.warn(f"Exponent «{exponent}» is not a number!", RuntimeWarning)
-        self.exponent=exponent
-        self.scaleFactor=scaleFactor  # Adding scale factor with default value 1.0
+                    exponent = exponent
+                    warnings.warn(
+                        f"Exponent «{exponent}» is not a number!", RuntimeWarning
+                    )
+        self.exponent = exponent
+        self.scaleFactor = scaleFactor  # Adding scale factor with default value 1.0
 
     def toLatex(self):
         """generates a latex string from a node
@@ -65,36 +83,45 @@ class dsiUnitNode:
         try:
             latexString += _dsiUnitsLatex[self.unit]
         except KeyError:
-            latexString += r'{\color{red}\mathrm{'+self.unit+r'}}'
-            if self.valid==True:
-                raise RuntimeError("Found invalid unit in valid node, this should not happen! Report this incident at: https://gitlab1.ptb.de/digitaldynamicmeasurement/dsiUnits/-/issues/new")
-        if isinstance(self.exponent,str):
+            latexString += r"{\color{red}\mathrm{" + self.unit + r"}}"
+            if self.valid == True:
+                raise RuntimeError(
+                    "Found invalid unit in valid node, this should not happen! Report this incident at: https://gitlab1.ptb.de/digitaldynamicmeasurement/dsiUnits/-/issues/new"
+                )
+        if isinstance(self.exponent, str):
             # exponent is str this shouldn't happen!
-            latexString += r'^{{\color{red}\mathrm{'+self.exponent+r'}}}'
-            if self.valid==True:
-                raise RuntimeError("Found invalid unit in valid node, this should not happen! Report this incident at: https://gitlab1.ptb.de/digitaldynamicmeasurement/dsiUnits/-/issues/new")
+            latexString += r"^{{\color{red}\mathrm{" + self.exponent + r"}}}"
+            if self.valid == True:
+                raise RuntimeError(
+                    "Found invalid unit in valid node, this should not happen! Report this incident at: https://gitlab1.ptb.de/digitaldynamicmeasurement/dsiUnits/-/issues/new"
+                )
         elif self.exponent != 1:
-            if not self.exponent.denominator == 1: # exponent is not an integer
-                if self.exponent.denominator == 2: # square root
-                    latexString = r'\sqrt{' + latexString 
-                else: # higher roots need an extra argument
-                    latexString = r'\sqrt[' + str(self.exponent.denominator) + ']{' + latexString
-                    if self.exponent.numerator != 1: # keep anything in the numerator of the exponent in the exponent
-                        latexString += '^{' + str(self.exponent.numerator) + '}'
-                latexString += r'}'
-                    
+            if not self.exponent.denominator == 1:  # exponent is not an integer
+                if self.exponent.denominator == 2:  # square root
+                    latexString = r"\sqrt{" + latexString
+                else:  # higher roots need an extra argument
+                    latexString = (
+                        r"\sqrt[" + str(self.exponent.denominator) + "]{" + latexString
+                    )
+                    if (
+                        self.exponent.numerator != 1
+                    ):  # keep anything in the numerator of the exponent in the exponent
+                        latexString += "^{" + str(self.exponent.numerator) + "}"
+                latexString += r"}"
+
             else:
-                latexString += r'^{' + str(self.exponent) + r'}'
+                latexString += r"^{" + str(self.exponent) + r"}"
 
-        
         if self.unit == "":
-            latexString = r'{\color{red}'+latexString+r'}'
-            if self.valid==True:
-                raise RuntimeError("Found invalid unit in valid node, this should not happen! Report this incident at: https://gitlab1.ptb.de/digitaldynamicmeasurement/dsiUnits/-/issues/new")
+            latexString = r"{\color{red}" + latexString + r"}"
+            if self.valid == True:
+                raise RuntimeError(
+                    "Found invalid unit in valid node, this should not happen! Report this incident at: https://gitlab1.ptb.de/digitaldynamicmeasurement/dsiUnits/-/issues/new"
+                )
 
         return latexString
 
-    def toBaseUnits(self, complete=False) -> List['dsiUnitNode']:
+    def toBaseUnits(self, complete=False) -> List["dsiUnitNode"]:
         """
         Converts this node to its base unit representation.
         Adjusts the scale factor during the conversion. Optionally resolves to kg, s, and m units,
@@ -107,7 +134,9 @@ class dsiUnitNode:
             List['dsiUnitNode']: List of nodes representing the base units or kg, s, m equivalents.
         """
         # Adjust the scale factor for the prefix
-        prefixScale = _dsiPrefixesScales.get(self.prefix, 1)  # Default to 1 if no prefix
+        prefixScale = _dsiPrefixesScales.get(
+            self.prefix, 1
+        )  # Default to 1 if no prefix
         adjustedScaleFactor = self.scaleFactor * prefixScale**self.exponent
 
         # Convert to base units if it's a derived unit
@@ -116,8 +145,19 @@ class dsiUnitNode:
             baseUnits = []
             for i, (baseUnit, exponent, scaleFactor) in enumerate(baseUnitsInfo):
                 # Apply the adjusted scale factor only to the first base unit
-                finalScaleFactor = math.pow(adjustedScaleFactor * scaleFactor, self.exponent) if i == 0 else 1.0
-                baseUnits.append(dsiUnitNode('', baseUnit, exponent * self.exponent, scaleFactor=finalScaleFactor))
+                finalScaleFactor = (
+                    math.pow(adjustedScaleFactor * scaleFactor, self.exponent)
+                    if i == 0
+                    else 1.0
+                )
+                baseUnits.append(
+                    dsiUnitNode(
+                        "",
+                        baseUnit,
+                        exponent * self.exponent,
+                        scaleFactor=finalScaleFactor,
+                    )
+                )
             return baseUnits
         elif complete:
             # Additional logic for converting ampere, volt, and mole to kg, s, and m equivalents
@@ -125,38 +165,56 @@ class dsiUnitNode:
                 kgsUnitsInfo = _additionalConversions[self.unit]
                 kgsUnits = []
                 for i, (kgsUnit, exponent, scaleFactor) in enumerate(kgsUnitsInfo):
-                    finalScaleFactor = math.pow(adjustedScaleFactor * scaleFactor, self.exponent) if i == 0 else 1.0
-                    kgsUnits.append(dsiUnitNode('', kgsUnit, exponent * self.exponent, scaleFactor=finalScaleFactor))
+                    finalScaleFactor = (
+                        math.pow(adjustedScaleFactor * scaleFactor, self.exponent)
+                        if i == 0
+                        else 1.0
+                    )
+                    kgsUnits.append(
+                        dsiUnitNode(
+                            "",
+                            kgsUnit,
+                            exponent * self.exponent,
+                            scaleFactor=finalScaleFactor,
+                        )
+                    )
                 return kgsUnits
 
         # Return the node as is if it's already a base unit, with adjusted scale factor
-        return [dsiUnitNode('', self.unit, self.exponent,  scaleFactor=adjustedScaleFactor)]
+        return [
+            dsiUnitNode("", self.unit, self.exponent, scaleFactor=adjustedScaleFactor)
+        ]
 
     def __eq__(self, other):
         """Checks if two nodes are identical after sorting their nodes alphabetically."""
-        return self.prefix == other.prefix and self.unit == other.unit and self.exponent == other.exponent and self.scaleFactor == other.scaleFactor
+        return (
+            self.prefix == other.prefix
+            and self.unit == other.unit
+            and self.exponent == other.exponent
+            and self.scaleFactor == other.scaleFactor
+        )
 
     def __str__(self):
-        result=''
+        result = ""
 
-        if self.prefix !='':
-            result+='\\'+self.prefix
-        result = result + '\\' + self.unit
+        if self.prefix != "":
+            result += "\\" + self.prefix
+        result = result + "\\" + self.unit
         if self.exponent != 1:
-            result = result + r'\tothe{' + '{:g}'.format(float(self.exponent)) + '}'
+            result = result + r"\tothe{" + "{:g}".format(float(self.exponent)) + "}"
         return result
 
-    def isScaled(self,other):
+    def isScaled(self, other):
         """Checks if two nodes are scaled equal."""
         if self.unit == other.unit and self.exponent == other.exponent:
-            return _dsiPrefixesScales[other.prefix]/_dsiPrefixesScales[self.prefix]
+            return _dsiPrefixesScales[other.prefix]**other.exponent / _dsiPrefixesScales[self.prefix]**self.exponent
         else:
             return math.nan
 
     def removePrefix(self):
         """Removes the prefix from the node and adjusts the scale factor accordingly."""
-        if self.prefix != '':
+        if self.prefix != "":
             self.scaleFactor = self.scaleFactor * _dsiPrefixesScales[self.prefix]
-            self.scaleFactor = self.scaleFactor ** self.exponent #TODO check this
-            self.prefix = ''
+            self.scaleFactor = self.scaleFactor**self.exponent  # TODO check this
+            self.prefix = ""
         return self
diff --git a/src/dsiUnits.py b/src/dsiUnits.py
index 54c4e58f50c21685064415e35b091d958e1e9a9e..7da858b3779d99b38e0e5bb6747b8bacd96e3958 100644
--- a/src/dsiUnits.py
+++ b/src/dsiUnits.py
@@ -1,18 +1,19 @@
 # This file is part of dsiUnits (https://gitlab1.ptb.de/digitaldynamicmeasurement/dsiUnits/)
 # Copyright 2024 [Benedikt Seeger(PTB), Vanessa Stehr(PTB)]
-#This library is free software; you can redistribute it and/or
-#modify it under the terms of the GNU Lesser General Public
-#License as published by the Free Software Foundation; either
-#version 2.1 of the License, or (at your option) any later version.
-
-#This library is distributed in the hope that it will be useful,
-#but WITHOUT ANY WARRANTY; without even the implied warranty of
-#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#Lesser General Public License for more details.
-
-#You should have received a copy of the GNU Lesser General Public
-#License along with this library; if not, write to the Free Software
-#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+from __future__ import annotations  # for type annotation recursion
 import re
 import warnings
 import difflib
@@ -23,11 +24,22 @@ from fractions import Fraction
 from decimal import Decimal, InvalidOperation
 import numbers
 
-from unitStrings import _dsiPrefixesLatex, _dsiPrefixesScales, _dsiPrefixesUTF8, _dsiUnitsLatex, _dsiUnitsUTF8, _derivedToBaseUnits, _additionalConversions, _dsiKeyWords
+from unitStrings import (
+    _dsiPrefixesLatex,
+    _dsiPrefixesScales,
+    _dsiPrefixesUTF8,
+    _dsiUnitsLatex,
+    _dsiUnitsUTF8,
+    _derivedToBaseUnits,
+    _additionalConversions,
+    _dsiKeyWords,
+)
 from dsiParser import NonDsiUnitWarning, dsiParser
 from dsiUnitNode import dsiUnitNode
 
-dsiPaserInstance = dsiParser()
+dsiParserInstance = dsiParser()
+
+
 class dsiUnit:
     def __init__(self, dsiString: str):
         """
@@ -35,10 +47,10 @@ class dsiUnit:
             dsiString (str): the D-SI unit string to be parsed
         """
         try:
-            parsedDsiUnit = dsiPaserInstance.parse(dsiString)
-            self.dsiString,self.tree, self.warnings, self.nonDsiUnit = parsedDsiUnit
+            parsedDsiUnit = dsiParserInstance.parse(dsiString)
+            self.dsiString, self.tree, self.warnings, self.nonDsiUnit = parsedDsiUnit
             self.valid = len(self.warnings) == 0
-            self.scaleFactor=1.0
+            self.scaleFactor = 1.0
         except Exception as e:
             warnings.warn(str(e))
             self.dsiString = dsiString
@@ -48,7 +60,14 @@ class dsiUnit:
             self.valid = False
 
     @classmethod
-    def fromDsiTree(cls, dsiString: str, dsiTree=[], warningMessages=[], nonDsiUnit=False,scaleFactor=1.0):
+    def fromDsiTree(
+        cls,
+        dsiString: str,
+        dsiTree=[],
+        warningMessages=[],
+        nonDsiUnit=False,
+        scaleFactor=1.0,
+    ):
         """
         Class method to create an instance from a D-SI tree and other optional arguments.
 
@@ -65,16 +84,15 @@ class dsiUnit:
         if nonDsiUnit:
             dsiTree = [dsiString]
         elif dsiString == "" and dsiTree != []:
-            dsiString = dsiPaserInstance._dsiStrFromNodes(dsiTree)
+            dsiString = dsiParserInstance._dsiStrFromNodes(dsiTree)
         instance.dsiString = dsiString
         instance.tree = dsiTree
         instance.warnings = warningMessages
         instance.nonDsiUnit = nonDsiUnit
         instance.valid = len(warningMessages) == 0
-        instance.scaleFactor=scaleFactor
+        instance.scaleFactor = scaleFactor
         return instance
 
-
     def toLatex(self, wrapper=None, prefix=None, suffix=None):
         """converts D-SI unit string to LaTeX
 
@@ -88,9 +106,9 @@ class dsiUnit:
         """
 
         # If no wrapper/prefix/suffix was given, set to the parser's default
-        wrapper = dsiPaserInstance._latexDefaultWrapper if wrapper == None else wrapper
-        prefix = dsiPaserInstance._latexDefaultPrefix if prefix == None else prefix
-        suffix = dsiPaserInstance._latexDefaultSuffix if suffix == None else suffix
+        wrapper = dsiParserInstance._latexDefaultWrapper if wrapper == None else wrapper
+        prefix = dsiParserInstance._latexDefaultPrefix if prefix == None else prefix
+        suffix = dsiParserInstance._latexDefaultSuffix if suffix == None else suffix
 
         if self.tree == []:
             if len(prefix) + len(suffix) > 0:
@@ -98,37 +116,37 @@ class dsiUnit:
             else:
                 return ""
         if self.nonDsiUnit:
-            if self.dsiString[0]!='|':
-                latexString=r'\textpipe'+r'\mathrm{'+self.dsiString+r'}'
+            if self.dsiString[0] != "|":
+                latexString = r"\textpipe" + r"\mathrm{" + self.dsiString + r"}"
             else:
-                latexString = r'\textpipe' + r'\mathrm{' + self.dsiString[1:] + r'}'
+                latexString = r"\textpipe" + r"\mathrm{" + self.dsiString[1:] + r"}"
             return wrapper + prefix + latexString + suffix + wrapper
         latexArray = []
         if len(self.tree) == 1:  # no fractions
             for node in self.tree[0]:
                 latexArray.append(node.toLatex())
-            latexString = r'\,'.join(latexArray)
+            latexString = r"\,".join(latexArray)
         elif len(self.tree) == 2:  # one fraction
             latexString = ""
-            latexString += r'\frac'
+            latexString += r"\frac"
             for frac in self.tree:
-                latexString += r'{'
+                latexString += r"{"
                 nodeArray = []
                 for node in frac:
                     nodeArray.append(node.toLatex())
-                latexString += r'\,'.join(nodeArray)
-                latexString += r'}'
+                latexString += r"\,".join(nodeArray)
+                latexString += r"}"
         else:  # more than one fraction
             latexString = ""
             for i in range(len(self.tree)):
                 nodeArray = []
                 if i > 0:
-                    latexString += r'{\color{red}/}'
+                    latexString += r"{\color{red}/}"
                 for node in self.tree[i]:
                     nodeArray.append(node.toLatex())
-                latexString += r'\,'.join(nodeArray)
+                latexString += r"\,".join(nodeArray)
         if self.scaleFactor != 1.0:
-            latexString = str(self.scaleFactor) + r'\cdot' + latexString
+            latexString = str(self.scaleFactor) + r"\cdot" + latexString
         return wrapper + prefix + latexString + suffix + wrapper
 
     def toUTF8(self):
@@ -137,25 +155,45 @@ class dsiUnit:
         def exponent_to_utf8(exp):
             """Converts numerical exponents to UTF-8 subscript."""
             # Mapping for common exponents to UTF-8
-            superscripts = {"1": "¹", "2": "²", "3": "³", "4": "⁴", "5": "⁵",
-                            "6": "⁶", "7": "⁷", "8": "⁸", "9": "⁹", "0": "⁰",
-                            "-": "⁻",".": "˙"}
+            superscripts = {
+                "1": "¹",
+                "2": "²",
+                "3": "³",
+                "4": "⁴",
+                "5": "⁵",
+                "6": "⁶",
+                "7": "⁷",
+                "8": "⁸",
+                "9": "⁹",
+                "0": "⁰",
+                "-": "⁻",
+                ".": "˙",
+            }
             # Convert fractional exponents to a more readable format if needed
-            return ''.join(superscripts.get(char, char) for char in str(exp))
+            return "".join(superscripts.get(char, char) for char in str(exp))
+
         if self.nonDsiUnit:
-            if self.dsiString[0]!='|':
-                return "|"+self.dsiString
+            if self.dsiString[0] != "|":
+                return "|" + self.dsiString
             return self.dsiString
         utf8Array = []
         for unitFraction in self.tree:
             fractionUtf8Array = []
             for node in unitFraction:
                 # Fetch UTF-8 unit representation
-                unitStr = _dsiUnitsUTF8.get(node.unit,'⚠'+node.unit+'⚠')#second arg is returend on itemError
+                unitStr = _dsiUnitsUTF8.get(
+                    node.unit, "⚠" + node.unit + "⚠"
+                )  # second arg is returned on itemError
 
                 # Handle prefix (if any) and unit
-                prefixStr = _dsiPrefixesUTF8.get(node.prefix, '⚠'+node.prefix+'⚠') if node.prefix else ""
-                utf8Str = f"{prefixStr}{unitStr}"  # Direct concatenation for compactness
+                prefixStr = (
+                    _dsiPrefixesUTF8.get(node.prefix, "⚠" + node.prefix + "⚠")
+                    if node.prefix
+                    else ""
+                )
+                utf8Str = (
+                    f"{prefixStr}{unitStr}"  # Direct concatenation for compactness
+                )
 
                 # Handle exponent, converting to UTF-8 subscript, if not 1
                 if node.exponent and node.exponent != 1:
@@ -166,15 +204,13 @@ class dsiUnit:
             # Join units within the same fraction with a dot for compactness
             utf8Array.append("".join(fractionUtf8Array))
         if self.scaleFactor != 1.0:
-            scalfactorStr = str(self.scaleFactor)+'*'
+            scaleFactorStr = str(self.scaleFactor) + "*"
         else:
-            scalfactorStr = ""
+            scaleFactorStr = ""
         # Handle fractions, join numerator and denominator with a slash for division
-        return scalfactorStr+" / ".join(utf8Array).replace(' ', '')
-
+        return scaleFactorStr + " / ".join(utf8Array).replace(" ", "")
 
-
-    def toBaseUnitTree(self,complete=False):
+    def toBaseUnitTree(self, complete=False):
         """
         Converts the entire D-SI tree to its base unit representation.
         """
@@ -185,11 +221,11 @@ class dsiUnit:
                 baseFraction.extend(node.toBaseUnits())
             baseUnitTree.append(baseFraction)
         unconsolidatedTree = dsiUnit.fromDsiTree(
-            dsiString=self.dsiString, 
-            dsiTree=baseUnitTree, 
-            warningMessages=self.warnings
+            dsiString=self.dsiString,
+            dsiTree=baseUnitTree,
+            warningMessages=self.warnings,
         )
-        reduced=unconsolidatedTree.reduceFraction()
+        reduced = unconsolidatedTree.reduceFraction()
         # if kgms True we do a second round but resolve volt ampere mole this round
         if complete:
             baseUnitTree = []
@@ -199,9 +235,9 @@ class dsiUnit:
                     baseFraction.extend(node.toBaseUnits(complete=complete))
                 baseUnitTree.append(baseFraction)
             unconsolidatedTree = dsiUnit.fromDsiTree(
-                dsiString=self.dsiString, 
-                dsiTree=baseUnitTree, 
-                warningMessages=self.warnings
+                dsiString=self.dsiString,
+                dsiTree=baseUnitTree,
+                warningMessages=self.warnings,
             )
             reduced = unconsolidatedTree.reduceFraction()
         return reduced
@@ -214,7 +250,9 @@ class dsiUnit:
         - The first node carries the overall scale factor.
         """
         if len(self.tree) > 2:
-            raise RuntimeError("D-SI tree with more than two fractions cannot be reduced.")
+            raise RuntimeError(
+                "D-SI tree with more than two fractions cannot be reduced."
+            )
 
         consolidated_nodes = []
 
@@ -230,7 +268,14 @@ class dsiUnit:
                 # Inverting the exponent for nodes in the denominator
                 invertedExponent = -1 * node.exponent
                 fractionalScaleFactor = 1 / node.scaleFactor**node.exponent
-                consolidated_nodes.append(dsiUnitNode(node.prefix, node.unit, invertedExponent,  scaleFactor=fractionalScaleFactor))
+                consolidated_nodes.append(
+                    dsiUnitNode(
+                        node.prefix,
+                        node.unit,
+                        invertedExponent,
+                        scaleFactor=fractionalScaleFactor,
+                    )
+                )
 
         # Consolidating nodes with the same unit
         i = 0
@@ -239,15 +284,24 @@ class dsiUnit:
             while j < len(consolidated_nodes):
                 if consolidated_nodes[i].unit == consolidated_nodes[j].unit:
                     # Consolidate nodes
-                    scaleFactor = consolidated_nodes[i].scaleFactor*consolidated_nodes[j].scaleFactor
-                    prefixScaleI=_dsiPrefixesScales[consolidated_nodes[i].prefix]
+                    scaleFactor = (
+                        consolidated_nodes[i].scaleFactor
+                        * consolidated_nodes[j].scaleFactor
+                    )
+                    prefixScaleI = _dsiPrefixesScales[consolidated_nodes[i].prefix]
                     prefixScaleJ = _dsiPrefixesScales[consolidated_nodes[j].prefix]
-                    combinedPrefixScale=prefixScaleI*prefixScaleJ
-                    consolidated_nodes[i].prefix=''# we wont allow prefixes in consolidated nodes since we dont want to have prefixes in the base units
-                    consolidated_nodes[i].scaleFactor *= consolidated_nodes[j].scaleFactor*combinedPrefixScale
+                    combinedPrefixScale = prefixScaleI * prefixScaleJ
+                    consolidated_nodes[i].prefix = (
+                        ""  # we wont allow prefixes in consolidated nodes since we don't want to have prefixes in the base units
+                    )
+                    consolidated_nodes[i].scaleFactor *= (
+                        consolidated_nodes[j].scaleFactor * combinedPrefixScale
+                    )
                     if combinedPrefixScale != 1:
                         raise RuntimeError("Prefixes in base units are not allowed")
-                    exponent=consolidated_nodes[i].exponent + consolidated_nodes[j].exponent
+                    exponent = (
+                        consolidated_nodes[i].exponent + consolidated_nodes[j].exponent
+                    )
                     consolidated_nodes[i].exponent = exponent
                     del consolidated_nodes[j]
                 else:
@@ -261,80 +315,111 @@ class dsiUnit:
         #    node.scaleFactor = 1.0  # Reset scale factor for individual nodes
         # Sort nodes alphabetically by unit
         consolidated_nodes.sort(key=lambda x: x.unit)
-        nodesWOPowerZero=[]
+        nodesWOPowerZero = []
         for node in consolidated_nodes:
             if node.exponent != 0:
                 nodesWOPowerZero.append(node)
         # ok all nodes have ben power of zero so we deleted them and end up with one or bytes or bits as unit and 1.0 as exponent
         if len(nodesWOPowerZero) == 0:
-            hadBytes=False
-            haBits=False
+            hadBytes = False
+            haBits = False
             for fraction in self.tree:
                 for node in fraction:
                     if node.unit == "byte":
-                        hadBytes=True
+                        hadBytes = True
                     if node.unit == "bit":
-                        haBits=True
+                        haBits = True
             if hadBytes and haBits:
-                raise RuntimeError("Can't have bytes and bits in the same unit this should have been consolidated allready in the parser")
+                raise RuntimeError(
+                    "Can't have bytes and bits in the same unit this should have been consolidated already in the parser"
+                )
             if hadBytes:
-                nodesWOPowerZero.append(dsiUnitNode("", "byte", 1.0,scaleFactor=overall_scale_factor))
+                nodesWOPowerZero.append(
+                    dsiUnitNode("", "byte", 1.0, scaleFactor=overall_scale_factor)
+                )
             elif haBits:
-                nodesWOPowerZero.append(dsiUnitNode("", "bit", 1.0,scaleFactor=overall_scale_factor))
+                nodesWOPowerZero.append(
+                    dsiUnitNode("", "bit", 1.0, scaleFactor=overall_scale_factor)
+                )
             else:
-                nodesWOPowerZero.append(dsiUnitNode("", "one", 1.0,scaleFactor=overall_scale_factor))
-        consolidated_nodes=nodesWOPowerZero
+                nodesWOPowerZero.append(
+                    dsiUnitNode("", "one", 1.0, scaleFactor=overall_scale_factor)
+                )
+        consolidated_nodes = nodesWOPowerZero
         # Check for ones and delete them if they are not the only node ad set there exponent to 1.0 since 1^x = 1
         if len(consolidated_nodes) > 1:
-            consolidated_nodes = [node for node in consolidated_nodes if node.unit != "one"]
+            consolidated_nodes = [
+                node for node in consolidated_nodes if node.unit != "one"
+            ]
         else:
             if consolidated_nodes[0].unit == "one":
-                consolidated_nodes[0].exponent=1.0
+                consolidated_nodes[0].exponent = 1.0
         # Create and return a new instance of _dsiTree with consolidated nodes
         return dsiUnit.fromDsiTree(
-            dsiString=self.dsiString, 
-            dsiTree=[consolidated_nodes], 
+            dsiString=self.dsiString,
+            dsiTree=[consolidated_nodes],
             warningMessages=self.warnings,
             nonDsiUnit=False,
-            scaleFactor=overall_scale_factor
+            scaleFactor=overall_scale_factor,
         )
 
     def _removePer(self):
-        if len(self.tree)==2:
-            for i,node in enumerate(self.tree[1]):
-                #invert exponent node.
-                node.exponent=node.exponent*-1
+        if len(self.tree) == 2:
+            for i, node in enumerate(self.tree[1]):
+                # invert exponent node.
+                node.exponent = node.exponent * -1
                 self.tree[0].append(node)
                 self.tree[1].pop(i)
             self.tree.pop(1)
 
     def negExponentsToPer(self):
         """Converts negative exponents to the denominator of the fraction."""
-        for node in self.tree[0]: # numerator
+        for node in self.tree[0]:  # numerator
             if node.exponent < 0:
                 node.exponent = -node.exponent
-                node.scaleFactor=1/node.scaleFactor
+                node.scaleFactor = 1 / node.scaleFactor
                 try:
-                    self.tree[1].append(dsiUnitNode("", node.unit, node.exponent,scaleFactor=node.scaleFactor))
-                except IndexError:# if we have only the numerator list we need to add the denominator list
-                    self.tree.append([dsiUnitNode("", node.unit, node.exponent,scaleFactor=node.scaleFactor)])
+                    self.tree[1].append(
+                        dsiUnitNode(
+                            "", node.unit, node.exponent, scaleFactor=node.scaleFactor
+                        )
+                    )
+                except (
+                    IndexError
+                ):  # if we have only the numerator list we need to add the denominator list
+                    self.tree.append(
+                        [
+                            dsiUnitNode(
+                                "",
+                                node.unit,
+                                node.exponent,
+                                scaleFactor=node.scaleFactor,
+                            )
+                        ]
+                    )
                 self.tree[0].remove(node)
-        if len(self.tree) ==2: # we have a numerator and a denominator so we must treat the denominator as well
-            for node in self.tree[1]: # numerator
+        if (
+            len(self.tree) == 2
+        ):  # we have a numerator and a denominator so we must treat the denominator as well
+            for node in self.tree[1]:  # numerator
                 if node.exponent < 0:
                     node.exponent = -node.exponent
                     node.scaleFactor = 1 / node.scaleFactor
-                    self.tree[0].append(dsiUnitNode("", node.unit, node.exponent,scaleFactor=node.scaleFactor))
+                    self.tree[0].append(
+                        dsiUnitNode(
+                            "", node.unit, node.exponent, scaleFactor=node.scaleFactor
+                        )
+                    )
                     self.tree[1].remove(dsiUnitNode)
         if len(self.tree[0]) == 0:
             self.tree[0].append(dsiUnitNode("", "one", 1.0))
         return self
 
-
     def sortTree(self):
         """Sorts each fraction's nodes alphabetically by their units."""
         for unitFraction in self.tree:
             unitFraction.sort(key=lambda node: node.unit)
+
     def __eq__(self, other):
         """Checks if two D-SI trees are identical after sorting their nodes alphabetically."""
         if not isinstance(other, dsiUnit):
@@ -351,42 +436,109 @@ class dsiUnit:
         else:
             selfCopy._removePer()
             otherCopy._removePer()
-            if selfCopy.tree==otherCopy.tree:
+            if selfCopy.tree == otherCopy.tree:
                 return True
             else:
                 return False
 
-    def isScalablyEqualTo(self, other,complete=False):
-        """Checks if two D-SI trees are scalably equal.
+    def getScaleFactor(self, other: dsiUnit) -> float:
+        """Get the factor with which the units can be converted into each other. x self == 1 other.
+
+        Args:
+            other (dsiUnit): Unit to compare against
+
+        Returns:
+            float: scale factor. scale factor * self == 1 * other
+        """
+        scaleFactor, baseUnit = self._calculateScaleFactorAndCommonUnit(
+            other, complete=True
+        )
+        return scaleFactor
+
+    def isScalable(self, other: dsiUnit) -> bool:
+        """returns whether the two units can be converted into each other.
+
+        Args:
+            other (dsiUnit): Unit to compare against
+
+        Returns:
+            bool: whether the two units can be converted into each other
+        """
+        return bool(self.getScaleFactor(other))
+
+    def getBaseUnit(self, other: dsiUnit) -> dsiUnit:
+        """Get the common base unit for the two units, if it exists
+
+        Args:
+            other (dsiUnit): Unit to compare against
+
+        Returns:
+            dsiUnit: common base unit
+        """
+        scaleFactor, commonUnit = self._calculateScaleFactorAndCommonUnit(
+            other, complete=True
+        )
+        if not commonUnit: # Check if commonUnit is None
+            return None
+        baseUnit = commonUnit.reduceFraction()
+        baseUnit.tree[0][
+            0
+        ].scaleFactor = 1.0  # TODO: check if this should be a Fraction
+        return baseUnit
+
+    def isScalablyEqualTo(self, other, complete=False):
+        """
+        Checks if two D-SI units are scalably equal and returns the scale factor and base unit, without modifying
+        the units involved.
+
+        Args:
+            other (dsiUnit): The other D-SI unit to compare against.
+            complete (bool): A flag to determine whether or not the units should be resolved completely to base units.
 
         Returns:
-            (bool, float): Tuple of a boolean indicating if trees are scalably equal, and the scale factor.
+            (float, dsiUnit):
+                - A tuple containing the scale factor as a float. If the units are not scalable, returns math.nan.
+                - The second element is the base unit of the calling object or None if not scalable.
+
+        Behavior:
+            - First, it checks if `other` is of type `dsiUnit`. If not, it returns math.nan and None.
+            - It sorts and compares the two trees. If they are identical, it returns a scale factor of 1.0 and the calling unit.
+            - If they are not identical, it attempts to compute the scale factor by iterating through the tree nodes and checking for scaling relationships.
+            - If direct comparison fails and complete == True, it converts both trees to their base unit representations, sorts them, and attempts to compute a scaling factor in the base units.
+        Raises:
+            RuntimeError: If there are multiple fractions in the base unit trees during comparison.
         """
+        warnings.warn(
+            "This function is deprecated. Please use one of the following functions instead: getScaleFactor, isScalable, getBaseUnit",
+            DeprecationWarning,
+        )
+        return self._calculateScaleFactorAndCommonUnit(other, complete=complete)
+
+    def _calculateScaleFactorAndCommonUnit(self, other, complete=False):
         if not isinstance(other, dsiUnit):
             return (math.nan, None)
 
-
-        sortedSelf=deepcopy(self)
+        sortedSelf = deepcopy(self)
         sortedSelf.sortTree()
-        sortedOther=deepcopy(other)
+        sortedOther = deepcopy(other)
         sortedOther.sortTree()
         # okay now check if is identical
         if sortedSelf.tree == sortedOther.tree:
-            return (1.0,self)
-        scaleFactor=1
-        for fracIdx,unitFraction in enumerate(sortedSelf.tree):
+            return (1.0, self)
+        scaleFactor = 1
+        for fracIdx, unitFraction in enumerate(sortedSelf.tree):
             try:
                 if len(unitFraction) != len(sortedOther.tree[fracIdx]):
-                    scaleFactor=math.nan
+                    scaleFactor = math.nan
                     break
-                for nodeIDX,node in enumerate(unitFraction):
+                for nodeIDX, node in enumerate(unitFraction):
                     scaleFactor *= node.isScaled(sortedOther.tree[fracIdx][nodeIDX])
             except IndexError:
                 # if we get here we have a fraction in one tree that is not in the other in this case we resolve to base units and compare
-                scaleFactor=math.nan
+                scaleFactor = math.nan
                 break
         if not math.isnan(scaleFactor):
-            return (scaleFactor,self)
+            return (scaleFactor, self)
         # Convert both trees to their base unit representations
         selfBaseUnitTree = self.toBaseUnitTree(complete=complete)
         otherBaseUnitTree = other.toBaseUnitTree(complete=complete)
@@ -400,8 +552,12 @@ class dsiUnit:
         # Calculate scale factor
         scaleFactor = 1.0
         if len(selfBaseUnitTree.tree) != 1 or len(otherBaseUnitTree.tree) != 1:
-            raise RuntimeError("D-SI tree with more than one fraction cannot be compared. And should not exist here since we consolidated earlier")
-        for selfNode, otherNode in zip(selfBaseUnitTree.tree[0], otherBaseUnitTree.tree[0]):
+            raise RuntimeError(
+                "D-SI tree with more than one fraction cannot be compared. And should not exist here since we consolidated earlier"
+            )
+        for selfNode, otherNode in zip(
+            selfBaseUnitTree.tree[0], otherBaseUnitTree.tree[0]
+        ):
             if selfNode.unit != otherNode.unit:
                 return (math.nan, None)
             if selfNode.exponent != otherNode.exponent:
@@ -409,39 +565,38 @@ class dsiUnit:
             scaleFactor *= otherNode.scaleFactor / selfNode.scaleFactor
         # resetting scaleFactor to 1.0
         scaleFactor = otherBaseUnitTree.scaleFactor / selfBaseUnitTree.scaleFactor
-        # TODO check reseting the scalfactors of the baseunits is a good idea ... but we calculated the scalefactor and returnd it so it should be fine
+        # TODO check resetting the scale factors of the base units is a good idea ... but we calculated the scale factor and returned it so it should be fine
         selfBaseUnitTree.scaleFactor = 1.0
         for fraction in selfBaseUnitTree.tree:
             for node in fraction:
                 node.scaleFactor = 1.0
-        return (scaleFactor,selfBaseUnitTree)
+        return (scaleFactor, selfBaseUnitTree)
 
     def __str__(self):
         result = ""
         if self.nonDsiUnit:
-            if self.dsiString[0]!='|':
-                return "|"+self.dsiString
+            if self.dsiString[0] != "|":
+                return "|" + self.dsiString
             return self.dsiString
         if self.scaleFactor != 1.0:
             result += str(self.scaleFactor) + "*"
         for node in self.tree[0]:
             result += str(node)
         if len(self.tree) == 2:
-            result += r'\per'
+            result += r"\per"
             for node in self.tree[1]:
                 result += str(node)
         return result
 
     def __repr__(self):
-        contentStr=self.toUTF8()
+        contentStr = self.toUTF8()
         if not self.valid:
-            contentStr+='INVALIDE'
+            contentStr += "INVALIDE"
         if self.warnings:
-            contentStr+=f" {len(self.warnings)} WARNINGS"
+            contentStr += f" {len(self.warnings)} WARNINGS"
         # Simple representation: class name and D-SI string
         return f"{contentStr}"
 
-
     def __pow__(self, other):
         if not isinstance(other, numbers.Real):
             raise TypeError("Exponent must be a real number")
@@ -451,16 +606,16 @@ class dsiUnit:
         for unitFraction in resultNodeLIst:
             for node in unitFraction:
                 node.removePrefix()
-                exponent = node.exponent*other
-                node.exponent *= Fraction(exponent).limit_denominator(dsiPaserInstance.maxDenominator)
+                exponent = node.exponent * other
+                node.exponent *= Fraction(exponent).limit_denominator(
+                    dsiParserInstance.maxDenominator
+                )
                 node.scaleFactor **= other
-        resultTree =dsiUnit.fromDsiTree(
-            dsiString="", 
-            dsiTree=resultNodeLIst, 
-            warningMessages=self.warnings
+        resultTree = dsiUnit.fromDsiTree(
+            dsiString="", dsiTree=resultNodeLIst, warningMessages=self.warnings
         )
         resultTree = resultTree.reduceFraction()
-        if len(self.tree)==2: # check if we had a per representation
+        if len(self.tree) == 2:  # check if we had a per representation
             resultTree.negExponentsToPer()
         return resultTree
 
@@ -468,24 +623,26 @@ class dsiUnit:
         if self.nonDsiUnit or other.nonDsiUnit:
             raise RuntimeError("Can't do math with non-DSI units")
         if len(self.tree) + len(other.tree) > 2:
-            convertToPer=True
+            convertToPer = True
         else:
-            convertToPer=False
-        resultNodeLIst=deepcopy(self.tree)
-        for i,unitFraction in enumerate(other.tree):
-            if i>1:
-                raise RuntimeError("D-SI tree with more than one fraction cannot be multiplied")
+            convertToPer = False
+        resultNodeLIst = deepcopy(self.tree)
+        for i, unitFraction in enumerate(other.tree):
+            if i > 1:
+                raise RuntimeError(
+                    "D-SI tree with more than one fraction cannot be multiplied"
+                )
             try:
                 resultNodeLIst[i].extend(deepcopy(unitFraction))
             except IndexError:
-                resultNodeLIst.append(deepcopy(unitFraction))# there was no fraction so we add it
-        for fractionComponenten in resultNodeLIst:
-            for node in fractionComponenten:
+                resultNodeLIst.append(
+                    deepcopy(unitFraction)
+                )  # there was no fraction so we add it
+        for fractionComponents in resultNodeLIst:
+            for node in fractionComponents:
                 node.removePrefix()
-        resultTree =dsiUnit.fromDsiTree(
-            dsiString="", 
-            dsiTree=resultNodeLIst, 
-            warningMessages=self.warnings
+        resultTree = dsiUnit.fromDsiTree(
+            dsiString="", dsiTree=resultNodeLIst, warningMessages=self.warnings
         )
         resultTree = resultTree.reduceFraction()
         if convertToPer:
@@ -495,8 +652,7 @@ class dsiUnit:
     def __truediv__(self, other):
         if self.nonDsiUnit or other.nonDsiUnit:
             raise RuntimeError("Can't do math with non-DSI units")
-        if dsiPaserInstance.createPerByDivision:
+        if dsiParserInstance.createPerByDivision:
             return (self * (other**-1)).negExponentsToPer()
         else:
-            return self * (other ** -1)
-
+            return self * (other**-1)
diff --git a/src/unitStrings.py b/src/unitStrings.py
index 89a6832a1fbcfe967ea7c911c8478e8be38e76d6..31628e49ef20988e36317c745d4056ffef62397c 100644
--- a/src/unitStrings.py
+++ b/src/unitStrings.py
@@ -29,7 +29,7 @@ _dsiPrefixesLatex = {
     'deci': r'\mathrm{d}',
     'centi': r'\mathrm{c}',
     'milli': r'\mathrm{m}',
-    'micro': r'\mu',# todo this ist most likly italic find a fix that dont needs external pacakges :(
+    'micro': r'\mu',# todo this ist most likely italic find a fix that doesn't needs external packages :(
     'nano': r'\mathrm{n}',
     'pico': r'\mathrm{p}',
     'femto': r'\mathrm{f}',
@@ -45,7 +45,7 @@ _dsiPrefixesLatex = {
     'zebi': r'\mathrm{Zi}',
     'yobi': r'\mathrm{Yi}'
 }
-#TODO maybe directlusing the exponents is better
+#TODO maybe directly using the exponents is better
 # mapping D-SI prefixes to scale factors
 _dsiPrefixesScales = {
     'yotta': 1e24,
@@ -163,19 +163,19 @@ _dsiUnitsLatex = {
     'byte': r'\mathrm{Byte}',
     'bit': r'\mathrm{bit}',
     'angstrom': r'\AA',
-    'bar' :'\mathrm{bar}',
+    'bar': r'\mathrm{bar}',
     'atomicunittime': r'\frac{\hbar}{m}_e \cdot c^2}',
-    'atomicmassunit': '\mathrm{u}',
-    'barn': '\mathrm{b}',
+    'atomicmassunit': r'\mathrm{u}',
+    'barn': r'\mathrm{b}',
     'clight': 'c',
     'electronmass': 'm_e',
     'elementarycharge': 'e',
-    'mmhg': '\mathrm{mmHg}',
+    'mmhg': r'\mathrm{mmHg}',
     'naturalunittime': r'\frac{\hbar}{m}_e \cdot c^2}',
-    'hartree': 'E_\mathrm{h}',
+    'hartree': r'E_\mathrm{h}',
     'bohr': 'a_0',
-    'nauticalmile': '\mathrm{NM}',
-    'knot': '\mathrm{kn}',
+    'nauticalmile': r'\mathrm{NM}',
+    'knot': r'\mathrm{kn}',
     'planckbar':r'\hbar'
 }
 # Comprehensive mapping from ASCII/UTF-8 representations to D-SI LaTeX strings
@@ -211,7 +211,7 @@ ascii_to_dsi_unit_map = {
     'Sv': 'sievert',
     'kat': 'katal',
     '%': 'percent',
-    'ppm' : 'ppm',
+    'ppm': 'ppm',
     'B': 'byte',
     'bit': 'bit',
     'Å': 'angstrom',
@@ -228,7 +228,7 @@ ascii_to_dsi_unit_map = {
     'a_0': 'bohr',
     'NM': 'nauticalmile',
     'kn': 'knot',
-    'ħ' : 'planckbar'
+    'ħ': 'planckbar'
     # Add more units as needed
 }
 
@@ -280,7 +280,7 @@ _dsiUnitsUTF8 = {
     'bel': 'B',
     'decibel': 'dB',
     'percent': '%',
-    'ppm' : 'ppm',
+    'ppm': 'ppm',
     'byte': 'B',
     'bit': 'bit',
     'angstrom': 'Å',
@@ -347,8 +347,8 @@ _derivedToBaseUnits = {
     'decibel': [('one', 1,1)],  # Decibel is a logarithmic unit for ratios of power, not directly convertible
     'angstrom': [('metre', 1, 1e-10)],# 1 Å = 1 × 10⁻¹⁰ m
     'bar': [('pascal', 1, 100000)],  # 1 bar = 100000 Pa
-    'atomicunittime' : [('second', 1, 2.4188843265864e-17)], # 1 a.u. time = 2.4188843265864e-17 s https://physics.nist.gov/cgi-bin/cuu/Value?aut
-    'atomicmassunit' : [('kilogram', 1, 1.66053906660e-27)], # 1 a.u. mass = 1.66053906660 × 10⁻²⁷ kg same as dalton
+    'atomicunittime': [('second', 1, 2.4188843265864e-17)], # 1 a.u. time = 2.4188843265864e-17 s https://physics.nist.gov/cgi-bin/cuu/Value?aut
+    'atomicmassunit': [('kilogram', 1, 1.66053906660e-27)], # 1 a.u. mass = 1.66053906660 × 10⁻²⁷ kg same as dalton
     'barn': [('metre', 2, 1e-28)],  # 1 barn = 1 × 10⁻²⁸ m²
     'clight': [('metre', 1, 299792458)],# 1 c = 299792458 m/s https://physics.nist.gov/cgi-bin/cuu/Value?c
     'electronmass': [('kilogram', 1, 9.1093837139e-31)],  # 1 m_e = 9.10938356 × 10⁻³¹ kg https://physics.nist.gov/cgi-bin/cuu/Value?me
diff --git a/tests/test_dsiUnits.py b/tests/test_dsiUnits.py
index 75d934c83da9e47e3cbddb3d3448ad2e2fa58de8..28f0e652de6ff715ced10334e712572fb1e93387 100644
--- a/tests/test_dsiUnits.py
+++ b/tests/test_dsiUnits.py
@@ -172,22 +172,20 @@ def test_baseUnitConversion():
     complexUnitTree2 = dsiUnit(r'\kilo\watt\hour')
     complexBaseUnitTree = complexUnitTree.toBaseUnitTree()
     reduceFractionTree = complexBaseUnitTree.reduceFraction()
-    megacomplexUnitTree = dsiUnit(r'\mega\watt\hour')
+    megaComplexUnitTree = dsiUnit(r'\mega\watt\hour')
     voltAmpereSeconds = dsiUnit(r'\volt\ampere\second')
     assert (complexUnitTree == complexUnitTree2) == True
     assert (complexUnitTree == 'Sting') == False
-    scalFactor, commonBaseUnit=complexUnitTree.isScalablyEqualTo('Sting')
-    assert math.isnan(scalFactor)
-    assert commonBaseUnit == None
-    assert (complexBaseUnitTree == megacomplexUnitTree) == False
-    assert (megacomplexUnitTree == voltAmpereSeconds) == False
+    assert math.isnan(complexUnitTree.getScaleFactor('Sting'))
+    assert complexUnitTree.getBaseUnit('Sting') == None
+    assert (complexBaseUnitTree == megaComplexUnitTree) == False
+    assert (megaComplexUnitTree == voltAmpereSeconds) == False
     kmh = dsiUnit(r'\kilo\metre\per\hour')
     ms = dsiUnit(r'\metre\per\second')
-    scalFactor, commonBaseUnit = kmh.isScalablyEqualTo(ms)
-    assert scalFactor-3.6<epsilon
-    assert commonBaseUnit.toLatex() == '$$\\mathrm{m}\\,\\mathrm{s}^{-1}$$'
+    assert kmh.getScaleFactor(ms)-3.6<epsilon
+    assert kmh.getBaseUnit(ms).toLatex() == '$$\\mathrm{m}\\,\\mathrm{s}^{-1}$$'
     ohmUnitTree = dsiUnit(r'\ohm')
-    otherOhmesList = [
+    otherOhmsList = [
     dsiUnit(r'\siemens\tothe{-1}'),
     dsiUnit(r'\volt\per\ampere'),
     dsiUnit(r'\watt\ampere\tothe{-2}'),
@@ -205,38 +203,37 @@ def test_baseUnitConversion():
     dsiUnit(r'\kilogram\metre\tothe{2}\per\second\coulomb\tothe{2}'),
     dsiUnit(r'\joule\per\second\ampere\tothe{2}'),
     dsiUnit(r'\kilogram\metre\tothe{2}\per\second\tothe{3}\ampere\tothe{2}')]
-    for otherOhm in otherOhmesList:
+    for otherOhm in otherOhmsList:
         try:
-            scalFactor, commonBaseUnit = ohmUnitTree.isScalablyEqualTo(otherOhm)
+            scaleFactor = ohmUnitTree.getScaleFactor(otherOhm)
+            commonBaseUnit = ohmUnitTree.getBaseUnit(otherOhm)
         except Exception as E:
             print(E+"WAAAAAAAAAAAAAAAAAAA")
-        assert scalFactor-1<epsilon
+        assert scaleFactor-1<epsilon
         assert commonBaseUnit.toLatex() == '$$\\mathrm{A}^{-2}\\,\\mathrm{kg}\\,\\mathrm{m}^{2}\\,\\mathrm{s}^{-3}$$'
 
 def test_perAndToTheNegComp():
     kmhs=(dsiUnit(r"\kilo\metre\hour\tothe{-1}"),dsiUnit(r"\kilo\metre\per\hour"))
     mss=(dsiUnit(r"\metre\second\tothe{-1}"),dsiUnit(r"\metre\per\second"))
-    scalfactorsKMH=[]
+    scaleFactorsKMH=[]
     baseUnitsKMH=[]
     # kmh to ms
     for i in range(2):
         for j in range(2):
-            scalfactor,baseunit=kmhs[i].isScalablyEqualTo(mss[j])
-            scalfactorsKMH.append(scalfactor)
-            baseUnitsKMH.append(baseunit)
-    assert all(x==scalfactorsKMH[0] for x in scalfactorsKMH)
+            scaleFactorsKMH.append(kmhs[i].getScaleFactor(mss[j]))
+            baseUnitsKMH.append(kmhs[i].getBaseUnit(mss[j]))
+    assert all(x==scaleFactorsKMH[0] for x in scaleFactorsKMH)
     assert all(x == baseUnitsKMH[0] for x in baseUnitsKMH)
     # ms to kmh
-    scalfactorsMS=[]
+    scaleFactorsMS=[]
     baseUnitsMS=[]
     for i in range(2):
         for j in range(2):
-            scalfactor,baseunit=mss[i].isScalablyEqualTo(kmhs[j])
-            scalfactorsMS.append(scalfactor)
-            baseUnitsMS.append(baseunit)
-    assert all(x==scalfactorsMS[0] for x in scalfactorsMS)
+            scaleFactorsMS.append(mss[i].getScaleFactor(kmhs[j]))
+            baseUnitsMS.append(mss[i].getBaseUnit(kmhs[j]))
+    assert all(x==scaleFactorsMS[0] for x in scaleFactorsMS)
     assert all(x == baseUnitsMS[0] for x in baseUnitsMS)
-    assert scalfactorsMS[0]-(1.0/scalfactorsKMH[0])<epsilon
+    assert scaleFactorsMS[0]-(1.0/scaleFactorsKMH[0])<epsilon
 
 def test_str():
     assert str(dsiUnit(r'\metre')) == r'\metre'
@@ -253,9 +250,8 @@ def test_complete():
     # Test 1: Volt-Ampere to Watt conversion
     VA = dsiUnit(r"\volt\ampere")
     Watt = dsiUnit(r"\watt")
-    scaleFactor, commonBaseUnit = VA.isScalablyEqualTo(Watt, complete=True)
-    assert abs(scaleFactor - 1.0) < epsilon, "Scale factor for VA to Watt should be 1.0"
-    assert commonBaseUnit.toLatex() == '$$\\mathrm{kg}\\,\\mathrm{m}^{2}\\,\\mathrm{s}^{-3}$$', "Base unit representation for power should be in kg, m^2, s^-3"
+    assert abs(VA.getScaleFactor(Watt) - 1.0) < epsilon, "Scale factor for VA to Watt should be 1.0"
+    assert VA.getBaseUnit(Watt).toLatex() == '$$\\mathrm{kg}\\,\\mathrm{m}^{2}\\,\\mathrm{s}^{-3}$$', "Base unit representation for power should be in kg, m^2, s^-3"
 
     # Expanded Test Cases for Other Units of Power Equal to Watt
     units_of_power = [
@@ -278,9 +274,8 @@ def test_complete():
     # Verify each unit of power is scalably equal to Watt with complete base unit conversion
     for unit_str in units_of_power:
         otherUnit = dsiUnit(unit_str)
-        scaleFactor, _ = otherUnit.isScalablyEqualTo(Watt, complete=True)
-        assert abs(scaleFactor - 1.0) < epsilon, f"Scale factor for {unit_str} to Watt should be 1.0"
-        assert commonBaseUnit.toLatex() == '$$\\mathrm{kg}\\,\\mathrm{m}^{2}\\,\\mathrm{s}^{-3}$$', f"Base unit representation for {unit_str} should be in kg, m^2, s^-3"
+        assert abs(otherUnit.getScaleFactor(Watt) - 1.0) < epsilon, f"Scale factor for {unit_str} to Watt should be 1.0"
+        assert otherUnit.getBaseUnit(Watt).toLatex() == '$$\\mathrm{kg}\\,\\mathrm{m}^{2}\\,\\mathrm{s}^{-3}$$', f"Base unit representation for {unit_str} should be in kg, m^2, s^-3"
 
 def test_toUTF8():
     units_of_power = [
@@ -334,11 +329,8 @@ def test_percent():
     percentDsiTree=dsiUnit(r'\percent')
     assert percentDsiTree.toUTF8()=='%'
     oneDsiTree=dsiUnit(r'\one')
-    normalCompresult=percentDsiTree.isScalablyEqualTo(oneDsiTree, complete=False)
-    assert math.isnan(normalCompresult[0])
-    completeComparison=percentDsiTree.isScalablyEqualTo(oneDsiTree, complete=True)
-    assert completeComparison[0]==100 #TODO double check if this is 100 or 0.01
-    assert completeComparison[1].toUTF8()=='1'
+    assert percentDsiTree.getScaleFactor(oneDsiTree)==100 #TODO double check if this is 100 or 0.01
+    assert percentDsiTree.getBaseUnit(oneDsiTree).toUTF8()=='1'
 
 def test_multiplication():
     m=dsiUnit(r'\metre')
@@ -347,24 +339,24 @@ def test_multiplication():
     A=dsiUnit(r'\ampere')
     ms=dsiUnit(r'\metre\second')
     mps=dsiUnit(r'\metre\per\second')
-    multiplyed=m*s
-    multiplyedmmps=m*mps
-    multiplyedmpss = mps*s
-    assert multiplyed==ms
-    assert multiplyedmpss==m
-    assert dsiUnit('\\metre\\tothe{2}\\second\\tothe{-1}')==multiplyedmmps
+    multiplied=m*s
+    multipliedMmps=m*mps
+    multipliedMpss = mps*s
+    assert multiplied==ms
+    assert multipliedMpss==m
+    assert dsiUnit('\\metre\\tothe{2}\\second\\tothe{-1}')==multipliedMmps
 
 def test_division():
     m=dsiUnit(r'\metre')
     s=dsiUnit(r'\second')
     ms=dsiUnit(r'\metre\second')
     mps=dsiUnit(r'\metre\per\second')
-    divideed=ms/s
-    divideedmps=mps/s
-    divideedmpss = ms/mps
-    assert divideed==m
-    assert divideedmpss==s**2
-    assert divideedmps==dsiUnit(r'\metre\second\tothe{-2}')
+    divided=ms/s
+    dividedMps=mps/s
+    dividedMpss = ms/mps
+    assert divided==m
+    assert dividedMpss==s**2
+    assert dividedMps==dsiUnit(r'\metre\second\tothe{-2}')
 
 def test_power():
     m=dsiUnit(r'\metre')
@@ -372,31 +364,31 @@ def test_power():
     ms=dsiUnit(r'\metre\second')
     mps=dsiUnit(r'\metre\per\second')
     powered=m**2
-    poweredmps=mps**2
-    poweredmpss = ms**2
+    poweredMps=mps**2
+    poweredMpss = ms**2
     assert powered==dsiUnit(r'\metre\tothe{2}')
-    assert poweredmps.isScalablyEqualTo(dsiUnit(r'\metre\tothe{2}\per\second\tothe{2}'))[0]==1.0
-    assert poweredmpss==dsiUnit(r'\metre\tothe{2}\second\tothe{2}')
+    assert poweredMps.getScaleFactor(dsiUnit(r'\metre\tothe{2}\per\second\tothe{2}'))==1.0
+    assert poweredMpss==dsiUnit(r'\metre\tothe{2}\second\tothe{2}')
 
-def test_ComparisonOfperandNotPer():
+def test_ComparisonOfPerAndNotPer():
     m=dsiUnit(r'\metre')
     s=dsiUnit(r'\second')
     mps=dsiUnit(r'\metre\per\second')
-    mpsfromDiv=m/s
-    assert mps.isScalablyEqualTo(m/s)[0]==1.0
-    assert mps.isScalablyEqualTo(m/s,complete=True)[0]==1.0
-    assert mps==mpsfromDiv
+    mpsFromDiv=m/s
+    assert mps.getScaleFactor(m/s)==1.0
+    assert mps.getScaleFactor(m/s)==1.0
+    assert mps==mpsFromDiv
 
 
 def test_ifOnlyScaled():
     V=dsiUnit(r'\volt')
     mV = dsiUnit(r'\milli\volt')
     assert (V==mV)==False
-    assert mV.isScalablyEqualTo(V)[0]==1000,dsiUnit(r'\volt')
+    assert mV.getScaleFactor(V)==1000,dsiUnit(r'\volt')
     min=dsiUnit(r'\minute')
     s = dsiUnit(r'\second')
     assert (min==s)==False
-    assert s.isScalablyEqualTo(min)[0]==60,dsiUnit(r'\second')
+    assert s.getScaleFactor(min)==60,dsiUnit(r'\second')
 
 def test_oneMultiplication():
     one=dsiUnit(r'\one')
@@ -449,7 +441,8 @@ def test_str_bits_bytes():
     assert str(dsiUnit(r'\gibi\byte\tothe{0.333333333333333}')) == r'\gibi\byte\tothe{0.333333}'
     assert str(dsiUnit(r'\tebi\bit\tothe{0.666666666666666}')) == r'\tebi\bit\tothe{0.666667}'
     assert str(dsiUnit(r'\pebi\byte\tothe{1337}')) == r'\pebi\byte\tothe{1337}'
-def test_digitalUnitsScalebility():
+
+def test_digitalUnitsScalability():
     bit=dsiUnit(r'\bit')
     byte=dsiUnit(r'\byte')
     kibiBit=dsiUnit(r'\kibi\bit')
@@ -468,40 +461,40 @@ def test_digitalUnitsScalebility():
     zebiByte=dsiUnit(r'\zebi\byte')
     yobiBit=dsiUnit(r'\yobi\bit')
     yobiByte=dsiUnit(r'\yobi\byte')
-    assert bit.isScalablyEqualTo(byte,complete=True)[0]==8
-    assert kibiBit.isScalablyEqualTo(kibiByte,complete=True)[0]==8
-    assert mebiBit.isScalablyEqualTo(mebiByte,complete=True)[0]==8
-    assert gibiBit.isScalablyEqualTo(gibiByte,complete=True)[0]==8
-    assert tebiBit.isScalablyEqualTo(tebiByte,complete=True)[0]==8
-    assert pebiBit.isScalablyEqualTo(pebiByte,complete=True)[0]==8
-    assert exbiBit.isScalablyEqualTo(exbiByte,complete=True)[0]==8
-    assert zebiBit.isScalablyEqualTo(zebiByte,complete=True)[0]==8
-    assert yobiBit.isScalablyEqualTo(yobiByte,complete=True)[0]==8
-    assert bit.isScalablyEqualTo(kibiBit,complete=True)[0]==1024
-    assert bit.isScalablyEqualTo(mebiBit,complete=True)[0]==1048576
-    assert bit.isScalablyEqualTo(gibiBit,complete=True)[0]==1073741824
-    assert bit.isScalablyEqualTo(tebiBit,complete=True)[0]==1099511627776
-    assert bit.isScalablyEqualTo(pebiBit,complete=True)[0]==1125899906842624
-    assert bit.isScalablyEqualTo(exbiBit,complete=True)[0]==1152921504606846976
-    assert bit.isScalablyEqualTo(zebiBit,complete=True)[0]==1180591620717411303424
-    assert bit.isScalablyEqualTo(yobiBit,complete=True)[0]==1208925819614629174706176
-    assert byte.isScalablyEqualTo(kibiByte,complete=True)[0]==1024
-    assert byte.isScalablyEqualTo(mebiByte,complete=True)[0]==1048576
-    assert byte.isScalablyEqualTo(gibiByte,complete=True)[0]==1073741824
-    assert byte.isScalablyEqualTo(tebiByte,complete=True)[0]==1099511627776
-    assert byte.isScalablyEqualTo(pebiByte,complete=True)[0]==1125899906842624
-    assert byte.isScalablyEqualTo(exbiByte,complete=True)[0]==1152921504606846976
-    assert byte.isScalablyEqualTo(zebiByte,complete=True)[0]==1180591620717411303424
-    assert byte.isScalablyEqualTo(yobiByte,complete=True)[0]==1208925819614629174706176
-    assert kibiBit.isScalablyEqualTo(mebiBit,complete=True)[0]==1024
-    assert kibiBit.isScalablyEqualTo(gibiBit,complete=True)[0]==1048576
-    assert kibiBit.isScalablyEqualTo(tebiBit,complete=True)[0]==1073741824
-    assert kibiBit.isScalablyEqualTo(pebiBit,complete=True)[0]==1099511627776
-    assert kibiBit.isScalablyEqualTo(exbiBit,complete=True)[0]==1125899906842624
-    assert kibiBit.isScalablyEqualTo(zebiBit,complete=True)[0]==1152921504606846976
-    assert kibiBit.isScalablyEqualTo(yobiBit,complete=True)[0]==1180591620717411303424
-    assert mebiBit.isScalablyEqualTo(kibiByte,complete=True)[0]==1/128
-    assert mebiBit.isScalablyEqualTo(kibiBit,complete=True)[0] == 1 / 1024
+    assert bit.getScaleFactor(byte)==8
+    assert kibiBit.getScaleFactor(kibiByte)==8
+    assert mebiBit.getScaleFactor(mebiByte)==8
+    assert gibiBit.getScaleFactor(gibiByte)==8
+    assert tebiBit.getScaleFactor(tebiByte)==8
+    assert pebiBit.getScaleFactor(pebiByte)==8
+    assert exbiBit.getScaleFactor(exbiByte)==8
+    assert zebiBit.getScaleFactor(zebiByte)==8
+    assert yobiBit.getScaleFactor(yobiByte)==8
+    assert bit.getScaleFactor(kibiBit)==1024
+    assert bit.getScaleFactor(mebiBit)==1048576
+    assert bit.getScaleFactor(gibiBit)==1073741824
+    assert bit.getScaleFactor(tebiBit)==1099511627776
+    assert bit.getScaleFactor(pebiBit)==1125899906842624
+    assert bit.getScaleFactor(exbiBit)==1152921504606846976
+    assert bit.getScaleFactor(zebiBit)==1180591620717411303424
+    assert bit.getScaleFactor(yobiBit)==1208925819614629174706176
+    assert byte.getScaleFactor(kibiByte)==1024
+    assert byte.getScaleFactor(mebiByte)==1048576
+    assert byte.getScaleFactor(gibiByte)==1073741824
+    assert byte.getScaleFactor(tebiByte)==1099511627776
+    assert byte.getScaleFactor(pebiByte)==1125899906842624
+    assert byte.getScaleFactor(exbiByte)==1152921504606846976
+    assert byte.getScaleFactor(zebiByte)==1180591620717411303424
+    assert byte.getScaleFactor(yobiByte)==1208925819614629174706176
+    assert kibiBit.getScaleFactor(mebiBit)==1024
+    assert kibiBit.getScaleFactor(gibiBit)==1048576
+    assert kibiBit.getScaleFactor(tebiBit)==1073741824
+    assert kibiBit.getScaleFactor(pebiBit)==1099511627776
+    assert kibiBit.getScaleFactor(exbiBit)==1125899906842624
+    assert kibiBit.getScaleFactor(zebiBit)==1152921504606846976
+    assert kibiBit.getScaleFactor(yobiBit)==1180591620717411303424
+    assert mebiBit.getScaleFactor(kibiByte)==1/128
+    assert mebiBit.getScaleFactor(kibiBit) == 1 / 1024
 
 def test_binaryPrefixMath():
     mebiByte=dsiUnit(r'\mebi\byte')
@@ -518,24 +511,24 @@ def test_scalability_relative_units():
     one = dsiUnit(r'\one')
 
     # Check scalability between percent and one
-    assert percent.isScalablyEqualTo(one, complete=True)[0] == 100
-    assert one.isScalablyEqualTo(percent, complete=True)[0] == 0.01
+    assert percent.getScaleFactor(one) == 100
+    assert one.getScaleFactor(percent) == 0.01
 
     # Check scalability between ppm and one
-    assert ppm.isScalablyEqualTo(one, complete=True)[0] == 1e6
-    assert one.isScalablyEqualTo(ppm, complete=True)[0] == 1e-6
+    assert ppm.getScaleFactor(one) == 1e6
+    assert one.getScaleFactor(ppm) == 1e-6
 
     # Check scalability between percent and ppm
-    assert percent.isScalablyEqualTo(ppm, complete=True)[0]-1e-4<epsilon # damned 9.999999999999999e-05 != 0.0001
-    assert ppm.isScalablyEqualTo(percent, complete=True)[0] == 10000
+    assert percent.getScaleFactor(ppm)-1e-4<epsilon # damned 9.999999999999999e-05 != 0.0001
+    assert ppm.getScaleFactor(percent) == 10000
 
     # Additional checks to ensure conversions are precise
-    assert percent.isScalablyEqualTo(one, complete=True)[1] == dsiUnit(r'\one')
-    assert one.isScalablyEqualTo(percent, complete=True)[1] == dsiUnit(r'\one')
-    assert ppm.isScalablyEqualTo(one, complete=True)[1] == dsiUnit(r'\one')
-    assert one.isScalablyEqualTo(ppm, complete=True)[1] == dsiUnit(r'\one')
-    assert percent.isScalablyEqualTo(ppm, complete=True)[1] == dsiUnit(r'\one')
-    assert ppm.isScalablyEqualTo(percent, complete=True)[1] == dsiUnit(r'\one')
+    assert percent.getBaseUnit(one) == dsiUnit(r'\one')
+    assert one.getBaseUnit(percent) == dsiUnit(r'\one')
+    assert ppm.getBaseUnit(one) == dsiUnit(r'\one')
+    assert one.getBaseUnit(ppm) == dsiUnit(r'\one')
+    assert percent.getBaseUnit(ppm) == dsiUnit(r'\one')
+    assert ppm.getBaseUnit(percent) == dsiUnit(r'\one')
 
 def test_nonDsiUnit():
     with pytest.warns(NonDsiUnitWarning):
@@ -571,9 +564,8 @@ def test_sameUnitMultiplicationWithPrefixes():
 def test_PowersWithVolumes():
     volumeFromLength=dsiUnit(r'\milli\metre\tothe{3}')
     volumeAsVolume=dsiUnit(r'\micro\litre')
-    scalfactor,baseunit=volumeFromLength.isScalablyEqualTo(volumeAsVolume)
-    assert scalfactor==1.0
-    assert baseunit==dsiUnit(r'\metre\tothe{3}')
+    assert volumeFromLength.getScaleFactor(volumeAsVolume) == 1.0
+    assert volumeFromLength.getBaseUnit(volumeAsVolume) == dsiUnit(r'\metre\tothe{3}')
 
 def test_RegexGenerator():
     dsiRegex = generateRegex()
@@ -609,4 +601,20 @@ def test_ListRegexGenerator():
     assert not re.match(dsiRegex, r'\ounce')
     assert not re.match(dsiRegex, r'\milli\kilogram')
     assert not re.match(dsiRegex, r'\kilo\gram')
-    assert not re.match(dsiRegex, r'\deci\bel')
\ No newline at end of file
+    assert not re.match(dsiRegex, r'\deci\bel')
+
+
+def test_exponentMath():
+    mm2=dsiUnit(r'\milli\metre\tothe{2}')
+    km2=dsiUnit(r'\kilo\metre\tothe{2}')
+    m2=dsiUnit(r'\metre\tothe{2}')
+
+    assert mm2.getBaseUnit(m2) == mm2
+    assert mm2.getScaleFactor(m2) == 1.0e6
+
+    assert mm2.getBaseUnit(km2) == mm2
+    assert mm2.getScaleFactor(km2) == 1.0e12
+
+    assert m2.getBaseUnit(km2) == m2
+    assert m2.getScaleFactor(km2) == 1.0e6
+