• ¯\(°_o)/¯ I DUNNO LOL (unregistered) in reply to PiisAWheeL
    PiisAWheeL:
    Ok, putting aside the fact that we have figured out an excellent solution, I think the real wtf is the problem. Under what circumstances would you need to do this conversion UNLESS you are trying to store your state as a tinyint in the db, in which case there is a special place in dante's 4th circle of hell for you. What other purpose would you need to represent a state as a number (an not even an in order number once you get past where ms should be).
    Or better yet...

    if(state == "AL") return 0x414C; if(state == "AK") return 0x414B; if(state == "AZ") return 0x415A;

  • Sigivald (unregistered) in reply to Meme
    Meme:
    More over Why convert to an arbitrary index in the first place?

    Ding.

    Use an enum for the states and then you get an index for free if you ever need one, which you shouldn't.

    Ever.

  • Charlie Dobbie (unregistered) in reply to Larry

    And then someone searched for Tennessee, and got Montana instead.

    Might want to pad your state codes...

  • (cs) in reply to Ben Jammin
    Ben Jammin:
    I hope most of these people responding don't read program requirements like they read comments. It seems like 9 out of 9 comments are saying the same reason why Larry's funny solution doesn't work and the other half are proposing other broken solutions.
    I think it's because some troll with mod powers made Larry's first attempt a featured comment.
  • (cs) in reply to Jack
    Jack:
    Planar:
    TGV:
    This solution is not (much) slower than looking it up in some table. It's only 51 comparisons, whereas an efficient searcher would do, say 7

    What? 2^6 is 64, so a binary search does it in 6 comparisons maximum, 5 average.

    But I'm surprised that nobody has noticed TRWTF: representing the states as numbers. If you're not going to do arithmetic on them, they are not numbers and you shouldn't use numbers to represent them. Shouldn't that be obvious to every TDWTF reader?

    It's returning an index, presumably to some array of data for each "state". Is that so wrong?

    Drastically. You should create an enum and use that as a key into a map, the value of that key being the data array (or whatever data structure). Storing all your data as arrays is so last millennium. Ignorant pricks and stupid cunts do that sort of thing all the time.

  • Gunslinger (unregistered) in reply to Cbuttius
    Cbuttius:
    Anonymous:
    Weird. It's almost like there should be something called ENUMs for this exact use case...

    Yes but I don't think you can automatically "unstringify" enums without writing your own code / table to do so. It would make a great language feature if it were done for you (as well as one to stringify them back).

    So "AR" would convert to the enum AR.

    .Net does this for you, with a .ToString() property of the enum.

  • Steven (unregistered) in reply to Larry
    Larry:
    return index('ALAKAZARCA...', $state) / 2;
    And there goes New Mexico :P
  • Troy (unregistered) in reply to Cbuttius
    Cbuttius:
    Anonymous:
    Weird. It's almost like there should be something called ENUMs for this exact use case...

    Yes but I don't think you can automatically "unstringify" enums without writing your own code / table to do so. It would make a great language feature if it were done for you (as well as one to stringify them back).

    So "AR" would convert to the enum AR.

    Java enums have the handy valueOf() method for this purpose.

  • DarrenC (unregistered)
    /*
     * assumes little-endian integers and ASCII charset
     * captcha: ACSI
     */
    int get_state_index(const char * state)
    {
    	int n;
    	
    	if (!state || strlen(state) != 2) return -1;
    	
    	n = *(const unsigned short *)state;
    	
    	switch (n & 0xdfdf)
    	{
    	
    	case 0x4c41 :	/* AL */
    		return 0;
    
    	case 0x4b41 :	/* AK */
    		return 1;
    		
    	case 0x5a41 :	/* AZ */
    		return 2;
    		
    	case 0x5241 :	/* AR */
    		return 3;
    
    	case 0x4143 :	/* CA */
    		return 4;
    		
    	...
    
    	default :
    		return 51;
    	}
    }
    
  • VAXcat (unregistered) in reply to Larry

    With this method, what happens when he looks for Louisiana, abbreviation LA?

  • derp (unregistered) in reply to Larry

    It's your fault because if I'm using your function, I expect that it would be secure enough to work. Would you want the developers of a 3rd party library to have your attitude?

    TRWTF is writing code that is not resilient to odd inputs okok

  • Illogique (unregistered) in reply to Larry

    Another "too smart for your own good solution" - the code fails miserably with input such as "LA", "KA", "ZA", "ZARCA", etc. I am sure you know that trying to be clever is no substitute for good validation.

  • khedoros (unregistered) in reply to Larry

    Heh.

    And when both "AL" and "LA" return 0, you'll have some fun =)

  • (cs)

    This looks to me like yet another of those "store everything as a number" idiocies.

    Joe: "Why is state converted to an integer?" Bob [with pitying look]: "Because you don't waste space storing strings in the database. Integers are much more efficient. Duh!"

  • (cs) in reply to Muzer
    Muzer:
    * It's not static, meaning you have to create a copy of the class just to call this function, which has no bearing on the class's own variables. * From the looks of the syntax, it's defined *inside* the class definition... imagine scrolling past that lot. * It returns 51 on error instead of a slightly more obvious error code (like -1) - consider writing another function, especially if you're not American (sorry, we don't know how many states your crazy country has) - what was it, 41? 51? You'd have to go back and check.
    * Static means global state which means bad. Albeit, in the case of a method that in itself is not terrible, but read on. It may be true that the method doesn't currently need access to the internals of the class, but that could change in the future and that would affect all code that calls this method. The overhead of creating an object is negligible (insert: past commenters realized before me that the method is private too, refuting this point for me). This is premature optimization. You should generally never have static anything unless absolutely required (i.e., the profiler said so or you're forced to do something stupid that can't be done without global state, presumably because somebody is not smart enough or you don't have enough time).
    • Defining the method inside the class is probably preferable to defining it elsewhere. It looks like C# to me, and Visual Studio (and most editors) will let you fold blocks of code if they're getting in your way (albeit, I prefer to unfold everything myself). Or you can use a decent editor (e.g., Vim) and skip right over it. :)

    • I'm not American (i.e., U.S. resident) so forgive me if I'm missing something, but I assumed the 51 was an unnamed state due to the fact that apparently Puerto Rico is included in the list of states. So it's not necessarily an error. Just an implicit state. Maybe.

    (Surely I'm too lazy to read through 3 pages of stupid comments to look for this already being said)

  • (cs) in reply to Muzer
    Muzer:
    * It's not static, meaning you have to create a copy of the class just to call this function, which has no bearing on the class's own variables. * From the looks of the syntax, it's defined *inside* the class definition... imagine scrolling past that lot. * It returns 51 on error instead of a slightly more obvious error code (like -1) - consider writing another function, especially if you're not American (sorry, we don't know how many states your crazy country has) - what was it, 41? 51? You'd have to go back and check.
    * Static means global state which means bad. Albeit, in the case of a method that in itself is not terrible, but read on. It may be true that the method doesn't currently need access to the internals of the class, but that could change in the future and that would affect all code that calls this method. The overhead of creating an object is negligible (insert: past commenters realized before me that the method is private too, refuting this point for me). This is premature optimization. You should generally never have static anything unless absolutely required (i.e., the profiler said so or you're forced to do something stupid that can't be done without global state, presumably because somebody is not smart enough or you don't have enough time).
    • Defining the method inside the class is probably preferable to defining it elsewhere. It looks like C# to me, and Visual Studio (and most editors) will let you fold blocks of code if they're getting in your way (albeit, I prefer to unfold everything myself). Or you can use a decent editor (e.g., Vim) and skip right over it. :)

    • I'm not American (i.e., U.S. resident) so forgive me if I'm missing something, but I assumed the 51 was an unnamed state due to the fact that apparently Puerto Rico is included in the list of states. So it's not necessarily an error. Just an implicit state. Maybe.

    (Surely I'm too lazy to read through 3 pages of stupid comments to look for this already being said)

  • (cs)

    Sweet, double post. I'm pretty sure I only activated the button once... Thanks, TDWTF. >_>

  • Austin (unregistered) in reply to Larry

    Nope,

    AL == LA == 0

  • (cs)

    Another interesting thing is that Visual Studio's Code Analyzer recommends that any Enum have a value at the very beginning for options that don't fit:

    Public Enum eGender As Integer
       NotSpecified = 0
       Female = 1
       Male = 2
    End Enum
    

    And I also like how easy it is to go back and forth:

    Dim intGender As Integer = CInt(eGender.Male)
    
    Dim objGender As eGender = DirectCast(intGender, eGender)
    
  • (cs) in reply to chubertdev
    chubertdev:
    Another interesting thing is that Visual Studio's Code Analyzer recommends that any Enum have a value at the very beginning for options that don't fit:
    Public Enum eGender As Integer
       NotSpecified = 0
       Female = 1
       Male = 2
    End Enum
    

    And I also like how easy it is to go back and forth:

    Dim intGender As Integer = CInt(eGender.Male)
    
    Dim objGender As eGender = DirectCast(intGender, eGender)
    
    You did NOT just post Visual Basic code to a thread that didn't involve Visual Basic. I know you didn't. That would be unnecessary, cruel torture.

    In C#, it's more or less the same (if a bit nicer, and much less torturous):

    using System;
    
    public enum Gender
    {
        Undefined, // I usually use None, per .NET framework guide.
        Male,
        Female
    }
    
    class Program
    {
        static int Main(string[] args)
        {
            var i = (int)Gender.Male;
            var g = (Gender)i;
            var s = Gender.Female.ToString();
    
            // Enum.Parse() throws if it doesn't match so you
            // may prefer Enum.TryParse() to handle the error
            // more gracefully.
            g = (Gender)Enum.Parse(typeof(Gender), s);
    
            return 0;
        }
    }
    

    Note: Enum.Parse or Enum.TryParse to convert a string to an Enum in any .NET language. n00bs. ;)

  • (cs)
    1. Readability
    2. Case-insensitivity
    3. Background compilation

    It's the future (and also a tangent here). :)

  • (cs) in reply to golddog
    golddog:
    cscastle:
    Another weirdness: The abbreviations use the alphabetical order of the full name of the states. Thus AR comes after AZ, IA comes after IN, etc.

    I wonder if the values are in some database somewhere, and this was an attempt to save db interactions. Originally, when someone had been building up the dbo.States table, they forgot Mississippi until the end, and that just is reflected here.

    Or, the states are ordered by the amount they spend on education or something where Mississippi finishes last.

    Except for education budget, I thought the same thing. If you wanted to be backwards compatible with some ancient system, you might do something just like this.

  • glue (unregistered)

    My favorite part is how calling it with an invalid state will return index 52. Of course.

  • DarrenC (unregistered) in reply to glue
    glue:
    My favorite part is how calling it with an invalid state will return index 52. Of course.

    No, this is future compatibility! When a new state is added, no modifications required!

  • (cs) in reply to xtremezone
    xtremezone:
    * Static means global state which means bad.
    You are obviously either trolling, or you have no idea what "static" means.
  • gary (unregistered) in reply to Coyne
    Coyne:
    This looks to me like yet another of those "store everything as a number" idiocies.

    Joe: "Why is state converted to an integer?" Bob [with pitying look]: "Because you don't waste space storing strings in the database. Integers are much more efficient. Strings belong in ivory towers. ha ha ho!"

    FTFY

    bene there, done that

  • Iain (unregistered) in reply to Ozz
    Ozz:
    Cbuttius:
    refoveo:
    Surely 51 represents the UK, the 51st State of America. plaga
    52nd. Canada is the 51st
    Not according to the New Model Army.

    I think that the The The record Heartland with the chorus "This is the 51st state of the USA" might have been released before NMA's 51st State. I heard the The The one before I heard the NMA one anyway.

  • (cs)

    Storing the states as contiguous numbers should mean you can iterate through them. It's a bit of a WTF in C++ that you cannot properly iterate through an enum wtihout converting to an int and back again. Not sure about other languages.

    Assuming you are not short of space but want something a bit faster, either use a table of 676 entries (26*26) or if you can afford it (and probably can) 65536 which will swiftly turn your two-letter code into a number. Within this table you can default info to null and have the data there for those that exist.

    What I want to know is how the USA will manage things when they declare their 677th state.

  • tchernobog (unregistered) in reply to Larry

    Ugh. Readability aside, you sure there is no overlapping acronym (e.g. "LA" in "ALAK...LA...")? For wants of being clever, sometimes we do nasty stuff...

  • (cs)

    I wouldn't mind if the UK did become the 51st or 52nd or whatever state of the USA if that meant we would all automatically have the rights to work in the USA, where all the cool development takes place.

  • (cs) in reply to Muzer
    Muzer:
    It could be C++... I can't see anything there that would be invalid in C++, and the use of underscores instead of camel case points towards a more Unixy programmer.

    It isn't the valid C++ syntax for private.

  • Tim (unregistered) in reply to Larry

    That won't work.

    There is a state on the list with abbreviation 'LA'.

    In your code, this would be index 0.

    There might be more such examples.

  • (cs) in reply to Cbuttius
    Cbuttius:
    Storing the states as contiguous numbers should mean you can iterate through them. It's a bit of a WTF in C++ that you cannot properly iterate through an enum wtihout converting to an int and back again. Not sure about other languages.
    Java enum:
    for( State currentState : State.values() ) {
     ...
    }
    
    Not sure about C#-enums.
  • (cs)

    It's fun to see that even the MSDN team has to jump through hoops to loop through enumeration values: http://msdn.microsoft.com/en-us/library/system.enum.getvalues.aspx

  • C-Derb (unregistered) in reply to Ben Jammin
    Ben Jammin:
    I hope most of these people responding don't read program requirements like they read comments. It seems like 9 out of 9 comments are saying the same reason why Larry's funny solution doesn't work and the other half are proposing other broken solutions
    I was told there would be no math.
  • Reply to TRWTF (unregistered) in reply to Larry

    states: ..., MN, MO,... string: "...MNMO..."

    Found "NM" at index 22 ((int)(45/2) = (int)22.5 = 22)

    Correct "NM" state at string index 58, state index 29.

    OOPS!

  • Shinobu (unregistered)
    #include <iostream>
    
    unsigned char StateIndex(char const * const StateCode)
    {
    	char const * const Table =
    		"KS\120\20" "NE\0\35"   "MS\0\31" "FL\0\11" "WI\0\61"  "CO\0\6"   "NH\0\36"   "OH\0\43"
    		"NV\0\41"   "OR\0\45"   "KY\0\21" "IN\0\17" "OK\0\44"  "NY\0\42"  "PR\0\47"   "MN\100\27"
    		"CT\0\7"    "WV\0\62"   "HI\0\13" "NC\0\33" "ME\0\25"  "AL\0\2"   "TN\240\53" "AZ\110\4"
    		"SC\0\51"   "MT\0\32"   "CA\14\5" "RI\0\50" "MI\24\26" "IL\0\16"  "GA\0\12"   "AR\0\3"
    		"IA\0\14"   "UT\154\55" "VT\0\57" "LA\0\22" "MA\0\23"  "ID\0\15"  "MO\20\30"  "PA\0\46"
    		"WY\0\63"   "MD\0\24"   "ND\0\34"            "  \0   \0 VA\44\56" "WA\70\60"  "SD\0\52"
    		                        "  \0   \0   \0   \0 NJ\0\37"               "  \0   \0 DE\0\10"
                       "  \0 NM\0\40"             "  \0   \0 TX\0\54"         "  \0 AK\0\1"   "  \0 ";
    	if(!*StateCode) return 0;
    	char const * s = Table + (*StateCode + 23 * StateCode[1] << 2 & 255);
    	while(*(short*)s != *(short*)StateCode)
    	{
    		if(!s[2]) return 0;
    		s = Table + (unsigned char)s[2];
    	}
    	if(StateCode[2]) return 0;
    	return s[3];
    }
    
    int main(int argc, char const * const * argv)
    {
    	if(argc)
    	{
    		argc--;
    		argv++;
    	}
    	while(argc--)
    	{
    		std::cout << *argv << " = " << (int)StateIndex(*argv) << std::endl;
    		argv++;
    	}
    }
  • (cs) in reply to Steven
    Steven:
    Larry:
    return index('ALAKAZARCA...', $state) / 2;
    And there goes New Mexico :P
    We didn't need that state anyways!
  • (cs) in reply to ¯\(°_o)/¯ I DUNNO LOL
    ¯\(°_o)/¯ I DUNNO LOL:
    PiisAWheeL:
    Ok, putting aside the fact that we have figured out an excellent solution, I think the real wtf is the problem. Under what circumstances would you need to do this conversion UNLESS you are trying to store your state as a tinyint in the db, in which case there is a special place in dante's 4th circle of hell for you. What other purpose would you need to represent a state as a number (an not even an in order number once you get past where ms should be).
    Or better yet...

    if(state == "AL") return 0x414C; if(state == "AK") return 0x414B; if(state == "AZ") return 0x415A;

    You sir, are a glutton for pain.

  • duh (unregistered) in reply to Cbuttius
    Cbuttius:
    [quote user="Muzer Well, apart from the obvious:
    • It's not static, meaning you have to create a copy of the class just to call this function, which has no bearing on the class's own variables.

    And it shouldn't be static. Because there is a "this" - the class that stores your lookup table.

    * From the looks of the syntax, it's defined *inside* the class definition... imagine scrolling past that lot. /quote] Unfortunately a feature of languages that don't have header files. However it should be in its own class. You might have a static (dreaded singleton) instance of that class.
    * It returns 51 on error instead of a slightly more obvious error code (like -1) - consider writing another function, especially if you're not American (sorry, we don't know how many states your crazy country has) - what was it, 41? 51? You'd have to go back and check.

    Not found isn't necessarily an error, and they are enumerations. Using an enum would probably be tidier, and a more efficient algorithm for string text to enum. 51 is a perfectly good number of "not found" as an enumeration albeit I would possibly use 0, however it is highly unlikely this list is ever going to change.

    The software is presumably written for internal use and not for international usage so countries that don't have 2 letter states or have a different number of them are irrelevant. Coding for this scenario would be a waste of developer time unless you intend to sell the software.

    Yes, it's only changed 37 times...

  • YeaChoo (unregistered) in reply to Larry

    What if we are looking for AZ in

    WAZAAZ

    wrong index returned.

  • Henry Troup (unregistered)

    Iirc, the USPS web site lists about 73 postal abbreviations.

    I once had an altercation with a QA manager who maintained that DC was not a valid input for the state field. Because it's a "district" not a "state" facepalm

  • Anon (unregistered) in reply to Larry

    That's pretty cool!

  • Moe (unregistered) in reply to Larry

    So LA == 1.5?

    Try:

    return index('AL,AK,AZ,...', $state) / 3;

    (Only what happens if $state isn't in the list?)

  • (cs) in reply to Ozz
    Ozz:
    Cbuttius:
    Ozz:
    Not according to the New Model Army.
    Cromwell's one or the 80s rock band?
    Well, seeing as Cromwell died almost 120 years before the USA got its independence, my money is on the latter. (The US had no real need to fight anyway. If they'd just waited 100 years or so the British would probably have just given it to them, like they did with the rest of their empire.)
    Except that if America had still been part of the British Empire in World War II, Britain wouldn't have ended up owing so much to the United States that it had to liquidate the rest of its empire to pay it off.
  • (cs) in reply to Anonymouse
    Anonymouse:
    xtremezone:
    * Static means global state which means bad.
    You are obviously either trolling, or you have no idea what "static" means.
    "Static" has different meanings in different languages and platforms. In C# or Java, static basically means global state (i.e,. aside from parameters the only other access it has is to global state i.e., static member variables). There doesn't happen to be any global state here, but that's irrelevant. The point is that there's no good reason for this method to be static and it would be a poorer design for it to be.

    http://youtu.be/-FRm3VPhseI

  • Shinobu (unregistered) in reply to xtremezone

    Actually, there is a good reason for this method to be static: it's a mathematically pure function, that is to say that it has no side effects and its return value depends only on its parameters and nothing else. It's bad design for such functions not to be static. For an example of this principle in practice, see for example java.lang.Math. (As a corollary, since mathematically pure functions don't influence global state, static does not imply global state. The reason for this is that Java has no way to declare a method side effect free, so any method, static or not, may or may not influence global state.)

  • Mike (unregistered)

    The USPS says there are actually 65 of those two-letter codes, not 50.

    https://www.usps.com/send/official-abbreviations.htm

  • Captcha (unregistered) in reply to BLs
    BLs:
    Including Puerto Rico isn't all that strange... in the banking industry it's been a common theme in most of my jobs. If you want strange consider my first finance company that had two divisions, domestic and international. Not all that unusual unless you consider that Hawaii was part of the international division yet Canada was part of the domestic division.

    ...And prior to the Treaty of Nerchinsk, the Chinese empire only had one division: The Celestial Dynasty, "All under heaven". Under this system, Mongolia, Tibet, England etc are all historically part of China, just less civilized than the centre.

  • Yariv (unregistered) in reply to Larry
    Larry:
    return index('ALAKAZARCA...', $state) / 2;
    Call that with "LA", I don't think you'll get 17. You could use a separator...

Leave a comment on “Pick-a-State”

Log In or post as a guest

Replying to comment #:

« Return to Article