Tutorial: Einfache Textmenüs mit Python
@Hyperion: Wenn Du Haskell installiert hast, dann kannst Du pandoc auch mit "cabal install --user pandoc" aus den Quellen installieren. Du musst dann lediglich "~/.cabal/bin" zu $PATH hinzufügen. Aber gut, wenn pandoc das proprietäre Format von MoinMoin nicht unterstützt, ist das ohnehin egal.
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Ah, danke für die Antwort. Gut zu wissen, dass Haskell sein eigenes Installationswerkzeug mitbringt
Hm... wenn es ein Format gäbe, bei dem die Hauptmerkmale umgewandelt würden, könnte man das zumindest als Zwischenschritt wählen.
Gibt es da evtl. einen abtrakten Syntaxbaum in einem Markdown-Parser? Wenn ja, sollte es doch nicht so schwer sein, dieses "MoinMoin"-Format zu generieren... die Elemente an sich bleiben ja gleich und auch in derselben Reihenfolge.
Hm... wenn es ein Format gäbe, bei dem die Hauptmerkmale umgewandelt würden, könnte man das zumindest als Zwischenschritt wählen.
Gibt es da evtl. einen abtrakten Syntaxbaum in einem Markdown-Parser? Wenn ja, sollte es doch nicht so schwer sein, dieses "MoinMoin"-Format zu generieren... die Elemente an sich bleiben ja gleich und auch in derselben Reihenfolge.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Man könnte in python-creole ein html2moinmoin implementieren: https://github.com/jedie/python-creole
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
@Jens: Ich habe ja jetzt eine Ruby-Lösung, mit der ich ganz zufrieden bin. Das dort noch fehlende kann man sicherlich noch implementieren
Aber kannst Du mir nicht mal meine Frage bezüglich des Anlegens einer Seite beantworten? Ohne diese Fähigkeit nützt mir meine bisherige Arbeit nämlich gar nichts
Aber kannst Du mir nicht mal meine Frage bezüglich des Anlegens einer Seite beantworten? Ohne diese Fähigkeit nützt mir meine bisherige Arbeit nämlich gar nichts
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
Seite anlegen = URL eingeben, wo man die Seite erreichen soll, dann kommt ne Fehlermeldungsseite (weil die Seite ja noch nicht existiert, 404-mäßig), wo du am Ende nen Link findest: "Seite anlegen". Wenn man's weiß, ist es ganz einfach
-
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Das hat Hyperion probiert. Ich schätze mal, das liegt daran dass er nicht angemeldet war. Wenn er sich einloggt, dann sollte es auch den Link geben. AFAIR.derdon hat geschrieben:Seite anlegen = URL eingeben, wo man die Seite erreichen soll, dann kommt ne Fehlermeldungsseite (weil die Seite ja noch nicht existiert, 404-mäßig), wo du am Ende nen Link findest: "Seite anlegen". Wenn man's weiß, ist es ganz einfach
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
@derdon: Danke
@Leonidas: Nee, ich hatte tatsächlich nur probiert, über das Suchen der Seite an einen "Create"-Link zu kommen. So kenne ich das von MediaWikis. Angemeldet war ich schon. Ehrlich gesagt finde ich es auch doof, dass das bei MoinMoin augenscheinlich so nicht geht.
Naja, man findet das ganze jetzt unter: http://wiki.python-forum.de/Tutorial_Textmen%C3%BC
@Leonidas: Nee, ich hatte tatsächlich nur probiert, über das Suchen der Seite an einen "Create"-Link zu kommen. So kenne ich das von MediaWikis. Angemeldet war ich schon. Ehrlich gesagt finde ich es auch doof, dass das bei MoinMoin augenscheinlich so nicht geht.
Naja, man findet das ganze jetzt unter: http://wiki.python-forum.de/Tutorial_Textmen%C3%BC
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
Hallo Hyperion,
das ist ein sehr schönes und anschauliches Tutorial. Hat mir als Einsteiger sehr geholfen, die Idee den Inhalt von der Logik zu trennen hatte ich auch in meinem Projekt, wusste aber nicht, wie man das in Python umsetzt. Im Tutorial hast Du ganz zum Schluss noch einen Hinweis auf weitere Module (Submenüs usw.) gegeben. Wo findet man die denn? Ich möchte nun auch so ein Submenü gestalten, weiß aber nicht, ob man nun eine vollumfängliche Menü-Liste (also mit allen Elementen aller Menüs) aufbaut oder für jedes (Sub-)Menü ein eigenes.
Des weiteren möchte ich Funktionen mit dem Menü aufrufen, die Instanz-Methoden sind, d.h. ich kann doch dann die Menü-Liste erst definieren, nachdem die Instanz erstellt wurde. Gibt es da vielleicht eine bessere Lösung? Mir ist da irgendwo im Sinn, dass es sowas wie Klassen-Funktionen gibt, wo man also keine Instanz vorher erstellen muss um auf die Funktionen zuzugreifen. Bin aber nicht sicher, ob ich da auf dem richtigen Wege bin...
Viele Grüße
stielchen
das ist ein sehr schönes und anschauliches Tutorial. Hat mir als Einsteiger sehr geholfen, die Idee den Inhalt von der Logik zu trennen hatte ich auch in meinem Projekt, wusste aber nicht, wie man das in Python umsetzt. Im Tutorial hast Du ganz zum Schluss noch einen Hinweis auf weitere Module (Submenüs usw.) gegeben. Wo findet man die denn? Ich möchte nun auch so ein Submenü gestalten, weiß aber nicht, ob man nun eine vollumfängliche Menü-Liste (also mit allen Elementen aller Menüs) aufbaut oder für jedes (Sub-)Menü ein eigenes.
Des weiteren möchte ich Funktionen mit dem Menü aufrufen, die Instanz-Methoden sind, d.h. ich kann doch dann die Menü-Liste erst definieren, nachdem die Instanz erstellt wurde. Gibt es da vielleicht eine bessere Lösung? Mir ist da irgendwo im Sinn, dass es sowas wie Klassen-Funktionen gibt, wo man also keine Instanz vorher erstellen muss um auf die Funktionen zuzugreifen. Bin aber nicht sicher, ob ich da auf dem richtigen Wege bin...
Viele Grüße
stielchen
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Danke, schön zu hörenstielchen hat geschrieben:Hallo Hyperion,
das ist ein sehr schönes und anschauliches Tutorial. Hat mir als Einsteiger sehr geholfen,
In einem Github-Repository: https://github.com/Lysander/snippets/tr ... implemenusstielchen hat geschrieben: Im Tutorial hast Du ganz zum Schluss noch einen Hinweis auf weitere Module (Submenüs usw.) gegeben. Wo findet man die denn?
Naja, es gibt Klassenmethoden, aber die haben dann eben auch keinen Zuggriff auf das Exemplar an sichstielchen hat geschrieben: Des weiteren möchte ich Funktionen mit dem Menü aufrufen, die Instanz-Methoden sind, d.h. ich kann doch dann die Menü-Liste erst definieren, nachdem die Instanz erstellt wurde. Gibt es da vielleicht eine bessere Lösung? Mir ist da irgendwo im Sinn, dass es sowas wie Klassen-Funktionen gibt, wo man also keine Instanz vorher erstellen muss um auf die Funktionen zuzugreifen. Bin aber nicht sicher, ob ich da auf dem richtigen Wege bin...
Ich fürchte da führt kein Weg drum herum; man kann sich natürlich irgend welche Wrapper bauen, die den Zugriff kapseln (``operator.methodcaller`` o.ä.), aber irgend wann muss man das Exemplar natürlich übergeben!
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
Das Beispiel aus "submenue.py" gefällt mir, habe es übernommen aber noch ein paar Anpassungen gemacht. So wird jetzt in jedem Menü eine Überschrift ausgegeben, damit man weiß wo man ist und die "Zurück"-Funktion habe ich nun fix auf Punkt 9 gelegt (viele Einträge habe ich eh nicht). So finde ich das navigieren leichter.
Aber an einem Punkt hänge ich nun fest. Einer der durch das Menü aufgerufenen Funktionen erwartet einen Parameter, der "command()"-Aufruf in Zeile 154 scheitert dann mit der Fehlermeldung:
command()
TypeError: 'NoneType' object is not callable
Irgendwie scheint er nicht zu erkennen, dass es da noch einen Parameter zu berücksichtigen gibt:
Beispiel (siehe "Python"-Zeile):
Aber an einem Punkt hänge ich nun fest. Einer der durch das Menü aufgerufenen Funktionen erwartet einen Parameter, der "command()"-Aufruf in Zeile 154 scheitert dann mit der Fehlermeldung:
command()
TypeError: 'NoneType' object is not callable
Irgendwie scheint er nicht zu erkennen, dass es da noch einen Parameter zu berücksichtigen gibt:
Beispiel (siehe "Python"-Zeile):
Code: Alles auswählen
menu = {
"root": (
("Hallo", hello),
("Python", python(arg)),
("Submenu", "submenu"),
("Exit", lambda: sys.exit(0))
)
@stielchen: *Du* rufst die Funktion `python()` auf und in dem Tupel landet dann der *Rückgabewert* dieser Funktion, der anscheinend `None` ist und sich natürlich nicht aufrufen lässt. Schau mal wie das mit dem `sys.exit()` gelöst ist.
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
@stielchen: Wie BlackJack schon sagte, rufst Du die Funktion auf. Das ist ja gerade der "Clou" an der ganzen Sache, dass man die Funktionsobjekte an sich als Daten auffassen kann und diese auch in Listen, Dictionaries usw. ablegen kann. Dazu darf ich diese aber nicht aufrufen! Lies Dir dazu noch mal den Abschnitt "Funktionen sind auch Objekte!" durch. Da wird der Unterschied iirc erklärt.
In der Tat gehe ich im Tutorial nicht darauf ein, wie man sich Callables erstellt, die Parameter benötigen. (Vielleicht sollte ich das bei Zeiten mal nachholen? Wobei dann noch Menüs via Dekoratoren auch noch ein Thema wären... *seufz* die liebe Zeit ) Zu diesem Thema schau Dir einfach mal etwas zu ``lambda``, oder auch ``functools.partial`` an. Beides kann man gut benutzen, um benötigte Parameter *vor* dem Aufrufzeitpunkt an eine Funktion zu binden, so dass man diese beim eigentlichen Aufruf selber *nicht* mehr angeben muss. Das sind übrigens Möglichkeiten, den Command Pattern in Python umzusetzen
Wo ich mir selber meinen Code noch mal angeguckt habe, folgendes würde ich heute wohl umschreiben:
In der Tat gehe ich im Tutorial nicht darauf ein, wie man sich Callables erstellt, die Parameter benötigen. (Vielleicht sollte ich das bei Zeiten mal nachholen? Wobei dann noch Menüs via Dekoratoren auch noch ein Thema wären... *seufz* die liebe Zeit ) Zu diesem Thema schau Dir einfach mal etwas zu ``lambda``, oder auch ``functools.partial`` an. Beides kann man gut benutzen, um benötigte Parameter *vor* dem Aufrufzeitpunkt an eine Funktion zu binden, so dass man diese beim eigentlichen Aufruf selber *nicht* mehr angeben muss. Das sind übrigens Möglichkeiten, den Command Pattern in Python umzusetzen
Wo ich mir selber meinen Code noch mal angeguckt habe, folgendes würde ich heute wohl umschreiben:
Code: Alles auswählen
if isinstance(command, str):
category = command
else:
command()
# imho eleganter
if callable(command):
command()
else:
category = command
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert