# Clarity and optimization of kmeans algorithms

I have written this k-means algorithm without using any class structure. The audience of my code are students who are pretty new to Python. Is it possible to review the code so that it is more readable by beginner of Python, and at the same time efficient. I wrote the code quite quickly, without reviewing it properly. I have a nagging feeling that it looks more like a code spaghetti. So I need some pointers here, please.

import matplotlib.pyplot as plt
import numpy as np

def colorCluster(data, k , numPoints,  clusterColors, numIterations):
#Get the distance from the centroids
def getDistFromCentroid(data,centroids,k):
def getDistance(a, X):
a = a.T
X = X.T
len = X.shape
distance = np.zeros(len)
for i in range (len):
b = X[i]
distance[i] = np.sqrt(np.square(a - b) + np.square(a - b))
return distance

dist = np.zeros((k,numPoints))
for i in range(k):
dist[i] = getDistance(centroids[i], data)
return dist

#Get the indices of the k clusters
def getIndicesOfClusters(dist):
indArr = []
for i in range(k):
ind = []
for j in range(numPoints):
if(np.argmin(dist[:,j]) == i):
ind.append(j)
indArr.append(ind)
return indArr

#Using the indices of the clustered points
#draw on the canvas
def drawClusterPoints(dist):
def plotMat(mat , ind, color):
ind = np.array(ind).reshape(-1,1).T
p = mat[:,ind]
plt.plot(p, p, 'o', color = color)

indArr = getIndicesOfClusters(dist)
for i in range(k):
plotMat(data, indArr[i], clusterColors[i])

#Centroids are calcuated using the average
#of x and y coordinates in each cluster
def getCentroid(dist):
indArr = getIndicesOfClusters(dist)
centroids = []
for i in range(k):
centroids.append(np.average(data[:,indArr[i]], axis = 1))
return np.array(centroids)

#Update the whole code
#Find new centroids
#Calculate the new distances from centroids
#Repeat for numIterations
def connectAll():
centroids = np.random.randint(1,numPoints, size = [k,2])
for i in range(numIterations):
dist = getDistFromCentroid(data,centroids,k)
centroids = getCentroid(dist)
drawClusterPoints(dist)
#plt.show()
plt.draw()
plt.pause(0.00000000000001)
plt.clf()
#print(centroids.shape)
connectAll()

def kmeans():
#initialize
numPoints = 1000
data = np.random.randint(1,numPoints, size = (2,numPoints))
plt.plot(data, data, 'o', color = "black")
plt.show()
k = 9
numIterations = 10
clusterColors = ["red","brown", "black", "blue", "orange", "purple", "olive", "gray", "cyan"]
colorCluster(data, k , numPoints,  clusterColors, numIterations)

$$$$
`