{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Foundations of Computational Economics #8\n", "\n", "by Fedor Iskhakov, ANU\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "fragment" } }, "source": [ "## Bundle goods market\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "\n", "\n", "[https://youtu.be/Y6CtsI8X914](https://youtu.be/Y6CtsI8X914)\n", "\n", "Description: Object oriented programming in modeling consumer choice model." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "Consider the following model of a bundle goods market. A\n", "bundle of goods is a collection of particular items offered at a\n", "specified price. For example, Happy Meals at McDonalds is a set\n", "of items in a meal sold for a particular price.\n", "\n", "One other example of bundled goods - subscription packages in theaters,\n", "for example [La Scala in\n", "Milan](http://www.teatroallascala.org/en/box-office/subscriptions/types/subscription-types-2018-2019.html)\n", "or [Mariinsky in\n", "St.Petersburg](https://www.mariinsky.ru/playbill/subscriptions/2018_2019).\n", "\n", "In this task you will write code to implement and operationalize this\n", "setup." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Bundle_good class\n", "\n", "Develop the Python class to represent a bundle good with the following specifications:\n", "\n", "- The class attribute (common to all objects of this class) is a\n", " list of goods \n", "- The public property is a vector of integers defining how many of each goods are in the bundle \n", "- The other property is the price for that bundle \n", "\n", "\n", "The following arithmetic operations are defined for the bungles:\n", "\n", "- addition: \n", " 1. sum of two bundles is a bundle with added up items and prices \n", " 1. sum of a bundle and a number (float or int) increases the price \n", "- subtraction: \n", " 1. difference between two bundles should produce a bundle with\n", " difference in items and difference in prices \n", " 1. subtracting a number (float or int) from a bundle should only\n", " decrease its price \n", "- multiplication is only defined for bundle and an integers, and results in the bundle with all items multiplied by this number, and price increased by the same number \n", "- devision is only defined for integers, and only such that the all quantities are divisible by this integer, the resulting bundle is a fraction of the original, with the price also decreased by the same number \n", "\n", "\n", "Complete the class definition code, and run the tests in the next cell." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "class bundle_good():\n", " '''Class of bundled goods with well defined arithmetics'''\n", "\n", " items = ('Opera A', 'Opera B', \\\n", " 'Ballet A', 'Ballet B', \\\n", " 'Symphonic orchestra concert', \\\n", " 'Rock opera', \\\n", " 'Operetta') # 7 different goods\n", "\n", " def __init__(self,quantities=[0,],price=0.0):\n", " '''Creates the bundle good object, empty by default'''\n", " pass\n", " # ignore extra quantities if passed\n", " # add zeros for the unspecified items\n", " # ensure all quantities are integers\n", "\n", " def __repr__(@@@):\n", " '''String representation of the object'''\n", " pass\n", "\n", " def __add__(self,other):\n", " '''Addition for bundle goods'''\n", " pass\n", " # if wrong type pass, raise the TypeError\n", " # raise TypeError('Can only add bundle to bundle, or number to bundle price')\n", "\n", " def __sub__(self,other):\n", " '''Subtraction for bundles: subtract items and prices, or decrease price'''\n", " pass\n", "\n", " def __mul__(self,num):\n", " '''Multiplication for bundles: proportional increase in nomenclature and price'''\n", " pass\n", "\n", " def __truediv__(self,num):\n", " '''Division for bundles: fraction of the original bundle, only if quantities are divisable'''\n", " pass" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Tests\n", "\n", "To make sure the class is running as it is supposed to, run all the\n", "tests below and confirm that the output is as expected." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "# Tests\n", "x=bundle_good([1,2,3,4,5,6,7],11.43)\n", "print(x) #should print \"Bundle object [1, 2, 3, 4, 5, 6, 7] with price 11.43\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "x=bundle_good([1,2])\n", "print(x) #should print \"Bundle object [1, 2, 0, 0, 0, 0, 0] with price 0.00\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "x=bundle_good(range(25),100.2)\n", "print(x) #should print \"Bundle object [0, 1, 2, 3, 4, 5, 6] with price 100.20\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "x=bundle_good([1.5,2.3,3.2,4.1,5.75,6.86,7.97],1.43)\n", "print(x) #should print \"Bundle object [1, 2, 3, 4, 5, 6, 7] with price 1.43\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "x=bundle_good([1,2,3,4,5,6,7],11.43)\n", "y=bundle_good([7,6,5,4,3,2,1],77.45)\n", "z=x+y\n", "print(z) #should print \"Bundle object [8, 8, 8, 8, 8, 8, 8] with price 88.88\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "z=y-x\n", "print(z) #should print \"Bundle object [6, 4, 2, 0, -2, -4, -6] with price 66.02\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "z=x+4.531\n", "print(z) #should print \"Bundle object [1, 2, 3, 4, 5, 6, 7] with price 15.96\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "z=y-77\n", "print(z) #should print \"Bundle object [7, 6, 5, 4, 3, 2, 1] with price 0.45\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "z=x*11\n", "print(z) #should print \"Bundle object [11, 22, 33, 44, 55, 66, 77] with price 125.73\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "try:\n", " z=x*11.5 #should raise a TypeError\n", "except TypeError:\n", " print(\"Ok 1\") #should print \"Ok 1\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "try:\n", " z=x*y #should raise a TypeError\n", "except TypeError:\n", " print(\"Ok 2\") #should print \"Ok 2\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "try:\n", " z=x/y #should raise a TypeError\n", "except TypeError:\n", " print(\"Ok 3\") #should print \"Ok 3\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "z=(x+y)/8\n", "print(z) #should print \"Bundle object [1, 1, 1, 1, 1, 1, 1] with price 11.11\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "try:\n", " (x+y)/7 #should raise a ValueError\n", "except ValueError:\n", " print(\"Ok 4\") #should print \"Ok 4\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "z=x*15-y*2\n", "print(z) #should print \"Bundle object [1, 18, 35, 52, 69, 86, 103] with price 16.55\"" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "### Solution" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide-output": false, "slideshow": { "slide_type": "slide" } }, "outputs": [], "source": [ "class bundle_good():\n", " '''Class of bundled goods with well defined arithmetics'''\n", "\n", " items = ('Opera A', 'Opera B', \\\n", " 'Ballet A', 'Ballet B', \\\n", " 'Symphonic orchestra concert', \\\n", " 'Rock opera', \\\n", " 'Operetta') # 7 different goods\n", "\n", " def __init__(self,quantities=[0,],price=0.0):\n", " '''Creates the bundle good object\n", " '''\n", " n = len(bundle_good.items) # number of available items\n", " if len(quantities)n:\n", " # ignore extra numbers\n", " quantities = quantities[0:n]\n", " # create public attributes\n", " # ensure the quantities in the object are integer\n", " self.quantities=[int(x) for x in quantities]\n", " self.price=price\n", "\n", " def __repr__(self):\n", " '''String representation of the object\n", " '''\n", " return 'Bundle object %r with price %1.2f' % (self.quantities,self.price)\n", "\n", " def __add__(self,other):\n", " '''Addition for bundles: add items and sum prices, or increase price\n", " '''\n", " if type(other) is bundle_good:\n", " # add the quantities using list comprehension with one-to-one matching (zip)\n", " q1 = [x+y for x,y in zip(self.quantities, other.quantities)]\n", " # sum of the prices\n", " p1 = self.price + other.price\n", " # return new bundle\n", " return bundle_good(quantities=q1,price=p1)\n", "\n", " elif type(other) in (float,int):\n", " # increase the price\n", " p1 = self.price + other\n", " # return new bundle\n", " return bundle_good(quantities=self.quantities,price=p1)\n", "\n", " else:\n", " raise TypeError('Can only add bundle to bundle, or number to bundle price')\n", "\n", " def __sub__(self,other):\n", " '''Subtraction for bundles: subtract items and prices, or decrease price\n", " '''\n", " if type(other) is bundle_good:\n", " # subtract the quantities using list comprehension with one-to-one matching (zip)\n", " q1 = [x-y for x,y in zip(self.quantities, other.quantities)]\n", " # sum of the prices\n", " p1 = self.price - other.price\n", " # return new bundle\n", " return bundle_good(quantities=q1,price=p1)\n", " elif type(other) in (float,int):\n", " # decrease the price\n", " p1 = self.price - other\n", " # return new bundle\n", " return bundle_good(quantities=self.quantities,price=p1)\n", " else:\n", " raise TypeError('Can only subtract bundle from bundle, or number from bundle price')\n", "\n", " def __mul__(self,num):\n", " '''Multiplication for bundles: repetition of the original bundle\n", " '''\n", " if type(num) is int:\n", " # multiply quantities using list comprehension\n", " q1 = [x * num for x in self.quantities]\n", " # multiply the price\n", " p1 = self.price * num\n", " # return new bundle\n", " return bundle_good(price=p1,quantities=q1)\n", " else:\n", " raise TypeError('Can only multiply bundle by an integer')\n", "\n", " def __truediv__(self,num):\n", " '''Division for bundles: fraction of the original bundle, only if quantities are devisable\n", " '''\n", " if type(num) is int:\n", " # divide quantities and check for divisibility\n", " q1 = [q//num for q in self.quantities]\n", " if not all(q%num==0 for q in self.quantities):\n", " # if can not be devided without a remainder, raise ValueError\n", " raise ValueError('Can not divide bundle into fractional parts')\n", " # divide the price\n", " p1=self.price / num\n", " # return new bundle\n", " return bundle_good(price=p1,quantities=q1)\n", " else:\n", " raise TypeError('Can only divide bundle by an integer')" ] } ], "metadata": { "celltoolbar": "Slideshow", "date": 1612589584.560981, "download_nb": false, "filename": "08_bundles_ex2.rst", "filename_with_path": "08_bundles_ex2", "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.6" }, "title": "Foundations of Computational Economics #8" }, "nbformat": 4, "nbformat_minor": 4 }