Seite 2 von 3
Re: Regulären Ausdruck in Python prüfen
Verfasst: Mittwoch 9. Oktober 2019, 19:52
von Unplayable
Ich habe noch eine kleine Verständnisfrage:
Wenn ich die Konstante ^a(a|b|c) *b$ in der Match Zeile manuell eingebe, dann gibt mir die Methode richtigerweise True zurück. Jetzt habe ich den Code wie folgt geschrieben:
Code: Alles auswählen
import re
class Rega:
def __init__(self,alphabet, RA):
self.alphabet = alphabet
self.regulaerer_ausdruck = RA
def print_alphabet(self):
for i in self.alphabet:
print(i)
def regulaerer_ausdruck(self):
return self.regulaerer_ausdruck
def passendes_wort(self, wort):
if re.match(ra.regulaerer_ausdruck, wort) == None:
return False
else:
return True
ra = Rega(["a","b","c"], "^a(a|b|c) *b$")
ra.print_alphabet()
print(ra.regulaerer_ausdruck)
print(ra.passendes_wort("abcb"))
In der init Methode habe ich mir ja den regulären Ausdruck in self.regulaerer_ausdruck geschrieben. Diesen habe ich dann mit ra.regulaerer_ausdruck in der Match Zeile statt der Konstanten verwendet. Wenn ich das jetzt ausführe gibt er mir aber komischerweise False zurück. Normalerweise müsste doch aber auch True zurückkommen, weil der Ausdruck ja noch der gleiche ist, nur dieses Mal eben in einer Variablen steht. Übersehe ich da etwas?
Re: Regulären Ausdruck in Python prüfen
Verfasst: Mittwoch 9. Oktober 2019, 20:21
von Sirius3
Dein Regulärer Ausdruck ist ja jetzt auch ein anderer.
RA ist kein sinnvoller Name für einen Parameter. Benutze keine Abkürzungen. Konvention ist auch, dass Variablennamen klein geschrieben werden. regulaerer_ausdruck wäre besser.
Die Methode `regulaerer_ausdruck` ist quatsch. Zum einen sollten Methodennamen eine Tätigkeit sein, weil sie ja was machen, zum anderen wird die Methode in __init__ von dem Attribut gleichen Namens überdeckt, zum dritten macht die Methode auch nichts sinnvolles, da sie nur etwas zurückgibt, was man auch direkt über Attributzugriff erreicht.
Was ist der Nutzen des Alphabets?
Re: Regulären Ausdruck in Python prüfen
Verfasst: Mittwoch 9. Oktober 2019, 20:28
von Unplayable
Okay, ich werde es mir aneignen. Aber wieso ist der Ausdruck denn jetzt ein anderer? Ich habe ihn doch nur in eine Variable geschrieben? Den Nutzen des Alphabeths kann ich nicht sagen, wir sollen die Klasse nur als Übung programmieren.
Re: Regulären Ausdruck in Python prüfen
Verfasst: Mittwoch 9. Oktober 2019, 20:55
von __blackjack__
@Unplayable: Der reguläre Ausdruck ist jetzt ein anderer weil es eben nicht mehr der gleiche ist. *Warum* Du den verändert hast, musst Du schon selbst wissen. Bezihungsweise passt der in Deinem ersten Beitrag ja schon nicht auf die Beispieldaten. Auch Leerzeichen haben eine Bedeutung.
Re: Regulären Ausdruck in Python prüfen
Verfasst: Mittwoch 9. Oktober 2019, 21:09
von Unplayable
Vielen Dank! Habe auf das Leerzeichen gar nicht geachtet
Re: Regulären Ausdruck in Python prüfen
Verfasst: Mittwoch 9. Oktober 2019, 21:21
von snafu
Das ist so ziemlich das übelste Beispiel für OOP, das ich seit langem gesehen habe...

Re: Regulären Ausdruck in Python prüfen
Verfasst: Mittwoch 9. Oktober 2019, 21:29
von snafu
Was mir noch fehlt, ist eine genauere Auswertung:
Code: Alles auswählen
if ra.passendes_wort("abcb") == True:
passt = True
else:
pass
if ra.passendes_wort("abcb") == False:
passt_nicht = True
else:
pass
try:
if passt == True:
print("Passt")
else:
if passt_nicht == True:
print("Passt nicht")
else:
pass
except:
print("Fehler")
Re: Regulären Ausdruck in Python prüfen
Verfasst: Mittwoch 9. Oktober 2019, 21:31
von __blackjack__
Nochmal zum Alphabet: Das sollte kein Argument sein und vom Programmierer nicht angegeben werden müssen. Die Informationen stecken ja bereits im Muster des regulären Ausdrucks, und von da sollte man sich das auch holen wenn man es braucht.
Code: Alles auswählen
#!/usr/bin/env python3
import re
from sre_parse import LITERAL, parse as sre_parse, SubPattern
def iter_literals(nodes):
for node in nodes:
if isinstance(node, (tuple, list, SubPattern)):
if node[0] == LITERAL:
yield chr(node[1])
else:
yield from iter_literals(node)
class RegularExpression:
def __init__(self, pattern):
self._regex = re.compile(pattern)
@property
def pattern(self):
return self._regex.pattern
@property
def alphabet(self):
return "".join(sorted(set(iter_literals(sre_parse(self.pattern)))))
def matches(self, text):
return self._regex.fullmatch(text) is not None
def main():
regular_expression = RegularExpression("a(a|b|c)*b")
for character in regular_expression.alphabet:
print(character)
print(regular_expression.pattern)
print(regular_expression.matches("abcb"))
if __name__ == "__main__":
main()
Re: Regulären Ausdruck in Python prüfen
Verfasst: Mittwoch 9. Oktober 2019, 21:53
von Sirius3
@snafu: Vorsicht, Anfänger könnten die Ironie darin nicht verstehen.
Re: Regulären Ausdruck in Python prüfen
Verfasst: Mittwoch 9. Oktober 2019, 21:57
von Unplayable
Danke für die äußerst fachliche Hilfe! Aber ich habe es eben so als Arbeitsauftrag bekommen, an den ich mich halten soll, auch wenn das im Auge eines erfahrenen Programmierers keinen Sinn ergibt bzw keine gute Übung ist.
Re: Regulären Ausdruck in Python prüfen
Verfasst: Donnerstag 10. Oktober 2019, 17:24
von Unplayable
Hallo nochmal,
in einem weiteren Teil der Aufgabe soll nun folgendes gemacht werden:
Ich soll alle Kombinationen aus den Elementen des Alphabets von Länge x bis Länge y erstellen. Man möchte also z.B. aus dem Alphabet a und b die Kombinationen mit Länge 1 bis 2 erstellen, was dann dieses Ergebnis bringt: "a","b","aa","ab","ba","bb" Anschließend soll ich alle diese generierten Wörter mit einem beliebigen regulären Ausdruck überprüfen. Ich habe mir mit der Rekursion immer sehr schwer getan, aber ich würde es zum Üben gerne noch ein Mal rekursiv machen.
Das hier ist mein Ansatz:
Code: Alles auswählen
def kombinationen_erstellen(startwert, endewert, zaehler, liste, alphabet):
a = liste # Kopie der übergebenen, leeren Liste
ergebnis = [] # Liste, in die passende Kombinationen geschrieben werden
while zaehler <= endewert: # solange die Länge der Wörter kleiner als der Endewert
for element in alphabet: # gehe jedes Element im Alphabet durch
a.append(element) # füge das Element in die temporäre Liste ein
ergebnis.append(element) # füge das Element in die Ergebnisliste ein
kombinationen_erstellen(startwert, endewert, zaehler+1, liste, alphabet) #rekursiver Aufruf mit zaehler + 1
del a[-1] # letztes Element der temporären Liste löschen
print(a)
kombinationen_erstellen(1,2,1,[],["a","b"])
Ich habe es ein Mal so weit versucht, wie ich es selbstständig hin bekomme. Jedoch weiß ich nicht, wie ich jetzt vorgehen muss, um weitere Elemente anzuhängen
Re: Regulären Ausdruck in Python prüfen
Verfasst: Donnerstag 10. Oktober 2019, 17:49
von __deets__
Du versuchst hier zwei Dinge gleichzeitig zu tun, und das geht in die Hose. Schreib eine Funktion die in der Lage ist, aus einem gegebenen Alphabet alle kartesischen Produkte (so nennen sich diese Kombinationen) mit einer gegebenen Laenge zu erzeugen. Das ist rekursiv, und einfach: die Funktion produkt(n, alphabet) ist die Kombination aus allen Worten aus produkt(n-1, alphabet) plus allen Elementen aus dem Alphabet. Die Ergebnisse dieser Funktion kannst du optimalerweise per "yield" nach aussen reichen, zur Not aber auch in einer riesen Liste aufsammeln.
Und danach baust du einfach ne for-schleife die deine gewuenschten n von x bis y zusammenpappt.
Und ein Tipp gibt's obendrauf: ich programmiere seit ~20 Jahren Python. Und in dieser ganzen Zeit kann ich an einer Hand abzaehlen, wie oft ich "del" benutzen musste. Wann immer du also versucht bist etwas dadurch zu machen, dass auf bestehenden Listen insbesondere durch loeschen arbeitet, solltest du innehalten und es anders machen. Das ist eigentlich niemals noetig.
Re: Regulären Ausdruck in Python prüfen
Verfasst: Donnerstag 10. Oktober 2019, 18:27
von Unplayable
Hey, danke erstmal für die Antwort. Ich wollte es ja auch so machen wie du gesagt hast und das oben gezeigte Programm soll ja zuerst auch die ganzen Kombinationen generieren. Aber ich scheitere eben schon daran. Für mich ist es schwer zu verstehen wie ich nun weiter verfahren muss
Re: Regulären Ausdruck in Python prüfen
Verfasst: Donnerstag 10. Oktober 2019, 19:09
von Sirius3
Bei Rekursion mußt Du zwei Fragen beantworten: wie sieht der Start aus? Und wie kommt man von Schritt n auf Schritt n+1? Beschreibe das mal erst mit eigenen Worten.
Re: Regulären Ausdruck in Python prüfen
Verfasst: Freitag 11. Oktober 2019, 12:26
von Unplayable
Also dann würde ich es so beschreiben:
Zu Beginn habe ich eine leere Liste. Außerdem habe ich n Elemente im Alphabet. Nun schreibe ich jedes Element im Alphabet in eine Teilliste und eine Ergebnisliste. Die Teilliste ist immer dann voll, wenn len(teilliste) == der Zählvariable ist. Diese zählt ja von x bis y hoch. Wenn das der Fall ist, wandert die Liste in die Ergebnisliste und ich habe diese Kombination fertig. Dann muss ich an die Teilliste ja die anderen Elemente aus dem Alphabet anhängen.
So hätte ich es beschrieben
Re: Regulären Ausdruck in Python prüfen
Verfasst: Freitag 11. Oktober 2019, 12:55
von __deets__
Du wirst nicht weit kommen mit diesem Ansatz, in dem du Listen versuchst zu *veraendern*. Ich habe dir das oben auch schon fuer einen anderen Fall beschrieben, bei dem du del verwandt hast. Es ist so gut wie immer falsch, datenstrukturen so massiv zu manipulieren. Und solange du den Moment wann das dann doch mal ok ist nicht selbst erkennst, solltest du immer so vorgehen, dass du *neue* Datenstrukturen schaffst.
Fuer dein konkretes Problem heisst das: statt zu versuchen eine Liste zu manipulieren, bis sie eine Laenge hat, baust du immer NEUE Listen.
Fangen wir mal so an: nehmen wir mal an, du hast eine magische Funktion "magische_loesung", und die loest dir dein Problem fuer n-1 lange Sequenzen deines Alphabetes a. Wie baust du dann die Funktion kartesisches_produkt fuer n?
Code: Alles auswählen
def kartesisches_produkt(n, a):
... # irgendwo kommt ein aufruf magische_loesung(n-1, a)
...
Re: Regulären Ausdruck in Python prüfen
Verfasst: Freitag 11. Oktober 2019, 14:47
von Unplayable
Okay, wir haben es eben so beigebracht bekommen, dass wir immer das letzte angefügte Element löschen. Irgendwie kommt es mir so vor als würde jeder das anders machen als wir im Unterricht
Ich habe jetzt an folgendes gedacht:
Code: Alles auswählen
def kartesisches_produkt (n, a):
while n >= 0:
magische_loesung(n-1), a)
return ergebnis
Re: Regulären Ausdruck in Python prüfen
Verfasst: Freitag 11. Oktober 2019, 14:54
von Sirius3
Was meinst Du mit dem "immer" beim Löschen?
Re: Regulären Ausdruck in Python prüfen
Verfasst: Freitag 11. Oktober 2019, 15:20
von __deets__
Das was du da geschrieben hast macht ja nicht wirklich was. Vor allem soll dein kartesisches produkt doch etwas zurueckliefern. Tut es aber nicht. ergebnis wird nicht definiert. Was du tun musst, wenn du die Loesungen fuer n generieren willst, und irgendwie die Loesungen fuer n-1 bekommst, ist
- ueber jeden Buchstaben des Alphabets iterieren
- und den an jede Loesung des Problems mit n-1 anhaengen.
- all die dadurch entstandenen len(alphabet) * len(alle_loesungen_n-1) Loesungen zurueckgeben.
Code: Alles auswählen
def kartesisches_produkt(n, alaphabet):
ergebnis = []
for buchstabe in alphabet:
for loesung in magische_loesungen(n-1, alphabet):
ergebnis.append([buchstabe] + loesung)
return ergebnis
Und jetzt ist die Frage: wie schreibt man die magische_loesung?
Re: Regulären Ausdruck in Python prüfen
Verfasst: Freitag 11. Oktober 2019, 15:36
von Unplayable
Kurze Verständnisfrage: Wieso denn genau n-1? Das verstehe ich noch nicht wirklich