42889 Application Development in the iOS Environment iOS Application Development -Simple Calculotor
Create a macOS command-line tool acting as a simple calculator. It performs arithmetic operations on integer numbers provided as command-line arguments. The calculator follows arithmetic rules and handles various operators: +, -, x, /, %. Proper error handling and input validation are ensured.
Main.swift:
import Foundation
//receive user input
var args = ProcessInfo.processInfo.arguments
args.removeFirst() // remove the name of the program
//checking if input is math equations or single number
guard args.count>=3 else{//basic math equations need at least 3 factors to run.
if args.count == 1 {
if let tmp = Int(args[0]){
print(tmp);// According to the test, even no calculation, I should also print out the single number
}
}
exit(2);//no need to do the calculation
}
//Using identifier to identify the index of those prior operators.
let userIdentifier = identifier(input: args);
var priorityLocation: [Int] = userIdentifier.identify();// All prior operators' index are stored into Int array.
//Do the prior calculation first
if priorityLocation.count != 0 {//Some cases have no prior operator inside the equation
let PriorCalculation=priorCalculation(args: args, priorityLocation: priorityLocation );
args = PriorCalculation.priorCalculationg();// args has only + or - operator to do.
}
if args.count != 1 {// Some cases have only '+' and '-' operator in equation.
let RegularCalculation = regularCalculation(args: args);
args = RegularCalculation.regularCalculating();
}
print(args[0]);//All the result will be put into first index of args, which is args[0].
Calculator.swift:
import Foundation
class Calculator {
/// For multi-step calculation, it's helpful to persist existing result
var currentResult = 0;
/// Perform Addition
///
/// - Author: Jacktator
/// - Parameters:
/// - no1: First number
/// - no2: Second number
/// - Returns: The addition result
///
/// - Warning: The result may yield Int overflow.
/// - SeeAlso: https://developer.apple.com/documentation/swift/int/2884663-addingreportingoverflow
func add(no1: Int, no2: Int) -> Int {
return no1 + no2;
}
func minus(no1: Int, no2: Int) -> Int {
return no1 - no2;
}
func times(no1: Int, no2: Int) -> Int {
return no1 * no2;
}
func divide(no1: Int, no2: Int) -> Int {
return no1 / no2;
}
func module(no1: Int, no2: Int) -> Int {
return no1 % no2;
}
}
//
class priorCalculation {
var args:[String];
var priorityLocation:[Int];
init (args:[String], priorityLocation:[Int]){
self.args = args;
self.priorityLocation = priorityLocation;
}
func priorCalculationg()->[String] {
let calculator = Calculator();
for i in 0...priorityLocation.count-1 {
switch args[priorityLocation[i]]{
case "x":
//check if the input can be trans into int or not
if let no1 = Int(args[priorityLocation[i]-1]), let no2 = Int(args[priorityLocation[i]+1]) {
//the current result will be stored in the front number.
args[priorityLocation[i]-1] = String(calculator.times(no1: no1, no2: no2));
//then delete the calculated operator and the rear number.
args.remove(at: priorityLocation[i]);
args.remove(at: priorityLocation[i]);
//Due to the array has reduce two data, the rest of the data in priorityLocation should also minus 2
for j in i...priorityLocation.count-1{
priorityLocation[j] -= 2;
}
}
else{
print("Input error");
exit(1);
}
case "*":
//check if the input can be trans into int or not
if let no1 = Int(args[priorityLocation[i]-1]), let no2 = Int(args[priorityLocation[i]+1]) {
//the current result will be stored in the front number.
args[priorityLocation[i]-1] = String(calculator.times(no1: no1, no2: no2));
//then delete the calculated operator and the rear number.
args.remove(at: priorityLocation[i]);
args.remove(at: priorityLocation[i]);
//Due to the array has reduce two data, the rest of the data in priorityLocation should also minus 2
for j in i...priorityLocation.count-1{
priorityLocation[j] -= 2;
}
}
else{
print("Input error");
exit(1);
}
case "/":
//check if the input can be trans into int or not
if let no1 = Int(args[priorityLocation[i]-1]), let no2 = Int(args[priorityLocation[i]+1]) {
if no2 != 0 {//check no2 is 0 or not
//the current result will be stored in the front number.
args[priorityLocation[i]-1] = String(calculator.divide(no1: no1, no2: no2));
//then delete the calculated operator and the rear number.
args.remove(at: priorityLocation[i]);
args.remove(at: priorityLocation[i]);
//Due to the array has reduce two data, the rest of the data in priorityLocation should also minus 2
for j in i...priorityLocation.count-1{
priorityLocation[j] -= 2;
}
}
else {
print("Divided by 0");
exit(1);
}
}
else{
print("Input error");
exit(1);
}
case "%":
//check if the input can be trans into int or not
if let no1 = Int(args[priorityLocation[i]-1]), let no2 = Int(args[priorityLocation[i]+1]) {
if no2 != 0 {//check no2 is 0 or not
//the current result will be stored in the front number.
args[priorityLocation[i]-1] = String(calculator.module(no1: no1, no2: no2));
//then delete the calculated operator and the rear number.
args.remove(at: priorityLocation[i]);
args.remove(at: priorityLocation[i]);
for j in i...priorityLocation.count-1{
priorityLocation[j] -= 2;
}
}
else {
print("Modded by 0");
exit(1);
}
}
else{
print("Input error");
exit(1);
}
default://if non-operator thing in the array, exit
print("Error occured");
exit(1);
break;
}
}
return args;
}
}
class regularCalculation {
var args:[String];
init (args:[String]) {
self.args = args;
}
func regularCalculating() -> [String] {
let calculator = Calculator();
for _ in 1...args.count/2 {
switch args[1] {
case "+":
//check if the input can be trans into int or not
if let no1 = Int(args[0]), let no2 = Int(args[2]) {
//the current result will be stored in the front number.
args[0] = String(calculator.add(no1: no1, no2: no2));
//then delete the calculated operator and the rear number.
args.remove(at: 1);
args.remove(at: 1);
}
else{
print("Input error");
exit(1);
}
case "-":
//check if the input can be trans into int or not
if let no1 = Int(args[0]), let no2 = Int(args[2]) {
//the current result will be stored in the front number.
args[0] = String(calculator.minus(no1: no1, no2: no2));
//then delete the calculated operator and the rear number.
args.remove(at: 1);
args.remove(at: 1);
}
else{
print("Input error");
exit(1);
}
default://if non-operator thing in the array, exit
print("Error occured");
exit(1);
break;
}
}
return args;
}
}
//This class will store the index of those prior operator
class identifier{
let input:[String];
init(input: [String]) {
self.input = input;
}
func identify() -> [Int] {
var tmp_number = 0;
var priorityLocation: [Int] = [];
for tmp in input{
if tmp == "/" || tmp == "%" || tmp == "x" || tmp == "*" {//if input[tmp_number] has contain prior operator, put the tmp_number into array.
priorityLocation.append(tmp_number);
}
tmp_number += 1 ;
}
return priorityLocation;//return the array contain all prior operators' index
}
}