from . import Exceptions
|
from math import floor, log10
|
|
STRING = 1
|
FLOAT = 2
|
|
|
class Variable:
|
def __init__(self, value=None, formatting=None):
|
self.formatted_value = None
|
try:
|
self.value = float(value)
|
self.type = FLOAT
|
except (ValueError, TypeError):
|
self.type = STRING
|
self.value = value
|
self.formatted_value = value
|
if formatting is not None:
|
self.format_float(formatting)
|
self.formatting = formatting
|
|
def is_float(self):
|
if self.type == FLOAT:
|
return True
|
else:
|
return False
|
|
def format_float(self, formatting=None):
|
if formatting is None:
|
formatting = self.formatting
|
formatter = FormatterFactory.get_formatter(formatting)
|
self.formatted_value = formatter.getValue(self.value)
|
|
def format_as_tex(self, formatting=None, glyph=None, unit=None, dollar="$"):
|
if formatting is None:
|
formatting = self.formatting
|
formatter = FormatterFactory.get_formatter(formatting)
|
if formatting.split()[0] == "prefix":
|
leading_space = ""
|
else:
|
leading_space = "\,"
|
if formatting == "str" or formatting == "string":
|
return formatter.toFormat(self.value)
|
elif glyph is None and unit is None:
|
return ("{}{}{}{}").format(
|
dollar, formatter.toFormat(self.value), leading_space, dollar
|
)
|
elif glyph is None and unit is not None:
|
return ("{}{}{}\mathrm{{{}}}{}{}").format(
|
dollar, formatter.toFormat(self.value), leading_space, unit, dollar
|
)
|
elif glyph is not None and unit is None:
|
return ("{}{}={}{}{}").format(
|
dollar, glyph, formatter.toFormat(self.value), leading_space, dollar
|
)
|
else:
|
return ("{}{}={}{}\mathrm{{{}}}{}").format(
|
dollar,
|
glyph,
|
formatter.toFormat(self.value),
|
leading_space,
|
unit,
|
dollar,
|
)
|
|
def get_formatted_value(self):
|
return self.formatted_value
|
# if self.type != STRING else self.value
|
|
def __str__(self):
|
return str(self.format_as_tex())
|
|
def __repr__(self):
|
return self.__str__()
|
|
|
class FormatterFactory:
|
@staticmethod
|
def get_formatter(formatstring):
|
spl = formatstring.split()
|
type = spl[0]
|
arglist = spl[1:]
|
|
if type == "sci" or type == "scientific":
|
return SciFloatFormatter(arglist)
|
elif type == "str" or type == "string":
|
return StringFormatter()
|
elif type == "eng" or type == "engineering":
|
return EngFloatFormatter(arglist)
|
elif type == "prefix":
|
return PrefixFloatFormatter(arglist)
|
elif type == "dec" or type == "decimal":
|
return DecFloatFormatter(arglist)
|
else:
|
return None
|
|
@staticmethod
|
def fexp(f):
|
return int(floor(log10(abs(f)))) if f != 0 else 0
|
|
@staticmethod
|
def fman(f):
|
return f / 10 ** FormatterFactory.fexp(f)
|
|
|
class StringFormatter(FormatterFactory):
|
def __init__(self):
|
pass
|
|
def toFormat(self, string):
|
return string
|
|
def getValue(self, string):
|
return string
|
|
class DecFloatFormatter(FormatterFactory):
|
def __init__(self, formatparameters):
|
if len(formatparameters) != 1:
|
raise Exceptions.WrongParameters("Dec format accept only one argument")
|
self.precision = int(formatparameters[0])
|
|
def toFormat(self, num):
|
try:
|
num = float(num)
|
except ValueError:
|
raise ValueError
|
except TypeError:
|
raise ValueError
|
|
num=float(("{:."+str(self.precision-1)+"e}").format(num))
|
places=self.fexp(num)
|
|
if(places>0):
|
decimal_places=self.precision-places-1
|
if(decimal_places<0):
|
decimal_places=0
|
format_str="{:"+str(places)+"."+str(decimal_places)+"f}"
|
else:
|
format_str="{:."+str(self.precision)+"f}"
|
|
return (
|
|
format_str.format(num).replace(".", ",\!")
|
)
|
|
def getValue(self, num):
|
|
|
num=float(("{:."+str(self.precision-1)+"e}").format(num))
|
places=self.fexp(num)
|
|
if(places>0):
|
decimal_places=self.precision-places-1
|
if(decimal_places<0):
|
decimal_places=0
|
format_str="{:"+str(places)+"."+str(decimal_places)+"f}"
|
else:
|
format_str="{:."+str(self.precision)+"f}"
|
val=format_str.format(num)
|
return float(val)
|
|
|
|
class SciFloatFormatter(FormatterFactory):
|
def __init__(self, formatparameters):
|
if len(formatparameters) != 1:
|
raise Exceptions.WrongParameters("Sci format accept only one argument")
|
self.precision = int(formatparameters[0])
|
|
def toFormat(self, num):
|
try:
|
num = float(num)
|
except ValueError:
|
raise ValueError
|
except TypeError:
|
raise ValueError
|
|
exp = self.fexp(num)
|
man = self.fman(num)
|
if exp == 0:
|
return (
|
("{:." + str(self.precision - 1) + "f}").format(man).replace(".", ",\!")
|
)
|
else:
|
return (
|
("{:." + str(self.precision - 1) + "f} \cdot 10^{{{}}}")
|
.format(man, int(exp))
|
.replace(".", ",\!")
|
)
|
|
def getValue(self, num):
|
exp = self.fexp(num)
|
man = self.fman(num)
|
man = ("{:." + str(self.precision - 1) + "f}e{}").format(man, int(exp))
|
return float(man)
|
|
|
class EngFloatFormatter(FormatterFactory):
|
def __init__(self, formatparameters):
|
if len(formatparameters) != 1:
|
raise Exceptions.WrongParameters("Eng format accept only one argument")
|
self.precision = int(formatparameters[0])
|
|
def realign3(self, exp, man):
|
mul = exp % 3
|
man = man * 10 ** mul
|
exp = exp - mul
|
return (exp, man)
|
|
def toFormat(self, num):
|
try:
|
num = float(num)
|
except ValueError:
|
raise ValueError
|
except TypeError:
|
raise ValueError
|
|
exp = self.fexp(num)
|
man = self.fman(num)
|
(exp, man) = self.realign3(exp, man)
|
if exp == 0:
|
return (
|
("{:." + str(self.precision - 1) + "f}").format(man).replace(".", ",\!")
|
)
|
else:
|
return (
|
("{:." + str(self.precision - 1) + "f} \cdot 10^{{{}}}")
|
.format(man, int(exp))
|
.replace(".", ",\!")
|
)
|
|
def getValue(self, num):
|
exp = self.fexp(num)
|
man = self.fman(num)
|
man = ("{:." + str(self.precision - 1) + "f}e{}").format(man, int(exp))
|
return float(man)
|
|
|
class PrefixFloatFormatter(EngFloatFormatter):
|
def __init__(self, formatparameters):
|
if len(formatparameters) != 1:
|
raise Exceptions.WrongParameters("Dec format accept only one argument")
|
self.precision = int(formatparameters[0])
|
|
def exp2prefix(self, exp):
|
prefixes = {
|
"24": "Y",
|
"21": "Z",
|
"18": "E",
|
"15": "P",
|
"12": "T",
|
"9": "G",
|
"6": "M",
|
"3": "k",
|
"-3": "m",
|
"-6": "\\upmu",
|
"-9": "n",
|
"-12": "p",
|
"-15": "f",
|
"-18": "a",
|
"-21": "z",
|
"-24": "y",
|
}
|
try:
|
prefix = prefixes[str(exp)]
|
except KeyError:
|
raise Exceptions.PrefixError(
|
"Could not change exponent " + str(exp) + " into prefix form!"
|
)
|
return prefix
|
|
def toFormat(self, num):
|
try:
|
num = float(num)
|
except ValueError:
|
raise ValueError
|
except TypeError:
|
raise ValueError
|
|
exp = self.fexp(num)
|
man = self.fman(num)
|
(exp, man) = self.realign3(exp, man)
|
if exp == 0:
|
return (
|
("{:." + str(self.precision - 1) + "f}\,").format(man).replace(".", ",\!")
|
)
|
else:
|
prefix = self.exp2prefix(exp)
|
return (
|
("{:." + str(self.precision - 1) + "f}\,\mathrm{{{}}}")
|
.format(man, prefix)
|
.replace(".", ",\!")
|
)
|