Featured

User Interface Developers: Please Have Mercy on Your Poor Users!

Woman screaming in rage,

This blog post is for any software engineers who are involved in programming or designing a user interface.

If someone performs a user interface action that should result in an instantaneous and clearly visible response they will only wait patiently for that response for a brief period of time.

If after a five second delay they do not see the expected clearly visible response they will perform the user interface action again, perhaps multiple times if the delay continues for another five seconds or so.

If for some reason there is a delay that prevents the expected instantaneous and clearly visible response, please, for the love of whatever deity or great power you follow, DO NOT PERFORM THE RESPONSE MULTIPLE TIMES.

The multiple user interface actions were not in any way a request to perform the response multiple times. They were multiple increasingly desperate attempts to get the response a single time.

For example, if the user is pressing enter on a desktop icon that starts a program that displays a message box before the main function is even called, they will press enter on the desktop icon multiple times if for some reason it takes between five and sixty seconds to start the application when it normally starts in far less than a second.

Trust me. The user has already started screaming at you by the time they have to hit enter on the desktop icon a third time because the message box still has not been displayed in response to the request to start the application that was made fifteen seconds earlier.

If you then start that application one time for each time they pressed the enter key on the desktop icon when your badly broken operating system finally realizes the user is desperately trying to start it the poor user might end up having a stroke because of the rage they are now experiencing!

Another example is opening a menu such as the start menu or an application menu. Normally this is a very quick operation that takes less than a second. So if five seconds after they pressed the key to open the menu the user does not see the menu, they will press the key to open it again. On the rare occasions when something delays the opening of the menu they may have pressed the open menu key four or five times before it is opened.

That does not mean they want the menu to be opened, then closed, then opened, then closed…

The multiple presses of the key to open the menu were multiple increasingly desperate attempts to open the menu once. By the second attempt the poor user is screaming at you. If you do the open menu, close menu, open menu, close menu, … foolishness it is very likely that the poor user might end up have a stroke because of the rage they are now experiencing!

These are problems I experience very often with Microsoft Windows. To be fair I have seen it with Linux and Mac OSX as well, but no where near as often as I see in in Windows.

Fuck you very much Microsoft for the wonderful user experience of Windows and every single Microsoft product I have every used! If I believed in hell I would wish for everyone responsible for these wonderful user experiences to suffer eternal torment in the hottest and most fiery section of hell!

Thank you for listening to me vent. I feel much better now.

Here is a song that expresses my heartfelt feelings towards Microsoft. Enjoy.

… you very much Microsoft
Featured

On the benefits of taking a course over learning by doing.

I am a self taught software engineer. It is something I take a great deal of pride in.

I started learning C programming language back in 1997. If I remember correctly I started by reading Sams Teach Yourself C in 21 Days and perhaps also C Programming Language by Brian W. Kernighan and Dennis M. Ritchie.

Then on January 5, 1999 I got a job working for Henter-Joyce (now Freedom Scientific) as an Associate Software Engineer. My responsibilities included writing code in the JAWS Scripting Language which a proprietary programming language that is used by the JAWS screen reader.

I quickly decided that I was not content with just writing code in the JAWS Scripting Language; I wanted to be able to modify the JAWS internals.

At that time almost all of the JAWS internal code was in the C++ programming language. Therefore I decided to teach myself C++.

To learn C++ I did the following.

  • I bought a copy of Sams Teach Yourself C++ in 21 Days and began reading it.
  • I wrote an application called SysInfo in C++ as a aid to our technical support department. SysInfo would gather information such as Video Card information, OS, memory, and send it to technical support via email. SysInfo was very similar to the current Microsoft System Information Tool.

This plan was so successful that I was promoted to Software Engineer in January 2000. I have used C++ as my primary programming language since then.

I never stopped learning. I have tried to keep up to date with new language standards and new technologies since then. But I always learned by doing. If the task I was working on required that I learn something new I would use Google and Stack Overflow and get the job done.

This has been my preferred method of gaining new knowledge until very recently.

On August 1, 2021 my knowledge of JavaScript was minimal. The last time I needed to use JavaScript as part of my job it took me two weeks to fix a bug that required that I change fewer than 10 lines of code.

Then I realized that there are some serious flaws with a browser extension for Google Chrome and Mozilla Firefox released by my employer that I am currently responsible for maintaining that necessitated a complete rewrite of the extension. I tried to make the necessary changes and found much to my horror that I could not even get started.

I had previously bought a lifetime membership to Eduonix and some courses on Udemy with the vague idea of taking the courses some day. However, I had made very minimal use of these educational resources.

I let my employer know what was going on and I was given permission to spend some time when I would normally be working on taking courses in JavaScript. I then spent every day for the next two weeks learning JavaScript.

In just four hours this Monday I rewrote one quarter of the Browser Extension. There is only one reason I did not finish the project; I was temporarily reassigned to another project.

I am not claiming that my knowledge of JavaScript is anywhere near my knowledge of C++. However, after just two weeks my knowledge of JavaScript is roughly equivalent to my knowledge of C++ back in 2001.

Looking back, I find myself wishing that I had followed a more structured approach to learning C++ back in the halcyon days of yore.

Featured

JAWS Scripting Tip: Optional Parameters

JAWS is a screen reader developed by Freedom Scientific. It includes a scripting language that allows users to customize the behavior of JAWS.

Many programming languages such as C++, C#, and Modern JavaScript support the concept of optional function parameters for which you supply a default value for the parameter. In C++ this might be done as follows.

std::wstring GetFavoriteNumberMessage(int64_t number = 42)
{
    std::wstringstream message;
    message
        << L"Hello. My favorite number is "
        << number
        << L". What is your favorite number?\n";
    return message.str();
}

See source on godbolt.org.

The JAWS scripting language supports optional parameters using the optional keyword, as follows.


string function GetFavoriteNumberMessage(optional int number)
  var string message = FormatString(
    "Hello. My favorite number is %1. What is your favorite number?",
     number)
  return message
endFunction

However, there is no direct method of assigning a default value for the optional parameter. If you were to call the function is as without specifying a value for the number parameter the number will be inserted into the returned message as an empty string. This is most likely not the desired behavior.

When the caller does not specify the value of an optional parameter, it does not resolve to 0 or false within the function; this is a common misconception. Instead the unspecified parameter resolves to nullptr. The misconception that the unspecified parameter resolves to 0 or false is a result of the fact that when nullptr is typecast to an int the result is 0 or false. However, if the unspecified parameter is typecast to a string the result is an empty string. This is why in the above example the number will be inserted into the returned message as an empty string; the number parameter is typecast to a string by the FormatString function. If the unspecified parameter did resolve to 0 or false within the function it would be inserted to the returned message as 0!

This problem can be resolved as follows.

string function GetFavoriteNumberMessage(optional int number)
    if (!DidCallerSpecifyTheValueOfTheParameter(number))
      number = 42
    endIf
    var string message = FormatString(
      "Hello. My favorite number is %1. What is your favorite number?",
      number)
    return message
endFunction

Unfortunately, there is no DidCallerSpecifyTheValueOfTheParameter function in the JAWS scripting language, so do not bother looking it up. However, there is a function that can achieve the same goal.

Behind the scenes all variables in the JAWS scripting language are VARIANTs (yes we are aware that there are modern alternatives that are vastly superior but the JAWS scripting language is very old; it has its roots in the JAWS macro language that was included in JAWS for DOS). One benefit of a VARIANT is it supports the concept of a VARTYPE or variant type. Furthermore, there is a VT_EMPTY variant type. Finally, there is a rarely used GetVariantType built-in script function that “determines the type of a variable”.

Thus, it is possible to assign a default value for an optional parameter as follows.

string function GetFavoriteNumberMessage(optional int number)
    if (GetVariantType(number) == VT_EMPTY)
      number = 42
    endIf
    var string message = FormatString(
      "Hello. My favorite number is %1. What is your favorite number?",
      number)
    return message
endFunction

Note that some people may think this is unnecessary because it is enough to rely on the perceived unspecified parameter resolves to 0 or false behavior. This is wrong for two reasons.

  • As I have already pointed this perceived behavior is not what is actually happening. The unspecified parameter actually resolves to nullptr.
  • In many cases, even if the perceived unspecified parameter resolves to 0 or false behavior may not be what is desired.

Every other programming language that supports the concept of optional parameters; such as C++, C#, and Modern JavaScript ; allows the value of the optional parameters to be explicitly defined. The purpose of the following code block is to add the same capabilities to optional parameters in the JAWS Scripting Language.

if (GetVariantType(number) == VT_EMPTY)
  number = 42
endIf

This is the only way to assign a non nullptr value for an optional parameter in the JAWS Scripting Language. You should consider doing this even for parameters where the default value is 0 or nullptr because explicitly specifying the value of your default parameters rather that making people who read your code guess what the behavior will be is just being polite.

Note that using this technique is absolutely necessary when overriding a built-in script function such as the SayObjectTypeAndText function in your scripts. The default value of the includeContainerName is true, not false. Failure to do this when overriding the SayObjectTypeAndText function will change the behavior of your function from the default resulting in hard to find bugs.

Featured

More advice on how to organize an article

The Upcoming changes to Google Drive sync clients page is another excellent example of how not to organize an article.

The section How Backup and Sync users can start using Drive for desktop begins as follows: “To get started with Drive for desktop, you can move your accounts and settings from Backup and Sync to Google Drive for desktop”. At this point the more impatient readers will have already started screaming at the author of this page because no information at all on how to get started was provided. Just above this paragraph is a link to “download Drive for Desktop” so you can assume that by the time your reader gets to this point on the page they have downloaded the software and they are continuing to read the page in order to find out what to do next.

To be more precise, at this point the reader has two questions that they are eager to learn the answer to.

  1. Do I uninstall Backup and Sync first?
  2. Or do I just install Drive for Desktop without first uninstalling Backup and Sync?

In the sentence “To get started with Drive for desktop, you can move your accounts and settings from Backup and Sync to Google Drive for desktop” you have not provided an answer to that question. You have instead annoyed the hell out of your reader. The reader is now screaming “But exactly how do I get started” at the top of their lungs.

The second sentence does not make matters any better: “During the process, you’ll review and confirm the settings for the folders on your computer you’re backing up and syncing with the cloud through Backup and Sync”. The reader is now two thirds of the way through the paragraph and they still have no idea what the answers to the above two questions are.

The final sentence does provide an answer to the question but only indirectly: “Backup and Sync will be automatically uninstalled after you’ve moved your accounts to Drive for desktop”. This sentence implies the answers to the two questions are as follows.

  1. Do I uninstall Backup and Sync first?: No
  2. Or do I just install Drive for Desktop without first uninstalling Backup and Sync?: Yes

The problem is that the impatient reader may have rage quit reading the page before getting this fare because of the issues with the first two sentences in the paragraph. I know that the first time I read this page, while I did manage to restrain myself from screaming, I did rage quit reading the page before I got to this critical sentence. It was not until I returned to the page the following day that I was able to answer my questions.

If a single sentence were added to the start of this paragraph things would be much better for the impatient reader: “You do not need to uninstall Backup and Sync before installing Drive for desktop”.

If the How Backup and Sync users can start using Drive for desktop section were rewritten as follows, this page would be far more useful and far easier to read.

How Backup and Sync users can start using Drive for desktop

You do not need to uninstall Backup and Sync before installing Drive for desktop. To get started with Drive for desktop simply run the Google Drive for desktop installer, GoogleDriveSetup.exe. After the installation of Drive for desktop completes a Move accounts to Drive for desktop form will be displayed to allow you to move your accounts and settings from Backup and Sync to Google Drive for desktop. During the process, you’ll review and confirm the settings for the folders on your computer you’re backing up and syncing with the cloud through Backup and Sync. Backup and Sync will be automatically uninstalled after you’ve moved your accounts to Drive for desktop.

Featured

Advice on how to organize an article

The article What causes the ‘Your Hardware Settings Have Changed’ issue on Windows 10? is very poorly organized.

In the introduction the article explains two possible causes of the issue. This introduction is well written and provides useful, and relevant, information.

After the introduction is a Note heading. The first paragraph in this section begins as follows: “If the given solutions don’t work for you, you will have to stop Windows from updating your device drivers”.

At this point many readers will begin screaming at you in rage because you have not said a single word about how to solve the problem, you just explained what is causing the problem.

Next comes several paragraphs that explain how to “stop Windows from updating your device drivers”.

This Note section ends with the ominous warning: here be dragons. The problem is that the impatient reader who is desperately trying to get their laptop working again may never even get this far because they may have followed the instructions on how to “stop Windows from updating your device drivers” and seeing that the issue has gone away closed the web page.

It is only if you continue scrolling down the page past the ominous warning that you find the solutions. Of course some readers will never see the solution because they stopped reading after following the instructions to “stop Windows from updating your device drivers”.

This article should have been organized as follows.

  1. Causes
  2. Solutions
  3. If the given solutions don’t work for you…

The way the article is presented just pisses the reader off. It may also cause them to try the alternative without ever being aware that the article actually does suggest solutions.

Don’t be like Kevin. Please use a logical order for your articles.

Coffee Cup Mystery

New Bug Entered

Title:

