Done challenge 7
[cipher-tools.git] / 2018 / 2018-challenge7.ipynb
diff --git a/2018/2018-challenge7.ipynb b/2018/2018-challenge7.ipynb
new file mode 100644 (file)
index 0000000..8240773
--- /dev/null
@@ -0,0 +1,558 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import os,sys,inspect\n",
+    "currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))\n",
+    "parentdir = os.path.dirname(currentdir)\n",
+    "sys.path.insert(0,parentdir) "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from cipher.caesar import *\n",
+    "from cipher.affine import *\n",
+    "from cipher.keyword_cipher import *\n",
+    "from cipher.vigenere import *\n",
+    "from cipher.playfair import *\n",
+    "from cipher.column_transposition import *\n",
+    "from support.text_prettify import *\n",
+    "from support.plot_frequency_histogram import *"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ca = open('7a.ciphertext').read()\n",
+    "cb = open('7b.ciphertext').read()\n",
+    "sca = sanitise(ca)\n",
+    "scb = sanitise(cb)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "8197"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "history_words = [w.strip() for w in open('history-words.txt')]\n",
+    "len(history_words)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('damager', <KeywordWrapAlphabet.from_last: 2>, -2752.7089249862242)"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_a, wrap_a), score_a = keyword_break_mp(sca)\n",
+    "key_a, wrap_a, score_a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "ex awt ly chat or cho had hit meic as nt sure but by the time iwa me around they had long gone if\n",
+      "you cille xw use the p unit casa professional hit just the right amount of for we to know k me out\n",
+      "probably no permanent damage the room had been expertly disassembled the shelves cere emptied of bla\n",
+      "wks mission files and mu who f the steam punkte wh nology had been taken apart presumably to make\n",
+      "sure it didnt wont a in any further sew rets the big beautiful roundtable had been wl eared and ile\n",
+      "anton it to steady myself as my heads cami guessed that cho ever had follo ced me into the tunnels\n",
+      "and on into the headquarters must have knoc n chat icas looking for it cas too mu who faw o in widen\n",
+      "we that they had found me here probably they cere won new ted c it h the emails that first got me\n",
+      "interested in b law k but in a won fused state after my b law k out icas puzzled chy had they\n",
+      "involved me perhaps they just didnt kno choc to find the shado car w hive and hoped i could be able\n",
+      "to help perhaps they canted to impl iwate me in the theft of the shado car w hive papers in that was\n",
+      "e they should have hit me hard eric as nt going to hang around long enough to get waugh t something\n",
+      "ca snagging at men one of the papers i had seen looked interesting enough to justify all this effort\n",
+      "i turned my head wa uti ously trying to ignore the throbbing behind m year and looked around the\n",
+      "room one more time to see chat cecere missing as i did so my foot waugh to n something and i bent\n",
+      "doc n top iwk it up chen they hit me i had been sitting reading bla wks wod ebook it cas full of\n",
+      "marvellous if dated ideas on wry p tography and information sew urity and i had just been reading\n",
+      "these w tion on transposition wip her sit seemed he caspar tiw ularly keen on w olum nar\n",
+      "transpositions and cas arguing that it could be best to read off the wip her text wol umn by wol umn\n",
+      "to won fuse enemy wry pt analysts icas musing on just hoc sew ure that could be chen the c orld cent\n",
+      "dark lu wk ilyas i had fallen i had dropped the book and it had slipped under the table some hoc\n",
+      "they had missed it during these a rw hand there it cas hidden in the shado csi took a deep breath to\n",
+      "sloc the spinning behind my eyes and pi wk ed the book up but as i pulled myself upright again the\n",
+      "tabletop shifted slightly to one side i struggled to regain my balan we and the table moved again\n",
+      "and this time i heard a distin wtw liw kasi shifted my c eight the table rotated b awk and there it\n",
+      "cason we more a soft metalli ww link as a rat whet tooth engaged i stood up grabbed at the table and\n",
+      "pulled si decays it turned again wli w king several times as it did so it casa noise ik nec very\n",
+      "cell the tumblers on a safe made the same sound though muw hmu wh quieter\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(sanitise(keyword_decipher(sca, key_a, wrap_a))))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "('gardens', <KeywordWrapAlphabet.from_last: 2>, -2770.1674703296317)"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(key_a, wrap_a), score_a = keyword_break_mp(sca, wordlist=history_words)\n",
+    "key_a, wrap_a, score_a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "exdftlywhdtorwhohdah it me i wds nt sure but by the time if d med roun a they hd along gone ic you\n",
+      "will ex fuse the p unit wds d procession dl hit just the right d mount oc corfe to kn of k me out\n",
+      "prob dbly no per md nent admd get he room hda been expertly a is ds semble a the shelves were emptie\n",
+      "ao cbldf ks mission ci les dna muf hoc the st edm punkte fh nology hda been tdk end pdr t pre sum\n",
+      "dbly to md ke sure it a i ant font d in d nyc urther se frets the big bed uti cul roun at dble hda\n",
+      "been fled read nailed nt on it to ste day mysel cds my he das wdm i guess eat hdt whoever hda collo\n",
+      "we a me into the tunnels dna on into the he daq udr ters must hdv e known wh dti wds looking cor it\n",
+      "wds to omufhocdfoinfiaenfet hdt they hda cou name here prob dbly they were f on nef tea with the emd\n",
+      "il sth dtc irst got me interest ea in bld fk but in df on c us east dte dc term y bld fk out i wds\n",
+      "puzzle a why hda they involve a me per hd ps they just a i ant know how to cina the shd a owd rf hiv\n",
+      "edna hope a i woul a be dble to help per hd ps they wdn tea to impl if dte me in the the c to c the\n",
+      "shdaowdrfhivepd pers in thd tfd se they shoul ahdvehitmehdraeriwds nt going to hdn gd roun along\n",
+      "enough to get fdu ght something wds nd gg in gdt men one oc the pd persi hda seen look ea\n",
+      "interesting enough to just icy dll this ec corti turn ea my he daf dut i ously trying to ignore the\n",
+      "throbbing be hina my ed rdna look ead roun a the room one more time to see w hdt we were missing\n",
+      "dsiaiasomycootfdught on something dna i bent a own top if kit up when they hit me i hda been sitting\n",
+      "red a in gb ldf ksfo a ebook it wd scull ocm drv ello us i cad tea i a edson fry p to grd phy dna\n",
+      "inc or md tions ef urity dna i hda just been red a ing these f tion on tr dns position fip her sit\n",
+      "see me a he wds pdr tiful drlykeenonfolumndrtr dns positions dna wds drg uing thd tit woul a be best\n",
+      "to red a occ the fip her text fol umn by fol um nt of on c use enemy fryptdndlystsiwdsm using on\n",
+      "just howse furet hd two ula be when the worl a went ad rklufkilydsihdacdlle nih daar op pea the book\n",
+      "dna it hd as lippe a una er the t dble somehow they hd am is sea it au ring these dr fh dna there it\n",
+      "wd shia a en in the sh dao wsi took da eep bred th to slow the spinning be hina my eyes dna p if kea\n",
+      "the book up but dsi pull ea mysel cup right dgd in the t dble tops hic tea slightly to ones iaei\n",
+      "struggle a to regd in my bdl dnf edna the t dble move a dgd in dna this time i he dr ada ist in ft\n",
+      "fl if kds is hic team y weight the tdblerotdteabdfkdna there it wds on fe more ds oct met dll iff\n",
+      "link ds dr dtf het too the ng dge a is too a upgr db be adt the tdb ledna pull e asia ew dys it turn\n",
+      "ead gdi nfl if kings ever dl times ds it aia so it wds d noise i knew very well the tumblers on dsd\n",
+      "cem dae the sd me so una though mu fhm ufh quieter\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(sanitise(keyword_decipher(sca, key_a, wrap_a))))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'damgerstuvwxyzbcfhijklnopq'"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kca = keyword_cipher_alphabet_of('damager', KeywordWrapAlphabet.from_last)\n",
+    "kca"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'dangerstuvwxyzbcfhijklmopq'"
+      ]
+     },
+     "execution_count": 20,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "sak, score = simulated_annealing_break(sca, cipher_alphabet=kca, fitness=Ptrigrams)\n",
+    "sak"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'dangerstuvwxyzbcfhijklmopq'"
+      ]
+     },
+     "execution_count": 22,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "kca = keyword_cipher_alphabet_of('dangers', KeywordWrapAlphabet.from_last)\n",
+    "kca"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "exactly what or who had hit me i wasnt sure but by the time i came around they had long gone if you\n",
+      "will excuse the p unit was a professional hit just the right amount of force to knock me out\n",
+      "probably no permanent damage the room had been expertly disassembled the shelves were emptied of\n",
+      "blacks mission files and much of the steampunk technology had been taken apart presumably to make\n",
+      "sure it didnt contain any further secrets the big beautiful roundtable had been cleared and ile\n",
+      "anton it to steady myself as my head swami guessed that whoever had followed me into the tunnels and\n",
+      "on into the headquarters must have known what i was looking for it was too much of a coincidence\n",
+      "that they had found me here probably they were connected with the emails that first got me\n",
+      "interested in black but in a confused state after my blackout i was puzzled why had they involved me\n",
+      "perhaps they just didnt know how to find the shadow archive and hoped i would be able to help\n",
+      "perhaps they wanted to implicate me in the theft of the shadow archive papers in that case they\n",
+      "should have hit me harder i wasnt going to hang around long enough to get caught something was\n",
+      "nagging at men one of the papers i had seen looked interesting enough to justify all this effort i\n",
+      "turned my head cautiously trying to ignore the throbbing behind m year and looked around the room\n",
+      "one more time to see what we were missing as i did so my foot caught on something and i bent down\n",
+      "topic kit up when they hit me i had been sitting reading blacks codebook it was full of marvellous\n",
+      "if dated ideas on cryptography and information security and i had just been reading the section on\n",
+      "transposition ciphers it seemed he was particularly keen on columnar transpositions and was arguing\n",
+      "that it would be best to read off the ciphertext column by column to confuse enemy crypt analysts i\n",
+      "was musing on just how secure that would be when the world went dark luckily as i had fallen i had\n",
+      "dropped the book and it had slipped under the table somehow they had missed it during the search and\n",
+      "there it was hidden in the shadows i took a deep breath to slow the spinning behind my eyes and\n",
+      "picked the book up but as i pulled myself upright again the tabletop shifted slightly to one side i\n",
+      "struggled to regain my balance and the table moved again and this time i heard a distinct click as i\n",
+      "shifted my weight the table rotated back and there it was once more a soft metallic c link as a\n",
+      "ratchet tooth engaged i stood up grabbed at the table and pulled sideways it turned again clicking\n",
+      "several times as it did so it was a noise i knew very well the tumblers on a safe made the same\n",
+      "sound though much much quieter\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(keyword_decipher(sca, 'dangers', KeywordWrapAlphabet.from_last)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2670"
+      ]
+     },
+     "execution_count": 25,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('7a.plaintext', 'w').write(lcat(tpack(segment(keyword_decipher(sca, 'dangers', KeywordWrapAlphabet.from_last)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/lib/python3.6/dist-packages/matplotlib/figure.py:459: UserWarning: matplotlib is currently using a non-GUI backend, so cannot show the figure\n",
+      "  \"matplotlib is currently using a non-GUI backend, \"\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "fc = collections.Counter(scb)\n",
+    "plot_frequency_histogram(fc, sort_key=fc.get)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "history_transpositions = collections.defaultdict(list)\n",
+    "for word in history_words:\n",
+    "    history_transpositions[transpositions_of(word)] += [word]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "3675"
+      ]
+     },
+     "execution_count": 28,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "len(history_transpositions)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(((4, 0, 3, 6, 2, 5, 1), False, True), -5440.482831185688)"
+      ]
+     },
+     "execution_count": 29,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(trans_b, fillcol_b, emptycol_b), score = column_transposition_break_mp(scb, translist=history_transpositions)\n",
+    "(trans_b, fillcol_b, emptycol_b), score"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'thechaosandconfusionthatfollowedthereichstadtmeetingwasmorecompletethanihadanyrighttohopetheplayfairgambitwasanoutstandingsuccessthedelegatesfromrussiaandaustrohungaryeachhadaclearviewofwhathadbeenagreedandtheseviewswereentirelydivergentevenbettertherecordsofthemeetingwereentirelyindependentofoneanotherattheurgingofouragentswithintheseparatecourtstheminutesweredictatedseparatelybythetwoforeignministersandrassyandgorchakovsoastoensurethedeepestpossibleunderstandingoftheagreedoutcomestherewasnosignedformalconventionnorevenanagreedprotocoloursubtlecampaignofwhispersandmisdirectionensuredthatneithersideentirelytrustedtheothersotheseminuteswereneversharedthediscussionsconcerningaustrianannexationinbosniaandherzegoveniawillconfusehistoriansanddiplomatsforgenerationstocomeithasalreadyconfusedtheprincipalsinthisaffairandnooneintheforeignofficecanmakesenseofthematalldespitethegreatcaretakenbytheofficersoftheshadowarchivetorecordthemaccuratelythereistalkoftheneedforfurthermeetingsofthegreatpowersandthistimeiwillmakesurethatbritainwillbeatthetabletoinfluencethedeliberationsandtoprotectourinterestsfromthepointofviewofhermajestyandtheprimeministerifnotthatofallherministersthisisclosetotheperfectoutcomediscussionisdisplacingwarandlowleveldistrustisinhibitingthesortoforganisedalliancethatmightdiminishourinfluenceoverthegatewaytotheeasttheforthcomingconferenceinconstantinoplewillforthefirsttimeinvolveourgovernmentinthediscussionsconcerningthefuturegovernanceoftheregionlordsalisburywillargueforthecreationofautonomousregionsunderbulgarianruleinthehopeofreducingtensionsandeliminatingtheexcusethatrussianeedstoengageinwarifhesucceedsthenwewillhaveestablishedacomprehensiveagreementwithrussiaconcerningitsterritorialambitionsincentralasiaresolvingtheconflictwithourownstrategicaimsevenifthisprovestobetoomuchforournegotiatorswecanatleasthopetobuytimetomakeourownpreparationsandtomanipulateouralliesandenemiesiwillconcentrateondevelopingfurtherconfusionspreadingmisinformationandasmuchdistrustasicanmanageifthetalksfailweshouldatleastensurethatnograndbargainisstruckagainstourinterestsandnomajorallianceisformedtodiminishusthemediterraneanisachokepointforthetraderoutesfromtheeastwecannotandwillnotallowotherstostrangletheflowofgoodsandpeoplethatenrichusnothreatisgreatertothehealthoftheempireandnoactionisbeyondcontemplationinoureffortstoremovethethreat'"
+      ]
+     },
+     "execution_count": 30,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "column_transposition_decipher(scb, trans_b, fillcolumnwise=fillcol_b, emptycolumnwise=emptycol_b)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "the chaos and confusion that followed the reich stadt meeting was more complete than i had any right\n",
+      "to hope the playfair gambit was an outstanding success the delegates from russia and austro hungary\n",
+      "each had a clearview of what had been agreed and these views were entirely divergent even better the\n",
+      "records of the meeting were entirely independent of one another at the urging of our agents within\n",
+      "the separate courts the minutes were dictated separately by the two foreign ministers andrassy and g\n",
+      "or chak ov so as to ensure the deepest possible understanding of the agreed outcomes there was no\n",
+      "signed formal convention nor even an agreed protocol our subtle campaign of whispers and\n",
+      "misdirection ensured that neither side entirely trusted the other so these minutes were never shared\n",
+      "the discussions concerning austrian annexation in bosnia and herzeg oven i a will confuse historians\n",
+      "and diplomats for generations to come it has already confused the principals in this affair and no\n",
+      "one in the foreign office can make sense of them at all despite the great care taken by the officers\n",
+      "of the shadow archive to record them accurately there is talk of the need for further meetings of\n",
+      "the great powers and this time i will make sure that britain will beat the table to influence the\n",
+      "deliberations and to protect our interests from the point of view of her majesty and the prime\n",
+      "minister if not that of all her ministers this is close to the perfect outcome discussion is\n",
+      "displacing war and low level distrust is inhibiting the sort of organised alliance that might\n",
+      "diminish our influence over the gateway to the east the forthcoming conference in constantinople\n",
+      "will for the first time involve our government in the discussions concerning the future governance\n",
+      "of the region lord salisbury will argue for the creation of autonomous regions under bulgarian rule\n",
+      "in the hope of reducing tensions and eliminating the excuse that russia needs to engage in war if he\n",
+      "succeeds then we will have established a comprehensive agreement with russia concerning its\n",
+      "territorial ambitions in central asia resolving the conflict with our own strategic aims even if\n",
+      "this proves to be too much for our negotiators we can atleast hope to buy time to make our own\n",
+      "preparations and to manipulate our allies and enemies i will concentrate on developing further\n",
+      "confusion spreading misinformation and as much distrust as i can manage if the talks fail we should\n",
+      "atleast ensure that no grand bargain is struck against our interests and no major alliance is formed\n",
+      "to diminish us the mediterranean is a choke point for the trade routes from the east we can not and\n",
+      "will not allow others to strangle the flow of goods and people that enrich us no threat is greater\n",
+      "to the health of the empire and no action is beyond contemplation in our efforts to remove the\n",
+      "threat\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(lcat(tpack(segment(column_transposition_decipher(scb, trans_b, fillcolumnwise=fillcol_b, emptycolumnwise=emptycol_b)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2846"
+      ]
+     },
+     "execution_count": 32,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "open('7b.plaintext', 'w').write(lcat(tpack(segment(column_transposition_decipher(scb, trans_b, fillcolumnwise=fillcol_b, emptycolumnwise=emptycol_b)))))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['bulgaria']"
+      ]
+     },
+     "execution_count": 33,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "history_transpositions[trans_b]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['bulgari', 'bulganin', 'bulgaria', 'extraverts']"
+      ]
+     },
+     "execution_count": 34,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "transpositions[trans_b]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.6.7"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}