Once upon a time I could write a paper for a class, type it once, and trust everything to be pretty much perfect. There might be a few small spelling errors or grammar mistakes, but for the most part it would be correct. Those days are gone. Today, I find myself making typos more and more often. What's more troubling is that I don't even see them right away. Sometimes it takes several readings through the same piece to spot them. Where once I would look in disdain at the broken English so prevalent on the web, I am now numbered among the offenders.
Among my more common mistakes are using the wrong forms of the words 'your' or 'their'. Intellectually I am well aware of the differences, and when each form is appropriate. But somehow, the part of my brain the creates the composition has become disconnected from the part the commits it to the keyboard. One part says "you're", and the other part hears only the phonics and types "your", which sounds identical. I might also make the mistake in reverse: it's not tied to always replacing one with the other. This really is how it happens; I know what I mean to say, which form I need to use, but when I look at what I've typed I see the wrong word.
I've also noticed other things, like missing words, missing or extra suffixes ('s' for plurals, 'ed' for past tense, etc), or plain old typos. Thankfully, I'm not prone to the ever common 'teh', 'hte' being a much more likely mistake. But it does bother me when I'm on my third reading through a composition and only just then notice the mistake. In fact, it's incredibly frustrating, and made all the more so by the fact that it never used to happen. Here I am trying to build a blog worthy of attracting a few readers, and I'm making silly grammatical mistakes like this.
And the blog is the least of my worries at the moment. Hardly anyone reads it, so it's really not a bid deal. Vastly more important is when this occurs in a posting to a forum with people I know, or when I sending an e-mail at work.
So... what can I do to train myself out of this typing rut? I'm looking for ideas to get great grammar going again.
This has been a very interesting project for me to work on, so I wanted to share an update for how things are progressing. Here are the highlights:
1) I had to change the administrator password. Checking logs showed a very large number of attempts to guess the administrator password and log into my FTP site. I had a very weak password and and fortunate that it wasn't cracked. I would like to remove the administrator account from being able to connect at all, but Windows 2000 doesn't allow that. The password is now 17 characters long and something that no one will ever guess, including myself (I can get it if I asbolutely must have it). In it's place I have another account I can use for administrative purposes.
2) I no longer have a file share for code... sort of. Instead, I have an SVN server running. I do share the SVN filesystem, but that's just for convenience in setting it up. I expect to be able to close that share soon.
3) It turns out my home IP changes almost weekly. That's much more often than I expected. Along with that I had a glitch where my program to update the IP address wasn't running. That's now corrected.
4) When staring out, I opted against using Active Directory. I didn't want to mess with trying to get my wife's XP Home system to play nice with an AD Domain, and it would overkill for our home anyway. Windows 2000 Server apparently has some glitches allowing non-administrative accounts to connect via remote desktop if you're not using Active Directory. It wasn't a problem before: I had been using the Administrator account to get things set up (since that's, you know, adminstrative work). Now that this is no longer that case I had to take the time to fix the problem.
Coming soon: I'm looking for a database engine to install that is full featured and will play nice on the older system (perhaps MySQL). Then I'll be setting up the web site so users belonging to a specific group on the local system can log in and see links to the FTP shares and the Terminal Services Web Page. I'm also considering moving this blog to the server.
I want to use today's post to explain the title for my blog. A renaissance man is one who embodies the ideals of the Renaissance Era: art, science, literature, poetry, and even physical strength. The idea is that a person should be able to excel in multiple fields. Leonardo da Vinci is probably the most famous person to hold this title. He was an accomplished painter, sculpter, inventor, and scientist.
When I think about a Renaissance Programmer, I think about narrowing the scope of the 'multiple fields' concept to software development and it's surrounding landscape. This includes web development, desktop development, and embedded development. It also includes computer hardware and gadgets, as well as an understand of software licensing and business issues. In short, just about anything IT. Most importantly, I think by having a better understanding of the larger IT field, of which Software Development is one part, you can be a better programmer.
So it's more than just knowing a bunch of programming languages. These days just about any programmer has to be pretty well rounded. It's hard to get your job done without having at least a basic understanding of XML, HTML, SQL, javascript, regular expressions, and CSS. Even if you concentrate soley on Windows applications you probably run into these regularly (even the web stuff- it's hard to escape now), and that's before you even take any 'real' application languages into account, of which most programmers can use at least two, if not more.
I began my personal journey towards this ideal the same way as many: by earning a BS in Computer Science. As part of that degree I wrote programs using such diverse languages as C++, FORTRAN, COBOL, VB6, and VB.Net, in addition to the staples mentioned earlier. A little old, a little new, and a little in between. But that's normal for a programmer. To expand my reach, I dual-boot Windows and linux at home on a computer I assembled myself. I've earned my A+ and Network+ certifications and spent some time doing help desk work and network adminstration. I keep a pretty close eye on technology news, both hardware and software. But I am not 'The' Renaissance Programmer. There are many. I also consider myself too green, with less than 5 years of experience in my field, to fully claim the title at all. Instead, consider this blog to be the ramblings of one who aspires to the goal of Renaissance Programmer.
As an aside: I'm not committed to the "Renaissance Programmer" title. It's too hard for new readers to type into an address bar. Once you've visited a site for a while the URL doesn't matter any more. You've book-marked it and you don't have to type it. But having a type-able URL is key to bringing new readers into the fold.
I found this article, entitled "Intel Diamondville shuns dual-core", earlier today, and I wanted to share it. It's about an up-coming chip design that seems to take a step backwards, in the name of low cost and power efficiency.
Don't let the title of the article fool you, however. Late in the article it mentions there will be a dual-core desktop version of the processor, and that's where I think the real value will be. That chip will be almost exactly what I've been looking for in a home server processor.
Most consumers, myself included, can't afford to spend a lot of money on an extra computer that no one ever uses directly. Even if they pick one up second hand, a computer running 24/7 will use several hundred dollars worth of electricity per year, and a high end system could even hit $1000. That's enough to give many people pause- its as much as they spent on the hardware in the first place.
Fortunately, modern power management features combined with the low usage rate of a home server mean such a system isn't likely to cost quite that much to run. But it's still something worth considering, especially as a home server system isn't likely to need a very fast CPU anyway (mine is very happy with a 700Mhz Pentium III).
There are other advantages to choosing a low-power system. Simpler cooling would be a big one. Via's C7 is so close to what I'm looking for. It can get by with just a heat sink-- no fan required. This reduces noise and increases the life expectancy of your system. It also means you can use a smaller, cheaper, and quieter power supply. Unfortunately, Via only produces small form factor boards for that chip, and it's only available as single core. Dual core systems have important advantages of their own, especially in servers.
I can envision a linux distribution designed with the low cost Diamonville in mind, geared towards windows home users. Sell it pre-installed on a cheap hardware, with intelligent power management and easy web configuration access for file and print services, that also prompts you to create security settings in a way even novice users can follow. Include other services, turned off by default, that more advanced users could enable. To get really innovative, I'd build a wireless router into a drive bay (with an option for DSL modem, cable modem, or Ethernet WAN connections) and sell low cost USB wireless NICs that could connect to it automatically. It's an instant full-featured home network, that's very cheap and simple to put together.
Notice that earlier in this article I said that the new Diamondvilles are 'close' to what I'm looking for. And they are very close, indeed. Certainly I'll be looking forward to building a system based on that chip when my current server is no longer usable. But if it's merely 'close', what is my ideal? Put simply, I want to be able to use the home server as a media center as well. To acheive a practical, efficient media server, I envision a three core chip. Start with the dual core Diamondville for common usage, and add one core from the mainstream Core -branded processor for the heavier lifting during video playback.
Lately I find myself wanting to throw 'warnings' in my code. What I mean by that is when you throw a normal exception that remains unhandled, program execution stops and an ugly error message displays to the user. I want to be able to throw a slightly different kind of exception. These exceptions, on their own, will never stop execution, will never result in an error being shown to the user, and resume execution at the instruction following the exception rather than after a catch block. This way it's not a big deal if a warning exception is unhandled and program execution can continue on it's merry way. If the application programmer thinks the exception is important they can handle it, and either create a log message somewhere, correct a potential issue earlier in the process, or throw a real exception depending on their needs.
This idea could raise some questions in the mind of a programmer:
Under what scenario would this kind of exception be a valid choice?
I will admit that often this urge is a result of being too lazy to want to clearly think out how an application should behave in a given scenario. It would be so easy to pick an option that seems right at first glance, and then throw a warning so if people don't like it they can handle it on their own. But like I said, that's just lazy. Still, I feel there is a legitimate use for this kind of functionalilty.
To understand where it could be valid, let's look at a real-world scenario. Pretend you're working on an HL7 library. For those who don't know (which is just about everybody), HL7 is a standard for transmitting medical records data. HL7 defines certain messages that can be sent. The messages consist of segments, which themselves consist of different data fields. There are specific rules defined for each of the data fields, and for many fields one of those rules is the length of the field.
Now let's say your HL7 library parses a message from medical practice software that sends more bytes for a field than is strictly allowed. This is actually very common, and the nature of HL7 makes this an easy problem to account for. When this occurs, you want your HL7 library to raise a notification to the larger application code. This gives the application a chance to log the event, truncate the extra bytes rather than keep them, throw a real exception of it's own, or even ignore it completely if it so chooses. This isn't exactly an error, since you've already handled the discrepancy, but it's more serious than a regular event. In this case, it would be very nice to be able to throw a warning exception.
I can hear people now thinking, "Oh, he's fallen into his own 'lazy coder' trap. The correct way is _____." But that's not quite true. The key here is that this is for a class library that will be used in several applications. One application may need to respond in a different manner than another. Having the library be able to run in different modes by requiring the program to set a configuration value or variable is less intuitive and slower. Note that warning exceptions also stop just short of using exceptions for flow control. Just like with exceptions that is a possibility if a programmer chooses to make it work that way, but the main purpose of a warning is to give you a chance to log the problem or correct a potential error.
Couldn't you just do this with an event or delegate?
Now that we've seen where this type of exception might be used, let's look at why I don't feel a regular delegate is good enough. To be fair, a delegate can accomplish my technical requirements. In fact, I have some code now that implements this using a delegate that I'll show in bit, but it's far from perfect.
To begin with, the application code isn't quite as clean, since it requires the programmer to call a static "AddListener()" method. It also differs from an explicit try/catch block in that it the handling code lives in a separate place from any other exceptions the block may handle, and it means using some CPU cycles before any warning is ever even thrown. It potentially exposes the ability to raise the warning outside of the class library (though implemented correctly this isn't a problem). Additionally, I need an extra parameter to differentiate between warning types rather than using a nice inheritance structure. Finally, for application developers to really make use of this kind of functionality it needs to be a top-level feature of the language. If you have to do extra work to use it, you're just going to ignore the capability and may miss on handing important messages.
Bonus
As promised, here's my generic, delegate-based WarningNotification code. I used a module (C# Static Class) because every member of the object is shared and I don't want to allow individual instances. Also notice that the RaiseWarning method is marked Friend, to prevent it's use outside of the assembly. Finally, I declined to comply fully with the standard event args structure, though I certainly could have if I wanted:
Public Enum WarningType
Generic 'Generic warning type. Add different warnings to the enum
End Enum
Public Delegate Sub WarningDelegate(ByVal Sender As Object, ByVal Type As WarningType, ByVal Message As String)
Public Module WarningNotification
Private Event Warning As WarningDelegate
Public Sub AddListener(ByRef callback As WarningDelegate)
AddHandler Warning, callback
End Sub
Friend Sub RaiseWarning(ByVal sender As Object, ByVal type As WarningType, ByVal Message As String)
RaiseEvent Warning(sender, type, Message)
End Sub
End Module
My good friend Dave Mitchel has a few posts on his blog covering a new project he's working on called NSDuctTape. NSDuctTape is an abstraction layer for the Mac that makes it easier to use .Net with Apple's native Objective-C widgets. Macs are out of my price range at the moment so I can't comment personally on the project, not having tried it myself. But if you're interested in using mono on the Mac, this is likely worth a look.
No, not that Home Server. I mean a custom server I put together myself, in the home, that provides services on my home network and even through the internet cloud.
I recently rescued an old Pentium III from the garbage. It had previously belonged to my sister, and was cursed with a mere 128MB of RAM and Windows ME. I added another 256MB I had lying around and installed a copy of Windows 2000 Server I obtained (legally!) while in college. Remember, for a Windows 2000 computer that's not doing any gaming, 384MB is more than enough to be responsive. My monitor has two inputs, so I shared the 2nd input with server. Most access, however, happens through terminal services. The machine is now happily acting as a file and print server.
That's about the limit of it's usefulness to our local home network and it's not doing very much I wasn't already doing with my desktop. I'd like to use it for backups as well, but I don't yet have a meaningful storage device so that will have to wait. The real usefulness comes when I start looking at services it can provide when I'm away from home. Imagine being able to access any of my shared files, or remote in to the local network, from anywhere in the world. To that end I've enabled a few other features, such as IIS and FTP, that I've only begun to fully implement.
The first step in taking advantage of the server outside the home is to set up the firewall on our home router. This process is extremely simple, yet still beyond the scope of most users. It's easy enough I feel confident in my ability to complete it using any modern consumer router, but not so streamlined that I could give a generic set of instructions that would work everywhere. I smell opportunity there for an enterprising software developer to accomplish the streamlining, but that's a topic for another day. So far I've just opened up ports for Remote Desktop and IIS. I won't open up e-mail. I have no desire to keep up with maintaining an smtp server. I briefly considered smb (microsoft file sharing), but decided it was likely to be blocked by internet routers and would create an unnecessary security risk. That means I still need at least FTP, and maybe a few others (Counter-strike:Source server, anyone?).
You can see the results of my work today by clicking on the Home link in my blog's side bar. This will point you to a page that is served up by the new machine. Currently, it's just the default "Under Construction" page, but it won't stay like that much longer. The nice thing about this link is that even though I'm on a residential connection with a dynamic IP, that static link should always work.
Getting a link that would work all the time was a trick in itself. My IP doesn't change often. Sometimes I can go months at a time with the same IP. But it can change without warning, and I wanted to account for that. To solve the problem I could use a service like that provided by DynDNS, but I wanted to try doing this one myself.
It's always nice to create software you're going to use yourself, even if it's just a simple utility. In this case, I built a simple Windows Service in .Net that determines my Internet IP, and every four hours uploads a web page to a free web host that will redirect to that IP. Now I have a simple URL that will always point to my home server and never changes (unless I change it), even though my IP can. The entire thing is only about 40 lines of code, but is still too much to just post here since I'm already running long and I don't have the capability to easily format it in a nice way.
Eventually, I'll probably move to the time-tested DynDNS solution. But it's nice to know I can do this myself if I want to.
Virtual PC is one of those things that I know what it is, but I've never really had a chance to try it out in person. Until this week. I'm in a training class this week that makes use of Virtual PC for all it's labs. So far I'm pretty impressed, but I do have a few complaints:
- The first default option when you quit is to commit your changes. After the first time it remembers what you chose, but only for that machine. There might be a way to change this default, but I don't have time to find it. This is bad, because most of the time you want to use your Virtual PC as a throw-away machine for testing. If you come back and the machine is polluted with work from a previous task, even accidently, you have to completely start over.
- The default cursor for Text Selection is practically invisible. For each little lab I have to go into the control panel and change it to something I can actually see. None of the regular text selection cursors worked well, so I eventually went with a vertical window resize cursor. I suppose in one sense this is more a Windows XP problem than for Virtual PC, but since Windows XP cursors work pretty much everywhere, there must be something different in Virtual PC that causes this.
Other than that it's a pretty neat product. I did have another complaint here and there, but they were minor and most likely due to the way a particular machine was configured for that lab.
I interrupt your regularly scheduled post to bring you this message, received this morning in my e-mail inbox from one of the users I support:
It looks like the last time my eamil was updated was at 10:56 this am. I can see that it is "offline" and don't think it is connecting. Can you help me?
I'll pause a moment to let all the implications sink in... Their e-mail client is 'offline', but they were able to send a request via e-mail? It must be a real big problem...
If you're a programmer, you have to cringe a little whenever you watch a movie where an actor has to hack into a computer. I remember learning that the Matrix runs Unix (unpatched, no less). Knight Rider is no exception. There's a scene where someone is hacking into K.I.T.T., and is almost through the second firewall. They display a profound misunderstanding about how firewalls and networks operate. If you design your network correctly, a firewall is almost an afterthought. This isn't entirely unexpected, just a little disappointing from a production that was otherwise very tech-savvy.
In addition to that minor gaff there were a few times where they played a little too loose with the laws of physics. The worst was the crash scene. I would concede K.I.T.T. could heal damage, but it must first sustain that damage. It could recover from the impact, but momentum must be conserved.
My final complaint was that the story didn't feel solid. I can't describe what was wrong with it, but it definitely had the same cheesy feel as the ill-fated Knight Rider 2000.
In spite of all this, I do hold some hope for the series. A lot of the fault in the story in the movie can be excused for laying groundwork for future episodes. They got a lot right. We'll see how it goes from here.