afmaths 2.0.3__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 (94) hide show
  1. {afmaths-2.0.3 → afmaths-2.1.0}/PKG-INFO +22 -16
  2. afmaths-2.0.3/lib/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.3/lib → 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.3 → afmaths-2.1.0/lib}/afmaths.egg-info/PKG-INFO +22 -16
  62. afmaths-2.1.0/lib/afmaths.egg-info/SOURCES.txt +83 -0
  63. afmaths-2.1.0/lib/afmaths.egg-info/requires.txt +1 -0
  64. afmaths-2.1.0/lib/afmaths.egg-info/top_level.txt +1 -0
  65. {afmaths-2.0.3 → afmaths-2.1.0}/setup.py +9 -4
  66. afmaths-2.1.0/test/test_astrodynamics.py +193 -0
  67. afmaths-2.1.0/test/test_celestial_mechanics.py +258 -0
  68. afmaths-2.1.0/test/test_computer_science.py +13 -0
  69. afmaths-2.1.0/test/test_coordinate_correction_functions.py +225 -0
  70. afmaths-2.1.0/test/test_coordinate_functions.py +273 -0
  71. afmaths-2.1.0/test/test_geometry.py +59 -0
  72. afmaths-2.1.0/test/test_kinematics.py +129 -0
  73. afmaths-2.1.0/test/test_list.py +43 -0
  74. afmaths-2.1.0/test/test_operation.py +132 -0
  75. afmaths-2.1.0/test/test_rocketry.py +196 -0
  76. afmaths-2.1.0/test/test_stats.py +19 -0
  77. afmaths-2.1.0/test/test_sun_functions.py +50 -0
  78. afmaths-2.1.0/test/test_thermal_subsystem.py +22 -0
  79. afmaths-2.1.0/test/test_time_functions.py +403 -0
  80. afmaths-2.1.0/test/test_tle.py +83 -0
  81. afmaths-2.1.0/test/test_visualisation_helpers.py +85 -0
  82. afmaths-2.0.3/afmaths.egg-info/SOURCES.txt +0 -16
  83. afmaths-2.0.3/afmaths.egg-info/top_level.txt +0 -1
  84. afmaths-2.0.3/lib/formula.py +0 -66
  85. afmaths-2.0.3/lib/geometry.py +0 -230
  86. afmaths-2.0.3/lib/list.py +0 -63
  87. afmaths-2.0.3/lib/operation.py +0 -115
  88. afmaths-2.0.3/lib/physics.py +0 -262
  89. afmaths-2.0.3/lib/space_engineering.py +0 -560
  90. afmaths-2.0.3/lib/statistics.py +0 -12
  91. {afmaths-2.0.3 → afmaths-2.1.0}/LICENSE +0 -0
  92. {afmaths-2.0.3/lib → afmaths-2.1.0/lib/afmaths}/__init__.py +0 -0
  93. {afmaths-2.0.3 → afmaths-2.1.0/lib}/afmaths.egg-info/dependency_links.txt +0 -0
  94. {afmaths-2.0.3 → afmaths-2.1.0}/setup.cfg +0 -0
@@ -1,19 +1,21 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: afmaths
3
- Version: 2.0.3
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
8
8
  Requires-Python: >=3.12
9
9
  Description-Content-Type: text/markdown
10
10
  License-File: LICENSE
11
+ Requires-Dist: astronomy_types>=2.1.0
11
12
  Dynamic: author
12
13
  Dynamic: classifier
13
14
  Dynamic: description
14
15
  Dynamic: description-content-type
15
16
  Dynamic: home-page
16
17
  Dynamic: license-file
18
+ Dynamic: requires-dist
17
19
  Dynamic: requires-python
18
20
  Dynamic: summary
19
21
 
@@ -23,20 +25,11 @@ A simple package of math functions. Originally this was written to enable loggin
23
25
 
24
26
  # Todo
25
27
 
26
- - Add tests
27
28
  - Create output functionality, which prints (in a user friendly way) the steps required
28
- - Doc comments
29
- - Document how to build/run
30
- - Document how to upgrade the npm package
31
29
  - Document and implement semantic versioning
32
30
  - Use currying for functions
33
- - Adapt hohmann transfer style to be closer to the repo's
34
31
 
35
- ## 1. Install or Activate the Virtual Environment
36
-
37
- It's recommended to use a virtual environment for isolation. If you don't already have a virtual environment, create and activate one:
38
-
39
- ### Create and start virtual environment:
32
+ # Create and start virtual environment:
40
33
 
41
34
  ```bash
42
35
  python3 -m venv venv
@@ -46,15 +39,28 @@ python3 -m venv venv
46
39
  source venv/bin/activate
47
40
  ```
48
41
 
49
- ## 2. Install Required Dependencies
42
+ # Install Required Dependencies
50
43
 
51
44
  Ensure that setuptools and wheel are installed in your environment:
52
45
 
53
46
  ```bash
54
47
  pip install -r requirements.txt
48
+ pip install -e .
49
+ ```
50
+
51
+ # Run files
52
+
53
+ ```bash
54
+ python -m afmaths.space.astrodynamics
55
+ ```
56
+
57
+ # Run tests
58
+
59
+ ```bash
60
+ python -m unittest
55
61
  ```
56
62
 
57
- ## 3. Update version number
63
+ # Update version number
58
64
 
59
65
  ```bash
60
66
  setup(
@@ -64,13 +70,13 @@ setup(
64
70
  )
65
71
  ```
66
72
 
67
- ## 4. Build the dist
73
+ # Build the dist
68
74
 
69
75
  ```bash
70
76
  python setup.py sdist bdist_wheel
71
77
  ```
72
78
 
73
- ## 5. Upload with `twine`
79
+ # Upload with `twine`
74
80
 
75
81
  ```bash
76
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