PDA

View Full Version : Raaaagggghhhh



pendell
2013-11-12, 03:53 PM
Dear fellow programmers.

This is me, your friendly neighborhood senior R&D guy and software engineer, just working through reverse engineering someone else's pile of , erm, handcrafted "masterpiece".

Imagine, if you will, that one of your attributes is an array.

Imagine, if you will, that this is in a language which can either be zero-based or one-based. That is, the first index can be either 0 or 1, depending on how the array is constructed.

Imagine that I, the maintainer, am tasked with a guessing game of figuring out which it is based on context.

You know what?

If I find this in two different methods in the same class?

for (i=0;i<nStuff;i++){}
for (i=1;i<=nstuff;i++){}

Then SOMEONE IS GOING TO DIE SCREAMING AND IT IS NOT ME.

*Pant pant pant*

Thank you.

Returning now to his normal respectful self,

Brian P.

Traab
2013-11-12, 04:00 PM
/puts on jock face "NEEERRRRRRRRRRDDDDDD!!!!!!!!!" :smallbiggrin:

That out of the way, I have no idea what the hell any of that means, but I can tell by the context that you are a mite frustrated. I hopw things work out for you. (Did my generic well wishes help?)

pendell
2013-11-12, 04:14 PM
They did, yes. :)

To get some idea of the frustration level, try to imagine that someone handed you a 3.5 character sheet, and it had a bunch of leftover stuff like THAC0 from previous editions on it, and it was your job to make sense of it.

I suspect what most DMs would do is tell the player their character was tragically killed by a meteor strike and to roll up a new one properly this time.

Respectfully,

Brian P.

gooddragon1
2013-11-12, 05:14 PM
They did, yes. :)

To get some idea of the frustration level, try to imagine that someone handed you a 3.5 character sheet, and it had a bunch of leftover stuff like THAC0 from previous editions on it, and it was your job to make sense of it.

I suspect what most DMs would do is tell the player their character was tragically killed by a meteor strike and to roll up a new one properly this time.

Respectfully,

Brian P.

All I got out of your initial comment was 2 for loops. I have no idea how you're supposed to guess stuff like that. Then again I have not much of an idea about how people make trainers for games that I have difficulty even using cheat engine on and the addresses change each time and yet somehow they make it work? Well good luck to you. I'm still learning java :(

TuggyNE
2013-11-12, 05:27 PM
Imagine, if you will, that one of your attributes is an array.

Imagine, if you will, that this is in a language which can either be zero-based or one-based. That is, the first index can be either 0 or 1, depending on how the array is constructed.

Imagine that I, the maintainer, am tasked with a guessing game of figuring out which it is based on context.

You know what?

If I find this in two different methods in the same class?

for (i=0;i<nStuff;i++){}
for (i=1;i<=nstuff;i++){}

That is pretty painful. But take heart! At least there's no loop that goes
for (i=0;i<=nStuff;i++){}
or
for (i=1;i<nstuff;i++){}

right? Right?

I think my favorite horrible code was a sample program for a commercial web API product, which consisted chiefly of a single large multi-tab form in VB.NET. And by "large" I mean not only physically, but code-wise, and there was enormous duplication of everything. There were maybe a dozen event procedures to handle several dozen API calls, each thousands of lines long and filled with nested conditionals six deep, and I'm not sure if there weren't a few labels for gotoing in there too. Worse yet, there were very few comments, error handling was minimal and inconsistent, the examples were not wholly complete, and I could observe the occasional apparent error in the code, which made it decidedly less than useful for most purposes. But since all we had was that, our own experience with the API, and sparse online documentation, we had to use it anyway. *tear*

shawnhcorey
2013-11-12, 05:34 PM
And, of course, the documentation explains it all. :smallwink:

pendell
2013-11-12, 05:54 PM
All I got out of your initial comment was 2 for loops.


The key point is that I'm trying to figure out whether the array is zero-based or one-based, and the writer did it both ways . Because he could .

Correct procedure would have been to stay consistent -- either do it all zero-based or do it all one-based, but for pity's sake don't mix the two.

This is especially true if this array is being populated by ... well, never mind. That's too much information. Suffice it to say this array is being interacted with from multiple sources, and therefore the ordering and position are critical.

Here is a truth of coding: Unless you are doing something like hard-realtime, where every microsecond counts, readability and consistency win over clever any day of the week and twice on Sunday.

I solved it and made it consistent, of course. Still won't stop me nailing the coder up by his figgin* if I ever find him.

@TuggyNE: Totally agreed and commisseration shared. :).

Respectfully,

Brian P.

* A small pastry with raisins.

Flickerdart
2013-11-12, 07:46 PM
Why does the language even allow one to have one-based arrays? Zero-based can do everything that one-based can.

Grinner
2013-11-12, 07:52 PM
Why does the language even allow one to have one-based arrays? Zero-based can do everything that one-based can.

Could that even be an option? If you can start an array at zero, couldn't you also just start it at one just as easily?

Douglas
2013-11-12, 09:47 PM
Allow me to introduce you to a great big regularly updated repository of similar stories (http://thedailywtf.com/) for you to shake your head at and be glad at least you're not dealing with <insert X entry here>.

Degree of coding terribleness varies highly between entries. Some situations described there will be less bad than yours.

factotum
2013-11-13, 02:22 AM
Why does the language even allow one to have one-based arrays? Zero-based can do everything that one-based can.

But if you actually *want* your array to start at 1, and your language only allows zero base, you end up allocating an array element that you'll never use. It's actually possible in some languages (VB.NET, for example) to declare an array whose starting bound is any arbitrary number you choose, and that can sometimes be darned useful!

Mono Vertigo
2013-11-13, 04:17 AM
I remember, during my computer lessons, I once came up with code that functioned perfectly well but used some weird logic (can't remember the language though). The teacher looked at me skeptically, and he'd never seen such a thing, but had to admit it worked. He didn't seem to enjoy my thinking outside the box, but I never quite understood why. I mean, it worked! And I couldn't imagine a situation where it wouldn't!
Now, I'm starting to understand his pain.
Apologizing to you by proxy.

Manga Shoggoth
2013-11-13, 05:14 AM
The key point is that I'm trying to figure out whether the array is zero-based or one-based, and the writer did it both ways . Because he could .

Correct procedure would have been to stay consistent -- either do it all zero-based or do it all one-based, but for pity's sake don't mix the two.

...

I solved it and made it consistent, of course. Still won't stop me nailing the coder up by his figgin* if I ever find him.

* A small pastry with raisins.

Are you sure it was the same programmer both times? I have seen some really weird bits of code come about because different programmers have worked on the same piece of code at different times. And usually not updated the header comments.

...Although you would think that an off-by-one error at the beginning of the array would show up when they tested the code. Oh yes... assumption there...

(And the Pratchett references are always welcome...)

dehro
2013-11-13, 05:22 AM
things can't be too bad if you can still quote Pratchett.

nedz
2013-11-13, 05:30 AM
I've seen far worse, at least the examples work.

TuggyNE
2013-11-13, 06:05 AM
And, of course, the documentation explains it all. :smallwink:

You wish. No, it was mostly "here are the elements of this structure, just as you can see in Object Browser, with no additional information on how they're used or what they mean".


I've seen far worse, at least the examples work.

Most of the examples worked. Mostly. Except when they didn't. And they weren't good at showing all the possible cases, so it was hard to figure out whether you'd made a mistake in adapting, or whether the API was buggy, or whether the example would have handled it wrong too, or what.

Protip: the API, which was on version 4, was not infrequently subtly buggy.


Here is a truth of coding: Unless you are doing something like hard-realtime, where every microsecond counts, readability and consistency win over clever any day of the week and twice on Sunday.

Because Sunday is both 0 and 7, of course. :smalltongue::smallwink:

(Also, agreed wholeheartedly.)


@TuggyNE: Totally agreed and commisseration shared. :)

Heh, thanks.

Krazzman
2013-11-13, 06:28 AM
I would've recommended making it consistent. But the I=1 or I=0 is not the only indicator for what sort of array you have there.

But now imagine this: COBOL. In a big company. Where multiple Programs are pieced together from different developers. And you have some grown progams that were written some 15 or more years ago (oldest one I saw was from 1995 here). And were handled by different people for every change.
and switching between formats and how they write and how long you can make a section (for the ones not knowing COBOL basically a method without parameters) before you can't read it anymore. Arbitrary Variable names and as if that isn't enough limited space. you have room for only ~60 characters and some variables have a namelength of 20 characters... or more.

Then additionally I can now program in SAS and have already seen a program where everything was bound to the left and the formatting was terrible.

KillianHawkeye
2013-11-13, 08:11 AM
Imagine, if you will, that this is in a language which can either be zero-based or one-based. That is, the first index can be either 0 or 1, depending on how the array is constructed.

I'm not sure which language that is, but it sounds like a HUGE MISTAKE. I'm thankful that I mostly stick to C-family languages.

shawnhcorey
2013-11-13, 08:43 AM
I'm not sure which language that is, but it sounds like a HUGE MISTAKE. I'm thankful that I mostly stick to C-family languages.

Actually, in Perl, you can change the base of all arrays to any integer. Not recommended though. :smallsmile:

warty goblin
2013-11-13, 05:07 PM
Then additionally I can now program in SAS and have already seen a program where everything was bound to the left and the formatting was terrible.

You poor bastard. SAS is just such a misery to use, at least for statistics. Except for ANOVA models, which it does approximately 1000% better than anything else. R needs to change their lm() function to just run SAS.

valadil
2013-11-13, 11:05 PM
Could that even be an option? If you can start an array at zero, couldn't you also just start it at one just as easily?

I know lua starts at 1 instead of 0. But as far as I'm aware, that's always the case. Using an inconsistent start point sounds awful, unless you have foreach/for in/some other way of iterating over all the things without knowing the index.

Here's my comisery. Today I was splitting up a function that had grown into 1000 lines into a set of classes. There was one point where a set of IDs was gathered and passed to the database as a condition to limit what you could query for.

Someone felt it necessary to check the size of the array of IDs. When it was 1, they set the value to the only item in the array and the comparison to =. When it was more than one, they kept the array as the value and set the comparison to IN. They could have just left it alone and asserted that the id was in the array that only had one value, but instead introduced two extra vars.

In retrospect this doesn't sound that bad. Except that `git blame` told me our team lead wrote that code and now I'm not sure if I should trust him anymore.

Flickerdart
2013-11-13, 11:42 PM
But if you actually *want* your array to start at 1, and your language only allows zero base, you end up allocating an array element that you'll never use. It's actually possible in some languages (VB.NET, for example) to declare an array whose starting bound is any arbitrary number you choose, and that can sometimes be darned useful!
Is having an empty cell in an array such a sin that programmers must suffer for it?

Razanir
2013-11-14, 12:21 AM
At least the only times I start a for loop at 1 is when I mean it. Cases where I really don't need to iterate over the 0th element.

for (int i = 1; i <= n; i++) is just ugly. I even use for (int i = 0; i < n; i++) when I just need to repeat something n times.

The ONLY time recently I've done something slightly bizarre was when I had a slew of stats functions to perform on an array (min, max, mean, variance) and wanted to get them all done in one loop.

Speaking of which, programming challenge: Write a method to find the variance of an array of double... IN A SINGLE LOOP

factotum
2013-11-14, 01:59 AM
Is having an empty cell in an array such a sin that programmers must suffer for it?

It's this sort of attitude that's why a modern-day copy of Windows needs 2Gb of RAM before it even wants to get out of bed in the morning, you realise? :smallsmile:

Savannah
2013-11-14, 02:19 AM
To get some idea of the frustration level, try to imagine that someone handed you a 3.5 character sheet, and it had a bunch of leftover stuff like THAC0 from previous editions on it, and it was your job to make sense of it.

I actually once had someone come to a 3.5 game I was running with minimal play experience, but they had done a fair bit of reading. Unfortunately, one of the books they'd read was the Player's Handbook II. The Fourth Edition PHBII. Took me aaaaages to figure out why they were saying totally random things and citing PHBII. Then once I'd figured it out, I couldn't make them understand the problem. So, yeah. I understand the pain, even if I'm not a programmer.

TuggyNE
2013-11-14, 02:37 AM
Is having an empty cell in an array such a sin that programmers must suffer for it?

Sometimes, yes. Cases where starting at 1 is semantically desirable are fairly common (counting occurrences of values in some particular range, perhaps), and while rare, there are a few examples where starting at 2, or 5, or 7, or even much higher numbers, are useful (for example, total sales in a given year, starting with the year a company was founded).

The same attitude could perhaps be held toward, say, variable names longer than 6 characters: "aw, come on, what do you really need that for?"

pendell
2013-11-14, 07:53 AM
Is having an empty cell in an array such a sin that programmers must suffer for it?

Imagine that you have an array of sensors that someone else must call. Imagine that the caller sends you a request for sensor 3. Okay, so does that mean they want the third sensor in the array or the fourth?

The only way to know this is to know whether the array starts with 0 or with 1.

Get it wrong and you might, say, send them the output from the aneroid altimeter instead of the radar altimeter. A distinction so small as to be trivial , so small it will never be caught in testing against the canned data set you feed it ... until you get a small number of edge cases where 'minimal difference' becomes critical and then this happens (http://www.economist.com/blogs/babbage/2013/08/cockpit-automation).

Most accidents and disasters that result from software or from engineering aren't from obvious errors that get caught in testing. Most problems and disasters happen because a train of errors occur in a sequence impossible to predict, so that each one error, trivial in itself, taken together turns into a catastrophe. As with the challenger (http://en.wikipedia.org/wiki/Space_Shuttle_Challenger_disaster).

Then again, sometimes things like this are just from plain miscommunication. Case in point: The Mars Climate Orbiter (http://en.wikipedia.org/wiki/Mars_Climate_Orbiter#Cause_of_failure). I suspect both the software on the spacecraft and the software on the ground passed rigorous quality control tests and someone signed off on all of it. But no one noticed that the ground unit was sending acceleration in pound-force, while the spacecraft was expecting Newtons. Result? One $125 million crater on the surface of Mars and years of wasted work.

This is the same sort of thing. A small, seemingly insignificant error that works in 99.5% of cases but, because it does something a little bit different than you would expect, opens up a potential for misunderstanding. Even if the code does work absolutely perfectly without problem, the original coder wrote it that way presumably because he figured no one else would ever touch it . Even if it works right the potential for a maintenance programmer to mess it up is quite high.

So, again, consistency and readability are critical in any program save low-level assembly or real-time coding.

This is also, why, incidentally, KDSI (http://encyclopedia2.thefreedictionary.com/Delivered+Source+Instruction) is a terrible metric for measuring productivity. I'd rather have 10 well-written lines at the end of the day that work than 1000 lines that will require extensive debugging because the person was in a hurry. It's like measuring the creator of a jigsaw puzzle by the number of pieces in it -- a small rubik's cube which elegantly fits together is much preferable to a 1000 piece monstrosity, especially if 100 of those pieces don't fit.

Respectfully,

Brian P.

warty goblin
2013-11-14, 11:34 AM
Speaking of which, programming challenge: Write a method to find the variance of an array of double... IN A SINGLE LOOP
Sufficient statistics baby. All you need is the sum of squared observations, the overall sum, and the number of observations. Though that's less a programming answer than it is knowing that the first and second sample moments are sufficient for the first and second population moments, and the variance, being the second central moment, is easily writable as a function of the non-central moments.

pendell
2013-11-14, 01:56 PM
Speaking of which, programming challenge: Write a method to find the variance of an array of double... IN A SINGLE LOOP

Challenge accepted.





/** Find variance by subtracting the square of the mean from the mean of
* the squares. See
* http://www.mun.ca/biology/scarr/Simplified_calculation_of_variance.html
* @param pSampleArray: array of sample data whose variance must be
* calculated.
* @return A Double representing the variance, or null in the case of
* an empty or non-existent array.
*/
public Double calculateVariance (Double[] pSampleArray) {

if (pSampleArray == null || pSampleArray.size() == 0) {
return null;
}

Double result = new Double(0);
Double mean = new Double(0);
Double meanOfSquares = new Double(0);

for (Double currentValue : pSampleArray) {
mean += currentValue;
meanOfSquares += currentValue * currentValue;
}

mean /= pSampleArray.size();
meanOfSquares /= pSampleArray.size();
result = meanOfSquares - (mean * mean);
return result;
}



Comments, criticism, feedback welcome.

ETA: You'll notice I have deliberately coded as clearly as possible. I believe this is in some ways more important than accuracy -- it is possible that I've goofed the algorithm, and the error is therefore easy to spot and correct.

By contrast, 'clever', obfuscated code is a nightmare to comprehend even when it works as it should.

I write my code to be read and maintained by people of moderate intelligence, not geniuses. Even if I have a genius working for me, I have better use for her
brains than deciphering lousy code.

Respectfully,

Brian P.

Razanir
2013-11-16, 11:17 PM
Sufficient statistics baby. All you need is the sum of squared observations, the overall sum, and the number of observations. Though that's less a programming answer than it is knowing that the first and second sample moments are sufficient for the first and second population moments, and the variance, being the second central moment, is easily writable as a function of the non-central moments.

Yeah, it really isn't that difficult. I'd mainly mentioned it because I was helping someone on CS homework, and I don't think he was expecting that. So convenient being able to find the mean, variance, min and max in a single for loop...

lesser_minion
2013-11-18, 03:16 AM
Why does the language even allow one to have one-based arrays? Zero-based can do everything that one-based can.

Pascal and Ada both allow you to have arrays where the set of keys is arbitrary, for a start. You could even have 42-based arrays if you wanted.

There's also Lua, where every array is an associative array, and there are plenty of other languages where your 'array' isn't necessarily an array at all.

Miklus
2013-11-21, 05:24 PM
And, of course, the documentation explains it all. :smallwink:

The documentation is in the code... *Cries into keyboard and sends out job applications*

Douglas
2013-11-22, 01:39 AM
The documentation is in the code... *Cries into keyboard and sends out job applications*
Hey, when it's well done that actually is a wonderful place for it to be. The problem is that it is far too often done poorly. VERY poorly.

TuggyNE
2013-11-22, 03:18 AM
The documentation is in the code... *Cries into keyboard and sends out job applications*

Best is if the code in question is a web API.

That you don't have direct access to.

Maintained by a different company's team.

Why no I have no experience with this particular situation why do you ask.

shawnhcorey
2013-11-22, 02:04 PM
The documentation is in the code... *Cries into keyboard and sends out job applications*


Hey, when it's well done that actually is a wonderful place for it to be. The problem is that it is far too often done poorly. VERY poorly.


Best is if the code in question is a web API.

That you don't have direct access to.

Maintained by a different company's team.

Why no I have no experience with this particular situation why do you ask.

The documentation is often poor to start with and rapidly becomes outdated. The best way to learn what it does is to read its unit tests. Their are normally every simple and they tell you what to expect. If you want to know how the code works, you have to read it itself.

the_druid_droid
2013-11-22, 02:39 PM
Fun documentation story on my end. I'm a scientific programmer (although I do about as much coding as most CS majors, so definitely not a black-boxer) and I needed to decide which molecular dynamics software package to couple into my code for a larger overall calculation.

Now, the method my group uses is fairly non-standard, so I knew I'd have to modify the source a bit to handle some of our special cases. Ultimately, this boiled down to a choice between the package with millions of lines of source code and documentation online... documentation from 10 years ago hidden on some server backup, that is, or the 100k+ code with a grand total of nine pages of current documentation (mostly at the level of "here are our abstract classes, have fun")...

I went with the latter, and it actually worked out okay, in part because it's one of the shining examples where the documentation in comments is reasonably accurate and up-to-date. I still had a mess in the end though, because what I do is a mix of two fields that almost never cross-pollinate, so when I tried to ask for help from developers they couldn't figure out why I was doing half the things I was doing... but I survived.

pendell
2013-11-22, 06:45 PM
Hey, when it's well done that actually is a wonderful place for it to be. The problem is that it is far too often done poorly. VERY poorly.

*Looks up from tens of thousands of lines of code*

What is this "in-line documentation" of which you speak...?

I suppose that if I can find the in-line documentation it'll tell me where the leprechaun keeps his pot o' gold ? :smallamused:

For myself, I maintain a project wiki and also use inline documentation for significant algorithms. After all, there's not much reason for documentation like this



/**
* This method sets the value of the blah attribute
* @param pBlah: The value to set the blah object to
* @author BDP
*/

public void setBlah (Blah pBlah) {
myBlah = pBlah;
}


I've been on projects which mandated 10-20 line comment templates on top of each and every method. Multiply that by a lot of accessors and you're going to be doing a lot of scrolling. The only thing worse than no documentation is cut-and-pasted template documentation which nonetheless tells you nothing useful about the code.

Respectfully,

Brian P.

pendell
2013-11-26, 12:08 AM
Dear field staff,

Please note that, as this is a holiday week, pretty much all the serious technical support staff are on vacation.

THEREFORE, this is not the week to start randomly pulling cables out of the wall to "clean up the rat's nest".

:smallsigh:

*Smiles sweetly, grabs the field guy by the shirt, then lowers his head into the guy's nose. Repeatedly.*

One of those happy weeks but at least I'm not dead or in prison yet,

Brian P.

factotum
2013-11-26, 03:16 AM
Please note that, as this is a holiday week, pretty much all the serious technical support staff are on vacation.

THEREFORE, this is not the week to start randomly pulling cables out of the wall to "clean up the rat's nest".


Well, couple of things there:

a) If it's a holiday week, the number of people potentially affected by their foolishness is lower, so that's surely a good thing!

b) At least they didn't try to randomly plug cables back *in*...broadcast storms are never pleasant and can be a sod to track down.

Tylorious
2013-11-26, 12:53 PM
Rewrite that junk sir...or guess. Your call, but just know that it is on you now, and if it were on me I wouldn't rely on someone elses shoddy work. Do you have documentation to go off of? If so, just throw his/her crap out and put your own in.

Is this program part of something bigger? Is there a shell meant to manage this program? If so, see how the shell reads the arrays and respond appropriately.

Tylorious
2013-11-26, 02:17 PM
I just had another thought about this. Check in other parts of the code that call specific elements of the array. If it calls for the 0th element, you know it is a 0-x array, whereas if it calls for the x+1 element, you know it is a 1-(x+1) array. Hope that helps :)

Miklus
2013-11-26, 03:53 PM
The documentation is in the code... *Cries into keyboard and sends out job applications*

What I meant to say was "The code IS the documentation". As in, the is NO documention. 16.600 Files and not a single piece of paper. Because paper is for amatuers, the so-called senior programmers seem to think.

They think sunshine comes out of their arses, but they can't make a function that does not rely on at least one global. :smallsigh: Classes are heresy to them.