Club PA 2.0 has arrived! If you'd like to access some extra PA content and help support the forums, check it out at patreon.com/ClubPA
The image size limit has been raised to 1mb! Anything larger than that should be linked to. This is a HARD limit, please do not abuse it.
Our new Indie Games subforum is now open for business in G&T. Go and check it out, you might land a code for a free game. If you're developing an indie game and want to post about it, follow these directions. If you don't, he'll break your legs! Hahaha! Seriously though.
Our rules have been updated and given their own forum. Go and look at them! They are nice, and there may be new ones that you didn't know about! Hooray for rules! Hooray for The System! Hooray for Conforming!

[Programming] Thread: Fixed last bug in 5 month thread

12357100

Posts

  • ecco the dolphinecco the dolphin Registered User regular
    Sometimes I wonder if the reason I name my variables relatively verbosely (e.g. rowIndex, pDataBuffer) is an automatic knee-jerk reaction to seeing variables named stuff like mpzhq, ii, hyp.

    Even in context, it is not immediately obvious what they are...

    Penny Arcade Developers at PADev.net.
  • KamiroKamiro Registered User regular
    At my first job, I worked on a pretty old C++ project. Among many baffling things that this old program did, my favorite was the 8000+ case switch statement.

    It went something like this:
    
    topFunctionId = functionId % 1000;
    switch topFunctionId
    {
       case 0:
            int middleFunctionId = topFunctionId % 100;
            switch middleFunctionId
            {
                 case 0:
                      int lowerFunctionId = middleFunctionId % 10;
                      switch lowerFunctionId
                      {
                            case 0:
                                doFunction1(param1, param2);
                                break;
                            case 1:
                                doFunction2(param1, param2);
                                break;
                            case 2:
                               doFunction3(param1, param2);
                               break;
                            ...
                      }
                 case 1:
                 case 2:
                 ...
            }
            break;
       case 1:
       case 2:
       ...
    }
    
    

    That sure was fun to maintain. We eventually got the go ahead to rewrite it into something that was much more useable and sane to read. a dictionary of <int, function pointer>! Who've thought?

  • ecco the dolphinecco the dolphin Registered User regular
    Looks like an ioctl() or something that went dramatically off the rails.

    Penny Arcade Developers at PADev.net.
  • LD50LD50 Registered User regular
    Sometimes I wonder if the reason I name my variables relatively verbosely (e.g. rowIndex, pDataBuffer) is an automatic knee-jerk reaction to seeing variables named stuff like mpzhq, ii, hyp.

    Even in context, it is not immediately obvious what they are...

    Meh, you should be naming all your variables after superheroes and religious figures.

    ecco the dolphinbowen
  • ecco the dolphinecco the dolphin Registered User regular
    LD50 wrote: »
    Sometimes I wonder if the reason I name my variables relatively verbosely (e.g. rowIndex, pDataBuffer) is an automatic knee-jerk reaction to seeing variables named stuff like mpzhq, ii, hyp.

    Even in context, it is not immediately obvious what they are...

    Meh, you should be naming all your variables after superheroes and religious figures.

    Like
    m_OtherTeresa;
    pLasticMan;
    static shock;
    

    ?

    Penny Arcade Developers at PADev.net.
    KamiroMNC DoveradmanbmightyjongyocrimsoncoyoteCarpyIncindiumDelmainLD50djmitchellajjae2123bowenPolaritieurahonkyTofystedethInfidelironsizide
  • ecco the dolphinecco the dolphin Registered User regular
    Ecco's moment of Friday duuuuuuuuh

    Ecco: "Man, I can't tell if this memory dump actually contains measured data from our ADCs, or just random memory corrupted garbage."

    An hour of frustrated debugging later getting nowhere...

    Ecco: "Oh, hang on, I can send in a known pattern into the signal to easily tell the different between corrupted data and actual measurements."

    Penny Arcade Developers at PADev.net.
  • templewulftemplewulf The Team Chump USARegistered User regular
    Does anyone have any Rails recommendations for:
    • datepicker gems compatible with Foundation
    • Reporting

    We only need a couple of simple reports so far, but I was hoping there'd be a gem that generates pages for Form/Run Report/View Report. Like how Rails generates Edit/Update and New/Create actions auto-magically.

    Twitch.tv/FiercePunchStudios | PSN | Steam | Discord | SFV CFN: templewulf
  • bowenbowen How you doin'? Registered User regular
    LD50 wrote: »
    Sometimes I wonder if the reason I name my variables relatively verbosely (e.g. rowIndex, pDataBuffer) is an automatic knee-jerk reaction to seeing variables named stuff like mpzhq, ii, hyp.

    Even in context, it is not immediately obvious what they are...

    Meh, you should be naming all your variables after superheroes and religious figures.

    Funny, my initial reaction to mpzhq was Mister Mxyzptlk.

    Ladies.
  • EtheaEthea Registered User regular
    edited March 2015
    Kamiro wrote: »
    At my first job, I worked on a pretty old C++ project. Among many baffling things that this old program did, my favorite was the 8000+ case switch statement.

    It went something like this:
    
    topFunctionId = functionId % 1000;
    switch topFunctionId
    {
       case 0:
            int middleFunctionId = topFunctionId % 100;
            switch middleFunctionId
            {
                 case 0:
                      int lowerFunctionId = middleFunctionId % 10;
                      switch lowerFunctionId
                      {
                            case 0:
                                doFunction1(param1, param2);
                                break;
                            case 1:
                                doFunction2(param1, param2);
                                break;
                            case 2:
                               doFunction3(param1, param2);
                               break;
                            ...
                      }
                 case 1:
                 case 2:
                 ...
            }
            break;
       case 1:
       case 2:
       ...
    }
    
    

    That sure was fun to maintain. We eventually got the go ahead to rewrite it into something that was much more useable and sane to read. a dictionary of <int, function pointer>! Who've thought?

    I would have though an array of function pointers, with the functionId is the index ( if the range of ids is fairly continuos ). Any no-op functions would be replaced with a function pointer to an error function.

    Edit: Don't post before you finish your first coffee of the day.

    Ethea on
  • urahonkyurahonky Registered User regular
    Jesus mother of fuck. Fuck migrations. Fuck databases. Fuck versioning.

  • EndEnd Registered User regular
    I really hate soap

    I wish that someway, somehow, that I could save every one of us
    zaleiria-by-lexxy-sig.jpgsteam~tinythumb.png
    an_alt
  • urahonkyurahonky Registered User regular
    Got ZERO sleep last night. I kept dreaming about work... Waking up and thinking "Okay stop dreaming about work dream about something else" and it was the same thing. As soon as work crept in I woke up.

    Geth
  • InfidelInfidel Heretic Registered User regular
    I took the afternoon off and went to the spa with my GF, got a massage.

    Email? Didn't see em until this morning.

    Sorry honky. :hydra:

    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
    crimsoncoyoteecco the dolphin
  • urahonkyurahonky Registered User regular
    You son of a...

    It doesn't help that my back is having some major problems right now.

  • IncindiumIncindium Registered User regular
    edited March 2015
    Geth evidently enjoys seeing you suffer honky :(

    Incindium on
    steam_sig.png
    Nintendo ID: Incindium
    Hex TCG: Incindium
    PSN: IncindiumX
  • urahonkyurahonky Registered User regular
    Yeah. Me and him aren't talking right now.

  • Jimmy KingJimmy King Registered User regular
    urahonky wrote: »
    Jesus mother of fuck. Fuck migrations. Fuck databases. Fuck versioning.

    I've got to ask what problems you're running into. I probably don't have a good solution, but db migration gotchas are something I'm always on the lookout for. Especially now that we're doing more multiple backend dev per project stuff.

  • urahonkyurahonky Registered User regular
    Jimmy King wrote: »
    urahonky wrote: »
    Jesus mother of fuck. Fuck migrations. Fuck databases. Fuck versioning.

    I've got to ask what problems you're running into. I probably don't have a good solution, but db migration gotchas are something I'm always on the lookout for. Especially now that we're doing more multiple backend dev per project stuff.

    It's primarily related to cleanerversions that we're using in django. If I have to convert a field from something like "models.ManyToManyField()" to "VersionedManyToMany()" it always takes like 45 minutes to get it back to a stable state. On top of that I have to drop the table and then recreate it.

  • urahonkyurahonky Registered User regular
    So the steps are:
    1. Notice I need to change from a standard model to Version model.
    2. Cry.
    3. Comment out every instance of the model. Hope/Pray it isn't used in every single util/view file.
    4. Run makemigrations.
    5. Run migrate.
    6. Convert model to Versioning.
    7. Run makemigrations.
    8. Run migrate.
    9. Uncomment out all of the code that called the mode previously.
    10. Hope/pray your unit tests still pass.

  • bowenbowen How you doin'? Registered User regular
    urahonky wrote: »
    Got ZERO sleep last night. I kept dreaming about work... Waking up and thinking "Okay stop dreaming about work dream about something else" and it was the same thing. As soon as work crept in I woke up.

    I dreamed that there was 4 relatively large meteors that were hitting in my general area.

    They hit every building around me but mine.

    I was still tasked with working on this stupid program.

    Dreams.

    Ladies.
    urahonkyInfidelPolaritieadmanbVegemyte
  • urahonkyurahonky Registered User regular
    Damn.

    bowen
  • bowenbowen How you doin'? Registered User regular
    I also didn't get a good video recording of them because for some reason I couldn't figure out how to record video on my iphone.

    So I couldn't even be youtube cool.

    Ladies.
  • InfidelInfidel Heretic Registered User regular
    You'll never be Youtube cool.

    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
    urahonkyEvigilantbowen
  • Joe KJoe K Registered User regular
    Ethea wrote: »
    Kamiro wrote: »
    At my first job, I worked on a pretty old C++ project. Among many baffling things that this old program did, my favorite was the 8000+ case switch statement.

    It went something like this:
    
    topFunctionId = functionId % 1000;
    switch topFunctionId
    {
       case 0:
            int middleFunctionId = topFunctionId % 100;
            switch middleFunctionId
            {
                 case 0:
                      int lowerFunctionId = middleFunctionId % 10;
                      switch lowerFunctionId
                      {
                            case 0:
                                doFunction1(param1, param2);
                                break;
                            case 1:
                                doFunction2(param1, param2);
                                break;
                            case 2:
                               doFunction3(param1, param2);
                               break;
                            ...
                      }
                 case 1:
                 case 2:
                 ...
            }
            break;
       case 1:
       case 2:
       ...
    }
    
    

    That sure was fun to maintain. We eventually got the go ahead to rewrite it into something that was much more useable and sane to read. a dictionary of <int, function pointer>! Who've thought?

    I would have though an array of function pointers, with the functionId is the index ( if the range of ids is fairly continuos ). Any no-op functions would be replaced with a function pointer to an error function.

    Edit: Don't post before you finish your first coffee of the day.

    Honestly, it looks like a good reason to break out the GOTO statement....

  • PolaritiePolaritie Sleepy Registered User regular
    Joe K wrote: »
    Ethea wrote: »
    Kamiro wrote: »
    At my first job, I worked on a pretty old C++ project. Among many baffling things that this old program did, my favorite was the 8000+ case switch statement.

    It went something like this:
    
    topFunctionId = functionId % 1000;
    switch topFunctionId
    {
       case 0:
            int middleFunctionId = topFunctionId % 100;
            switch middleFunctionId
            {
                 case 0:
                      int lowerFunctionId = middleFunctionId % 10;
                      switch lowerFunctionId
                      {
                            case 0:
                                doFunction1(param1, param2);
                                break;
                            case 1:
                                doFunction2(param1, param2);
                                break;
                            case 2:
                               doFunction3(param1, param2);
                               break;
                            ...
                      }
                 case 1:
                 case 2:
                 ...
            }
            break;
       case 1:
       case 2:
       ...
    }
    
    

    That sure was fun to maintain. We eventually got the go ahead to rewrite it into something that was much more useable and sane to read. a dictionary of <int, function pointer>! Who've thought?

    I would have though an array of function pointers, with the functionId is the index ( if the range of ids is fairly continuos ). Any no-op functions would be replaced with a function pointer to an error function.

    Edit: Don't post before you finish your first coffee of the day.

    Honestly, it looks like a good reason to break out the GOTO statement....

    Burn the evil! Clease it with fire and deletes!

    Steam: Polaritie
    3DS: 0473-8507-2652
    Switch: SW-5185-4991-5118
    PSN: AbEntropy
  • Joe KJoe K Registered User regular
    Polaritie wrote: »
    Joe K wrote: »
    Ethea wrote: »
    Kamiro wrote: »
    At my first job, I worked on a pretty old C++ project. Among many baffling things that this old program did, my favorite was the 8000+ case switch statement.

    It went something like this:
    
    topFunctionId = functionId % 1000;
    switch topFunctionId
    {
       case 0:
            int middleFunctionId = topFunctionId % 100;
            switch middleFunctionId
            {
                 case 0:
                      int lowerFunctionId = middleFunctionId % 10;
                      switch lowerFunctionId
                      {
                            case 0:
                                doFunction1(param1, param2);
                                break;
                            case 1:
                                doFunction2(param1, param2);
                                break;
                            case 2:
                               doFunction3(param1, param2);
                               break;
                            ...
                      }
                 case 1:
                 case 2:
                 ...
            }
            break;
       case 1:
       case 2:
       ...
    }
    
    

    That sure was fun to maintain. We eventually got the go ahead to rewrite it into something that was much more useable and sane to read. a dictionary of <int, function pointer>! Who've thought?

    I would have though an array of function pointers, with the functionId is the index ( if the range of ids is fairly continuos ). Any no-op functions would be replaced with a function pointer to an error function.

    Edit: Don't post before you finish your first coffee of the day.

    Honestly, it looks like a good reason to break out the GOTO statement....

    Burn the evil! Clease it with fire and deletes!

    it results in a cleaner implementation better than nested switch statements. which, was probably implemented to alleviate a tangle of nested if's.

    goto's have their (limited) uses, and this is one of them.

  • bowenbowen How you doin'? Registered User regular
    Infidel wrote: »
    You'll never be Youtube cool.

    That's ice cold.

    Ladies.
    iTunesIsEvil
  • EtheaEthea Registered User regular
    I imagined if you used an array of function pointers the result would look something like:
    int topFunctionId = functionId % 1000;
    int middleFunctionId = topFunctionId % 100;
    int lowerFunctionId = middleFunctionId % 10;
    
    lowerFunctionPointers[lowerFunctionId](param1, param2);
    middleFunctionPointers[middleFunctionId](param3, param2);
    topFunctionPointers[topFunctionId](param4, param3);
    

    Mahnmut
  • urahonkyurahonky Registered User regular
    bowen wrote: »
    Infidel wrote: »
    You'll never be Youtube cool.

    That's ice cold.

    http://i.imgur.com/G5NdxmZ.gif

    boweniTunesIsEvil
  • KamiroKamiro Registered User regular
    Ethea wrote: »
    I imagined if you used an array of function pointers the result would look something like:
    int topFunctionId = functionId % 1000;
    int middleFunctionId = topFunctionId % 100;
    int lowerFunctionId = middleFunctionId % 10;
    
    lowerFunctionPointers[lowerFunctionId](param1, param2);
    middleFunctionPointers[middleFunctionId](param3, param2);
    topFunctionPointers[topFunctionId](param4, param3);
    

    That's basically what we did when we got the go ahead to rework it. Except there was no longer a need for all those MODed ids. I was told it had been done that way to make it run faster? I'm not quite sure how a switch statements work in runtime. Is it more like a huge if/else block where it has to hit each case statement, evaluate it, then move on to the next one until it finds the match? Or is it like an array where it can pretty much immediately access the block it needs?

  • InfidelInfidel Heretic Registered User regular
    Kamiro wrote: »
    Ethea wrote: »
    I imagined if you used an array of function pointers the result would look something like:
    int topFunctionId = functionId % 1000;
    int middleFunctionId = topFunctionId % 100;
    int lowerFunctionId = middleFunctionId % 10;
    
    lowerFunctionPointers[lowerFunctionId](param1, param2);
    middleFunctionPointers[middleFunctionId](param3, param2);
    topFunctionPointers[topFunctionId](param4, param3);
    

    That's basically what we did when we got the go ahead to rework it. Except there was no longer a need for all those MODed ids. I was told it had been done that way to make it run faster? I'm not quite sure how a switch statements work in runtime. Is it more like a huge if/else block where it has to hit each case statement, evaluate it, then move on to the next one until it finds the match? Or is it like an array where it can pretty much immediately access the block it needs?

    It's like a binary search / radix sort.

    If you have a switch with 1000 items, it goes from top to bottom until it hits the conditional that matches.

    If you have a switch first on the leading digit (id / 1000, say) then you have only 10 conditionals to exhaust and bam, you're in the correct set of 100.

    Repeat and you get a final switch of 10.

    If you have switch 0 ... 999, it can't assume as much and optimize this. So if I have id = 998, that is 998 failed comparisons it does until it gets there. O(n) growth on indexing functions as the number of functions increase.

    Instead I can do the first switch of 10. Look for my leading 9, ... nope, nope, nope... ahh there it is. Next look in another switch of 10 for the next 9. Done. Switch and look for the 8. In this worse case I did 9 + 9 + 8 = 28 comparisons to find the right branch with my function.

    With functions being added, I still only look at constant-size switches of 10 options. I only add another layer of switches when my functions increase ten-fold. O(log N) growth on indexing.

    Since this lookup is entirely about indexing, taking the O(log N) one makes sense.


    Now, as mentioned, this is similar to radix sorting. Best thing to do (because this is humongous to implement as switch statements and terribad) is to use a data structure that hashes and organizes this way instead, and store function pointers in it. Anything that provides O(log N) access.

    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
  • InfidelInfidel Heretic Registered User regular
    eg. If you don't have sparse index numbers, just use an array and get O(1) lookup! :rotate:

    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
    Ethea
  • Jimmy KingJimmy King Registered User regular
    edited March 2015
    Lol. The office got evacuated today because of fumes from painting or stripping paint or something in part of the building.

    Jimmy King on
    bowen
  • crimsoncoyotecrimsoncoyote Registered User regular
    Sounds like someone wanted an early weekend ;-)

    urahonkybowen
  • EtheaEthea Registered User regular
    Infidel wrote: »
    eg. If you don't have sparse index numbers, just use an array and get O(1) lookup! :rotate:

    And depending on the level of sparseness you can have dummy function pointers for empty entries. The upside for having 3 arrays of function pointers is that it allows for some level of sparseness too.

  • gavindelgavindel The reason all your software is brokenRegistered User regular
    I missed the meeting Tuesday and missed the assignment of work for the next two weeks.

    I am now writing out the seventy two test cases for our system test plan.

    It is a truth of the universe: whoever misses the meeting gets the scut work.


    Infidel
  • urahonkyurahonky Registered User regular
    You know it's the end of the week when there's 4 devs in the room and absolutely no typing is going on.

  • bowenbowen How you doin'? Registered User regular
    urahonky wrote: »
    You know it's the end of the week when there's 4 devs in the room and absolutely no typing is going on.

    Code's compiling.

    Ladies.
    TofystedethPolaritie
  • RendRend Registered User regular
    bowen wrote: »
    urahonky wrote: »
    You know it's the end of the week when there's 4 devs in the room and absolutely no typing is going on.

    Code's compiling.

    zzzzzzzzz-*snort*huh, nnng? ouuhhh.. uh, yeah. ...Um, compiling. Ahem.
    *assorted chair squeaks and creaks before more snoring*

    mightyjongyoecco the dolphinbowenadmanbEvigilant
  • TofystedethTofystedeth veni, veneri, vamoosi Registered User regular
    Speaking of optimizing. If you have some code that looks like this
    string poopy = "buttsbuttsbuttsbutts";
    if(poopy.find("butts"))
    {
        print(poopy.find("butts"));
    }
    else
    {
        print(poopy.find("butts") + 1);
    }
    
    Does the (any/some/most?) compiler see all those identical calls to find and just put them in a variable to use as needed or does it do it each time?

    steam_sig.png
This discussion has been closed.