Coverage for app/utility/numbers.py: 100%

29 statements  

« prev     ^ index     » next       coverage.py v7.10.5, created at 2025-08-28 09:13 +0000

1import math 

2import numpy as np 

3 

4 

5def get_power_html( 

6 value: float | list[float], 

7 n: None | int = 3, 

8) -> str | list[str]: 

9 """Converts a value to html-formatted text with base 10 

10 :param value: positive value 

11 :param n: number of decimals. None to keep only the exponent bit. -1 to display all significant digits.""" 

12 

13 if isinstance(value, list): 

14 return [get_power_html(val, n) for val in value] 

15 

16 if value == 0: 

17 return "0" 

18 

19 base10 = math.floor(np.log10(abs(value))) 

20 mantissa = value / 10**base10 

21 

22 if n is None: 

23 mantissa_str = "" 

24 

25 # Dynamic number of digits 

26 elif n == -1: 

27 mantissa_str = f"{mantissa:g}" 

28 

29 # Fixed number of digits 

30 else: 

31 mantissa_str = f"{mantissa:.{n}f}" 

32 

33 if base10 == 0: 

34 return mantissa_str 

35 else: 

36 return (mantissa_str + f" &#10005; 10<sup>{base10}</sup>").strip() 

37 

38 

39def to_scientific(value: float | int | list[float | int] | None) -> str: 

40 """Convert a number to scientific notation without trailing zeros 

41 

42 Examples 

43 -------- 

44 >>> to_scientific(1.4e-4) 

45 '1.4E-04' 

46 >>> to_scientific(None) 

47 '' 

48 >>> to_scientific([1e-4, 1e-5]) 

49 '1E-04, 1E-05'""" 

50 

51 if value is None: 

52 return "" 

53 if value == 0: 

54 return "0" 

55 elif isinstance(value, (float, int, np.integer)): 

56 string = "%E" % value 

57 mantissa, exponent = string.split("E") 

58 return (mantissa[0] + mantissa[1:].strip("0")).strip(".") + "E" + exponent 

59 else: 

60 return ", ".join([to_scientific(f) for f in value]) 

61 

62 

63def get_concentrations_html(N0s: list[float]) -> list[str]: 

64 """Get the carrier concentration labels in html format 

65 :param N0s: initial carrier concentrations""" 

66 

67 return ["N<sub>0</sub> = " + get_power_html(N0, -1) + " cm<sup>-3</sup>" for N0 in N0s]