Randomly coloring with script doesn't work correctly Consider:

I'm having trouble with making each of these circles to have a random color
and the problem is that the color is random, but that color applies to all of them.
import bpy
import random as r
import math as m
n=25

for i in range(1,n+1):

    material_i= bpy.data.materials.new(f'm{i}')
    material_i.diffuse_color=(r.uniform(0,1),r.uniform(0,1),r.uniform(0,1),1)
    bpy.context.object.data.materials.append(material_i)
    angle = ((i-1)*4*(m.pi))/n
    bpy.ops.object.duplicate_move(OBJECT_OT_duplicate={&quot;linked&quot;:False, &quot;mode&quot;:'TRANSLATION'}, TRANSFORM_OT_translate={&quot;value&quot;:(0, 0, 0), &quot;orient_type&quot;:'GLOBAL', &quot;orient_matrix&quot;:((0, 0, 0), (0, 0, 0), (0, 0, 0)), &quot;orient_matrix_type&quot;:'GLOBAL', &quot;constraint_axis&quot;:(False, False, False), &quot;mirror&quot;:False, &quot;use_proportional_edit&quot;:False, &quot;proportional_edit_falloff&quot;:'SMOOTH', &quot;proportional_size&quot;:1, &quot;use_proportional_connected&quot;:False, &quot;use_proportional_projected&quot;:False, &quot;snap&quot;:False, &quot;snap_target&quot;:'CLOSEST', &quot;snap_point&quot;:(0, 0, 0), &quot;snap_align&quot;:False, &quot;snap_normal&quot;:(0, 0, 0), &quot;gpencil_strokes&quot;:False, &quot;cursor_transform&quot;:False, &quot;texture_space&quot;:False, &quot;remove_on_cancel&quot;:False, &quot;release_confirm&quot;:False, &quot;use_accurate&quot;:False, &quot;use_automerge_and_split&quot;:False})
    bpy.context.object.rotation_euler[2] = angle
Part of the issue is that when you append the new material to the duplicated object you never change the index of the active material slot which remains at 0 from the initial object. If you inspect the material slots of each object in turn you continue to add another material but never assign it. I would think that instead of constantly adding additional materials you would rather just have 1 material per object in this case.
import bpy
import random as r
import math as m
n=25

for i in range(1,n+1):
    ob = bpy.context.object
    material_i= bpy.data.materials.new(f'm{i}')
    material_i.diffuse_color=(r.uniform(0,1),r.uniform(0,1),r.uniform(0,1),1)
    if not ob.material_slots:
        bpy.ops.object.material_slot_add()
        new_mat = material_i
        ob.material_slots[0].material = new_mat
    else:
        new_mat = material_i
        ob.material_slots[0].material = new_mat
    angle = ((i-1)*4*(m.pi))/n
    bpy.ops.object.duplicate_move(OBJECT_OT_duplicate={&quot;linked&quot;:False, &quot;mode&quot;:'TRANSLATION'})
    bpy.context.object.rotation_euler[2] = angle