Coffee cup is empty (Incident number 24,078).

Repro Steps:

  1. Observe coffee cup.
    • Expected Results: Coffee cup should have coffee in it.
    • Actual Results: Coffee cup does not have coffee in it.

Status Update

Re: Coffee cup is empty (Incident number 24,078).

The Bug “Coffee cup is empty (Incident number 24,078)” was resolved by getting up, going into the kitchen and pouring myself another cup of coffee.

Second New Bug Entered

Title:

Coffee cup periodically becomes empty for unknown reason.

Repro Steps:

Warning: The precise process for reproducing this Bug is unknown. I have no idea why this intermittent Bug is occurring.

  1. Fill cup with coffee.
  2. Observe coffee cup periodically.
    • Expected Results: The coffee cup should always have coffee in it.
    • Actual Results: Sometimes the coffee cup does not have coffee in it. I have no idea what causes this to happen.

Status update from Product Management.

Re: Coffee cup periodically becomes empty for unknown reason.

You are drinking the coffee you fool. Our Coffee Cup product does not currently have and automatic refill feature. That feature is planned for the future. We may be able to get to that feature in the year 3025.

Stop reporting these Bugs, please.

Status update from tester.

Re: Coffee cup periodically becomes empty for unknown reason.

I have no memory of drinking the coffee. However, I acknowledge that it is remotely possible that I did drink the coffee without realizing what I was doing.

I will do as you requested and stop entering these “Coffee cup is empty” bugs.

Is there any chance we can get to the automatic refill feature before the year 3025?

The Birth of the Lizard Man

I was frightened when, after taking the most painful shit in my life, which came after the longest period of constipation I have ever experienced in my life, I looked down into the toilet and saw movement. My fear turned into horror when a being that looked like a cross between a human infant and a lizard crawled out of the toilet, held up its arms, looked up at me and said “mommy”.

Bed Sizes

Official

  • Crib
  • Single Small
  • Twin
  • Twin XL
  • Full
  • Full XL
  • Queen
  • Olympic Queen
  • King
  • California King
  • Wyoming King
  • Alaska King

Unofficial

  • Orgy
  • Super Orgy
  • Olympic Pool
  • Football Field
  • Stadium
  • City Block
  • City
  • Lake
  • State
  • Nation
  • Ocean
  • Continent
  • World
  • Star System
  • Star Cluster
  • Galaxy
  • Galaxy cluster
  • Universe
  • Multiverse

Can you imagine how large a multiverse bed would be?

New Software Engineer versus Experienced Software Engineer

New Software Engineer

A new Software Engineer may do the following.

  1. The new Software Engineer spends hours or perhaps even days writing a new application just to get to the point where they have an application that should run.
  2. The new Software Engineer begins to test the new application, fully expecting it to work.
  3. The new Software Engineer is surprised to learn that the application does not work at all.
  4. The new Software Engineer reviews the source code of the application hoping to deduce why the application is not working only to conclude that it is one of the unfathomable mysteries of the universe.
  5. The new Software Engineer then begins debugging the application out of desperation.
  6. Hours or even days later the new Software Engineer has finally fixed all known issues and concludes that the application is now working as expected.
  7. The new Software Engineer sends the new application to Quality Assurance for testing fully expecting Quality Assurance to pass all test cases.
  8. The new Software Engineer is shocked to learn that one or more test cases failed.
  9. The new Software Engineer begins to suffer from impostor syndrome.

Experienced Software Engineer

An experienced Software Engineer may do the following.

  1. The experienced Software Engineer spends hours or perhaps even days writing a new application just to get to the point where they have an application that should run.
  2. The experienced Software Engineer begins to test the new application, fully expecting it to work.
  3. The experienced Software Engineer is surprised to learn that the application does work with a few minor issues.
  4. The experienced Software Engineer reviews the source code of the application hoping to deduce why the application is working nearly as expected only to conclude that it is one of the unfathomable mysteries of the universe.
  5. The experienced Software Engineer then begins debugging the application out of desperation.
  6. Hours or even days later the experienced Software Engineer is finally satisfied that the new application is working nearly as expected and begins resolving the few minor issues they found.
  7. A few hours or days later they feel that they finally have something that is ready for testing.
  8. The experienced Software Engineer sends the new application to Quality Assurance for testing fully expecting Quality Assurance to fail at least half of the test cases.
  9. The experienced Software Engineer is shocked to learn that most, if not all, of the test cases passed.
  10. The experienced Software Engineer begins to suffer from impostor syndrome.

7 is the loneliest number.

Long ago “6 7 8” and “7 8 9”. After that, we counted objects as follows: “1 2 3 4 5 7 8 10”.

Some time later “5 7 8” and “7 8 10”. After that, we counted objects as follows: “1 2 3 4 7 8 11”.

Some time later “4 7 8” and “7 8 11”. After that, we counted objects as follows: “1 2 3 7 8 12”.

Many years went by. 7 ate more and more numbers.

Until eventually, 7 was all alone in the universe because it had eaten all the other numbers.

Stabby McStabber

Stabby McStabber is widely regarded to be the stabbiest stabber of them all. Stabby McStabber has stabbed so many people that all the governments of the world have given up on their attempts to bring him to justice since they have lost too many armies to him.

Stabby McStabber has an arch rival, Stabby McBackStabber. Stabby McStabber believes that Stabby McBackStabber is dishonorable for stabbing people in the back. Stabby McBackStabber believes that Stabby McStabber is a fool for insisting on facing the people he stabs.

Law McLawMan has sworn to bring both Stabby McStabber and Stabby McBackStabber to justice, no matter what it takes. Unfortunately, Law McLawMan does not have the support of any governments. Law McLawMan has also sworn to bring the author of this tale, Auth McAuthor, to justice.

Gov McGovMan is actively interfering with the efforts of Law McLawMan. Gov McGovMan believes that the efforts of Law McLawMan will only get more people killed needlessly.

Ass McAssassin has on multiple occasions refused to accept a contract to kill Stabby McStabber or Stabby McBackStabber. Last month, Ass McAssassin was questioned about his refusal to go after Stabby McStabber or Stabby McBackStabber in a tavern after having a few too many drinks. While he was drunk, Ass McAssassin admitted that he will not go after Stabby McStabber or Stabby McBackStabber because he admires them both. Ass McAssassin did accept a contract to kill Auth McAuthor.

Sol McSoldier has turned against his government because he is angry at his government due to having lost too many friends as a result of pointless battles against Stabby McStabber.

Warp Drive Fart

Every time you fart, Fate rolls a 20 sided dice. The variable R represents the result.

  • If R is equal to 6, 10, 14, or 20 you are launched into space in a random direction at Warp 9.999.
  • As long as you are traveling at Warp you are safe. The Warp bubble contains an enclosed environment that supports life.
  • You will remain at Warp for precisely 2 * R hours.
  • When you drop out of Warp you will continue moving straight forward at the same speed you were traveling at when you entered Warp.
  • You do not have the ability to survive in space without life support.

If you had this ability, how would you survive?

Do you think this weapon is over powered?

Exquisite Enchanted Ass-ass-in Dagger

  • Base Damage: 20 – 50
  • + 100 Piercing Damage
  • – 100 Damage Resistance in Target
  • + 50 Poison Damage
  • + 50 Acid Damage
  • + 50 Necrotic Damage
  • + 50 Fire Damage
  • + 50 Explosive Damage
  • + 50 Holy Damage
  • + 5000 Additional Damage Against Dragons
  • + Disfiguring Wounds Curse
  • + Eternal Stench Curse
  • + Eternal Impotence Curse

With the Disfiguring Wounds Curse, the Eternal Stench Curse, and the Eternal Impotence Curse, if this dagger does not kill you it adds insult to injury.

The foolish last words of many dead people

This list contains the foolish last words of many dead people.

  • What could possibly go wrong?
  • What’s the worst that can happen?
  • Want to see something cool?
  • I can make that jump.1
  • It could not possibly get any worse than this.
  • It is just a minor problem.
  • There is no need to worry about it.
  • This is going to be fun!
  • It is just a harmless animal bite.2

Can any of you think of examples that I missed?

BTW: This was inspired by a book I am reading. The main character in the book said to himself “It could not possibly get any worse than this”. An hour or so later it got much worse. Nine people died. The main character survived.

  1. Contributed by one of my co-workers, Andrew Derry-Farrell. ↩︎
  2. Usually not the last words spoken. However, a person who dies of rabies may say this several months before they die. ↩︎

How would you respond in this situation?

Consider the following scenario. A warrior has a magical war cry skill that has the effects described in the war cry. For example, if the warrior uses the skill and shouts “intimidating war cry” all people who hear  the war cry are intimidated unless they have the appropriate resistance skill.
What would you do if you are part of an army that is facing that warrior in battle, the warrior uses the skill and shouts “humiliating, intimidating, frightening, emasculating, feminizing war cry”?