{ "cells": [ { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "## Lecture 3: Loops, Functions, and I/O\n", "### J.R. Gladden, Univ. of Mississippi, Spring 2018" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "This lecture material will focus on the use of **functions** in python. Functions are a way to:\n", "* Make your code more modular\n", "* Make you programming more efficient. Need to repeatedly accomplish a task in your program? Write and function and repeatedly call it\n", "* A first step to creating your own libraries to import - it's not very hard!!\n", "\n", "**Defining a function**: Define with any arguments (input) needed by the function. Always have a colon (:) to set of the block of code that will run when the function is called. Note this function didn't really need to return anything to the main program, but good practice to always return something. \"1\" is common to indicate everything went smoothly." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true, "deletable": true, "editable": true }, "outputs": [], "source": [ "def myFunction(arg1,arg2):\n", " print(\"This is a silly function that prints arguments\")\n", " print(\"Argument 1: %s\" % arg1)\n", " print(\"Argument 2: %s\" % arg2)\n", " print(\"My work is done - exiting the function...\")\n", " return 1" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Now, call the function to make use of it:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "This is a silly function that prints arguments\n", "Argument 1: Billy\n", "Argument 2: Sally\n", "My work is done - exiting the function...\n" ] }, { "data": { "text/plain": [ "1" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "myFunction(\"Billy\", \"Sally\")" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Can also define a function to take an arbitrary number of arguments. Preceed the variable with a *" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": true, "deletable": true, "editable": true }, "outputs": [], "source": [ "def sumnums(*nums):\n", " sum=0\n", " for num in nums:\n", " sum+=num\n", " return sum" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [ "115" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sumnums(1,2,3,4,5,6,23,45,26)" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "You can also call one function from within another function. This allows functions to get very specific and modular. Good rule of thumb is a function shouldn't generally be longer than 10-15 lines of code. This example uses sumnums defined above to compute an average. Note here I included a \"docstring\", offset by triple quotes, which contains documentation returned to the user via help(functname) or functname? ." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": true, "deletable": true, "editable": true }, "outputs": [], "source": [ "def myavg(*nums):\n", " '''\n", "\tFunction to average a sequence of numbers.\n", "\tUsage: testavg = avg(70,80,75,99,98)\n", "\tInput: arbitrary length series of integers or floats\n", "\tOutput: a float equal to the average\n", "\tHistory: version 0.1, last updated Jan. 23, 2012 by JRG\n", " '''\n", " #pass the sequence *nums just as it is, otherwise it sends a tuple object to sumnums\n", " sum=float(sumnums(*nums)) #convert to float to avoid division problems\n", " return sum/len(nums)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [ "7.166666666666667" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "myavg?\n", "myavg(4,5,2,7,15,10)" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "Here is a bit more complicated function that computes the standard deviation of a set of numbers. It uses the smaller functions we've already defined above. Mathematically defined as $$ \\sigma = \\sqrt{ \\frac{ \\sum_i^N (x_i - \\bar{x})^2}{N}} $$\n", "Note we make in **import** call within the function. Also note we only call __myavg__ once and store the result in memory rather than call it a bunch of times in the loop!" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": true, "deletable": true, "editable": true }, "outputs": [], "source": [ "def stddev(*nums):\n", " '''\n", " sigma=stddev(sequence)\n", " returns the standard deviation of the sequence of numbers\n", " '''\n", " from math import sqrt\n", " N=len(nums)\n", " avgnum=myavg(*nums)\n", " sum=0.\n", " for num in nums:\n", " sum+=(num-avgnum)**2\n", " return sqrt(sum/N) " ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "data": { "text/plain": [ "1.5491933384829668" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stddev(1,5,1,1,2)" ] }, { "cell_type": "markdown", "metadata": { "deletable": true, "editable": true }, "source": [ "**Random Module**: Many scientific algorithms require a random number. The _random_ module provides a number of functions to generate a variety of random numbers." ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false, "deletable": true, "editable": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.0727895660584\n", "13.1557094832\n", "51.2367135254\n" ] } ], "source": [ "import random as r\n", "print(r.random())\n", "print(r.uniform(10,20))\n", "print(r.gauss(50,10))" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true, "deletable": true, "editable": true }, "source": [ "## File Input and Output\n", "Often we need to save computed data to a file or read it from the computer for analysis. What I show here is the \"standard\" Python way to do this that will always work. For numerical data, we have a more efficient way to read and write files using Numpy arrays - which we'll handle later.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### File output\n", "The file will be saved in the current working directory. Unless it's been changed, that's the directory the program is being run in. After running this code, you should see a new file called \"test.txt\". Note the same syntax for formatted printing to the screen can be used with file output." ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false }, "outputs": [], "source": [ "outfile=open('test.txt','w') # ‘w’ to write, ‘r’ to read\n", "outfile.write('First line \\nsecond line \\t %1.2f \\n' % (25.4) )\n", "outfile.write('='*30) #prints 30 ‘=‘ characters\n", "x=[1,2,3,4,5]\n", "y=[1,4,9,16,25]\n", "for xi,yi in zip(x,y):\n", "\toutfile.write(' \\n %2.2f \\t %2.2f' % (xi,yi))\n", "outfile.close()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### File Input\n", "We can also read data into the program from a saved text file (ASCII text file only). By default, it expects to find the file in the current working directory and will throw an error if it isn't. You can generate your own \"data.dat\" file or download it from the course website." ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": true }, "outputs": [], "source": [ "infile=open('data.dat','r')\n", "lines = infile.readlines() # returns a list of each line in file\n", "infile.close() # It's important to close the file!\n", "x=[] # Set up some empty lists to put the numbers in\n", "y=[]\n", "for line in lines:\n", "\tif line[0] == '#': continue #Comments - skip this line and move on to the next\n", "\tx.append( float( line.split()[0]))\n", "\ty.append( float( line.split()[1]))\n" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'2.004008016032064049e-02 1.564674931511246814e-01\\n'" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lines[3]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": 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 }