{ "cells": [ { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "## Introduction to Scientific Computing\n", "### Lecture 09: Object Oriented Programming and Class - 2\n", "#### J.R. Gladden, Spring 2018, Univ. of Mississippi" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "A **Super Class** is one that defines methods and attributes that can be shared across multiple other classes. It is another method of making your code more modular. Let's see an example of a *Shape()* superclass that incorporates multiple sub-classes such as Circle and Square. The calcVolume method will be common to all sub-classes. Note \"volume\" is computed here by simply extruding the shape into a 3rd dimension by a distance *h*.\n" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [], "source": [ "class Shapes():\n", " def calcVolume(self,h):\n", " area = self.calcArea()\n", " #The next line allows the 'h' value to be accessed by the subclasses\n", " self.h=h\n", " return area*self.h" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Now define ** sub-classes ** that are more specific to the type of shape. These will have methods that are specific to the type of shape: calculating area and the perimeter. Note how the Shapes super-class is now a \"parameter\" in the sub-class definitions. These sub-classes with *inherit* the methods of the super-class." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [], "source": [ "class MySquare(Shapes):\n", " def __init__(self,s=1.0):\n", " self.s = s\n", " \n", " def calcArea(self):\n", " self.area = self.s**2 \n", " return self.area\n", " \n", " def calcPerim(self):\n", " return 4.0*self.s\n", "\n", "class MyCircle(Shapes):\n", " \n", " def __init__(self,r=1.0):\n", " from math import pi\n", " self.pi = pi\n", " self.r = r\n", " \n", " def calcArea(self): \n", " self.area = self.pi*self.r**2\n", " return self.area\n", " \n", " def calcPerim(self):\n", " return 2.0*self.pi*self.r" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [], "source": [ "acircle = MyCircle(r=2.0)\n", "asquare = MySquare(s=1.5)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "12.566370614359172" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "acircle.calcPerim()" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "4.5" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "asquare.calcVolume(2.0)" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "---\n", "### Ball Class\n", "This is a slightly more complicated (and arguably useful) class is presented here. We create a *Ball* class that computes and plots the trajectory of a ball thrown in the air." ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": true }, "outputs": [], "source": [ "%matplotlib wx" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [], "source": [ "class Ball:\n", " \"\"\"\n", " Ball class for a ball thrown in the air. JRG, Feb. 2012\n", " Arguments:\n", " y0: initial height\n", " v0: initial velocity\n", " Methods:\n", " height(t): returns height at time t (t is float or array)\n", " initParams(): returns tuple of initial parameters for a ball\n", " maxHeight(t): returns the maximum height the ball reaches over a time interval t\n", " showPlot(t): plots y(t)\n", " Usage:\n", " ball1=Ball(0.0,12.0)\n", " t=linspace(0,5,100)\n", " ball1.maxHeight(t)\n", " ball1.showPlot(t)\n", " NOTE: best to run in ipython with --pylab flag to show multiple trajectories\n", " \"\"\"\n", " \n", " def __init__(self,y0,v0,balllabel='Ball'):\n", " self.y0 = y0\n", " self.v0 = v0\n", " self.g=-9.81\n", " self.ballLabel=balllabel\n", " import numpy as np\n", " import matplotlib.pyplot as plt\n", " \t\n", " def setLabel(self,label):\n", " \tif type(label).__name__ == 'str': self.ballLabel = label\n", " \t\n", " def getLabel(self):\n", " \treturn self.ballLabel\n", " \t\n", " def height(self,t):\n", " if type(t).__name__ in ('ndarray', 'float', 'int'):\n", " \treturn self.y0 + self.v0*t + 0.5*self.g*t**2\n", " else: \n", " \tprint 'An time array must be supplied to compute the maximum height'\n", " \n", " def initParams(self):\n", " return self.y0,self.v0,self.g\n", " \n", " def maxHeight(self,t):\n", " if type(t).__name__ in ('ndarray', 'float', 'int'): \n", " \treturn max(self.height(t))\n", " else: print 'An time array must be supplied to compute the maximum height'\n", " \n", " def showPlot(self,t):\n", " plt.plot(t,self.height(t),'-',label=self.ballLabel)\n", " plt.xlabel('Time')\n", " plt.ylabel('Height')\n", " plt.legend()\n", " plt.show()\n", " " ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Here's how the ball class can be used. Note multiple balls can be created." ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [], "source": [ "ball1=Ball(0.0,20.0)\n", "ball1.setLabel(\"Ball 1\")\n", "\n", "ball2=Ball(10.0,1.0)\n", "ball2.setLabel(\"Ball 2\")\n", "\n", "from numpy import linspace\n", "t=linspace(0,5,100)\n", "\n", "ball2Yvals = ball2.height(t)\n", "ball1.showPlot(t)\n", "ball2.showPlot(t)" ] }, { "cell_type": "markdown", "metadata": { "collapsed": false, "deletable": true, "editable": true }, "source": [ "---\n", "### Polymorphism\n", "\n", "Finally we return to the Charge class to illustrate **polymorphism** by redefining the \"+\" operator to apply to 2 charge objects and return a new charge object with the sum of the masses and charges. Note this is done with a \"magic\" method: __add__. Similar methods exist to redifine other operators." ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [], "source": [ "class Charge:\n", " def __init__(self):\n", " #Provide some default properties which can be changed later\n", " #Everything in here will be executed when a \"Charge\" instance\n", " #is created.\n", " self.charge = 1.0\n", " self.mass = 1.0\n", " \n", " def __add__(self,q2):\n", " qsum=Charge()\n", " qsum.charge=self.charge + q2.charge\n", " qsum.mass = self.mass + q2.mass\n", " return qsum\n", " \n", " def setCharge(self,value):\n", " self.charge = value\n", " \n", " def getCharge(self):\n", " return self.charge\n", " \n", " def getPolarity(self):\n", " \n", " if self.charge > 0.0: return '+'\n", " elif self.charge == 0.0: return '0'\n", " else: return '-'\n", " \n", " def switchPolarity(self):\n", " self.charge = - self.charge\n", " \n", " def setMass(self,value):\n", " self.mass = value\n", " \n", " def getMass(self):\n", " return self.mass " ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Here's an example of the usage:\n" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [ "4.0" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "q1 = Charge()\n", "q2 = Charge()\n", "q2.setMass(3.0)\n", "q2.setCharge(-5.0)\n", "\n", "# q3 is a new charge object\n", "q3 = q1+q2\n", "\n", "q3.getCharge()\n", "q3.getMass()" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "### Large Collections of objects\n", "Let's say we want to create and manipulate 100 Star objects. We can create lists of instances and loop over those lists to change attributes, compute interactions, ...\n", "\n", "Each instance can be referenced by it's location in the list: " ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "collapsed": true, "deletable": true, "editable": true }, "outputs": [], "source": [ "N=100\n", "stars = [ Star() for i in range(N)] # This creates a list of 100 Stars()\n", "Ms= [ random.randint(100,1000) for i in range(N)] # random masses between 100 and 1000" ] }, { "cell_type": "code", "execution_count": 50, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [ "1000000000.0" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stars[4].getMass()" ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [], "source": [ "for i in range(N):\n", " stars[i].setMass(Ms[i])" ] }, { "cell_type": "code", "execution_count": 52, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [ "753" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stars[4].getMass()" ] }, { "cell_type": "code", "execution_count": 57, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The mass of star 0 is: 578.0 Kg and density 1.380e-16 Kg/M^3\n", "The mass of star 1 is: 968.0 Kg and density 2.311e-16 Kg/M^3\n", "The mass of star 2 is: 220.0 Kg and density 5.252e-17 Kg/M^3\n", "The mass of star 3 is: 457.0 Kg and density 1.091e-16 Kg/M^3\n", "The mass of star 4 is: 753.0 Kg and density 1.798e-16 Kg/M^3\n", "The mass of star 5 is: 217.0 Kg and density 5.180e-17 Kg/M^3\n", "The mass of star 6 is: 241.0 Kg and density 5.753e-17 Kg/M^3\n", "The mass of star 7 is: 971.0 Kg and density 2.318e-16 Kg/M^3\n", "The mass of star 8 is: 638.0 Kg and density 1.523e-16 Kg/M^3\n", "The mass of star 9 is: 141.0 Kg and density 3.366e-17 Kg/M^3\n", "The mass of star 10 is: 512.0 Kg and density 1.222e-16 Kg/M^3\n", "The mass of star 11 is: 577.0 Kg and density 1.377e-16 Kg/M^3\n", "The mass of star 12 is: 618.0 Kg and density 1.475e-16 Kg/M^3\n", "The mass of star 13 is: 997.0 Kg and density 2.380e-16 Kg/M^3\n", "The mass of star 14 is: 566.0 Kg and density 1.351e-16 Kg/M^3\n", "The mass of star 15 is: 383.0 Kg and density 9.143e-17 Kg/M^3\n", "The mass of star 16 is: 462.0 Kg and density 1.103e-16 Kg/M^3\n", "The mass of star 17 is: 801.0 Kg and density 1.912e-16 Kg/M^3\n", "The mass of star 18 is: 459.0 Kg and density 1.096e-16 Kg/M^3\n", "The mass of star 19 is: 355.0 Kg and density 8.475e-17 Kg/M^3\n", "The mass of star 20 is: 657.0 Kg and density 1.568e-16 Kg/M^3\n", "The mass of star 21 is: 826.0 Kg and density 1.972e-16 Kg/M^3\n", "The mass of star 22 is: 346.0 Kg and density 8.260e-17 Kg/M^3\n", "The mass of star 23 is: 150.0 Kg and density 3.581e-17 Kg/M^3\n", "The mass of star 24 is: 353.0 Kg and density 8.427e-17 Kg/M^3\n", "The mass of star 25 is: 982.0 Kg and density 2.344e-16 Kg/M^3\n", "The mass of star 26 is: 962.0 Kg and density 2.297e-16 Kg/M^3\n", "The mass of star 27 is: 617.0 Kg and density 1.473e-16 Kg/M^3\n", "The mass of star 28 is: 550.0 Kg and density 1.313e-16 Kg/M^3\n", "The mass of star 29 is: 940.0 Kg and density 2.244e-16 Kg/M^3\n", "The mass of star 30 is: 697.0 Kg and density 1.664e-16 Kg/M^3\n", "The mass of star 31 is: 360.0 Kg and density 8.594e-17 Kg/M^3\n", "The mass of star 32 is: 354.0 Kg and density 8.451e-17 Kg/M^3\n", "The mass of star 33 is: 837.0 Kg and density 1.998e-16 Kg/M^3\n", "The mass of star 34 is: 392.0 Kg and density 9.358e-17 Kg/M^3\n", "The mass of star 35 is: 642.0 Kg and density 1.533e-16 Kg/M^3\n", "The mass of star 36 is: 189.0 Kg and density 4.512e-17 Kg/M^3\n", "The mass of star 37 is: 973.0 Kg and density 2.323e-16 Kg/M^3\n", "The mass of star 38 is: 597.0 Kg and density 1.425e-16 Kg/M^3\n", "The mass of star 39 is: 435.0 Kg and density 1.038e-16 Kg/M^3\n", "The mass of star 40 is: 166.0 Kg and density 3.963e-17 Kg/M^3\n", "The mass of star 41 is: 429.0 Kg and density 1.024e-16 Kg/M^3\n", "The mass of star 42 is: 723.0 Kg and density 1.726e-16 Kg/M^3\n", "The mass of star 43 is: 120.0 Kg and density 2.865e-17 Kg/M^3\n", "The mass of star 44 is: 620.0 Kg and density 1.480e-16 Kg/M^3\n", "The mass of star 45 is: 779.0 Kg and density 1.860e-16 Kg/M^3\n", "The mass of star 46 is: 664.0 Kg and density 1.585e-16 Kg/M^3\n", "The mass of star 47 is: 879.0 Kg and density 2.098e-16 Kg/M^3\n", "The mass of star 48 is: 774.0 Kg and density 1.848e-16 Kg/M^3\n", "The mass of star 49 is: 735.0 Kg and density 1.755e-16 Kg/M^3\n", "The mass of star 50 is: 207.0 Kg and density 4.942e-17 Kg/M^3\n", "The mass of star 51 is: 732.0 Kg and density 1.748e-16 Kg/M^3\n", "The mass of star 52 is: 351.0 Kg and density 8.380e-17 Kg/M^3\n", "The mass of star 53 is: 580.0 Kg and density 1.385e-16 Kg/M^3\n", "The mass of star 54 is: 335.0 Kg and density 7.998e-17 Kg/M^3\n", "The mass of star 55 is: 612.0 Kg and density 1.461e-16 Kg/M^3\n", "The mass of star 56 is: 913.0 Kg and density 2.180e-16 Kg/M^3\n", "The mass of star 57 is: 939.0 Kg and density 2.242e-16 Kg/M^3\n", "The mass of star 58 is: 527.0 Kg and density 1.258e-16 Kg/M^3\n", "The mass of star 59 is: 417.0 Kg and density 9.955e-17 Kg/M^3\n", "The mass of star 60 is: 306.0 Kg and density 7.305e-17 Kg/M^3\n", "The mass of star 61 is: 385.0 Kg and density 9.191e-17 Kg/M^3\n", "The mass of star 62 is: 441.0 Kg and density 1.053e-16 Kg/M^3\n", "The mass of star 63 is: 518.0 Kg and density 1.237e-16 Kg/M^3\n", "The mass of star 64 is: 513.0 Kg and density 1.225e-16 Kg/M^3\n", "The mass of star 65 is: 607.0 Kg and density 1.449e-16 Kg/M^3\n", "The mass of star 66 is: 157.0 Kg and density 3.748e-17 Kg/M^3\n", "The mass of star 67 is: 945.0 Kg and density 2.256e-16 Kg/M^3\n", "The mass of star 68 is: 473.0 Kg and density 1.129e-16 Kg/M^3\n", "The mass of star 69 is: 615.0 Kg and density 1.468e-16 Kg/M^3\n", "The mass of star 70 is: 550.0 Kg and density 1.313e-16 Kg/M^3\n", "The mass of star 71 is: 145.0 Kg and density 3.462e-17 Kg/M^3\n", "The mass of star 72 is: 438.0 Kg and density 1.046e-16 Kg/M^3\n", "The mass of star 73 is: 809.0 Kg and density 1.931e-16 Kg/M^3\n", "The mass of star 74 is: 736.0 Kg and density 1.757e-16 Kg/M^3\n", "The mass of star 75 is: 568.0 Kg and density 1.356e-16 Kg/M^3\n", "The mass of star 76 is: 143.0 Kg and density 3.414e-17 Kg/M^3\n", "The mass of star 77 is: 328.0 Kg and density 7.830e-17 Kg/M^3\n", "The mass of star 78 is: 898.0 Kg and density 2.144e-16 Kg/M^3\n", "The mass of star 79 is: 564.0 Kg and density 1.346e-16 Kg/M^3\n", "The mass of star 80 is: 605.0 Kg and density 1.444e-16 Kg/M^3\n", "The mass of star 81 is: 877.0 Kg and density 2.094e-16 Kg/M^3\n", "The mass of star 82 is: 237.0 Kg and density 5.658e-17 Kg/M^3\n", "The mass of star 83 is: 399.0 Kg and density 9.525e-17 Kg/M^3\n", "The mass of star 84 is: 500.0 Kg and density 1.194e-16 Kg/M^3\n", "The mass of star 85 is: 521.0 Kg and density 1.244e-16 Kg/M^3\n", "The mass of star 86 is: 702.0 Kg and density 1.676e-16 Kg/M^3\n", "The mass of star 87 is: 569.0 Kg and density 1.358e-16 Kg/M^3\n", "The mass of star 88 is: 216.0 Kg and density 5.157e-17 Kg/M^3\n", "The mass of star 89 is: 776.0 Kg and density 1.853e-16 Kg/M^3\n", "The mass of star 90 is: 966.0 Kg and density 2.306e-16 Kg/M^3\n", "The mass of star 91 is: 137.0 Kg and density 3.271e-17 Kg/M^3\n", "The mass of star 92 is: 361.0 Kg and density 8.618e-17 Kg/M^3\n", "The mass of star 93 is: 205.0 Kg and density 4.894e-17 Kg/M^3\n", "The mass of star 94 is: 989.0 Kg and density 2.361e-16 Kg/M^3\n", "The mass of star 95 is: 876.0 Kg and density 2.091e-16 Kg/M^3\n", "The mass of star 96 is: 999.0 Kg and density 2.385e-16 Kg/M^3\n", "The mass of star 97 is: 421.0 Kg and density 1.005e-16 Kg/M^3\n", "The mass of star 98 is: 774.0 Kg and density 1.848e-16 Kg/M^3\n", "The mass of star 99 is: 371.0 Kg and density 8.857e-17 Kg/M^3\n" ] } ], "source": [ "# List all the masses for each star\n", "for i in range(N):\n", " mass = stars[i].getMass()\n", " rho = stars[i].calcDensity()\n", " print(\"The mass of star %3i is: %2.1f Kg and density %2.3e Kg/M^3\"%(i,mass,rho))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true, "deletable": true, "editable": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.13" } }, "nbformat": 4, "nbformat_minor": 0 }