-1

I have three variables: calorieNumber, yourWeight, and exerciseCurrentValue.

var yourWeight:Float = 0
var calorieNumber:Float = 0
var exerciseCurrentValue:Float = 0.009

var yourWeight and calorieNumber` are changed from the user when they enter a numbers into UITextFields:

self.yourWeight = (self.yourWeightTextField.text as NSString).floatValue
self.calorieNumber = (self.calorieNumberTextField.text as NSString).floatValue

(This is in my ViewDidLoad method)

The var exerciseCurrentValue is changed based off the row of a UIPickerView:

var exerciseCurrentValue:Float = 0.009
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    switch (row) {
    case (0):
        exerciseCurrentValue = 0.009
    case (1):
        exerciseCurrentValue = 0.019
    case (2):
        exerciseCurrentValue = 0.023
    case (3):
        exerciseCurrentValue = 0.029
    case (4):
        exerciseCurrentValue = 0.045
    case (5):
        exerciseCurrentValue = 0.033
    case (6):
        exerciseCurrentValue = 0.038
    case (7):
        exerciseCurrentValue = 0.038
    case (8):
        exerciseCurrentValue = 0.039
    case (9):
        exerciseCurrentValue = 0.053
    case (10):
        exerciseCurrentValue = 0.061
    case (11):
        exerciseCurrentValue = 0.063
    case (12):
        exerciseCurrentValue = 0.063
    case (13):
        exerciseCurrentValue = 0.064
    case (14):
        exerciseCurrentValue = 0.076
    case (15):
        exerciseCurrentValue = 0.083
    default:
        exerciseCurrentValue = 0.009
    }
}

I also have an IBAction for when my calculateButton is tapped:

@IBAction func calculateButtonTapped(sender: AnyObject) {

Inside this method, I call my answer1Label to be shown and the text inside it to be changed:

answer1Label.hidden = false
answer1Label.text = "It will take you about \(round((calorieNumber) / ((yourWeight) * (exerciseCurrentValue)))) minutes to burn off that amount of calories by performing that exercise."

As you can see, I also use the round method to round the answer. When I use the simulator, enter numbers into the textfields and change the row of the UIPicker: The text becomes:

"It will take you about nan minutes to burn off that amount of calories by performing that exercise."

Why is this "nan" (not a number) being printed instead of the actual answer? The textfields both contain numbers, so what is wrong? Please provide the code to fix it. I am new to programming, so please be as thorough but simple as possible. If needed, here is all of my code:

import UIKit

class ViewController: UIViewController, UITextFieldDelegate, UIPickerViewDelegate, UIPickerViewDataSource {

@IBOutlet weak var calculatorButton: UIButton!
@IBOutlet weak var inspirationLabel: UILabel!
@IBOutlet weak var beginningLabel: UILabel!
@IBOutlet weak var calculatorContainer: UIView!
@IBOutlet weak var answer1Label: UILabel!
@IBOutlet weak var doneButton: UIButton!
@IBOutlet weak var yourWeightTextField: UITextField!
@IBOutlet weak var exerciseListPickerView: UIPickerView!
@IBOutlet weak var calorieNumberTextField: UITextField!
@IBOutlet weak var menuExampleButton: UIButton!
@IBOutlet weak var aboutButton: UIButton!
@IBOutlet weak var calculateButton: UIButton!

var yourWeight:Float = 0
var calorieNumber:Float = 0

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib
    yourWeightTextField.delegate = self
    calorieNumberTextField.delegate = self
    exerciseListPickerView.delegate = self
    exerciseListPickerView.dataSource = self
    calculateButton.enabled = false
    // Calling the textfield valueChanged Methods
    yourWeightTextField.addTarget(self, action:"yourWeightEditingChanged:", forControlEvents:.EditingChanged);
    calorieNumberTextField.addTarget(self, action:"calorieNumberEditingChanged:", forControlEvents:.EditingChanged);
    // Making the textfields convert to float values
    self.yourWeight = (self.yourWeightTextField.text as NSString).floatValue
    self.calorieNumber = (self.calorieNumberTextField.text as NSString).floatValue
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

@IBAction func calculatorButtonTapped(sender: AnyObject) {
    calculatorContainer.hidden = !calculatorContainer.hidden
    inspirationLabel.hidden = !inspirationLabel.hidden
    beginningLabel.hidden = !beginningLabel.hidden
    menuExampleButton.hidden = !menuExampleButton.hidden
    aboutButton.hidden = !aboutButton.hidden
    if calculatorButton.currentTitle == "Calculator" {
        calculatorButton.setTitle("Back", forState: .Normal)
    } else {
        calculatorButton.setTitle("Calculator", forState: .Normal)
    }
    if answer1Label.hidden == false {
        calculatorContainer.hidden = true
    }
    answer1Label.hidden = true
}
var yourWeightFilled = false
var calorieNumberFilled = false

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    // Find out what the text field will be after adding the current edit
    let text = (textField.text as NSString).stringByReplacingCharactersInRange(range, withString: string)

    // If the textfields have the properties of the function
    if textField == yourWeightTextField {
        yourWeightFilled = text.toInt() != nil
    } else if textField == calorieNumberTextField {
        calorieNumberFilled = text.toInt() != nil
    } else {
        calculateButton.enabled = false
    }
    return true
}

func textFieldShouldReturn(textField: UITextField) -> Bool
{
    textField.resignFirstResponder();
    return true;
}
func textFieldShouldClear(textField: UITextField) -> Bool {
    calculateButton.enabled = false
    return true
}

// The methods to close the keyboard when editing is finished
@IBAction func yourWeightEditingDidEnd(sender: AnyObject) {
    yourWeightTextField.resignFirstResponder()
    calculatorButton.enabled = true
}

@IBAction func calorieNumberEditingDidEnd(sender: AnyObject) {
    calorieNumberTextField.resignFirstResponder()
    calculatorButton.enabled = true
}
// Method regonizing if both variables are true, then enable button
func validateCalculateButton() {
    self.calculateButton.enabled = (self.yourWeightFilled &&
        self.calorieNumberFilled)
}

@IBAction func calorieNumberEditingChanged(sender: AnyObject) {
    // If both variables are true and the text fields contain integers, enable button
    self.validateCalculateButton()
}
@IBAction func yourWeightEditingChanged(sender: AnyObject) {
    // If both variables are true and the text fields contain integers, enable button
    self.validateCalculateButton()
}
@IBAction func yourWeightEditingDidBegin(sender: AnyObject) {
    calculatorButton.enabled = false
}
@IBAction func calorieNumberEditingDidBegin(sender: AnyObject) {
    calculatorButton.enabled = false
}
var exerciseArray = ["Sitting","Walking","Bowling","Biking Slow","Biking Fast","Golf","SoftBall","BaseBall","Weight Training","Ice Skating","Tennis","Basketball","Jogging","Swimming","Soccer","Jump Rope"]

func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
    return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    return exerciseArray.count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
    return exerciseArray[row]
}
var exerciseCurrentValue:Float = 0.009
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    switch (row) {
    case (0):
        exerciseCurrentValue = 0.009
    case (1):
        exerciseCurrentValue = 0.019
    case (2):
        exerciseCurrentValue = 0.023
    case (3):
        exerciseCurrentValue = 0.029
    case (4):
        exerciseCurrentValue = 0.045
    case (5):
        exerciseCurrentValue = 0.033
    case (6):
        exerciseCurrentValue = 0.038
    case (7):
        exerciseCurrentValue = 0.038
    case (8):
        exerciseCurrentValue = 0.039
    case (9):
        exerciseCurrentValue = 0.053
    case (10):
        exerciseCurrentValue = 0.061
    case (11):
        exerciseCurrentValue = 0.063
    case (12):
        exerciseCurrentValue = 0.063
    case (13):
        exerciseCurrentValue = 0.064
    case (14):
        exerciseCurrentValue = 0.076
    case (15):
        exerciseCurrentValue = 0.083
    default:
        exerciseCurrentValue = 0.009
    }
}
@IBAction func calculateButtonTapped(sender: AnyObject) {
    calculatorButton.enabled = true
    calculatorContainer.hidden = true
    answer1Label.hidden = false
    answer1Label.text = "It will take you about \(round((calorieNumber) / ((yourWeight) * (exerciseCurrentValue)))) minutes to burn off that amount of calories by performing that exercise."
}
}
TheCentral
  • 35
  • 1
  • 6

1 Answers1

0

You are actually doing let x = 0 / 0 = nan = (not a number) So you need to make sure your code don't do that calculation until the user inputs his/her weight and calories amount or just set a minimum value for yourWeight and calorieNumber vars other than zero.

try breaking it down

var yourWeight:Float = 0.1  // 0.100000001490116
var calorieNumber:Float = 0.1  // 0.100000001490116
var exerciseCurrentValue:Float = 0.009 // 0.00899999961256981
let divisor = (yourWeight * exerciseCurrentValue) // 0.000899999984540045
let dividendo = calorieNumber  // 0.100000001490116
let result = dividendo / divisor // 111.111114501953

with zero as input

var yourWeight:Float = 0  // 0.0
var calorieNumber:Float = 0  // 0.0
var exerciseCurrentValue:Float = 0.009 // 0.00899999961256981
let divisor = (yourWeight * exerciseCurrentValue) // 0.0
let dividendo = calorieNumber  // 0.0

if yourWeight > 0 && exerciseCurrentValue > 0 {
    let result = dividendo / divisor
    println(result)
} else {
    println("yourWeight or caloriNumber = 0 ====> yourWeight = \(yourWeight) | caloriNumber = \(calorieNumber)") // yourWeight or caloriNumber = 0 ====> yourWeight = 0.0 | caloriNumber = 0.0
}
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
  • I tried setting minimum values for my variables `yourWeight` and `calorieNumber`, but the same result is still occurring. – TheCentral Nov 30 '14 at 21:24
  • What do you mean by "break it down"? – TheCentral Nov 30 '14 at 21:27
  • I tried breaking it down like you said, but "nan" is still being printed. Do you think it might be a problem with my switch statement for my UIPickerView rows? – TheCentral Nov 30 '14 at 21:35
  • http://stackoverflow.com/questions/27215495/limit-uitextfield-input-to-numbers-in-swift/27216156#27216156 – Leo Dabus Nov 30 '14 at 21:39
  • I think the problem is with the zero value – Leo Dabus Nov 30 '14 at 21:39
  • Yes, I have already used the shouldCharactersInRange method for this, so that cannot be the problem. – TheCentral Nov 30 '14 at 21:42
  • try protecting the result calculation checking the values before as did now. I have just edited the answer – Leo Dabus Nov 30 '14 at 21:45
  • Ok. I see what is happening. The system still thinks that `yourWeight` and `calorieNumber` = 0. Do you think the reason the variables think that the textFields contain 0s is in this code in my ViewDidLoad? `self.yourWeight = (self.yourWeightTextField.text as NSString).floatValue self.calorieNumber = (self.calorieNumberTextField.text as NSString).floatValue` – TheCentral Nov 30 '14 at 21:56
  • Yes! I figured it out! I wasn't calling `self.yourWeight = (self.yourWeightTextField.text as NSString).floatValue` and `self.calorieNumber = (self.calorieNumberTextField.text as NSString).floatValue` when the textField edits finished! Thank you! – TheCentral Nov 30 '14 at 22:04