Friday, May 11, 2012

Generic XML attribute parser

I may just end up using something like LINQ to XSD for this (if possible), but I wanted to see how easy it would be to write an XML parser that takes in an element of any kind, and returns a strongly-typed value. Here's what I came up with:

private T parseAttr<T>(XElement x, string elemName)
{
    Type type = typeof(T);
    T parsedValue;

    try
    {
        parsedValue = type.IsEnum ? (T)Enum.Parse(typeof(T), x.Element(elemName).Value) : (T)Convert.ChangeType(x.Element(elemName).Value, typeof(T));
    }
    catch
    {
        parsedValue = default(T);
    }

    return parsedValue;
}

which can be used like this (example is from a LINQ projection):

let picks =
    from pick in playerPicks.Element("PlayerList").Descendants("Player").Elements("Picks")
    select new PlayerPick
    {
        TickerSymbol = parseAttr<string>(pick, "TickerSymbol"),
        Status = parseAttr<Status>(pick, "Status"),
        PickCall = parseAttr<PickCall>(pick, "PickCall"),
        StartPrice = parseAttr<double>(pick, "StartPrice"),
        EndPrice = parseAttr<double>(pick, "EndPrice"),
        StartDate = parseAttr<DateTime>(pick, "StartDate"),
        EndDate = parseAttr<DateTime>(pick, "EndDate")
    }

It works on regular types as well as enums. I'm not completely happy with it - "Convert" is generally less useful than .Parse(), but I couldn't figure out how to use Parse with generics on static methods (i.e. (T).Parse()).

Also, it's hardly bulletproof, but I think I may validate the whole XML document first anyway if it doesn't take too long. Not sure if I'll end up using this or not - I was just amazed about how easy this was to write using generics, and thought it might be useful to somebody.

Monday, May 7, 2012

Renaming an ASP.NET MVC solution in Visual Studio

The Platinum Bay blog has a good writeup on how to rename a Visual Studio project correctly (so that the underlying folders are renamed and re-hooked up). 

But I still ran into problems - an MVC project that I renamed returned the following error :
Multiple types were found that match the controller named 'Home'. This can happen if the route that services this request ('{controller}/{action}/{id}') does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter. 
The request for 'Home' has found the following matching controllers:
(new project namespace).Controllers.HomeController
(old project namespace).Controllers.HomeController
A file system search even turned up nothing, but I finally figured out the solution while reading a great in-depth article on controllers by Scott Allen, where he states:
...if you tell the factory to look for a "Home" controller, the factory can return a newly instantiated instance of a HomeController class regardless of the namespace or assembly it lives in—as long as it implements IController
If you've build the old project, you'll probably have old debugging dlls in the project's "bin" folder, so MVC will search and find those. Clear them out and rebuild, and everything should work. By the way, you could actually just follow the instructions in the error, and specify your route like this:

routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
                namespaces: new string[] {"(new project namespace)"}
            );

but it's cleaner to delete the old .dlls, as they could potentially cause you other problems as well. I'm very surprised that even the VS 11 beta still doesn't rename solutions correctly out of the box.



Thursday, April 26, 2012

Querying fact tables for lower-level members (SAP BPC - MS version)

Top-level dimension members aren't represented at all in BPC fact tables (SQL side), so if you need to find records that belong to a top-level member, you either need to manually look up all of the lower-level members, or have a query do it for you. Here's one I put together using a basic recursive CTE that will give you all records that contain lower-level members, given a higher-level member:

WITH a
AS (
 SELECT *
 FROM mbrDataSrc_F
 WHERE [ID] = 'Top_Level_Datasource_Name' --top parent
         
 UNION ALL
         
 SELECT b.*
 FROM mbrDataSrc_F b
  JOIN a
   ON b.PARENTH1 = a.[ID]
        )
SELECT *
FROM tblFactForecast
WHERE DataSrc_F IN (
 SELECT [ID]
 FROM a
)

