Recursive get/set/has-attr

def _getattr(obj, attr, default=None):
    try: left, right = attr.split('.', 1)
    except: return getattr(obj, attr, default)
    return _getattr(getattr(obj, left), right, default)

def _setattr(obj, attr, val):
    try: left, right = attr.split('.', 1)
    except: return setattr(obj, attr, val)
    return _setattr(getattr(obj, left), right, val)

def _hasattr(obj, attr):
    try: left, right = attr.split('.', 1)
    except: return hasattr(obj, attr)
    return _hasattr(getattr(obj, left), right)


class C(object): pass

a = C()
a.b = C()
a.b.c = 4
assert _getattr(a, 'b.c') == 4

_setattr(a, 'b.c', 2)
assert a.b.c == 2

assert _hasattr(a, 'b.c')

Thread-Safe Observable List for WPF

I’m probably posting this too early; I haven’t had a chance to extensively test it yet but I basically just locked every function down, and made any method that actually modifies the list run on the main thread so that notifications can be sent. It ought to work :)

class ObservableList<T> : IList<T>, INotifyCollectionChanged where T : INotifyPropertyChanged
{
    private Dispatcher dispatcher;
    private List<T> list;
    private object sync;

    public ObservableList(Dispatcher dispatcher = null)
    {
        this.dispatcher = dispatcher ?? Dispatcher.CurrentDispatcher;
        this.list = new List<T>();
        this.sync = new object();
    }

    public event NotifyCollectionChangedEventHandler CollectionChanged;

    public virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        lock (sync)
        {
            if (CollectionChanged != null)
            {
                CollectionChanged(this, e);
            }
        }
    }

    public int IndexOf(T item)
    {
        lock (sync)
        {
            return list.IndexOf(item);
        }
    }

    public void Insert(int index, T item)
    {
        if (dispatcher.CheckAccess())
        {
            lock (sync)
            {
                list.Insert(index, item);
                OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index));
            }
        }
        else
        {
            dispatcher.Invoke(new Action<int, T>(Insert), DispatcherPriority.Send, index, item);
        }
    }

    public void RemoveAt(int index)
    {
        if (dispatcher.CheckAccess())
        {
            lock (sync)
            {
                var item = list[index];
                list.RemoveAt(index);
                OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index));
            }
        }
        else
        {
            dispatcher.Invoke(new Action<int>(RemoveAt), DispatcherPriority.Send, index);
        }
    }

    public T this[int index]
    {
        get
        {
            lock (sync) { return list[index]; }
        }
        set
        {
            lock (sync) { list[index] = value; }
        }
    }

    public void Add(T item)
    {
        if (dispatcher.CheckAccess())
        {
            lock (sync)
            {
                list.Add(item);
                OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
            }
        }
        else
        {
            dispatcher.Invoke(new Action<T>(Add), DispatcherPriority.Send, item);
        }
    }

    public void Clear()
    {
        if (dispatcher.CheckAccess())
        {
            lock (sync)
            {
                list.Clear();
                OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
            }
        }
        else
        {
            dispatcher.Invoke(new Action(Clear), DispatcherPriority.Send);
        }
    }

    public bool Contains(T item)
    {
        lock (sync) { return list.Contains(item); }
    }

    public void CopyTo(T[] array, int arrayIndex)
    {
        lock (sync) { list.CopyTo(array, arrayIndex); }
    }

    public int Count
    {
        get { lock (sync) { return list.Count; } }
    }

    public bool IsReadOnly
    {
        get { return false; }
    }

    public bool Remove(T item)
    {
        if (dispatcher.CheckAccess())
        {
            lock (sync)
            {
                var index = list.IndexOf(item);
                var result = list.Remove(item);
                OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index));
                return result;
            }
        }
        else
        {
            return (bool)dispatcher.Invoke(new Func<T, bool>(Remove), DispatcherPriority.Send, item);
        }
    }

    public IEnumerator<T> GetEnumerator()
    {
        lock (sync)
        {
            return list.GetEnumerator();
        }
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

You can simply delete the “where T : INotifyPropertyChanged” if you don’t like that restriction, but I put it there so that you don’t forget that your objects should notify your controls that their properties have changed, so that the GUI gets refreshed properly.

Posted in

Thread-Safe Observable Priority Queue for WPF

Building on my last post, I realized that you couldn’t push elements onto the queue from a worker thread, making it pretty much useless. However, if we dispatch the pushes back to the UI thread, it should work, right?

Here’s (what I believe to be) a thread-safe observable priority queue with notifications for use in WPF.

class PriorityQueue<TValue, TPriority> : IEnumerable<TValue>, INotifyCollectionChanged
    where TValue : INotifyPropertyChanged
    where TPriority : IComparable
{
    private SortedDictionary<TPriority, Queue<TValue>> dict;
    private int count;
    private Dispatcher dispatcher;

    public int Count { get { return count; } }
    public bool Empty { get { return Count == 0; } }

    public PriorityQueue(Dispatcher dispatcher = null)
    {
        this.dispatcher = dispatcher ?? Dispatcher.CurrentDispatcher;
        this.count = 0;
        this.dict = new SortedDictionary<TPriority, Queue<TValue>>(new ReverseComparer());
    }

    private class ReverseComparer : IComparer<TPriority>
    {
        public int Compare(TPriority x, TPriority y) { return y.CompareTo(x); }
    }

    public virtual void Push(TValue val, TPriority pri = default(TPriority))
    {
        if (dispatcher.CheckAccess())
        {
            ++count;
            if (!dict.ContainsKey(pri)) dict[pri] = new Queue<TValue>();
            dict[pri].Enqueue(val);
            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, val));
        }
        else
        {
            dispatcher.Invoke(new Action<TValue, TPriority>(Push), DispatcherPriority.Send, val, pri);
        }
    }

    public virtual TValue Peek()
    {
        return dict.First().Value.Peek();
    }

    public virtual TValue Pop()
    {
        if (dispatcher.CheckAccess())
        {
            --count;
            var pair = dict.First();
            var queue = pair.Value;
            var val = queue.Dequeue();
            if (queue.Count == 0) dict.Remove(pair.Key);
            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, val));
            return val;
        }
        else
        {
            return (TValue)dispatcher.Invoke(new Func<TValue>(Pop), DispatcherPriority.Send);
        }
    }

    public event NotifyCollectionChangedEventHandler CollectionChanged;

    public virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        if (CollectionChanged != null)
        {
            CollectionChanged(this, e);
        }
    }

    public IEnumerator<TValue> GetEnumerator()
    {
        foreach (var queue in dict.Values)
        {
            foreach (var value in queue)
            {
                yield return value;
            }
        }
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

Read this blog post to find out how this works.

Observable Priority Queue

Just started playing around with WPF in VS 2010. They have this ObservableCollection class which you can bind to your DataGrid or ListControl and then when you add or remove items from it, the control is refreshed automatically. However, I wanted to use my PriorityQueue class that I posted about earlier, so I modified it a bit:

class PriorityQueue<TValue> : PriorityQueue<TValue, int> where TValue : INotifyPropertyChanged { }
class PriorityQueue<TValue, TPriority> : IEnumerable<TValue>, INotifyCollectionChanged
    where TValue : INotifyPropertyChanged
    where TPriority : IComparable
{
    private SortedDictionary<TPriority, Queue<TValue>> dict = new SortedDictionary<TPriority, Queue<TValue>>(new ReverseComparer());
    private int count = 0;

    public int Count { get { return count; } }
    public bool Empty { get { return Count == 0; } }

    private class ReverseComparer : IComparer<TPriority>
    {
        public int Compare(TPriority x, TPriority y) { return y.CompareTo(x); }
    }

    public void Enqueue(TValue val, TPriority pri = default(TPriority))
    {
        ++count;
        if (!dict.ContainsKey(pri)) dict[pri] = new Queue<TValue>();
        dict[pri].Enqueue(val);
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, val));
    }

    public TValue Dequeue()
    {
        --count;
        var pair = dict.First();
        var queue = pair.Value;
        var val = queue.Dequeue();
        if (queue.Count == 0) dict.Remove(pair.Key);
        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, val));
        return val;
    }

    public event NotifyCollectionChangedEventHandler CollectionChanged;

    public virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        if (CollectionChanged != null)
        {
            CollectionChanged(this, e);
        }
    }

    public IEnumerator<TValue> GetEnumerator()
    {
        foreach (var queue in dict.Values)
        {
            foreach (var value in queue)
            {
                yield return value;
            }
        }
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

Priorities are sorted in descending order (higher value = higher priority).

Also discovered that I could just use “yield return” instead of having to write a custom Enumerator class too! Very nice. Especially since I wouldn’t have known how to write it :)

Human-readable file size in C#

static string ReadableFileSize(double size, int unit = 0)
{
    string[] units = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB" };

    while (size >= 1024)
    {
        size /= 1024;
        ++unit;
    }

    return String.Format("{0:G4} {1}", size, units[unit]);
}

I made “bytes” a double so you could pass in fractions, which you might get when calculating download speeds.

A Simple Priority Queue in C#

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

namespace QueueSpace
{
    public class PriorityQueue<TValue> : PriorityQueue<TValue, int> { }

    public class PriorityQueue<TValue, TPriority> where TPriority : IComparable
    {
        private SortedDictionary<TPriority, Queue<TValue>> dict = new SortedDictionary<TPriority, Queue<TValue>>();

        public int Count { get; private set; }
        public bool Empty { get { return Count == 0; } }

        public void Enqueue(TValue val)
        {
            Enqueue(val, default(TPriority));
        }

        public void Enqueue(TValue val, TPriority pri)
        {
            ++Count;
            if (!dict.ContainsKey(pri)) dict[pri] = new Queue<TValue>();
            dict[pri].Enqueue(val);
        }

        public TValue Dequeue()
        {
            --Count;
            var item = dict.Last();
            if (item.Value.Count == 1) dict.Remove(item.Key);
            return item.Value.Dequeue();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var pq = new PriorityQueue<int>();

            for (int i = 0; i < 10; ++i)
            {
                pq.Enqueue(i,i/2);
            }
            while (!pq.Empty)
            {
                Console.Write(pq.Dequeue() + " ");
            }

            Console.ReadKey();
        }
    }
}

Output

8 9 6 7 4 5 2 3 0 1

Items with the same priority are dequeued in the same order that they were inserted.

Django Send HTML Emails

You can use this little function to load emails from a template and send them in both HTML and plaintext formats.

from django.core.mail import EmailMultiAlternatives
from django.template import loader, Context
from django.conf import settings

def send_multipart_email(subject, template, data_dict, recipient_list, from_email=settings.DEFAULT_FROM_EMAIL):
    if type(recipient_list) != list: recipient_list = [recipient_list]
   
    tt = loader.get_template(template+'.txt')
    c = Context(data_dict)
   
    e = EmailMultiAlternatives(subject, tt.render(c), from_email, recipient_list)
   
    try:
        ht = loader.get_template(template+'.html')
        e.attach_alternative(ht.render(c), 'text/html')
    except:
        pass
   
    e.send()

.NET Dock Panel

Apparently .NET does not come with any dock widget, like the ones used for the Toolbox and Properties window in Visual Studio. However, there is a freely available one on sourceforge called DockPanel Suite. Unfortunately, it seems to lack any sort of documentation!

This little code snippet below should be enough to get you started though. Just make sure you your form’s IsMdiContainer property to True first.

public Form1() {
    InitializeComponent();

    glControl.Load += new System.EventHandler(glControl_Load);
    glControl.Paint += new System.Windows.Forms.PaintEventHandler(glControl_Paint);
    glControl.Dock = DockStyle.Fill;

    var dockPanel = new DockPanel();
    dockPanel.Dock = DockStyle.Fill;
    Controls.Add(dockPanel);
    dockPanel.BringToFront();

    var mainDock = new DockContent();
    mainDock.ShowHint = DockState.Document;
    mainDock.TabText = "untitled1";
    mainDock.Controls.Add(glControl);
    mainDock.Show(dockPanel);

    var propGrid = new PropertyGrid();
    propGrid.Dock = DockStyle.Fill;

    var propertyDock = new DockContent();
    propertyDock.Controls.Add(propGrid);
    propertyDock.ShowHint = DockState.DockRight;
    propertyDock.TabText = "Properties";
    propertyDock.Show(dockPanel);
}

C# Blocking Queue

If you’re writing a threaded application in C# and you need to wait until a resource becomes available, you can use this class. Very handy for producer/consumer scenarios.

public class BlockingQueue<T>
{
    Queue<T> que = new Queue<T>();
    Semaphore sem = new Semaphore(0, Int32.MaxValue);

    public void Enqueue(T item)
    {
        lock (que)
        {
            que.Enqueue(item);
        }

        sem.Release();
    }

    public T Dequeue()
    {
        sem.WaitOne();

        lock (que)
        {
            return que.Dequeue();
        }
    }
}

Django, Flatpages, Markdown, and Syntax Highlighting

For what should have been an easy task, this turned out to be extraordinarily difficult.

I assume you have Django already installed. If not, the tutorials on djangoproject.com aren’t too terrible, provided you’re not on a shared server (that’s another story!). I’m using Flatpages, but you can use whatever you want to follow along with this tutorial.

1. Install Markdown and Pygments for Python if you haven’t already. If you’re on Ubuntu, you can `sudo apt-get install python-markdown` or `easy_install Markdown` and `sudo apt-get install python-pygments`.

2. Go into your Django app and `mkdir templatetags`. This should be at the same level as `manage.py`, `settings.py` and `urls.py`. Then `cd` into that directory, and `touch __init__.py` (so that it becomes a module) and then add another file called something like `tags.py` (don’t name it “markdown.py” — that’ll bite you later). Paste this code in there:

from django import template
from django.template.defaultfilters import stringfilter

from django.conf import settings

register = template.Library()

@register.filter(name='markdown')
@stringfilter
def markdown(value, arg=''):
    """
    Filter to create HTML out of Markdown, using custom extensions.

    The diffrence between this filter and the django-internal markdown
    filter (located in ``django/contrib/markup/templatetags/markup.py``)
    is that this filter enables extensions to be load.

    Usage::

        {{ object.text|markdown }}
        {{ object.text|markdown:"save" }}
        {{ object.text|markdown:"codehilite" }}
        {{ object.text|markdown:"save,codehilite" }}

    This code is taken from
    http://www.freewisdom.org/projects/python-markdown/Django
    """

    try:
        import markdown
    except ImportError:
        if settings.DEBUG:
            raise (template.TemplateSyntaxError,
                   "Error in {% markdown %} filter: "
                   + "The markdown library isn't installed.")
        else :
            from django.utils.html import escape, linebreaks
            return linebreaks(escape(value))
    else:
        extensions=arg.split(",")
        if len(extensions) > 0 and extensions[0] == "safe" :
            extensions = extensions[1:]
            safe_mode = True
        else :
            safe_mode = False
        return markdown.markdown(value, extensions, safe_mode=safe_mode)

Yes, I’m leaving the link in there; I didn’t write that code.

3. Go into `settings.py` and add your app to the `INSTALLED_APPS`. You actually have to `import` your own app too; this baffled me for about an hour. My app is called `tech_eval` so my `INSTALLED_APPS` looks like this:

import tech_eval # you can put this line at the top of settings.py if you want

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.admin',
    'django.contrib.flatpages',
    'tech_eval',
)

4. Like I said, I’m using Flatpages, so my template looks like this (I saved it to djangoproject/app/templates/flatpages/default.html).

{% load tags %}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
    <title>{{ flatpage.title }}</title>
    <link rel="stylesheet" type="text/css" href="/tech_eval/media/css/code_style.css" />
</head>
<body>
    <h1>{{ flatpage.title }}</h1>
    {{ flatpage.content|markdown:"codehilite"|safe}}
</body>
</html>

Notice how we filter the content with markdown, make sure the codehilite extension is used, and flag it as `safe` afterwords (otherwise Django will automatically character-encode everything).

5. Hopefully this is already working for you at this point, but you probably want to add some color to your code. You can generate the appropriate css file with this:

pygmentize -f html -S default -a .codehilite >> code_style.css

Some different styles you can use (at least on my system) are:

['manni', 'colorful', 'murphy', 'autumn', 'bw', 'pastie', 'native', 'perldoc', 'borland', 'trac', 'default', 'fruity', 'emacs', 'friendly']

(stolen from here).

Or just copy and paste this CSS file if you’re lazy:

.codehilite .c { color: #408080; font-style: italic } /* Comment */
.codehilite .err { border: 1px solid #FF0000 } /* Error */
.codehilite .k { color: #008000; font-weight: bold } /* Keyword */
.codehilite .o { color: #666666 } /* Operator */
.codehilite .cm { color: #408080; font-style: italic } /* Comment.Multiline */
.codehilite .cp { color: #BC7A00 } /* Comment.Preproc */
.codehilite .c1 { color: #408080; font-style: italic } /* Comment.Single */
.codehilite .cs { color: #408080; font-style: italic } /* Comment.Special */
.codehilite .gd { color: #A00000 } /* Generic.Deleted */
.codehilite .ge { font-style: italic } /* Generic.Emph */
.codehilite .gr { color: #FF0000 } /* Generic.Error */
.codehilite .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.codehilite .gi { color: #00A000 } /* Generic.Inserted */
.codehilite .go { color: #808080 } /* Generic.Output */
.codehilite .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
.codehilite .gs { font-weight: bold } /* Generic.Strong */
.codehilite .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.codehilite .gt { color: #0040D0 } /* Generic.Traceback */
.codehilite .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
.codehilite .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
.codehilite .kp { color: #008000 } /* Keyword.Pseudo */
.codehilite .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
.codehilite .kt { color: #B00040 } /* Keyword.Type */
.codehilite .m { color: #666666 } /* Literal.Number */
.codehilite .s { color: #BA2121 } /* Literal.String */
.codehilite .na { color: #7D9029 } /* Name.Attribute */
.codehilite .nb { color: #008000 } /* Name.Builtin */
.codehilite .nc { color: #0000FF; font-weight: bold } /* Name.Class */
.codehilite .no { color: #880000 } /* Name.Constant */
.codehilite .nd { color: #AA22FF } /* Name.Decorator */
.codehilite .ni { color: #999999; font-weight: bold } /* Name.Entity */
.codehilite .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
.codehilite .nf { color: #0000FF } /* Name.Function */
.codehilite .nl { color: #A0A000 } /* Name.Label */
.codehilite .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
.codehilite .nt { color: #008000; font-weight: bold } /* Name.Tag */
.codehilite .nv { color: #19177C } /* Name.Variable */
.codehilite .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
.codehilite .w { color: #bbbbbb } /* Text.Whitespace */
.codehilite .mf { color: #666666 } /* Literal.Number.Float */
.codehilite .mh { color: #666666 } /* Literal.Number.Hex */
.codehilite .mi { color: #666666 } /* Literal.Number.Integer */
.codehilite .mo { color: #666666 } /* Literal.Number.Oct */
.codehilite .sb { color: #BA2121 } /* Literal.String.Backtick */
.codehilite .sc { color: #BA2121 } /* Literal.String.Char */
.codehilite .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
.codehilite .s2 { color: #BA2121 } /* Literal.String.Double */
.codehilite .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
.codehilite .sh { color: #BA2121 } /* Literal.String.Heredoc */
.codehilite .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
.codehilite .sx { color: #008000 } /* Literal.String.Other */
.codehilite .sr { color: #BB6688 } /* Literal.String.Regex */
.codehilite .s1 { color: #BA2121 } /* Literal.String.Single */
.codehilite .ss { color: #19177C } /* Literal.String.Symbol */
.codehilite .bp { color: #008000 } /* Name.Builtin.Pseudo */
.codehilite .vc { color: #19177C } /* Name.Variable.Class */
.codehilite .vg { color: #19177C } /* Name.Variable.Global */
.codehilite .vi { color: #19177C } /* Name.Variable.Instance */
.codehilite .il { color: #666666 } /* Literal.Number.Integer.Long */
.codehilitetable { border: 1px solid #666; width: 100%; background-color: #666; }
.codehilitetable .linenos { background-color: #666; padding: 0 5px; width: 20px; }
.codehilitetable .code { padding: 0 15px; background-color: #fff; }

And that should pretty much be it. Let me know if I missed anything or this was too difficult to follow along.