TypeError: 'str' object is not callable-Python
Question: Define a function test_sort that takes a tuple containing a sort function
reference and a function description as a parameter and executes that sort
function with the data from the previous task. Track the comparisons for each
set of data, calculate the average number of comparisons for the list of
random lists.

The sort function reference just means that you can put a function definition
into a variable just like any other value, and then execute that function
variable. You can also pass a function definition as an argument to a another
function and then execute the resulting parameter as a function.

this is the code

    
    
    def test_sort(function_tuple, a_sorte, a_reverse, a_random):
        Number.comparisons = 0
        f = function_tuple[0]
       f(a_sorte)
        x = Number.comparisons
    
        Number.comparisons = 0
        f = function_tuple[0]
        f(a_reverse)
        y = Number.comparisons
    
        Number.comparisons = 0
        f = function_tuple[0]
        for i in range(len(a_random)):
            f(a_random[i])
        z = Number.comparisons
        print("{0}        {1}         {2}        {3}".format(
            function_tuple[1], x, y, z))
        return
    

the main:

    
    
    import copy
    
    from sorts_array import Sorts
    import functions
    SORTS = (
        ('Bubble Sort', Sorts.bubble_sort),
        ('Insertion Sort', Sorts.insertion_sort),
        ('Selection Sort', Sorts.selection_sort),
        ('Merge Sort', Sorts.merge_sort),
        ('Quick Sort', Sorts.quick_sort),
        ('Heap Sort', Sorts.heap_sort),
        ('Shell Sort', Sorts.shell_sort),
        ('Cocktail Sort', Sorts.cocktail_sort),
        ('Comb Sort', Sorts.comb_sort),
        ('Bin. Ins. Sort', Sorts.binary_insert_sort)
    )
    
    a_sorte = functions.create_sorted()
    
    a_reverse = functions.create_reversed()
    
    a_random = functions.create_randomly()
    
    
    for i in range(0, 9):
        x = copy.deepcopy(a_sorte)
        y = copy.deepcopy(a_reverse)
        z = copy.deepcopy(a_random)
        functions.test_sort(SORTS[i], x, y, z)
    

The error I get:

    
    
    Traceback (most recent call last):
     functions.test_sort(SORTS[i], x, y, z)
            f(a_sorte)
      TypeError: 'str' object is not callable
    

This what I did in the previous task as mentioned in the question above:

    
    
    def create_sorted():
    
        value = []
        for i in range(0, SIZE):
            n = Number(i)
            value.append(copy.deepcopy(n))
        return value
    
    
    def create_reversed():
        value = []
        for i in range(SIZE, -1, -1):
            n = Number(i)
            value.append(copy.deepcopy(n))
        return value
    
    
    def create_randomly():
        value = []
        for i in range(N):
            n = Number(random.randint(0, RANGE))
            value.append(copy.deepcopy(n))
        return value
    


Answer: > Define a function test_sort that takes a tuple containing a sort function
> reference and a function description as a parameter

Following those instructions, your logic is fine, but your tuple is not. You
put the description first.

    
    
    SORTS = (
        ('Bubble Sort', Sorts.bubble_sort),
        ('Insertion Sort', Sorts.insertion_sort),
        ('Selection Sort', Sorts.selection_sort),
        ('Merge Sort', Sorts.merge_sort),
        ('Quick Sort', Sorts.quick_sort),
        ('Heap Sort', Sorts.heap_sort),
        ('Shell Sort', Sorts.shell_sort),
        ('Cocktail Sort', Sorts.cocktail_sort),
        ('Comb Sort', Sorts.comb_sort),
        ('Bin. Ins. Sort', Sorts.binary_insert_sort)
    )
    

Therefore, your error starts with

    
    
    f = function_tuple[0]
    f(a_sorte) # TypeError: 'str' object is not callable
    

Because `f` is a string (the description of the function).

I also see you have

    
    
    print("{0}        {1}         {2}        {3}".format(
        function_tuple[1], x, y, z))
    

Which will print the **function** object (`<function Sorts.bubble_sort at
0x1029beae8>`), not the description string.

So, you have two options.

  1. Switch the ordering of all the tuples. I.e `(Sorts.bubble_sort, 'Bubble Sort')` and keep the other code the same
  2. Use `f = function_tuple[1]` for the function that you can call and `function_tuple[0]` as the string to print. 

* * *

Also, why is `a_random` treated any differently than the others? Just do the
same thing as the other lists.

    
    
    Number.comparisons = 0
    f = function_tuple[0]
    f(a_random)
    z = Number.comparisons
    

