Today, Mark and I announced the winner of the 3rd Madgex Coding Challenge. This coding challenge was announced on the 3rd June and entries needed to be in on the 30th June. The email announcement said:
We had 4 solutions submitted, and they were all of a really high standard. I tested them with 6 different input scenarios:
- The original provided sample - the text for "Mary had a little lamb"
- An empty string - which caused a few exceptions to be raised
- A single space
- A string of numbers
- The contents of war and peace
- The contents of the 3 musketeers in French
Each sample was run through each person's solution, and the most compressed result won that round. In the end, one person won 2 rounds (having implemented their own algorithm) and one won 4 rounds (having implemented 3 different methods and selected the one with the highest compression).
This was based around Puzzle 16: Zip me up, Buttercup from the great resource Collection Of Puzzles For Programmers
Previous coding challenges have been based loosely on LTD Puzzle 4: Finding Prime Numbers (which was Madgex coding challenge 1) and LTD Puzzle 3: ASCII Art Shapes (Madgex coding challenge 2).
I'm delighted with how these are going, and the interest and general communication that they generate - lots of discussion, hints of secrecy, and comparisons between each other - and then lots of discussion once the results have been announced, and the code is available for scrutiny. So, I'm now busy thinking up ideas for Madgex Coding Challenge 4 - if anyone has any suggestions or resources for me to use, please pop them in the comments
So, the challenge this time is all around compression.
Take a string, compress it into a byte[], record the size, decompress it.
You can use any algorithm you chose, but it must be coded by you and not included from an external library
I have defined an Interface ICompress as follows:
public interface ICompress
{
/// <summary>
/// Take a string and convert it into a byte[]
/// </summary>
/// <param name="source">The string to be converted</param>
/// <returns>The converted byte[]</returns>
byte[] Compress(string source);
/// <summary>
/// Take the bytearray produced by the call to Compress, and decompress it
/// </summary>
/// <param name="compressedData">The data to be decompressed</param>
/// <returns>The string</returns>
string DeCompress(byte[] compressedData);
}
I have provided a solution with the interface (Interface), a console app (CodingChallenge3) and an implementation of the interface (Compressor) (which just converts from string to byte[] and back again, no compression) on the development file share.
The source string is provided through the app.config file of the CodingChallenge3 project (the console app).
What do you need to submit?
- A Compressor project that I can plug in to the provided solution
- A couple of paragraphs explaining how your algorithm works
We had 4 solutions submitted, and they were all of a really high standard. I tested them with 6 different input scenarios:
- The original provided sample - the text for "Mary had a little lamb"
- An empty string - which caused a few exceptions to be raised
- A single space
- A string of numbers
- The contents of war and peace
- The contents of the 3 musketeers in French
Each sample was run through each person's solution, and the most compressed result won that round. In the end, one person won 2 rounds (having implemented their own algorithm) and one won 4 rounds (having implemented 3 different methods and selected the one with the highest compression).
This was based around Puzzle 16: Zip me up, Buttercup from the great resource Collection Of Puzzles For Programmers
Previous coding challenges have been based loosely on LTD Puzzle 4: Finding Prime Numbers (which was Madgex coding challenge 1) and LTD Puzzle 3: ASCII Art Shapes (Madgex coding challenge 2).
I'm delighted with how these are going, and the interest and general communication that they generate - lots of discussion, hints of secrecy, and comparisons between each other - and then lots of discussion once the results have been announced, and the code is available for scrutiny. So, I'm now busy thinking up ideas for Madgex Coding Challenge 4 - if anyone has any suggestions or resources for me to use, please pop them in the comments
A colleague asked me today about generating a comma separated list of values based on the results of a SELECT statement. A quick google later and I found Using COALESCE to Build Comma-Delimited String
So, for my table Continent, and my usual SELECT of
SELECT [Name]
FROM Continent
with just a variable declaration and a use of COALESCE and hey presto, we get our required result of Africa, Antarctica, Asia, Australia and Oceania, Europe, North America, South America
The code is now:
DECLARE @List VARCHAR(1000)
SELECT @List = COALESCE(@List + ', ', '') + Name
FROM Continent
SELECT @List
Nice and simple. I like!
So, for my table Continent, and my usual SELECT of
SELECT [Name]
FROM Continent
with just a variable declaration and a use of COALESCE and hey presto, we get our required result of Africa, Antarctica, Asia, Australia and Oceania, Europe, North America, South America
The code is now:
DECLARE @List VARCHAR(1000)
SELECT @List = COALESCE(@List + ', ', '') + Name
FROM Continent
SELECT @List
Nice and simple. I like!
Jo Wadsworth, the Web Editor for The Argus has been in touch about getting publicity for Brighton Blogs via The Argus. She says
So, get in touch with Jo if you want to contribute
Update - 18 June 2009
Having checked with Jo, the best ways to contact are her:
Email: jo.wadsworth@theargus.co.uk
Telephone: 01273 544 775
Twitter: brightonargusjo
Facebook: brightonargusjo
I'm going to write my own weekly blog highlighting some of my favourite posts from the last week, as an accessible way of dipping a toe into the Brighton blogosphere. If you could let people know I'm going to be doing this, that would be great. I'm going to take the position that if someone's put details of their blog on Brighton Bloggers, then it's okay to talk about them in this blog, especially as I will be careful not to select anything which is clearly personal without checking first. However, in terms of feeds onto our site, I would like people to give me the nod it's okay to do this before I start. I think I'm going to divide them loosely into business blogs, personal blogs and political blogs, although I may have to revise this . . ..
Some blogs, sadly, won't ever be suitable to be linked to from The Argus, as we are a family newspaper (anything with graphic sexual content, for instance).
Many thanks!
Jo Wadsworth
Web Editor
The Argus
So, get in touch with Jo if you want to contribute
Update - 18 June 2009
Having checked with Jo, the best ways to contact are her:
Email: jo.wadsworth@theargus.co.uk
Telephone: 01273 544 775
Twitter: brightonargusjo
Facebook: brightonargusjo
I use toodledo to manage my todo list, and this works fine, except that it means I have my browser open all the time and don't really plan my days too well being a bit more reactive than proactive. A few weeks ago I stumbled across a tweet from Craig Murphy linking to the ebook version of a (very well written) Pomodoro manual (Pomodoro being a time mangement system). I've been using the Do It Tomorrow technique with toodledo, but haven't really embraced the daily system. Combining the two looks like it'll work well for me, allowing me to focus on what I need to do each day, whilst still recording other items (tomorrow and beyond) in toodledo.
I also recently stumbled across the PocketMod books from paper concept, and have been using a simple one as my work week planner for the last couple of weeks. Today I went one stage further and used Natalie's Pocket Project html/css work to create a Pocket Pomodoro template for myself to use.
It has a week view on the front page - so I can put known appointments in there, allowing me to carry my calendar around the office with me. And then 5 pages of todos, one per week day with an Unplanned and Urgent section to note down extra items. I haven't put any checkboxes in as the number of pomodoros taken to fulfill a task will dictate this. There is an Activity Inventory page, to put any of the items that appear that are not do it today urgent - these will be put into toodledo at an opportune moment. Finally there is a notes page, to jot down anything that comes up during my week. Over time, as I use this more, this may become a second Activity Inventory page, so watch this space.
As with Natalie's example, it only works on Webkit based browsers so I've also created it as a PDF for anyone who is interested in using this but isn't using a webkit based browser.
And of course, once you've got your PocketMod printed, you'll need to fold it, and this YouTube video does a great job of explaining how to do that
The links again: Pocket Pomodoro as HTML, Pocket Pomodoro as PDF
As with the other tools, utilities etc I've made available, leave me feedback either via comments, or via the contact form.
I also recently stumbled across the PocketMod books from paper concept, and have been using a simple one as my work week planner for the last couple of weeks. Today I went one stage further and used Natalie's Pocket Project html/css work to create a Pocket Pomodoro template for myself to use.
It has a week view on the front page - so I can put known appointments in there, allowing me to carry my calendar around the office with me. And then 5 pages of todos, one per week day with an Unplanned and Urgent section to note down extra items. I haven't put any checkboxes in as the number of pomodoros taken to fulfill a task will dictate this. There is an Activity Inventory page, to put any of the items that appear that are not do it today urgent - these will be put into toodledo at an opportune moment. Finally there is a notes page, to jot down anything that comes up during my week. Over time, as I use this more, this may become a second Activity Inventory page, so watch this space.
As with Natalie's example, it only works on Webkit based browsers so I've also created it as a PDF for anyone who is interested in using this but isn't using a webkit based browser.
And of course, once you've got your PocketMod printed, you'll need to fold it, and this YouTube video does a great job of explaining how to do that
The links again: Pocket Pomodoro as HTML, Pocket Pomodoro as PDF
As with the other tools, utilities etc I've made available, leave me feedback either via comments, or via the contact form.
I updated spu_generateinsert again today when one of my colleagues reminded me that I needed to prefix my strings with a capital N to ensure that any unicode values go into the database correctly.
So now instead of the call spu_generateinsert @table = 'LanguageData' producing
INSERT INTO [LanguageData] ([liID], [Value])VALUES (7,'D''Artagnan raconte qu''à sa première visite à')
it produces
INSERT INTO [LanguageData] ([liID], [Value])VALUES (7,N'D''Artagnan raconte qu''à sa première visite à')
As usual, the script is available here
And again as usual, leave me a comment if you think of some new functionality I should include, or any issues you come across.
So now instead of the call spu_generateinsert @table = 'LanguageData' producing
INSERT INTO [LanguageData] ([liID], [Value])VALUES (7,'D''Artagnan raconte qu''à sa première visite à')
it produces
INSERT INTO [LanguageData] ([liID], [Value])VALUES (7,N'D''Artagnan raconte qu''à sa première visite à')
As usual, the script is available here
And again as usual, leave me a comment if you think of some new functionality I should include, or any issues you come across.
I managed not to do an update for May, so here is a bumper crop
- Dom Pates: Collected Writings
- Joe Blogs
- A Brighton Boy Blogs
- Jon Silver Photography - wedding, portrait and portfolio photographer, Brighton, Sussex, UK
- A Sussex Wedding Photographer's Blog
- Sussex wedding photographer's blog
- Tales from my handbag
- Sour Mango Powder
- They paved paradise, put up a parking lot
- The people versus stand-up comedy
Yet another in the note to self category.
When using App_offline.htm files to take down a site in IIS, if the file size isn't 512 bytes of content or greater then IE may choose to default to the "Show Friendly Http Errors". Comments count towards the byte size so client side comments will work too.
There is more about this at ScottGu's blog
When using App_offline.htm files to take down a site in IIS, if the file size isn't 512 bytes of content or greater then IE may choose to default to the "Show Friendly Http Errors". Comments count towards the byte size so client side comments will work too.
There is more about this at ScottGu's blog
Another for the Note To Self list
A lot of our sites use a url mapper, so when setting up the sites within IIS we map extension .* to the appropriate aspnet_isapi.dll.
I'd got carried away when setting up the webservice and did the same thing, resulting in a The HTTP verb POST used to access path '/WebService/WebService.asmx/DoSomething' is not allowed. error. Removing the .* mapping fixes this.
A lot of our sites use a url mapper, so when setting up the sites within IIS we map extension .* to the appropriate aspnet_isapi.dll.
I'd got carried away when setting up the webservice and did the same thing, resulting in a The HTTP verb POST used to access path '/WebService/WebService.asmx/DoSomething' is not allowed. error. Removing the .* mapping fixes this.
Definitely under the note to self category this one...
I've been working with installing a service and took the base code from our platform. Part of the command line specifies a parameter to be used within the installer, but no matter what I did I could not get the parameter to be picked up.
An example of the installation command line is
"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\installUtil.exe" "C:\Services\MyService.exe" /SERVICENAME="My Special Service"
which, at least in theory, allows the service to be created so that in the Services dialog it is listed under the name "My Special Service"
A quick google with the right keywords and I stumbled across The curious case of InstallUtil and service parameters which both explains the situation and provides a lovely working solution.
In my case, the code was even simpler than the example as I was specifically looking for only one parameter, the service name, and so my OnBeforeInstall and OnBeforeUninstall become
protected override void OnBeforeInstall(System.Collections.IDictionary savedState)
{
base.OnBeforeInstall(savedState);
SetServiceNameFromCommandLineParameter();
}
protected override void OnBeforeUninstall(System.Collections.IDictionary savedState)
{
base.OnBeforeUninstall(savedState);
SetServiceNameFromCommandLineParameter();
}
where SetServiceNameFromCommandLineParameter is :
void SetServiceNameFromCommandLineParameter()
{
const string SERVICE_NAME = "SERVICENAME";
String[] args = System.Environment.GetCommandLineArgs();
String no_log_file = null;
InstallContext tmp_ctx = new InstallContext(no_log_file, args);
string serviceName = tmp_ctx.Parameters[SERVICE_NAME];
if (serviceName == null)
{
throw new ApplicationException(string.Format("{0} undefined", SERVICE_NAME));
}
//Set service name
this.serviceInstaller1.DisplayName = serviceName ;
this.serviceInstaller1.ServiceName = serviceName;
}
where serviceInstaller1 is defined as private ServiceInstaller serviceInstaller1;
As to why this works in the base code, but doesn't for mine I have no idea, but I have at least got it working now
I've been working with installing a service and took the base code from our platform. Part of the command line specifies a parameter to be used within the installer, but no matter what I did I could not get the parameter to be picked up.
An example of the installation command line is
"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\installUtil.exe" "C:\Services\MyService.exe" /SERVICENAME="My Special Service"
which, at least in theory, allows the service to be created so that in the Services dialog it is listed under the name "My Special Service"
A quick google with the right keywords and I stumbled across The curious case of InstallUtil and service parameters which both explains the situation and provides a lovely working solution.
In my case, the code was even simpler than the example as I was specifically looking for only one parameter, the service name, and so my OnBeforeInstall and OnBeforeUninstall become
protected override void OnBeforeInstall(System.Collections.IDictionary savedState)
{
base.OnBeforeInstall(savedState);
SetServiceNameFromCommandLineParameter();
}
protected override void OnBeforeUninstall(System.Collections.IDictionary savedState)
{
base.OnBeforeUninstall(savedState);
SetServiceNameFromCommandLineParameter();
}
where SetServiceNameFromCommandLineParameter is :
void SetServiceNameFromCommandLineParameter()
{
const string SERVICE_NAME = "SERVICENAME";
String[] args = System.Environment.GetCommandLineArgs();
String no_log_file = null;
InstallContext tmp_ctx = new InstallContext(no_log_file, args);
string serviceName = tmp_ctx.Parameters[SERVICE_NAME];
if (serviceName == null)
{
throw new ApplicationException(string.Format("{0} undefined", SERVICE_NAME));
}
//Set service name
this.serviceInstaller1.DisplayName = serviceName ;
this.serviceInstaller1.ServiceName = serviceName;
}
where serviceInstaller1 is defined as private ServiceInstaller serviceInstaller1;
As to why this works in the base code, but doesn't for mine I have no idea, but I have at least got it working now
The final helper procedure I wrote as part of my recent integration exercise was spu_scriptprocedures. It is a simple stored procedure which builds up a defensive SQL script for one or many stored procedures.
It has 4 parameters:
Example usage:
spu_scriptprocedures @db='master', @proceduresToScriptCondition='ROUTINE_NAME = ''spu_compareprocedures'''
This has been tested on SQL Server 2005.
As with my other SQL helper procedures, please leave a comment if you have any suggestions on way to improve it, or bugs to report.
Download the script here.
It has 4 parameters:
- @db - the name of the database. Mandatory
- @rolename - the name of the role for which a grant execute statement should be prepared. Optional - no grant statement is printed if this isn't specified
- @proceduresToScriptCondition - the condition (based on the INFORMATION_SCHEMA.ROUTINES view) to use to select the procedures. Optional - if not specified all stored procedures will be scripted
- @debug - print out the SQL being generated to help debug the code. Optional - defaults to off
Example usage:
spu_scriptprocedures @db='master', @proceduresToScriptCondition='ROUTINE_NAME = ''spu_compareprocedures'''
This has been tested on SQL Server 2005.
As with my other SQL helper procedures, please leave a comment if you have any suggestions on way to improve it, or bugs to report.
Download the script here.
Today seems to have been a day of finding cool data visualisation links.
Firstly, via information aesthetics I found Christian Nold's Emotional Cartography eBook which
This is especially of interest to me as Christian was one of the speakers at last years Geekyoto, and I blogged at the time about the beautiful maps he'd produced using emotional responses to different geographic areas.
And then, via Cool Infographics a link to the online magazine Visualisation Volume 2 which explores the use of circles as visualisation tools. Finding this also resulted in me exploring Visualisation Volume 1. Both of these are good illustrations on the many ways to report data, and some of the examples used in Volume 2 can also be found in beautiful book Data Flow: Visualising information in graphic design which is sitting on my bookshelf waiting for me to read some more.
Firstly, via information aesthetics I found Christian Nold's Emotional Cartography eBook which
is a collection of essays from artists, designers, psychogeographers, cultural researchers, futurologists and neuroscientists, brought together by Christian Nold, to explore the political, social and cultural implications of visulising intimate biometric data and emotional experiences using technology.
This is especially of interest to me as Christian was one of the speakers at last years Geekyoto, and I blogged at the time about the beautiful maps he'd produced using emotional responses to different geographic areas.
And then, via Cool Infographics a link to the online magazine Visualisation Volume 2 which explores the use of circles as visualisation tools. Finding this also resulted in me exploring Visualisation Volume 1. Both of these are good illustrations on the many ways to report data, and some of the examples used in Volume 2 can also be found in beautiful book Data Flow: Visualising information in graphic design which is sitting on my bookshelf waiting for me to read some more.
I have been a long time fan of RedGate's SQL Compare tool to compare all aspects of a database. The work I'm doing at the moment needs me to integrate some new code into an existing project - some of which involves database manipulation. However, I'm only interested in a subset of stored procedures as many of them are different for valid reasons. I couldn't work out how to do this in SQL Compare so, I wrote a script to do it for me. It is called spu_CompareProcedures and I thought I'd share it in the hope that is of value to others.
There are 5 parameters available, they are:
spu_compareprocedures @db1 = 'MyMasterDatabase', @db2 = 'MyOtherDatabase', @proceduresToCompare='spu_generateinsert,spu_compareprocedures', @displayOnlyDifferent=1, @debug=0
As with spu_generateinsert, the output is displayed in the Messages window. It will report on what is being checked, any errors - i.e. procedures which exist in one database and not the other, or maybe either, and those which are different (or the same as well depending on the value of @displayOnlyDifferent). Sample output is:
******************************************************************
Comparing databases MyMasterDatabase and MyOtherDatabase
Objects:
spu_generateinsert
spu_compareprocedures
******************************************************************
*****************
** ERRORS **
*****************
spu_compareprocedures is missing for MyMasterDatabase
spu_compareprocedures is missing for MyOtherDatabase
*****************
** COMPARISONS **
*****************
No differences found
It is very simple, and just checks the contents of the stored procedure, it doesn't attempt to identify the differences. But, at least theoretically, this is enough to give a heads up as to the procedures to be concerned about.
Download the script here.
If you have suggestions, comments or bug reports, please leave me a comment and I'll do what I can to help out.
There are 5 parameters available, they are:
- db1 - the name of the 1st database to use
- db2 - the name of the 2nd database to use
- proceduresToCompare - either set to '' to compare ALL stored procedures in both databases, or set to a comma separated list to restrict what gets checked
- displayOnlyDifferent - defaults to 1, i.e. only display the stored procedures which are different. If set to 0 it'll show the ones that are the same as well, but in most cases this is just too much information
- debug - defaults to 0. Used to output the SQL being generated behind the scenes to enable debugging of this stored procedure
spu_compareprocedures @db1 = 'MyMasterDatabase', @db2 = 'MyOtherDatabase', @proceduresToCompare='spu_generateinsert,spu_compareprocedures', @displayOnlyDifferent=1, @debug=0
As with spu_generateinsert, the output is displayed in the Messages window. It will report on what is being checked, any errors - i.e. procedures which exist in one database and not the other, or maybe either, and those which are different (or the same as well depending on the value of @displayOnlyDifferent). Sample output is:
******************************************************************
Comparing databases MyMasterDatabase and MyOtherDatabase
Objects:
spu_generateinsert
spu_compareprocedures
******************************************************************
*****************
** ERRORS **
*****************
spu_compareprocedures is missing for MyMasterDatabase
spu_compareprocedures is missing for MyOtherDatabase
*****************
** COMPARISONS **
*****************
No differences found
It is very simple, and just checks the contents of the stored procedure, it doesn't attempt to identify the differences. But, at least theoretically, this is enough to give a heads up as to the procedures to be concerned about.
Download the script here.
If you have suggestions, comments or bug reports, please leave me a comment and I'll do what I can to help out.
Further to my earlier update today I've reworked the printing out of the insert statements - mainly because I need it for the work I'm doing today...
It now produces a single statement per row of data, and then checks the DATALENGTH of that statement. If it exceeds the 8000 byte limit, then it looks for CHAR(10)/CHAR(13) characters and breaks the row into chunks based on these CHAR(10)/CHAR(13) limits.
This relies on the fact that
PRINT 'Hello ' + CHAR(13) + 'World'
and
PRINT 'Hello'
PRINT 'World'
both produce the same output of
Hello
World
So, instead of PRINTing CHAR(13) we're PRINTing multiple lines.
All of which seems to work and I can finally get the
As per usual, download the spu_generateInsert script here.
It now produces a single statement per row of data, and then checks the DATALENGTH of that statement. If it exceeds the 8000 byte limit, then it looks for CHAR(10)/CHAR(13) characters and breaks the row into chunks based on these CHAR(10)/CHAR(13) limits.
This relies on the fact that
PRINT 'Hello ' + CHAR(13) + 'World'
and
PRINT 'Hello'
PRINT 'World'
both produce the same output of
Hello
World
So, instead of PRINTing CHAR(13) we're PRINTing multiple lines.
All of which seems to work and I can finally get the
As per usual, download the spu_generateInsert script here.
As mentioned in my update yesterday about spu_generateInsert there is a limitation on the TSQL PRINT function which limits the output to 8000 bytes.
I'm about to try and make the procedure work within this limitation (a table I'm trying to script exceeds this), but in the meantime I've added an additional bit of error reporting which results in the final line in the messages window being displayed as:
-- ** WARNING: The data length for at least one row exceeds 8000 bytes. The PRINT command is limited to 8000 bytes (for more information see http://msdn.microsoft.com/en-us/library/ms176047.aspx). Do not trust this data. ** --
so at least the user is informed of the issue.
Download the updated script here.
As always, comments and suggestions are welcomed.
I'm about to try and make the procedure work within this limitation (a table I'm trying to script exceeds this), but in the meantime I've added an additional bit of error reporting which results in the final line in the messages window being displayed as:
-- ** WARNING: The data length for at least one row exceeds 8000 bytes. The PRINT command is limited to 8000 bytes (for more information see http://msdn.microsoft.com/en-us/library/ms176047.aspx). Do not trust this data. ** --
so at least the user is informed of the issue.
Download the updated script here.
As always, comments and suggestions are welcomed.
Earlier today I had a user error using spu_generateinsert and couldn't work out what was wrong. It turns out I had specified the table name wrongly. So, I've updated the procedure to check for the existence of the table and to report if there isn't one. Hopefully, this will stop me making the same mistake again :-)
Download the updated script here.
I also noticed today that the PRINT command only outputs 8000 bytes worth of data - so if the contents of a VARCHAR(MAX) is larger than this the output will be truncated. I'm mulling over various fixes for this but in the mean time have noted it as a known issue in the SQL.
Download the updated script here.
I also noticed today that the PRINT command only outputs 8000 bytes worth of data - so if the contents of a VARCHAR(MAX) is larger than this the output will be truncated. I'm mulling over various fixes for this but in the mean time have noted it as a known issue in the SQL.
Just a couple of new blogs for April Brighton Bits and
Free Brighton Guide | Brighton Art : Music : Cool Free Stuff : Magazine | The Brighton Hussy. Take a look and enjoy them.
Free Brighton Guide | Brighton Art : Music : Cool Free Stuff : Magazine | The Brighton Hussy. Take a look and enjoy them.
I've been using Dropbox for a good few months now, and have it installed at work and at home as a way to transfer files between the 2 without resorting to a USB stick. I've also been using it to store non-sensitive odds and ends, like photos of me that I might use as profile pictures, or eBooks etc. Until last week I hadn't really used it as a backup device.
Last week I was due to give a Madgex ILP talk on Introduction to Digital Photography and realised that when I'd swapped my laptop for a desktop, the slidedeck was one thing I hadn't copied over. I headed off in search of my old laptop and discovered it was still unformatted, but I'd been a bit too thorough and had deleted all the files. I checked the file share in the office, but I hadn't put the slides there either. By this point I'd cancelled the talk, and was preparing to rewrite it. Then I thought about dropbox. I remembered that I'd put the file onto Dropbox to transfer it home and back again, but could only find the background material - photos, mindmap etc. I investigated Dropbox a bit further, and realised that Dropbox saves all previous versions of a file and so all I needed to do was to click the "Show deleted files" link, find my slidedeck and restore it. Job done, I breathed a deep sigh of relief and was able to reschedule the presentation.
If you want to get a dropbox account, and fancy getting an extra 250MB on top of your standard free 2GB, then follow my referral, create an account, install the software and voila. We're both 250MB better off.
Last week I was due to give a Madgex ILP talk on Introduction to Digital Photography and realised that when I'd swapped my laptop for a desktop, the slidedeck was one thing I hadn't copied over. I headed off in search of my old laptop and discovered it was still unformatted, but I'd been a bit too thorough and had deleted all the files. I checked the file share in the office, but I hadn't put the slides there either. By this point I'd cancelled the talk, and was preparing to rewrite it. Then I thought about dropbox. I remembered that I'd put the file onto Dropbox to transfer it home and back again, but could only find the background material - photos, mindmap etc. I investigated Dropbox a bit further, and realised that Dropbox saves all previous versions of a file and so all I needed to do was to click the "Show deleted files" link, find my slidedeck and restore it. Job done, I breathed a deep sigh of relief and was able to reschedule the presentation.
If you want to get a dropbox account, and fancy getting an extra 250MB on top of your standard free 2GB, then follow my referral, create an account, install the software and voila. We're both 250MB better off.
This blog post is part of the Ada Lovelace day celebrations. Quite some time ago I signed the pledge to blog about a woman in technology on 24th March 2009, so here it is.
I had a long, hard think about who to blog about, and wanted to choose someone who was more than just a name to me, someone who was doing something to encourage women into technology and wasn't a technologist who was also a woman - if that makes sense (for the record I think that sums me up too) and preferably someone I had at least met.
So, I decided to choose Sarah Blow, a software engineer and a person who actively encourages groups of women to get together on a regular basis by organising Girl Geek dinners. She started off organising the London Girl Geek Dinners in April 2005, and soon after got involved with the "franchising" of them to different towns and even countries, attending at least one of my local Brighton Girl Geek Dinners. I have benefitted from this by attending Brighton Girl Geek Dinners, but also the occasional London one too and have found them to be friendly, high-quality events.
Sarah has done us all a service by providing a safe environment for women in the technology industries to get together without the usual distractions, and has consequently encouraged women to get more involved in mainstream events by giving them confidence. Thanks Sarah!
View more Ada Lovelace Day blog posts
I had a long, hard think about who to blog about, and wanted to choose someone who was more than just a name to me, someone who was doing something to encourage women into technology and wasn't a technologist who was also a woman - if that makes sense (for the record I think that sums me up too) and preferably someone I had at least met.
So, I decided to choose Sarah Blow, a software engineer and a person who actively encourages groups of women to get together on a regular basis by organising Girl Geek dinners. She started off organising the London Girl Geek Dinners in April 2005, and soon after got involved with the "franchising" of them to different towns and even countries, attending at least one of my local Brighton Girl Geek Dinners. I have benefitted from this by attending Brighton Girl Geek Dinners, but also the occasional London one too and have found them to be friendly, high-quality events.
Sarah has done us all a service by providing a safe environment for women in the technology industries to get together without the usual distractions, and has consequently encouraged women to get more involved in mainstream events by giving them confidence. Thanks Sarah!
View more Ada Lovelace Day blog posts
Some new blogs added today:
100 Abandoned Artworks
actionscripter.co.uk
Writer by Night
The Contended Mummy Blog
daveavenue
Digital United | Full-service integrated Digital agency - Award-winning Creative, Marketing, Advertising, Branding, Technology and Games Development
superlative
Creativeblokes Blog
Enjoy!
100 Abandoned Artworks
actionscripter.co.uk
Writer by Night
The Contended Mummy Blog
daveavenue
Digital United | Full-service integrated Digital agency - Award-winning Creative, Marketing, Advertising, Branding, Technology and Games Development
superlative
Creativeblokes Blog
Enjoy!
Yesterday, a colleague was attempting to compare a text column in a table against a literal string and kept coming up against the old
Msg 402, Level 16, State 1, Line 1
The data types text and varchar are incompatible in the equal to operator. error.
He was only trying to do some updates based on known data, so I suggested he converted the text column to VARCHAR before doing the comparison.
We used CONVERT(VARCHAR, <Text Column>) = '<String to compare>') and were surprised that it didn't match. We forced the CONVERT to use VARCHAR(100) and this seemed to work ok, so this got me thinking about what a CONVERT to VARCHAR without a length defaulted to.
SELECT CONVERT(VARCHAR,'123456789012345678901234567890123456789012345678901234567890123456789')
resulted in
123456789012345678901234567890
SELECT DATALENGTH(CONVERT(VARCHAR,'123456789012345678901234567890123456789012345678901234567890123456789'))
resulted in
30
So, CONVERT(VARCHAR,
Msg 402, Level 16, State 1, Line 1
The data types text and varchar are incompatible in the equal to operator. error.
He was only trying to do some updates based on known data, so I suggested he converted the text column to VARCHAR before doing the comparison.
We used CONVERT(VARCHAR, <Text Column>) = '<String to compare>') and were surprised that it didn't match. We forced the CONVERT to use VARCHAR(100) and this seemed to work ok, so this got me thinking about what a CONVERT to VARCHAR without a length defaulted to.
SELECT CONVERT(VARCHAR,'123456789012345678901234567890123456789012345678901234567890123456789')
resulted in
123456789012345678901234567890
SELECT DATALENGTH(CONVERT(VARCHAR,'123456789012345678901234567890123456789012345678901234567890123456789'))
resulted in
30
So, CONVERT(VARCHAR,
Pulling together the thoughts and posts of a snowboarding developing photographer :-)
SuprTags
archives
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- February 2009
- January 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
- June 2007
- May 2007
- April 2007
- March 2007
- February 2007
- January 2007
- December 2006
- November 2006
- September 2006
- August 2006
- July 2006
- May 2006
- July 2005
- July 2003
- March 2003



