Monday, August 19, 2013

Loving to Hate GNOME 3

You're going to hate GNOME. Really, trust me on this. You will absolutely despise it. The dumb thing starts up with an empty screen. There is no menu. The intrepid among you will stumble across that "Activities" thing in the upper left. You might even click and see... another empty screen. Seriously! What is up with these empty screens. How do I actually get at my *stuff*? Try it. Go ahead, give it a try right now. See what I mean? Let it out - a nice primal scream of frustration. Good. Now take a deep breath and let's explore why I'm wrong. Huh? Put on your thinking caps. Let's look at the computer like it's your personal secretary. No, not Bill Clinton's secretary. Get your mind out of the gutter. Your secretary. You're sitting at your desk. Papers spread out in front of you. A nice leather chair. A picture of the wife and kids in the corner. Wham! It hits you. The idea of the century. This will catapult your entire company onto the world stage. You mumble an order to take notes and start blabbering away. Your secretary simply carries on whatever you had her doing before. Why? Because she's in the other room, dummy. You didn't get her attention. And she has no idea you wanted her to do something else. Now no rational human being would do this. You would immediately yell her name, get her attention, give the order, _then_ start dictating. So why do you expect the computer to be any different? The computer is an electronic secretary. And when you want it to do something new, you have to get its attention first. That is what the Activities button does - tells the computer that you want something. The computer starts paying attention. So tell it what you want. Start typing the command. Whoa! A bunch of icons pop up onto the screen. Those icons match what you type. The more you type, the more the computer narrows down what you want. Sounds a lot like a human secretary. It learns your habits, putting the most likely choices up front. Click an icon to finish the command. And the computer obeys. You would never expect a human secretary to list all of her job functions every time you grab her attention. That's silly. Yet this is exactly what a menu does. Menus are the computer's list of job functions. Menus make a very poor secretary. We have been spoiled by decades of poor user interfaces. We think of the computer like a hammer - a tool to wield. And that's wrong. The computer is a secretary. Change your expectations, and that crazy GNOME interface makes a lot more sense.

Thursday, August 2, 2012

Realpolitick

It is simply amazing how many ways we can divide people: conservative, liberal, rich, poor, Republican, Democrat, compassionate, greedy. You guessed it - I'm listening to the presidential race on talk radio again. Conservative radio hosts make this race about conservatives and liberals. The politicians themselves talk about Republican versus Democrat. The president pits poor against rich. Everyone has reasons for their position. And the opponent has a compelling counter-example. Class warfare is alive and well!

As it should be. Huh?

No, I'm not writing a diatribe against class warfare. I'm writing a diatribe in favor of it! I agree that class warfare exists. I disagree with the classes. The Bible clearly divides people into classes: sheep and goats, sons and enemies, righteous and wicked. Money and politics are merely secondary issues.

Start at the beginning

Dave Ramsey describes personal finances as 20% knowledge and 80% behavior. Tom Stanley takes it even further in his books The Millionaire Mind and The Millionaire Next Door. Mindset - character - drives behavior. Improving finances involves not just doing what rich people do. It means being the same kind of people.

What, you mean greedy and self absorbed? I can do that!

No, that's not what I mean. Where does money come from? How does one become rich?

Well by working hard, saving instead of spending, discipline, and perseverance.

Bzzz! Wrong answer. Thank you for playing. You get rich by blind luck. Follow me for just a moment here. At some point, every business owner took a risk. Yes, they put research and elbow grease into their venture. They mitigated the risks through knowledge and hard work. But in the end, any one of a million adversities could have completely taken their head off, leaving a bankrupt shell of a person. In many cases, this happened several times before the one successful venture!

In any business, a thousand things completely outside of your control can go wrong. And in the earliest stages, you are vulnerable. You cannot avoid risk. That raises the question, why did none of those things happen this one time? It wasn't you. Remember, these events are beyond your control. Blind luck.

I don't believe in blind luck. And truth be told, neither do you. These events are beyond my control. They are not beyond all control. The Bible shows us that God exercises sovereign control over all things. And by sovereign, I mean absolute and total. Those events that never happened? God did that. God blessed your venture for His own pleasure. Money, aka riches, are a gift from God.

The nature of a gift

Gifts are an act of generosity from the giver. Gifts never expect anything in return - otherwise it's a reward or bribe. Gifts are not earned. They are given solely at the whim of the giver. Wake up - this is the important part. Money is a gift from God, given solely at His whim. You do not earn money. You are not entitled to anything no matter how hard you work. God gives it.

Why does God give us these gifts? Because it pleases Him. Really, it's that simple. He likes it! And He enjoys our gratitude when we understand just how much He gives.

Through the Bible, God let us know what pleases Him. And He stated, as a fact, that He showers gifts on people who please Him. In other words, the path to riches is doing what pleases God.

Now I want to be very clear - following the law (i.e. doing what God told us to do) does NOT entitle you to a lot of money. This is not a deal. Paul made tents to earn money for food. And he certainly obeyed God! We should obey God because He told us to. Sometimes, at His whim, He responds by giving gifts of wealth.

This why it is so STUPID to divide people into rich and poor. The same God who provided one man with wealth gave another just enough. And He did it as He saw fit. Wealth is NOT a measure of God's favor. It is just one possible conduit for His gifts.

Did God do it wrong?

The people who preach re-distribution of wealth believe that He did. If wealth is a gift from God, then it follows that He chose the people who receive it. By taking from them, you believe that God made a mistake. Seriously, you want to stand in front of the God who created heaven and earth, rests his feet on our world, wears the stars as a crown, tells the wind where to blow, keeps us moving around the sun in a safe orbit, and tell Him that He was wrong?

Now having said that, God Himself tells us to give away part of that gift. Notice that He never tells you that you have the right to take it. He instructs the recipient of His gift to reflect His generosity. Our giving builds the same generosity in our spirit. Taking builds selfishness.

Putting the "class" in class warfare

Okay, so we have debunked the idea of wealth as a class divider. If class warfare exists, then what are the sides? I propose that we label them righteous and wicked.

You see, people like wealth because it's so easy to see. Politicians like it because wealth is easy to fake. Character, on the other hand, is harder to hide. So many folks in the news today make it a point of pride that they focus on the issues. "I don't care about their personal life. Do they agree with me on most issues?" That's foolish.

Proverbs teaches us that even the kindest acts of the wicked are cruel. Look at President Obama. A lot of Americans agreed with his stand on "the issues" in 2008. They conveniently ignored the fact that he's a known liar. And they seemed genuinely surprised when, duh, he lied to them. Character matters. Opinions change. Politicians can and should change positions as they learn. Character lasts forever. One righteous man (or woman) who disagrees with me on everything will do more for this country than a dozen politicians who tell me what I want to hear. Of course, if I disagree with a righteous person, maybe my positions aren't so good?

Perl Modules and Packages

This morning, someone posted a question on the Perl Beginner's mailing list about functions. They use two modules. Each module has its own collection of utility functions. For the first module, the code calls the functions directly - with just the function name. With the second module, the code puts the module name in front of the function names. The poster asked why the difference?

One of the Perl experts on the list asked if the functions lived in a module or a package. There is a difference. And the difference is very important. I thought it helpful to explore.

What's in a name?

Let's start with a discussion on namespaces. Consider the variable named $a. Its name is, well, a. So your code declares $a and assigns it a value:

    my $a = 6;
    ...
    $a += 3;
    print "$a\n";

Now imagine that we include a module named foo. foo also has a variable named $a.

    # Main program
    my $a = 6;
    ...
    use foo;
    $a += 3;
    print "$a\n";

    #-------------
    # Module "foo"
    my $a = 27;

The code above prints 30, not 9! What happened? The definition of $a in module foo overrode our main program. Both places referenced the same variable: $a. Now imagine that every module on CPAN clobbered variables in your code! You would rename all of your variables every time you use a new module.

Perl solves this problem by putting a namespace in front of every variable name. Internally, Perl translates $a into $main::a. Technically, you can put $main::a in your code and it works. But why type all of those extra characters when Perl does the work for you?

I picture namespaces like boxes. All of the variables from your main program go into a box named main::. All of the variables from foo go into a box named foo::

    +-----------+     +-----------+
    | main::    |     | foo::     |
    +-----------+     +-----------+
    | $a = 3    |     | $a = 27   |
    | $b = 'hi' |     | $h = 'oh' |
    | $c = 10   |     | $x = 30   |
    +-----------+     +-----------+

The big match: Module versus Package

Modules are files that you can include. A module uses the same namespace as the code that included it. When we say use foo, Perl puts all of foo's variables in the main:: namespace.

Packages create namespaces. The package foo puts all of its variables in the namespace foo::. You create a package with the package command.

You use modules. The module declares a package.

So back to our original poster's question. He has two files (aka modules). That first module drops its functions into the main:: namespace. It is a module in the truest sense - a file that simply inserts itself into the code. The second module contains a package statement. Perl creates a namespace and puts the functions in there. To call those functions, his code specifies the namespace - the module name he saw in front.

Best practice says that...

  1. Every module starts with a package statement.
  2. Any module contains only one package.
  3. The module and package have the same name.

As the original e-mail implies, Perl does not enforce these rules. You must specifically implement them. On the plus side, the rules come from very smart people who have learned hard lessons over the years. Save yourself the confusion and aggravation.

Saturday, June 30, 2012

Worst Web Site Ever

I write this post as a reminder to myself. The NET10 website (as of this date, anyway) offers a perfect example of what not to do. Here's the story...

Their technical support page insists that I enter a PIN for Buy It Now. Never mind that I'm not buying anything. The submit button doesn't work at all. I hit continue a dozen times and nothing happens. Cancel works. It drops you back to the home page. This page has no way to submit a technical support ticket!

So I went looking for another way to add this PIN. I found the menu option for that. It says that I have no phone. Huh? The phone's listed right there on the home page. In effect, it's impossible to set the PIN. And it's impossible to log a ticket without a PIN. Therefore, it's impossible to log a technical support ticket.

Maybe it's your browser?

That is certainly possible. That merely begs the question, though. The site does not meet expectations. I expected to get help with a problem on the wife's phone. Instead, I ran around and around never accomplishing anything.

The user doesn't know or care about all of the little pieces that make up your application. They see that they can or cannot accomplish a goal. Anything else gets in the way. As the programmer, those details are my responsibility.

Tuesday, June 12, 2012

Indexes, Indexes, Indexes

Around 2:30 this afternoon one of our users comes by the Data area.

"PARS is running slow."

This is no surprise. PARS has been randomly performing mediocre to tolerable for most of my two years.

"I go get a cup of coffee and it finally times out just as I get back."

Uh-oh. Slow is annoying. A timeout means the system is down. First we check with the other users. Nope, nothing unusual here. Hmmm. This user performs a search. We emulate their exact criteria. Boom - PARS times out here too!

Okay, the search function calls a stored procedure that dynamically generates an SQL query. I copy out the relevant parts and build the query by hand. It takes 35 seconds and returns a dozen rows. First, I take out the date check. Presto, the query runs in 6 seconds.

Let's see what effect other criteria have. Comment out the client check - 6 seconds. Odd, I would have expected it was just the date search. A little more playing and it becomes clear that three search clauses take 35 seconds. Two only take 6 seconds.

Now I examine the execution plans. Aha! A clue! Two criteria go into a bitmap index. Three criteria do not have the bitmap. What happens if I index the three search fields? We use this query a lot. Relatively, we upload minute amounts of data. So an index won't affect load performance. What do I have to lose?

Well, how long does building the index take? Am I going to bring down the database for 2 hours? It's down now, so again, no harm. Turns out that I was being stupid. SQL Server built the index in like 2 seconds.

I hit the query again. It still takes 35 seconds. I found that very surprising. The execution plan put a lot of time into looking up those fields. The second worst spot was a sub-select. The sub-select checks if we have any records for this row in another table. Actually, I'm looking for the case where we don't have corresponding records. The second table has a foreign key that points back to this table.

No one ever added indices to the database. SQL Server does not automatically index foreign keys either. So for kicks, I indexed it. Pow! The query displays results immediately. I couldn't believe it. I usually hit the button, sit back, and watch the timer for when they finish. This sucker ran instantaneously! I was dumb-founded. My user was happy to get back to work.

What did I learn from this experience? First, I was an idiot for waiting this long. I had noticed that we had no indices two years ago. Performance wasn't that bad. So other priorities moved ahead.

Secondly, a well placed index can breathe new life into sluggish queries. I know, I know, a million DBA's just slapped their palms against their foreheads and exclaimed "duh!". Seriously, though, this was on my radar because, well, it might shave off a few seconds. Going from timeout to instant response, though. I had no idea the effect was so dramatic. Seeing was believing.

So go ahead and chuckle. I deserve it. And now it's time that we look at our other tables. I may be able to eek even more performance out of this system!

Sunday, June 3, 2012

All That You Can Be

Vania, we went for a walk on Saturday. You won't remember. You're too young. We walked around the entire park. Okay, I walked around the entire park. You rode in the stroller. That's life with a toddler.

As we walked, I made an effort to pay attention to the trees. There are LOTS of trees down by the creek. Little trees, big trees, trees with birds, and trees with bugs. I also noticed how the trees grew together. They each found space for their leaves. Every tree had value. The ones with birds provided a home. Close to the path, trees provide shade. And all turn nasty carbon dioxide into fresh air. Plus they look downright great all decked out in green.

It kind of reminded me of people. No, not little green men. People come in different shapes and sizes. We have different talents - different ways of changing the world around us. God created a place for each of us, even you, Vania. You will never be everyone else. Your body is broken. Yet in spite of that, you will become all that God created you to be.

In his book How To Be Good In A World Gone Bad, Dr. Jim Spiegel talks about how God plants metaphors of spiritual truths in the real world [chapter 10, Living Artfully]. You have a special place in the world. You will change those around you in some way. And that makes you unique.

Being unique means that it doesn't matter how you compare with other people. God never measures us against anyone else. He measures us against His plan for our life. He gives us all that we need. And expects us to make use of that. Pastor Bob O'Bannon gave a sermon about the parable of talents. Bob made a point that the master praised the first and second servants equally even though one made far less than the other.

God expects Vania to be Vania. He gave you very special talents. Never let the things you can't do distract you from the things you're supposed to do.

Sounds so simple, right? Never is. Too often, people let themselves get distracted by what they think they should do. Schools will want to make you a well rounded person. Your genetic condition puts you in a unique position to ignore all of the noise. Some things will come easy. You already solve puzzles, learn about machines, and manipulate shapes. Focus on those things. Struggling with some subject? Then ignore it. Don't waste your precious energy on things that come hard. Grow in the space God carved out just for you.

Thursday, May 24, 2012

Catalyst Credentialing

I really like the Catalyst web framework. It handles all of the boring, repetitive details while leaving me the juicy, fun pieces of coding. For the most recent web application, I added authentication. I pieced together the functionality by reading module documentation. Here's what I learned - all in one place.

Catalyst has a plugin for authentication - Catalyst::Plugin::Authentication. It performs authentication in two steps: look up and password check. Catalyst calls these store and credential respectively. The store accesses your list of users (look up). The credential then compares the password.

Okay, let's walk through this. Henry comes to your web site. You greet him with a normal looking login screen. Henry types in his user name and password. Then he hits theLogin button. Your backend code passes off the user name and password to Catalyst::Plugin::Authentication. The plugin searches the store for the user name. At this point, all we know is that this user is on our list of valid users.

Next, the plugin compares the password Henry typed to the password in his user record. If they match, Catalyst::Plugin::Authentication authenticates Henry and he logs in successfully. Now we know that Henry is who he claims.

The User List

To use Catalyst::Plugin::Authentication, you first configure a store. Remember, the store is where you keep your list of users. Search CPAN for Catalyst::Authentication::Store. There's a whole bunch of them. Shoot, they even have one for when you don't need a store

The store populates a user object with the user's information. The exact fields depend on what your store holds. That's good news. Catalyst::Plugin::Authentication provides standard ways of checking the user without limiting the information you keep.

I used Catalyst::Plugin::Authentication::Store::DBIx::Class. The application keeps a list of valid users in an SQL database. The examples had everything to get it up and running.

Check the Password

99% of the time, you can use the simple Catalyst::Authentication::Credential::Password. It compares the password Henry typed with the password in his user record. Catalyst::Authentication::Credential::Password fully supports encrypted passwords. This part was dead simple to setup.

Unfortunately, my application required a little more. Work uses Active Directory as a single sign-on system. My Linux server accesses it through LDAP. To validate a password, I actually have to log into LDAP with that user name and password. If the query returns a record, then the password is valid. My code never sees a password from the LDAP server. And anonymous queries fails.

I couldn't find an existing Catalyst credential for this type of password check. So I wrote one. Turns out much easier than I thought. Catalyst::Plugin::Authentication calls the authentication method in the credential. Then the credential code calls down into the store for loading the user.

My custom module loads the user from the database with Catalyst::Plugin::Authentication::Store::DBIx::Class. If that succeeds, it then queries the LDAP server with the login and password typed by the user. This is not the normal way that you authenticate with LDAP. Our setup at work is, well, odd.

I created the custom credential module specifically for our setup. Server name, dn, and all of the LDAP settings are hard coded into the module. On the up side, it makes adding single sign-on a piece of cake.