2

Type error :unsupported operand type(s) for +: 'int' and 'QVariant' Traceback (most recent call last): ,line 260, in rac s=s+ar

Code :

def rac():
    cur_prov = self.dlg.comboBox_2.currentText()

    #calculate the amount of population in all provinces
    prov = layers[1].layer()
    s = 0
    for c in prov.getFeatures(): 
        st = st + c.attributes()[2]
   
    #calculate the amount of park's area
    park = layers[0].layer()   
    s = 0
    for p in park.getFeatures(): 
        ar = p.attributes()[6]
        s = s + ar
    rac = s / st
    self.dlg.textBrowser_2.setText(str(rac))
1
  • Voting to reopen because this question is likely to help future visitors, given that a good answer is here. The question itself could and should be improved. Jan 12, 2022 at 6:53

2 Answers 2

8

You should skip the NULL values.

for p in park.getFeatures(): 
    ar = p.attributes()[6]
    
    if ar != NULL:
        s = s + ar

rac = s / st
5
  • I got this error: line 259, in rac ar=float(p.attributes()[6]) TypeError: float() argument must be a string or a number, not 'QVariant' Jan 9, 2022 at 23:48
  • 1
    Is there any NULL value in the column 6? Jan 9, 2022 at 23:52
  • Yes there are many NULL values Jan 9, 2022 at 23:54
  • 1
    Then, you should skip the NULL values. Jan 10, 2022 at 0:37
  • Thank you it works . The problem was in a line of the field area who has a string value who cannot be converted . Thank you for the help. Jan 10, 2022 at 10:18
6

There are many things you can change about your code, but first your question.

The solution that Kadir proposes is very practical, it works for me in the console but not in the plugin, so I present you other alternatives.

Evaluate if it is a QVariant

Generally when you query the attributes of a field, it returns the data type of the field, either int, float or string, unless it is empty, so it returns an empty QVariant.

You can simply test to see if it is a QVariant

for p in park.getFeatures():
   ar = p.attributes()[6]
   if type(ar)!= QVariant:
        s = s + ar

Another option is the opposite, to evaluate if it gives a numerical value, but there are two conditionals:

for p in park.getFeatures():
   ar = p.attributes()[6]
   if type(ar)==int or type(ar)==float:
        s = s + ar

Other aspects

  • You can consult the QgsFeature as a dictionary:
for p in park.getFeatures():
   ar = p[name of the field]
   if type(ar)!= QVariant:
        s = s + ar
  • Compressing lists can make your code shorter and faster
lf=park.getFeatures()
list_values=[p[name of the field] for ar in lf   if type(ar)!= QVariant]
  • For optimal performance in attribute queries you should apply QgsFeatureRequest:

For example, configure the request so that it does not return geometries, using less memory and faster.

request = QgsFeatureRequest()
request.setFlags(QgsFeatureRequest.NoGeometry )
lf=park.getFeatures(request)
list_values=[p[name of the field] for ar in lf   if type(ar)!= QVariant]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.