# Thursday, June 28, 2007

Learning through Anti-Patterns

I was gaining much (renewed) amusement through anti-patterns the other day when I took a look at Scott's blog on 'real world' development approaches, and subsequently dug a bit further on management and development anti-patterns on Wikipedia.

You can also find a bit more info here.

It then struck me that although these are absolute classics that we've all seen (management ones 'all the time'), I probably don't know any developer (including myself) that could truly say they've never been guilty of at least one of these.  I'd go further and say that some of these anti-patterns can form an effective apprenticeship for software development, as you really need to know what not to do as much as what to do in regards to design and coding approaches.

  • Who hasn't hard-coded?
  • Who hasn't read an article on some cool way of doing things, then taken it all out of context and ended up doing something like error hiding, or mistaken delegation for poltergeists?
  • Who hasn't thought (eugh - a world of pain will ensue if I try and get rid of this code) - the lava flow.

I could go on all day here as 'so many' of the Wikipedia anti-patterns ring true as something I've encountered (and still encounter) along the way.

Ultimately none have killed me so I guess therefore have made me stronger and hopefully a little wiser on what not to do.

posted on Thursday, June 28, 2007 12:03:16 PM (AUS Eastern Standard Time, UTC+10:00)  #    Comments [0]
# Tuesday, June 26, 2007

SQL Server - Kill all users script

Found this the other day - for when you're restoring SQL databases.  You need to kick out all current users right?

Run this little fella into your master database and away you go - just run this step before your restore.

CREATE PROCEDURE usp_KillUsers @dbname varchar(50as
SET NOCOUNT ON

DECLARE 
@strSQL varchar(255)
PRINT 'Killing Users'
PRINT '-----------------'

CREATE table #tmpUsers(
spid 
int,
dbname 
varchar(50))

INSERT INTO #tmpUsers
SELECT 
[Process ID]    l.req_spid, db_name(l.rsc_dbid)
from master.dbo.syslockinfo l with (NOLOCK
where db_name(l.rsc_dbid) @dbname
group by l.req_spid, db_name(l.rsc_dbid)


DECLARE LoginCursor CURSOR
READ_ONLY
FOR SELECT spid, dbname FROM #tmpUsers WHERE dbname @dbname

DECLARE @spid varchar(10)
DECLARE @dbname2 varchar(40)
OPEN LoginCursor

FETCH NEXT FROM LoginCursor INTO @spid, @dbname2
WHILE (@@fetch_status <> -1)
BEGIN
    IF 
(@@fetch_status <> -2)
    
BEGIN
    PRINT 
'Killing ' + @spid
    
SET @strSQL 'KILL ' + @spid
    
EXEC (@strSQL)
    
END
    FETCH 
NEXT FROM LoginCursor INTO  @spid, @dbname2
END

CLOSE 
LoginCursor
DEALLOCATE LoginCursor

DROP table #tmpUsers

Colorized by: CarlosAg.CodeColorizer
posted on Tuesday, June 26, 2007 8:15:39 AM (AUS Eastern Standard Time, UTC+10:00)  #    Comments [0]
# Wednesday, June 13, 2007

Signs of Discontent? - Increased Food and Coffee

I like observing human behaviour at work and I've noticed recently that the amount of 'junk' food appearing in the dev pod has increased quite a bit.  People are also going for more coffee breaks (as far as I can see).  I may be imagining this, but I think it's probably a good indicator of any or all of the following:

  • Boredom
  • Lack of enthusiasm for the current work
  • Need for stress relief (mucho long hours)

I'd have to admit the current project has its frustrations (integration work with a 'less than extendable' 3rd party product) and I'd probably rather be doing something else - so I'll keep my eye on this and see what happens when the supplies run out!

I think there's a bit of synergy here with the triangle of happiness.  My own experience is if you're happy and engaged in what you're doing then you often don't even find the time to eat..

posted on Wednesday, June 13, 2007 8:22:56 AM (AUS Eastern Standard Time, UTC+10:00)  #    Comments [0]
# Monday, April 23, 2007

Visual Studio 2005 - Source Control Warnings (or lack thereof)

I've just had to apologise to my peers for breaking the build (thankfully not something that happens often).  I encountered an interesting situation where writeable files don't show as such (a build script had 'got latest' but left files writeable).  I then made some changes and performed an incomplete checkin as half of the changed items weren't checked out.  Visual Studio interestingly showed all of the files as 'locked' even though they were writeable.  VS2003 used to detect that and give you a different type of 'tick' to show the file was writeable but not checked out (I think :-) ).

'Silly boy' - I hear you cry - yes I should have done a get latest before checking in (but didn't - my bad).  This does highlight however the Source Control settings available in the Tools-->Options dialog.  We enforce Checkin comments (through a VSS Addin) and so for safety (knowing what VS2005 is doing with VSS) it's always worth ensuring the following are enforced:

  • Prompt before checkout
  • Prompt before checkin (to allow comments)
  • Don't allow editing of checked-in items
  • Checked-in item behaviour
    • On Save - prompt for checkout
    • On Edit  - prompt for checkout

I'd changed some of these items in the past week but some had reverted to previous settings (a little concerning!!).

Anyway - it's all good - the build passed and I'm a little wiser about what options to tick in future.

posted on Monday, April 23, 2007 9:50:13 AM (AUS Eastern Standard Time, UTC+10:00)  #    Comments [0]
# Tuesday, March 20, 2007

PrevX - DeleteOld (eh?)

I just found that the top entry in google for 'codebureau' is actually some listing on prevx.com (which I'd never heard of) that's seeming to suggest that DeleteOld (a console app I posted on CodeProject some time ago) is possibly spyware/malware - bloody cheek!  I'd be interested to know how this pops up on that tool, and also whether the .NET code has some flaws that means it can be used in a malicious way.  At least then I could defend myself.

posted on Tuesday, March 20, 2007 1:02:11 PM (AUS Eastern Daylight Time, UTC+11:00)  #    Comments [0]

Visual Studio 2003 Colours - Registry Entries

Visual Studio 2003 doesn't give you any way of exporting your customised colours (I've gone for a 'black' theme) - well, black is the new black you know!

The theme's shown below (not that it's that great - but illustrates the effect the registry entries (further below) have...  In Visual Studio 2005 of course you can simply export your entire settings.  Oh yeah - also ignore the code as that's simply a work in progress for something I'm going to post on CodeProject in the next couple of months.

To create this look - simply copy the text below and save in a .reg file.  Take a backup of your current colours first of course by exporting the key: [HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\7.1\FontAndColors] to a file.  I've got some ReSharper v2 settings in there too so you can remove those if you don't use ReSharper (shame on you!)

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\7.1\FontAndColors]
"Color Palette"=hex:ff,ff,ff,00,ff,ff,ff,00,ff,ff,ff,00,ff,ff,ff,00,ff,ff,ff,\
  00,ff,ff,ff,00,ff,ff,ff,00,ff,ff,ff,00,ff,ff,ff,00,ff,ff,ff,00,ff,ff,ff,00,\
  ff,ff,ff,00,ff,ff,ff,00,ff,ff,ff,00,ff,ff,ff,00,ff,ff,ff,00

[HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\7.1\FontAndColors\{A27B4E24-A735-4D1D-B8E7-9716E1E3D8E0}]
"Colorable item format version"=dword:00000008
"FontName"="Monaco"
"FontPointSize"=dword:00000008
"FontCharSet"=dword:00000000
"Plain Text Foreground"=dword:00ffffff
"Plain Text Background"=dword:00000000
"Plain Text FontFlags"=dword:00000000
"Line Numbers Foreground"=dword:00c0c0c0
"Line Numbers Background"=dword:00000000
"Line Numbers FontFlags"=dword:80000000
"Collapsible Text Foreground"=dword:0000aaaa
"Collapsible Text Background"=dword:00000000
"Collapsible Text FontFlags"=dword:00000000
"Comment Foreground"=dword:002cef10
"Comment Background"=dword:02000000
"Comment FontFlags"=dword:00000000
"Current Statement Foreground"=dword:00000000
"Current Statement Background"=dword:0000ffff
"Current Statement FontFlags"=dword:00000000
"HTML Element Name Foreground"=dword:008080ff
"HTML Element Name Background"=dword:02000000
"HTML Element Name FontFlags"=dword:00000000
"HTML Operator Foreground"=dword:004080ff
"HTML Operator Background"=dword:02000000
"HTML Operator FontFlags"=dword:00000000
"HTML String Foreground"=dword:0000ff00
"HTML String Background"=dword:02000000
"HTML String FontFlags"=dword:00000000
"HTML Tag Delimiter Foreground"=dword:0000ffff
"HTML Tag Delimiter Background"=dword:02000000
"HTML Tag Delimiter FontFlags"=dword:00000000
"Identifier Foreground"=dword:00dfdfdf
"Identifier Background"=dword:02000000
"Identifier FontFlags"=dword:00000000
"Keyword Foreground"=dword:00538bff
"Keyword Background"=dword:02000000
"Keyword FontFlags"=dword:00000000
"Other Error Foreground"=dword:0000ff00
"Other Error Background"=dword:02000000
"Other Error FontFlags"=dword:00000000
"Preprocessor Keyword Foreground"=dword:00c0b4f3
"Preprocessor Keyword Background"=dword:02000000
"Preprocessor Keyword FontFlags"=dword:00000000
"ReSharper Completion Replacement Range Foreground"=dword:00e1e4ff
"ReSharper Completion Replacement Range Background"=dword:00000000
"ReSharper Completion Replacement Range FontFlags"=dword:00000000
"ReSharper Current Line Foreground"=dword:00ffffff
"ReSharper Current Line Background"=dword:00313131
"ReSharper Current Line FontFlags"=dword:00000000
"ReSharper Matched Brace Foreground"=dword:01000000
"ReSharper Matched Brace Background"=dword:00ffff00
"ReSharper Matched Brace FontFlags"=dword:00000000
"ReSharper Method Identifier Foreground"=dword:008b8b00
"ReSharper Method Identifier Background"=dword:01000001
"ReSharper Method Identifier FontFlags"=dword:00000000
"ReSharper Operator Identifier Foreground"=dword:008b8b00
"ReSharper Operator Identifier Background"=dword:01000001
"ReSharper Operator Identifier FontFlags"=dword:00000000
"ReSharper Read Usage Foreground"=dword:01000000
"ReSharper Read Usage Background"=dword:00face87
"ReSharper Read Usage FontFlags"=dword:00000000
"ReSharper Usage Foreground"=dword:01000000
"ReSharper Usage Background"=dword:00face87
"ReSharper Usage FontFlags"=dword:00000000
"ReSharper Write Usage Foreground"=dword:01000000
"ReSharper Write Usage Background"=dword:00c1b6ff
"ReSharper Write Usage FontFlags"=dword:00000000
"String Foreground"=dword:0034cb65
"String Background"=dword:02000000
"String FontFlags"=dword:00000000
"XML Doc Comment Foreground"=dword:002cef10
"XML Doc Comment Background"=dword:02000000
"XML Doc Comment FontFlags"=dword:00000000

 

posted on Tuesday, March 20, 2007 12:39:43 PM (AUS Eastern Daylight Time, UTC+11:00)  #    Comments [0]
# Tuesday, February 20, 2007

Unit Tests - They've got to be worth it

This is a re-hash of a post I wrote and 'lost' a while ago after I was reading Charlie Poole's first blog entry (from September 05) 'What's a test worth?', and found a hard-copy this morning.

It occurred to me (originally) that we tend to never remove unit tests as we have some strange and irrational fear that we should only ever move forwards with tests and the 'rainy day' tests should be retained as a 'just in case' safety net.  All this does of course is water down your test library for a number of reasons:

  1. The test library takes longer than is desired AND required to run
  2. Tests exist with a purpose that no-one's quite sure about and thus are more difficult to maintain and fix when something causes them to fail
  3. The test library cannot possibly be well defined and categorised due to point 2, leading to more developer and tester confusion

I therefore tried to give myself a small number of practical rules to follow when adding or maintaining unit tests.  Refactoring is something that applies equally to unit tests (and I don't just mean changes that stop your build from breaking when you change your functionality).

The question is 'What characteristics should a test display in order to avoid being deleted'

  1. If the test covers unique specific functionality (not covered in any other test) in a contained and specific way, sets up its own data and tears it down whilst making a number of useful assertions, and tests logic 'not' data - it should stay
  2. If the test duplicates other coverage, but also covers something else at a higher level - i.e. more of a system test - it may also still be of some use.  If the new functionality is at the same logical level as that already covered, then it's probably an indicator that some refactoring should be undertaken to allow that to be specifically unit-tested (that's not very clear but hopefully you get what I mean)
  3. We're clutching at straws now, but if the test does 'anything' useful at all (that's not been done in another test), then it may still be a good 'catcher' for some other high-level scenarios - you'd probably want to re-categorise the test at least in this case.

