/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

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