Einfache Kombinatorik

Code-Stücke können hier veröffentlicht werden.
Antworten
iScream
User
Beiträge: 11
Registriert: Samstag 25. Juli 2009, 11:15

Für den Biologieunterricht mussten wir gemäß dem Mendelschen Gesetzen Erbschemata aufmalen. Ich habe dazu dieses kleine Skript geschrieben, das die Arbeit übernimmt. Ist nichts großes, war aber mein erstes Skript, das ich mir selbst ausgedacht habe :)

Man braucht nur die beiden Genome eingeben, und erhält eine Liste der möglichen Kombinationen.

Code: Alles auswählen

#! /usr/bin/python

print 'Einfache Kombinatorik v3 - ein Skript von iScream'

def kombi(eins,zwei,laenge):
	global ausgabeliste
	liste = []
	for i in range(laenge):
		for j in range(laenge):
			liste.append(eins[i] + zwei[j])
	ausgabeliste = liste

erstes = raw_input('Erster Teil? ')
zweites = raw_input('Zweiter Teil? ')
langegesamt = len(erstes)

kombi(erstes, zweites, langegesamt)
print ausgabeliste
print 'Beendet'

Freue mich über Rückmeldungen :)
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Code: Alles auswählen

def kombi(eins,zwei):
    liste = []
    for i in eins:
        for j in zwei:
            liste.append(eins + zwei)
    return liste

if __name__ == "__main__":
    erstes = raw_input('Erster Teil? ')
    zweites = raw_input('Zweiter Teil? ')
    print kombi(erstes, zweites)
Das noetigste geaendert. Aber da ist noch weit mehr drin ;)

Generell solltest du dir mal PEP 8 anschauen und vor allem mal ueber sprechende Namen nachdenken. Daneben ist deutsch in Code ein 'no go' - in dem Stueckchen stecken 3 Sprachen!
http://docs.python.org/howto/doanddont.html kann auch nicht schaden.
iScream
User
Beiträge: 11
Registriert: Samstag 25. Juli 2009, 11:15

Hey cofi, Danke für die Rückmeldung. Ich bin noch absoluter Anfänger, daher würde ich mich freuen, wenn du eine Erläutterung dazu schreiben könntest, denn im Moment kann ich nicht jede Änderung nachvollziehen.

Zu den Sprachen: Habe ich hier schon in einigen Threats gelesen, dass man möglichst beim Englischen bleiben soll. Werde ich mir auch angewöhnen. Habe das damals jedoch noch nicht gewusst.

Konkret folgende Fragen:
  • Was ist PEP8?
    Was macht "if __name__ == "__main__""?

Vielen Dank für deine Hilfe :)
BlackJack

@cofi: Du meintest beim Anhängen an die Liste wohl ``i + j``. :-)

Ansonsten ist das immer noch furchtbar lang:

Code: Alles auswählen

def kombi(eins, zwei):
    return [a + b for a in eins for b in zwei]
iScream
User
Beiträge: 11
Registriert: Samstag 25. Juli 2009, 11:15

@BlackJack: Kannst auch du das bitte erläutern *lieb-guck*?
Ich versuche es mal zu verstehen:

Die Funktion kombi nimmt immernoch die 2 Parameter entgegen
Das eigentliche Kombinieren passiert nur noch in der Klammer
Man kann also die Schleifen so zusammenschieben?
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

iScream: siehe List Comprehensions
lunar

Nach dem Wort "PEP 8" wirst du doch selbst suchen können, oder?

Ein Ausdruck der Art "if __name__ == '__main__'" führt auf Modulebene dazu, dass der Code im Block nur ausgeführt wird, wenn das Modul als Skript ausgeführt wird. Somit kann man das Modul ohne Seiteneffekte importieren. Bei deinem kleinen Skript ist der Vorteil wohl noch nicht ersichtlich, bei größeren Modulen, die automatisiert getestet werden sollen, ist es allerdings sehr wichtig, dass ein "import" möglichst keine Seiteneffekte hat. "__name__" ist dabei eine "magische Variable", die mit dem Namen des aktuellen Moduls belegt wird. Bei der Ausführung als Skript ist dieser Namen "__main__".

In BlackJacks Posting kommt eine sogenannte List Comprehension zum Einsatz. Im Prinzip ist das eine Kurzform für eine "for"-Schleife, deren Block an eine Liste ".append()"ed. Probiere das mal im interaktiven Interpreter aus, das Prinzip ist eigentlich sehr einfach.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Das ist eine verschachtelte List Comprehension. [a, b for a in first for b in second] ergibt das Kartesische Produkt, wobei es imho verständlicher ist itertools.product zu verwenden.

Code: Alles auswählen

from itertools import product, imap
from operator import add
from functional import unfold_args
print "\n".join(imap(unfold_args(add), product(raw_input("First? "),
                                                raw_input("Second? "))))
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

@DasIch: Findest du wirklich?^^ Geschmackssache würde ich sagen...
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Zugegeben man hätte dass nicht funktional lösen müssen :D
lunar

Man kann sich trefflich darüber streiten, ob das verständlicher ist ... unabhängig davon sollte man aber trotzdem erklären, woher die Funktionen kommen, die man benutzt. In der Standardbibliothek jedenfalls kann man lange nach "unfold_args()" suchen ...
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

BlackJack hat geschrieben:@cofi: Du meintest beim Anhängen an die Liste wohl ``i + j``. :-)
Das war die Denkaufgabe :twisted:
BlackJack hat geschrieben:Ansonsten ist das immer noch furchtbar lang:

Code: Alles auswählen

def kombi(eins, zwei):
    return [a + b for a in eins for b in zwei]
Na man muss ja nich gleich mit der groessten Keule kommen :)

@iScream: Zur List Comprehension gibts auch ausfuehrliche Beispiele im Tutorial, wenn du das noch nicht gelesen hast, solltest du das nachholen ;)
iScream
User
Beiträge: 11
Registriert: Samstag 25. Juli 2009, 11:15

Ich danke euch allen dafür, dass ihr euch soviel mit meinem Code beschäftigt :)

Dieses List Comprehension sieht für mich aus wie die Kurzschreibweisen in der CSS-Design-Programmierung. Wieder was gelernt 8)


@DasIch: Da steige ich leider noch nicht durch ;) Ich werde es im Interpreter ausprobieren, sobald ich Zeit habe. :)



EDIT: PEP8 ist also so eine Art "Python-Knigge"?
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

iScream hat geschrieben:Dieses List Comprehension sieht für mich aus wie die Kurzschreibweisen in der CSS-Design-Programmierung. Wieder was gelernt 8)
Nein. Das ist etwas voellig anderes. List Comp. (und die ganzen neuen in Python 3) kommen aus der funktionalen Programmierung und sind nicht nur einfach eine Zusammenfassung.
iScream hat geschrieben: @DasIch: Da steige ich leider noch nicht durch ;) Ich werde es im Interpreter ausprobieren, sobald ich Zeit habe. :)
Das ist die richtige Einstellung.
iScream hat geschrieben: EDIT: PEP8 ist also so eine Art "Python-Knigge"?
Nein, nicht direkt. Es ist ein Styleguide, der gut lesbaren und konsistenten Code bei Befolgung quasi garantiert ;) Er ist zwar nur fuer die Pythondistribution "verpflichtend", aber hat sich auch sonst durchgesetzt.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

cofi hat geschrieben:
iScream hat geschrieben:Dieses List Comprehension sieht für mich aus wie die Kurzschreibweisen in der CSS-Design-Programmierung. Wieder was gelernt 8)
Nein. Das ist etwas voellig anderes. List Comp. (und die ganzen neuen in Python 3) kommen aus der funktionalen Programmierung und sind nicht nur einfach eine Zusammenfassung.
Eigentlich stammt das nicht wirklich aus der funktionalen Programmierung sondern aus der Mathematik. Es stimmt natürlich insofern als dass Haskell, eine funktionale Programmiersprache sowas mitbringt und ebenso PLT Scheme, wo das etwa so ausschaut:

Python

Code: Alles auswählen

[i * 2 for i in range(5)]
PLT Scheme:

Code: Alles auswählen

(for/list ([i (in-range 5)]) (* i 2))
In Scheme sieht BlackJacks Lösung übrigens so aus:

Code: Alles auswählen

(define (kombi eins zwei)
  (for*/list ([a eins]
              [b zwei])
             (string-append a b)))

(kombi '("A" "T") '("C" "G"))
(Ja, wenig exotisch, fast identisch mit dem was Python bietet)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Leonidas hat geschrieben:Eigentlich stammt das nicht wirklich aus der funktionalen Programmierung sondern aus der Mathematik.
Ja, natuerlich basiert es auf der Zermelo-Fraenken-Notation, allerdings muss man nun wirklich nicht bei Adam und Eva anfangen, zumal der Verbreitungsgrad der Information unter nicht-Mathematikern doch eher gering ist. Ausserdem wollte ich das einfach konsistent halten, denn das Tutorial beruft sich auch auf Haskell ;)[1] :twisted:

[1] Und BJ hat es noch nicht geschafft seine Fussnote in die Dokumentation zu bringen ;)
Antworten