Return to my home page
Me Humour Links Pics Articles Feedback Updates Map Info Fun Search

- Computer Humour Archive -

There is more computer humour in the general humour archives, but I've singled these ones out for "special treatment" as they are very unlikely to be understood by anyone who is not into computer programming - I'm aware that some of the funnies in the general humour archive maybe ought to be moved into here, but right now I have to admit that I just can't be bothered to work out which ones to move!
Right now this archive is pretty small as I've only just set it up - in time I'm sure I'll remember more of my experiences and post them here, or if anybody E-mails me with something it may well end up here as well - watch this space!

  1. Obfuscated no-ops and other stupidities
  2. Hexadecimal words
  3. Undocumented Instruction Opcodes
  4. Everyday SQL
  5. How to write illegible programs
  6. Information: Use of the MotherInLaw object
  7. Types of Bug
  8. Information: Possible Solution to MotherInLaw problems
  9. Technical Support: a bug in the system
  10. Murphy's Computer Laws (9th September 2005)
  11. Obfuscating your Error Messages (18h October 2005)

Return to the top of this pageTop    

Return to my home pageHome

Return to Humour ArchiveHumour

Site MapMap


OBFUSCATED NO-OPS AND OTHER STUPIDITIES

The following is a great way to include a no-op in your Unix shell scripting:-

For ENVAR substitute any environment variable of your choice, whether or not it exists. As you can see, the env will pull out every environment variable, the grep will find the line that starts with ENVAR followed by an equals sign, and the sed will get rid of it leaving only the value of the variable. The value returned will therefore be the existing value of ENVAR, which will then be plugged back into ENVAR and exported. Pretty impressive no-op, huh?

==================

How about this to test for execution timings in C?
followed by
A decent compiler will pick up the fact that the loop does absolutely nothing and will replace the first statement with i=10; and the latter with i=100000;
Even better, if the loop variable is not used anymore or re-initialised without first being used, the compiler (if it's worth it's salt) will get rid of the whole loop altogether!
What is really fun is when someone asks you to debug their C code because after the for (...) statement they have mistakenly placed a semicolon before the opening curly. It can take ages to spot mistakes like that!
==================

At one stage, I was required to debug a program which had the following lines of code - in those days I was working in 6800 Assembler Language, and the CLR instruction is used to clear a single byte of memory:-

I presume the second clear was needed in case the first one should fail, and the third one in case the second one failed....(!) Or maybe it was the bug I was looking for?

Return to the top of this pageTop    

Return to my home pageHome

Return to Humour ArchiveHumour

Site MapMap


HEXADECIMAL WORDS

You're probably aware that machine-code programmers (and others!) use hexadecimal a lot. This is a numbering system that uses the digits 0 to 9 and the letters A to F as it required to represent 0 through 15 each using a single digit. Using 0 as an "O," 1 as an "I" and 5 as an "S" it is possible to make the following words (ignoring plurals formed by adding an S or ES):-

A1D A1DED AB1DE AB0DE ACE ACCE55
ADD ADDED A5 A5CE515 A51A A51DE
A55 BAB1E5 BAD BADE BADD1E BA5E
BA5ED BA5E5 BA51C BA515 BA55 BE
BEAD BEE BEEF BEEFED BED BED51DE
BED51DE5 BE5IDE B1A5 B1A5ED B105 B1D
B1DE B1D5 B0D B0DE B055 B055ED
CAB CABB1E CADD15 CACA0 CAD CAD1
CADD1E CAFE CA1550N CA5E CA5ED CEA5E
CEA5ED CEA5E5 C1A0 C0D C0DA C0DE
C0DED C0DE5 C0FFEE C00 C00ED DA15
DAD DADD1E5 DEAD DEAF DEBB1E DECADE
DECAF DECEA5E DECEA5ED DECEA5E5 DEC1DE DEC1DED
DEC1DE5 DEBA5ED DEC0DE DEC0DED DEED DEFACE
DEFACED DEFACE5 DEED DEF1ED DEF1E5 DE1F1ED
DE1F1E5 D1CE D1CED D1E D1ED D1E5
D10DE D15C D15C0 D15C5 D15EA5E D15EA5ED
D0 D0E5 D05E D05ED EA5E EA5ED
FACADE FACE FACED FADE FADED FAECE5
FA5C1A FED FEE FEED FEED5 F1A5C0
F0B F0E F00D 1CE 1CED 1DEA
15 0A515 0DE 0F 0FF 51DE
51DED 51DE5 5AD 5AFE 5A1D 50D
50DA 5EA5 5EA51DE 5EE 5EED 5EEDED
5EE5 50        

I hope the phrase, "Get a Life" doesn't spring to mind! There are almost certainly plenty more, and I'll add them as I come across them!

I think what really takes the biscuit was the day I was running the C debugger at work, and gave the X command by mistake, which displays the internal registers. Most of the registers contained DEADBEEF.

Return to the top of this pageTop    

Return to my home pageHome

Return to Humour ArchiveHumour

Site MapMap


UNDOCUMENTED INSTRUCTION OPCODES

I've finally discovered that the reason why computers don't always behave as expected is because it is executing one of the following instructions.

Some of these can be modified with the BT (Big Time) modifier, and others with the WAV (With A Vengeance) suffix. Sometimes the two can be combined, hence it is possible to have the following instruction:-

Return to the top of this pageTop    

Return to my home pageHome

Return to Humour ArchiveHumour

Site MapMap


EVERYDAY SQL

Here are some SQL instructions you may find useful from time to time:

Return to the top of this pageTop    

Return to my home pageHome

Return to Humour ArchiveHumour

Site MapMap


HOW TO WRITE ILLEGIBLE PROGRAMS
  1. Use non-obvious abbreviations for your variable, function and subroutine names. For example, why use a variable name such as "return_code" when "rc" will do? When you need to have a variable such as "run_condition" in the same program then call it something like "rc1."

  2. Make sure that you use such variable names as "retncd," "retcode," "returncd," "return_code", "returncode", etc. all in the same program.

  3. If you don't like short variable names, then try using long names instead. We love having to plough through programs which use variable names such as "property_status_after_the_first_iteration_of_the_outer_loop." If that really is too long then just use "psatfiotol" instead.

  4. If variable names are case-sensitive, use all possible combinations available. So "rc," "Rc," "rC" and "RC" are all game on. This technique is good for when you don't want other people to understand your code - a sort of software protection if you like.

  5. If you must use variable names such as "return_code," ensure also that you use a variable such as "code_returned" as well. It gets really confusing when you have to continually use similar-sounding variable names, and one common mistake is to use one when you should be using the other.

  6. Sorry - another one on variable names. I recently discovered the following variable names in use at work. They were both of type BLOB (Binary Large OBject):
  7. Use GOTO whenever possible. There's nothing that support guys like more than having to wade through tons of spaghetti coding that is nigh on impossible to understand. It gives them a kick to know that they can understand something that the rest of us wouldn't have a clue about, or would have given up on ages ago.

  8. Do not indent your code at conditional statements, functions, subroutines and loops. You will probably need to save the space that indenting tabs or spaces would have used up. Plus lines of code that spead over 2 lines due to indentation look really, really ugly.
    Alternatively, use a non-standard indentation technique to make readers think that code at one level should be at a different level.

  9. Do not, whatever you do, dare to use comments. They take up valuable space and clutter your program up so you can't see the code for the remarks. It's sooooooo much fun trying to figure out what your code does that you wrote 5 years ago and are now required to modify.

  10. If you do like comments and can't bear the thought of having a program without any, then make sure you comment every line of code in such a way as to be absolutely no help to others whatsoever.
    They're only there for your own benefit anyway.
    Alternatively, write a dissertation at the top of every 5-line function explaining what it does, the way it does it, and why it does it.

  11. Do not remove dead code, or even comment it out. Just leave it hanging around in there so that others will come across it and try to understand what it does. When someone does do this, gently point out to him/her that the code is dead so it doesn't matter, but leave it a day or so first so you can have a good laugh.

  12. When you change the functionality of a section of code, do not alter the comments (if any) to reflect what it now does. Support people like having to clairvoyantly detect whether any particular comment is accurate or not.

  13. When you need to write some code that does 75% of what an existing function does, do not lift the code from the function and write a customised version. Rather, call the function and follow this with lots more code to unpick the work the function did that you didn't require. It's sure to contain a bug somewhere along the line as well.

  14. Have umpteen copies of the same section of code hanging around and refuse to package it up in a function.
    You'll have loads of fun in 5 years time when you have to make a change - now you've got to change it in 20 different places instead of just one, and (as an added bonus) have to work out what each occurrence of the code does to make sure there are no subtle differences between each one.

  15. Adopt the attitude, "Why make it simple when I can make it complicated?"
    Write code in as obfuscated a manner as possible, and cram as much as you can into each line of code. This is particularly effective in such languages as C, Perl, and shell-scripting. People who can't understand your code shouldn't come anywhere near your programs anyway.

  16. Tips for assembler programmers:
  17. Make your error messages as incomprehensible or meaningless as possible, and use the same message to mean entirely different things. If a routine can display an error message at several different points, use the same message each time with no indication as to which error exit is being taken. A good message might run along the lines of, "Function <name> has detected a memory violation." Let support sort it out - they're good at that sort of thing.

  18. Make sure that messages written to log files are of absolutely no use whatsoever. God forbid that anybody should be able to trace your code should it appear to work but does absolutely nothing without letting you know about it. The same applies for messages written to error log files.

Return to the top of this pageTop    

Return to my home pageHome

Return to Humour ArchiveHumour

Site MapMap


INFORMATION: USE OF THE MOTHERINLAW OBJECT

The YoungLady object inherits from its Mother object. When you use the Marry() method of the YoungLady object, because it inherits from its Mother object, you end up instantiating this same object by default. To you, this object may be referenced using MotherInLaw, although TheOldBattleaxe is usually an accepted synonym. Very few methods of the MotherInLaw are useful, but some are, and others may be exploited to good use:

  1. SendToTaxidermist()
    This method will make the MotherInLaw object get stuffed.
    Usage: li_RetVal = MotherInLaw.SendToTaxidermist();
    An exit value of 0 indicates that your MotherInLaw has successfuly got stuffed, while any other value indicates abject failure. It is suggested you use this function in a loop such as the following:

    li_RetVal = -1;
    while (li_RetVal != 0) li_RetVal = MotherInLaw.SendToTaxidermist();

    This will continue executing until the function is successful.

  2. PopUp()
    This method causes the MotherInLaw object to pop up.
    Usage: li_RetVal = MotherInLaw.PopUp();
    This method may not appear useful at first sight, since very few, if any, applications require the MotherInLaw object to pop up at all. Unfortunately, this method has the undesired side-effect in that it often executes without warning and for no known or good reason, and sometimes seems to execute explicitly when required not to do so. However, if you can control when the MotherInLaw pops up, you may use the Punch() method (see below).
    The exit status of the PopUp() method is usually 0 (popped up successfully) or 1 (already popped up). A value of -1 (failure to pop up) is theoretically possible but in practice never occurs, unless the Marry() method of some YoungLady object has not been used.

  3. Punch(arg)
    This method will punch the MotherInLaw object wherever specified by the argument passed as a parameter. The accepted values for arg are "eyes," "nose," "mouth," "stomach." A null or invalid value will default to "mouth".
    It usually works fine, but the PopUp() method must have been executed first, or your Punch() will return an error code of -1 (meaning "missed").
    It has been discovered that using this method often triggers the Offend() event of the YoungLady object. This is unfortunate, but as it takes very little indeed to trigger this event, this is hardly surprising.
    The Offend() method of the YoungLady object has the effect of setting the Offended property which can only be cleared by the use of other YoungLady methods such as GiveChocolates(), GiveLotsOfTLC(), DealWithYouDontLoveMeRemarks(), and ApologiseProfuselyButExplainWhyItHadToBeDone().

  4. Interfere()
    You NEVER need to call this method. It will always execute spontaneously, and for no known or good reason. Anyone who writes an application that uses this method needs his/her head seen to, or (much better) the men in white coats to come and take them away.
    Interference can only be caused by a popped-up MotherInLaw, so the first thing the Interfere() method does is to call the PopUp() method. This is why the PopUp() method sometimes seems to execute spontaneously. A sufficiently quick use of Punch() after the implicit PopUp() may stop interference, but MotherInLaw objects usually have built-in regeneration methods that enable them to bounce back, usually with quite a vengeance.

    Code (function) example:

    void DealWithMotherInLaw()
    {
      // Ensure the MotherInLaw is popped up
      li_RetVal = MotherInLaw.PopUp();
      // Ensure MotherInLaw has popped up
      // Crash the system if not because
      // something has gone seriously wrong
      if (li_RetVal < 0)
        This.Crash();
      else
      {
        // Deal with popped up object
        MotherInLaw.Punch(mouth);
        MotherInLaw.Punch(eyes);
        MotherInLaw.Punch(nose);
        MotherInLaw.Punch(stomach);
        // Now let her get stuffed
        li_RetVal = -1;
        while (li_RetVal < 0)
          li_RetVal = MotherInLaw.SendToTaxidermist();
      }
      // Now deal with the unwanted side-effects
      // many of which could be very serious.
      // Use the 'with YoungLady' construct to
      // specify which object the methods are in.
      with YoungLady
      {
        while (Offended)
        {
          GiveChocolates(expensive);
          GiveLotsOfTLC();
          DealWithYouDontLoveMeRemarks();
          ApologiseProfuselyButExplainWhyItHadToBeDone();
        }
      }
    }
    

    Note that this code is packaged into a function. It is worth placing it into a global object, so it can be referenced from anywhere within the system.

Additional Complications:
The fact that you used a Marry() method of some YoungLady object means that she, by default, has used your Marry() method. As you inherit from your Mother object, this means that the YoungLady will also instantiate a MotherInLaw object too. This has been known to cause system conflicts, especially should the two MotherInLaw objects come close together in memory, and can often result in a deadly embrace. Whatever you do, DO NOT let the two MotherInLaw objects use the Interfere() method simultaneously as the results can be quite fatal.

Please Click here to see a possible solution to the Mother-In-Law problem.

Return to the top of this pageTop    

Return to my home pageHome

Return to Humour ArchiveHumour

Site MapMap


TYPES OF BUG

Return to the top of this pageTop    

Return to my home pageHome

Return to Humour ArchiveHumour

Site MapMap


INFORMATION: POSSIBLE SOLUTION TO MOTHERINLAW PROBLEMS

You may, at some stage, find it desirable to use some YoungLady's Marry() method (assuming you haven't already done so), but at the same time not want the problems caused by inheriting MotherInLaw objects in the process. This is perfectly understandable, and nobody will blame you if you find such a desire arising within yourself.

Please Click here for a description of the methods of a MotherInLaw object, and how some of them can be exploited to good use.

What if the YoungLady object is instantiated halfway across the world? What do you think the effects of that could be? Especially if her default Language property is not set to the same as yours?

Firstly, it could result in communication problems between the Self object and the YoungLady. She would need to use her Language.Learn(English) method and you would need to use your Language.Learn(x) method, where x is the default value of the YoungLady's Language property. Alternatively, you could both use your Language.Learn(y) methods, where y is any other language of choice for both of you.
Unfortunately this appears to be the only way to get a common language that both objects can communicate in.

However, there would be no need for the respective MotherInLaw objects to use any Language.Learn() methods, thus they will be unable to communicate due to the lack of a common language as well as the vast distance separating the two objects.

Another conflict that would never arise with this scenario is that of problems occurring due to the two MotherInLaw objects coming too close in memory: either they will remain a safe distance from each other, or, should they come too close, the fact that their Language properties are set differently will ensure that no Interfere() method can be called.

Thus, chances are, you'll be safe from many problems caused by these objects being around.

Return to the top of this pageTop    

Return to my home pageHome

Return to Humour ArchiveHumour

Site MapMap


TECHNICAL SUPPORT: A BUG IN THE SYSTEM

This woman went out to a local computer store to buy a computer that her family wanted her to get so she can e-mail them. The sales person told her that they would deliver the computer, set it up and give her some pointers on using it, if she had any problems later all she had to do was call their "Technical Support" they would talk her through it over the phone or come back to her house to find the problem.

The sales person asked her if she wanted to purchase 2 years in house warranty, the woman said yes. A few months went by, she was getting good sending and receiving mail and checking the other web sites with only one call to tech support until one day. She called tech support.

SUPPORT: Hello, technical support how can I help you?
LADY: Last night my computer started making a lot of hissing noise at me so I shut it down. This morning, when I turned it on, the computer started hissing and cracking then started smoking and a bad smell, then nothing.
SUPPORT: I will have a technician come over first thing this morning. Just leave the computer just like it is so they can find the problem and fix it or change it with another computer. Give me your address and phone number and the technician will be there just as soon as they can in the morning.

When the technician got there, the lady showed the technician where the computer was, and said what had happened to it. This is what the technician found wrong...

Technical Support 1

Technical Support 2

Technical Support 3

Technical Support 4

Return to the top of this pageTop    

Return to my home pageHome

Return to Humour ArchiveHumour

Site MapMap


MURPHY'S COMPUTER LAWS

Return to the top of this pageTop    

Return to my home pageHome

Return to Humour ArchiveHumour

Site MapMap


OBFUSCATING YOUR ERROR MESSAGES

One thing that Support people really detest is being able to find error messages in any given program quickly and easily.

They like those messages to be hidden behind lots of confusing code; it gives them a kick to know they can suss out how the most cleverly-obfuscated error messages are being generated, especially when they have customers breathing down their necks for a quick resolution to their fault calls.

Given that these days most job descriptions state that you "must be able to work well under pressure", there is no excuse for not obscuring these errors; anyone who cannot hack the pressure is in the wrong job and probably ought to find a supermarket somewhere that needs a shelf-stacker.

Note that any code provided in this tutorial is not intended to be in any given computer language; it is designed to give an outline only rather than a specific implementation.

This tutorial explains one method for burying your error messages so deeply in the code that your support personnel will really have to know what they're doing to be in with a fighting chance of ever understanding how you did it. An example could be used at the interview for new support personnel: if they can't find where the error message is coming from, you simply don't hire them!

Consider an application error message such as the following:

"No accounts for that property exist"

This could be generated using a simple Message Box function, thus:

MessageBox("Application Title",
	"No accounts for that property exist");

But that would be far too simple, wouldn't it? I mean, Support could easily carry out a search for the text of the error message and find it within seconds. It's an insult to his intelligence!

Stage 1 is to remove the error message itself, and hide it away securely into a database table. Have a database table defined something like this:

CODE   NUMBER(6)
TEXT   VARCHAR2(255)

with a unique index on CODE. Note that the column names are words that are likely to crop up all over the program during a word search, thereby making it hard to track down where this table is being used. Call the table something like ECODES (for 'Error CODES') as this also potentially introduces some bonus obfuscation.

So ... for each error message you have an error number. Let's call this one error number 1. Your database table entry will look like this:

CODE = 1
TEXT = 'No accounts for that property exist'

Now instead of your simple MessageBox, you can do the following:

SELECT text
INTO   :ls_error
FROM   ecodes
WHERE  code = 1
<check for database errors>
MessageBox("Application Title", ls_error);

Stage 2 is to make certain that the error message is not raised in an obvious place. This is an attempt to make using a debugger difficult (at worst) or nigh on impossible (best possible case).

If you're using an object-oriented language, then this is very easy as you can bury your errors behind lots of levels of inheritance, thus necessitating the need for Support to plough through (or debug their way through) dozens of scripts to get to it.

DO NOT, UNDER ANY CIRCUMSTANCES, give your error numbers meaningful names as this makes it easy to track the messages down, thereby defeating the object of the whole exercise!

In any large application, there should be a good few thousand references to the table ECODES, thus this is quite safe. It is even safe to wrap that up in a function along the following lines:

function generate_error(errno)
{
	string ls_error;

	SELECT text
	INTO   :ls_error
	FROM   ecodes
	WHERE  code = :errno

	<check for database errors>

	MessageBox("Application Title", ls_error);
}

and call it like this:

generate_error(1);

as there will still be thousands of calls to this function, so it will still be hard enough to find which invocation is the relevant one.

Next, we can parameterise the error messages. This is where the real fun begins (the fun we just had was fake fun).

The first step here is to identify a common grammatical structure for each error message. For instance, we've already seen

"No accounts for that property exist"

but let's suppose we also have the following errors:

"No details for that account exist"
"No occupants for that property exist"
"No parties for that account exist"

Note how they all take the following form:

"No %1 for that %2 exist"

where %1 and %2 would be "accounts" and "property" respectively for our original error message. But it is easy to see that other error messages follow exactly the same form. Therefore, error 1 now becomes:

"No %1 for that %2 exist"

The function can now be rewritten thus:

function generate_error(errno, s1, s2, s3, s4)
{
	string ls_error;

	SELECT text
	INTO   :ls_error
	FROM   ecodes
	WHERE  code = :errno

	<check for database errors>

	if (s1 != "")
	{
		ls_error = Replace(ls_error, "%1", s1);
	}

	if (s2 != "")
	{
		ls_error = Replace(ls_error, "%2", s2);
	}
	if (s3 != "")
	{
		ls_error = Replace(ls_error, "%3", s3);
	}

	if (s4 != "")
	{
		ls_error = Replace(ls_error, "%4", s4);
	}

	MessageBox("Application Title", ls_error);
}

We're allowing for upto 4 parameters for each error message; if any require fewer parameters, just pass blanks in.

For our original error, we can now call it thus:

generate_error(1, "accounts", "property", "", "");

You've now got a very obfuscated error reporting system that should make your programs as unsupportable as possible, and should provide endless hours of 'fun' for your support personnel when they need to track down any given error message and where it's coming from.

Alternatively, it will leave them thoroughly discombobulated by the obfuscation...

Return to the top of this pageTop    

Return to my home pageHome

Return to Humour ArchiveHumour

Site MapMap


Extradisambiguator Need an Extradisambiguator? Click here! Extradisambiguator