【问题标题】:CS193P Assignment 1 πCS193P 作业 1 π
【发布时间】:2015-02-15 19:04:34
【问题描述】:

我正在 iTunesU 上学习 CS193P 课程。我有一个与第一个作业有关的问题 - 可编程计算器。我尝试按照讲座和家庭作业中的说明添加 π 按钮。但是,按 π 键后跟 enter or 和操作数会导致崩溃并显示以下消息:“致命错误:在展开可选值时意外发现 nil”

class CalculatorBrain
{
private enum Op {
    case Operand(Double)
    case NullaryOperation(String, () -> Double)
    case UnaryOperation(String, Double -> Double)
    case BinaryOperation(String, (Double,Double) -> Double)

    var description: String{
        get {
            switch self {
            case .Operand(let operand): return "\(operand)"
            case .NullaryOperation(let symbol, _): return symbol
            case .UnaryOperation(let symbol, _): return symbol
            case .BinaryOperation(let symbol,_):return symbol
            }
        }
    }
}

private var opStack = [Op]()

private var knownOps = [String:Op]() //initialize dictionary

init() {
    func learnOp (op: Op) {
        knownOps[op.description] = op
    }
    learnOp(Op.BinaryOperation("×", *))
    learnOp(Op.BinaryOperation("÷", { $1 / $0 }))
    learnOp(Op.BinaryOperation("+", +))
    learnOp(Op.BinaryOperation("−", { $1 - $0 }))
    learnOp(Op.UnaryOperation("√", sqrt))
    learnOp(Op.UnaryOperation("sin", sin))
    learnOp(Op.UnaryOperation("cos", cos))
    learnOp(Op.NullaryOperation("π", { M_PI }))
}

我已经能够在视图控制器中强制它,但知道这是一个 hack:

var displayValue: Double{
    get{
        // I don't understand why I had to put this hack in for π
      //  if (calcDisplay.text != "π"){
            return NSNumberFormatter().numberFromString(calcDisplay.text!)!.doubleValue
       // } else {
       // return M_PI
       // }
    }
    set{
        calcDisplay.text = "\(newValue)"
        userIsInTheMiddleOfTyping = false
    }
}

我是 Swift / Obj-C 的新手。有人可以帮我指出正确的方向来解决这个问题吗?

完整来源:https://github.com/philnewman/Calculator

【问题讨论】:

  • 据我了解,当您按π 时,计算器显示屏会显示“3.1415926...”。您的所有其他操作都会将结果显示在显示屏上(例如,cos)。 π 的工作方式相同。这是一种将结果显示在屏幕上的操作。这个结果是双重的M_PI。看起来您的显示器是 π,而 NSNumberFormatter 不能变成 NSNumber
  • 啊!谢谢@vacawama 你的回答引发了检查viewController的想法。 π 按钮被映射到 appendDisplay,就像数字 0-9 一样。我将它重新映射为像 sin 和 cos 运算符一样运行,现在它可以正常工作了。

标签: ios swift cs193p itunesu


【解决方案1】:
@IBAction func appendPi(sender: UIButton) {

    let x = M_PI
    if userIsInTheMiddleOfTypingANumber {
        displayValue = x
        display.text = "\(displayValue)"
    }else {
        displayValue = x
        userIsInTheMiddleOfTypingANumber = true
        enter()
    }
}

为 PI 创建了一个与其他函数分开的新 UIButton 函数。为我工作,试一试。

【讨论】:

    【解决方案2】:

    NSNumberFormatter().numberFromString 旨在将数字字符串转换为数字。 “数字字符串”是一个字符串,其内容格式为:

    ([:digit:]+(\.[:digit:]*)?)|(\.[:digit:]+)
    

    其中[:digit:] 是一组数字{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

    本质上,它只会解析字符在0-9 和可选. 内的字符串中的数字。

    因为π 不属于这10 个字符的集合,所以被拒绝,NSNumberFormatter 无法从字符串中解析出数字。

    【讨论】:

    • RegEx 可能处于不适合新手的水平。 (我猜是因为转义的“。”。
    • 也许吧。不过,没有理由认为他是一个全面的新手。为了以防万一,我加了一句解释。
    • 啊!谢谢@IanMacDonald!!您的回答引发了检查 viewController 的想法。 π 按钮被映射到 appendDisplay,就像数字 0-9 一样。我重新映射它以像 sin 和 cos 运算符一样运行,现在它可以正常工作了。 (没关系,我是新手)
    【解决方案3】:

    我正在做同样的课程,但由于我还没有分离我的 MVC(将在下一个作业中这样做),我只能给你一个提示,你哪里出错了。因为它对我有用....

    您的 hack 正在测试 calcDisplay.text 为“π”,但此时 calcDisplay.text 应该已经是 3,14159。 这就是我在工作任务中使用 println 检查的内容。

    因此,我可以向您展示我的部分代码,这对于 MVC 来说还不是最佳的:

       case "cos": performOperation{cos($0)}
        case "∏": performConstant(operation)
    
    func performOperation (operation: (Double) -> Double) {
        if operandStack.count >= 1 {
            displayValue = operation(operandStack.removeLast())
            enter()
        }
    }
    
    func performConstant (symbol: (String)) {
        switch symbol {
        case "∏": displayValue = M_PI
        default: break
        }
        display.text = "\(displayValue)"
        enter()
    }
    

    我认为它也可以更优化,但它可能会帮助您找到代码中的错误。

    【讨论】:

      【解决方案4】:

      我也在做同样的课程。我确实解决了“。”和“馅饼”问题。看看这是否对你有帮助。

      @IBAction func appendDigit(sender: UIButton) {
              let digit = sender.currentTitle!        
              if digit == "." {
      
                  if (display.text!.rangeOfString(".") == nil) {
                      display.text = display.text! + "."
      
      
                  } else {
                      //Don't display anything
                  }
              } else if digit == "∏" {
                  displayValue = pie
              } else {
                      if userIsInTheMiddleOfTypingANumber {
                          display.text = display.text! + digit
                      } else {
                          display.text = digit
                          userIsInTheMiddleOfTypingANumber = true
                      }
              }
          }
      

      【讨论】:

        猜你喜欢
        • 2012-02-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-26
        • 2012-05-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多