Skip to content

Instantly share code, notes, and snippets.

@JakubKoralewski
Last active November 28, 2019 18:58
Show Gist options
  • Save JakubKoralewski/be26896ff19617de8ba9d4323997f921 to your computer and use it in GitHub Desktop.
Save JakubKoralewski/be26896ff19617de8ba9d4323997f921 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"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
}
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