4 <title>Caesar cipher
</title>
5 <meta http-equiv=
"Content-Type" content=
"text/html; charset=UTF-8"/>
6 <style type=
"text/css">
15 h1 { font-size:
3em; }
16 h2 { font-size:
2em; }
17 h3 { font-size:
1.6em; }
19 text-decoration: none;
22 -moz-border-radius:
5px;
23 -web-border-radius:
5px;
31 text-shadow:
0 0 20px #
333;
37 text-shadow:
0 0 20px #
333;
48 <textarea id=
"source">
52 ![centre-aligned Caesar wheel](caesarwheel1.gif)
54 Letter-by-letter enciphering
60 .indexlink[[Index](index.html)]
64 # Enciphering and deciphering
66 ## Arithmetic on letters
68 Convert .plaintext[letter] → .plaintext[number] →
69 .ciphertext[number] → .ciphertext[letter]
71 Functions you will need
81 * What are good test cases?
87 Before doing anything, create a new branch in Git
89 * This will keep your changes isolated
91 Experiment in IPython (ephemeral, for us)
93 Once you've got something working, export the code into a `.py` file (permanent and reusable)
96 from imp import reload
103 Re-evaluate the second cell to reload the file into the IPython notebook
105 When you've made progress, make a Git commit
107 * Commit early and often!
109 When you've finished, change back to `master` branch and `merge` the development branch
113 # The [string module](http://docs.python.org/
3.3/library/string.html) is your friend
119 string.ascii_lowercase
120 string.ascii_uppercase
139 def caesar_encipher_letter(letter, shift):
140 """Encipher a letter, given a shift amount
142 >>> caesar_encipher_letter('a', 1)
145 if letter in string.ascii_letters:
153 # The magic doctest incantation
156 if __name__ ==
"__main__":
163 # Doing the whole message
165 ## Test-first developement
168 * They will fail. There is no code.
169 2. Write code until the tests pass.
174 # Doing the whole message
180 for i in range(len(plaintext)):
181 ciphertext += caesar_encipher_letter(plaintext[i], key)
188 # Doing the whole message
195 ciphertext += caesar_encipher_letter(p, key)
198 ...but easily generalisable
202 # Doing the whole message
204 ## Good (but unPythonic)
207 ciphertext = map(lambda p: caesar_encipher_letter(p, key), plaintext)
212 # Doing the whole message
217 ciphertext = [caesar_encipher_letter(p, key) for p in plaintext]
221 # Not all iterables are equal
227 You'll be doing this a lot, so define a couple of utility functions:
234 `cat` after the Unix command (_concatenate_ files), `wcat` for _word concatenate_.
237 <script src=
"http://gnab.github.io/remark/downloads/remark-0.6.0.min.js" type=
"text/javascript">
239 <script type=
"text/javascript">
240 var slideshow = remark.create({ ratio:
"16:9" });