math-spec-mapping 0.3.5__py3-none-any.whl → 0.3.7__py3-none-any.whl
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.
- math_spec_mapping/Classes/Block.py +5 -0
- math_spec_mapping/Classes/MathSpec.py +151 -4
- math_spec_mapping/Classes/StatefulMetric.py +1 -0
- math_spec_mapping/Load/stateful_metrics.py +9 -0
- math_spec_mapping/Reports/markdown.py +1 -1
- {math_spec_mapping-0.3.5.dist-info → math_spec_mapping-0.3.7.dist-info}/METADATA +4 -3
- {math_spec_mapping-0.3.5.dist-info → math_spec_mapping-0.3.7.dist-info}/RECORD +10 -10
- {math_spec_mapping-0.3.5.dist-info → math_spec_mapping-0.3.7.dist-info}/WHEEL +1 -1
- {math_spec_mapping-0.3.5.dist-info → math_spec_mapping-0.3.7.dist-info}/LICENSE +0 -0
- {math_spec_mapping-0.3.5.dist-info → math_spec_mapping-0.3.7.dist-info}/top_level.txt +0 -0
@@ -37,6 +37,7 @@ class Block:
|
|
37
37
|
)
|
38
38
|
]
|
39
39
|
)
|
40
|
+
self.domain_blocks2 = self.domain_blocks[:]
|
40
41
|
self.codomain_blocks = tuple(
|
41
42
|
[
|
42
43
|
self
|
@@ -191,6 +192,9 @@ class ParallelBlock(Block):
|
|
191
192
|
self.domain_blocks = tuple(
|
192
193
|
[i for x in self.components for i in x.domain_blocks]
|
193
194
|
)
|
195
|
+
self.domain_blocks2 = tuple(
|
196
|
+
[x for x in self.components for i in x.domain_blocks2]
|
197
|
+
)
|
194
198
|
self.codomain_blocks = tuple(
|
195
199
|
[i for x in self.components for i in x.codomain_blocks]
|
196
200
|
)
|
@@ -320,6 +324,7 @@ class StackBlock(Block):
|
|
320
324
|
)
|
321
325
|
|
322
326
|
self.domain_blocks = self.components[0].domain_blocks
|
327
|
+
self.domain_blocks2 = self.components[0].domain_blocks2
|
323
328
|
self.codomain_blocks = self.components[-1].codomain_blocks
|
324
329
|
self.domain_blocks_empty = self.components[0].domain_blocks_empty
|
325
330
|
self.codomain_blocks_empty = self.components[-1].codomain_blocks_empty
|
@@ -7,6 +7,7 @@ from .BoundaryAction import BoundaryAction
|
|
7
7
|
import os
|
8
8
|
from copy import deepcopy
|
9
9
|
import shutil
|
10
|
+
import pandas as pd
|
10
11
|
|
11
12
|
|
12
13
|
class MathSpec:
|
@@ -45,6 +46,7 @@ class MathSpec:
|
|
45
46
|
self._check_dictionary_names()
|
46
47
|
self._build_functional_parameters()
|
47
48
|
self._build_parameter_types()
|
49
|
+
self._crawl_spaces()
|
48
50
|
|
49
51
|
def _check_dictionary_names(self):
|
50
52
|
for key in self.boundary_actions:
|
@@ -406,6 +408,18 @@ class MathSpec:
|
|
406
408
|
self.behavioral_parameters_types = behavioral_parameters_types
|
407
409
|
self.functional_parameters_types = functional_parameters_types
|
408
410
|
|
411
|
+
def _crawl_spaces(self):
|
412
|
+
self._used_spaces = []
|
413
|
+
self._used_spaces.extend([x.codomain for x in self.control_actions.values()])
|
414
|
+
self._used_spaces.extend([x.codomain for x in self.boundary_actions.values()])
|
415
|
+
self._used_spaces.extend([x.domain for x in self.policies.values()])
|
416
|
+
self._used_spaces.extend([x.codomain for x in self.policies.values()])
|
417
|
+
self._used_spaces.extend([x.domain for x in self.mechanisms.values()])
|
418
|
+
|
419
|
+
self._used_spaces = list(set().union(*self._used_spaces))
|
420
|
+
us_names = [y.name for y in self._used_spaces]
|
421
|
+
self._unused_spaces = [self.spaces[x] for x in self.spaces if x not in us_names]
|
422
|
+
|
409
423
|
def metaprogramming_python_types(self, model_directory, overwrite=False):
|
410
424
|
path = model_directory + "/types.py"
|
411
425
|
if not overwrite:
|
@@ -456,6 +470,75 @@ class MathSpec:
|
|
456
470
|
with open(path, "w") as f:
|
457
471
|
f.write(out)
|
458
472
|
|
473
|
+
def run_experiment(
|
474
|
+
self,
|
475
|
+
experiment,
|
476
|
+
params_base,
|
477
|
+
state_base,
|
478
|
+
post_processing_function,
|
479
|
+
state_preperation_functions=None,
|
480
|
+
metrics_functions=None,
|
481
|
+
):
|
482
|
+
if experiment["Param Modifications"]:
|
483
|
+
params_base = deepcopy(params_base)
|
484
|
+
for key in experiment["Param Modifications"]:
|
485
|
+
params_base[key] = experiment["Param Modifications"][key]
|
486
|
+
msi = self.build_implementation(params_base)
|
487
|
+
state, params = msi.prepare_state_and_params(
|
488
|
+
state_base,
|
489
|
+
params_base,
|
490
|
+
state_preperation_functions=state_preperation_functions,
|
491
|
+
)
|
492
|
+
|
493
|
+
state = msi.execute_blocks(state, params, experiment["Blocks"])
|
494
|
+
df = post_processing_function(state, params)
|
495
|
+
|
496
|
+
if metrics_functions:
|
497
|
+
metrics = {}
|
498
|
+
for metrics_function in metrics_functions:
|
499
|
+
metrics_function(metrics, state, params, df)
|
500
|
+
metrics = pd.Series(metrics)
|
501
|
+
else:
|
502
|
+
metrics = None
|
503
|
+
|
504
|
+
return state, params, msi, df, metrics
|
505
|
+
|
506
|
+
def run_experiments(
|
507
|
+
self,
|
508
|
+
experiments,
|
509
|
+
params_base,
|
510
|
+
state_base,
|
511
|
+
post_processing_function,
|
512
|
+
state_preperation_functions=None,
|
513
|
+
metrics_functions=None,
|
514
|
+
):
|
515
|
+
state_l = []
|
516
|
+
params_l = []
|
517
|
+
df_l = []
|
518
|
+
metrics_l = []
|
519
|
+
for experiment in experiments:
|
520
|
+
for i in range(experiment["Monte Carlo Runs"]):
|
521
|
+
state, params, msi, df, metrics = self.run_experiment(
|
522
|
+
experiment,
|
523
|
+
params_base,
|
524
|
+
state_base,
|
525
|
+
post_processing_function,
|
526
|
+
state_preperation_functions=state_preperation_functions,
|
527
|
+
metrics_functions=metrics_functions,
|
528
|
+
)
|
529
|
+
df["Monte Carlo Run"] = i + 1
|
530
|
+
df["Experiment"] = experiment["Name"]
|
531
|
+
metrics.loc["Monte Carlo Run"] = i + 1
|
532
|
+
metrics.loc["Experiment"] = experiment["Name"]
|
533
|
+
metrics.name = "{}-{}".format(experiment["Name"], i + 1)
|
534
|
+
state_l.append(state)
|
535
|
+
params_l.append(params)
|
536
|
+
df_l.append(df)
|
537
|
+
metrics_l.append(metrics)
|
538
|
+
df = pd.concat(df_l)
|
539
|
+
metrics = pd.concat(metrics_l, axis=1).T
|
540
|
+
return df, metrics, state_l, params_l
|
541
|
+
|
459
542
|
def metaprogramming_python_states(
|
460
543
|
self, model_directory, overwrite=False, default_values=None
|
461
544
|
):
|
@@ -683,7 +766,9 @@ class MathSpecImplementation:
|
|
683
766
|
self.boundary_actions = self.load_boundary_actions()
|
684
767
|
self.policies = self.load_policies()
|
685
768
|
self.mechanisms = self.load_mechanisms()
|
769
|
+
self.stateful_metrics = self.load_stateful_metrics()
|
686
770
|
self.load_wiring()
|
771
|
+
self.load_components()
|
687
772
|
|
688
773
|
def load_control_actions(self):
|
689
774
|
control_actions = {}
|
@@ -761,6 +846,10 @@ class MathSpecImplementation:
|
|
761
846
|
return mechanisms
|
762
847
|
|
763
848
|
def load_single_wiring(self, wiring):
|
849
|
+
hold = wiring
|
850
|
+
domain_sizes = {}
|
851
|
+
for x in wiring.components:
|
852
|
+
domain_sizes[x.name] = len(x.domain)
|
764
853
|
components = [x.name for x in wiring.components]
|
765
854
|
if wiring.block_type == "Stack Block":
|
766
855
|
|
@@ -772,16 +861,32 @@ class MathSpecImplementation:
|
|
772
861
|
elif wiring.block_type == "Parallel Block":
|
773
862
|
|
774
863
|
spaces_mapping = {}
|
775
|
-
for x in wiring.components:
|
776
|
-
spaces_mapping[x.name] = []
|
777
864
|
|
778
|
-
for
|
865
|
+
for y in [x.name for x in wiring.domain_blocks2]:
|
866
|
+
spaces_mapping[y] = []
|
867
|
+
|
868
|
+
for i, x in enumerate([x.name for x in wiring.domain_blocks2]):
|
779
869
|
spaces_mapping[x].append(i)
|
780
870
|
|
781
871
|
def wiring(state, params, spaces):
|
872
|
+
spaces_mapping_temp = deepcopy(spaces_mapping)
|
782
873
|
codomain = []
|
783
874
|
for component in components:
|
784
|
-
|
875
|
+
if component in spaces_mapping_temp:
|
876
|
+
spaces_i = [spaces[i] for i in spaces_mapping_temp[component]][
|
877
|
+
: domain_sizes[component]
|
878
|
+
]
|
879
|
+
# Fix for repeated block names
|
880
|
+
spaces_mapping_temp[component] = spaces_mapping_temp[component][
|
881
|
+
domain_sizes[component] :
|
882
|
+
]
|
883
|
+
else:
|
884
|
+
assert component in [
|
885
|
+
x.name for x in hold.domain_blocks_empty
|
886
|
+
], "{} not in domain_blocks_empty of wiring {}".format(
|
887
|
+
component, hold
|
888
|
+
)
|
889
|
+
spaces_i = []
|
785
890
|
spaces_i = self.blocks[component](state, params, spaces_i)
|
786
891
|
if spaces_i:
|
787
892
|
codomain.extend(spaces_i)
|
@@ -822,6 +927,22 @@ class MathSpecImplementation:
|
|
822
927
|
policies[p.name] = opt.implementations["python"]
|
823
928
|
return policies
|
824
929
|
|
930
|
+
def load_stateful_metrics(self):
|
931
|
+
stateful_metrics = {}
|
932
|
+
|
933
|
+
for sm in self.ms.stateful_metrics_map:
|
934
|
+
sm = self.ms.stateful_metrics_map[sm]
|
935
|
+
if "python" not in sm.implementations:
|
936
|
+
print(
|
937
|
+
"No python implementation for {}. To fix this, go to Implementations/Python/StatefulMetrics and add {}".format(
|
938
|
+
sm.name, sm.name
|
939
|
+
)
|
940
|
+
)
|
941
|
+
else:
|
942
|
+
stateful_metrics[sm.name] = sm.implementations["python"]
|
943
|
+
|
944
|
+
return stateful_metrics
|
945
|
+
|
825
946
|
def load_wiring(
|
826
947
|
self,
|
827
948
|
):
|
@@ -885,3 +1006,29 @@ class MathSpecImplementation:
|
|
885
1006
|
assert (
|
886
1007
|
len(shouldnt_be_in_params) == 0
|
887
1008
|
), "The following parameters are extra: {}".format(shouldnt_be_in_params)
|
1009
|
+
|
1010
|
+
def prepare_state_and_params(self, state, params, state_preperation_functions=None):
|
1011
|
+
self.validate_state_and_params(state, params)
|
1012
|
+
state = deepcopy(state)
|
1013
|
+
params = deepcopy(params)
|
1014
|
+
state["Stateful Metrics"] = self.stateful_metrics
|
1015
|
+
if state_preperation_functions:
|
1016
|
+
for f in state_preperation_functions:
|
1017
|
+
state = f(state)
|
1018
|
+
assert (
|
1019
|
+
state is not None
|
1020
|
+
), "A state must be returned from the state preperation functions"
|
1021
|
+
return state, params
|
1022
|
+
|
1023
|
+
def load_components(self):
|
1024
|
+
self.components = {}
|
1025
|
+
self.components.update(self.control_actions)
|
1026
|
+
self.components.update(self.boundary_actions)
|
1027
|
+
self.components.update(self.policies)
|
1028
|
+
self.components.update(self.mechanisms)
|
1029
|
+
self.components.update(self.wiring)
|
1030
|
+
|
1031
|
+
def execute_blocks(self, state, params, blocks):
|
1032
|
+
for block in blocks:
|
1033
|
+
self.components[block](state, params, [])
|
1034
|
+
return state
|
@@ -39,6 +39,15 @@ def convert_stateful_metric(ms, data: Dict) -> StatefulMetricSet:
|
|
39
39
|
), "Variable '{}' not in variable map for stateful metrics variables used".format(
|
40
40
|
x[1]
|
41
41
|
)
|
42
|
+
|
43
|
+
var["implementations"] = {}
|
44
|
+
|
45
|
+
if "python" in ms["Implementations"]:
|
46
|
+
if "stateful_metrics" in ms["Implementations"]["python"]:
|
47
|
+
if var["name"] in ms["Implementations"]["python"]["stateful_metrics"]:
|
48
|
+
var["implementations"]["python"] = ms["Implementations"]["python"][
|
49
|
+
"stateful_metrics"
|
50
|
+
][var["name"]]
|
42
51
|
new_variables.append(StatefulMetric(var))
|
43
52
|
data["metrics"] = new_variables
|
44
53
|
|
@@ -538,7 +538,7 @@ def write_stateful_metrics_markdown_report(ms, path, metric, add_metadata=True):
|
|
538
538
|
out += "Domain: {}\n\n".format(metric.domain)
|
539
539
|
|
540
540
|
out += "## Parameters Used\n"
|
541
|
-
for i, x in enumerate(sorted(metric.parameters_used, key=lambda x: x
|
541
|
+
for i, x in enumerate(sorted(metric.parameters_used, key=lambda x: x)):
|
542
542
|
out += "{}. [[{}]]".format(i + 1, x)
|
543
543
|
out += "\n"
|
544
544
|
out += "\n"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: math-spec-mapping
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.7
|
4
4
|
Summary: A library for easy mapping of mathematical specifications.
|
5
5
|
Author-email: Sean McOwen <Sean@Block.Science>
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
@@ -45,8 +45,9 @@ Writing mathematical specifications can be a difficult process, especially when
|
|
45
45
|
```mermaid
|
46
46
|
graph TD
|
47
47
|
A[JSON Object \n\n Each spec has a repo for tracking changes \n Must conform to the json specification \n Defines all aspects of the spec including blocks, spaces and actions] -->B[MSML Object \n\n JSON file is parsed, with validations and mappings along the way \n Can show different views on the fly]
|
48
|
-
B --> C[Report Outputs \n\n Automatically build reports for the full spec or subviews \n Example: all blocks with an effect on variable XYZ]
|
49
|
-
|
48
|
+
B --> C[Report Outputs & Obsidian Directory \n\n Automatically build reports for the full spec or subviews \n Example: all blocks with an effect on variable XYZ\n Also builds an entire Obsidian directory of all components as linked notes]
|
49
|
+
D[Python Function Implementations \n\n Optional enhancement to actually execute code\n Done for each referenced policy option, mechanism, etc. \n Just needs a function definition for each] --> B
|
50
|
+
B --> E[Python Wirings & Simulations \n\n MSML can be used to run blocks \n Wirings automatically work to pass between domain/codomains \n Entire simulations can be built up as composed wirings]
|
50
51
|
```
|
51
52
|
|
52
53
|
## MSML in the Engineering Lifecycle
|
@@ -2,11 +2,11 @@ math_spec_mapping/__init__.py,sha256=CzT9KycdX5nuiUzDFmLXVeAIr8v8UKGbXsEQF8vjl1c
|
|
2
2
|
math_spec_mapping/schema.py,sha256=6mrRqzEnTTSXjb19xJ63MBp0KjKH0s7i6TfT4MkAY9k,233
|
3
3
|
math_spec_mapping/schema.schema.json,sha256=hJP2TcV5WPFPmx4u_A5U1xtnpkE1LeYaTeYOXadTot0,30916
|
4
4
|
math_spec_mapping/Classes/ActionTransmissionChannel.py,sha256=zWMo5QsgPh5WGIWXl-xOrZNMXYJXmK6Vejw1dQvi0og,246
|
5
|
-
math_spec_mapping/Classes/Block.py,sha256=
|
5
|
+
math_spec_mapping/Classes/Block.py,sha256=cGtIhNgRfoDZ0O3SxeXcNzNlHcdXIB89sT2uaZct8LY,17667
|
6
6
|
math_spec_mapping/Classes/BoundaryAction.py,sha256=KuZqtvZwSHWDP7gFQXGnG-r3EuYJU_oU9wMCuqvRkzk,593
|
7
7
|
math_spec_mapping/Classes/ControlAction.py,sha256=ysqpgANwdizVdwqtgZmnxXMpCqrzmVEF_6YT0M3l4Ho,526
|
8
8
|
math_spec_mapping/Classes/Entity.py,sha256=fA0-b128_OHHxfCg4pzqyQV083EYev1HlVpy86S5igg,1226
|
9
|
-
math_spec_mapping/Classes/MathSpec.py,sha256=
|
9
|
+
math_spec_mapping/Classes/MathSpec.py,sha256=YopqG_ca7nxgPPZxQR9b442C155ZJGfs73CDEIL5uMc,39038
|
10
10
|
math_spec_mapping/Classes/Mechanism.py,sha256=2sLm3wYBIeTQaMBcsJ9btqIWsbS895Ra8NY6Y9_G_Dg,379
|
11
11
|
math_spec_mapping/Classes/Metric.py,sha256=AhPgYppOP6q49xvR8S9STxQsXUKJlTWx7wI1LfZEtww,581
|
12
12
|
math_spec_mapping/Classes/Parameter.py,sha256=ZuJ_w0sChvRElJ4sOnXZ2EV4Ell2xXFulKLjVOpgz2E,1237
|
@@ -14,7 +14,7 @@ math_spec_mapping/Classes/Policy.py,sha256=fzV85tB3QScjiYGfhw_dyQt9L1BYYfTyTIQQc
|
|
14
14
|
math_spec_mapping/Classes/Space.py,sha256=QsahxoUfRsDWQLBL683KnGx72MAmRxv7CDE7TMgCG-E,472
|
15
15
|
math_spec_mapping/Classes/State.py,sha256=U40DoF2qlx_k9gvqQiP1S3C9ZLk3cW_-jmJn71TiCxg,1599
|
16
16
|
math_spec_mapping/Classes/StateUpdateTransmissionChannel.py,sha256=3hBLvD1lE64PkwqksBXAfFWv7foOZzGQLAFQWy42tOA,257
|
17
|
-
math_spec_mapping/Classes/StatefulMetric.py,sha256=
|
17
|
+
math_spec_mapping/Classes/StatefulMetric.py,sha256=plMFMAFEk1y2t4DR5lA2SRC9UrYArsx_W33l3mZSdgE,804
|
18
18
|
math_spec_mapping/Classes/Type.py,sha256=2KFY8d3cv1PzJJ7SSMHJf1zcfQ3ZbqxotK2KgTaLZdM,289
|
19
19
|
math_spec_mapping/Classes/__init__.py,sha256=0zxgOqns_9JybD74HKMVh6aw8ij8WVbfQ4Q_1uWzof0,761
|
20
20
|
math_spec_mapping/Convenience/__init__.py,sha256=z2W-E5Wg1CNEkDI5UqH3qIVBqp-3A1e63f3u9fA-N7w,112
|
@@ -35,7 +35,7 @@ math_spec_mapping/Load/parameters.py,sha256=W4utm7to3s2fo4z3XgLH0TM1agaIad1qfM2I
|
|
35
35
|
math_spec_mapping/Load/policy.py,sha256=HvlhGHGJTweVs7DOI2HSL_2_diECr8ukDUmzoFLQELo,2444
|
36
36
|
math_spec_mapping/Load/spaces.py,sha256=7zgGA57Te7T4hfuCCDElffiidWgn1lKm5E14e1yjt8M,1116
|
37
37
|
math_spec_mapping/Load/state_update_transmission_channels.py,sha256=FJWp5n4HdtHAfof5BUQ6BnRakljatL2h8dWCapaVSc0,2238
|
38
|
-
math_spec_mapping/Load/stateful_metrics.py,sha256=
|
38
|
+
math_spec_mapping/Load/stateful_metrics.py,sha256=pX2w3MvX2akFAOo6XWybkRE_X-v5BqchV2jTx0EekF0,2356
|
39
39
|
math_spec_mapping/Load/states.py,sha256=3YurI7eTNkN6nrXRFVrc58wH0VfM22XOuWE07HVpR7Y,1365
|
40
40
|
math_spec_mapping/Load/type.py,sha256=z6cBdBNjWed7cRyA0Bj7Jd5PmtemVVh07n3mWFj_5U4,4356
|
41
41
|
math_spec_mapping/Load/wiring.py,sha256=1dR94U5N1W_WI5rL6lYBltH25ZvApB2pIpq9r5Opkug,3083
|
@@ -44,7 +44,7 @@ math_spec_mapping/Reports/boundary_actions.py,sha256=45BPp4QjWdD-3E9ZWwqgj_nI2-Y
|
|
44
44
|
math_spec_mapping/Reports/control_actions.py,sha256=NksekZKIPFSIkubttFstKFthc5AU9B9PWRLSl9j1wWs,1216
|
45
45
|
math_spec_mapping/Reports/general.py,sha256=WOOn6Wlb8M4fsdN49FlKLwOka6vJPQ9aCUy88TL2ki0,1610
|
46
46
|
math_spec_mapping/Reports/html.py,sha256=uUXxMgGoL2yQelSg7CmJjIsU84SbZarqPg2d9x7Z13k,9220
|
47
|
-
math_spec_mapping/Reports/markdown.py,sha256=
|
47
|
+
math_spec_mapping/Reports/markdown.py,sha256=SdhgOMpMBnGKWDG0cimk-LI_UqjQDPy87IxTb-PrBQ0,22866
|
48
48
|
math_spec_mapping/Reports/mechanisms.py,sha256=d2Rxt3JBYvqAOAYUynl0buYVoXEHrO8EGq7GK6hK8NA,1322
|
49
49
|
math_spec_mapping/Reports/node_map.py,sha256=FdSMDQG16NX6n9sZcH-T5xwsvgjrV9OqBHc9J_VlNK0,3129
|
50
50
|
math_spec_mapping/Reports/parameters.py,sha256=yizNG4lNGrgrlzYYcHMGfXKDFlPw4PMDYshDqZ3YARs,535
|
@@ -53,8 +53,8 @@ math_spec_mapping/Reports/spaces.py,sha256=-76hR5wQBv4lsG000ypBJ-OprjsNjI-rNRMYd
|
|
53
53
|
math_spec_mapping/Reports/state.py,sha256=RkqfSonar74KVC8PpA9GgI2xaHX6BrkNdAuWMZlYQfI,2321
|
54
54
|
math_spec_mapping/Reports/tables.py,sha256=O0CNuqh3LMECq5uLjBOoxMUk5hUvkUK660FNnwWUxDY,1505
|
55
55
|
math_spec_mapping/Reports/wiring.py,sha256=u9SvKWy6T-WJUEgFI6-zgZanoOaTTs_2YwmEceDLsV8,1618
|
56
|
-
math_spec_mapping-0.3.
|
57
|
-
math_spec_mapping-0.3.
|
58
|
-
math_spec_mapping-0.3.
|
59
|
-
math_spec_mapping-0.3.
|
60
|
-
math_spec_mapping-0.3.
|
56
|
+
math_spec_mapping-0.3.7.dist-info/LICENSE,sha256=ObyEzSw8kgCaFbEfpu1zP4TrcAKLA0xhqHMZZfyh7N0,1069
|
57
|
+
math_spec_mapping-0.3.7.dist-info/METADATA,sha256=Y4GIicxIeBa44LDgCxCdNAedQ7EZunZn-VD3JPMfFF4,6500
|
58
|
+
math_spec_mapping-0.3.7.dist-info/WHEEL,sha256=mguMlWGMX-VHnMpKOjjQidIo1ssRlCFu4a4mBpz1s2M,91
|
59
|
+
math_spec_mapping-0.3.7.dist-info/top_level.txt,sha256=AImhn9wgazkdV0a9vfiphtQR8uGe2nq-ZIOp-6yUk9o,18
|
60
|
+
math_spec_mapping-0.3.7.dist-info/RECORD,,
|
File without changes
|
File without changes
|