iOS:Case.计算器Calculator Modal写法对比

============自己的============

定义:

 double result;
    NSString *operator;  
    NSMutableString *operand1;
    double operand0;
主要方法:
// 获取结果
-(NSString *)getCalculateOutput{
    
    return [NSString stringWithFormat:@"%f",result];
}
//处理输入
-(void)dealWithInput:(NSString *)input{
        // num
    if ([self inputIsOperand:input]) {
        [operand1 appendString:input];
        result  = [operand1 doubleValue];
    }else{
        // operator
        
        int whichOperator = [self getOperator:operator];
        switch (whichOperator) {
            case 0:
                result = [operand1 doubleValue];
                
                break;
            case 1:
                result = [operand1 doubleValue] + operand0;
                
                break;
            case 2:
                result = [operand1 doubleValue] - operand0;
                
                break;
            case 3:
                result = [operand1 doubleValue] * operand0;
                
                break;
            case 4:
                result = [operand1 doubleValue] / operand0;
                break;
                
            default:
                break;
        }
         operand0 = result;
        operator = [NSString stringWithString:input];
        [operand1 setString:@""];
        
    }
}

-(BOOL)inputIsOperand:(NSString *)input{
    
    if ([@"0123456789" rangeOfString:input].length > 0) {
        return YES;
    }
    return NO;
}
-(int)getOperator:(NSString *)aOperator{
    
    if ([aOperator isEqualToString:@"+"]) {
        return Add;
    }else if([aOperator isEqualToString:@"-"]){
        return Sub;
    }else if([aOperator isEqualToString:@"*"]){
        return Mul;
    }else if([aOperator isEqualToString:@"*"]){
        return Div;
    }
    return non;
}

============官网============

定义:

@private
   NSMutableString *_display;    // The calculator display (the value a harwdare-based calculator shows on its LCD screen).
   double           _operand;
   NSString        *_operator;
// These string constants contain the characters that the input: method accepts.
const NSString *Operators = @"+-*/";
const NSString *Equals    = @"=";
const NSString *Digits    = @"0123456789.";
const NSString *Period    = @".";
const NSString *Delete    = @"D";
const NSString *Clear     = @"C";
主要方法:
/*
 * The input: method accepts the characters in the string constants
 * Operators, Equals, Digits, Period Delete, and Clear.
 *
 * The results of this method's computations are stored in _display.
 * This method uses _operand, and _operator in its calculations.
 */
- (void) input:(NSString *) input_character {
   static BOOL last_character_is_operator = NO;
   BOOL bad_character;
   
   // Does input_character contain exactly one character?
   if (!(bad_character = !(input_character && [input_character length] == 1))) {
      
      // Is input_character in Digits?
      if ([Digits rangeOfString: input_character].length) {
         if (last_character_is_operator) {
            // Set the display to input_character.
            [_display setString: input_character];
            
            last_character_is_operator = NO;
         }
         // Is input_character a digit, or is a period while a period has not been added to _display?
         else if (![input_character isEqualToString: (NSString *)Period] || [_display rangeOfString: (NSString *)Period].location == NSNotFound) {
            // Add input_character to _display.
            [_display appendString:input_character];
         }
      }
      
      // Is input_character in Operators or is it Equals?
      else if ([Operators rangeOfString:input_character].length || [input_character isEqualToString:(NSString *)Equals]) {
         if (!_operator && ![input_character isEqualToString:(NSString *)Equals]) {
            // input_character is this calculation's operator.
            //
            // Save the operand and the operator.
            _operand  = [[self displayValue] doubleValue];
            _operator = input_character;
         }
         else {
            // input_character is in Operators or Equals.
            //
            // Perform the computation indicated by the saved operator between the saved operand and _display.
            // Place the result in _display.
            if (_operator) {
               double operand2 = [[self displayValue] doubleValue];
               switch ([Operators rangeOfString: _operator].location) {
                  case 0:
                     _operand = _operand + operand2;
                     break;
                  case 1:
                     _operand = _operand - operand2;
                     break;
                  case 2:
                     _operand = _operand * operand2;
                     break;
                  case 3:
                     _operand = _operand / operand2;
                     break;
               }
               [_display setString: [[NSNumber numberWithDouble: _operand] stringValue]];
            }
            // Save the operation (if this is a chained computation).
            _operator = ([input_character isEqualToString:(NSString *)Equals])? nil : input_character;
         }
         last_character_is_operator = YES;
      }
      // Is input_character Delete?
      else if ([input_character isEqualToString:(NSString *)Delete]) {
         // Remove the rightmost character from _display.
         NSInteger index_of_char_to_remove = [_display length] - 1;
         if (index_of_char_to_remove >= 0) {
            [_display deleteCharactersInRange:NSMakeRange(index_of_char_to_remove, 1)];
            last_character_is_operator = NO;
         }
      }
      // Is input_character Clear?
      else if ([input_character isEqualToString:(NSString *)Clear]) {
         // If there's something in _display, clear it.
         if ([_display length]) {
            [_display setString:[NSString string]];
         }
         // Otherwise, clear the saved operator.
         else {
            _operator = nil;
         }
      }
      else {
         // input_character is an unexpected (invalid) character.
         bad_character = TRUE;
      }
   }
   if (bad_character) {
      // Raise exception for unexpected character.
      NSException *exception = [NSException exceptionWithName:NSInvalidArgumentException
                                                       reason:@"The input_character parameter contains an unexpected value."
                                                     userInfo:[NSDictionary dictionaryWithObjectsAndKeys: input_character, @"arg0", nil]];
      [exception raise];
   }
}

#pragma mark Outlets

/*
 * The displayValue method rerutns a copy of _display.
 */
- (NSString *) displayValue {
   if ([_display length]) {
      return [_display copy];
   }
   return @"0";
}

###############对比###############

---------算法-----------
--变量:
result:存储当前要显示的结果
operand0:存储上一个操作数
operator:存储上一个操作符
operand1:存储当前操作数
--输入处理:
输入如果是数字,保存为operand1,更新result的值;如果是操作符,则将之前保存的operand0、operator和operand1计算,并将结果保存为新的operand0,当前操作符保存为operator;更新result的值;
--输出:
显示result的值
---------------
--变量:
_display:显示的结果(当前操作数)
_operand:存储上一个操作数
_operator:存储上一个操作数
--输入处理:
输入如果是数字,_display接收输入,更新_display; 输入如果是运算符,判断是不是第一个运算符号,{如果是,保持操作数_operand和当前操作符_operator} {如果不是,将当前操作数_display、之前操作数_operand、操作符_operator运算,结果保存为新的operand,当前操作符保存为operator} 更新_display
--输出思路:
显示_display的值
-------比较
-大体一样,不过例2更精简(直接用显示的_display代替operand1,虽然_display显示的时候不总代表当前操作数operand1,但只要是开始运算,_display完全就是当前operand1),更全面(首个运算符号的判断);而且这更符合计算器model的思路,随意的输入值然后从display中get结果。

-算法,不仅仅要考虑变量选择,逻辑思路,对于变量初值的选择也很重要,_display为空字符串,operator为nil,lastCharacterIsOperator为no,这些值跟算法思路和逻辑分支判断完全对起来了;这些初值完全适用代码的逻辑判断,

-一个算法最基本要满足‘正常情况/循环结构’的处理,好的算法,变量初值完全契合‘正常情况/循环结构’,就像该例,循环结构为:碰到数字,更新显示;碰到运算符,如果运算符为nil怎么处理,或者用operator运算当前显示和operand,或者更新运算符(本例子不是做更新处理,另外一种思路);这些情况初值完全适用,开始时候,输入数字,更新display,如果输入计算符,默认operand为0,同时operator为当前输入的运算符。算法思路详见‘算法’分类中‘概念’文章。
----------命名问题----------

--result既然是存储着要显示的结果,叫display更合理;它不是运算结果(当输入操作数的时候,它的值为操作数)

--成员变量名字没有前缀下划线;
----------质量问题----------
--没有异常判断:对输入的字符串长度是不是1,有没有值,没判断,直接当作正确的去用了;
--没有合法值判断:输入的字符串应该限定在自己接受的范围内;
--考虑条件不够全面,算法逻辑不清晰:当运算完,当前操作符为‘=’号和其它符号的区别处理

----------其他技巧----------

- 第一个操作数为double类型,操作符和第二个操作数位字符串类型;

- 输入一个字符串判断是哪个字符:switch方法([const字符串常量 rangOfString ].location),其中case直接是数字,而不用写很多if,else if判断;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是加上计算器窗口界面后的代码,包括显示器和键盘界面的设计: ```python import math import tkinter as tk class Calculator: def __init__(self): self.result = 0 def add(self, num): self.result += num def sub(self, num): self.result -= num def mul(self, num): self.result *= num def div(self, num): if num == 0: self.result = "Error: Cannot divide by zero!" else: self.result /= num def getResult(self): return self.result def clear(self): self.result = 0 class CalculatorGUI: def __init__(self, master): self.master = master master.title("Calculator") self.result_label = tk.Label(master, text="0", width=20, font=("Arial", 20)) self.result_label.grid(row=0, column=0, columnspan=4) self.create_buttons() self.calculator = Calculator() def create_buttons(self): self.button1 = tk.Button(self.master, text="1", width=5, height=2, command=lambda: self.button_click(1)) self.button2 = tk.Button(self.master, text="2", width=5, height=2, command=lambda: self.button_click(2)) self.button3 = tk.Button(self.master, text="3", width=5, height=2, command=lambda: self.button_click(3)) self.button4 = tk.Button(self.master, text="4", width=5, height=2, command=lambda: self.button_click(4)) self.button5 = tk.Button(self.master, text="5", width=5, height=2, command=lambda: self.button_click(5)) self.button6 = tk.Button(self.master, text="6", width=5, height=2, command=lambda: self.button_click(6)) self.button7 = tk.Button(self.master, text="7", width=5, height=2, command=lambda: self.button_click(7)) self.button8 = tk.Button(self.master, text="8", width=5, height=2, command=lambda: self.button_click(8)) self.button9 = tk.Button(self.master, text="9", width=5, height=2, command=lambda: self.button_click(9)) self.button0 = tk.Button(self.master, text="0", width=5, height=2, command=lambda: self.button_click(0)) self.button_add = tk.Button(self.master, text="+", width=5, height=2, command=lambda: self.operation_click("+")) self.button_subtract = tk.Button(self.master, text="-", width=5, height=2, command=lambda: self.operation_click("-")) self.button_multiply = tk.Button(self.master, text="*", width=5, height=2, command=lambda: self.operation_click("*")) self.button_divide = tk.Button(self.master, text="/", width=5, height=2, command=lambda: self.operation_click("/")) self.button_clear = tk.Button(self.master, text="C", width=5, height=2, command=lambda: self.clear_click()) self.button_equals = tk.Button(self.master, text="=", width=5, height=2, command=lambda: self.equals_click()) self.button1.grid(row=3, column=0) self.button2.grid(row=3, column=1) self.button3.grid(row=3, column=2) self.button_add.grid(row=3, column=3) self.button4.grid(row=2, column=0) self.button5.grid(row=2, column=1) self.button6.grid(row=2, column=2) self.button_subtract.grid(row=2, column=3) self.button7.grid(row=1, column=0) self.button8.grid(row=1, column=1) self.button9.grid(row=1, column=2) self.button_multiply.grid(row=1, column=3) self.button_clear.grid(row=4, column=0) self.button0.grid(row=4, column=1) self.button_equals.grid(row=4, column=2) self.button_divide.grid(row=4, column=3) def button_click(self, number): current = self.result_label.cget("text") if current == "0": self.result_label.config(text=str(number)) else: self.result_label.config(text=current + str(number)) def operation_click(self, operation): current = self.result_label.cget("text") self.calculator.result = float(current) self.operation = operation self.result_label.config(text="0") def clear_click(self): self.calculator.clear() self.result_label.config(text="0") def equals_click(self): current = self.result_label.cget("text") self.calculator.result = float(current) if self.operation == "+": self.calculator.add(self.calculator.getResult()) elif self.operation == "-": self.calculator.sub(self.calculator.getResult()) elif self.operation == "*": self.calculator.mul(self.calculator.getResult()) elif self.operation == "/": self.calculator.div(self.calculator.getResult()) self.result_label.config(text=str(self.calculator.getResult())) if __name__ == '__main__': root = tk.Tk() calculator_gui = CalculatorGUI(root) root.mainloop() ``` 这个代码为用户提供了一个计算器界面,包括数字键、运算符键、清除键、等于键和显示器。当用户点击数字键时,数字将添加到显示器上。当用户点击运算符键时,当前数字将被存储并清除显示器。当用户点击等于键时,计算器将执行相应的操作并将结果显示在显示器上。如果用户点击清除键,那么计算器的结果将被重置为零。整个程序的控制流程是由按钮的事件处理程序控制的,这些事件处理程序与 Calculator 类中定义的方法相对应。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值