If you're not familiar with them, the SQL after the UNION is the recursive part (some more info on recursive Common Table Expressions). I use them a lot in place of derived tables for their slightly cleaner syntax, but don't usually have too much of a need for recursion.

BTW, I don't believe in SELECT *, except for ad-hoc queries, which this one was for me. There is an interesting discussion about it over at StackOverflow.com - basically, minimal performance gains in most situations, but more clean and safer to select the actual columns.

Wednesday, February 8, 2012

FizzBuzz

Apparently, the "FizzBuzz" problem is a common programming interview question. I came across it while reading You Can't Teach Height - Measuring Programmer Competence via FizzBuzz on Scott Hanselman's blog.

The "FizzBuzz" problem is:
Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.
After reading this, my first thought was to write code to solve the problem. Funny that the end of Hansleman's post states:
One other thing that's amazing to me ... is that some of the programmers who read these blogs feel the need to actually solve the FizzBuzz problem.
They've completely - no, I need a work with more oomph - utterly? missed the point.
I'm pretty sure the point of his post is just that an interviewer should ask the applicant to show what he/she can do, rather than just talk about it. I agree with this. And I always have a better feeling about a place where I interview if they at least have me provide code samples and have me talk about them.

But I've got to agree with one of the commenters:
Missed the point?? Developers are problem-solvers - OF COURSE we're going to try to code a solution! :-)
I love puzzles. So I tried coding it without looking up anything, then compiling to see if it worked. I first used a switch/case statement, so that if a number was both a multiple of 3 and 5, it would fall through both and output "FizzBuzz" without needing a separate case to handle both, something like this:

switch (i)
{
    case i % 3 == 0:
        Console.WriteLine("Fizz");
    case i % 5 == 0:
        Console.WriteLine("Buzz");
    default:
        Console.WriteLine(i);
}

Whoops. C# only allows constants in switch/case statements, and it doesn't support break fall-throughs, either (need to use "goto"!). So I tried to mimic it with regular if/then statements. But at the same time, I also had the idea to make it a method, so I ended up with this:

using System;
using System.Collections;
using System.Text;

namespace FizzBuzz
{
    class Program
    {
        static void Main(string[] args)
        {
            foreach (string i in fizzBuzz())
            {
                Console.WriteLine(i);
            }

            Console.ReadLine();
        }

        private static IEnumerable fizzBuzz()
        {
            bool isReplaced = false;

            for (int i = 1; i < 101; i++)
            {
                if (i % 3 == 0)
                {
                    yield return "Fizz";
                    isReplaced = true;
                }

                if (i % 5 == 0)
                {
                    yield return "Buzz";
                    isReplaced = true;
                }

                if (!isReplaced)
                {
                    yield return i.ToString();
                }

                isReplaced = false;
            }
        }
    }
}
This works, but for numbers like 15, it outputs Fizz and Buzz on two separate lines. It would be better off combining the 3 and 5 multiple case first, and having one if/else statement.

By the way, this doesn't loop twice - it starts the loop in main, goes into the fizzBuzz method, runs the logic until it gets to a "yield" statement, then finishes the loop in main, then runs the next iteration of the loop. It then picks up where it left off in the fizzBuzz method. This approach would let you format each string iteration differently if you wanted to (i.e. having the word "Fizz" output in green).

So my next thought was to compare my solution to others. I found this, which has a number of solutions in many different languages (none use the enumerable interface idea).

The Articulating Ideas blog has a really interesting post on efficient ways to solve the problem using C# - the bitwise operator one is very interesting (and a bit beyond my current coding skills):

string[] messages = new string[]{null, "Fizz", "Buzz", "FizzBuzz"};
int acc = 810092048; //11 00 00 01 00 10 01 00 00 01 10 00 01 00 00
int c = 0;
for (int i=1; i < = N; ++i)  {
    c = acc & 3;
    result += (c > 0 ? messages[c] : i.ToString()) + ", ";
    acc = acc >> 2 | c < < 28;
}


I'm surprised that this solution wasn't the clear winner (it tied another very slick version that doesn't use modulo, and was only a little faster than another using modulo). Division is usually the most expensive math operation, and shifting bits lets you get around that very cleverly (if you are clever enough to know how to use it...).

It really is true that 100 different programmers will come up with 100 different solutions to the same problem.

Saturday, February 4, 2012

C# "??" operator

I just ran across something I hadn't seen before - a two question mark operator. I found it in the AccountMembership service method in the default AccountModel.cs file that's used when you start a new ASP.NET MVC 3 project. Here's the line of code:
_provider = provider ?? Membership.Provider;
I did a little research and found it's just a shortcut for this, using an iif/conditional:
_provider = provider != null ? provider : Membership.Provider;
which of course is a shortcut for this regular if statement:
if(provider != null) {
     _provider = provider;
} else {
     _provider = Membership.Provider;
}

More info here: http://msdn.microsoft.com/en-us/library/ms173224.aspx
Very cool. I love the terseness of C#.

Thursday, October 13, 2011

Not happy with .NET's FileSystemWatcher

I created a Windows Service to watch for a specific file, which heavily relies on the FileSystemWatcher class. I'm not sure it was worth the hassle over using Timer to just check for the file at a certain interval.

FileSystemWatcher fires an event when a file is created, which is great, except that it seems that it fires the millisecond the file starts to be created (acting more like a "Creating" event...). This was causing problems for me, because my relatively small file was apparently still being written to while I was trying to send it as an attachment and subsequently delete it. There is no "ReallyDoneBeingCreated" event. There is a "Change" event, but that was causing me even more problems.

I ended up adding "Thread.Sleep(30000)" (waits for 30 seconds) after it sees there is a new file. This is crap. I HATE doing stuff like this, but it works, since it takes about a second to create the file in my case. The only other thing I could think of doing is having some crazy recursive try/catch loop that fails, tries again and again until it succeeds. This is ugly, too, but would probably be better if the file size was unknown.

My kludge is upsetting me to the point that I may just end up re-writing the code to use a timer interval to check for a new file, but that is a bit backwards,  too. Can't win. Anybody know of a better way of doing this?

Friday, September 9, 2011

Converting a QuickTime .mov (ProRes codec) to a Windows AVI

On the phone last month to our video production agency, I told them I could work with any video format. Yesterday I was afraid they had proved me wrong.

They sent me a QuickTime .mov encoded with the ProRes codec. This was their source format, and the goal was to ensure no loss of quality on their side, so this wasn't just some crazy attempt on their part to trip me up :-). In any case, I figured any standard video converter (like AVC) could handle this, but nothing I tried worked. I then remembered the amazing FFMPEG from my DVR-building days, and was sure this could easily do the conversion if I could just figure out the correct command-line args. Still no luck. I kept getting the error, "swScalar: Unknown format is not supported as input pixel format". Some searching provided some clues that this was due to mapping, so based on a forum post suggestion, I tried adding the flags, "-map 0:0 -map 0:1". I then got a "codec type mismatch error". I installed the ProRes QuickTime decoder, but this didn't help either.

Finally, I happened upon the following solution:

- install AviSynth (http://avisynth.org/mediawiki/Main_Page)
- add the QTSource dll to AviSynths "plugins" directory (http://www.tateu.net/software/dl.php?f=QTSource)
- install VirtualDub (http://www.virtualdub.org/)

Then you just need to write an AviSynth script in the same directory as the video file and name it with an ".avs" extension:
QTInput("C:\test.mov", audio=1)
BicubicResize(720,486,0.1,1.00).AssumeFPS(29.97)

(BTW, the documentation for QTSource says to use audio=true, but AviSynth was having none of that.)

- open the .avs file as if it was a video in VirtualDub
- save as .avi

Whew. I was about five minutes away from admitting defeat and asking them for a different format. Aside from bruising my ego a bit, this would have wasted at least another day or two that I didn't have to spare.