Questions regarding to value setting and getters and setters in Swift - ios

Hi I just picked up Swift and am following the Stanford open course. I was making this calculator and got a breakpoint at the line of userIsInTheMiddleOfTyping = false in the func enter part when I placed the line before operandStack.append(displayValue). After I placed the line at the bottom of the function, the problem was solved. But why?
Also, I don't get the part of get and set in displayValue part. Can anyone help to explain how this part is executed. And where is the newValue from? why does it represent whatever value on the display? The code is followed. I would appreciate any answers and comments!
class ViewController: UIViewController {
#IBOutlet weak var display: UILabel!
var userIsInTheMiddleOfTypingAnNumber = false
#IBAction func AppendDigit(sender: UIButton) {
let digit = sender.currentTitle!
if userIsInTheMiddleOfTypingAnNumber {
display.text = display.text! + digit
}
else{
display.text = digit
userIsInTheMiddleOfTypingAnNumber = true
}
}
var operandStack = Array<Double>()
#IBAction func enter() {
operandStack.append(displayValue)
println("operandStack=\(operandStack)")
userIsInTheMiddleOfTypingAnNumber = false
}
var displayValue: Double{
get{
return NSNumberFormatter().numberFromString(display.text!)!.doubleValue
}
set{
display.text = "\(newValue)"
userIsInTheMiddleOfTypingAnNumber = false
}
}
}

get and set are the keywords used in Swift to define custom getters and setters to a property.
newValue is the default name for the new value that will be assigned to the variable at the end of the setter, it allows you to check various things before assigning it.
For the first part of your question I don't quite understand what's not working for you.

Related

Im trying to run my calculator

Im using swift code on Xcode 8. Can someone please help me out and figure out the error? It says the expression pattern of type 'string' cannot match values of type 'operation'. the error appeared at the switch operation and then the case that held × in it.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var display: UILabel!
var userIsInTheMiddleOfTyping = false
#IBAction func Appenddigit(_ sender: UIButton) {
let digit = sender.currentTitle!
if userIsInTheMiddleOfTyping {
display.text = display.text! + digit
} else {
display.text = digit
userIsInTheMiddleOfTyping = true
}
}
#IBAction func operate(_ sender: UIButton) {
_ = sender.currentTitle!
if userIsInTheMiddleOfTyping{
enter()
}
switch Operation() {
case "×":
if operandStack.count >= 2 {
displayValue = operandStack.removeLast() * .operandStack.removeLast()
enter()
}
// case "÷":
// case "+":
// case "−":
default:
break
}
}
var operandStack: Array<Double> = []
#IBAction func enter() {
userIsInTheMiddleOfTyping = false
operandStack.append(displayValue)
print("operandStack = \(operandStack)")
}
var displayValue: Double {
get {
return NumberFormatter().number(from: display.text!)!.doubleValue
}
set {
display.text = "\(newValue)"
userIsInTheMiddleOfTyping = false
}
}
}
In Swift 3, Operation is the new name of the class NSOperation.
Your expression Operation() is creating an Operation object.
Whatever "Operation" is in your program, you need to rename it to something else. You should also explain what that code is supposed to be doing so we can help you fix it. The line
switch Operation()
Doesn't make sense to me.
Operation() is creating a new object of type Operation which cant be compared to "x"which is a string. What i think you want is to be calling a function called operation which would return a string.

Working on a calculator in swift and I'm stuck

I'm new to coding and just learning now. swift code and I'm running into a snag and can't seem to figure it out, so I've been flowing along with the Stanford YouTube channel on swift coding and they are doing a calculator. Currently we are trying to get double value.
#IBOutlet weak var display: UILabel!
var userIsInTheMiddleOfTypingANumber = false
#IBAction func appendDigit(sender: UIButton) {
let digit = sender.currentTitle!
if userIsInTheMiddleOfTypingANumber {
display.text = display.text! + digit
} else {
display.text = digit
userIsInTheMiddleOfTypingANumber = true
}
}
var operandStack: Array<Double> = Array<Double>()
#IBAction func enter() {
userIsInTheMiddleOfTypingANumber = false
operandStack.append(displayValue)
print("operandStack = \(operandStack)")
}
var displayValue: Double {
get {
return NSNumberFormatter().numberFromString(display.text!)!.doubleValue
// This is my problem and comes back with exc_bad_instruction (code=exc_i387_invop any help would be greatly appreciated on this! thank you for your time!
}
set {
display.text = "\(newValue)"
userIsInTheMiddleOfTypingANumber = false
}
}
In addition to Martin R: Actually you have two big problems and both are related to your unwrapping of optionals.
First is this line:
#IBOutlet weak var display: UILabel!
The problem is the !. An #IBOutlet links to a view in a storyboard. But depending on the stage the GUI is at it may be that this displaywon`t exist yet. So this should be a optional marked with ? not !. Then your compiler would complain about this line:
return NSNumberFormatter().numberFromString(display.text!)!.doubleValue
He would complain that display probably does not exist and that you can`t just do that. You would probably "solve" the problem like this:
return NSNumberFormatter().numberFromString(display!.text!)!.doubleValue
But this will either fail if displayist not ready or of the NSNumberFormatter can`t convert the string to a number. And you will never know why. So stop using forced unwrapping. You have different tools to solve your problem though. But at first you should think about your problem. Your problem is in the end that not every string can be converted to a double. So you have to deal with this at some point. There are countless possibilities to do so. But as a starter, if you have code that will crash if an optional (can be nil value) is actually nil then you can use this pattern:
if let thisValueIsNotNil = dontKnowIfItIsNil {
// Do something with thisValueIsNotNil - it is save
}
Edit: The core problem an mechanism are pretty well explained IMO in this blog post:
http://appventure.me/2014/06/13/swift-optionals-made-simple/

UILabel variable needs to be an Optional Double but I don't want the the label to display optional(valueOfNumber)

I'm trying to complete the CS193P Course independently. I am on assignment 2 of the course and part of the assignment asks for me to do the following:
"Change the computed instance variable displayValue to be an Optional Double rather than a Double"
I was able to change displayValue to be an Optional Double, but now my UILabel which shows the displayValue now will display the optional value instead of the double value (which makes sense).
Example:
5 (then press enter) will display a value of Optional(5.0) in the UILabel.
Here is what I tried:
I determined that result and displayValue! will return a double.
I tried changing display.text = result to display!.text! = result but that did not fix the issue.
Here is a snippet of my code, I think you shouldn't need any more but please comment if you think I should show something else!
P.S. the name of the display is display
#IBAction func enter() {
if let result = brain.pushOperand(displayValue!) {
displayValue = result
} else {
displayValue = 0
}
}
var displayValue: Double? {
get {
return NSNumberFormatter().numberFromString(display.text!)!.doubleValue
}
set{
display!.text! = "\(newValue)" //display is the UILabel
}
I believe the display is supposed to be blank when, for example, the stack cannot be evaluated to give a result.
So you can just use
var displayValue: Double? {
get { return NSNumberFormatter().numberFromString(display.text!)?.doubleValue }
set { if newValue != nil { display.text = "\(newValue!)" }
else { display.text = " " }
}
}
And then for "enter"
#IBAction func enter() {
if let dV = displayValue {
brain.pushOperand(dV)
displayValue = brain.evaluate()
}
userIsInTheMiddleOfTypingANumber = false
}
This solution worked for me. I am working through this course independently too. It is tricky and I have to listen to the lectures LOTS of times :-)
Jacki

Why does this swift code work when newValue has nothing assigned to it?

import UIKit
class ViewController: UIViewController {
#IBOutlet weak var display: UILabel!
var inMid = false
#IBAction func appendDigit(sender: UIButton) {
let digit = sender.currentTitle!
if inMid{
display.text = display.text! + digit
}else{
display.text = digit
inMid = true
}
}
var operandStack = Array<Double>()
#IBAction func enter() {
inMid = false
operandStack.append(displayValue)
println("operandStack = \(operandStack)")
}
var displayValue:Double{
get {
return NSNumberFormatter().numberFromString(display.text!)!.doubleValue
}
set{
display.text = "\(newValue)"
}
}
}
This is the part of code used in the latest Standford IOS 8 course using swift to build a calculator(Youtube address: https://www.youtube.com/watch?v=QLJtT7eSykg)
Every time I call enter() (press enter), a new number is supposed to be saved in a stack. For example: "8, enter()" --> {8}, "16, enter()" --> {8,16}.
I got confused about the computed property "displayValue" here. There is nothing assigned to the "newValue". If there is something like "displayValue = 8", then I know "newValue" is 8, and it all makes sense. But there is not such thing.
How come it still works?
(What I mean is not the name "newValue" itself,I know it is a default setting by Swift, instead, the missing of assigned value is the one that confuses me)
"newValue" is an implicitly defined variable in swift.
What he does is a very neat way of letting the label show the values of the double "displayValue" Every time displayValue is changed, the label is automatically updated with the newest (double) value.
Or when you write: displayValue = 45.0, the label will also show this value. Very handy when you constantly need to update textfield or labels with data you get from databases, rest interfaces, etc. What "newValue" does is taking the last "setter" value holding that.

I unwrapped the optional value but still getting this unexpectedly found nil while unwrapping an Optional value

I am new to IOS development and couldn't figure out how to resolve this error. Could any one help me out. Following is my code and the error point on the part of the code where I am using NSNumberFormatter(). waiting for your reply
class ViewController: UIViewController {
#IBOutlet weak var display: UILabel!
var usertyping
= false
#IBAction func appendDigit(sender: UIButton) {
let digit = sender.currentTitle!
if usertyping
{
display.text = display.text! + digit
}
else
{
display.text = digit
usertyping = true
}
}
#IBAction func operate(sender: UIButton) {
let operation = sender.currentTitle!
if usertyping{
enter()
}
switch operation {
case "×":
if operandstack.count >= 2
{
displayValue = operandstack.removeLast() * operandstack.removeLast()
enter()
}
default: break
}
}
var operandstack = Array<Double>()
#IBAction func enter() {
usertyping = false
operandstack.append(displayValue)
println("operandstack=\(operandstack)")
}
var displayValue: Double
{
get{
return NSNumberFormatter().numberFromString(display.text!)!.doubleValue
}
set{
display.text="(\newValue)"
usertyping=false
}
}
}
My guess is that it is failing over because display.text is nil or some invalid value.
Unwrapping an optional doesn't stop it being nil. It says that you realise that it could be nil, but you know that it isn't. If you are wrong and it is nil, it will fail.
Normally, unwrapping optionals for things like you are loading an image from a file. The file could be missing, but you know it isn't in your program, so you can assume the result can never be nil.
In your case, I assume display.text can be nil and you have to explicitly handle it or use optional chaining (the ?).
I see 2 dangerous "!" in this line
return NSNumberFormatter().numberFromString(display.text!)!.doubleValue
One on them could be the cause of your fatal error.
display.text! are you sure text is not nil?
numberFromString returns an optional, are you sure the input you are passing is something the method can transform into a NSNumber?
Hope this helps.
It is because numberFromString returns nil if there is no valid number found.
An NSNumber object created by parsing string using the receiver’s
format. Returns nil if there are no numbers in the passed string.
Reference numberFromString:
If your display.text doesn't have any valid number that statement will crash.
You can fix that by:
var displayValue: Double
{
get
{
var returnVal = NSNumber(int: 0)
if let dVal = NSNumberFormatter().numberFromString(display.text!)
{
returnVal = dVal
}
return returnVal.doubleValue
}
set
{
display.text = "(\newValue)"
usertyping = false
}
}

Resources