-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathblog.atom.xml
2228 lines (2120 loc) · 219 KB
/
blog.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>The L Blog</title><link href="http://lmontopo.github.io/" rel="alternate"></link><link href="http://lmontopo.github.io/feeds/blog.atom.xml" rel="self"></link><id>http://lmontopo.github.io/</id><updated>2014-12-15T00:00:00-05:00</updated><entry><title>Scopes got me again!</title><link href="http://lmontopo.github.io/scopes-got-me-again.html" rel="alternate"></link><updated>2014-12-15T00:00:00-05:00</updated><author><name>Leta Montopoli</name></author><id>tag:lmontopo.github.io,2014-12-15:scopes-got-me-again.html</id><summary type="html"><p>In a previous blog post I wrote about some of the struggles I encountered with scoping when Margo and I worked on our web framework Chapeau. This week, scopes got me again! This time, while I was working on my Template Engine. </p>
<p>I think that, as a new programmer, its not totally surprising that I've been a bit naive and carefree about scopes and global variables. However, I think that making mistakes was a good way for me to learn. Having been tricked by scoping issues twice now, I'll be much more careful with these matters in the future. </p>
<p>In this blog post I'm going to present a peice of code I wrote as an example. It illustrates in a straightforward manner the issues I was facing with my Template Engine. After presenting the code, I'll explain what is problematic about it. I'll present some examples tests I wrote for it, I'll show the weird things that the tests were doing, and I'll explain what I initially thought was happening and what I learned was <em>actually</em> happening. </p>
<p>Here's the example file which I've named string_maker.py</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
2
3
4
5
6
7
8
9
10
11</pre></div></td><td class="code"><div class="highlight"><pre><span class="k">class</span> <span class="nc">HTMLString</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span> <span class="o">=</span> <span class="s">&quot;&quot;</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="n">value</span>
<span class="k">def</span> <span class="nf">update</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">html_text</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">+</span> <span class="n">html_text</span>
<span class="n">my_HTML</span> <span class="o">=</span> <span class="n">HTMLString</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">add_to_string</span><span class="p">(</span><span class="n">text</span><span class="p">):</span>
<span class="n">my_HTML</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">text</span><span class="p">))</span>
</pre></div>
</td></tr></table>
<p>First the class HTMLString is defined with attribute 'value', initially set to be the empty string. This class also contains a method, update, which adds an inputed string to the end of value. An instance of this class called my_HTML is created and a function, 'add_to_string()', is defined. This function basically turns some input into a string format and calls my_HTML's update method on that string. </p>
<p>This code is pretty simple and it does a satisfactory job of concatinating more characters to the end of an existing string. But notice that only one string is ever being added to. Indeed, we only have one instance of the StringHTML class. If we wanted this program to produce two different strings, well it can't (or at least I don't think it can in its current state). This isn't really an issue unless, say, this code was part of a larger program intended to work as a template engine... So consider for a moment that the strings we are creating in this program are HTML pages. Perhaps these webpages will be sent back to a web-app which wants multiple web-pages. If more than one HTML page is being created, then our program would have to terminate, and then start up again, in between HTML pages. That's not really ideal. </p>
<p>Since my Template Engine has code that is similar to string_maker.py, we can already can see that I wasn't going about things in the smartest way. I did realize this at some point but I wanted to get some working tests up and running before improving my code.mSo lets write some tests for string_maker.py! I started with this:</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7
8</pre></div></td><td class="code"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">string_maker</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">import</span> <span class="nn">unittest</span>
<span class="k">class</span> <span class="nc">TestMain</span><span class="p">(</span><span class="n">unittest</span><span class="o">.</span><span class="n">TestCase</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">test_simple</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">add_to_string</span><span class="p">(</span><span class="s">&#39;&lt;html&gt;Hey!&lt;/html&gt;&#39;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">my_HTML</span><span class="o">.</span><span class="n">value</span><span class="p">,</span> <span class="s">&#39;&lt;html&gt;Hey!&lt;/html&gt;&#39;</span><span class="p">)</span>
</pre></div>
</td></tr></table>
<p>And received this lovely little message back:</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3</pre></div></td><td class="code"><div class="highlight"><pre>Ran 1 test in 0.000s
OK
</pre></div>
</td></tr></table>
<p>Gotta love that!</p>
<p>Now lets add another test function to this class, and we'll call add_to_string() multiple times in this test to make sure that it will keep updating as we expect. Here's what we'll add:</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5</pre></div></td><td class="code"><div class="highlight"><pre> <span class="k">def</span> <span class="nf">test_call_multiple</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">add_to_string</span><span class="p">(</span><span class="s">&#39;&lt;html&gt;One&#39;</span><span class="p">)</span>
<span class="n">add_to_string</span><span class="p">(</span><span class="s">&#39;two&#39;</span><span class="p">)</span>
<span class="n">add_to_string</span><span class="p">(</span><span class="s">&#39;three&lt;/html&gt;&#39;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">my_HTML</span><span class="o">.</span><span class="n">value</span><span class="p">,</span> <span class="s">&#39;&lt;html&gt;Onetwothree&lt;/html&gt;&#39;</span><span class="p">)</span>
</pre></div>
</td></tr></table>
<p>At this point I expect an error. Afterall, I know that string_maker.py can only create one html page at a time. So lets run the test and see. </p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
2
3
4
5
6
7
8
9
10
11
12
13
14</pre></div></td><td class="code"><div class="highlight"><pre>$ python test.py
.F
======================================================================
FAIL: test_class (__main__.TestMain)
----------------------------------------------------------------------
Traceback (most recent call last):
File &quot;test.py&quot;, line 8, in test_class
self.assertEqual(my_HTML.value, &#39;<span class="nt">&lt;html&gt;</span>Hey!<span class="nt">&lt;/html&gt;</span>&#39;)
AssertionError: &#39;<span class="nt">&lt;html&gt;</span>Onetwothree<span class="nt">&lt;/html&gt;&lt;html&gt;</span>Hey!<span class="nt">&lt;/html&gt;</span>&#39; != &#39;<span class="nt">&lt;html&gt;</span>Hey!<span class="nt">&lt;/html&gt;</span>&#39;
----------------------------------------------------------------------
Ran 2 tests in 0.000s
FAILED (failures=1)
</pre></div>
</td></tr></table>
<p>A single error, as expected. What I didn't expect was for the first test, test_simple, to be the failing test! This lead to a nice lesson about Python Unittests: <strong>Tests do not run in the order that you declare them</strong>. Cool! </p>
<p>At this point I get all naive and think "OK, I can fix this, here's how":</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16</pre></div></td><td class="code"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">string_maker</span> <span class="kn">import</span> <span class="o">*</span>
<span class="kn">import</span> <span class="nn">unittest</span>
<span class="k">class</span> <span class="nc">TestMain</span><span class="p">(</span><span class="n">unittest</span><span class="o">.</span><span class="n">TestCase</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">test_simple</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">my_HTML</span> <span class="o">=</span> <span class="n">HTMLString</span><span class="p">()</span>
<span class="n">add_to_string</span><span class="p">(</span><span class="s">&#39;&lt;html&gt;Hey!&lt;/html&gt;&#39;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">my_HTML</span><span class="o">.</span><span class="n">value</span><span class="p">,</span> <span class="s">&#39;&lt;html&gt;Hey!&lt;/html&gt;&#39;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">test_call_multiple</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">my_HTML</span> <span class="o">=</span> <span class="n">HTMLString</span><span class="p">()</span>
<span class="n">add_to_string</span><span class="p">(</span><span class="s">&#39;&lt;html&gt;One&#39;</span><span class="p">)</span>
<span class="n">add_to_string</span><span class="p">(</span><span class="s">&#39;two&#39;</span><span class="p">)</span>
<span class="n">add_to_string</span><span class="p">(</span><span class="s">&#39;three&lt;/html&gt;&#39;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">my_HTML</span><span class="o">.</span><span class="n">value</span><span class="p">,</span> <span class="s">&#39;&lt;html&gt;Onetwothree&lt;/html&gt;&#39;</span><span class="p">)</span>
</pre></div>
</td></tr></table>
<p>I figured, if I just re-instantiate my class inside each function, then my_HTML.value will be whiped clean at the begining of each test. Problem solved, right? Wrong....</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22</pre></div></td><td class="code"><div class="highlight"><pre><span class="err">$</span> <span class="n">python</span> <span class="n">test</span><span class="o">.</span><span class="n">py</span>
<span class="n">FF</span>
<span class="o">======================================================================</span>
<span class="n">FAIL</span><span class="p">:</span> <span class="n">test_call_multiple</span> <span class="p">(</span><span class="n">__main__</span><span class="o">.</span><span class="n">TestMain</span><span class="p">)</span>
<span class="o">----------------------------------------------------------------------</span>
<span class="n">Traceback</span> <span class="p">(</span><span class="n">most</span> <span class="n">recent</span> <span class="n">call</span> <span class="n">last</span><span class="p">):</span>
<span class="n">File</span> <span class="s">&quot;test.py&quot;</span><span class="p">,</span> <span class="n">line</span> <span class="mi">16</span><span class="p">,</span> <span class="ow">in</span> <span class="n">test_call_multiple</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">my_HTML</span><span class="o">.</span><span class="n">value</span><span class="p">,</span> <span class="s">&#39;&lt;html&gt;Onetwothree&lt;/html&gt;&#39;</span><span class="p">)</span>
<span class="ne">AssertionError</span><span class="p">:</span> <span class="s">&#39;&#39;</span> <span class="o">!=</span> <span class="s">&#39;&lt;html&gt;Onetwothree&lt;/html&gt;&#39;</span>
<span class="o">======================================================================</span>
<span class="n">FAIL</span><span class="p">:</span> <span class="n">test_class</span> <span class="p">(</span><span class="n">__main__</span><span class="o">.</span><span class="n">TestMain</span><span class="p">)</span>
<span class="o">----------------------------------------------------------------------</span>
<span class="n">Traceback</span> <span class="p">(</span><span class="n">most</span> <span class="n">recent</span> <span class="n">call</span> <span class="n">last</span><span class="p">):</span>
<span class="n">File</span> <span class="s">&quot;test.py&quot;</span><span class="p">,</span> <span class="n">line</span> <span class="mi">9</span><span class="p">,</span> <span class="ow">in</span> <span class="n">test_class</span>
<span class="bp">self</span><span class="o">.</span><span class="n">assertEqual</span><span class="p">(</span><span class="n">my_HTML</span><span class="o">.</span><span class="n">value</span><span class="p">,</span> <span class="s">&#39;&lt;html&gt;Hey!&lt;/html&gt;&#39;</span><span class="p">)</span>
<span class="ne">AssertionError</span><span class="p">:</span> <span class="s">&#39;&#39;</span> <span class="o">!=</span> <span class="s">&#39;&lt;html&gt;Hey!&lt;/html&gt;&#39;</span>
<span class="o">----------------------------------------------------------------------</span>
<span class="n">Ran</span> <span class="mi">2</span> <span class="n">tests</span> <span class="ow">in</span> <span class="mf">0.000</span><span class="n">s</span>
<span class="n">FAILED</span> <span class="p">(</span><span class="n">failures</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
</pre></div>
</td></tr></table>
<p>AHHH!! WHAT IS HAPPENING!? My instinct was to think that UnitTests just work in reallly wierd ways that I don't understand. So I figured I experimented. </p>
<p>The next thing I tried was this: Instead of re-instantiating HTMLString inside each test function I defined one of UnitTest's magic setUp functions. When running unit tests, if you define a function called <code>setUp()</code>, then Python will know to run this function before every other test funciton. So I made a setUp function to perform <code>my_HTML = HTMLString()</code>. And then I got the same errors as I did when I never re-instantiated at all. Its like my program didn't even run my setUp function at all! I tried doing the same thing but with a tearDown() function, and again had no luck. </p>
<p>I was so confused. I got my awesome friend <a href="http://programmingforwitches.tumblr.com">Amanda</a>'s help, and she suggested that, instead of writing <code>from string_maker import *</code>, that I just import the functions I needed to run my code. This was a good idea, but it didn't work either. Amanda was awesome though, because she asked me all sorts of questions, and those questions helped me realize what I was doing wrong! Here's what I learned:</p>
<p>When I re-instantiate the <code>my_HTML = HTMLString()</code> inside each of my test functions, I am creating a local instance of this class. Local, meaning, in the scope of the function. Then I call <code>add_to_string</code> which updates the <em>global</em> instance of my_HTML (ie. the instance of the class that is in my code string_maker.py)
. <strong>These are not the same object!</strong> So I update the global instance, and then assertEqual on the local instance, which of course still have an empty value string. </p>
<p>If this isn't making sense, remember that when you create a function you create a scope for that function. When a function encounters a name its not familiar with, it will first check within its own scope, ie within its own definition, to see if there is anything by that name defined there. If there isn't, then it will look for things outside of its own scope. As soon as it finds something, it uses it. </p>
<p>Take Away: <strong>You can have a local variable and a global variable that have the same name, but they are not the same thing!!!!</strong> </p></summary></entry><entry><title>Regular Expressions in Python - with LOTS of Examples!</title><link href="http://lmontopo.github.io/regular-expressions-in-python-with-lots-of-examples.html" rel="alternate"></link><updated>2014-12-04T05:00:00-05:00</updated><author><name>Leta Montopoli</name></author><id>tag:lmontopo.github.io,2014-12-04:regular-expressions-in-python-with-lots-of-examples.html</id><summary type="html"><p>Over the past several days I've learned a great deal about regular
expressions. I struggled initially with the subject, but I think things
have finally clicked. So, I'm going to write what I've learned! In this
blog post I am going to:</p>
<ul>
<li>Explain what a regular expression is.</li>
<li>Introduce <code>re.split()</code> and use it to provide examples.</li>
<li>Explain some of the ways that the star, dot, and question mark can
be used in a regular expression.</li>
<li>Explain, in detail, the plague of the backslash.</li>
</ul>
<p>As I learned about regular expressions, I found examples to be
enourmously helpful. For this reason, there will be a TON of examples
throughout this blogpost.</p>
<h4>What is a regular expression?</h4>
<p>A regular expression is sequence of characters that represent a pattern
we would like to search for within a larger chunk of text. There are two
types of characters within a regular expression: ones that represent
themselves, called <strong>ordinary characters</strong>, and one's that don't
represent themselves, called <strong>special characters</strong>. Most common
characters, like the letter 'a', match to themselves in a python regular
expression.</p>
<h4>Introducing the split function:</h4>
<p>To use regular expression in Python you need to <code>import re</code>. This module
gives you access to many different methods. The ones I use the most are
<code>re.split(pattern, string)</code> and <code>re.match(patter, string)</code>. I find
<code>re.split()</code> easiest to understand, so we'll start there. We'll visit
<code>re.search()</code> later.</p>
<p>The <code>re.split(pattern, string)</code> is very similar to python's built in
split method for strings. It splits the inputed string over the pattern
expressed by the regular expression. By default, <code>re.split()</code> will
return a list of all the parts of the string, excluding the parts that
matched the pattern. If you would like the resulting list to include the
sections which match to the pattern then parenthesis are needed around
the regular expression:</p>
<h5>Example 1: Introductiory Example:</h5>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4</pre></div></td><td class="code"><div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="kn">import</span> <span class="nn">re</span><span class="o">&gt;&gt;&gt;</span> <span class="n">text</span> <span class="o">=</span> <span class="s">&#39;Hackerschool is cool.&#39;</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;a&quot;</span><span class="p">,</span> <span class="n">text</span><span class="p">)</span>
<span class="p">[</span><span class="s">&#39;H&#39;</span><span class="p">,</span> <span class="s">&#39;ckerschool is cool.&#39;</span><span class="p">]</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;(a)&quot;</span><span class="p">,</span> <span class="n">text</span><span class="p">)[</span><span class="s">&#39;H&#39;</span><span class="p">,</span> <span class="s">&#39;a&#39;</span><span class="p">,</span> <span class="s">&#39;ckerschool is cool.&#39;</span><span class="p">]</span>
</pre></div>
</td></tr></table>
<p>As you can see, when we put parentheses around 'a', then 'a' is included
in the resulting list. But perhaps we have a pattern that is more than
one character long, and we want only part of the pattern to be kept in
the array. To do this brackets are put around the part of the regular
expression we want to keep. Check it out:</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2</pre></div></td><td class="code"><div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="n">re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;a(ck)&quot;</span><span class="p">,</span> <span class="n">text</span><span class="p">)</span>
<span class="p">[</span><span class="s">&#39;H&#39;</span><span class="p">,</span><span class="s">&#39;ck&#39;</span><span class="p">,</span> <span class="s">&#39;erschool is cool.&#39;</span><span class="p">]</span>
</pre></div>
</td></tr></table>
<p>Here the 'a' is still left out because it wasn't included in the
parentheses!</p>
<h4>Special Characters Star, Period and Question Mark:</h4>
<p>We're going to use <code>re.split()</code> to explore what these special symbols
match to in a regular expression.</p>
<h5>Example 2: The period:</h5>
<p>According to Python's regular expression documentation, the period
matches any character except a newline.</p>
<p>so as you'd expect it is going to split on every character...</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7
8</pre></div></td><td class="code"><div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="n">text</span> <span class="o">=</span> <span class="s">&quot;Hackerschool is cool</span>
<span class="err">!</span><span class="s">&quot;&gt;&gt;&gt; re.split(&quot;</span><span class="p">(</span><span class="o">.</span><span class="p">)</span><span class="s">&quot;, text)[&#39;&#39;, &#39;H&#39;,</span>
<span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39;a&#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39;c&#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39;k&#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39;e&#39;</span><span class="p">,</span>
<span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39;r&#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39;s&#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39;c&#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39;h&#39;</span><span class="p">,</span>
<span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39;o&#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39;o&#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39;l&#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39; &#39;</span><span class="p">,</span>
<span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39;i&#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39;s&#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39; &#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39;c&#39;</span><span class="p">,</span>
<span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39;o&#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39;o&#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39;l&#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">,</span> <span class="s">&#39;!&#39;</span><span class="p">,</span>
<span class="s">&#39;&#39;</span><span class="p">]</span>
</pre></div>
</td></tr></table>
<p>It might be surprising to you that there are empty string elements
between each character. I was surprised! I don't really have a good
explanation for why this happens except to say that this is just the way
the split function works. It finds the pattern we are searching for, and
then says "OK, on the left side of this pattern instance we have (fill
in the blank) and on the right side we have (fill in the blank)". In our
example, since every character is an instance of the pattern, on either
side of each pattern instance there is only the empty string. We'll see
another occurence of this behaviour in a later example. If it doesn't
make sense to you now, hopefully it will then.</p>
<p>Now lets combine the dot with other characters:</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3</pre></div></td><td class="code"><div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="n">re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;(.ool)&quot;</span><span class="p">,</span> <span class="n">text</span><span class="p">)[</span><span class="s">&#39;Ha</span>
<span class="n">ckersc</span><span class="s">&#39;, &#39;</span><span class="n">hool</span><span class="s">&#39;, &#39;</span> <span class="ow">is</span> <span class="s">&#39;, &#39;</span><span class="n">cool</span><span class="s">&#39;, &#39;</span><span class="err">!</span><span class="s">&#39;</span>
<span class="p">]</span>
</pre></div>
</td></tr></table>
<p>This makes sense - there were two occurences where there appeared "some
character followed by 'ool'".</p>
<p>Lets try a couple more examples just to make sure we get the hang of it:</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4</pre></div></td><td class="code"><div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="n">re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;(c.o)&quot;</span><span class="p">,</span> <span class="n">text</span><span class="p">)</span>
<span class="p">[</span><span class="s">&#39;Hackers&#39;</span><span class="p">,</span> <span class="s">&#39;cho&#39;</span><span class="p">,</span> <span class="s">&#39;ol is &#39;</span><span class="p">,</span> <span class="s">&#39;coo&#39;</span><span class="p">,</span> <span class="s">&#39;l!&#39;</span><span class="p">]</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;(c.h)&quot;</span><span class="p">,</span> <span class="n">text</span><span class="p">)</span>
<span class="p">[</span><span class="s">&#39;Hackerschool is cool!&#39;</span><span class="p">]</span>
</pre></div>
</td></tr></table>
<p>The first time we split over 'cho' and 'coo' since both are instances of
the pattern "'c' followed by some character followed by 'o'". The second
time we don't split the expression at all. Even though 'ch' is in
school, there is no character between the 'c' and the 'h'. So 'ch'
doesn't match to the regular expression 'c.h'. The lesson here is that
<strong>'.' on its own matches to exactly one instance of any character</strong>. Not
zero, not two, one.</p>
<h5>Example 3: The period and the star.</h5>
<p>The star represents 0 or more repititions of the previous character
expressed in the regular expression. Whenever possible, the star will
'suck up' as much as it can. Because of this behaviour, star is called a
<strong>greedy character</strong>.</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6</pre></div></td><td class="code"><div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="n">text</span> <span class="o">=</span> <span class="s">&quot;I like reading scify books.&quot;</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;(s.i)&quot;</span><span class="p">,</span> <span class="n">text</span><span class="p">)</span>
<span class="p">[</span><span class="s">&#39;I like reading &#39;</span><span class="p">,</span> <span class="s">&#39;sci&#39;</span><span class="p">,</span> <span class="s">&#39;fi books.&#39;</span><span class="p">]</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;(s.*i)&quot;</span><span class="p">,</span> <span class="n">text</span><span class="p">)</span>
<span class="p">[</span><span class="s">&#39;I like reading &#39;</span><span class="p">,</span> <span class="s">&#39;scifi&#39;</span><span class="p">,</span> <span class="n">books</span><span class="o">.</span><span class="s">&#39;]</span>
<span class="o">&gt;&gt;&gt;</span>
</pre></div>
</td></tr></table>
<p>Without the star, the regular expression 's.i' will match to 'sci'. When
the star is added the regular expression matches to more stuff! The
expression 's.*i' matches to 'scifi' because the star indicates that
the dot can be repeated 0 or more times. Because the star is greedy it
soaks up as many repetitions as possible.</p>
<p>Lets see what happens when we change the text to "I like science
books.".</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3</pre></div></td><td class="code"><div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="n">text</span> <span class="o">=</span> <span class="s">&quot;I like science books.&quot;</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;(s.*i)&quot;</span><span class="p">,</span> <span class="n">text</span><span class="p">)</span>
<span class="p">[</span><span class="s">&#39;I like &#39;</span><span class="p">,</span> <span class="s">&#39;sci&#39;</span><span class="p">,</span> <span class="s">&#39;ence books.&#39;</span><span class="p">]</span>
</pre></div>
</td></tr></table>
<p>Now that there is only one 'i' in the text, there are no more characters
that the star can suck up, so, "s.*i" matches to 'sci'.</p>
<h5>Example 4: The Question Mark</h5>
<p>The question matches either 0 or 1 repetitions of the preceeding regular
expression. Here are some examples:</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6</pre></div></td><td class="code"><div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="n">text</span> <span class="o">=</span> <span class="s">&quot;There are num sections in this document.&quot;</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;(e.*)&quot;</span><span class="p">,</span> <span class="n">text</span><span class="p">)</span>
<span class="p">[</span><span class="s">&#39;Th&#39;</span><span class="p">,</span> <span class="s">&#39;ere are num sections in this document.&#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">]</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;(e.?)&quot;</span><span class="p">,</span> <span class="n">text</span><span class="p">)</span>
<span class="p">[</span><span class="s">&#39;Th&#39;</span><span class="p">,</span> <span class="s">&#39;er&#39;</span><span class="p">,</span> <span class="s">&#39;&#39;</span><span class="p">,</span><span class="s">&#39;e &#39;</span><span class="p">,</span> <span class="s">&#39;ar&#39;</span><span class="p">,</span> <span class="s">&#39;e &#39;</span><span class="p">,</span> <span class="s">&#39;num s&#39;</span><span class="p">,</span> <span class="s">&#39;ec&#39;</span><span class="p">,</span> <span class="s">&#39;tions in this docum&#39;</span><span class="p">,</span> <span class="s">&#39;en&#39;</span><span class="p">,</span> <span class="s">&#39;t.&#39;</span><span class="p">]</span>
<span class="o">&gt;&gt;&gt;</span>
</pre></div>
</td></tr></table>
<p>When we use the question mark instead of the star there are many more
matches to the regular expression! The question mark is basically the
oposite of a greedy character.</p>
<p>Also, notice the occurence of an empty string between the 'er' and the
'e'. Since we are splitting over the 'er' and the 'e' the split
functions wants to put something on either side of these that isn't
something else we're splitting over. The only thing between the 'er' and
the 'e' is the empty string. Hopefully this examples helps to understand
the whole empty string phenomenon.</p>
<h5>Example 5: Combining the dot, star, and question mark:</h5>
<p>Lets see what happens when we combine all three: the dot, the star, and
the question mark.</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5</pre></div></td><td class="code"><div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="n">text</span> <span class="o">=</span> <span class="s">&quot;There are num sections in this document.&quot;</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;(e.*?)&quot;</span><span class="p">,</span> <span class="n">text</span><span class="p">)</span>
<span class="p">[</span><span class="s">&#39;Th&#39;</span><span class="p">,</span> <span class="s">&#39;e&#39;</span><span class="p">,</span> <span class="s">&#39;r&#39;</span><span class="p">,</span> <span class="s">&#39;e&#39;</span><span class="p">,</span> <span class="s">&#39;ar&#39;</span><span class="p">,</span> <span class="s">&#39;e&#39;</span><span class="p">,</span> <span class="s">&#39; num s&#39;</span><span class="p">,</span> <span class="s">&#39;e&#39;</span><span class="p">,</span>
<span class="s">&#39;ctions in this docum&#39;</span><span class="p">,</span> <span class="s">&#39;e&#39;</span><span class="p">,</span> <span class="s">&#39;nt.&#39;</span><span class="p">]</span>
<span class="o">&gt;&gt;&gt;</span>
</pre></div>
</td></tr></table>
<p>Placing the question mark after a the star makes the regular expression
match to the minimal number of characters possible. We'll see this more
in the next example...</p>
<h5>Example #4: Application to my Template Engine:</h5>
<p>I have been working on writing my own template engine. In my language,
variables will be contained within double curly braces. I used regular
expressions to parse the html template and find all of the variables.
Lets see an example:</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3</pre></div></td><td class="code"><div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="n">html_text</span> <span class="o">=</span> <span class="s">&quot;&lt;html&gt;&lt;title&gt; Hello {{name}}.&lt;/title&gt; Today is {{day}}.&lt;/html&gt;&quot;</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;({{.*?}})&quot;</span><span class="p">,</span> <span class="n">html_text</span><span class="p">)</span>
<span class="p">[</span><span class="s">&#39;&lt;html&gt;&lt;title&gt; Hello &#39;</span><span class="p">,</span><span class="s">&#39;{{name}}&#39;</span><span class="p">,</span> <span class="s">&#39;.&lt;/title&gt; Today is &#39;</span><span class="p">,</span><span class="s">&#39;{{day}}&#39;</span><span class="p">,</span> <span class="s">&#39;.&lt;/html&gt;&#39;</span><span class="p">]</span>
</pre></div>
</td></tr></table>
<p>Just to make sure we understand what the star and question mark are
doing, lets see what happens when either one is removed:</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4</pre></div></td><td class="code"><div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="n">re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;({{.*}})&quot;</span><span class="p">,</span> <span class="n">html_text</span><span class="p">)</span>
<span class="p">[</span><span class="s">&#39;&lt;html&gt;&lt;title&gt; Hello &#39;</span><span class="p">,</span> <span class="s">&#39;{{name}}.&lt;/title&gt; Today is {{day}}&#39;</span><span class="p">,</span> <span class="s">&#39;.&lt;/html&gt;&#39;</span><span class="p">]</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">re</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">&quot;({{.?}})&quot;</span><span class="p">,</span> <span class="n">html_text</span><span class="p">)</span>
<span class="p">[</span><span class="s">&#39;&lt;html&gt;&lt;title&gt; Hello {{name}}.&lt;/title&gt; Today is {{day}}.&lt;/html&gt;&#39;</span><span class="p">]</span>
</pre></div>
</td></tr></table>
<p>When the question mark is removed, the star acts greedily and soaks
everything up until the last occurence of '}}'. When the star is
removed, we have no match to our pattern at all. This is because the
variable names inside the curly braces are more than 1 character long.</p>
<h4>The plague of the backslash:</h4>
<p>Now we have a handle on those special functions, lets explore the ...
dun dun dun... THE BACKSLASH!</p>
<p>Beleive it or not, the regular expression for a backslash is FOUR
backslashes. Woah. Lets walk through why this is the case:</p>
<p>In python, a backslash is a special character, and so to represent a
backslash we actually need to use two backslashes. So in python two
backslashes represents one. I'm not even talking about regular
expressions yet, I'm just talking about python strings. Lets verify
this:</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5</pre></div></td><td class="code"><div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="n">backslash</span> <span class="o">=</span> <span class="s">&quot;</span><span class="se">\\</span><span class="s">&quot;</span>
<span class="o">&gt;&gt;&gt;</span> <span class="nb">len</span><span class="p">(</span><span class="n">backslash</span><span class="p">)</span>
<span class="mi">1</span>
<span class="o">&gt;&gt;&gt;</span> <span class="k">print</span> <span class="n">backslash</span>
\
</pre></div>
</td></tr></table>
<p>Neat!</p>
<p>Ok, so this means that we actually have to write a regular expression
which will match to two backslashes instead of to a single backslash.
Now, in regular expression land, backlash is one of those special
characters we talked about previously. They don't match to themselves.
The regular expression for a backslash is also two backslashes. So,
since we want to match to the python string <code>\\</code> the regular expression
to do so becomes <code>\\\\</code>.</p>
<p>I hope you've enjoyed this introduction to regular expression in Python.
If anything is confusing, don't hesitate to contact me!</p></summary></entry><entry><title>I made my first cookie!</title><link href="http://lmontopo.github.io/i-made-my-first-cookie.html" rel="alternate"></link><updated>2014-11-27T05:00:00-05:00</updated><author><name>Leta Montopoli</name></author><id>tag:lmontopo.github.io,2014-11-27:i-made-my-first-cookie.html</id><summary type="html"><p>Margo and I have been working on our web-framework, Chapeau. To test out
its functionality and user-friendliness, we've been using Chapeau to
build various web-apps. This week we implimented a buzz-feed-style quiz.
To challenge ourselves (and Chapeau) we structured the app to have a
separate webpage for each question, and then a final webpage displaying
the result. This forced us to address the issues: 'Does Chapeau allow
data to be transfered between non-adjacent webpages?' and 'Does Chapeau
allow for the data to be accessed directly and used in a calculation'?
As we tried to answer these questions and broaden the functionality of
Chapeau, the framework took on several variations. In this blog post
I'll begin by describing how Chapeau works for very simple web-apps, and
then I'll continue by explaining some of the changes we made to Chapeau
as we worked towards our buzz-feed-style quiz.</p>
<h4>Simple Web Apps</h4>
<p>Chapeau's design makes very simple web-apps just that: very simple. To
make such an app, a developer needs only to define a dicitonary matching
URL's to their corresponding html pages. Then calling Chapeau's 'go'
function on the dictionary gets everything going. Pretty simple right?
Beleive it or not, with Chapeau, an app this simple can even pass
variables from an html form to the webpage that follows. The app itself
(by 'app' I mean the python code) does not need to be changed to include
this feature. Adding very basic variable passing to a Chapeau app is
just a matter of formatting your html pages accordingly. Here's how to
do it:</p>
<ul>
<li>The form must specify either 'method = get' or 'method = post',
since Chapeau deals only with post and get requests.</li>
<li>The form's action needs to specify the URL that this form redirects
to.</li>
<li>The html page corresponding to this URL should have '%(key)s'
wherever this key's value is meant to appear.</li>
</ul>
<p>How is this all working? In the background Chapeau parses the request
made from the form's submission. Chapeau finds the user's input in this
request and stores it in a dictionary of key-value pairs called params.
The specified html file is then read in as a string with '%params'
tacked on to the end. Python's built in string formatting takes care of
the rest, and the page renders with the desired arguments! Easy-peasy.</p>
<p>But what if we wanted to mutate the user input in some way? Or what if
we wanted to <em>use</em> the input to perform some sort of analysis or
calculation? Perhaps we want to create some results for a quiz? Our
initial version of Chapeau could not handle such situations.</p>
<h4>Adding Functions</h4>
<p>To extend Chapeau's usability Margo and I decided that web developers
would have the choice to route a URL to a path or to a function. If a
URL is routed to a function then this function would have a few
structural constraints. Initially, these were the constraints we
implimented:</p>
<ul>
<li>Chapeau will be passing a dictionary into the function, so the
function must be defined to accept it. This dictionary will contain
some of the request information and will look something like:
'{'type': 'get', 'query': 'query_string', 'path': 'url' , 'body':
'user_input_from_post_form'}'. (Basically this dictionary stores
all of the request information except for the headers.)</li>
<li>The function must return two objects: a path and a dictionary. The
path will specify the next html page to be rendered and the
dictionary will be the same one that the function receives, but
possibly with some mutated data.</li>
</ul>
<p>The dictionary that the function takes in gives the developer access to
the user input that was just aquired. If the developer wanted to mutate
this user input in anyway, they could do so. Alternatively, if the
developper wants user input to be saved so that it can be obtained
later, Margo and I figured this could be done as well. The developper
could create a global dictionary that they can add to when user input is
submitted, and that they could read from later. Problem solved. Except
not really.</p>
<p>More experienced developpers might already see the problem we've
created. Consider the buzz-feed-style quiz that Margo and I wanted to
create. Suppose that we implimented this app by storing the user input
in a global dictionary. This dictionary is updated after every question
is answered. When the results page needs to be rendered all of the user
input is obtained from the global dictionary. But suppose two clients,
client1 and client2, are taking the quiz simultaneously. Client1 inputs
their answer to question 1 first, and chooses 'grapes'. Before client1
finishes the quiz client2 submits their answer to question 1 as
'oranges'. When our app goes to fetch the results of client1, their
'grapes' answer will have been overwritten by 'oranges'. Afterall, we've
only implimented one global dictionary for our entire client base. Oups.</p>
<h4>Finally, adding Cookies!</h4>
<p>At this point Margo and I weren't really sure how to solve this issue.
How do we keep track of which answer corresponds to which client? For
advice, we turned to our trusted friend
<a href="http://www.greghendershott.com">Greg</a> who suggested we use cookies!</p>
<p><strong>What is a cookie, and how do I make one?</strong></p>
<p>A cookie is a very small peice of data that will be sent from a server
and stored temporarily on a client's computer. To create a cookie, the
server needs to include a 'Set-Cookie' header in their HTTP response to
the client. This will prompt the client's browser to create a 'cookie'
to store the specified data. When a browser has a cookie from our server
any HTTP request it sends to us will include a 'Cookie' header
containing the data we asked it to store.</p>
<p><strong>How does this help our situation?</strong></p>
<p>Margo and I used cookies to store every quiz answer submited from a
client. Then, when the client's browser sends our server an HTTP request
asking for their results page, this request will include all of that
client's quiz answers - stored in the form of cookies! Great!</p>
<p>Now lets talk about how we implimented this. To create cookies Margo and
I changed the constraints of our functions (the ones that URL's are
routed to) as follows:</p>
<ul>
<li>Chapeau will now pass to these functions both the dictionary
containing the request information and a client object. So these
functions must now accept two parameters! The dicitonary accepted
contains everything the previous one does, but also includes
'{header: {all of the headers and their values}}'.</li>
<li>The functions must call Chapeau's render function: render(client,
path/to/html/file, args, header) before returning None.</li>
</ul>
<p>Now that <em>all</em> of the request information is passed to the developper,
cookies can be read. Since the developer is now also in charge of
calling the render function, they have control over any headers they
want to include in their response. The header parameter in the render
function is optional, and when unspecified it will be set to None. The
args parameter is a dictionary of variables that we want to pass to the
html file. So, in our buzz-feed-style-quiz, every client's answer will
be saved in a cookie. When we want to render the results page all of the
incoming cookies can be read from the inputed dictionary of request
information. We can create another dictionary out of the received
cookies and can pass this dictionary into our render function to be
passed to our html file. Yay!</p>
<p>Thanks Margo for working on this project with me, its been an adventure!</p></summary></entry><entry><title>Lisp Interpreter: Episode 3 (The Finally!) ... Continued.</title><link href="http://lmontopo.github.io/lisp-interpreter-episode-3-the-finally-continued.html" rel="alternate"></link><updated>2014-11-24T05:00:00-05:00</updated><author><name>Leta Montopoli</name></author><id>tag:lmontopo.github.io,2014-11-24:lisp-interpreter-episode-3-the-finally-continued.html</id><summary type="html"><p>In last week's episode we inspected how my program tokenizes and parses
the user's input. In the spirit of finishing this series of blog posts,
I have decided today to present an overview of how the rest of my
program works. We'll walk through the basic algorithm that my program
follows, pausing at some of the more exciting and important parts. I'll
do my best to skip over the less exciting bits of code, while still
providing enough information to convey the general ideas. If anyone
would like to see the code in its entirety, feel free to check it out on
my github account: <a href="https://github.com/lmontopo/Lispeter">https://github.com/lmontopo/Lispeter</a>. As always, I
welcome any questions or comments about either this blog post or the
code i'm describing. Lets begin!</p>
<p>After the user's Scheme input is parsed and tokenzied, it is passed to a
function which 'unwraps' it. This funciton is called 'outer_evaluate'.
Remember how, in the tokenzier, the input gets wrapped in an extra set
of parenthesis? My 'outer_evaluate' function is how I dealt with this.
It evaluates from left to right each of the internal expressions within
the parsed expression and then it spit out the result of the last
expression. Here's the function:</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5</pre></div></td><td class="code"><div class="highlight"><pre><span class="k">def</span> <span class="nf">outter_evaluate</span><span class="p">(</span><span class="n">list_input</span><span class="p">,</span><span class="n">env</span><span class="p">):</span>
<span class="n">evaluated_list</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">expression</span> <span class="ow">in</span> <span class="n">list_input</span><span class="p">:</span>
<span class="n">evaluated_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">evaluate</span><span class="p">(</span><span class="n">expression</span><span class="p">,</span> <span class="n">env</span><span class="p">))</span>
<span class="k">return</span> <span class="n">evaluated_list</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
</pre></div>
</td></tr></table>
<p>Here, 'evaluate' is the main function that interprets the parsed input.
Inside 'evaluate' the input is classified as either a list or an atom
and is passed to the 'is_cons' and 'is_atom' functions respectively.
The 'is_atom' function is pretty straightforward since atoms are
self-evaluating, but I'll take a bit of time to describe how the
'is_cons' function works.</p>
<p>When 'is_cons' is called it inspects the first element of the list that
is inputed. Assuming that our input is a valid Scheme expression, we
expect the first item in this list to be a function. 'is_cons' will
check to see if this function is in our pre-defined list of special
functions. (Recall that special functions are the ones that change the
flow of the interpretation.) Once the program has decided if the
function is special or not, input is directed to either the
'is_special' or 'is_regular' function, whichever is appropriate. Lets
talk a bit about both of these functions.</p>
<p>The 'is_special' function consists of a case by case evaluation of what
to do for each special operator. I'll just present a subset of this
function because the whole thing is a little long and overwhelming.
Here's some of it:</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 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</pre></div></td><td class="code"><div class="highlight"><pre><span class="k">def</span> <span class="nf">call_special</span><span class="p">(</span><span class="n">list_input</span><span class="p">,</span> <span class="n">env</span><span class="p">):</span>
<span class="n">head</span><span class="p">,</span> <span class="n">rest</span> <span class="o">=</span> <span class="n">list_input</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">list_input</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
<span class="k">if</span> <span class="n">head</span> <span class="o">==</span> <span class="s">&quot;map&quot;</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">rest</span><span class="p">)</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>
<span class="n">new_head</span><span class="p">,</span> <span class="n">list_to_act_on</span> <span class="o">=</span> <span class="n">rest</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">evaluate</span><span class="p">(</span><span class="n">rest</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">env</span><span class="p">)</span>
<span class="n">new_list</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">list_to_act_on</span><span class="p">:</span>
<span class="n">new_item</span> <span class="o">=</span> <span class="n">interpret</span><span class="p">(</span><span class="s">&quot;(</span><span class="si">%s</span><span class="s"> </span><span class="si">%s</span><span class="s">)&quot;</span> <span class="o">%</span><span class="p">(</span><span class="n">new_head</span><span class="p">,</span> <span class="n">item</span><span class="p">),</span> <span class="n">env</span><span class="p">)</span>
<span class="n">new_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">new_item</span><span class="p">)</span>
<span class="k">return</span> <span class="n">new_list</span>
<span class="k">if</span> <span class="n">head</span> <span class="o">==</span> <span class="s">&#39;define&#39;</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">rest</span><span class="p">)</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">rest</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="ow">is</span> <span class="nb">str</span><span class="p">:</span>
<span class="n">env</span><span class="o">.</span><span class="n">add_values</span><span class="p">(</span><span class="n">rest</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">rest</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">name</span> <span class="o">=</span> <span class="n">rest</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span>
<span class="n">expression</span> <span class="o">=</span> <span class="n">MakeLambda</span><span class="p">(</span><span class="n">rest</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">:],</span> <span class="n">rest</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
<span class="n">env</span><span class="o">.</span><span class="n">add_values</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">expression</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">too_many</span>
<span class="k">if</span> <span class="n">head</span> <span class="o">==</span> <span class="s">&#39;lambda&#39;</span><span class="p">:</span>
<span class="n">func</span> <span class="o">=</span> <span class="n">MakeLambda</span><span class="p">(</span><span class="n">rest</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span><span class="n">rest</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
<span class="n">env</span><span class="o">.</span><span class="n">add_values</span><span class="p">(</span><span class="s">&#39;lam&#39;</span><span class="p">,</span> <span class="n">func</span><span class="p">)</span>
<span class="k">return</span> <span class="s">&#39;lam&#39;</span>
<span class="k">if</span> <span class="n">head</span> <span class="o">==</span> <span class="s">&#39;quote&#39;</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">list_input</span><span class="p">)</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>
<span class="k">return</span> <span class="n">rest</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">quote_error</span>
</pre></div>
</td></tr></table>
<p>The input is split into the 'head' and 'rest', the 'head' being the
special operator. Each special function has a corresponding bit of code
which indicates how to interpret that kind of expression. Notice that
when we encounter 'lambda' and 'define' operators we use some sort of
'MakeLambda' magic. Don't worry, i'll come back to explaining this
magic, but first I want to present the 'call_regular' function, where
more magic appears!</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7
8
9</pre></div></td><td class="code"><div class="highlight"><pre><span class="k">def</span> <span class="nf">call_regular</span><span class="p">(</span><span class="n">list_input</span><span class="p">,</span><span class="n">env</span><span class="p">):</span>
<span class="n">new_list_input</span> <span class="o">=</span><span class="p">[]</span>
<span class="k">for</span> <span class="n">term</span> <span class="ow">in</span> <span class="n">list_input</span><span class="p">:</span>
<span class="n">new_list_input</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">evaluate</span><span class="p">(</span><span class="n">term</span><span class="p">,</span><span class="n">env</span><span class="p">))</span>
<span class="n">list_input</span> <span class="o">=</span> <span class="n">new_list_input</span>
<span class="n">head</span><span class="p">,</span> <span class="n">rest</span> <span class="o">=</span> <span class="n">list_input</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">list_input</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
<span class="k">return</span> <span class="n">env</span><span class="o">.</span><span class="n">fetch</span><span class="p">(</span><span class="n">head</span><span class="p">)</span><span class="o">.</span><span class="n">do_fun</span><span class="p">(</span><span class="n">rest</span><span class="p">,</span> <span class="n">env</span><span class="p">)</span>
</pre></div>
</td></tr></table>
<p>In contrast to the 'call_special' function which outlines a specific
proceedure for each special operator, the regular functions are all
dealt with in exactly the same way. This is something I'm quite proud
of. Its just so <em>pretty</em>!</p>
<p>Again, notice the magic... I'm calling some 'do_fun' method on some
'env.fetch' thing... What is all this?! To explain whats going on here,
I'll start by talking about environments. I implimented a class called
Scope to keep track of my environment throughout the evaluation process.
Here it is:</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
2
3
4
5
6
7
8
9
10
11
12
13
14</pre></div></td><td class="code"><div class="highlight"><pre><span class="c"># --- DEFINING SCOPE --- </span>
<span class="k">class</span> <span class="nc">Scope</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">env</span><span class="p">,</span> <span class="n">parent</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">env</span> <span class="o">=</span> <span class="n">env</span>
<span class="bp">self</span><span class="o">.</span><span class="n">parent</span> <span class="o">=</span> <span class="n">parent</span>
<span class="k">def</span> <span class="nf">add_values</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">key</span><span class="p">,</span><span class="n">value</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span>
<span class="k">def</span> <span class="nf">fetch</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
<span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="o">.</span><span class="n">keys</span><span class="p">():</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">env</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">parent</span> <span class="o">!=</span> <span class="bp">None</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">fetch</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
</pre></div>
</td></tr></table>
<p>Every scope object consists of an environment and a parent. The
environment is a dictionary containing variables/functions and their
values/expressions. The parent of a scope instance is the smallest scope
containing it. If a scope's parent is not specified then it gets the
default parent, 'None'. The global scope will have a None parent but all
other scopes should have a legitimate parent, possibly the global scope.</p>
<p>Lets inspect the methods of the Scope class. The 'add_values' method
simply updates the environment by adding more key value pairs. The
'fetch' method looks up variables in the scope's environment. Notice
that if we have no luck looking up a variable in the current
environment, then fetch will redirect us to our parent's environment.
This means that even if our current scope is not the global scope, all
of the variables in the global environment can still be accessed. But,
since we look in our current scope first, it also means that we can
re-define any of the global variables in our current scope, and, when we
fetch for the values of these variables, we'll get the appropriate,
re-defined, value.</p>
<p>By now we should understand that <code>env.fetch(head)</code> is returning the
value of the key 'head' from the dictionary in our current scope. What
we have yet to discuss is what 'MakeLambda', and 'do_fun' are refering
to. Here's the bit of code that defines these terms:</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 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</pre></div></td><td class="code"><div class="highlight"><pre><span class="c"># ------ CLASSES OF FUNCTIONS ------</span>
<span class="k">class</span> <span class="nc">MakeLambda</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">first</span><span class="p">,</span> <span class="n">second</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">first</span> <span class="o">=</span> <span class="n">first</span>
<span class="bp">self</span><span class="o">.</span><span class="n">second</span> <span class="o">=</span> <span class="n">second</span>
<span class="bp">self</span><span class="o">.</span><span class="n">params</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">first</span>
<span class="bp">self</span><span class="o">.</span><span class="n">exp</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">second</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<span class="k">def</span> <span class="nf">do_fun</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">env</span><span class="p">):</span>
<span class="n">zipped</span> <span class="o">=</span> <span class="nb">zip</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">params</span><span class="p">,</span> <span class="n">args</span><span class="p">)</span>
<span class="n">temp_scope</span> <span class="o">=</span> <span class="n">Scope</span><span class="p">({},</span> <span class="n">env</span><span class="p">)</span>
<span class="k">for</span> <span class="n">param</span><span class="p">,</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">zipped</span><span class="p">:</span>
<span class="n">temp_scope</span><span class="o">.</span><span class="n">add_values</span><span class="p">(</span><span class="n">param</span><span class="p">,</span> <span class="n">arg</span><span class="p">)</span>
<span class="k">return</span> <span class="n">evaluate</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">exp</span><span class="p">,</span> <span class="n">temp_scope</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">MakePyFun</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">everything</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span> <span class="n">everything</span> <span class="o">=</span> <span class="n">everything</span>
<span class="k">def</span> <span class="nf">do_fun</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">arguments</span><span class="p">,</span> <span class="n">env</span><span class="p">):</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">arguments</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">everything</span><span class="p">(</span><span class="n">arguments</span><span class="p">)</span>
<span class="k">elif</span> <span class="nb">len</span><span class="p">(</span><span class="n">arguments</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">everything</span><span class="p">(</span><span class="o">*</span><span class="n">arguments</span><span class="p">)</span>
</pre></div>
</td></tr></table>
<p>These classes are used to create function objects. I use the MakePyFun
class to make function objects out of the built-in, non-special, Scheme
functions. I use MakeLambda to make function objects for user defined
functions. (You'll remember that this MakeLambda was called when the
user input contained either 'lambda' or 'define' expressions.) The main
difference between these two classes is that functions created with the
MakeLambda class have a defined set of parameters which are specified in
their definition. This means that instances of MakeLambda cannot operate
on an arbitrary number of arguments. In comparison, functions defined
using the MakePyFun class, <em>can</em> be called on an aribitrary number of
arguments. One very important thing to notice, though, is that both the
MakePyFun class and the MakeLambda class have 'do_fun' methods which do
essentially the same thing: They take in some arguments and evaluate the
function on those arguments. This is how the 'call_regular' function
needed only to fetch the value of 'head' in our current scope and call
'do_fun' on the result. It didn't matter whether the result of fetch
was an instance of MakeLambda or of MakePyFun, because both have the
'do_fun' method!</p>
<p>At this point I've pretty much described all of the exciting aspects of
my program. But, before wrapping up this blog series, I think I owe it
to anyone who's made it this far to present a nice solid example.</p>
<p>Consider the user input <code>((define (f x)(+ x x))(f 4))</code>. After this
expression is tokenized and parsed it will enter the 'outer_evaluate'
function as: <code>[['define', ['f', 'x'], ['+', 'x', 'x']], ['f', '4']]</code>.
'Outter_evaluate' then calls 'evaluate' on the first item in this list,
<code>['define', ['f', 'x'], ['+', 'x', 'x']]</code>. Evaluate decides that this is
a list, and passes it on to the 'is_cons' function. 'is_cons' decides
that 'define' is a special function and passes the expression to
'call_special'. In 'call_special', 'head' is assigned to 'define' and
'rest' to <code>[['f', 'x'], ['+', 'x', 'x']]</code>. Since the
<code>if 'head' == 'define'</code> condition is satisfied, it's consequent block of
code is executed. This assigns 'name' to 'f' and 'expression' to
<code>MakeLambda(['x'], ['+', 'x', 'x'])</code> and adds them as a key-value pair
to our current environment. The first part of the user input has now
been evaluated, and control is turned back over to the <code>outter_evaluate</code>
function which calls <code>evaluate(['f', '4'])</code>. From 'evaluate' we are
redirected to 'is_cons' and then to 'call_regular'. In 'call_regular'
the value of 'f' is fetched from our current environment, returning the
MakeLambda object we previously instantiated. It's 'do_fun' method is
called with argument '4', returning <code>evaluate(['+', 'x', 'x'], env)</code>
where env contains <code>{'x' : '4'}</code>. This time 'evaluate' directs us once
again 'is_cons' which directs us to 'is_regular'. Here, both x's
evaluate to 4. and then we fetch '+' from our environment. We will not
find '+' in our current environment, but will find it in the global
environment. <code>env.fetch('+')</code> will return the instance of 'MakePyFun'
associated to addition. This will be called on the arguments
<code>['4','4']</code>, and finally, 8 will be returned. Phew.</p>
<p>And finally, I have finished my series of interpreting the interpreter.
I've learned alot through this project, and had a lot of fun in the
process. Thanks again to the awesome <a href="http://akaptur.com">Allison
Kaptur</a> for suggesting this project to me and for
your encouragement along the way. To anyone else out there who is
contemplating writing a lisp interpreter, I whole heartedly encourage
you to do so!</p>
<p>Thanks for reading!</p></summary></entry><entry><title>Little Lessons 3: URI's, 'urllib', Template engines, and generators.</title><link href="http://lmontopo.github.io/little-lessons-3-uris-urllib-template-engines-and-generators.html" rel="alternate"></link><updated>2014-11-19T05:00:00-05:00</updated><author><name>Leta Montopoli</name></author><id>tag:lmontopo.github.io,2014-11-19:little-lessons-3-uris-urllib-template-engines-and-generators.html</id><summary type="html"><p>I've learned so many fun little lessons over the past week, its time for
another post!</p>
<h4>What is a URI? Is it the same as a URL?</h4>
<p>URI stands for uniform resource identifier. A very common form of a URI
is the URL, which stands for uniform resource locator. The URL is just
the address of a website - ie. the thing you type into your browser when
you want to visit a webpage. Apparently, sometimes, the terms URI and
URL are used interchangeably. But, if you want to be precise, know that
a URL is a type of URI. Time to dig a little deaper into URL's...</p>
<h4>What meant by the 'path' and the 'query' of a URL?</h4>
<p>The wikipedia page,
<a href="http://en.wikipedia.org/wiki/Uniform_resource_locator">here</a>, does a
good job at explaining the URL. I'll summarize what I learned from it
here. The URL consists of several different parts. I'll introduce these
parts and discuss them with respect to this example:
http://www.cineplex.com/Search?Query=Interstellar</p>
<ul>
<li>The very first part of the URL is the <strong>protocol</strong>. It specifies
which application protocol is being used to obtain the resource. In
our example the application protocol is 'http'.</li>
<li>The <strong>domain name</strong> can be an IP address or a registered and easier
to remember name associated to an IP address. In our example the
domain name is 'cineplex.com'. If you are creating a server on your
own computer, your domain name might be 'localhost'.</li>
<li>After the domain name a <strong>port number</strong> can optionally be specified.
By default we are directed to port 8000, and so it is almost always
unnecessary to manually specify a port.</li>
<li>A single domain name or IP address can host a multitude of files.
The particular file/resource that a URL is after is specified by the
<strong>URL path</strong>. It specifies the address of the particular file we are
requesting and is analogous to the way in which we specify the path
to a particular file within our own computer. In our example the URL
path is '/Search'.</li>
<li>The <strong>query string</strong> contains data (usually inputed by the user)
which will be passed to some sort of software running on the server.
The example I've shown is the result of typing "Interstellar" into
the search bar on the cineplex homepage. "Interstellar" was passed
to the servers computer and used in some program to figure out the
output. Then the results were passed back to me in the webpage with
URL "http://www.cineplex.com/Search?Query=Interstellar". The query
string part of the URL is '?Query=Interstellar'. As far as I know,
the query string always starts with a question mark.</li>
</ul>
<h4>urllib.uncode('string') is great! Here's why:</h4>
<p>As I may have previously mentioned, I have decided to write my own web
framework. Not because I think I can do a better job than the existing
frameworks, but because I want to learn more about what is happening
behind the scenes with web development. An issue I encountered as I
developped my framework involved html forms and processing user input.
If a user inputed any special characters, like '!', '\~', '?', etc., my
browser would encode these characters and send my server an http request
with these encodings. For example, '!' was encoded as '%21'. Why is the
browser doing this? Although its tempting to think that this character
encoding is just a pain in the butt, its actually pretty useful! Indeed,
some characters in the URL have a special meaning. The question mark,
for example, is always used to signify the begining of a query. So
whenever the <em>USER</em> inputs characters which have (or may have) a special
meaning, the browser will encode these characters to avoid confusion.
The places where these characters are used by the browser to indicate a
special meaning, they are NOT encoded. So, to make this clear, when a
user inputs "?" into a form, it will be encoded. But if a query string
is present, the "?" at the begining of the query will not be encoded.
And this makes my life alot easier when I have to parse through the raw
http requests. I can guarantee that whenever I see a "?" it is
signifying the begining of a query string, and NOT some user input.
Great! But now, I DO have to worry about decoding the encoded characters
so that they can correctly be passed as a variable to an html page. How
do I decode a special character from its encoded represenation? Using
the python's urllib module!! Check it out:</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7
8
9</pre></div></td><td class="code"><div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="n">urllib</span><span class="o">.</span><span class="n">quote</span><span class="p">(</span><span class="s">&#39;!!!&#39;</span><span class="p">)</span>
<span class="s">&#39;</span><span class="si">%21%</span><span class="s">21%21&#39;</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">encoded_input</span> <span class="o">=</span> <span class="n">urllib</span><span class="o">.</span><span class="n">quote</span><span class="p">(</span><span class="s">&#39;&amp;!?&#39;</span><span class="p">)</span>
<span class="o">&gt;&gt;&gt;</span> <span class="k">print</span> <span class="n">encoded_input</span>
<span class="o">%</span><span class="mi">26</span><span class="o">%</span><span class="mi">21</span><span class="o">%</span><span class="mi">3</span><span class="n">F</span>
<span class="o">&gt;&gt;&gt;</span> <span class="n">decoded_input</span> <span class="o">=</span> <span class="n">urllib</span><span class="o">.</span><span class="n">unquote</span><span class="p">(</span>
<span class="n">encoded_input</span><span class="p">)</span>
<span class="o">&gt;&gt;&gt;</span> <span class="k">print</span> <span class="n">decoded_input</span>
<span class="o">&amp;</span><span class="err">!?</span>
</pre></div>
</td></tr></table>
<h4>What is a template engine?</h4>
<p>A template engine provides a way for users to put variables and possibly
even logic into their html templates. Templating engines consist of a
templating language and a templating compiler. The templating language
specifies syntax that will be understood to mean specific things in your
html template. So, for example, you could say that two curly braces will
enclose any variables and that a curly brace and a percent sign will
enclose any python logic. Then, you're compiler will parse this html
template and then will see which parts need to perform logic or input
variables, and will ultimately translate the template into an html page
void of any logic or variables, that can be displayed by your browser.
Often, template engines are part of what makes up a web framework.</p>
<h4>Generators are a kind of python object!</h4>
<p>You know how you can write lists like:</p>
<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2</pre></div></td><td class="code"><div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="p">[</span><span class="n">x</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="s">&#39;abcdefg&#39;</span><span class="p">]</span>
<span class="p">[</span><span class="s">&#39;a&#39;</span><span class="p">,</span><span class="s">&#39;b&#39;</span><span class="p">,</span> <span class="s">&#39;c&#39;</span><span class="p">,</span> <span class="s">&#39;d&#39;</span><span class="p">,</span> <span class="s">&#39;e&#39;</span><span class="p">,</span> <span class="s">&#39;f&#39;</span><span class="p">,</span> <span class="s">&#39;g&#39;</span><span class="p">]</span>
</pre></div>
</td></tr></table>