Please navigate to the bottom of the page for Table of Contents
Showing posts with label code. Show all posts
Showing posts with label code. Show all posts

Monday, October 14, 2013

Linked List create, insert, sort, min, max, find and print complete program

I have been asked a few times to provide a complete working example of different operations on Linked List.

This post is an attempt to do just that.

#include <stdio.h>
#include <stdlib.h> // for malloc

// define your linked list struct
// make sure to typedef to give better name
typedef struct ll
{
int data;
struct ll *next;
} LinkedListNode;


// remember to declare functions that will be used in main but defined after it
LinkedListNode* AddElementsToBeginningOfList(int inputSize, int input[], LinkedListNode *head);
LinkedListNode* AddElementsToEndOfList(int inputSize, int input[], LinkedListNode *head);

LinkedListNode* InsertElementAtBeginning(int input, LinkedListNode *head);
LinkedListNode* InsertElementAtEnd(int input, LinkedListNode *head);

void Sort(LinkedListNode *head);
LinkedListNode* Find(int value, LinkedListNode *head);
void MaxMinInList(int *max, int *min, LinkedListNode *head);

void PrintLinkedList(char* name, LinkedListNode *node);

int main(int argc, char* argv[])
{
// define head node
LinkedListNode* head = NULL;
LinkedListNode* inOrderList = NULL;
int max = 0, min = 0;
LinkedListNode* ele = NULL;

// de fine array
int input[] = { 43, 22, 11, 4, 22, 56, 47, 21, 78, 99, 97 };

// find the array length in C
int inputSize = sizeof(input) / sizeof(input[0]);

// add elements to the beginning of the list
head = AddElementsToBeginningOfList(inputSize, input, head);

// Print list
PrintLinkedList("AddElementsToBeginningOfList", head);

// add elements to the end of the list
inOrderList = AddElementsToEndOfList(inputSize, input, inOrderList);

// Print list
PrintLinkedList("AddElementsToEndOfList", inOrderList);

// insert a single element at beginning
inOrderList = InsertElementAtBeginning(100, inOrderList);

// Print list
PrintLinkedList("InsertElementAtBeginning", inOrderList);

// insert a single element at end
inOrderList = InsertElementAtEnd(200, inOrderList);

// Print list
PrintLinkedList("InsertElementAtEnd", inOrderList);

// Search for an element
ele = Find(56, inOrderList);

if (ele != NULL) {
printf("\r\nElement found: %d", ele->data);
}

// Find max and min in the list
MaxMinInList(&max, &min, inOrderList);

printf("\r\nMax: %d, Min: %d", max, min);

// sort the list
Sort(inOrderList);

// Print list
PrintLinkedList("Sorted list", inOrderList);

return 0;
}

LinkedListNode* AddElementsToBeginningOfList(int inputSize, int input[], LinkedListNode *head)
{
// define loop variable
int i = 0;

// add elements to the linked list
for (i = 0; i < inputSize; i++)
{
// create a temp node
LinkedListNode *temp = (LinkedListNode *)malloc(sizeof(LinkedListNode));
temp->data = input[i];

// add to the beginning of the list
// make this new node point to the current beginning of the list
temp->next = head;
// NOW set the head of the list to this new node
head = temp;
}

return head;
}

LinkedListNode* AddElementsToEndOfList(int inputSize, int input[], LinkedListNode *head)
{
// define loop variable
int i = 0;

// define the end of the list
// here is where new elements will be inserted
LinkedListNode* end = NULL;

// add elements to the linked list
for (i = 0; i < inputSize; i++)
{
// create a temp node
LinkedListNode *temp = (LinkedListNode *)malloc(sizeof(LinkedListNode));
temp->data = input[i];
// make sure to null the pointer to the last element
temp->next = NULL;

// if this is the first element, make head point to it
if (i == 0) {
head = temp;
}
else {
// add to the end of the list
end->next = temp;
}

// NOW set the end of the list to this new node
end = temp;
}

return head;

}

LinkedListNode* InsertElementAtBeginning(int input, LinkedListNode *head)
{
// create a temp node
LinkedListNode *temp = (LinkedListNode *)malloc(sizeof(LinkedListNode));
temp->data = input;

// add to the beginning of the list
// make this new node point to the current beginning of the list
temp->next = head;
// NOW set the head of the list to this new node
head = temp;

return head;
}

LinkedListNode* InsertElementAtEnd(int input, LinkedListNode *head)
{
LinkedListNode* curr = head;

// create a temp node
LinkedListNode *temp = (LinkedListNode *)malloc(sizeof(LinkedListNode));
temp->data = input;
temp->next = NULL;


while (curr->next != NULL)
curr = curr->next;

// add it as the last node
curr->next = temp;

return head;
}

void Sort(LinkedListNode *head)
{
LinkedListNode *list = NULL;
LinkedListNode *pass = NULL;

// traverse the entire list
for (list = head; list->next != NULL; list = list->next)
{
// compare to the list ahead
for (pass = list->next; pass != NULL; pass = pass->next)
{
// compare and swap
if (list->data > pass->data)
{
// swap
int temp = list->data;
list->data = pass->data;
pass->data = temp;
}
}
}
}

// finds the first node with the specified value
LinkedListNode* Find(int value, LinkedListNode *head)
{
// start at the root
LinkedListNode *currentNode = head;

// loop through the entire list
while (currentNode != NULL)
{
// if we have a match
if (currentNode->data == value)
return currentNode;
else // move to the next element
currentNode = currentNode->next;
}
}

// finds the maximum and minimum in the list
void MaxMinInList(int *max, int *min, LinkedListNode *head)
{
// start at the root
LinkedListNode *curr = head;

if (curr == NULL)
return 0; // list is empty

// initialize the max and min values to the first node
*max = *min = curr->data;

// loop through the list
for (curr = curr->next; curr != NULL; curr = curr->next)
{
if (curr->data > *max)
*max = curr->data;
else if (curr->data < *min)
*min = curr->data;
}
}

// print the list
void PrintLinkedList(char* name, LinkedListNode *node)
{
printf("\r\nName: %s", name);
printf("\r\n HEAD");

// loop while we have data
while (node != NULL)
{
printf(" -> %d", node->data);
// move to next node
node = node->next;
}
}

Friday, April 19, 2013

LINQ design interview question

LINQ is one of my favorite interview topics for many reasons. It allows me to check a candidate's ability to define logic, use SQL skills, showcase lambda expressions, distill the problem into easy steps and of course, see some code in action. Also, since LINQ code is generally quite compact, it is perfect for white boarding.

I was recently helping a friend solve a problem and felt that it could be modified to an excellent interview question. It has a bit of algorithm design, heavy use of simple to medium complex LINQ and is not more that 10-15 lines of actual code. Perfect.

Question: Given a class of students  (ID, Name, Grades) with results for at least 2 semesters, find the students whose Grades have significantly improved in the second semester as compared to the first. Bonus: List out top 25% of the students.

As the first step, let us define the rough algorithm for solving this problem:

  1. Load Student data for first semester
  2. Load student data for second semester
  3. Merge Grades for each student from second semester into the first semester result set
  4. For each student, calculate the grade difference for students whose grades have improved (you do not want to waste computational cycles for students whose grades have fallen)
  5. For each student from 4 above, calculate the grade improvement percent
  6. Sort the result by descending order of grade improvement percent
  7. Select rows that constitute top 25% of students

Now, let’s define our POCO class that will represent the student data structure. The data structure has two parts: basic student properties (Id, Name, Grade) and some computational properties that we will use to solve our algorithm.

    public class StudentRecord
{
// basic properties
public int Id { get; set; }
public string Name { get; set; }
public double Grade { get; set; }

// computational properties
public double GradeSecondSemester { get; set; }
public double GradeDifference { get; set; }
public double GradeDifferencePercent { get; set; }
}

In addition to a Student record, we also need to a collection to hold these records. Let’s call it ClassReport:

    public class ClassReport
{
// some basic properties of a class
public int Id { get; set; }
public string Name { get; set; }
public int SemesterId { get; set; }

// list of student records for that semester
public List<StudentRecord> Students;

public ClassReport()
{
Students =
new List<StudentRecord>();
}
}

For steps 1 and 2 of the algorithm, I am not going to focus on this blog. We will assume that we have a way to load this data (stubbed in our code sample below).


Step 1 and 2: Load Student data:


We will mock up our student data in this example. In real life, this data probably will come from a database or a web service call, etc. As you can see below, we generate some dummy student data for two different semesters. Note that the student Id’s need to match across (not really a hard requirement, but good to have for our demo purposes).

        static void Main(string[] args)
{
// Step 1 and 2: Load Student data
ClassReport cr1 = MockSem1();
ClassReport cr2 = MockSem2();

}

private static ClassReport MockSem1()
{
ClassReport cr = new ClassReport()
{
Id = 1,
Name =
"First Grade",
SemesterId = 1
};

// add dummy data - in real life, this comes from database
cr.Students.Add(
new StudentRecord()
{
Id = 1,
Name =
"Ray",
Grade = 90
});
cr.Students.Add(
new StudentRecord()
{
Id = 2,
Name =
"Jack",
Grade = 80
});
cr.Students.Add(
new StudentRecord()
{
Id = 3,
Name =
"John",
Grade = 60
});
cr.Students.Add(
new StudentRecord()
{
Id = 4,
Name =
"Lisa",
Grade = 67
});
cr.Students.Add(
new StudentRecord()
{
Id = 5,
Name =
"Jill",
Grade = 94
});
return cr;
}

private static ClassReport MockSem2()
{
ClassReport cr = new ClassReport()
{
Id = 1,
Name =
"First Grade",
SemesterId = 2
};

// add dummy data - in real life, this comes from database
cr.Students.Add(
new StudentRecord()
{
Id = 1,
Name =
"Ray",
Grade = 85
});
cr.Students.Add(
new StudentRecord()
{
Id = 2,
Name =
"Jack",
Grade = 95
});
cr.Students.Add(
new StudentRecord()
{
Id = 3,
Name =
"John",
Grade = 82
});
cr.Students.Add(
new StudentRecord()
{
Id = 4,
Name =
"Lisa",
Grade = 95
});
cr.Students.Add(
new StudentRecord()
{
Id = 5,
Name =
"Jill",
Grade = 96
});
return cr;
}

Step 3: Merge Grades for each student from second semester into the first semester result set


Here is where our LINQ fun starts. In one of my previous post, I had explained how LINQ join works. Now would be a good time to review bunch of LINQ related interview questions and answers from the past.

            // step 3: Merge Grades for each student from second 
// semester into the first semester result set

// in-line merge; no need for a separate assignment
// for each student in first semester report
(from firstSem in cr1.Students
// join to second sem class report
join secondSem in cr2.Students
// on student id as the key
on firstSem.Id equals secondSem.Id
// assign second sem grade to first (via a select; clever)
select firstSem.GradeSecondSemester = secondSem.Grade)
// execute
.ToList();
As you can see from the LINQ statement, we join first semester class report with second semester and then do an in-line update of the first semester data structure’s GradeSecondSemester property.

Step 4: Calculate grade difference for students whose grades have improved


Now we need to process those students whose grades improved in the 2nd semester and update our data structure to reflect the difference:

// step 4: For each student, calculate the grade difference 
// for students whose grades have improved (you do not want
// to waste computational cycles for students whose grades have fallen)
cr1.Students
// find all students who did better in 2nd semester
.FindAll(s => ((s.GradeSecondSemester - s.Grade) > 0))
// and update their grade difference property
.ForEach(x => x.GradeDifference = (x.GradeSecondSemester - x.Grade));

We use FindAll to find those students who have better grades and then loop for those records using ForEach to update the GradeDifference property.


Step 5: For each student from 4 above, calculate the grade improvement percent

// Step 5: For each student from 4 above, 
// calculate the grade improvement percent

// 5.a. calculate total difference sum
double gradeDiffSum = cr1.Students.Sum(x => x.GradeDifference);

// 5.b. calculate percent for each row
cr1.Students
// find all students who did better in 2nd semester
.FindAll(s => ((s.GradeSecondSemester - s.Grade) > 0))
// update grade percent
.ForEach(x => x.GradeDifferencePercent =
((x.GradeDifference * 100) / gradeDiffSum));

Step 6: Sort the result by descending order of grade improvement percent


By this point, I am hoping you get the gist of how to approach such LINQ queries. Sorting a list is a relatively simple operation as shown below:

    // Step 6: Sort the result by descending order of grade improvement percent
var sortedList =
(
from entry in cr1.Students
orderby entry.GradeDifferencePercent descending
select
entry)
.ToList();
Step 7: Select rows that constitute top 25% of students

We use TakeWhile here to keep selecting students till we reach our number.

    //Step 7: Select rows that constitute top 25% of students
// 7.a. - sum of grade diff percent
double gradeDiffPercentSum = 0;

// 7.b - take as many rows as needed till we reach the 25% sum
var bestStudents =
sortedList
.TakeWhile(x =>
((gradeDiffPercentSum += x.GradeDifferencePercent) <= 25.0))
.ToList();

// 7.c account for the case where the first element is more than 25
if (bestStudents.Count() == 0)
bestStudents = sortedList.Take(1).ToList();
That’s it. You now have a list of top 25% students whose grades have improved in the second semester.

I am pasting the complete program here in case you like to see the whole thing in one shot.


The complete solution:

using System.Linq;

namespace
StudentReport
{
class
Program
{
static void Main(string
[] args)
{
// Step 1 and 2: Load Student data
ClassReport
cr1 = MockSem1();
ClassReport
cr2 = MockSem2();

// step 3: Merge Grades for each student from second
// semester into the first semester result set

// in-line merge; no need for a separate assignment
// for each student in first sem report
(from firstSem in
cr1.Students
// join to second sem class report
join secondSem in
cr2.Students
// on student id as the key
on firstSem.Id equals
secondSem.Id
// assign second sem grade to first (via a select; clever)
select
firstSem.GradeSecondSemester = secondSem.Grade)
// execute
.ToList();

// step 4: For each student, calculate the grade difference
// for students whose grades have improved (you do not want
// to waste computational cycles for students whose grades have fallen)
cr1.Students
// find all students who did better in 2nd semester
.FindAll(s => ((s.GradeSecondSemester - s.Grade) > 0))
// and update their grade difference property
.ForEach(x => x.GradeDifference = (x.GradeSecondSemester - x.Grade));

// Step 5: For each student from 4 above,
// calculate the grade improvement percent

// 5.a. calculate total difference sum
double
gradeDiffSum = cr1.Students.Sum(x => x.GradeDifference);

// 5.b. calculate percent for each row
cr1.Students
// find all students who did better in 2nd semester
.FindAll(s => ((s.GradeSecondSemester - s.Grade) > 0))
// update grade percent
.ForEach(x => x.GradeDifferencePercent =
((x.GradeDifference * 100) / gradeDiffSum));


// Step 6: Sort the result by descending order of grade improvement percent
var
sortedList =
(
from entry in
cr1.Students
orderby entry.GradeDifferencePercent
descending
select
entry)
.ToList();


//Step 7: Select rows that constitute top 25% of students
// 7.a. - sum of grade diff percent
double
gradeDiffPercentSum = 0;

// 7.b - take as many rows as needed till we reach the 25% sum
var
bestStudents =
sortedList
.TakeWhile(x =>
((gradeDiffPercentSum += x.GradeDifferencePercent) <= 25.0))
.ToList();

// 7.c account for the case where the first element is more than 25
if
(bestStudents.Count() == 0)
bestStudents = sortedList.Take(1).ToList();

// do something with this result set
}

private static ClassReport
MockSem1()
{
ClassReport cr = new ClassReport
()
{
Id = 1,
Name =
"First Grade"
,
SemesterId = 1
};

// add dummy data - in real life, this comes from database
cr.Students.Add(
new StudentRecord
()
{
Id = 1,
Name =
"Ray"
,
Grade = 90
});
cr.Students.Add(
new StudentRecord
()
{
Id = 2,
Name =
"Jack"
,
Grade = 80
});
cr.Students.Add(
new StudentRecord
()
{
Id = 3,
Name =
"John"
,
Grade = 60
});
cr.Students.Add(
new StudentRecord
()
{
Id = 4,
Name =
"Lisa"
,
Grade = 67
});
cr.Students.Add(
new StudentRecord
()
{
Id = 5,
Name =
"Jill"
,
Grade = 94
});
return
cr;
}

private static ClassReport
MockSem2()
{
ClassReport cr = new ClassReport
()
{
Id = 1,
Name =
"First Grade"
,
SemesterId = 2
};

// add dummy data - in real life, this comes from database
cr.Students.Add(
new StudentRecord
()
{
Id = 1,
Name =
"Ray"
,
Grade = 85
});
cr.Students.Add(
new StudentRecord
()
{
Id = 2,
Name =
"Jack"
,
Grade = 85
});
cr.Students.Add(
new StudentRecord
()
{
Id = 3,
Name =
"John"
,
Grade = 70
});
cr.Students.Add(
new StudentRecord
()
{
Id = 4,
Name =
"Lisa"
,
Grade = 82
});
cr.Students.Add(
new StudentRecord
()
{
Id = 5,
Name =
"Jill"
,
Grade = 96
});
return
cr;
}
}
}

Wednesday, March 20, 2013

SQL read text from a file

Consider the following scenario: Your database has a table called Customer (who doesn't these days) with millions of rows (lucky you). You production support team just called you in the middle of the night with a live site issue - Around 10,000 customers are getting a message that their logins have been disabled. And they send you a text file with 10,000 customer id's :-)

Great! Now you need to look these customers up in the database and enable their access again. 

So how can you load these 10K values from a text file into SQL? One way would be to edit the text file, replace each new line with a comma and then use the resulting string in the select clause as shown:

select * from Customer where Id in (1, 2, 6, 8, 10)   

Now this might prove to be too much non-techy way. You are a programmer, right? You don't hard-code stuff! You write code!!

So how can you load these disabled customer list in the database programatically?

Create a temporary table and call it DisabledCustomers with just one column (name it Id and make sure it allows nulls and is not primary key - just in case your list from support has duplicates).  

Run the following SQL to load the values from the file into this table.  
BULK INSERT dbo.DisabledCustomers
   FROM 'c:\temp\customerids.txt'
   WITH
      (
         ROWTERMINATOR ='\n'
      )
 

Now your select statement becomes quite simple: 
select * from Customer c
inner join DisabledCustomers dc on c.Id = dc.Id
 

Many production systems have BULK INSERT disabled? As an exercise to you, my dear reader, I look forward to seeing some innovative solutions to that.

SQL self join or sub-query interview question (employee-manager salary)

One of my favorite interview questions that tips even seasoned SQL guys (maybe because it's too simple) is around querying data that involves a self join.

What is a self join?
A self join is a join in which a table is joined with itself, specially when the table has a foreign  key which references its own primary key. 

Question: Given an Employee table which has 3 fields - Id (Primary key), Salary and Manager Id, where manager id is the id of the employee that manages the current employee, find all employees that make more than their manager in terms of salary. Bonus: Write the table creation script.

Friday, January 11, 2013

Asp.Net MVC interview questions

Asp.Net web UI has come a long way in the last 10 years. Starting for classic ASP world, we are now seeing the evolution of world class product in the form of Asp.Net MVC. Web Forms still work and are great for many specific applications. But MVC is the correct way to go for most internet applications.
In this and future posts, we will go over a few ASP.NET MVC interview questions. Let’s tackle Razor engine in this post.

Question: What is Asp.Net MVC Razor?

Sunday, July 29, 2012

JavaScript functions explained

Functions are the basic building blocks in JavaScript. They can be used everywhere, can be passed as parameters, attached as event handlers, overridden, deleted, etc. Functions can be anonymous or not.

// In the example below, dont forget the semicolon!
// However, its name will not appear in the debugger
var anonymous = function() {
console.log('anonymous function!');
};

// This the classic syntax, without a semicolon at the end!
function nonAnonymous() {
console.log('non anonymous!');
}

// This is similar to the above, but is more
// debugger-friendly, as the name of the function
// will be printed in the debugger.
var nonAnonymous2 = function nonAnonymous2() {
console.log('non anonymous too!');
};

// This is the syntax for adding event handlers in jQuery
$('field').bind('tap',
function(event, data) {
console.log('binding an anonymous function!');
event.preventDefault();
});

How to time any function

One key aspect during performance testing is to time how long a function takes to execute. In this small post, I will show how to create a generic timing function that takes as argument the function to time and shows the time to execute along with the output of the function:

/// <summary>
/// Times the execution of a function and outputs both the elapsed time and the function's result.
/// </summary>
static void Time<T>(Func<T> work)
{
    var sw = Stopwatch.StartNew();
    var result = work();
    Console.WriteLine(sw.Elapsed + ": " + result);
}


To call the time, use the following invocation style:



Time(() => DoSomeWork());

Saturday, July 28, 2012

LINQ interview questions part 3

In this post, we will do a quick review of LINQ operators Any() and All().

Question 1: Using LINQ, determine if any word in a list contains the substring “ei”.

 
    string[] words = { "believe", "relief", "receipt", "field" };
    bool iAfterE = words.Any(w => w.Contains("ei"));
    Console.WriteLine("list has words that contains 'ei': {0}", iAfterE);


Question 2: Using LINQ, return a grouped list of products only for categories that have at least one product that is out of stock.


In this case, we run any over a grouping as shown below:



 
    List<Product> products = GetProductList();
    var productGroups =
        from p in products
        group p by p.Category into g
        where g.Any(p => p.UnitsInStock == 0)
        select new { Category = g.Key, Products = g };

Question 3: Determine if an array of numbers contains all odds.



int[] numbers = { 1, 11, 3, 19, 41, 65, 19 };
bool onlyOdd = numbers.All(n => n % 2 == 1);
Console.WriteLine("The list contains only odd numbers: {0}", onlyOdd);

Question 4: Using LINQ, return a grouped list of products only for categories that have all of their products in stock.



 
    List<Product> products = GetProductList();
 
    var productGroups =
        from p in products
        group p by p.Category into g
        where g.All(p => p.UnitsInStock > 0)
        select new { Category = g.Key, Products = g };
    

LINQ interview questions part 2

Based on popular demand, I am posting a follow up post to my first LINQ interview questions article. In this post, we will follow a similar pattern of rapid fire interview questions and answers on LINQ concepts.

Question 1: How can you sort a result set based on 2 columns?

Assume that you have 2 tables – Product and Category and you want to sort first by category and then by product name.

var sortedProds = _db.Products.Orderby(c => c.Category).ThenBy(n => n.Name) 


Question 2: How can you use LINQ to query against a DataTable?


You cannot query against the DataTable's Rows collection, since DataRowCollection doesn't implement IEnumerable<T>. You need to use the AsEnumerable() extension for DataTable. As an example:

var results = from myRow in myDataTable.AsEnumerable() 
where myRow.Field<int>("RowNo") == 1
select myRow;


Question 3: LINQ equivalent of foreach for IEnumerable<T>


There is no ForEach extension for IEnumerable; only for List. There is a very good reason for this as explained by Eric Lippert here.

Having said that, there are two ways you can solve this:

Convert the items to list and then do a foreach on it:


items.ToList().ForEach(i => i.DoStuff());



Or, alternatively, you can write an extension method of your own.


public static void ForEach<T>(this IEnumerable<T> enumeration, Action<T> action) 
{
foreach(T item in enumeration)
{
action(item);
}
}



Question 4: When to use .First and when to use .FirstOrDefault with LINQ?


You should use First when you know or expect the sequence to have at least one element. In other words, when it is an exceptional if the sequence is empty.

Use FirstOrDefault, when you know that you will need to check whether there was an element or not. In other words, when it is legal for the sequence to be empty. You should not rely on exception handling for the check.

Question 5: Write a LINQ expression to concatenate a List<string> in a single string separated by a delimiter.

First of all, it is better to use string.Join to tackle this problem. But for interview purposes, this problem can be approached as follows:


string delimeter = ","; 
List<string> items = new List<string>() { "foo", "boo", "john", "doe" }; 
Console.WriteLine(items.Aggregate((i, j) => i + delimeter + j)); 

Question 6: Write a LINQ expression to concatenate a List<MyClass> objects in a single string separated by a delimiter. The class provides a specific property (say Name) that contains the string in question.



items.Select(i => i.Name).Aggregate((i, j) => i + delimeter + j)

Regular expressions - groups and alternations (Part 3)

This is part 3 in the series on regular expressions programming interview questions and answers. Here are the links to the previous posts:

  1. Regular expressions interview questions–Part 1
  2. Regular Expressions interview questions–part 2

In this post, we will talk about Groups. Groups in regular expressions allows you to perform different operations such as alternations, sub patterns, quantifiers, etc.

Question: Find all the occurrences of the, The and THE.

Here we will utilize the notion of groups and alternations. Alternation gives you a choice of alternate patterns to match. Let’s try a few solutions to this problem.

  1. The simplest solution is (the|The|THE). This matches any of the 3 different alternatives in the group.
  2. RegEx also has the notion of options. Options let you specify the way you would like to search for a pattern. For our example, we are interested in the ignore case option - (?i). Using this option, we can solve the above problem as (?i)the.
  3. A solution utilizing sub patterns can look like (tT)(hH)(eE).

Question: Find all the even numbers between 0 and 99.

The solution requires you to think and use two alternates – one for 0 to 9 set and the other for remaining using grouping. One possible solution is \b[24680]\b|\b[1-9][24680]\b.

Question: Identify hexadecimal numbers in a string of numbers.

This one is simple. [a-fA-F0-9].

Question: Ignore all vowels in the given text.

In this question, you need to use the negation operator ^. Note that the caret (^) at the beginning of the class means “No, I don’t want these characters.” (The caret must appear at the beginning.). Given this knowledge, the answer is quite simple – [^aeiou]

Friday, July 27, 2012

Regular Expressions interview questions–part 2

In our previous post, we talked about regular expression character sets, groups, quantifiers, shorthand and gives a full solution to matching a a 10-digit, US phone number, with or without parentheses, hyphens, or dots and optional 3 digit area code. In this post, we well dive deeper into some examples of pattern matching.

Regular expressions at their core are all about pattern finding and matching – strings, digits, letters or characters.

Question: Show different ways of matching digits and non-digits using regular expressions.

There are many ways to match a single digit

  • \d
  • [0-9]
  • [0123456789]
  • [012] – matches to either 0, 1 or 2

Similarly, there are many ways to match to a non-digit.

  • \D
  • [^0-9]
  • [^\d]

A couple of notes:

  1. ^ signals negation of the expression to the processor.
  2. \D matches whitespace, punctuation, quotation marks, hyphens, forward slashes, square brackets, and other similar characters.

Question: Explain the different ways to match words and non-words.

  •  \w is the main character shorthand for matching letters and numbers. Consider it to match alpha numeric characters.
  • [a-zA-Z0-9] is the same as \w.
  • Note that \D matches whitespace also; \w does not.
  • \W (capital W) matches non-word matches - whitespace, punctuation, and other kinds of characters that
    aren’t used in words.
  • [^a-zA-Z0-9] is the same as \W (capital).

Question: Write a regular expression to match anything that is a non-space.

  • Space (blank) can be matched by \s. So to match non-space character, we can use \S.
  • Another equivalent way to match non-space would be [^\s]
  • Yet another way would be [^ \t\n\r]

Question: Write a regular expression to match words that are exactly 7 characters in length and start with P and end with D.

In this question, the interviewer is testing your ability to understand word boundaries and repeat notations. The following expression solves this question: \bP.{5}D\b.

To dissect the expression:

  • The shorthand \b matches a word boundary, without consuming any characters.
  • The characters P and D also bound the sequence of characters.
  • .{5} matches any five characters.
  • Match another word boundary with \b.

Thursday, July 26, 2012

Regular expressions interview questions–Part 1

Regular expressions (RegEx for short) are special strings that define patterns for matching specific sets of strings. RegEx are a favorite interview question for many developers as it allows you to quickly quiz an interviewee’s ability to decode a problem into smaller parts without needing to write a lot of code.

There are some excellent online tools available to test your regular expression syntax and match. http://regexpal.com/ is an interesting one to play around with. TextMate on Mac and Notepad++ are good alternatives from a desktop perspective.

In this post, we will review some of the basic regular expressions. In future posts, we will look into constructing more complex patterns.

Question: Develop a regular expression to match a US phone number.

Let us take an example phone number – 425-882-8080 (this also happens to be Microsoft’s main line number so don’t call it unless you absolutely have to ).

  1. The simplest RegEx pattern for this can be the number itself. Yes, that works too. But I don’t think the interviewer would be very happy if you give her this answer.
  2. Using character classes or sets, we can  match a group of characters with or without specifying all of them. For example, [0-9] tells the processor to match any digit in the range of 0 to 9. The square brackets are not literally matched because they are treated specially as meta-characters. A meta-character has special meaning in regular expressions and is reserved. A regular expression in the form [0-9] is called a character class, or sometimes
    a character set. In addition, you can be more specific and specify the digits you want matched. For example, [02468] only matches if the input contains one of 0, 2, 4, 6 or 8. As a next step solution for our problem using character classes, the following RegEx will work (but don’t tell the interviewer that this is your final solution yet): [0-9][0-9][0-9]-[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]
  3. Let’s bump up our skills now by using character shorthand. A \d matches any digit. A \D matches any non-digit. Our answer can now be shortened to \d\d\d-\d\d\d-\d\d\d\d (which does an exact match for hyphen(-) or better yet to \d\d\d\D\d\d\d\D\d\d\d\d. Note that instead of using a \D, we could have used a dot (.) which allows you to match to any character.
  4. Note that wrapping a part of a regular expression in parentheses () creates a group. We will learn more about groups in a future post.
  5. To shorten our RegEx more, we can enlist the help of Quantifiers. As the name suggests, quantifiers allow you to specify how many times the preceding expression should match. There are a number of ways to specify a quantifier – \d{3} implies match a digit exactly 3 times; The question mark (?) signifies zero or one; plus sign (+), which means one or more, or the asterisk (*) which means zero or more. Given our new knowledge about quantifiers, our answer can be updated to (\d{3}[-]?){2}\d{4} which will match two non-parenthesized sequences of three digits each, followed by an optional hyphen, and then followed by exactly four digits.
  6. We are almost there. It is now time to make our RegEx more robust, professional, smart and production ready. Let’s add the following features:
    • The area code can be optional
    • allow literal parentheses to optionally wrap the first sequence of three digits
    • The separator character can either be a dot (.) or a hyphen (-)

Our final answer that should be good enough for an interview to match a 10-digit, US phone number, with or without parentheses, hyphens, or dots and optional 3 digit area code  can be ^(\(\d{3}\)|^\d{3}[.-]?)?\d{3}[.-]?\d{4}$

Let’s dissect this RegEx on a character by character basis to make sure we are on the right track:

  • ^ (caret) at the beginning of the regular expression, or following the vertical bar (|), means that the phone number will be at the beginning of a line.
  • ( opens a group.
  • \( is a literal open parenthesis.
  • \d matches a digit.
  • {3} is a quantifier that, following \d, matches exactly three digits.
  • \) matches a literal close parenthesis.
  • | (the vertical bar) indicates alternation, that is, a given choice of alternatives. In other words, this says “match an area code with parentheses or without them.”
  • ^ matches the beginning of a line.
  • \d matches a digit.
  • {3} is a quantifier that matches exactly three digits.
  • [.-]? matches an optional dot or hyphen.
  • ) close capturing group.
  • ? make the group optional, that is, the prefix in the group is not required.
  • \d matches a digit.
  • {3} matches exactly three digits.
  • [.-]? matches another optional dot or hyphen.
  • \d matches a digit.
  • {4} matches exactly four digits.
  • $ matches the end of a line.

In future posts, we will look at some more advanced regular expressions with examples.

Thursday, June 7, 2012

Entity Framework transaction scope examples

Transactions as a core building block of entity framework. The DbContext object which we heavily use for interacting with the database uses transactions internally without you having to do anything extra. In case you need to manually provide transaction support, here is how you can do it.
In this post, I cover three cases in which transaction scope is being used to show rollback when an error occurs during an update of multiple entities:
  1. when you have multiple save calls to the context;
  2. when you have  single save with multiple object; and
  3. transactions across multiple contexts.
Let’s first review our simple model and context object. To re-create this project, use Visual Studio 2010 console project with Entity Framework 5.0 RC bits from nuget.
Our model is a simplified version of a “Product” object and it’s definition look like this:
using System;
using System.ComponentModel.DataAnnotations;
 
namespace EFTransactionsDemo.Model
{
    public class Product
    {
        public int Id { get; set; }
        [Required]
        public string Name { get; set; }
        [Required]
        public DateTime DateAdded { get; set; }
    }
}



Our context definition looks like:

using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
 
namespace EFTransactionsDemo.Model
{
    public class EFTDbContext : DbContext
    {
        public DbSet<Product> Products { get; set; }
         
        public EFTDbContext() : 
            base("EFTransactionsDemo")
        {
            // disable proxy creation 
            this.Configuration.ProxyCreationEnabled = false;
        }
         
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            // Tell Code First to ignore PluralizingTableName convention
            // If you keep this convention then the generated tables will have pluralized names.
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        }
    }
}



The main method (this is demo code; in production environments, please make sure to use proper programming paradigms, do error handling, parameter checks, etc.), calls three functions that demonstrate the use of transaction scope for the three scenarios I listed above.

using System;
using System.Linq;
using System.Transactions;
using EFTransactionsDemo.Model;

namespace EFTransactionsDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            // setup
            CreateDatabase();

            // transaction demo - 1
            // wrap multiple save calls within one transaction
            // and roll back on a bad one
            TestMultipleSaveCalls();

            // transaction demo - 2
            // wrap multiple adds and one save within one transaction
            // and roll back on a bad one
            TestMultipleAddWithOneSaveCall();

            // transaction demo - 3
            // multiple contexts in same transaction
            TestMultipleContexts();
        }

        private static void TestMultipleSaveCalls()
        {
            // good product
            Product goodProduct = new Product()
            {
                Name = "My awesome book",
                DateAdded = DateTime.UtcNow
            };

            // invalid product
            Product invalidProd = new Product()
            {
                Name = "My awesome book part 2"
                // note - no date added specified
            };

            // define our transaction scope
            var scope = new TransactionScope(
                // a new transaction will always be created
                TransactionScopeOption.RequiresNew,
                // we will allow volatile data to be read during transaction
                new TransactionOptions()
                {
                    IsolationLevel = IsolationLevel.ReadUncommitted
                }
            );

            try
            {
                // use the scope we just defined
                using (scope)
                {
                    // create a new db context
                    using (var ctx = new EFTDbContext())
                    {
                        // add the product
                        ctx.Products.Add(goodProduct);
                        // save
                        ctx.SaveChanges();

                        // add the invalid product
                        ctx.Products.Add(invalidProd);
                        // save
                        ctx.SaveChanges();
                    }

                    // everything good; complete
                    scope.Complete();
                }
            }
            catch { }

            // verify that we actually rolled back
            using (var ctx = new EFTDbContext())
            {
                Console.WriteLine(ctx.Products.Count());
            }
        }

        private static void TestMultipleAddWithOneSaveCall()
        {
            // good product
            Product goodProduct = new Product()
            {
                Name = "My awesome book",
                DateAdded = DateTime.UtcNow
            };

            // invalid product
            Product invalidProd = new Product()
            {
                Name = "My awesome book part 2"
                // note - no date added specified
            };

            // define our transaction scope
            var scope = new TransactionScope(
                // a new transaction will always be created
                TransactionScopeOption.RequiresNew,
                // we will allow volatile data to be read during transaction
                new TransactionOptions()
                {
                    IsolationLevel = IsolationLevel.ReadUncommitted
                }
            );

            try
            {
                // use the scope we just defined
                using (scope)
                {
                    // create a new db context
                    using (var ctx = new EFTDbContext())
                    {
                        // add the product
                        ctx.Products.Add(goodProduct);

                        // add the invalid product
                        ctx.Products.Add(invalidProd);
                        // save
                        ctx.SaveChanges();
                    }

                    // everything good; complete
                    scope.Complete();
                }
            }
            catch { }

            // verify that we actually rolled back
            using (var ctx = new EFTDbContext())
            {
                Console.WriteLine(ctx.Products.Count());
            }
        }

        private static void TestMultipleContexts()
        {
            // good product
            Product goodProduct = new Product()
            {
                Name = "My awesome book",
                DateAdded = DateTime.UtcNow
            };

            // invalid product
            Product invalidProd = new Product()
            {
                Name = "My awesome book part 2"
                // note - no date added specified
            };

            // define our transaction scope
            var scope = new TransactionScope(
                // a new transaction will always be created
                TransactionScopeOption.RequiresNew,
                // we will allow volatile data to be read during transaction
                new TransactionOptions()
                {
                    IsolationLevel = IsolationLevel.ReadUncommitted
                }
            );

            try
            {
                // use the scope we just defined
                using (scope)
                {
                    // create a new db context
                    var firstCtx = new EFTDbContext();
                    // create a second context
                    var secondCtx = new EFTDbContext();

                    // add the product to first context
                    firstCtx.Products.Add(goodProduct);
                    // save
                    firstCtx.SaveChanges();

                    // add the invalid product to second context
                    secondCtx.Products.Add(invalidProd);
                    // save
                    secondCtx.SaveChanges();

                    // everything good; complete
                    scope.Complete();
                }
            }
            catch { }

            // verify that we actually rolled back
            using (var ctx = new EFTDbContext())
            {
                Console.WriteLine(ctx.Products.Count());
            }
        }

        private static void CreateDatabase()
        {
            using (var ctx = new EFTDbContext())
            {
                ctx.Database.CreateIfNotExists();
            }
        }
    }
}

As always, please do leave your thoughts and comments. It is the user feedback that drives the product and blog better.