iPhoto: Find those unnamed facesThis post marks yet another first. This is the first time that I will post something regarding Apple software. A few months ago I decided to try my luck with a Mac computer. I have not abandoned Windows or Windows development. I have broadened my horizons a bit to now include additional development. With that being said and with the quality of the Mac and great software such as Parallels my PC days are extinct.
iPhoto is a photo management software that comes with Mac OS X. One of the nice features, of which there are several, of this software is its facial recognition capabilities. One of the first things I did when I started using the new Mac was import all of my digital photos into iPhoto. As the pictures were importing, iPhoto churned as it tried to identify the faces in each photo. Once it was complete, I spent some time reviewing each photo to verify the faces that were identified. I had made corrections where necessary. Among the faces in the photos were those that iPhoto couldn't recognize; the 'unnamed' faces.
According to the documentation, iPhoto is supposed to learn from the faces that it has properly identified and any faces that are manually identified. What about the faces that it can't identify and are marked 'unnamed'? I was going through each of my photos, which was a daunting task, and seeing if there were any unnamed faces on them. With several thousand photos, this turns out to be quite a chore. Well, it was quite a chore until I recognized the Smart Albums feature of iPhoto.
Smart Albums allow you to specify photo criteria for it to be included into the album. This 'automatic' album creations saves a lot of time by dynamically creating albums for you (no more drag and drop although you can create those types of albums too). One of the criteria that you can identify is 'faces'. This makes finding those 'unnamed' faces a lot easier than scrolling one by one through each photo. Place the following condition on a smart album and all those unnamed photos will be in the album: Face is unnamed. That is it. Nice and simple. The neat thing is that after all of the unnamed faces have been identified or removed from the photos they will no longer appear in the Album.
iPhoto also allows for the tagging of a photos location (place). This is another way photos can be grouped or even better, selected from the location on a map. Just as a smart album can assist in the identification of photos that contained unnamed faces, a smart album condition can be set to display photos that do not have a location set. Place the following condition in a smart album to see the photos that do not have a location set: 'Place does not contain '. That's it. Nice and simple.
Show Desktop in my QuickLaunch Toolbar?
Command Line: Visual Source Safe
SQL: Remove / Delete Orphan Users
SQL Delete/Drop a User from each Database
The stored procedure is called like;
SQL Optimization: Am I missing any indexes? - Part I
A little System.DiagnosticsI am not going to get overly verbose here; however the importance of application logging is immeasurable. When applications are deployed, obtaining ‘real life’ application can assist in diagnostic and overall application health situations. Excessive logging can be ineffective (too much to analyze) and burdensome (logging to a text file that grows forever) if not implemented appropriately.
When developing and deploying an application having the flexibility of what, when and how to log can alleviate the burden and ineffectiveness of logging. The System.Diagnostics namespace has a number of classes available that allow for this type of flexible logging. The applied use of these classes allows a developer to specify what to log in an application at various levels of detail within one application without the need to deploy diagnostic builds. Depending on diagnostic needs, the application’s config file can specify the level of diagnostic information to write and where. A simple Logging class (this is the class I created to use this functionality) can be developed as follows:
namespace BPSoftware
...{
public class Logging
...{
/**//// <summary>
/// strNameSpace is the base namespace for use in the logging message.
/// </summary>
public static string strNameSpace;

/**//// <summary>
/// GeneralTraceSwitch is a traceswitch object for logging. Switch level is set through
/// the application config switches section. The destination listener is also set through
/// the application config file.
/// </summary>
public static TraceSwitch GeneralTraceSwitch = new TraceSwitch( "General", "General Trace Switch" );

Methods#region Methods
/**//// <summary>
/// Writeline is the base logging method. Messages are logged to the listener specified
/// in the application config file.
/// </summary>
/// <param name="strClassName">Calling class name.</param>
/// <param name="strMethodName">Calling method name.</param>
/// <param name="strMessage">The message sent to the listener.</param>
public static void WriteLine( string strClassName, string strMethodName, string strMessage )
...{
lock ( typeof( Logging ) )
...{
Trace.WriteLine( string.Concat(
new object[] ...{
"(", DateTime.Now, ") ",
strNameSpace, ".", strClassName, ".", strMethodName, " -->", strMessage
}
) );
}
}

/**//// <summary>
/// Pass information to the base WriteLine if the TraceError switch is set.
/// </summary>
/// <param name="strClassName">Calling class name.</param>
/// <param name="strMethodName">Calling method name.</param>
/// <param name="strMessage">The message sent to the listener.</param>
public static void WriteLineTraceError( string strClassName, string strMethodName, string strMessage )
...{
if ( Logging.GeneralTraceSwitch.TraceError )
WriteLine( strClassName, strMethodName, strMessage );
}

/**//// <summary>
/// Pass information to the base WriteLine if the TraceWarning switch is set.
/// </summary>
/// <param name="strClassName">Calling class name.</param>
/// <param name="strMethodName">Calling method name.</param>
/// <param name="strMessage">The message sent to the listener.</param>
public static void WriteLineTraceWarning( string strClassName, string strMethodName, string strMessage )
...{
if ( Logging.GeneralTraceSwitch.TraceWarning )
WriteLine( strClassName, strMethodName, strMessage );
}

/**//// <summary>
/// Pass information to the base WriteLine if the TraceInfo switch is set.
/// </summary>
/// <param name="strClassName">Calling class name.</param>
/// <param name="strMethodName">Calling method name.</param>
/// <param name="strMessage">The message sent to the listener.</param>
public static void WriteLineTraceInfo( string strClassName, string strMethodName, string strMessage )
...{
if ( Logging.GeneralTraceSwitch.TraceInfo )
WriteLine( strClassName, strMethodName, strMessage );
}

/**//// <summary>
/// Pass information to the base WriteLine if the TraceVerbose switch is set.
/// </summary>
/// <param name="strClassName">Calling class name.</param>
/// <param name="strMethodName">Calling method name.</param>
/// <param name="strMessage">The message sent to the listener.</param>
public static void WriteLineTraceVerbose( string strClassName, string strMethodName, string strMessage )
...{
if ( Logging.GeneralTraceSwitch.TraceVerbose )
WriteLine( strClassName, strMethodName, strMessage );
}
#endregion
}
}
catch ( Exception ex)
...{
Logging.WriteLineTraceError( "ClassName", "Method", "Exception: " + ex.Message );
}
Logging.WriteLineTraceInfo( "ClassName", "Method",,
String.Format( "{0}: {1}", e.ActionType.ToString(), e.Message )
);
<system.diagnostics>
<trace autoflush="true" indentsize="4">
<!-- Specify listener output -->
<listeners>
<remove name="Default" />
<!-- Write to a log file -->
<add name="Default"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="AFileSync.log" />
<!-- Write to the Event Log-->
<!-- <add name="Default"
type="System.Diagnostics.EventLogTraceListener"
initializeData="Application" /> -->
</listeners>
</trace>
<switches>
<!-- Off = 0, Error = 1, Warning = 2, Info = 3, Verbose = 4 -->
<add name="General" value="3" />
</switches>
</system.diagnostics>
Compact that Virtual PCLabels: How-To, Information, Tech
Running a .NET Framework application from a network locationLabels: How-To, Information, Tech
Custom Word Fields

Labels: Apps, How-To, Information, Tech
ARP! ARP!

Labels: How-To, Information, Tech
FTP Batch
Ode to BackupLabels: Apps, How-To, Information, Misc, Tech
Conditional FormatSpreadsheets are a great tool for analyzing, manipulating and 'testing' data. Over the years there have been significant advances in spreadsheets that allow for a lot more functionality. Based upon my interactions, I feel comfortable in saying that most people are unaware of and/or greatly underutilize many of the functions and features found in most popular spreadsheet applications.
I often find myself importing thousands of records from databases into a Microsoft Excel spreadsheet for some random ‘quick and dirty’ analysis or output. Once in Excel the possibilities are almost limitless when it comes to the representation of this data, whether it’s via pivot table, charts or just a plain old on the fly filtered list.
When viewing thousands of records it is more often palatable and easier on the eyes with some sort of visual record cues. For example, let’s say we’re looking at a list of customer invoice records, which are sorted by customer. Ata quick glance, by default, all the rows generally look the same. Without intense scrutiny the data sort of, blends all together. What about some sort of visual separation by customer? Excel does have Grouping and AutoFormat, however sometimes the grouping can be overkill. All those '+' and '-' can become overwhelming. Don’t get me wrong grouping is great for adding fast subtotals. The AutoFormat is nice for shading; however it shades on alternating records. What if you wanted to shade groups of records? One answer.. Conditional Formatting.
Conditional Formatting allows you to specify cell properties based upon certain value or formula information. After playing with it a bit, one can see that it is really quite useful. For my scenario:
We’re only going to apply the format if the cell value is 1. The 'Helper Column' should be alternating 0 and 1 on a change in Customer.
Labels: Apps, How-To, Information, Tech
My Send To
The ability to right clicking on a file or folder in Windows Explorer and selecting ‘Send To' to perform some action is a great time saver. What better way to quickly e-mail a file to a colleague There is a downfall to the limit the default options leave you. There are often times when I want to copy a file or folder to another location for backup or distribution purposes. There are also times that I’d like to quickly print and unopened text documents.Labels: How-To, Information, Misc, Tech
Straight to the Prompt
Even in the world of Windows it is often necessary to perform tasks via the command prompt. Along with the console applications that I have created, there are many other command line utilities that I use. Often, these utilities need to be run within a specific directory (a.k.a. folder). Instead of opening up the command window and changing to the desired directory, I find it much easier to open up Windows Explorer, right click on a folder select a menu option and have a command window open, already changed to a selected directory (similar to New Date Folder). This option is not a standard part of Windows Explorer but can be added rather easily.
1. Open Windows Explorer
2. Select Tools --> Folder Options
3. Select the File Types Tab
4. Select Folder from the list of Registered file types
5. Click on Advanced
6. Click the New… button
7. Type Prompt in the Action field
8. In the application field you can type one of two lines:
command.com /k cd %1
or
cmd.exe /k cd "%1"
The difference between the two is that the first option will browse with short file name and the second with long file names.
9. Keep clicking the OK button until you are back to Windows Explorer
Labels: How-To, Information, Misc, Tech
New Date Folder
Opening Windows Explorer, browsing to the desired folder, selecting File--> New -->Folder and then renaming the folder, IMHO, takes way too much effort. I find it a lot easier to just open Windows Explorer, right clicking on a folder and then selecting ‘New Date Folder’ from the context menu . This speeds things up significantly and requires a lot less thought.
Labels: How-To, Information, Tech