load and change material with python script
Set the active material not the name

The line

bpy.context.object.active_material.name = "Gold"


sets only the name of the material on the object to "Gold", not the material to the "Gold" material. Do something like this

ob.active_material = bpy.data.materials.get("Gold")


Please Note: blender is case sensitive, the material in file is either named "gold" or "Gold", there is a mix of both in your question.

Using the link / append operator adds a new material to the file. If there is another material already in blend of same name, the naming convention will append numbers to it, meaning above will only ever link the first material named "Gold" from file.  

Simple API methods to link append rather than the op

How to Link/Append a data-block using the Python API?

# Append material named "Gold"
filepath = "C:/Users/ME/Downloads/78-gold.blend"
with bpy.data.libraries.load(filepath, link=False) as (data_from, data_to):
    data_to.materials = ["Gold"]
    #data_to.materials = data_from.materials #  append all materials from blend


Copy an object (and optionally its data)

Second lastly rather than call the add sphere operator 400 times, can call it once outside loop then copy and link to our collection

collection = bpy.data.collections.get("Blahs") or bpy.data.collections.new("Blahs")
bpy.ops.mesh.primitive_blah_add()
blah = context.object
for i in range(copies):
    copy = blah.copy()
    copy.data = copy.data.copy() # a copy of data (mesh) also
    collection.objects.link(copy)


Apply transforms directly to mesh

and lastly rather than the transform apply scale operator

from mathutils import Matrix
# don't set ob.scale = scale do
S = Matrix.Diagonal(scale).to_4x4() # a 4 x 4 scaling matrix

ob.data.transform(S)


Changes suggested will reduce operator calls from 801 to 1, could get rid of add primitive operator, but nuffnuff one is ok.. lol.

Related

Python performance with Blender operators