If you can't place the test in any of the 3 above then you need to do one or more of the following

    1. Remove the test
    2. Refactor the functionality you're testing
    3. Improve the test so that there is a specific and unique purpose

I'll try and add to and refine this over time, but for now there's my starting point.

posted on Tuesday, February 20, 2007 9:26:39 AM (AUS Eastern Daylight Time, UTC+11:00)  #    Comments [0]
# Sunday, February 18, 2007

Ant Problems (Nothing to do with builds)

I've got ant problems - lots of 'em - coming from every orifice (in my house).  Googling for some 'intelligence' on how the little blighters' minds work so I might better exterminate them I stopped for a moment when I read this heartening tale about the guts and determination of the average ant...

http://www.adventurejournalist.com/notebook/archives/001005.html

I then promptly moved on and started looking for more and ingenious ways to get rid of them for good so I wouldn't have to continually feel (slight) guilt whenever I squash one.

posted on Sunday, February 18, 2007 7:59:26 PM (AUS Eastern Daylight Time, UTC+11:00)  #    Comments [0]
# Wednesday, January 31, 2007

Dynamic FTP Scripts

I seem to be getting back to basics at the moment with some of the things I'm doing - and didn't imagine myself having to get an automated FTP update working this week...

My objective was to 'get' files from a remote machine using a folder pattern consisting of the date in an 'yymmdd' format.  I'd forgotten that script files used with ftp (ftp -s:myscript.txt) are dumb text files, and if you want to 'get' from a dynamic location - or dynamic filenames you need to magic something up.

My interest was sparked here, and although I found a C# FTP library on CodeProject that would clearly do the job, and would be cool to use in itself, I was more interested in using 'old skool' lo-tech methods to solve the problem.

I read one article that suggested using batch files to spit out the ftp script.  Excellent idea I thought - so this is what I ended up with.... (I've changed a few details to protect the innocent so if it doesn't quite work it's only due to my own typo :-) )

I won't explain each bit as that would spoil the fun - but the general gist is that FTPReportsForDate is normally run without parameters and it finds files in a specific folder and renames them on the local host.  The process also does other stuff I didn't have time to go into....

FTPReportsForDate.cmd (which accepts a parameter or gets current date if not supplied)

@echo off

echo Creating Log Folder
IF NOT EXIST C:\logs\FTP\ md c:\logs\FTP

echo Removing previous processing date
IF EXIST processingdate.txt del processingdate.txt /F

IF "%1" == "" (
 echo Getting current processing date
 cscript //NoLogo GetCurrentDate.vbs >> processingdate.txt
 echo Transferring File
 FOR /F %%f in (processingdate.txt) do CALL FTPCommand.cmd %%f
)

IF "%1" NEQ == "" (
 echo Transferring File
 CALL FTPCommand.cmd %1
)

FTPCommand.cmd  This constructs the FTP script file and does the FTP itself...

IF EXIST FTPLatestFile.txt del FTPLatestFile.txt /F

Type FTPHeader.txt >> FTPLatestFile.txt
echo cd RP%1.IN >> FTPLatestFile.txt
echo get staticfilename.fil dyn%1.fil >> FTPLatestFile.txt
echo close >> FTPLatestFile.txt
echo bye >> FTPLatestFile.txt

ftp -s:FTPLatestFile.txt >> c:\logs\ftp\transfer_%1.log

FTPHeader.txt This contains the static information used in the FTP script

open 192.168.0.1
myftpuser
myftppwd
prompt
lcd c:\incoming


GetCurrentDate.vbs
gets current date in a yymmdd format in the event we don't pass in a date to FTPReportsForDate.cmd

'Simple script to output todays date in yymmdd format for FTP processing

Function pd(n, totalDigits)
 if totalDigits > len(n) then
  pd = String(totalDigits-len(n),"0") & n
 else
  pd = n
 end if
End Function

Wscript.echo pd(RIGHT(YEAR(date()),2),2) & pd(MONTH(date()),2) & pd(DAY(date()),2)
Wscript.echo
        

posted on Wednesday, January 31, 2007 4:51:13 PM (AUS Eastern Daylight Time, UTC+11:00)  #    Comments [0]