From c6a244c5f395c9f8557a96d3e0800c3957ebab3b Mon Sep 17 00:00:00 2001 From: Antonio Feregrino Date: Sun, 11 Dec 2016 22:21:29 -0600 Subject: [PATCH] Small flaws with the Description field --- Calculator/CalculatorBrain.cs | 390 ++++++++++++++++++---------------- Calculator/Main.storyboard | 4 +- Calculator/ViewController.cs | 18 +- 3 files changed, 220 insertions(+), 192 deletions(-) diff --git a/Calculator/CalculatorBrain.cs b/Calculator/CalculatorBrain.cs index ce18b2b..ab66c37 100644 --- a/Calculator/CalculatorBrain.cs +++ b/Calculator/CalculatorBrain.cs @@ -5,187 +5,211 @@ namespace Calculator { - public class CalculatorBrain - { - double _accumulator; - bool _hasSetDot; - double DecimalPositions = 10; - const double IntegerPositions = 10; - const int MaxMemory = 10; - Queue _operations = new Queue(MaxMemory); - - - internal void AddOperand(double operand, bool userIsInTheMiddleOfTyping) - { - if (userIsInTheMiddleOfTyping) - { - if (!_hasSetDot) - { - _accumulator = _accumulator * IntegerPositions + operand; - //_integerPositions *= 10; - } - else - { - _accumulator = _accumulator + operand / DecimalPositions; - DecimalPositions *= 10; - } - } - else - { - DecimalPositions = 10; - if (!_hasSetDot) - { - _accumulator = operand; - //_integerPositions *= 10; - } - else - { - _accumulator = operand / DecimalPositions; - DecimalPositions *= 10; - } - } - } - - enum Operation - { - Constant, - UnaryOperation, - BinaryOperation, - Equals, - Dot, - Clear - } - - struct PendingOperationInfo - { - public PendingOperationInfo(Func binaryOperation, double firstOperand) - { - BinaryOperation = binaryOperation; - FirstOperand = firstOperand; - } - public double FirstOperand { get; private set; } - public Func BinaryOperation { get; private set; } - - } - - PendingOperationInfo? _pendingOperation; - - void PerformPendingOperation() - { - if (_pendingOperation.HasValue) - { - var p = _pendingOperation.Value; - _accumulator = p.BinaryOperation(p.FirstOperand, _accumulator); - _pendingOperation = null; - } - } - - Dictionary operations = new Dictionary - { - { "π", Operation.Constant }, - { "e", Operation.Constant }, - { "C", Operation.Clear }, - { "√", Operation.UnaryOperation }, - { "±", Operation.UnaryOperation }, - { "cos", Operation.UnaryOperation }, - { "sin", Operation.UnaryOperation }, - { "tan", Operation.UnaryOperation }, - { "x!", Operation.UnaryOperation }, - { "×", Operation.BinaryOperation }, - { "÷", Operation.BinaryOperation }, - { "−", Operation.BinaryOperation }, - { "+", Operation.BinaryOperation }, - { "=", Operation.Equals }, - { ".", Operation.Dot } - }; - - Dictionary constants = new Dictionary - { - { "π", Math.PI }, - { "e", Math.E } - }; - - Dictionary> unaries = new Dictionary> - { - { "√", Math.Sqrt }, - { "±", (d ) => -1 * d }, - { "cos", Math.Cos }, - { "sin", Math.Sin}, - { "tan", Math.Tan }, - { "x!", (d) => d } - }; - - Dictionary> binaries = new Dictionary> - { - { "×", (a,b) => a * b }, - { "÷", (a,b) => a / b }, - { "−", (a,b) => a - b }, - { "+", (a,b) => a + b }, - }; - - internal void PerformOperation(string symbol) - { - Operation op; - if (operations.TryGetValue(symbol, out op)) - { - AddRecentOp(symbol); - switch (op) - { - case Operation.Constant: - _accumulator = constants[symbol]; - break; - case Operation.UnaryOperation: - _accumulator = unaries[symbol](_accumulator); - break; - case Operation.BinaryOperation: - - _hasSetDot = false; - PerformPendingOperation(); - _pendingOperation = new PendingOperationInfo(binaries[symbol], _accumulator); - - break; - case Operation.Equals: - PerformPendingOperation(); - break; - case Operation.Dot: - if (!_hasSetDot) - { - _hasSetDot = true; - } - break; - case Operation.Clear: - Clear(); - break; - default: - break; - } - } - } - - void Clear() - { - _hasSetDot = false; - _accumulator = 0; - _pendingOperation = null; - DecimalPositions = 10; - } - - - internal String RecentOperations - { - get { return String.Join(" ", _operations); } - } - - private void AddRecentOp(string op) - { - if(_operations.Count == MaxMemory) - _operations.Dequeue(); - _operations.Enqueue(op); - } - - internal Double Result - { - get { return _accumulator; } - } - } + public class CalculatorBrain + { + double _accumulator; + bool _hasSetDot; + double DecimalPositions = 10; + const double IntegerPositions = 10; + const int MaxMemory = 10; + + + internal void AddOperand(double operand, bool userIsInTheMiddleOfTyping) + { + if (userIsInTheMiddleOfTyping) + { + if (!_hasSetDot) + { + _accumulator = _accumulator * IntegerPositions + operand; + } + else + { + _accumulator = _accumulator + operand / DecimalPositions; + DecimalPositions *= 10; + } + } + else + { + DecimalPositions = 10; + if (!_hasSetDot) + { + _accumulator = operand; + //_integerPositions *= 10; + } + else + { + _accumulator = operand / DecimalPositions; + DecimalPositions *= 10; + } + } + } + + enum Operation + { + Constant, + UnaryOperation, + BinaryOperation, + Equals, + Dot, + Clear + } + + struct PendingOperationInfo + { + public PendingOperationInfo(Func binaryOperation, double firstOperand) + { + BinaryOperation = binaryOperation; + FirstOperand = firstOperand; + } + public double FirstOperand { get; private set; } + public Func BinaryOperation { get; private set; } + + } + + PendingOperationInfo? _pendingOperation; + + void PerformPendingOperation() + { + if (_pendingOperation.HasValue) + { + var p = _pendingOperation.Value; + _accumulator = p.BinaryOperation(p.FirstOperand, _accumulator); + _pendingOperation = null; + } + } + + Dictionary operations = new Dictionary + { + { "π", Operation.Constant }, + { "e", Operation.Constant }, + { "C", Operation.Clear }, + { "√", Operation.UnaryOperation }, + { "±", Operation.UnaryOperation }, + { "cos", Operation.UnaryOperation }, + { "sin", Operation.UnaryOperation }, + { "tan", Operation.UnaryOperation }, + { "^2", Operation.UnaryOperation }, + { "×", Operation.BinaryOperation }, + { "÷", Operation.BinaryOperation }, + { "−", Operation.BinaryOperation }, + { "+", Operation.BinaryOperation }, + { "=", Operation.Equals }, + { ".", Operation.Dot } + }; + + Dictionary constants = new Dictionary + { + { "π", Math.PI }, + { "e", Math.E } + }; + + Dictionary> unaries = new Dictionary> + { + { "√", Math.Sqrt }, + { "±", (d ) => -1 * d }, + { "cos", Math.Cos }, + { "sin", Math.Sin}, + { "tan", Math.Tan }, + { "^2", (d) => d * d } + }; + + Dictionary> binaries = new Dictionary> + { + { "×", (a,b) => a * b }, + { "÷", (a,b) => a / b }, + { "−", (a,b) => a - b }, + { "+", (a,b) => a + b }, + }; + + internal void PerformOperation(string symbol) + { + Operation op; + if (operations.TryGetValue(symbol, out op)) + { + AddRecentOp(symbol, op); + switch (op) + { + case Operation.Constant: + _accumulator = constants[symbol]; + break; + case Operation.UnaryOperation: + _accumulator = unaries[symbol](_accumulator); + break; + case Operation.BinaryOperation: + _hasSetDot = false; + PerformPendingOperation(); + _pendingOperation = new PendingOperationInfo(binaries[symbol], _accumulator); + break; + case Operation.Equals: + PerformPendingOperation(); + break; + case Operation.Dot: + if (!_hasSetDot) + { + _hasSetDot = true; + } + break; + case Operation.Clear: + Clear(); + break; + default: + break; + } + _previousOperation = op; + } + } + + void Clear() + { + _description = null; + _hasSetDot = false; + _accumulator = 0; + _pendingOperation = null; + DecimalPositions = 10; + } + + private string _description; + internal string Description => _description ?? " "; + + internal bool IsPartialResult => _pendingOperation != null; + + + private Operation? _previousOperation; + private void AddRecentOp(string symbol, Operation operation) + { + + switch (operation) + { + case Operation.Constant: + if (IsPartialResult) + _description = $"{_description} {symbol}"; + else + _description = $"{symbol}"; + break; + case Operation.UnaryOperation: + _description = $" {symbol} ({_description ?? _accumulator.ToString()})"; + break; + case Operation.BinaryOperation: + if (IsPartialResult) break; + _description = $"({_description ?? _accumulator.ToString()}) {symbol} "; + break; + case Operation.Equals: + if (_previousOperation.HasValue && + _previousOperation.Value != Operation.Constant && + _previousOperation.Value != Operation.Equals) + { + if (_description != null) + _description = $"{_description} {_accumulator}"; + } + break; + default: + break; + } + } + + internal Double Result + { + get { return _accumulator; } + } + } } diff --git a/Calculator/Main.storyboard b/Calculator/Main.storyboard index 17ad260..fd5f4a9 100644 --- a/Calculator/Main.storyboard +++ b/Calculator/Main.storyboard @@ -1,4 +1,4 @@ - + @@ -218,7 +218,7 @@ - + diff --git a/Calculator/ViewController.cs b/Calculator/ViewController.cs index 719a4fe..a9e93e6 100644 --- a/Calculator/ViewController.cs +++ b/Calculator/ViewController.cs @@ -17,9 +17,8 @@ partial void TouchDigit(UIButton sender) { var digit = sender.CurrentTitle; brain.AddOperand(Double.Parse(digit), userIsInTheMiddleOfTyping); - DisplayValue = brain.Result; - recentOperations.Text = brain.RecentOperations; userIsInTheMiddleOfTyping = true; + SetResult(); } CalculatorBrain brain = new CalculatorBrain(); @@ -30,20 +29,25 @@ Double DisplayValue set { display.Text = value.ToString(); } } + void SetResult() + { + DisplayValue = brain.Result; + recentOperations.Text = brain.Description + (brain.IsPartialResult ? "..." : " ="); + } + partial void PressDot(UIButton sender) { var symbol = sender.CurrentTitle; brain.PerformOperation(symbol); - DisplayValue = brain.Result; - } + SetResult(); + } partial void PerformOperation(UIButton sender) { userIsInTheMiddleOfTyping = false; var symbol = sender.CurrentTitle; brain.PerformOperation(symbol); - DisplayValue = brain.Result; - recentOperations.Text = brain.RecentOperations; - } + SetResult(); + } } }