License Public Domain
Lines 140
Keywords
PointSort (4)
Permissions
Owner: jsimones
Group Owner: SnortSnort
Viewable by Everyone
Editable by All Siafoo Users

Stou's I/O and sorting assignment Atom Feed 0

# 's
  1"""
2Simple I/O "Assignment"
3
4The "assignment":
5
61. Load a file of arbitrary length that is composed of 3 tab-separated columns
7 with floating point numbers representing x, y, z coordinates of points. Lines
8 starting with the pound character (i.e. #) are comments and your program
9 should ignore them.
10
112. Accept file on the command lines:
12 $ ./a.out some_data.dat
13
143. Use STL sort to sort all data points beyond the first by their distance from
15 the first data point (shortest to longest).
16
174. Output sorted list as x y z distance use only 4 significant figures (output
18 only once we can compare speed and correctness with a script later).
19
205. (bonus) Implement your own sorting method and compare to STL method.
21
226. (bonus) Try some of the Boost libraries
23
247. (bonus) Accept command line arguments to pick algorithm, sort order, data
25 points. Try Boost Program Options
26
27Python suggestions:
28
291. Use the standard sorting routine and define your own comparator function
30
31Oh and I suggest sticking to the standard libraries (STL and Python)... if you
32decide to use stuff from Boost and numpy it would probably be good to implement
33your own too and compare them.
34
35"""
36import sys
37import numpy as np
38
39def set_options(opt_list, func_dict):
40 opt_dict = {}
41
42 if '-xyz' in opt_list:
43 i = opt_list.index('-xyz')
44 xyz = float(opt_list[i+1]), float(opt_list[i+2]), float(opt_list[i+3])
45 opt_dict['xyz0'] = xyz
46 else:
47 opt_dict['xyz0'] = None
48
49 if '-d' in opt_list:
50 i = opt_list.index('-d')
51 opt_dict['distfunc'] = func_dict[opt_list[i+1]]
52 else:
53 opt_dict['distfunc'] = calc_dist1
54
55 if '-s' in opt_list:
56 i = opt_list.index('-s')
57 opt_dict['sortfunc'] = func_dict[opt_list[i+1]]
58 else:
59 opt_dict['sortfunc'] = dist_sort1
60
61 return opt_dict
62
63def get_coords(file, delim='\t', skip=['#', '\n']):
64 """
65 Return a list of x,y,z tuples from the coordinates listed in file. Lines
66 starting with # and empty lines are ignored.
67
68 file : file
69 An open file object containing x,y,z data.
70 delim : str
71 String on which split each line of data into x,y,z components.
72 skip : list
73 List of strings. A line will be skipped if it begins with any of these.
74
75 """
76 xyz = []
77 for line in file:
78 if any(line.startswith(i) for i in skip):
79 continue
80 xyz.append(tuple(float(i) for i in line.split(delim)))
81 return xyz
82
83def calc_dist1(xyz, xyz0=None):
84 """
85 Add a distance column to the input coordinate list.
86
87 xyz : list
88 List of x,y,z tuples.
89 xyz0 : list
90 x,y,z location from which to calculated distance to all other points.
91
92 """
93 if xyz0 is None:
94 x0, y0, z0 = xyz[0]
95 else:
96 x0, y0, z0 = xyz0
97
98 xyzr = []
99 for x, y, z in xyz:
100 r = ((x - x0)**2 + (y - y0)**2 + (z - z0)**2)**0.5
101 xyzr.append((x, y, z, r))
102
103 return xyzr
104
105def calc_dist2(xyz, xyz0=None):
106 """
107 numpy version of calc_dist1.
108
109 """
110 xyz = np.array(xyz)
111
112 if xyz0 is None:
113 x0, y0, z0 = xyz[0]
114 else:
115 x0, y0, z0 = xyz0
116
117 r = ((xyz[:,0] - x0)**2 + (xyz[:,1] - y0)**2 + (xyz[:,2] - z0)**2)**0.5
118 return np.c_[xyz, r]
119
120def dist_sort1(xyzr):
121 """
122 Sort points by distance using the built-in sorted function.
123
124 xyzr : list
125 List of x,y,z,r tuples.
126
127 """
128 def keyfunc(xyzr):
129 return xyzr[-1]
130
131 return sorted(xyzr, key=keyfunc)
132
133def dist_sort2(xyzr):
134 """
135 Sort using argsort array method, then use fancy indexing to return the
136 sorted xyzr array.
137
138 """
139 try:
140 idx = xyzr[:,3].argsort()
141 except AttributeError:
142 xyzr = np.array(xyzr)
143 idx = xyzr[:,3].argsort()
144 return xyzr[idx]
145
146def pretty_print(xyzr):
147 """
148 Print the contents of xyzr, a list of 4-tuples.
149
150 """
151 for x, y, z, r in xyzr:
152 print '%.4f\t%.4f\t%.4f\t%.4f' % (x, y, z, r)
153
154def main():
155 """
156 Command line options
157 --------------------
158 -xyz <x> <y> <z> :
159 Coordinates of the desired reference point for distance calculations.
160 -d <distfunc>:
161 Choose which function in func_dict to use when opt_dict['distfunc'] is
162 called.
163 -s <sortfunc>:
164 Choose which function in func_dict to use when opt_dict['sortfunc'] is
165 called.
166
167 """
168 filename = sys.argv[1]
169 opt_dict = set_options(sys.argv[1:], func_dict)
170
171 file = open(filename, 'r')
172 xyz = get_coords(file)
173 file.close()
174
175 xyzr = opt_dict['distfunc'](xyz, opt_dict['xyz0'])
176 xyzr = opt_dict['sortfunc'](xyzr)
177 pretty_print(xyzr)
178
179func_dict = {'calc_dist1': calc_dist1, 'calc_dist2': calc_dist2,
180 'dist_sort1': dist_sort1, 'dist_sort2': dist_sort2}
181
182if __name__ == '__main__':
183 main()