5 <meta name=
"viewport" content=
"width=device-width, initial-scale=1, minimum-scale=1" />
6 <meta name=
"generator" content=
"pdoc 0.9.2" />
7 <title>szyfrow.support.utilities API documentation
</title>
8 <meta name=
"description" content=
"A mish-mash of utility functions" />
9 <link rel=
"preload stylesheet" as=
"style" href=
"https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity=
"sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin
>
10 <link rel=
"preload stylesheet" as=
"style" href=
"https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity=
"sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin
>
11 <link rel=
"stylesheet preload" as=
"style" href=
"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin
>
12 <style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:
1.5em}#content{padding:
20px}#sidebar{padding:
30px;overflow:hidden}#sidebar
> *:last-child{margin-bottom:
2cm}.http-server-breadcrumbs{font-size:
130%;margin:
0 0 15px
0}#footer{font-size:
.75em;padding:
5px
30px;border-top:
1px solid #ddd;text-align:right}#footer p{margin:
0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:
30px}h1,h2,h3,h4,h5{font-weight:
300}h1{font-size:
2.5em;line-height:
1.1em}h2{font-size:
1.75em;margin:
1em
0 .50em
0}h3{font-size:
1.4em;margin:
25px
0 10px
0}h4{margin:
0;font-size:
105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:
.2em
0}a{color:#
058;text-decoration:none;transition:color
.3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^=
"header-"]{margin-top:
2em}.ident{color:#
900}pre code{background:#f8f8f8;font-size:
.8em;line-height:
1.4em}code{background:#f2f2f1;padding:
1px
4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:
0;border-top:
1px solid #ccc;border-bottom:
1px solid #ccc;margin:
1em
0;padding:
1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:
10%}#http-server-module-list p{margin-top:
0}.toc ul,#index{list-style-type:none;margin:
0;padding:
0}#index code{background:transparent}#index h3{border-bottom:
1px solid #ddd}#index ul{padding:
0}#index h4{margin-top:
.6em;font-weight:bold}@media (min-width:
200ex){#index .two-column{column-count:
2}}@media (min-width:
300ex){#index .two-column{column-count:
3}}dl{margin-bottom:
2em}dl dl:last-child{margin-bottom:
4em}dd{margin:
0 0 1em
3em}#header-classes + dl
> dd{margin-bottom:
3em}dd dd{margin-left:
2em}dd p{margin:
10px
0}.name{background:#eee;font-weight:bold;font-size:
.85em;padding:
5px
10px;display:inline-block;min-width:
40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name
> span:first-child{white-space:nowrap}.name.class
> span:nth-child(
2){margin-left:
.4em}.inherited{color:#
999;border-left:
5px solid #eee;padding-left:
1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:
400;font-size:
1.25em}.desc h3{font-size:
1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#
666;text-align:right;font-weight:
400;font-size:
.8em;text-transform:uppercase}.source summary
> *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:
1em}.source pre{max-height:
500px;overflow:auto;margin:
0}.source pre code{font-size:
12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\
2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:
1em}img{max-width:
100%}td{padding:
0 .5em}.admonition{padding:
.1em
.5em;margin-bottom:
1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}
</style>
13 <style media=
"screen and (min-width: 700px)">@media screen and (min-width:
700px){#sidebar{width:
30%;height:
100vh;overflow:auto;position:sticky;top:
0}#content{width:
70%;max-width:
100ch;padding:
3em
4em;border-left:
1px solid #ddd}pre code{font-size:
1em}.item .name{font-size:
1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:
1.5em}.toc
> ul
> li{margin-top:
.5em}}
</style>
14 <style media=
"print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#
000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:
" (" attr(href)
")";font-size:
90%}a[href][title]:after{content:none}abbr[title]:after{content:
" (" attr(title)
")"}.ir a:after,a[href^=
"javascript:"]:after,a[href^=
"#"]:after{content:
""}pre,blockquote{border:
1px solid #
999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:
100% !important}@page{margin:
0.5cm}p,h2,h3{orphans:
3;widows:
3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}
</style>
15 <script defer
src=
"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity=
"sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin
></script>
16 <script>window.addEventListener('DOMContentLoaded', () =
> hljs.initHighlighting())
</script>
20 <article id=
"content">
22 <h1 class=
"title">Module
<code>szyfrow.support.utilities
</code></h1>
24 <section id=
"section-intro">
25 <p>A mish-mash of utility functions
</p>
26 <details class=
"source">
28 <span>Expand source code
</span>
30 <pre><code class=
"python">"""A mish-mash of utility functions
"""
35 from itertools import zip_longest
38 """join a a list of letters into a string.
"""
40 wcat =
' '.join
41 """join a list of words into a string, separated by spaces
"""
43 lcat =
'\n
'.join
44 """join a list of lines, separated by newline
"""
47 """Return the position of a letter in the alphabet (
0-
25)
"""
48 if letter in string.ascii_lowercase:
49 return ord(letter) - ord(
'a
')
50 elif letter in string.ascii_uppercase:
51 return ord(letter) - ord(
'A
')
53 raise ValueError(
'pos requires input of {} to be an ascii letter
'.format(letter))
56 """Return the letter in the given position in the alphabet (mod
26)
"""
57 return chr(number %
26 + ord(
'a
'))
59 def pad(message_len, group_len, fillvalue):
60 """Return the padding needed to extend a message to a multiple of group_len
63 fillvalue can be a function or a literal value. If a function, it is called
64 once for each padded character. Use this with fillvalue=random_english_letter
65 to pad a message with random letters.
67 padding_length = group_len - message_len % group_len
68 if padding_length == group_len: padding_length =
0
70 if callable(fillvalue):
71 for i in range(padding_length):
72 padding += fillvalue()
74 padding += fillvalue * padding_length
77 def every_nth(text, n, fillvalue=
''):
78 """Returns n strings, each of which consists of every nth character,
79 starting with the
0th,
1st,
2nd, ... (n-
1)th character
81 >>> every_nth(string.ascii_lowercase,
5)
82 [
'afkpuz
',
'bglqv
',
'chmrw
',
'dinsx
',
'ejoty
']
83 >>> every_nth(string.ascii_lowercase,
1)
84 [
'abcdefghijklmnopqrstuvwxyz
']
85 >>> every_nth(string.ascii_lowercase,
26) # doctest: +NORMALIZE_WHITESPACE
86 [
'a
',
'b
',
'c
',
'd
',
'e
',
'f
',
'g
',
'h
',
'i
',
'j
',
'k
',
'l
',
'm
',
'n
',
87 'o
',
'p
',
'q
',
'r
',
's
',
't
',
'u
',
'v
',
'w
',
'x
',
'y
',
'z
']
88 >>> every_nth(string.ascii_lowercase,
5, fillvalue=
'!
')
89 [
'afkpuz
',
'bglqv!
',
'chmrw!
',
'dinsx!
',
'ejoty!
']
91 split_text = chunks(text, n, fillvalue)
92 return [cat(l) for l in zip_longest(*split_text, fillvalue=fillvalue)]
94 def combine_every_nth(split_text):
95 """Reforms a text split into every_nth strings
97 >>> combine_every_nth(every_nth(string.ascii_lowercase,
5))
98 'abcdefghijklmnopqrstuvwxyz
'
99 >>> combine_every_nth(every_nth(string.ascii_lowercase,
1))
100 'abcdefghijklmnopqrstuvwxyz
'
101 >>> combine_every_nth(every_nth(string.ascii_lowercase,
26))
102 'abcdefghijklmnopqrstuvwxyz
'
105 for l in zip_longest(*split_text, fillvalue=
'')])
107 def chunks(text, n, fillvalue=None):
108 """Split a text into chunks of n characters
110 >>> chunks(
'abcdefghi
',
3)
111 [
'abc
',
'def
',
'ghi
']
112 >>> chunks(
'abcdefghi
',
4)
113 [
'abcd
',
'efgh
',
'i
']
114 >>> chunks(
'abcdefghi
',
4, fillvalue=
'!
')
115 [
'abcd
',
'efgh
',
'i!!!
']
118 # padding = fillvalue[
0] * (n - len(text) % n)
119 padding = pad(len(text), n, fillvalue)
120 padded_text = text + padding
123 return [(padded_text)[i:i+n] for i in range(
0, len(text), n)]
125 def transpose(items, transposition):
126 """Moves items around according to the given transposition
128 >>> transpose([
'a
',
'b
',
'c
',
'd
'], (
0,
1,
2,
3))
129 [
'a
',
'b
',
'c
',
'd
']
130 >>> transpose([
'a
',
'b
',
'c
',
'd
'], (
3,
1,
2,
0))
131 [
'd
',
'b
',
'c
',
'a
']
132 >>> transpose([
10,
11,
12,
13,
14,
15], (
3,
2,
4,
1,
5,
0))
133 [
13,
12,
14,
11,
15,
10]
135 transposed = [
''] * len(transposition)
136 for p, t in enumerate(transposition):
137 transposed[p] = items[t]
140 def untranspose(items, transposition):
141 """Undoes a transpose
143 >>> untranspose([
'a
',
'b
',
'c
',
'd
'], [
0,
1,
2,
3])
144 [
'a
',
'b
',
'c
',
'd
']
145 >>> untranspose([
'd
',
'b
',
'c
',
'a
'], [
3,
1,
2,
0])
146 [
'a
',
'b
',
'c
',
'd
']
147 >>> untranspose([
13,
12,
14,
11,
15,
10], [
3,
2,
4,
1,
5,
0])
148 [
10,
11,
12,
13,
14,
15]
150 transposed = [
''] * len(transposition)
151 for p, t in enumerate(transposition):
152 transposed[t] = items[p]
155 def deduplicate(text):
156 """Return the input string, but with second (and subsequent) occurrences
157 of a character removed.
159 return list(collections.OrderedDict.fromkeys(text))
163 """Remove all non-alphabetic characters from a text
164 >>> letters(
'The Quick
')
166 >>> letters(
'The Quick BROWN fox jumped! over... the (
9lazy) DOG
')
167 'TheQuickBROWNfoxjumpedoverthelazyDOG
'
169 return
''.join([c for c in text if c in string.ascii_letters])
171 # Special characters for conversion, such as smart quotes.
172 unaccent_specials =
''.maketrans({
"’
":
"'",
'“
':
'"',
'”
':
'"'})
175 """Remove all accents from letters.
176 It does this by converting the unicode string to decomposed compatability
177 form, dropping all the combining accents, then re-encoding the bytes.
179 >>> unaccent(
'hello
')
181 >>> unaccent(
'HELLO
')
183 >>> unaccent(
'héllo
')
185 >>> unaccent(
'héllö
')
187 >>> unaccent(
'HÉLLÖ
')
190 translated_text = text.translate(unaccent_specials)
191 return unicodedata.normalize(
'NFKD
', translated_text).\
192 encode(
'ascii
',
'ignore
').\
193 decode(
'utf-
8')
196 """Remove all non-alphabetic characters and convert the text to lowercase
198 >>> sanitise(
'The Quick
')
200 >>> sanitise(
'The Quick BROWN fox jumped! over... the (
9lazy) DOG
')
201 'thequickbrownfoxjumpedoverthelazydog
'
202 >>> sanitise(
'HÉLLÖ
')
205 return letters(unaccent(text)).lower()
208 def index_of_coincidence(text):
209 """Index of coincidence of a string. This is low for random text,
210 higher for natural langauge.
212 stext = sanitise(text)
213 counts = collections.Counter(stext)
214 denom = len(stext) * (len(text) -
1) /
26
216 sum(max(counts[l] * counts[l] -
1,
0) for l in string.ascii_lowercase)
222 def frequencies(text):
223 """Count the number of occurrences of each character in text
225 >>> sorted(frequencies(
'abcdefabc
').items())
226 [(
'a
',
2), (
'b
',
2), (
'c
',
2), (
'd
',
1), (
'e
',
1), (
'f
',
1)]
227 >>> sorted(frequencies(
'the quick brown fox jumped over the lazy
' \
228 'dog
').items()) # doctest: +NORMALIZE_WHITESPACE
229 [(
' ',
8), (
'a
',
1), (
'b
',
1), (
'c
',
1), (
'd
',
2), (
'e
',
4), (
'f
',
1),
230 (
'g
',
1), (
'h
',
2), (
'i
',
1), (
'j
',
1), (
'k
',
1), (
'l
',
1), (
'm
',
1),
231 (
'n
',
1), (
'o
',
4), (
'p
',
1), (
'q
',
1), (
'r
',
2), (
't
',
2), (
'u
',
2),
232 (
'v
',
1), (
'w
',
1), (
'x
',
1), (
'y
',
1), (
'z
',
1)]
233 >>> sorted(frequencies(
'The Quick BROWN fox jumped! over... the
' \
234 '(
9lazy) DOG
').items()) # doctest: +NORMALIZE_WHITESPACE
235 [(
' ',
8), (
'!
',
1), (
'(
',
1), (
')
',
1), (
'.
',
3), (
'9',
1), (
'B
',
1),
236 (
'D
',
1), (
'G
',
1), (
'N
',
1), (
'O
',
2), (
'Q
',
1), (
'R
',
1), (
'T
',
1),
237 (
'W
',
1), (
'a
',
1), (
'c
',
1), (
'd
',
1), (
'e
',
4), (
'f
',
1), (
'h
',
2),
238 (
'i
',
1), (
'j
',
1), (
'k
',
1), (
'l
',
1), (
'm
',
1), (
'o
',
2), (
'p
',
1),
239 (
'r
',
1), (
't
',
1), (
'u
',
2), (
'v
',
1), (
'x
',
1), (
'y
',
1), (
'z
',
1)]
240 >>> sorted(frequencies(sanitise(
'The Quick BROWN fox jumped! over...
'\
241 'the (
9lazy) DOG
')).items()) # doctest: +NORMALIZE_WHITESPACE
242 [(
'a
',
1), (
'b
',
1), (
'c
',
1), (
'd
',
2), (
'e
',
4), (
'f
',
1), (
'g
',
1),
243 (
'h
',
2), (
'i
',
1), (
'j
',
1), (
'k
',
1), (
'l
',
1), (
'm
',
1), (
'n
',
1),
244 (
'o
',
4), (
'p
',
1), (
'q
',
1), (
'r
',
2), (
't
',
2), (
'u
',
2), (
'v
',
1),
245 (
'w
',
1), (
'x
',
1), (
'y
',
1), (
'z
',
1)]
246 >>> frequencies(
'abcdefabcdef
')[
'x
']
249 return collections.Counter(c for c in text)
251 if __name__ ==
"__main__
":
253 doctest.testmod()
</code></pre>
261 <h2 class=
"section-title" id=
"header-functions">Functions
</h2>
263 <dt id=
"szyfrow.support.utilities.cat"><code class=
"name flex">
264 <span>def
<span class=
"ident">cat
</span></span>(
<span>iterable, /)
</span>
267 <div class=
"desc"><p>Concatenate any number of strings.
</p>
268 <p>The string whose method is called is inserted in between each given string.
269 The result is returned as a new string.
</p>
270 <p>Example: '.'.join(['ab', 'pq', 'rs']) -
> 'ab.pq.rs'
</p></div>
272 <dt id=
"szyfrow.support.utilities.chunks"><code class=
"name flex">
273 <span>def
<span class=
"ident">chunks
</span></span>(
<span>text, n, fillvalue=None)
</span>
276 <div class=
"desc"><p>Split a text into chunks of n characters
</p>
277 <pre><code class=
"language-python-repl">>>> chunks('abcdefghi',
3)
278 ['abc', 'def', 'ghi']
279 >>> chunks('abcdefghi',
4)
280 ['abcd', 'efgh', 'i']
281 >>> chunks('abcdefghi',
4, fillvalue='!')
282 ['abcd', 'efgh', 'i!!!']
284 <details class=
"source">
286 <span>Expand source code
</span>
288 <pre><code class=
"python">def chunks(text, n, fillvalue=None):
289 """Split a text into chunks of n characters
291 >>> chunks(
'abcdefghi
',
3)
292 [
'abc
',
'def
',
'ghi
']
293 >>> chunks(
'abcdefghi
',
4)
294 [
'abcd
',
'efgh
',
'i
']
295 >>> chunks(
'abcdefghi
',
4, fillvalue=
'!
')
296 [
'abcd
',
'efgh
',
'i!!!
']
299 # padding = fillvalue[
0] * (n - len(text) % n)
300 padding = pad(len(text), n, fillvalue)
301 padded_text = text + padding
304 return [(padded_text)[i:i+n] for i in range(
0, len(text), n)]
</code></pre>
307 <dt id=
"szyfrow.support.utilities.combine_every_nth"><code class=
"name flex">
308 <span>def
<span class=
"ident">combine_every_nth
</span></span>(
<span>split_text)
</span>
311 <div class=
"desc"><p>Reforms a text split into every_nth strings
</p>
312 <pre><code class=
"language-python-repl">>>> combine_every_nth(every_nth(string.ascii_lowercase,
5))
313 'abcdefghijklmnopqrstuvwxyz'
314 >>> combine_every_nth(every_nth(string.ascii_lowercase,
1))
315 'abcdefghijklmnopqrstuvwxyz'
316 >>> combine_every_nth(every_nth(string.ascii_lowercase,
26))
317 'abcdefghijklmnopqrstuvwxyz'
319 <details class=
"source">
321 <span>Expand source code
</span>
323 <pre><code class=
"python">def combine_every_nth(split_text):
324 """Reforms a text split into every_nth strings
326 >>> combine_every_nth(every_nth(string.ascii_lowercase,
5))
327 'abcdefghijklmnopqrstuvwxyz
'
328 >>> combine_every_nth(every_nth(string.ascii_lowercase,
1))
329 'abcdefghijklmnopqrstuvwxyz
'
330 >>> combine_every_nth(every_nth(string.ascii_lowercase,
26))
331 'abcdefghijklmnopqrstuvwxyz
'
334 for l in zip_longest(*split_text, fillvalue=
'')])
</code></pre>
337 <dt id=
"szyfrow.support.utilities.deduplicate"><code class=
"name flex">
338 <span>def
<span class=
"ident">deduplicate
</span></span>(
<span>text)
</span>
341 <div class=
"desc"><p>Return the input string, but with second (and subsequent) occurrences
342 of a character removed.
</p></div>
343 <details class=
"source">
345 <span>Expand source code
</span>
347 <pre><code class=
"python">def deduplicate(text):
348 """Return the input string, but with second (and subsequent) occurrences
349 of a character removed.
351 return list(collections.OrderedDict.fromkeys(text))
</code></pre>
354 <dt id=
"szyfrow.support.utilities.every_nth"><code class=
"name flex">
355 <span>def
<span class=
"ident">every_nth
</span></span>(
<span>text, n, fillvalue='')
</span>
358 <div class=
"desc"><p>Returns n strings, each of which consists of every nth character,
359 starting with the
0th,
1st,
2nd,
… (n-
1)th character
</p>
360 <pre><code class=
"language-python-repl">>>> every_nth(string.ascii_lowercase,
5)
361 ['afkpuz', 'bglqv', 'chmrw', 'dinsx', 'ejoty']
362 >>> every_nth(string.ascii_lowercase,
1)
363 ['abcdefghijklmnopqrstuvwxyz']
364 >>> every_nth(string.ascii_lowercase,
26) # doctest: +NORMALIZE_WHITESPACE
365 ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
366 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
367 >>> every_nth(string.ascii_lowercase,
5, fillvalue='!')
368 ['afkpuz', 'bglqv!', 'chmrw!', 'dinsx!', 'ejoty!']
370 <details class=
"source">
372 <span>Expand source code
</span>
374 <pre><code class=
"python">def every_nth(text, n, fillvalue=
''):
375 """Returns n strings, each of which consists of every nth character,
376 starting with the
0th,
1st,
2nd, ... (n-
1)th character
378 >>> every_nth(string.ascii_lowercase,
5)
379 [
'afkpuz
',
'bglqv
',
'chmrw
',
'dinsx
',
'ejoty
']
380 >>> every_nth(string.ascii_lowercase,
1)
381 [
'abcdefghijklmnopqrstuvwxyz
']
382 >>> every_nth(string.ascii_lowercase,
26) # doctest: +NORMALIZE_WHITESPACE
383 [
'a
',
'b
',
'c
',
'd
',
'e
',
'f
',
'g
',
'h
',
'i
',
'j
',
'k
',
'l
',
'm
',
'n
',
384 'o
',
'p
',
'q
',
'r
',
's
',
't
',
'u
',
'v
',
'w
',
'x
',
'y
',
'z
']
385 >>> every_nth(string.ascii_lowercase,
5, fillvalue=
'!
')
386 [
'afkpuz
',
'bglqv!
',
'chmrw!
',
'dinsx!
',
'ejoty!
']
388 split_text = chunks(text, n, fillvalue)
389 return [cat(l) for l in zip_longest(*split_text, fillvalue=fillvalue)]
</code></pre>
392 <dt id=
"szyfrow.support.utilities.frequencies"><code class=
"name flex">
393 <span>def
<span class=
"ident">frequencies
</span></span>(
<span>text)
</span>
396 <div class=
"desc"><p>Count the number of occurrences of each character in text
</p>
397 <pre><code class=
"language-python-repl">>>> sorted(frequencies('abcdefabc').items())
398 [('a',
2), ('b',
2), ('c',
2), ('d',
1), ('e',
1), ('f',
1)]
399 >>> sorted(frequencies('the quick brown fox jumped over the lazy ' 'dog').items()) # doctest: +NORMALIZE_WHITESPACE
400 [(' ',
8), ('a',
1), ('b',
1), ('c',
1), ('d',
2), ('e',
4), ('f',
1),
401 ('g',
1), ('h',
2), ('i',
1), ('j',
1), ('k',
1), ('l',
1), ('m',
1),
402 ('n',
1), ('o',
4), ('p',
1), ('q',
1), ('r',
2), ('t',
2), ('u',
2),
403 ('v',
1), ('w',
1), ('x',
1), ('y',
1), ('z',
1)]
404 >>> sorted(frequencies('The Quick BROWN fox jumped! over... the ' '(
9lazy) DOG').items()) # doctest: +NORMALIZE_WHITESPACE
405 [(' ',
8), ('!',
1), ('(',
1), (')',
1), ('.',
3), ('
9',
1), ('B',
1),
406 ('D',
1), ('G',
1), ('N',
1), ('O',
2), ('Q',
1), ('R',
1), ('T',
1),
407 ('W',
1), ('a',
1), ('c',
1), ('d',
1), ('e',
4), ('f',
1), ('h',
2),
408 ('i',
1), ('j',
1), ('k',
1), ('l',
1), ('m',
1), ('o',
2), ('p',
1),
409 ('r',
1), ('t',
1), ('u',
2), ('v',
1), ('x',
1), ('y',
1), ('z',
1)]
410 >>> sorted(frequencies(sanitise('The Quick BROWN fox jumped! over... ' 'the (
9lazy) DOG')).items()) # doctest: +NORMALIZE_WHITESPACE
411 [('a',
1), ('b',
1), ('c',
1), ('d',
2), ('e',
4), ('f',
1), ('g',
1),
412 ('h',
2), ('i',
1), ('j',
1), ('k',
1), ('l',
1), ('m',
1), ('n',
1),
413 ('o',
4), ('p',
1), ('q',
1), ('r',
2), ('t',
2), ('u',
2), ('v',
1),
414 ('w',
1), ('x',
1), ('y',
1), ('z',
1)]
415 >>> frequencies('abcdefabcdef')['x']
418 <details class=
"source">
420 <span>Expand source code
</span>
422 <pre><code class=
"python">def frequencies(text):
423 """Count the number of occurrences of each character in text
425 >>> sorted(frequencies(
'abcdefabc
').items())
426 [(
'a
',
2), (
'b
',
2), (
'c
',
2), (
'd
',
1), (
'e
',
1), (
'f
',
1)]
427 >>> sorted(frequencies(
'the quick brown fox jumped over the lazy
' \
428 'dog
').items()) # doctest: +NORMALIZE_WHITESPACE
429 [(
' ',
8), (
'a
',
1), (
'b
',
1), (
'c
',
1), (
'd
',
2), (
'e
',
4), (
'f
',
1),
430 (
'g
',
1), (
'h
',
2), (
'i
',
1), (
'j
',
1), (
'k
',
1), (
'l
',
1), (
'm
',
1),
431 (
'n
',
1), (
'o
',
4), (
'p
',
1), (
'q
',
1), (
'r
',
2), (
't
',
2), (
'u
',
2),
432 (
'v
',
1), (
'w
',
1), (
'x
',
1), (
'y
',
1), (
'z
',
1)]
433 >>> sorted(frequencies(
'The Quick BROWN fox jumped! over... the
' \
434 '(
9lazy) DOG
').items()) # doctest: +NORMALIZE_WHITESPACE
435 [(
' ',
8), (
'!
',
1), (
'(
',
1), (
')
',
1), (
'.
',
3), (
'9',
1), (
'B
',
1),
436 (
'D
',
1), (
'G
',
1), (
'N
',
1), (
'O
',
2), (
'Q
',
1), (
'R
',
1), (
'T
',
1),
437 (
'W
',
1), (
'a
',
1), (
'c
',
1), (
'd
',
1), (
'e
',
4), (
'f
',
1), (
'h
',
2),
438 (
'i
',
1), (
'j
',
1), (
'k
',
1), (
'l
',
1), (
'm
',
1), (
'o
',
2), (
'p
',
1),
439 (
'r
',
1), (
't
',
1), (
'u
',
2), (
'v
',
1), (
'x
',
1), (
'y
',
1), (
'z
',
1)]
440 >>> sorted(frequencies(sanitise(
'The Quick BROWN fox jumped! over...
'\
441 'the (
9lazy) DOG
')).items()) # doctest: +NORMALIZE_WHITESPACE
442 [(
'a
',
1), (
'b
',
1), (
'c
',
1), (
'd
',
2), (
'e
',
4), (
'f
',
1), (
'g
',
1),
443 (
'h
',
2), (
'i
',
1), (
'j
',
1), (
'k
',
1), (
'l
',
1), (
'm
',
1), (
'n
',
1),
444 (
'o
',
4), (
'p
',
1), (
'q
',
1), (
'r
',
2), (
't
',
2), (
'u
',
2), (
'v
',
1),
445 (
'w
',
1), (
'x
',
1), (
'y
',
1), (
'z
',
1)]
446 >>> frequencies(
'abcdefabcdef
')[
'x
']
449 return collections.Counter(c for c in text)
</code></pre>
452 <dt id=
"szyfrow.support.utilities.index_of_coincidence"><code class=
"name flex">
453 <span>def
<span class=
"ident">index_of_coincidence
</span></span>(
<span>text)
</span>
456 <div class=
"desc"><p>Index of coincidence of a string. This is low for random text,
457 higher for natural langauge.
</p></div>
458 <details class=
"source">
460 <span>Expand source code
</span>
462 <pre><code class=
"python">def index_of_coincidence(text):
463 """Index of coincidence of a string. This is low for random text,
464 higher for natural langauge.
466 stext = sanitise(text)
467 counts = collections.Counter(stext)
468 denom = len(stext) * (len(text) -
1) /
26
470 sum(max(counts[l] * counts[l] -
1,
0) for l in string.ascii_lowercase)
476 <dt id=
"szyfrow.support.utilities.lcat"><code class=
"name flex">
477 <span>def
<span class=
"ident">lcat
</span></span>(
<span>iterable, /)
</span>
480 <div class=
"desc"><p>Concatenate any number of strings.
</p>
481 <p>The string whose method is called is inserted in between each given string.
482 The result is returned as a new string.
</p>
483 <p>Example: '.'.join(['ab', 'pq', 'rs']) -
> 'ab.pq.rs'
</p></div>
485 <dt id=
"szyfrow.support.utilities.letters"><code class=
"name flex">
486 <span>def
<span class=
"ident">letters
</span></span>(
<span>text)
</span>
489 <div class=
"desc"><p>Remove all non-alphabetic characters from a text
</p>
490 <pre><code class=
"language-python-repl">>>> letters('The Quick')
492 >>> letters('The Quick BROWN fox jumped! over... the (
9lazy) DOG')
493 'TheQuickBROWNfoxjumpedoverthelazyDOG'
495 <details class=
"source">
497 <span>Expand source code
</span>
499 <pre><code class=
"python">def letters(text):
500 """Remove all non-alphabetic characters from a text
501 >>> letters(
'The Quick
')
503 >>> letters(
'The Quick BROWN fox jumped! over... the (
9lazy) DOG
')
504 'TheQuickBROWNfoxjumpedoverthelazyDOG
'
506 return
''.join([c for c in text if c in string.ascii_letters])
</code></pre>
509 <dt id=
"szyfrow.support.utilities.pad"><code class=
"name flex">
510 <span>def
<span class=
"ident">pad
</span></span>(
<span>message_len, group_len, fillvalue)
</span>
513 <div class=
"desc"><p>Return the padding needed to extend a message to a multiple of group_len
515 <p>fillvalue can be a function or a literal value. If a function, it is called
516 once for each padded character. Use this with fillvalue=random_english_letter
517 to pad a message with random letters.
</p></div>
518 <details class=
"source">
520 <span>Expand source code
</span>
522 <pre><code class=
"python">def pad(message_len, group_len, fillvalue):
523 """Return the padding needed to extend a message to a multiple of group_len
526 fillvalue can be a function or a literal value. If a function, it is called
527 once for each padded character. Use this with fillvalue=random_english_letter
528 to pad a message with random letters.
530 padding_length = group_len - message_len % group_len
531 if padding_length == group_len: padding_length =
0
533 if callable(fillvalue):
534 for i in range(padding_length):
535 padding += fillvalue()
537 padding += fillvalue * padding_length
538 return padding
</code></pre>
541 <dt id=
"szyfrow.support.utilities.pos"><code class=
"name flex">
542 <span>def
<span class=
"ident">pos
</span></span>(
<span>letter)
</span>
545 <div class=
"desc"><p>Return the position of a letter in the alphabet (
0-
25)
</p></div>
546 <details class=
"source">
548 <span>Expand source code
</span>
550 <pre><code class=
"python">def pos(letter):
551 """Return the position of a letter in the alphabet (
0-
25)
"""
552 if letter in string.ascii_lowercase:
553 return ord(letter) - ord(
'a
')
554 elif letter in string.ascii_uppercase:
555 return ord(letter) - ord(
'A
')
557 raise ValueError(
'pos requires input of {} to be an ascii letter
'.format(letter))
</code></pre>
560 <dt id=
"szyfrow.support.utilities.sanitise"><code class=
"name flex">
561 <span>def
<span class=
"ident">sanitise
</span></span>(
<span>text)
</span>
564 <div class=
"desc"><p>Remove all non-alphabetic characters and convert the text to lowercase
</p>
565 <pre><code class=
"language-python-repl">>>> sanitise('The Quick')
567 >>> sanitise('The Quick BROWN fox jumped! over... the (
9lazy) DOG')
568 'thequickbrownfoxjumpedoverthelazydog'
569 >>> sanitise('HÉLLÖ')
572 <details class=
"source">
574 <span>Expand source code
</span>
576 <pre><code class=
"python">def sanitise(text):
577 """Remove all non-alphabetic characters and convert the text to lowercase
579 >>> sanitise(
'The Quick
')
581 >>> sanitise(
'The Quick BROWN fox jumped! over... the (
9lazy) DOG
')
582 'thequickbrownfoxjumpedoverthelazydog
'
583 >>> sanitise(
'HÉLLÖ
')
586 return letters(unaccent(text)).lower()
</code></pre>
589 <dt id=
"szyfrow.support.utilities.transpose"><code class=
"name flex">
590 <span>def
<span class=
"ident">transpose
</span></span>(
<span>items, transposition)
</span>
593 <div class=
"desc"><p>Moves items around according to the given transposition
</p>
594 <pre><code class=
"language-python-repl">>>> transpose(['a', 'b', 'c', 'd'], (
0,
1,
2,
3))
596 >>> transpose(['a', 'b', 'c', 'd'], (
3,
1,
2,
0))
598 >>> transpose([
10,
11,
12,
13,
14,
15], (
3,
2,
4,
1,
5,
0))
599 [
13,
12,
14,
11,
15,
10]
601 <details class=
"source">
603 <span>Expand source code
</span>
605 <pre><code class=
"python">def transpose(items, transposition):
606 """Moves items around according to the given transposition
608 >>> transpose([
'a
',
'b
',
'c
',
'd
'], (
0,
1,
2,
3))
609 [
'a
',
'b
',
'c
',
'd
']
610 >>> transpose([
'a
',
'b
',
'c
',
'd
'], (
3,
1,
2,
0))
611 [
'd
',
'b
',
'c
',
'a
']
612 >>> transpose([
10,
11,
12,
13,
14,
15], (
3,
2,
4,
1,
5,
0))
613 [
13,
12,
14,
11,
15,
10]
615 transposed = [
''] * len(transposition)
616 for p, t in enumerate(transposition):
617 transposed[p] = items[t]
618 return transposed
</code></pre>
621 <dt id=
"szyfrow.support.utilities.unaccent"><code class=
"name flex">
622 <span>def
<span class=
"ident">unaccent
</span></span>(
<span>text)
</span>
625 <div class=
"desc"><p>Remove all accents from letters.
626 It does this by converting the unicode string to decomposed compatability
627 form, dropping all the combining accents, then re-encoding the bytes.
</p>
628 <pre><code class=
"language-python-repl">>>> unaccent('hello')
630 >>> unaccent('HELLO')
632 >>> unaccent('héllo')
634 >>> unaccent('héllö')
636 >>> unaccent('HÉLLÖ')
639 <details class=
"source">
641 <span>Expand source code
</span>
643 <pre><code class=
"python">def unaccent(text):
644 """Remove all accents from letters.
645 It does this by converting the unicode string to decomposed compatability
646 form, dropping all the combining accents, then re-encoding the bytes.
648 >>> unaccent(
'hello
')
650 >>> unaccent(
'HELLO
')
652 >>> unaccent(
'héllo
')
654 >>> unaccent(
'héllö
')
656 >>> unaccent(
'HÉLLÖ
')
659 translated_text = text.translate(unaccent_specials)
660 return unicodedata.normalize(
'NFKD
', translated_text).\
661 encode(
'ascii
',
'ignore
').\
662 decode(
'utf-
8')
</code></pre>
665 <dt id=
"szyfrow.support.utilities.unpos"><code class=
"name flex">
666 <span>def
<span class=
"ident">unpos
</span></span>(
<span>number)
</span>
669 <div class=
"desc"><p>Return the letter in the given position in the alphabet (mod
26)
</p></div>
670 <details class=
"source">
672 <span>Expand source code
</span>
674 <pre><code class=
"python">def unpos(number):
675 """Return the letter in the given position in the alphabet (mod
26)
"""
676 return chr(number %
26 + ord(
'a
'))
</code></pre>
679 <dt id=
"szyfrow.support.utilities.untranspose"><code class=
"name flex">
680 <span>def
<span class=
"ident">untranspose
</span></span>(
<span>items, transposition)
</span>
683 <div class=
"desc"><p>Undoes a transpose
</p>
684 <pre><code class=
"language-python-repl">>>> untranspose(['a', 'b', 'c', 'd'], [
0,
1,
2,
3])
686 >>> untranspose(['d', 'b', 'c', 'a'], [
3,
1,
2,
0])
688 >>> untranspose([
13,
12,
14,
11,
15,
10], [
3,
2,
4,
1,
5,
0])
689 [
10,
11,
12,
13,
14,
15]
691 <details class=
"source">
693 <span>Expand source code
</span>
695 <pre><code class=
"python">def untranspose(items, transposition):
696 """Undoes a transpose
698 >>> untranspose([
'a
',
'b
',
'c
',
'd
'], [
0,
1,
2,
3])
699 [
'a
',
'b
',
'c
',
'd
']
700 >>> untranspose([
'd
',
'b
',
'c
',
'a
'], [
3,
1,
2,
0])
701 [
'a
',
'b
',
'c
',
'd
']
702 >>> untranspose([
13,
12,
14,
11,
15,
10], [
3,
2,
4,
1,
5,
0])
703 [
10,
11,
12,
13,
14,
15]
705 transposed = [
''] * len(transposition)
706 for p, t in enumerate(transposition):
707 transposed[t] = items[p]
708 return transposed
</code></pre>
711 <dt id=
"szyfrow.support.utilities.wcat"><code class=
"name flex">
712 <span>def
<span class=
"ident">wcat
</span></span>(
<span>iterable, /)
</span>
715 <div class=
"desc"><p>Concatenate any number of strings.
</p>
716 <p>The string whose method is called is inserted in between each given string.
717 The result is returned as a new string.
</p>
718 <p>Example: '.'.join(['ab', 'pq', 'rs']) -
> 'ab.pq.rs'
</p></div>
731 <li><h3>Super-module
</h3>
733 <li><code><a title=
"szyfrow.support" href=
"index.html">szyfrow.support
</a></code></li>
736 <li><h3><a href=
"#header-functions">Functions
</a></h3>
738 <li><code><a title=
"szyfrow.support.utilities.cat" href=
"#szyfrow.support.utilities.cat">cat
</a></code></li>
739 <li><code><a title=
"szyfrow.support.utilities.chunks" href=
"#szyfrow.support.utilities.chunks">chunks
</a></code></li>
740 <li><code><a title=
"szyfrow.support.utilities.combine_every_nth" href=
"#szyfrow.support.utilities.combine_every_nth">combine_every_nth
</a></code></li>
741 <li><code><a title=
"szyfrow.support.utilities.deduplicate" href=
"#szyfrow.support.utilities.deduplicate">deduplicate
</a></code></li>
742 <li><code><a title=
"szyfrow.support.utilities.every_nth" href=
"#szyfrow.support.utilities.every_nth">every_nth
</a></code></li>
743 <li><code><a title=
"szyfrow.support.utilities.frequencies" href=
"#szyfrow.support.utilities.frequencies">frequencies
</a></code></li>
744 <li><code><a title=
"szyfrow.support.utilities.index_of_coincidence" href=
"#szyfrow.support.utilities.index_of_coincidence">index_of_coincidence
</a></code></li>
745 <li><code><a title=
"szyfrow.support.utilities.lcat" href=
"#szyfrow.support.utilities.lcat">lcat
</a></code></li>
746 <li><code><a title=
"szyfrow.support.utilities.letters" href=
"#szyfrow.support.utilities.letters">letters
</a></code></li>
747 <li><code><a title=
"szyfrow.support.utilities.pad" href=
"#szyfrow.support.utilities.pad">pad
</a></code></li>
748 <li><code><a title=
"szyfrow.support.utilities.pos" href=
"#szyfrow.support.utilities.pos">pos
</a></code></li>
749 <li><code><a title=
"szyfrow.support.utilities.sanitise" href=
"#szyfrow.support.utilities.sanitise">sanitise
</a></code></li>
750 <li><code><a title=
"szyfrow.support.utilities.transpose" href=
"#szyfrow.support.utilities.transpose">transpose
</a></code></li>
751 <li><code><a title=
"szyfrow.support.utilities.unaccent" href=
"#szyfrow.support.utilities.unaccent">unaccent
</a></code></li>
752 <li><code><a title=
"szyfrow.support.utilities.unpos" href=
"#szyfrow.support.utilities.unpos">unpos
</a></code></li>
753 <li><code><a title=
"szyfrow.support.utilities.untranspose" href=
"#szyfrow.support.utilities.untranspose">untranspose
</a></code></li>
754 <li><code><a title=
"szyfrow.support.utilities.wcat" href=
"#szyfrow.support.utilities.wcat">wcat
</a></code></li>
761 <p>Generated by
<a href=
"https://pdoc3.github.io/pdoc"><cite>pdoc
</cite> 0.9.2</a>.
</p>