Home > Software design >  in swap array[i] = array[j] TypeError: 'tuple' object does not support item assignment
in swap array[i] = array[j] TypeError: 'tuple' object does not support item assignment

Time:04-09

the code is supposed to show a video frame using the laptop webcam as a source, all is working fine, so after it shows the colors calibration window , it has to show next is the video frame,

I know that this "Tuple" issue is related to lists initialization, I tried some modifications based on stackoverflow, but unfortunately,I couldn't recognize what is it exactly.

Error : File ~\Downloads\Gesture-Controlled-Mouse-master\Gesture-Controlled-Mouse-master\main - Copy.py:39 in swap array[i] = array[j] TypeError: 'tuple' object does not support item assignment .

Here is the code section that has the issue :

def swap( array, i, j):
temp = array[i]
array[i] = array[j]
array[j] = temp

here is the main code :

import cv2
import numpy as np
import pyautogui
import time

blue_range = np.array([[88,78,20],[128,255,255]])
yellow_range = np.array([[21,70,80],[61,255,255]])
red_range = np.array([[158,85,72],[180 ,255,255]])
# Prior initialization of all centers for safety
b_cen, y_pos, r_cen = [240,320],[240,320],[240,320]
cursor = [960,540]
# Area ranges for contours of different colours to be detected
r_area = [100,1700]
b_area = [100,1700]
y_area = [100,1700]
# Rectangular kernal for eroding and dilating the mask for primary noise removal 
kernel = np.ones((7,7),np.uint8)
# Status variables defined globally
perform = False
# 'nothing' function is useful when creating trackbars
# It is passed as last arguement in the cv2.createTrackbar() function
def nothing(x):
    pass
def swap( array, i, j):
    array = list(array)
    temp = array[i]
    array[i] = array[j]
    array[j] = temp

The whole code : Main code

some assistance would guide me , Output with error Thank you in advance

CodePudding user response:

Now I understand the problem:

You got the error because you tried to swap elements of tuple. Which is an unchangeable variable type. So you would get an error saying you cannot alter a tuple.

Next you decided to change the type of the tuple to list. Which would work. The only problem is it will not.

One can categorize python object in two:

Immutable and Mutable.

Immutable

Immutable objects are kind of objects you can't alter/change/update. Such as str, int, tuple.

Mutable

Mutable objects are kind of objects you can alter/change/update. Such as list, dict.

When an object is passed to a function:

  1. The object would be copied to function, if the object is immutable
  2. A reference to object would be given if the object is mutable:

Example:

lst = [1, 2, 3, 4]

def alter_mutable(obj):
    del obj[0]

print(lst)
alter_mutable(lst)
print(lst)

Result:

[1, 2, 3, 4]
[2, 3, 4]

See the lst changed outside the function, because a reference was given to function and altering it in the function changed it everywhere.

num = 2

def alter_immutable(obj):
    obj  = 1

print(num)
alter_immutable(num)
print(num)

Result:

2
2

Here num did not change. Because a copy of it was given to function and change it inside the function did not effect it outside.

The tuple you were given to the function will be copied and changing it to a list, altering it is not effecting the data outside the function.

What can be done?

You can return the object and use it:

def swap( array, i, j):
    array = list(array)
    array[i], array[j] = array[j], array[i]
    return tuple(array)

Since we changed the function, the usage must change as well.

Usage:

contour = swap(contour, i, j)

CodePudding user response:

I think I figured out the problem.

Firstly, when calling the function: cv2.findContours() to assign to contour, the return value of the function is a Tuple, thus trying to swap elements creates an error.

Secondly, If you want to swap the values anyway there are several options:

  • copying tuple into a list and changing it
  • casting tuple to list
  • and probably more

And, there's a better way to swap as described in the comments:

def swap(array, i, j):
    array[i], array[j] = array[j], array[i]
    return array

This is a valid way to swap between variables

  • Related