math-spec-mapping 0.3.17__py3-none-any.whl → 0.3.18__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 +13 -3
- math_spec_mapping/Classes/MathSpec.py +173 -0
- math_spec_mapping/Convenience/starter.py +142 -22
- math_spec_mapping/Load/__init__.py +1 -1
- math_spec_mapping/Load/load.py +6 -1
- math_spec_mapping/Load/spec_tree.py +71 -0
- math_spec_mapping/Reports/markdown.py +96 -17
- math_spec_mapping/__init__.py +1 -1
- {math_spec_mapping-0.3.17.dist-info → math_spec_mapping-0.3.18.dist-info}/METADATA +1 -1
- {math_spec_mapping-0.3.17.dist-info → math_spec_mapping-0.3.18.dist-info}/RECORD +13 -12
- {math_spec_mapping-0.3.17.dist-info → math_spec_mapping-0.3.18.dist-info}/LICENSE +0 -0
- {math_spec_mapping-0.3.17.dist-info → math_spec_mapping-0.3.18.dist-info}/WHEEL +0 -0
- {math_spec_mapping-0.3.17.dist-info → math_spec_mapping-0.3.18.dist-info}/top_level.txt +0 -0
| @@ -73,7 +73,7 @@ class Block: | |
| 73 73 | 
             
                    i += 1
         | 
| 74 74 | 
             
                    out = 'X{}["{}"]'.format(i, self.name)
         | 
| 75 75 | 
             
                    if self.block_type == "Mechanism":
         | 
| 76 | 
            -
                        for u in self.updates:
         | 
| 76 | 
            +
                        for u in sorted(self.updates, key=lambda x: x[0].name + "-" + x[1].name):
         | 
| 77 77 | 
             
                            out += "\n"
         | 
| 78 78 | 
             
                            out += "X{} --> {}".format(
         | 
| 79 79 | 
             
                                i,
         | 
| @@ -241,7 +241,9 @@ class ParallelBlock(Block): | |
| 241 241 | 
             
                    elif go_deep == False:
         | 
| 242 242 | 
             
                        i += 1
         | 
| 243 243 | 
             
                        out = 'X{}["{}"]'.format(i, self.name)
         | 
| 244 | 
            -
                        for u in  | 
| 244 | 
            +
                        for u in sorted(
         | 
| 245 | 
            +
                            self.all_updates, key=lambda x: x[0].name + "-" + x[1].name
         | 
| 246 | 
            +
                        ):
         | 
| 245 247 | 
             
                            out += "\n"
         | 
| 246 248 | 
             
                            out += "X{} --> {}".format(
         | 
| 247 249 | 
             
                                i,
         | 
| @@ -305,6 +307,7 @@ class ParallelBlock(Block): | |
| 305 307 | 
             
                        d = domain_map[ix1]
         | 
| 306 308 | 
             
                        if len(d) > 0:
         | 
| 307 309 | 
             
                            d_length = len(d)
         | 
| 310 | 
            +
                            d = ["<a href='{}' class=internal-link>{}</a>".format(x, x) for x in d]
         | 
| 308 311 | 
             
                            d = "\n".join(d)
         | 
| 309 312 | 
             
                            d = '"{}"'.format(d)
         | 
| 310 313 | 
             
                            out += "X{} --{}{}-> X{}".format(domain_i, d, "-" * d_length, ix1)
         | 
| @@ -434,7 +437,10 @@ class StackBlock(Block): | |
| 434 437 | 
             
                    elif go_deep == False:
         | 
| 435 438 | 
             
                        i += 1
         | 
| 436 439 | 
             
                        out = 'X{}["{}"]'.format(i, self.name)
         | 
| 437 | 
            -
             | 
| 440 | 
            +
             | 
| 441 | 
            +
                        for u in sorted(
         | 
| 442 | 
            +
                            self.all_updates, key=lambda x: x[0].name + "-" + x[1].name
         | 
| 443 | 
            +
                        ):
         | 
| 438 444 | 
             
                            out += "\n"
         | 
| 439 445 | 
             
                            out += "X{} --> {}".format(
         | 
| 440 446 | 
             
                                i,
         | 
| @@ -486,6 +492,10 @@ class StackBlock(Block): | |
| 486 492 | 
             
                                optional = global_optional
         | 
| 487 493 | 
             
                                if len(d) > 0:
         | 
| 488 494 | 
             
                                    d_length = len(d)
         | 
| 495 | 
            +
                                    d = [
         | 
| 496 | 
            +
                                        "<a href='{}' class=internal-link>{}</a>".format(x, x)
         | 
| 497 | 
            +
                                        for x in d
         | 
| 498 | 
            +
                                    ]
         | 
| 489 499 | 
             
                                    d = "\n".join(d)
         | 
| 490 500 | 
             
                                    d = '"{}"'.format(d)
         | 
| 491 501 | 
             
                                    if optional:
         | 
| @@ -33,6 +33,7 @@ class MathSpec: | |
| 33 33 | 
             
                    ]
         | 
| 34 34 | 
             
                    self.stateful_metrics = ms_dict["Stateful Metrics"]
         | 
| 35 35 | 
             
                    self.wiring = ms_dict["Wiring"]
         | 
| 36 | 
            +
                    self.tree = None
         | 
| 36 37 | 
             
                    # self.blocks = ms_dict["Blocks"]
         | 
| 37 38 | 
             
                    self._load_blocks()
         | 
| 38 39 | 
             
                    self._load_components()
         | 
| @@ -440,6 +441,178 @@ class MathSpec: | |
| 440 441 | 
             
                    us_names = [y.name for y in self._used_spaces]
         | 
| 441 442 | 
             
                    self._unused_spaces = [self.spaces[x] for x in self.spaces if x not in us_names]
         | 
| 442 443 |  | 
| 444 | 
            +
                def _add_spec_tree(self, tree):
         | 
| 445 | 
            +
                    self.tree = tree
         | 
| 446 | 
            +
                    for folder in [
         | 
| 447 | 
            +
                        "StatefulMetrics",
         | 
| 448 | 
            +
                        "Metrics",
         | 
| 449 | 
            +
                        "Mechanisms",
         | 
| 450 | 
            +
                        "BoundaryActions",
         | 
| 451 | 
            +
                        "Types",
         | 
| 452 | 
            +
                        "ControlActions",
         | 
| 453 | 
            +
                        "Displays",
         | 
| 454 | 
            +
                        "Spaces",
         | 
| 455 | 
            +
                        "State",
         | 
| 456 | 
            +
                        "Policies",
         | 
| 457 | 
            +
                        "Wiring",
         | 
| 458 | 
            +
                        "Parameters",
         | 
| 459 | 
            +
                        "Entities",
         | 
| 460 | 
            +
                    ]:
         | 
| 461 | 
            +
                        tree = self.tree[folder]
         | 
| 462 | 
            +
                        if folder == "StatefulMetrics":
         | 
| 463 | 
            +
                            for component in self.stateful_metrics_map:
         | 
| 464 | 
            +
                                if component not in tree:
         | 
| 465 | 
            +
                                    print(
         | 
| 466 | 
            +
                                        "Can't find component code source in {} for {}".format(
         | 
| 467 | 
            +
                                            folder, component
         | 
| 468 | 
            +
                                        )
         | 
| 469 | 
            +
                                    )
         | 
| 470 | 
            +
                                    self.stateful_metrics_map[component].source_code_location = None
         | 
| 471 | 
            +
                                else:
         | 
| 472 | 
            +
                                    self.stateful_metrics_map[component].source_code_location = (
         | 
| 473 | 
            +
                                        tree[component]
         | 
| 474 | 
            +
                                    )
         | 
| 475 | 
            +
                        elif folder == "Metrics":
         | 
| 476 | 
            +
                            for component in self.metrics:
         | 
| 477 | 
            +
                                if component not in tree:
         | 
| 478 | 
            +
                                    print(
         | 
| 479 | 
            +
                                        "Can't find component code source in {} for {}".format(
         | 
| 480 | 
            +
                                            folder, component
         | 
| 481 | 
            +
                                        )
         | 
| 482 | 
            +
                                    )
         | 
| 483 | 
            +
                                    self.metrics[component].source_code_location = None
         | 
| 484 | 
            +
                                else:
         | 
| 485 | 
            +
                                    self.metrics[component].source_code_location = tree[component]
         | 
| 486 | 
            +
                        elif folder == "Mechanisms":
         | 
| 487 | 
            +
                            for component in self.mechanisms:
         | 
| 488 | 
            +
                                if component not in tree:
         | 
| 489 | 
            +
                                    print(
         | 
| 490 | 
            +
                                        "Can't find component code source in {} for {}".format(
         | 
| 491 | 
            +
                                            folder, component
         | 
| 492 | 
            +
                                        )
         | 
| 493 | 
            +
                                    )
         | 
| 494 | 
            +
                                    self.mechanisms[component].source_code_location = None
         | 
| 495 | 
            +
                                else:
         | 
| 496 | 
            +
                                    self.mechanisms[component].source_code_location = tree[
         | 
| 497 | 
            +
                                        component
         | 
| 498 | 
            +
                                    ]
         | 
| 499 | 
            +
                        elif folder == "BoundaryActions":
         | 
| 500 | 
            +
                            for component in self.boundary_actions:
         | 
| 501 | 
            +
                                if component not in tree:
         | 
| 502 | 
            +
                                    print(
         | 
| 503 | 
            +
                                        "Can't find component code source in {} for {}".format(
         | 
| 504 | 
            +
                                            folder, component
         | 
| 505 | 
            +
                                        )
         | 
| 506 | 
            +
                                    )
         | 
| 507 | 
            +
                                    self.boundary_actions[component].source_code_location = None
         | 
| 508 | 
            +
                                else:
         | 
| 509 | 
            +
                                    self.boundary_actions[component].source_code_location = tree[
         | 
| 510 | 
            +
                                        component
         | 
| 511 | 
            +
                                    ]
         | 
| 512 | 
            +
                        elif folder == "Types":
         | 
| 513 | 
            +
                            for component in self.types:
         | 
| 514 | 
            +
                                if component not in tree:
         | 
| 515 | 
            +
             | 
| 516 | 
            +
                                    print(
         | 
| 517 | 
            +
                                        "Can't find component code source in {} for {}".format(
         | 
| 518 | 
            +
                                            folder, component
         | 
| 519 | 
            +
                                        )
         | 
| 520 | 
            +
                                    )
         | 
| 521 | 
            +
                                    self.types[component].source_code_location = None
         | 
| 522 | 
            +
                                else:
         | 
| 523 | 
            +
                                    self.types[component].source_code_location = tree[component]
         | 
| 524 | 
            +
                        elif folder == "ControlActions":
         | 
| 525 | 
            +
                            for component in self.control_actions:
         | 
| 526 | 
            +
                                if component not in tree:
         | 
| 527 | 
            +
                                    print(
         | 
| 528 | 
            +
                                        "Can't find component code source in {} for {}".format(
         | 
| 529 | 
            +
                                            folder, component
         | 
| 530 | 
            +
                                        )
         | 
| 531 | 
            +
                                    )
         | 
| 532 | 
            +
                                    self.control_actions[component].source_code_location = None
         | 
| 533 | 
            +
                                else:
         | 
| 534 | 
            +
                                    self.control_actions[component].source_code_location = tree[
         | 
| 535 | 
            +
                                        component
         | 
| 536 | 
            +
                                    ]
         | 
| 537 | 
            +
                        elif folder == "Displays":
         | 
| 538 | 
            +
                            print("Displays not implemented")
         | 
| 539 | 
            +
                            # keys = [x["name"] for x in ms.displays["Wiring"]]
         | 
| 540 | 
            +
                        elif folder == "Spaces":
         | 
| 541 | 
            +
                            for component in self.spaces:
         | 
| 542 | 
            +
                                if component in ["Terminating Space", "Empty Space"]:
         | 
| 543 | 
            +
                                    self.spaces[component].source_code_location = None
         | 
| 544 | 
            +
                                    continue
         | 
| 545 | 
            +
                                if component not in tree:
         | 
| 546 | 
            +
                                    print(
         | 
| 547 | 
            +
                                        "Can't find component code source in {} for {}".format(
         | 
| 548 | 
            +
                                            folder, component
         | 
| 549 | 
            +
                                        )
         | 
| 550 | 
            +
                                    )
         | 
| 551 | 
            +
                                    self.spaces[component].source_code_location = None
         | 
| 552 | 
            +
                                else:
         | 
| 553 | 
            +
                                    self.spaces[component].source_code_location = tree[component]
         | 
| 554 | 
            +
                        elif folder == "State":
         | 
| 555 | 
            +
                            for component in self.state:
         | 
| 556 | 
            +
                                if component not in tree:
         | 
| 557 | 
            +
                                    print(
         | 
| 558 | 
            +
                                        "Can't find component code source in {} for {}".format(
         | 
| 559 | 
            +
                                            folder, component
         | 
| 560 | 
            +
                                        )
         | 
| 561 | 
            +
                                    )
         | 
| 562 | 
            +
                                    self.state[component].source_code_location = None
         | 
| 563 | 
            +
                                else:
         | 
| 564 | 
            +
                                    self.state[component].source_code_location = tree[component]
         | 
| 565 | 
            +
                        elif folder == "Policies":
         | 
| 566 | 
            +
                            for component in self.policies:
         | 
| 567 | 
            +
                                if component not in tree:
         | 
| 568 | 
            +
                                    print(
         | 
| 569 | 
            +
                                        "Can't find component code source in {} for {}".format(
         | 
| 570 | 
            +
                                            folder, component
         | 
| 571 | 
            +
                                        )
         | 
| 572 | 
            +
                                    )
         | 
| 573 | 
            +
                                    self.policies[component].source_code_location = None
         | 
| 574 | 
            +
                                else:
         | 
| 575 | 
            +
                                    self.policies[component].source_code_location = tree[component]
         | 
| 576 | 
            +
                        elif folder == "Wiring":
         | 
| 577 | 
            +
                            for component in self.wiring:
         | 
| 578 | 
            +
                                if component not in tree:
         | 
| 579 | 
            +
                                    print(
         | 
| 580 | 
            +
                                        "Can't find component code source in {} for {}".format(
         | 
| 581 | 
            +
                                            folder, component
         | 
| 582 | 
            +
                                        )
         | 
| 583 | 
            +
                                    )
         | 
| 584 | 
            +
                                    self.wiring[component].source_code_location = None
         | 
| 585 | 
            +
                                else:
         | 
| 586 | 
            +
                                    self.wiring[component].source_code_location = tree[component]
         | 
| 587 | 
            +
                        elif folder == "Parameters":
         | 
| 588 | 
            +
                            for component in self.parameters.parameter_map:
         | 
| 589 | 
            +
                                if component not in tree:
         | 
| 590 | 
            +
                                    print(
         | 
| 591 | 
            +
                                        "Can't find component code source in {} for {}".format(
         | 
| 592 | 
            +
                                            folder, component
         | 
| 593 | 
            +
                                        )
         | 
| 594 | 
            +
                                    )
         | 
| 595 | 
            +
                                    self.parameters.parameter_map[
         | 
| 596 | 
            +
                                        component
         | 
| 597 | 
            +
                                    ].source_code_location = None
         | 
| 598 | 
            +
                                else:
         | 
| 599 | 
            +
                                    self.parameters.parameter_map[
         | 
| 600 | 
            +
                                        component
         | 
| 601 | 
            +
                                    ].source_code_location = tree[component]
         | 
| 602 | 
            +
                        elif folder == "Entities":
         | 
| 603 | 
            +
                            for component in self.entities:
         | 
| 604 | 
            +
                                if component not in tree:
         | 
| 605 | 
            +
                                    print(
         | 
| 606 | 
            +
                                        "Can't find component code source in {} for {}".format(
         | 
| 607 | 
            +
                                            folder, component
         | 
| 608 | 
            +
                                        )
         | 
| 609 | 
            +
                                    )
         | 
| 610 | 
            +
                                    self.entities[component].source_code_location = None
         | 
| 611 | 
            +
                                else:
         | 
| 612 | 
            +
                                    self.entities[component].source_code_location = tree[component]
         | 
| 613 | 
            +
                        else:
         | 
| 614 | 
            +
                            assert False
         | 
| 615 | 
            +
             | 
| 443 616 | 
             
                def metaprogramming_python_types(self, model_directory, overwrite=False):
         | 
| 444 617 | 
             
                    path = model_directory + "/types.py"
         | 
| 445 618 | 
             
                    if not overwrite:
         | 
| @@ -33,9 +33,9 @@ def remove_dummy_repo_components(path): | |
| 33 33 | 
             
                    if "__init__.py" in contents:
         | 
| 34 34 | 
             
                        with open(path2 + "/__init__.py", "r") as f:
         | 
| 35 35 | 
             
                            contents = f.read()
         | 
| 36 | 
            -
                            contents = contents.replace("from .Dummy import  | 
| 37 | 
            -
                            contents = contents.replace("metrics.extend( | 
| 38 | 
            -
                            contents = contents.replace("metrics.extend( | 
| 36 | 
            +
                            contents = contents.replace("from .Dummy import dummy_metrics\n", "")
         | 
| 37 | 
            +
                            contents = contents.replace("metrics.extend(dummy_metrics)\n", "")
         | 
| 38 | 
            +
                            contents = contents.replace("metrics.extend(dummy_metrics)", "")
         | 
| 39 39 | 
             
                        with open(path2 + "/__init__.py", "w") as f:
         | 
| 40 40 | 
             
                            f.write(contents)
         | 
| 41 41 |  | 
| @@ -46,17 +46,17 @@ def remove_dummy_repo_components(path): | |
| 46 46 | 
             
                        with open(path2 + "/wiring.py", "r") as f:
         | 
| 47 47 | 
             
                            contents = f.read()
         | 
| 48 48 |  | 
| 49 | 
            -
                            contents = contents.replace('" | 
| 50 | 
            -
                            contents = contents.replace('" | 
| 51 | 
            -
                            contents = contents.replace('" | 
| 49 | 
            +
                            contents = contents.replace('"DUMMY Length-1 Boundary Wiring",\n', "")
         | 
| 50 | 
            +
                            contents = contents.replace('"DUMMY Length-1 Boundary Wiring",', "")
         | 
| 51 | 
            +
                            contents = contents.replace('"DUMMY Length-1 Boundary Wiring"', "")
         | 
| 52 52 |  | 
| 53 | 
            -
                            contents = contents.replace('" | 
| 54 | 
            -
                            contents = contents.replace('" | 
| 55 | 
            -
                            contents = contents.replace('" | 
| 53 | 
            +
                            contents = contents.replace('"DUMMY Length-2 Boundary Wiring",\n', "")
         | 
| 54 | 
            +
                            contents = contents.replace('"DUMMY Length-2 Boundary Wiring",', "")
         | 
| 55 | 
            +
                            contents = contents.replace('"DUMMY Length-2 Boundary Wiring"', "")
         | 
| 56 56 |  | 
| 57 | 
            -
                            contents = contents.replace('" | 
| 58 | 
            -
                            contents = contents.replace('" | 
| 59 | 
            -
                            contents = contents.replace('" | 
| 57 | 
            +
                            contents = contents.replace('"DUMMY Control Wiring",\n', "")
         | 
| 58 | 
            +
                            contents = contents.replace('"DUMMY Control Wiring",', "")
         | 
| 59 | 
            +
                            contents = contents.replace('"DUMMY Control Wiring"', "")
         | 
| 60 60 |  | 
| 61 61 | 
             
                        with open(path2 + "/wiring.py", "w") as f:
         | 
| 62 62 | 
             
                            f.write(contents)
         | 
| @@ -188,6 +188,32 @@ def remove_dummy_repo_components(path): | |
| 188 188 | 
             
                            contents = contents.replace("dummy_state", "")
         | 
| 189 189 | 
             
                        with open(path2 + "/__init__.py", "w") as f:
         | 
| 190 190 | 
             
                            f.write(contents)
         | 
| 191 | 
            +
                    contents = os.listdir(path2)
         | 
| 192 | 
            +
                    if "Global.py" in contents:
         | 
| 193 | 
            +
                        with open(path2 + "/Global.py", "r") as f:
         | 
| 194 | 
            +
                            contents = f.read()
         | 
| 195 | 
            +
                        for x in [
         | 
| 196 | 
            +
                            """        {
         | 
| 197 | 
            +
                        "type": "DUMMY Integer Type",
         | 
| 198 | 
            +
                        "name": "Time",
         | 
| 199 | 
            +
                        "description": "The clock time",
         | 
| 200 | 
            +
                        "symbol": None,
         | 
| 201 | 
            +
                        "domain": None,
         | 
| 202 | 
            +
                    }""",
         | 
| 203 | 
            +
                            """        {
         | 
| 204 | 
            +
                        "type": "Entity Type",
         | 
| 205 | 
            +
                        "name": "Dummy",
         | 
| 206 | 
            +
                        "description": "The dummy entity",
         | 
| 207 | 
            +
                        "symbol": None,
         | 
| 208 | 
            +
                        "domain": None,
         | 
| 209 | 
            +
                    }""",
         | 
| 210 | 
            +
                        ]:
         | 
| 211 | 
            +
                            contents = contents.replace("{},\n".format(x), "")
         | 
| 212 | 
            +
                            contents = contents.replace("{}\n".format(x), "")
         | 
| 213 | 
            +
                            contents = contents.replace("{},".format(x), "")
         | 
| 214 | 
            +
                            contents = contents.replace("{}".format(x), "")
         | 
| 215 | 
            +
                        with open(path2 + "/Global.py", "w") as f:
         | 
| 216 | 
            +
                            f.write(contents)
         | 
| 191 217 |  | 
| 192 218 | 
             
                if "Parameters" in directory_folders:
         | 
| 193 219 | 
             
                    path2 = path + "/Parameters"
         | 
| @@ -257,12 +283,15 @@ def remove_dummy_repo_components(path): | |
| 257 283 | 
             
                    if "types.py" in contents:
         | 
| 258 284 | 
             
                        with open(path2 + "/types.py", "r") as f:
         | 
| 259 285 | 
             
                            contents = f.read()
         | 
| 260 | 
            -
                             | 
| 261 | 
            -
                                "" | 
| 262 | 
            -
             | 
| 263 | 
            -
             | 
| 264 | 
            -
             | 
| 265 | 
            -
             | 
| 286 | 
            +
                            for x in [
         | 
| 287 | 
            +
                                '"DummyABCDEFType": str',
         | 
| 288 | 
            +
                                '"DummyIntegerType": int',
         | 
| 289 | 
            +
                                '"DummyDecimalType": float',
         | 
| 290 | 
            +
                            ]:
         | 
| 291 | 
            +
                                contents = contents.replace("{},\n".format(x), "")
         | 
| 292 | 
            +
                                contents = contents.replace("{}\n".format(x), "")
         | 
| 293 | 
            +
                                contents = contents.replace("{},".format(x), "")
         | 
| 294 | 
            +
                                contents = contents.replace("{}".format(x), "")
         | 
| 266 295 |  | 
| 267 296 | 
             
                        with open(path2 + "/types.py", "w") as f:
         | 
| 268 297 | 
             
                            f.write(contents)
         | 
| @@ -271,7 +300,7 @@ def remove_dummy_repo_components(path): | |
| 271 300 | 
             
                    path2 = path + "/TypeMappings"
         | 
| 272 301 | 
             
                    contents = os.listdir(path2)
         | 
| 273 302 |  | 
| 274 | 
            -
                    if "types. | 
| 303 | 
            +
                    if "types.jl" in contents:
         | 
| 275 304 | 
             
                        with open(path2 + "/types.jl", "r") as f:
         | 
| 276 305 | 
             
                            contents = f.read()
         | 
| 277 306 | 
             
                            contents = contents.replace(
         | 
| @@ -295,11 +324,102 @@ end""", | |
| 295 324 | 
             
                        with open(path2 + "/types.ts", "r") as f:
         | 
| 296 325 | 
             
                            contents = f.read()
         | 
| 297 326 | 
             
                            contents = contents.replace(
         | 
| 298 | 
            -
                                """type  | 
| 299 | 
            -
             | 
| 300 | 
            -
             | 
| 327 | 
            +
                                """type DummyABCDEFType = string""",
         | 
| 328 | 
            +
                                "",
         | 
| 329 | 
            +
                            )
         | 
| 330 | 
            +
                            contents = contents.replace(
         | 
| 331 | 
            +
                                """type DummyIntegerType = number""",
         | 
| 332 | 
            +
                                "",
         | 
| 333 | 
            +
                            )
         | 
| 334 | 
            +
                            contents = contents.replace(
         | 
| 335 | 
            +
                                """type DummyDecimalType = number""",
         | 
| 301 336 | 
             
                                "",
         | 
| 302 337 | 
             
                            )
         | 
| 303 338 |  | 
| 304 339 | 
             
                        with open(path2 + "/types.ts", "w") as f:
         | 
| 305 340 | 
             
                            f.write(contents)
         | 
| 341 | 
            +
             | 
| 342 | 
            +
                remove_dummy_repo_implementations(path)
         | 
| 343 | 
            +
             | 
| 344 | 
            +
             | 
| 345 | 
            +
            def remove_implementation_folder(path, folder, component_names, import_statement):
         | 
| 346 | 
            +
                path = path + "/" + folder
         | 
| 347 | 
            +
                contents = os.listdir(path)
         | 
| 348 | 
            +
                if "Dummy.py" in contents:
         | 
| 349 | 
            +
                    os.remove(path + "/Dummy.py")
         | 
| 350 | 
            +
                if "__init__.py" in contents:
         | 
| 351 | 
            +
                    with open(path + "/__init__.py", "r") as f:
         | 
| 352 | 
            +
                        contents = f.read()
         | 
| 353 | 
            +
                        contents = contents.replace(import_statement + "\n", "")
         | 
| 354 | 
            +
                        contents = contents.replace(import_statement, "")
         | 
| 355 | 
            +
                        for x in component_names:
         | 
| 356 | 
            +
                            contents = contents.replace("{},\n".format(x), "")
         | 
| 357 | 
            +
                            contents = contents.replace("{}\n".format(x), "")
         | 
| 358 | 
            +
                            contents = contents.replace("{},".format(x), "")
         | 
| 359 | 
            +
                            contents = contents.replace("{}".format(x), "")
         | 
| 360 | 
            +
                    with open(path + "/__init__.py", "w") as f:
         | 
| 361 | 
            +
                        f.write(contents)
         | 
| 362 | 
            +
             | 
| 363 | 
            +
             | 
| 364 | 
            +
            def remove_dummy_repo_implementations(path):
         | 
| 365 | 
            +
                path = path + "/Implementations/Python"
         | 
| 366 | 
            +
                directory_folders = os.listdir(path)
         | 
| 367 | 
            +
             | 
| 368 | 
            +
                if "BoundaryActions" in directory_folders:
         | 
| 369 | 
            +
                    remove_implementation_folder(
         | 
| 370 | 
            +
                        path,
         | 
| 371 | 
            +
                        "BoundaryActions",
         | 
| 372 | 
            +
                        [
         | 
| 373 | 
            +
                            '"Length-1 ABC Equal Weight Option": v1_dummy_boundary',
         | 
| 374 | 
            +
                            '"DUMMY Length-2 ABC Equal Weight Option": v1_dummy_boundary2',
         | 
| 375 | 
            +
                            '"DUMMY Length-2 ABC Equal Weight 2 Option": v2_dummy_boundary2',
         | 
| 376 | 
            +
                        ],
         | 
| 377 | 
            +
                        "from .Dummy import v1_dummy_boundary, v1_dummy_boundary2, v2_dummy_boundary2",
         | 
| 378 | 
            +
                    )
         | 
| 379 | 
            +
                if "ControlActions" in directory_folders:
         | 
| 380 | 
            +
                    remove_implementation_folder(
         | 
| 381 | 
            +
                        path,
         | 
| 382 | 
            +
                        "ControlActions",
         | 
| 383 | 
            +
                        [
         | 
| 384 | 
            +
                            '"DUMMY Length-1 DEF Equal Weight Option": v1_dummy_control',
         | 
| 385 | 
            +
                            '"DUMMY Length-1 DEF D Probability Option": v2_dummy_control',
         | 
| 386 | 
            +
                        ],
         | 
| 387 | 
            +
                        "from .Dummy import v1_dummy_control, v2_dummy_control",
         | 
| 388 | 
            +
                    )
         | 
| 389 | 
            +
                if "Policies" in directory_folders:
         | 
| 390 | 
            +
                    remove_implementation_folder(
         | 
| 391 | 
            +
                        path,
         | 
| 392 | 
            +
                        "Policies",
         | 
| 393 | 
            +
                        ['"DUMMY Letter Count Policy V1": dummy_letter_count_policy'],
         | 
| 394 | 
            +
                        "from .Dummy import dummy_letter_count_policy",
         | 
| 395 | 
            +
                    )
         | 
| 396 | 
            +
                if "Mechanisms" in directory_folders:
         | 
| 397 | 
            +
                    remove_implementation_folder(
         | 
| 398 | 
            +
                        path,
         | 
| 399 | 
            +
                        "Mechanisms",
         | 
| 400 | 
            +
                        [
         | 
| 401 | 
            +
                            '"DUMMY Update Dummy Entity Mechanism": dummy_update_dummy_entity_mechanism',
         | 
| 402 | 
            +
                            '"DUMMY Increment Time Mechanism": dummy_increment_time_mechanism',
         | 
| 403 | 
            +
                            '"DUMMY Log Simulation Data Mechanism": dummy_log_simulation_data_mechanism',
         | 
| 404 | 
            +
                        ],
         | 
| 405 | 
            +
                        """from .Dummy import (
         | 
| 406 | 
            +
                dummy_update_dummy_entity_mechanism,
         | 
| 407 | 
            +
                dummy_increment_time_mechanism,
         | 
| 408 | 
            +
                dummy_log_simulation_data_mechanism,
         | 
| 409 | 
            +
            )""",
         | 
| 410 | 
            +
                    )
         | 
| 411 | 
            +
             | 
| 412 | 
            +
                if "StatefulMetrics" in directory_folders:
         | 
| 413 | 
            +
                    remove_implementation_folder(
         | 
| 414 | 
            +
                        path,
         | 
| 415 | 
            +
                        "StatefulMetrics",
         | 
| 416 | 
            +
                        ['"DUMMY Nominal Length Stateful Metric": dummy_metric'],
         | 
| 417 | 
            +
                        """from .Dummy import dummy_metric""",
         | 
| 418 | 
            +
                    )
         | 
| 419 | 
            +
                if "Metrics" in directory_folders:
         | 
| 420 | 
            +
                    remove_implementation_folder(
         | 
| 421 | 
            +
                        path,
         | 
| 422 | 
            +
                        "Metrics",
         | 
| 423 | 
            +
                        ['"DUMMY Multiplied Length Metric": dummy_multiplied_length_metric'],
         | 
| 424 | 
            +
                        """from .Dummy import dummy_multiplied_length_metric""",
         | 
| 425 | 
            +
                    )
         | 
| @@ -1 +1 @@ | |
| 1 | 
            -
            from .load import load_from_json
         | 
| 1 | 
            +
            from .load import load_from_json, load_spec_tree
         | 
    
        math_spec_mapping/Load/load.py
    CHANGED
    
    | @@ -17,9 +17,10 @@ from .type import load_types, load_type_keys | |
| 17 17 | 
             
            from .metrics import load_metrics
         | 
| 18 18 | 
             
            from .displays import load_displays
         | 
| 19 19 | 
             
            from .implementations import load_implementations
         | 
| 20 | 
            +
            from .spec_tree import load_spec_tree
         | 
| 20 21 |  | 
| 21 22 |  | 
| 22 | 
            -
            def load_from_json(json: Dict) -> MathSpec:
         | 
| 23 | 
            +
            def load_from_json(json: Dict, spec_path=None) -> MathSpec:
         | 
| 23 24 | 
             
                """Function to load a math spec from a json format
         | 
| 24 25 |  | 
| 25 26 | 
             
                Args:
         | 
| @@ -81,4 +82,8 @@ def load_from_json(json: Dict) -> MathSpec: | |
| 81 82 | 
             
                for space in ms.spaces.values():
         | 
| 82 83 | 
             
                    space.domain_blocks = list(set(space.domain_blocks))
         | 
| 83 84 | 
             
                    space.codomain_blocks = list(set(space.codomain_blocks))
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                if spec_path:
         | 
| 87 | 
            +
                    tree = load_spec_tree(spec_path, ms)
         | 
| 88 | 
            +
                    ms._add_spec_tree(tree)
         | 
| 84 89 | 
             
                return ms
         | 
| @@ -0,0 +1,71 @@ | |
| 1 | 
            +
            import ast
         | 
| 2 | 
            +
            import os
         | 
| 3 | 
            +
             | 
| 4 | 
            +
             | 
| 5 | 
            +
            def load_spec_tree(path, ms):
         | 
| 6 | 
            +
                tree = {}
         | 
| 7 | 
            +
                for folder in [
         | 
| 8 | 
            +
                    "StatefulMetrics",
         | 
| 9 | 
            +
                    "Metrics",
         | 
| 10 | 
            +
                    "Mechanisms",
         | 
| 11 | 
            +
                    "BoundaryActions",
         | 
| 12 | 
            +
                    "Types",
         | 
| 13 | 
            +
                    "ControlActions",
         | 
| 14 | 
            +
                    "Displays",
         | 
| 15 | 
            +
                    "Spaces",
         | 
| 16 | 
            +
                    "State",
         | 
| 17 | 
            +
                    "Policies",
         | 
| 18 | 
            +
                    "Wiring",
         | 
| 19 | 
            +
                    "Parameters",
         | 
| 20 | 
            +
                    "Entities",
         | 
| 21 | 
            +
                ]:
         | 
| 22 | 
            +
                    if folder == "StatefulMetrics":
         | 
| 23 | 
            +
                        keys = ms.get_all_stateful_metric_names()
         | 
| 24 | 
            +
                    elif folder == "Metrics":
         | 
| 25 | 
            +
                        keys = ms.metrics.keys()
         | 
| 26 | 
            +
                    elif folder == "Mechanisms":
         | 
| 27 | 
            +
                        keys = ms.mechanisms.keys()
         | 
| 28 | 
            +
                    elif folder == "BoundaryActions":
         | 
| 29 | 
            +
                        keys = ms.boundary_actions.keys()
         | 
| 30 | 
            +
                    elif folder == "Types":
         | 
| 31 | 
            +
                        keys = ms.types.keys()
         | 
| 32 | 
            +
                    elif folder == "ControlActions":
         | 
| 33 | 
            +
                        keys = ms.control_actions.keys()
         | 
| 34 | 
            +
                    elif folder == "Displays":
         | 
| 35 | 
            +
                        keys = [x["name"] for x in ms.displays["Wiring"]]
         | 
| 36 | 
            +
                    elif folder == "Spaces":
         | 
| 37 | 
            +
                        keys = ms.spaces.keys()
         | 
| 38 | 
            +
                    elif folder == "State":
         | 
| 39 | 
            +
                        keys = ms.state.keys()
         | 
| 40 | 
            +
                    elif folder == "Policies":
         | 
| 41 | 
            +
                        keys = ms.policies.keys()
         | 
| 42 | 
            +
                    elif folder == "Wiring":
         | 
| 43 | 
            +
                        keys = ms.wiring.keys()
         | 
| 44 | 
            +
                    elif folder == "Parameters":
         | 
| 45 | 
            +
                        keys = ms.parameters.all_parameters
         | 
| 46 | 
            +
                    elif folder == "Entities":
         | 
| 47 | 
            +
                        keys = ms.entities.keys()
         | 
| 48 | 
            +
                    else:
         | 
| 49 | 
            +
                        assert False
         | 
| 50 | 
            +
                    keys = list(keys)
         | 
| 51 | 
            +
                    tree[folder] = {}
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                    init_path = path + "/" + folder + "/__init__.py"
         | 
| 54 | 
            +
                    with open(init_path, "r") as file:
         | 
| 55 | 
            +
                        tree2 = ast.parse(file.read(), filename=init_path)
         | 
| 56 | 
            +
                        imports = []
         | 
| 57 | 
            +
                        for node in ast.walk(tree2):
         | 
| 58 | 
            +
                            if isinstance(node, ast.Import):
         | 
| 59 | 
            +
                                for alias in node.names:
         | 
| 60 | 
            +
                                    imports.append(alias.name)
         | 
| 61 | 
            +
                                assert False, "Not implemented for imports that are not import from"
         | 
| 62 | 
            +
                            elif isinstance(node, ast.ImportFrom):
         | 
| 63 | 
            +
                                if node.module:
         | 
| 64 | 
            +
                                    for name in node.names:
         | 
| 65 | 
            +
                                        file_path = "{}/{}/{}.py".format(path, folder, node.module)
         | 
| 66 | 
            +
                                        with open(file_path, "r") as file2:
         | 
| 67 | 
            +
                                            contents = file2.read()
         | 
| 68 | 
            +
                                        for key in keys:
         | 
| 69 | 
            +
                                            if key in contents:
         | 
| 70 | 
            +
                                                tree[folder][key] = os.path.abspath(file_path)
         | 
| 71 | 
            +
                return tree
         | 
| @@ -3,7 +3,11 @@ from .state import write_state_section | |
| 3 3 | 
             
            from inspect import signature, getsource, getfile
         | 
| 4 4 |  | 
| 5 5 |  | 
| 6 | 
            -
            def get_source_code( | 
| 6 | 
            +
            def get_source_code(
         | 
| 7 | 
            +
                ms,
         | 
| 8 | 
            +
                component_type,
         | 
| 9 | 
            +
                implementation_name,
         | 
| 10 | 
            +
            ):
         | 
| 7 11 | 
             
                if implementation_name in ms.implementations["python"][component_type]:
         | 
| 8 12 | 
             
                    code = ms.implementations["python"][component_type][implementation_name]
         | 
| 9 13 | 
             
                else:
         | 
| @@ -55,10 +59,25 @@ def write_entity_markdown_report(ms, path, entity, add_metadata=True): | |
| 55 59 | 
             
                    out += "### [[{}]]".format(ac.name)
         | 
| 56 60 | 
             
                    out += "\n"
         | 
| 57 61 |  | 
| 58 | 
            -
                 | 
| 62 | 
            +
                path = "{}/Entities/{}.md".format(path, entity.name)
         | 
| 63 | 
            +
                out = write_source_code_block(entity, out, path)
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                with open(path, "w") as f:
         | 
| 59 66 | 
             
                    f.write(out)
         | 
| 60 67 |  | 
| 61 68 |  | 
| 69 | 
            +
            def write_source_code_block(component, text, path):
         | 
| 70 | 
            +
                file_path = component.source_code_location
         | 
| 71 | 
            +
                if file_path:
         | 
| 72 | 
            +
                    file_path = os.path.relpath(file_path, path)
         | 
| 73 | 
            +
                    text += "## Spec Source Code Location\n\n"
         | 
| 74 | 
            +
                    text += "Spec Path (only works if vault is opened at level including the src folder): [{}]({})".format(
         | 
| 75 | 
            +
                        file_path, file_path
         | 
| 76 | 
            +
                    )
         | 
| 77 | 
            +
                    text += "\n\n"
         | 
| 78 | 
            +
                return text
         | 
| 79 | 
            +
             | 
| 80 | 
            +
             | 
| 62 81 | 
             
            def write_state_markdown_report(ms, path, state, add_metadata=True):
         | 
| 63 82 | 
             
                state = ms.state[state]
         | 
| 64 83 | 
             
                if "States" not in os.listdir(path):
         | 
| @@ -83,7 +102,10 @@ def write_state_markdown_report(ms, path, state, add_metadata=True): | |
| 83 102 | 
             
                    out += "### [[{}]]".format(ba.name)
         | 
| 84 103 | 
             
                    out += "\n"
         | 
| 85 104 |  | 
| 86 | 
            -
                 | 
| 105 | 
            +
                path = "{}/States/{}.md".format(path, state.name)
         | 
| 106 | 
            +
                out = write_source_code_block(state, out, path)
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                with open(path, "w") as f:
         | 
| 87 109 | 
             
                    f.write(out)
         | 
| 88 110 |  | 
| 89 111 |  | 
| @@ -121,8 +143,11 @@ def write_types_markdown_report(ms, path, t, add_metadata=True): | |
| 121 143 | 
             
                out += "## Notes"
         | 
| 122 144 | 
             
                out += "\n\n"
         | 
| 123 145 | 
             
                out += t.notes
         | 
| 146 | 
            +
                out += "\n"
         | 
| 124 147 |  | 
| 125 | 
            -
                 | 
| 148 | 
            +
                path = "{}/Types/{}.md".format(path, t.name)
         | 
| 149 | 
            +
                out = write_source_code_block(t, out, path)
         | 
| 150 | 
            +
                with open(path, "w") as f:
         | 
| 126 151 | 
             
                    f.write(out)
         | 
| 127 152 |  | 
| 128 153 |  | 
| @@ -211,9 +236,10 @@ def write_boundary_action_markdown_report(ms, path, boundary_action, add_metadat | |
| 211 236 |  | 
| 212 237 | 
             
                        out += "\n"
         | 
| 213 238 |  | 
| 214 | 
            -
                 | 
| 215 | 
            -
             | 
| 216 | 
            -
             | 
| 239 | 
            +
                path = "{}/Boundary Actions/{}.md".format(path, boundary_action.label)
         | 
| 240 | 
            +
                out = write_source_code_block(boundary_action, out, path)
         | 
| 241 | 
            +
             | 
| 242 | 
            +
                with open(path, "w") as f:
         | 
| 217 243 | 
             
                    f.write(out)
         | 
| 218 244 |  | 
| 219 245 |  | 
| @@ -302,7 +328,10 @@ def write_policy_markdown_report(ms, path, policy, add_metadata=True): | |
| 302 328 |  | 
| 303 329 | 
             
                        out += "\n"
         | 
| 304 330 |  | 
| 305 | 
            -
                 | 
| 331 | 
            +
                path = "{}/Policies/{}.md".format(path, policy.label)
         | 
| 332 | 
            +
                out = write_source_code_block(policy, out, path)
         | 
| 333 | 
            +
             | 
| 334 | 
            +
                with open(path, "w") as f:
         | 
| 306 335 | 
             
                    f.write(out)
         | 
| 307 336 |  | 
| 308 337 |  | 
| @@ -381,7 +410,10 @@ def write_mechanism_markdown_report(ms, path, mechanism, add_metadata=True): | |
| 381 410 |  | 
| 382 411 | 
             
                out += "\n"
         | 
| 383 412 |  | 
| 384 | 
            -
                 | 
| 413 | 
            +
                path = "{}/Mechanisms/{}.md".format(path, mechanism.label)
         | 
| 414 | 
            +
                out = write_source_code_block(mechanism, out, path)
         | 
| 415 | 
            +
             | 
| 416 | 
            +
                with open(path, "w") as f:
         | 
| 385 417 | 
             
                    f.write(out)
         | 
| 386 418 |  | 
| 387 419 |  | 
| @@ -415,19 +447,22 @@ def write_space_markdown_report(ms, path, space, add_metadata=True): | |
| 415 447 |  | 
| 416 448 | 
             
                out += "## Blocks with Space in Domain"
         | 
| 417 449 | 
             
                out += "\n"
         | 
| 418 | 
            -
                for i, x in enumerate(space.domain_blocks):
         | 
| 450 | 
            +
                for i, x in enumerate(sorted(space.domain_blocks, key=lambda x: x.name)):
         | 
| 419 451 | 
             
                    out += "{}. [[{}]]".format(i + 1, x.name)
         | 
| 420 452 | 
             
                    out += "\n"
         | 
| 421 453 | 
             
                out += "\n"
         | 
| 422 454 |  | 
| 423 455 | 
             
                out += "## Blocks with Space in Codomain"
         | 
| 424 456 | 
             
                out += "\n"
         | 
| 425 | 
            -
                for i, x in enumerate(space.codomain_blocks):
         | 
| 457 | 
            +
                for i, x in enumerate(sorted(space.codomain_blocks, key=lambda x: x.name)):
         | 
| 426 458 | 
             
                    out += "{}. [[{}]]".format(i + 1, x.name)
         | 
| 427 459 | 
             
                    out += "\n"
         | 
| 428 460 | 
             
                out += "\n"
         | 
| 429 461 |  | 
| 430 | 
            -
                 | 
| 462 | 
            +
                path = "{}/Spaces/{}.md".format(path, space.name)
         | 
| 463 | 
            +
                out = write_source_code_block(space, out, path)
         | 
| 464 | 
            +
             | 
| 465 | 
            +
                with open(path, "w") as f:
         | 
| 431 466 | 
             
                    f.write(out)
         | 
| 432 467 |  | 
| 433 468 |  | 
| @@ -510,7 +545,10 @@ def write_control_action_markdown_report(ms, path, control_action, add_metadata= | |
| 510 545 |  | 
| 511 546 | 
             
                        out += "\n"
         | 
| 512 547 |  | 
| 513 | 
            -
                 | 
| 548 | 
            +
                path = "{}/Control Actions/{}.md".format(path, control_action.label)
         | 
| 549 | 
            +
                out = write_source_code_block(control_action, out, path)
         | 
| 550 | 
            +
             | 
| 551 | 
            +
                with open(path, "w") as f:
         | 
| 514 552 | 
             
                    f.write(out)
         | 
| 515 553 |  | 
| 516 554 |  | 
| @@ -626,7 +664,10 @@ def write_wiring_markdown_report(ms, path, wiring, add_metadata=True): | |
| 626 664 | 
             
                    out += "\n"
         | 
| 627 665 | 
             
                out += "\n"
         | 
| 628 666 |  | 
| 629 | 
            -
                 | 
| 667 | 
            +
                path = "{}/Wiring/{}.md".format(path, wiring.name)
         | 
| 668 | 
            +
                out = write_source_code_block(wiring, out, path)
         | 
| 669 | 
            +
             | 
| 670 | 
            +
                with open(path, "w") as f:
         | 
| 630 671 | 
             
                    f.write(out)
         | 
| 631 672 |  | 
| 632 673 |  | 
| @@ -651,7 +692,10 @@ def write_parameter_markdown_report(ms, path, parameter, add_metadata=True): | |
| 651 692 | 
             
                out += "Domain: {}\n\n".format(param.domain)
         | 
| 652 693 | 
             
                out += "Parameter Class: {}\n\n".format(param.parameter_class)
         | 
| 653 694 |  | 
| 654 | 
            -
                 | 
| 695 | 
            +
                path = "{}/Parameters/{}.md".format(path, param.name)
         | 
| 696 | 
            +
                out = write_source_code_block(param, out, path)
         | 
| 697 | 
            +
             | 
| 698 | 
            +
                with open(path, "w") as f:
         | 
| 655 699 | 
             
                    f.write(out)
         | 
| 656 700 |  | 
| 657 701 |  | 
| @@ -687,7 +731,25 @@ def write_stateful_metrics_markdown_report(ms, path, metric, add_metadata=True): | |
| 687 731 | 
             
                    out += "\n"
         | 
| 688 732 | 
             
                out += "\n"
         | 
| 689 733 |  | 
| 690 | 
            -
                 | 
| 734 | 
            +
                temp = get_source_code(ms, "stateful_metrics", metric.name)
         | 
| 735 | 
            +
                if temp:
         | 
| 736 | 
            +
                    source_code, file_path = temp
         | 
| 737 | 
            +
                    file_path = os.path.relpath(file_path, "{}/Stateful Metrics".format(path))
         | 
| 738 | 
            +
                    out += "## Python Implementation\n"
         | 
| 739 | 
            +
                    out += source_code
         | 
| 740 | 
            +
                    out += "\n"
         | 
| 741 | 
            +
                    out += "Implementation Path (only works if vault is opened at level including the src folder): [{}]({})".format(
         | 
| 742 | 
            +
                        file_path, file_path
         | 
| 743 | 
            +
                    )
         | 
| 744 | 
            +
                    out += "\n"
         | 
| 745 | 
            +
             | 
| 746 | 
            +
                out += "\n"
         | 
| 747 | 
            +
             | 
| 748 | 
            +
                path = "{}/Stateful Metrics/{}.md".format(path, metric.name)
         | 
| 749 | 
            +
             | 
| 750 | 
            +
                out = write_source_code_block(metric, out, path)
         | 
| 751 | 
            +
             | 
| 752 | 
            +
                with open(path, "w") as f:
         | 
| 691 753 | 
             
                    f.write(out)
         | 
| 692 754 |  | 
| 693 755 |  | 
| @@ -742,7 +804,24 @@ def write_metrics_markdown_report(ms, path, metric, add_metadata=True): | |
| 742 804 | 
             
                    out += "{}. [[{}]]".format(i + 1, x.name)
         | 
| 743 805 | 
             
                    out += "\n"
         | 
| 744 806 |  | 
| 745 | 
            -
                 | 
| 807 | 
            +
                temp = get_source_code(ms, "metrics", metric.name)
         | 
| 808 | 
            +
                if temp:
         | 
| 809 | 
            +
                    source_code, file_path = temp
         | 
| 810 | 
            +
                    file_path = os.path.relpath(file_path, "{}/Metrics".format(path))
         | 
| 811 | 
            +
                    out += "## Python Implementation\n"
         | 
| 812 | 
            +
                    out += source_code
         | 
| 813 | 
            +
                    out += "\n"
         | 
| 814 | 
            +
                    out += "Implementation Path (only works if vault is opened at level including the src folder): [{}]({})".format(
         | 
| 815 | 
            +
                        file_path, file_path
         | 
| 816 | 
            +
                    )
         | 
| 817 | 
            +
                    out += "\n"
         | 
| 818 | 
            +
             | 
| 819 | 
            +
                out += "\n"
         | 
| 820 | 
            +
             | 
| 821 | 
            +
                path = "{}/Metrics/{}.md".format(path, metric.name)
         | 
| 822 | 
            +
                out = write_source_code_block(metric, out, path)
         | 
| 823 | 
            +
             | 
| 824 | 
            +
                with open(path, "w") as f:
         | 
| 746 825 | 
             
                    f.write(out)
         | 
| 747 826 |  | 
| 748 827 |  | 
    
        math_spec_mapping/__init__.py
    CHANGED
    
    
| @@ -1,12 +1,12 @@ | |
| 1 | 
            -
            math_spec_mapping/__init__.py,sha256= | 
| 1 | 
            +
            math_spec_mapping/__init__.py,sha256=7fGuxoSDYl61z0PZ_PzS6x5P8l174gOzobI9u0aoLVw,1260
         | 
| 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=D-UNvG7kYJa3iVgBH9KUaaldnFL4RVjCQQvrjjm00k4,20082
         | 
| 6 6 | 
             
            math_spec_mapping/Classes/BoundaryAction.py,sha256=_rFvEZ4LNxmlM59js4SuQ9n5CgVmITw4YWKs0-q0r-4,560
         | 
| 7 7 | 
             
            math_spec_mapping/Classes/ControlAction.py,sha256=4AzMSA8fbnUf-fGlvMJXHJFbz32G1h1QVWf2yzrXrLA,493
         | 
| 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=GVyRz_a-afJcmj3W5fqqFYlX1YmxpmbjLFdLpFZGN60,51282
         | 
| 10 10 | 
             
            math_spec_mapping/Classes/Mechanism.py,sha256=2sLm3wYBIeTQaMBcsJ9btqIWsbS895Ra8NY6Y9_G_Dg,379
         | 
| 11 11 | 
             
            math_spec_mapping/Classes/Metric.py,sha256=iQhH4g8Z60QlM22nPX9ytGmidOsZSiSs0KjqwmsScwU,636
         | 
| 12 12 | 
             
            math_spec_mapping/Classes/Parameter.py,sha256=ZuJ_w0sChvRElJ4sOnXZ2EV4Ell2xXFulKLjVOpgz2E,1237
         | 
| @@ -20,8 +20,8 @@ math_spec_mapping/Classes/__init__.py,sha256=0zxgOqns_9JybD74HKMVh6aw8ij8WVbfQ4Q | |
| 20 20 | 
             
            math_spec_mapping/Convenience/__init__.py,sha256=BEZr1rXohKAknOa3wjNVx3EvSVxDcfftJsvtSw5mvmQ,264
         | 
| 21 21 | 
             
            math_spec_mapping/Convenience/documentation.py,sha256=1ziWVJznbCUxeAAt03nAdEYtMlXNo5TeedHfgs0vSBU,1625
         | 
| 22 22 | 
             
            math_spec_mapping/Convenience/github.py,sha256=Wddr1FCxcIxaFeiKyvx3mvVDbzjcgTxs4rU8ulc4qXk,3539
         | 
| 23 | 
            -
            math_spec_mapping/Convenience/starter.py,sha256= | 
| 24 | 
            -
            math_spec_mapping/Load/__init__.py,sha256= | 
| 23 | 
            +
            math_spec_mapping/Convenience/starter.py,sha256=dD1R9wcVFZV-BCTflxNkR6Ay6NF1TlVBdIaWmbJwMGE,17379
         | 
| 24 | 
            +
            math_spec_mapping/Load/__init__.py,sha256=QfHMLatZAKqj4up-LkDL_r42tO7Mo_-qdqPQYLYY5l0,49
         | 
| 25 25 | 
             
            math_spec_mapping/Load/action_transmission_channel.py,sha256=9Wer7g2s5SSOcUYuZ0PqSKUVVnW3EvGQJZNXJTwW__0,2561
         | 
| 26 26 | 
             
            math_spec_mapping/Load/boundary_actions.py,sha256=cDN0pjkkWfYY3HHmgSrD__-weGD4DXElnG8w1pRc5Lc,2933
         | 
| 27 27 | 
             
            math_spec_mapping/Load/control_actions.py,sha256=Y9LeEJuVj2OwxdTfnHZ57UV48j6PYCfyQWux4uXp1Mo,2371
         | 
| @@ -29,12 +29,13 @@ math_spec_mapping/Load/displays.py,sha256=uQvs0Jhp8-9SXGex8SG3ibxHJu7ahAV3xLeBFb | |
| 29 29 | 
             
            math_spec_mapping/Load/entities.py,sha256=Ds7VQY_govWEn1vSHYVrLa8IadSNyOQzaCK18JPYPKk,1289
         | 
| 30 30 | 
             
            math_spec_mapping/Load/general.py,sha256=2q6aGKxXhebiHHTZhtACvM4nWIkTben0o5rXuvfv2Vw,4463
         | 
| 31 31 | 
             
            math_spec_mapping/Load/implementations.py,sha256=a8YvumnyQvrnCo-o52Rv4yU8D7nmkMrV1iIA15fr6Bw,490
         | 
| 32 | 
            -
            math_spec_mapping/Load/load.py,sha256= | 
| 32 | 
            +
            math_spec_mapping/Load/load.py,sha256=Cm1IP_jIzWNGFVPcb1OOfQQYSNgyIfUdT--v1D1dkKE,2797
         | 
| 33 33 | 
             
            math_spec_mapping/Load/mechanism.py,sha256=VRjkR2McsSJh2oq8n9JkeewirdlVjPRA-T5SRSKWPPQ,2293
         | 
| 34 34 | 
             
            math_spec_mapping/Load/metrics.py,sha256=CcVM0_aN-aPnH5_AyEKzFCJGPbgMb0brw5nECsdNVeU,3936
         | 
| 35 35 | 
             
            math_spec_mapping/Load/parameters.py,sha256=W4utm7to3s2fo4z3XgLH0TM1agaIad1qfM2I-lLMua4,1393
         | 
| 36 36 | 
             
            math_spec_mapping/Load/policy.py,sha256=QTIcslHKgdYjjG69cqkJbW20CPvEL-B8R5u51rd2Puo,2697
         | 
| 37 37 | 
             
            math_spec_mapping/Load/spaces.py,sha256=5nJto38BVMED5KuMXOqavYj8gcSTKiNSTdMOOp5ThTA,1186
         | 
| 38 | 
            +
            math_spec_mapping/Load/spec_tree.py,sha256=4If9twlH30tDFxmZSRkwrRnfLlG_dTWOHbzvVrn42Bg,2481
         | 
| 38 39 | 
             
            math_spec_mapping/Load/state_update_transmission_channels.py,sha256=FJWp5n4HdtHAfof5BUQ6BnRakljatL2h8dWCapaVSc0,2238
         | 
| 39 40 | 
             
            math_spec_mapping/Load/stateful_metrics.py,sha256=3Lq1ZGMaDd5OcGeqR2p5c_znkYw7ETTNPFjUVdZAHKk,2384
         | 
| 40 41 | 
             
            math_spec_mapping/Load/states.py,sha256=3YurI7eTNkN6nrXRFVrc58wH0VfM22XOuWE07HVpR7Y,1365
         | 
| @@ -45,7 +46,7 @@ math_spec_mapping/Reports/boundary_actions.py,sha256=45BPp4QjWdD-3E9ZWwqgj_nI2-Y | |
| 45 46 | 
             
            math_spec_mapping/Reports/control_actions.py,sha256=NksekZKIPFSIkubttFstKFthc5AU9B9PWRLSl9j1wWs,1216
         | 
| 46 47 | 
             
            math_spec_mapping/Reports/general.py,sha256=WOOn6Wlb8M4fsdN49FlKLwOka6vJPQ9aCUy88TL2ki0,1610
         | 
| 47 48 | 
             
            math_spec_mapping/Reports/html.py,sha256=RpyQQON8pDnMmfcyxOsm8UAD5Ad8VKnnW-OyOarTmzA,9711
         | 
| 48 | 
            -
            math_spec_mapping/Reports/markdown.py,sha256= | 
| 49 | 
            +
            math_spec_mapping/Reports/markdown.py,sha256=ErQYnMtl1yxvFVS1Y4AuhifQYEmEab-75HN5kVRFAMo,30114
         | 
| 49 50 | 
             
            math_spec_mapping/Reports/mechanisms.py,sha256=d2Rxt3JBYvqAOAYUynl0buYVoXEHrO8EGq7GK6hK8NA,1322
         | 
| 50 51 | 
             
            math_spec_mapping/Reports/node_map.py,sha256=FdSMDQG16NX6n9sZcH-T5xwsvgjrV9OqBHc9J_VlNK0,3129
         | 
| 51 52 | 
             
            math_spec_mapping/Reports/parameters.py,sha256=-ucL71lolqU0xvV7yb0sXl4pFMRl5tXNWdoBfUjLOaQ,1944
         | 
| @@ -54,8 +55,8 @@ math_spec_mapping/Reports/spaces.py,sha256=-76hR5wQBv4lsG000ypBJ-OprjsNjI-rNRMYd | |
| 54 55 | 
             
            math_spec_mapping/Reports/state.py,sha256=QYeCvX5cHeZBrbvMeDsTqJcUDTuDFJSLvPbasjLspk8,3643
         | 
| 55 56 | 
             
            math_spec_mapping/Reports/tables.py,sha256=O0CNuqh3LMECq5uLjBOoxMUk5hUvkUK660FNnwWUxDY,1505
         | 
| 56 57 | 
             
            math_spec_mapping/Reports/wiring.py,sha256=u9SvKWy6T-WJUEgFI6-zgZanoOaTTs_2YwmEceDLsV8,1618
         | 
| 57 | 
            -
            math_spec_mapping-0.3. | 
| 58 | 
            -
            math_spec_mapping-0.3. | 
| 59 | 
            -
            math_spec_mapping-0.3. | 
| 60 | 
            -
            math_spec_mapping-0.3. | 
| 61 | 
            -
            math_spec_mapping-0.3. | 
| 58 | 
            +
            math_spec_mapping-0.3.18.dist-info/LICENSE,sha256=ObyEzSw8kgCaFbEfpu1zP4TrcAKLA0xhqHMZZfyh7N0,1069
         | 
| 59 | 
            +
            math_spec_mapping-0.3.18.dist-info/METADATA,sha256=hQL3NZ1h1AWYGEQvanepfsOHymyzJbwks-puwjMI0Ho,6498
         | 
| 60 | 
            +
            math_spec_mapping-0.3.18.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
         | 
| 61 | 
            +
            math_spec_mapping-0.3.18.dist-info/top_level.txt,sha256=AImhn9wgazkdV0a9vfiphtQR8uGe2nq-ZIOp-6yUk9o,18
         | 
| 62 | 
            +
            math_spec_mapping-0.3.18.dist-info/RECORD,,
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         |