Viele verschachtelte Schleifen und PEP8

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
würmchen
User
Beiträge: 255
Registriert: Mittwoch 7. November 2007, 14:17

Viele verschachtelte Schleifen und PEP8

Beitragvon würmchen » Sonntag 31. August 2008, 15:46

Hi Leute,
ich wollt euch mal fragen wie ihr das macht, wenn ihr einfach mit den 80 Zeichen nicht auskommt. PEP8 gibt ja vor möglichst nicht mehr als 79 Zeichen zu nutzen und dann mit einem Backslash umzubrechen.

Ich hab jetzt gerade eine Aufgabe in der ich 8 Schleifen habe. Die ganzen sind dann in einer Funktion in einer Klasse definiert und somit schonmal von vornherein 8 Leerzeichen eingerückt. In der letzten Schleife hab ich dann nur noch 36 Zeichen übrig wenn ich mich an PEP8 halten will.

Ich würde mich mal über euren Rat freuen.
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Beitragvon audax » Sonntag 31. August 2008, 15:51

du solltest einfach keine 8-fach geschachtelten Schleifen nutzen.
würmchen
User
Beiträge: 255
Registriert: Mittwoch 7. November 2007, 14:17

Beitragvon würmchen » Sonntag 31. August 2008, 16:27

Also das Problem ist das die Daten leider so geschachtelt vorliegen.
Ich dachte auch schon ein eine Funktion die praktisch die Schleife darstellt (versteht man das).
Wollte halt mal die Tipps von den Fachmenschen hören...
EyDu
User
Beiträge: 4868
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Beitragvon EyDu » Sonntag 31. August 2008, 16:44

Die einzelnen Verschachtelungsebenen werden sicherlich irgend eine Bedeutung haben, daran kannst du dich beim Entwurf deiner Funktionen etwas orientieren. Im Normalfall wirst du sicher nicht mehr als zwei bis drei Verschachtelungen pro Funktion brauchen.
BlackJack

Beitragvon BlackJack » Sonntag 31. August 2008, 16:47

Bei so etwas bieten sich Generatorfunktionen an.

So eine tief verschachtelte Datenstruktur, bei der man in *einer* Funktion komplett durch greift, statt die entsprechenden Methoden auf den Objekten auf zu rufen könnte ein "code smell" sein.
epsilon
User
Beiträge: 71
Registriert: Freitag 20. Juni 2008, 19:48

Beitragvon epsilon » Montag 1. September 2008, 06:36

Also das Problem ist das die Daten leider so geschachtelt vorliegen.


Kannst du mal ein Beispiel für die Daten posten?
würmchen
User
Beiträge: 255
Registriert: Mittwoch 7. November 2007, 14:17

Beitragvon würmchen » Montag 1. September 2008, 08:07

Ich frage MySQL Tabellen ab, die Daten sind in insgesamt 93 Tabellen verteilt.

Beipiel, ein Entry kann mehrere Modelle haben, ein Modell kann mehrere Proteinketten haben, jede Proteinkette besteht aus mehreren Residues, Jedes Residue aus mehreren Atomen, Jedes atom hat 3 Koordinaten.

Ganz grob die Struktur....

Sind riesige Tabellen und ich denke es macht nicht so viel Sinn hier ausschnitte zu posten.



Ich bin gerade dabei mir mehr über Generatorfunktionen anzueigenen...
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Beitragvon audax » Montag 1. September 2008, 08:14

Dann Teil das in Unteraufgaben auf und pack die in eigene Funktionen
Mad-Marty
User
Beiträge: 317
Registriert: Mittwoch 18. Januar 2006, 19:46

Beitragvon Mad-Marty » Montag 1. September 2008, 08:49

Aufteilen zum einen, und die indent size auf 2 hilft ;)

Jetzt kommt bestimmt noch ein entrüstetes "not 4 spaces-posting" :twisted:
würmchen
User
Beiträge: 255
Registriert: Mittwoch 7. November 2007, 14:17

Beitragvon würmchen » Montag 1. September 2008, 08:51

ok, so bin ich gerade dabei das zu machen, und jede funktion ruft dann eben eine andere funktion nochmal auf...

ich benenne die gerade wie ich die schleifenköpfe beschreiben würde...

Code: Alles auswählen

def loopMolecule:
    ....
    loopResidue()

def loopModel:
    ....
    loopMolecule()
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Beitragvon CM » Montag 1. September 2008, 09:23

würmchen hat geschrieben:Beipiel, ein Entry kann mehrere Modelle haben, ein Modell kann mehrere Proteinketten haben, jede Proteinkette besteht aus mehreren Residues, Jedes Residue aus mehreren Atomen, Jedes atom hat 3 Koordinaten.

Das ist ja eine ganz normale Datenstruktur in der Strukturbiologie (NMR-Daten?). Wieso ist denn so was *so* in einer Datenbank? Da muß es ja erstmal reingekommen sein. Und so umständlich ist doch gar nicht notwendig: Es kann ja eine Eingabe mit einer Datei assoziiert sein und dann kann ein normaler Parser mit dem Text dieser Datei (PDB, mmCIF, das eine oder ander XML-Derivat, etc.) arbeiten.

Jedenfalls: Eine Funktion, bzw. eine Schleife, für jede Hierachieebene ist tierisch umständlich und dauert im Zweifel lange.

Gruß,
Christian
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Beitragvon audax » Montag 1. September 2008, 09:35

würmchen hat geschrieben:ok, so bin ich gerade dabei das zu machen, und jede funktion ruft dann eben eine andere funktion nochmal auf...

ich benenne die gerade wie ich die schleifenköpfe beschreiben würde...

Code: Alles auswählen

def loopMolecule:
    ....
    loopResidue()

def loopModel:
    ....
    loopMolecule()

Das ist leider ebenso keine gute Idee :/
Du benutzt da globale Variablen, oder?
Zeig einfach deinen Code...
würmchen
User
Beiträge: 255
Registriert: Mittwoch 7. November 2007, 14:17

Beitragvon würmchen » Montag 1. September 2008, 09:56

CM hat geschrieben:
würmchen hat geschrieben:Beipiel, ein Entry kann mehrere Modelle haben, ein Modell kann mehrere Proteinketten haben, jede Proteinkette besteht aus mehreren Residues, Jedes Residue aus mehreren Atomen, Jedes atom hat 3 Koordinaten.

Das ist ja eine ganz normale Datenstruktur in der Strukturbiologie (NMR-Daten?). Wieso ist denn so was *so* in einer Datenbank? Da muß es ja erstmal reingekommen sein. Und so umständlich ist doch gar nicht notwendig: Es kann ja eine Eingabe mit einer Datei assoziiert sein und dann kann ein normaler Parser mit dem Text dieser Datei (PDB, mmCIF, das eine oder ander XML-Derivat, etc.) arbeiten.

Jedenfalls: Eine Funktion, bzw. eine Schleife, für jede Hierachieebene ist tierisch umständlich und dauert im Zweifel lange.

Gruß,
Christian



ganz recht, es dreht sich um eine datenbank in der rund 30000 mmCIF gespeichert sind. der code der die datenbank erstellt hat stammt nicht von mir, ich arbeite nur mit der datenbank. jetzt geht es darum praktisch wieder ein mmCIF bzw PDB zu schreiben und das noch mit verschiedenen einschränkungen bzw zusätzlichen Infos


@audax
ich bin noch am bauen, aber so sieht der verschachtelte code aus der fast fertig ist
die ganzen getXyz() funktionen sind in der Klasse von der Ich ableite definiert.

Code: Alles auswählen

class CreateAllPdbFiles(CreatePdbFiles):
    def __init__(self,cursor,entry_key_string):
        CreatePdbFile.__init__(self,cursor)
        self.entry_key_list = entry_key_string.split()

        for entry_key in self.entry_key_list:
            pdb_obj = self.getPdbCode(entry_key)
            pdb_obj['model'] = self.getModelInfo(entry_key)
            pdb_file = pdb(name=pdb_obj['pdb_code']+'.pdb')
     
     
            for model_key,model_id in pdb_obj['model']:
                if len(pdb_obj['model']) > 1:
                    newmodel = ['MODEL',str(model_id)]
                    pdbfile.addAtom(newmodel)
     
                pdb_obj['molecule'] = self.getMoleculeInfo(entry_key,model_key)

                for molecule_key,moleculetype in pdb_obj['molecule']:
                    my_atom_to_atom = {}
                    bonds[]

                    pdb_obj['residue'] = getResidueInfo(entry_key,molecule_key)
                    for redidue_key,resName,resSeq,iCode,heteroFlag,chainID \
                            in pdb_obj['residue']:

                        if self.only_catres:
                            pdb_obj['catres'] = getCatResInfo(entry_key)
                            if not residue_key in \
                                    [i[2] for i in pdb_obj['catres']]:
                                        continue
                        hetero = "ATOM"   
                        if heteroFlag.strip(" ") != "":
                            hetero = "HETATM"

                        # Residue filter
                        if skip_all_hetero:
                            if hetero == "HETATM":
                                continue
                        if only_nat_residues:
                            if resName not in nat_residues:
                                print 'Warning from getPdb::protein2pdb: ' +
                                'Residue was ' + str(resName)
                                continue

                        # Get atom info
                        pdb_obj['atom'] = self.getAtomInfo(entry_key)
     
                        for atom in [i for i in pdb_obj['atom'] \
                                if i[3] == residue_key]:
                            pass
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Beitragvon CM » Montag 1. September 2008, 10:32

Oh :shock:. Also, ich nehme mal an, andere hier können Dich da noch eher auf den Senkel stellen und ggf. auch zeigen, wie man effizienter durch die Datenbank crawlt.

Aber zunächst einmal sollte man nicht so viel Funktionalität in die __init__-Funktion einer Klasse stecken. Dann würde ich auch nicht eine Klasse nach ihrer wesentlichen Funktionalität benennen (sehr seltsame Herangehensweise).

Vor allem aber: Du kennst biopython (besitzt die Möglichkeit ein PDB-File zu schreiben, wenn Du einmal ein PDB-Objekt erstellt hast)? Oder openbabel (damit kannst Du ebenfalls PDB-Files schreiben und parsen und auch mmCIF-Files erstellen - besitzt auch eine Pythonanbindung)?

Gruß,
Christian
Benutzeravatar
snafu
User
Beiträge: 5426
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Beitragvon snafu » Montag 1. September 2008, 10:40

Muss man hier überhaupt mit einer Klasse arbeiten?

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder