I follow Joel Spolsky's Blog, which I find very useful and pithy. Joel is a former Microsoft programmer, now CEO and programmer. Joel published a blog way back in the Halcyon Days of 2000 entitled "The Joel Test: 12 Steps to Better Code"
So how do we stack up?
The Joel Test
1. Do you use source control?
Not yet. We make file-system copies. Our score: 0
2. Can you make a build in one step?
Depends. My code is usually a yes, others, not a chance. Our score is a generous .5
3. Do you make daily builds?
Not really. Our score: 0
4. Do you have a bug database?
Nope Our score: 0
5. Do you fix bugs before writing new code?
We try, but without a bug database, it's often hard to tell. I'm going to be very generous and say yes. Our score 1.
6. Do you have an up-to-date schedule?
What's a schedule? Our score: 0
7. Do you have a spec?
Real programmers don't need no stinkin' specs! That's a no, by the way. Our score: 0
8. Do programmers have quiet working conditions?
What did you say? It's too noisy in here! Our score: 0
9 Do you use the best tools money can buy?
Mostly. Being a state agency, buying anything is challenging. I'll say "yes". Our score: 1
10 Do you have testers?
Do programmers and users count? No? Then no. The only thing harder than buying stuff is hiring people. Our score: 0
11. Do new candidates write code during their interview?
Nope. Our score: 0
12. Do you do hallway usability testing?
No. Our score: 0
Joel says "A score of 12 is perfect, 11 is tolerable, but 10 or lower and you've got serious problems. The truth is that most software organizations are running with a score of 2 or 3, and they need serious help, because companies like Microsoft run at 12 full-time. "
We scored a pathetic 2.5. But there's hope! I spend some time today investigating source control, and am confident that we will, kinda, sorta, start using it soon. We're going with Mercurial , an open source distributed source control management tool.
If you've not looked at it, it is a command-line code repository. If you are not using source control at all, look at this tutorial, this blog post, and this tutorial. These sites will bring you up to speed.
Next in my sites, bug tracking!
Friday, September 02, 2011
That's Generic!
So you are creating a small config file and think "Gee, it would be nice to use the auto-serialization feature of dot net"
So you wrap the serialization and deserialization routines as shared (static for you c# guys) functions, and throw a _ in front of your class, and viola!
But, what if you are doing two, three, 48, 72 small serializable objects? Ah, the power of object orientation! Yes folks, object orientation makes this cake. I created an abstract base class which contains the code I need to repeat for each small class.
Much neater!
So you wrap the serialization and deserialization routines as shared (static for you c# guys) functions, and throw a
But, what if you are doing two, three, 48, 72 small serializable objects? Ah, the power of object orientation! Yes folks, object orientation makes this cake. I created an abstract base class which contains the code I need to repeat for each small class.
Imports System.IO
Imports System.Xml.Serialization
Public Class AbstractSerialzationClass(Of t)
Private Shared _ErrorOccured As Boolean = False
Private Shared _ErrorText As String = ""
Shared Function Deserialize(ByRef anObject As t, _ ByVal FileNameString As String) As Boolean
Now to use this in a class, all I've got to do is this_ErrorOccured = False
If File.Exists(FileNameString) Then
Try
Dim aStreamReader As New StreamReader(FileNameString)
Dim x As New XmlSerializer(anObject.GetType)
anObject = CType(x.Deserialize(aStreamReader), t)
aStreamReader.Close()
Catch ex As Exception
_ErrorOccured = True
_ErrorText = "Unable to deserialze '" & FileNameString & "'." & ex.Message
End Try
Else
_ErrorOccured = True
_ErrorText = "XML File -'" & FileNameString & "' was not found"
End If
Return _ErrorOccured
End Function
Shared Sub Serialize(ByVal FileNameString As String, ByVal InObject As t)
_ErrorOccured = False
If File.Exists(FileNameString) Then
If File.Exists(FileNameString & ".old") Then
File.Delete(FileNameString & ".old")
End If
File.Copy(FileNameString, FileNameString & ".old")
File.Delete(FileNameString)
End If
Try
Dim aStreamWriter As New StreamWriter(FileNameString)
Dim x As New XmlSerializer(InObject.GetType)
x.Serialize(aStreamWriter, InObject)
aStreamWriter.Close()
Catch ex As Exception
_ErrorText = "Unable to Serialze Annotation object to file named '" & FileNameString & "'. " & ex.ToString
_ErrorOccured = True
End Try
End Sub
Public ReadOnly Property ErrorOccured() As Boolean
Get
Return _ErrorOccured
End Get
End Property
Public ReadOnly Property ErrorText() As String
Get
Return _ErrorText
End Get
End Property
End Class
Public Class foo
Inherits AbstractSerialzationClass(Of foo)
end Class
Much neater!
Thursday, August 11, 2011
What's Different?
What's Different?
Remember the kids puzzles which asked you to spot the differences? They were fun but also frustrating. I remember straring at a picture saying "WHAT'S DIFFERENT!"
How does this pertain to development? Well, we don't use an automated source code versioning system here at work (I know, we should). Instead, we make copies of each version of the program. So I will have a folder for each version of the code. Sometimes, we accidentally use the wrong folder, and that makes my life resembles these puzzles. I am puzzling out what changed, when and why.
We have some command-line tools to compare folders, but that only reveals files that have changed. We then have to load the files and do a file comparison with them. Can we say tedious and time consuming?
That tedium was ended the day I found K-diff. K-Diff is a really useful tool that can compare two folders and display all of the differences for you. It highlights the files which have change, and double-clicking them brings up the files side-by-side for easy comparison. It makes comparing differences easier and quicker. It has made my life much easier.
You can find K-Diff here at http://kdiff3.sourceforge.net/ It's open source and is available for Windows, Linux, Unix, Mac and anything (in theory) that supports the qt libraries.
Wednesday, August 03, 2011
How To: Hash Data with Salt (C#/VB.NET)
This is a very good example for Dot Net Hashing. It formats the code in both C# and VB.Net.
How To: Hash Data with Salt (C#/VB.NET)
How To: Hash Data with Salt (C#/VB.NET)
Saturday, July 09, 2011
Too Cool no really it is
Most of my posts are very code-specific. This one isn't. This one is more on development philosophy.
I ordered a pizza from Papa Johns online. Being the geek I am, I have an established account in which I have specified my address, phone number, and which store is my local store. I design the perfect pizza, and click order, and WAM. The too-cool technology of IP address geo-location kicks in and bites my butt.
It seems that in an effort to better serve their customers, Papa Johns looked at the physical location of my IP address and.determined the city from which I was accessing the web page Problem is that my ISP is out of Hurricane, about twenty minutes away from here on the Interstate, and that is where Papa Johns thought I was located.
They HAD my address on file. THEY KNEW WHAT STORE I ALWAYS ORDER FROM. But they were" helpful" and placed the order with the store a half-an-hour away, instead the store which is located less than two minutes from my house.
I had to call the distant store and cancel the order. While the pizzas where in the oven, The manager was very nice, the order was canceled and everyone is happy.
These stories illiterate a design principle that programmers should consider. Sometimes, you don't know what you think you know. Automated data capture/data entry can save time but there are gotcha's you have to keep in mind. Just remember, just because it's possible to automate something it doesn't mean that it is a wise idea to do so.
Sometimes in our rush to make software easier to use, we actually make it less useful by making the user have to fight our programs.
I ordered a pizza from Papa Johns online. Being the geek I am, I have an established account in which I have specified my address, phone number, and which store is my local store. I design the perfect pizza, and click order, and WAM. The too-cool technology of IP address geo-location kicks in and bites my butt.
It seems that in an effort to better serve their customers, Papa Johns looked at the physical location of my IP address and.determined the city from which I was accessing the web page Problem is that my ISP is out of Hurricane, about twenty minutes away from here on the Interstate, and that is where Papa Johns thought I was located.
They HAD my address on file. THEY KNEW WHAT STORE I ALWAYS ORDER FROM. But they were" helpful" and placed the order with the store a half-an-hour away, instead the store which is located less than two minutes from my house.
I had to call the distant store and cancel the order. While the pizzas where in the oven, The manager was very nice, the order was canceled and everyone is happy.
I'll give you another example. I automated order entry for certain preprinted applications which print with the birth certificate. The application has an ID number which links it to our master birth file.
The automation saves staff time and makes us more efficient. My probelm was that the address mom gave on the birth certificate may or may not be the one included on the application. She may have moved since the birth occurred and our staff wasn't double checking the address. A significant number of orders were returned to us as undelivered. This was bad customer service and consumed additional staff time to corret the mistakes.
One last example. On my phone, I have a feature that auto-corrects words that are misspelled when typing a text message with the on-screen keyboard. More than one of my Facebook updates didn't make much sense because the software 'helped' me when it didn't need to.
Microsoft is bad for this type of problem. Every try to put a asterisk in a Microsoft Word document? Auto-changes it to a bullet.
These stories illiterate a design principle that programmers should consider. Sometimes, you don't know what you think you know. Automated data capture/data entry can save time but there are gotcha's you have to keep in mind. Just remember, just because it's possible to automate something it doesn't mean that it is a wise idea to do so.
- The data you think you know, you may not know. It may be stale, or just wrong.
- .The data may be correct, but you're measuring the wrong thing. The location of my IP was correct, but the location was the location of my ISP, not my home.
- The time you save by automation may be consumed quickly by the mistakes such automation breeds.
Sometimes in our rush to make software easier to use, we actually make it less useful by making the user have to fight our programs.
Saturday, June 18, 2011
Windows Event Log by Visual Basic 2008
We've been experiencing Delayed Write Errors, which result in a loss of data. In an effort to provide enough data points for our IT section to determine the problem, I needed to extract from the Window's Event Log all logged events.
For those who may not know, the Event Log is a system managed place in which the system logs certain events that users may use to diagnose problems. It only took a few minutes on Google to pick up enough pieces to do what I needed.
Everything we need is found in the System.Diagnostics namespace.
Imports System.Diagnostics
Module Module1
Sub Main()
'Here we create an EventLog object
Dim a As New EventLog
Dim z As Long
'This creates a streamwriter through which we will
'write the log data.
Dim myOut As New System.IO.StreamWriter("delayed.txt")
'This is which of the EventLogs we are accessing
a.Log = "System"
'We have to specify the machine name
a.MachineName = My.Computer.Name
'----------------------------------------
' the good stuff
' We iterate through each event log entry,
' looking for the word "delayed". If we
' find it, we write out the entry.
'------------------------------------------
For Each entry As EventLogEntry In a.Entries
z += 1
If entry.Message.ToLower.Contains("delayed") Then
myOut.WriteLine(entry.TimeGenerated & "," & entry.Message & "," & entry.MachineName)
Console.WriteLine(entry.Message)
Else
If z Mod 100 = 0 Then
Console.Write(".")
End If
End If
Next
myOut.Close()
End Sub
End Module
For those who may not know, the Event Log is a system managed place in which the system logs certain events that users may use to diagnose problems. It only took a few minutes on Google to pick up enough pieces to do what I needed.
Everything we need is found in the System.Diagnostics namespace.
Imports System.Diagnostics
Module Module1
Sub Main()
'Here we create an EventLog object
Dim a As New EventLog
Dim z As Long
'This creates a streamwriter through which we will
'write the log data.
Dim myOut As New System.IO.StreamWriter("delayed.txt")
'This is which of the EventLogs we are accessing
a.Log = "System"
'We have to specify the machine name
a.MachineName = My.Computer.Name
'----------------------------------------
' the good stuff
' We iterate through each event log entry,
' looking for the word "delayed". If we
' find it, we write out the entry.
'------------------------------------------
For Each entry As EventLogEntry In a.Entries
z += 1
If entry.Message.ToLower.Contains("delayed") Then
myOut.WriteLine(entry.TimeGenerated & "," & entry.Message & "," & entry.MachineName)
Console.WriteLine(entry.Message)
Else
If z Mod 100 = 0 Then
Console.Write(".")
End If
End If
Next
myOut.Close()
End Sub
End Module
Friday, June 17, 2011
more RegEx
The more I use Regular Expressions, the more I rely upon the ease of use they provide in pattern matching in real, everyday work.
Want to match a date at the start of a line? try
The \d matches all numbers
The [A|P] matches to either "A" or "P" as in AM/PM.
The rest are just string literals.
I was needing to clean a log file I extracted from the Windows Event log to report a problem to our IT support staff.
I had several hundred line s like
I used this as my search query.
* says "repeat the last search term 0 or more times.
Want to match a date at the start of a line? try
^\d*/\d*/\d* \d*:\d*:\d* [A|P]MThe ^ means the start of a line.
The \d matches all numbers
The [A|P] matches to either "A" or "P" as in AM/PM.
The rest are just string literals.
I was needing to clean a log file I extracted from the Windows Event log to report a problem to our IT support staff.
I had several hundred line s like
The description for Event ID '1073741850' in Source 'Application Popup' cannot be found. The local computer may not have the necessary registry information or message DLL files to display the message, or you may not have permission to access them.Where each ID was different. Solution? RegEx and Repetition!
I used this as my search query.
The description for Event ID '\d*' in Source 'Application Popup' cannot be found. The local computer may not have the necessary registry information or message DLL files to display the message, or you may not have permission to access them. The following information is part of the event:The \d is, of course, the shorthand meaning "numeric information." this is the same as the expression [0-9$.,]
* says "repeat the last search term 0 or more times.
Subscribe to:
Posts (Atom)