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