Created
June 13, 2018 19:04
-
-
Save nhfruchter/7a0325b4061b79b32b12a2d71b817359 to your computer and use it in GitHub Desktop.
Dumb stuff with operator overloading
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": "code", | |
"execution_count": 3, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"from math import inf\n", | |
"class Node(object):\n", | |
" MAX_ATTACHMENTS = inf\n", | |
" \n", | |
" def __init__(self, label=\"Generic Node\"):\n", | |
" self.attachments = []\n", | |
" self.label = label\n", | |
"\n", | |
" def _attach(self, other):\n", | |
" if len(self.attachments) >= self.MAX_ATTACHMENTS:\n", | |
" raise ValueError(\"{cls} can only be attached to a maximum of {max} objects.\".format(cls=self.__class__, max=self.MAX_ATTACHMENTS))\n", | |
"\n", | |
" if other in self.attachments:\n", | |
" raise Exception(\"Already attached.\")\n", | |
" \n", | |
" self.attachments.append(other)\n", | |
" \n", | |
" def _detach(self, string, called_from=\"node\"):\n", | |
" if string not in self.attachments:\n", | |
" raise ValueError(\"Cannot detach an unattached string.\")\n", | |
" \n", | |
" removed_string = self.attachments.pop(string)\n", | |
"\n", | |
" if called_from == \"node\":\n", | |
" removed_string.detach(self, called_from=\"node\")\n", | |
" \n", | |
" def relationship(self, string):\n", | |
" if self == string.start:\n", | |
" return \"beginning of string\"\n", | |
" elif self == string.end:\n", | |
" return \"end of string\" \n", | |
" else:\n", | |
" raise ValueError(\"No relationship.\") \n", | |
"\n", | |
"class Endpoint(Node):\n", | |
" MAX_ATTACHMENTS = 1\n", | |
" \n", | |
" def __init__(self, label=\"Endpoint\"):\n", | |
" super(Endpoint, self).__init__(label=label)\n", | |
"\n", | |
"class Vertex(Node):\n", | |
" MAX_ATTACHMENTS = 3\n", | |
" \n", | |
" def __init__(self, label=\"Vertex\"):\n", | |
" super(Vertex, self).__init__(label=label)\n", | |
" \n", | |
" \n", | |
"class String(object):\n", | |
" @classmethod\n", | |
" def is_node(self, other):\n", | |
" if not isinstance(other, Node):\n", | |
" raise TypeError(\"Strings can only be attached to Node or its subclasses.\")\n", | |
" else:\n", | |
" return True\n", | |
" \n", | |
" def __init__(self, start=None, end=None):\n", | |
" self.start = start\n", | |
" self.end = end\n", | |
"\n", | |
" def __radd__(self, other):\n", | |
" \"\"\"\n", | |
" Called when String is on the RH of plus sign: <other> + String().\n", | |
" \n", | |
" Attachment to beginning of string. \n", | |
" \"\"\"\n", | |
" \n", | |
" assert self.is_node(other)\n", | |
" self.start = other\n", | |
" other._attach(self)\n", | |
" \n", | |
" def __add__(self, other):\n", | |
" \"\"\"\n", | |
" Called when String is on the LH of plus sign: String() + <other>.\n", | |
"\n", | |
" Attachment to end of string.\n", | |
" \"\"\"\n", | |
" \n", | |
" assert self.is_node(other)\n", | |
" self.end = other\n", | |
" other._attach(self)\n", | |
"\n", | |
" def __rsub__(self, other):\n", | |
" self.detach(self.start)\n", | |
"\n", | |
" def __sub__(self, other):\n", | |
" self.detach(self.end)\n", | |
"\n", | |
" def detach(self, node, called_from=\"string\"):\n", | |
" if self.start == node:\n", | |
" self.start = None\n", | |
" if called_from == \"string\":\n", | |
" node._detach(self)\n", | |
" elif self.end == node:\n", | |
" self.end = None\n", | |
" if called_from == \"string\":\n", | |
" node._detach(self)\n", | |
" else:\n", | |
" raise ValueError(\"Cannot detach unattached node.\")" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"v = Vertex(label=\"v1\")\n", | |
"e = Endpoint(label=\"e1\")\n", | |
"s1 = String()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"v + s1 # Attach to vertex at the start\n", | |
"s1 + e # And endpoint at the end" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"('v1', 'e1')" | |
] | |
}, | |
"execution_count": 7, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"s1.start.label, s1.end.label" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 11, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"([<__main__.String at 0x10a599780>], [<__main__.String at 0x10a599780>])" | |
] | |
}, | |
"execution_count": 11, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"v.attachments, e.attachments " | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 13, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"s2 = String()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 14, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"ename": "ValueError", | |
"evalue": "<class '__main__.Endpoint'> can only be attached to a maximum of 1 objects.", | |
"output_type": "error", | |
"traceback": [ | |
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", | |
"\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", | |
"\u001b[0;32m<ipython-input-14-9a252a698327>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0me\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0ms2\u001b[0m \u001b[0;31m# Endpoints can fill up\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", | |
"\u001b[0;32m<ipython-input-3-3520e491b69b>\u001b[0m in \u001b[0;36m__radd__\u001b[0;34m(self, other)\u001b[0m\n\u001b[1;32m 67\u001b[0m \u001b[0;32massert\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mis_node\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mother\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 68\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstart\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 69\u001b[0;31m \u001b[0mother\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_attach\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 70\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 71\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__add__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;32m<ipython-input-3-3520e491b69b>\u001b[0m in \u001b[0;36m_attach\u001b[0;34m(self, other)\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_attach\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mother\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mattachments\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mMAX_ATTACHMENTS\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 11\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"{cls} can only be attached to a maximum of {max} objects.\"\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcls\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__class__\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmax\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mMAX_ATTACHMENTS\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 12\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 13\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mother\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mattachments\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", | |
"\u001b[0;31mValueError\u001b[0m: <class '__main__.Endpoint'> can only be attached to a maximum of 1 objects." | |
] | |
} | |
], | |
"source": [ | |
"e + s2 # Endpoints can fill up" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 15, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"[<__main__.String at 0x10a599780>, <__main__.String at 0x10a5941d0>]" | |
] | |
}, | |
"execution_count": 15, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"v + s2 # But vertices haven't yet\n", | |
"v.attachments" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 16, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'beginning of string'" | |
] | |
}, | |
"execution_count": 16, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"v.relationship(s2)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 17, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"s3 = String()\n", | |
"s3 + v" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 18, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'end of string'" | |
] | |
}, | |
"execution_count": 18, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"v.relationship(s3)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"collapsed": true | |
}, | |
"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.3" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment