Пример #1
0
def generate_compound_general(torque,turns,pipe = None):
    """ Uses the old method for constructing a Compound Assembly """
    pipe = validate_assembly_pipe(pipe)
    for wire in [wire for wire in iterwire(reverse= True) if wire['min_od'] <= pipe.max_wireod]:
        spring = classes.Spring(wire, od = pipe.max_wireod, cycles= pipe.cycles)
        ## Strongest a spring can be is when turns is equal to max turns
        ## Max turns is MP / Torque, therefore Torque = MP / Max Turns
        ## 1.05 is a safety factor (increased from 1.015)
        st = spring.mp / turns / 1.05
        ## If outerwire can do all the pulling itself, we won't return it with this method
        ## (generate_single_springs will return it)
        if st >= torque * .95:
            continue
        spring.setlengthbytorque(st)
        #print(torque, st, spring.lift)
        remaining = torque - spring.lift
        maxod = max(od for od in SPRINGOD if od and od < spring.id)
        modmp = turns * remaining / pipe.cyclerating
        inners = [wire for wire in iterwire(reverse = True) if wire['min_od'] <= maxod and wire['mp_base'] > turns * remaining / pipe.cyclerating]
        for inner in inners:
            innerspring = classes.Spring(inner, od = maxod, cycles = pipe.cycles)
            innerspring.setlengthbytorque(remaining)
            assembly = classes.Socket(spring,innerspring)


            if assembly.validate(turns):
                return assembly
    
    ## TODO: Mostly a placeholder; not sure whether to raise Exception if no compounds generated or just return an empty list.
    return []
Пример #2
0
 def test_socket(self):
     """" Tests that sockets compare equally """
     s1 = classes.Socket(classes.Spring())
     s2 = classes.Socket(classes.Spring())
     ## Something is seriously wrong if this first one doesn't pass...
     self.assertEqual(s1, s1)
     self.assertEqual(s1, s2)
Пример #3
0
def build_assemblywrapper_tests():
    """ Separate Area for putting together the tests for test_assemblywrapper """
    ## Test that a Single Spring output results in 1 Assembly with 1 Single-Spring Assembly
    test1 = [
        classes.Spring(),
    ]
    assembly1 = classes.Assembly()
    assembly1.addsocket(classes.Socket(*test1))

    ## Test that a list of springs gets turned into single-spring assemblies
    test2 = [classes.Spring(), classes.Spring()]
    assembly2 = [classes.Assembly() for spring in test2]
    for spring, assembly in zip(test2, assembly2):
        assembly.addsocket(classes.Socket(spring))

    ## Test that a Single Socket output results in 1 Assembly with 1 Socket
    test3 = classes.Socket(classes.Spring())
    assembly3 = classes.Assembly()
    assembly3.addsocket(test3)

    ## Test that list of sockets gets turned into single-socket Assemblies
    test4 = [
        classes.Socket(classes.Spring()),
        classes.Socket(classes.Spring())
    ]
    assembly4 = [classes.Assembly() for socket in test4]
    for socket, assembly in zip(test4, assembly4):
        assembly.addsocket(socket)

    ## Test that a mix of Sockets and Springs gets sorted into their own assemblies (adding sockets for individual springs)
    test5 = [classes.Spring(), classes.Socket(classes.Spring())]
    assembly5 = [classes.Assembly(), classes.Assembly()]
    assembly5[0].addsocket(classes.Socket(test5[0]))
    assembly5[1].addsocket(test5[1])

    ## Test that a single assembly results in the assembly being outputted without change
    test6 = [
        classes.Assembly(),
    ]
    test6[0].addsocket(classes.Socket(classes.Spring()))
    assembly6 = test6[0]

    return [
        (test1, [
            assembly1,
        ]),
        (test2, assembly2),
        (test3, [
            assembly3,
        ]),
        (test4, assembly4),
        (test5, assembly5),
        (test6, [
            assembly6,
        ]),
    ]
Пример #4
0
 def test_od_None(self):
     """ Tests that ommitting od results in min_od specified by the wire """
     for testwire in [.25, .375, .5]:
         with self.subTest(testwire=testwire):
             self.assertEqual(
                 classes.Spring(testwire).od,
                 constants.WIRE[testwire]['min_od'])
Пример #5
0
    def test_addsocket(self):
        """ Tests that Assembly.addsocket works as expected """
        assem = classes.Assembly()
        socket = classes.Socket(classes.Spring())
        assem.addsocket(socket)

        self.assertEqual(len(assem.sockets), 1)
        self.assertEqual(assem.sockets[0], socket)
