tag:blogger.com,1999:blog-79166180035727137402009-07-06T13:10:10.516-07:00Paul MaddoxSoftware development team leader specialising in Microsoft Visual C# and C++ from the Northwest of England. Experience working in a globalised business and team; understanding of enterprise business operation and practices; experience reporting to executive management Skills in numerous languages and technologies; knowledge of formal software development lifecycle; experience of architecture design.noreply@blogger.comBlogger40125tag:blogger.com,1999:blog-7916618003572713740.post-69818309129462715722009-05-15T01:10:00.000-07:002009-05-15T01:14:24.274-07:00What happens if a statement fails in a SQL Server stored procedure?Answer: it carries on regardless! In other words: if you want a stored proc to specifically stop upon error, test for it and return.<br /><br />Take this example:<br /><br />CREATE TABLE [dbo].[PaulTest](<br /> [Number] [int] NOT NULL<br />) ON [PRIMARY]<br /><br />CREATE PROCEDURE uspPaulTest AS<br />BEGIN<br /> INSERT INTO PaulTest (Number) VALUES (NULL) -- fails as NULL is invalid<br /> INSERT INTO PaulTest (Number) VALUES(1) -- still gets processed as the query doesn't return<br />END<br /><br />-- Let's test it:<br /><br />SELECT * FROM PaulTest<br /><br />EXEC uspPaulTest<br /><br />SELECT * FROM PaulTest<br /><br />-- Output:<br /><br />Number<br />-----------<br />(0 row(s) affected)<br /><br />Msg 515, Level 16, State 2, Procedure uspPaulTest, Line 10<br />Cannot insert the value NULL into column 'Number', table 'Test.dbo.PaulTest'; column does not allow nulls. INSERT fails.<br />The statement has been terminated.(1 row(s) affected)<br /><br />Number<br />-----------<br />1<br />(1 row(s) affected)<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7916618003572713740-6981830912946271572?l=paulmaddox.net'/></div>.noreply@blogger.com0tag:blogger.com,1999:blog-7916618003572713740.post-47423553579022923112009-04-22T10:19:00.001-07:002009-04-22T10:19:58.682-07:00Visual Studio 2008 Errors<p>Recently I had my VS 2008 RTM/RC installation go pear shaped. Overnight I stopped being able to create VC++ smartdevice projects with the error</p> <p>“Creating Project '&lt;ProjectName&gt;'... project creation failed”</p> <p>‘No problem’, I thought, ‘I’ll just run setup and do a repair’.&nbsp; Unfortunately, I got an error with the setup of</p> <p>“A problem has been encountered while loading the setup components. Canceling setup.”</p> <p>Luckily I came across a <a href="http://stackoverflow.com/questions/114332/visual-studio-setup-problem-a-problem-has-been-encountered-while-loading-the-s" target="_blank">post on StackOverflow</a> (which is running turning out to be a useful resource from the author of <a href="http://www.codinghorror.com" target="_blank">CodingHorror.com</a>) pointing to a Microsoft tool to ‘force’ uninstall various Microsoft products, including Visual Studio:</p> <p><a title="http://msdn.microsoft.com/en-us/vstudio/bb968856.aspx" href="http://msdn.microsoft.com/en-us/vstudio/bb968856.aspx">http://msdn.microsoft.com/en-us/vstudio/bb968856.aspx</a></p> <p><a href="http://paulmaddox.net/writerpics/VisualStudio2008Errors_10188/image.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://paulmaddox.net/writerpics/VisualStudio2008Errors_10188/image_thumb.png" width="244" height="203"></a></p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7916618003572713740-4742355357902292311?l=paulmaddox.net'/></div>.noreply@blogger.com0tag:blogger.com,1999:blog-7916618003572713740.post-76271590161314731512009-04-21T12:44:00.001-07:002009-04-21T12:44:50.342-07:00SQL Server 2008 Truncating Log File<p>First find the filename labels for your database: <p><strong>select name from &lt;DatabaseName&gt;.dbo.sysfiles</strong></p> <p>Next truncate the log:</p> <p><strong>BACKUP LOG &lt;DatabaseName&gt; WITH TRUNCATE_ONLY</strong> <p>Finally shrink the database based on the log file in step 1: <p><strong>DBCC SHRINKFILE('NameAbove_log',2048)</strong> <p>2048 is the resultant file size in MB.</p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7916618003572713740-7627159016131473151?l=paulmaddox.net'/></div>.noreply@blogger.com0tag:blogger.com,1999:blog-7916618003572713740.post-10565953365635832752009-04-21T12:39:00.001-07:002009-04-21T12:40:08.663-07:00Screen Real Estate Wastage<p>Usually I’m a fan of Microsoft UI design, however having installed the latest version of Windows Live Messenger (or more accurately had it forced on me) I’m astounded by the amount of screen real estate squandered.&nbsp; Clearly Microsoft have been buying too many 24” monitors.&nbsp; After turning off as much of the unneeded fluff as possible I was still left with a window far larger than necessary, with no real benefit.&nbsp; See below!</p> <p><a href="http://paulmaddox.net/writerpics/ScreenRealEstateWastage_1216F/image.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://paulmaddox.net/writerpics/ScreenRealEstateWastage_1216F/image_thumb.png" width="226" height="244"></a></p> <div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7916618003572713740-1056595336563583275?l=paulmaddox.net'/></div>.noreply@blogger.com0tag:blogger.com,1999:blog-7916618003572713740.post-88246111578026742442009-04-21T05:07:00.000-07:002009-05-15T07:38:19.010-07:00SQL Quiz of the Day<pre><br /><span style="color:#000000;"><br />Let’s say you have raw data as so:<br /><br />Id Counter Ident<br />----------- ----------- -----<br />1 1 A<br />2 2 A<br />3 1 A<br />4 3 B<br />5 3 B<br />6 2 A<br />7 1 A<br />8 4 C<br />9 2 C<br />10 1 B<br />11 1 B<br />12 4 B<br /><br />And you want to group by the Ident field, but<br />only contiguous blocks. So you want to display<br />the following:<br /><br />Counter Ident<br />----------- -----<br />4 A<br />6 B<br />3 A<br />6 C<br />6 B<br /><br />Naturally one can’t use GROUP BY, because this would<br />aggregate multiple A’s and B’s.<br /><br />Answers on a postcard!<br /><br />====<br /><br />CREATE TABLE [dbo].[Test](<br /> [Id] [int] IDENTITY(1,1) NOT NULL,<br /> [Counter] [int] NOT NULL,<br /> [Ident] [varchar](3)<br /> COLLATE Latin1_General_CI_AS NOT NULL,<br /> CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED<br />(<br /> [Id] ASC<br />)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]<br />) ON [PRIMARY]<br /></span><br /></pre><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7916618003572713740-8824611157802674244?l=paulmaddox.net'/></div>.noreply@blogger.com1tag:blogger.com,1999:blog-7916618003572713740.post-10713766174100982282009-04-20T13:27:00.000-07:002009-04-20T13:29:44.435-07:00MaddogTCP network TCP/IP fuzzerA while ago - almost three years in fact - I wrote a fuzzer to test network security of TCP/IP connections. Due to one reason and another I never really released it, and despite being published on the net it was hidden from Google, and hence remained undiscovered.<br /><br />Looking back, it was a reasonably succinct little program that deserves the light of day, so here it is:<br /><br /><a href="http://www.calcaria.net/MaddogTCP/">http://www.calcaria.net/MaddogTCP/</a><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7916618003572713740-1071376617410098228?l=paulmaddox.net'/></div>.noreply@blogger.com0tag:blogger.com,1999:blog-7916618003572713740.post-24671491852288965692009-04-08T13:16:00.000-07:002009-05-15T07:39:59.667-07:00Generic type parser using Generics C# .NET<p>Recently I had the need to safely parse multiple types from text ignoring exceptions. Microsoft did not implement an IParsable interface (despite requests) so I thought a solution was crying out for using generics.</p><p>The concept was simple: pass in an object of type T and call T.Parse.  The .NET compiler can check at compile time that the type supports Parse, right?  Unfortunately not.  Although generics allows constraints such as new(), it does not support arbitrary method constraints.</p><p>Lack of method constraints means attempting to call T.Parse won't work.  The result is having to use reflection to get around this.  Of course passing in a type that does not support Parse will  throw an exception, but by virtue of the design this will be handled and the type will return the default.</p><p></p><pre>private T SafeParseAndAssign&lt;T&gt;(string val)<br /> where T : new()<br />{<br />try<br />{<br /> T ValOut = new T();<br /><br /> MethodInfo MI = ValOut.GetType().<br /> GetMethod("Parse", new Type[] { val.GetType() });<br /><br /> return (T)MI.Invoke(ValOut, new object[] { val });<br />}<br />catch<br />{<br /> // swallow exception<br />}<br />return default(T);<br />}<br /></pre><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7916618003572713740-2467149185228896569?l=paulmaddox.net'/></div>.noreply@blogger.com0tag:blogger.com,1999:blog-7916618003572713740.post-71310253473670910302008-12-30T07:55:00.000-08:002008-12-30T08:00:58.748-08:00TinyHomepage - icon based favourites web appMy latest venture - an icon based favourites web app for mobile phones. Feedback gratefully received.<br /><br /><a href="http://tinyhomepage.com/" target="_blank">TinyHomepage.com</a><br /><br /><img src="http://tinyhomepage.com/TinyHomepageScreenshot.png" /><br /><br /><img src="http://tinyhomepage.com/TinyHomepageScreenshotWM1.png" /><br /><br /><img src="http://tinyhomepage.com/TinyHomepageScreenshotWM2.png" /><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7916618003572713740-7131025347367091030?l=paulmaddox.net'/></div>.noreply@blogger.com0tag:blogger.com,1999:blog-7916618003572713740.post-28702087677980222112008-12-23T04:30:00.000-08:002008-12-23T04:35:18.326-08:00.NET GetTempFileName throws System.IO.IOException: The file existsGetting an exception System.IO.IOException: The file exists when calling GetTempFileName? I had this problem with a legacy app, despite the call working fine on nearly all of our systems. It turns out the temp directory had been filling with temp files and eventually went bang. From the MSDN:<br /><ul><li> The <span><span class="selflink">GetTempFileName</span></span> method will raise an <span><a id="ctl00_rs1_mainContentContainer_ctl32" onclick="javascript:Track('ctl00_rs1_mainContentContainer_cpe873965_c|ctl00_rs1_mainContentContainer_ctl32',this);" href="http://msdn.microsoft.com/en-us/library/system.io.ioexception.aspx">IOException</a></span> if it is used to create more than 65535 files without deleting previous temporary files. </li><li> The <span><span class="selflink">GetTempFileName</span></span> method will raise an <span><a id="ctl00_rs1_mainContentContainer_ctl33" onclick="javascript:Track('ctl00_rs1_mainContentContainer_cpe873965_c|ctl00_rs1_mainContentContainer_ctl33',this);" href="http://msdn.microsoft.com/en-us/library/system.io.ioexception.aspx">IOException</a></span> if no unique temporary file name is available. To resolve this error, delete all unneeded temporary files. </li></ul>Simple really.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7916618003572713740-2870208767798022211?l=paulmaddox.net'/></div>.noreply@blogger.com1tag:blogger.com,1999:blog-7916618003572713740.post-85620902749578555342008-11-17T13:21:00.000-08:002008-11-17T13:23:30.819-08:00C# .NET Image Manipulation Resize + Grayscale + TIFFCode from the last three posts can be downloaded formatted properly here:<br /><br /><a href="http://paulmaddox.net/BlogFiles/ImageManipulation_Program.cs.txt">http://paulmaddox.net/BlogFiles/ImageManipulation_Program.cs.txt</a><br /><br />Note you need to add the System.Drawing reference in order to get it to work with a new project.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7916618003572713740-8562090274957855534?l=paulmaddox.net'/></div>.noreply@blogger.com0tag:blogger.com,1999:blog-7916618003572713740.post-59477352678550995592008-11-17T13:10:00.000-08:002008-11-17T13:17:15.779-08:00Convert C# .NET Bitmap to grayscaleHere's some code to convert a Bitmap into grayscale using luminance. Note, this does not change the color depth, rather it sets the pixels to grey within a 24bit color space.<br /><br /><span style="font-family:courier new;"></span><span style="font-family:courier new;"><span style="font-family:courier new;"><span style="font-family:courier new;">private static Bitmap ToGrayscale(Bitmap bmIn)<br />{<br />&nbsp;Bitmap bmOut = new Bitmap(bmIn.Width, bmIn.Height, PixelFormat.Format24bppRgb);<br /><br />&nbsp;for (int x = 0; x &lt; bmIn.Width; x++)<br />&nbsp;{<br />&nbsp;&nbsp;for (int y = 0; y &lt; bmIn.Height; y++)<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;Color px = bmIn.GetPixel(x, y);<br /><br />&nbsp;&nbsp;&nbsp;int luminance = (int)((0.3f * px.R) + (0.59 * px.G) + (0.11 * px.B));<br /><br />&nbsp;&nbsp;&nbsp;bmOut.SetPixel(x, y, Color.FromArgb(luminance, luminance, luminance));<br />&nbsp;&nbsp;}<br />&nbsp;}<br /><br />&nbsp;return bmOut;<br />}<br /></span></span></span><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7916618003572713740-5947735267855099559?l=paulmaddox.net'/></div>.noreply@blogger.com0tag:blogger.com,1999:blog-7916618003572713740.post-70098364489974503062008-11-17T13:04:00.000-08:002008-11-17T13:09:20.163-08:00C# .NET reading a bitmap, resizing / rescaling and saving as a TIFFHere's some code to read in a bitmap and save a new bitmap at a quarter of the size. Note. a boilerplate method is needed to get the encoder for the write format. This makes it easy to change from TIFF to JPEG, PNG, etc.<br /><br /><br /><span style="font-family: courier new;">// Load the bitmap from first argument filename</span><br /><span style="font-family: courier new;">Bitmap bmIn = new Bitmap(inputFilename);</span><br /><br /><span style="font-family: courier new;">// Create a new bitmap from the first, scaling down as we go</span><br /><span style="font-family: courier new;">Bitmap bmOut = new Bitmap(bmIn, new Size(bmIn.Width/2, bmIn.Height/2));</span><br /><br /><span style="font-family: courier new;">// Create an parameter set that we use to save the file</span><br /><span style="font-family: courier new;">EncoderParameters encParams = new EncoderParameters(3);</span><br /><br /><span style="font-family: courier new;">// Set some parameters</span><br /><span style="font-family: courier new;"> encParams.Param[0] = new EncoderParameter(Encoder.ColorDepth, 24L);</span><br /><span style="font-family: courier new;">encParams.Param[1] = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionNone);</span><br /><span style="font-family: courier new;">encParams.Param[2] = new EncoderParameter(Encoder.SaveFlag, (long)EncoderValue.MultiFrame);</span><br /><br /><span style="font-family: courier new;">// Save bitmap to second argument filename</span><br /><span style="font-family: courier new;">bmOut2.Save(outputFilename, GetEncoder(ImageFormat.Tiff), encParams);</span><br /><span style="font-family: courier new;">private static ImageCodecInfo GetEncoder(ImageFormat format)</span><br /><span style="font-family: courier new;">{</span><br /><span style="font-family: courier new;"> ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();</span><br /><br /><span style="font-family: courier new;"> foreach (ImageCodecInfo codec in codecs)</span><br /><span style="font-family: courier new;"> {</span><br /><span style="font-family: courier new;"> if (codec.FormatID == format.Guid)</span><br /><span style="font-family: courier new;"> {</span><br /><span style="font-family: courier new;"> return codec;</span><br /><span style="font-family: courier new;"> }</span><br /><span style="font-family: courier new;"> }</span><br /><span style="font-family: courier new;"> return null;</span><br /><span style="font-family: courier new;">}</span><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7916618003572713740-7009836448997450306?l=paulmaddox.net'/></div>.noreply@blogger.com0tag:blogger.com,1999:blog-7916618003572713740.post-10660216094591361352008-11-17T12:52:00.000-08:002008-11-17T13:04:22.181-08:00Out of Memory / OutOfMemoryException on Graphics.FromImage with PixelFormat.Format16bppArgb1555 or PixelFormat.Format16bppGrayScaleIf you have some code like this:<br /><br /><span style="font-family: courier new;">Bitmap bmp = new Bitmap(100,100, PixelFormat.Format16bppArgb1555);</span><br /><span style="font-family: courier new;">Graphics gfx = Graphics.FromImage(bmp);</span><br /><br />You will find you get an out of memory exception upon executing the code. The reason? .NET does not actually support <span style="font-weight: bold;">Format16bppArgb1555 </span>or <span style="font-weight: bold;">PixelFormat.Format16bppGrayScale</span>.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7916618003572713740-1066021609459136135?l=paulmaddox.net'/></div>.noreply@blogger.com0tag:blogger.com,1999:blog-7916618003572713740.post-20226346131334912042008-11-05T04:45:00.000-08:002008-12-23T04:50:31.901-08:00Visual Studio ErrorsThanks to Matt at Siemens for this one.<br /><br />"If you get similar errors to below then deleting everything in the C:\Documents and Settings\<user>\Local Settings\Application Data\Microsoft\VisualStudio\<vs>\ProjectAssemblies will solve this. Do not delete anything above this directory as you will lose all your toolbars and settings."<br /><br />Error 4 The "ResolveAssemblyReference" task failed unexpectedly.<br /><br />System.IO.IOException: Incorrect function.<br /><br /> at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)<br /><br /> at System.IO.Directory.InternalGetFileDirectoryNames(String path, String userPathOriginal, String searchPattern, Boolean includeFiles, Boolean includeDirs, SearchOption searchOption)<br /><br /> at System.IO.Directory.GetDirectories(String path, String searchPattern, SearchOption searchOption)<br /><br /> at System.IO.Directory.GetDirectories(String path, String searchPattern)<br /><br /> at Microsoft.Build.Tasks.SystemState.GetDirectories(String path, String pattern)<br /><br /> at Microsoft.Build.Tasks.ReferenceTable.FindSatellites(Reference reference)<br /><br /> at Microsoft.Build.Tasks.ReferenceTable.FindAssociatedFiles()<br /><br /> at Microsoft.Build.Tasks.ReferenceTable.ComputeClosure()<br /><br /> at Microsoft.Build.Tasks.ReferenceTable.ComputeClosure(DependentAssembly[] remappedAssembliesValue, ITaskItem[] referenceAssemblyFiles, ITaskItem[] referenceAssemblyNames, ArrayList exceptions)<br /><br /> at Microsoft.Build.Tasks.ResolveAssemblyReference.Execute(FileExists fileExists, DirectoryExists directoryExists, GetDirectories getDirectories, GetAssemblyName getAssemblyName, GetAssemblyMetadata getAssemblyMetadata, GetRegistrySubKeyNames getRegistrySubKeyNames, GetRegistrySubKeyDefaultValue getRegistrySubKeyDefaultValue, GetLastWriteTime getLastWriteTime)<br /><br /> at Microsoft.Build.Tasks.ResolveAssemblyReference.Execute()<br /><br /> at Microsoft.Build.BuildEngine.TaskEngine.ExecuteInstantiatedTask(EngineProxy engineProxy, ItemBucket bucket, TaskExecutionMode howToExecuteTask, ITask task, Boolean&amp; taskResult) MyProject<br /></vs></user><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7916618003572713740-2022634613133491204?l=paulmaddox.net'/></div>.noreply@blogger.com0tag:blogger.com,1999:blog-7916618003572713740.post-90486844805414052252008-08-28T12:13:00.000-07:002008-08-28T12:28:17.660-07:00Encrypting ASP.NET web.config impersonation dataIt always irked me that using impersonate for my ASP.NET web apps meant I had to expose the username and password in plain text. Eg./<br /><br />&lt;identity impersonate="true" username="BOB" password="NOTSOSECRET"&gt;<br /><br />Luckily it irked someone at Microsoft too and they came out with a hotfix allowing the credentials to be stored in encrypted form in the registry.<br /><br /><a href="http://support.microsoft.com/kb/329290">http://support.microsoft.com/kb/329290</a><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7916618003572713740-9048684480541405225?l=paulmaddox.net'/></div>.noreply@blogger.com0tag:blogger.com,1999:blog-7916618003572713740.post-75194015208352945912008-05-30T07:01:00.001-07:002008-05-30T07:06:22.436-07:00Microsoft Source AnalysisMicrosoft have released their previously internal tool Source Analysis (aka StyleCop). This allows project- and file- level source code analysis checking it meets a whole raft of style rules developed by Microsoft. Some you will agree with, some you won't. The good news is you can turn off rules you don't like, the bad news is you cannot develop your own.<br /><br /><a href="http://blogs.msdn.com/sourceanalysis/archive/2008/05/23/announcing-the-release-of-microsoft-source-analysis.aspx">blogs.msdn.com</a><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7916618003572713740-7519401520835294591?l=paulmaddox.net'/></div>.noreply@blogger.com1tag:blogger.com,1999:blog-7916618003572713740.post-78042619744986545572008-03-27T05:33:00.000-07:002008-11-17T13:26:23.851-08:00Visual Studio 2008 IDE C# - UK Launch Notes<ul><li>VS08 allows seamless (re)targeting of apps to .NET 2.0, 3.0 and 3.5. This provides graceful upgrading of existing applications. Applications initially targeted for 3.x can also be targeted to .NET 2.0 as long as features of 3.x have not been used.<br /><br /></li><li>Properties have now been improved so the implementation of the get and set methods do not need to be provided if the default implementation is all that is required. Eg./<br /><br /><pre>public string FirstName { get; set; }</pre>This creates a hidden private member variable.<br /><br /></li><li>It is now possible to use braces to initialise multiple object properties:<br /><br /><pre>Thread myThread = new Thread(MyThreadMethod)<br />{<br />Name="my thread",<br />IsBackground=true<br />};<br /></pre></li><li>Anonymous types can be created using the 'var' keyword. This is NOT weak typing - C# knows what the type is and it cannot change. Anonymous types are used in instances where the developer does not know the type, the primary instance of this being LINQ. Eg./<br /><br /><pre>var anonobject = new {Name = "Bob", Age = "40"};<br /></pre></li><li>Anonymous methods are best described in detail here:<br /><br /><a href="http://msdn.microsoft.com/msdnmag/issues/04/05/C20/#S5">http://msdn.microsoft.com/msdnmag/issues/04/05/C20/#S5</a><br /><br /></li><li>Partial methods can be used as a lightweight event system in cases where a large number of objects are held in memory (IE. LINQ) or where the method may be optionally implemented. Eg./<br /><br /><pre>partial class MyClass<br />{<br />MyClass()<br />{<br /> DisplayMessage(); // Only called if definition exists<br />}<br /><br />static partial DisplayMessage(); // Not implemented<br />}<br /><br />partial class MyClass<br />{<br />static partial DisplayMessage() // Optional<br />{<br /> Console.WriteLine("MyClass created");<br />}<br />}<br /></pre></li><li>Extension methods allow you to 'tack on' functionality to classes that you would otherwise not be able to due to inheritance being prevented (IE. .NET classes). Eg./<br /><br /><pre>public static class MyExtensions<br />{<br />public static bool<br /> IsValidEmailAddress(this string s) // "this" keyword<br />{<br /> Regex regex =<br /> new Regex(@"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$");<br /> return regex.IsMatch(s);<br />}<br />}<br /><br />public class MyClass<br />{<br />public void MyMethod()<br />{<br /> string email = "paul@here.com";<br /><br /> // Extension method used like a standard string method<br /> if (email.IsValidEmailAddress())<br /> {<br /> Console.WriteLine("Valid!");<br /> }<br />}<br />}</pre></li></ul><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7916618003572713740-7804261974498654557?l=paulmaddox.net'/></div>.noreply@blogger.com0tag:blogger.com,1999:blog-7916618003572713740.post-56726896013562083632008-03-27T01:12:00.001-07:002008-03-27T01:12:30.930-07:00C# Programming - Part 2 - Conditions<span style="font-size:180%;">Scope of work</span><br /><br />The work is split into two parts: the first is a training part where you are encouraged to use books and the Internet to help you complete the questions; the second is a test part where you should complete the questions with no external help. The pass score is 80%.<br /><br />1. if, else if, else<br /><br />2. Nested conditions<br /><br />3. &amp;&amp; and<br /><br />4. switch statement<br /><br /><span style="font-size:180%;">Training Questions</span><br /><br />Create console applications to:<br /><br />1. Read a number from the console (use ReadLine and Int32.Parse) and using if, else if and else output one of the following<br /><br /><strong>“The number is negative”<br /><br />“The number is lower than 100”<br /><br />“The number is 100 or above”</strong><br /><br />2. Read two numbers from the console (one after the other) and by nesting if, else if and else output one of the following:<br /><br /><strong>“The numbers are the same”<br /><br />“The numbers are not the same”<br /><br />– the first is lower than the second”<br /><br />“The numbers are not the same<br /><br />– the second is lower than the first”</strong><br /><br />3. Read two numbers from the console (one after the other) and using if, else if and else along with &amp;&amp; output one of the following:<br /><br /><strong>“The numbers are the same and are negative”<br /><br />“The numbers are the same and are positive”<br /><br />“The numbers are not the same”</strong><br /><br />4. Read a number from the console (use ReadLine and Int32.Parse) and using a switch statement with cascading, and depending on an input 1-10 output one of the following:<br /><br /><strong>“You entered an even number” or<br /><br />“You entered an odd number” or<br /><br />“You entered a number that is not 1-10”<br /></strong><br />5. Read a number from the console (use ReadLine and Int32.Parse) and by nesting if, else if and else output one of the following depending on what range the number is in, and whether it is divisible by 5:<br /><br /><strong>“The number is 0-25 and is divisible by 5” or<br /><br />“The number is 0-25 and is not divisible by 5” or<br /><br />“The number is 26-50 and is divisible by 5” or<br /><br />“The number is 26-50 and is not divisible by 5” or<br /><br />“The number is 51-75 and is divisible by 5” or<br /><br />“The number is 51-75 and is not divisible by 5” or<br /><br />“The number is above 75”</strong><br /><br />* Note. To check if a number is divisible by 5 you can use:<br /><br /><strong>(number % 5 == 0)<br /></strong><br /><span style="font-size:180%;">Test Questions</span><br /><br />Create console applications to:<br /><br />1. Read two numbers from the console (one after the other) and using if, else if and else output one of the following:<br /><br /><strong>“The first number is lower than the second”<br /><br />“The second number is lower than the first”<br /><br />“The numbers are the same”</strong><br /><br />2. Read two numbers from the console (one after the other) and by nesting if, else if and else output one of the following:<br /><br /><strong>“Both numbers are negative”<br /><br />”Both numbers are positive”<br /><br />“The first number is positive, the second is negative”<br /><br />“The second number is positive, the first is negative”</strong><br /><br />3. Read a letter from the console and by if, else if and else with (or) output one of the following:<br /><br /><strong>“1” (if the letter is a, b or c)<br /><br />“2” (if the letter is d, e or f)<br /><br />“3” (if the letter is g, h or i)<br /><br />“4” (if the letter is j, k or l)</strong><br /><br />4. Read a number from the console (use ReadLine and Int32.Parse) and using a switch statement with cascading, and depending on an input 1-9 output one of the following:<br /><br /><strong>“You entered the number one, two or three” or<br /><br />“You entered the number four, five or six” or<br /><br />“You entered the number seven, eight or nine” or<br /><br />“You entered a number that is not 1-9”</strong><br /><br />5. Read three numbers from the console (one after the other) and by nesting if, else if and else sort the three numbers and output them in order:<br /><br /><strong>Example: input numbers: 2 5 and 1<br /><br />Output: 1, 2, 5<br /><br />Example: input numbers 100, 45, 30<br /><br />Output: 30, 45, 100</strong><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7916618003572713740-5672689601356208363?l=paulmaddox.net'/></div>.noreply@blogger.com0tag:blogger.com,1999:blog-7916618003572713740.post-52415955989964281152008-03-22T14:16:00.000-07:002008-03-22T14:51:46.644-07:00C# Programming - Part 1 - StringsAs languages become more high-level it seems training material focuses more on dragging and dropping components and interacting with the IDE than teaching fundamentals like problem solving and creating logical procedural code. From this deficit I created a set of C# Programming tasks that concentrate on problem solving and creating logical code. This work is made available by kind approval of <a href="http://www.siemens.com/" target="_blank">Siemens AG Industry</a>.<br /><br /><span style="color:#cc0000;">The tasks are provided free of charge but may NOT be copied or redistributed. The work is copyright and all rights are reserved.<br /></span><br /><span style="font-size:180%;">Scope of work</span><br /><br />The work is split into two parts: the first is a training part where you are encouraged to use books and the Internet to help you complete the questions; the second is a test part where you should complete the questions with no external help. The pass score is 80%.<br /><br />1. Manipulating strings<br /><br />2. Substrings<br /><br />3. Upper/lower case<br /><br />4. Concatenation<br /><br />5. Locating a character in a string<br /><br />6. Replacing characters in a string<br /><br /><span style="font-size:180%;">Training Questions</span><br /><br />Create console applications to:<br /><br />1. Store your name as a string literal and output it to screen.<br /><br />2. Read a string from the console and output it in upper case.<br /><br />3. Read a name from the console (for example "Bob") and output the following:<br /><br /><strong>"Hello, Bob!"</strong><br /><br />4. Use the following string:<br /><br /><strong>string telephone = "0800 123 4567";</strong><br /><br />and replace the space with a - so that the output is:<br /><br /><strong>0800-123-4567<br /></strong><br />5. Use the following string:<br /><br /><strong>string alphabet = "abcdefghijklmnopqrstuvwxyz";</strong><br /><br />and output six letters starting from e, so that the output is:<br /><br /><strong>efghij</strong><br /><br />6. Create a simple CSV (comma separated values) parser capable of dealing with a string read in from the console. The string will always be in the format:<br /><br /><strong>firstvalue,secondvalue,thirdvalue</strong><br /><br />Some example strings:<br /><br /><strong>"1,2,3"</strong><br /><br /><strong>"aa,bb,cc"</strong><br /><br /><strong>"apple,banana,pear"<br /></strong><br />The output (using the third string as an example) should be output to screen as follows:<br /><br /><strong>First value: apple</strong><br /><br /><strong>Second value: banana<br /><br />Third value: pear</strong><br /><br /><span style="font-size:180%;">Test Questions</span><br /><br />Create console applications to:<br /><br />1. Store your name in a string and output it to the screen in upper case.<br /><br />2. Use the following strings:<br /><br /><strong>string countryCode = “44”;<br /><br />string areaCode = “1260”;<br /><br />string number = “123456”<br /></strong><br />along with string literals to output:<br /><br /><strong>+44-1260-123456</strong><br /><br />to screen<br /><br />3. Use a string as follows:<br /><br /><strong>string test = "siemens automation and drives";</strong><br /><br />Replace every i character with a 1 and then output the string in upper case as so:<br /><br /><strong>S1EMENS AUTOMAT1ON AND DR1VES</strong><br /><br />4. Parse the following string:<br /><br /><strong>string surnameforename = "Siemens, Werner";<br /></strong><br />so the forename appears before the surname as follows:<br /><br /><strong>"Werner Siemens"<br /></strong><br />store it in a string variable and output it to screen.<br /><br />5. Read in a string from the console that will always be in the following format:<br /><br /><strong>+<br /></strong><br />This should be done using the substring function.<br /><br />For example:<br /><br /><strong>12+4<br /></strong><br />Where the example would output:<br /><br /><strong>First number: 12<br /><br />Second number: 4 </strong><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7916618003572713740-5241595598996428115?l=paulmaddox.net'/></div>.noreply@blogger.com0tag:blogger.com,1999:blog-7916618003572713740.post-1117540353384688062007-11-23T03:00:00.000-08:002007-11-23T03:05:43.499-08:00Resizing a logical volume without unmounting in LinuxI had a problem where the logical volume our kickstart image created was too small, despite the disk having enough space. As you see it only allocated 4GB:<br /><pre>[root@example sbin]# df<br />Filesystem 1K-blocks Used Available Use% Mounted on<br />/dev/mapper/VolGroup00-LogVol00<br /> 4128448 3716732 202004 95% /<br />/dev/sda1 101086 18598 77269 20% /boot<br />none 8203424 0 8203424 0% /dev/shm</pre><br />The logical volume can be resized by running lvm (as root) at the command prompt and the following command (For 50GB):<br /><pre>lvm&gt; lvresize -L 50G VolGroup00/LogVol00</pre><br />The issue we then had is that this isn't committed! Exit lvm, and then type the following:<br /><pre>ext2online /dev/mapper/VolGroup00-LogVol00</pre><br />After a few minutes of processing you will now find you have a larger volume:<br /><pre>[root@example sbin]# df<br />Filesystem 1K-blocks Used Available Use% Mounted on<br />/dev/mapper/VolGroup00-LogVol00<br /> 51606140 3721676 45263616 8% /<br />/dev/sda1 101086 18598 77269 20% /boot<br />none 8203424 0 8203424 0% /dev/shm</pre><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7916618003572713740-111754035338468806?l=paulmaddox.net'/></div>.noreply@blogger.com0tag:blogger.com,1999:blog-7916618003572713740.post-17500383446186371652007-08-07T14:55:00.001-07:002007-08-07T14:55:37.197-07:00Syntax highlighting in colour in HTMLI recently found a fantastic feature in GVIM that allows me to syntax highlight my code and turns it into HTML. I'm sure there are tools out there specifically for this job, but given the convenience of having this built into my editor I couldn't help but mention it.<br /><br />You can get <a href="http://www.vim.org/" target="_blank">GVIM from their website</a>. When you've loaded your code up (and practically every language is supported), click the Syntax -> Convert to HTML menu option.<br /><br />Here's a sample:<br /><br /><pre><br /><span style="color:#6a5acd;">&lt;?php</span><br /><br /><span style="color:#804040;"><b>if</b></span> <span style="color:#6a5acd;">(</span><span style="color:#008080;">isset</span><span style="color:#6a5acd;">(</span><span style="color:#804040;"><b>$</b></span><span style="color:#008080;">_GET</span><span style="color:#6a5acd;">[</span>'<span style="color:#ff00ff;">album</span>'<span style="color:#6a5acd;">]))</span><br /><span style="color:#6a5acd;">{</span><br /> <span style="color:#0000ff;">//echo 'gallery: ' . $_GET['album'];</span><br /> <span style="color:#804040;"><b>$</b></span><span style="color:#008080;">d</span> <span style="color:#804040;"><b>=</b></span> <span style="color:#008080;">dir</span><span style="color:#6a5acd;">(</span>'<span style="color:#ff00ff;">Photos/</span>' <span style="color:#804040;"><b>.</b></span> <span style="color:#804040;"><b>$</b></span><span style="color:#008080;">_GET</span><span style="color:#6a5acd;">[</span>'<span style="color:#ff00ff;">album</span>'<span style="color:#6a5acd;">])</span>;<br /><br /> <span style="color:#804040;"><b>$</b></span><span style="color:#008080;">bFirst</span> <span style="color:#804040;"><b>=</b></span> <span style="color:#ff00ff;">true</span>;<br /> <span style="color:#804040;"><b>while</b></span> <span style="color:#6a5acd;">(</span> <span style="color:#6a5acd;">(</span><span style="color:#804040;"><b>$</b></span><span style="color:#008080;">file</span> <span style="color:#804040;"><b>=</b></span> <span style="color:#804040;"><b>$</b></span><span style="color:#008080;">d</span><span style="color:#2e8b57;"><b>-&gt;</b></span><span style="color:#008080;">read</span><span style="color:#6a5acd;">())</span> <span style="color:#804040;"><b>!=</b></span><span style="color:#804040;"><b>=</b></span> <span style="color:#ff00ff;">false</span><span style="color:#6a5acd;">)</span><br /> <span style="color:#6a5acd;">{</span><br /> <span style="color:#804040;"><b>if</b></span> <span style="color:#6a5acd;">(</span><span style="color:#008080;">strpos</span><span style="color:#6a5acd;">(</span><span style="color:#804040;"><b>$</b></span><span style="color:#008080;">file</span>, '<span style="color:#ff00ff;">tb.jpg</span>'<span style="color:#6a5acd;">)</span> <span style="color:#804040;"><b>!=</b></span><span style="color:#804040;"><b>=</b></span> <span style="color:#ff00ff;">false</span><span style="color:#6a5acd;">)</span><br /> <span style="color:#6a5acd;">{</span><br /></pre><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7916618003572713740-1750038344618637165?l=paulmaddox.net'/></div>.noreply@blogger.com0tag:blogger.com,1999:blog-7916618003572713740.post-43824559951502973202007-08-02T15:02:00.000-07:002007-08-07T15:03:24.675-07:00Search Engine Effectiveness - Practical TestI've been wondering recently how effective alternate search engines are compared to Google. As a small test I decided to take 25 searches I had performed in the last week and search on Google, Yahoo and MSN Live Search to compare results.<br /><br />The following table shows the results. A score of zero means the target info was found on the search page itself (I didn't have to click through to the site). A number 1-10 is the position of the search result with the target info. A blank score means the target info was not found on the first page of links.<br /><br />The score is a sum of each search position negated from 11. As so:<br /><br />Target info on search page: 11-0 = 11<br />Target info on page result 4: 11-4 = 7<br />Target info on page result 10: 11-10 = 1<br />Target info not found: 0<br /><br /><img src="http://www.paulmaddox.net/Files/search.gif" /><br /><br />Conclusions:<br /><br />I was pretty suprised Google was so far ahead compared to Yahoo and MSN. Google won because it was better at finding more niche searches, whereas Yahoo and MSN failed completely. For more obvious searches all three performed flawlessly and may do for day-to-day searches.<br /><br />Google tended to either have the result first, or not at all. Yahoo had a few useful results in the top five. MSN had some results nearer the bottom of the top 10. This is significant for MSN because much lower results seriously increases the time taken to find what you want.<br /><br />Some oddities included Yahoo having numerous entries that were highly irrelevant and MSN having a curious slant to open source results, particularly source code.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7916618003572713740-4382455995150297320?l=paulmaddox.net'/></div>.noreply@blogger.com0tag:blogger.com,1999:blog-7916618003572713740.post-23517843824759836552007-06-27T01:04:00.001-07:002007-06-27T01:04:06.898-07:00Data set Pagination in MSSQL not MySQL!<p>A poster by the name of Stripe-man has come up with a really simple way of paginating&nbsp;data in SQL Server.&nbsp; This has always been easy with MySQL using the LIMIT keyword, which is missing from SQL Server 2000.&nbsp; (SQL Server 2005 added a row count similar to Oracle's, I believe.)</p> <p>Here is the template:</p> <blockquote> <p><font color="#804040"><b>SELECT</b></font> TOP&nbsp;<font color="#ff00ff">&lt;PAGESIZE&gt;</font> * <font color="#6a5acd">FROM</font> task_log <font color="#6a5acd">WHERE</font> id <font color="#804040"><b>NOT</b></font> <font color="#804040"><b>IN</b></font> (<font color="#804040"><b>SELECT</b></font> TOP&nbsp;<font color="#ff00ff">&lt;PAGEOFFSET&gt;</font> id <font color="#6a5acd">FROM</font> task_log <font color="#6a5acd">ORDER</font> <font color="#6a5acd">BY</font> ID) <font color="#6a5acd">ORDER</font> <font color="#6a5acd">BY</font> ID </p></blockquote> <p>So, for example, to display 10 items from 51-60 we would do:</p> <blockquote> <p><font color="#804040"><b>SELECT</b></font> TOP <font color="#ff00ff">10</font> * <font color="#6a5acd">FROM</font> task_log <font color="#6a5acd">WHERE</font> id <font color="#804040"><b>NOT</b></font> <font color="#804040"><b>IN</b></font> (<font color="#804040"><b>SELECT</b></font> TOP&nbsp;<font color="#ff00ff">50</font> id <font color="#6a5acd">FROM</font> task_log <font color="#6a5acd">ORDER</font> <font color="#6a5acd">BY</font> ID) <font color="#6a5acd">ORDER</font> <font color="#6a5acd">BY</font> ID </p></blockquote> <p>What this essentially says is: show me the top ten results that do not appear in the top fifty results.</p> <p><a href="http://www.phpbuilder.com/board/showpost.php?p=10668964&amp;postcount=13" target="_blank">PHPBuilder.com - View Single Post - Pagination with PHP / MsSQl not MySQL!</a></p><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7916618003572713740-2351784382475983655?l=paulmaddox.net'/></div>.noreply@blogger.com0tag:blogger.com,1999:blog-7916618003572713740.post-86531322439489621252007-06-26T07:40:00.001-07:002007-06-26T07:41:24.484-07:00Google adding new business customers at a rate of 1000 per day since it launched in February<p>Google is making a pretty good progress getting business customers on to its mail platform, at a rate of 1000 per day.&nbsp; However Rishi Chandra, product manager for Google Apps, is perhaps being a bit optimistic in terms of product development, which in the case of GMail we have seen relatively little of since its beta inception.</p> <p><em>"At the end of the day, Google Apps is about innovation," said Chandra. "You don't have to wait for a major release to get these features. It happens in real time. ... It's taking the speed and innovation of the consumer world and applying it to the business world."</em> <p>The problem is, it seems we do have to wait.&nbsp; Whilst Windows Live Mail and Yahoo Mail have seen dramatic improvements in the user interface, Google can be seen lagging behind with what cynics might even call a dated user experience. <p>As Information Week identifies: <p><em>"Such relentless change has the potential to leave users lost, but Chandra insists Google's focus on the user experience means that new features are easy to understand and don't require new training."</em> <p>Unfortunately to produce a high level of innovation along with consistency of user experience is not an easy task, despite Chandra's insistence, but only time will tell what emphasis Google chooses, or whether they will attempt the impossible.</p> <p><a href="http://www.informationweek.com/management/showArticle.jhtml?articleID=200000609&amp;cid=RSSfeed_TechWeb" target="_blank">Google Apps Opens Door To Migrating E-Mail Users -- Google Apps -- InformationWeek</a></p><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7916618003572713740-8653132243948962125?l=paulmaddox.net'/></div>.noreply@blogger.com0tag:blogger.com,1999:blog-7916618003572713740.post-63379851676401452802007-06-17T14:59:00.000-07:002007-08-07T14:59:58.794-07:00Arithmetic overflow error converting expression to data type intIn SQL Server I get the following error when I try to COUNT(*) rows in very large tables:<br /><br />"Arithmetic overflow error converting expression to data type int."<br /><br />Googling and sifting through pages about the same problem for SUM( ), I found you can use this function:<br /><br />COUNT_BIG(*)<br /><br />This uses a bigint rather than int for storage.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7916618003572713740-6337985167640145280?l=paulmaddox.net'/></div>.noreply@blogger.com0