-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
694 lines (372 loc) · 35 KB
/
index.html
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
<!DOCTYPE html>
<!--[if IEMobile 7 ]><html class="no-js iem7"><![endif]-->
<!--[if lt IE 9]><html class="no-js lte-ie8"><![endif]-->
<!--[if (gt IE 8)|(gt IEMobile 7)|!(IEMobile)|!(IE)]><!--><html class="no-js" lang="en"><!--<![endif]-->
<head>
<meta charset="utf-8">
<title>My Beginnings as a Web Developer</title>
<meta name="author" content="May Lee">
<meta name="description" content="Having built out the authentication system for the last project I worked on I decided to try out the Devise RubyGem this time. For this post, I&rsquo …">
<!-- http://t.co/dKP3o1e -->
<meta name="HandheldFriendly" content="True">
<meta name="MobileOptimized" content="320">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="canonical" href="http://maycmlee.github.io">
<link href="/favicon.png" rel="icon">
<link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css">
<link href="/atom.xml" rel="alternate" title="My Beginnings as a Web Developer" type="application/atom+xml">
<script src="/javascripts/modernizr-2.0.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>!window.jQuery && document.write(unescape('%3Cscript src="/javascripts/libs/jquery.min.js"%3E%3C/script%3E'))</script>
<script src="/javascripts/octopress.js" type="text/javascript"></script>
<!--Fonts from Google"s Web font directory at http://google.com/webfonts -->
<link href="//fonts.googleapis.com/css?family=PT+Serif:regular,italic,bold,bolditalic" rel="stylesheet" type="text/css">
<link href="//fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet" type="text/css">
<link href="//fonts.googleapis.com/css?family=Fjalla+One" rel="stylesheet" type="text/css">
<!--- MathJax Configuration -->
<script type="text/javascript" src="//cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body class="collapse-sidebar sidebar-footer" >
<header role="banner"><hgroup>
<h1><a href="/">My Beginnings as a Web Developer</a></h1>
</hgroup>
</header>
<nav role="navigation"><ul class="subscribe" data-subscription="rss">
<li><a href="/atom.xml" rel="subscribe-rss" title="subscribe via RSS" target="_blank"><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="25" height="25" viewbox="0 0 100 100"><path class="social" d="M 13.310204,73.332654 C 5.967347,73.332654 0,79.322448 0,86.621428 c 0,7.338776 5.967347,13.262246 13.310204,13.262246 7.370408,0 13.328572,-5.92245 13.328572,-13.262246 0,-7.29898 -5.958164,-13.288774 -13.328572,-13.288774 z M 0.01530612,33.978572 V 53.143878 C 12.493878,53.143878 24.229592,58.02347 33.068368,66.865306 41.894898,75.685714 46.767346,87.47449 46.767346,100 h 19.25 C 66.017346,63.592858 36.4,33.979592 0.01530612,33.978572 l 0,0 z M 0.03877552,0 V 19.17449 C 44.54796,19.17551 80.77551,55.437756 80.77551,100 H 100 C 100,44.87653 55.15102,0 0.03877552,0 z"></path></svg></a></li>
</ul>
<form action="https://www.google.com/search" method="get">
<fieldset role="search">
<input type="hidden" name="sitesearch" value="maycmlee.github.io" />
<input class="search" type="text" name="q" results="0" placeholder="Search"/>
</fieldset>
</form>
<ul class="main-navigation">
<li><a href="/">Blog</a></li>
<li><a href="/blog/archives">Archives</a></li>
</ul>
</nav>
<div id="main">
<div id="content">
<div class="blog-index">
<article>
<header>
<h1 class="entry-title"><a href="/blog/2016/01/29/customizing-devise/">Customizing the Devise Gem</a></h1>
<p class="meta">
<time class='entry-date' datetime='2016-01-29T17:39:40-08:00'><span class='date'><span class='date-month'>Jan</span> <span class='date-day'>29</span><span class='date-suffix'>th</span>, <span class='date-year'>2016</span></span> <span class='time'>5:39 pm</span></time>
</p>
</header>
<div class="entry-content"><p>Having built out the authentication system for the last project I worked on I decided to try out the Devise RubyGem this time.</p>
<p>For this post, I’m going to assume that you have already used Devise to setup a basic authentication system for a user to sign up, log in and log out. Devise is a Rails engine that sets up its authentication system by generating its own <code>views</code>. To access these views we have to copy them from the Rails engine by entering this command…</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>rails generate devise views</span></code></pre></td></tr></table></div></figure>
<p>Now if you open your <code>views</code> folder you’ll see all the views that Devise had created in a subfolder called <code>devise</code>…</p>
<p><img src="/images/devise_post/devise_views.png"></p>
<p>So currently the sign up page looks something like this…</p>
<p><img src="/images/devise_post/signup.png"></p>
<p>Right now, as you can see, the user password created is requred to have 8 characters. So what if we just wanted it to have 6 characters?</p>
<p>In <code>app/config/initializers/devise.rb</code> you’ll see configurations options for Devise.</p>
<p>There is one that is…</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">config</span><span class="o">.</span><span class="n">password_length</span> <span class="o">=</span> <span class="mi">8</span><span class="o">.</span><span class="n">.</span><span class="mi">72</span>
</span></code></pre></td></tr></table></div></figure>
<p>…and if we change the <code>8</code> to <code>6</code>…and go back to the Sign Up page, we see that the password requirement has now changed to 6 characters.</p>
<p><img src="/images/devise_post/signup_changed.png"></p>
<p>Now let’s say we want the user to be able to have a <code>username</code> and log in with that <code>username</code> instead of their email. How do we do that?</p>
<p>First we have to create a column in the <em><strong>user table</strong></em> for <code>username</code>…</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>rails g migration add_username_to_users username:string</span></code></pre></td></tr></table></div></figure>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>rake db:migrate</span></code></pre></td></tr></table></div></figure>
<p>Next we want to add the <code>username</code> field on the Sign Up page.<br/>
So in <code>app/views/devise/registrations/new.html.erb</code> we add the following code…</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'><div class="field">
</span><span class='line'> <%= f.label :username %><br />
</span><span class='line'> <%= f.text_field :username%>
</span><span class='line'></div></span></code></pre></td></tr></table></div></figure>
<p>And our Sign Up now looks like this…</p>
<p><img src="/images/devise_post/signup_username.png"></p>
<p>But our current Log In page still uses the email address to verify the user…</p>
<p><img src="/images/devise_post/login.png"></p>
<p>So then if we want to use the <code>username</code> instead of <code>email</code> to log someone in we have to change the Devise configuration in <code>app/config/initializers/devise.rb</code>. In that file you’ll see this line commented out…</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># config.authentication_keys = [:email]</span></code></pre></td></tr></table></div></figure>
<p>To authenticate using <code>username</code> we have to uncomment this line and change it to be…</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">config</span><span class="o">.</span><span class="n">authentication_keys</span> <span class="o">=</span> <span class="o">[</span><span class="ss">:username</span><span class="o">]</span>
</span></code></pre></td></tr></table></div></figure>
<p>Then opening up <code>app/views/devise/sessions/new.html.erb</code>, which is the Log In page, you’ll see this block of code…</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'><div class="field">
</span><span class='line'> <%= f.label :email %><br />
</span><span class='line'> <%= f.email_field :email, autofocus: true %>
</span><span class='line'></div></span></code></pre></td></tr></table></div></figure>
<p>and need to change <code>email</code> to <code>username</code>…</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'><div class="field">
</span><span class='line'> <%= f.label :username %><br />
</span><span class='line'> <%= f.email_field :username, autofocus: true %>
</span><span class='line'></div></span></code></pre></td></tr></table></div></figure>
<p>However, because you can’t use Devise’s <code>:validatable</code> when using an authentication key that is not <code>:email</code> a couple of changes have to be made in <code>app/models/user.rb</code>.</p>
<p>First, we have to comment out <code>:validatable</code> and then write out the validations for <code>username</code>…</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">User</span> <span class="o"><</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span><span class='line'> <span class="c1"># Include default devise modules. Others available are:</span>
</span><span class='line'> <span class="c1"># :confirmable, :lockable, :timeoutable and :omniauthable, :validatable</span>
</span><span class='line'> <span class="n">devise</span> <span class="ss">:database_authenticatable</span><span class="p">,</span> <span class="ss">:registerable</span><span class="p">,</span>
</span><span class='line'> <span class="ss">:recoverable</span><span class="p">,</span> <span class="ss">:rememberable</span><span class="p">,</span> <span class="ss">:trackable</span>
</span><span class='line'> <span class="n">validates_uniqueness_of</span> <span class="ss">:username</span>
</span><span class='line'> <span class="n">validates_presence_of</span> <span class="ss">:username</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>
<p> Sidenote: <code>lockable</code> and <code>confirmable</code> require an email field to work.</p>
<p>The Log In page now looks like this…</p>
<p><img src="/images/devise_post/login_username.png"></p>
<p> And you have a Devise user authentication system that logs users in with their <code>username</code>!</p>
</div>
</article>
<article>
<header>
<h1 class="entry-title"><a href="/blog/2015/12/30/using-imagemagick-and-rmagick-gem/">Resizing Images Using the RMagick Gem</a></h1>
<p class="meta">
<time class='entry-date' datetime='2015-12-30T14:48:27-08:00'><span class='date'><span class='date-month'>Dec</span> <span class='date-day'>30</span><span class='date-suffix'>th</span>, <span class='date-year'>2015</span></span> <span class='time'>2:48 pm</span></time>
</p>
</header>
<div class="entry-content"><p>The other day I was trying to find a way to resize photos that I found using the Flickr API. Scouring around the web I found the RMagick Ruby gem.</p>
<p>To user RMagick, however, you had to first install ImageMagick, which actually does all of the image manipulation. RMagick just provides a easier user interface.</p>
<p>To install ImageMagick I just did..</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>brew install imagemagick</span></code></pre></td></tr></table></div></figure>
<p>And then added the RMagic gem into my gemfile…</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>gem install rmagick</span></code></pre></td></tr></table></div></figure>
<p>I also had to add this to the file where I was going to use RMagick or wherever I set up the environment…</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>require 'RMagick'
</span><span class='line'>include Magick</span></code></pre></td></tr></table></div></figure>
<p>…because RMagick is implemented in the Magick module, the line <code>include Magick</code> adds RMagick’s constants and methods to the Magick namespace.</p>
<p>Before I could manipulate the images, I had to first download the photos I found on flickr using their API. So I wrote method to do just that…</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'> <span class="k">def</span> <span class="nf">download</span>
</span><span class='line'> <span class="no">Dir</span><span class="o">.</span><span class="n">mkdir</span><span class="p">(</span><span class="s2">"images"</span><span class="p">)</span> <span class="k">unless</span> <span class="no">File</span><span class="o">.</span><span class="n">exist?</span><span class="p">(</span><span class="s2">"images"</span><span class="p">)</span>
</span><span class='line'> <span class="nb">open</span><span class="p">(</span><span class="n">url</span><span class="p">)</span> <span class="p">{</span><span class="o">|</span><span class="n">f</span><span class="o">|</span>
</span><span class='line'> <span class="no">File</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">photo_path</span><span class="p">,</span><span class="s2">"wb"</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">file</span><span class="o">|</span>
</span><span class='line'> <span class="n">file</span><span class="o">.</span><span class="n">puts</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span>
</span><span class='line'> <span class="k">end</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>
<p>Line 2 creates a new directory called “images” if it doesn’t already exist. All the images are downloaded into this folder.</p>
<p>In line 3, <strong>url</strong> is the url to the flickr image.</p>
<p>In line 4, <strong>photo_path</strong> is the path to the downloaded photo image. For example: images/img_0.jpg.</p>
<p>Then I wrote a method to resize the images…</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'> <span class="k">def</span> <span class="nf">resize</span>
</span><span class='line'> <span class="n">image</span> <span class="o">=</span> <span class="no">Image</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">photo_path</span><span class="p">)</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span>
</span><span class='line'> <span class="n">resize</span> <span class="o">=</span> <span class="n">image</span><span class="o">.</span><span class="n">resize_to_fill</span><span class="p">(</span><span class="mi">200</span><span class="p">,</span> <span class="mi">150</span><span class="p">)</span>
</span><span class='line'> <span class="n">resize</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">photo_path</span><span class="p">)</span>
</span><span class='line'> <span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>
<p>In line 2, <code>Image.read(photo_path)</code> opens the image file with RMagick. It returns a collection and asks for the first element.</p>
<p>The <code>image</code> variable is a RMagick Image object. We can now use Image object methods to manipulate the image.</p>
<p>Here I used the method <code>resize_to_fill()</code>. From the Rmagick documentation, this method “resizes the image to fit within the specified dimensions while retaining the aspect ratio of the original image. If necessary, crop the image in the larger dimension.</p>
<p>Here are the photos. Left is the original. Right is the resized one.</p>
<p><img src="/images/rmagick_post/img_original.jpg">
<img src="/images/rmagick_post/img_resize.jpg"></p>
<p>Have fun!</p>
</div>
</article>
<article>
<header>
<h1 class="entry-title"><a href="/blog/2015/12/06/git-stash/">Git Stash</a></h1>
<p class="meta">
<time class='entry-date' datetime='2015-12-06T08:23:00-08:00'><span class='date'><span class='date-month'>Dec</span> <span class='date-day'>6</span><span class='date-suffix'>th</span>, <span class='date-year'>2015</span></span> <span class='time'>8:23 am</span></time>
</p>
</header>
<div class="entry-content"><p>We started our second project mode last week and I’d like to talk about <em><strong>git stash</strong></em>, which I’ve found really helpful for when I need to put something I’m working on on hold to work on something else.</p>
<p>So, for example, say I’m trying to write a new feature, but was asked to fix a bug in another part of the code.</p>
<p>If I did <code>git status</code></p>
<p>I get…</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>On branch new_feature
</span><span class='line'>Changes not staged for commit:
</span><span class='line'> (use "git add <file>..." to update what will be committed)
</span><span class='line'> (use "git checkout -- <file>..." to discard changes in working directory)
</span><span class='line'>
</span><span class='line'> modified: app/models/country.rb
</span><span class='line'>
</span><span class='line'>no changes added to commit (use "git add" and/or "git commit -a")</span></code></pre></td></tr></table></div></figure>
<p>I don’t really want to commit my test code yet because it’s only half done. So, instead, I can take a snapshot of my current work using <code>git stash</code>.</p>
<p>By doing <code>git stash</code> you save your work on your local directory and clear out your working directory.</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Saved working directory and index state WIP on new_feature: fb67f7a This is a test
</span><span class='line'>HEAD is now at fb67f7a another test</span></code></pre></td></tr></table></div></figure>
<p>After fixing the bug, to get back the work I was doing before I just have to use <code>git pop</code>, which gives me the most recent work I have stashed.</p>
<p>To stash with a message you can do…</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>git stash save "This is a test"</span></code></pre></td></tr></table></div></figure>
<p>You can also stash more than one work-in-progress. And to get a list of all of your stashes you can use</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>git stash list</span></code></pre></td></tr></table></div></figure>
<p>…which gives you…</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>stash@{0}: WIP on new-feature: 5cedcc This is a test
</span><span class='line'>stash@{1}: WIP on new-feature: 9f4434 Try different method
</span><span class='line'>stash@{2}: WIP on new-feature: 5acd291 Start new feature</span></code></pre></td></tr></table></div></figure>
<p><em><strong>git pop</strong></em> only gives you the most recent stash so if you wanted to get <em><strong>stash@{1}</strong></em> you would do</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>git stash apply stash@{1}</span></code></pre></td></tr></table></div></figure>
<p>This has been really helpful when I’m trying to solve a problem but want to try different methods. So I can try one method, stash it and try another method and then use the one I want.</p>
</div>
</article>
<article>
<header>
<h1 class="entry-title"><a href="/blog/2015/11/19/transpilers/">Transpilers or Source-to-Source Compilers</a></h1>
<p class="meta">
<time class='entry-date' datetime='2015-11-19T17:32:10-08:00'><span class='date'><span class='date-month'>Nov</span> <span class='date-day'>19</span><span class='date-suffix'>th</span>, <span class='date-year'>2015</span></span> <span class='time'>5:32 pm</span></time>
</p>
</header>
<div class="entry-content"><p>Yesterday before we started learning Ember we were given a crash course in Babel, a transpiler or transcompiler, for Javascript. I had never heard of transpilers so decided to look a little more into them.</p>
<p><b>Transpilers</b> are also known as <b>source-to-source compilers</b>, meaning they translate the source code of a program written in one language into a source code written in another language. These two source code languages have similar levels of abstraction and are both high-level languages, like Ruby, Python, or JavaScript.</p>
<center><img src= "http://qph.is.quoracdn.net/main-qimg-13f269ab119b5c97abf0ad52c57fffac?convert_to_webp=true">
<br><small>Source: <a href ="http://softwareengineeringdaily.com/2015/07/30/transpiler-tradeoffs-typescript-coffeescript-es6/">Software Engineering Daily</a></small></center>
<p></center></p>
<p>A <b>compiler</b>, on the other hand, translates the source code of a high-level language program to a low-level language, such as machine code, which is understood by the computer’s CPU.</p>
<center><img src="images/high-to-low-level-languages.png" width=250px>
<br><small>Source: <a href ="http://learntocodewith.me/programming/source-code">Learn to Code With Me</a></small></center>
<p>CoffeeScript, TypeScript, Dart, ECMAScript 6 (ES6) are just a couple of languages that transpile to JavaScript.</p>
<p>Why use a JavaScript transpiler?</p>
<p>Different transpilers also offer different advantages. For example, CoffeeScript has similarties to Ruby and Python and implments some of the features from those two languages. So if you know Ruby or Python then CoffeeScript might feel more familiar and be easier for writing JavaScript programs.</p>
<p>Typescript, another example, is a superset of JavaScript which means that any JavaScript code you write would work with it, but Typescript offers more object oriented programming features than JavaScript alone. Also, Typescript has similarities to Java and C# so would be easier to program in if you already know those languages.</p>
<p>ES6 is JavaScript compiled to JavaScript, but with many additional features that have just been approved in June by ECMA International. ES5, the previous version, was approved back in 2009 so major improvements and new features can be found in ES6. However, even though these new features have been approved, it will take time for browser developers to update their browsers so that ES6 features can be used. But even so, if web developers want to start using these new features they can do so because Babel transpiles ES6 back to ES5.</p>
<p>For more pros and cons of different JavaScript transpilers: <a href = "http://jessewarden.com/2015/02/javascript-transpiled-languages.html">
JavaScript Transpiled Languages</a></p>
</div>
</article>
<article>
<header>
<h1 class="entry-title"><a href="/blog/2015/11/03/yelp-api/">Yelp API Keys and tokens....oops</a></h1>
<p class="meta">
<time class='entry-date' datetime='2015-11-03T17:18:32-08:00'><span class='date'><span class='date-month'>Nov</span> <span class='date-day'>3</span><span class='date-suffix'>rd</span>, <span class='date-year'>2015</span></span> <span class='time'>5:18 pm</span></time>
</p>
</header>
<div class="entry-content"><p>For our project, we’re using a Yelp API to help us find restaurants in a specific neighborhood. To get access to the API we generated keys and tokens from Yelp’s developer website.</p>
<p><img src="images/yelp_secret.png"></p>
<p>These keys and tokens allow us to make a HTTP request to the Yelp API to get the information we want.</p>
<p>To keep these API keys safe, we first stored them in a separate YAML file called <b>application.yml</b>.</p>
<p>Inside application.yml:<br><br>
<img src="images/yaml_file.png"></p>
<p>And then we can created a <b>.gitignore</b> file that lists our <b>application.yml</b> in it. Doing this allowed us to keep application.yml from being pushed up to GitHub and keep people from getting a hold of our API keys. A <b>.gitignore</b> file contains a list of files that are not to be pushed up to GitHub.</p>
<p>So when we wanted to make a request to our API, we had to first <b> load </b> the file <b>application.yaml</b>.<br><br>
<img src="images/load_yaml.png"></p>
<p>…which gave us a hash of our API keys and tokens: <br><br></p>
<p><img src="images/keys.png"></p>
<p>…and then we made the actual request to the API by sending over our API keys as key-value pairs from our hash. <br><br>
<img src="images/protected.png"></p>
<p>However, because we wanted to see if we could just get the API code working, we decided to hardcode the keys in first…<br><br>
<img src="images/hardcoded.png"></p>
<p>Then an hour or so later….we got the API working and were able to get the information we were looking for from Yelp. Yay! git add. git commit. git push. OOPS. We had just completely exposed our API keys to everyone.</p>
<p>So, how do we resolve this problem? The problem with just fixing our code, hiding our API keys, and then pushing the code back up to GitHub was that all of our previous git commits still contained those keys. So, the best thing to do was to destroy those keys and generate new ones. And not expose them again.</p>
<p>Our case was not too serious, hopefully. However, there have been a number of cases where programmers who used Amazon Web Services (AWS) had mistakenly published their tokens on GitHub and ended up getting their accounts hacked into. One programmer using AWS realized his keys were revealed in his code just five minutes after he commited his files to GitHub. So he immediately reverted his last few commits and deleted all traces of his keys from GitHub. But the next morning he had four emails from Amazon AWS, a missed phone call from them and 140 servers running on his AWS account, along with a bill for $2375. So his keys were discovered within those five minutes they were exposed on GitHub. Luckily, when he explained the situation to Amazon customer support, they dropped the charges.</p>
<p>You can find the full story here: <a href="http://www.devfactor.net/2014/12/30/2375-amazon-mistake/"> My $2375 Amazon EC2 Mistake.</a></p>
</div>
</article>
<article>
<header>
<h1 class="entry-title"><a href="/blog/2015/10/17/what-it-all-comes-down-to-dot-dot-dot-binary-code/">What It All Comes Down to...Binary Code</a></h1>
<p class="meta">
<time class='entry-date' datetime='2015-10-17T15:24:03-07:00'><span class='date'><span class='date-month'>Oct</span> <span class='date-day'>17</span><span class='date-suffix'>th</span>, <span class='date-year'>2015</span></span> <span class='time'>3:24 pm</span></time>
</p>
</header>
<div class="entry-content"><p>While I was working on the “Secret Handshake” lab, I became interested in binary codes. I knew vaguely that computers at the lowest level operated on a binary system, but I didn’t quite understand what that meant. How does a computer understand what we are asking for when we run a program? I decided to do a little investigation.</p>
<p>First, I found out that a computer, in terms of its hardware, can actually only understand the states of ‘on’ and ‘off’. So everything a computer does is based on a combination of turning switches (transistors) on and off. These on and off states are represented by the binary code of 0’s and 1’s.</p>
<p>So what is the binary number system? Our counting system is a base-ten system, meaning we have digits from 0 to 9. The binary number system or base-two contains only 0 and 1.</p>
<p>So how do we convert our regular decimal numbers into binary code?</p>
<p>For example, how do we convert 14 into binary code?</p>
<p>14/2 = 7 remainder <b>0</b></p>
<p>7/2 = 3 remainder <b>1</b></p>
<p>3/2 = 1 remainder <b>1</b></p>
<p>1/2 = 0 remainder <b>1</b></p>
<p><b>1110</b> in binary = <b>14</b> in our decimal counting system.</p>
<p>But what about the alphabet and other symbols such as #, &, % and etc?</p>
<p>That’s where the ASCII (American Standard Code for Information Interchange) table comes in. The ASCII table converts the upper case, lower case alphabet and symbols into a decimal number.</p>
<p><img src="images/asciitable.png"></p>
<p>Another <a href="http://www.ascii.cl/htmlcodes.htm" target=_blank>ASCII table</a>.</p>
<p>From the decimal number the computer can then convert it into a binary number.</p>
<p>For example, let’s take the capital letter “A”. Looking at the ASCII table we see that it is 65. Converting 65 into a binary number…</p>
<p>65/2 = 32 remainder = <b>1</b></p>
<p>32/2 = 16 remainder = <b>0</b></p>
<p>16/2 = 8 remainder = <b>0</b></p>
<p>8/2 = 4 remainder = <b>0</b></p>
<p>4/2 = 3 remainder = <b>0</b></p>
<p>2/2 = 1 remainder = <b>0</b></p>
<p>1 remainder = <b>1</b></p>
<p>Binary code for “A” is <b>1000001</b>.</p>
<p>And the binary code for a string like ‘Hello World’ is…</p>
<p>01001000 01100101 01101100 01101100 01101111 00100000 01010111 01101111 01110010 01101100 01100100</p>
<p>I found it fascinating that everything we input into a computer is at the end read and understood by the computer as a long long string of 0’s and 1’s.</p>
<p><a href="http://binarytranslator.com/">http://binarytranslator.com/</a></p>
</div>
</article>
<div class="pagination">
<a href="/blog/archives">Blog Archives</a>
</div>
</div>
<aside class="sidebar">
</aside>
</div>
</div>
<footer role="contentinfo"><p>
Copyright © 2016 - May Lee -
<span class="credit">Powered by <a href="http://octopress.org">Octopress</a> | Themed with <a href="https://github.com/lucaslew/whitespace">Whitespace</a></span>
</p>
</footer>
<script type="text/javascript">
(function(){
var twitterWidgets = document.createElement('script');
twitterWidgets.type = 'text/javascript';
twitterWidgets.async = true;
twitterWidgets.src = '//platform.twitter.com/widgets.js';
document.getElementsByTagName('head')[0].appendChild(twitterWidgets);
})();
</script>
</body>
</html>