Second variable takes the firsts value - swift

I built an binary calculator app, For the numbers I have two variables. previousNumber and numberOnScreen. The idea is to convert the binary numbers to decimals, do the calculation and convert the answer back.
Lets say the first (previousNumber)number I pick is 1010 and the second (numberOnScreen) 10100
var numberOnScreen:Int = 0;
var previousNumber:Int = 0;
var doingMath = false
var operation = 0;
var decimal = 0;
var decimal1 = 0;
var binary:String = ""
var binary1:String = ""
#IBOutlet weak var label: UILabel!
#IBAction func Numbers(_ sender: UIButton) {
if doingMath == true
{
label.text = String(sender.tag-1)
numberOnScreen = Int(label.text!)!
doingMath = false
}
else
{
label.text = label.text! + String(sender.tag-1)
numberOnScreen = Int(label.text!)!
}
}
#IBAction func buttons(_ sender: UIButton) {
if label.text != "" && sender.tag != 6 && sender.tag != 8
{
previousNumber = Int(label.text!)!
binary = "\(previousNumber)"
decimal = Int(binary, radix: 2)!
binary1 = "\(numberOnScreen)"
decimal1 = Int(binary1, radix: 2)!
operation = sender.tag
doingMath = true;
}
else if sender.tag == 8
{
if operation == 3 //adding
{
print(previousNumber, numberOnScreen, decimal, decimal1)
It prints [ 1010, 10100, 10, 10 }
Any ideas why this is happening?

When you hit the = key, you need to update the calculation of decimal1. Move that code to the place where you are processing =:
#IBAction func buttons(_ sender: UIButton) {
if label.text != "" && sender.tag != 6 && sender.tag != 8
{
previousNumber = Int(label.text!)!
binary = "\(previousNumber)"
decimal = Int(binary, radix: 2)!
operation = sender.tag
doingMath = true;
}
else if sender.tag == 8
{
binary1 = "\(numberOnScreen)"
decimal1 = Int(binary1, radix: 2)!
if operation == 3 //adding
{
print(previousNumber, numberOnScreen, decimal, decimal1)
Also, I recommend that you get rid of the magic numbers in your code and replace them with constants. For your key tags, you could define a struct like this:
struct Key {
static let clear = 6
static let equals = 8
static let plus = 3
}
and then your code would read:
if label.text != "" && sender.tag != Key.clear && sender.tag != Key.equals {
which is much clearer.

Related

How divide result from text field to label and get it on another label

I need to finish(Label) = totalAmount(TextField) / adam (Label).
Here is my code:
import UIKit
var plusAndMinus = 0
class ViewController234: UIViewController {
#IBOutlet weak var adam: UILabel!
#IBAction func plus(_ sender: Any) {
plusAndMinus += 1
adam.text = "\(plusAndMinus)"
}
#IBAction func minus(_ sender: Any) {
if(plusAndMinus != 0 ) {
plusAndMinus -= 1
}
adam.text = "\(plusAndMinus)"
}
// Write total amonunt to calculate
#IBOutlet weak var totalAmount: UITextField!
#IBAction func equal(_ sender: Any) {
var adam = 0
var totalAmount = 0
var result = 0
adam = Int(adam)
totalAmount = Int(totalAmount)
guard result != 0 else {return}
result = totalAmount / adam
finish.text = String(result)
}
//Show calculated
// finish = totalAmount / adam
#IBOutlet weak var finish: UILabel!
It looks to me like you are only accessing your local variables and not the text fields in the equal() function.
It is better to use different names for local variables and class properties to avoid confusion.
So first lets validate that the text fields contains values that can be converted to Int variables and otherwise return directly by using guard. Then it's simply a matter of dividing the values but of course we also want to avoid decision by zero so we check that to
#IBAction func equal(_ sender: Any) {
guard let text = Adam.text, let adamValue = Int(text), adamValue != 0,
let totalAmountValue = Int(totalAmount.text!) else { return }
let result = totalAmountValue / adamValue
finish.text = String(result)
}
By using integers we are doing integer division and thus loosing precision, if you want to keep the precision you can switch to Double in the code above and perhaps add some formatting of the result
#IBAction func equal(_ sender: Any) {
guard let text = Adam.text, let adamValue = Double(text), adamValue != 0,
let totalAmountValue = Double(totalAmount.text!) else { return }
let result = totalAmountValue / adamValue
finish.text = String(format: "%.2f", result)
}
I'm not sure what your finish label is because you don't have a label for it, but given that you're meaning to output your answer to it:
enum InputError: Error {
case emptyAdamLabel
case emptyTotalAmountLabel
case divideByZero
case invalidFormat
}
func calculate() throws {
if let adamText = adam.text, adamText.trimmingCharacters(in: .whitespacesAndNewlines) == "" {
throw InputError.emptyAdamLabel
} else if let total = totalAmount.text, total.trimmingCharacters(in: .whitespacesAndNewlines) == "" {
throw InputError.emptyTotalAmountLabel
} else if let adamText = adam.text, adamText == "0" {
throw InputError.divideByZero
} else if let adamNumber = Double(adam.text!), let totalAmountNumber = Double(totalAmount.text!) {
finish.text = String(format: "%.2f", totalAmountNumber / adamNumber)
} else {
throw InputError.invalidFormat
}
}
#IBAction func equal(_ sender: Any) {
do {
try calculate()
} catch InputError.emptyAdamLabel {
print("Adam's label cannot be empty")
} catch InputError.emptyTotalAmountLabel {
print("Total Amount's label cannot be empty")
} catch InputError.divideByZero {
print("Adam's label cannot be zero")
} catch InputError.invalidFormat {
print("Both Adam's label and Total Amount's label have to be integers")
} catch {
print("Unknown errors")
}
adam.text = "0"
totalAmount.text = "0"
}

Adding a Decimal Point button to the calculator app

Can someone please add the code to this so I'm able to add a decimal point button?
This is what I have so far, can someone please fill in the code required for the decimal point button. so I can learn from it. please view over the code and let me know what you think.
import UIKit
class ViewController: UIViewController {
var numberOnScreen:Double = 0;
var previousNumber:Double = 0;
var preformingMath = false
var operation = 0;
#IBOutlet weak var label: UILabel!
#IBAction func numbers(_ sender: UIButton)
{
if preformingMath == true
{
label.text = String(sender.tag-1)
numberOnScreen = Double(label.text!)!
preformingMath = false
}
else
{
label.text = label.text! + String(sender.tag-1)
numberOnScreen = Double(label.text!)!
}
}
#IBAction func buttons(_ sender: UIButton)
{
if label.text != "" && sender.tag != 11 && sender.tag != 16
{
previousNumber = Double(label.text!)!
if sender.tag == 12 //Divide
{
label.text = "/";
}
else if sender.tag == 13//Multiply
{
label.text = "x";
}
else if sender.tag == 14 //Minus
{
label.text = "-";
}
else if sender.tag == 15 //Plus
{
label.text = "+";
}
operation = sender.tag;
preformingMath = true;
}
else if sender.tag == 16
{
if operation == 12
{
label.text = String(previousNumber / numberOnScreen)
}
else if operation == 13
{
label.text = String(previousNumber * numberOnScreen)
}
else if operation == 14
{
label.text = String(previousNumber - numberOnScreen)
}
else if operation == 15
{
label.text = String(previousNumber + numberOnScreen)
}
}
else if sender.tag == 11
{
label.text = ""
previousNumber = 0;
numberOnScreen = 0;
operation = 0;
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
Add this #IBAction to your code and hook it to your . button.
If the user presses . before any numbers, the display will be set to 0..
If there are numbers in the display, then . will be appended to the display if there isn't already a decimal point in the number.
Finally, the numberOnScreen will be updated.
#IBAction func decimal(_ sender: UIButton) {
if preformingMath || label.text!.isEmpty
{
label.text = "0."
preformingMath = false
}
else
{
if !label.text!.contains(".") {
label.text = label.text! + "."
}
}
numberOnScreen = Double(label.text!)!
}

Multiplying, subtracting and dividing binary numbers give wrong answers

I'm making a binary calculator app.
No buildtime issues but in the app only adding binary numbers give the right answer, multiplying, subtracting and dividing don't.
Dividing - every answer = 1 (1010-0001 = 1; 10101010-1010 = 1)
Multiplying - every answer is wrong, (11111 x 101010 = 1111000001, should be 10100010110)
Subtracting - every answer = 0 ( 1010-0001 = 0; 1010101-0001 = 0)
I tried making the code more explanatory and it worked in the playground (ending with print() ) but when I changed the apps code, the answers were the same.
var numberOnScreen:Int = 0;
var previousNumber:Int = 0;
var doingMath = false
var operation = 0;
var decimal = 0;
var decimal1 = 0;
var binary:String = ""
var binary1:String = ""
#IBOutlet weak var label: UILabel!
#IBAction func Numbers(_ sender: UIButton) {
if doingMath == true
{
label.text = String(sender.tag-1)
numberOnScreen = Int(label.text!)!
doingMath = false
}
else
{
label.text = label.text! + String(sender.tag-1)
numberOnScreen = Int(label.text!)!
}
}
#IBAction func buttons(_ sender: UIButton) {
if label.text != "" && sender.tag != 6 && sender.tag != 8
{
previousNumber = Int(label.text!)!
binary = "\(previousNumber)"
decimal = Int(binary, radix: 2)!
binary1 = "\(numberOnScreen)"
decimal1 = Int(binary1, radix: 2)!
operation = sender.tag
doingMath = true;
}
else if sender.tag == 8
{
if operation == 3 //adding
{
label.text = String((decimal + decimal1), radix: 2)
}
else if operation == 4 //subtracting
{
label.text = String((decimal - decimal1), radix: 2)
}
else if operation == 5 //multiplying
{
label.text = String((decimal * decimal1), radix: 2)
}
else if operation == 7 //dividing
{
label.text = String((decimal / decimal1), radix: 2)
}

Can't make calculator app in Swift get more than one digit?

So this is the class for my Operation:
class Calculation {
var currentNumber: String = ""
var resultNumber = Int()
var operationInput = String()
func operationIdentifier() {
if operationInput == "=" {
resultNumber = Int(currentNumber)!
print("\(resultNumber)")
} else if operationInput == "+" {
resultNumber += Int(currentNumber)!
print("\(resultNumber)")
} else if operationInput == "-" {
resultNumber -= Int(currentNumber)!
print("\(resultNumber)")
} else if operationInput == "*" {
resultNumber *= Int(currentNumber)!
print("\(resultNumber)")
} else if operationInput == "/" {
resultNumber /= Int(currentNumber)!
print("\(resultNumber)")
} else {
print("Operation does not exist.")
}
print("\(resultNumber)")
}
And this is where I get this button to get the title for numbers:
#IBAction func numberPressed(_ sender: UIButton) {
calculation.currentNumber = (sender.titleLabel?.text!)!
calculation.currentNumber.append(<#T##other: String##String#>)
//calculation.currentNumber.append((sender.titleLabel?.text)!) This is how I use it to append.
calculation.operationIdentifier()
resultTextField.text = "\(calculation.currentNumber)"
}
The append command is for strings as showed in the code section which I use to add to the end of the previous number, and the result is always a double of some Int e.g : If you press 5, it returns 55.
First of all, you are overwriting value here: calculation.currentNumber = (sender.titleLabel?.text!)!. Second, you will need to clear a current number after pressing.
Here is my concept for you(your edited code), you can try it in Playground.
enum Operator: String {
case plus = "+"
case minus = "-"
case multiply = "*"
case divide = "/"
case equal = "="
}
class Calculation {
var currentNumber: String = ""
var resultNumber = Int()
var operationInput = String()
func recalculate() {
if resultNumber == 0 {
resultNumber = Int(currentNumber) ?? 0
return
}
guard let sign = Operator(rawValue: operationInput), let number = Int(currentNumber) else { return }
switch sign {
case .plus: resultNumber += number
case .minus: resultNumber -= number
case .divide: resultNumber /= number
case .multiply: resultNumber *= number
case .equal: resultNumber = number
}
}
func operatorPressed(_ op: Operator) {
recalculate()
operationInput = op.rawValue
currentNumber = ""
print(resultNumber)
}
func numberPressed(_ number: String) {
currentNumber.append(number)
}
}
let c = Calculation()
c.numberPressed("5")
c.numberPressed("5")
c.operatorPressed(.plus)
c.numberPressed("5")
c.operatorPressed(.multiply)
c.numberPressed("5")
c.operatorPressed(.equal)
c.operatorPressed(.plus)
c.numberPressed("5")
c.operatorPressed(.equal)
In numberPressed you are setting currentNumber in from the label text and then appending the same value to it again. It should be something like:
#IBAction func numberPressed(_ sender: UIButton) {
guard let label = sender.titleLabel, let numberString = label.text else{
return
}
calculation.currentNumber.append(numberString)
print("currentNumber = \(calculation.currentNumber)")
}
Also, why do you call calculation.operationIdentifier() in numberPressed? Wouldn't that go in an operatorPressed method?

Swift Calculator works perfectly but not when preforming a fresh operation

I have been spending the day today getting familiar with swift and I decided to try to build a calculator. I have the entire thing working except for one issue:
1 + 1 will return 2 to the label (this is fine)
But when I attempt to type a new number, example 1, the string gets appended to 21 instead of clearing the label and placing a singular 1
This occurs because I wanted to add the option for the operators to keep adding ex:
1 + 1 returns 2 then the user types + 3 to get a result of 5
The only issue is I dont know how to clear the label only when a new number is being entered after the equal sign is pressed
Here is the code of the view controller Hopefully I do not have to think of a completely different approach.
import UIKit
class ViewController: UIViewController {
var num1 = ""
var num2 = ""
var finalString = ""
var isFirstNumber = true
var hasFinalString = false
var isClear = true
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBOutlet weak var LBLOutput: UILabel!
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func btrNumberClick(_ sender: UIButton) {
if isClear {
LBLOutput.text = ""
isClear = false
}
let currentText = LBLOutput.text!
let textLabel = sender.titleLabel?.text
if let text = textLabel {
switch text {
case "+", "x", "/", "-","%":
if hasFinalString {
return
}
finalString = text
isFirstNumber = false
hasFinalString = true
LBLOutput.text = "\(currentText) \(finalString) "
break
case "=":
isFirstNumber = true
hasFinalString = false
isClear = true
let result = calculate()
LBLOutput.text = "\(result)"
num1 = "\(result)"
break
default:
if isFirstNumber {
num1 = "\(num1)\(text)"
} else {
num2 = "\(num2)\(text)"
}
LBLOutput.text = "\(currentText)\(text)"
break;
}
}
}
func calculate() -> Double {
let firstNumber = Double(num1)!
let secondNumber = Double(num2)!
num1 = ""
num2 = ""
isClear = false
switch finalString {
case "+":
return firstNumber + secondNumber
case "-":
return firstNumber - secondNumber
case "x":
return firstNumber * secondNumber
case "/":
return firstNumber / secondNumber
case "%":
return (firstNumber * 100) / secondNumber
default:
return 0
}
}
#IBAction func clearTheLabel(_ sender: Any) {
num1 = ""
num2 = ""
LBLOutput.text = "0"
isClear = true
}
}
Why won't this work?
default:
if isFirstNumber {
LBLOutput.text = ""
num1 = "\(num1)\(text)"
LBLOutput.text = num1
} else {
num2 = "\(num2)\(text)"
LBLOutput.text = "\(currentText)\(text)"
}
break;
}
If isFirstNumber is true only after = is pressed then clearing then seems right. I hope I'm understanding your problem.
BTW: The Stanford course with the calculator example hooks all the buttons up to one IBAction as you've done. I think the switch statement is very clear and made for examples like this.