| 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 | |
| da1010 | 34 | def format_as_tex(self, formatting=None, glyph=None, unit=None, dollar="$"): |
| 993a25 | 35 | if formatting is None: |
| SP | 36 | formatting = self.formatting |
| 04ee9d | 37 | formatter = FormatterFactory.get_formatter(formatting) |
| da1010 | 38 | if formatting.split()[0] == "prefix": |
| SP | 39 | leading_space = "" |
| 40 | else: | |
| 39922f | 41 | leading_space = "\," |
| 5bc997 | 42 | if formatting == "str" or formatting == "string": |
| 04ee9d | 43 | return formatter.toFormat(self.value) |
| 08b2a2 | 44 | elif glyph is None and unit is None: |
| da1010 | 45 | return ("{}{}{}{}").format( |
| SP | 46 | dollar, formatter.toFormat(self.value), leading_space, dollar |
| 08b2a2 | 47 | ) |
| da1010 | 48 | elif glyph is None and unit is not None: |
| SP | 49 | return ("{}{}{}\mathrm{{{}}}{}{}").format( |
| 50 | dollar, formatter.toFormat(self.value), leading_space, unit, dollar | |
| 51 | ) | |
| 52 | elif glyph is not None and unit is None: | |
| 53 | return ("{}{}={}{}{}").format( | |
| 54 | dollar, glyph, formatter.toFormat(self.value), leading_space, dollar | |
| 55 | ) | |
| 56 | else: | |
| 57 | return ("{}{}={}{}\mathrm{{{}}}{}").format( | |
| 58 | dollar, | |
| 59 | glyph, | |
| 60 | formatter.toFormat(self.value), | |
| 61 | leading_space, | |
| 62 | unit, | |
| 63 | dollar, | |
| 64 | ) | |
| 7b5760 | 65 | |
| SP | 66 | def get_formatted_value(self): |
| 993a25 | 67 | return self.formatted_value |
| 08b2a2 | 68 | # if self.type != STRING else self.value |
| 7b5760 | 69 | |
| ef19a9 | 70 | def __str__(self): |
| SP | 71 | return str(self.format_as_tex()) |
| 72 | ||
| 78d798 | 73 | def __repr__(self): |
| SP | 74 | return self.__str__() |
| 75 | ||
| 7b5760 | 76 | |
| d89217 | 77 | class FormatterFactory: |
| 404823 | 78 | @staticmethod |
| SP | 79 | def get_formatter(formatstring): |
| 80 | spl = formatstring.split() | |
| 81 | type = spl[0] | |
| 82 | arglist = spl[1:] | |
| 83 | ||
| 5bc997 | 84 | if type == "sci" or type == "scientific": |
| d89217 | 85 | return SciFloatFormatter(arglist) |
| 5bc997 | 86 | elif type == "str" or type == "string": |
| 993a25 | 87 | return StringFormatter() |
| 5bc997 | 88 | elif type == "eng" or type == "engineering": |
| 993a25 | 89 | return EngFloatFormatter(arglist) |
| 5bc997 | 90 | elif type == "prefix": |
| SP | 91 | return PrefixFloatFormatter(arglist) |
| 92 | elif type == "dec" or type == "decimal": | |
| 839d16 | 93 | return DecFloatFormatter(arglist) |
| 404823 | 94 | else: |
| SP | 95 | return None |
| 5288d6 | 96 | |
| SP | 97 | @staticmethod |
| 98 | def fexp(f): | |
| 99 | return int(floor(log10(abs(f)))) if f != 0 else 0 | |
| 100 | ||
| 101 | @staticmethod | |
| 102 | def fman(f): | |
| 7b5760 | 103 | return f / 10 ** FormatterFactory.fexp(f) |
| 993a25 | 104 | |
| SP | 105 | |
| 106 | class StringFormatter(FormatterFactory): | |
| 107 | def __init__(self): | |
| 108 | pass | |
| 109 | ||
| 110 | def toFormat(self, string): | |
| 111 | return string | |
| 112 | ||
| 113 | def getValue(self, string): | |
| 114 | return string | |
| 404823 | 115 | |
| 839d16 | 116 | class DecFloatFormatter(FormatterFactory): |
| SP | 117 | def __init__(self, formatparameters): |
| 118 | if len(formatparameters) != 1: | |
| 119 | raise Exceptions.WrongParameters("Dec format accept only one argument") | |
| 120 | self.precision = int(formatparameters[0]) | |
| 121 | ||
| 122 | def toFormat(self, num): | |
| 123 | try: | |
| 124 | num = float(num) | |
| 125 | except ValueError: | |
| 126 | raise ValueError | |
| 127 | except TypeError: | |
| 128 | raise ValueError | |
| 129 | ||
| 34c8f6 | 130 | num=float(("{:."+str(self.precision-1)+"e}").format(num)) |
| SP | 131 | places=self.fexp(num) |
| 132 | ||
| 133 | if(places>0): | |
| 134 | decimal_places=self.precision-places-1 | |
| 135 | if(decimal_places<0): | |
| 136 | decimal_places=0 | |
| 137 | format_str="{:"+str(places)+"."+str(decimal_places)+"f}" | |
| 138 | else: | |
| 139 | format_str="{:."+str(self.precision)+"f}" | |
| 839d16 | 140 | |
| SP | 141 | return ( |
| 34c8f6 | 142 | |
| SP | 143 | format_str.format(num).replace(".", ",\!") |
| 839d16 | 144 | ) |
| SP | 145 | |
| 146 | def getValue(self, num): | |
| 34c8f6 | 147 | |
| SP | 148 | |
| 149 | num=float(("{:."+str(self.precision-1)+"e}").format(num)) | |
| 150 | places=self.fexp(num) | |
| 151 | ||
| 152 | if(places>0): | |
| 153 | decimal_places=self.precision-places-1 | |
| 154 | if(decimal_places<0): | |
| 155 | decimal_places=0 | |
| 156 | format_str="{:"+str(places)+"."+str(decimal_places)+"f}" | |
| 157 | else: | |
| 158 | format_str="{:."+str(self.precision)+"f}" | |
| 159 | val=format_str.format(num) | |
| 839d16 | 160 | return float(val) |
| SP | 161 | |
| 162 | ||
| 404823 | 163 | |
| d89217 | 164 | class SciFloatFormatter(FormatterFactory): |
| SP | 165 | def __init__(self, formatparameters): |
| 404823 | 166 | if len(formatparameters) != 1: |
| 91fb15 | 167 | raise Exceptions.WrongParameters("Sci format accept only one argument") |
| 404823 | 168 | self.precision = int(formatparameters[0]) |
| SP | 169 | |
| 170 | def toFormat(self, num): | |
| 171 | try: | |
| 172 | num = float(num) | |
| 173 | except ValueError: | |
| 174 | raise ValueError | |
| 175 | except TypeError: | |
| 176 | raise ValueError | |
| 177 | ||
| 7b5760 | 178 | exp = self.fexp(num) |
| SP | 179 | man = self.fman(num) |
| 78d798 | 180 | if exp == 0: |
| 08b2a2 | 181 | return ( |
| SP | 182 | ("{:." + str(self.precision - 1) + "f}").format(man).replace(".", ",\!") |
| 183 | ) | |
| 78d798 | 184 | else: |
| 08b2a2 | 185 | return ( |
| SP | 186 | ("{:." + str(self.precision - 1) + "f} \cdot 10^{{{}}}") |
| 187 | .format(man, int(exp)) | |
| 188 | .replace(".", ",\!") | |
| 78d798 | 189 | ) |
| d89217 | 190 | |
| 33c054 | 191 | def getValue(self, num): |
| SP | 192 | exp = self.fexp(num) |
| 193 | man = self.fman(num) | |
| 78d798 | 194 | man = ("{:." + str(self.precision - 1) + "f}e{}").format(man, int(exp)) |
| 33c054 | 195 | return float(man) |
| d89217 | 196 | |
| 78d798 | 197 | |
| ce4fc9 | 198 | class EngFloatFormatter(FormatterFactory): |
| d89217 | 199 | def __init__(self, formatparameters): |
| SP | 200 | if len(formatparameters) != 1: |
| 201 | raise Exceptions.WrongParameters("Eng format accept only one argument") | |
| 202 | self.precision = int(formatparameters[0]) | |
| 203 | ||
| ce4fc9 | 204 | def realign3(self, exp, man): |
| SP | 205 | mul = exp % 3 |
| 206 | man = man * 10 ** mul | |
| 207 | exp = exp - mul | |
| 208 | return (exp, man) | |
| 209 | ||
| d89217 | 210 | def toFormat(self, num): |
| SP | 211 | try: |
| 212 | num = float(num) | |
| ce4fc9 | 213 | except ValueError: |
| d89217 | 214 | raise ValueError |
| ce4fc9 | 215 | except TypeError: |
| SP | 216 | raise ValueError |
| 5288d6 | 217 | |
| ce4fc9 | 218 | exp = self.fexp(num) |
| SP | 219 | man = self.fman(num) |
| 220 | (exp, man) = self.realign3(exp, man) | |
| 221 | if exp == 0: | |
| 222 | return ( | |
| 223 | ("{:." + str(self.precision - 1) + "f}").format(man).replace(".", ",\!") | |
| 224 | ) | |
| 225 | else: | |
| 226 | return ( | |
| 227 | ("{:." + str(self.precision - 1) + "f} \cdot 10^{{{}}}") | |
| 228 | .format(man, int(exp)) | |
| 229 | .replace(".", ",\!") | |
| 230 | ) | |
| 231 | ||
| 232 | def getValue(self, num): | |
| 233 | exp = self.fexp(num) | |
| 234 | man = self.fman(num) | |
| 235 | man = ("{:." + str(self.precision - 1) + "f}e{}").format(man, int(exp)) | |
| 236 | return float(man) | |
| 237 | ||
| 238 | ||
| 5bc997 | 239 | class PrefixFloatFormatter(EngFloatFormatter): |
| ce4fc9 | 240 | def __init__(self, formatparameters): |
| SP | 241 | if len(formatparameters) != 1: |
| 242 | raise Exceptions.WrongParameters("Dec format accept only one argument") | |
| 243 | self.precision = int(formatparameters[0]) | |
| 244 | ||
| 245 | def exp2prefix(self, exp): | |
| 246 | prefixes = { | |
| 247 | "24": "Y", | |
| 248 | "21": "Z", | |
| 249 | "18": "E", | |
| 250 | "15": "P", | |
| 251 | "12": "T", | |
| 252 | "9": "G", | |
| 253 | "6": "M", | |
| 254 | "3": "k", | |
| 255 | "-3": "m", | |
| da1010 | 256 | "-6": "\\upmu", |
| SP | 257 | "-9": "n", |
| 258 | "-12": "p", | |
| 259 | "-15": "f", | |
| 260 | "-18": "a", | |
| 261 | "-21": "z", | |
| 262 | "-24": "y", | |
| ce4fc9 | 263 | } |
| SP | 264 | try: |
| 265 | prefix = prefixes[str(exp)] | |
| 266 | except KeyError: | |
| da1010 | 267 | raise Exceptions.PrefixError( |
| SP | 268 | "Could not change exponent " + str(exp) + " into prefix form!" |
| 269 | ) | |
| ce4fc9 | 270 | return prefix |
| SP | 271 | |
| 272 | def toFormat(self, num): | |
| 273 | try: | |
| 274 | num = float(num) | |
| 275 | except ValueError: | |
| 276 | raise ValueError | |
| 277 | except TypeError: | |
| 278 | raise ValueError | |
| 279 | ||
| 280 | exp = self.fexp(num) | |
| 281 | man = self.fman(num) | |
| 282 | (exp, man) = self.realign3(exp, man) | |
| 283 | if exp == 0: | |
| 284 | return ( | |
| 39922f | 285 | ("{:." + str(self.precision - 1) + "f}\,").format(man).replace(".", ",\!") |
| ce4fc9 | 286 | ) |
| SP | 287 | else: |
| 288 | prefix = self.exp2prefix(exp) | |
| 289 | return ( | |
| 39922f | 290 | ("{:." + str(self.precision - 1) + "f}\,\mathrm{{{}}}") |
| ce4fc9 | 291 | .format(man, prefix) |
| SP | 292 | .replace(".", ",\!") |
| 293 | ) | |