- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
So now it's bad form to rely on an exception in your standard code path? Picky picky.
Admin
How about just letting the values overwrite each other
foreach(string s in strObj){ UniqueHT[s] = "My CAPTCHA: craaazy"; }
Admin
Ah, the old "use exception handling for non-exceptional logic" trick. That's the third time this week!
Yes, I just got my "Get Smart" DVD set.
Admin
This is so enterprisey I might spring this on my co-workers. I mean it has arbitrarily adding values to an array, Exceptions used for standard processing, and recursion.
Who wouldn't like this solution?
Admin
To get a bit biblical... He who has never used exceptions in this manner, cast the first stone
captcha: Noone gives a rat's ass
Admin
This person was probably translating VB6 code. I believe in VB6 collections did not have .contains, and using On Error Resume Next and checking the error number was the only way to check if the collection had a given key.
.Net has done a lot to prevent using exceptions for flow control. For example they add tryparse for parsing strings into various datatypes in 2.0.
Admin
For those too lazy to google: http://www.codeproject.com/useritems/tips.asp#tip1.12
I like how the snippet has "OOPS" in big letters right underneath.
Funnily enough, found it in standard google search but not code search.
Admin
Admin
The 'contains(value)' solution isn't good either, now your code uses O(n^2) operations, when the original uses just O(n).
Admin
There's no Set object in .Net? In Java we just do:
Done.
Admin
Admin
The real WTF is that you have no idea what you're talking about.
The exception he's using is caused by duplicate keys.
Hashtables have O(1) lookup.
Admin
I believe .Net Hashtables store keys in some sensible (read: tree) data structure rather than just a list; I don't think .ContainsKey does an O(n) pass through the whole list of keys any time. Assuming some kind of balanced binary tree, you're looking at O(n lg n) instead, which is not so bad.
Also, check your math on the original solution -- the recursion adds a heaping helping of extra, wasted computation if there are any duplicated values.
Admin
Exception handling is expensive.. unwinding the stack and all..
Admin
FRIST POST!
THE REAL WTF IS
CAPTCHA: dubya - Mandate of Heaven
Admin
Umm... no.
Admin
Umm, I don't know if it's some kind of a requirement in this case to use hashtables (probably not since it's an example), but I wouldn't if I just needed to find unique values. I'd just use:
List<string> Unique; foreach(string s in strObj) if(! Unique.ContainsKey(s)) Unique.Add(s);
But maybe I'm just stupid. (And in .NET 1.1 I'd just use ArrayList)
Admin
What part of the name "Hashtable" suggests that there is a tree involved?
Admin
even taking the exception-in-ordinary-code-path thing as given, isn't there a bug in the way the exception is handled? if the last item in the array is a dupe, won't the exception "handler" risk advancing the loop counter too far?
or i could be worng, seeing as i still haven't managed my morning cup of coffee yet. gotta get on that problem now.
Admin
Well, it's not such a big deal in many languages. Just because .Net exceptions are SO EXPENSIVE, does not mean catching exceptions in mainstream logic is so horrid.
In Python, for instance, the try to insert then catch if it's there is a somewhat agreed on pattern (with the motto "it's easier to be forgiven than to be granted").
Anyway, the code snippet was a little braindead anyway. And in .Net you should not merrily throw exceptions like this. No huge WTF, just poor code.
Admin
I think I'll take the original programmer over some of these commenters.
Admin
The real WTF is that the Article got a rating of 4/5...
CAPTCHA: pling-pling - spaboing - pling
Admin
Mcoder,
The point of a hashtable is to store data for quick finds later. Based on the hash value, you can jump directly to the "bucket" where the value is stored, you do NOT iterate through. However, you then have to iterate that bucket (Unless it is doubly hashed) until you find the value. This is usually not a problem since that bucket is usually significantly smaller than the total number of elements.
Admin
No. no no no. exceptions do not belong as part of the main flow of a program. just dont do it kids.
Admin
I believe .NET hashtable stores keys in a hashtable. I suggest you do a little research on a hash tables subject.
Admin
Admin
Completely right. I need more coffee this morning...
Admin
Admin
The REAL WTF is these comments.
Seriously WTF.
Admin
Admin
Yes, that's why they're called exceptions - because they're normal occurrences, and not exceptional at all...
Anyone using exception handling as part of the normal control flow of their code on one of my projects is going to have to have an exceptionally good reason, or they're going to be rewriting it.
Admin
Since this is apparently the only* way to identify an empty array, I can't run the application with "break on all errors" set, at least not until I get into my own code.
Admin
There's no Set in .Net? And adding to a HashTable with a previously used key throws an exception?
Anyway, the part I like is calling the function again every time you throw the exception, rather than just skipping that item and continuing the loop.
Admin
I agree. Definitely translated VB6 code.
I hate that thing. I'm having to work on a project that was "upgraded" from VB6 to VB.NET, then thrown into a VB.NET -> C# converter. Furthermore, the "developer" decided that having different Subs / Functions wasn't necessary because they were called all after each other in a predetermined fixed order.
The result... one looooong function of about 1600+ lines of C# code, vaguely resembling VB6 flow.
Admin
I was wondering about that... the way to do it in python >= 2.4 is in one line:
unique = set(astring)
I don't know squat about .NET, but a quick look at msdn suggests that is in fact the case: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemCollectionsHashtableClassAddTopic.asp
even so, surely calling .Contains() or .ContainsKey() would be more idiomatic than checking for the exception.
Admin
I love how people conjecture about what they don't know just to make a point. That should be the real WTF. Just bullshiting here but now let me have a point.
Admin
My gut reaction was pretty much the one proposed by the second smartass, but what's more important, the REAL WTF is, of course C#. Why? Because you can't call a xxx on Dictionary to do the job, like, say d.xxx( key, ... ). No, you have to do d[key] = ..., and it just plain sucks bigtime that exported functionality REQUIRES special syntax (i.e. you can't do it with a plain old function call.)
(Of course this does not wholly excuse the poor sod :) He could have discarded the exception within the iteration, as the next smartass suggested.)
Admin
uhm...
^aCollection asSet.
Smalltalk wins
Admin
hasmaps don't allow duplicate keys for classes that have properly implemented HashCode() (in java and .Net).
the cleaner option is NOT O(n^2) - the very point of a cleanly implemented hash based collection strategy is to speed lookups. If you've not implemented a hashtable/map you won't know this bit of practical information.
Conclusion - your response is as WTF as the original code....
Admin
Here is the best way to do it in .NET 2.0
No need to mess around with the inefficient hashtable class.
Admin
F/OSS using the patent minefield that is .NET? Seems unduly rash!
Admin
Admin
Admin
This is nothing. Back in the dot-com days I worked for a stock trading firm that was writing their own trading system in Java 1.2. If only I remembered any of the code nowadays, I'd send it in, because it totally was WTF quality. One of their 'hallmarks' was a signaling system that was based entirely on exception handling. They would throw exceptions as signals that would hit the parent caller that would then act as an operator to another child process. The best part of the system was that none of it had comments. Our CTO at the time would brag about the sheer complexity of the system, and how something that was so complicated couldn't possibly be so wrong.
throw new CAPTCHAException("Smile! Your code is crap.");
Admin
Oh, what a tragedy!! Poor C# coders are forced to use the same syntax that is used in every other collection in the language on their hash table. Typing a square bracket puts a person through so much suffering. All other aspects of a language which commits such a pernicious evil should be ignored, as they'll surely be overshadowed by a syntax variation.
Admin
All of you that just use library funcions, be remembered that a library function also has to work for its effects. Personally, I would only call a function/solution "bad" if it ends in undefined behaviour or it is significantly slower than another one. Optimization while compiling is your friend. In dubio pro reo.
Anyway, funny idea of the original writer. Wonder if he feels dirty today.
Admin
The last two are hidden by C# but that's what you'll see in the CLI. Properties and default accessors are syntactic sugar that make our lives as developers easier, not harder. Not everybody loves verbosity for the sake of verbosity. Regardless, it's still fully compatible with languages that don't support that uh, "special syntax".
Mind you, only .NET 1.x programmers still use the Hashtable. The .NET 2.0 framework introduced Dictionary<TKey, TValue> which also has the TryGetValue method, a very convenient one that I use extensively.
Really, people need to read more than 3 lines from the first Google search result before they open their mouths.
For any .NET programmers who are really anxious to get sets, or bags, or non-unique dictionaries, etc., just get the free PowerCollections library. Or wait for 3.0 which will have most of these built in for LINQ (and you can run SQL-like queries on them).
Admin
Hashtable does not mention anything about a tree, nor should it, since it's implemented using a hash table.
Admin
If we assume we were using just the letters A-Z, then a simple solution that "inlines" the hashset would be:
bool[26] values = new bool[26]; //all values are false.
foreach(string s in array) { int index = s[0]-'A'; if(values[index]) { values[index] = true; Console.WritLine(s); } }
For anything else, just remember that java and c# every object has the hashcode/Hashcode method. But since hashcodes can collide, we need buckets. If any string value was allowed, then yes, the worst time for this is:O(n^2)
Admin