Wie kann ich ein Programm "unendlich" laufen lassen?

Code-Stücke können hier veröffentlicht werden.
Antworten
lacreature
User
Beiträge: 17
Registriert: Dienstag 5. März 2019, 23:34

Ich habe ein "Guess the number"-Spiel geschrieben, allerdings in zwei verschiedenen Ausführungen:

1. Ausführung:
Als erstes kann man wählen, ob man spielen möchte, falls ja, beginnt das Spiel. Man hat 3 Versuche die Zahl zu erraten:

Code: Alles auswählen

"""Guess number game"""
import random
attempt = 0

print("""
I have a number in mind between 1 and 10.

Do you want to guess it?

You have 3 tries!

Enjoy :)
""")
letsstart = input("Do you want to start? (yes/no):  ")

if letsstart == 'yes':
    print("Let's start")
else:
    print("Ok, see you :) ")

    
computernumber = random.randrange(10)
print("I think of a number between 0 and 10")

while attempt < 3:
    guess = int(input("What is your guess?:  "))

    attempt = attempt + 1

    if guess == computernumber:
        break
    
    elif guess <= computernumber:
        print("My number is bigger than yours")

    elif guess >= computernumber:
        print("My number is smaller than yours")

    

if guess == computernumber:
    print("Nice, you got it! :-)")
if guess != computernumber:
    print("try it again ;-) ")
2. Ausführung:
Dieses Mal habe ich es objektorientiert versucht (erster Versuch). Es klappt aber nach einer Eingabe, endet es, wie kann ich es weiter laufen lassen, komme nicht mehr weiter:

Code: Alles auswählen

import random

class Game:
    def __init__(self, low , up):
        self.low , self.up = low , up
        self.winNumber = random.randint(self.low , self.up)

    def userGuess(self):
        self.userGuessNumber = usenum

    def gameWin(self, x):
        self.userGuessNumber = usenum
        self.progNumber = random.randint(self.low , self.up)
      


low, up = 0 , 20
game = Game(low , up)
usenum = int(input("guess a number from %d to %d: " %(low , up)))
while game.gameWin(usenum):
    print("you won")
else:
    print("maybe next time ;) ")
Meine wichtigste Frage ist, wie bekomme ich es hin, dass das Programm so lange weiter läuft, bis der Benutzer das nicht mehr will? Ich weiß nicht wie ich da beim ersten Beispiel die Schleifen setzen kann.
Kann ich außerdem die Funktionen des Beispiels in der Klasse beschreiben, also sozusagen das erste in das zweite einfügen und so das Programm laufen lassen?
Vielen Dank für die Hilfe schon mal!
lacreature
User
Beiträge: 17
Registriert: Dienstag 5. März 2019, 23:34

Ok habe jetzt noch eins geschrieben und jetzt klappt es auch so wie ich will :)
Was sagt ihr dazu?

Code: Alles auswählen

import random
name = input("Hey, What's your name?  ")
print("Welcome to this game, ", name ,  ".", "This is a 'Guess number game' , I will think of a number between 0 and 50 and I will give you 5 tries to guess it ;)")

def numbergame():
    game_number = random.randint(0,50)
    i = 1
    r = 1
    while i <6:
        user_number = int(input("What is your guess?  "))
        if user_number < game_number:
            print(name , " , my number is bigger.. ")
            i = i+1
        elif user_number > game_number:
            print(name, " , my number is smaller..")
            i = i+1
        elif user_number == game_number:
            print("Nice, ", name , "you guessed my number! :) ")
            r = 0;
            break
    if r == 1:
        print("Sorry, maybe you'll guess it next time ;) ")
        print("my number was: ", str(game_number))

def main():
    numbergame()
    while True:
        again = input("Do you wish to play again? (yes/no):  ")
        if again == 'yes':
            numbergame()
        else:
            break
main()
print("See you soon!")
__deets__
User
Beiträge: 14523
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wenn du numbergame() als erstes in der Schleife aufrufst, und dann nur bei nein breakst, kommst du mit einem Aufruf weniger aus.

Und while-schleifen mit zählen macht man nicht. Benutz “for in range(6)” und benutz for-else für deine hat-nicht-geklappt-Nachricht.
Benutzeravatar
__blackjack__
User
Beiträge: 13071
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@lacreature: Die Eingabe des Namens sowie die Verabschiedung gehören auch mit in die `main()`-Funktion. Auf Modulebene sollte nur Code stehen, der Konstanten, Funktionen, und Klassen definiert.

Funktionen und Methoden sollten alles was sie ausser Konstanten benötigen als Argument(e) übergeben bekommen, und nicht ”magisch” aus der Umgebung. Das betrifft hier den vom Benutzer eingegebenen Namen, der an `numbergame()` übergeben werden muss.

Bei ``r = 0;`` ist das Semikolon überflüssig. Der Name `r` ist auch nicht gut, weil der nicht deutlich vermittelt wofür der Wert steht. Zudem scheint das eigentlich ein Wahrheitswert zu sein, wofür Python den Typ `bool` und die Werte `True` und `False` hat.

`print()` wandelt die auszugebenden Argumente selbst in Zeichenketten um. Der `str()`-Aufruf bei `game_number` ist also überflüssig.

Die `print()`-Funktion gibt zwischen den auszugebenden Argumenten jeweils ein Leerzeichen aus, darum ist diese Art des Aufrufs nicht geeignet wenn nach einer Variablen ein Punkt oder ein anderes Satzzeichen ausgegeben werden soll. Zeichenkettenformatierung mittels `format()`-Methode oder f-Zeichenketten ist da flexibler.

Man sollte Code und Daten nicht wiederholen. Das ist fehleranfällig wenn man Programme später einmal ändern möchte und dann an allen wiederholten Stellen den Quelltext gleich ändern muss. Dabei können Fehler passieren wenn man nicht alle Stellen erwischt, oder nicht alle gleichartig verändert. Im vorliegenden Programm wäre das der Zahlenbereich aus dem die Nummer gewählt wird, und die Anzahl der Versuche. Wenn man das ändern möchte, muss man das an zwei Stellen tun: In der Ausgabe am Anfang, und in der `numbergame()`-Funktion.

Die Zahlen kann man beispielsweise als Konstanten herausziehen, und als Argumente an `numbergame()` übergeben.

Da wären wir dann ungefähr hier (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python3
import random

LOWER_LIMIT = 0
UPPER_LIMIT = 50
TRIAL_COUNT = 5


def numbergame(name, lower_limit, upper_limit, trial_count):
    game_number = random.randint(lower_limit, upper_limit)
    for _ in range(trial_count):
        user_number = int(input('What is your guess? '))
        if user_number < game_number:
            print(f'{name}, my number is bigger..')
        elif user_number > game_number:
            print(f'{name}, my number is smaller..')
        elif user_number == game_number:
            print(f'Nice, {name} you guessed my number! :)')
            break
    else:
        print("Sorry, maybe you'll guess it next time ;) ")
        print(f'my number was: {game_number}')


def main():
    name = input("Hey, What's your name?  ")
    print(
        f"Welcome to this game, {name}. This is a 'Guess number game',"
        f" I will think of a number between {LOWER_LIMIT} and {UPPER_LIMIT}"
        f" and I will give you {TRIAL_COUNT} tries to guess it ;)"
    )
    while True:
        numbergame(name, LOWER_LIMIT, UPPER_LIMIT, TRIAL_COUNT)
        again = input('Do you wish to play again? (yes/no):  ')
        if again != 'yes':
            break
    
    print('See you soon!')


if __name__ == '__main__':
    main()
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
lacreature
User
Beiträge: 17
Registriert: Dienstag 5. März 2019, 23:34

oh cool, habe meinen code jetzt umgeschrieben und es funktioniert super :)
könntest du mir vielleicht noch erklären, warum du am ende

Code: Alles auswählen

if __name__ == '__main__':
    main()
schreibst? main() alleine würde doch reichen oder? ich kann es lesen, verstehe nur nicht warum du es so schreibst, wäre nämlich nie darauf gekommen :D
Benutzeravatar
__blackjack__
User
Beiträge: 13071
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@lacreature: `__name__` hat als Wert den Namen des Moduls, also in der Regel den Dateinamen ohne die *.py-Endung. Ausser wenn man das Modul als Programm startet, dann hat `__name__` den Wert '__main__'. So kann man das Modul als Programm ausführen und die `main()`-Funktion wird dann ausgeführt. Aber man kann das Modul auch importieren, in einem anderen Modul, oder in einer interaktiven Python-Shell, und `main()` wird dann *nicht* automatisch ausgeführt. Das ist zur Fehlersuche praktisch, weil man dann einzelne Funktionen in einer Python-Shell ausprobieren kann. Und man automatisierte Tests schreiben. Und einige Werkzeuge, zum Beispiel zum Dokumentieren von Code, erwarten ebenfalls das man Module importieren kann ohne das etwas ”passiert” was über die Definition von Konstanten, Funktionen, und Klassen hinaus geht.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten