A Modern Take, The LINQ Answer

How Can Testing Be Bad?

An imaginary programming test question
This is very interesting answer because it suggests that the question itself is deeply flawed and says more about the limits of the person setting the question than the answer says about the candidate.

This answer suggests a candidate used to using the latest language features in an environment that encourages this.

The problem is that the question requires the use of what this candidate could probably see as obsolete technology and he has been forced to bodge an answer together.

I don't like this answer because it panders to my prejudices about how things are being over complicated for the sake of convenience, reusability and productivity resulting in an unmaintainable mess.

The "Modern Answer"

An answer from someone who is used to LINQ being forced to answer a question that doesn't reflect their background, this tells the test setter nothing.
LINQ is part of the VB and C# .Net languages and its use splits programmers, some like it and some hate it. Of course the reality is that LINQ is neither brilliant or evil but is a good or bad tool depending upon what you want to do.

Unfortunately all to often a culture develops within an IT department where LINQ is always used or never used so a LINQ based answer to this test leaves a lot of questions.

In this example people who use LINQ would probably approach the problem in a slightly different way and not use a DataTable at all, but the question said that a DataTable was wanted so we end up with a bit of a mish-mash of technologies.

I would go as far as saying that for anyone who answered the question this way the question was an inappropriate test. It was testing something that they don't normally use and is a reflection of the lack of experience of the person setting the test not to realise this.

Answer C#

    [Table(Name = "StockTickers")]
    public class StockTicker 
    {
        [Column] public Int32 pk_StockTickers { get; set; }
        [Column] public DateTime DateCreated { get; set; }
        [Column] public DateTime DateLastModified { get; set; }
        [Column] public String Company { get; set; }
        [Column] public String CompanyTicker { get; set; }
        [Column] public String Keypoints { get; set; }
        [Column] public String SharePriceCat { get; set; }
        [Column] public Decimal? MinPrice { get; set; }
        [Column] public Decimal? MaxPrice { get; set; }
        [Column] public Decimal? LastReviewPrice { get; set; }
        [Column] public DateTime? LastReviewDate { get; set; }
        [Column] public String ShareIndex { get; set; }
        [Column] public Double? Ratio { get; set; }
        [Column] public Decimal? HighestEver { get; set; }
        [Column] public String MarketSector { get; set; }
        [Column] public DateTime? UninterestedUntil { get; set; }
        [Column] public Boolean FavouredStock { get; set; }
        [Column] public Boolean DoNotCollectCurrentPrice { get; set; }
        [Column] public Decimal? MarketCap { get; set; }
        [Column] public DateTime? TodaysShare { get; set; }
        [Column] public DateTime? Prev1Date { get; set; }
        [Column] public Decimal? Prev1Value { get; set; }
        [Column] public DateTime? Prev2Date { get; set; }
        [Column] public Decimal? Prev2Value { get; set; }
        [Column] public DateTime? Prev3Date { get; set; }
        [Column] public Decimal? Prev3Value { get; set; }
        [Column] public DateTime? Prev4Date { get; set; }
        [Column] public Decimal? Prev4Value { get; set; }
        [Column] public DateTime? Prev5Date { get; set; }
        [Column] public Decimal? Prev5Value { get; set; }
        [Column] public DateTime? Prev6Date { get; set; }
        [Column] public Decimal? Prev6Value { get; set; }
        [Column] public DateTime? LastReviewDateDateOnly { get; set; }
        [Column] public String CurrencySymbol { get; set; }
    }
    public partial class StockTickersDatabase : DataContext
    {
        public Table<StockTicker> StockTickers;
        public StockTickersDatabase(String connectionString) : base(connectionString) { }
    }
    protected Boolean LoadDataAnswer3(String connectionStringLocal, DataTable interesting)
    {
        Boolean funcRes = false;
        DataRow newRow;
        try
        {
            StockTickersDatabase Database = new StockTickersDatabase(connectionStringLocal);

            var dbQuery = 
                 from Company in Database.StockTickers.AsEnumerable()
                 where Company.ShareIndex == "FTSE 100"
                 select Company;

            interesting = new DataTable();
            interesting.Columns.Add("Company", typeof(String));
            interesting.Columns.Add("CompanyTicker", typeof(String));
            interesting.Columns.Add("Keypoints", typeof(String));
            interesting.Columns.Add("SharePriceCat", typeof(String));
            interesting.Columns.Add("MinPrice", typeof(Double));
            interesting.Columns.Add("MaxPrice", typeof(Double));
            interesting.Columns.Add("LastReviewPrice", typeof(Double));
            interesting.Columns.Add("LastReviewDate", typeof(DateTime));
            interesting.Columns.Add("ShareIndex", typeof(String));

            foreach (var company in dbQuery)
            {
                newRow = interesting.NewRow();
                newRow["Company"] = company.Company;
                newRow["CompanyTicker"] = company.CompanyTicker;
                newRow["Keypoints"] = company.Keypoints;
                newRow["SharePriceCat"] = company.SharePriceCat;
                newRow["MinPrice"] = company.MinPrice;
                newRow["MaxPrice"] = company.MaxPrice;
                newRow["LastReviewPrice"] = company.LastReviewPrice;
                newRow["LastReviewDate"] = company.LastReviewDate;
                newRow["ShareIndex"] = company.ShareIndex;
                interesting.Rows.Add(newRow);
            }

            funcRes = true;
        }
        catch (Exception ex)
        {
            HandleErrorMessage(ex.Message);
        }
        return funcRes;
    }
There are better ways of doing the above but they are probably too time consuming when someone is sitting a test.

In practice any environment that uses LINQ and DataTables would likley have a generic solution to the problem of populating the DataTable from the LINQ query, so I would expect a slightly messy answer.

Answer SQL

Candidate's point of view - It's only a test so if in the real world I would need a stored proc or whatever the company policy is then that's fine, it's just a slightly different LINQ query.


Other Interesting Pages On Some Of My Sites.
Buy A Ghost
Picture of a cat with yellow star Buy A Ghost is a light hearted source of one page ghost stories aimed at pubs and restaurants as talking points.

Print them off and put them on the tables or walls and you have an instant talking point.

Aimed at regulars who have run out of things to say or new groups or couples as an ice-breaker.
Weight Loss Calculator
Screen shot of weight loss calculator Weight Loss Calculator Tries to simulate the body and report the effects of food and exercise in periods as short as 15 minutes.

This level of detail highlights the effects of a run, bike ride or chocolate bar.

For those who are new to exercise, weight fluctuation due to glycogen usage is made much clearer.
Initial Programming Language
IPL Screen shot Initial Programming Language possibly the easiest way to learn programming on a Windows computer.

Designed to mimic the simplicity of the 1980s home computers where you could get started in minutes...

...but still powerful enough to do pretty complex things.
Please note that these links do not use any tracking cookies or similar technology.