afmaths 2.0.4__tar.gz → 2.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. {afmaths-2.0.4 → afmaths-2.1.0}/PKG-INFO +19 -16
  2. afmaths-2.0.4/lib/afmaths/cs.py → afmaths-2.1.0/lib/afmaths/computer_science.py +191 -190
  3. afmaths-2.1.0/lib/afmaths/constants.py +97 -0
  4. afmaths-2.1.0/lib/afmaths/geometry/__init__.py +0 -0
  5. afmaths-2.1.0/lib/afmaths/geometry/geometry.py +382 -0
  6. afmaths-2.1.0/lib/afmaths/geometry/transformations.py +158 -0
  7. {afmaths-2.0.4 → afmaths-2.1.0}/lib/afmaths/graph.py +30 -38
  8. afmaths-2.1.0/lib/afmaths/list.py +78 -0
  9. afmaths-2.1.0/lib/afmaths/operation.py +260 -0
  10. afmaths-2.1.0/lib/afmaths/physics/__init__.py +0 -0
  11. afmaths-2.1.0/lib/afmaths/physics/ballistics.py +0 -0
  12. afmaths-2.1.0/lib/afmaths/physics/electromagnetism.py +51 -0
  13. afmaths-2.1.0/lib/afmaths/physics/kinematics.py +208 -0
  14. afmaths-2.1.0/lib/afmaths/physics/physics.py +123 -0
  15. afmaths-2.1.0/lib/afmaths/physics/space/__init__.py +0 -0
  16. afmaths-2.1.0/lib/afmaths/physics/space/astronomy/__init__.py +0 -0
  17. afmaths-2.1.0/lib/afmaths/physics/space/astronomy/coordinate_correction_functions.py +270 -0
  18. afmaths-2.1.0/lib/afmaths/physics/space/astronomy/coordinate_functions.py +292 -0
  19. afmaths-2.1.0/lib/afmaths/physics/space/astronomy/sun_functions.py +108 -0
  20. afmaths-2.1.0/lib/afmaths/physics/space/astronomy/time_functions.py +512 -0
  21. afmaths-2.1.0/lib/afmaths/physics/space/celestial_mechanics.py +1129 -0
  22. afmaths-2.1.0/lib/afmaths/physics/space/engineering/__init__.py +0 -0
  23. afmaths-2.1.0/lib/afmaths/physics/space/engineering/astrodynamics/__init__.py +0 -0
  24. afmaths-2.1.0/lib/afmaths/physics/space/engineering/astrodynamics/ground_track.py +120 -0
  25. afmaths-2.1.0/lib/afmaths/physics/space/engineering/astrodynamics/hohmann_transfer.py +115 -0
  26. afmaths-2.1.0/lib/afmaths/physics/space/engineering/astrodynamics/maneuvers.py +246 -0
  27. afmaths-2.1.0/lib/afmaths/physics/space/engineering/astrodynamics/orbital_directions.py +48 -0
  28. afmaths-2.1.0/lib/afmaths/physics/space/engineering/astrodynamics/phase_orbit.py +196 -0
  29. afmaths-2.1.0/lib/afmaths/physics/space/engineering/rocketry.py +259 -0
  30. afmaths-2.1.0/lib/afmaths/physics/space/engineering/thermal_subsystem.py +51 -0
  31. afmaths-2.1.0/lib/afmaths/physics/space/engineering/two_line_elements.py +241 -0
  32. afmaths-2.1.0/lib/afmaths/physics/space/external/__init__.py +0 -0
  33. afmaths-2.1.0/lib/afmaths/physics/space/external/horizons_api.py +382 -0
  34. afmaths-2.1.0/lib/afmaths/physics/space/external/space_track_api.py +307 -0
  35. afmaths-2.1.0/lib/afmaths/physics/space/relativity.py +21 -0
  36. afmaths-2.1.0/lib/afmaths/physics/space/sgp4/__init__.py +0 -0
  37. afmaths-2.1.0/lib/afmaths/physics/space/sgp4/sgp4.py +9 -0
  38. afmaths-2.1.0/lib/afmaths/physics/space/transformations.py +280 -0
  39. afmaths-2.1.0/lib/afmaths/physics/space/type_conversion_helpers.py +196 -0
  40. afmaths-2.1.0/lib/afmaths/physics/waves.py +12 -0
  41. afmaths-2.1.0/lib/afmaths/statistics.py +17 -0
  42. afmaths-2.1.0/lib/afmaths/tensors.py +174 -0
  43. afmaths-2.1.0/lib/afmaths/types.py +27 -0
  44. afmaths-2.1.0/lib/afmaths/visualisations/__init__.py +0 -0
  45. afmaths-2.1.0/lib/afmaths/visualisations/base.py +782 -0
  46. afmaths-2.1.0/lib/afmaths/visualisations/collision_detection.py +57 -0
  47. afmaths-2.1.0/lib/afmaths/visualisations/control_room.py +47 -0
  48. afmaths-2.1.0/lib/afmaths/visualisations/eci_orbit_3d.py +64 -0
  49. afmaths-2.1.0/lib/afmaths/visualisations/ground_track.py +285 -0
  50. afmaths-2.1.0/lib/afmaths/visualisations/helpers.py +643 -0
  51. afmaths-2.1.0/lib/afmaths/visualisations/hohmann_tradeoff.py +267 -0
  52. afmaths-2.1.0/lib/afmaths/visualisations/hohmann_transfer_perifocal_2d.py +325 -0
  53. afmaths-2.1.0/lib/afmaths/visualisations/itrs_orbit_3d.py +86 -0
  54. afmaths-2.1.0/lib/afmaths/visualisations/keplers_ellipse_2d.py +52 -0
  55. afmaths-2.1.0/lib/afmaths/visualisations/moon_earth_3d.py +44 -0
  56. afmaths-2.1.0/lib/afmaths/visualisations/newton_iteration.py +43 -0
  57. afmaths-2.1.0/lib/afmaths/visualisations/phase_orbit_2d.py +477 -0
  58. afmaths-2.1.0/lib/afmaths/visualisations/solar_system_3d.py +96 -0
  59. afmaths-2.1.0/lib/afmaths/visualisations/two_body_visualiser_2d.py +551 -0
  60. afmaths-2.1.0/lib/afmaths/visualisations/velocity_time.py +51 -0
  61. {afmaths-2.0.4 → afmaths-2.1.0}/lib/afmaths.egg-info/PKG-INFO +19 -16
  62. afmaths-2.1.0/lib/afmaths.egg-info/SOURCES.txt +83 -0
  63. {afmaths-2.0.4 → afmaths-2.1.0}/setup.py +2 -2
  64. afmaths-2.1.0/test/test_astrodynamics.py +193 -0
  65. afmaths-2.1.0/test/test_celestial_mechanics.py +258 -0
  66. afmaths-2.1.0/test/test_computer_science.py +13 -0
  67. afmaths-2.1.0/test/test_coordinate_correction_functions.py +225 -0
  68. afmaths-2.1.0/test/test_coordinate_functions.py +273 -0
  69. afmaths-2.1.0/test/test_geometry.py +59 -0
  70. afmaths-2.1.0/test/test_kinematics.py +129 -0
  71. afmaths-2.1.0/test/test_list.py +43 -0
  72. afmaths-2.1.0/test/test_operation.py +132 -0
  73. afmaths-2.1.0/test/test_rocketry.py +196 -0
  74. afmaths-2.1.0/test/test_stats.py +19 -0
  75. afmaths-2.1.0/test/test_sun_functions.py +50 -0
  76. afmaths-2.1.0/test/test_thermal_subsystem.py +22 -0
  77. afmaths-2.1.0/test/test_time_functions.py +403 -0
  78. afmaths-2.1.0/test/test_tle.py +83 -0
  79. afmaths-2.1.0/test/test_visualisation_helpers.py +85 -0
  80. afmaths-2.0.4/lib/afmaths/formula.py +0 -66
  81. afmaths-2.0.4/lib/afmaths/geometry.py +0 -210
  82. afmaths-2.0.4/lib/afmaths/list.py +0 -63
  83. afmaths-2.0.4/lib/afmaths/operation.py +0 -115
  84. afmaths-2.0.4/lib/afmaths/physics.py +0 -270
  85. afmaths-2.0.4/lib/afmaths/space_engineering.py +0 -590
  86. afmaths-2.0.4/lib/afmaths/statistics.py +0 -12
  87. afmaths-2.0.4/lib/afmaths.egg-info/SOURCES.txt +0 -17
  88. {afmaths-2.0.4 → afmaths-2.1.0}/LICENSE +0 -0
  89. {afmaths-2.0.4 → afmaths-2.1.0}/lib/afmaths/__init__.py +0 -0
  90. {afmaths-2.0.4 → afmaths-2.1.0}/lib/afmaths.egg-info/dependency_links.txt +0 -0
  91. {afmaths-2.0.4 → afmaths-2.1.0}/lib/afmaths.egg-info/requires.txt +0 -0
  92. {afmaths-2.0.4 → afmaths-2.1.0}/lib/afmaths.egg-info/top_level.txt +0 -0
  93. {afmaths-2.0.4 → afmaths-2.1.0}/setup.cfg +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: afmaths
3
- Version: 2.0.4
4
- Summary: A simple package of math functions.
3
+ Version: 2.1.0
4
+ Summary: A suite of mathematical functions
5
5
  Home-page: https://github.com/Arturius771/afmaths
6
6
  Author: Artur Foden
7
7
  Classifier: Programming Language :: Python :: 3
@@ -25,20 +25,11 @@ A simple package of math functions. Originally this was written to enable loggin
25
25
 
26
26
  # Todo
27
27
 
28
- - Add tests
29
28
  - Create output functionality, which prints (in a user friendly way) the steps required
30
- - Doc comments
31
- - Document how to build/run
32
- - Document how to upgrade the npm package
33
29
  - Document and implement semantic versioning
34
30
  - Use currying for functions
35
- - Adapt hohmann transfer style to be closer to the repo's
36
31
 
37
- ## 1. Install or Activate the Virtual Environment
38
-
39
- It's recommended to use a virtual environment for isolation. If you don't already have a virtual environment, create and activate one:
40
-
41
- ### Create and start virtual environment:
32
+ # Create and start virtual environment:
42
33
 
43
34
  ```bash
44
35
  python3 -m venv venv
@@ -48,7 +39,7 @@ python3 -m venv venv
48
39
  source venv/bin/activate
49
40
  ```
50
41
 
51
- ## 2. Install Required Dependencies
42
+ # Install Required Dependencies
52
43
 
53
44
  Ensure that setuptools and wheel are installed in your environment:
54
45
 
@@ -57,7 +48,19 @@ pip install -r requirements.txt
57
48
  pip install -e .
58
49
  ```
59
50
 
60
- ## 3. Update version number
51
+ # Run files
52
+
53
+ ```bash
54
+ python -m afmaths.space.astrodynamics
55
+ ```
56
+
57
+ # Run tests
58
+
59
+ ```bash
60
+ python -m unittest
61
+ ```
62
+
63
+ # Update version number
61
64
 
62
65
  ```bash
63
66
  setup(
@@ -67,13 +70,13 @@ setup(
67
70
  )
68
71
  ```
69
72
 
70
- ## 4. Build the dist
73
+ # Build the dist
71
74
 
72
75
  ```bash
73
76
  python setup.py sdist bdist_wheel
74
77
  ```
75
78
 
76
- ## 5. Upload with `twine`
79
+ # Upload with `twine`
77
80
 
78
81
  ```bash
79
82
  twine upload dist/*
@@ -1,190 +1,191 @@
1
- import math
2
- from geometry import pythagoras
3
- from operation import (
4
- HALF,
5
- add,
6
- divide,
7
- exponentiate,
8
- factorial,
9
- multiply,
10
- subtract,
11
- )
12
- from list import sum
13
-
14
-
15
- def file_compression_ratio(uncompressed_size: float):
16
- return lambda compressed_size: divide(compressed_size)(uncompressed_size)
17
-
18
-
19
- def compressed_file_size(uncompressed_size):
20
- return lambda compression_ratio: divide(compression_ratio)(uncompressed_size)
21
-
22
-
23
- def diagonal_pixel_length(length_in_pixels):
24
- return lambda width_in_pixels: math.floor(
25
- pythagoras(length_in_pixels)(width_in_pixels)
26
- )
27
-
28
-
29
- def travelling_salesman_problem_total_routes(number_of_cities) -> float:
30
- ##(n - 1)!/2
31
- subtract1 = subtract(1)
32
- total_routes = HALF(factorial(subtract1(number_of_cities)))
33
-
34
- return total_routes
35
-
36
-
37
- def check_drive_clusters(
38
- sectors_per_cluster, sector_size_bytes, physical_file_size_bytes
39
- ) -> tuple[int, float]:
40
- ## TM255
41
- if (
42
- physical_file_size_bytes % (multiply(sectors_per_cluster)(sector_size_bytes))
43
- == 0
44
- ):
45
- number_of_clusters = physical_file_size_bytes // multiply(sectors_per_cluster)(
46
- sector_size_bytes
47
- )
48
- else:
49
- number_of_clusters = (
50
- physical_file_size_bytes // (sectors_per_cluster * sector_size_bytes)
51
- ) + 1
52
-
53
- multiply_number_of_clusters = multiply(number_of_clusters)
54
- multiply_number_of_clusters_by_sectors_per_cluster = multiply(
55
- multiply_number_of_clusters(sectors_per_cluster)
56
- )
57
- slack_space_bytes = subtract(physical_file_size_bytes)(
58
- multiply_number_of_clusters_by_sectors_per_cluster(sector_size_bytes)
59
- )
60
-
61
- return (number_of_clusters, slack_space_bytes)
62
-
63
-
64
- def ml_f1_score(precision: float, recall: float) -> float:
65
- """F1 score: related to the harmonic mean of precision and recall. Calculated as F1 = 2/[(1/Precision) + (1/Recall)] = 2/[(TP + FP)/TP + (TP + FN)/TP] = 2/[(2TP + FP + FN)/TP] = 2TP/[2TP + FP + FN] . A high F1 score implies the system has low numbers of false positives and false negatives. - TM358"""
66
- f1 = divide(add(divide(precision)(1))(divide(recall)(1)))(2)
67
-
68
- return f1
69
-
70
-
71
- def ml_precesion(true_positives):
72
- return lambda false_positives: divide(add(true_positives)(false_positives))(
73
- true_positives
74
- )
75
-
76
-
77
- def ml_recall(true_positives):
78
- """Fraction of total positives out of both true and false positives - also known as the true positive rate."""
79
- return lambda false_negatives: divide(add(true_positives)(false_negatives))(
80
- true_positives
81
- ) # TM358
82
-
83
-
84
- def ml_false_positive_rate(false_positives):
85
- return lambda true_negatives: divide(add(false_positives)(true_negatives))(
86
- false_positives
87
- )
88
-
89
-
90
- def ml_weighted_inputs(inputs: list[float], weights: list[float]) -> list[float] | None:
91
- "Multiply the inputs by the weights - TM358 Block 1"
92
- weighted_inputs = []
93
- loop_count = 0
94
- if len(inputs) != len(weights):
95
- return None
96
- for x in inputs:
97
- weighted_inputs.append(multiply(x)(weights[inputs.index(x, loop_count)]))
98
- loop_count += 1
99
-
100
- return weighted_inputs
101
-
102
-
103
- def ml_perceptron(inputs: list[float], weights: list[float], bias: float = 0) -> float:
104
- x = ml_weighted_inputs(inputs, weights)
105
- if x == None:
106
- return 0 # TODO: this is dangerous
107
- return ml_activation_function(add(sum(x))(bias))
108
-
109
-
110
- def ml_activation_function(input: float, threshold: float = 0):
111
- if input > threshold:
112
- return 1
113
- else:
114
- return 0
115
-
116
-
117
- def byte_to_ascii_text(input: int) -> str:
118
- # https://www.rapidtables.com/convert/number/binary-to-ascii.html
119
- value = byte_to_decimal(input)
120
-
121
- return chr(value)
122
-
123
-
124
- def byte_to_decimal(input: int) -> int:
125
- """Takes an 8 bit value and returns its value in decimal form."""
126
- value = 0
127
- tracker = len(str(input)) - 1
128
-
129
- for bit in str(input):
130
- if int(bit) != 0:
131
- exponentiateByTracker = exponentiate(tracker)
132
- value += exponentiateByTracker(2)
133
- tracker -= 1
134
- return value
135
-
136
-
137
- def byte_to_hex(input: int) -> str:
138
- str_input = str(input)
139
- length = len(str_input)
140
-
141
- if length == 8:
142
- return f"{bit_to_hex(str_input[:4])}{bit_to_hex(str_input[4:])}"
143
- if length == 7:
144
- return f"{bit_to_hex(str_input[:3])}{bit_to_hex(str_input[3:])}"
145
- if length == 6:
146
- return f"{bit_to_hex(str_input[:2])}{bit_to_hex(str_input[2:])}"
147
- if length == 5:
148
- return f"{bit_to_hex(str_input[:1])}{bit_to_hex(str_input[1:])}"
149
- if length <= 4:
150
- return f"{bit_to_hex(str_input)}"
151
-
152
- return str_input
153
-
154
-
155
- def bit_to_hex(bit_string: str) -> str:
156
- bit_string = bit_string
157
- if bit_string == "0":
158
- return "0"
159
- if bit_string == "1":
160
- return "1"
161
- if bit_string == "10":
162
- return "2"
163
- if bit_string == "11":
164
- return "3"
165
- if bit_string == "100":
166
- return "4"
167
- if bit_string == "101":
168
- return "5"
169
- if bit_string == "110":
170
- return "6"
171
- if bit_string == "111":
172
- return "7"
173
- if bit_string == "1000":
174
- return "8"
175
- if bit_string == "1001":
176
- return "9"
177
- if bit_string == "1010":
178
- return "A"
179
- if bit_string == "1011":
180
- return "B"
181
- if bit_string == "1100":
182
- return "C"
183
- if bit_string == "1101":
184
- return "D"
185
- if bit_string == "1110":
186
- return "E"
187
- if bit_string == "1111":
188
- return "F"
189
-
190
- return bit_string
1
+ import math
2
+
3
+ from afmaths.geometry.geometry import pythagoras_theorem
4
+
5
+ from .operation import (
6
+ HALF,
7
+ add,
8
+ divide_by,
9
+ exponentiate,
10
+ factorial,
11
+ multiply,
12
+ subtract,
13
+ )
14
+ from .list import list_sum
15
+
16
+
17
+ def file_compression_ratio(uncompressed_size: float):
18
+ return lambda compressed_size: divide_by(compressed_size)(uncompressed_size)
19
+
20
+
21
+ def compressed_file_size(uncompressed_size):
22
+ return lambda compression_ratio: divide_by(compression_ratio)(uncompressed_size)
23
+
24
+
25
+ def diagonal_pixel_length(length_in_pixels):
26
+ return lambda width_in_pixels: math.floor(
27
+ pythagoras_theorem(length_in_pixels)(width_in_pixels)
28
+ )
29
+
30
+
31
+ def travelling_salesman_problem_total_routes(number_of_cities) -> float:
32
+ ##(n - 1)!/2
33
+ subtract1 = subtract(1)
34
+ total_routes = HALF(factorial(subtract1(number_of_cities)))
35
+
36
+ return total_routes
37
+
38
+
39
+ def check_drive_clusters(
40
+ sectors_per_cluster, sector_size_bytes, physical_file_size_bytes
41
+ ) -> tuple[int, float]:
42
+ ## TM255
43
+ if (
44
+ physical_file_size_bytes % (multiply(sectors_per_cluster)(sector_size_bytes))
45
+ == 0
46
+ ):
47
+ number_of_clusters = physical_file_size_bytes // multiply(sectors_per_cluster)(
48
+ sector_size_bytes
49
+ )
50
+ else:
51
+ number_of_clusters = (
52
+ physical_file_size_bytes // (sectors_per_cluster * sector_size_bytes)
53
+ ) + 1
54
+
55
+ multiply_number_of_clusters = multiply(number_of_clusters)
56
+ multiply_number_of_clusters_by_sectors_per_cluster = multiply(
57
+ multiply_number_of_clusters(sectors_per_cluster)
58
+ )
59
+ slack_space_bytes = subtract(physical_file_size_bytes)(
60
+ multiply_number_of_clusters_by_sectors_per_cluster(sector_size_bytes)
61
+ )
62
+
63
+ return (number_of_clusters, slack_space_bytes)
64
+
65
+
66
+ def ml_f1_score(precision: float, recall: float) -> float:
67
+ """F1 score: related to the harmonic mean of precision and recall. Calculated as F1 = 2/[(1/Precision) + (1/Recall)] = 2/[(TP + FP)/TP + (TP + FN)/TP] = 2/[(2TP + FP + FN)/TP] = 2TP/[2TP + FP + FN] . A high F1 score implies the system has low numbers of false positives and false negatives. - TM358"""
68
+ f1 = divide_by(add(divide_by(precision)(1))(divide_by(recall)(1)))(2)
69
+
70
+ return f1
71
+
72
+
73
+ def ml_precesion(true_positives):
74
+ return lambda false_positives: divide_by(add(true_positives)(false_positives))(
75
+ true_positives
76
+ )
77
+
78
+
79
+ def ml_recall(true_positives):
80
+ """Fraction of total positives out of both true and false positives - also known as the true positive rate."""
81
+ return lambda false_negatives: divide_by(add(true_positives)(false_negatives))(
82
+ true_positives
83
+ ) # TM358
84
+
85
+
86
+ def ml_false_positive_rate(false_positives):
87
+ return lambda true_negatives: divide_by(add(false_positives)(true_negatives))(
88
+ false_positives
89
+ )
90
+
91
+
92
+ def ml_weighted_inputs(inputs: list[float], weights: list[float]) -> list[float] | None:
93
+ "Multiply the inputs by the weights - TM358 Block 1"
94
+ weighted_inputs = []
95
+ loop_count = 0
96
+ if len(inputs) != len(weights):
97
+ return None
98
+ for x in inputs:
99
+ weighted_inputs.append(multiply(x)(weights[inputs.index(x, loop_count)]))
100
+ loop_count += 1
101
+
102
+ return weighted_inputs
103
+
104
+
105
+ def ml_perceptron(inputs: list[float], weights: list[float], bias: float = 0) -> float:
106
+ x = ml_weighted_inputs(inputs, weights)
107
+ if x == None:
108
+ return 0 # TODO: this is dangerous
109
+ return ml_activation_function(add(list_sum(x))(bias))
110
+
111
+
112
+ def ml_activation_function(input: float, threshold: float = 0):
113
+ if input > threshold:
114
+ return 1
115
+ else:
116
+ return 0
117
+
118
+
119
+ def ascii_text_from_byte(input: int) -> str:
120
+ # https://www.rapidtables.com/convert/number/binary-to-ascii.html
121
+
122
+ return chr(decimal_from_byte(input))
123
+
124
+
125
+ def decimal_from_byte(input: int) -> int:
126
+ """Takes an 8 bit value and returns its value in decimal form."""
127
+ value = 0
128
+ tracker = len(str(input)) - 1
129
+
130
+ for bit in str(input):
131
+ if int(bit) != 0:
132
+ exponentiateByTracker = exponentiate(tracker)
133
+ value += exponentiateByTracker(2)
134
+ tracker -= 1
135
+ return value
136
+
137
+
138
+ def hex_from_byte(input: int) -> str:
139
+ str_input = str(input)
140
+ length = len(str_input)
141
+
142
+ if length == 8:
143
+ return f"{hex_from_bit(str_input[:4])}{hex_from_bit(str_input[4:])}"
144
+ if length == 7:
145
+ return f"{hex_from_bit(str_input[:3])}{hex_from_bit(str_input[3:])}"
146
+ if length == 6:
147
+ return f"{hex_from_bit(str_input[:2])}{hex_from_bit(str_input[2:])}"
148
+ if length == 5:
149
+ return f"{hex_from_bit(str_input[:1])}{hex_from_bit(str_input[1:])}"
150
+ if length <= 4:
151
+ return f"{hex_from_bit(str_input)}"
152
+
153
+ return str_input
154
+
155
+
156
+ def hex_from_bit(bit_string: str) -> str:
157
+ bit_string = bit_string
158
+ if bit_string == "0":
159
+ return "0"
160
+ if bit_string == "1":
161
+ return "1"
162
+ if bit_string == "10":
163
+ return "2"
164
+ if bit_string == "11":
165
+ return "3"
166
+ if bit_string == "100":
167
+ return "4"
168
+ if bit_string == "101":
169
+ return "5"
170
+ if bit_string == "110":
171
+ return "6"
172
+ if bit_string == "111":
173
+ return "7"
174
+ if bit_string == "1000":
175
+ return "8"
176
+ if bit_string == "1001":
177
+ return "9"
178
+ if bit_string == "1010":
179
+ return "A"
180
+ if bit_string == "1011":
181
+ return "B"
182
+ if bit_string == "1100":
183
+ return "C"
184
+ if bit_string == "1101":
185
+ return "D"
186
+ if bit_string == "1110":
187
+ return "E"
188
+ if bit_string == "1111":
189
+ return "F"
190
+
191
+ return bit_string
@@ -0,0 +1,97 @@
1
+ import math
2
+ from typing import Generic, NewType
3
+
4
+ from astronomy_types import (
5
+ T,
6
+ Acceleration,
7
+ Anomaly,
8
+ ArgumentOfPeriapsis,
9
+ Coordinate3D,
10
+ Eccentricity,
11
+ Enum,
12
+ GravitationalParameter,
13
+ Distance,
14
+ Hour,
15
+ Inclination,
16
+ Minute,
17
+ OrbitalElements,
18
+ Radians,
19
+ Ratio,
20
+ RightAscension,
21
+ Scalar,
22
+ Second,
23
+ SemiMajorAxis,
24
+ TrueAnomaly,
25
+ Vector2D,
26
+ Vector3D,
27
+ Velocity,
28
+ )
29
+
30
+ from afmaths.operation import exponentiate, multiply, negate
31
+
32
+ EARTH_MU_KM_CUBED = GravitationalParameter(Scalar(398_600.4418)) # km^3 / s^2
33
+ EARTH_MU = GravitationalParameter(Scalar(3.986004418e14)) # m^3 / s^2
34
+ EARTH_RADIUS = Distance(Scalar(6_378_137.0)) # m
35
+ EARTH_RADIUS_KM = Distance(Scalar(6378.0)) # km
36
+ EARTH_ANGULAR_VELOCITY = Radians(
37
+ Scalar((multiply(exponentiate(negate(5))(10))(7.29115)))
38
+ )
39
+ MOON_ELEMENTS = OrbitalElements(
40
+ Inclination(Radians(Scalar(0.08956146531375098))),
41
+ RightAscension(Radians(Scalar(5.765000161307142))),
42
+ ArgumentOfPeriapsis(Radians(Scalar(1.9751206723485106))),
43
+ SemiMajorAxis(Distance(Scalar(388470793.3846703))),
44
+ Eccentricity(Ratio(Scalar(0.04483641146974054))),
45
+ TrueAnomaly(Anomaly(Radians(Scalar(4.171189773145077)))),
46
+ )
47
+ EXAMPLE_ELEMENTS = OrbitalElements(
48
+ Inclination(Radians(Scalar(math.radians(1.145)))),
49
+ RightAscension(Radians(Scalar(3.024483909022929))),
50
+ ArgumentOfPeriapsis(Radians(Scalar(1.5))),
51
+ SemiMajorAxis(Distance(Scalar(384448))),
52
+ Eccentricity(Ratio(Scalar(0.549006))),
53
+ TrueAnomaly(Anomaly(Radians(Scalar(4.1)))),
54
+ )
55
+ SATELLITE_EXAMPLE_ELEMENTS = OrbitalElements(
56
+ Inclination(Radians(Scalar(math.radians(75)))),
57
+ RightAscension(Radians(Scalar(1.2))),
58
+ ArgumentOfPeriapsis(Radians(Scalar(0.5))),
59
+ SemiMajorAxis(Distance(Scalar(368470793.3846703))),
60
+ Eccentricity(Ratio(Scalar(0.05449006))),
61
+ TrueAnomaly(Anomaly(Radians(Scalar(1)))),
62
+ )
63
+ SPEED_OF_LIGHT_METRES_PER_SECONDS = 299792458
64
+ PLANCK_CONSTANT = multiply(6.62607004)(exponentiate(negate(34))(10))
65
+ GRAVITATIONAL_CONSTANT = multiply(6.67430)(exponentiate(negate(11))(10)) # 6.67430e-11
66
+ STANDARD_GRAVITY = Acceleration(Scalar(9.80665)) # m/s
67
+ STEFAN_BOLTZMANN_CONSTANT = multiply(5.670367)(exponentiate(negate(8))(10))
68
+ UNIT_VECTOR_XY_PLANE = Vector3D[Scalar](Scalar(0), Scalar(0), Scalar(1))
69
+ ITRS_EXAMPLE_POSITION: list[Coordinate3D[Scalar]] = [
70
+ Coordinate3D(x=Scalar(6790.0), y=Scalar(0.0), z=Scalar(0.0)),
71
+ Coordinate3D(x=Scalar(0.0), y=Scalar(6790.0), z=Scalar(0.0)),
72
+ Coordinate3D(x=Scalar(-6790.0), y=Scalar(0.0), z=Scalar(0.0)),
73
+ Coordinate3D(x=Scalar(0.0), y=Scalar(-6790.0), z=Scalar(0.0)),
74
+ Coordinate3D(x=Scalar(4153.518707), y=Scalar(732.377413), z=Scalar(5321.278575)),
75
+ Coordinate3D(x=Scalar(1091.593504), y=Scalar(-4073.882417), z=Scalar(5321.278575)),
76
+ Coordinate3D(
77
+ x=Scalar(-3230.864009), y=Scalar(-2711.016798), z=Scalar(-5321.278575)
78
+ ),
79
+ Coordinate3D(x=Scalar(2982.288913), y=Scalar(2982.288913), z=Scalar(-5321.278575)),
80
+ ]
81
+ ISS_TLE_EXAMPLE = (
82
+ "1 25544U 98067A 26191.34711344 .00005681 00000-0 11131-3 0 9996"
83
+ "2 25544 51.6302 185.4700 0006688 278.6359 81.3872 15.48968037575346"
84
+ )
85
+ ISS_NORAD_ID = 25544
86
+ GALILEO_7_NORAD_ID = 40544
87
+ MOLNIYA_3_50_NORAD_ID = 25847
88
+ EUTELSAT_EUTE_117_NORAD_ID = 39122
89
+ BEIDOU_IGSO_6 = 41434
90
+ ARIANE_6_FM1_UPPER = 60235
91
+ TERRA_SAR = 31698
92
+ JAMES_WEBB = 50463
93
+ SECONDS_PER_DAY = Second(Scalar(86400))
94
+ MINUTES_PER_DAY = Minute(1440)
95
+ HOURS_PER_DAY = Hour(24)
96
+ SECONDS_PER_MINUTE = Second(Scalar(60))
97
+ SECONDS_PER_HOUR = Second(Scalar(3600))
File without changes