Blutiger Anfänger sucht Verbesserungsvorschläge :P

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Kristally
User
Beiträge: 6
Registriert: Sonntag 12. Februar 2017, 12:15

Hallo zusammen :D , ich habe angefangen mit Python zu programmieren und bin somit blutiger Anfänger. Als wir in der Schule mit der Kreisberrechung angefangen haben, dachte ich dass sich das doch als erstes Programm gut anbieten würde. Ich hab da einfach mal was zusammen geschustert und naja, es funktioniert, aber der Code ist für eure Augen wahrscheinlich furchtbar :lol: . Hättet ihr vll Ideen wie ich den Code verbessern/ abkürzen könnte?

Lg, Kristally

Code: Alles auswählen

#Kreisberechung

#Imports
import time
import sys
import os

#Variablen initalisieren
x = 1
Pi = 3.14159265359
y = 1
yy = 1
yyy = 1

#Einleitung
print("Kreisberechnung")
print("")
time.sleep(2)

#Auswahl treffen
while x == 1:
	os.system('cls')
	print("Zuerst müssen sie auswählen, welche Angabe vorhanden ist.")
	time.sleep(2)
	print("")
	print("-----------------------------------------------------")
	print("Wenn der Umfang vorhanden ist, tippen sie die 1 ein.")
	print("Wenn der Radius vorhanden ist, tippen sie die 2 ein.")
	print("Wenn Durchmesser vorhanden ist, tippen sie die 3 ein.")
	print("-----------------------------------------------------")
	time.sleep(1)
	z = input("Welche Nummer wählen sie?: ")

	#Unwandlung
	try:
		zahl = int(z)
		

	except:
		print(z + " war keine der angegebenen Möglichkeiten.")
		time.sleep(1.5)
		os.system('cls')
		continue
	
	
	#Wenn Umfang vorhanden
	if zahl == 1:
		x = 0
		os.system('cls')
		print("Der Umfang ist also vorhanden.")
		print("")
		time.sleep(0.5)
		while yyy == 1:
			u1 = input("Geben sie nun den Umfang ein: ")
		
			try:
				uFloat = float(u1)
				
		
			except:
				print(u1 + " ist keine gültige Zahl.")
				continue
			yyy = 0
		#Rechnung
		Durchmesser = uFloat/Pi
		Radius = Durchmesser/2
		Umfang = uFloat
		
		
	
	#Wenn Radius vorhanden
	if zahl == 2:
		x = 0
		os.system('cls')
		print("Der Radius ist also vorhanden.")
		print("")
		time.sleep(0.5)
		while y == 1:
			r1 = input("Geben sie nun den Radius ein: ")
		
			try:
				rFloat = float(r1)
				
		
			except:
				print(r1 + " ist keine gültige Zahl.")
				continue
			y = 0
	
		#Rechnung
		Durchmesser = rFloat*2
		Umfang = Pi*Durchmesser
		Radius = rFloat
		
		
	#Wenn Durchmesser vorhanden.	
	if zahl == 3:
		x = 0
		os.system('cls')
		print("Der Durchmesser ist also vorhanden.")
		print("")
		time.sleep(0.5)
		while yy == 1:
			d1 = input("Geben sie nun den Durchmesser ein: ")
		
			try:
				dFloat = float(d1)
				
		
			except:
				print(d1 + " ist keine gültige Zahl.")
				continue
			yy = 0
			
			
			
	
		
		
		
		
		#Rechnung
		Umfang = Pi*dFloat
		Radius = dFloat/2
		Durchmesser = dFloat
		
		
			

	#Ergebnis
	os.system('cls')
	print("--------------------------------------------")
	print("Ihre Daten werden bearbeitet...")
	print("--------------------------------------------")
	time.sleep(1.5)
	os.system('cls')
	print("Ihre Daten lauten: ")
	print("")
	time.sleep(0.7)
	print("Umfang: ", Umfang)
	time.sleep(0.5)
	print("Radius: ", Radius)
	time.sleep(0.5)
	print("Durchmesser: ", Durchmesser)
	print("")
	time.sleep(2)

	#Frage nach restart
	print("Wollen sie zurück zum Hauptmenü?")
	print("Wenn Ja, tippen sie Ja, ein. Wenn nicht drücken sie eine beliebige Taste.")
	Restart = (str(input()))	

	if Restart == "Ja":
		x = 1

	else:
		print("")
	
Zuletzt geändert von Anonymous am Sonntag 12. Februar 2017, 13:21, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@Kristally: Kommentare sollten dem Code gegenüber einen Mehrwert bieten. Vor den Importen ``#Imports`` zu kommentieren tut das beispielsweise nicht. Wer ohne den Kommentar nicht versteht das dort Importe stehen, dem hilft auch der Kommentar kein Stück weiter.

Variablen sollte man nicht in einem Block irgendwo am Anfang initialisieren, sondern immer erst dann wenn man sie auch tatsächlich braucht.

Pi ist bereits im `math`-Modul als Konstante definiert.

Namen sollten dem Leser vermitteln was der Wert der daran gebunden wird, im Programm bedeutet. Denn der Leser will das Programm ja verstehen. `x`, `y`, `yy`, und `yyy` sind Beispiele für sehr schlechte Namen. Die sind absolut nichtssagend. `x` und `y` sogar etwas verwirrend, denn das wären Namen bei denen der Leser so etwas wie X- und Y-Koordinaten erwarten würde. Einbuchstabige sind in der Regel bis aus wenige Ausnahmen keine gute Wahl wenn sie einen grösseren Gültigkeitsbereich als einen Ausdruck haben. Ausnahmen wären `x`, `y`, und `z` für Koordinaten, oder `i`, `j`, und `k` für ganzzahlige Laufvariablen, weil man das aus der Mathematik kennt.

Was sollten die ganzen `sleep()`-Aufrufe? Der Benutzer hat einen normalen, oder vielleicht sogar alten oder schwachen Rechner, möchte aber sich nicht sinnlos 5 Sekunden warten bis er eine Eingabe beim Menü machen kann. Das würde mich, genau wie das Bildschirm löschen, als Benutzer massiv stören.

Python hat einen Datentyp für Wahrheitswerte (`bool`) mit den Werten `True` und `False`. Man sollte stattdessen keine Zahlen verwenden wenn man eigentlich Wahrheitswerte meint.

Das Programm hat einen Fehler, denn bei einem Restart wird nur das `x`-Flag zurückgesetzt, aber nicht die Flags für die anderen Schleifen.

Allerdings sollte man die sowieso alle loswerden. Man würde da besser ”Endlosschleifen” schreiben (``while True:``) und die dann bei der passenden Bedingung mit ``break`` verlassen. Oder auch mit ``return`` wenn man das in einer Funktion stehen hat und mit dem Ende der Schleife auch der Rückgabewert der Funktion feststeht.

Womit wir bei Funktionen wären: Das Programm ist viel zu lang. Das sollte man sinnvoll auf Funktionen aufteilen. Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.

Keine ”nackten” ``except:``\s verwenden. Das behandelt *alle* Ausnahmen, auch solche bei denen die Behandlung keinen Sinn macht, die in dem ``except:``-Zweig steht. Und da man immer mit Ausnahmen rechnen muss an die man nicht gedacht hat, kann man sich so die Fehlersuche schwer bis unmöglich machen.

Von ``continue`` würde ich die Finger lassen. Das kann man fast immer anders strukturieren, so dass man keine Sprünge hat die man nicht an der Einrückung erkennen kann. ``continue`` kann es auch schwierig machen Teile aus einer Schleife in eine eigene Funktion auszulagern, oder später etwas ans Ende der Schleife zu schreiben, was bei jedem Schleifendurchlauf ausgeführt werden soll. In allen Fällen im Programm kann man das Beispielsweise loswerden in dem man ein ``else`` zum ``try``/``except`` verwendet.

Ein zweiter Programmfehler schlägt zu wenn der Benutzer im Menü zwar eine Zahl eingibt, aber nicht 1, 2, oder 3. Den Fall sollte man auch behandeln. Da die Eingabe nur einen Wert haben kann, machen auch keine drei getrennten ``if``-Anweisungen Sinn. Denn wenn `zahl` 1 ist, dann braucht man die anderen beiden ``if``-Anweisungen gar nicht ausführen, denn die Bedingungen *müssen* dann ja unwahr sein. Also ``if``/``elif`` und für die Falscheingaben noch ein ``else``.

Den gemeinsamen Code aus den drei Menüpunkten sollte man in eine eigene Funktion auslagern. Don't Repeat Yourself (DRY) ist ein wichtiges Prinzip beim Programmieren, das sowohl für Code als auch für Daten gilt. Immer wenn man Code hat der nach kopieren, einfügen, und leicht verändern aussieht, ist das ein Warnzeichen, dass man etwas falsch macht.

Der Grunddatentyp hat nichts in Namen zu suchen.

Zur Namensschreibweise: Konstanten werden per Konvention komplett in GROSSBUCHSTABEN_MIT_UNTERSTRICHEN geschrieben, Klassen in MixedCase, und alles andere klein_mit_unterstrichen.

Die `input()`-Funktion liefert schon Zeichenketten, da macht es keinen Sinn die mit `str()` in eine Zeichenkette zu wandeln. Und das ganze dann noch mal unnötig in Klammern zu setzen.

Den Benutzer zur Eingabe von 'Ja' mit Beachtung von Gross-/Kleinschreibung zu zwingen ist nicht besonders nutzerfreundlich.
Kristally
User
Beiträge: 6
Registriert: Sonntag 12. Februar 2017, 12:15

Danke für das detaillierte Feedback :) Werde versuchen deine Liste abzuarbeiten :P
MARSi
User
Beiträge: 9
Registriert: Samstag 11. Februar 2017, 13:14
Wohnort: 127.0.0.1:8080
Kontaktdaten:

Hi,

ich weiss nicht, ob dich das weiter bringt, aber mir wurde das Buch "Weniger Schlecht programmieren von Kathrin Passig und Johannes Jander" empfohlen ... Hat erstmal nich wirklich was mit Python zu tun.
Das soll jetzt keine Anspielung auf deine Leistung sein, aber mir hat das damals sehr geholfen....

Oder ZEN of Python

MARS
Benutzeravatar
pixewakb
User
Beiträge: 1408
Registriert: Sonntag 24. April 2011, 19:43

http://www.gailer-net.de/tutorials/java/java-toc.html

http://www.hpcodewars.org/

Ich mag diese beiden Seiten und zwar die Programmieraufgaben (!) dort. Bei gailer-net.de habe ich in Python mal die Programmieraufgaben gelöst. Gerade zu Beginn sind die in Python sehr schnell zu lösen und helfen m. E.
RIN67630
User
Beiträge: 91
Registriert: Sonntag 29. April 2018, 08:07

BlackJack hat geschrieben:Kommentare sollten dem Code gegenüber einen Mehrwert bieten.
Oh, ja!
Natürlich, nur kommentieren was man macht, wenn es nicht trivial ist.

Aber auch -und das kommt sehr oft vor- nicht vergessen zu kommentieren warum man etwas so programmiert !

So kommt es immer wieder vor, dass ein weiterer Nutzer des Codes die berechtigte Intention des Programmierers nicht versteht, den Code für Blödsinn erklärt, nur um -nach vielen try-and-error Zyklen- wieder etwas ähnliches einbauen zu müssen. :P

Am Anfang sollte man -insbesondere bei lange Programme- kommentieren, was das Programm macht [machen soll] und die soft- und hardwaremäßige Abhängigkeiten vorgeben. Bei Python: für welche Python- Hauptversion der Code getestet wurde.
Antworten