.Net Regular Expressions – Finding Decimal Numbers that are Divisible by Three

It’s very easy to check a decimal number is divisible by three using a simple DFA with 3 states.

A regex, therefor, is possible, but not too pretty (source):

(?:[0369]|
[147](?:[0369]*[147][0369]*[258])*(?:[0369]*[258]|[0369]*[147][0369]*[147])|
[258](?:[0369]*[258][0369]*[147])*(?:[0369]*[147]|[0369]*[258][0369]*[258])
)*

Example: http://www.rubular.com/r/ZcRDblHg8M

Here’s another approach, using .Net’s stacks as a simple counter:

\b
(?>             # No regrets - don't backtrack on if/else decisions.
    [0369]      # = 0 (mod 3)
    |
    [147]       # = 1 (mod 3)
    (?:         # if possible pop 2, else push 1
        (?<-Sum>){2}|(?<Sum>)
    )
    |
    [258]       # = 2 (mod 3)
    (?:         # if possible pop 1, else push 2
        (?<-Sum>)|(?<Sum>){2}
    )
)+
\b
(?(Sum)(?!)) # Assert nothing's left in the stack

Why? Well, I was bored while I shaved. Luckily, this regex is simple enough for Mono. Working example: http://ideone.com/Yp6Ti (ok, maybe not, mono is missing 111222)

Advertisement

.Net Regular Expressions – Using the Stack State to Understand Numeric Values

It is common knowledge that regular expressions should handle text and not values. A recent stack overflow question got me thinking though – it is possible to use .Net regular expressions to understand numbers or other values while matching the pattern?
Regular expressions can be used to perform numerical tasks, but that is usually when working in unary base.
It turns out this is possible – .Net keeps a stack for every capture of every matched group while matching the pattern, and that state is available for use while matching. The idea is simple: we can represent numbers as depth of the stack, so the number 0 is an empty stack, 6 is a stack with 6 captures, and so forth.

(?>
    (?=[0-9])   # optimization - don't multiply when we don't have a digit.
    # multiply the content of the stack by 10
    # for each item on Stack, push 10 items to a Temp stack.
    (?(Decimal)
        (?<-Decimal>
            (?<Temp>){10}
        )
    ){100000}
    (?(Decimal)(?!))
    # Push all items from Temp back to Stack
    (?(Temp)
        (?<-Temp>
            (?<Decimal>)
        )
    ){100000}
    (?(Temp)(?!))
    # match a digit, and push its value to the stack
    (?:
        0                 |
        1 (?<Decimal>)    |
        2 (?<Decimal>){2} |
        3 (?<Decimal>){3} |
        4 (?<Decimal>){4} |
        5 (?<Decimal>){5} |
        6 (?<Decimal>){6} |
        7 (?<Decimal>){7} |
        8 (?<Decimal>){8} |
        9 (?<Decimal>){9}
    )
)+

The idea is very simple: when we see a new digit, we multiply the depth of the stack by 10, and add the number represented by the new digit. The value of the number can be verified using:

match.Groups["Decimal"].Captures.Count

A curious bit here is the use of the loop to copy stacks:

(?(Temp)
    (?<-Temp>
        (?<Decimal>)
    )
){100000}

I’d expect this to be enough:

(?<-Temp> (?<Decimal>) )*
(?(Temp)(?!))

It turns out the above loop is only executed once, and the condition always fails. It is probably a documented optimization, I’ll look more into that later. As a proof of concept, the workaround should do.

It is even possible to perform basic arithmetic operations on these stacks such as adding, subtracting, multiplying and such from within the regex engine, but that may be a few extra steps too many.
It should go without saying, of course, that regex isn’t a good option here – this is for recreational use. The run time and complexity are far from ideal.

See also:

jQuery UI Datepicker Slow On IE6

Internet Explorer 6 is, unfortunately, still is widely used in corporate environments. I’ve found the jQuery UI (1.7.2) Datepicker too slow on IE6, taking several seconds to display, and another few seconds to hide.

