C.Bodger C.Bodger - 23 days ago 7
Swift Question

EXC_BAD_INSTRUCTION error when attempting to print a function in Swift Playground

I'm currently working on a University Maths project that requires me to create an application in relation to mortgages. I'm attempting to write Swift code for calculating the principal amounts and interest paid in each month of the mortgage.

The code I have written is as follows (worth mentioning i'm very new to coding with a little experience with Python, this is all self taught so any critique is welcome!):

// Declare all variables
// y = periodic interest rate
// n = time left of repayment period (months)

let y = [Float](arrayLiteral: 0.02/12,0.03/12,0.04/12,0.05/12)
let n = [Float](arrayLiteral: 240,180,120,60)

var x = [Float]()
var interest = [Float]()
var T_1 = [Int]()

// Create Array from 0 to 240
for a in 0...240 {
T_1.append(a)
}

// Create Array of all 240 interest values

for a in 0...239 {
if a < 60 {
interest.append(y[0])
var repay = n[0]
x.append(repay)
}
else if a < 120 {
interest.append(y[1])
var repay = n[1]
x.append(repay)
}
else if a < 180 {
interest.append(y[2])
var repay = n[2]
x.append(repay)
}
else {
interest.append(y[3])
var repay = n[3]
x.append(repay)
}
}
print("Interest array:",interest)

// Calculate Each months Principal paid and Interest Paid

func variablerate(P: inout Float) -> [Float] {
var principal = [Float]()
var i_paid = [Float]()
var repayments = [Float]()
var R = Float(0)
let temporaryP = P
i_paid.append(0)

for a in 0...240 {
if (a>0) && (a<240) && (interest[a-1] == interest[a]) {
let ip = P*(1+interest[a-1])-P
i_paid.append(i_paid[a-1] + ip)
P = (1+interest[a-1])*temporaryP
P = P-R
let h = interest[a]
R = (P*h)/(1-pow(1+h,Float(interest.count-a)))
repayments.append(R)
principal.append(round(100*P)/100)
}
else if a==240 || a==241 {
P = P - R
principal.append(round(100*P)/100)
let ip = P*(1+interest[a-1])-P
i_paid.append(i_paid[a-1] + ip)
let h = interest[a-1]
P = P*(1+h)
}
else {
P = P - R
let h = interest[a]
R = (P*h)/(1-pow(1+h,Float(interest.count-a)))
repayments.append(R)
principal.append(round(100*P)/100)
let ip = P*(1+interest[a])-P
i_paid.append(i_paid[a-1] + ip)
P = P*(1+h)
}
}
return i_paid
return principal

}
var z = Float(100000)

print(variablerate(P: &z)) //This is where the error appears


The error given is:


error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP,subcode=0x0).


Any help or guidance on this issue would be massively appreciated!

Answer

Reason for crash is Index out of range.

You are getting Index out of range exception because in code you are running a loop from 0 to 240 and from the local variable a subtracting 1 so in first iteration a will contain 0 and subtracting 1 from 0 will give negative index.

Here is mistake

for a in 0...240 {
if (a>0) && (a<240) && (interest[a-1] == interest[a])

Below code is with correction

// Declare all variables
// y = periodic interest rate
// n = time left of repayment period (months)

let y = [Float](arrayLiteral: 0.02/12,0.03/12,0.04/12,0.05/12)
let n = [Float](arrayLiteral: 240,180,120,60)

var x = [Float]()
var interest = [Float]()
var T_1 = [Int]()

// Create Array from 0 to 240
for a in 0...240 {
    T_1.append(a)
}

// Create Array of all 240 interest values

for a in 0...239 {
    if a < 60 {
        interest.append(y[0])
        var repay = n[0]
        x.append(repay)
    }
    else if a < 120 {
        interest.append(y[1])
        var repay = n[1]
        x.append(repay)
    }
    else if a < 180 {
        interest.append(y[2])
        var repay = n[2]
        x.append(repay)
    }
    else {
        interest.append(y[3])
        var repay = n[3]
        x.append(repay)
    }
}
print("Interest array:",interest)

// Calculate Each months Principal paid and Interest Paid

func variablerate(P: inout Float) -> [Float] {
    var principal = [Float]()
    var i_paid = [Float]()
    var repayments = [Float]()
    var R = Float(0)
    let temporaryP = P
    i_paid.append(0)

    for a in 1...240 { // Code corrected now loop go from 1 to 240 
        if (a>0) && (a<240) && (interest[a-1] == interest[a]) {
            let ip = P*(1+interest[a-1])-P
            i_paid.append(i_paid[a-1] + ip)
            P = (1+interest[a-1])*temporaryP
            P = P-R
            let h = interest[a]
            R = (P*h)/(1-pow(1+h,Float(interest.count-a)))
            repayments.append(R)
            principal.append(round(100*P)/100)
        }
        else if a == 240 || a == 241 {
            P = P - R
            principal.append(round(100*P)/100)
            let ip = P*(1+interest[a-1])-P
            i_paid.append(i_paid[a-1] + ip)
            let h = interest[a-1]
            P = P*(1+h)
        }
        else {
            P = P - R
            let h = interest[a]
            R = (P*h)/(1-pow(1+h,Float(interest.count-a)))
            repayments.append(R)
            principal.append(round(100*P)/100)
            let ip = P*(1+interest[a])-P
            i_paid.append(i_paid[a-1] + ip)
            P = P*(1+h)
        }
    }
    //return i_paid
    return principal

}
var z = Float(100000)

print("\(variablerate(P: &z))")