Laden...

Code übersichtlicher und einfacher verständlich machen.

Letzter Beitrag vor 8 Monaten 13 Posts 741 Views
Code übersichtlicher und einfacher verständlich machen.

Hi,

gleich vorab: ich bin absoluter Anfänger mache also auch Anfänger (Denk-)Fehler. Haltet Beispiele und Erklärungen daher auch bitte simpel und einfach verständlich. Ich lerne gerne mit Codebeispielen, da ich Artikel über Funktionen und Operatoren meist nicht verstehe. Bitte antwortet nicht auf diese Frage, wenn ihr mir nicht grundsätzlich bei der Frage helfen wollt. Danke! Ich verwende auch die ungarische Notation, da wir das in der Berufsschule so lernen und dieses Programm nur eine Übung für die Schule ist.

Ich habe in einer anderen Frage in diesem Forum einiges an Feedback bekommen (teilweise hilfreich). Viele fanden meinen Code nicht strukturiert und einfach lesbar. Könnt ihr mir da helfen? Was würdet ihr verändern, dass die verständlichkeit einfacher bleibt.

			//Do/while Schleife falls falsche Nummer gewählt wird
			do
			{
				//Man kann nicht mehr einfach Enter drücken oder einen Buchstaben eingeben. Exeptions werden abgefangen.
				do
				{
					Console.WriteLine("Wähle deine Biersorte:");
					Console.WriteLine();

					//gibt keine Zahl ein (z.B Buchstabe, oder enter etc...
					if (!Int32.TryParse(Console.ReadLine(), out iBiersortenwahl))
					{                           
						Console.WriteLine();
						Console.WriteLine("Der eingegebene Wert muss eine Zahl sein!");
						Console.WriteLine();
						bKeineZahleingegeben = true;
					}

					//gibt negative Zahl ein
					else if (iBiersortenwahl < 0)
					{
                        Console.WriteLine();
                        Console.WriteLine("Der eingegebene Wert muss positiv sein!");
						Console.WriteLine();
						bKeineZahleingegeben = true;
					}

					//gibt richtig ein
					else
					{
						bKeineZahleingegeben = false;
					}
				}
				while (bKeineZahleingegeben);

				Console.WriteLine();
				{
					if (iBiersortenwahl == 0)
					{

						Console.WriteLine("Es werden nun keine weiteren Biere deiner Auswahl hinzugefügt.");
						bWeitersBier = false;
					}

					else if (iBiersortenwahl != 0 | iBiersortenwahl > iVerfügbareBiersorten)
					{
						iBiersortenwahl--;

						if (lAnzahlverfügbarkeitnummern[iBiersortenwahl] <= 0)
						{
							Console.WriteLine(lAusgaben[1]);
							continue;
						}

						else if (lAnzahlverfügbarkeitnummern[iBiersortenwahl] <= 5)
						{
							Console.WriteLine(lAusgaben[6] + lAnzahlverfügbarkeitnummern[iBiersortenwahl] + lAusgaben[7]);
							Console.WriteLine();
                        }

						//Berechnungen 
						lAnzahlverfügbarkeitnummern[iBiersortenwahl]--;
						dEndpreis += lPreise[iBiersortenwahl];

						//Array für Ausgabe der Biere
						//ArrayZähler für nächste Belegung von Bit von Array
						sGewählteBiere[iArrayZähler] = lBiersorten[iBiersortenwahl];
						iArrayZähler += 1;

						//Ausgabe was bestellt wurde
						Console.WriteLine(lBiersorten[iBiersortenwahl] + lAusgaben[3] + "{0:f}" + lAusgaben[4] + "{1:f}" + lAusgaben[5], lPreise[iBiersortenwahl], dEndpreis);

						//Maximal-Bestellwert    
						if (iArrayZähler == sGewählteBiere.Length)
						{
							Console.WriteLine(lAusgaben[2]);
							bWeitersBier = false;
						}

						//Nachfrage ob mehr Bier
						Console.WriteLine(lAusgaben[0]);
					}

					//User drückt den Falschen Key
					else
					{
						Console.WriteLine("Unter diesem Wert ist kein Bier hinterlegt!");
						Console.WriteLine();
						Console.WriteLine(lAusgaben[0]);
					}					
				}
			}
			//While Fußsteuerung
			while (bWeitersBier);
			}

			{
			//Bezahlung 
			Console.WriteLine("Preis deiner Gesamten Auswahl: {0:f} EUR", dEndpreis);
			do
			{
				//User gibt falschen Wert ein
				do
				{
					Console.WriteLine("Bitte wirf das Geld ein:");
					Console.WriteLine();

					//gibt keine Zahl ein (z.B Buchstabe, oder enter etc...
					if (!double.TryParse(Console.ReadLine(), out dGeldeinwurf))
					{
						Console.WriteLine("Der eingegebene Wert musss eine Zahl sein!");
						dGeldeinwurfIstkeineZahl = true;
					}

					//gibt negative Zahl ein
					else if (dGeldeinwurf < 0)
					{
						Console.WriteLine("Der eingegebene Wert muss positiv sein!");
						dGeldeinwurfIstkeineZahl = true;
					}

					//gibt richtig ein
					else
					{
						dGeldeinwurfIstkeineZahl = false;
					}
				}
				while (dGeldeinwurfIstkeineZahl);

				//dDifference weil double im Arbeitsspeicher 0,000000...000001 abgelegt wird --> ist nicht gleich 0
				double dDifference = Math.Abs(dEndpreis - dGeldeinwurf);

				if (dDifference < 0.001)
				{
                    Console.WriteLine();
                    Console.WriteLine("Passend bezahlt.");
					bAbgeschlossen = true;			    
				}

				//zu viel bezahlt
				else if (dEndpreis < dGeldeinwurf)
				{
					double dRückgeld = dGeldeinwurf - dEndpreis;
					Console.WriteLine("{0:f} EUR bezahlt. {1:f} EUR zurück.", dGeldeinwurf, dRückgeld);
					bAbgeschlossen = true;
				}

				//zu wenig gezahlt
				else
				{
					dEndpreis -= dGeldeinwurf;
					Console.WriteLine();
					Console.WriteLine("{0:f} EUR bezahlt. {1:f} EUR noch zu zahlen.", dGeldeinwurf, dEndpreis);
					Console.WriteLine();
				}

			}
			while (!bAbgeschlossen);
			}

Danke euch!

Elmini08

Meine 50 Cents

Variablen einführen

Statt

if (!Int32.TryParse(Console.ReadLine(), out iBiersortenwahl))

eben

string read = Console.ReadLine();
if (!Int32.TryParse(read, out iBiersortenwahl))

Keine Präfixe

Macht man in modernen Sprachen nicht.

Schleifen richtig verwenden

Statt dem dGeldeinwurfIstkeineZahl  kannst Du einfach mit continue arbeiten

if (!double.TryParse(Console.ReadLine(), out dGeldeinwurf))
{
   Console.WriteLine("Der eingegebene Wert musss eine Zahl sein!");
   continue;
}

Richtige Typen verwenden

Man verwendet kein Double oder Float für Geldbeträge, sondern entweder Ganzzahlen (Milldarstellung: 1000 = 1€) oder Decimal.
double darf hier aufgrund des Rundungsthemas sogar gesetzlich nicht verwendet werden (Fahrlässigkeit etc..). In vielen Bereichen muss Software zertifiziert werden, und das hier wäre ein Grund, dass man durchfällt.

Klassen verwenden

Die Idee einer Objektorientierten Sprache sind Klassen - und eben Objekte. Ergo: arbeite damit.
Mach aus dingen wie lAusgaben[0] entsprechend eine Klasse mit Eigenschaften.

Classes - C# | Microsoft Learn


-> Kein Code auf Deutsch schreiben.
In meiner Schul-, Ausbildungs- und Studienzeit gabs 1 Note Abzug, wenn der Code auf Deutsch war - und das war gut so.
Im Berufsleben ist i.d.R. deutschsprachiger Code ein riesen Problem und Hindernis. Erlebe ich leider tagtäglich.

Was sagt denn eigentlich Dein Ausbilder? Kannst Du den nicht fragen?

Paar Punkte, die mir spontan auffallen:

Größe der Codeblöcke: Kurzer, kompakter Code ist besser verständlich. Alles, was länger als 30 Zeilen ist sollte man überdenken, ob man da nicht Teile davon sinnvoll in separate Functions oder Klassen auslagern kann.

Geschachtelte Schleifen: Würde ich versuchen zu vermeiden. Auch hier: Blöcke in Functions auslagern.

do while: Mag ich nicht (Persönliche Hassliebe). Konditionen am Ende der Schleife finde ich einfach bescheiden lesbar.

Ausgaben sinnvoll zusammenfassen, um kompakten Code zu erhalten. Die drei Varianten machen alle das Gleiche. Man muss halt ggfs. schauen, für welche Plattform(en) man entwickelt:

Console.WriteLine();
Console.WriteLine("Der eingegebene Wert muss eine Zahl sein!");
Console.WriteLine();

Console.WriteLine("\r\nDer eingegebene Wert muss eine Zahl sein!\r\n");

Console.WriteLine($"{Environment.NewLine}Der eingegebene Wert muss eine Zahl sein!{Environment.NewLine}");

Zitat von vieledinge

Alles, was länger als 30 Zeilen ist sollte man überdenken

Mit welchem Sinn? Der Sinn von Trennung in Methoden ist Verantwortlichkeit.
Die Sinn mag potentiell höher sein, je länger eine Methode ist - das fixe Denken in "30 Zeilen" ist jedoch das, das man überdenken sollte; das ist schon lange nicht mehr Zeitgemäß und hatte mal ihren Ursprung in mittlerweile alten Programmiersprachen und eher rudimentären IDEs.

Die Methodenlänge als Empfehlung ist Gott sei dank auch mittlerweile aus den meisten Lehrbüchern verschwunden; hingegen kam die Zeilenlänge aufgrund von Tooling hinzu (Code Reviews etc...). Oft hab ich hier schon 120 Zeichen gesehen; Herkunft würde ich aus der JavaScript-Welt vermuten.

Grundsätzlich würde ich erst einmal sagen, dass der Ansatz falsch gewählt ist.

So ist ein Getränke-Automaten ein Endlicher Automat und sollte zunächst auch so skizziert werden. Das ist erst einmal unabhängig von jeder Programmiersprache.

Anhand dieser Skizze geht man dann an die Umsetzung. Man kann dafür z.B. eine fertige Bibliothek (z.B. Stateless) nehmen oder auch selber umsetzen. Allerdings benötigt man hier auf jeden Fall die Grundlagen von OOP.

Hat die Blume einen Knick, war der Schmetterling zu dick.

Zitat von BlonderHans

Man kann dafür z.B. eine fertige Bibliothek (z.B. Stateless) nehmen oder auch selber umsetzen.

Das mag für eine reale Anwendung sicherlich der beste Weg sein - für jemand, der gerade in der Schule die Grundlagen lernt, vielleicht bisschen Overshoot.

Zitat von Abt

Zitat von vieledinge

Alles, was länger als 30 Zeilen ist sollte man überdenken

Mit welchem Sinn? Der Sinn von Trennung in Methoden ist Verantwortlichkeit.

Da stimme ich Dir durchaus zu.

Die 30 Zeilen sind kein Dogma. Die Praxis zeigt aber, dass es ab einer gewissen Codeblockgröße durchaus sinnvoll sein kann, da hinterher nochmal drüber nachzudenken, was man da tut und ob man das eventuell nochmal aufteilen sollte. Und wenn die Antwort "Nein" lautet, dann ist es auch gut.

Vielen Dank für Eure Antworten schonmal! Da mir @Abt privat geschrieben hat ich solle am besten den ganzen Code hier bereitstellen. Kommt hier jetzt über mehrere Nachrichten mein vollständiger Code.

LG 
Elmini08

using System;
using System.Collections.Generic;
using System.Threading;

namespace Getränkeautomat
{
    internal class ProgrammGetränkeautomat
    {
        static void Main()
        {
            //Variablen für Bezahlung 			
            bool bAbgeschlossen = false; //bool für (if/else if/else) bei Bezahlung
            double dEndpreis = 0;
            double dGeldeinwurf;
            bool dGeldeinwurfIstkeineZahl; //zum Abfangen der Exeptions		

            //Variable für Biersortenwahl
            int iIndexVonListe;
            int iVerfügbareBiersorten = 8;			
            bool bWeitersBier = true;
            int iBiersortenwahl;
            int iArrayZähler = 0;
            string[] sGewählteBiere = new string[15];
            bool bKeineZahleingegeben; //zum Abfangen der Exeptions

            //Vairablen für Bierausgabe		
            int iWelcheBiersorte = 0;
            int iIndex;
            int iIndexBiersorten = 0;

            //LISTEN
            //LISTEN
            //LISTEN

            //Preise
            List<double> lPreise = new List<double>()
            {
                //index 0
                2.80 ,

                //index 1
                2.60 ,

                //index 2
                3.00 ,

                //index 3
                3.20 ,

                //index 4
                3.00 ,

                //index 5
                3.30 ,

                //index 6
                3.50 ,

                //index 7
                3.10

            };

            //Liste für Biersorten während Cases
            List<string> lBiersorten = new List<string>()
            {
                //index 0
                "Helles Bier ",

                //index 1
                "Pils ",

                //index 2
                "Schwarzbier ",

                //index 3
                "Weizen ",

                //index 4
                "Lagerbier ",

                //index 5
                "Kellerbier ",

                //index 6
                "Bockbier ",

                //index 7
                "Zwickl "
            };

            //Liste für Abfragen während Cases
            List<string> lAusgaben = new List<string>()
            {
                //index 0
                "Möchtest du ein weiters Bier deiner Auswahl hinzufügen? Dann drücke die jeweilige Nummer der gewünschten Biersorte.\nMöchtest du kein weiters Bier drücke Taste <0>.\n",

                //index 1
                "Diese Biersorte ist aktuell nicht verfügbar!\n",

                //index 2
                "Maximal-Bestellwert erreicht. Bitte bezahle jetzt.\n",

                //index 3
                "wurde deiner Aktuellen Auswahl hinzugefügt. \nPreis pro Bier: " ,
                
                //index 4			
                "EUR. \n \nPreis deiner aktuellen Auswahl: ",

                //index 5
                "EUR",

                //index 6
                "Es sind nur noch ",

                //index 7
                " Flaschen dieser Biersorte verfügbar\n"
            };

            //Liste für Variablen während Cases
            List<int> lAnzahlverfügbarkeitnummern = new List<int>()
            {
                //index 0
                8 ,

                //index 1
                9 ,

                //index 2
                6 ,

                //index 3
                0 ,

                //index 4
                0 ,

                //index 5
                0 ,

                //index 6
                0 ,

                //index 7
                0
            };

            List<int> lAnzahlBiersorten = new List<int>()
            {
                //index 0
                0,

                //index 1
                0,

                //index 2
                0,

                //index 3
                0,

                //index 4
                0,

                //index 5
                0,

                //index 6
                0,

                //index 7
                0,

            };

            List<string> lNummern = new List<string>()
            {
                //index 0
                "Nummer 1: ",

                //index 1
                "Nummer 2: ",

                //index 2
                "Nummer 3: ",

                //index 3
                "Nummer 4: ",

                //index 4
                "Nummer 5: ",

                //index 5
                "Nummer 6: ",

                //index 6
                "Nummer 7: ",

                //index 7
                "Nummer 8: "
            };

            Console.WriteLine("Willkommen beim Lecker Bierchen Automat!");
            Console.WriteLine();

            //Ausgabe der wählbaren Biersorten
            Console.WriteLine("Es gibt folgende Biersorten zur Auswahl:");

            for (iIndexVonListe = 0; iIndexVonListe < iVerfügbareBiersorten; iIndexVonListe++)
            {
                Console.WriteLine(lNummern[iIndexVonListe] + lBiersorten[iIndexVonListe]);
            }

            //Biersorte wählen:
            {
            Console.WriteLine("Sie können Maximal " + sGewählteBiere.Length + " Biere pro Bestellung bestellen.");
            Console.WriteLine();

            //Do/while Schleife falls falsche Nummer gewählt wird
            do
            {
                //Man kann nicht mehr einfach Enter drücken oder einen Buchstaben eingeben. Exeptions werden abgefangen.
                do
                {
                    Console.WriteLine("Wähle deine Biersorte:");
                    Console.WriteLine();

                    //gibt keine Zahl ein (z.B Buchstabe, oder enter etc...
                    if (!Int32.TryParse(Console.ReadLine(), out iBiersortenwahl))
                    {                           
                        Console.WriteLine();
                        Console.WriteLine("Der eingegebene Wert muss eine Zahl sein!");
                        Console.WriteLine();
                        bKeineZahleingegeben = true;
                    }

                    //gibt negative Zahl ein
                    else if (iBiersortenwahl < 0)
                    {
                        Console.WriteLine();
                        Console.WriteLine("Der eingegebene Wert muss positiv sein!");
                        Console.WriteLine();
                        bKeineZahleingegeben = true;
                    }

                    //gibt richtig ein
                    else
                    {
                        bKeineZahleingegeben = false;
                    }
                }
                while (bKeineZahleingegeben);

                Console.WriteLine();
                {
                    if (iBiersortenwahl == 0)
                    {

                        Console.WriteLine("Es werden nun keine weiteren Biere deiner Auswahl hinzugefügt.");
                        bWeitersBier = false;
                    }

                    else if (iBiersortenwahl != 0 | iBiersortenwahl > iVerfügbareBiersorten)
                    {
                        iBiersortenwahl--;

                        if (lAnzahlverfügbarkeitnummern[iBiersortenwahl] <= 0)
                        {
                            Console.WriteLine(lAusgaben[1]);
                            continue;
                        }

                        else if (lAnzahlverfügbarkeitnummern[iBiersortenwahl] <= 5)
                        {
                            Console.WriteLine(lAusgaben[6] + lAnzahlverfügbarkeitnummern[iBiersortenwahl] + lAusgaben[7]);
                            Console.WriteLine();
                        }

                        //Berechnungen 
                        lAnzahlverfügbarkeitnummern[iBiersortenwahl]--;
                        dEndpreis += lPreise[iBiersortenwahl];

                        //Array für Ausgabe der Biere
                        //ArrayZähler für nächste Belegung von Bit von Array
                        sGewählteBiere[iArrayZähler] = lBiersorten[iBiersortenwahl];
                        iArrayZähler += 1;

                        //Ausgabe was bestellt wurde
                        Console.WriteLine(lBiersorten[iBiersortenwahl] + lAusgaben[3] + "{0:f}" + lAusgaben[4] + "{1:f}" + lAusgaben[5], lPreise[iBiersortenwahl], dEndpreis);

                        //Maximal-Bestellwert    
                        if (iArrayZähler == sGewählteBiere.Length)
                        {
                            Console.WriteLine(lAusgaben[2]);
                            bWeitersBier = false;
                        }

                        //Nachfrage ob mehr Bier
                        Console.WriteLine(lAusgaben[0]);
                    }

                    //User drückt den Falschen Key
                    else
                    {
                        Console.WriteLine("Unter diesem Wert ist kein Bier hinterlegt!");
                        Console.WriteLine();
                        Console.WriteLine(lAusgaben[0]);
                    }					
                }
            }
            //While Fußsteuerung
            while (bWeitersBier);
            }

            {
            //Bezahlung 
            Console.WriteLine("Preis deiner Gesamten Auswahl: {0:f} EUR", dEndpreis);
            do
            {
                //User gibt falschen Wert ein
                do
                {
                    Console.WriteLine("Bitte wirf das Geld ein:");
                    Console.WriteLine();

                    //gibt keine Zahl ein (z.B Buchstabe, oder enter etc...
                    if (!double.TryParse(Console.ReadLine(), out dGeldeinwurf))
                    {
                        Console.WriteLine("Der eingegebene Wert musss eine Zahl sein!");
                        dGeldeinwurfIstkeineZahl = true;
                    }

                    //gibt negative Zahl ein
                    else if (dGeldeinwurf < 0)
                    {
                        Console.WriteLine("Der eingegebene Wert muss positiv sein!");
                        dGeldeinwurfIstkeineZahl = true;
                    }

                    //gibt richtig ein
                    else
                    {
                        dGeldeinwurfIstkeineZahl = false;
                    }
                }
                while (dGeldeinwurfIstkeineZahl);

                //dDifference weil double im Arbeitsspeicher 0,000000...000001 abgelegt wird --> ist nicht gleich 0
                double dDifference = Math.Abs(dEndpreis - dGeldeinwurf);

                if (dDifference < 0.001)
                {
                    Console.WriteLine();
                    Console.WriteLine("Passend bezahlt.");
                    bAbgeschlossen = true;			    
                }

                //zu viel bezahlt
                else if (dEndpreis < dGeldeinwurf)
                {
                    double dRückgeld = dGeldeinwurf - dEndpreis;
                    Console.WriteLine("{0:f} EUR bezahlt. {1:f} EUR zurück.", dGeldeinwurf, dRückgeld);
                    bAbgeschlossen = true;
                }

                //zu wenig gezahlt
                else
                {
                    dEndpreis -= dGeldeinwurf;
                    Console.WriteLine();
                    Console.WriteLine("{0:f} EUR bezahlt. {1:f} EUR noch zu zahlen.", dGeldeinwurf, dEndpreis);
                    Console.WriteLine();
                }

            }
            while (!bAbgeschlossen);
            }
            //Bier ausgabe
            {
                //Ihre Auswahl Zeile
                {
                    Console.WriteLine();
                    Console.WriteLine("Ihre Auswahl:");
                    Console.WriteLine();
                }

                //Ausgabe der Biersorten
                do
                {
                    for (iIndex = 0; iIndex < sGewählteBiere.Length; iIndex++)
                    {
                        if (sGewählteBiere[iIndex] == lBiersorten[iWelcheBiersorte])
                        {
                            lAnzahlBiersorten[iWelcheBiersorte]++;
                        }
                    }
                    iIndexBiersorten++;
                    iWelcheBiersorte++;
                }
                while (iIndexBiersorten != iVerfügbareBiersorten);

                for (iIndex = 0; iIndex < iVerfügbareBiersorten; iIndex++)
                {
                    if (lAnzahlBiersorten[iIndex] > 0)
                    {
                        Console.WriteLine(lAnzahlBiersorten[iIndex] + "x " + lBiersorten[iIndex]);
                    }
                }

                //Verabschiedung
                {
                    Console.WriteLine();
                    Console.WriteLine("wird ausgegeben!");
                    Console.WriteLine("Mhhhh so ein Lecker Bierchen ist schon was schönes! PROST!");
                    return;
                }
            }
        }   
    }
}