Whiz-zarD Geschrieben 13. März 2018 Teilen Geschrieben 13. März 2018 vor 4 Minuten schrieb Eleu: Edit: Ach so, das soll auch dabei rauskommen? Genau Eleu reagierte darauf 1 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
HJST1979 Geschrieben 13. März 2018 Teilen Geschrieben 13. März 2018 vor 34 Minuten schrieb Eleu: Hi, ich verwende Visual Studio 2015, allerdings die kostenlose Variante, die man hier downloaden kann: https://www.microsoft.com/germany/techwiese/aktionen/visual-studio-kostenlos.aspx Kleiner Tipp, diese Version ist auch kostenlos zumindest für dich als Privatanwender: https://www.visualstudio.com/de/vs/community/ Eleu reagierte darauf 1 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Eleu Geschrieben 13. März 2018 Autor Teilen Geschrieben 13. März 2018 Vielen Dank noch mal an alle Es geht auch so etwas: public class ResultWriter { virtual public void SendToFile(ICalculation calculation) { using (System.IO.StreamWriter sw = new System.IO.StreamWriter("C:\\VB_net\\Test.txt", true)) { sw.WriteLine(calculation.Calculate()); } } } Aber die anderen Varianten sind sehr interessant. Gruß Eleu Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Whiz-zarD Geschrieben 13. März 2018 Teilen Geschrieben 13. März 2018 File.AppendAllText() macht im Grunde nichts anderes, was du geschrieben hast: public static void AppendAllText(String path, String contents) { // ... InternalAppendAllText(path, contents, StreamWriter.UTF8NoBOM); } private static void InternalAppendAllText(String path, String contents, Encoding encoding) { // ... using (StreamWriter sw = new StreamWriter(path, true, encoding)) sw.Write(contents); } So sieht der Source Code im .NET Framework aus. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Eleu Geschrieben 13. März 2018 Autor Teilen Geschrieben 13. März 2018 vor 39 Minuten schrieb Whiz-zarD: File.AppendAllText() macht im Grunde nichts anderes, was du geschrieben hast: public static void AppendAllText(String path, String contents) { // ... InternalAppendAllText(path, contents, StreamWriter.UTF8NoBOM); } private static void InternalAppendAllText(String path, String contents, Encoding encoding) { // ... using (StreamWriter sw = new StreamWriter(path, true, encoding)) sw.Write(contents); } So sieht der Source Code im .NET Framework aus. System.IO.File liefert mir aber keine Methode, um zeilenweise in die Datei zu schreiben. Es fehlt die Methode WriteLine. Oder was müsste ich ändern, damit zeilenweise hineingeschrieben wird? File.AppendAllText(_file, $"{calculation.GetType()} result: {calculation.Calculate()}"); Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
maestro impostor Geschrieben 13. März 2018 Teilen Geschrieben 13. März 2018 (bearbeitet) Könntest ein Environment.NewLine hinten dranhängen Wenn du bei File bleiben möchtest: File.AppendAllText(_file, $"{calculation.GetType()} result: {calculation.Calculate()}{Environment.NewLine}"); Dann wird am Ende der Zeile ein Zeilenumbruch eingefügt. Bearbeitet 13. März 2018 von r4phi Eleu reagierte darauf 1 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Eleu Geschrieben 13. März 2018 Autor Teilen Geschrieben 13. März 2018 vor 4 Minuten schrieb r4phi: Könntest ein Environment.NewLine hinten dranhängen Wenn du bei File bleiben möchtest: File.AppendAllText(_file, $"{calculation.GetType()} result: {calculation.Calculate()}{Environment.NewLine}"); Dann wird am Ende der Zeile ein Zeilenumbruch eingefügt. Ich denke, da muss ich mir noch so einiges anschauen Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
maestro impostor Geschrieben 13. März 2018 Teilen Geschrieben 13. März 2018 vor 3 Minuten schrieb Eleu: Ich denke, da muss ich mir noch so einiges anschauen Environment.NewLine macht eigentlich nichts spannendes. Abhängig vom Betriebssystem bzw. der Plattform liefert es dir die Zeichen für einen Zeilenumbruch zurück. Bei Windows wäre das bspw. "\n\r" Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
arlegermi Geschrieben 14. März 2018 Teilen Geschrieben 14. März 2018 (bearbeitet) Dass der Text nicht superschön ist, stimmt. Du könntest dir jetzt überlegen, ob du in deinem ICalculation Interface noch eine Methode definierst, die eine "schöne" Ausgabe liefert. Beispielsweise: public interface ICalculation { double Calculate(); string GetRepresentation(); } public abstract class BinaryCalculation : ICalculation { // ... bekannter Kram public abstract string GetRepresentation(); } public class Addition : BinaryCalculation { // ... bekannter Kram public string GetRepresentation() { return $"Addition: ({_firstOperand} + {_secondOperand})"; } } //... beim Schreiben: File.AppendAllText(_file, $"{calculation.GetRepresentation()}, result: {calculation.Calculate()}"); Damit bekämst du dann eine vernünftig lesbare Ausgabe à la "Addition: (5 + 4), result: 9". p.s. Das ganze kann man auch durch überschreiben von ToString erreichen, ich finde das explizit aber manchmal angenehmer. Bearbeitet 14. März 2018 von arlegermi Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Eleu Geschrieben 14. März 2018 Autor Teilen Geschrieben 14. März 2018 (bearbeitet) Hallo arlegermie, vielen dank ich probiere das mal aus. Ich hoffe ich nerve nicht, denn ich hätte noch ein paar Fragen, bzgl. der prinzipiellen Vorgehensweise, bei der Klassenprogrammierung mit Vererbung. Ich habe jetzt folgende Klassen und ein Interface programmiert: { public interface ICalculation { double Calculate(); } public abstract class BinaryCalculation : ICalculation { protected double _firstOperand; protected double _secondOperand; public BinaryCalculation(double a, double b) { _firstOperand = a; _secondOperand = b; } public abstract double Calculate(); } public class Addition : BinaryCalculation { public Addition(double a, double b) : base(a, b) { } public override double Calculate() => _firstOperand + _secondOperand; } public class Multiplikation : BinaryCalculation { public Multiplikation(double a, double b) : base(a, b) { } public override double Calculate() => _firstOperand * _secondOperand; } public class ResultWriter { private string _file; public ResultWriter(string path) { _file = path; // Dateipfad und Dateiname werden der Variablen _file übergeben } public void WriteResultToFile(ICalculation calculation) //Vereerbung über das Interface ICalculation { File.AppendAllText(_file, $"{calculation.GetType()} result: {calculation.Calculate()}{Environment.NewLine}"); } } } Nun möchte ich eine Klasse programmieren, die 3 Variable addieren soll. Wenn ich es nun richtig verstanden habe, müsste ich nun eine neue Klasse Addieren2 programmieren, mit einer Methode Calculate2, sowie ein weitere abstrakte Klasse BinaryCalculation2, um nicht gegen das Single-Responsibility-Prinzip zu verstoßen. Soll ich dann im Interface ICalculation diese Methode Calculate2 einfügen, oder soll ich ein neues Interface ICalculation2 hinzufügen? Oder kann ich die Calculate auch für Addition2 verwenden? Sahe dann so aus: public abstract class BinaryCalculation2 : ICalculation { protected double _firstOperand; protected double _secondOperand; protectet double _thirdOperand; public BinaryCalculation2(double a, double b, double c) { _firstOperand = a; _secondOperand = b; _thirdOperand = c; } public abstract double Calculate(); } public class Addition2 : BinaryCalculation2 { public Addition(double a, double b, double c) : base(a, b, c) { } public override double Calculate() => _firstOperand + _secondOperand + _thirdOperand; } Ist das die richtige Vorgehensweise? Edit: Letztgenannte Variante funktioniert jedenfalls. Bearbeitet 14. März 2018 von Eleu arlegermi reagierte darauf 1 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Whiz-zarD Geschrieben 14. März 2018 Teilen Geschrieben 14. März 2018 vor 3 Minuten schrieb Eleu: Nun möchte ich eine Klasse programmieren, die 3 Variable addieren soll. Wenn ich es nun richtig verstanden habe, müsste ich nun eine neue Klasse Addieren2 programmieren, mit einer Methode Calculate2, sowie ein weitere abstrakte Klasse BinaryCalculation2, um nicht gegen das Single-Responsibility-Prinzip zu verstoßen. Im Grunde haben wir schon alles, was wir brauchen. Wir haben doch das Interface ICalculation, dessen Methode Calculate() ein double zurückgibt, also ein Parameter für die Addition-Klasse. Wenn du drei Zahlen miteinander addieren möchtest, kannst du es ganz einfach machen: new Addition(new Addition(1,2).Calculate(), 3) Jetzt rechnet er 1 + 2 + 3. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
KeeperOfCoffee Geschrieben 14. März 2018 Teilen Geschrieben 14. März 2018 (bearbeitet) Du könntest jetzt einfach eine Methode schreiben die einen String mit Operatoren übergibt "+-*\\" und ein Array mit den Operanden. Du müsstest nur überprüfen ob das Array.Length gleich string.Length + 1 ist, damit die Rechnung funktioniert. Dann könntest du die chars den Strings auslesen und jeweils die Methode (Addition usw) ausführen. Wobei man dann erst nach Multiplikationen und Divisionen suchen müsste. Ebenfalls müsste man die Division durch 0 abfangen. Das ist natürlich nur nützlich, wenn du längere Rechnungen angeben willst, anstatt schrittweise Ergebnisse anzugeben. Es gab mal so eine Standardlösung, die Eingabe sah dann so aus "+-/*54123", die aber (in meiner Erinnerung) nur für die Zahlen von 0-9 funktionierte. Mir fällt nur nicht mehr der Name ein... Kannst noch viel machen . Diese Rechner werden meist unterschätzt. Bearbeitet 14. März 2018 von KeeperOfCoffee Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Whiz-zarD Geschrieben 14. März 2018 Teilen Geschrieben 14. März 2018 (bearbeitet) vor 28 Minuten schrieb KeeperOfCoffee: ... Ich glaube, es wird echt mal Zeit, dass ich mein Artikel "Wie man einen Taschenrechner programmiert" veröffentliche. vor 28 Minuten schrieb KeeperOfCoffee: Es gab mal so eine Standardlösung, die Eingabe sah dann so aus "+-/*54123", die aber (in meiner Erinnerung) nur für die Zahlen von 0-9 funktionierte. Mir fällt nur nicht mehr der Name ein... Du meinst wohl die (umgekehrte) polnische Notation. Genannt auch Postfix- und Präfix-Schreibweise. Eine Umwandlung von der bekannten Infix-Schreibweise in die Post-/Präfix-Schreibweise, lässt sich durch den Shunting-Yard-Algorithmus lösen. Das würde hier aber viel zu weit gehen. Bearbeitet 14. März 2018 von Whiz-zarD KeeperOfCoffee reagierte darauf 1 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Eleu Geschrieben 14. März 2018 Autor Teilen Geschrieben 14. März 2018 vor einer Stunde schrieb Whiz-zarD: Im Grunde haben wir schon alles, was wir brauchen. Wir haben doch das Interface ICalculation, dessen Methode Calculate() ein double zurückgibt, also ein Parameter für die Addition-Klasse. Wenn du drei Zahlen miteinander addieren möchtest, kannst du es ganz einfach machen: new Addition(new Addition(1,2).Calculate(), 3) Jetzt rechnet er 1 + 2 + 3. Es funktioniert, aber ich habe noch nicht ganz kapiert wie das gehen kann? Was müsste ich denn programmieren, wenn ich noch eine weitere 4te Zahl addieren möchte? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
maestro impostor Geschrieben 14. März 2018 Teilen Geschrieben 14. März 2018 vor 10 Minuten schrieb Eleu: Was müsste ich denn programmieren, wenn ich noch eine weitere 4te Zahl addieren möchte? Um mit vier Zahlen zu rechnen: new Addition(new Addition(new Addition(1,2).Calculate(), 3).Calculate(), 4) Zitat Es funktioniert, aber ich habe noch nicht ganz kapiert wie das gehen kann? Eigentlich ganz einfach new Addition(1,2).Calculate() => liefert Ergebnis X. Ergebnis X packst du wiederum als ersten Summanden in deine Addition Klasse. Wenn man das ganze nicht einzeilig machen möchte würde das so aussehen: var x = new Addition(1,2).Calculate(); var result = new Addition(x, 3).Calculate(); Und bei vier Zahlen: var x = new Addition(1, 2).Calculate(); var y = new Addition(x, 3).Calculate(); var result = new Addition(y, 4).Calculate(); Eleu reagierte darauf 1 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
KeeperOfCoffee Geschrieben 14. März 2018 Teilen Geschrieben 14. März 2018 vor 12 Minuten schrieb Whiz-zarD: Ich glaube, es wird echt mal Zeit, dass ich mein Artikel "Wie man einen Taschenrechner programmiert" veröffentliche. Macht man natürlich anders. Trotzdem sollte er, wenn er z.B. 1000 Additionen hat, die Rechnung doch besser auslesen und entsprechend auswerten. Es ist ein Unterschied, ob es immer x (operator) y macht, oder eine fertige Rechnung eingibt (sich zusammenklickt) und das Ergebnis haben will. Der Windows Rechner rechnet auch stupid eine Operation nach der anderen aus und zeigt am Ende an: 6+6*2 = 24 was so natürlich nicht stimmt, aber die Aufbau des Rechners macht es nunmal so. vor 8 Minuten schrieb Eleu: s funktioniert, aber ich habe noch nicht ganz kapiert wie das gehen kann? Was müsste ich denn programmieren, wenn ich noch eine weitere 4te Zahl addieren möchte? Das müsste dann sein new Addition(new Addition(new Addition(1,2).Calculate(), 3).Calculate(), 4) Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
arlegermi Geschrieben 14. März 2018 Teilen Geschrieben 14. März 2018 (bearbeitet) Vielleicht führt das jetzt zu weit (und wirklich sinnvoll ist es außer als Übung auch nicht), aber: Anstatt die BinaryCalculations ineinander zu schachteln kannst du dir auch überlegen, eine Klasse zu schreiben, die beliebig viele Operanden akzeptiert und die dann alle aufaddiert. Das Gerüst könnte so aussehen: public class SeriesCalculation : ICalculation { private BinaryCalculation _binaryCalculation; private double[] _numbers; public SeriesCalculation(BinaryCalculation binaryCalculation, params double[] numbers) { _binaryCalculation = binaryCalculation; _numbers = numbers; } public double Calculate() { // immer zwei Zahlen aus _numbers nehmen, die Berechnung ausführen und das Ergebnis in die // nächste Berechnung übergeben. } } //aufrufbar wäre das dann folgendermaßen: var calc = new SeriesCalculation(new Addition(), 1,2,3,4,5,6); // hierfür bräuchtest du noch einen neuen Konstruktor in Addition Wie gesagt: Das mag gerade ein wenig zu kompliziert sein, ist vielleicht aber eine ganz schöne Übung, um das Prinzip zu verstehen. Einfacher ist's vielleicht erstmal immer nur aufzuaddieren, ohne die Berechnung auch von außen mit reinzunehmen. Wenn "params" neu für dich ist, kannst du hier was dazu lesen. Bearbeitet 14. März 2018 von arlegermi KeeperOfCoffee reagierte darauf 1 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Whiz-zarD Geschrieben 14. März 2018 Teilen Geschrieben 14. März 2018 vor 2 Minuten schrieb KeeperOfCoffee: Der Windows Rechner rechnet auch stupid eine Operation nach der anderen aus und zeigt am Ende an: 6+6*2 = 24 was so natürlich nicht stimmt, aber die Aufbau des Rechners macht es nunmal so. Das stimmt nicht ganz. Stellt man den Taschenrechner auf "Wissenschaftlich", so kennt er auch eine Operatorreihenfolge. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
maestro impostor Geschrieben 14. März 2018 Teilen Geschrieben 14. März 2018 @arlegermi Würde dein Vorschlag nicht sogar in Richtung des Strategy-Pattern gehen? arlegermi reagierte darauf 1 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
arlegermi Geschrieben 14. März 2018 Teilen Geschrieben 14. März 2018 vor 1 Minute schrieb r4phi: @arlegermi Würde dein Vorschlag nicht sogar in Richtung des Strategy-Pattern gehen? Genau, da geht's quasi hin. Auch wenn man das "in echt" natürlich anders lösen würde. maestro impostor reagierte darauf 1 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
maestro impostor Geschrieben 14. März 2018 Teilen Geschrieben 14. März 2018 vor 1 Minute schrieb arlegermi: Genau, da geht's quasi hin. Auch wenn man das "in echt" natürlich anders lösen würde. Wobei, das SeriesCalculation wäre im der "Context" und "BinaryCalculation" wäre die "Strategy" die du den Context injectest. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Eleu Geschrieben 14. März 2018 Autor Teilen Geschrieben 14. März 2018 (bearbeitet) Hallo, ich kann euch jetzt nicht mehr so ganz folgen, aber das ist nicht so schlimm. Ich schau mir das noch mal in Ruhe an. Interessant finde ich jedenfalls, dass ich damit auch meine Multiplikations-Klasse mit der Additions-Klasse verketten kann: private void button5_Click(object sender, EventArgs e) { Addition s = new Addition(new Multiplikation(new Addition(1, 2).Calculate(), 13).Calculate(), 4); MessageBox.Show(Convert.ToString(s.Calculate())) } Die Message Box zeigt mir 43 als Ergebnis an Bearbeitet 14. März 2018 von Eleu Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
maestro impostor Geschrieben 14. März 2018 Teilen Geschrieben 14. März 2018 vor 10 Minuten schrieb Eleu: Interessant finde ich jedenfalls, dass ich damit auch meine Multiplikations-Klasse mit der Additions-Klasse verketten kann: Bitte nicht durcheinander kommen. Du verkettest die Ergebnisse (Rückgabewerte) der Calculate Methode! Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Eleu Geschrieben 14. März 2018 Autor Teilen Geschrieben 14. März 2018 vor 15 Minuten schrieb r4phi: Bitte nicht durcheinander kommen. Du verkettest die Ergebnisse (Rückgabewerte) der Calculate Methode! private void button6_Click(object sender, EventArgs e) { double x = new Addition(1, 2).Calculate(); double y = new Multiplikation(x, 13).Calculate(); double result = new Addition(y, 4).Calculate(); MessageBox.Show(Convert.ToString(result)); } Ja, mit deinem Beispiel ist es für mich verständlicher.. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
KeeperOfCoffee Geschrieben 14. März 2018 Teilen Geschrieben 14. März 2018 (bearbeitet) vor 14 Minuten schrieb Eleu: Ja, mit deinem Beispiel ist es für mich verständlicher.. Mal langsam. 1+2*13+4 wäre ja dann. double x = new Multiplikation(2, 13).Calculate(); double y = new Addition(new Addition(x, 1).Calculate(), 4).Calculate(); // y = 31 Die Frage ist also genau, wo du deine Multiplikation in der Rechnung haben willst. Desweiteren solltest du das nicht in das Klick Ereignis des Buttons packen. Bearbeitet 14. März 2018 von KeeperOfCoffee Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.