Skip to content

Instantly share code, notes, and snippets.

@yeesian
Last active December 26, 2015 20:49
Show Gist options
  • Save yeesian/7211486 to your computer and use it in GitHub Desktop.
Save yeesian/7211486 to your computer and use it in GitHub Desktop.
Mission 12 Description for CS1010S (AY2013/14 Sem 1)
Display the source blob
Display the rendered blob
Raw
{
"metadata": {
"name": ""
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Introduction\n",
"---\n",
"In this mission, we will investigate how generic operators can help us to manage a system whether there are multiple related data types that sometimes interact. We will study and modify a generic number system that works with a number of number data types.\n",
"\n",
"[...]\n",
"\n",
"There is a large amount of code for you to manage in this mission and the next, and the code makes heavy use of data-directed programming techniques. We do not intend for you to study it all\u2014and you may run out of time if you try. These missions will give you an opportunity to acquire a key professional skill: mastering code *organization* well enough to know what you need to understand and what you don\u2019t.\n",
"\n",
"That said, I could run through the code a little, for you to develop a sense for how we \n",
"\n",
"1. read a problem statement, \n",
"2. \"walk through\" the code (across multiple files) to get to information we want, and\n",
"3. interpret and understand what they do.\n",
"\n",
"As a result, if you're hoping I'll jump to the simple pictures directly, you'll be disappointed - the point here is not to just simplify the mission for you; it's to equip you with the skills to do so on your own in the future.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Getting Started\n",
"---\n",
"We'll work with the following 2 files:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ls *.py"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
" Volume in drive D is home\n",
" Volume Serial Number is 6831-925B\n",
"\n",
" Directory of D:\\yeesian\\Desktop\n",
"\n",
"29-Oct-13 10:26 AM 5,384 generic_arith.py\n",
"29-Oct-13 10:25 AM 4,428 mission12a-template.py\n",
" 2 File(s) 9,812 bytes\n",
" 0 Dir(s) 111,976,378,368 bytes free\n"
]
}
],
"prompt_number": 15
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We have some familiar arithmetic operations on generic numbers (inside `mission12-template.py`):"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def add(x,y): return apply_generic(\"add\", x, y)\n",
"def sub(x,y): return apply_generic(\"sub\", x, y)\n",
"def mul(x,y): return apply_generic(\"mul\", x, y)\n",
"def div(x,y): return apply_generic(\"div\", x, y)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 7
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We also have others, like"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def negate(x): return apply_generic(\"negate\", x)\n",
"def is_zero(x): return apply_generic(\"is_zero\", x)\n",
"def is_equal(x,y): return apply_generic(\"is_equal\", x, y)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 8
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"So it's probably a good idea to look at what `apply_generic()` is doing *under the hood*."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Generic Operations\n",
"-----\n",
"\n",
"If you look inside `generic_arith.py`, we have:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def apply_generic(op, *args):\n",
" type_tags = tuple(map(type_tag, args))\n",
" proc = get(op, type_tags)\n",
" if proc:\n",
" return proc(*map(content, args))\n",
" raise Exception('No method for these types -- apply_generic', (op, type_tags))"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 9
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If you scan through the code, you can pick out the parts of it that haven't been mentioned so far:\n",
"\n",
"1. `type_tag` (line 2)\n",
"2. `get()` (line 3)\n",
"2. `content` (line 5)\n",
"\n",
"To find out what `type_tag` and `content` are, we could scroll through the document and hope we find them. Alternatively, if we read the code and see the context (they are the first arguments to `map()`), we'll infer that they're probably functions. I'll list them below:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def type_tag(datum):\n",
" if type(datum) == tuple and len(datum) == 2:\n",
" return datum[0]\n",
" raise Exception('Bad tagged datum -- type_tag ', datum)\n",
"\n",
"\n",
"def content(datum):\n",
" if type(datum) == tuple and len(datum) == 2:\n",
" return datum[1]\n",
" raise Exception('Bad tagged datum -- content ', datum)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 11
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In this case, we can figure out what `type_tag` and `content` are doing, since the code is simple: we imagine each *datum* to be represented as a tuple:\n",
"\n",
" (tag, content)\n",
" \n",
"Now, what about `get()`?"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def get(op, types):\n",
" if op in _operation_table and types in _operation_table[op]:\n",
" return _operation_table[op][types]\n",
" else:\n",
" return None"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 12
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Interpreting Code\n",
"---\n",
"There are multiple ways of figuring out:\n",
"\n",
"- from the way it is used (in `apply_generic()`)\n",
"- from the way it is implemented (in the code cell above)\n",
"\n",
"Let me do it using the first method (from the way it is used). Let's put a few things together:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def add(x,y): return apply_generic(\"add\", x, y) # in mission12-template.py\n",
"\n",
"# [...]\n",
"\n",
"# in generic_arith.py\n",
"# ---\n",
"def apply_generic(op, *args): # op => \"add\", args => (x,y)\n",
" type_tags = tuple(map(type_tag, args)) # type_tags => (type_tag(x), type_tag(y))\n",
" proc = get(op, type_tags) # this will evaluate to => get(\"add\",(type_tag(x), type_tag(y)))\n",
" if proc:\n",
" return proc(*map(content, args))\n",
" raise Exception('No method for these types -- apply_generic', (op, type_tags))\n",
" \n",
"def get(op, types):\n",
" if op in _operation_table and types in _operation_table[op]:\n",
" # if \"add\" in _operation_table (which is a dictionary)\n",
" # and (type_tag(x), type_tag(y)) in _operation_table[\"add\"] (which is another table)\n",
" return _operation_table[op][types]\n",
" else:\n",
" return None"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 13
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"So here's my *mental model* of `_operation_table` by now:\n",
"\n",
"**tags** | ('generic') | ('complex','complex') | ('rational','rational') | ... |\n",
" ------------ | :-------------------: | :-------------------: | :---------------------: |\n",
"**operation** | | ||\n",
"'add' | |add(x,y)| add(x,y)|\n",
"'mul' | |mul(x,y)| mul(x,y)|\n",
"'negate' | negate(x) | ||\n",
"'is_zero' | is_zero(x)| ||\n",
"'is_equal' | |is_equal(x,y)| is_equal(x,y)|\n",
"... | | ||\n",
"\n",
"So in `get(op, args)`: we first look up the appropriate `op` (operation) in the left side-bar, before we use the *tags* (in the top/header row) to find the appropriate function to use."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Moving Forward\n",
"---\n",
"A quick scan of the `generic arith.py` code will reveal three generic number packages\n",
"\n",
"- generic ordinary numbers\n",
"- generic rational numbers\n",
"- generic complex numbers.\n",
"\n",
"The following functions (in `generic_arithy.py`) should be easier to understand now:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def attach_tag(tag, content):\n",
" return (tag, content)\n",
"\n",
"def put(op, types, value):\n",
" if op not in _operation_table:\n",
" _operation_table[op] = {}\n",
" _operation_table[op][types] = value\n",
" \n",
"#composite generic operators\n",
"def square(x):\n",
" return mul(x,x)\n",
"\n",
"#Generic Number package\n",
"def create_number(x):\n",
" return get(\"make\", \"number\")(x)\n",
"\n",
"#Specific Number package(s)\n",
"\n",
"def create_rational(x, y):\n",
" return get(\"make\",\"rational\")(x, y)\n",
"\n",
"def create_complex(x,y):\n",
" return get(\"make\",\"complex\")(x,y)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 14
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"I hope that's a good starting point for you all to continue exploring the rest of the mission. Feel free to discuss and clarify among yourselves (in the whatsapp group, in the IVLE forum, in person, or over email), but when you do the mission, it has to be from a blank slate, on your own (:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [],
"language": "python",
"metadata": {},
"outputs": []
}
],
"metadata": {}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment