More fake content here! A few days ago, I posted a simple text-to-speech application I wrote in C#. Well, I've cleaned up the code and I'm putting it out there for general consumption. It's essentially just a wrapper for the SpeechLib object, although the Choose Voices part is pretty cool.
Anyway, open it up and let 'er rip. The code hasn't been tested or anything, so if it accidentally pokes your eye out, don't come looking in my direction. The code is released under the GNU Public License.
Alas, real world has interrupted the vlog momentarily. Until I can get back to the important stuff, here's a little text-to-speech engine I wrote in C#. Nothing is funnier than making your computer talk about corny dogs.
(You need the .NET run-time to run it.)
For the past few weeks, the summer interns at Fog Creek Software have been blogging about a top secret product they're building. Recently, on the JoS boards, someone revealed what the top secret project is: a remote PC assistance tool. Since I have nothing better to do with my life, I am practically compelled to write about it here.
Assuming this is not a hoax (and really, I have no idea), the idea is that you'd pay $9.95 for a day pass to this service, and once you've paid, you'd use the service to allow your techie friends to remotely fix your PC. There are a lot of products already like this, and I'm sure that other folks on the web are hashing out the weak points even as I speak. That's not what I want to do; instead, I'd like to point out an opportunity for a great feature.
Like a lot of other technically inclined folks, friends and family often ask me to help fix their system. Usually, they've done something silly, like replacing their video card with a grilled cheese sandwich. Usually I say no, just because there's nothing in it for me. There are absolutely no incentives to helping stupid people with their computers for free. If Joel wants people to use this service, he should include a method to compensate the person doing the work.
Rather than the service costing $9.95, it could cost $9.95 plus $X, where X is set by the technician in advance. (It'd be neat if, rather than depositing the money in your bank account, you could donate it to charity.) Suddenly, an incentive appears for me to help these people with their problems. Not just help to them, but to through one and only remote assistance tool. It's money for the company, money for me, and a functioning PC for the user. Repeat that enough times, and you'll have people dancing out in the streets in their underwear.
You could even take that one step further, and set up a marketplace where individuals would offer their time, and non-techies could read their reviews and then chose accordingly. There are lots of intriguing possibilities here. I think if you want something to catch on, there must be a compelling reason to use it. This definitely qualifies as one to me.
Question! Does anyone know of a developer-friendly VoIP company? Perhaps one that already has some good APIs out there I can mess around with?
Now that school is over and I'm left with plenty of time, I'd like to fulfill one of my ultimate fantasies, an application that answers the phone for me. After that, maybe I can write something to make all of my outgoing phone calls for me. Hopefully, little by little, I can automate all manual tasks in my life, building up into some sort of robot butler who does everything for me.
Man oh man, I came up with a great idea for a summer project yesterday. I
even came up with a zinger of a name for it. If I had a million dollars for
every project I devised, gave a clever name to, and then failed to complete,
I wouldn't be screwing around on this site. No way, I'd be running down the
streets with burlap sacks full of Sacajawea dollars, whomping people on the
head with it. And whenever someone tried to arrest me or stop me, I'd hand
them one of the bags. Can't you see the beauty of it?
I think I'm going to be changing the format of this site from longer,
less-frequent updates to short, frequent dispatches. All of that essay-type
stuff takes a long time to do, plus I hate sounding like some pompous
windbag. More pomposity, less windbaggery, that's my thinking. Also, it's
hard to motivate myself to do any coding after spouting off here for several
paragraphs. So there!
Sorry about the time between entries here on the vlog; real life intruded. Anyway, before all of that happened, we were getting all hot and heavy with the Piggybank project (apologies to Jake Jarmel). I came up with some requirements, both functional and technical, and I also decided upon the platform I'd be using. Now, all I have to do is slap all of that into a Word doc, email it to India, and voila, the project will be done by Boxing Day.
Maybe some folks over on the other side of the building think it's that easy, but it never, ever is. I think that's because, when we think of our projects, we use very mushy terms: we need a thingie that does a bunch of junk and sends a deal to whosits. As some point, someone needs to turn that jumble of ambiguity into a discrete, well-defined product. That's where we, as technologists, come racing into the picture with our supercharged Segways. Of course, it's not all programming; a major part of the development process is eliminating that ambiguity, and putting the entire project into concrete terms.
That's what I've been trying to do here with Piggybank, by asking what it's going to do and how it's going to do it. I'm doing this project for my own amusement, not to corner the frozen orange juice futures market, so I've kept it as fun and informal as a tickle fight during a sleep over. I've done a pretty good job so far, almost enough to start coding, but I'm not done yet.
A few entries ago, I came up with some very basic technical specs. They were so basic, in fact, I should've written them in fingerpaints on a Denny's place mat. And I would've, if the waitress hadn't thrown me out for making a mess. Part of these specs was the description of a few very important classes. Before I get too carried away with the coding, it seems important for me to go back and look at how I should implement these classes. I need to don a beret, stick a fancy cigarette holder in my mouth, and call myself an architect for the next few minutes. Since lots of classes will be inheriting the asset class, that's the one I'll focus on for today.
What are the characteristics of an asset, and how will I implement these characteristics?
1. A description, to differentiate it from other assets. I'll contain this in a string in the class.
2. A present value. Sometimes, this is just a total (savings account); other times, this is number of shares times share price (stock). Rather than deal with that bit of complexity, I'm going to use the stock approach for everything, with two floats for shares and share price. For a $120 savings account, I'll handle it in the program as if the user had 120 shares of cash, each of which were worth $1. That's how real life banking systems work, I think.
3. A series of transactions. For instance, you may buy a stock, sell a little bit, then buy some more. All of that happens to one asset, and we need a way to handle it. Also, transactions occur linearly, so we need to store them in such a manner. With that in mind, the asset class will have a linked list of transactions. Each node in the linked list will have a date, a monetary amount (positive or negative), and a share amount (positive or negative). The first transaction will occur when the user purchases the asset; that way, we don't need any separate vars for that bit of info. If you total up shares involved in the transactions, it should equal the shares held; that way, we dont' need any separate vars for that bit of info.
In writing that brief list, I did a whole lot of rewriting as new ideas occurred to me. I also realized that some of the items from my specifications that I thought fit into the asset class (gain/loss calcuations, etc.) shouldn't appear there. In fact, if they do appear there, I'll have no choice but to chase them around with a pitchfork and a demented gleam in my eye. That's architecture in action, my so-called friends. And that's what specs are for, so you can rewrite paragraphs instead of rewriting entire applications.
To spare you, the nice people of the electroweb, I am going to do the rest of the architecture by myself and jump right into the coding next time. Bring your galoshes because we'll be getting muddy.
Today, I'll do a bit more on the continuing saga of Piggybank, an investment tracker/profane haiku generator I'm beginning to develop.
Last time, I think I came up with some pretty good ideas of how to implement the functionality. I know the number of classes I need, as well as what these classes need to do and how they're relate to each other. Notice, however, that I did NOT mention a single thing about which language I'd be using. I did that on purpose, not because of a mental lapse which temporarily had me believing all software was constructed from crepe paper and popsicle sticks.
It seems to me that all too often, developers select their tools for a project before they've even defined the project. A builder in real life would never select a hammer and some woodglue, and then decide to build a car with them. Well, he might, but I speak from experience when I say that balsa wood cars rarely prove to good ideas in the long run, especially if you break down near a beaver lodge (what do beavers live in?).
Anyway, I think I've defined the project pretty well, so I'm now ready to choose my language. There are two requirements here. First, the language needs to be multiplatform, since I boot into Linux a lot. Second, it needs to be capable of producing a nice UI without a lot of work. Simple enough, but those eliminate almost everything.
Since it needs to be multiplatform, C# and VB.NET are out of luck. Since it needs to produce a pretty UI, C, C++, and Perl are all out. The best option it seems to me is to use Java with the SWT toolkit. Immediately after typing that, I read something about wxPython, which supposedly produces really nice, native-looking GUIs. I have two choices then: Java w/ SWT and wxPython. Anything else is almost certainly too obscure for me.
When making these decisions, I operate a bit differently from most folks. Most folks would ask, "What here could work the best?" and then make the decision accordingly. I, on the other hand, ask, "What has the minimum probability of causing a maximum amount of damage?" The conventional wisdom is to decide based on reward, whereas I decide based on risk. To me, that's a good strategy; I'd much rather work with a language that's sturdy, dependable, and well-understood than one that vacillates between greatness and mind-numbing horror. In mathematics speak, all I'm trying to do is to minimize the amplitude of the variation.
Now, keeping all of this in mind, I'm still in training pants mode in Python. Add to that the fact that I know nothing of the graphics toolkit behind wxPython, and I'm inclined to think that selecting it could pose a very real risk to my project's success. I'm not real familiar with it and I don't have any reliable resources to which I could turn if a disaster occurred. It could be absolutely fabulous for this task, but I don't enough to venture a guess. Java, meanwhile, has been around for quite a while. I'm pretty good with both it and SWT, and I know a few Java gurus who could help to keep me from eating any rat poison, programmatically speaking.
Okay, I made that decision. The important thing, I think, is to have a methodology you trust. Even though mine may seem kinda weird, it works pretty well for me. It's a little less precise than Paper Rock Scissors, but what isn't? Next time, we don our nerd classes and begin to design the classes.
In case you've been missing out on the fun, I have been planning a new project to track investments. I know what you're thinking here: "Your set of Yoda bath towels isn't really considered an investment, Cody." That's debatable, I think. Nevertheless, some people do put their money into more conventional securities and it'd behoove them to have an easy way to analyze all of that business. That's the impetus behind the Piggybank project.
Last post, I came up with a really simple set of things I wanted the program to do; I called it my functional requirements. I didn't come up with any fancy word documents or diagrams for this, I just came up with a quick list. To me, the specificity of the requirements is based on the importance of the project: the more important a project is, the more work needs to be devoted to requirements gathering. And since every project is at least a little important (or else why are you doing it?), some amount of effort should always be directed towards that stage. With Piggybank, I have a budget of $0 and a target audience of 1, so a list on my website seems like the appropriate amount of effort.
Now that I've identified what I want to the program to do, I need to examine how I'd like to accomplish this functionality. Certainly there exists a really complicated way to do that, but I'm so lazy, it's a minor miracle that I'm not morbidly obsese. In keeping with that, I'll spec this section out by going back to list of requirements and expanding each item with a few ideas on implementation. I laugh haughtily and spit in the direction of a wholly new document for this.
What will Piggybank do, and how will Piggybank do it?
1. Handle the basic variety of investments (stocks, bonds, mutual funds, cash).
These assets all share a few common traits, so I'll start off here with a base asset class. The asset class will contain things like cost, name, and value. I'll then create classes for each type of asset, all of which will inherit from the base asset class.
2. Store the cost of an investment.
This will be stored in the base asset class. Rather than force the user to enter this each time the program is started, I'll store this amount on the user's hard drive. There's really no need for an entire database for such a simple application, so we'll save it in an XML file.
3. Store the present, near real-time value of an investment. (it's really hard to get actual real-time quotes for the market.)
We'll scrape this value from the Yahoo Finance website, since that's what everyone else does. We won't be hitting the site constantly, but just once when the program is first launched, and then whenever the user hits a Refresh button. In the event of network troubles, we'll also store the last valid value in the XML file. (Side note: isn't it amazing how Yahoo has managed to build the definitive resource for the world of finance? I used to work at an investment bank, and it was definitely the most popular site there. Something for Jeremy Zawodny to be jazzed about.)
4. Calculate the gain/loss on that investment.
This value is easily calculated using data contained in the asset class: (value + distributions) - cost. If it's that easy, there's no point in storing that in the class or the XML file; we'll just a method in the class to perform the calculation.
5. Calculate the tax consequences.
In order to this, we need to know the purchase date. Since this bit of information doesn't pertain to all types of assets (eg, there are no tax consequences for cash), we'll make this part of the asset-type classes that inherit from the base asset class. Also, some investment accounts are tax exempt (eg, Roth IRAs). Since all assets belong to an account, we'll create an account class that contains a collection of assets and also the account's tax status, description, etc. We'll group the assets by account in the XML file.
6. Calculate that investment's weighting in the portfolio.
This is another example of something that's very easy to calculate: asset value / portfolio value. That marks the first time portfolio has been used, but it's important, since all accounts (and thus all assets) belong to a portfolio. We'll have to create a portfolio class that contains a collection of accounts, along with some basic descriptive data.
7. Create a few basic graphs: an asset allocation graph, an asset weighting graph, etc.
I have absolutely no interest in graphing out financial data myself (note the delicious pun). We'll accomplish this using a third party library.
8. Calculate an annualized rate of return for the investment, wherever possible.
Also easy to calculate, since we'll have cost and date of purchase, along with value and the current date. I don't remember the exact formula, but it's something like: cost * (1+ rate of return)^years = present value. Since it's easy to calculate, we'll just create a method that does this, rather than storing it in the class or XML.
9. Calculate the time horizon of a few simple goals: I'm saving X amount per month, it's compounding at Y, how long until I reach Z amount of dollars?
This stuff also isn't too difficult to calculate, but it doesn't really fit in with any of the objects I've discussed. Should I attach these methods to the portfolio class, or is a wholly new class needed? Since some of the calculations involved will involve the user to speculate some, it seems best to separate it from the portfolio so nothing gets mixed up. We'll need a calculator class that contains these methods.
Verbose list, I dub thee my specifications! Actually, I like it that the specs are here online, because that means it'll be easier to change them later. I'll almost certainly have to do this, since I haven't devoted a great deal of thought to the planning. To me, that's okay. I'm not flying the space shuttle here, just keeping track of a few stocks. We'll save the space shuttle control functionaly for version 2.
In my last post, I outlined a piece of software I'd going to write, an investment tracker called Piggybank. I have a basic idea of what I want it to do and a snazzy name (subject to change based on my violent whims), so it's time to start coding. That is, it'd be time to start coding if I weren't an utter moron, but I am. Not in the "I don't know how to work a zipper" way, but in the "Hey, it'd be neat if it could do this!" way. If all I do is shoot from the hip, I'll end up with a load of cool features that are all 40% complete, and I'll lose interest rapidly.
My hard drive is littered with the corpses of projects who died from this. I call it neatoitis. The project suffers from an inflamation of its neato factor, as I jump from cool feature to cool feature like some sort of rabid monkey. Eventually, the frenetic pace wears me out and I give up entirely. Fool me 700 times, neatoitis, shame on you; fool me 701 times, shame on me!
The only way for me to beat neatoitis is to never give a chance to appear. The best way to accomplish this is to, gasp, document and plan. Trust me, it hurts to say that. I know, though, that I must give myself some firm guidelines with regards to what the program will do, or else it will never do anything at all. In addition, I need to make it clear what the program WON'T do, lest neatoitis don a nun disguise and try to sneak its way into my coding.
Okay, I now have two questions to ask, through which I will define the scope of the project.
What will Piggybank do?
1. Handle the basic variety of investments (stocks, bonds, mutual funds, cash). 2. Store the cost of an investment.
3. Store the present, near real-time value of an investment. (it's really hard to get actual real-time quotes for the market.)
4. Calculate the gain/loss on that investment.
5. Calculate the tax consequences.
6. Calculate that investment's weighting in the portfolio.
7. Create a few basic graphs: an asset allocation graph, an asset weighting graph, etc.
8. Calculate an annualized rate of return for the investment, wherever possible.
9. Calculate the time horizon of a few simple goals: I'm saving X amount per month, it's compounding at Y, how long until I reach Z amount of dollars?
What won't Piggybank do?
1. Handle any of the complicated stuff like derivatives or real estate.
2. Allow the user to do any trading of any kind.
3. Make any sort of recommendations.
4. Determine anything about the security in question, except for what the user inputs. (you can't, for example, put in a stock symbol and have it tell you if it's a small-cap, growth stock or a tortilla company.)
5. Send alerts based on certain events. (nothing like stock hits price X, send me an email.)
Dig it, in defining the scope, we came up with a set of requirements! Almost as important, it's a set of anti-requirements, listing the things I have no business dirtying my little paws with. (Speculation: If requirements and anti-requirements were to meet, they'd tear a whole in the space-time continuum.) Why, if it weren't for the absence of a few thousand lines of code, I'd have one rock and roll program right now. Unfortunately, I'm not quite sure how to do all of this stuff. It's not too hard, but it's not too easy. And so, next time, we'll don our Hammer Pants and get jiggy with some technical requirements. Until then, let's all remain too legit to quit.
Okay, I mentioned on Thursday that I was working on a big piece for this site, but now I have no idea to what I was referring. I can only assume that my cat turned on my computer, logged in to Movable Type, and added that sentence herself. There is cause for concern here, since if she is successfully navigating the web as me, it's just a matter of time before she hits the Bank of America site and begins to liquidate my accounts. Octopussy, you better learn to scoop your own litter box if you're going to be pulling those kinds of shenanigans.
All of this talk about financial matters brings me back to an idea I've flirted with many times, writing my own personal finance program. Yeah, Quicken and MS Money are cheap and fully featured, but why spend $50 on something when I could instead devote hundreds of hours of leisure time to replicating it? That's the cool thing about my personal time: I can spend it as ridiculously as I choose. And believe me, it does get pretty ridiculous.
It'd probably be way too hard to handle checking accounts and credit cards, with the amount of transactions that occur there. Investments, though, are easier; you put your money in and wait for something to happen. In my case, the thing that happens is usually a catastrophic drop in price. But really, this presents an itch I've always wanted to scratch. I have, probably, the nerdiest two pursuits in the history of mankind: programming and the stock market. An ideal project would be something simple that combines the two. An investment tracker is just simple enough to be fun, and just complicated enough to hold my interest.
Okay, I've convinced myself; I'm going to do this. Over the next few weeks, I'll be covering the entire process of the creation of this piece of software, from planning to testing to maintenance. I'm so jazzed about it, I've even picked a name: Piggybank. There's absolutely no way it'll become a Quicken slayer, but at the very least, it should help me determine which accounts my cat has been siphoning.
Coming next: assessing the scope and determining the functional requirements of Piggybank.