As was foretold, we've added advertisements to the forums! If you have questions, or if you encounter any bugs, please visit this thread: https://forums.penny-arcade.com/discussion/240191/forum-advertisement-faq-and-reports-thread/

[PROGRAMMING] Pimping Vanilla HL7s by A02-A17 XML Coffeescripts

19495969799

Posts

  • PhyphorPhyphor Building Planet Busters Tasting FruitRegistered User regular
    Also, for fun times, the compiler is allowed to assume that pointers with different fundamental types don't alias (strict aliasing)

    ecco the dolphinASimPerson
  • InfidelInfidel Heretic Registered User regular
    That explains it well, sounds useful and straight-forward.

    Also you don't have much to lose using it because if your compiler doesn't support it then oh well, it just won't optimize with that feature.

    OrokosPA.png
    Play D&D 4e? :: Check out Orokos and upload your Character Builder sheet! :: Orokos Dice Roller
    The PhalLounge :: Chat board for Critical Failures IRC! :: #CriticalFailures and #mafia on irc.slashnet.org
  • PhyphorPhyphor Building Planet Busters Tasting FruitRegistered User regular
    Pretty much, the trick is figuring out where to put it so it can't break things

  • InfidelInfidel Heretic Registered User regular
    That's a given if you're working with C/C++.

    OrokosPA.png
    Play D&D 4e? :: Check out Orokos and upload your Character Builder sheet! :: Orokos Dice Roller
    The PhalLounge :: Chat board for Critical Failures IRC! :: #CriticalFailures and #mafia on irc.slashnet.org
  • DehumanizedDehumanized Registered User regular
    Much like my preferred sorting method, I recommend treating it like a game of darts

  • PhyphorPhyphor Building Planet Busters Tasting FruitRegistered User regular
    Well the main difference is that it breaks things very subtly - only under high optimization and only sometimes

  • bowenbowen How you doin'? Registered User regular
    What kind of gains are you honestly going to see using restrict? I can't see much necessity for it.

    not a doctor, not a lawyer, examples I use may not be fully researched so don't take out of context plz, don't @ me
  • EtheaEthea Registered User regular
    edited May 2013
    bowen wrote: »
    What kind of gains are you honestly going to see using restrict? I can't see much necessity for it.

    less register tension. Without restrict every time you read or write to a pointer you need to copy the value to a register first and modify
    it there. If you know that no other pointer is aliased directly to that pointer you get the benefit of directly changing the pointers value.

    Edited: restrict can cut both ways. You can increase register usage or reduce it. The primary benefit is more room for the compiler to reorder instructions or do vector operations.

    Ethea on
  • InfidelInfidel Heretic Registered User regular
    bowen wrote: »
    What kind of gains are you honestly going to see using restrict? I can't see much necessity for it.

    Pretty huge ones in the right situations, orders of magnitude potentially. Knowing what it is now, it basically would remove a lot of the need to hand-optimize or write assembly critical sections of code. Instead of bastardizing your code in C or ASM you can write it mostly straight-forward while avoiding data dependencies (data hazards).

    It is "fixing" the kinds of things I had to do "magic" for before, I'm not doing anything with that anymore but if I ever go back to it I'll definitely see if restrict is in play.

    OrokosPA.png
    Play D&D 4e? :: Check out Orokos and upload your Character Builder sheet! :: Orokos Dice Roller
    The PhalLounge :: Chat board for Critical Failures IRC! :: #CriticalFailures and #mafia on irc.slashnet.org
  • bowenbowen How you doin'? Registered User regular
    That makes a bit more sense in my mind, thanks you two.

    not a doctor, not a lawyer, examples I use may not be fully researched so don't take out of context plz, don't @ me
  • KakodaimonosKakodaimonos Registered User regular
    Man, I love it when you hit a chunk of code and you're all "Now why in the hell would anyone ever think that would work?"

    Had to spend the morning unwinding all of the changes the new guy made to the python byte packing we do for our message layer.

    And they really don't seem to be teaching new grads how bit shifting works. He was utterly lost when I started explaining how to shift the data into a ulong and unpack it.

  • InfidelInfidel Heretic Registered User regular
    Man, I love it when you hit a chunk of code and you're all "Now why in the hell would anyone ever think that would work?"

    Had to spend the morning unwinding all of the changes the new guy made to the python byte packing we do for our message layer.

    And they really don't seem to be teaching new grads how bit shifting works. He was utterly lost when I started explaining how to shift the data into a ulong and unpack it.

    The majority can't do bitmasking.

    OrokosPA.png
    Play D&D 4e? :: Check out Orokos and upload your Character Builder sheet! :: Orokos Dice Roller
    The PhalLounge :: Chat board for Critical Failures IRC! :: #CriticalFailures and #mafia on irc.slashnet.org
  • EtheaEthea Registered User regular
    Man, I love it when you hit a chunk of code and you're all "Now why in the hell would anyone ever think that would work?"

    Had to spend the morning unwinding all of the changes the new guy made to the python byte packing we do for our message layer.

    And they really don't seem to be teaching new grads how bit shifting works. He was utterly lost when I started explaining how to shift the data into a ulong and unpack it.

    Aren't you just reinterpret casting the memory reference to be a ulong array? Or do you have a non contiguous collection that you need to pack? I normally think of packing as being easier to reason about if you think of raw memory references. So when I have non contiguous items that need to be packed I generally just copy them to contiguous memory and pack that ( unless it becomes a time / memory bottleneck ).

  • bowenbowen How you doin'? Registered User regular
    Bitmasking is a lost technique from when memory was important. Flags seem to have gone the way of the dodo. I still like the concept and like to use it.

    Especially useful when pulling octets from an int based IP address.

    not a doctor, not a lawyer, examples I use may not be fully researched so don't take out of context plz, don't @ me
  • gjaustingjaustin Registered User regular
    bowen wrote: »
    Bitmasking is a lost technique from when memory was important. Flags seem to have gone the way of the dodo. I still like the concept and like to use it.

    Especially useful when pulling octets from an int based IP address.

    I still find bitmasking to be useful in SQL where dynamically declaring columns is not something you want to even think about doing.

  • bowenbowen How you doin'? Registered User regular
    Got an example? Don't think I've ever ran across that gjaustin.

    not a doctor, not a lawyer, examples I use may not be fully researched so don't take out of context plz, don't @ me
  • gjaustingjaustin Registered User regular
    bowen wrote: »
    Got an example? Don't think I've ever ran across that gjaustin.

    Yeah, just let me clean it up so that I'm not posting proprietary code :)

    bowen
  • KakodaimonosKakodaimonos Registered User regular
    Ethea wrote: »
    Man, I love it when you hit a chunk of code and you're all "Now why in the hell would anyone ever think that would work?"

    Had to spend the morning unwinding all of the changes the new guy made to the python byte packing we do for our message layer.

    And they really don't seem to be teaching new grads how bit shifting works. He was utterly lost when I started explaining how to shift the data into a ulong and unpack it.

    Aren't you just reinterpret casting the memory reference to be a ulong array? Or do you have a non contiguous collection that you need to pack? I normally think of packing as being easier to reason about if you think of raw memory references. So when I have non contiguous items that need to be packed I generally just copy them to contiguous memory and pack that ( unless it becomes a time / memory bottleneck ).

    It's a non-contiguous custom data structure. We do a forced pack to send these suckers over the wire so we aren't wasting space when we're trying to drop a few hundred thousand of them out there.

  • gjaustingjaustin Registered User regular
    bowen wrote: »
    Got an example? Don't think I've ever ran across that gjaustin.

    It's really useful when writing a search algorithm and you want to calculate how many hits you have.
    OPEN SearchCursor
        FETCH NEXT FROM SearchCursor INTO @RelevanceExponent, @Term, @MatchType, @MatchTable
        WHILE @@FETCH_STATUS = 0
        BEGIN
    	    -- By flagging a bit in the relevance column, we can track exactly which term caused the hit
    	    -- These hits are then combined with a bitwise OR.  This prevents double counting a hit.
    	    IF (@RelevanceExponent = 31)
    	    BEGIN
    	        -- Special case, since x8000 is actually a negative number we can't get it with the POWER function
    	        SET @RelevanceValue = 0x8000
    	    END
    	    ELSE
    	    BEGIN
    	        SET @RelevanceValue = POWER(2, @RelevanceExponent)
    	    END
        	
        	
    	    IF (@MatchType LIKE 'AND')
    	    BEGIN
    		    -- Later on we'll AND this value against the relevance for a returned row.
    		    -- If the result doesn't still match this value, that means that the row didn't meet all the AND requirements
    		    SET @AndRelevanceMask = @AndRelevanceMask | @RelevanceValue
    	    END
    
    	    IF (@MatchTable = '' OR @MatchTable LIKE 'Foo')
    	    BEGIN
    		    UPDATE @FooIDs
    			    SET Relevance = Relevance | @RelevanceValue
    		    FROM @FooIDs FooIDs
    		    INNER JOIN Foo ON FooIDs.FooID = Foo.FooID
    		    WHERE (Foo.Name LIKE @Term
    				      OR Foo.Abbr LIKE @Term
    				      OR Foo.Description LIKE @Term)
    	    END
    
    	    IF (@MatchTable = '' OR @MatchTable LIKE 'Bar')
    	    BEGIN
    		    UPDATE @BarIDs
    			    SET Relevance = Relevance | @RelevanceValue
    		    FROM @BarIDs BarIDs
    		    INNER JOIN BarON BarIDs.BarID = Bar.BarID
    		    WHERE (Bar.Name LIKE @Term
    				      OR Bar.Abbr LIKE @Term
    				      OR Bar.Description LIKE @Term)
    	    END
            
            -- If we're doing an AND match on a specific table, we can delete unmatched IDs
            -- This doesn't replace the later check, as we could have an AND without a table or multiple AND matches
            IF (@MatchType LIKE 'AND')
            BEGIN
    		IF (@MatchTable LIKE 'Foo')
    		BEGIN
    		    DELETE FROM @FooIDs
    	                WHERE (Relevance & @RelevanceValue) <> @RelevanceValue
    		END
                    IF (@MatchTable LIKE 'Bar')
    		BEGIN
    		    DELETE FROM @BarIDs
    	                WHERE (Relevance & @RelevanceValue) <> @RelevanceValue
    		END
    	END
            
    
    	    FETCH NEXT FROM SearchCursor INTO @RelevanceExponent, @Term, @MatchType, @MatchTable
        END
    

    Then later on:
    SELECT top (@MaxRows)
    	    Foo.Name,
    	    Bar.Description,
    	    dbo.fnBitCount(ISNULL(FooIDs.Relevance, 0)  -- fnBitCount allows us to calculate exactly how many terms were hit by this row
    		    | ISNULL(BarIDs.Relevance, 0)) AS HitCount,
    	    dbo.fnBitCount(ISNULL(FooIDs.Relevance, 0)  -- fnBitCount allows us to calculate exactly how many terms were hit by this row
    		    | ISNULL(BarIDs.Relevance, 0)) / @TermCount AS Relevance
        FROM Data
                  LEFT OUTER JOIN @FooIDs FooIDs
                       ON Data.FooID = FooIDs.FooID
                  LEFT OUTER JOIN @BarIDs BarIDs
                       ON Data.BarID = BarIDs.BarID
    

    bowen
  • InfidelInfidel Heretic Registered User regular
    It really doesn't matter if you use it directly or not.

    If you made it through a four-year Computer Science degree, you should just know this shit conceptually. Engineers know it better in my experience. I can explain it to a non-sciences non-math person without much difficulty.

    The work I've seen submitted in a fourth year course on real-time systems with prereqs of second and third year architecture courses, where you will be doing FPGA logic, and not understanding bitmasking? Shit should be a warcrime.

    How do you expect to do digital circuit logic when you don't even understand bitmasking.

    OrokosPA.png
    Play D&D 4e? :: Check out Orokos and upload your Character Builder sheet! :: Orokos Dice Roller
    The PhalLounge :: Chat board for Critical Failures IRC! :: #CriticalFailures and #mafia on irc.slashnet.org
    bowenmightyjongyo
  • bowenbowen How you doin'? Registered User regular
    @infidel I've noticed less and less people understand how memory even works, meaning how a byte is a collection of bits, so going down a level and understanding bit masking would require those fundamentals first.

    Seems like comp-sci is pumping out high level abstracted coders more than people who understand software as a concept?

    not a doctor, not a lawyer, examples I use may not be fully researched so don't take out of context plz, don't @ me
  • JasconiusJasconius sword criminal mad onlineRegistered User regular
    i have almost no grasp of applied bit-level programming

    but i have an excuse

    i didn't go to college

    Melkster
  • KakodaimonosKakodaimonos Registered User regular
    And then all the recruiters whine that comp-sci graduates don't know the latest Java release or .Net.

    I know my company is somewhat unusual in that we actually need people who understand the low-level abstractions and how to actually write serious high-performance code, but it's still surprising to see how little the new grads know when we interview them.

  • bowenbowen How you doin'? Registered User regular
    Jasconius wrote: »
    i have almost no grasp of applied bit-level programming

    but i have an excuse

    i didn't go to college

    You could probably give a good answer knowing how bits and bytes interact. They didn't teach us in my degree, either, so, I know it's pretty common to not know that kind of thing. Didn't even really teach proper memory management. Just sort of lumped it together with "you know the basics, extrapolate, because we're moving on."

    not a doctor, not a lawyer, examples I use may not be fully researched so don't take out of context plz, don't @ me
  • InfidelInfidel Heretic Registered User regular
    bowen wrote: »
    @infidel I've noticed less and less people understand how memory even works, meaning how a byte is a collection of bits, so going down a level and understanding bit masking would require those fundamentals first.

    Seems like comp-sci is pumping out high level abstracted coders more than people who understand software as a concept?

    Some people are just fine without getting into the lower level knowledge.

    But I do a lot of tutoring and training and establishing concepts on how memory works has always improved grades and competency in general.

    OrokosPA.png
    Play D&D 4e? :: Check out Orokos and upload your Character Builder sheet! :: Orokos Dice Roller
    The PhalLounge :: Chat board for Critical Failures IRC! :: #CriticalFailures and #mafia on irc.slashnet.org
    bowen
  • EtheaEthea Registered User regular
    Ethea wrote: »
    Man, I love it when you hit a chunk of code and you're all "Now why in the hell would anyone ever think that would work?"

    Had to spend the morning unwinding all of the changes the new guy made to the python byte packing we do for our message layer.

    And they really don't seem to be teaching new grads how bit shifting works. He was utterly lost when I started explaining how to shift the data into a ulong and unpack it.

    Aren't you just reinterpret casting the memory reference to be a ulong array? Or do you have a non contiguous collection that you need to pack? I normally think of packing as being easier to reason about if you think of raw memory references. So when I have non contiguous items that need to be packed I generally just copy them to contiguous memory and pack that ( unless it becomes a time / memory bottleneck ).

    It's a non-contiguous custom data structure. We do a forced pack to send these suckers over the wire so we aren't wasting space when we're trying to drop a few hundred thousand of them out there.

    That should be pretty easy than, presuming you are padding the class to be unsigned long aligned.
    const std::size_t itemLength =  sizeof(DataStructure) / sizeof(unsigned long);
    const std::size_t length =  numberOfItems * itemLength;
    unsigned long* storage = new unsigned long[ length ]
    unsigned long* current = storage;
    
    for(std::size_t i=0; i < numberOfItems; ++i)
    {
     DataStructure* item = getDataStructure(i);
     unsigned long* start = reinterpret_cast<unsigned long*>(item);
     std::copy( start, start + itemLength, current );
     curent += itemLength;
    }
    
    

    I am ignoring the possibility of pointers which would make this even more enjoyable.

  • bowenbowen How you doin'? Registered User regular
    Infidel wrote: »
    bowen wrote: »
    @infidel I've noticed less and less people understand how memory even works, meaning how a byte is a collection of bits, so going down a level and understanding bit masking would require those fundamentals first.

    Seems like comp-sci is pumping out high level abstracted coders more than people who understand software as a concept?

    Some people are just fine without getting into the lower level knowledge.

    But I do a lot of tutoring and training and establishing concepts on how memory works has always improved grades and competency in general.

    I think I remember you posting that infographic you made like... 6ish years ago when I was first going through my degree. That really solidified my shaky knowledge, I know that. Either it was you or ecco. I can't remember.

    not a doctor, not a lawyer, examples I use may not be fully researched so don't take out of context plz, don't @ me
  • gjaustingjaustin Registered User regular
    Hah, I just realized something.

    I hope there's no one on the forums called @RelevanceValue, @RelevanceMask, @FooIDs, or @BarIDs. Because I just pinged them 20 times each.

    @IcyLiquid - Would it be possible to get the code tags to ignore the @ logic?

    DelmainInfidelMelkster
  • EtheaEthea Registered User regular
    And then all the recruiters whine that comp-sci graduates don't know the latest Java release or .Net.

    I know my company is somewhat unusual in that we actually need people who understand the low-level abstractions and how to actually write serious high-performance code, but it's still surprising to see how little the new grads know when we interview them.

    So do you guys hire remote workers? :)

  • bowenbowen How you doin'? Registered User regular
    Ethea wrote: »
    And then all the recruiters whine that comp-sci graduates don't know the latest Java release or .Net.

    I know my company is somewhat unusual in that we actually need people who understand the low-level abstractions and how to actually write serious high-performance code, but it's still surprising to see how little the new grads know when we interview them.

    So do you guys hire remote workers? :)

    And is it flex time?

    not a doctor, not a lawyer, examples I use may not be fully researched so don't take out of context plz, don't @ me
  • InfidelInfidel Heretic Registered User regular
    bowen wrote: »
    Infidel wrote: »
    bowen wrote: »
    @infidel I've noticed less and less people understand how memory even works, meaning how a byte is a collection of bits, so going down a level and understanding bit masking would require those fundamentals first.

    Seems like comp-sci is pumping out high level abstracted coders more than people who understand software as a concept?

    Some people are just fine without getting into the lower level knowledge.

    But I do a lot of tutoring and training and establishing concepts on how memory works has always improved grades and competency in general.

    I think I remember you posting that infographic you made like... 6ish years ago when I was first going through my degree. That really solidified my shaky knowledge, I know that. Either it was you or ecco. I can't remember.

    Apparently May 2009 for the "beginner's thread" as I how-do-mine-4-pointers primer.

    Or you might be thinking of something else, I think I've made large posts on that topic a few times. But I think that is the only one I used images for convenience.

    OrokosPA.png
    Play D&D 4e? :: Check out Orokos and upload your Character Builder sheet! :: Orokos Dice Roller
    The PhalLounge :: Chat board for Critical Failures IRC! :: #CriticalFailures and #mafia on irc.slashnet.org
  • PhyphorPhyphor Building Planet Busters Tasting FruitRegistered User regular
    Ethea wrote: »
    Ethea wrote: »
    Man, I love it when you hit a chunk of code and you're all "Now why in the hell would anyone ever think that would work?"

    Had to spend the morning unwinding all of the changes the new guy made to the python byte packing we do for our message layer.

    And they really don't seem to be teaching new grads how bit shifting works. He was utterly lost when I started explaining how to shift the data into a ulong and unpack it.

    Aren't you just reinterpret casting the memory reference to be a ulong array? Or do you have a non contiguous collection that you need to pack? I normally think of packing as being easier to reason about if you think of raw memory references. So when I have non contiguous items that need to be packed I generally just copy them to contiguous memory and pack that ( unless it becomes a time / memory bottleneck ).

    It's a non-contiguous custom data structure. We do a forced pack to send these suckers over the wire so we aren't wasting space when we're trying to drop a few hundred thousand of them out there.

    That should be pretty easy than, presuming you are padding the class to be unsigned long aligned.
    const std::size_t itemLength =  sizeof(DataStructure) / sizeof(unsigned long);
    const std::size_t length =  numberOfItems * itemLength;
    unsigned long* storage = new unsigned long[ length ]
    unsigned long* current = storage;
    
    for(std::size_t i=0; i < numberOfItems; ++i)
    {
     DataStructure* item = getDataStructure(i);
     unsigned long* start = reinterpret_cast<unsigned long*>(item);
     std::copy( start, start + itemLength, current );
     curent += itemLength;
    }
    
    

    I am ignoring the possibility of pointers which would make this even more enjoyable.

    He did say he was packing Python, so I would expect there to be some pointers somewhere

  • bowenbowen How you doin'? Registered User regular
    Infidel wrote: »
    bowen wrote: »
    Infidel wrote: »
    bowen wrote: »
    @infidel I've noticed less and less people understand how memory even works, meaning how a byte is a collection of bits, so going down a level and understanding bit masking would require those fundamentals first.

    Seems like comp-sci is pumping out high level abstracted coders more than people who understand software as a concept?

    Some people are just fine without getting into the lower level knowledge.

    But I do a lot of tutoring and training and establishing concepts on how memory works has always improved grades and competency in general.

    I think I remember you posting that infographic you made like... 6ish years ago when I was first going through my degree. That really solidified my shaky knowledge, I know that. Either it was you or ecco. I can't remember.

    Apparently May 2009 for the "beginner's thread" as I how-do-mine-4-pointers primer.

    Or you might be thinking of something else, I think I've made large posts on that topic a few times. But I think that is the only one I used images for convenience.

    Yeah I think you've done it a few times before that, that's the one that sticks out in my memory though.

    You should make a blog on padev for it.

    not a doctor, not a lawyer, examples I use may not be fully researched so don't take out of context plz, don't @ me
  • EtheaEthea Registered User regular
    Phyphor wrote: »
    Ethea wrote: »
    Ethea wrote: »
    Man, I love it when you hit a chunk of code and you're all "Now why in the hell would anyone ever think that would work?"

    Had to spend the morning unwinding all of the changes the new guy made to the python byte packing we do for our message layer.

    And they really don't seem to be teaching new grads how bit shifting works. He was utterly lost when I started explaining how to shift the data into a ulong and unpack it.

    Aren't you just reinterpret casting the memory reference to be a ulong array? Or do you have a non contiguous collection that you need to pack? I normally think of packing as being easier to reason about if you think of raw memory references. So when I have non contiguous items that need to be packed I generally just copy them to contiguous memory and pack that ( unless it becomes a time / memory bottleneck ).

    It's a non-contiguous custom data structure. We do a forced pack to send these suckers over the wire so we aren't wasting space when we're trying to drop a few hundred thousand of them out there.

    That should be pretty easy than, presuming you are padding the class to be unsigned long aligned.
    const std::size_t itemLength =  sizeof(DataStructure) / sizeof(unsigned long);
    const std::size_t length =  numberOfItems * itemLength;
    unsigned long* storage = new unsigned long[ length ]
    unsigned long* current = storage;
    
    for(std::size_t i=0; i < numberOfItems; ++i)
    {
     DataStructure* item = getDataStructure(i);
     unsigned long* start = reinterpret_cast<unsigned long*>(item);
     std::copy( start, start + itemLength, current );
     curent += itemLength;
    }
    
    

    I am ignoring the possibility of pointers which would make this even more enjoyable.

    He did say he was packing Python, so I would expect there to be some pointers somewhere

    Stop getting in my way of ignoring the facts!

  • bowenbowen How you doin'? Registered User regular
    *snort* memory

    not a doctor, not a lawyer, examples I use may not be fully researched so don't take out of context plz, don't @ me
  • EtheaEthea Registered User regular
    I wonder if you could do some pickle style packing into ulongs, hmmmmm.

  • Jimmy KingJimmy King Registered User regular
    pickle packing. lol.

    Etheabowen
  • bowenbowen How you doin'? Registered User regular
    I do enjoy a good pickle.

    not a doctor, not a lawyer, examples I use may not be fully researched so don't take out of context plz, don't @ me
  • DelmainDelmain Registered User regular
    Infidel wrote: »
    bowen wrote: »
    Infidel wrote: »
    bowen wrote: »
    @infidel I've noticed less and less people understand how memory even works, meaning how a byte is a collection of bits, so going down a level and understanding bit masking would require those fundamentals first.

    Seems like comp-sci is pumping out high level abstracted coders more than people who understand software as a concept?

    Some people are just fine without getting into the lower level knowledge.

    But I do a lot of tutoring and training and establishing concepts on how memory works has always improved grades and competency in general.

    I think I remember you posting that infographic you made like... 6ish years ago when I was first going through my degree. That really solidified my shaky knowledge, I know that. Either it was you or ecco. I can't remember.

    Apparently May 2009 for the "beginner's thread" as I how-do-mine-4-pointers primer.

    Or you might be thinking of something else, I think I've made large posts on that topic a few times. But I think that is the only one I used images for convenience.

    Wait, when was Obs banned?

    syndalis wrote: »
    Apple is a terrible company.
  • bowenbowen How you doin'? Registered User regular
    A looooonnnnng time ago.

    Alts and general trolling. Tube never really got much more in depth than that I don't think. I don't want to ping him because I don't know how annoying that is when people do that to you as a mod.

    not a doctor, not a lawyer, examples I use may not be fully researched so don't take out of context plz, don't @ me
This discussion has been closed.