Monday, May 5, 2014

Creating Mini Applications to Learn More in the Process

The topic of how to approach developing programming skills is one I've discussed before, both on this blog and on the Geeking After Dark podcast. On the podcast, we (Pete and I) generally agreed that it was best to have a project in mind when trying to program; it gave you a goal to work towards, and you were solving a practical problem. Too often the exercises in programming classes seem boring; what't the point of creating an application that counts to 10, unless it's a prime number?

I missed one another approach to improving programming skills; solving mini-problems. Unexpected things that crop up present opportunities; scripting tasks can be done with actual scripts, or you can try creating small, compiled utilities for future use...scripts on steroids.

 I've been working on a project for awhile that involves creating kiosk-like functionality on a few select laptops. A utility was installed whose purpose was to restore the systems to a specific configuration when restarted; that way users could save files or reconfigure the system and it would go back to its pre-login state. 

I had a few issues with them that led me to believe things weren't working the way they were supposed to, but one of the big ones that I definitely could tell wasn't happening was the setting that told the laptops to automatically reboot every X minutes. 

In the course discussing the problem with their tech support, they said they spoke to the developers and it used the same mechanism (GetLastInputInfo) as the Windows screen saver for determining when to trigger the reboot. They suggested I set the screen saver to run 5 minutes before the reboot was supposed to happen to see if something wasn't resetting the idle counter. 

I thought there had to be a way to get a more direct way to get the counter setting; as I had been playing with Go, maybe that had a method of printing that value. 

Why Go? It's fast. It compiles to work on multiple platforms. It seems pretty flexible. And it compiles a single executable, so there's no need to install a framework or support libraries. Or even run an installer. Plus it's the language I've been recently trying to learn. 

The initial problem wasn't simple to solve; turns out there isn't a direct way to access an API call on Windows using Go. I asked for help on Stack Overflow and fortunately found someone who gave a thorough response; Go has a mechanism for indirectly getting information from API functions. 

The code snippets he gave worked rather well, but reading the code made me think that there was no way I would have figured it out on my own; this was rather disheartening. Once again the "programming makes me feel dumb" bug was biting; it was a profession for people with some kind of innate ability that I lacked. 

I approached a developer working at our company (and who was also playing with Go in his spare time) to ask him for some advice. In part I said,

I’m not entirely sure I understand it, and am hoping that the process of implementing it will shed some light on how it works, but…this is where it seems like there’s a cliff between compiling “Hello, world!” and “WTF is this?” 
So as an experienced developer that looks at that question and probably sees it as, “Of course that’s how you do it!,” where and how do you think that cliff is scaled? Just experience? Is there a thought process or some comprehension that I’m simply missing?

I was still anxious to ask this since I felt that it made me look as stupid as I felt, plus this was a coworker I looked up to. I had to set aside the hero worship part of my brain and instead cash in the reality check that he was an actual person who might be willing to spend a few minutes to offer some encouragement. And he came through. His reply read in part,

Programming experience does have the quality of amassing an amount of trivia (like this) over time. And devs have a habit of making one feel like you should have known that. But no, you shouldn't have known that. You might have known it, or not. 
There are problems that are a test of smarts, but this one has more to do with whether you happen to have been down a very specific road before. Hope this helps! 

That's the kind of encouragement that helps validate that it's okay to be confused or feel a little lost. So I kept with it and within a couple of days of after-hours tinkering, I had a very bare-bones utility that ran a loop dumping the current last input count; the API returns the Windows tick count when input was last recorded from the keyboard or mouse.

So what was I missing?

The laptop was set to run as a kiosk; it booted up and logged in as a non-privileged account, with access from the desktop to a few basic communication tools. When the computer logs in automatically, the tick count reads 0. Let the computer sit until it was supposed to reboot, nothing happened. Let it sit for a bit then hit a key on the keyboard so the last input tick count was non-zero, wait the length of time for the automatic reboot, and it rebooted.

I sent this information to the company, and they realized that I was actually auto-logging in and it sounded like that wasn't a test case they'd tried, although it also sounded like this was purposely designed this way because otherwise it would reboot constantly without ever having been touched. The Windows screen saver didn't care if the counter was zero.

I won't get into the reasons why, yes, I'd like to reboot the computer anyway, because the point is that instead of having to indirectly test the state of the idle timer (which in this case it wouldn't help, since the screen saver counts an idle tick count of 0 and the utility didn't) I had a small utility that can give the accurate insight to what's happening.

It was a small project with a niche purpose, but it was useful and solved a problem while giving me some experience with the language, and it gave some information on how Windows treats login sessions and the scope of the idle timer (I tested at one point whether the mouse/keyboard being used on the laptop would be affected while I was logged into an RDP session, for example.)

You don't need a large project to assist in learning. Small, niche projects can be very useful as well. Mixed with the occasional bit of encouragement from those with more experience, and you have a pretty good recipe for building some programming experience.

No comments:

Post a Comment