Пример #6
0
 def test_build_sockets_bad(self):
     """ Bad arguments for build_sockets """
     self.assertRaises(ValueError, methods.build_sockets, [
         classes.Spring(
             wire=.1875,
             od=2.75,
         ),
     ], ["Standard 2 Spring"])
Пример #7
0
def API_setsprings(request):
    data = request.POST
    doorid = data.get("doorid")
    if doorid is None:
        return dhttp.HttpResponseServerError("Not Implemented")
    door = models.Door.objects.filter(doorid=doorid).first()
    if not door:
        return dhttp.HttpResponseBadRequest("Invalid Door ID")
    
    pipeobj = models.Pipe.objects.filter(door = door).first()
    pipesize = data.get("pipe")
    if not pipesize:
        if not pipeobj or not pipeobj.pipediameter:
            return dhttp.HttpResponseBadRequest("Door requires Pipe Size")
        pipesize = pipeobj.pipediameter
    else:
        pipeobj.pipediameter = pipesize

    assembly = data.get("assembly")
    if assembly:
        assembly = json.loads(assembly)
        castings = assembly.get("castings", False)
    if not assembly or not castings:
        return dhttp.JsonResponse({"success":False,"reason":"nocastings"})
    
    doorinstance = dio.to_doorinstance(door)
    doorinstance.pipe.shell = pipesize

    oval.checkdefaults(doorinstance)
    #oval._set_slats(doorinstance)
    
    assemblyinstance = doorinstance.pipe.assembly
    assemblyinstance.clear()
    for casting in castings:
        castingobj = classes.Socket()
        for spring in casting:
            springobj = classes.Spring(wire = float(spring['gauge']), od = float(spring['od']))
            springobj.coils = float(spring['coils'])
            castingobj.addspring(springobj)
        assemblyinstance.addsocket(castingobj)

    if not doorinstance.validatepipeassembly():
        return dhttp.JsonResponse({"success":False,"reason":"badcastings"})

    ## Remove previous springs
    models.Spring.objects.filter(pipe = pipeobj).delete()

    ## Save Springs
    for c,casting in enumerate(assemblyinstance.sockets):
        for i,spring in enumerate(casting.springs):
            models.Spring(pipe = pipeobj, spring_type = models.Spring.TYPE[i][0],
                          outer_diameter = spring.od, wire_diameter = spring.wirediameter,
                          uncoiledlength= spring.uncoiledlength, casting = c).save()

    orderid = door.order.pk
    return dhttp.JsonResponse({"success":True,"target": reverse("orderoverview",args = (orderid,))})
Пример #8
0
def get_all_compounds(pipe = None):
    """ Based on the given pipe, return a list of all 2-Spring Compound sockets that will fit inside.
   
        This only validates that each inner wire will fit inside the outer wire and that 
        the outerwire will fit inside the pipe: it DOES NOT validate that the given
        set of springs will be valid for any given amount of required torque (if at all).
    """
    pipe = validate_assembly_pipe(pipe)
    output = _get_all_compound_springs(pipe = pipe)
    return [classes.Socket(*[classes.Spring(**spring, cycles = pipe.cycles) for spring in springs]) for springs in output]
Пример #9
0
def generate_single_spring(torque, turns, pipe = None):
    """ Generates a list of valid Assemblies """
    pipe = validate_assembly_pipe(pipe)
    od = max([od for od in WIREODINDEX if od <= pipe.max_wireod])
    ## Get a list of springs that will fit inside the OD
    potential_springs = [classes.Spring(wire = wire['wirediameter'], od = od, cycles = pipe.cycles) for wire in WIRE.values() if wire['min_od'] <= od]
    ## Set length of all springs to match torque
    for spring in potential_springs: spring.setlengthbytorque(torque)
    ## Validate springs
    valid_springs = list(filter(lambda spring: spring.validatemaxturns(turns),potential_springs))
    ## Return valid springs
    return valid_springs
Пример #10
0
    def test_compare_assembly(self):
        """ Simple test for compare_assembly """
        a1, a2 = classes.Assembly(), classes.Assembly()
        self.assertEqual(methods.compare_assembly(a1, a2), [])

        s1 = nddmethods.build_sockets([
            classes.Spring(.375),
        ], ["Standard 4 Pipe", "Standard 4 Spring"])[0]
        a1.addsocket(s1)

        self.assertEqual(methods.compare_assembly(a1, a2), [
            Difference("Assembly Extra Socket", (1, s1)),
        ])

        s2 = nddmethods.build_sockets([
            classes.Spring(.3125),
        ], ["Standard 4 Pipe", "Standard 2 Spring"])[0]
        a2.addsocket(s2)

        self.assertEqual(methods.compare_assembly(a1, a2), [
            Difference("Assembly Extra Socket", (1, s1)),
            Difference("Assembly Extra Socket", (2, s2))
        ])
Пример #11
0
 def test_get_all_compound_castings(self):
     """ Tests that get_all_compounds can be safely used without throwing Casting errors. """
     ## Using a None-type pipe allows us to get all possible spring configurations
     pipe = pipecalculations.validate_assembly_pipe(None)
     ## _get_all_compound_springs is a testing/extension method that will avoid generating the Sockets immediately
     ## which allows us to see what Springs (if any) cannot be matched to a Casting configuration
     springs = pipecalculations._get_all_compound_springs()
     for pair in springs:
         with self.subTest(pair=pair):
             ## Cycles is probably unnecessary as we aren't validating here.
             springs = [
                 classes.Spring(**spring, cycles=pipe.cycles)
                 for spring in pair
             ]
             ## See if this raises an exception
             methods.getcasting(*springs)
Пример #12
0
def parsesheet_toDoor(costingsheet: "CostingSheet") -> "NewDadsDoor.Door":
    """ Converts a CostingSheet Instance into a NewDadsDoor.Door """
    ## Convert feet to inches (or otherwise could convert to a string)
    door = nddmethods.basic_torsion_door(costingsheet.width * 12,
                                         costingsheet.height * 12)
    table = get_table_by_name(costingsheet.workbook, "CostsTable")
    ## First item is header list
    _, *rows = table.todicts()

    springs = filter(lambda row: constants.SPRINGRE.match(row['Item']), rows)
    springs = [(constants.SPRINGRE.search(row['Item']), row['Unit/Qty'] * 12)
               for row in springs]
    wires = [
        classes.Spring(wire=fixwire(spring['wire']),
                       od=float(spring['size']),
                       coiledlength=float(length))
        for spring, length in springs
    ]
    castings = _convert_castings(
        filter(lambda row: constants.CASTINGRE.match(row['Item']), rows))
    sockets = nddmethods.build_sockets(wires, castings)
    door.pipe.assembly = sockets

    shaft = list(
        filter(
            lambda row: row['Subcomponent'] == "Assembly" and "Solid Shaft" in
            row['Item'], rows))
    if shaft:
        shaft = shaft[0]
        shaftsize = constants.SHAFTRE.match(shaft['Item']).group("shaftsize")
        shaftsize = Imperial(shaftsize)

    slats = list(
        filter(
            lambda row: row['Subcomponent'] == "Curtain" and "Slats" in row[
                'Item'], rows))
    if slats:
        slats = slats[0]
        curtainslats = door.curtain.slatsections()[0]
        if "528" in slats['Item ID']:
            curtainslats.slat = "2 1/2 INCH FLAT SLAT"
        else:
            curtainslats.slat = "2 7/8 INCH CROWN SLAT"
        curtainslats.slats = slats['Qty']

    return door
Пример #13
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)
Пример #14
0
    def test_compare_socket(self):
        """ Simple test for compare_socket """
        s1, s2 = classes.Socket(), classes.Socket()
        self.assertEqual(methods.compare_socket(s1, s2), [])

        sp1 = classes.Spring(.5)
        s1.addspring(sp1)
        self.assertEqual(methods.compare_socket(s1, s2), [
            Difference("Socket Difference", Difference("Extra Spring",
                                                       (1, sp1)))
        ])

        s2.addspring(sp1)
        self.assertEqual(methods.compare_socket(s1, s2), [])

        c1 = nddmethods.convert_to_casting("Standard 4 Pipe")
        s2.castings.addcasting(c1)
        self.assertEqual(methods.compare_socket(s1, s2), [
            Difference("Socket Difference", Difference("Extra Casting",
                                                       (2, c1)))
        ])
Пример #15
0
def _get_all_compound_springs(pipe = None):
    """ For extension and testing purposes, the body of get_all_compounds was extracted so that its output is Class Agnostic.

        This function returns tuple-pairs of dicts (outer,inner) -> {wire:wirediameter [float], od:wire_od [float]}
    """
    pipe = validate_assembly_pipe(pipe)
    maxindex = max([i for i,od in enumerate(WIREODINDEX) if od <= pipe.max_wireod])
    ## If we can only use the smallest OD, then we can't generate any Compounds
    if maxindex < 1: return []

    output = []

    ## Stop before the smallest OD
    outerods = WIREODINDEX[maxindex:0:-1]
    for out_od in outerods:
        #print()
        #print(out_od)
        out_wires = [wire for wire in WIRE.values() if wire['min_od'] <= out_od]
        for outer in out_wires:
            #print(">>>",outer['wirediameter'])
            outerspring = classes.Spring(wire = outer, od = out_od, cycles = pipe.cycles)

            id = outerspring.id
            #print(">>>>>>>",id)
            ## Try for every possible id
            for in_od in [od for od in WIREODINDEX if od < id]:
                #print(">>>>>>>>>>>",in_od)
                ## Inner Wires are a natural subset of Outer Wires
                in_wires = [wire for wire in out_wires if wire['min_od'] <= in_od]
                for inner in in_wires:
                    #print(">>>>>>>>>>>>>>>",inner['wirediameter'])
                    ospring = dict(wire = outer['wirediameter'], od = out_od)
                    ispring = dict(wire = inner['wirediameter'], od = in_od)

                    output.append((ospring, ispring))
    ## NOTE: I don't think this should ever need to be pared down (i.e.- I don't
    ##       think it will ever produce duplicates) but it's something to keep in mind
    return output
Пример #16
0
"""  NewDadsDoor.tests.utils.methods

    Utilties for testing NewDadsDoor.methods

"""
from NewDadsDoor import classes as c, constants

BUILD_SOCKET_VALUES = [
    (([], []), []),
    (  ## 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,
Пример #17
0
def to_doorinstance(doorobj):
    """ Converts a Django Door Model to a NewDadsDoor Door Instance (as well as all components) """

    if not isinstance(doorobj, models.Door):
        raise ValueError("to_doorinstance only accepts a Door Model instance")

    doorinstance = classes.Door(**doorobj.to_kwargs())

    hood = doorinstance.sethood()

    tracksobj = models.Tracks.objects.filter(door=doorobj.pk).first()

    tracks = doorinstance.settracks()
    if tracksobj:
        doorinstance.bracketplatesize = float(
            tracksobj.brackets.bracket_size
        ) if tracksobj.brackets.bracket_size else tracksobj.brackets.bracket_size
        if tracksobj.outer_angle_height:
            tracks.outer = tracksobj.outer_angle_height
        if tracksobj.inner_angle_height:
            tracks.inner = tracksobj.inner_angle_height
        if tracksobj.wall_angle_height:
            tracks.wall = tracksobj.wall_angle_height

    pipeobj = models.Pipe.objects.filter(door=doorobj.pk).first()
    if pipeobj:
        pipe = doorinstance.setpipe(**pipeobj.to_kwargs())
        assembly = pipe.setassembly()

        springs = models.Spring.objects.filter(pipe=pipeobj.pk)
        castings = sorted(
            list(
                set(spring.casting for spring in springs
                    if spring is not None)))
        for casting in castings:
            ## Instead of referencing spring_type to determine order, we're just going to sort the od
            spngs = sorted(springs.filter(casting=casting),
                           key=lambda spring: spring.outer_diameter,
                           reverse=True)
            spngs = [classes.Spring(**spring.to_kwargs()) for spring in spngs]
            socket = classes.Socket(*spngs)
            assembly.addsocket(socket)

    else:
        pipe = doorinstance.setpipe()
        assembly = pipe.setassembly()

    curtain = doorinstance.setcurtain()
    for slatobj in models.Slats.objects.filter(door=doorobj.pk):
        slats = classes.SlatSection(curtain=curtain, **slatobj.to_kwargs())
        curtain.append(slats)

    bbarobj = models.BottomBar.objects.filter(door=doorobj.pk).first()
    if bbarobj:
        bbar = classes.BottomBar(**bbarobj.to_kwargs())
        curtain.append(bbar)

    accessories = []
    for accessorytype in models.ACCESSORYLIST:
        for accessory in accessorytype.objects.filter(door=doorobj.pk):
            o = {"kind": accessory.kind, "description": accessory.description}
            ## TODO: expand this
            accessories.append(o)

    doorinstance.accessories = accessories
    return doorinstance
Пример #18
0
Tests for the NewDadsDoor.classes module

"""

## Test Target
from NewDadsDoor import classes
## Test Framework
import unittest
## This module
from NewDadsDoor import constants, pipecalculations, methods
## 3rd Party
from alcustoms import measurement

## Basic Springs
INNER1 = classes.Spring()
OUTER1 = classes.Spring(wire=.375, od=3.75)
OUTER2 = classes.Spring(wire=.5, od=5.625)

INNER1.coiledlength = 40
OUTER1.coiledlength = 50

VALIDSOCKETS = [
    classes.Socket(),  ## Empty Socket
    classes.Socket(INNER1),  ## Single Spring (smallest)
    classes.Socket(OUTER1),  ## Single Spring (largest in 4" pipe)
    classes.Socket(OUTER1, INNER1),  ## 4" Duplex
]


class DoorCase(unittest.TestCase):