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.
Kristally
User
Beiträge: 3
Registriert: Sonntag 12. Februar 2017, 12:15

Blutiger Anfänger sucht Verbesserungsvorschläge :P

Beitragvon Kristally » Sonntag 12. Februar 2017, 12:40

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
  1. #Kreisberechung
  2.  
  3. #Imports
  4. import time
  5. import sys
  6. import os
  7.  
  8. #Variablen initalisieren
  9. x = 1
  10. Pi = 3.14159265359
  11. y = 1
  12. yy = 1
  13. yyy = 1
  14.  
  15. #Einleitung
  16. print("Kreisberechnung")
  17. print("")
  18. time.sleep(2)
  19.  
  20. #Auswahl treffen
  21. while x == 1:
  22.     os.system('cls')
  23.     print("Zuerst müssen sie auswählen, welche Angabe vorhanden ist.")
  24.     time.sleep(2)
  25.     print("")
  26.     print("-----------------------------------------------------")
  27.     print("Wenn der Umfang vorhanden ist, tippen sie die 1 ein.")
  28.     print("Wenn der Radius vorhanden ist, tippen sie die 2 ein.")
  29.     print("Wenn Durchmesser vorhanden ist, tippen sie die 3 ein.")
  30.     print("-----------------------------------------------------")
  31.     time.sleep(1)
  32.     z = input("Welche Nummer wählen sie?: ")
  33.  
  34.     #Unwandlung
  35.     try:
  36.         zahl = int(z)
  37.        
  38.  
  39.     except:
  40.         print(z + " war keine der angegebenen Möglichkeiten.")
  41.         time.sleep(1.5)
  42.         os.system('cls')
  43.         continue
  44.    
  45.    
  46.     #Wenn Umfang vorhanden
  47.     if zahl == 1:
  48.         x = 0
  49.         os.system('cls')
  50.         print("Der Umfang ist also vorhanden.")
  51.         print("")
  52.         time.sleep(0.5)
  53.         while yyy == 1:
  54.             u1 = input("Geben sie nun den Umfang ein: ")
  55.        
  56.             try:
  57.                 uFloat = float(u1)
  58.                
  59.        
  60.             except:
  61.                 print(u1 + " ist keine gültige Zahl.")
  62.                 continue
  63.             yyy = 0
  64.         #Rechnung
  65.         Durchmesser = uFloat/Pi
  66.         Radius = Durchmesser/2
  67.         Umfang = uFloat
  68.        
  69.        
  70.    
  71.     #Wenn Radius vorhanden
  72.     if zahl == 2:
  73.         x = 0
  74.         os.system('cls')
  75.         print("Der Radius ist also vorhanden.")
  76.         print("")
  77.         time.sleep(0.5)
  78.         while y == 1:
  79.             r1 = input("Geben sie nun den Radius ein: ")
  80.        
  81.             try:
  82.                 rFloat = float(r1)
  83.                
  84.        
  85.             except:
  86.                 print(r1 + " ist keine gültige Zahl.")
  87.                 continue
  88.             y = 0
  89.    
  90.         #Rechnung
  91.         Durchmesser = rFloat*2
  92.         Umfang = Pi*Durchmesser
  93.         Radius = rFloat
  94.        
  95.        
  96.     #Wenn Durchmesser vorhanden.   
  97.     if zahl == 3:
  98.         x = 0
  99.         os.system('cls')
  100.         print("Der Durchmesser ist also vorhanden.")
  101.         print("")
  102.         time.sleep(0.5)
  103.         while yy == 1:
  104.             d1 = input("Geben sie nun den Durchmesser ein: ")
  105.        
  106.             try:
  107.                 dFloat = float(d1)
  108.                
  109.        
  110.             except:
  111.                 print(d1 + " ist keine gültige Zahl.")
  112.                 continue
  113.             yy = 0
  114.            
  115.            
  116.            
  117.    
  118.        
  119.        
  120.        
  121.        
  122.         #Rechnung
  123.         Umfang = Pi*dFloat
  124.         Radius = dFloat/2
  125.         Durchmesser = dFloat
  126.        
  127.        
  128.            
  129.  
  130.     #Ergebnis
  131.     os.system('cls')
  132.     print("--------------------------------------------")
  133.     print("Ihre Daten werden bearbeitet...")
  134.     print("--------------------------------------------")
  135.     time.sleep(1.5)
  136.     os.system('cls')
  137.     print("Ihre Daten lauten: ")
  138.     print("")
  139.     time.sleep(0.7)
  140.     print("Umfang: ", Umfang)
  141.     time.sleep(0.5)
  142.     print("Radius: ", Radius)
  143.     time.sleep(0.5)
  144.     print("Durchmesser: ", Durchmesser)
  145.     print("")
  146.     time.sleep(2)
  147.  
  148.     #Frage nach restart
  149.     print("Wollen sie zurück zum Hauptmenü?")
  150.     print("Wenn Ja, tippen sie Ja, ein. Wenn nicht drücken sie eine beliebige Taste.")
  151.     Restart = (str(input()))   
  152.  
  153.     if Restart == "Ja":
  154.         x = 1
  155.  
  156.     else:
  157.         print("")
  158.    
Zuletzt geändert von BlackJack am Sonntag 12. Februar 2017, 13:21, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Benutzeravatar
BlackJack
Moderator
Beiträge: 33001
Registriert: Dienstag 25. Januar 2005, 23:29
Wohnort: Berlin
Kontaktdaten:

Re: Blutiger Anfänger sucht Verbesserungsvorschläge :P

Beitragvon BlackJack » Sonntag 12. Februar 2017, 13:52

@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.
“Programs must be written for people to read, and only incidentally for machines to execute.” — Abelson & Sussman, SICP (preface to the first edition)
Kristally
User
Beiträge: 3
Registriert: Sonntag 12. Februar 2017, 12:15

Re: Blutiger Anfänger sucht Verbesserungsvorschläge :P

Beitragvon Kristally » Sonntag 12. Februar 2017, 16:48

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:

Re: Blutiger Anfänger sucht Verbesserungsvorschläge :P

Beitragvon MARSi » Sonntag 12. Februar 2017, 18:57

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: 731
Registriert: Sonntag 24. April 2011, 19:43

Re: Blutiger Anfänger sucht Verbesserungsvorschläge :P

Beitragvon pixewakb » Samstag 18. Februar 2017, 19:23

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.

Zurück zu „Allgemeine Fragen“

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder