/
atom.xml
1044 lines (655 loc) · 112 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title><![CDATA[Things To Think About]]></title>
<link href="http://agnanachandran.github.io/atom.xml" rel="self"/>
<link href="http://agnanachandran.github.io/"/>
<updated>2018-11-11T17:31:00-05:00</updated>
<id>http://agnanachandran.github.io/</id>
<author>
<name><![CDATA[Anojh Gnanachandran]]></name>
<email><![CDATA[anojhgnanachandran@gmail.com]]></email>
</author>
<generator uri="http://octopress.org/">Octopress</generator>
<entry>
<title type="html"><![CDATA[Onwards and Upwards]]></title>
<link href="http://agnanachandran.github.io/blog/2017/04/12/onwards-and-upwards/"/>
<updated>2017-04-12T17:59:00-04:00</updated>
<id>http://agnanachandran.github.io/blog/2017/04/12/onwards-and-upwards</id>
<content type="html"><![CDATA[<p>I’m about 8 days away from finishing my last final exam at the University of Waterloo. Over the past few weeks I’ve often been asked, “what do you plan on doing after graduation?” I usually respond with some combination of “travelling, living in Toronto for a while, doing my own thing,” but nothing really concrete. I guess that’s because I don’t really know myself. While many of my friends have found and accepted full-time jobs, I have not. I’m not really sure what I want to do yet, or where I want to work. Besides, I’ve been alternating between studying and working for the past 5 years or so of my life. I’m not ready to just jump into something new and start working.</p>
<!-- more -->
<p>So I figured I would take a break. Not so much go on vacation, but try to spend time doing more non-academic things, the sort of stuff I didn’t make enough time to do during my undergrad. Things like playing more volleyball, working out more, or cooking. Honestly, getting this degree was difficult and at times (many times), stressful.</p>
<p>So I wanna unwind for a bit, and really focus on the goals I haven’t been prioritizing. But of course, I can’t do this forever; I only have enough money saved to justify doing this for a few months.</p>
<p>Being in a co-op program, you might have thought I’d’ve figured it all out by now. I thought I would have too, but as graduation grew closer, I realized I hadn’t quite found what I was looking for in terms of a full-time job. Being in co-op has helped tremendously in figuring out what aspects of software engineering I enjoy and which ones I don’t. I’ve gained invaluable experiences and learned a ton about creating software, tech companies, and the work life in general.</p>
<p><img class="center" src="http://agnanachandran.github.io/images/golden_gate_bridge.jpg"></p>
<p>But throughout my co-op terms I never felt completely <em>fulfilled</em>. To be clear, this is no fault of my employers. Overall, I’ve enjoyed my co-op terms; I’ve learned a lot and worked on some pretty cool things. There were many times (in fact I’d say most of the time) where I enjoyed what I was doing. I could see myself doing these jobs for a few months at a time, but not for much longer. There was just something missing.</p>
<hr />
<p>When I was in the eighth grade, I wrote in the yearbook that I aspired to be a <em>professional software engineer</em>. I wonder, how did I know what I wanted to be when I was 13? Well, I didn’t. But I knew software engineering involved math and computers, and I liked both of those things (and still do), so it was an obvious choice. Of course, I didn’t really know what it meant to be a software engineer. By that point, I had never written a single line of code in my life. But I stuck with it, and now almost ten years later, I’m about to graduate with a degree in software engineering.</p>
<p>Now that I’m at the end of my degree, I feel much better prepared to answer the question of why exactly I want to be a software engineer. I think there’s a few reasons:</p>
<p>1) I really enjoy the problem solving aspect of it; software engineering requires a lot of critical thinking, creativity, and perseverance. Technical challenges are often fun yet frustrating. You feel good when you finally complete something you’ve been working on for hours, days, or weeks. It’s addicting, in many ways, constantly learning and creating incrementally more complex things and trying to make all the pieces fit together.</p>
<p>2) I also enjoy the <em>magic</em> of the whole experience; you can write text on your computer and create a website, or a game, or anything really, with just your mouse and keyboard and mind. Thinking of an idea, working on it, and having your idea come to life often feels like magic. Working hard on something and then seeing people use the product you made is incredibly rewarding.</p>
<p>These two things are still what I enjoy the most about programming; it’s something where you can just sit and think and create and struggle and eventually end up with something really cool, something you can be proud of.</p>
<p>Although programming is usually enjoyable, there are times when it’s boring, annoying, or just not very fun. I’ve found that I thrive the most and work the hardest when I work on something I really care about. And I’ll usually care more about something if it’s directly related to a cause I care about, or it’s technically interesting. I also enjoy having a lot of ownership over what I work on; by having ownership, I’m making myself personally invested in that work, and so I work harder because I want to succeed by virtue of my work being successful. I like making product, design, and user experience decisions related to the feature I’m working on, instead of just being told to code something and generally only making “technical” decisions.</p>
<p>At my co-op jobs, it’s often felt more like I was just ticking off boxes (finish this task, then there’s another one to do, then after that there’s this thing), and although I had some ownership, I didn’t feel as personally invested in my work as I might have liked. There were times when my work was sufficiently interesting or engaging, and that’s when I worked the hardest, but it didn’t last long.</p>
<p>Maybe it’s because I was just a co-op student. As a full-time engineer, I’m certain I’d have a lot more ownership, but I don’t think that’s all that was missing. I also need to care about the work I’m doing. How does my work impact the product? How does the feature I’m working on impact our users? How can I contribute my skills to make sure the product is successful? And do I even care if the product succeeds?</p>
<p>It seems like I’d be most likely to fulfill these desires by working at a startup working on something like education or social good (two causes I care about), and working with technologies I find interesting, like artificial intelligence and machine learning. Unfortunately, I haven’t quite yet found my ideal job yet, so I’ve been thinking about some alternatives, something to work on while I figure out what I want to do and where I want to work.</p>
<hr />
<p>For the past year or so, I’ve been working with a few friends on <a href="https://www.interncompass.io">InternCompass</a>, a platform where students can learn about internships and read reviews written by other students who have interned at various companies around the world. Having so much control over the product, from its design to its user experience to its infrastructure, has been a really rewarding experience. The encouragement from our users, and our future plans for the product, give me hope that it’ll take off and be really useful to students from a variety of disciplines looking for internships. By working on InternCompass, I’ll get to work on a product I really care about, and further develop my engineering, design, and communication skills.</p>
<p>So that’s what I’ve decided on for now. For the next few months I’ll be living in Toronto, and when I’m not exercising, socializing, cooking, or whatever else, I’ll be working on InternCompass. Toronto’s always seemed like a lovely place to live, so I’m excited to finally experience the city to its fullest. I’ve also found that living away from home gives me a sense of responsibility that’s conducive towards achieving my goals. Plus I figure with the rising rent prices, I’ll be more motivated to make the most of my time when I’m there. And hey, maybe I’ll change my mind next week, or next month, but that’s okay. This gives me something to work on while I work on myself and figure things out. If InternCompass takes off, that’s great. And if it doesn’t, that’s fine too.</p>
<p>Either way, I’m glad I finally know what I’m going to do. I’m anxious, but I’m also really excited for what’s to come. I’m excited to work on something I care about and feel the joy of creation. I’m excited to work on myself in ways that I haven’t had the chance to until now. I’m not sure where I’ll be or what I’ll be doing a year from now, but I’m excited to find out.</p>
<p><img class="center" src="http://agnanachandran.github.io/images/toronto_cn_tower.jpg"></p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Using Simulated Annealing To Solve Logic Puzzles]]></title>
<link href="http://agnanachandran.github.io/blog/2016/07/17/using-simulated-annealing-to-solve-logic-puzzles/"/>
<updated>2016-07-17T02:43:00-04:00</updated>
<id>http://agnanachandran.github.io/blog/2016/07/17/using-simulated-annealing-to-solve-logic-puzzles</id>
<content type="html"><![CDATA[<p>The other day, I was watching Ted Ed’s collection of YouTube videos on riddles and came across this interesting logic puzzle described as <a href="https://www.youtube.com/watch?v=1rDVz_Fb6HQ">“Einstein’s Riddle”</a>. Einstein probably didn’t make up the riddle, but the problem itself is kind of interesting for a few reasons. You can either watch the video or keep reading for a retelling of the problem below.</p>
<!-- more -->
<hr />
<h3>The Riddle</h3>
<blockquote><p>The world’s rarest fish has been stolen from the city aquarium, and the police have followed the scent to a street of 5 identical looking houses all in a row. The police can only search one house without the thief getting away, and so we have to find out which house contains the fish.</p></blockquote>
<p><span class="caption-wrapper center" style="width: 1702px"><img class="caption" src="http://agnanachandran.github.io/images/simulated_annealing/houses.png" title="Houses in a row" alt="The 5 houses as shown in the video"><span class="caption-text">The 5 houses as shown in the video</span></span></p>
<p>We have the following information:</p>
<ol>
<li>Each house’s owner is of a different nationality,<br> either Dane, Brit, Swede, Norwegian, or German.</li>
<li>The interior walls of each house are coloured differently,<br> either yellow, red, white, green, or blue.</li>
<li>Each house contains a different animal,<br> either horse, cat, bird, fish, or dog.</li>
<li>The owner of each house drinks a different beverage,<br> either water, tea, milk, coffee, or root beer.</li>
<li>The owner of each house smokes a different kind of cigar,<br> either Pall Mall, Prince, Blue Master, Dunhill, or Blends.</li>
</ol>
<p>Furthermore, we have the following 15 clues:</p>
<ol>
<li>The Brit lives in the house with red walls.</li>
<li>The Swede has a dog.</li>
<li>The Dane drinks tea.</li>
<li>The house with green walls is directly to the left of the house with white walls.</li>
<li>The owner of the house with green walls drinks coffee.</li>
<li>The person who smokes Pall Mall cigars owns a bird.</li>
<li>The owner of the house with yellow walls smokes Dunhill.</li>
<li>The man living in the center house drinks milk.</li>
<li>The Norwegian lives in the first house.</li>
<li>The man who smokes blends lives next to the cat owner.</li>
<li>The horse’s owner lives next to the man who smokes Dunhill.</li>
<li>The man who smokes Blue Master drinks root beer.</li>
<li>The German smokes Prince.</li>
<li>The Norwegian lives next to the house with blue walls.</li>
<li>The man who smokes Blends lives next to the man who drinks water.</li>
</ol>
<p>Using nothing but this information, it is possible to figure out who has the fish.</p>
<p>Don’t read ahead yet if you want to figure this out on your own first.</p>
<hr />
<p>I remember having seen this problem several years ago, and I solved it on paper using the traditional logical solution shown in the video using a lot of process of elimination. Solving the problem using this method is probably how it was meant to be done, and I’d recommend trying it first to compare the different methods.</p>
<p>When I first learned about the problem years ago, I didn’t have much programming knowledge. But now, I wondered if I could use my programming knowledge to solve the problem a different way. At first I wondered if it could be brute forced, just trying every possible arrangement.</p>
<p>How many arrangements are there? Well for the first house, there are 5 “attributes” to pick (nationality, wall colour, animal, beverage, and cigar), and each has 5 options. This gives 5<sup>5</sup> possibilities for the first house. Then for the second house, there are still 5 attributes to pick, but only 4 options for each. This gives 4<sup>5</sup> possibilities for the second house, 3<sup>5</sup> for the third, 2<sup>5</sup> for the fourth and 1<sup>5</sup> for the fifth. Multiplying these together gives 24 883 200 000 or almost 25 billion possibilities. If we could check 100 000 possibilities every second, it would take 69 hours to check all the possibilities.</p>
<p>There are many ways we could speed up the process, like using some of the clues to significantly reduce the size of the search space. We could also turn the clues into logic expressions in code and use them to perform a similar process of elimination technique to simulate how it would be done on paper. I thought to use a technique I learned in my cooperative and adaptive algorithms class called simulated annealing. Simulated annealing can be used to solve problems like this, where there’s a large search space and we are trying to find a global optimum. In this case, the global optimum is the arrangement in which all 15 of the clues are satisfied.</p>
<h3>Simulated Annealing</h3>
<p>The idea behind <a href="https://en.wikipedia.org/wiki/Simulated_annealing">simulated annealing</a> is fairly simple.</p>
<p>We start with an initial state (or “solution”), where a state is one of the almost 25 billion possibilities described above. That is, for each house and for each of its attributes, one of the five choices for the attribute is picked.</p>
<p>We also need to define a cost function which, when given a state, tells us how “good” the state is. Here, a natural cost function would be “the number of clues that are NOT satisfied”. For example, if out of the 15 clues, 12 are satisfied, but 3 are not satisfied, our cost function would give us 3 for the corresponding state. We seek to minimize the cost of our state. If the cost of a state is 0, that means all the clues are satisfied!</p>
<p>So now we have the concept of a state and a cost function. Now what if the initial state we picked doesn’t have a cost of zero? Then we want to reduce it, right? But how? We have to pick a new state to replace our initial one and evaluate its cost and hope its cost is better (lower). But if we just pick another totally random state, that’s basically just doing the brute-force method described earlier.</p>
<p>Instead, we can try to take advantage of what we have and change it little by little. We can do that by defining what’s called a “neighbour state”. Here, a neighbour state is simply a state which can be reached by swapping an attribute choice between two houses. For example, if our current state has the German in the second house and the Brit in the fourth house, a neighbour of the current state would be the state in which everything is the same except that the German is in the fourth house and the Brit is in the second house. For a given state, there are <sub>5</sub>C<sub>2</sub> = 10 choices for the two houses to swap, and 5 attributes to choose from, giving a total of 50 neighbouring states for any state. The hope is that by simply performing a swap, the cost will probably not drastically increase.</p>
<p>Now that we have the concept of a neighbour state, we can simply choose a random neighbour and “move” to it; that is, change our current state to the neighbour state. But we probably don’t want to do that if it has a worse cost right? If our current state has cost 3, then we probably don’t want to move to a state of cost 7. However, we will not always be able to move to a state of lower cost. For this problem, it turns out we’ll often get stuck in a local minimum, a state in which all neighbouring states have cost greater than or equal to the cost of the current state.</p>
<p><span class="caption-wrapper center" style="width: 391px"><img class="caption" src="http://agnanachandran.github.io/images/simulated_annealing/local_minimum.png" title="Local minimum" alt="We want to find the global minimum, not the local minimum"><span class="caption-text">We want to find the global minimum, not the local minimum</span></span></p>
<p>We won’t be able to find the global minimum just by choosing neighbours with lower cost all the time, because eventually there won’t be any. We can escape this trap either by moving to another random state, or instead, we can sometimes accept worse solutions. The hope here is that by following this worse solution, we can eventually get to the global minimum.</p>
<p>Simulated annealing performs the latter using what’s called an acceptance probability. The acceptance probability is used to determine whether we want to move to a neighbouring state or not. There are a few basic properties of the acceptance probability.</p>
<p>If the neighbouring state has lesser or equal cost, then we will always move to it.</p>
<p>If it has greater cost, we will only move to it with a certain probability. Otherwise we’ll stay where we are and choose another neighbour. We define the cost delta denoted by Δc, which is simply the current cost subtracted from the neighbour cost, and a parameter t, which stands for temperature, and influences how likely we are to accept the neighbouring state.</p>
<p><span class="caption-wrapper center" style="width: 894px"><img class="caption" src="http://agnanachandran.github.io/images/simulated_annealing/acceptance_probability.png" title="Acceptance Probability" ><span class="caption-text"></span></span></p>
<p>Looking at the exponential function, the greater the cost delta, the lower the power, and thus the lower the acceptance probability is. If the neighbouring cost is much higher than the current cost, we are not likely to move to it.</p>
<p>t affects how often we pick worse solutions. The greater the value of t, the higher the acceptance probability is. t is a parameter we choose which typically starts high and steadily decreases every so often, so we are less likely to accept worse solutions as time goes on (where we are hopefully close to finding the global minimum).</p>
<p>Note that since Δc and t are both positive, the exponential function’s value is in the range (0, 1). We can use a random number in this range to choose, based on the acceptance probability, whether we should move to the new state or not. If the random number is less than the acceptance probability’s value, we should move to the new state.</p>
<h4>Turning It Into Code</h4>
<p>We now have everything necessary to apply this technique to our problem. To summarize:</p>
<ol>
<li>Pick an initial solution and compute its cost</li>
<li>Pick a random neighbour of the current solution</li>
<li>Compute its cost, the cost delta, and the acceptance probability</li>
<li>Move to the neighbour if a random number in (0, 1) is less than the acceptance probability</li>
<li>Repeat steps 2-4 until the current solution’s cost is 0. Decrease the temperature <code>t</code> every so often.</li>
</ol>
<p>We’ll write the code in python because it’s great for stuff like this. First, we need to setup the initial state.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr></pre></td><td class='code'><pre><code class='python'><span class='line'><span class="n">nationalities</span> <span class="o">=</span> <span class="p">[</span> <span class="s">'dane'</span><span class="p">,</span> <span class="s">'brit'</span><span class="p">,</span> <span class="s">'swede'</span><span class="p">,</span> <span class="s">'norwegian'</span><span class="p">,</span> <span class="s">'german'</span> <span class="p">]</span>
</span><span class='line'><span class="n">colours</span> <span class="o">=</span> <span class="p">[</span> <span class="s">'yellow'</span><span class="p">,</span> <span class="s">'red'</span><span class="p">,</span> <span class="s">'white'</span><span class="p">,</span> <span class="s">'green'</span><span class="p">,</span> <span class="s">'blue'</span> <span class="p">]</span>
</span><span class='line'><span class="n">animals</span> <span class="o">=</span> <span class="p">[</span> <span class="s">'horse'</span><span class="p">,</span> <span class="s">'cat'</span><span class="p">,</span> <span class="s">'bird'</span><span class="p">,</span> <span class="s">'fish'</span><span class="p">,</span> <span class="s">'dog'</span> <span class="p">]</span>
</span><span class='line'><span class="n">beverages</span> <span class="o">=</span> <span class="p">[</span> <span class="s">'water'</span><span class="p">,</span> <span class="s">'tea'</span><span class="p">,</span> <span class="s">'milk'</span><span class="p">,</span> <span class="s">'coffee'</span><span class="p">,</span> <span class="s">'root beer'</span> <span class="p">]</span>
</span><span class='line'><span class="n">cigars</span> <span class="o">=</span> <span class="p">[</span> <span class="s">'pall mall'</span><span class="p">,</span> <span class="s">'prince'</span><span class="p">,</span> <span class="s">'blue master'</span><span class="p">,</span> <span class="s">'dunhill'</span><span class="p">,</span> <span class="s">'blends'</span> <span class="p">]</span>
</span><span class='line'>
</span><span class='line'><span class="n">attributes</span> <span class="o">=</span> <span class="p">[</span><span class="n">nationalities</span><span class="p">,</span> <span class="n">colours</span><span class="p">,</span> <span class="n">animals</span><span class="p">,</span> <span class="n">beverages</span><span class="p">,</span> <span class="n">cigars</span><span class="p">]</span>
</span><span class='line'>
</span><span class='line'><span class="n">NUM_HOUSES</span> <span class="o">=</span> <span class="mi">5</span>
</span><span class='line'><span class="n">initial</span> <span class="o">=</span> <span class="p">[]</span>
</span><span class='line'>
</span><span class='line'><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="n">NUM_HOUSES</span><span class="p">):</span>
</span><span class='line'> <span class="n">initial</span><span class="o">.</span><span class="n">append</span><span class="p">([</span><span class="n">attr</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="k">for</span> <span class="n">attr</span> <span class="ow">in</span> <span class="n">attributes</span><span class="p">])</span>
</span></code></pre></td></tr></table></div></figure>
<p>For each attribute, the <i>i<sup>th</sup></i> house will take on the <i>i<sup>th</sup></i> choice for the attribute. Thus, the initial state can be represented by a list of 5 houses, each of which is a list of the attributes it takes on.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr></pre></td><td class='code'><pre><code class='python'><span class='line'><span class="p">[</span>
</span><span class='line'> <span class="p">[</span> <span class="s">'dane'</span><span class="p">,</span> <span class="s">'yellow'</span><span class="p">,</span> <span class="s">'horse'</span><span class="p">,</span> <span class="s">'water'</span><span class="p">,</span> <span class="s">'pall mall'</span> <span class="p">],</span> <span class="c"># House 1</span>
</span><span class='line'> <span class="p">[</span> <span class="s">'brit'</span><span class="p">,</span> <span class="s">'red'</span><span class="p">,</span> <span class="s">'cat'</span><span class="p">,</span> <span class="s">'tea'</span><span class="p">,</span> <span class="s">'prince'</span> <span class="p">],</span> <span class="c"># House 2</span>
</span><span class='line'> <span class="p">[</span> <span class="s">'swede'</span><span class="p">,</span> <span class="s">'white'</span><span class="p">,</span> <span class="s">'bird'</span><span class="p">,</span> <span class="s">'milk'</span><span class="p">,</span> <span class="s">'blue master'</span> <span class="p">],</span> <span class="c"># House 3</span>
</span><span class='line'> <span class="p">[</span> <span class="s">'norwegian'</span><span class="p">,</span> <span class="s">'green'</span><span class="p">,</span> <span class="s">'fish'</span><span class="p">,</span> <span class="s">'coffee'</span><span class="p">,</span> <span class="s">'dunhill'</span> <span class="p">],</span> <span class="c"># House 4</span>
</span><span class='line'> <span class="p">[</span> <span class="s">'german'</span><span class="p">,</span> <span class="s">'blue'</span><span class="p">,</span> <span class="s">'dog'</span><span class="p">,</span> <span class="s">'root beer'</span><span class="p">,</span> <span class="s">'blends'</span> <span class="p">],</span> <span class="c"># House 5</span>
</span><span class='line'><span class="p">]</span>
</span></code></pre></td></tr></table></div></figure>
<p>For convenience, we’ll also define the following constants:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr></pre></td><td class='code'><pre><code class='python'><span class='line'><span class="n">NAT</span> <span class="o">=</span> <span class="mi">0</span> <span class="c"># Nationality index</span>
</span><span class='line'><span class="n">COL</span> <span class="o">=</span> <span class="mi">1</span> <span class="c"># Colour index</span>
</span><span class='line'><span class="n">ANI</span> <span class="o">=</span> <span class="mi">2</span> <span class="c"># Animal index</span>
</span><span class='line'><span class="n">BEV</span> <span class="o">=</span> <span class="mi">3</span> <span class="c"># Beverage index</span>
</span><span class='line'><span class="n">CIG</span> <span class="o">=</span> <span class="mi">4</span> <span class="c"># Cigar index</span>
</span></code></pre></td></tr></table></div></figure>
<p>Each index in the list for a house corresponds to a specific attribute as shown above.</p>
<p>Now we’re ready to define our simulated annealing procedure.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr></pre></td><td class='code'><pre><code class='python'><span class='line'><span class="kn">import</span> <span class="nn">math</span>
</span><span class='line'><span class="kn">import</span> <span class="nn">random</span>
</span><span class='line'>
</span><span class='line'><span class="k">def</span> <span class="nf">sa</span><span class="p">(</span><span class="n">initial</span><span class="p">):</span>
</span><span class='line'> <span class="c"># Define initial values</span>
</span><span class='line'> <span class="n">current</span> <span class="o">=</span> <span class="n">initial</span>
</span><span class='line'> <span class="n">current_cost</span> <span class="o">=</span> <span class="n">cost_of_state</span><span class="p">(</span><span class="n">current</span><span class="p">)</span>
</span><span class='line'> <span class="n">temp</span> <span class="o">=</span> <span class="mf">1.0</span> <span class="c"># initial value of t used in acceptance probability</span>
</span><span class='line'> <span class="n">num_iterations</span> <span class="o">=</span> <span class="mi">0</span>
</span><span class='line'>
</span><span class='line'> <span class="k">while</span> <span class="n">current_cost</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span> <span class="c"># keep going until we find the global minimum</span>
</span><span class='line'> <span class="n">num_iterations</span> <span class="o">+=</span> <span class="mi">1</span>
</span><span class='line'>
</span><span class='line'> <span class="n">neighbour</span> <span class="o">=</span> <span class="n">get_random_neighbour</span><span class="p">(</span><span class="n">current</span><span class="p">)</span>
</span><span class='line'> <span class="n">neighbour_cost</span> <span class="o">=</span> <span class="n">cost_of_state</span><span class="p">(</span><span class="n">neighbour</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'> <span class="n">cost_delta</span> <span class="o">=</span> <span class="n">neighbour_cost</span> <span class="o">-</span> <span class="n">current_cost</span>
</span><span class='line'>
</span><span class='line'> <span class="c"># If the neighbouring state is at least as good as the current state</span>
</span><span class='line'> <span class="c"># move to it, otherwise check the acceptance probability and only</span>
</span><span class='line'> <span class="c"># move if the random number is less than it</span>
</span><span class='line'> <span class="k">if</span> <span class="n">cost_delta</span> <span class="o"><=</span> <span class="mi">0</span> <span class="ow">or</span> <span class="n">random</span><span class="o">.</span><span class="n">random</span><span class="p">()</span> <span class="o"><</span> <span class="n">math</span><span class="o">.</span><span class="n">exp</span><span class="p">(</span><span class="o">-</span><span class="n">cost_delta</span><span class="o">/</span><span class="n">temp</span><span class="p">):</span>
</span><span class='line'> <span class="n">current</span><span class="p">,</span> <span class="n">current_cost</span> <span class="o">=</span> <span class="n">neighbour</span><span class="p">,</span> <span class="n">neighbour_cost</span>
</span><span class='line'>
</span><span class='line'> <span class="c"># Decrease the temperature by 0.05 every 500 iterations until it's at 0.20</span>
</span><span class='line'> <span class="k">if</span> <span class="n">num_iterations</span> <span class="o">%</span> <span class="mi">500</span> <span class="o">==</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">temp</span> <span class="o">></span> <span class="mf">0.20</span><span class="p">:</span>
</span><span class='line'> <span class="n">temp</span> <span class="o">-=</span> <span class="mf">0.05</span>
</span><span class='line'>
</span><span class='line'> <span class="c"># We found the solution!</span>
</span><span class='line'> <span class="c"># Return it and the number of iterations it took to get there</span>
</span><span class='line'> <span class="k">return</span> <span class="n">current</span><span class="p">,</span> <span class="n">num_iterations</span>
</span></code></pre></td></tr></table></div></figure>
<p>There’s two functions we haven’t defined yet that are used above. These are <code>get_random_neighbour</code> and <code>cost_of_state</code>.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr></pre></td><td class='code'><pre><code class='python'><span class='line'><span class="k">def</span> <span class="nf">get_random_neighbour</span><span class="p">(</span><span class="n">state</span><span class="p">):</span>
</span><span class='line'> <span class="n">neighbour</span> <span class="o">=</span> <span class="p">[</span><span class="n">house</span><span class="p">[:]</span> <span class="k">for</span> <span class="n">house</span> <span class="ow">in</span> <span class="n">state</span><span class="p">]</span> <span class="c"># Deep copy</span>
</span><span class='line'>
</span><span class='line'> <span class="n">i</span><span class="p">,</span> <span class="n">j</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">sample</span><span class="p">(</span><span class="nb">xrange</span><span class="p">(</span><span class="mi">5</span><span class="p">),</span> <span class="mi">2</span><span class="p">)</span>
</span><span class='line'> <span class="n">attr_idx</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">4</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'> <span class="n">neighbour</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">attr_idx</span><span class="p">],</span> <span class="n">neighbour</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="n">attr_idx</span><span class="p">]</span> <span class="o">=</span>
</span><span class='line'> <span class="n">neighbour</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="n">attr_idx</span><span class="p">],</span> <span class="n">neighbour</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">attr_idx</span><span class="p">]</span>
</span><span class='line'>
</span><span class='line'> <span class="k">return</span> <span class="n">neighbour</span>
</span></code></pre></td></tr></table></div></figure>
<p>We first deepcopy the current state since we don’t want to mutate the current state when determining the neighbour state. We then pick two houses to swap (<code>i</code> and <code>j</code>) and an <code>attr_index</code> (one of NAT, COL, ANI, BEV, and CIG, the constants we defined earlier). Finally, for the two houses picked, we swap their attribute choices for the corresponding attribute and return the neighbour state.</p>
<p>We now need to define the <code>cost_of_state</code> function, which when given a state returns its cost. As mentioned earlier, it will be the number of clues that are not satisfied by the state.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr></pre></td><td class='code'><pre><code class='python'><span class='line'><span class="k">def</span> <span class="nf">cost_of_state</span><span class="p">(</span><span class="n">state</span><span class="p">):</span>
</span><span class='line'> <span class="n">cost</span> <span class="o">=</span> <span class="mi">15</span>
</span><span class='line'> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">h</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">state</span><span class="p">):</span>
</span><span class='line'> <span class="n">cost</span> <span class="o">-=</span> <span class="nb">sum</span><span class="p">([</span>
</span><span class='line'> <span class="n">h</span><span class="p">[</span><span class="n">NAT</span><span class="p">]</span> <span class="o">==</span> <span class="s">'brit'</span> <span class="ow">and</span> <span class="n">h</span><span class="p">[</span><span class="n">COL</span><span class="p">]</span> <span class="o">==</span> <span class="s">'red'</span><span class="p">,</span>
</span><span class='line'> <span class="n">h</span><span class="p">[</span><span class="n">NAT</span><span class="p">]</span> <span class="o">==</span> <span class="s">'swede'</span> <span class="ow">and</span> <span class="n">h</span><span class="p">[</span><span class="n">ANI</span><span class="p">]</span> <span class="o">==</span> <span class="s">'dog'</span><span class="p">,</span>
</span><span class='line'> <span class="n">h</span><span class="p">[</span><span class="n">NAT</span><span class="p">]</span> <span class="o">==</span> <span class="s">'dane'</span> <span class="ow">and</span> <span class="n">h</span><span class="p">[</span><span class="n">BEV</span><span class="p">]</span> <span class="o">==</span> <span class="s">'tea'</span><span class="p">,</span>
</span><span class='line'> <span class="n">i</span> <span class="o"><</span> <span class="mi">4</span> <span class="ow">and</span> <span class="n">h</span><span class="p">[</span><span class="n">COL</span><span class="p">]</span> <span class="o">==</span> <span class="s">'green'</span> <span class="ow">and</span> <span class="n">state</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">][</span><span class="n">COL</span><span class="p">]</span> <span class="o">==</span> <span class="s">'white'</span><span class="p">,</span>
</span><span class='line'> <span class="n">h</span><span class="p">[</span><span class="n">COL</span><span class="p">]</span> <span class="o">==</span> <span class="s">'green'</span> <span class="ow">and</span> <span class="n">h</span><span class="p">[</span><span class="n">BEV</span><span class="p">]</span> <span class="o">==</span> <span class="s">'coffee'</span><span class="p">,</span>
</span><span class='line'> <span class="n">h</span><span class="p">[</span><span class="n">CIG</span><span class="p">]</span> <span class="o">==</span> <span class="s">'pall mall'</span> <span class="ow">and</span> <span class="n">h</span><span class="p">[</span><span class="n">ANI</span><span class="p">]</span> <span class="o">==</span> <span class="s">'bird'</span><span class="p">,</span>
</span><span class='line'> <span class="n">h</span><span class="p">[</span><span class="n">COL</span><span class="p">]</span> <span class="o">==</span> <span class="s">'yellow'</span> <span class="ow">and</span> <span class="n">h</span><span class="p">[</span><span class="n">CIG</span><span class="p">]</span> <span class="o">==</span> <span class="s">'dunhill'</span><span class="p">,</span>
</span><span class='line'> <span class="n">i</span> <span class="o">==</span> <span class="mi">2</span> <span class="ow">and</span> <span class="n">h</span><span class="p">[</span><span class="n">BEV</span><span class="p">]</span> <span class="o">==</span> <span class="s">'milk'</span><span class="p">,</span>
</span><span class='line'> <span class="n">i</span> <span class="o">==</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">h</span><span class="p">[</span><span class="n">NAT</span><span class="p">]</span> <span class="o">==</span> <span class="s">'norwegian'</span><span class="p">,</span>
</span><span class='line'> <span class="n">h</span><span class="p">[</span><span class="n">CIG</span><span class="p">]</span> <span class="o">==</span> <span class="s">'blends'</span> <span class="ow">and</span> <span class="p">((</span><span class="n">i</span> <span class="o">></span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">state</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">][</span><span class="n">ANI</span><span class="p">]</span> <span class="o">==</span> <span class="s">'cat'</span><span class="p">)</span>
</span><span class='line'> <span class="ow">or</span> <span class="p">(</span><span class="n">i</span> <span class="o"><</span> <span class="mi">4</span> <span class="ow">and</span> <span class="n">state</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">][</span><span class="n">ANI</span><span class="p">]</span> <span class="o">==</span> <span class="s">'cat'</span><span class="p">)),</span>
</span><span class='line'> <span class="n">h</span><span class="p">[</span><span class="n">ANI</span><span class="p">]</span> <span class="o">==</span> <span class="s">'horse'</span> <span class="ow">and</span> <span class="p">((</span><span class="n">i</span> <span class="o">></span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">state</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">][</span><span class="n">CIG</span><span class="p">]</span> <span class="o">==</span> <span class="s">'dunhill'</span><span class="p">)</span>
</span><span class='line'> <span class="ow">or</span> <span class="p">(</span><span class="n">i</span> <span class="o"><</span> <span class="mi">4</span> <span class="ow">and</span> <span class="n">state</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">][</span><span class="n">CIG</span><span class="p">]</span> <span class="o">==</span> <span class="s">'dunhill'</span><span class="p">)),</span>
</span><span class='line'> <span class="n">h</span><span class="p">[</span><span class="n">CIG</span><span class="p">]</span> <span class="o">==</span> <span class="s">'blue master'</span> <span class="ow">and</span> <span class="n">h</span><span class="p">[</span><span class="n">BEV</span><span class="p">]</span> <span class="o">==</span> <span class="s">'root beer'</span><span class="p">,</span>
</span><span class='line'> <span class="n">h</span><span class="p">[</span><span class="n">NAT</span><span class="p">]</span> <span class="o">==</span> <span class="s">'german'</span> <span class="ow">and</span> <span class="n">h</span><span class="p">[</span><span class="n">CIG</span><span class="p">]</span> <span class="o">==</span> <span class="s">'prince'</span><span class="p">,</span>
</span><span class='line'> <span class="n">h</span><span class="p">[</span><span class="n">NAT</span><span class="p">]</span> <span class="o">==</span> <span class="s">'norwegian'</span> <span class="ow">and</span> <span class="p">((</span><span class="n">i</span> <span class="o">></span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">state</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">][</span><span class="n">COL</span><span class="p">]</span> <span class="o">==</span> <span class="s">'blue'</span><span class="p">)</span>
</span><span class='line'> <span class="ow">or</span> <span class="p">(</span><span class="n">i</span> <span class="o"><</span> <span class="mi">4</span> <span class="ow">and</span> <span class="n">state</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">][</span><span class="n">COL</span><span class="p">]</span> <span class="o">==</span> <span class="s">'blue'</span><span class="p">)),</span>
</span><span class='line'> <span class="n">h</span><span class="p">[</span><span class="n">CIG</span><span class="p">]</span> <span class="o">==</span> <span class="s">'blends'</span> <span class="ow">and</span> <span class="p">((</span><span class="n">i</span> <span class="o">></span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">state</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">][</span><span class="n">BEV</span><span class="p">]</span> <span class="o">==</span> <span class="s">'water'</span><span class="p">)</span>
</span><span class='line'> <span class="ow">or</span> <span class="p">(</span><span class="n">i</span> <span class="o"><</span> <span class="mi">4</span> <span class="ow">and</span> <span class="n">state</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">][</span><span class="n">BEV</span><span class="p">]</span> <span class="o">==</span> <span class="s">'water'</span><span class="p">)),</span>
</span><span class='line'> <span class="p">])</span>
</span><span class='line'>
</span><span class='line'> <span class="k">return</span> <span class="n">cost</span>
</span></code></pre></td></tr></table></div></figure>
<p>The above 15 boolean expressions correspond to the 15 clues in the order they were presented at the beginning of this post. For each house, we check how many clues are satisfied and subtract this total from the current cost. After doing this for each house we have our cost for the state.</p>
<p>Finally we have everything we need to run the simulated annealing technique.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr></pre></td><td class='code'><pre><code class='python'><span class='line'><span class="n">random</span><span class="o">.</span><span class="n">seed</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="n">solution</span><span class="p">,</span> <span class="n">iterations</span> <span class="o">=</span> <span class="n">sa</span><span class="p">(</span><span class="n">initial</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="k">for</span> <span class="n">house</span> <span class="ow">in</span> <span class="n">solution</span><span class="p">:</span>
</span><span class='line'> <span class="k">print</span> <span class="n">house</span>
</span><span class='line'>
</span><span class='line'><span class="k">print</span> <span class="s">'Number of iterations:'</span><span class="p">,</span> <span class="n">iterations</span>
</span></code></pre></td></tr></table></div></figure>
<p>We use a seed value of 100 for the random number generator so we can produce the same results over and over. The output of the above is:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr></pre></td><td class='code'><pre><code class='python'><span class='line'><span class="p">[</span><span class="s">'norwegian'</span><span class="p">,</span> <span class="s">'yellow'</span><span class="p">,</span> <span class="s">'cat'</span><span class="p">,</span> <span class="s">'water'</span><span class="p">,</span> <span class="s">'dunhill'</span><span class="p">]</span>
</span><span class='line'><span class="p">[</span><span class="s">'dane'</span><span class="p">,</span> <span class="s">'blue'</span><span class="p">,</span> <span class="s">'horse'</span><span class="p">,</span> <span class="s">'tea'</span><span class="p">,</span> <span class="s">'blends'</span><span class="p">]</span>
</span><span class='line'><span class="p">[</span><span class="s">'brit'</span><span class="p">,</span> <span class="s">'red'</span><span class="p">,</span> <span class="s">'bird'</span><span class="p">,</span> <span class="s">'milk'</span><span class="p">,</span> <span class="s">'pall mall'</span><span class="p">]</span>
</span><span class='line'><span class="p">[</span><span class="s">'german'</span><span class="p">,</span> <span class="s">'green'</span><span class="p">,</span> <span class="s">'fish'</span><span class="p">,</span> <span class="s">'coffee'</span><span class="p">,</span> <span class="s">'prince'</span><span class="p">]</span>
</span><span class='line'><span class="p">[</span><span class="s">'swede'</span><span class="p">,</span> <span class="s">'white'</span><span class="p">,</span> <span class="s">'dog'</span><span class="p">,</span> <span class="s">'root beer'</span><span class="p">,</span> <span class="s">'blue master'</span><span class="p">]</span>
</span><span class='line'><span class="n">Number</span> <span class="n">of</span> <span class="n">iterations</span><span class="p">:</span> <span class="mi">9870</span>
</span></code></pre></td></tr></table></div></figure>
<p>We found the solution! In 9870 iterations of simulated annealing, we found that the German has the fish in the fourth house. We only had to look at about 0.00004% of the possibilities to find the solution. If you’d like to review the code in full, it can be found <a href="https://gist.github.com/agnanachandran/1cdb49e8360d4c1ac8bea877c252aed3">here</a>.</p>
<p>Although taking the time to code this may have taken longer than to solve the problem by hand, this technique can be applied to many other problems, most notably, the <a href="https://en.wikipedia.org/wiki/Travelling_salesman_problem">Travelling Salesman Problem</a> in which we would swap cities instead. The only things we would need to change are the state representation, the neighbouring state selection, and the cost function. The technique itself is generally applicable to all sorts of problems.</p>
<h3>Final Notes</h3>
<p>It’s worth noting that simulated annealing has many tunable parameters (initial temperature, temperature reduction function, stopping conditions, acceptance probability function). If these are changed, the number of iterations taken to find the solution can vary drastically. In my tests, I saw as many as a million iterations and as few as 200 iterations to converge to the solution. Choosing the parameters wisely is part of the art of making simulated annealing performant.</p>
<p>Logic problems can be often be solved in a variety of ways. Doing it this way allows us to do very little thinking with regards to the clues and how they all relate to each other. We let the computer do the work for us.</p>
<p>The applications of techniques like this are of course not limited to logic puzzles like this. Simulated annealing in particular can be used for circuit board placement, physics simulations, and structural optimization. Artificial intelligence techniques in general have wide-reaching applications and implications. Learning about different techniques is both interesting and valuable, if only for solving fun logic puzzles like this one.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Short Interval Updating in Angular]]></title>
<link href="http://agnanachandran.github.io/blog/2015/08/15/short-interval-updating-in-angular/"/>
<updated>2015-08-15T22:51:00-04:00</updated>
<id>http://agnanachandran.github.io/blog/2015/08/15/short-interval-updating-in-angular</id>
<content type="html"><![CDATA[<p>Let’s take a look at a problem. We have a webapp to track build times for a continuous integration (CI) server. The main page has an HTML table with dozens of rows (one row for each build) and each row has an entry for the creation time of the build and the length of time it took for the build to be deployed, tested, or whatever else you’re doing with your CI server.</p>
<p>For most rows in your table, the duration can be populated with information from the server. The server sends back a creation time, and if the build is finished, a finishing time. Both the creation time and finishing time are specified in a milliseconds version of <a href="https://en.wikipedia.org/wiki/Unix_time">Unix time</a>. The duration is easy enough to calculate. Firstly, in Angular we would opt to use the <code>ng-repeat</code> directive to display the data in a table:</p>
<!-- more -->
<p>(I use double square brackets instead of double curly braces in Angular templating here because it conflicts with the rendering engine I use for this blog)</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr></pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt"><tr</span> <span class="na">ng-repeat=</span><span class="s">"contentData in content"</span><span class="nt">></span>
</span><span class='line'> <span class="nt"><td</span> <span class="na">ng-repeat=</span><span class="s">"header in headers"</span><span class="nt">></span>
</span><span class='line'> [[contentData[header].value]]
</span><span class='line'> <span class="nt"></td></span>
</span><span class='line'><span class="nt"></tr></span>
</span></code></pre></td></tr></table></div></figure>
<p>and a specific <code>contentData</code> object would look something like:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr></pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">var</span> <span class="nx">contentData</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'> <span class="p">...</span>
</span><span class='line'> <span class="nx">durationString</span><span class="o">:</span> <span class="nx">getDurationString</span><span class="p">(</span><span class="nx">msTimeDifferenceInSeconds</span><span class="p">(</span>
</span><span class='line'> <span class="nx">serverData</span><span class="p">.</span><span class="nx">creationTime</span><span class="p">,</span> <span class="nx">serverData</span><span class="p">.</span><span class="nx">finishingTime</span><span class="p">)),</span>
</span><span class='line'> <span class="p">...</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'><span class="nx">$scope</span><span class="p">.</span><span class="nx">content</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">contentData</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="kd">function</span> <span class="nx">msTimeDifferenceInSeconds</span><span class="p">(</span><span class="nx">startTime</span><span class="p">,</span> <span class="nx">endTime</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">msDifference</span> <span class="o">=</span> <span class="nx">endTime</span> <span class="o">-</span> <span class="nx">startTime</span><span class="p">;</span>
</span><span class='line'> <span class="k">return</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">ceil</span><span class="p">(</span><span class="nx">msDifference</span><span class="o">/</span><span class="mi">1000</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>where getDurationString(seconds) is some function that returns a nicer version of a duration in seconds.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr></pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">getDurationString</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="o">=></span> <span class="mi">1</span> <span class="nx">second</span>
</span><span class='line'><span class="nx">getDurationString</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span> <span class="o">=></span> <span class="mi">1</span> <span class="nx">minute</span><span class="p">,</span> <span class="mi">40</span> <span class="nx">seconds</span>
</span><span class='line'><span class="nx">getDurationString</span><span class="p">(</span><span class="mi">10000</span><span class="p">)</span> <span class="o">=></span> <span class="mi">2</span> <span class="nx">hours</span><span class="p">,</span> <span class="mi">46</span> <span class="nx">minutes</span><span class="p">,</span> <span class="mi">40</span> <span class="nx">seconds</span>
</span></code></pre></td></tr></table></div></figure>
<p>What about the (arguably more interesting) case when a build isn’t complete? We want to update the duration every second for every row in the table whose corresponding build is incomplete. We would also want to poll the server every so often so that the table displays the most updated information. How would you do this sort of thing in Angular?</p>
<p>Well the obvious thing to do would be to have a function that updates the specific model data for the build that contains the duration. Store the duration as part of the model data for the build, and update it (and the value that’s display in the HTML table through getDurationString) every second. Something similar to the following pseudocode:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr></pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">var</span> <span class="nx">durationInterval</span> <span class="o">=</span> <span class="nx">$interval</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="k">for</span> <span class="nx">each</span> <span class="nx">contentData</span> <span class="k">in</span> <span class="nx">$scope</span><span class="p">.</span><span class="nx">content</span><span class="o">:</span>
</span><span class='line'> <span class="k">if</span> <span class="o">!</span><span class="p">(</span><span class="nx">contentData</span><span class="p">.</span><span class="nx">isFinished</span><span class="p">())</span><span class="o">:</span>
</span><span class='line'> <span class="nx">contentData</span><span class="p">.</span><span class="nx">duration</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'> <span class="nx">contentData</span><span class="p">.</span><span class="nx">durationString</span> <span class="o">=</span> <span class="nx">getDurationString</span><span class="p">(</span><span class="nx">contentData</span><span class="p">.</span><span class="nx">duration</span><span class="p">);</span>
</span><span class='line'><span class="p">},</span> <span class="mi">1000</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>
<p>and we could have this code run just after loading all the data into the <code>content</code> array. We can stop this interval and restart it upon polling for updated data from the server.</p>
<p>Since this is executing once every second, the duration property increments every second. This seems like an okay solution. Angular will automatically update the DOM for us once it sees that the underlying model has changed.</p>
<p>But there’s a couple major problems with it. For one, there’s a fairly large delay between the first element in the <code>content</code> array being populated with the finishing time and the time that the <code>durationInterval</code> gets set off (more than 1 second). This effect compounds with other delays and effects the rest of the <code>content</code> array as well. We can sort of solve this by calculating the duration again using the current time (<code>new Date().getTime</code>) and the known creation time every second, since it’s not really that expensive.</p>
<p>A bigger issue still is that it takes time for the DOM to update. Angular needs to realize the <code>content</code> array has been changed and update the appropriate parts of the DOM (specifically the duration column in the table for every affected row). This happens in the <code>$digest</code> cycle Angular uses to update the DOM upon model changes. This can take a substantial amount of time and adds further delay to the DOM updating.</p>
<p>Implementing this solution, I found the table updates about 10 times in 14 seconds. It should have updated 14 times though. We can’t update the model directly and wait for Angular to update the DOM.</p>
<p>An alternative solution would be to update the DOM ourselves. Since this is just a simple table cell and not an input element, Angular won’t check it as part of its 2-way data binding procedures. In other words, when we update a table cell, the corresponding model in the Javascript won’t change, which is what we want.</p>
<p>We simply want to update the table cell every second. First, we have to find the table cell. One way to do this would be to place a unique id on the table cell</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr></pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="o"><</span><span class="nx">td</span> <span class="nx">ng</span><span class="o">-</span><span class="nx">attr</span><span class="o">-</span><span class="nx">id</span><span class="o">=</span><span class="s2">"[[header.field + '-' + $parent.$index + '-cell']]"</span> <span class="p">...</span><span class="o">></span>
</span></code></pre></td></tr></table></div></figure>
<p>and we can easily find the table cell we wish to modify.</p>
<p>We could parse what’s in the table cell (a <code>durationString</code> like 3 minutes and 4 seconds) back to a time in seconds (184), add 1, and transform it back to a <code>durationString</code>. But that’s more work than necessary, and can result in the time slowly drifting (so naturally, I tried that first). We’ll just go with the approach of calculating the duration each time for every applicable row (once for each incomplete build), and updating the table cell’s <code>innerHTML</code> with our updated data.</p>
<p>The finished product looks something like this:</p>
<p><img class="center" src="http://agnanachandran.github.io/images/angular_timer.gif" width="410" height="334"></p>
<p>This solution works super well; the duration field in the table correctly updates once every second. And that’s the solution to our problem.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[When StackOverflow isn't the answer]]></title>
<link href="http://agnanachandran.github.io/blog/2014/04/06/when-stackoverflow-isnt-the-answer/"/>
<updated>2014-04-06T20:10:00-04:00</updated>
<id>http://agnanachandran.github.io/blog/2014/04/06/when-stackoverflow-isnt-the-answer</id>
<content type="html"><![CDATA[<p>I spent the better half of today debugging one of my current projects, an Android app designed to help users do things on their phone faster. Vague, I know.</p>
<p>The issue at hand was a <code>java.lang.IllegalStateException</code> resulting from a fragment not being attached to its activity. Reproducing the bug was easy. Launch the app, search for a YouTube video, back out of the app, and search for another YouTube video. The app crashes. An easy ‘solution’ was to check <code>fragment.isAdded()</code> in the <code>onVideosRetrieved</code> callback. Of course, the real problem is that the fragment still wasn’t attached to an activity.</p>
<!-- more -->
<blockquote><p><a href="http://developer.android.com/guide/components/fragments.html">“A fragment must always be embedded in an activity”</a>.</p></blockquote>
<p>Searching every relevant stackoverflow answer yielded nothing. I tried switching to the non-support version of <code>fragment</code>, not using a <code>FragmentActivity</code>, and not using the <code><fragment></code> tag in the activity layout. Nothing changed.</p>
<p>The answer revealed itself to me after reading a tangentially related answer</p>
<blockquote><p><a href="http://stackoverflow.com/questions/11536166/android-get-activity-returns-null">“This can happen if you’re trying to keep references to your Fragments, rather than accessing them via the FragmentManager.”</a></p></blockquote>
<h3>Singleton misuse</h3>
<p>I immediately remembered all the “Manager” classes I had, which for some reason, I decided should be singletons.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr></pre></td><td class='code'><pre><code class='java'><span class='line'><span class="kd">public</span> <span class="kd">static</span> <span class="n">WeatherManager</span> <span class="nf">getInstance</span><span class="o">(</span><span class="n">Fragment</span> <span class="n">fragment</span><span class="o">,</span> <span class="n">OnFinishedListener</span> <span class="n">listener</span><span class="o">)</span> <span class="o">{</span>
</span><span class='line'> <span class="k">if</span> <span class="o">(</span><span class="n">instance</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
</span><span class='line'> <span class="n">instance</span> <span class="o">=</span> <span class="k">new</span> <span class="n">WeatherManager</span><span class="o">(</span><span class="n">fragment</span><span class="o">,</span> <span class="n">listener</span><span class="o">);</span>
</span><span class='line'> <span class="o">}</span>
</span><span class='line'> <span class="k">return</span> <span class="n">instance</span><span class="o">;</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>Oops.</p>
<p>The static reference to the WeatherManager instance is of course kept across the lifetime of the app, and thus, so is the fragment, and its reference to its activity. Big mistake. Fragments are detached from their activity as necessary when the app is backgrounded. By maintaining this static reference, not only was more memory being consumed, but the fragment couldn’t reattach itself to the activity (presumably due to the logic present in <code>Fragment.java</code>).</p>
<p>What did I learn from all this?</p>
<p>1) Don’t use singletons if you don’t need to. Or rather, make sure you understand the reason you’re using them in the first place.</p>
<p>2) StackOverflow is a tremendous help in most situations. And it was a great help here too (so my title is a lie). <a href="https://xkcd.com/979/">Sometimes, you have to figure it out yourself</a>. And if/when you do, you’ll probably facepalm.</p>
<p>Singletons. Not even once.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[On 2048]]></title>
<link href="http://agnanachandran.github.io/blog/2014/03/14/on-2048/"/>
<updated>2014-03-14T23:08:00-04:00</updated>
<id>http://agnanachandran.github.io/blog/2014/03/14/on-2048</id>
<content type="html"><![CDATA[<p>This week on Hacker News, a game called 2048 rose to the top of the front page. Subsequently, productivity at software companies everywhere dropped tremendously.</p>
<p><a href="http://gabrielecirulli.github.io/2048/">The game itself is quite simple</a>. Use the arrow keys and get the numbered tiles to combine over and over again until you get a ‘2048’ tile.</p>
<p>The game is partially (read: very) luck-based. When the board is getting tight, a single wrong number, or a number popping up in the wrong place, can mess you up for the rest of the game.</p>
<!-- more -->
<p>The general strategy to winning the game is a simple one. Keep your largest number in the corner, and progressively smaller numbers next to it in a row/column. Doing this guarantees you won’t have useless pieces floating around the board (as long as you don’t move a piece in the row/column in any perpendicular direction), and provides a systematic method to playing the game. You’re then limited to moving in only a couple directions.</p>
<br>
<p><span class="caption-wrapper center" style="width: 600px"><img class="caption" src="http://agnanachandran.github.io/images/small_moment.png" title="'About to win'" ><span class="caption-text"></span></span></p>
<br>
<p>The game is pretty addicting; you feel some sense of satisfaction when pieces combine to make numbers twice as large (and twice as yellow). The larger the number , the greater the satisfaction. After finally beating the game, I’m probably not going to play it again, at least not to completion.</p>
<p>What is interesting is the viral nature of the game’s popularity. What started as a Hacker News post with thousands of points, became an office-phenomenon at the place I currently work. Walking by people, you’d see random computers with the game shamelessly front and centre on the screen. I have no doubt that the same sort of thing happened at other software companies.</p>
<p>Also of interest are the numerous spinoffs of this game. There’s been everything from 2 (like 2048, except starting at the opposite end and numbers get halved instead of doubled when they meet), to 2048 made in python and available in the terminal.</p>
<p>There’s also an AI that uses the <a href="http://en.wikipedia.org/wiki/Minimax">Minimax algorithm</a> to play the game. <a href="http://ov3y.github.io/2048-AI/">It’s kinda cool to watch</a>. It doesn’t win every time, but when it does, it’s pretty spectacular.</p>
<p>Overall, the game is fairly well made. It’s not an original idea (the author states his inspirations), but it’s a good one. It hooked me for hours. Maybe it’ll do the same thing to you.</p>
<br>
<p><img class="center" src="http://agnanachandran.github.io/images/small_win.png" title="win" alt="Image of a win"></p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[How to do X in Octopress]]></title>
<link href="http://agnanachandran.github.io/blog/2013/12/20/how-to-do-x-in-octopress/"/>
<updated>2013-12-20T23:11:00-05:00</updated>
<id>http://agnanachandran.github.io/blog/2013/12/20/how-to-do-x-in-octopress</id>
<content type="html"><![CDATA[<p>So I spent the last couple days tweaking my Octopress themes and relearning how to do things since not blogging for a while and getting a new MBP. Navigating the Octopress file hierarchy isn’t easy, but hopefully this post will help you (and be a useful reference for myself).</p>
<!-- more -->
<p>So, let’s start with a preview of what we have to work with. If you’re reading this, I assume you know a bit about Git, the Unix shell, and what Octopress is.</p>
<p>Let’s start with the file hierarchy, my current setup, and the Git configuration.</p>
<h3>My current setup:</h3>
<p>For starters, I’m using [oh-my] zsh with the popular <u>Solarized</u> colour scheme. A typical Octopress folder looks something like this:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr></pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>tree octopress -LF 1
</span><span class='line'>octopress
</span><span class='line'>├── CHANGELOG.markdown
</span><span class='line'>├── Gemfile
</span><span class='line'>├── Gemfile.lock
</span><span class='line'>├── README.markdown
</span><span class='line'>├── README.md
</span><span class='line'>├── Rakefile
</span><span class='line'>├── _config.yml
</span><span class='line'>├── _deploy/
</span><span class='line'>├── config.rb
</span><span class='line'>├── config.ru
</span><span class='line'>├── plugins/
</span><span class='line'>├── public/
</span><span class='line'>├── sass/
</span><span class='line'>└── <span class="nb">source</span>/
</span><span class='line'>
</span><span class='line'>5 directories, 9 files
</span></code></pre></td></tr></table></div></figure>
<p>A typical Octopress configuration uses two branches (master and source). I use GitHub Pages for deployment and it looks for files in the master branch. But while editing posts and stylesheets, we really only have to worry about the source branch.</p>
<h3>Top-level Configuration</h3>
<p>_config.yml holds various top-level/administrative info for your blog. This is where you’d put your blog’s name, your Disqus shortname (if applicable), what links you want in your navigation bar, usernames for various services (GitHub, Facebook, G+, etc.), Google analytics tracking ID, and so on.</p>
<h3>Rake Tasks</h3>
<p>A quick primer for non-ruby enthusiasts:
<code>rake</code> is basically the Ruby version of <code>GNU make</code>. Some of the useful rake tasks descriptions are below. Upon executing any of the below rake tasks, a number of useful commands will be run resulting in some otherwise complex thing being completed.</p>
<p><strong>clean</strong> — clean out caches: .pygments-cache, .gist-cache, .sass-cache</p>
<p><strong>deploy</strong> — default deploy task</p>
<p><strong>gen_deploy</strong> — generate website and deploy</p>
<p><strong>generate</strong> — generate jekyll site</p>
<p><strong>install[theme]</strong> — initial setup for octopress: copies the default theme into the path of jekyll’s generator.</p>
<p><strong>list</strong> — list tasks</p>
<p><strong>new_post[title]</strong> — begin a new post in source/_posts</p>
<p><strong>preview</strong> — preview the site in a web browser</p>
<p><strong>watch</strong> — watch the site and regenerate when it changes</p>
<h3>Writing a new post</h3>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr></pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>rake new_post<span class="o">[</span><span class="s1">'New post title with Punctuation!'</span><span class="o">]</span>
</span></code></pre></td></tr></table></div></figure>
<p>creates a Markdown file in <code>source/_posts</code> named “2013-12-28-new-post-title-with-punctuation.markdown”, for example.</p>
<p>Deleting the file effectively deletes the post (assuming you haven’t already published the post to the interwebs)</p>
<p>If you’d like to preview your post in the browser,</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr></pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>rake preview
</span></code></pre></td></tr></table></div></figure>
<p>will do the trick and show you your blog at localhost:4000 (<a href="http://whatismyipaddress.com/localhost">more info on localhost</a>). HTTP requests and responses will be logged in the same terminal window, so I recommend opening a seperate tab/window specifically for running this process.</p>
<p>Upon saving the file and refreshing the browser window, you’ll see how your post (along with the rest of the blog) will look.</p>
<p>Lastly, saving your post’s progress (anything done in the source branch really), can be done through</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr></pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span>git add .
</span><span class='line'><span class="nv">$ </span>git commit -m <span class="s1">'Your helpful message goes here'</span>
</span><span class='line'><span class="nv">$ </span>git push origin <span class="nb">source</span>
</span></code></pre></td></tr></table></div></figure>
<h3>Changing themes</h3>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr></pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span><span class="nb">cd </span>octopress
</span><span class='line'><span class="nv">$ </span>git clone GIT_URL .themes/THEME_NAME
</span><span class='line'><span class="nv">$ </span>rake install<span class="o">[</span><span class="s1">'THEME_NAME'</span><span class="o">]</span>
</span><span class='line'><span class="nv">$ </span>rake generate
</span></code></pre></td></tr></table></div></figure>
<p>A number of themes are available <a href="https://github.com/imathis/octopress/wiki/3rd-Party-Octopress-Themes">here</a>. I’ve opted for the <a href="https://github.com/mikeclarke/villainy-octopress-theme">“villainy”</a> theme with several personal customizations. I’ll detail how I did those changes below.</p>
<h3>Make your blog feel like home</h3>
<p>Disclaimer: If you’re anything like me, you may spend several hours tweaking the various SCSS, HTML, and JS files at your disposal. It’s pretty addicting.</p>
<p>A little trick I use when I want to find where a specific css selector’s attributes are defined is to use <code>fgrep</code>. For example, running</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr></pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nv">$ </span><span class="nb">cd </span>sass
</span><span class='line'><span class="nv">$ </span>fgrep -r <span class="s1">'meta'</span> *
</span><span class='line'><span class="c"># For long results, pipe to 'less' if desired</span>
</span></code></pre></td></tr></table></div></figure>
<p>finds me the exact SASS file(s) I need (and any duplicate declarations that need to be eliminated).</p>
<p>A more detailed description can be found <a href="http://octopress.org/docs/theme/">here</a>.</p>
<p>That’s all for now folks; if there’s anything you’d like me to add, shoot me an <a href="mailto:anojhgnanachandran@gmail.com">email</a>!</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[A Masterpiece of Music]]></title>
<link href="http://agnanachandran.github.io/blog/2013/07/29/a-masterpiece-of-music/"/>
<updated>2013-07-29T23:29:00-04:00</updated>
<id>http://agnanachandran.github.io/blog/2013/07/29/a-masterpiece-of-music</id>
<content type="html"><![CDATA[<p><em>Originally posted June 23rd, 2013</em></p>
<p>I was at a grocery store a couple weeks back, and over the PA system, I heard the lyrics “we are, we are we are, we are we are”, and for some reason, I thought it was catchy. It sounded like Kesha, so I had a starting point for searching (and I was too embarrassed to use Soundhound/Shazam in public to recognize the song).</p>
<!-- more -->
<p>I eventually found the song <a href="http://www.youtube.com/watch?v=xdeFB7I0YH4">“Crazy Kids“</a>. Before you read the rest of this, I’d recommend watching the entire video from start to finish (you’ll enjoy this post much more).</p>
<p>Note: viewing the linked video may lower your IQ by 20-40 points. You may experience feelings of hopelessness in humanity, despair, and/or intense hatred of dreadlocks.</p>
<p>Classic Kesha.</p>
<p>I proceeded to watch the mind-bogglingly stupid music video. I knew pop music videos were usually pretty bad, especially ones from Kesha, but this was so bad that I had to write about it. So, here’s my totally not sarcastic review of the video.</p>
<p>It starts off with her strutting towards the camera in the most ridiculous outfit I’ve ever seen; a baby blue hoodie adorned with pink-circle-flower-things, over-sized golden glasses which obviously serve no purpose, “grills”, several gold chains, necklaces, rings, and earrings.</p>
<p>Then she attempts to rap. I do have to give her some credit for some of these genius rhymes:</p>
<blockquote><p>Catch a dub, catch a deuces<br/>
Ya’ll hatins useless<br/>
It’s such a nuisance<br/>
Ya’ll chickens keep your two cents</p></blockquote>
<p>I’m not sure what she’s trying to say here, or how she managed to mangle the last words of each of those sentences so that they “rhyme”, but it’s great. No complaints here.</p>
<p><a href="http://youtu.be/xdeFB7I0YH4?t=54s">She then says</a>:</p>
<blockquote><p>Them boys, they want my coochie<br/>
I say nope, I’m no hootchie<br/>
You’re no hootchie? Ehh I’m not so sure Kesha.</p></blockquote>
<p>Let’s formally analyze this one:</p>
<p>Urban dictionary, a reliable source on slang, says a hootchie is “trashy, fowl talking, provocative dressing, loud, appearing confident but stupid.”</p>
<p>Nope, not Kesha, sorry about that, I was wrong.</p>
<p><a href="http://youtu.be/xdeFB7I0YH4?t=56s">At the same time</a>, she opens a refrigerator of what appears to be dozens of bottles of urine. She should probably clear out her collection before the rest of the partiers arrive.</p>
<p>Let’s talk about the chorus for a second. Kesha greets us with a classic “hello”, wherever we are, and proceeds to ask whether we are dancing on the dance floor or drinking by the bar (she rhymes “bar” with “are”, genius 3 letter rhyme that I haven’t thought of since the 3rd grade).</p>
<p><a href="http://youtu.be/xdeFB7I0YH4?t=1m36s">At 1:38 in the video</a>, there’s some sort of golden spaceman playing what looks like pinball; turns out it’s will.i.am. A green hologram of his face is superimposed on the mask of the astronaut and he begins to sing.</p>
<p>I think I had a nightmare of this exact scenario once.</p>
<p>He uses some terrific similes and symbolism with lyrics like “I took her to my place to blast off like the shuttle”, and completes his verse with some of the greatest lyrics in history. This part deserves a section of its own.</p>
<p>Most of the songs I listen to, I can tell the lyricists really put effort into the lyrics they wrote. They have meaning, they rhyme, they flow well. They do something that elicits some emotional response from the listener.</p>
<p>I have never seen lyrics as amazing as what comes out of will.i.am’s mouth next.</p>
<blockquote><p>Kissin’ while we talkin’<br/>
So I’m speaking with a mumble<br/>
Dibidiboodiboobouyewejoubeeguidibmble</p></blockquote>
<p>I tried really hard to transcribe that last lyric, but basically he mumbles. It’s really something you have to hear for yourself to fully appreciate the artistry that went into this lyric alone. To end his verse with that lyric is really a testimony to will.i.am’s musical abilities and the level of intelligence that is expected of will.i.am’s listeners. I know now that at any time I want to see the pinnacle of the history of musical talent, I can go to this video and listen at the 2:05 mark for “Dibidiboodiboobouyewejoubeeguidibmble”. In the future, we will compare the lyrics of other great artists against this lyric right here. We will not rate things out of 10, we will rate them in terms of how good they are compared to “Dibidiboodiboobouyewejoubeeguidibmble”. I for one can not wait for this level of lyrical mastery to be surpassed, but I fear it will not come for a long time.</p>
<p>Long live “Dibidiboodiboobouyewejoubeeguidibmble”.</p>
<p>Immediately after we see some hippies elderly people dancing in and around a pool. They dance with Kesha wearing another one of her golden outfits (presumably to attract the opposite gender, kinda like a peacock’s feathers, except I don’t think she’ll be attracting much at all).</p>
<p>They proceed to do an interesting “dance” involving the “Great Flapping of the Hands” ritual I’ve heard so much about, and the “Immaculate Wobbling of the Legs” to signify that they really are the “Crazy Kids.”</p>
<p>After singing another verse, she goes back into the chorus, continues the Great Flapping of the Hands (I believe you have to do it twice for it to count), and ends the video after 3:54 of bad music.</p>
<p>I’ve heard several pieces by Vivaldi, Mozart, Beethoven, and the like, but this is on a whole different level. I did not even know this level of musical ingenuity was possible. Kesha and will.i.am show us the true power of music and what can be done with the fantastic video technology we have today in their Crazy Kids video.</p>
<p>All in all, Kesha and will.i.am set the bar higher than ever before for music videos and I am continuously amazed by what can be done when you put two talented musicians like will.i.am and kesha and tell them to make music together.</p>
<p>I’m giving this one a 2/10. For effort.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Software Engineering at the University of Waterloo]]></title>
<link href="http://agnanachandran.github.io/blog/2013/07/29/software-engineering-at-the-university-of-waterloo/"/>
<updated>2013-07-29T00:23:00-04:00</updated>
<id>http://agnanachandran.github.io/blog/2013/07/29/software-engineering-at-the-university-of-waterloo</id>
<content type="html"><![CDATA[<p>This post was inspired by <a href="http://aimango.wordpress.com/2013/05/12/software-engineering-waterloo-courses/">a fellow software engineering student at UW</a>. If you want even more detail than I’m providing here, check it out.</p>
<p><em>Last updated December 29th, 2013</em></p>
<h2>The Courses</h2>
<p>Here’s a quick list of the courses I’ve taken (the full curriculum can be found <a href="https://uwaterloo.ca/software-engineering/class-2017-2a#course%20sequence">here</a>):</p>
<!-- more -->
<h4>First Term (Fall 2012) 1A:</h4>
<ul>
<li><p>CS 137 – Programming Principles</p></li>
<li><p>ECE 105 – Physics of Electrical Engineering I</p></li>
<li><p>ECE 140 – Linear Circuits</p></li>
<li><p>MATH 115 – Linear Algebra for Engineering</p></li>
<li><p>MATH 117 – Calculus I for Engineering</p></li>
</ul>
<h4>Second Term (Winter 2013) 1B:</h4>
<ul>
<li><p>CS 138 – Introduction to Data Abstraction and Implementation</p></li>
<li><p>ECE 106 – Physics of Electrical Engineering 2</p></li>
<li><p>ECE 124 – Digital Circuits and Systems</p></li>
<li><p>MATH 119 – Calculus II for Engineering</p></li>
<li><p>MATH 135 – Algebra for Honours Mathematics</p></li>
</ul>
<h4>Third Term (Fall 2013) 2A:</h4>
<ul>
<li><p>CS 241 – Foundations of Sequential Programs</p></li>
<li><p>ECE 222 – Digital Computers</p></li>
<li><p>CHE 102 – Chemistry for Engineers</p></li>
<li><p>SE 212 – Logic and Computation</p></li>
<li><p>STAT 206 – Statistics for Software Engineers</p></li>
<li><p>(elective) PSYCH 101 – Introductory Psychology</p></li>
</ul>
<hr />
<h2>First Term:</h2>
<p>I didn’t really know what to expect going into this term; people say your average will drop 10-30%. I found that that’s not true for everyone. You can drop a lot more, and you can drop less. It all depends on your work ethic, innate abilities, and willpower.</p>
<p>A quick disclaimer before I go on, any information here is only completely valid for the term I took it. If/when you take it, it may be slightly different. Your enjoyment and how much you get out of the course will also depend on the instructor. Also, my abilities and your abilities will be different. I try my best to speak to the average prospective student.</p>
<h3>CS 137 – Programming Principles</h3>
<p><em>Relevant xkcd: <a href="http://xkcd.com/138/">http://xkcd.com/138/</a></em></p>
<p>Your standard introductory CS course. Covers big-O notation (read here for more info: <a href="http://stackoverflow.com/questions/487258/plain-english-explanation-of-big-o">http://stackoverflow.com/questions/487258/plain-english-explanation-of-big-o</a>), <a href="https://www.google.ca/search?q=recursion">recursion</a>, methods, sorting and searching, and of course pointers, since the course uses C. If you know any Java, or any other C-like programming language, you shouldn’t have too much trouble.</p>
<p>Many people in my class took notes on paper; I opted for writing on a laptop; I highly recommend doing this for both CS 137 and CS 138 for a couple reasons. You won’t have to type it up again to see what the code does, and you’ve got syntax highlighting so you can more easily read it.</p>
<p>Assignments: Enjoyable; they are paced reasonably well, and if you have a year or two of programming experience, you should be good. Working with pointers was really the only new thing for me in this course, coming from a Java background.</p>
<p>The assignments themselves are marked with an online judge called “Marmoset”. You submit your code, it’s graded based on a comparison between your output and the expected (correct) output and you are awarded points. You may submit as many times as possible until the time it’s due. The catch is as follows. First you start by trying to pass the public (easier) tests. You have unlimited tries for these, and you can submit as often as you want. Once you get these all correct, you move on to what are called release tests. You need tokens to try a release test. You have 3 release tokens and every time you attempt the release tests, you lose a token. The token regenerates after 12 hours. Once you pass the release tests, you get 100% on the assignment. If you don’t pass all the release tests, once the deadline arrives, you get whatever points you were able to get from the public and release tests that you were able to pass.</p>
<h3>ECE 105 – Physics of Electrical Engineering I</h3>
<p><em>Hahaha. Hahahahahaha…</em></p>
<p>This course is infamous for a few reasons. Despite being high school level physics content for the most part (just mechanics, no electromagnetism), there’s a couple reasons why people don’t like this course.</p>
<p>Mastering Physics: Weekly assignments with about 10 questions to answer. They are purely short answer with some multiple choice and true and false. This means there’s no place to show your work; it’s either right or wrong. However, you get 3 chances for each question (except for the true/false of course). The questions vary from super easy (plug into a formula) to moderately difficult. It’s not a big deal to miss the hard ones, the whole point of Mastering Physics is to force you to practice the course material.</p>
<p>The quizzes: these weren’t too bad actually, you spend most of the 2 hour tutorial listening to the TA and doing problems, and in the last 20 minutes, there’s a quiz. Take the time to learn the course material, try hard, and you’ll do fine on the quizzes</p>
<p>The mid-term and final: Unfortunately, our mid-term was 13 multiple choice questions (the questions weren’t actually terribly hard), which meant there was no chance for you to get marks for showing your work. You get one wrong, there goes a couple percent off your final grade. Study hard because the stuff you learn during the first half of the course will be used frequently during the second half. The final was pretty brutal. This dropped my mark/overall average a lot.</p>
<p>Fortunately, there was a nice bell curve of sorts (not necessarily a true Gaussian distribution, but some sort of normalization). Study hard in this course if you want to do well; you won’t be doing mechanics again for quite some time.</p>
<h3>ECE 140 – Linear Circuits</h3>
<p><em>Remember the circuits in grade 9 or 10 science? It’s like that, but harder.</em></p>
<p>You start off with the basics; what’s current, charge, power, what are their units, what’s electricity. Then basic circuits, Ohm’s law, some more advanced systematic techniques of solving circuits, capacitors and inductors, and finally complex numbers play a role in some pretty abstract concepts that I will likely never remember again. Oh and op-amps; those questions were fun.</p>
<p>I bought the textbook for this course. It’s got good practice problems, and you could very well just read the textbook instead of going to class (I don’t recommend that, it goes more in-depth sometimes and going to class is good for at least a few reasons…).</p>
<p>What I did in the second half of the course was simply pay attention in class instead of taking notes; I found I learned better this way because, at least for this course, drawing circuits and taking written notes and trying to pay attention and learn all simultaneously was a bit too much for me. Also my prof posted his lecture notes online, which were neater than the notes I would have taken (it’s pretty easy to mess up drawing a complex circuit, and it takes a while to erase).</p>
<p>You also have labs in this course. You get a partner and you make circuits on breadboards. The labs are fortnightly and you have to submit a small report a few days after the lab (nothing fancy; no procedure, hypothesis, or conclusion, just answer a few questions, graph some data, and talk about your <del>feelings</del> findings).</p>
<p>Midterm was easy (class average of 87), final was fair, harder than the weekly quizzes that were given during the tutorial though.</p>
<h3>MATH 117 – Calculus I for Engineering</h3>
<p><em>I wish I was your derivative… so I could lie tangent to your curves</em></p>
<p>Covers pre-calculus (limits, trigonometry), various types of functions (Heaviside, cosh(x)**), derivatives, integrals, applications of integrals.</p>
<p>If you took AP or IB (I didn’t), you’ll probably be fine since most of the course will be review and/or easy for you. If not, that’s fine too; integrals are objectively harder than derivatives (at least for first year calculus problems), but KhanAcademy, going to lectures, and office hours will help you a lot here.</p>
<p>The weekly assignments can be challenging at times; you will need to do a lot of practice but fortunately, these assignments are great practice for the mid-term and final. There’s also tons of resources for learning the content and there’s no shortage of calculus practice problems out there; in fact it’s not too hard to make up your own if you’re ever bored on the bus.</p>
<p>Complex numbers are also taught. You use them in a few courses, if you haven’t noticed yet.</p>
<p>**not a typo, cosh(x) is not the same as cos(x)</p>
<h3>MATH 115 – Linear Algebra for Engineering</h3>
<p><em>Vectors, matrices, and proofs, oh my!</em></p>
<p>Pretty abstract course; unlike most of the courses you’ll have this term, there are proofs in this course, and some of the content is too abstract to apply to things you’ve learned before. Fortunately we did some work with matrices in high school, but all of it was covered in this course within a couple weeks.</p>
<p>Once again, tons of resources on the internet if you need other places to learn the content, there’s also lots of practice problems out there. The course notes by Dan Wolczuk are great for this course.</p>
<p>“Assignments” took the form of weekly test-like pieces of paper. During the tutorial you’d sit down, collaborate with whoever you want, and answer several questions relating to the previous week’s content. It’s completely open book (and open laptop ;) ), so it’s not too bad. I had this tutorial Monday mornings, and I woke up late a couple of times. That didn’t help me very much.</p>
<h3>SE 101 – Introduction to Methods of Software Engineering</h3>
<p><em>Hard to describe this one. So here’s a funny unrelated comic <a href="http://www.somethingofthatilk.com/index.php?id=135">http://www.somethingofthatilk.com/index.php?id=135</a></em></p>
<p>Yes, you’re going to have 6 courses but this one’s a half-credit (or well, a 0.25 credit, most courses you take at Waterloo will be 0.5 credits, so 0.25 credit courses are called half-credit courses; confusing, I know).</p>
<p>The majority of the course deals with things like ethics and professional engineering and rules. Some parts, like the software development life cycle were actually useful and interesting, so pay attention to that, but otherwise, the 4 quizzes we had were fairly easy.</p>
<p>Our final project had us using Scribblr robots (read: roomba clones). They have a few sensors on them and there’s a fairly simplistic API. Setup can be a pain depending on your computer. You code in python and get it to solve some problem (the problem itself is up to you). You also have to write a report and present it with your fellow group partners.</p>
<hr />
<h2>Second Term:</h2>
<p>The subjects in this term are similar to first term’s, except the physics is about electromagnetism and integrals, not mechanics and breaking hearts.</p>
<h3>CS 138 – Introduction to Data Abstraction and Implementation</h3>
<p><em>Linked lists, queues, binary trees, linked lists, C++, object oriented development, and oh, linked lists.</em></p>
<p>If you know about any of these, the implementations of the ADTs (abstract data types) will be easier for you to understand. Once you know how to do one of them, and understand the concepts of pointers and the new features in C++ compared to C, you won’t have much trouble understanding anything in this course. All that’s left are the assignments.</p>
<p>The ADTs themselves are useful for technical interviews (more on this in a later post). Mostly everything you learn in C can be applied to C++.</p>
<p>The assignments here were more involved than those in CS 137. They were assigned every 1-2 weeks and once again use marmoset. I took notes with my com-poo-ter. Found it super handy, especially when studying those ADTs. I just type them up in OneNote, paste to vim for all its awesome vim features, and stare at the screen.</p>
<h3>ECE 106 – Physics of Electrical Engineering II</h3>
<p><em>Calculus-based electromagnetism – tons of fun, for some definition of fun</em></p>
<p>You don’t need much prior experience with electricity for this; but the more you remember from grade 12, the better. You’ll do Gauss’ law, Faraday’s law, Lenz’s law, Ampere’s law, Coulomb’s law, …</p>
<p>You should have a good understanding of how integrals work by the time you get here. They’re used frequently. You don’t actually need to memorize many formulas though. Most of the important physics formulae and integrals on the formula sheet which are provided with the tutorial quizzes, mid-term, and final.</p>
<p>Your enjoyment of this course will depend on a few things; how easy/difficult they decide to make the course, how comfortable you are with the idea of integrals, and how much practice you do. I’d recommend doing the practice problems out of the textbook; they’re super useful for the weekly tutorial quizzes.</p>
<p>Labs are also in this physics course. The content is very similar to what you did in ECE 140; you don’t really apply much of what you learn in class in the lab. They consisted of setting up some circuits, learning to use some new measurement tools, and writing a small report after the fact (fairly simple stuff, not a full report).</p>
<p>Last bit of physics you do for a while.</p>
<h3>ECE 124 – Digital Circuits and Systems</h3>
<p><em>There are 10 types of people in the world: Those who understand binary, those who don’t, and those who didn’t see a ternary joke coming.</em></p>
<p>This is the first course that actually kind of felt like an engineering course; there’s some design involved and the applications to the content you learn are obvious. You learn about binary, logical operators (AND, OR, XOR, etc.), and how to design various types of logic circuits. The powerpoint notes are great, but you’ll need to do a decent amount of practice. The textbook/assigned questions were at an appropriate level, but since they weren’t mandatory, you’ll really have to push yourself to actually do them.</p>
<p>This course also has labs (fortnightly, as usual). You learn VHDL along the way, a hardware descriptive language that’s used to directly manipulate the lights and whatnot on an FPGA board. The labs apply only basic knowledge from the course. It’s mostly fun and design and learning the syntax of VHDL.</p>
<p>The postlab reports here are a bit more wordy and open-ended than your previous labs. A couple pages with strict requirements on the formatting. The labs were worth a decent portion of your mark and were relatively easy, so I was happy about that. You get a partner for these labs too, so you’ll also have some practice coding together on one computer.</p>
<h3>MATH 119 – Calculus II for Engineering</h3>
<p><em>Insert calculus pick-up line here</em></p>
<p>Calculus II won’t be review for most people, at least for those who only know high school material (maybe you know Taylor series and Newton’s method). You learn multi-variable calculus (partial derivatives, basic limits, gradients, directional derivatives), approximations of non-polynomial functions with Taylor series, infinite series, and some vector calculus (weren’t on any tests for us). There weren’t too many proofs in this course, like some people might expect for a math course. Once again, there’s tons of places to find help if you need it for Calc II.</p>
<p>Assignments here weren’t too bad. Study the course notes well and you should be fine. You might need to look online for practice problems if you choose not to buy the textbook (I didn’t).</p>
<p>The final for this course was weighted 65% or so I believe. This was the highest I’ve experienced so far (common percentages were 50% and 64%). How this course is structured and marked will however depend on if they change anything for future students and/or how your fellow students taking the course are doing on the assignments/mid-terms.</p>
<h3>MATH 135 – Algebra for Honours Mathematics</h3>
<p><em>Quod erat demonstrandum</em></p>
<p>I could talk about this course for hours (or rather, write for several paragraphs). It was by far my favourite course and highest mark. You learn various properties about numbers (particularly integers), sets, primes, divisibility, and proofs. You learn how to think logically (you aren’t taught by the professor necessarily, it’s something you develop by doing proofs), and you get a taste of what math is really all about.</p>
<p>Weekly assignments are at a moderate difficulty; your difficulty with them will depend on how good you are at critical thinking. I found them to be very fair and enjoyable (maybe I’m just weird though…), and when I needed help, office hours were available.</p>
<p>There’s a large range of scores that people get in this course; it’s really hard to say how much or how little you need to study. I think a lot of it is actually natural ability. Practicing proofs and the content is absolutely necessary to do well in this course, but if you’re a genius, you won’t need as much of that as others. The proposition sheets provided on the mid-term and final were helpful for the subtleties in the theorems.</p>
<p>The mid-term and final were both good, but it’s hard to speak for others, especially in this course. You’ll just have to wait till you get here!</p>
<h3>SE 102 – Seminar</h3>
<p><em>Make sure you know how to make pizza for the midterm</em></p>
<p>This weekly seminar only actually ended up happening a few times during the term. It’s marked credit/no credit so there’s no evaluations to worry about.</p>
<h2>Third Term:</h2>
<p>2A was an interesting term. After going on my first co-op in Waterloo, I returned to school for the Fall 2013 term. Second year is typically where the various engineering programs start to diverge more and more since the courses become more specialized.</p>
<h3>CS 241 – Foundations of Sequential Programs</h3>
<p>Probably one of the most enjoyable courses thus far. The course is extremely well-structured and the applications to the things you learn are immediately obvious.</p>
<p>The course starts off with some tedious (though not too tedious) work with a subset of MIPS, which is one of the many types of assembly languages out there. Eventually you move to compiler design which made me appreciate how ‘deep the rabbit hole goes’. That is, there are several steps that must be taken before an idea in your head can become a reality on a computer, and thanks to thousands of people who came before you, you can do all these steps in a matter of minutes.</p>
<p>The coolest thing about the course is that the assignments are directly connected to each other as well as to the course content. By the end, if you complete all the assignments, you’ll have built a compiler for a <em>very</em> <em>very</em> small subset of C++.</p>
<p>This course is probably the most important one I’ve taken with regards to my profession. This fact will probably change by the end of 2B.</p>
<h3>ECE 222 – Digital Computers</h3>
<p>Another in a series of hardware courses. This course was more interesting than I initially gave it credit for. I’m definitely at fault here; it was hard to deal with morning classes for me this term.</p>
<p>At any rate, I learned a lot of useful info from this course, most notably, how to design a cache, memory management, and memory pipelining. I’d definitely like to continue learning about this stuff, whether as part of a course or on my own.</p>
<p>The assignments were not mandatory for my class, but they were very helpful. Be careful not to fall into the trap of not doing the assignments though. The labs required you to program an ARM Cortex-M3 processor to perform increasingly complex tasks.</p>
<ul>
<li>CHE 102 – Chemistry for Engineers</li>
</ul>
<p>To be continued…</p>
<ul>
<li>SE 212 – Logic and Computation</li>
</ul>
<p>To be continued…</p>
<ul>
<li>STAT 206 – Statistics for Software Engineers</li>
</ul>
<p>The only stats course you’ll have to take as a software engineer. Statistics is of course very important in various sub-fields of CS, like machine learning. Also, if you took data management in high school, many parts of the course will be familiar. Probability and statistical distributions are the main focuses of the course.</p>
<p>Unfortunately, by the end of the course, I felt I did not have a thorough understanding of the meaning of some of the statistical distributions we studied. Much of the course required memorization of unintuitive formulas. I believe this course, which is a combination of STAT 230 and STAT 231, is too compact to provide a sufficient explanation of all the concepts covered. Proofs were few and far between and too abstract for the average student to relate the concept to the real world.</p>
<p>Once again, no mandatory assignments here. A common complaint of the course was a lack of homework problems which probably contributed to the aforementioned problem. Unfortunately, we were kinda swathed this term with the whole 6 courses and non-trivial assignments due every week and JobMine and exams and …, so who knows if I would have had time for them anyway.</p>
<ul>
<li>(elective) PSYCH 101 – Introductory Psychology</li>
</ul>
<p>To be continued…</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[:%s/WordPress/Octopress/g]]></title>
<link href="http://agnanachandran.github.io/blog/2013/07/28/percent-s-slash-wordpress-slash-octopress-slash-g/"/>
<updated>2013-07-28T14:00:00-04:00</updated>
<id>http://agnanachandran.github.io/blog/2013/07/28/percent-s-slash-wordpress-slash-octopress-slash-g</id>
<content type="html"><![CDATA[<p>So after only a few months of using WordPress, I decided to switch to Octopress. I decided to make that obligatory post that every new Octopress user writes. It’s some sort of rite of passage, I think.</p>
<!-- more -->
<p>Anyway, I used WordPress at first because it is by far the most popular blogging platform out there, and was fairly easy to setup with my current hosting provider. I knew about Octopress before I started my WordPress blog but thought it wasn’t worth the trouble. I was very wrong. I followed <a href="http://robdodson.me/blog/2012/04/30/custom-domain-with-octopress-and-github-pages/">this tutorial</a> (with some adjustments due to GitHub Pages now being at …github.io instead of …github.com and updated versions of ruby/rvm) and I was up and running the same day.</p>
<p>There’s 5 reasons I can think of at the top of my head about why Octopress is so awesome.</p>
<h2>Super quick deployment; no fumbling with <insert your favourite blogging platform here>.</h2>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr></pre></td><td class='code'><pre><code class='bash'><span class='line'>rake generate
</span><span class='line'>rake deploy