Tutorial: Einfache Textmenüs mit Python

Gute Links und Tutorials könnt ihr hier posten.
sh4nks
User
Beiträge: 13
Registriert: Montag 5. März 2012, 22:08
Wohnort: Styria

Ah ok danke.

Dies würde aber so auch funktionieren:

Code: Alles auswählen

command = menu[choice][1]
Ist es eine schlechte Idee das so zu verwenden?
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Das würde auch funktionieren, nur macht es mMn. unleserlicher.
the more they change the more they stay the same
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

/me hat geschrieben:Ich mag diesen Einsatz [gemeint ist der Unterstrich] ]nicht so. Er konterkariert PEP-20 (Zen of Python) und PEP-8 bei den Punkten "Readability counts." unter besonderer Berücksichtigung von "code is read much more often than it is written"
Ich finde den "_" im Gegenteil "intention revealing" und auch wenn Python das im Gegensatz zu anderen Sprachen nicht als Teil der Semantik kennt, ist es IMHO guter Stil. Ein anderes Beispiel wäre "i" für eine Schleifenvariable oder das man eine Pluralform wählt, wenn man eine Collection von Dingen bezeichnen will.

Die Python-IDE PyCharm weiß bei ihrer heuristischen Typanalyse beispielsweise, dass sie das "_" nicht an unbenutzt Variable markieren soll. Würde man `foo, bar = foobars` schreiben und dann `foo` nie wieder benutzen, würde PyCharm das als wahrscheinlichen anmerken.

Stefan
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

sma hat geschrieben:Ich finde den "_" im Gegenteil "intention revealing" und auch wenn Python das im Gegensatz zu anderen Sprachen nicht als Teil der Semantik kennt, ist es IMHO guter Stil. Ein anderes Beispiel wäre "i" für eine Schleifenvariable oder das man eine Pluralform wählt, wenn man eine Collection von Dingen bezeichnen will.
Hier scheine ich den Kontext nicht deutlich genug gemacht zu haben. Ich mag den Unterstrich "als Verkürzung für oft verwendete Funktionen" nicht, sonst durchaus.
sma hat geschrieben:Die Python-IDE PyCharm ...
Gerade habe ich noch 66,70€ für das Upgrade Subscription Renewal ausgegeben. Und das mir als FSFE-Fellow ...
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

/me hat geschrieben:Hier scheine ich den Kontext nicht deutlich genug gemacht zu haben. Ich mag den Unterstrich "als Verkürzung für oft verwendete Funktionen" nicht, sonst durchaus.
Ach so. Ja, das teile ich.
sma hat geschrieben:Die Python-IDE PyCharm ...
/me hat geschrieben:Gerade habe ich noch 66,70€ für das Upgrade Subscription Renewal ausgegeben. Und das mir als FSFE-Fellow ...
Wird nicht immer gepredigt: Free != Kostenlos ;) Gute Software darf ruhig etwas kosten, finde ich.

Außerdem: Die Grund-IDE von Jetbrains für Java, Scala und Android ist ja außerdem auch als Opensource verfügbar...

Stefan
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

sma hat geschrieben:
sma hat geschrieben:Die Python-IDE PyCharm ...
/me hat geschrieben:Gerade habe ich noch 66,70€ für das Upgrade Subscription Renewal ausgegeben. Und das mir als FSFE-Fellow ...
Wird nicht immer gepredigt: Free != Kostenlos ;) Gute Software darf ruhig etwas kosten, finde ich.
PyCharm ist aber weder "free" noch "kostenlos", von daher fällt dieser Vergleich flach.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Noch Anmerkungen von mir: Bei Code Beispielen die absichtlich "schlecht" sind, würde ich davor darauf hinweisen.

Das folgende, würde ich anders machen:

Code: Alles auswählen

def get_user_input(menu):
    while True:
        try:
            choice = int(input("Ihre Wahl?: ")) - 1
            if 0 <= choice < len(menu):
                return choice
            else:
                raise IndexError
        except (ValueError, IndexError):
            print("Bitte nur Zahlen aus dem Bereich 1 - {} eingeben".format(
                                                                    len(menu)))


def handle_menu(menu):
    while True:
        print_menu(menu)
        choice = get_user_input(menu)
        menu[choice][1]()
eh so:

Code: Alles auswählen

def get_user_input(menu):
    while True:
        try:
            choice = int(raw_input("Ihre Wahl?: "))
            choice -= 1
            return menu[choice][1]
        except (ValueError, IndexError):
            print("Bitte nur Zahlen aus dem Bereich 1 - {} eingeben".format(
                                                                    len(menu)))


def handle_menu(menu):
    while True:
        print_menu(menu)
        func = get_user_input(menu)
        func()
...und ganz wichtig: überall statt input() lieber raw_input() nehmen! Und kurz erwähnen, das input() eigentlich eval(raw_input(prompt)) ist und das ist keine gute Idee.

Im Tutorial kannst du dann noch kurz auf try...except eingehen und es fehlt IMHO am Ende ein Beispiel das funktioniert. Also noch die pseudo Funktionen dabei packen. Dann kann man direkt copy&paste und probieren.

und zum Schluss, das ganze in's Wiki packen ;) Der fertige Code kann ja bei github bleiben und verlinkt werden...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

@jens: `raw_input()` ist in Python 3 in `input()` umbenannt worden.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

sma hat geschrieben:Wenn du format() nicht zum Formatieren benutzt, würde statt

Code: Alles auswählen

    print("{}  {}".format(index+1, menu[index]))
auch einfach

Code: Alles auswählen

    print(index+1, menu[index])
Oder um genau zu sein:

Code: Alles auswählen

print(index + 1, menu[index], sep='  ')
8)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Danke für die weiteren Anmerkungen. Ich war einige Tage offline und muss das erst einmal in Ruhe durchlesen und mir überlegen, was ich wie umsetze.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
Kebap
User
Beiträge: 687
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

Gute geschrieben! Vielen Dank dafür! 8)
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

So, ich habe mal die Hauptkritik umgesetzt und IPython raus geschmissen. Jetzt lesen sich die Konsolenausgaben wirklich schöner :-)

@sma:

- Danke für den Hinweis auf Unicode - habe "≤" auch gleich mal eingebaut ;-)

- Ich mag ja `format`... :oops: Ok, man könnte danke Python3 auch ohne arbeiten, aber ich finde das jetzt nicht so schlimm, als dass ich das alles umstellen wollen würde. So kompliziert ist das ja auch nicht, als dass sich ein Anfänger nicht auch damit selber befassen kann.

- Mit dem Lügen hast Du wohl recht... um nicht zu viel umstellen zu müssen habe ich nach den imho wesentlichen Teilen in dem Abschnitt einen Hinweis eingebaut, dass man sich den Rest über Objekte schenken kann. Wenn ich mal Lust habe, kürze ich das evtl. komplett zusammen und lagere den bisherigen Teil in ein separates Tutorial aus :-)

- Die Anregung mit den Dekoratoren finde ich gut :-) Das kann mich mir gut als "Simple menus reloaded" vorstellen :mrgreen:

@Jens:

- Die Diskussion über einen Hinweis zu absichtlich schlechten Code habe ich mit frabron schon diskutiert ;-)

- Bei Deinem Vorschlag passt der Name `get_user_input` nicht mehr. Imho würde da schon zu viel Funktionalität von `handle_menu` ausgelagert. Zudem finde ich das direkte Subtrahieren von "1" leserlicher als Deine zweite nachgeschobene Zeile... da musste ich echt zweimal hingucken. Insofern lasse ich das wie gehabt.

- Mein Tut ist für Python3 - ich habe das zu Beginn noch einmal hervorgehoben und liefere ein paar Hinweise für Python2 Benutzer.

- Am Ende habe ich nun ein komplettes Beispiel :-)

- Sofern größere Änderungen ausbleiben, würde ich das sicherlich ins wiki integrieren. Gibt es da automatische Umwandlung vom Markdown Dialekt auf GitHub in die Wiki-Syntax (Creole?) ? So ganz manuell macht mir das ein wenig viel Arbeit... zumal man bei Änderungen dann zwei Versionen pflegen müsste.

So, ich hoffe ich habe nun alles so weit berücksichtigt :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Hyperion hat geschrieben:- Sofern größere Änderungen ausbleiben, würde ich das sicherlich ins wiki integrieren. Gibt es da automatische Umwandlung vom Markdown Dialekt auf GitHub in die Wiki-Syntax (Creole?) ? So ganz manuell macht mir das ein wenig viel Arbeit... zumal man bei Änderungen dann zwei Versionen pflegen müsste.
Ich glaube unser Wiki versteht auch Markdown. Also Markdown, nicht den GitHub-Dialekt, aber immerhin.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
lunar

@Hyperion: Man kann das bestimmt auch mit pandoc konvertieren.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

@Leonidas: Hm... also laut Wiki-Beschreibung ist das wohl mindestens ein Dialekt und unterscheidet sich in einigen Punkten stark von dem hier beschriebenen...

@lunar: Das Tool sieht gut aus, aber... unter Arch finden sich nur veraltete oder verwaiste Pakete und zudem sehe ich nicht, dass das Ding in die MoinMoin-Syntax übersetzen kann. Per google fand ich eine Diskussion über einen Ansatz, der wohl nie perfektioniert wurde.

Ich habe mir jetzt einfach mal die "Mühe" gemacht und das ganze manuell angepasst. Das meiste bekam ich per Suchen&Ersetzen schnell konvertiert. Bei den Links, Listen und Überschriften musste ich manuell eingreifen - aber davon habe ich ja nicht viel. Auf Dauer ist das sicher keine Lösung, wenn man am Original noch viel ändern würde. Der einmalige Aufwand war nicht so groß.

Aber eine dumme Frage habe ich jetzt noch: Wie lege ich im wiki eine neue Seite an? Ich finde keinen Link im Menü, noch klappt der "Trick", eine Seite zu suchen und bei der Nichtexistenz die Option zum Anlegen zu bekommen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
lunar

@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.
Benutzeravatar
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.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
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

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
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 :-D
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

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 ;)
Antworten