4afd78dad4f3367c5107a99d0f40ff8f1e0aa037
[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 # Using the tools
86
87 Before doing anything, create a new branch in Git
88
89 * This will keep your changes isolated
90
91 Experiment in IPython (ephemeral, for us)
92
93 Once you've got something working, copy the code into a `.py` file (permanent and reusable)
94
95 ```python
96 from imp import reload
97
98 import test
99 reload(test)
100 from test import *
101 ```
102
103 Re-evaluate the second cell to reload the file into the IPython notebook
104
105 When you've made progress, make a Git commit
106
107 * Commit early and often!
108
109 When you've finished, change back to `master` branch and `merge` the development branch
110
111 ---
112
113 # The [string module](http://docs.python.org/3.3/library/string.html) is your friend
114
115 ```python
116 import string
117
118 string.ascii_letters
119 string.ascii_lowercase
120 string.ascii_uppercase
121 string.digits
122 string.punctuation
123 ```
124
125 ---
126
127 # DRY and YAGNI
128
129 Is your code DRY?
130
131 ---
132
133 # Doctest
134
135 * Why document?
136 * Why test?
137
138 ```python
139 def caesar_encipher_letter(letter, shift):
140 """Encipher a letter, given a shift amount
141
142 >>> caesar_encipher_letter('a', 1)
143 'b'
144 """
145 if letter in string.ascii_letters:
146 .
147 .
148 .
149 ```
150
151 ---
152
153 # The magic doctest incantation
154
155 ```python
156 if __name__ == "__main__":
157 import doctest
158 doctest.testmod()
159 ```
160
161 ---
162
163 # Doing the whole message
164
165 ## Test-first developement
166
167 1. Write the tests.
168 * They will fail. There is no code.
169 2. Write code until the tests pass.
170 3. Refactor.
171
172 ---
173
174 # Doing the whole message
175
176 ## Abysmal
177
178 ```python
179 ciphertext = ''
180 for i in range(len(plaintext)):
181 ciphertext += caesar_encipher_letter(plaintext[i], key)
182 ```
183
184 Try it in IPython
185
186 ---
187
188 # Doing the whole message
189
190 ## Bad
191
192 ```python
193 ciphertext = ''
194 for p in plaintext:
195 ciphertext += caesar_encipher_letter(p, key)
196 ```
197
198 ...but easily generalisable
199
200 ---
201
202 # Doing the whole message
203
204 ## Good (but unPythonic)
205
206 ```python
207 ciphertext = map(lambda p: caesar_encipher_letter(p, key), plaintext)
208 ```
209
210 ---
211
212 # Doing the whole message
213
214 ## Best
215
216 ```python
217 ciphertext = [caesar_encipher_letter(p, key) for p in plaintext]
218 ```
219 ---
220
221 # Not all iterables are equal
222
223 ```python
224 ''.join()
225 ```
226
227 </textarea>
228 <script src="http://gnab.github.io/remark/downloads/remark-0.6.0.min.js" type="text/javascript">
229 </script>
230 <script type="text/javascript">
231 var slideshow = remark.create({ ratio: "16:9" });
232 </script>
233 </body>
234 </html>