2015-02-15 4 views
0

Я изучаю курс CS193P на iTunesU. У меня есть вопрос, связанный с 1-м заданием - Программируемый калькулятор. Я попытался добавить кнопку π, как описано в лекциях и задании домашней работы. Тем не менее, нажав клавишу П а затем введите или и операнд вызывает сбой с сообщением: «Фатальная ошибка: неожиданно нашел ноль в то время как разворачивание необязательного значения»CS193P Назначение 1 π

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 })) 
} 

Я был в состоянии заставить он находится в контроллере вида, но знает, что это взломать:

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

+0

Как я понимаю, на дисплее калькулятора будет указано «3.1415926 ...», когда вы нажимаете 'π'. Все остальные операции отображают результат (например, 'cos'). 'π' работает одинаково. Это операция, которая выводит результат на дисплей. Этот результат - двойной «M_PI». Похоже, ваш дисплей 'π', который' NSNumberFormatter' не может превратиться в 'NSNumber'. – vacawama

+0

Ах! Спасибо @vacawama. Ваш ответ вызвал мысль о проверке viewController. Кнопка π отобразилась в appendDisplay как номер 0-9.Я переделал его, чтобы работать как операторы sin и cos, и теперь он работает правильно. – fil

ответ

0

NSNumberFormatter().numberFromString предназначен для преобразования числовых строк в числа. А «числовая строка» является строкой, содержание которой имеют вид:

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

Где [:digit:] это набор цифр {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}.

По существу, он будет анализировать только цифры из строк, символы которых находятся в пределах 0-9 и необязательно ..

Потому что π не относится к этому набору из 10 символов, его отклоняют, и NSNumberFormatter не может проанализировать число из строки.

+0

RegEx, вероятно, находится на неприемлемом уровне для новичков. (Я угадываю из-за бегства ".) – zaph

+0

Возможно, нет оснований предполагать, что он новичок по всем направлениям. На всякий случай я включил дополнительное предложение объяснения. –

+0

Ах, спасибо @IanMacDonald! Ваш ответ вызвал мысль о проверке viewController. Кнопка π отобразилась в appendDisplay как номер 0-9. Я переделал его, чтобы работать как операторы sin и cos, и теперь он работает правильно. (И все в порядке, я новичок) – fil

0

Я делаю тот же курс, но поскольку я еще не в состоянии отделить мой MVC (сделаю это в следующем задании), я могу только дать вам подсказку, где вы ошибетесь. Как это работает для меня ....

Ваш хак тестирует 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() 
} 

Я думаю, что это может быть более оптимальным тоже, но это может помочь вам найти ошибку в коде.

0

Я также делаю такой же курс. Я действительно решил "." и "пирог". Посмотрите, поможет ли вам это.

@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 
       } 
     } 
    } 
1
@IBAction func appendPi(sender: UIButton) { 

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

Создан новая функция UIButton для PI отдельно от других функций. Работая для меня, отпустите его.