PageRenderTime 64ms CodeModel.GetById 18ms app.highlight 42ms RepoModel.GetById 1ms app.codeStats 0ms

/exercises/mlclass-ex1/submit.m

http://github.com/jneira/machine-learning-course
Objective C | 336 lines | 300 code | 36 blank | 0 comment | 31 complexity | 9728b3f1a4a51c12fae3a07a387c8136 MD5 | raw file
  1function submit(part)
  2%SUBMIT Submit your code and output to the ml-class servers
  3%   SUBMIT() will connect to the ml-class server and submit your solution
  4
  5  fprintf('==\n== [ml-class] Submitting Solutions | Programming Exercise %s\n==\n', ...
  6          homework_id());
  7  if ~exist('part', 'var') || isempty(part)
  8    partId = promptPart();
  9  end
 10  
 11  % Check valid partId
 12  partNames = validParts();
 13  if ~isValidPartId(partId)
 14    fprintf('!! Invalid homework part selected.\n');
 15    fprintf('!! Expected an integer from 1 to %d.\n', numel(partNames) + 1);
 16    fprintf('!! Submission Cancelled\n');
 17    return
 18  end
 19
 20  [login password] = loginPrompt();
 21  if isempty(login)
 22    fprintf('!! Submission Cancelled\n');
 23    return
 24  end
 25
 26  fprintf('\n== Connecting to ml-class ... '); 
 27  if exist('OCTAVE_VERSION') 
 28    fflush(stdout);
 29  end
 30  
 31  % Setup submit list
 32  if partId == numel(partNames) + 1
 33    submitParts = 1:numel(partNames);
 34  else
 35    submitParts = [partId];
 36  end
 37
 38  for s = 1:numel(submitParts)
 39    % Submit this part
 40    partId = submitParts(s);
 41    
 42    % Get Challenge
 43    [login, ch, signature] = getChallenge(login);
 44    if isempty(login) || isempty(ch) || isempty(signature)
 45      % Some error occured, error string in first return element.
 46      fprintf('\n!! Error: %s\n\n', login);
 47      return
 48    end
 49  
 50    % Attempt Submission with Challenge
 51    ch_resp = challengeResponse(login, password, ch);
 52    [result, str] = submitSolution(login, ch_resp, partId, output(partId), ...
 53                                 source(partId), signature);
 54                                 
 55    fprintf('\n== [ml-class] Submitted Homework %s - Part %d - %s\n', ...
 56            homework_id(), partId, partNames{partId});
 57    fprintf('== %s\n', strtrim(str));
 58    if exist('OCTAVE_VERSION') 
 59      fflush(stdout);
 60    end
 61  end
 62  
 63end
 64
 65% ================== CONFIGURABLES FOR EACH HOMEWORK ==================
 66
 67function id = homework_id() 
 68  id = '1';
 69end
 70
 71function [partNames] = validParts()
 72  partNames = { 'Warm up exercise ', ...
 73                'Computing Cost (for one variable)', ...
 74                'Gradient Descent (for one variable)', ...
 75                'Feature Normalization', ...
 76                'Computing Cost (for multiple variables)', ...
 77                'Gradient Descent (for multiple variables)', ...
 78                'Normal Equations'};
 79end
 80
 81function srcs = sources()
 82  % Separated by part
 83  srcs = { { 'warmUpExercise.m' }, ...
 84           { 'computeCost.m' }, ...
 85           { 'gradientDescent.m' }, ...
 86           { 'featureNormalize.m' }, ...
 87           { 'computeCostMulti.m' }, ...
 88           { 'gradientDescentMulti.m' }, ...
 89           { 'normalEqn.m' }, ...
 90         };
 91end
 92
 93function out = output(partId)
 94  % Random Test Cases
 95  X1 = [ones(20,1) (exp(1) + exp(2) * (0.1:0.1:2))'];
 96  Y1 = X1(:,2) + sin(X1(:,1)) + cos(X1(:,2));
 97  X2 = [X1 X1(:,2).^0.5 X1(:,2).^0.25];
 98  Y2 = Y1.^0.5 + Y1;
 99  if partId == 1
100    out = sprintf('%0.5f ', warmUpExercise());
101  elseif partId == 2
102    out = sprintf('%0.5f ', computeCost(X1, Y1, [0.5 -0.5]'));
103  elseif partId == 3
104    out = sprintf('%0.5f ', gradientDescent(X1, Y1, [0.5 -0.5]', 0.01, 10));
105  elseif partId == 4
106    out = sprintf('%0.5f ', featureNormalize(X2(:,2:4)));
107  elseif partId == 5
108    out = sprintf('%0.5f ', computeCostMulti(X2, Y2, [0.1 0.2 0.3 0.4]'));
109  elseif partId == 6
110    out = sprintf('%0.5f ', gradientDescentMulti(X2, Y2, [-0.1 -0.2 -0.3 -0.4]', 0.01, 10));
111  elseif partId == 7
112    out = sprintf('%0.5f ', normalEqn(X2, Y2));
113  end 
114end
115
116function url = challenge_url()
117  url = 'http://www.ml-class.org/course/homework/challenge';
118end
119
120function url = submit_url()
121  url = 'http://www.ml-class.org/course/homework/submit';
122end
123
124% ========================= CHALLENGE HELPERS =========================
125
126function src = source(partId)
127  src = '';
128  src_files = sources();
129  if partId <= numel(src_files)
130      flist = src_files{partId};
131      for i = 1:numel(flist)
132          fid = fopen(flist{i});
133          while ~feof(fid)
134            line = fgets(fid);
135            src = [src line];
136          end
137          src = [src '||||||||'];
138      end
139  end
140end
141
142function ret = isValidPartId(partId)
143  partNames = validParts();
144  ret = (~isempty(partId)) && (partId >= 1) && (partId <= numel(partNames) + 1);
145end
146
147function partId = promptPart()
148  fprintf('== Select which part(s) to submit:\n', ...
149          homework_id());
150  partNames = validParts();
151  srcFiles = sources();
152  for i = 1:numel(partNames)
153    fprintf('==   %d) %s [', i, partNames{i});
154    fprintf(' %s ', srcFiles{i}{:});
155    fprintf(']\n');
156  end
157  fprintf('==   %d) All of the above \n==\nEnter your choice [1-%d]: ', ...
158          numel(partNames) + 1, numel(partNames) + 1);
159  selPart = input('', 's');
160  partId = str2num(selPart);
161  if ~isValidPartId(partId)
162    partId = -1;
163  end
164end
165
166function [email,ch,signature] = getChallenge(email)
167  str = urlread(challenge_url(), 'post', {'email_address', email});
168
169  str = strtrim(str);
170  [email, str] = strtok (str, '|');
171  [ch, str] = strtok (str, '|');
172  [signature, str] = strtok (str, '|');
173end
174
175
176function [result, str] = submitSolution(email, ch_resp, part, output, ...
177                                        source, signature)
178
179  params = {'homework', homework_id(), ...
180            'part', num2str(part), ...
181            'email', email, ...
182            'output', output, ...
183            'source', source, ...
184            'challenge_response', ch_resp, ...
185            'signature', signature};
186
187  str = urlread(submit_url(), 'post', params);
188  
189  % Parse str to read for success / failure
190  result = 0;
191
192end
193
194% =========================== LOGIN HELPERS ===========================
195
196function [login password] = loginPrompt()
197  % Prompt for password
198  [login password] = basicPrompt();
199  
200  if isempty(login) || isempty(password)
201    login = []; password = [];
202  end
203end
204
205
206function [login password] = basicPrompt()
207  login = input('Login (Email address): ', 's');
208  password = input('Password: ', 's');
209end
210
211
212function [str] = challengeResponse(email, passwd, challenge)
213  salt = ')~/|]QMB3[!W`?OVt7qC"@+}';
214  str = sha1([challenge sha1([salt email passwd])]);
215  sel = randperm(numel(str));
216  sel = sort(sel(1:16));
217  str = str(sel);
218end
219
220
221% =============================== SHA-1 ================================
222
223function hash = sha1(str)
224  
225  % Initialize variables
226  h0 = uint32(1732584193);
227  h1 = uint32(4023233417);
228  h2 = uint32(2562383102);
229  h3 = uint32(271733878);
230  h4 = uint32(3285377520);
231  
232  % Convert to word array
233  strlen = numel(str);
234
235  % Break string into chars and append the bit 1 to the message
236  mC = [double(str) 128];
237  mC = [mC zeros(1, 4-mod(numel(mC), 4), 'uint8')];
238  
239  numB = strlen * 8;
240  if exist('idivide')
241    numC = idivide(uint32(numB + 65), 512, 'ceil');
242  else
243    numC = ceil(double(numB + 65)/512);
244  end
245  numW = numC * 16;
246  mW = zeros(numW, 1, 'uint32');
247  
248  idx = 1;
249  for i = 1:4:strlen + 1
250    mW(idx) = bitor(bitor(bitor( ...
251                  bitshift(uint32(mC(i)), 24), ...
252                  bitshift(uint32(mC(i+1)), 16)), ...
253                  bitshift(uint32(mC(i+2)), 8)), ...
254                  uint32(mC(i+3)));
255    idx = idx + 1;
256  end
257  
258  % Append length of message
259  mW(numW - 1) = uint32(bitshift(uint64(numB), -32));
260  mW(numW) = uint32(bitshift(bitshift(uint64(numB), 32), -32));
261
262  % Process the message in successive 512-bit chs
263  for cId = 1 : double(numC)
264    cSt = (cId - 1) * 16 + 1;
265    cEnd = cId * 16;
266    ch = mW(cSt : cEnd);
267    
268    % Extend the sixteen 32-bit words into eighty 32-bit words
269    for j = 17 : 80
270      ch(j) = ch(j - 3);
271      ch(j) = bitxor(ch(j), ch(j - 8));
272      ch(j) = bitxor(ch(j), ch(j - 14));
273      ch(j) = bitxor(ch(j), ch(j - 16));
274      ch(j) = bitrotate(ch(j), 1);
275    end
276  
277    % Initialize hash value for this ch
278    a = h0;
279    b = h1;
280    c = h2;
281    d = h3;
282    e = h4;
283    
284    % Main loop
285    for i = 1 : 80
286      if(i >= 1 && i <= 20)
287        f = bitor(bitand(b, c), bitand(bitcmp(b), d));
288        k = uint32(1518500249);
289      elseif(i >= 21 && i <= 40)
290        f = bitxor(bitxor(b, c), d);
291        k = uint32(1859775393);
292      elseif(i >= 41 && i <= 60)
293        f = bitor(bitor(bitand(b, c), bitand(b, d)), bitand(c, d));
294        k = uint32(2400959708);
295      elseif(i >= 61 && i <= 80)
296        f = bitxor(bitxor(b, c), d);
297        k = uint32(3395469782);
298      end
299      
300      t = bitrotate(a, 5);
301      t = bitadd(t, f);
302      t = bitadd(t, e);
303      t = bitadd(t, k);
304      t = bitadd(t, ch(i));
305      e = d;
306      d = c;
307      c = bitrotate(b, 30);
308      b = a;
309      a = t;
310      
311    end
312    h0 = bitadd(h0, a);
313    h1 = bitadd(h1, b);
314    h2 = bitadd(h2, c);
315    h3 = bitadd(h3, d);
316    h4 = bitadd(h4, e);
317
318  end
319
320  hash = reshape(dec2hex(double([h0 h1 h2 h3 h4]), 8)', [1 40]);
321  
322  hash = lower(hash);
323
324end
325
326function ret = bitadd(iA, iB)
327  ret = double(iA) + double(iB);
328  ret = bitset(ret, 33, 0);
329  ret = uint32(ret);
330end
331
332function ret = bitrotate(iA, places)
333  t = bitshift(iA, places - 32);
334  ret = bitshift(iA, places);
335  ret = bitor(ret, t);
336end