Added Python idiom links, added fancy web font for quote
[cipher-training.git] / slides / caesar-encipher.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title>Caesar cipher</title>
5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
6 <style type="text/css">
7 /* Slideshow styles */
8 body {
9 font-size: 20px;
10 }
11 h1, h2, h3 {
12 font-weight: 400;
13 margin-bottom: 0;
14 }
15 h1 { font-size: 3em; }
16 h2 { font-size: 2em; }
17 h3 { font-size: 1.6em; }
18 a, a > code {
19 text-decoration: none;
20 }
21 code {
22 -moz-border-radius: 5px;
23 -web-border-radius: 5px;
24 background: #e7e8e2;
25 border-radius: 5px;
26 font-size: 16px;
27 }
28 .plaintext {
29 background: #272822;
30 color: #80ff80;
31 text-shadow: 0 0 20px #333;
32 padding: 2px 5px;
33 }
34 .ciphertext {
35 background: #272822;
36 color: #ff6666;
37 text-shadow: 0 0 20px #333;
38 padding: 2px 5px;
39 }
40 .indexlink {
41 position: absolute;
42 bottom: 1em;
43 left: 1em;
44 }
45 </style>
46 </head>
47 <body>
48 <textarea id="source">
49
50 # Caesar ciphers
51
52 ![centre-aligned Caesar wheel](caesarwheel1.gif)
53
54 Letter-by-letter enciphering
55
56 ---
57
58 layout: true
59
60 .indexlink[[Index](index.html)]
61
62 ---
63
64 # Enciphering and deciphering
65
66 ## Arithmetic on letters
67
68 Convert .plaintext[letter] → .plaintext[number] →
69 .ciphertext[number] → .ciphertext[letter]
70
71 Functions you will need
72
73 ```python
74 ord()
75
76 chr()
77
78 %
79 ```
80
81 * What are good test cases?
82
83 ---
84
85 # The [string module](http://docs.python.org/3.3/library/string.html) is your friend
86
87 ```python
88 import string
89
90 string.ascii_letters
91 string.ascii_lowercase
92 string.ascii_uppercase
93 string.digits
94 string.punctuation
95 ```
96
97 ---
98 # DRY and YAGNI
99
100 Is your code DRY?
101
102 ---
103
104 # Doctest
105
106 * Why document?
107 * Why test?
108
109 ```python
110 def caesar_encipher_letter(letter, shift):
111 """Encipher a letter, given a shift amount
112
113 >>> caesar_encipher_letter('a', 1)
114 'b'
115 """
116 if letter in string.ascii_letters:
117 .
118 .
119 .
120 ```
121
122 ---
123
124 # The magic doctest incantation
125
126 ```python
127 if __name__ == "__main__":
128 import doctest
129 doctest.testmod()
130 ```
131
132 ---
133
134 # Doing all the letters
135
136 ## Test-first developement
137
138 1. Write the tests.
139 * They will fail. There is no code.
140 2. Write code until the tests pass.
141 3. Refactor.
142
143 ---
144
145 # Doing all the letters
146
147 ## Abysmal
148
149 ```python
150 ciphertext = ''
151 for i in range(len(plaintext)):
152 ciphertext += caesar_encipher_letter(plaintext[i], key)
153 ```
154
155 ---
156
157 # Doing all the letters
158
159 ## Bad
160
161 ```python
162 ciphertext = ''
163 for p in plaintext:
164 ciphertext += caesar_encipher_letter(p, key)
165 ```
166
167 ...but easily generalisable
168
169 ---
170
171 # Doing all the letters
172
173 ## Good (but unPythonic)
174
175 ```python
176 ciphertext = map(lambda p: caesar_encipher_letter(p, key), plaintext)
177 ```
178
179 ---
180
181 # Doing all the letters
182
183 ## Best
184
185 ```python
186 ciphertext = [caesar_encipher_letter(p, key) for p in plaintext]
187 ```
188 ---
189
190 # Not all iterables are equal
191
192 ```python
193 ''.join()
194 ```
195
196 </textarea>
197 <script src="http://gnab.github.io/remark/downloads/remark-0.6.0.min.js" type="text/javascript">
198 </script>
199 <script type="text/javascript">
200 var slideshow = remark.create({ ratio: "16:9" });
201 </script>
202 </body>
203 </html>