Thursday, July 28, 2011

C# recursive file counter

I am constantly surprised with how easy .NET makes things sometimes. I needed a quick recursive file counter output to a report, and was able to write this in just a few minutes, using some new methods available in .NET 4 (EnumerateFiles/Directories) (UPDATE: not sure what I was thinking here - .GetFiles()/.GetDirectories() provides pretty much the same thing - array vs. generic list):

static void Main(string[] args)
   string startingDir = @"C:\files";
   string reportFile = @"C:\file_count.txt";

   using (StreamWriter report = new StreamWriter(reportFile))
        countFiles(startingDir, report);

private static void countFiles(string dir, StreamWriter report) {
   DirectoryInfo directory = new DirectoryInfo(dir);
   IEnumerable<FileInfo> files = directory.EnumerateFiles();
   IEnumerable<DirectoryInfo> dirs = directory.EnumerateDirectories();

   report.WriteLine(String.Format("{0}: {1}", dir, files.Count()));

   foreach (var d in dirs)
        countFiles(d.FullName, report);

It works very quickly (100,000 files in as much as 8 directories deep in less than 30 seconds on a modest machine), and couldn't have been more straightforward to write.

BTW, if all you need is just a total file count, this works well:

DirectoryInfo d = new DirectoryInfo(startingDir);
int totalCount = d.EnumerateFiles("*.*", SearchOption.AllDirectories).Count();

After thinking about this some more, I wonder if this may even be easier/more efficient with LINQ. I've got to try that for fun, and check the performance of each.

Wednesday, July 20, 2011

Graphical Saccades

My son is working through some vision issues, and one of the exercises his vision therapist has him do is called "saccades", basically quick movements of the eyes in the same direction. She gave us a web site that had an animated gif that sequentially displayed a bunch of lines of numbers, at varying distances apart.

This was quite boring for my son, so my wife had an idea for me to make a version of this with pictures of things that he liked. He absolutely LOVES this version of the "game", and wants to play it all the time!

The exercise randomly displays 20 images at varying distances (five lines with four images per line), and can include the same image more than once. The speed can be adjusted before the run, or in progress.

From what I understand, the important part of the exercise is just to track and identify sequentially revealed items at the same pace, but at varying distances apart. I would love to hear from any vision therapists out there, though, to make sure that this is correct, and that a graphical version still satisfies the objective. Our therapist is out for a few weeks, so I can't ask her about it now, but I'll update the post when I get any new information.

If you want to try it out yourself, here's a zip file (under the Google Docs icon, click "File" --> "Download Original") with the code and a few sample images. It's set up to go with 30 random images, but it's easily customizable if you want to use your own images, or add more. To run it, just unzip the .zip file, and double-click on the .html file that best fits your screen.

In the meantime, I'm working on getting the exercise set up on its own web site, but I'm having a hard time finding a free web site provider that allows HTML.

Technically, this was a breeze to do with jQuery. I define an array of images, and use code similar to JavaScript built-in "setTimeout", but with the ability to adjust the interval in progress (thanks, Peter Bailey, for the brilliant function). The key lines are:

vi = setVariableInterval(function() {
if (currentItem == 20) {

randomSpacer = Math.floor(Math.random() * maxPixelLength) + minPixelLength;
randomPicture = Math.floor(Math.random() * pictures.length);

replacementPic = "<img class='p' src='" + pictures[randomPicture].src + "' width='100' height='75' style='margin-left: " + randomSpacer + "px;' />";

}, initialInterval);

"randomSpacer" and "randomPicture" create random numbers up to the defined maximums. And the jQuery line just replaces each placeholder with a random image. "pics" lets me access via index all images that use the "p" class (they are initially set up with placeholders).

pics = $(".p");