How I Made Gradulator

Wow. Its submitted. All the work is done. Now for a quick code review of some key stuff I learnt during Gradulator.


Nested Functions

I’m almost certain we all use this in our projects, but Gradulator took it to the next level. I set out with the goal of writing as little code as possible, considering Gradulator V1 and V2 used crazy amounts of code to draw graphs and the like, I needed a smarter solution. Here are some of the functions I created to help me make it easier.

Full disclosure, some of these are from Stack Overflow but I honestly can’t remember which, hat tip to anyone who I used the code of!

This one is really useful for all projects.

// MARK: -
/// Obtain a uiColor from a Hex value.
/// You might need to add a '0x' to the beginning of your Hex value.
/// Pass in a value of type UInt32
func uicolorFromHex(rgbValue:UInt32)->UIColor{
    let red = CGFloat((rgbValue & 0xFF0000) >> 16)/256.0
    let green = CGFloat((rgbValue & 0xFF00) >> 8)/256.0
    let blue = CGFloat(rgbValue & 0xFF)/256.0
    return UIColor(red:red, green:green, blue:blue, alpha:1.0)
}

Basically a must have for any project using custom textfields.

// MARK: -
/// Add padding to the beginning of a textfield.
/// paddingAmount must be an integer.
func addPaddingToTextfield (paddingAmount: Int, textfield: UITextField) {
    let paddingHeight = UIView(frame: CGRect(x: 0, y: 0, width: paddingAmount, height: Int(textfield.frame.height)))
    textfield.leftView = paddingHeight
    textfield.leftViewMode = UITextFieldViewMode.always
}

I used this function -alot- of times.

// MARK: -
/// Calculates how much to score on next test.
/// Can return a value greater than 100 or a negative value.
/// For purposes of informing the user if obtaining goal is not possible, greater than 100 will be handled in viewcontroller.
func returnScoreNextTest (underSubject: String, percentage: Int, weightage: Double) -> Int {
    // Obtain an individual ResultData object for the subject in question.
    let subjectData = resultsList.first(where: { $0.subject == underSubject })
    // If there is data in subjectData
    if !(subjectData == nil) {
        var resultsArray = subjectData?.results
        resultsArray?.append(percentage)
        var weightagesArray = subjectData?.weightage
        weightagesArray?.append(weightage)
        var WeightagesTotalArray: [Double] = []
        for (perc, weight) in zip(resultsArray!, weightagesArray!) {           WeightagesTotalArray.append(calculateWeightage(percentage: perc, weightage: weight))
        }
        if !(subjectData?.goal == nil) {
            let markToScoreNextTest = ( ( ( Double((subjectData?.goal)!) - (WeightagesTotalArray.reduce(0, +)) ) / returnRemainingWeightage(ofSubject: underSubject) ) * 100 )
            return Int(markToScoreNextTest)
        }
        // No goal set, defaulting to a default goal of 75% or A1
        else { return 75 }
    }
    // The expected subjectData doesn't exist, likely first time creation, return 75.
    else { return 75 }
}

Leave a Reply

Your email address will not be published. Required fields are marked *