Friday, March 18, 2011

ScreenGrabber and Github

The screenshotting program that I've been working on for so long is finally nearing completion. I've updated it to include a lot of neat features, and I've gotten rid of the stupid way that I was capturing screen areas, replaced with being able to draw a box around what you want.

It's too big to just post the code here, and I really can't upload anything here anyway. So I'll use this to also mention that I have a Github account. My repos are here:

https://github.com/insertAlias

ScreenGrabber has my screen shot program.

Download it, build it, and break it for me so I can make it better!

Also, if anyone wants to make any better icons for me, I'd love them, since mine suck.

Thursday, March 10, 2011

New Extension Method for IList: SafeInsert

IList.Insert takes an index and a value, and attempts to insert that value at that index, pushing all following values out to the next index. Of course, that index must exist to do the insert.

I figured, why? If I want to move something to position 50, but there are only 5 values in the List, is it reasonable to assume that I want it to go to the last spot, since 50 isn't available? Maybe. Especially in the case where I'm presenting the user a grid, and allowing them to change a row's index manually. I'd rather not bother testing the number they enter, and just assume that if they put an index greater than exists that they want it to be inserted at the end.

This really isn't challenging code or anything, but it's useful, and the first time I thought of it, so I'll share:

public static void SafeInsert<t>(this IList<t> list, int index, T val){
    if (index < 0)
        list.Insert(0, val);
    else if (index > list.Count)
        list.Insert(list.Count, val);
    else
        list.Insert(index, val);
}

Friday, February 11, 2011

Extension methods: For<T> and ForEach<T>

I noticed that List has a method called ForEach, that takes an Action and applies it to all elements in the collection. This is not an extension method, it's part of List.

I wondered why it's not part of the LINQ Extension methods. The best I could come up with was that IEnumerables can be infinite, so a non-terminable ForEach would cause problems. Of course, we can do these with standard foreach loops, so I see no harm in including it if you know what you're getting into. Also, it should be possible to provide a terminator clause to exit the foreach loop as a Func.

With that said, I also felt the need to be able to simulate a simple for loop. An indexed-foreach, if you will. So here are three extension methods I've come up with:

public static void For<T>(this IEnumerable<T> items, Action<int, T> action) {
    for (int i = 0; i < items.Count(); i++)
        action(i, items.ElementAt(i));
}

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

public static void ForEach<T>(this IEnumerable<T> items, Action<T> action, Func<T, bool> breakWhen) {
    foreach (T item in items) {
        if (breakWhen(item))
            break;
        action(item);
    }
}

Here's an example of use:

var numbers = Enumerable.Range(10, 10);
numbers.For((i, x) => Console.WriteLine("Index: {0}, Value: {1}", i, x));
numbers.ForEach(x => Console.WriteLine(x));
var allReal = Extensions.Real(0);
allReal.ForEach(x => Console.WriteLine(x), x => x > 9);

Extensions.Real(0) is just a method that returns an IEnumerable that starts at 0 and counts up. There's no exit condition, so if you tried to iterate through the whole thing, it'd just go until it hit an integer overflow. But it shows we can provide an exit condition for a ForEach loop.

Tuesday, December 21, 2010

How to Get Values From Form1 to Form2 (or any other forms, for that matter).

This question is asked practically every day on C# Forums: "how do I get a value from Form1 to Form2?" or the other way around. There is a shocking amount of bad advice out there on the internet about how to go about doing this. This tutorial is intended to show you more "correct" ways of passing data between forms.

The scope of this tutorial is limited to passing data between forms. We will look at both properties and custom events, but in a brief overview.

Friday, November 26, 2010

Silverlight RPN Calculator Tutorial.

Well I beat my old nemesis and finished an RPN calculator. It was much easier than I remember, but then again, I tried it like four years ago. I've learned so much in the time since, I can hardly believe how silly my old code is.

Have any of you ever used a Reverse Polish Notation calculator? I did in high school. It was easily the best calculator ever (the HP=32SII). RPN is great, because you don't have to use parenthesis. The stack and the order in which you key the operators maintains order of operations.

Today, I'll walk you through creating one. Note this tutorial is technically for Silverlight, but except for the marked sections, it can be applied wholesale to WinForms or WPF. Most if this is simple stack logic, and that exists on all .NET platforms.

Read more after the jump.

Tuesday, November 23, 2010

Postfix expression parser.

A question on DreamInCode lead me to my old nemesis, the Postfix expression parser. I'd fallen in love with a Reverse Polish Notation calculator in high school (the HP-32SII, they sadly don't make them anymore). When I tried to program a RPNC to use on my PC years ago, I failed miserably. But I've learned a lot since then, and I figured I could at least try a simple postfix parser.

It wasn't that bad. You don't have to check for a lot of things a calculator does. Here's the body of the code. I made it static, since you really don't need to instantiate it. If I ever make it into a calculator, I'd probably make it non-static, and make the stack a class-level field.

class PostfixParser
{
    const string Placeholder = "[x]";

    private static Dictionary<string, Func<double, double, double>> op;

    private static List<string> operators = new List<string>() { "+", "-", "*", "/" };

    static PostfixParser()
    {
        op = new Dictionary<string, Func<double, double, double>>();
        op.Add("+", (x, y) => x + y);
        op.Add("-", (x, y) => x - y);
        op.Add("*", (x, y) => x * y);
        op.Add("/", (x, y) => x / y);
        op.Add("^", (x, y) => Math.Pow(x, y));
    }

    public static double ParseExp(string exp, double? val)
    {
        string[] tokens = exp.Split(new string[] { " " } , StringSplitOptions.RemoveEmptyEntries);
        if (tokens.Contains(Placeholder) && val == null)
            throw new InvalidOperationException("Placeholder token detected in expression, but parameter \"val\" was null.");
        Stack<double> stack = new Stack<double>();
        foreach (string token in tokens)
        {
            if (operators.Contains(token))
            {
                if (stack.Count < 2)
                    throw new InvalidOperationException("Operator imbalance.");
                double y = stack.Pop();
                double x = stack.Pop();
                stack.Push(op[token](x, y));
            }
            else
            {
                double n;
                if (token == Placeholder)
                    n = val.Value;
                else if (!double.TryParse(token, out n))
                    throw new InvalidOperationException("Invalid token detected: " + token);
                stack.Push(n);
            }
        }

        if (stack.Count > 1)
            throw new InvalidOperationException("More than one result on the stack.");
        if (stack.Count < 1)
            throw new InvalidOperationException("No results on the stack.");
        return stack.Pop();
    }

    public static double ParseExp(string exp)
    {
        return ParseExp(exp, null);
    }
}

This can be used like this:
string fToCExp = "5 9 / [x] 32 - *";
string cToFExp = "9 5 / [x] * 32 + ";
Console.WriteLine("100C converted to F:");
Console.WriteLine(PostfixParser.ParseExp(cToFExp, 100));
Console.WriteLine("32F converted to C:");
Console.WriteLine(PostfixParser.ParseExp(fToCExp, 32));
Console.ReadKey();

To give an output of:

100C converted to F:
212
32F converted to C:
0

You could add more operators if you wished, like a 1/x or a SQRT, but since most other operators are unary rather than binary, you'd have to change your popping logic.

Note: I did it with a placeholder value in mind. I used "[x]" for whatever reason, but it could be anything that won't parse into a double by itself or match one of the operators. You could remove this altogether, if you cared to.

Tuesday, October 26, 2010

More extension methods: To and In. Also, a static class to make Sequences.

It's been quite a while since I posted. I've been quite busy with work. But without further ado, here's a static class I've been working on (code after the break):