Seite 1 von 1

Python-Skript mit einem Befehl stoppen

Verfasst: Freitag 20. März 2020, 08:08
von GhastCraftHD
Moin,
ich programmiere für die Schule gerade eine Art BIOS.
Ich würde gerne wissen, wie ich, wenn man den falschen Benutzernamen oder ein falsches Passwort eingibt, das Programm durch einen Befehl schließen lassen kann.

hier das Programm:

username = input("Bitte geben sie ihren Benutzernamen ein.")
if username == "GhastCraftHD"
print "Hallo GhastCraftHD"
password = input("Bitte gib dein Passwort ein.")
if password == "ghastcrafthd"
print "Zugriff gewährt!"
else:
print "Zugriff verweigert!"
#hier sollte das Programm dann beendet werden

Re: Python-Skript mit einem Befehl stoppen

Verfasst: Freitag 20. März 2020, 08:42
von Jankie
Naja im Moment beendet sich ja das Programm ja, weil es dann am Ende angekommen ist. Was möchtest du denn danach machen?

Hilft dir so etwas hier?

Code: Alles auswählen

import getpass

while True: #Endlosschleife
    username = input("Benutzername: ")
    passwort = getpass.getpass("Passwort: ") #"unsichtbare" Passwort eingabe
    if username == "GhastCraftHD" and passwort == "ghastcrafthd":
        print(f"Willkommen {username}")
        break #verlässt die Endlosschleife
    else:
        print(f"Falsche Anmeldedaten")
#hier kann das Programm dann weiter gehen
print("Anmeldung erfolgreich, Programm wird beendet.")

Sonstige Anmerkungen:

Beim Posten von Code bitte die Code-Tags (</>) im vollständigen Editor benutzen, sonst geht die Einrückung verloren.
Und der String hinter print gehört in Klammern, also print("mein string"), falls du noch Python 2.x verwendest solltest du auf Python 3.x updaten, da Python 2.x nicht mehr supported wird.
Hinter die Bedingung des Ifs gehören Doppelpunkte.

Re: Python-Skript mit einem Befehl stoppen

Verfasst: Freitag 20. März 2020, 09:22
von GhastCraftHD
Also, mein Programm soll danach noch weiter gehen, ich habe auch schon weiter programmiert, ich möchte nur, dass sich das Programm beendet, wenn man die falschen Anmeldedaten eingibt.

Trotzdem Danke für deinen Vorschlag

Es würde mir auch noch helfen, wenn du mir sagst, wie man, wenn man bei der Frage: Willst du weiter rechnen, oder etwas anderes machen? Bei der Antwort nein wieder zur Aktivitäten Auswahl zurück geht.

Außerdem programmiere ich das ganze in einem Online-Editor und kann daher nur Datenbanken, die Turtle, Farben und Befehle ohne Importe benutzen.

Der Online Editor, den ich benutze ist: https://webtigerjython.ethz.ch/
Dort kann man aber auch Python 3 benutzen

Code: Alles auswählen

username = input("Bitte geben sie ihren Benutzernamen ein.")
if username == "Benutzer 1":
    print "Hallo Benutzer 1!"
    password4 = input("Bitte gib dein Passwort ein, Benutzer 1.")
    if password4 == "passwort":
        print "Zugriff gewährt!"
    else:
        print "Zugriff verweigert! Falsches Passwort!"
else:
    print "Unbekannter Benutzername"

#Aktivitätenauswahl
activity = input("Was möchtest du jetzt machen?")
if activity == "TR" or activity == "Rechnen" or activity == "Taschenrechner":
    print "Okay, jetzt wird gerechnet!"
    while True:
        num1 = input("Gib die erste Zahl ein: ")
        oper = input("Welche Rechenoperation soll durchgeführt werden? (+,-,/.,*): ")
        num2 = input("Gib die zweite Zahl ein: ")

        num1 = int(num1)
        num2 = int(num2)

        if (oper == "+"):
            print("Deine Rechnung:", num1, " + ", num2)
            print("Ergebnis:", num1 + num2)

        elif (oper == "-"):
            print("Deine Rechnung:", num1, " - ", num2)
            print("Ergebnis:", num1 - num2)

        elif (oper == "/"):
            print("Deine Rechnung:", num1, " / ", num2)
            print("Ergebnis:", num1 / num2)

        elif (oper == "*"):
            print("Deine Rechnung:", num1, " * ", num2)
            print("Dein Ergebnis:", num1 * num2)
        else:
            print("Deine Eingaben sind nicht gültig")

        jein = input("Willst du weiter rechnen, oder etwas anderes machen?")

        if jein == "Nein" or jein == "Nein" or jein == "Stopp":
            break

Re: Python-Skript mit einem Befehl stoppen

Verfasst: Freitag 20. März 2020, 09:24
von GhastCraftHD
Außerdem programmiere ich das ganze in einem Online-Editor und kann daher nur Datenbanken, die Turtle, Farben und Befehle ohne Importe benutzen.

Re: Python-Skript mit einem Befehl stoppen

Verfasst: Freitag 20. März 2020, 09:58
von Sirius3
Warum heißt dass Passwort passwort4? Variablennamen sollten keine Nummern enthalten und vor allem keine zufälligen.
Um manche if-Bedingungen hast Du zu viele Klammern. Beim `activity` ist `in` hilfreich.
Bitte keine Abkürzungen. Beim Rechnen willst Du sicher nicht in die Oper gehen.
Bei umgangssprachlichen oder-Fragen ist die Antwort "Nein" nicht eindeutig: "Nein, ich möchte nichts anderes machen."
Was Du brauchst sind Funktionen, mit denen kannst Du den Programmfluss einfach durch `return` steuern:

Code: Alles auswählen

def login():
    username = input("Bitte geben sie ihren Benutzernamen ein.")
    if username == "Benutzer 1":
        print "Hallo Benutzer 1!"
        password = input("Bitte gib dein Passwort ein, Benutzer 1.")
        if password == "passwort":
            print "Zugriff gewährt!"
            return True
        else:
            print "Zugriff verweigert! Falsches Passwort!"
            return False
    else:
        print "Unbekannter Benutzername"
        return False

def rechnen():
    print "Okay, jetzt wird gerechnet!"
    while True:
        num1 = input("Gib die erste Zahl ein: ")
        operation = input("Welche Rechenoperation soll durchgeführt werden? (+,-,/.,*): ")
        num2 = input("Gib die zweite Zahl ein: ")

        num1 = int(num1)
        num2 = int(num2)

        if operation == "+":
            print("Deine Rechnung:", num1, " + ", num2)
            print("Ergebnis:", num1 + num2)
        elif operation == "-":
            print("Deine Rechnung:", num1, " - ", num2)
            print("Ergebnis:", num1 - num2)
        elif operation == "/":
            print("Deine Rechnung:", num1, " / ", num2)
            print("Ergebnis:", num1 / num2)
        elif operation == "*":
            print("Deine Rechnung:", num1, " * ", num2)
            print("Dein Ergebnis:", num1 * num2)
        else:
            print("Deine Eingaben sind nicht gültig")

        antwort = input("Willst du weiter rechnen, oder etwas anderes machen?")
        if antwort.lower() in ("nein", "stopp"):
            break

        
def main():
    if not login():
        # Programm beendet
        return
        
    #Aktivitätenauswahl
    activity = input("Was möchtest du jetzt machen?")
    if activity in ("TR", "Rechnen", "Taschenrechner"):
        rechnen()
                
main()

Re: Python-Skript mit einem Befehl stoppen

Verfasst: Freitag 20. März 2020, 10:07
von Jankie
Ich löse das immer mit Schleifen und breaks:

#edit: Denke aber die Version von Sirius ist besser, da bei mir schon etwas viel eingerückt wird.

Code: Alles auswählen

def do_math(first_number, operator, second_number):
    if operator == "+":
        return first_number + second_number
    if operator == "-":
        return first_number - second_number
    if operator == "/":
        return first_number / second_number
    if operator == "*":
        return first_number * second_number
    
def is_valid_login(username, passwort):
    if username == "GhastCraftHD" and passwort == "ghastcrafthd":
        return True
    else:
        return False
        
def main():
    username = input("Benutzername: ")
    passwort = input("Passwort: ")
    if is_valid_login(username, passwort):
        print("Anmeldung erfolgreich")
        activity = input("Was möchtest du jetzt machen?[TR/Rechnen/Taschenrechner]: ")
        if activity in ("TR","Rechnen","Taschenrechner"):
            print("Okay, jetzt wird gerechnet!")
            while True:
                first_number = int(input("Gib die erste Zahl ein: "))
                operator = input("Welche Rechenoperation soll durchgeführt werden? [+, -, /, *]: ")
                second_number = int(input("Gib die zweite Zahl ein: "))
                result = do_math(first_number, operator, second_number)
                print(f"{first_number} {operator} {second_number} = {result}")
                choice = input("Willst du weiter rechnen, oder etwas anderes machen? [Nein/Ja]: ")
                if choice == "Nein":
                    break

