Example #1
0
 def test_sortcastings(self):
     """ Tests that sort_castings works as expected """
     TESTVALUES = (
         [],  ## Empty does nothing
         ["Standard 4 Pipe", "Standard 4 Spring"
          ],  ## 2 Castings in proper order already (does nothing)
         ["Standard 4 Spring",
          "Standard 4 Pipe"],  ## Same castings reversed (4P -> 4S)
         ["Standard 2 Spring", "Standard 4 Spring",
          "Standard 4 Pipe"],  ## 3 Scrambled Castings (4P -> 2S -> 4S)
         ["Standard 6 Spring",
          "Standard 4 Spring"]  ## Missing Pipe and backwards (4S -> 6S)
     )
     TESTRESULTS = ([], ["Standard 4 Pipe", "Standard 4 Spring"], [
         "Standard 4 Pipe", "Standard 4 Spring"
     ], ["Standard 4 Pipe", "Standard 2 Spring",
         "Standard 4 Spring"], ["Standard 4 Spring", "Standard 6 Spring"])
     for (test, result) in zip(TESTVALUES, TESTRESULTS):
         with self.subTest(test=test, result=result):
             casting = classes.CastingSet()
             casting._castings = [
                 methods.convert_to_casting(c) for c in test
             ]
             resultcasting = classes.CastingSet()
             resultcasting._castings = [
                 methods.convert_to_casting(c) for c in result
             ]
             casting._sortcastings()
             self.assertEqual(casting, resultcasting)
Example #2
0
 def test_castings_equal(self):
     """ Tests that two identical CastingSets evaluate as equal """
     for castings in [
         ("Standard 4 Pipe", "Standard 2 Spring"),  ## Single small spring
         ("Standard 4 Pipe", "Standard 2 Spring",
          "Standard 4 Spring"),  ## Compound Spring
         ("Standard 6 Pipe",
          "Standard 6 Pipe"),  ## Single Large Spring (Probably Unnecessary)
         ("Standard 6 Pipe", "Standard 4 Spring", "Standard 6 Pipe"
          ),  ## Compound Large Springs (Also, probably unnecessary)
     ]:
         with self.subTest(castings=castings):
             c1 = classes.CastingSet(*castings)
             c2 = classes.CastingSet(*castings)
             self.assertEqual(c1, c2)
Example #3
0
def getcasting(*springs):
    """ Attempts to select castings for the given springs """
    if not springs: return None
    nsprings = len(springs)
    springods = sorted([spring.od for spring in springs])
    castings = [
        casting for casting in constants.CASTINGS
        if casting['type'] == "pipe" and casting['springs'] >= nsprings
        and all(od in casting['ods'] for od in springods)
    ]
    ## There's a possibility we don't have a matching casting, so return None
    if not castings:
        return None
    ## We only have just so many casting options at this point... only one is going to work
    pipecasting = castings[0]

    springcastings = []
    for od in springods:
        castings = [
            casting for casting in constants.CASTINGS
            if casting['type'] == "spring" and od in casting['ods']
        ]
        ## As above, maybe we don't have a valid casting: return None
        if not castings:
            return None
        ## Pick the casting with the smallest loss of space
        ## As above,this maya s well be castings[0]
        springcastings.append(
            min(castings, key=lambda casting: casting['innerloss']))
    return classes.CastingSet(pipecasting, *springcastings)
Example #4
0
 def test_castings_not_equal(self):
     """ Tests that two different CastingSets evaluate as inequal """
     for c1, c2 in [
         (("Standard 4 Pipe", "Standard 2 Spring"),
          ("Standard 6 Pipe",
           "Standard 6 Spring")),  ## Completely Different
         (("Standard 4 Pipe", "Standard 2 Spring"),
          ("Standard 2 Spring", "Standard 4 Pipe")),  ## Reverse Order
         (("Standard 4 Pipe", "Standard 2 Spring", "Standard 4 Spring"),
          ("Standard 4 Pipe", "Standard 4 Spring")),  ## Missing Casting
     ]:
         with self.subTest(c1=c1, c2=c2):
             C1 = classes.CastingSet()
             C2 = classes.CastingSet()
             C1._castings = [methods.convert_to_casting(c) for c in c1]
             C2._castings = [methods.convert_to_casting(c) for c in c2]
             self.assertNotEqual(C1, C2)
Example #5
0
 def test_name_to_casting(self):
     """ Tests that the CastingSet object automatically converts names to casting dicts """
     ## Using CASTINGLOOKUP to garauntee the values exist
     for name in list(classes.CASTINGLOOKUP):
         with self.subTest(name=name):
             try:
                 casting = classes.CastingSet(name)
             except Exception as e:
                 self.fail(e, e.message)
             self.assertEqual(classes.CASTINGLOOKUP[name],
                              casting.castings[0])
Example #6
0
    def test_getcasting(self):
        """ Tests the getcasting method for expected values.
        
            The expected output of this method should be inspected if castings are changed or added.
        """
        for result, wires in [
            (["Standard 4 Pipe", "Standard 2 Spring"], [
                (.1875, 2.75),
            ]),
        ]:
            with self.subTest(result=result, wires=wires):
                result = classes.CastingSet(*result)
                springs = [classes.Spring(wire, od=od) for (wire, od) in wires]
                ## socket automatically runs getcasting when casting is False
                socket = classes.Socket(*springs, castings=False)

                self.assertEqual(socket.castings, result)
Example #7
0
    def test_addcasting(self):
        """ Tests that addcasting works as expected """
        cs = classes.CastingSet()
        self.assertEqual(cs.castings, [])

        ## Testing add string
        cs.addcasting("Standard 4 Pipe")
        self.assertEqual(cs.castings, [
            methods.convert_to_casting("Standard 4 Pipe"),
        ])

        ## Testing add "Instance" (technically dict right now, unless it changes in the future)
        spring = methods.convert_to_casting("Standard 4 Spring")
        cs.addcasting(spring)
        self.assertEqual(
            cs.castings,
            [methods.convert_to_casting("Standard 4 Pipe"), spring])

        ## Testing that new Pipe castings replace old ones (highlander rule)
        pipe = methods.convert_to_casting("Standard 6 Pipe")
        cs.addcasting(pipe)
        self.assertEqual(cs.castings, [pipe, spring])
Example #8
0
File: methods.py Project: RB3IT/ndd
 (([], []), []),
 (  ## 2.75 Inch Spring
     ## Test
     ([
         c.Spring(
             wire=.1875,
             od=2.75,
         ),
     ], ["Standard 4 Pipe", "Standard 2 Spring"]),
     ## Result
     [
         c.Socket(c.Spring(
             wire=.1875,
             od=2.75,
         ),
                  castings=c.CastingSet("Standard 4 Pipe",
                                        "Standard 2 Spring"))
     ]),
 (  ## 3.75 Inch Spring
     ## Test
     ([
         c.Spring(
             wire=.3125,
             od=3.75,
         ),
     ], ["Standard 4 Pipe", "Standard 4 Spring"]),
     ## Result
     [
         c.Socket(c.Spring(wire=.3125, od=3.75),
                  castings=c.CastingSet("Standard 4 Pipe",
                                        "Standard 4 Spring"))
     ]),
Example #9
0
def build_sockets(springs, castings):
    """ Builds Sockets from a list of springs and a corresponding list of Castings.
    
        springs should be a list of classes.Spring instances.
        castings should be a list of dictionaries taken from constants.CASTINGS or
        the string ['name'] value taken from that list.
        Returns a list of castings.
        Castings without Springs will simply be discarded.
        At least one Pipe Casting is required if any Springs are passed.
        Every Spring requires a Spring Casting.
        If the Springs and either type of Castings are mismatched (either too many
        of one or not enough) a ValueError is raised.
    """
    if not all(isinstance(spring, classes.Spring) for spring in springs):
        raise TypeError("Springs should be a list of Spring objects.")

    _c = []
    for casting in castings:
        ## Check if castings are strings and try to convert them if necessary.
        casting = convert_to_casting(casting)
        _c.append(casting)
    castings = _c
    del _c

    ## Sort Castings into pipe/spring types
    pipecastings, springcastings = [], []
    for casting in sorted(castings,
                          key=lambda casting: max(casting['ods']),
                          reverse=True):
        if casting['type'] == 'pipe': pipecastings.append(casting)
        else: springcastings.append(casting)

    ## If there are no Springs, we can return an empty list since all
    ## Castings are extra and therefore disregarded
    if not springs: return []
    ## There should be atleast one Pipe Casting
    if len(pipecastings) < 1:
        raise ValueError("At least one Pipe Casting is required")
    ## Every spring should have its own Spring Casting
    if len(springs) != len(springcastings):
        raise ValueError("Insufficient Spring Castings")

    ## Sort Springs by OD, wire, and coiledlength (largest->smallest on all categories)
    springs = sorted(sorted(sorted(springs,
                                   key=lambda spring: spring.coiledlength,
                                   reverse=True),
                            key=lambda spring: spring.wirediameter,
                            reverse=True),
                     key=lambda spring: spring.od,
                     reverse=True)
    sockets = []
    """ Dev Note: Algorithm
        ( While Pipe Casting and Springs:
            Check Socket:
                If no socket: pop Pipe casting
            ( for Springs
                Check Next Spring:
                    Check pipe casting fit
                    Check previous spring fit
                If Next Spring:
                    ( for spring castings
                        Check next Spring Casting fit
                    )
            )
            If not Spring and Spring Casting:
                If Pipe Casting doesn't have a single successful spring:
                    raise Error
                add Socket to output
                clear socket
                continue from beginning
            Pop Spring and Spring Casting
            Add Spring and Spring Casting to Socket
            If no slots open on Socket:
                add Socket to output
                clear socket
        )
    """
    socket = None
    while (socket or pipecastings) and springs:
        if not socket:
            pipecasting = pipecastings.pop(0)
            castingset = classes.CastingSet(pipecasting)
            socket = classes.Socket(castings=castingset)

        spring = None
        springcasting = None
        for pospring in springs:
            ## If pipe casting can't accept the spring, skip it
            if pospring.od not in pipecasting['ods'][len(socket.springs):]:
                continue
            ## If previous spring can't accept the spring, skip it
            if socket.springs and socket.springs[-1].id < pospring.od: continue
            ## Otherwise we can find a spring casting for it
            for pocast in springcastings:
                if pospring.od in pocast['ods']:
                    springcasting = pocast
                    break
            if springcasting:
                spring = pospring
                break

        if not spring or not springcasting:
            ## Socket does not have any springs at all
            if not socket.springs:
                raise ValueError("Mismatched Pipe Casting")
            ## Socket is not a compound: store and restart with no socket
            sockets.append(socket)
            socket = None
            continue

        springs.remove(spring)
        springcastings.remove(springcasting)
        socket.addspring(spring)
        castingset.addcasting(springcasting)

        ## Socket is full: store and restart with no socket
        if len(socket.springs) == socket.castings.maxsprings:
            sockets.append(socket)
            socket = None
            continue

    ## Mismatched Springs
    if springs:
        raise ValueError(f"Mismatched Springs: {springs}")
    ## Mismatched Spring Castings
    if springcastings:
        raise ValueError("Mismatched Spring Castings: {springcastings}")

    ## If there's an open socket, add it to output
    if socket:
        sockets.append(socket)

    return sockets