These days when people find out the industry I work in, one of the first questions they ask me is about the current financial crisis. When I started my job, I received some excellent training on the financial markets and in particular the credit crisis. A college friend recently tweeted a link to a short video explaining the whole mess in a way that almost anyone can understand and it reminded me of the training that I received. I decided to post the link here just in case you missed my post on Twitter. I highly recommend watching this video. Hopefully it will reduce the number of questions I am asked.
An Excellent Explanation of the Financial Crisis
February 22nd, 2009Why I shouldn’t Buy Train Tickets – Final Part
January 5th, 2009Happy 2009 everyone! It is the new year and that means my little experiment is done. I have December’s train ticket results and they are identical to November’s. My ticket was checked a total of 9 times which at $2.25 USD a ticket comes to $20.25 USD total. This means I could have saved $39.75 USD if I did not buy the $60.00 USD monthly pass.
Totals
I did this little experiment for 5 months. That means I bought 5 monthly passes at $60.00 USD. That adds up to $300.00 USD that I paid for travel on the NJ Transit rail system. If I only bought tickets for the times that I was checked I would have only needed 46 tickets and my total would have been $103.50 USD. That is a difference of $197.50 USD. I could have saved almost two hundred dollars by not buying monthly passes. That is a pretty staggering number if you ask me.
Conclusion
My only explanation for these results is that NJ transit just doesn’t care about checking tickets between Secaucus Junction and Hoboken. It’s a ten minute ride and I guess they just think they have better things to do than to worry about who boarded the train for the short journey. That annoys me slightly since I am following the rules for no real reason. I hope you have enjoyed reading about my little experiement as much as I enjoyed performing it.
PHP: Time To Break With the Past
December 29th, 2008A few weeks ago the Python Software Foundation released version 3.0 of the Python programming language. This was a big deal because version 3.0 broke backwards compatibility with the widely popular 2.x line of the language. Obviously, making the decision to break backwards compatibility was an extremely difficult one to make and many people have mixed feelings on the subject. My opinion on it is that the break is a good thing. The changes made to the language make it better and the way the organization is making the transition is smart.
But this post is not about Python, but another programming language: PHP. Unlike the Python Software Foundation, the PHP group have made some poor decisions about their language and I believe it is hurting the language and will ultimately lead to their downfall. I think it is time for PHP to do exactly what Python did and break backwards compatibility.
Now I don’t claim to be an expert in the inner workings of the PHP organization but I am a user of the language. I program all of my web sites in PHP and I have written a few applications in full object orientated PHP 5. I can say that trying to write a OO PHP app wasn’t the greatest experience and that is directly related to the deficiencies of the language. Here are a few things I think that the PHP group should do in the next version of the language to make it a more viable, competitive programming language.
Get Rid of Old Stuff
One of the first things that needs to be done to clean up PHP is to get rid of all of the duplicate functions and old libraries that continue to hang around from PHP 4 and below. For example, there are currently two different libraries for connecting to MySQL databases plus the PHP data objects library that also supports MySQL. There is no need for three separate ways to connect to the same database. The language is also riddled with functions that do the exact same thing. For example the die() function and the exit() perform the same action. The documentation even says that they are same. There is no reason to keep both of them around. PHP needs to clean up all of the redundant functions in the language and focus on making the core functions better.
Add Real Namespace Support
PHP is adding namespace support in the upcoming version 5.3. Unfortunately, rather than use a normal, sensible delimiter that many other languages use, such as the period (.) or double colon (::), the PHP group has decided to use the backslash (\), most commonly known as the directory separator in MS Windows. If you combine that with any sort of auto-loading, your asking for confusion. The developers need to wake up, admit their wrong, and overload one of their reserved characters to give us some proper namespace support.
Real Constructor and Function Overloading
While PHP 5 gave us much improved support for object oriented programming constructs, they dropped the ball in the area of polymorphism, especially constructor and function overloading. Its time to get rid of those stupid magic methods __get() and __set() and give developers real function overloading support. Storing all of your private instance variables in an array is not a clean, easy to read approach to storing data in objects.
Better Type Hinting Support
PHP is a dynamically typed language and I don’t mind that one bit. But even with a dynamically typed language, there still is a difference between a string and a boolean value. Type hinting goes a long way in making sure that the data you pass into a function is of the correct type but I think it needs a bit more to be truly useful. PHP needs to enable type hinting for the primitive types as well as custom object types and arrays.
Built in Documentation Support
This is sort of a want to have feature that I think all languages should have. I know that there are plug-ins and external programs that give you Javadoc like support (I use phpDocumentor) but having it built in would make it so much easier to generate documention. Its not a deal breaker but it would be great to have.
Single Extension Repository
One of the great parts about PHP is the large number of high quality plugins and modules that you can download and instantly expand the PHP language to support all sorts of technologies and systems. The problem is that they are housing in two different extension repositories: PECL and PEAR. While they use the same package structure there really isn’t any reason that I can tell to have two. To me it just creates confusion for newcomers and inexperienced developers. Lets drop the separate repositories and and create one uniform repository to house all of those great extensions.
So that is my short list on things that need to be fixed in PHP for it to continue to compete against languages like Java, C# and Python. Feel free to disagree and comment below. If you have a suggestion for other features that should be added/changed/removed, let me know. I welcome a good discussion.
Why I shouldn’t Buy Train Tickets – Part 4
December 3rd, 2008December is here and so is November’s results. Of the 36 possible times my train ticket could be checked, it was only checked 9 times. One way tickets are still $2.25 USD so if I only bought one way tickets, it would have cost me $20.25 USD. This means I could have saved $39.75 USD by not buying a monthly pass.
I have decided to run the experiement through the end of the year. I figure 5 months is more than enough data to reasonably conclude whether or not I should buy train tickets. Stay tuned!
Why I shouldn’t Buy Train Tickets – Part 3
November 2nd, 2008I have October’s results for my train ticket experiement and the . Of the 45 times I rode the train this past month, my ticket was only checked three times! At $2.25 USD a one way ticket, my three tickets would have costed me $6.75 USD. That means I could have saved $53.25 USD if I did not buy a monthly pass.
I am beginning to wonder if I am somehow a factor in all of this. I don’t take my ticket out unless I am asked to display it. I am thinking that because I am not waving my pass around at the first sight of a conductor, that the train staff thinks my ticket has been checked already. That is not acceptable to me since it is not my responsibility to make sure my ticket is checked. That is the train staff’s responsibility and I am not going to do their job. I will see if next month continues the streak of no checks.
LAME MP3 Encoder for Windows Download
October 22nd, 2008For those of you who use the LAME MP3 Encoder to rip CDs to MP3 (like me), the LAME project recently released version 3.98.2 of the encoder. Since the LAME project does not release compiled binaries, I thought I would compile the encoder and stick it on my site for all to download. I know from experience that finding the latest version of the encoder compiled for windows can sometimes be hard so I thought I would help the cause. The zip file below contains both lame.exe and lame_enc.dll. It was compiled with Visual Studio 2008 on Windows Vista. Please let me know if you have any issues with the files or if you find a newer version of LAME was released (so I can update my files).
Apple Notebook Event Reaction
October 15th, 2008Yesterday Apple had a small event in California to unveil their new notebook line. Apple announced a new Macbook, Macbook Pro, and Macbook Air. I was especially interested in the announcements because I am in the market for a new Mac and I was leaning towards a laptop.
Nvidia Graphics
One of the larger announcements made at the event was how the new notebooks were going to include the new Nvidia mobile chipset and graphics chip. The new chipset should give a nice speed boost for many high end graphics applications (like the new Photoshop CS4) and allow for more gaming capabilities on the Mac platform. While I welcome the new chipset I am not going to be doing much graphics work on my laptop so I am not that interested.
Aluminum Enclosure
Another big announcement made was about the new manufacturing process for the notebooks. All three of the notebooks are now being made using a unibody construction technique. They made the cases out of solid aluminum to make them stronger and more durable. I really like the new aluminum cases and I am all for a stronger, durable laptop. I am glad I waited to buy a new mac because these cases are much nicer than the plastic ones of the previous generation.
Glass Trackpad
One feature I am going to have to try before I buy is the new mouse trackpad. I have been wishing Apple add a right-click button on their laptops (or all Apple computers for that matter) for a long time. But instead of adding a button, they decided to take away mouse buttons all together. Apple made the entire trackpad a button and made the it even larger to support multi-touch gestures like they have on the iPhone. I have an iPhone and iPod touch and I like the touch gestures but I don’t know how well they will work on a notebook. I plan on going to an Apple store to try out the new trackpad before I make any decisions on the notebook.
24 Inch Cinema Display
Another announcement they made was a brand new 24 inch monitor with a built in web cam, microphone, and USB hub. It’s a very nice monitor but it is still much more expensive then other monitors of the same side. I don’t think a web cam is worth an extra 200-300 bucks.
Disappointments
I was disappointed with the lack of Blu-Ray support for any of Apple’s computers. I could care less if they put the drives in the computers but I at least want the ability to play them if I put my own drive in. Steve Jobs said that they are holding off until licensing issues are resolved and demand picks up. While I agree that Sony needs to ease up on some of these absurd licensing and DRM restrictions but I don’t think Blu-Ray will take off until a company like Apple makes it easy.
I was also disappointed with the lack of a real price cut. Apple did technically reduce the cost of the laptops but that is only for an under powered machine with the old plastic case. The new notebooks with all the great features are still rather expensive and I think that is a mistake. But I can’t say that I am surprised since Apple never has any really affordable products.
Final Thoughts
Overall I am pleased with the new notebooks. As I said earlier, I am definitely going to try before I buy any notebook so I guess I am off to an Apple store this weekend.
Why I shouldn’t Buy Train Tickets – Part 2
October 2nd, 2008October has begun and I have the September’s results for my train travels. Make sure to read part 1 of this story to learn why I am keeping track of the number of times my train ticket is checked.
For the month of September I traveled on the train a total of 42 times and had my ticket checked only 15 times. Remember that a one way ticket is $2.25 USD and a monthly pass is $60.00 USD. If I only bought one way passes for the times I was checked I would have saved $26.25 USD.
So it seems that buying a monthly pass is turning out to be a bad idea.
Simple Backup Script using Windows Script Host and JScript
September 29th, 2008At work, I do my development on my local hard disk. I do this mainly for speed. But in between CVS check-ins I need to make sure I don’t lose any data. The company gives us all network drives that they keep backed up so I decided I would backup my local data to the network drive every night. I didn’t want to do this every day before I left work so I decided to write a script to automate the process. I had a few goals for this script to accomplish:
- Back up all the data in my local folder to a designated folder on my network drive.
- Keep each days backup in a separate folder labeled with the date of the backup.
- Automatically check the backup directory for backups older than a specified amount of days. I wanted to keep 5 days of backups at a time.
So I started to write a simple batch script to accomplish my goals. I always try to start with the simplest language to solve my problem. There is no reason to write a full blown application for a such a simple task. As I was writing the batch script the backing up part was easy to write but I couldn’t quite get my automatic deletion of older backups to work the way I wanted to. So I decided to abandon the batch script and move up to the next level. I examined the tools I could use and I decided to utilize another scripting technology built into Windows: the Windows Script Host or WSH.
There are two types of languages you can use to write WSH scripts: VBScript and JScript. VBScript is a simple scripting language based on Visual Basic and JScript is the same but based on JavaScript. I am familiar with both Visual Basic and JavaScript so I had a choice to make. I decided to use JScript because I like the syntax style better than Visual Basic.
So I hopped onto MSDN and read up on WSH and JScript syntax and a few hours later, had a finished script. I was pleasantly surprised at the power that the WSH and how easy it was to develop the script. Below is the script:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | /* * Local to Network Drive Backup Script * Version 1.0.2 -- 2008-10-22 * Written by Matt Bertolini * * Copyright (c) 2008 Matt Bertolini * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ // Variables to customize var appName = "Local to Network Drive Backup Script"; var appVersion = "1.0.2"; var appVersionDate = "2008-10-22"; var sourceDir = "C:\\path\\to\\files\\to\\backup"; var backupDir = "C:\\path\\to\\backup\\folder"; var numDaysSaved = 5; // Editing below this line is not recommended. // Windows Script Host objects var out = WScript.StdOut; var fso = WScript.CreateObject("Scripting.FileSystemObject"); var WshShell = WScript.CreateObject("WScript.Shell"); var currentDateObj = new Date(); // Event log constants var LOG_EVENT_SUCCESS = 0; var LOG_EVENT_ERROR = 1; var LOG_EVENT_WARNING = 2; var LOG_EVENT_INFORMATION = 4; var LOG_EVENT_AUDIT_SUCCESS = 8; var LOG_EVENT_AUDIT_FAILURE = 16; // Display script information to console. out.WriteLine("==============================================================================="); out.WriteLine("\n " + appName + "\n"); out.WriteLine(" Version " + appVersion + " -- " + appVersionDate); out.WriteLine(" Written by Matt Bertolini\n"); out.WriteLine(" Script Directory: " + WScript.ScriptFullName); out.WriteLine(" Backing up files for date: " + dateToIsoString(currentDateObj)); out.WriteLine(" Number of days to keep backups: " + numDaysSaved); out.WriteLine(" Directory being backed up: " + sourceDir); out.WriteLine(" Backing up to directory: " + backupDir); out.WriteLine("\n===============================================================================\n"); // Execute script functions. backupFolder(sourceDir, backupDir); deleteOldBackups(backupDir, numDaysSaved); WScript.Quit(0); function deleteOldBackups(backupDir, numDaysSaved) { // Create folder object for backup directory var backupDirObj = fso.GetFolder(backupDir); var fc = new Enumerator(backupDirObj.SubFolders); for(; !fc.atEnd(); fc.moveNext()) { var folderName = fc.item().Name; var cutoffDateObj = new Date(); cutoffDateObj.setDate(currentDateObj.getDate() - numDaysSaved); if(fc.item().DateCreated < cutoffDateObj) { out.Write("Deleting backup " + folderName + "... "); fso.DeleteFolder(fc.item(), true); out.WriteLine("done"); WshShell.LogEvent(LOG_EVENT_SUCCESS, appName + " - Old backup " + folderName + " deleted successfully."); } } } function backupFolder(sourceDir, backupDir) { try { if(fso.FolderExists(backupDir) == false) { out.Write("Backup folder does not exist. Creating folder..."); fso.CreateFolder(backupDir); out.WriteLine("done"); } } catch(e) { out.WriteLine("Could not create backup folder."); WshShell.LogEvent(LOG_EVENT_ERROR, appName + " - Could not create backup folder -- " + e); } try { out.Write("Creating folder for today\'s backup..."); backupDir = backupDir + "\\" + dateToIsoString(currentDateObj); fso.CreateFolder(backupDir); out.WriteLine("done"); out.Write("Backing up files..."); fso.CopyFolder(sourceDir, backupDir); out.WriteLine("done"); WshShell.LogEvent(LOG_EVENT_SUCCESS, appName + " - " + "Backup successful."); } catch(e) { out.WriteLine("Backup failed."); WshShell.LogEvent(LOG_EVENT_ERROR, appName + " - Backup failed -- " + e); } } function dateToIsoString(dateObj) { var yearStr = dateObj.getYear().toString(); var monthStr = (dateObj.getMonth() + 1).toString(); var dayStr = dateObj.getDate().toString(); if(monthStr.length == 1) { monthStr = "0" + monthStr; } if(dayStr.length == 1) { dayStr = "0" + dayStr; } return yearStr + "-" + monthStr + "-" + dayStr; } |
Next, I wrote a small batch file to call the Windows Script Host with the parameters that I wanted. Here is the batch file:
1 2 3 4 5 6 7 8 | @echo off cls setlocal title Local to Network Drive Backup Script call cscript.exe //nologo backup.js endlocal cls exit |
Now for the best part. I am releasing the script under the MIT License so everyone is free to use and modify the script. All you have to do is keep the license at the top. Now I know the script is not perfect so if you find any bugs or have any suggestions on how to improve it, comment in this post and I will see what I can do.
Update 1 – 2008-10-02
I found a small bug in the ISO date formatting function so I have updated the script and bumped the version up to 1.0.1.
Update 2 – 2008-10-22
I have updated the script to version 1.0.2 by adding some more logging features (to the Windows Event Viewer) and to fix a bug with the deletion of old backups).
Why I shouldn’t Buy Train Tickets – Part 1
September 19th, 2008I am a regular working stiff now and that means that I am also a commuter. To get to work I have to take two trains: New Jersey Transit and PATH. Every month I have to buy a monthly pass to ride NJ Transit but as I settled into my commute I quickly noticed a disturbing trend; my ticket was not being checked.
Since I payed $60 USD for my monthly pass I was kind of annoyed that my ticket wasn’t being checked. Every time I rode the train without a check, I was wasting money. Because of this, I decided to do a little experiment. I started keeping track of when my ticket was checked to see how much money I could be saving by not buying a monthly pass. My backup plan would be a standard one way ticket. Since a one way ticket does not expire, I would keep one in my wallet for a time when my ticket was checked.
The first month I conducted this test was August. In this month I rode the train a total of 40 times. Of those 40 times, my ticket was checked only 10 times. A one way ticket for my trip costs $2.25 USD. So for the month of august, if I just bought one way tickets, my travel costs would be $22.50 USD. That is $37.50 cheaper than a monthy pass. That’s quite a savings.
Because of my findings in August, I decided to continue my experiment through September. I wanted to gather more data to see if it August was just a fluke or if NJ Transit really doesn’t care. I will post my September results in part 2 of this story. Stay tuned.