| commit | author | age | ||
| 91fb15 | 1 | from . import Exceptions |
| 5288d6 | 2 | from math import floor, log10 |
| d89217 | 3 | |
| 7b5760 | 4 | STRING = 1 |
| SP | 5 | FLOAT = 2 |
| 6 | ||
| 7 | ||
| 8 | class Variable: | |
| 7e7033 | 9 | def __init__(self, value=None, formatting=None): |
| 993a25 | 10 | self.formatted_value = None |
| 7b5760 | 11 | try: |
| SP | 12 | self.value = float(value) |
| 7e7033 | 13 | self.type = FLOAT |
| 7b5760 | 14 | except (ValueError, TypeError): |
| SP | 15 | self.type = STRING |
| 08b2a2 | 16 | self.value = value |
| SP | 17 | self.formatted_value = value |
| 7b5760 | 18 | if formatting is not None: |
| 33c054 | 19 | self.format_float(formatting) |
| 7b5760 | 20 | self.formatting = formatting |
| 08b2a2 | 21 | |
| SP | 22 | def is_float(self): |
| ce4fc9 | 23 | if self.type == FLOAT: |
| 08b2a2 | 24 | return True |
| SP | 25 | else: |
| 26 | return False | |
| 7b5760 | 27 | |
| 33c054 | 28 | def format_float(self, formatting=None): |
| 993a25 | 29 | if formatting is None: |
| SP | 30 | formatting = self.formatting |
| 31 | formatter = FormatterFactory.get_formatter(formatting) | |
| 32 | self.formatted_value = formatter.getValue(self.value) | |
| 7b5760 | 33 | |
| 04ee9d | 34 | def format_as_tex(self, formatting=None, glyph=None, unit=None): |
| 993a25 | 35 | if formatting is None: |
| SP | 36 | formatting = self.formatting |
| 04ee9d | 37 | formatter = FormatterFactory.get_formatter(formatting) |
| 5bc997 | 38 | if formatting == "str" or formatting == "string": |
| 04ee9d | 39 | return formatter.toFormat(self.value) |
| 08b2a2 | 40 | elif glyph is None and unit is None: |
| 04ee9d | 41 | return ("${}$").format(formatter.toFormat(self.value)) |
| 08b2a2 | 42 | elif glyph is None and unit is not None: |
| SP | 43 | return ("${}~\mathrm{{{}}}$").format(formatter.toFormat(self.value), unit) |
| 44 | elif glyph is not None and unit is None: | |
| 45 | return ("${}={}$").format(glyph, formatter.toFormat(self.value)) | |
| 04ee9d | 46 | else: |
| 08b2a2 | 47 | return ("${}={}~\mathrm{{{}}}$").format( |
| SP | 48 | glyph, formatter.toFormat(self.value), unit |
| 49 | ) | |
| 7b5760 | 50 | |
| 04ee9d | 51 | def format_without_dollar(self, formatting=None): |
| SP | 52 | if formatting is None: |
| 53 | formatting = self.formatting | |
| 993a25 | 54 | formatter = FormatterFactory.get_formatter(formatting) |
| SP | 55 | return formatter.toFormat(self.value) |
| 7b5760 | 56 | |
| SP | 57 | def get_formatted_value(self): |
| 993a25 | 58 | return self.formatted_value |
| 08b2a2 | 59 | # if self.type != STRING else self.value |
| 7b5760 | 60 | |
| ef19a9 | 61 | def __str__(self): |
| SP | 62 | return str(self.format_as_tex()) |
| 63 | ||
| 78d798 | 64 | def __repr__(self): |
| SP | 65 | return self.__str__() |
| 66 | ||
| 7b5760 | 67 | |
| d89217 | 68 | class FormatterFactory: |
| 404823 | 69 | @staticmethod |
| SP | 70 | def get_formatter(formatstring): |
| 71 | spl = formatstring.split() | |
| 72 | type = spl[0] | |
| 73 | arglist = spl[1:] | |
| 74 | ||
| 5bc997 | 75 | if type == "sci" or type == "scientific": |
| d89217 | 76 | return SciFloatFormatter(arglist) |
| 5bc997 | 77 | elif type == "str" or type == "string": |
| 993a25 | 78 | return StringFormatter() |
| 5bc997 | 79 | elif type == "eng" or type == "engineering": |
| 993a25 | 80 | return EngFloatFormatter(arglist) |
| 5bc997 | 81 | elif type == "prefix": |
| SP | 82 | return PrefixFloatFormatter(arglist) |
| 83 | elif type == "dec" or type == "decimal": | |
| 84 | return EngFloatFormatter(arglist) #fallback to engineering | |
| 404823 | 85 | else: |
| SP | 86 | return None |
| 5288d6 | 87 | |
| SP | 88 | @staticmethod |
| 89 | def fexp(f): | |
| 90 | return int(floor(log10(abs(f)))) if f != 0 else 0 | |
| 91 | ||
| 92 | @staticmethod | |
| 93 | def fman(f): | |
| 7b5760 | 94 | return f / 10 ** FormatterFactory.fexp(f) |
| 993a25 | 95 | |
| SP | 96 | |
| 97 | class StringFormatter(FormatterFactory): | |
| 98 | def __init__(self): | |
| 99 | pass | |
| 100 | ||
| 101 | def toFormat(self, string): | |
| 102 | return string | |
| 103 | ||
| 104 | def getValue(self, string): | |
| 105 | return string | |
| 404823 | 106 | |
| SP | 107 | |
| d89217 | 108 | class SciFloatFormatter(FormatterFactory): |
| SP | 109 | def __init__(self, formatparameters): |
| 404823 | 110 | if len(formatparameters) != 1: |
| 91fb15 | 111 | raise Exceptions.WrongParameters("Sci format accept only one argument") |
| 404823 | 112 | self.precision = int(formatparameters[0]) |
| SP | 113 | |
| 114 | def toFormat(self, num): | |
| 115 | try: | |
| 116 | num = float(num) | |
| 117 | except ValueError: | |
| 118 | raise ValueError | |
| 119 | except TypeError: | |
| 120 | raise ValueError | |
| 121 | ||
| 7b5760 | 122 | exp = self.fexp(num) |
| SP | 123 | man = self.fman(num) |
| 78d798 | 124 | if exp == 0: |
| 08b2a2 | 125 | return ( |
| SP | 126 | ("{:." + str(self.precision - 1) + "f}").format(man).replace(".", ",\!") |
| 127 | ) | |
| 78d798 | 128 | else: |
| 08b2a2 | 129 | return ( |
| SP | 130 | ("{:." + str(self.precision - 1) + "f} \cdot 10^{{{}}}") |
| 131 | .format(man, int(exp)) | |
| 132 | .replace(".", ",\!") | |
| 78d798 | 133 | ) |
| d89217 | 134 | |
| 33c054 | 135 | def getValue(self, num): |
| SP | 136 | exp = self.fexp(num) |
| 137 | man = self.fman(num) | |
| 78d798 | 138 | man = ("{:." + str(self.precision - 1) + "f}e{}").format(man, int(exp)) |
| 33c054 | 139 | return float(man) |
| d89217 | 140 | |
| 78d798 | 141 | |
| ce4fc9 | 142 | class EngFloatFormatter(FormatterFactory): |
| d89217 | 143 | def __init__(self, formatparameters): |
| SP | 144 | if len(formatparameters) != 1: |
| 145 | raise Exceptions.WrongParameters("Eng format accept only one argument") | |
| 146 | self.precision = int(formatparameters[0]) | |
| 147 | ||
| ce4fc9 | 148 | def realign3(self, exp, man): |
| SP | 149 | mul = exp % 3 |
| 150 | man = man * 10 ** mul | |
| 151 | exp = exp - mul | |
| 152 | return (exp, man) | |
| 153 | ||
| d89217 | 154 | def toFormat(self, num): |
| SP | 155 | try: |
| 156 | num = float(num) | |
| ce4fc9 | 157 | except ValueError: |
| d89217 | 158 | raise ValueError |
| ce4fc9 | 159 | except TypeError: |
| SP | 160 | raise ValueError |
| 5288d6 | 161 | |
| ce4fc9 | 162 | exp = self.fexp(num) |
| SP | 163 | man = self.fman(num) |
| 164 | (exp, man) = self.realign3(exp, man) | |
| 165 | if exp == 0: | |
| 166 | return ( | |
| 167 | ("{:." + str(self.precision - 1) + "f}").format(man).replace(".", ",\!") | |
| 168 | ) | |
| 169 | else: | |
| 170 | return ( | |
| 171 | ("{:." + str(self.precision - 1) + "f} \cdot 10^{{{}}}") | |
| 172 | .format(man, int(exp)) | |
| 173 | .replace(".", ",\!") | |
| 174 | ) | |
| 175 | ||
| 176 | def getValue(self, num): | |
| 177 | exp = self.fexp(num) | |
| 178 | man = self.fman(num) | |
| 179 | man = ("{:." + str(self.precision - 1) + "f}e{}").format(man, int(exp)) | |
| 180 | return float(man) | |
| 181 | ||
| 182 | ||
| 5bc997 | 183 | class PrefixFloatFormatter(EngFloatFormatter): |
| ce4fc9 | 184 | def __init__(self, formatparameters): |
| SP | 185 | if len(formatparameters) != 1: |
| 186 | raise Exceptions.WrongParameters("Dec format accept only one argument") | |
| 187 | self.precision = int(formatparameters[0]) | |
| 188 | ||
| 189 | def exp2prefix(self, exp): | |
| 190 | prefixes = { | |
| 191 | "24": "Y", | |
| 192 | "21": "Z", | |
| 193 | "18": "E", | |
| 194 | "15": "P", | |
| 195 | "12": "T", | |
| 196 | "9": "G", | |
| 197 | "6": "M", | |
| 198 | "3": "k", | |
| 199 | "-3": "m", | |
| 200 | "-6":"\\upmu", | |
| 201 | "-9":"n", | |
| 202 | "-12":"p", | |
| 203 | "-15":"f", | |
| 204 | "-18":"a", | |
| 205 | "-21":"z", | |
| 206 | "-24":"y" | |
| 207 | } | |
| 208 | try: | |
| 209 | prefix = prefixes[str(exp)] | |
| 210 | except KeyError: | |
| 211 | raise Exceptions.PrefixError("Could not change exponent " + str(exp) + " into prefix form!") | |
| 212 | return prefix | |
| 213 | ||
| 214 | ||
| 215 | def toFormat(self, num): | |
| 216 | try: | |
| 217 | num = float(num) | |
| 218 | except ValueError: | |
| 219 | raise ValueError | |
| 220 | except TypeError: | |
| 221 | raise ValueError | |
| 222 | ||
| 223 | exp = self.fexp(num) | |
| 224 | man = self.fman(num) | |
| 225 | (exp, man) = self.realign3(exp, man) | |
| 226 | if exp == 0: | |
| 227 | return ( | |
| 228 | ("{:." + str(self.precision - 1) + "f}").format(man).replace(".", ",\!") | |
| 229 | ) | |
| 230 | else: | |
| 231 | prefix = self.exp2prefix(exp) | |
| 232 | return ( | |
| 233 | ("{:." + str(self.precision - 1) + "f}~\mathrm{{{}}}") | |
| 234 | .format(man, prefix) | |
| 235 | .replace(".", ",\!") | |
| 236 | ) | |