Last active
November 28, 2019 18:58
-
-
Save JakubKoralewski/be26896ff19617de8ba9d4323997f921 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"<center>\n", | |
"<h1>Introduction to Computer Science<br>\n", | |
" Labs 07 Homework</h1> \n", | |
"By Jakub Koralewski\n", | |
"</center>" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": { | |
"pycharm": { | |
"is_executing": false | |
}, | |
"scrolled": true, | |
"tags": [ | |
"hide_input" | |
] | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<center><table>\n", | |
"<thead>\n", | |
"<tr><th>Building </th><th style=\"text-align: right;\"> Hosts</th></tr>\n", | |
"</thead>\n", | |
"<tbody>\n", | |
"<tr><td>Amsterdam </td><td style=\"text-align: right;\"> 1024</td></tr>\n", | |
"<tr><td>Berlin </td><td style=\"text-align: right;\"> 4012</td></tr>\n", | |
"<tr><td>Kiev </td><td style=\"text-align: right;\"> 230</td></tr>\n", | |
"<tr><td>Poznan </td><td style=\"text-align: right;\"> 214</td></tr>\n", | |
"<tr><td>Praga </td><td style=\"text-align: right;\"> 714</td></tr>\n", | |
"</tbody>\n", | |
"</table></center>" | |
], | |
"text/plain": [ | |
"<IPython.core.display.HTML object>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"# Visualizes table of buildings\n", | |
"import ipaddress\n", | |
"from IPython.display import HTML, display\n", | |
"import tabulate\n", | |
"\n", | |
"original = ipaddress.ip_network(\"8.56.32.0/19\")\n", | |
"\n", | |
"buildings = {\n", | |
" \"Amsterdam\": 1024,\n", | |
" \"Berlin\": 4012,\n", | |
" \"Kiev\": 230,\n", | |
" \"Poznan\": 214,\n", | |
" \"Praga\": 714\n", | |
"}\n", | |
"display(HTML(\"<center>\" + tabulate.tabulate(buildings.items(), headers=[\"Building\", \"Hosts\"], tablefmt='html')+\"</center>\"))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"pycharm": { | |
"name": "#%% md\n" | |
} | |
}, | |
"source": [ | |
"<center>\n", | |
"We require 5 subnetworks each with minimum 4012 hosts.<br>\n", | |
"<br>\n", | |
"We can add 3 additional bits as it is the minimum \n", | |
"number of bits that will allow us to create 5 subnetworks: <br>\n", | |
"$ 2^2 = 4 $ <br>\n", | |
"$ 2^3 = 8 $ \n", | |
"</center>" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": { | |
"pycharm": { | |
"is_executing": false | |
}, | |
"scrolled": true | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"application/vnd.jupyter.widget-view+json": { | |
"model_id": "55ec918aa7aa42c0938c92c895d0dbab", | |
"version_major": 2, | |
"version_minor": 0 | |
}, | |
"text/plain": [ | |
"interactive(children=(IntSlider(value=3, description='New bits', max=13), Output()), _dom_classes=('widget-int…" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"# Shows hosts vs subnetworks distribution as default mask changes\n", | |
"from ipywidgets import interactive, widgets, fixed\n", | |
"\n", | |
"new = None\n", | |
"num_hosts = 0\n", | |
"\n", | |
"def mask(x):\n", | |
" return '.'.join(map(lambda x: bin(x)[2:].zfill(8), x))\n", | |
"def interact_mask(x, should_print=True):\n", | |
" global new\n", | |
" global num_hosts\n", | |
" new_subnets = list(original.subnets(x))\n", | |
" new = new_subnets[0]\n", | |
" num_hosts = len(list(new.hosts()))\n", | |
" if should_print:\n", | |
" print(f\"Original mask: {mask(original.netmask.packed)}\")\n", | |
" print(f\"New mask: {mask(new.netmask.packed)}\\n\")\n", | |
" print(f\"Number of networks: {len(new_subnets)}\")\n", | |
" print(f\"Number of addresses: {new.num_addresses}\")\n", | |
" print(f\"Number of actual hosts: {num_hosts}\")\n", | |
" return new_subnets\n", | |
"\n", | |
"interactive(interact_mask, x=widgets.IntSlider(min=0, max=32-19, step=1,value=3, description=\"New bits\"), should_print=fixed(True))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"pycharm": { | |
"name": "#%% md\n" | |
} | |
}, | |
"source": [ | |
"<h3>We can see two possible problems:</h3>\n", | |
"\n", | |
"1. We have too many networks than necessary. (8/5)\n", | |
"2. We don't have enough host addresses to facilitate our Berlin facility. (1022/4012)\n", | |
"\n", | |
"An obvious decision would be to associate multiple subnetworks for each company building:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": { | |
"pycharm": { | |
"is_executing": true | |
} | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"application/vnd.jupyter.widget-view+json": { | |
"model_id": "3703fb8b768541389da2554f2894b912", | |
"version_major": 2, | |
"version_minor": 0 | |
}, | |
"text/plain": [ | |
"interactive(children=(IntSlider(value=3, description='New bits', max=13), Output()), _dom_classes=('widget-int…" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"# Visualizes grouping of subnetworks for each building\n", | |
"from typing import Dict\n", | |
"\n", | |
"def associate(d: Dict, subnets_count=0):\n", | |
" global num_hosts\n", | |
" new_dict = {}\n", | |
" for i, key in enumerate(d):\n", | |
" if i + 1 > subnets_count:\n", | |
" break\n", | |
" h = num_hosts\n", | |
" old = d[key]\n", | |
" j = 1\n", | |
" while h < old:\n", | |
" h += num_hosts\n", | |
" j += 1\n", | |
" new_dict[key] = (old, h, j)\n", | |
" return new_dict\n", | |
"\n", | |
"def interact_group(x: int, should_print=True):\n", | |
" global buildings\n", | |
" new_subnets = len(interact_mask(x, should_print=should_print))\n", | |
" new_dict = associate(buildings, subnets_count=new_subnets)\n", | |
" if should_print:\n", | |
" display(HTML(\"<center>\" + tabulate.tabulate(list((d[0], d[1][0], d[1][1], d[1][2]) for d in new_dict.items()), headers=[\"Building\", \"Needed hosts\", \"Hosts\", \"Number of networks\"], tablefmt='html')+\"</center>\"))\n", | |
" print(f\"Needed networks: {max(len(buildings), sum(new_dict[key][2] for key in new_dict))}\")\n", | |
" print(f\"Available networks: {new_subnets}\")\n", | |
" return new_dict\n", | |
"\n", | |
"interactive(interact_group, x=widgets.IntSlider(min=0, max=32-19, step=1,value=3, description=\"New bits\"), should_print=fixed(True))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"pycharm": { | |
"name": "#%% md\n" | |
} | |
}, | |
"source": [ | |
"We can see that when splitting into 8 subnetworks and merging into the above configuration (3 bit split)\n", | |
"we are lacking a single network needed for one of our facilities. This is a result of many IP addresses\n", | |
"being wasted for smaller buildings such as the one in Poznań.\n", | |
"\n", | |
"A successful split would be the one with 4 bits creating 16 new networks, while leaving one reserved\n", | |
"in case our company wanted to explore new markets.\n", | |
" " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": { | |
"pycharm": { | |
"is_executing": true, | |
"name": "#%%\n" | |
} | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/html": [ | |
"<center><table>\n", | |
"<thead>\n", | |
"<tr><th>Building </th><th style=\"text-align: right;\"> Needed hosts</th><th style=\"text-align: right;\"> Hosts</th><th style=\"text-align: right;\"> Number of networks</th></tr>\n", | |
"</thead>\n", | |
"<tbody>\n", | |
"<tr><td>Amsterdam </td><td style=\"text-align: right;\"> 1024</td><td style=\"text-align: right;\"> 1530</td><td style=\"text-align: right;\"> 3</td></tr>\n", | |
"<tr><td>Berlin </td><td style=\"text-align: right;\"> 4012</td><td style=\"text-align: right;\"> 4080</td><td style=\"text-align: right;\"> 8</td></tr>\n", | |
"<tr><td>Kiev </td><td style=\"text-align: right;\"> 230</td><td style=\"text-align: right;\"> 510</td><td style=\"text-align: right;\"> 1</td></tr>\n", | |
"<tr><td>Poznan </td><td style=\"text-align: right;\"> 214</td><td style=\"text-align: right;\"> 510</td><td style=\"text-align: right;\"> 1</td></tr>\n", | |
"<tr><td>Praga </td><td style=\"text-align: right;\"> 714</td><td style=\"text-align: right;\"> 1020</td><td style=\"text-align: right;\"> 2</td></tr>\n", | |
"</tbody>\n", | |
"</table></center>" | |
], | |
"text/plain": [ | |
"<IPython.core.display.HTML object>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
}, | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Example split of networks: \n" | |
] | |
}, | |
{ | |
"data": { | |
"text/html": [ | |
"<center><table>\n", | |
"<thead>\n", | |
"<tr><th>Building </th><th>Networks </th></tr>\n", | |
"</thead>\n", | |
"<tbody>\n", | |
"<tr><td>Amsterdam </td><td>['8.56.34.0/23', '8.56.36.0/23', '8.56.38.0/23'] </td></tr>\n", | |
"<tr><td>Berlin </td><td>['8.56.40.0/23', '8.56.42.0/23', '8.56.44.0/23', '8.56.46.0/23', '8.56.48.0/23', '8.56.50.0/23', '8.56.52.0/23', '8.56.54.0/23']</td></tr>\n", | |
"<tr><td>Kiev </td><td>['8.56.56.0/23'] </td></tr>\n", | |
"<tr><td>Poznan </td><td>['8.56.58.0/23'] </td></tr>\n", | |
"<tr><td>Praga </td><td>['8.56.60.0/23', '8.56.62.0/23'] </td></tr>\n", | |
"</tbody>\n", | |
"</table></center>" | |
], | |
"text/plain": [ | |
"<IPython.core.display.HTML object>" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"bit4_split = {'Amsterdam': (1024, 1530, 3), 'Berlin': (4012, 4080, 8), 'Kiev': (230, 510, 1), 'Poznan': (214, 510, 1), 'Praga': (714, 1020, 2)} \n", | |
"display(HTML(\"<center>\" + tabulate.tabulate(list((d[0], d[1][0], d[1][1], d[1][2]) for d in bit4_split.items()), headers=[\"Building\", \"Needed hosts\", \"Hosts\", \"Number of networks\"], tablefmt='html')+\"</center>\"))\n", | |
"\n", | |
"\n", | |
"print(\"Example split of networks: \")\n", | |
"def create_example_split(x:int, dict_split: Dict):\n", | |
" example_split = []\n", | |
" nets = 0\n", | |
" networks = interact_mask(x, should_print=False)\n", | |
" num_networks = len(networks)\n", | |
" for i, split in enumerate(dict_split.items()):\n", | |
" example_split.append([split[0], []])\n", | |
" for j in range(split[1][2]):\n", | |
" nets += 1\n", | |
" # if nets >= num_networks:\n", | |
" # return example_split\n", | |
" example_split[i][1].append(networks[nets])\n", | |
" return example_split\n", | |
"example_split = create_example_split(4, bit4_split)\n", | |
"example_split = list(map(lambda x: [x[0], [y.exploded for y in x[1]]], example_split))\n", | |
" \n", | |
"display(HTML(\"<center>\" + tabulate.tabulate(example_split, headers=[\"Building\", \"Networks\"], tablefmt='html')+\"</center>\"))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"However, now we are still left with the problem of wasted IP addresses in smaller buildings!" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": { | |
"pycharm": { | |
"is_executing": false, | |
"name": "#%%\n" | |
} | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"application/vnd.jupyter.widget-view+json": { | |
"model_id": "247b06404b0b42b5a456c46fae29cd99", | |
"version_major": 2, | |
"version_minor": 0 | |
}, | |
"text/plain": [ | |
"interactive(children=(IntSlider(value=5, description='New bits', max=9), Output()), _dom_classes=('widget-inte…" | |
] | |
}, | |
"metadata": {}, | |
"output_type": "display_data" | |
} | |
], | |
"source": [ | |
"# Shows waste of IP addresses\n", | |
"def interact_waste(x: int):\n", | |
" distribution = interact_group(x, should_print=True)\n", | |
" example_split = create_example_split(x, distribution)\n", | |
" table = list((d[0], d[1][0], d[1][1], d[1][2], d[1][1]-d[1][0], sum(x.num_addresses - len(list(x.hosts())) for x in example_split[i][1])) for i, d in enumerate(distribution.items()))\n", | |
" display(HTML(\"<center>\" + tabulate.tabulate(table, headers=[\"Building\", \"Needed hosts\", \"Hosts\", \"Number of networks\", \"Unused addresses\", \"Wasted addresses\"], tablefmt='html')+\"</center>\"))\n", | |
" \n", | |
"interactive(interact_waste, x=widgets.IntSlider(min=0, max=9, step=1,value=5, description=\"New bits\"))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"pycharm": { | |
"name": "#%% md\n" | |
} | |
}, | |
"source": [ | |
"The \"Wasted Addresses\" column shows how with every added subnetwork the necessary broadcast and network address\n", | |
"result in less and less addresses available for hosts. With 10-bit and larger default mask we lose so much so\n", | |
"that we can't fit all our hosts.\n", | |
"\n" | |
] | |
} | |
], | |
"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.7.4" | |
}, | |
"pycharm": { | |
"stem_cell": { | |
"cell_type": "raw", | |
"metadata": { | |
"collapsed": false | |
}, | |
"source": [] | |
} | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
tabulate==0.8.6 | |
ipaddress==1.0.23 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://mybinder.org/v2/gist/JakubKoralewski/be26896ff19617de8ba9d4323997f921/a5afa45f21704efc7477a40eeb3ffacd693ca971