Need to modernize my scripting, this bpy based script from 2.77 doesn't run in 2.92 so I can't post my main question yet I need to make a custom mesh, don't know how and want to post a question about it.
However before I do I want to run an example of something simple. I've been away for several years, this runs on 2.77.
Question: What are the changes to Blender that prevent this old script from running in the modern world, and how to change it so that it runs in 2.92 which I will start using now?
Once I can do this I can create an example on which to base my more challenging question.

runs in 2.77, fails in 2.92 with error message:
Traceback (most recent call last):
  File &quot;/Users/your-name-here/Documents/NTHU/Blender/meshitest.blend/Text&quot;, line 25, in &lt;module&gt;
AttributeError: 'bpy_prop_collection' object has no attribute 'link'
Error: Python script failed, check the message in the system console


import numpy as np
import bpy

x = 0.5 *np.arange(-8, 9)
X, Y = np.meshgrid(x, x[2:-2])
Z = np.ones_like(X) -0.1
ny, nx = X.shape
X, Y, Z = [thing.flatten() for thing in (X, Y, Z)]
Z[::2] += 0.2
verts = list(zip(X, Y, Z))

faces = []
for i in range(ny-1):
    for j in range(nx-1):
        v1 = i*(nx) + j
        v2 = v1 + 1
        v3 = v2 + nx
        v4 = v3 - 1
        faces.append((v1, v2, v3, v4))

name = 'sqr'
me = bpy.data.meshes.new(name)
ob = bpy.data.objects.new(name, me)

bpy.context.scene.objects.link(ob)
me.from_pydata(verts, [], faces)

bpy.data.objects[name].select = False
bpy.data.objects[name].select = True

bpy.ops.object.shade_smooth()
The answer to your question may be found in this Q&amp;A. Since 2.8, it seems that objects should be linked to collections instead of scenes.
old:
bpy.context.scene.objects.link(ob)

new:
bpy.context.scene.collection.objects.link(ob)