# L-6 MCS 275 25 Jan 2010 : makedata.py # Generates k clusters of some number of points with integer coordinates. import random, turtle from math import cos, sin, pi, sqrt def Cluster(n,c,r): """ Returns a list of n points with integer coordinates, in a disk with center c and radius r. """ L = [] L.append(c) for k in range(1,n): rp = r*random.random() ap = 2*pi*random.random() x = c[0] + round(rp*cos(ap)) y = c[1] + round(rp*sin(ap)) L.append((x,y)) return L def MakeData(): """ Returns a list of lists of points with integer coordinates. The user is prompted for k : the number of lists, and for each list : n : the number of points in the cluster, c : the center of the cluster, r : the radius of the cluster. Then n points with integer coordinates in a disk centered at c and with radius r will be generated. """ R = [] k = input("Give the number of clusters : ") for i in range(0,k): n = input("-> give the number of points in cluster %d : " % i) c = input("give the center of the cluster %d as tuple : " % i) r = input(" give the radius of the cluster %d : " % i) R.append(Cluster(n,c,r)) return R def TypicalData(): """ Generates random numbers for (n,c,r). """ R = [] k = input("Give the number of clusters : ") for i in range(0,k): n = random.randint(10,100) c = (random.randint(-200,200),random.randint(-200,200)) r = random.randint(10,50) R.append(Cluster(n,c,r)) return R def Centroid(L): """ Given a list L of tuples (x,y), returns the centroid of the points in L. """ n = len(L) if n == 0: return (0,0) else: sx = sy = 0 for p in L: sx = sx + p[0] sy = sy + p[1] c = (sx/n,sy/n) return c def Centroids(L): """ Given in L a list of lists of points, returns the list of centroids. """ R = [Centroid(e) for e in L] return R def Distance(p,q): """ Returns the Euclidean distance between p and q. """ x = p[0] - q[0] y = p[1] - q[1] return sqrt(x*x + y*y) def Radius(L,c): """ Returns the largest distance of any point in L to the centroid c. """ if len(L) == 0: return 0 else: d = [Distance(p,c) for p in L] return max(d) def Radii(L,C): """ Given on input in L a list of lists and in C the corresponding centroids, returns the list of radii for each centroid. """ R = [] for k in range(0,len(L)): R.append(Radius(L[k],C[k])) return R def ShowData(L): """ For each point in L, draws a circle of radius 2 pixels, centered at the data point. """ turtle.tracer(False) for K in L: for p in K: turtle.up() turtle.goto(p[0],p[1]-2) turtle.down() turtle.circle(2) turtle.up() turtle.goto(0,0) def ShowCentroids(C,R): """ Given on input in C a list of centroids and in R the corresponding radii, draws the disks. """ for k in range(0,len(C)): c = C[k] r = R[k]+2 turtle.up() turtle.goto(c[0],c[1]-r) turtle.down() turtle.circle(r) turtle.up() def SaveToFile(L): """ Prompts the user for a file name and writes the data to file. """ name = raw_input("give a file name : ") f = file(name,'w') f.write(str(L)) f.close() def main(): """ Generates a list of clustered points. """ ans = raw_input("typical input data ? (y/n) ") if ans == 'y': L = TypicalData() else: L = MakeData() # print L C = Centroids(L) R = Radii(L,C) ShowData(L) ShowCentroids(C,R) ans = raw_input("save to file ? (y/n) ") if ans == 'y': SaveToFile(L) if __name__=="__main__": main()