How to find sum of values in Variables

Hello:


I am fetching records from CoreData in which there is an item called QValue. qValue is defined as a String but it has a number.

qValue has different values (1000,1450, 1830, etc.)


Each time the user calls for a record it returns a qValue in the data set.


I want to Sum all the qValues returned in a session.


I have tried many different ways but without success: for example (The error here is "Ambiguous reference to member '+' ")


if let record = item.value(forKey: "qValue") as? String {
               qValueItem.append(record)
               groupScoreLabel.stringValue = qValueItem
                print ("qValue is \(qValueItem)")
                }

            if (oneRadioButton.state == NSControl.StateValue(rawValue: 1))
                && distractor1 == answerItem {
                let arr = [qValueItem]
                let totalSum = arr.reduce(0, +) // Ambiguous reference to member '+'

                print("totalSum \(totalSum)")


I want an increasing value with each record call which will be the "totalSum"


Any help with implementing will be appreciated.

Answered by Claude31 in 400047022

OK, add a test before line 23:


    print ("qValueNumbers before radiobuttons", qValueNumbers)


Tell what it gives


But most likely, the print you get is the one line 67.


Here, totalSum has not been recomputed.


So, once again, it is likely that all the tests fail


if oneRadioButton.state == .on && distractor1 == answerItem {

and the others as well

-> You need to understand why.


Add just before line 67:

           let totalSum = qValueNumbers.reduce(0, +)

That should give you 7700


Note: I don't understand what those tests as

if oneRadioButton.state == .on && distractor1 == answerItem {

are used for: you do the same thing in all the cases !

You try to add Strings, which is not possible, unless you define an extension to String to do it (pretty easy). But that will concatenate Strings, not sum their values.


Otherwise, append the values themselves; if they are all Int, very easy (if I understood correctly your code, in particular, you don't show how you loop over items):


var qValueNumbers = [Int]()

// You probably loop over items somewhere here ?????

if let record = item.value(forKey: "qValue") as? String, let theValue = Int(record) {
               qValueItem.append(record)
               groupScoreLabel.stringValue = qValueItem
                print ("qValue is \(qValueItem)")
               qValueNumbers.append(theValue)     
                }
// Probably end of loop here ?????

            if (oneRadioButton.state == NSControl.StateValue(rawValue: 1))
                && distractor1 == answerItem {
                // That has no meaning: an array with a single item (even an array of String), what would you sum up
                // ???   let arr = [qValueItem]
                let totalSum = qValueNumbers.reduce(0, +)   // Now, you sum up all numbers

                print("totalSum \(totalSum)")



Also, when you ask question, show the result of the logs, that does help figure out what happens.

print ("qValue is \(qValueItem)")

Hello Claude 31:


This code is giving the result below for 3 calls to func calcGroupScore:


@IBActionfunc calcGroupScore(_ sender: NSButton) {
       
       
        answerItem = ""
        var qValueNumbers = [Int]()
        var qValueMultiplier = [Int]()
       
        for item in results {
            if let record = item.value(forKey: "answer") as? String {
                answerItem.append(record)
                answerLabel.stringValue = answerItem
                print ("Answer is \(answerItem)")
            }
            // You probably loop over items somewhere here ?????
             
            if let record = item.value(forKey: "qValue") as? String, let theValue = Int(record) {
                           qValueItem.append(record)
                           groupScoreLabel.stringValue = qValueItem
                            print ("qValue is \(theValue)")
                           qValueNumbers.append(theValue)
                            print (qValueNumbers)
                            }
           
           
            // Probably end of loop here ?????
             
                        if (oneRadioButton.state == NSControl.StateValue(rawValue: 1))
                            && distractor1 == answerItem {
                            // That has no meaning: an array with a single item (even an array of String), what would you sum up
                            // ???   let arr = [qValueItem]
                            let totalSum = qValueNumbers.reduce(0, +)   // Now, you sum up all numbers
             
                            print("totalSum \(totalSum)")
                        }
        else {
           
            if (twoRadioButton.state == NSControl.StateValue(rawValue: 1))
                && distractor2 == answerItem {
                let totalSum = qValueNumbers.reduce(0, +)
                    print ("Result is \(totalSum)")
                print ("Group score is \(totalSum)")
            }
               
        else {
               
            if (threeRadioButton.state == NSControl.StateValue(rawValue: 1))
                    && distractor3 == answer {
                  let totalSum = qValueNumbers.reduce(0, +)
                                      print ("Result is \(totalSum)")
                                  print ("Group score is \(totalSum)")
                }
                   
        else {
                   
            if (fourRadioButton.state == NSControl.StateValue(rawValue: 1))
                    && distractor4 == answer {
                  let totalSum = qValueNumbers.reduce(0, +)
                                      print ("Result is \(totalSum)")
                                  print ("Group score is \(totalSum)")
            }
        else {
            if (fiveRadioButton.state == NSControl.StateValue(rawValue: 1))
                    && distractor5 == answer {
                  let totalSum = qValueNumbers.reduce(0, +)
                                      print ("Result is \(totalSum)")
                                  print ("Group score is \(totalSum)")
                            }
                        }
//                      var qValueMultiplier = result
                    }
                }
            }
           
        }

    }


Answer is 3

qValue is 3850

[3850]

Result is 3850

Group score is 3850


Answer is 4

qValue is 3850

[3850]

Result is 3850

Group score is 3850


Answer is 1

qValue is 3850

[3850]


What I want is to sum the three qValue(s): 3850, 3850, 3850. To do this I have to be able to save each value in a variable then add the value to waht is in that variable each time that I make a new call. I do this in Oracle very simple but in swift it seem so complicated.

I don't understand the ouput of line 21 only giving a single item in qValueNumbers.


Do these logs correspond to a single tap on the button or on 3 consecutive taps ?

Answer is 3

qValue is 3850

[3850]

Result is 3850

Group score is 3850


Answer is 4

qValue is 3850

[3850]

Result is 3850

Group score is 3850


Answer is 1

qValue is 3850

[3850]


This is a VERY important question.

If 3 taps on button, then you need to move the declaration oif

        var qValueNumbers = [Int]()
        var qValueMultiplier = [Int]()

out of the IBAction


Could you complete lines 19 to 21 with:


                            print ("qValue is \(theValue)")
                            print ("qValueNumbers before append", qValueNumbers, "for item", item)
                            qValueNumbers.append(theValue)
                            print ("qValueNumbers after append", qValueNumbers)


There is a problem in the loop control.

Here is a proper loop:


@IBAction func calcGroupScore(_ sender: NSButton) {
        
        answerItem = ""
        var qValueNumbers = [Int]()
        var qValueMultiplier = [Int]()
        
        for item in results {
            if let record = item.value(forKey: "answer") as? String {
                answerItem.append(record)
                answerLabel.stringValue = answerItem
                print ("Answer is \(answerItem)")
            }
              
            if let record = item.value(forKey: "qValue") as? String, let theValue = Int(record) {
                qValueItem.append(record)
                groupScoreLabel.stringValue = qValueItem
                print ("qValue is \(theValue)")
                qValueNumbers.append(theValue)
                print (qValueNumbers)
            }
           
    }  // END LOOP HERE

    if (oneRadioButton.state == NSControl.StateValue(rawValue: 1))
        && distractor1 == answerItem {
        // That has no meaning: an array with a single item (even an array of String), what would you sum up
        // ???   let arr = [qValueItem]
        let totalSum = qValueNumbers.reduce(0, +)   // Now, you sum up all numbers
       
        print("totalSum \(totalSum)")
    } else {
        if (twoRadioButton.state == NSControl.StateValue(rawValue: 1))
            && distractor2 == answerItem {
            let totalSum = qValueNumbers.reduce(0, +)
            print ("Result is \(totalSum)")
            print ("Group score is \(totalSum)")
        } else {
            if (threeRadioButton.state == NSControl.StateValue(rawValue: 1))
                && distractor3 == answer {
                let totalSum = qValueNumbers.reduce(0, +)
                print ("Result is \(totalSum)")
                print ("Group score is \(totalSum)")
            } else {
                if (fourRadioButton.state == NSControl.StateValue(rawValue: 1))
                    && distractor4 == answer {
                    let totalSum = qValueNumbers.reduce(0, +)
                    print ("Result is \(totalSum)")
                    print ("Group score is \(totalSum)")
                } else {
                    if (fiveRadioButton.state == NSControl.StateValue(rawValue: 1))
                        && distractor5 == answer {
                        let totalSum = qValueNumbers.reduce(0, +)
                        print ("Result is \(totalSum)")
                        print ("Group score is \(totalSum)")
                    }
                }
                //  var qValueMultiplier = result
            }
        }
    }
 
}



Note: you could replace those tests:

if (oneRadioButton.state == NSControl.StateValue(rawValue: 1)) && distractor1 == answerItem {

which a simpler:

if oneRadioButton.state == .on && distractor1 == answerItem {

Hello Claude:


print("totalSum \(totalSum)")


This print statement is not being read. Can't explain why. On solving this I will submit the result for the corrected code.

It does not print in which version of code ?

- the one I sent on Dec 26, 2019 11:28 PM

- or your version Dec 26, 2019 6:27 PM


In my code, add a test on line 23


print("oneRadioButton.state", oneRadioButton.state, "distractor1", distractor1, "answerItem"; answerItem, "equal", distractor1 == answerItem)

I suspect the test fails

OK. Solved the Print problem.

But doesn't sum the array of [qValueNumbers]


qValueNumbers before append [0, 3850] for item <TempSCQ: 0x600002128f50> (entity: TempSCQ; id: 0x19ef073893d5deab


qValueNumbers after append [0, 3850, 3850]


Total is 0

Well, I am not sure what code I look at.


Could you gine an email to exchange files ?

Current Code is:


var qValueNumbers = [0]
    var totalSum = Int()
    @IBAction func calcGroupScore(_ sender: NSButton) {
        answerItem = ""
       
            for item in results {
                if let record = item.value(forKey: "answer") as? String {
                    answerItem.append(record)
                    answerLabel.stringValue = answerItem
                    print ("Answer is \(answerItem)")
                }
                   
                if let record = item.value(forKey: "qValue") as? String, let theValue = Int(record) {
                   groupScoreLabel.stringValue = qValueItem
                    print ("qValue is \(theValue)")
                    print ("qValueNumbers before append", qValueNumbers, "for item", item)
                    qValueNumbers.append(theValue)
                    print ("qValueNumbers after append", qValueNumbers)
                   
                }
                
        }
            if oneRadioButton.state == .on && distractor1 == answerItem {
            let totalSum = qValueNumbers.reduce(0, { x, y in
                x + y
            })   // Now, you sum up all numbers
                print("Total is\(totalSum)")
                        }
        else
           
            if twoRadioButton.state == .on && distractor1 == answerItem {
                let totalSum = qValueNumbers.reduce(0, { x, y in
                    x + y
                })
                    print("Total is\(totalSum)")
                print ("Group score is \(totalSum)")
            }
               
        else
               
            if threeRadioButton.state == .on && distractor1 == answerItem {
                  let totalSum = qValueNumbers.reduce(0, { x, y in
                      x + y
                  })
                print("Total is\(totalSum)")
                print ("Group score is \(totalSum)")
                }
                   
        else
                   
            if fourRadioButton.state == .on && distractor1 == answerItem {
                  let totalSum = qValueNumbers.reduce(0, { x, y in
                      x + y
                  })
                print("Total is\(totalSum)")
                print ("Group score is \(totalSum)")
            }
        else
            if fiveRadioButton.state == .on && distractor1 == answerItem {
                  let totalSum = qValueNumbers.reduce(0, { x, y in
                      x + y
                  })
                  print("Total is\(totalSum)")
//                  print ("Group score is \(totalSum)")
//                  print ("Group score is \(totalSum)")
                            }
        print("Total is \(totalSum)")
                        }

                    }
Accepted Answer

OK, add a test before line 23:


    print ("qValueNumbers before radiobuttons", qValueNumbers)


Tell what it gives


But most likely, the print you get is the one line 67.


Here, totalSum has not been recomputed.


So, once again, it is likely that all the tests fail


if oneRadioButton.state == .on && distractor1 == answerItem {

and the others as well

-> You need to understand why.


Add just before line 67:

           let totalSum = qValueNumbers.reduce(0, +)

That should give you 7700


Note: I don't understand what those tests as

if oneRadioButton.state == .on && distractor1 == answerItem {

are used for: you do the same thing in all the cases !

Hello Claude31:


That change produces the following Log:


qValue is 3850

qValueNumbers before append [0, 3850] for item <TempSCQ: 0x60000213e990> (entity: TempSCQ; id: 0x92b6a91c2988268d <x-

qValueNumbers after append [0, 3850, 3850]

qValueNumbers before radiobuttons [0, 3850, 3850]

Total is 7700

Group score is 7700


That change seems to have done the trick!!


This code is to check which radio button is checked and to get the score for that item. I'm sure there may be a better way to code that.

if oneRadioButton.state == .on && distractor1 == answerItem {

OK, you can finally close the thread. You'll open a new one for other question if needed.


To improve, you should note :

- that the test

distractor1 == answerItem

could be an initial test for all 5 buttons

- more important, need to understand why younever get into the 5 cases of buttons

To find, add before line 23:

print("distractor1", distractor1 , "answerItem", answerItem)

Thank You.

Really appreciate your expertise that is phenominal!

How to find sum of values in Variables
 
 
Q