seidenschwert Geschrieben 17. Oktober 2010 Geschrieben 17. Oktober 2010 Hallo Leute, haben über die Ferien auf einen Taschenrechner objektorientiert zu programmieren!! Also mit Fenster und allem drum und dran. (Zahlen 0-9, Reset-Button(mit C beschriftet), + - * / =, Ein Anzeige Fenster) Ich hab eigentlich fast alles fertig und es funktioniert vieles, das Problem ist, das Mal und Geteielt nicht funzt und ich kann einmal rechnen, aber das vorrangegangene Ergebnise wird nicht gelöscht..außerdem rechnet das programm nicht in den minusbreich... Könnt ihr mir bitte helfen? Das ist mein Momentaner Programmcode, hoffe iwer kann sich etwas zeit nehmen und mit paar tipps geben: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace Taschenrechner { public partial class Rechner : Form { public Rechner() { InitializeComponent(); } double zahl1 = 0; double zahl2 = 0; private void textBox1_TextChanged(object sender, EventArgs e) { } private void bttNull_Click(object sender, EventArgs e) { textBox1.Text = textBox1.Text + bttNull.Text; } private void bttEins_Click(object sender, EventArgs e) { textBox1.Text = textBox1.Text + bttEins.Text; } private void bttZwei_Click(object sender, EventArgs e) { textBox1.Text = textBox1.Text + bttZwei.Text; } private void bttDrei_Click(object sender, EventArgs e) { textBox1.Text = textBox1.Text + bttDrei.Text; } private void bttVier_Click(object sender, EventArgs e) { textBox1.Text = textBox1.Text + bttVier.Text; } private void bttFünf_Click(object sender, EventArgs e) { textBox1.Text = textBox1.Text + bttFünf.Text; } private void bttSechs_Click(object sender, EventArgs e) { textBox1.Text = textBox1.Text + bttSechs.Text; } private void bttSieben_Click(object sender, EventArgs e) { textBox1.Text = textBox1.Text + bttSieben.Text; } private void bttAcht_Click(object sender, EventArgs e) { textBox1.Text = textBox1.Text + bttAcht.Text; } private void bttNeun_Click(object sender, EventArgs e) { textBox1.Text = textBox1.Text + bttNeun.Text; } private void bttPlus_Click(object sender, EventArgs e) { zahl1 = zahl1 + double.Parse(textBox1.Text); textBox1.Clear(); } private void bttMinus_Click(object sender, EventArgs e) { zahl1 = zahl1 - double.Parse(textBox1.Text); textBox1.Clear(); } private void bttMal_Click(object sender, EventArgs e) { zahl1 = zahl1 * double.Parse(textBox1.Text); textBox1.Clear(); } private void bttTeilen_Click(object sender, EventArgs e) { zahl1 = zahl1 / doubl.Parse(textBox1.Text); textBox1.Clear(); } private void bttGleich_Click(object sender, EventArgs e) { zahl2 = zahl1 + double.Parse(textBox1.Text); textBox1.Text = zahl2.ToString(); zahl1 = 0; } private void bttLoeschen_Click(object sender, EventArgs e) { textBox1.Clear(); } } } Danke Zitieren
matze2k2 Geschrieben 17. Oktober 2010 Geschrieben 17. Oktober 2010 Das sollte dir zumindest helfen, dass du nach dem ersten rechnen, ein weiteres mal rechnen kannst. private void bttLoeschen_Click(object sender, EventArgs e) { textBox1.Clear(); zahl1 = 0; } Zitieren
Murphy9904 Geschrieben 18. Oktober 2010 Geschrieben 18. Oktober 2010 ich würd an deiner stelle noch ne Variable für "zwischenergebniss" machen wennde auf plus klickst zum beispiel erg = double.Parse(textbox1.text) + erg und beim klicken auf "=" gibste dann halt einfach nur "erg" aus. beim geteilt musstes halt bissel anders machen. LG und noch viel Spaß Murphy Zitieren
NerdonRails Geschrieben 18. Oktober 2010 Geschrieben 18. Oktober 2010 Hallo Leute, haben über die Ferien auf einen Taschenrechner objektorientiert zu programmieren!! Dann mal los: Als erstes Schnittstellenbeschreibungen (Interfaces): public interface ICalculator { void SetLeftOperand(Single operand); void SetRightOperand(Single operand); void SetOperation(Operations operation); Single Calculate(); void CalculateWithCallbackInvocation(); void Reset(); } Definiert die Methoden des Rechners. public interface IFactory<T> { IOperator<T> Build(Operations op); } Definiert die Methoden der Factory die die Operatoren erstellt. public interface IOperator<T> { void Initialize(T leftOperand, T rightOperand); T Operate(); } Definiert, wie unsere Operatoren funktionieren. public enum Operations { Addition, Substraction, Multiplication, Division } Zu guter letzt eine Enumeration die unsere verfügbaren Operationen definiert. Dann eine kurze Definition einer marginalen Basisklasse und Code-Duplizierung zu reduzieren: public abstract class OperatorBase : IOperator<Single> { #region LeftOperand protected Single LeftOperand { get; set; } #endregion #region RightOperand protected Single RightOperand { get; set; } #endregion #region Initialize public abstract void Initialize(Single leftOperand, Single rightOperand); #endregion #region Operate public abstract Single Operate(); #endregion } Als nächstes die Implementierung der Operatoren: Addition: public class AdditionOperator : OperatorBase { public override void Initialize(Single leftOperand, Single rightOperand) { base.LeftOperand = leftOperand; base.RightOperand = rightOperand; } public override Single Operate() { return base.LeftOperand + base.RightOperand; } } Division: public class DivisionOperator : OperatorBase { #region Operate public override Single Operate() { return (this.LeftOperand / RightOperand); } #endregion #region Initialize public override void Initialize(Single leftOperand, Single rightOperand) { base.LeftOperand = leftOperand; base.RightOperand = rightOperand; } #endregion } Multiplikation: public class MultiplicationOperator : OperatorBase { public override void Initialize(Single leftOperand, Single rightOperand) { base.LeftOperand = leftOperand; base.RightOperand = rightOperand; } public override Single Operate() { return base.LeftOperand * base.RightOperand; } } Substraktion: public class SubstractionOperator : OperatorBase { public override void Initialize(Single leftOperand, Single rightOperand) { base.LeftOperand = leftOperand; base.RightOperand = rightOperand; } public override Single Operate() { return base.LeftOperand - base.RightOperand; } } Als nächstes die Implementierung der Factory die anhand unserer Enumeration die Operatoren erstellt: public class OperatorFactory : IFactory<Single> { public IOperator<Single> Build(Operations op) { IOperator<Single> result = null; switch (op) { case Operations.Addition: result = new AdditionOperator(); break; case Operations.Substraction: result = new SubstractionOperator(); break; case Operations.Multiplication: result = new MultiplicationOperator(); break; case Operations.Division: result = new DivisionOperator(); break; } return result; } } Als nächstes die eigentliche implementierung eine Calculators: public class Calculator : ICalculator { // Properties #region Callback private Action<Single> Callback { get; set; } #endregion #region OperatorFactory private OperatorFactory OperatorFactory { get; set; } #endregion #region Operator protected IOperator<Single> Operator { get; set; } #endregion #region LeftOperand protected Single LeftOperand { get; set; } #endregion #region RightOperand protected Single RightOperand { get; set; } #endregion // Constructors public Calculator() { this.Reset(); } public Calculator(Action<Single> callback) : this() { this.Callback = callback; } // Methods #region SetLeftOperand public void SetLeftOperand(Single operand) { this.LeftOperand = operand; } #endregion #region SetRightOperand public void SetRightOperand(Single operand) { this.RightOperand = operand; } #endregion #region SetOperation public void SetOperation(Operations operation) { this.Operator = this.OperatorFactory.Build(operation); } #endregion #region Calculate public Single Calculate() { this.Operator.Initialize(this.LeftOperand, this.RightOperand); return this.Operator.Operate(); } #endregion #region CalculateWithCallbackInvocation public void CalculateWithCallbackInvocation() { this.Callback(this.Calculate()); } #endregion #region Reset public void Reset() { this.OperatorFactory = new OperatorFactory(); this.Operator = this.OperatorFactory.Build(Operations.Addition); this.LeftOperand = 0; this.RightOperand = 0; } #endregion } Und zu guter letzt unit-tests die belegen, das das ganze auch klappt: [TestClass] public class CalculatorTests { [TestMethod] public void TestThatByDefaultAAdditionOperationIsSet() { CalculatorDerive calculator = new CalculatorDerive(); Assert.IsTrue(calculator.Operator.GetType() == typeof(AdditionOperator)); } [TestMethod] public void TestThatYouCanSetTheOperation() { CalculatorDerive calculator = new CalculatorDerive(); calculator.SetOperation(Operations.Division); Assert.IsTrue(calculator.Operator.GetType() == typeof(DivisionOperator)); } [TestMethod] public void TestThatYouCanSetTheLeftOperand() { CalculatorDerive calculator = new CalculatorDerive(); calculator.SetLeftOperand(2); Assert.IsTrue(calculator.LeftOp == 2); } [TestMethod] public void TestThatYouCanSetTheRightOperand() { CalculatorDerive calculator = new CalculatorDerive(); calculator.SetRightOperand(2); Assert.IsTrue(calculator.RightOp == 2); } [TestMethod] public void TestThatYouCanCalculateTheOperationalResultOfTwoNumbers() { CalculatorDerive calculator = new CalculatorDerive(); calculator.SetOperation(Operations.Multiplication); calculator.SetLeftOperand(2); calculator.SetRightOperand(4); Assert.IsTrue(calculator.Calculate() == 8); } [TestMethod] public void TestThatYouCanHaveAnCAllbackInvokedWhenCalculatingIsFinished() { Single result = 0; Calculator calculator = new Calculator(s => result = s); calculator.SetOperation(Operations.Multiplication); calculator.SetLeftOperand(2); calculator.SetRightOperand(4); calculator.CalculateWithCallbackInvocation(); Assert.IsTrue(result == 8); } } [TestClass] public class OperatorFactoryTests { [TestMethod] public void TestThatOperatorFactoryReturnsAAdditionOperatorIfCalledWithAddition() { OperatorFactory factory = new OperatorFactory(); IOperator<Single> op = factory.Build(Operations.Addition); Assert.IsTrue(op.GetType() == typeof(AdditionOperator)); } [TestMethod] public void TestThatOperatorFactoryReturnsASubstractionOperatorIfCalledWithSubstraction() { OperatorFactory factory = new OperatorFactory(); IOperator<Single> op = factory.Build(Operations.Substraction); Assert.IsTrue(op.GetType() == typeof(SubstractionOperator)); } [TestMethod] public void TestThatOperatorFactoryReturnsADivisionOperatorIfCalledWithTheDivision() { OperatorFactory factory = new OperatorFactory(); IOperator<Single> op = factory.Build(Operations.Division); Assert.IsTrue(op.GetType() == typeof(DivisionOperator)); } [TestMethod] public void TestThatOperatorFactoryReturnsADivisionOperatorIfCalledWithMultiplication() { OperatorFactory factory = new OperatorFactory(); IOperator<Single> op = factory.Build(Operations.Multiplication); Assert.IsTrue(op.GetType() == typeof(MultiplicationOperator)); } } [TestClass] public class OperatorTests { [TestMethod] public void TestThatTheDivisionOperatorDivides() { Single leftOperand = 4; Single rightOperand = 2; IOperator<Single> op = new DivisionOperator(); op.Initialize(leftOperand, rightOperand); Assert.IsTrue(op.Operate() == 2); } [TestMethod] public void TestThatTheMultiplicationOperatorMultiplies() { Single leftOperand = 4; Single rightOperand = 2; IOperator<Single> op = new MultiplicationOperator(); op.Initialize(leftOperand, rightOperand); Assert.IsTrue(op.Operate() == 8); } [TestMethod] public void TestThatTheAdditionOperatorSummateTwoNumbers() { Single leftOperand = 4; Single rightOperand = 2; IOperator<Single> op = new AdditionOperator(); op.Initialize(leftOperand, rightOperand); Assert.IsTrue(op.Operate() == 6); } [TestMethod] public void TestThatTheSubstractionOperatorSubstractsTwoNumbers() { Single leftOperand = 4; Single rightOperand = 2; IOperator<Single> op = new SubstractionOperator(); op.Initialize(leftOperand, rightOperand); Assert.IsTrue(op.Operate() == 2); } } Warum so kompliziert ? Ganz einfach: Testability sowie einhaltubg von DRY sowie SRP. Zitieren
Klotzkopp Geschrieben 18. Oktober 2010 Geschrieben 18. Oktober 2010 Warum viermal dieselbe Initialize-Methode? Zitieren
NerdonRails Geschrieben 18. Oktober 2010 Geschrieben 18. Oktober 2010 (bearbeitet) Warum viermal dieselbe Initialize-Methode? Jeder Operator sollte meiner Meinung nach individuell initialisierbar sein, z.b. könnte man bei Divisionen noch eine Validierung einbauen, ob der Divisor 0 ist. Im zweifel kann man das aber natürlich auch noch refaktorieren und daraus einen call machen. Edit meint: mein Fehler, man könnte das auch so machen und 3 Implementierungen streichen: public abstract class OperatorBase : IOperator<Single> { #region LeftOperand protected Single LeftOperand { get; set; } #endregion #region RightOperand protected Single RightOperand { get; set; } #endregion #region Initialize public virtual void Initialize(Single leftOperand, Single rightOperand) { this.LeftOperand = leftOperand; this.RightOperand = rightOperand; } #endregion #region Operate public abstract Single Operate(); #endregion } Bearbeitet 18. Oktober 2010 von NerdonRails Zitieren
seidenschwert Geschrieben 18. Oktober 2010 Autor Geschrieben 18. Oktober 2010 Wow, o man.. also so weit sind wir eig noch nich Ich bin auch eigentlich voll die Null im programmieren.. Geht es auch leichter, bzw öhm etwas mehr so weit das es in meinen Code reinpasst? weil das leider was anderes ist als das was ich brauche, fürchte ich O.o Es ist ja auf ein bestimmtes "Taschenrechnermodell" zugeschnitten mit buttons usw.. Zitieren
2K1.INC Geschrieben 18. Oktober 2010 Geschrieben 18. Oktober 2010 Dann mal los:..... glaubst du sie könnte das erklärn o.O gibt warscheinlich nur ne 6 Zitieren
NerdonRails Geschrieben 18. Oktober 2010 Geschrieben 18. Oktober 2010 glaubst du sie könnte das erklärn o.O gibt warscheinlich nur ne 6 Es war ein Ansatz... der Code ist nicht sonderlich schwer und war eigentlich als ein Ideengeber gedacht, wie man es anders machen kann. Und im Zweifel: nicht meckern, sondern selber Vorschläge machen, ich habs nämlich nur gut gemeint. Zitieren
2K1.INC Geschrieben 19. Oktober 2010 Geschrieben 19. Oktober 2010 Es war ein Ansatz... der Code ist nicht sonderlich schwer und war eigentlich als ein Ideengeber gedacht, wie man es anders machen kann. Und im Zweifel: nicht meckern, sondern selber Vorschläge machen, ich habs nämlich nur gut gemeint. der ansatz ist gut, nur vll zu gut und sie sagte selber schon so weit sind sie noch nicht... Zitieren
seidenschwert Geschrieben 19. Oktober 2010 Autor Geschrieben 19. Oktober 2010 Wenn ihr euch hier battelt hilft das leider keinem^^ Bald sind meine Ferien vorbei und ich komm einfach nich weiter :'( Zitieren
2K1.INC Geschrieben 19. Oktober 2010 Geschrieben 19. Oktober 2010 du brauchst doch nur einen simplen Taschenrechner oder? Zitieren
SeToY Geschrieben 19. Oktober 2010 Geschrieben 19. Oktober 2010 Hallo, nur ein kleines "schönheits-feature": textBox1.Text = textBox1.Text + bttDrei.Text; -> (beispielsweise) textBox1.Text += bttDrei.Text; Zitieren
seidenschwert Geschrieben 19. Oktober 2010 Autor Geschrieben 19. Oktober 2010 ja der muss nicht mal punkt vor strich rechnung beherrschen.. solange er aber einen ähnlichen aufbau wie mein code hat, weil darauf basiert die aufgabe.. bei mir funzt ja nur mal und geteilelt nicht und das wenn ich 2+3 =5 rechne die 5 auf wenn ich ne neue zahl eingebe immernoch da ist sodass dann da steht 51.. und das er nicht in den minus breich geht Zitieren
Klotzkopp Geschrieben 19. Oktober 2010 Geschrieben 19. Oktober 2010 bei mir funzt ja nur mal und geteilelt nichtDa "funzt" viel mehr nicht. Dein Ansatz ist Quatsch. Du kannst nicht "Plus" rechnen, wenn jemand auf "Plus" klickt, weil du zu diesem Zeitpunkt den zweiten Operanden noch gar nicht hast. Gleiches gilt für die anderen Rechenarten. Du musst dir die erste Zahl und die gewählte Rechenart merken, und erst dann anwenden, wenn jemand "Gleich" klickt. Momentan rechnest du bei "Gleich" immer "Plus". Zitieren
seidenschwert Geschrieben 19. Oktober 2010 Autor Geschrieben 19. Oktober 2010 Das kann durchaus sein.. Ich beherrsche die programmierung nich... Ich hab mich an euch gewendet weil ich dacht das man mir helfen kann.. durch einfach erklärung komm ich nicht weiter.. Zitieren
2K1.INC Geschrieben 19. Oktober 2010 Geschrieben 19. Oktober 2010 Das kann durchaus sein.. Ich beherrsche die programmierung nich... Ich hab mich an euch gewendet weil ich dacht das man mir helfen kann.. durch einfach erklärung komm ich nicht weiter.. der fehler den der klotz beschreibt war das es ein logischer fehler im kopf is ^^ klingt so als ob du die lösung willst und ned einen lösungsweg Zitieren
Klotzkopp Geschrieben 19. Oktober 2010 Geschrieben 19. Oktober 2010 Ich hab mich an euch gewendet weil ich dacht das man mir helfen kann.. durch einfach erklärung komm ich nicht weiter.. Ich habe dir gesagt, was an deinem Ansatz falsch ist, damit du das überdenken und berichtigen kannst. Ich habe dir auch schon gesagt, was die richtige Vorgehensweise ist. Was soll ich noch tun? Soll ich deine Hausaufgaben machen? Zitieren
SeToY Geschrieben 19. Oktober 2010 Geschrieben 19. Oktober 2010 Wir können dir helfen, indem wir dir erklären, was du falsch machst. Aber deine Aufgabe übernehmen können bzw. wollen wir nicht - deshalb erhälst du Tipps, mit denen du dann dein Wissen erweitern kannst Edit: Zu langsam... Zitieren
seidenschwert Geschrieben 19. Oktober 2010 Autor Geschrieben 19. Oktober 2010 Ich weiß, darum gings auch nicht.. aber iwie beschreibt ihr das so wie ihr es versteht, an mich kommt das iwie nicht ran.. mein lehrer scheitert ja auch schon an mir.. ich bin einfach in visueler mensch ich lerne an beispielen.. ihr könnt mir ja versuchen ein bespiel zu geben^^ Schulwahl fail Zitieren
Klotzkopp Geschrieben 19. Oktober 2010 Geschrieben 19. Oktober 2010 Also ein Beispiel: Stell dir vor, der Benutzer macht folgende Eingaben: 1 5 - 2 3 = Nach welcher Eingabe kannst du Ergebnis ausrechnen? Was brauchst du dafür? Zitieren
SeToY Geschrieben 19. Oktober 2010 Geschrieben 19. Oktober 2010 Ein gutes beispiel findest du hier: WIN + R -> calc -> enter Das ist das beste beispiel, was du haben kannst ;P Du musst dir beim Klick auf deine Operatoren (plus, minus, mal, geteilt) merken, welche du gewählt hast, und beim klick auf gleich diesen operator auf die eingegebenen zahlen anwenden. Edit: Klotzkopp ist zu schnell Zitieren
seidenschwert Geschrieben 19. Oktober 2010 Autor Geschrieben 19. Oktober 2010 Danke für eure bemühungen An mir ist Hopfen und Malz verloren :'( Ich versuchs einfach weiter.. Aber wie gesagt großes Danke Zitieren
Klotzkopp Geschrieben 19. Oktober 2010 Geschrieben 19. Oktober 2010 An mir ist Hopfen und Malz verloren :'( Ich versuchs einfach weiter..Du wolltest ein Beispiel, jetzt bekommst du eins, und gibst sofort auf? Willst du es nicht wenigstens versuchen? Zitieren
seidenschwert Geschrieben 19. Oktober 2010 Autor Geschrieben 19. Oktober 2010 Und wie ich das will... aber mein denken reicht einfach nicht aus.. ich kämpf mich schon seid der 11. klasse mit c# mehr oder minder durch.. ich hab da einfach kein verständnis zu.. Ich hab ja schon bei hamster schlapp gemacht O.o Ich guck mir einfach nochmal alles durch was zum thema geschrieben wurde und versuch da vllt doch ne lösung rauszufiltern.. auf iwas kann ich sicher ein wneig aufbauen.. ansonsten muss mein lehrer woll damit leben dasich ein hoffnungsloser fall bin^^ Zitieren
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.