if __name__ == "__main__":
    main() 

@Sirius3:
Ich habe mal gehört man soll es vermeiden print Befehle in Funktionen zu nutzen und sollte die Ausgaben im main() machen basierend auf dem return der Funktion, stimmt das oder hat mir da jemand Quatsch erzählt?

Re: Python-Skript mit einem Befehl stoppen

Verfasst: Freitag 20. März 2020, 11:02
von __blackjack__
@GhastCraftHD: Bei Anmeldedaten sollte man den Benutzer immer erst beide Angaben, Name *und* Passwort, machen lassen, bevor man die prüft. Wenn man nämlich beim Namen den Benutzer schon wissen lässt ob man ihn kennt oder nicht, dann kann ein Angreifer den Namen und das Passwort getrennt raten. Wenn man beides zugleich prüft, sind auch die Namen schon besser gegen raten geschützt.

Wie man etwas wiederholt hat Jankie ja bereits gezeigt: Eine Schleife. Wenn man beim Schleifeneintritt nicht weiss wie oft die Schleife wiederholt werden wird und auch noch keinen Abbruchbedingung an der Stelle formulieren kann, dann nimmt man eine ”Endlosschleife” (``while True:``). Die kann man dann im Schleifenkörper mit der ``break``-Anweisung verlassen. Das machst Du im Grunde ja bereits für das Rechnen selbst. Dann musst es halt auch für die Aktivitäten machen.

Mit ”WebTigerJython” programmierst Du kein Python sondern eine Sprache die Python sehr ähnlich ist. Und die Turtle-Befehle dort sind auch nicht die gleichen wie die vom `turtle`-Modul aus der Python-Standardbibliothek. Warum TigerJython an der Stelle abweicht ist mir ein Rätsel. Die haben da dann auch Java-Namenskonventionen. Bäh.

Was soll die 4 bei `password4`? Man nummeriert in aller Regel keine Namen. Dann will man entweder bessere Namen oder gar keine Einzelnamen sondern eine Datenstruktur. Oft eine Liste.

Der Code der ausgeführt werden soll wenn der Benutzer die richtigen Zugangsdaten eingegeben hat, muss entweder dort stehen wo auch das ``print("Zugriff gewährt!")`` steht, oder man verschiebt den Code in eine Funktion und bricht die ab, falls falsche Zugangsdaten eingegeben wurden.

Man hat sowieso in der Regel immer eine Funktion, denn auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst und deren Ausführung durch ein ``if __name__ == "__main__":`` bedingt wird. Auch wenn das im Webeditor von TigerJython nicht so viel Sinn macht, funktioniert es dort, und man sollte sich das IMHO gleich angewöhnen.

Statt `activity` mit drei Werten zu vergleichen und das mit ``or`` zu Verknüpfen würde man eher den ``in``-Operator mit einer Sequenz mit den Werten für den Test verwenden.

Bei solchen Benutzereingaben bietet es sich an die in Kleinbuchstaben zu wandeln und mit Worten in Kleinbuchstaben zu vergleichen, damit der Benutzer es einfacher hat und nicht auf Gross-/Kleinschreibung achten muss.

Namen sollte man nicht kryptisch abkürzen. Wenn man `number` oder `operator` meint, sollte man das auch schreiben.

In den ``if``/``elif``-Zweigen steht fast überall das gleiche, es unterscheided sich nur der Operator und die Zeichenkette mit dem Operator bei der ersten Ausgabe. Die Zeichenkette kann man sich sparen weil `oper` ja bereits diesen Wert hat, womit das erste `print()` in jedem Fall gleich ist. Wenn man in den Zweigen nur das Ergebnis berechnet, dann kann man beide `print()`-Aufrufe *einmal* *hinter* das ganze ``if``-Konstrukt schreiben.

Zwischenstand:

Code: Alles auswählen

#!/usr/bin/env python3


