The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Pref: severity as int - zero worst or best?

I need to categorize some validation faults in a workflow application.  Right now, I've got only two "severities":  stop and review.  The idea here is that a "stop" violation will prevent the user from moving something to the next workflow step, while a "review" violation will let the user move something to the next step, but notify the next person in the workflow to the problem so that it can be reviewed.

Design question - I want to indicate this severity w/ an int field in the DB, though I'll enumerate the severities in code.  So,

0=stop, and 1=review, or 0=review and 1=stop?  Zero is most severe, or least severe?

By extension, I can imagine adding a third severity for "audit" or "info" which would be less severe than "review".  Hopefully, you get the idea.
D. Lambert Send private email
Wednesday, November 15, 2006
 
 
In the Unix world, a return value of zero means that everything worked and no errors occured.
KC Send private email
Wednesday, November 15, 2006
 
 
There are standards for these sorts of things in different industries like telecom. Usually they are configurable by customer so each customer can specify the severity and handling of each error. A simple number won't cut it.
son of parnas
Wednesday, November 15, 2006
 
 
This is entirely specific to this application.  It's an data value used to manage workflow, and the workflow exists only for this app.
D. Lambert Send private email
Wednesday, November 15, 2006
 
 
In high integrity code you should use enumerations, not integers. Your coding problem completely disappears and the software is more readable. In Pascal:

type TReviewState = (stop, review);

Problem solved.
Karel Thönissen Send private email
Wednesday, November 15, 2006
 
 
> This is entirely specific to this application.

Then it doesn't matter, unless you are doing range comparisons, which doesn't make sense for an enum. I would use a string personally.
son of parnas
Wednesday, November 15, 2006
 
 
I would also use a string but these people telling you just to use an enumeration are just talking nonsense. You will probably log the thing to a database or some other destination which doesn't have the concept of an enumeration anyway. This means that you will ultimately have to supply some sort of value. When C# came out with full blown enumerations I was very excited. But then I had to try and figure out how to get them in and out of a database easily and I ended up throwing them out the window. Now I just use constant strings or ints.

But to answer your question, I would use zero as no error and high numbers for more severe errors. It makes sense logically and it doesn't constrain you. You will never want to have an error that is "less" severe than "no error" but you may want to add much more severe errors in the future than what you currently consider the most severe error. If the most severe error is marked with zero, what value do you give something that is even more severe? Negative one?

If you are going to use integer values for errors be sure to leave some gaps. This will allow you to add errors in the future more easily.
anon
Wednesday, November 15, 2006
 
 
"0=stop, and 1=review, or 0=review and 1=stop?  Zero is most severe, or least severe?"

Well, if it were me, I'd use 0 = none, 1 = stop, and 2 = review.  Or 0 = none, 1 = review, and 2 = stop.  Having a "none" value will help you make sure you're not just mixing up "none" with the first value in the enumeration.
Kyralessa Send private email
Wednesday, November 15, 2006
 
 
+1 to Kyralessa.  You need a 'no problem' value, and zero makes a very good 'no problem' value in a 'ProblemSeverity' data entry.

I dislike using 'null' for 'no problem' in this case, because 'null' to me means "we haven't assigned a value yet".
AllanL5
Wednesday, November 15, 2006
 
 
Anon,

You should use a language were enumerations are /not/ broken.

And even if your language does not support symbolic IO for enumerations, you should use them, because manifest immutables all over your code is a maintenance bomb waiting to go off.

In a good language (Ada for example) enumerations also define a class which makes it impossible to mix things up.

Glad we are not working in the same shop.
Karel Thönissen Send private email
Wednesday, November 15, 2006
 
 
One place I worked had Severity 1 (highest) - Severity 4 and Informational as priority ratings.
Cymen
Wednesday, November 15, 2006
 
 
Karel, there are usually much bigger timebombs than "manifest immutables" all over the code. Using constant string values and integers hardly constitutes timebombs in my opinion. But please show me a language that allows something like Oracle or SQL server to natively utilize enumerations without basically relying on some other form of translation in between. The last time I checked, SQL Server had no built in support for Ada enumerations as such. So you may have fewer so-called timebombs in your code but you haven't eliminated timebombs in your database. And the mapping that you must now manually supply hardly seems worth the effort.

Besides, enumerations are fine for well defined values but how about user defined values? As I said before, I was pretty excited about C# having native support for enumerations. But in practice they haven't panned out to be that terribly useful.
anon
Wednesday, November 15, 2006
 
 
Why should be mapping be relevant /at all/, unless you intent to do calculus with the values (which is highly dubious)?

Anon, when was the last time you checked the documentation of Ada or Delphi? I am sure that there are other languages that allow this, e.g. via attributes or RTI.

Both Ada and Delphi have excellent routines for converting enumerated values to either ordinals or identifier strings and v.v. Ada has unique in that it even allows representation clauses. Ada was developed with problems like these in mind. If the system is not multi-language, this can be a complete non-problem by deriving all code from a common unit (Delphi) or package (Ada).

The use of enumerations in Pascal-like lnaguages has more benefits than just removing manifest immutables from the code. There indeed are more time-bombs, but this is the low hanging fruit.
Karel Thönissen Send private email
Wednesday, November 15, 2006
 
 
If ease of use matters, use strings for display, and internally use whatever the hell you want.

People can understand the scale from "info, warning, error" (or "stop" vs "review") but merely using numbers requries them to learn what your choice was. Unless you're in a domain with a universally recognised standard (and if that was the case you wouldn't want to ask people for preferences) avoiding the need to learn the number system is a good thing.

Some people say high numbers are more severe, others say low numbers are more critical - your users can either read the meaning directly, or they can look it up in a table. Which do you think will be more useful in most cases? And remember, it's either not that important, or they're unlikely to have half an hour to hunt down the misplaced manual.

Wednesday, November 15, 2006
 
 
Think of the days of BASIC.
How about:
0  = None
10 = Review
20 = Stop

This allows you to in use the ordering of the number to mean severity and still allow future proofing against adding a new code.
Adrian
Thursday, November 16, 2006
 
 
Thanks.  I'll use ints in the DB, enums in the code, and text values for users.  Severity will be ascending -- 0=no problem, higher numbers=more severe.
D. Lambert Send private email
Thursday, November 16, 2006
 
 
I love the comment about language support for mapping enums to integers or strings.  What a bunch of garbage that would complicate debugging from a query window (which happens in the real, non Ada world all the time.)

I would use 0 for "OK" and positive integers for errors.

If you are creating a system that could be customized, reserve errors below 1000 for "built in" errors and those over 1000 for "custom" errors.

Create another table to map codes to names, perhaps, if you need readable/customized status codes.

Ada, Delphi.. Whatever.  I'm glad I don't work in THAT shop.
Glad I Don't Work in Karel's Shop
Thursday, November 16, 2006
 
 
I would hire you, given your comment.
Karel Thönissen Send private email
Thursday, November 16, 2006
 
 
Oops. I just hired you by accident. Well, then: you are fired! Picking a language because it is simpler to debug, in lieu of a language that is safe by construction. My god.
Karel Thönissen Send private email
Thursday, November 16, 2006
 
 
>Picking a language because it is simpler to debug, in
>lieu of a language that is safe by construction. My god.

Because if you pick a language that is safe by construction, YOU'LL write bug-free programs, right?

My point is that it is often useful and/or necessary to poke into a database to see what's going on, and if the status fields are plain things like integers or strings that can be interpreted very easily by the individual at the console, problems will make themselves more evident and may be easier to fix.

I've got around 7 years of experience with enterprise applications, have been programming for much longer, and I've yet to hear of a silver-bullet language that prevents people from making coding mistakes.  In light of this, I've found that keeping things simple in terms of representing data (but no simpler) is a great idea that saves time and headache when the problems inevitable rear their ugly head.

Along those lines, relying on one language's implementation of converting enumerated types into some other value so that it can be stored in the database seems to me like it could present problems.  What if you need to write a new version of the software that utilizes the same database schema but in a different language? 

The choice of languages is an economic decision based on, among other things, the application requirements, the proposed hardware platform(s), availability of tools, availability of manpower (qualified programmers) sprinkled with an ounce of religious zeal.  Any factor could mean more depending on the situation, and it's silly to suggest that one aspect of a language would make it an automatic choice over another.

Signed,
A guy who's received immediate offers at 95% of the places he's ever interviewed and doesn't care about being turned down once in awhile :)
Glad I Don't Work in Karel's Shop
Thursday, November 16, 2006
 
 
If this is to be stored in a database, why not create a code table with the values of "Stop" and "Review"?  There is no reason in the world to have an integer value running around that has a secret meaning.  If you add another value, "Okay" you can even make the link Not Null, which often simplifies reproting queries.
Wayne M.
Thursday, November 16, 2006
 
 
"Enums" are stupid for something that may change. You want to add a new severity, you need to recompile your code? Please. The guy who says store the # in a database and create a mapping is right on.
ARandom Send private email
Thursday, November 16, 2006
 
 
ARandom,

If you change the encoding, you must do so anyway, because otherwise your code will fall through with the new unhandled case you just added. Ever wondered why software has the tendency to increase its entropy? Adding a new value in de database, without understanding the consequences for existing application code is a real big problem. It is one of the most common scale-2 design errors in software.

However, if you are willing to accept this risk, then there are several solutions, even if you use enumerations. Particularly if you use enumerations, I should perhaps add.

I: you define an enumeration value for 'unrecognised' values in the data base and deal with that value *explicitly* in your code, e.g. by producing log or error messages. This isolation requires one additional line of code in the entire code base, if architectured correctly. This is not so easy with simple integers, since it is the mapping from integers to enumerations that does the trick in a nice and readalbe way.

II: you define an abstract classification system of codes, like the error messages in HTTP. This works, but goes well beyond the scope of the question of OP and is not without its own problems.
Karel Thönissen Send private email
Friday, November 17, 2006
 
 
"Ever wondered why software has the tendency to increase its entropy? "

Who talks like that? I smell a bullshitter. Software doesn't have "entropy". Maybe if you spent more time trying to give us practical reasons why enumerations are so damn important instead of trying to make us feel stupid we might actually listen to you. You've said nothing of substance to counter anyone's argument. Enumerations give you compile time checking and that is all. If an invalid value gets into my database then enumerations and Ada aren't going to save me. The code will still just puke.

Blah blah blah entropy. Blah blah blah scale-2 design errors. Blah blah blah I think I'm smarter than you because I'm in a university setting. Who else besides the military would be stupid enough to still be using Ada? Give me a freaking break!
I'll be the ass
Friday, November 17, 2006
 
 
> Who talks like that?

People who think about software after long hours of practice.

> I smell a bullshitter.

You should shower occasionally.

> The code will still just puke.

True and so clearly said. "puking" is a common computer response, everyone knows exactly what you mean.

> Blah blah blah I think I'm smarter than you because
> I'm in a university setting.

A little more self confidence would go a long way.
son of parnas
Friday, November 17, 2006
 
 
Regarding my use of the word entropy, I was referring to the second law of thermodynamics metaphorically applied to software systems. Software systems have the tendency to react more and more randomly over time; their behavior starts to depart more and more from the design. It was not exact science, but certainly no BS. Entropy and information are closely related.

I checked, I gave several arguments (summarised below) that are known to work and that are used every day in high-integrity code. You do not have to believe me. Also, I do not have to convince you. Given the childish reaction of yours, I won't after this.

<<<...us feel stupid we might actually listen to you.>>>

I provided facts, you feel offended, you isolate yourself, your choice.

Perhaps you feel stupid, that was not my intention. Now if you were a /wise/ person, you would have asked me to explain and we could have had a detailed discussion of techniques and methods. But you are not wise and you start attacking a valid and reasonable contribution. Even the (incorrect) idea that somebody is in a university setting pisses you off.

<<<You've said nothing of substance to counter anyone's argument>>>:

I mentioned: readablity, isolation, abstraction, ease of maintenance, type checking, range checking, inhibition of doing semantically meaningless calculus on arbitrary values, possibility to catch uncatered extensions of the value domain at runtime (using the unrecognised idiom).

<<<Enumerations give you compile time checking and that is all.>>>

I mentioned isolation in combination with logging.

<<<If an invalid value gets into my database then enumerations and Ada aren't going to save me. The code will still just puke>>>

That is exactly the point! Correct use of enumerations makes the code puke. At least you know that something is rotting away (hence my use of the words entropy) and quite possibly, where something is rotting away. Then you can make the choice to leave it that way or not.

'Glad' made valid points, one of which was that this will not save your skin if you use different languages; I mentioned that myself earlier. The point is true, absolutely. Often the use of different languages is inevitable. However, from an integrity point of view it is best avoided, unless there are others reasons to do otherwise.

<<<[...] I'm in a university setting>>>

???

<<<Who else besides the military would be stupid enough to still be using Ada?>>>

http://www.seas.gwu.edu/~mfeldman/ada-project-summary.html

I guess they are all stupid.

You choose to play ad hominem without checking information readily available to you on the Internet. You make several bold statement about Ada, university, etc. but you never checked the facts.

Given the sorry state of the contribution of the previous poster, this is my last post in this thread.

Thanks. Bye.
Karel Thönissen Send private email
Friday, November 17, 2006
 
 
Not referring to you, Son of Parnas. You overtook me in your response.
Karel Thönissen Send private email
Friday, November 17, 2006
 
 
> You overtook me in your response.

Being a smart ass is a lot faster :-)
son of parnas
Friday, November 17, 2006
 
 
"Regarding my use of the word entropy, I was referring to the second law of thermodynamics metaphorically applied to software systems. Software systems have the tendency to react more and more randomly over time; ..."

"Metaphorically applied" is the key. Why create metaphors that don't really apply other than to try and look scholarly? Software systems NEVER react randomly. In other words, this is all just bullshit. I stand by my comments. I may be stupid but I know when someone is overcompensating in order to try and look smart.

I'll stop being the ass now. But I just couldn't resist considering just how "deep" it was getting around here. The OP just asked about using an int for severity level. There are many reasons why he/she might want to do so. I would assume that integers make it easier to compare severity levels for logging purposes. Enumerations don't help here unless they are backed by an integer so that they can be compared in value. They also keeps you from being able to support user-defined severity levels. So enumerations are certainly no cure-all.

By the way, Ada has nothing on C# in terms of enumerations. C# enumeration values can be sent to a database as int's or strings. But the main point that people are trying to make is that if a database doesn't support the concept of an enumeration then you have a disconnect that decreases their perceived benefits.

I'm done as well. Have a scholarly day!  ;)
I'll be the ass
Friday, November 17, 2006
 
 
In java the util.logging class(es) use integers for severity levels. You can see the details here:

http://java.sun.com/j2se/1.4.2/docs/api/java/util/logging/Level.html

Basically, here is the way they define the different levels.

OFF = Integer.MAX_VALUE
SEVERE = 1000
WARNING = 900
INFO = 800
CONFIG = 700
FINE = 500
FINER = 400
FINEST = 300
ALL = Iteger.MIN_VALUE

Note that these are the values used to turn on/off logging based on severity level. This explains the values for OFF and ALL. But the same logic applies for creating errors.

The reason I'm providing this is just to give an example of how this was done in an actual system. You can take it or leave it.
Turtle Rustler
Friday, November 17, 2006
 
 
I believe the "entropy" comment refers to the tendency of software to become more and more 'brittle' as changes are applied to it (over time).

Without effective refactoring, as changes are applied on top of changes, it becomes more and more likely for code to 'break' as new changes are applied to it, and harder and harder to correct those breakages.

Much of the data that supports this comes from the 1980's and '90's -- I haven't seen an analysis of this effect from the 2000's yet.  Still, I'd be surprised if this "bath-tub" curve of faults versus time does not still exist.

The 'bath-tub' curve resulting from initial fixes, then a time of few fixes, then the number of faults rising again as new modifications to fit new conditions make the code increasingly hard to 'get right'.
AllanL5
Friday, November 17, 2006
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz