Im trying to run my calculator - ios

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.

Related

Swift app for solving factors of numbers and display

i'm new the forum and also new to the swift language. I've been playing around with xcode and wanted to create an app that uses a fenceloop to display the factors of a number as a "solution." The app currently uses a label to display, a text for input, and a button to initiate. I have what i think to be functioning code but i can't see to get it to work because from what i understand, i have to convert the input that's a string into an int. If anyone has any ideas how to get this working; since i feel like i've done what i can.
The problem in particular i am getting is it is saying that "Cannot convert value of type 'UITextField!; to expected argument type 'Int'. What i intend to happen is that on the button click, it solves for the factors of whatever is in the text box and displays it as a string in the label. Any help is appreciated!
import UIKit
class ViewController: UIViewController {
#IBOutlet var input1 : UITextField!
#IBOutlet var label : UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func printFactors(n: Int) {
var result: String = ""
for i in 1...n {
guard n % i == 0 else {continue}
result += i == 1 ? "1" : " and \(i)"
}
print(result)
let outputText = printFactors(n: input1)
label.text = outputText
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
You have a lot of issues and confusion in your printFactors method. Lets split it up and setup things properly.
First, make a separate method to do the math:
func calculateFactors(n: Int) -> String {
var result: String = ""
for i in 1...n {
guard n % i == 0 else {continue}
result += i == 1 ? "1" : " and \(i)"
}
print(result)
return result
}
Now lets setup the button action:
#IBAction func factorAction(sender: UIButton) {
if let text = input1.text {
if let num = Int(text) {
let factor = calculateFactors(n: num)
label.text = factor
} else {
// Show the user that the entered text isn't a number
}
} else {
// There's no text
}
}
Setup your button to use the new factoryAction: method instead of the old printFactors: method.
Swift 3
Can reduce this code down to two lines with some functional magic.
func factors(of number: Int) -> [Int] {
return (1...number).filter { number % $0 == 0 }
}
print(factors(of: 24))

Swift error: Initializer for conditional binding must have Optional type, not '()'

I'm doing the course of iTunes University called "Developing iOS 8 Apps with Swift". On the third video I encountered with a problem that did not happen in the video, even though it was the same code, that is as follows:
class ViewController: UIViewController{
…
#IBAction func operate(sender: UIButton) {
if userIsInTheMiddleOfTypingANumber{
enter()
}
if let operation = sender.currentTitle {
if let result = brain.performOperation(operation) { > ERROR HERE
displayValue = result
} else {
displayValue = 0
}
}
}
…
}
After reading many explanations of this error I suppose the problem comes from here:
class CalculatorBrain
{
…
func performOperation(symbol: String) {
if let operation = knownOps[symbol] { opStack.append(operation)
}
}
}
Thank you if you can help me!
performOperation doesn't return anything and needs to return an optional type so that it can be used in your if let statement (to check if it did indeed return a value) and that's what it could be moaning about.
Try:
func performOperation(symbol: String) -> Int? {
which means it could return an Int, and then your if let statement should be happy.

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

Questions regarding to value setting and getters and setters in Swift

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.

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