Sorting represented data from a dictionary
Question: I am trying to sort my data, something similar to sorting example in here:
<http://www.blog.pythonlibrary.org/2011/01/04/wxpython-wx-listctrl-tips-and-
tricks/>

But for some reason when my data is represented in the table, things are all
over the place. For example, the computer name does not match the owner. At
first I though that the dictionary was not create correctly. But then I tried
printing it and the dictionary looks perfectly fine. So, the error must be
somewhere in lines with list_ctrl. Do you see where my mistake is?

    
    
    #!/usr/bin/env python
    import wx
    import wx.lib.mixins.listctrl as listmix
    import csv
    from wxPython.wx import *
    
    key_index = 4
    
    ##########################################################################
    info = csv.reader(open(report.csv', 'rb'),delimiter=',')
    length = 0
    info_list = []
    
    for row in info: #search each row in the report
        info_list.append([length,row[1],row[4]])
        length = length + 1
    
    dict_info = {}
    rows = 0
    
    for item in info_list:
        dict_info[item[rows]] = (item[rows + 1], item[rows + 2])
    ####################################################################
    class TestListCtrl(wx.ListCtrl):
        def __init__(self, parent, ID=wx.ID_ANY, pos=wx.DefaultPosition,
                        size=wx.DefaultSize, style=0):
            wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
    ########################################################################
    class TestListCtrlPanel(wx.Panel, listmix.ColumnSorterMixin):
        def __init__(self, parent):
            wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS)
            self.index = 0
    
            self.list_ctrl = TestListCtrl(self, size=(-1,100),style=wx.LC_REPORT
                                            |wx.BORDER_SUNKEN|wx.LC_SORT_ASCENDING)
            self.list_ctrl.InsertColumn(0, "Computer Name")
            self.list_ctrl.InsertColumn(1, "Owner")
    
            items = dict_info.items()
            index = 0
            for key, data in items:
                self.list_ctrl.InsertStringItem(self.index, data[0])
                self.list_ctrl.SetStringItem(self.index, 1, data[1])
                self.list_ctrl.SetItemData(self.index, key)
                index += 1
    
            # Now that the list exists we can init the other base class,
            # see wx/lib/mixins/listctrl.py
            self.itemDataMap = dict_info
            listmix.ColumnSorterMixin.__init__(self, 2)
            self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick, self.list_ctrl)
    
            sizer = wx.BoxSizer(wx.VERTICAL)
            sizer.Add(self.list_ctrl, 0, wx.ALL|wx.EXPAND, 5)
            self.SetSizer(sizer)
    
        #----------------------------------------------------------------------
        # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
        def GetListCtrl(self):
            return self.list_ctrl
    
        #----------------------------------------------------------------------
        def OnColClick(self, event):
            print "column clicked"
            event.Skip()
    
    ########################################################################
    
    ###################################################################
    
    
    class MyFrame(wx.Frame):
        def __init__(self):
            wx.Frame.__init__(self, None, wx.ID_ANY, 
                                "Search")
    
            panel = TestListCtrlPanel(self) #create a panel
    
    
    #run code
    if __name__ == '__main__':
        app = wx.App(False)
        frame = MyFrame()
        frame.Show()
        app.MainLoop()
    


Answer: Looks like you copied and pasted my code but changed a critical piece. You
need to change the for loop in your **init** to look like this:

    
    
    for key, data in items:
        print "%s: %s - %s" % (key, data[0], data[1])
        print
        self.list_ctrl.InsertStringItem(index, data[0])
        self.list_ctrl.SetStringItem(index, 1, data[1])
        self.list_ctrl.SetItemData(index, key)
        index += 1
    

The "self.index" that I left in my example is set to zero, but I never use it
in that loop. Instead I create a local variable called **index** and use that
instead. I have fixed my article by removing the **self.index** bit since it
is unneeded in that particular example.

In your code, you increment index, but use self.index in all your
self.list_ctrl.*() methods.

