Vereinfachung

Code-Stücke können hier veröffentlicht werden.
Antworten
Nihtus
User
Beiträge: 14
Registriert: Mittwoch 4. Dezember 2019, 13:40

Dienstag 10. Dezember 2019, 12:02

Hi Leute,
ich Arbeite gerade an einem kleinen bioinformatischen Script. Dieses soll mir aus den verschiedenen dominanten/rezessiven Merkmalen von Mäusen eine Vererbungstabelle (nach Mendel:https://de.wikipedia.org/wiki/Mendelsche_Regeln) und das Vorkommmen der einzelnen Kombinationen zählen:

Code: Alles auswählen

    Maus1=["AA","Bb"]
    Maus2=["Aa", "bb"]
    x1= Maus1[0][0]+Maus1[1][0]
    x2= Maus1[0][0]+Maus1[1][1]
    x3= Maus1[0][1]+Maus1[1][0]
    x4= Maus1[0][1]+Maus1[1][1]
    y1= Maus2[0][0]+Maus2[1][0]
    y2= Maus2[0][0]+Maus2[1][1]
    y3= Maus2[0][1]+Maus2[1][0]
    y4= Maus2[0][1]+Maus2[1][1]
    Matrix=[
        ["M1/M2",x1,x2,x3,x4],
        [y1, "".join(sorted(x1+y1)), "".join(sorted(x2+y1)), "".join(sorted(x3+y1)), "".join(sorted(x4+y1))],
        [y2, "".join(sorted(x1+y2)), "".join(sorted(x2+y2)), "".join(sorted(x3+y2)), "".join(sorted(x4+y2))],
        [y3, "".join(sorted(x1+y3)), "".join(sorted(x2+y3)), "".join(sorted(x3+y3)), "".join(sorted(x4+y3))],
        [y4, "".join(sorted(x1+y4)), "".join(sorted(x2+y4)), "".join(sorted(x3+y4)), "".join(sorted(x4+y4))],
        ]
    AABB= sum(x.count("AABB") for x in Matrix)
    AABb= sum(x.count("AABb") for x in Matrix)
    AAbb= sum(x.count("AAbb") for x in Matrix)
    AaBB= sum(x.count("AaBB") for x in Matrix)
    AaBb= sum(x.count("AaBb") for x in Matrix)
    Aabb= sum(x.count("Aabb") for x in Matrix)
    aaBB= sum(x.count("aaBB") for x in Matrix)
    aaBb= sum(x.count("aaBb") for x in Matrix)
    aabb= sum(x.count("aabb") for x in Matrix)
An sich ist das ja kein Problem, aber wie man hier sieht wiederhole ich die verschiedenen Codeteile immer wieder. Das kommt bei mir nicht zum erstmal vor. Da ich noch ein Anfänger im Programmieren bin, suche ich nach einer Möglichkeit, meinen Programmierstyle zu optimieren. Besonders wichtig wäre dass für mich, weil ich dass ganze noch auf 3 oder 4 Merkmale erhöhen will. Pro Merkmal wird das Ganze exponentiell immer mehr abtippen. Ich weiß nur einfach nicht was ich da benutzen soll/kann.
Danke für eure Hilfe
LG
Nihtus
Benutzeravatar
__blackjack__
User
Beiträge: 6402
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Dienstag 10. Dezember 2019, 12:23

@Nihtus: Schleifen und Funktionen und wenn Du anfängst Namen zu nummerieren, dann willst Du eigentlich keine einzelnen Namen sondern eine geeignete Datenstruktur. Oft eine Liste. Oder ein Wörterbuch. `Maus` und `x`/`y` sind im Grunde auch keine Namen sondern Daten, genau so wie die ganzen `AABB`-Namen in den verschiedenen Variationen keine Namen sondern Daten sind.

Du möchtest Dir vielleicht auch mal das `itertools`-Modul anschauen mit den ganzen kombinatorischen Funktionen.

Edit: `Matrix` ist auch keine gute Datenstruktur zur Weiterverarbeitung, denn die ist ja offensichtlich eine Aufbereitung für die Präsentation der Daten mit Kopfzeile und -spalte. Du zählst dann Werte auch in diesen beiden obwohl da gar nicht die Daten drin stehen die gezählt werden sollen.

Namen schreibt man in Python klein_mit_unterstrichen. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase).

Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.
long long ago; /* in a galaxy far far away */
Nihtus
User
Beiträge: 14
Registriert: Mittwoch 4. Dezember 2019, 13:40

Dienstag 10. Dezember 2019, 14:04

__blackjack__ hat geschrieben:
Dienstag 10. Dezember 2019, 12:23
@Nihtus: Schleifen und Funktionen und wenn Du anfängst Namen zu nummerieren, dann willst Du eigentlich keine einzelnen Namen sondern eine geeignete Datenstruktur. Oft eine Liste. Oder ein Wörterbuch. `Maus` und `x`/`y` sind im Grunde auch keine Namen sondern Daten, genau so wie die ganzen `AABB`-Namen in den verschiedenen Variationen keine Namen sondern Daten sind.

Du möchtest Dir vielleicht auch mal das `itertools`-Modul anschauen mit den ganzen kombinatorischen Funktionen.

Edit: `Matrix` ist auch keine gute Datenstruktur zur Weiterverarbeitung, denn die ist ja offensichtlich eine Aufbereitung für die Präsentation der Daten mit Kopfzeile und -spalte. Du zählst dann Werte auch in diesen beiden obwohl da gar nicht die Daten drin stehen die gezählt werden sollen.

Namen schreibt man in Python klein_mit_unterstrichen. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase).

Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.
Danke für die Tipps! Das itertools-Modul wird mir auf jeden Fall helfen.
Sind mit Konstanten Varaiblen gemeint(wie man sie jetzt aus Mathe kennt). Ich spreche sonst kurz erstmal von Variablen. Wenn ichs richtig verstanden habe, dann ist es besser mehrere Variablen in Listen oder Wörterbüchern zu defenieren. Ist das dann nicht unpraktisch mit dynamische Variablen ?
__deets__
User
Beiträge: 8292
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dienstag 10. Dezember 2019, 14:25

Mit Konstanten sind auch wie in der Mathematik Konstanten gemeint. math.PI ist zB eine Konstante.

Und was meinst du mit "unpraktisch mit dynamischen Variablen"? Die Nutzung von Datenstrukturen erlaubt es, das Programm so zu schreiben, dass es zB abhaengig von einigen Variablen wie der Laenge von Permutationen automatisch alle moeglichen Permutationen und Kombinationen etc zu erzeugen und zu speichern und weiter zu verwenden. Unpraktisch hingegen ist es (wie dir ja auch schon selbst auffiel) bei einer Aenderung eines solchen Parameters ploetztlich Code verdoppeln oder gar mehr zu muessen, weil man jede Variable von Hand benannt und ausgeschrieben hat.
Nihtus
User
Beiträge: 14
Registriert: Mittwoch 4. Dezember 2019, 13:40

Dienstag 10. Dezember 2019, 15:15

__deets__ hat geschrieben:
Dienstag 10. Dezember 2019, 14:25
Mit Konstanten sind auch wie in der Mathematik Konstanten gemeint. math.PI ist zB eine Konstante.

Und was meinst du mit "unpraktisch mit dynamischen Variablen"? Die Nutzung von Datenstrukturen erlaubt es, das Programm so zu schreiben, dass es zB abhaengig von einigen Variablen wie der Laenge von Permutationen automatisch alle moeglichen Permutationen und Kombinationen etc zu erzeugen und zu speichern und weiter zu verwenden. Unpraktisch hingegen ist es (wie dir ja auch schon selbst auffiel) bei einer Aenderung eines solchen Parameters ploetztlich Code verdoppeln oder gar mehr zu muessen, weil man jede Variable von Hand benannt und ausgeschrieben hat.
Danke
Ich meine halt eine Variabel, die öfter innerhalberhalb eines Codes geändert wird bzw. dessens Zweck ist, geändert zu werden. Ein Beispeil wäre eine for Schleife mit Parameter als Begrenzung:

Code: Alles auswählen

def countdown(n):
  if n == 0:
    print "Blastoff!"
  else:
    print n
    countdown(n-1) 
Wie genau kann ich sachen defenieren mit Listen ?
Und du hast vorhin gesagt, dass Matrizen nicht so gute Datenträger sind. Was würdest du mir sonst empfehlen für mein Beispiel? Mir fällt halt sonst keine gute Alternative ein
LG
Nihtus
__deets__
User
Beiträge: 8292
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dienstag 10. Dezember 2019, 16:50

Ich verstehe nicht ganz was du mit diesem countdown meinst. Imperativ macht man da in Python

Code: Alles auswählen

for i in range(n):
Und ein Beispiel fuer eine Datenstruktur waere zB

Code: Alles auswählen

results = {}
for expression in ["AABB", "AABb", ...]:
    results[expression] = sum(x.count(expression) for x in Matrix)
Und wahrscheinlich kann man das sogar noch vereinfachen, wenn man die Systematik hinter den AAbb/... etc korrekt kodiert. Dazu fehlt mir aber im Moment der Hintergrund, das muesstest du ausfuehren.

__blackjack__ hat was zur Matrix gesagt - was er wohl meint ist, dass du darin Daten hast die du gar nicht haben solltest, weil sie fuer die Darstellung aber nicht vearbeitung gedacht sind.
Nihtus
User
Beiträge: 14
Registriert: Mittwoch 4. Dezember 2019, 13:40

Mittwoch 11. Dezember 2019, 09:57

__deets__ hat geschrieben:
Dienstag 10. Dezember 2019, 16:50
Ich verstehe nicht ganz was du mit diesem countdown meinst. Imperativ macht man da in Python

Code: Alles auswählen

for i in range(n):
Und ein Beispiel fuer eine Datenstruktur waere zB

Code: Alles auswählen

results = {}
for expression in ["AABB", "AABb", ...]:
    results[expression] = sum(x.count(expression) for x in Matrix)
Und wahrscheinlich kann man das sogar noch vereinfachen, wenn man die Systematik hinter den AAbb/... etc korrekt kodiert. Dazu fehlt mir aber im Moment der Hintergrund, das muesstest du ausfuehren.

__blackjack__ hat was zur Matrix gesagt - was er wohl meint ist, dass du darin Daten hast die du gar nicht haben solltest, weil sie fuer die Darstellung aber nicht vearbeitung gedacht sind.
Vergiss das mit dem countdown. Ich hab verstanden was du und __blackjack__ sagten. Danke!
Ich hab jetzt den Code optimiert und deine Datenstruktur benutzt(das Counter_modul macht fast genau das gleiche, wie den Code den du geschrieben hast):

Code: Alles auswählen

def heredity():
    maus_1=["AA","Bb"]
    maus_2=["Aa", "bb"]
    x=list(product(maus_1[0], maus_1[1])) 
    y=list(product(maus_2[0], maus_2[1]))
    table=list(product(x,y))
    count=Counter(table)
    print(count)
Um den Input maus_1 und so kümmere ich noch. Ich will noch ein GUI integrieren. Das gleiche gilt für den Output. Was denkst du ?
__deets__
User
Beiträge: 8292
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mittwoch 11. Dezember 2019, 11:14

Bitte nicht den Beitrag davor komplett zitieren. Der steht doch da fuer alle zum lesen.

Und wenn der Code tut, was der Code oben tat, dann ist das doch super. Keine Ahnung was da jetzt noch erweitert werden muss, dazu bin ich im Thema nicht genug drin. Und mit GUI hat dieser Teil ja auch erstmal nichts zu tun.
Benutzeravatar
__blackjack__
User
Beiträge: 6402
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Mittwoch 11. Dezember 2019, 12:18

@Nihtus: Da sind noch Indexzugriffe die man sich sparen kann und die ganzen `list()`-Aufrufe sind nicht nötig.

Wenn man nicht jedes Zwischenergebnis an einen Namen bindet und Ein- und Ausgabe nach aussen verlagert, ist die Funktion ein Einzeiler:

Code: Alles auswählen

#!/usr/bin/env python3
from collections import Counter
from itertools import product


def heredity(mouse_a, mouse_b):
    return Counter(product(product(*mouse_a), product(*mouse_b)))


def main():
    print(heredity(["AA", "Bb"], ["Aa", "bb"]))


if __name__ == "__main__":
    main()
long long ago; /* in a galaxy far far away */
Nihtus
User
Beiträge: 14
Registriert: Mittwoch 4. Dezember 2019, 13:40

Donnerstag 12. Dezember 2019, 09:20

Ja perfekt. Danke für eure Tipps und Hilfe. Ich hab viel lernen können!
Lg
Nihtus
Antworten