Just to pass time… One way to approach a simple C# programming assessment

I posted this on my other blog earlier, so excuse the first couple of paragraphs that have nothing to do with this blog…

Why must it be so heart-breaking to drop a child at crèche? She’s happy and chatters all the way in the car, but as soon as she has to part from my arms, you’d swear her little world is over! Otherwise she is a happy little devil… she’ll be one year old on May 20th, and yesterday she walked halfway across the lounge, though she is still unsteady on her feet and prefers to crawl. She’s also learned to say her name, sort-of, which came out first as “Udder Udder Udder”, but after a bit of reinforcement and encouragement, it now sounds closer to “Aishah Aishah Aishah” and she does know that she is saying her name.

Although I still don’t have feedback from last week’s assessment, I aced yesterday’s one. I hope they give me feedback by this afternoon, and either make an offer or line up an interview. This one was at least more to my liking, as it was a pure programming assessment, consisting of four programming tasks, where each took only a few minutes to complete. Too bad I did it at home, which meant I left the solution open for hours and only got to it now and then… If I’d done this one in their office, they’d have been impressed by my finishing it in less than half an hour.

So just to pass the time, I’ll share my answers to it, in case anyone who reads this gets something similar… (I’ll paraphrase what I remember of the questions, rather than copying and pasting them here.)

Question 1: Create a Customer class, with properties Id (int), Name (string) and RegistrationNo (string). Populate a collection containing 300 000 customers, and then find the customer in the collection with Id equal to 251887.

This is very simple, and any c# programmer who can’t do this is in the wrong line of work. For this question I wrote a simple Customer class, and did the work in a console application. Here’s the customer class:

namespace Question1
{
    public class Customer
    {
        public int Id { get; set; }

        public string Name { get; set; }

        public string RegistrationNo { get; set; }

        public Customer(int id)
        {
            this.Id = id;
            this.Name = string.Format("Customer {0}", id);
            this.RegistrationNo = id.GetHashCode().ToString();
        }
    }
}

And here’s the code for the console application that uses it:

using System;
using System.Collections.Generic;
using System.Linq;

namespace Question1
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Customer> customers = new List<Customer>();

            for (int i = 0; i < 300000; i++)
            {
                customers.Add(new Customer(i + 1));
            }

            var customer = customers.FirstOrDefault(c => c.Id == 251887);
            Console.WriteLine(customer.Id);
            Console.ReadLine();
        }
    }
}

Question 2: Create a class called SampleProcess, which exposes a method called Process. The method must implement a loop which counts from 1 to 10 000, which is consumed by a user interface. The method must provide status to the user interface in each loop iteration. (They could have made this question more interesting by stipulating that the process should be cancelled at any time, but they did not.)

I decided to do this one in Windows Forms, since it is really easy to use the Task-based Asynchronous Pattern (TAP) in that framework, which allows the process to happen in a separate thread seamlessly, such that you can move the form around, minimize it and so on while the task is run. If you use the old way, e.g. a BackgroundWorker, or hand-code a thread, or even use the thread pool, there is a fair amount more work to be done, whereas this way is as easy as just writing sing-threaded code, with a couple of keywords so the compiler does the magic for you. Only problem… I have not met anyone else here in Johannesburg who uses the .Net4.5 async code yet, or even knows what it is.

Since this is Windows Forms, I decided to use an event. That is, the class exposes an event which, if subscribed to by the user interface code, is triggered in each loop iteration, and passes to the event subscriber the status as an integer.

Thus it needs a simple event handler with a single property, being the status integer:

using System;

namespace Question2
{
    public class ProcessEventArgs : EventArgs
    {
        public int Status { get; private set; }

        public ProcessEventArgs(int status)
        {
            this.Status = status;
        }
    }
}

Then it needs the class they asked for, which exposes an event as well as the method asked for, and just raises the event in each loop iteration:

using System;
using System.Threading.Tasks;

namespace Question2
{
    public class SampleProcess
    {
        public event EventHandler<ProcessEventArgs> Status;

        protected virtual void OnStatus(ProcessEventArgs e)
        {
            var status = Status;

            if (status != null)
                status(this, e);
        }

        public async Task Process()
        {
            for (int i = 1; i <= 10000; i++)
            {
                OnStatus(new ProcessEventArgs(i));

                /* Simulate doing something for one second, asynchronously 
                 * because there is no need for the thread to sleep.*/
                await Task.Delay(1000);
            }

            await Task.FromResult(true);
        }
    }
}

Then the form contains a single button and a label. The button click event handler is an async method, which creates the sample process class, assigns an event handler (that just sets the label’s text to the event’s status integer), waits for the “process” asynchronously, then removes the event handler:

using System;
using System.Windows.Forms;

namespace Question2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private async void processButton_Click(object sender, EventArgs e)
        {
            SampleProcess sampleProcess = new SampleProcess();
            sampleProcess.Status += sampleProcess_Status;

            try
            {
                /* I made the Process method async to wait for it asynchronously. 
                 * If it was async void we would remove the event handler immediately 
                 * and only get the first event. */
                await sampleProcess.Process();
            }
            finally
            {
                sampleProcess.Status -= sampleProcess_Status;
            }
        }

        void sampleProcess_Status(object sender, ProcessEventArgs e)
        {
            statusLabel.Text = e.Status.ToString();
        }
    }
}

It looks like this:

Question2

Question 3: We have various types that need to be serialized to JSON. Create a generic base class, called SerializeBase, which exposes the Serialize and Deserialize methods. Then create two derived subclasses, instantiate them, and demonstrate how they each serialize and deserialize a type.

This question was unfortunately somewhat ambiguous… There are standard ways of doing serialization in .Net, and I gather they are not asking about those. I figured they just want to know that the programmer knows what inheritance is. The way they used the word ‘generic’ also made it unclear whether they just want a reusable base class, which is what inheritance is, or whether they actually want to know that I know how to write a class that uses the .Net Generic pattern. Thus I decided to do both.

There’s a mistake in this class below… Well, not really a mistake, but something I should have done better. Can you see it? I’ll write it in the comments.

There is already a JavaScript serializer built into the framework, and all you need to do to use it is add a reference to System.Web.Extensions. Having done that, here’s the base class:

using System.Web.Script.Serialization;

namespace Question3
{
    public class SerializeBase<T>
    {
        public virtual string Serialize(object obj)
        {
            return new JavaScriptSerializer().Serialize(obj);
        }

        public virtual dynamic Deserialize(string json)
        {
            return new JavaScriptSerializer().Deserialize<T>(json);
        }
    }
}

Next, my subclasses need to do the serialization of the type that is called T in the base class, but will be defined as some class type in the two subclasses. Since I already wrote a class called Customer in Question 1, I’ll reuse that one, and just define a second class, which for want of a better name, I shall call SomethingElse. Here are my two classes (Customer is defined again in this namespace, because I copied it in here so that I don’t have to reference the other project, which in my solution is a separate project in the same solution.)

(For the deserialization to work, I also had to add a parameterless constructor to the Customer class.)

namespace Question3
{
    public class Customer
    {
        public int Id { get; set; }

        public string Name { get; set; }

        public string RegistrationNo { get; set; }

        public Customer() { }

        public Customer(int id)
        {
            this.Id = id;
            this.Name = string.Format("Customer {0}", id);
            this.RegistrationNo = id.GetHashCode().ToString();
        }
    }

    public class SomethingElse
    {
        public int Id { get; set; }

        public string Thing { get; set; }
    }
}

Now I need two classes to derive from my simple base class, one to do Customer, and one to do SomethingElse: (And they have of course inherited the mistake I made in the base class, although they do work.)

using System;

namespace Question3
{
    public class CustomerSerialiser : SerializeBase<Customer>
    {
        public override dynamic Deserialize(string json)
        {
            if (json == null)
                throw new ArgumentNullException("json");

            if (json.GetType() != typeof(string))
                throw new ArgumentException("json must be a string.");

            var deserialized = base.Deserialize(json);

            if (deserialized.GetType() != typeof(Customer))
                throw new InvalidCastException("Object is not a customer.");

            return deserialized;
        }

        public override string Serialize(object obj)
        {
            if (obj == null)
                throw new ArgumentNullException("obj");

            if (obj.GetType() != typeof(Customer))
                throw new ArgumentException("Object is not a customer.");

            return base.Serialize(obj);
        }
    }

    public class SomethingElseSerialiser : SerializeBase<SomethingElse>
    {
        public override dynamic Deserialize(string json)
        {
            if (json == null)
                throw new ArgumentNullException("json");

            if (json.GetType() != typeof(string))
                throw new ArgumentException("json must be a string.");

            var deserialized = base.Deserialize(json);

            if (deserialized.GetType() != typeof(SomethingElse))
                throw new InvalidCastException("Object is not a SomethingElse.");

            return deserialized;
        }

        public override string Serialize(object obj)
        {
            if (obj == null)
                throw new ArgumentNullException("obj");

            if (obj.GetType() != typeof(SomethingElse))
                throw new ArgumentException("Object is not a SomethingElse.");

            return base.Serialize(obj);
        }
    }

}

Lastly for this one, I wrote a console app to instantiate the two classes, then demonstrate serializing and deserializing them.

using System;

namespace Question3
{
    class Program
    {
        static void Main(string[] args)
        {
            Customer customer = new Customer(666);
            SomethingElse somethingElse = new SomethingElse { Id = 7, Thing = "day" };

            CustomerSerialiser serializer1 = new CustomerSerialiser();
            var serializedCustomer = serializer1.Serialize(customer);
            Console.WriteLine(serializedCustomer);

            Console.WriteLine();
            SomethingElseSerialiser serializer2 = new SomethingElseSerialiser();
            var serializedSomethingElse = serializer2.Serialize(somethingElse);
            Console.WriteLine(serializedSomethingElse);

            var customer2 = serializer1.Deserialize(serializedCustomer);
            var anotherThing = serializer2.Deserialize(serializedSomethingElse);

            Console.ReadLine();
        }
    }
}

Question 4: Write a function that finds all the multiples of 3 or 5 that are below 1000, and calculates the sum of all the values.

This one is too easy and I don’t see why they made the last one so easy. Normally the last one would be challenging, but not here. Thus I wrote a method that can take any number of integer parameters, using the params keyword, and calculate their sum below a given value, which I also passed as a parameter.

I assume that the question relies on the fact that idiots don’t know that to find if any number is divisible exactly by a value (and is thus a multiple of that value), the modulus of the value will be zero. Since I’m not an idiot, I answered this question without even needing to think about it.

using System;
using System.Collections.Generic;
using System.Linq;

namespace Question4
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(GetSum(1000, 3, 5));
            Console.ReadLine();
        }

        private static int GetSum(int threshHold, params int[] values)
        {
            var list = new List<int>();

            for (int i = 1; i < threshHold; i++)
            {
                foreach (var value in values)
                {
                    if (i % value == 0 && !list.Contains(i))
                        list.Add(i);
                }
            }

            return list.Sum();
        }
    }
}
Advertisements

About Jerome

I am a senior C# developer in Johannesburg, South Africa. I am also a recovering addict, who spent nearly eight years using methamphetamine. I write on my recovery blog about my lessons learned and sometimes give advice to others who have made similar mistakes, often from my viewpoint as an atheist, and I also write some C# programming articles on my programming blog.
This entry was posted in Family, Programming and tagged , . Bookmark the permalink.

3 Responses to Just to pass time… One way to approach a simple C# programming assessment

  1. Jerome says:

    The mistake in question 3 is a result of my initial code not being a generic class… I only changed it to a generic class when coding the subclasses.

    Since it was not generic, I did not know the type of the return value for the Deserialize method, and thus declared it as dynamic. I should have declared it as T.

    Like

  2. Arnold says:

    With a slight loss of generality (limiting the number of parameters to 2) for Question 4 you could also have done:

    int GetSum(int threshHold, int value1, int value2)
    {
    int iN1 = (threshHold – 1) / value1;
    int iN2 = (threshHold – 1) / value2;
    int iN3 = (threshHold – 1) / (value1 * value2);

    int iSum = (value1 * iN1 * (iN1 + 1) + value2 * iN2 * (iN2 + 1) – value1 * value2 * iN3 * (iN3 + 1)) / 2;
    return(iSum);
    }

    This has only 8 additions/subtractions and 11 multiplications/divisions, as compared to 2000 divisions and 2000 additions for threshHold = 1000.

    I’m sure my effort can be generalized to more than 2 parameters, but I’ll leave that as an exercise to the reader.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s