def main():
    username = input("Bitte geben sie ihren Benutzernamen ein: ")
    password = input("Bitte gib dein Passwort ein, {}: ".format(username))
    if not (username == "Benutzer 1" and password == "passwort"):
        print("Falsche Zugangsdaten!")
        return

    print("Zugriff gewährt!")
    while True:
        activity = input("Was möchtest du jetzt machen? ").lower()
        if activity in ["tr", "rechnen", "taschenrechner"]:
            print("Okay, jetzt wird gerechnet!")
            while True:
                number_a = int(input("Gib die erste Zahl ein: "))
                operator = input(
                    "Welche Rechenoperation soll durchgeführt werden?"
                    " (+,-,/,*): "
                )
                number_b = int(input("Gib die zweite Zahl ein: "))
                #
                # TODO ``if``-Konstrukt durch Wörterbuch ersetzen, welches
                # Operator auf passende Funktion aus dem `operator`-Modul
                # abbildet.
                #
                if operator == "+":
                    result = number_a + number_b
                elif operator == "-":
                    result = number_a - number_b
                elif operator == "/":
                    result = number_a / number_b
                elif operator == "*":
                    result = number_a * number_b
                else:
                    result = None

                if result is None:
                    print("Deine Eingaben sind nicht gültig!")
                else:
                    print(
                        "Deine Rechnung: {} {} {}.".format(
                            number_a, operator, number_b
                        )
                    )
                    print("Ergebnis: {}.".format(result))

                jein = input(
                    "Willst du weiter rechnen, oder etwas anderes machen?"
                ).lower()
                if jein in ["nein", "stopp"]:
                    break


if __name__ == "__main__":
    main()
Die `main()`-Funktion macht hier aber viel zu viel, das sollte man dringend sinnvoll auf Funktionen aufteilen.

Und es fehlt Fehlerbehandlung. Wenn der Benutzer beispielsweise keine Zahlen eingibt, oder wenn er Division auswählt und als zweiten Operanden eine 0 eingibt.

PS:Oi, Du hast mein Avatar-Bild geklaut! 😠

Re: Python-Skript mit einem Befehl stoppen

Verfasst: Freitag 20. März 2020, 13:29
von GhastCraftHD
@_blackjack_ nimms als Kompliment, es sieht halt einfach gut aus.

An die anderen:
Ich danke euch vielmals für eure tolle Hilfe.
Wir nehmen Python gerade in Informatik durch und deswegen bin ich noch nicht so erfahren.
Ich versuche zu eure guten Vorschläge zu verstehen und sie richtig anwenden zu können.
Auch vielen Dank an die Vielen Tipps.
DANKE!!!

Re: Python-Skript mit einem Befehl stoppen

Verfasst: Freitag 20. März 2020, 13:34
von __deets__
GhastCraftHD hat geschrieben: Freitag 20. März 2020, 13:29 @_blackjack_ nimms als Kompliment, es sieht halt einfach gut aus.
Ich weiss nicht, ob wir hier eine offizielle Policy haben - aber ich wuerde mir wuenschen, du denkst dir was eigenes aus. Solange das nicht der Fall ist, werden ich jedenfalls auf keine deiner Fragen eingehen. Und wenn sich der betroffene __blackjack__ da noch mit anschliesst, dann hast du schon zusammen ~60% der Poweruser verloren. Ueberleg's dir.

Re: Python-Skript mit einem Befehl stoppen

Verfasst: Freitag 20. März 2020, 15:29
von __blackjack__
@GhastCraftHD: Das Kompliment nehme ich gerne an, das ist nämlich selbst gemacht. In einem C64-Emulator fix aus den Grafikzeichen zusammengetippt und dann einen Screenshot gemacht. 😎

Der Zweck von Avataren ist ja, dass man die Benutzer daran optisch leicht erkennen/unterscheiden kann. Du kannst das gerne als Grundlage nehmen und soweit verändern das man die beiden nicht verwechseln kann.

Re: Python-Skript mit einem Befehl stoppen

Verfasst: Freitag 20. März 2020, 22:38
von hyle
GhastCraftHD hat geschrieben: Freitag 20. März 2020, 13:29 nimms als Kompliment, es sieht halt einfach gut aus.
:shock: :roll: (SCNR!)

Re: Python-Skript mit einem Befehl stoppen

Verfasst: Samstag 21. März 2020, 07:54
von GhastCraftHD
@_blackjack_

Sorry, is weg

Re: Python-Skript mit einem Befehl stoppen

Verfasst: Samstag 21. März 2020, 07:59
von GhastCraftHD
Welches Python-Programm könntet ihr mir denn für Linux oder Raspian empfehlen?
Also zum Programmieren.

Re: Python-Skript mit einem Befehl stoppen

Verfasst: Samstag 21. März 2020, 09:52
von __blackjack__
@GhastCraftHD: Editoren und IDEs gibt's wie Sand am Meer. Da solltest Du selbst ein wenig forschen welches Programm am besten zu Dir passt. Ich persönlich verwende Sublime Text, der allerdings etwas kostet, und Vim wenn ich auf der Konsole arbeite, beispielsweise wenn ich über eine SSH-Verbindung direkt auf einem Server arbeiten muss.

Neben einem Editor habe ich immer noch eine interaktive Python-Shell offen, entweder IPython in der Konsole oder JupyterLab im Browser, zum herum probieren und erkunden von Bibliotheken.

Re: Python-Skript mit einem Befehl stoppen

Verfasst: Samstag 21. März 2020, 10:03
von __blackjack__
@Jankie: `print()` muss nicht zwingend auf die `main()`-Funktion beschränkt sein, aber `print()` und `input()` sind Benutzerinteraktion und die sollte man möglichst von der Programmlogik trennen, damit man die Programmlogik ohne einen Benutzer zu benötigen (automatisiert) testen und wiederverwenden kann. Also letztlich die gleiche Argumentation warum man GUI-Code und Programmlogik trennt, denn auch der GUI-Code sollte nur zur Kommunikation mit dem Benutzer dienen.

In dem Beispiel hier würde man beispielsweise sinnvollerweise eine Funktion schreiben die den Benutzer zur Eingabe einer Zahl auffordert, weil man diesen Vorgang zweimal benötigt, einmal für jeden Operanden, und weil das an sich auch eine in sich geschlossene Teilaufgabe darstellt. In dieser Funktion würde man natürlich `input()` und `print()` für eventuelle Fehlermeldungen verwenden.

Neben `print()` um direkt mit dem Benutzer zu kommunizieren, gibt es das noch um die Fehlersuche zu erleichtern oder in Programmlogik allgemein den Fortschritt auszugeben. Bei solchen `print()`-Aufrufen sollte man über Logging nachdenken. Dann kann man die Ausgaben anhand des Log-Levels auch leicht ein-/auschalten oder das ganze in eine oder mehrere Logdateien schreiben (lassen).

Re: Python-Skript mit einem Befehl stoppen

Verfasst: Samstag 21. März 2020, 12:50
von __blackjack__
Noch ein Ansatz das auf Funktionen aufzuteilen und mit Fehlerbehandlung (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python3
from operator import add, sub, truediv, mul

SYMBOL_TO_OPERATION = {"+": add, "-": sub, "/": truediv, "*": mul}


def check_credentials():
    username = input("Bitte geben Sie ihren Benutzernamen ein: ")
    password = input("Bitte geben Sie ihr Passwort ein, {}: ".format(username))
    return username == "Benutzer 1" and password == "passwort"


def ask_for_confirmation(prompt):
    return input(prompt).lower() not in ["n", "nein", "stopp"]


def ask_for_integer(prompt):
    prompt += ": "
    while True:
        try:
            return int(input(prompt))
        except ValueError:
            print("Fehler! Bitte eine ganze Zahl eingeben.")


def ask_for_operation():
    symbols = ",".join(SYMBOL_TO_OPERATION)
    while True:
        operator = input(
            "Welche Rechenoperation soll durchgeführt werden? ({}): ".format(
                symbols
            )
        )
        if operator not in SYMBOL_TO_OPERATION:
            print("Ungültiger Operator: {}".format(operator))
        else:
            return operator, SYMBOL_TO_OPERATION[operator]


def run_calculator():
    print("Okay, jetzt wird gerechnet!")
    while True:
        number_a = ask_for_integer("Gib die erste Zahl ein")
        operator, operation = ask_for_operation()
        number_b = ask_for_integer("Gib die zweite Zahl ein")

        print("Deine Rechnung: {} {} {}.".format(number_a, operator, number_b))
        try:
            result = operation(number_a, number_b)
        except ZeroDivisionError:
            print("Fehler! Versuch durch 0 zu teilen.")
        else:
            print("Ergebnis: {}.".format(result))

        if not ask_for_confirmation(
            "Willst du weiter rechnen, oder etwas anderes machen?"
        ):
            break


def run_main_menu():
    while True:
        answer = input("Was möchtest du jetzt machen? ").lower()
        if answer in ["tr", "rechnen", "taschenrechner"]:
            run_calculator()


def main():
    if check_credentials():
        print("Zugriff gewährt!")
        run_main_menu()
    else:
        print("Falsche Zugangsdaten!")


if __name__ == "__main__":
    main()