wxGrid Daten aus Listen

Plattformunabhängige GUIs mit wxWidgets.
Antworten
ete
User
Beiträge: 218
Registriert: Montag 19. Februar 2007, 13:19
Kontaktdaten:

Hallo!

Folgender Code funktioniert problemlos:

Code: Alles auswählen

import wx
import wx.grid

data = [[65.0, 'HO13D22_R08d21', '20', '13', '36..48 HO13D22_R08d21', '...TGGTGGCTGGTCG...\n   |||||||||||||\nATGGTGGCTGGTCGTAATGG']
,[55.0, 'HW06J24', '20', '11', '52..42 HW06J24', '...GCCACCACCAA...\n   |||||||||||\nGCCACCACCAAAGTCAAATG']
,[55.0, 'HO14B24', '20', '11', '162..152 HO14B24', '...ACTCAATCCCG...\n   |||||||||||\nCATGCAGGTACTCAATCCCG']
,[55.0, 'HO10M21', '20', '11', '52..42 HO10M21', '...GCCACCACCAA...\n   |||||||||||\nGCCACCACCAAAGTCAAATG']
,[55.0, 'HO10D21_R06b22', '20', '11', '299..289 HO10D21_R06b22', '...GCCTTCAAGAT...\n   |||||||||||\nGCTCATGCCTTCAAGATCCG']
,[55.0, 'HK04J17', '20', '11', '49..59 HK04J17', '...GTTTGGGTTGG...\n   |||||||||||\nAGCCTGTTTGGGTTGGATGT']]

data.sort()

colLabels = ("% matching", "primer name", "primer length", "match length", "binding position", "sequence")


class GenericTable(wx.grid.PyGridTableBase):
            
    def __init__(self, data, colLabels=None):
        wx.grid.PyGridTableBase.__init__(self)
        self.data = data
        self.colLabels = colLabels

        self.odd=wx.grid.GridCellAttr()
        face = 'Courier'
        self.odd.SetFont(wx.Font(10, wx.DEFAULT, wx.NORMAL, wx.NORMAL, False, face))
         
    def GetNumberRows(self):
        return len(self.data)

    def GetNumberCols(self):
        return len(self.data[0])

    def GetColLabelValue(self, col):
        if self.colLabels:
            return self.colLabels[col]
              
    def IsEmptyCell(self, row, col):
        return False

    def GetValue(self, row, col):
        return self.data[row][col]

    def SetValue(self, row, col, value):
        pass

    def GetAttr(self, row, col, kind):
        attr = self.odd
        attr.IncRef()
        return attr
                  
class SimpleGrid(wx.grid.Grid):
    def __init__(self, parent):
        wx.grid.Grid.__init__(self, parent, -1)
        tableBase = GenericTable(data, colLabels)
        self.SetTable(tableBase)
        self.SetDefaultRowSize(55, True)
        self.SetColSize(1, 200)
        self.SetColSize(2, 100)
        self.SetColSize(3, 100)
        self.SetColSize(4, 250)
        self.SetColSize(5, 450)
        self.SetCellAlignment(1, 1, wx.CENTRE, wx.CENTRE)       

class TestFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, -1, "A Grid", 
                size=(1280, 1024))
        grid = SimpleGrid(self)

if __name__ == '__main__':
    app = wx.PySimpleApp()
    frame = TestFrame(None)
    frame.Show(True)
    app.MainLoop()
Nun möchte ich die Daten (Listen) aber aus einer txt Datei laden. Ich habs so probiert bekomme aber immer unzufriedene Ergebnisse.

Code: Alles auswählen

data = open('liste.txt', 'r')
data = data.read()
print type(data), data
Wobei readline(s) auch nicht funzt, sowie das ganze in eine Liste umzuwandeln...Irgendwie werden immer alle Wörte in Buchstaben gesplittet...

Kann jemand helfen?

Liebe Grüsse
Stefanie
BlackJack

Mit `read()` liesst Du die gesamte Datei als eine Zeichenkette ein. Mit `readlines()` bekommst Du eine Liste mit den Zeilen der Datei.

Wie sieht denn der Dateiinhalt aus und wie soll `data` nach dem einlesen aussehen? Und kann es sein, dass die Frage letztendlich gar nichts mit der GUI zu tun hat!?
ete
User
Beiträge: 218
Registriert: Montag 19. Februar 2007, 13:19
Kontaktdaten:

Der Dateninhalt sieht so aus :

[55.0, 'HW06J24', '20', '11', '52..42 HW06J24', '...GCCACCACCAA...\n |||||||||||\nGCCACCACCAAAGTCAAATG']
[55.0, 'HO14B24', '20', '11', '162..152 HO14B24', '...ACTCAATCCCG...\n |||||||||||\nCATGCAGGTACTCAATCCCG']

Und er soll eingelesen so aussehen:

data = [[55.0, 'HW06J24', '20', '11', '52..42 HW06J24', '...GCCACCACCAA...\n |||||||||||\nGCCACCACCAAAGTCAAATG'],
[55.0, 'HO14B24', '20', '11', '162..152 HO14B24', '...ACTCAATCCCG...\n |||||||||||\nCATGCAGGTACTCAATCCCG']]

Ich habs hier gepostet weil ich die Liste ja einlesen kann, aber sie merkwürdig in die Zellen gepackt wird.

print data, type(data):
<type 'list'> ["['100.0', 'ARM-TS-10F', '25', '25', '312..288 ARM-TS-10F', '...AGCCTTCAAGATTTGAGCACCACAG...\\n|||||||||||||||||||||||||\\nAGCCTTCAAGATTTGAGCACCACAG']\n", "['88.0', 'ARM-EXON2-F1', '26', '23', '316..294 ARM-EXON2-F1', '...CAAGATTTGAGCACCACAGGCAA...\\n |||||||||||||||||||||||\\nCAAGATTTGAGCACCACAGGCAACAG']\n"]

Error ist folgender (unter readlines()):
Traceback (most recent call last):
File "J:\Blast\grid\grid.py", line 41, in GetColLabelValue
return self.colLabels[col]
IndexError: tuple index out of range

Er packt halt jedes Zeichen in eine Zelle.
BlackJack

Du kannst die Listen so nicht als Listen einlesen. Schau Dir noch einmal genau an wass Du da hast: Eine Liste von *Zeichenketten* und keine Liste von Listen mit Zeichenketten.

Was Du hast ist so etwas:

Code: Alles auswählen

In [173]: a = ["['a', 'b']", "['c', 'd']"]

In [174]: a[0]
Out[174]: "['a', 'b']"

In [175]: a[0][0]
Out[175]: '['

In [176]: a[0][1]
Out[176]: "'"

In [177]: a[0][2]
Out[177]: 'a'
Was Du möchtest ist das hier:

Code: Alles auswählen

In [178]: b = [['a', 'b'], ['c', 'd']]

In [179]: b[0]
Out[179]: ['a', 'b']

In [180]: b[0][0]
Out[180]: 'a'

In [181]: b[0][1]
Out[181]: 'b'
Es wäre einfacher, wenn die Daten nicht so "komisch" vorliegen würden, sondern zum Beispiel als CSV-Datei. Falls das schreiben der Daten bei Dir liegt, solltest Du das ändern.

So bleibt als schnelle quick'n'dirty Lösung nur ``eval``.
ete
User
Beiträge: 218
Registriert: Montag 19. Februar 2007, 13:19
Kontaktdaten:

Danke für die Erklärung und den Tip mit csv.
Ich versuchs mal damit...Wenn ich Probleme habe meld ich mich nochmal!

Liebe Grüsse
Stefanie
ete
User
Beiträge: 218
Registriert: Montag 19. Februar 2007, 13:19
Kontaktdaten:

Hallo!

Ich habs hinbekommen, das die Daten nicht so 'komisch' vorliegen:

Text File Input:

100.0;ARM-TS-10F;25;25;312..288 ARM-TS-10F;...AGCCTTCAAGATTTGAGCACCACAG...|||||||||||||||||||||||||AGCCTTCAAGATTTGAGCACCACAG
88.0;ARM-EXON2-F1;26;23;316..294 ARM-EXON2-F1;...CAAGATTTGAGCACCACAGGCAA...|||||||||||||||||||||||CAAGATTTGAGCACCACAGGCAACAG
96.0;ARM-TS-3F;23;22;28..7 ARM-TS-3F;...GCATTTCCTTGTTGCTTCCCCA...||||||||||||||||||||||GCATTTCCTTGTTGCTTCCCCAG

Und ich schreibs dann so in ein Grid:

Code: Alles auswählen

quellname = "quelle.txt"
f = file(quellname, "r") 
sn = csv.Sniffer() 
dialect = sn.sniff(f.readline()) 
f.seek(0)

data = [] 
for fields in csv.reader(f, dialect = dialect): 
    data.append(fields)   
f.close()
Leider gibts jetzt folgende Probleme:

1.) \n funktioniert nicht mehr (csv und txt)

Bsp.
...GCATTTCCTTGTTGCTTCCCCA...\n||||||||||||||||||||||\nGCATTTCCTTGTTGCTTCCCCAG

soll in einer Zelle so dargestellt werden:

...GCATTTCCTTGTTGCTTCCCCA...
||||||||||||||||||||||
GCATTTCCTTGTTGCTTCCCCAG

2.) Ich kann nicht mehr nach dem ersten Wert sortieren, da dieser als string vorliegt...

Hat jemand eine Idee?

Liebe Grüsse
Stefanie
BlackJack

Zu 1): CSV darf auch Zeilenumbrüche enthalten:

Code: Alles auswählen

$ cat test.csv
65.0;HO13D22_R08d21;20;13;36..48 HO13D22_R08d21;"...TGGTGGCTGGTCG...
   |||||||||||||
ATGGTGGCTGGTCGTAATGG"
55.0;HW06J24;20;11;52..42 HW06J24;"...GCCACCACCAA...
   |||||||||||
GCCACCACCAAAGTCAAATG"
55.0;HO14B24;20;11;162..152 HO14B24;"...ACTCAATCCCG...
   |||||||||||
CATGCAGGTACTCAATCCCG"
55.0;HO10M21;20;11;52..42 HO10M21;"...GCCACCACCAA...
   |||||||||||
GCCACCACCAAAGTCAAATG"
55.0;HO10D21_R06b22;20;11;299..289 HO10D21_R06b22;"...GCCTTCAAGAT...
   |||||||||||
GCTCATGCCTTCAAGATCCG"
55.0;HK04J17;20;11;49..59 HK04J17;"...GTTTGGGTTGG...
   |||||||||||
AGCCTGTTTGGGTTGGATGT"
Zu 2): Die Zeichenketten beim Einlesen wieder in die entsprechenden Objekte umwandeln:

Code: Alles auswählen

import csv
from itertools import izip
from pprint import pprint

def convert_row(row):
    return [f(s) for f, s in izip((float, str, int, int, str, str), row)]

csv_file = open('test.csv', 'rb')
reader = csv.reader(csv_file, delimiter=';')
data = map(convert_row, reader)
csv_file.close()

pprint(data)
ete
User
Beiträge: 218
Registriert: Montag 19. Februar 2007, 13:19
Kontaktdaten:

Coole Sache 8) Wäre auch zu einfach gewesen :roll:

Hab mich gestern ewig lang mit den blöden Trennzeichen rumgeärgert :twisted:

Danke für deine Hilfe :D

Liebe Grüsse
Stefanie
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Hoi Stefanie,

vielleicht etwas spät für diesen Thread, aber: Warum machst Du Dir überhaupt die Mühe? biopython hat 1001 Parser für ebenjene Formate eingebaut, die Du verwendest. Warum selber ein Datenformat + Parser entwickeln?

Gruß,
Christian
ete
User
Beiträge: 218
Registriert: Montag 19. Februar 2007, 13:19
Kontaktdaten:

Hallo Christian!

Falls du die Sequenz Anzeige meinst:

Ich weiss, hab ich auch benutz. Mein Blast ist aber etwas ausergewöhnlich, da ich gegen eine Oligo Datenbank blaste. Also die subject sequence ist nicht grösser als 50 bp. Desshalb möchte ich mir gerne die full length subject sequence und den match part anzeigen lassen , welche ich über clustalw aligne. Deswegen der merkwürdige output...Ist aber für die Praxis eine bessere Ansicht.

Ich find Python übrigens so toll (auch wenn ich noch nicht so gut bin :roll: ) :!:
Man stelle sich vor: es haben sich ca. 5000 Primer angesammelt. Nun braucht sucht man für Gen x in einem bestimmten Bereich nen passenden Primer. Früher hab ich manuell gecheckt, nach ca. 20 Primern keinen Bock mehr gehabt und nen neuen bestellt. Heut benutz ich Python :D

Wollt ich nurmal loswerden :mrgreen:
ete
User
Beiträge: 218
Registriert: Montag 19. Februar 2007, 13:19
Kontaktdaten:

Hab mal wieder ein ein Problem:

Leider wird der Zeilenumbruch als dicker Schwarzer Balken angezeigt...Kann man das verhindern?

Zweites Problem:

Mein Grid Code hat ein Problem damit, wenn das CSV File leer ist.

Folgende Fehlermeldung:

Traceback (most recent call last):
File "J:\Blast\Final\grid.py", line 80, in <module>
frame = TestFrame(None)
File "J:\Blast\Final\grid.py", line 76, in __init__
grid = SimpleGrid(self)
File "J:\Blast\Final\grid.py", line 65, in __init__
self.SetColSize(1, 200)
File "C:\Python25\Lib\site-packages\wx-2.8-msw-unicode\wx\grid.py", line 1703, in SetColSize
return _grid.Grid_SetColSize(*args, **kwargs)
PyAssertionError: C++ assertion "col >= 0 && col < m_numCols" failed at ..\..\src\generic\grid.cpp(10350) in wxGrid::SetColSize(): invalid column index


Bei ausgefüllten File funktioniert alles...

Liebe Grüsse
Stefanie
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Zum ersten Problem: Keine Ahnung.
Zum zweiten Problem: In Python ist EAFP ("it's easier to ask forgiveness than
permission") üblich (sprich: try/except) in C/C++ LBYL ("look before you leap"). Wenn man C/C++-Code einbaut kann es bei den unterschiedlichen Philosophien zu Problemen kommen. Lange Rede, kurzer Sinn: Wenn Du die CSV-Datei ausliest, teste doch, ob Du was zurückbekommst oder nicht. Im zweiten Fall gib eine Fehlermeldung, die Du in der GUI mit einer Nachricht abfängst.

Gruß,
Christian
ete
User
Beiträge: 218
Registriert: Montag 19. Februar 2007, 13:19
Kontaktdaten:

Gut, vielleicht sollte ich es besser so erklären:

Ich schreib meine Daten in ein CSV File und öffne danach die Klasse Grid (also Daten werden als Grid angezeigt). Nur wenn das CSV File schon Daten enthält funktioniert es problemlos...

Code: Alles auswählen

#... 
        # Daten in csv file schreiben
        quellname = "new.csv"                       
        f = open(quellname, "a")
        f.writelines(daten)
        f.close()

        # Grid aufrufen
        self.show_grid()
#...
lg
Antworten