October 11, 2010

Recent months list in django

After a while I'm back with hot new stuff for you and me :) Recently I needed to select blog entries from 5 consecutive months (counting from current) to my footer archive list. The biggest problem was with the range of months in different years. After a lot of struggle I've came across a python module (probably you will have it in your default setup) `dateutil`, which gives new functionality to date related functions. Ok, so let's get to the code. My function was added to context processors to provide me functionality across whole site. Then we build a date object from current date. Next step is to run a generator expression (which I will speak about some more in the future as they're one of the most important features of python language together with coroutines and generator functions) for a increasing range of months (you can also use a list comprehension here if you need some additional lists functionality or a generator function. but I've tried to keep it simple). This gives us a generator object so we create a dictionary of it, with years as keys and corresponding months as dates. Because this dictionary provides us with numbers only, I've added additional function to translate them to string months values (note the brilliant Python's switch-case funcionality) here shown with Polish dictionary.

from datetime import datetime
from dateutil.relativedelta import relativedelta

def get_blog_archive(request):
    now = datetime.today()
    first_month = datetime(now.year, now.month, 1)
    previous_months = (first_month - relativedelta(months = months) for months in range(0, 5, 1))
    
    news_archive = {}
    for pm in previous_months:
        m = translate_month(pm.month)
        if news_archive.has_key(pm.year):
            news_archive[pm.year].append(m)
        else:
            news_archive[pm.year] = [m]
    m = translate_month(current_month)
    news_archive[current_year].append(m)
    
    return {'NEWS_ARCHIVE': news_archive,}

def translate_month(month):
    ret_month = ""
    months = {
            1: "Styczeń",
            2: "Luty",
            3: "Marzec",
            4: "Kwiecień",
            5: "Maj",
            6: "Czerwiec",
            7: "Lipiec",
            8: "Sierpień",
            9: "Wrzesień",
            10: "Październik",
            11: "Listopad",
            12: "Grudzień",
        }
    ret_month = months.get(month)
    return ret_month

Okay this code is nice but not really functional, beacuse we get months names as String (here with utf-8 chars) and its troublesome to parse them as urls. So here's a bit more functional approach :

    news_archive = []
    for pm in previous_months:
        d = datetime(pm.year,pm.month,1)
        news_archive.append(d)
    
    return {'NEWS_ARCHIVE': news_archive,}

And now in our template we just parse with for loop through list elements.
So that's all and stay tooned for some more advanced django examples. I'm doing a really big project right now but there's a ready shoutbox for django example, few implementations of django-registration, something about handling files and more :)

July 29, 2010

Conditional context processor for authenticated users

Recently I needed a context processor to display friends of my logged user. Userprofile is the name for extended user model. Here's the code :

def friends_list(request):
    try:
        user = request.user
    except User.DoesNotExist:
        user = AnonymousUser()
    
    userprofile = None
    try:
        userprofile = UserProfile.objects.get(user=request.user)
    except UserProfile.DoesNotExist:
        pass
    if userprofile:
        friends = Friend.objects.filter(friend_of=userprofile)
    else:
        friends = {}
    return {'friends': friends}

July 28, 2010

Python's lambda

Because I don't quite get what and when python's lambda function's can be of any use - I did some research. Then I've found this sleek way of calling one lined function with unnamed parameter :
>>> (lambda x: x*2)(3)
6
Pretty cool.

July 27, 2010

Scroll to top - the new way

Thing you will find useful at some point - how to scroll from random part of page to the top ? Here's a way how to obtain it with jQuery :

$(document).ready(function(){
  $('a[href=#]').click(function(){
    $.scrollTo(0,'slow');
    return false;
  });
});

But remember to include jQuery ScrollTo plugin in your imports. Now every link with hash as target will scroll your page back to the top with nice jquerish effect. Cooll huh ?

July 2, 2010

Random sort of array elements

Recently I came across problem of sorting randomly elements of some array. Here's what I came up with :
Pseudocode :

for each element in the array
calculate a random number with index range from 0 to array size -1
store the current element in a temporary variable
replace the current element in the array with the element at the random index
replace the element at random index with the element at temporary variable

Solution :
        int[] buttons = new int[16];

        for(int i=0; i<16; i++){
            buttons[i] = i;
        }

        int rand;
        int temp;
        Random random;

        random = new Random(System.currentTimeMillis());
        for (int i = 0; i < buttons.length; i++) {
            rand = (random.nextInt() & 0x7FFFFFFF) % buttons.length;
            temp = buttons[i];
            buttons[i] = buttons[rand];
            buttons[rand] = temp;
        }
stat4u