Looking for a solution, I’ve found this thread, suggesting it’s an IE6 bug that caused it to load the same background images dozens of times. The suggested solution, however, didn’t work for me. I came up with a slightly better solution. Simply add this CSS rule to prevent the background images from loading in IE6:

* html .ui-datepicker tbody a {background-image:none !important;}

The next step is to disable animation. The date picker has many elements – animating them is too much work for IE6, resulting in the animation not showing at all – but still delaying the calendar. Wonderful. The solution is to disable the animation for IE6 by setting its duration to 0. You may also want to set the animation to null, because some animations ignore the zero duration. This is done for IE6 only, as there is no need to penalize modern browsers.

$('input.Calendar').datepicker({
           showAnim: jQuery.support.boxModel ? 'drop' : null, // optional
           duration: jQuery.support.boxModel ? 'normal' : ''
        });

Adding Items to a SharePoint List

Ok, a low-tech post this time. I’ve wasted the better part of my last few days battling Share Point permissions. My goal was to write a web part that lets users add an entry to a Share Point list. So, in case you (or me) need users to add items to a list, this could save us a lot of time…
Continue reading

Sending Meeting Requests to Outlook via ASP.NET Mail Message

Numerous programs on my company deal with event registration. Naturally, that involves sending our employees meeting requests. Here’s the best way I’ve found so far for doing that. The long function at the end is from a web-service already in use for a few months.

Meeting Request

Meeting Request

To make these ICS files dynamically, I use the .Net library DDay.iCal. It’s aewsome.
It took some trial and error, but at the end I was able to create events that work well for all versions of Outlook.
Unlike the solutions I’ve found on the web, this one doesn’t use the office interop thing, so I don’t need outlook installed on the server. I’m using a regular SMTP mail message and add the ICS as attachment.

Anyway, assuming you know how to send mails and how to generate the right ICS for your event (we’ll get to that later), this is the way to send it to Outlook:
First the variables:

//init the message with your defaults (from, to, subject, etc)
MailMessage message = initMailMessage();
string iCal = initICal(parameters ...);

And the code that adds the attachment:

//Add the attachment, specify it is a calendar file.
System.Net.Mail.Attachment attachment =
System.Net.Mail.Attachment.CreateAttachmentFromString(
iCal, new ContentType("text/calendar"));
attachment.TransferEncoding = TransferEncoding.Base64;
attachment.Name = "EventDetails.ics"; //not visible in outlook

message.Attachments.Add(attachment);

sendMailMessage(message);

Ok. That’s probably disappointing, since you can’t just copy-paste this code and make it work. I’m including more code you may want to use, but first some rules for the ICS files you’re about to create:

Rules of Thumb

  • Make sure to specify the Method property – should be Publish or Request. Outlook won’t accept the file without it.
  • Add an Organizer – or Outlook 2007 won’t let people save the event.
  • Add the meeting’s subject and description to the ICS file, but also as the mail’s subject and body. Outlook may display either one.

Now for that extra code.
This one is pretty simple – sends an SMTP message:

private static void sendMailMessage(MailMessage mailMessage)
{
string mailHost = "Ask.Someone.com";
SmtpClient smtpClient = new SmtpClient(mailHost, 25);
smtpClient.DeliveryMethod =
   SmtpDeliveryMethod.PickupDirectoryFromIis;
smtpClient.Send(mailMessage);
}

This fine function creates the ICS:

[WebMethod(Description =
   "Send an appointment with much details.")]
public void SendAppointment(string from, string to,
   string title, string body, DateTime startDate,
   double duration, string location, string organizer,
   bool updatePreviousEvent, string eventId,
   bool allDayEvent,
   int recurrenceDaysInterval, int recurrenceCount)
{
  iCalendar iCal = new iCalendar();

  // outlook 2003 needs this property,
  //  or we'll get an error (a Lunar error!)
  iCal.Method = "PUBLISH";

  // Create the event
  Event evt = iCal.Create();

  evt.Summary = title;

  evt.Start = new iCalDateTime(startDate.Year,
    startDate.Month, startDate.Day, startDate.Hour,
    startDate.Minute, startDate.Second);
  evt.Duration = TimeSpan.FromHours(duration);
  evt.Description = body;
  evt.Location = location;

  if (recurrenceDaysInterval > 0)
  {
    RecurrencePattern rp = new RecurrencePattern();
    rp.Frequency = FrequencyType.Daily;
    rp.Interval = recurrenceDaysInterval; // interval of days

    rp.Count = recurrenceCount;
    evt.AddRecurrencePattern(rp);
  }
  evt.IsAllDay = allDayEvent;

  //organizer is mandatory for outlook 2007 - think about
  // trowing an exception here.
  if (!String.IsNullOrEmpty(organizer))
    evt.Organizer = organizer;


  if (!String.IsNullOrEmpty(eventId))
    evt.UID = eventId;

  //"REQUEST" will update an existing event with the same
  // UID (Unique ID) and a newer time stamp.
  if (updatePreviousEvent)
    iCal.Method = "REQUEST";

  // Save into calendar file.
  iCalendarSerializer serializer =
    new iCalendarSerializer(iCal);
  //serializer.Serialize(@"iCalendar.ics");

  string icalData = serializer.SerializeToString();

  //send the iCal data. Also sends the subject and body
  //on the mail.
  SendAppointmentFromICalWithMailTitle(from, to,
    icalData, title, body);
}

See Also:

How not to Code: The String Identity Function

Yesterday I started working on a small system that’s been having some problems lately. Reviewing the code, I quickly came across the following function:

public static string IsNullToString(string _str)
{
    string name = null;
    if (_str != null)
    {
        name = _str.ToString();
    }
    return name;
}

Now, it seems that if that function receives a null it returns a null, and for other string it’s returning that string. Remembering that String is a sealed class and cannot be inherited, and that String.ToString() does very little, I fail to see why this function is used every time a string is printed out, 108 times in the code…

See Also:

Using jQuery to Filter Table Rows

I’m retouching an old system, and though it could use a filter on it’s report page. The report has a large table with about 300 rows. After some play with jQuery, I came out with this little filter.
The project is using the .net GridView control, so I had limited control over the output HTML code. Still, I think this code can work for most tables. One thing to notice: you should use the class “filterable” on your table or on one of its parents for the code to work.
First, we need a text box:

Filter:
<input type="text" id="FilterTextBox" name="FilterTextBox" />

And the code:

$(document).ready(function(){
 //add index column with all content.
 $(".filterable tr:has(td)").each(function(){
   var t = $(this).text().toLowerCase(); //all row text
   $("<td class='indexColumn'></td>")
    .hide().text(t).appendTo(this);
 });//each tr
 $("#FilterTextBox").keyup(function(){
   var s = $(this).val().toLowerCase().split(" ");
   //show all rows.
   $(".filterable tr:hidden").show();
   $.each(s, function(){
       $(".filterable tr:visible .indexColumn:not(:contains('"
          + this + "'))").parent().hide();
   });//each
 });//key up.
});//document.ready

Explanation:

  1. Create Index Column – lines 2-7 – The jQuery “:contains()” selector is case sensitive, so at the first step I create another column on the table, than contains the whole row’s text on lowered case. On line 3 you may have noticed I’m filtering only rows that has <td>, to avoid hiding the header column (presumably, the header only has <th>). Later, I could make searches in this column alone. This works as long as the text on the table doesn’t change.
  2. Bind the Key-Up Event – lines 8-16.
  3. Make an array with all filter keywords – line 9 – Get all word from the text box and put them in an array. Again, I’m using toLowerCase() because “:contains” is case sensitive.
  4. Hide rows – lines 12-15 – I’m using jQurey’s each function to go through the array, and hiding all rows that don’t contain the current keyword (Assuming AND between all words).

That’s it. Now rows on our table can be filtered.

Converting DataSets to Strongly-Typed DataSets

One of the first things shown to me when I started working in my company was Microsoft’s Data Access Application Block. One thing that bothered me was that I constantly had to convert DataSets it returned to strongly typed DataSets used in our programs, which usually meant merging the returned data set with a newly created DataTable. To relieve myself of those repeating tedious 6 lines of code, I made this little class that converts untyped DataSets and DataTables to a strongly typed DataTable.
In a first attempt to solve this problem, I used reflation to create an instance of the typed DataTable, so I had to pass the method the type of the DataTable, and cast it back to itself.
This is a more elegant solution, using generics:

/// <summary>
/// Helper methods and functions.
/// </summary>
/// <typeparam name="T">A strongly type DataTable.
/// A DataTable of type T will be returned from the DataSet.
/// </typeparam>
public static class DataSetAdapter<T>
                          where T : DataTable, new()
{
    /// <summary>
    /// Convert the first DataTable from a DataSet to a
    /// strongly-typed data table.
    /// </summary>
    public static T convert(DataSet dataSet)
    {
        if (dataSet == null)
            return null;
        if (dataSet.Tables.Count == 0)
            return null;
        DataTable dataTable = dataSet.Tables[0];
        return convert(dataTable);
    }
    /// <summary>
    /// Convert an ordinary DataTable to a strongly-typed
    /// data table.
    /// </summary>
    public static T convert(DataTable dataTable)
    {
        if (dataTable == null)
            return null;
        T stronglyTyped = new T();
        // add data from the regular DataTable to the
        // strongly typed DataTable.
        stronglyTyped.Merge(dataTable);
        return stronglyTyped;
    }
}

The use of the class if pretty straightforward, just pass the DataSet and the Type:

DataSet employeesDataSet = OracleHelper.ExecuteDataset(
 connectionString, storedProcedure, parameters);
EmployeesDataTable employees =
 DataSetAdapter<EmployeesDataTable>.convert(employeesDataSet);

Links:

Using Sharepoint’s File Type Icons

We have an old web part that displays documents from a list, and shows an icon next to file. After reading the list, the web part has a long “if-else” block that checks the files extension and displays the proper image. The images come from sharepoint template directory. I need to update this web part to display more file types icons. At first we though to create a list that maps images to extensions, but after little research I’ve decided to read sharepoint’s docicon.xml file.
First, we need to find the file docicon.xml. The file usually sits under

C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\template\xml\docicon.xml

The xml directory is not mapped on the IIS, but we can still find it using this little trick:

string path = MapPathSecure("~/_layouts/");
path = Path.Combine(path, @"..\xml\docicon.xml");

Now all that’s left is to read the xml and add the data to a collection:
(This is actually the first time using XmlDataReader, but how wrong can I be?)
First, we define two members, for all files and the default icon, and then go through the XML nodes:

protected NameValueCollection fileTypeIcons;
protected string defaultIcon;

protected void readIconsXml()
{
    XmlReader reader = XmlReader.Create(path);
    reader.ReadToFollowing("ByExtension");
    //find the first child. This doesn't skip the first node.
    reader.ReadToFollowing("Mapping");
    while (reader.ReadToNextSibling("Mapping"))
    {
        readOneNodeMapping(reader);
    }
    //find the default icon
    reader.ReadToFollowing("Default");
    reader.ReadToFollowing("Mapping");
    defaultIcon = reader.GetAttribute("Value");
}

protected void readOneNodeMapping(XmlReader reader)
{
    string tempKey = null;
    string tempValue = null;
    tempValue = reader.GetAttribute("Value");
    tempKey = reader.GetAttribute("Key");
    if ((tempKey != null) && (tempValue != null))
        fileTypeIcons.Add(tempKey, tempValue);
}

And that’s it. We have all icons defined in the site ready in our project.