Einfaches Python-Konsolenspiel mit ineffizientem Codefluss
Ich habe ein einfaches Programm als Übung zur Verbesserung meines Codeflusses in Python erstellt, das Folgendes bewirkt:
- fordert den Benutzer auf, seinen Namen einzugeben
- bietet ihnen die Wahl, entweder ihren Namen in umgekehrter Reihenfolge oder die Anzahl der Zeichen zu drucken
- Nachdem die Ausgabe gedruckt wurde, wird der Benutzer gefragt, ob er "erneut spielen" möchte. Wenn nicht, wird beendet
Habe ich etwas besonders doof gemacht? Irgendwelche niedrig hängenden Früchte? Best Practice, die mir nicht bekannt ist?
from sys import exit
def userinput():
print('Enter your name:')
n = input()
print('Hello, ' + n + ', would you rather (R)everse or (C)ount the letters of your name?')
a = input()
return (a,n)
def choosef(choice,myname):
while choice not in ['R','C']:
print("Only 'R' or 'C' are valid. Try again:")
choice = input()
if choice == 'R':
print(''.join(reversed(myname)))
else:
spaces = 0
for c in list(myname):
if c == ' ':
spaces = spaces + 1
print('Total # Characters: ' + str(len(myname) - spaces))
playagain()
def playagain():
print("Would you like to play again, (Y)es or any other character to exit?")
yn = input()
if yn == 'Y':
ui = userinput()
choosef(ui[0],ui[1])
else:
exit()
ui = userinput()
choosef(ui[0],ui[1])
Antworten
Versuchen Sie, alles zu vergessen, was Sie über den Code wissen, und nehmen Sie an, dass Sie nicht der Autor sind. Stellen Sie sich vor, Sie sind eine dritte Person, die den Code liest, nichts darüber weiß und ihn nur zum ersten Mal liest.
ui = userinput()
choosef(ui[0],ui[1])
Okay, userinput()ich muss etwas eingeben und hineinstecken ui. Sinnvoll, aber was ist choosef()?
Namenskonvention
Verwenden Sie aussagekräftige Namen für Funktionen und Variablen. Nehmen Sie dieses Beispiel
x = 3.14
y = 24
Was ist xund yfür den Leser? Ist das der Preis von etwas?
pi_value = 3.14
number_of_hours = 24
Ahhh okay, jetzt weiß ich genau was 3.14bedeutet. Wenn ich es also irgendwo benutze, weiß der Leser auch, was ich genau meine. Dies ist ein wichtiger Teil beim Schreiben von sauberem Code.
Ein weiterer Aspekt ist der Stil. Es gibt einige Möglichkeiten, wie ich Benutzereingaben schreiben kann *
user_input()
USERINPUT()
UserInput()
userinput()
Welchem soll ich folgen?
Um eine konsistente Namenskonvention zu erhalten, folgt der Python-Code der PEP-8- Namenskonvention. Wenn ich Folgendes sage, meine ich, dass es empfohlen wird, dass Sie es auch befolgen, da andere Python-Bibliotheken dies ebenfalls verwenden. Dadurch sieht der Code sauberer aus.
Dinge wie Funktionen folgen: lower_snake_case
Klassen folgen: CamelCase
Sie können den Link für weitere Informationen lesen.
Eingaben in Python
print('Enter your name:')
n = input()
Natürlich möchten Sie dem Benutzer eine Nachricht anzeigen, bevor er etwas eingibt. Aus diesem Grund verfügt die input()Funktion über eine sogenannte Eingabeaufforderung .
name = input("Enter your name: ")
Sie können die Nachricht zwischen dem anzeigen (). Dadurch wird die zusätzliche Zeile entfernt. Beachten Sie auch , dass ich geändert , num nameaus den Gründen , die ich oben erwähnt.
Zeichenfolgen formatieren
Aus Ihrem Code kann ich ersehen, dass Sie Zeichenfolgen verkettet haben +, um aussagekräftige Sätze zu bilden. Das funktioniert, aber es gibt ein großes Problem, wenn Sie Variablen unterschiedlichen Typs verwenden möchten.
name = "Eric"
age = 14
job = "Comedian"
print("Hello " + name + "You are " + age + " years old and you are a " + comedian)
TypeError: Kann nur str (nicht "int") mit str verketten
Verwenden Sie einfach die F-Strings von Python 3 . Setzen Sie den Buchstaben 'f' vor"
print(f"Hello {name}, you are {age} years old ")
Reiniger.
Rückgabewert von userinput()
Was Sie gerade tun, ist die Rückgabe eines Tupels von choiceund name. Es ist besser, wenn Sie sie so lassen, wie sie sind, weil Sie später davon abschneiden, nur um sie wieder zu bekommen. Dies bedeutet, dass Sie dies direkt tun
return name, choice
# Calling the function
name, choice = userinput()
Codestruktur
Ein paar Punkte
Fragen Sie nicht
"Do you want to play again? "in derplay_again()Funktion. Der Grund, warum Sie diese Funktion aufgerufen haben, sollte sein, dass der Benutzer erneut spielen möchte. Bewegen Sie dies zu einerplaygame()Funktion, dieuser_input()jedes Mal aufgerufen wird, wenn der Benutzer das Spiel spielen möchte, und brechen Sie die Schleife nur ab, wenn der Benutzer'n'oder eingibt"no"spaces = spaces + 1kann vereinfacht werden inspaces += 1Verschieben Sie den Teil, in dem Sie die Anzahl der Zeichen zählen, in eine separate Funktion, die eine Ganzzahl zurückgibt. Ihre
play_game()Funktion macht also nichts anderes als das Spiel zu spielen . Wenn Sie die Zeichen brauchen ,number_of_char = character_len( name ).Verwenden Sie zur Verdeutlichung die Aufzählung .
Eine verbesserte Version des Codes
from enum import Enum
class PrintChoices(Enum):
number_of_char = 'c'
reversed_name = 'r'
exit_choice = 'e'
def find_num_of_char(name):
return len(name) - name.count(' ')
def reverse_name(name):
return name[::-1]
def user_input():
name = input("Enter your name: " )
choice = input("Would you like to (r)everse your name\n or would you like to print the number of (c)haracters or (e)xit?: ")
return name, choice
def clear_screen():
print(chr(27) + "[2J")
def play_game():
while True:
clear_screen()
name, choice = user_input()
if choice == PrintChoices.reversed_name.value:
print(reverse_name(name))
input("Press any key to continue...")
elif choice == PrintChoices.number_of_char.value:
print(find_num_of_char(name))
input("Press any key to continue...")
elif choice == PrintChoices.exit_choice.value:
break
else:
input("Invalid input, Press any key to continue...")
play_game()
Hinweis: Ich habe auch hinzugefügt print(chr(27) + "[2J"), um den Bildschirm zu löschen.
Sie können eine bessere Struktur haben. Hier finden Sie eine ausführliche Erklärung. Datenflussfehler, die Sie in der realen Welt nicht machen sollten:
- Hier machen Ihre Funktionsaufrufe keinen Sinn. Wenn Sie Funktionen definieren und verwenden, definieren Sie sie so, dass sie sich nicht gegenseitig aufrufen, dh es sollte eine Baumstruktur geben. Hauptfunktion steuert alle. (Siehe untenstehenden Code, um einen Einblick zu erhalten.)
- Ihr Skript kann besser strukturiert sein. Siehe unten Code.
*** PROTIP: Wenn Sie Ihren Code wartbarer machen möchten, teilen Sie ihn in Module auf, fügen Sie alle in verschiedene Dateien ein und importieren Sie sie ***
def take_name_input():
print('Enter your name:')
n = input()
return n
def ask_choice():
print('Hello, ' + n + ', would you rather (R)everse or (C)ount the letters of your name?')
a = input()
return a
def playgame(myname):
while True:
choice = ask_choice()
if choice == 'R':
print(''.join(reversed(myname)))
elif choice == 'C':
for c in list(myname):
if c == ' ':
spaces = spaces + 1
print('Total # Characters: ' + str(len(myname) - spaces))
else:
break
name = take_name_input()
playgame(name)
Ich denke, die Struktur ist ziemlich kompliziert, mit Aufrufen von input () und Choosef (), die an mehreren Stellen / Ebenen verteilt sind, daher ist das Programm nicht super lesbar und nicht skalierbar (wenn Sie mehr Benutzereingaben verarbeiten müssten).
Ein besser lesbarer Ansatz wäre eine Hauptschleife wie - im Pseudocode
while True:
Get user input from 3 choices R / C / E(xit)
if input = E:
exit
else if input = R:
handle R case
else
handle C case
Auch in Python gibt es eine kürzere Möglichkeit, einen String mit Slicing-Syntax umzukehren: "abc" [:: - 1]
Es gibt zwei Bereiche, in denen sich Ihr Code weiter verbessern könnte.
Zuerst können Sie Tools wie flake8 oder pylint ausführen, um Ihren Code auf "Verstöße" gegen PEP8 zu überprüfen. PEP8 ist ein Python-Styleguide, der als De-facto-Style für Python-Code akzeptiert wird. Ich werde mich nicht darauf konzentrieren, da dies meistens ein automatischer Prozess und eine etwas persönliche Entscheidung ist.
Zweitens können Sie Ihren Code in Bezug auf Benennung und Dokumentation verbessern. Dies nennen wir die Lesbarkeit Ihres Codes. Ich habe selbst einen Versuch unternommen und dies ist, was ich (persönlich) als besseren Code empfinde.
Eine Sache, die Sie verbessern können, ist das Entfernen aller Magie aus Ihrem Code. In den beiden folgenden Zeilen legen Sie eine Variable fest uiund übergeben das erste und zweite Element an eine andere Funktion. Wenn ich diese beiden Zeilen sehe, habe ich keine Ahnung, was Sie tun.
ui = userinput()
choosef(ui[0],ui[1])
Dies kann vereinfacht und lesbarer gemacht werden, indem bessere Variablennamen ausgewählt werden und (zumindest in diesem Fall) Tupel entpackt wird:
action, name = get_user_input()
handle_user_action(action, name)
Das obige Beispiel kann auf Ihren gesamten Code angewendet werden. Ich beurteile meinen Code (und den Code, den ich überprüfe) immer mit der Frage: "Wenn ich diesen Codeblock jemandem zeige, ist die Absicht des Codes für die Person, die ihn liest, klar, ohne Kenntnisse des gesamten Programms zu benötigen?"