rulururu

post Sorting Strings containing Numbers

March 24th, 2008

Filed under: .NET, General Programming — Kai @ 6:20 pm

It’s often necessary to sort lists. The Sort method of ArrayList class shows that it can’t be difficult. Also some other classes can be sorted unless they are type IComparable.
The sort method of ArrayList class has several overloads, some can be given to a Comparer, which implements the IComparer interface.

The interface has just one method called Compare which returns equal, greater or smaller depending on the two values it compares.

If you’d make your own comparer you’d simply do that like this:

public class MySpecialComparer : object, System.Collections.IComparer
{
 
    /// <summary>
    /// Default constructor - initializes all fields to default values
    /// </summary>
    public MySpecialComparer()
    {
    }
}

There’s also a difference in ascending and descending sort order. Mention the following code which compares String descending:

public class DescendingComparer : IComparer
{
  public int Compare(object objA, object objB)
  {
    return String.Compare(objB.ToString(), objA.ToString());
  }
}

The trick is just to compare B to A and not the way round.

To sort a simplest one dimensional array in alphabetical order, we’ll leverage the static “Sort” method in the Array class to sort the array. The Array.Sort method will sort the array in place, meaning we don’t have to create another array to contain the resulting array. Here is how:

String[] myAnimals = {"Zebra","Elephant","Snake"};
Array.Sort(myAnimals);

As expected this will result in the array getting sorted in the ascending order i.e. iterating the elements of this array will cause the output in the following manner:

Elephant, Snake, Zebra

Computer string sorting algorithms generally don’t order strings containing numbers in the same way that a human would do. Consider:

rfc1.txt, rfc2086.txt, rfc822.txt

It would be more friendly if the program listed the files as

rfc1.txt, rfc822.txt, rfc2086.txt

Filenames sort properly if people insert leading zeros, but they don’t always do that.
It’s kinda tricky when strings that contain numbers are sorted ’cause they’ve to be sorted numerically.

Imagine an array of values like this:

string[] Items = { "z4", "z2", "z15", "z1" };

The idea is to write a Comparer (implements IComparer) which extracts the numeric part e.g. by RegEx: [0-9]*
Then sort as already familiar with a Collections.Sort method that uses the comparator.

Generally you’d “invent” an algorithm that breaks strings into chunks, where a chunk contains either all alphabetic characters, or all numeric characters. These chunks are then compared against each other. If both chunks contain numbers, a numerical comparison is used. If either chunk contains characters, the ASCII comparison is used.

Ian Griffith offered a code sample that helps to handle string sorting with numbers:

/// <summary>
/// Compares two sequences.
/// </summary>
/// <typeparam name="T">Type of item in the sequences.</typeparam>
/// <remarks>
/// Compares elements from the two input sequences in turn. If we
/// run out of list before finding unequal elements, then the shorter
/// list is deemed to be the lesser list.
/// </remarks>
public class EnumerableComparer<T> : IComparer<IEnumerable<T>>
{
    /// <summary>
    /// Create a sequence comparer using the default comparer for T.
    /// </summary>
    public EnumerableComparer()
    {
        comp = Comparer<T>.Default;
    }
 
    /// <summary>
    /// Create a sequence comparer, using the specified item comparer
    /// for T.
    /// </summary>
    /// <param name="comparer">Comparer for comparing each pair of
    /// items from the sequences.</param>
    public EnumerableComparer(IComparer<T> comparer)
    {
        comp = comparer;
    }
 
    /// <summary>
    /// Object used for comparing each element.
    /// </summary>
    private IComparer<T> comp;
 
 
    /// <summary>
    /// Compare two sequences of T.
    /// </summary>
    /// <param name="x">First sequence.</param>
    /// <param name="y">Second sequence.</param>
    public int Compare(IEnumerable<T> x, IEnumerable<T> y)
    {
        using (IEnumerator<T> leftIt = x.GetEnumerator())
        using (IEnumerator<T> rightIt = y.GetEnumerator())
        {
            while (true)
            {
                bool left = leftIt.MoveNext();
                bool right = rightIt.MoveNext();
 
                if (!(left || right)) return 0;
 
                if (!left) return -1;
                if (!right) return 1;
 
                int itemResult = comp.Compare(leftIt.Current, rightIt.Current);
                if (itemResult != 0) return itemResult;
            }
        }
    }
}

When using it a regular expression for the numbers is needed.
Using C# 3.0 it can be used that way:

Func<string, object> convert = str =>
{   try { return int.Parse(str); }
    catch { return str; } };
 
var sorted = testItems.OrderBy(
    str => Regex.Split(str.Replace(" ", ""), "([0-9]+)").Select(convert),
    new EnumerableComparer<object>());

Again the lambda expression can help a lot. sorted is an untyped listed that can be iterated with foreach.

When sorting / comparing strings that contain numbers you always should consider to sort them the way a human would do.

post Short type names

March 24th, 2008

Filed under: .NET — Kai @ 2:10 pm

One nice tidbit is how to create new short type names without having to specify the full name of every non-primitive type, especially inside of generic type names.

Normally, using “using” to create a new type name, even in the presence of the appropriate namespace import, one has to fully qualify every type name that is not a keyword.

using System.Collections.Generic;
using T = System.Collections.Generic.List<string>

However, if the “using” is inside a namespace, then it will utilize any imports located in an outer namespace.

using System.Collections.Generic;
 
namespace MyCompany
{
    using T = List<string>;
}

post Unzip or Unrar many files at once

March 22nd, 2008

Filed under: Linux — Kai @ 4:03 pm

If you’ve got a directory with dozens of zipped or rar’d files, you can run a single command to unzip them all in one step, thanks to the power of the bash shell.

For this task, we’ll use bash’s for loop command structure. Replace var with a variable name, and list with either a command that outputs a list or an explicit list.

for <var> in <list>
do
  command $<var>;
done

You can run it on a single line with this syntax instead:

for <var> in <list>;do command $<var>;done

So if you want to unrar a list of files, you could use this command. You don’t necessarily need the quotes, but it helps when the filenames have spaces or something like that in them.

for f in *.rar;do unrar e "$f";done

If you wanted to use 7zip to extract a list of files:

for f in *.001;do 7z e "$f";done

Or if you wanted to unzip a list of files:

for f in *.zip;do unzip "$f";done

You could even chain commands together if you wanted to. For instance, if all your zip files contained .txt files and you wanted to unzip them and then move the unzipped files to another directory:

for f in *.zip;do unzip "$f";done; for f in *.txt;do mv "$f" /myfolder/;done

The bash shell is just so incredibly powerfull, this doesn’t even tap the power, but it should give you a good idea of what is possible.

post Realtime Apache monitoring with apachetop

March 17th, 2008

Filed under: Internet, Linux, Software — Kai @ 5:10 pm

Using apachetop you can watch every request on your apache webserver smiliar to watching progresses with top at your local system.

It works by processing the logfiles found in /var/log/apache.

By default apachetop will use your log in /var/log/apache/access.log, but you can add a -f flag to the command and point it to wherever your apache log really is if you moved it.

apachetop -f var/log/httpd-access.log

In the header of the output apachetop generates some small statistics about number of requests, the transfered data and the returned status codes since apachetop was started and for also for the last 30 seconds.
Additionally the last few requests are listed. Press “d” to switch from requested urls to refferrers or client IPs.

Man Page:
apachetop(1)
Project Page:
Apachetop - Top-like display of Apache logs

post Caffeine Kills You

March 14th, 2008

Filed under: Internet — Kai @ 7:04 pm

109.89 cans of Afri Cola + Me = Death.

This has nothing to do with software development, but seems too cool to left it uncommented.

Afri Cola

On my odyssey thought the world wide web I came across that funny website.

The calculator tells you how many drinks of your favorite caffeinated drink you can consume before dying.
Take this quick test and find out.

Good thing is that I don’t drink Coke or other coffeine drinks that often - bad thing about is that far less coffein will probably kill me because of the heartburn I get from ;)

Every programmer should review this before stepping over that line. :D
By the way a 12 ounce can of Afri Cola contains 89 milligrams of caffeine.

post Disabling balloon tips

March 14th, 2008

Filed under: Windows — Kai @ 6:47 pm

I just want to share some information, which to browse the web for everytime again may require some time that can be better used otherways if already posted here.

I found the informational balloon tips that appear on my task bar to be very informative - initially, but become very annoying over time.

BallonTipp

I personally like having the icons appear on the task bar, but the balloons have become very annoying. To allow your icons to appear without the balloons, you can do the following.

These instructions are for Windows XP:

  • Run the REGEDIT from the Start > Run dialog.
  • Locate the following registry folder:
    HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced
  • Create a DWORD value called “EnableBalloonTips“. The default value will be zero. Leave the value as zero.
  • Reboot your computer for this change to take effect.

This will disable all balloon tips on your task bar.

For connection tool tips like the one on the screenshot there’s also another way to disable them:
Just uncheck the “Show icon in the notification area when connected” option in connection properties.

ruldrurd
« Previous PageNext Page »
Powered by WordPress, Content and Design by Kai Bellmann
Entries (RSS) and Comments (RSS)