There are a number of ways to run Python interactively. For the sake of consistency of all the student's environments, and for the numerous features availalble, we are only going to use the IPython Notebook environment.
Introductory help on the IPython Notebook may be found at http://ipython.org/ipython-doc/dev/interactive/htmlnotebook.html.
When you start it this way, it will create a new tab in your browser. All subsequent interactions are through your browser (unless you use Control-C within the terminal window used to start the IPython Notebook. Leave your terminal window alone otherwise; it is running a server that the browser interacts with.
The ipython notebook looks for notebook files in the directory you started the ipython notebook in. It assumes any file with a .ipynb extension is a notebook file. This tutorial is such a file named Session1_Introduction.ipynb.
What follows will highlight various capabilities with simple examples of use before we embark on scientific examples.
print "Hello, STSCI!"
Hello, STSCI!
print "Hello earthlings"
print "Take me to your leader"
Hello earthlings Take me to your leader
Code cells are editable. If you make a mistake, just put the cursor in the cell and edit it. When you are done making changes, just re-execute. Rather than a long history of failed attempts as you would get in traditional logging of an interactive session, you just keep changing one thing until you get it right
print 'Hubbel rocks!'
Hubbel rocks!
Note the menus and toolbar at the top of the browser page. These allow quite a few actions to be performed. This tutorial won't go in to exhaustive detail on each choice, but will highlight some key features. You can always explore the choices on your own, and there is a help menu item for the ipython notebook and other Python tools. If you hover on toolbar widgets, a tooltip will appear. Finally, many of these have keyboard shortcuts; you can see these under the help menu (most of the keyboard shortcuts are two character combinations starting with
Click on the text to the right of "Notebook" at the top of the screen to rename your Notebook to something more informative.
An IPython Notebook is a document much like any other. If you don't save your changes can be lost. To save your notebook just select "save" from the "File" dropdown at the top of the browser window or click the disk icon. The file will appear in the directory where you ran ipython notebook
with the title as the name of the file and .ipynb as its extension.
In the "Edit" menu and in the toolbar are options for editing actions like delete, copy, cut, paste, merge, split, etc.
IPython will automatically insert new cells at the end of the Notebook. In the menus and toolbars are buttons for inserting cells above and below the cursor.
Notebook cells can be switched between different input types, including cells expecting Markdown (like this cell), cells expecting Python code, and cells that take raw text and do nothing to it. Cells can be converted between these types using the "Cell" menu or the toolbar dropdown.
There are keyboard shortcuts for most of the actions described above. To see all of the available shortcuts click the "Keyboard Shortcuts" item in the "Help" menu (or type <ctrl>-m-h
).
An Notebook can be executed linearly from top to bottom by selecting "Run All" from the "Cell" menu. This can be useful when resuming work in an existing Notebook.
You can put nicely rendered equations into Markdown cells. Use $...$
for inline equations and $$...$$
for block equations.
For example, $E = mc^2$
is rendered as $E = mc^2$. $$f(x) = \int_0^x sin(\theta) d{\theta}$$
is rendered as:
ls
README.rst Session1_Introduction.ipynb Session1_Astro_Demo.ipynb Session2_Basics.ipynb
cd Music
[Errno 2] No such file or directory: 'Music' /Users/mrdavis/projects/scientific-python-training-2012/lecture_notebooks
cd dropbox/ScientificPythonCourse
[Errno 2] No such file or directory: 'dropbox/ScientificPythonCourse' /Users/mrdavis/projects/scientific-python-training-2012/lecture_notebooks
pwd
u'/Users/mrdavis/projects/scientific-python-training-2012/lecture_notebooks'
You can run generic shell commands by prefacing a code line with '!
'.
!echo "IPython"
IPython
You can even capture the output of these:
files = !ls
print files
['README.rst', 'Session1_Astro_Demo.ipynb', 'Session1_Introduction.ipynb', 'Session2_Basics.ipynb']
IPython has a number of help features including tab completion and inline documentation viewing. For example, type r
and then <tab>
in a code cell to see a list of existing names that begin with r
. (This will include variables you've defined as well as built-in or imported names.)
Type the name of a function, for example range
and then open parentheses to and press <tab>
again. A floating window will pop up useful information about the range
function.
r
range(
You can also access help using IPython's '?
' feature:
range?
Click the dividing bar on the frame that pops up to collapse the frame.
%pylab inline
Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.zmq.pylab.backend_inline]. For more information, type 'help(pylab)'.
import pyfits
data = pyfits.getdata('../data/pix.fits')
pylab.imshow(data,vmax=500)
<matplotlib.image.AxesImage at 0x106821290>
import numpy as np
data[data <= 1] = 1
ldata = np.log(data)
pylab.imshow(ldata)
pylab.gray()
hdr = pyfits.getheader('../data/pix.fits')
hdr
SIMPLE = T / Fits standard BITPIX = 16 / Bits per pixel NAXIS = 2 / Number of axes NAXIS1 = 512 / Axis length NAXIS2 = 512 / Axis length EXTEND = F / File may contain extensions ORIGIN = 'NOAO-IRAF FITS Image Kernel July 2003' / FITS file originator DATE = '2004-07-20T20:35:38' / Date FITS file was generated IRAF-TLM= '17:35:38 (20/07/2004)' / Time of last modification OBJECT = 'm51 B 600s' / Name of the object observed IRAF-MAX= 1.993600E4 / DATA MAX IRAF-MIN= -1.000000E0 / DATA MIN CCDPICNO= 53 / ORIGINAL CCD PICTURE NUMBER ITIME = 600 / REQUESTED INTEGRATION TIME (SECS) TTIME = 600 / TOTAL ELAPSED TIME (SECS) OTIME = 600 / ACTUAL INTEGRATION TIME (SECS) DATA-TYP= 'OBJECT (0)' / OBJECT,DARK,BIAS,ETC. DATE-OBS= '05/04/87' / DATE DD/MM/YY RA = '13:29:24.00' / RIGHT ASCENSION DEC = '47:15:34.00' / DECLINATION EPOCH = 0.00 / EPOCH OF RA AND DEC ZD = '22:14:00.00' / ZENITH DISTANCE UT = ' 9:27:27.00' / UNIVERSAL TIME ST = '14:53:42.00' / SIDEREAL TIME CAM-ID = 1 / CAMERA HEAD ID CAM-TEMP= -106.22 / CAMERA TEMPERATURE, DEG C DEW-TEMP= -180.95 / DEWAR TEMPRATURE, DEG C F1POS = 2 / FILTER BOLT I POSITION F2POS = 0 / FILTER BOLT II POSITION TVFILT = 0 / TV FILTER CMP-LAMP= 0 / COMPARISON LAMP TILT-POS= 0 / TILT POSITION BIAS-PIX= 0 / BI-FLAG = 0 / BIAS SUBTRACT FLAG BP-FLAG = 0 / BAD PIXEL FLAG CR-FLAG = 0 / BAD PIXEL FLAG DK-FLAG = 0 / DARK SUBTRACT FLAG FR-FLAG = 0 / FRINGE FLAG FR-SCALE= 0.00 / FRINGE SCALING PARAMETER TRIM = 'Apr 22 14:11 Trim image section is [3:510,3:510]' BT-FLAG = 'Apr 22 14:11 Overscan correction strip is [515:544,3:510]' FF-FLAG = 'Apr 22 14:11 Flat field image is Flat1.imh with scale=183.9447' CCDPROC = 'Apr 22 14:11 CCD processing done' AIRMASS = 1.08015632629395 / AIRMASS HISTORY 'KPNO-IRAF' HISTORY '24-04-87' HISTORY 'KPNO-IRAF' / HISTORY '08-04-92' /
hdr['object']
'm51 B 600s'
pylab.plot(data[256])
pylab.plot(data[246])
[<matplotlib.lines.Line2D at 0x106851e10>]
Many, if not most, Python libraries deal in objects. Developing object oriented code is beyond the scope of this course, particularly given the focus of the course, but a few words are needed about how to use objects. It's not very hard, and most quickly get the hang of it.
Think of objects as a set of data and attributes that describe something. In this way they are much like C structures. An object can have a bunch of properties that describe it in detail, and some of these properties may be other kinds of objects (they can even be turtles all the way down). These properties are standardly called "attributes" and they are accessed by appending .<attribute_name>
to the object. To take an example, arrays are such objects, such as was returned by pyfits.
print 'shape:', data.shape
print 'size:', data.size
print 'nbytes:', data.nbytes
print 'dtype:', data.dtype
shape: (512, 512) size: 262144 nbytes: 524288 dtype: >i2
The dtype attribute is itself a complex object that has a name attribute
data.dtype.name
'int16'
So, objects can carry multiple bits of named data around. Objects can also carry their own functions with them. These functions have access to all the attributes attached to the object. Functions attached to an object are called "methods". Most objects have a standard set of things you can do with them. Methods are accessed just like attributes, except you use them like functions, i.e., you can give them arguments (though they don't always require any). Sticking with arrays:
data.sum()
28394236
data.sum(axis=1)
array([ 27681, 27913, 28150, 27963, 28152, 28254, 28191, 28120, 28302, 28404, 28521, 28563, 28766, 28937, 29011, 28929, 29222, 29633, 29655, 29809, 30121, 30246, 30487, 30663, 31002, 31479, 31885, 32187, 32487, 32831, 33301, 34232, 34825, 34435, 34158, 34127, 34280, 34399, 34720, 35141, 35663, 36344, 36676, 36831, 37111, 37359, 37590, 38035, 38595, 38890, 39031, 39292, 39654, 39829, 40063, 40236, 40290, 40756, 41265, 42336, 45712, 49010, 47794, 45328, 46463, 51643, 54405, 49559, 44751, 43286, 42736, 42269, 42019, 42073, 42073, 42545, 42502, 41883, 42382, 42340, 42335, 42583, 42893, 43113, 43087, 42961, 43399, 43690, 43870, 44362, 44923, 45443, 45923, 46035, 46737, 47270, 48065, 48699, 49128, 49500, 49971, 49952, 49241, 50261, 49935, 50248, 50668, 51701, 52726, 34947, 53060, 52955, 51924, 51548, 51433, 50980, 50891, 50930, 51194, 51033, 51101, 51521, 52186, 53708, 55735, 56617, 55529, 53970, 53580, 56364, 59592, 57349, 53818, 52638, 51897, 51329, 50784, 50386, 50110, 50093, 50867, 51441, 51706, 52144, 52509, 52563, 52732, 52930, 53018, 53270, 53618, 53887, 54130, 54375, 54679, 55680, 57232, 57372, 55922, 54650, 54298, 54660, 55185, 55301, 55250, 55754, 56552, 57137, 57766, 58826, 60436, 62218, 63698, 64764, 65488, 65934, 66349, 67362, 68720, 69289, 68231, 67000, 65412, 64809, 65944, 69494, 81313, 108129, 121173, 91719, 69963, 64237, 62918, 62735, 62517, 62310, 61895, 61691, 61446, 61563, 61187, 61690, 62183, 62857, 63513, 64290, 64919, 65174, 65003, 64619, 64332, 64044, 63652, 63206, 63411, 63824, 64837, 66011, 67401, 68721, 69217, 69861, 70520, 71151, 73223, 75178, 74951, 74552, 75607, 77173, 79926, 80806, 79107, 78393, 79797, 81487, 83119, 85198, 87629, 89907, 91627, 93310, 94576, 95711, 96857, 98086, 99414, 100612, 101656, 103226, 106495, 110086, 112636, 114786, 117356, 121027, 126775, 134085, 137502, 132594, 124318, 118643, 115461, 113562, 112255, 109878, 106760, 104664, 102846, 100574, 98904, 99661, 104563, 109923, 106648, 97962, 92355, 88825, 86082, 83550, 81805, 80777, 80342, 80644, 81020, 80313, 78249, 75937, 74203, 73775, 72839, 71080, 69998, 69220, 68181, 67612, 67456, 67906, 66872, 67285, 66283, 65545, 64332, 63786, 63655, 63800, 63586, 63618, 63134, 62882, 62858, 63245, 63448, 63334, 63685, 64349, 64780, 61399, 64052, 63166, 62937, 62869, 62521, 62509, 62779, 63193, 63435, 62523, 61252, 60356, 59921, 59629, 59083, 58548, 58651, 59391, 60512, 61381, 62106, 62710, 62674, 61650, 60915, 60587, 60336, 59983, 59779, 59578, 59195, 58953, 58828, 58690, 58794, 59073, 59471, 59863, 59695, 58864, 58164, 57755, 57524, 57555, 57321, 56628, 56138, 55468, 54320, 53844, 53680, 53175, 52979, 52906, 52759, 52575, 52565, 52274, 51950, 51837, 52082, 52510, 52592, 52817, 53012, 52897, 52602, 52273, 52257, 52594, 53087, 53957, 54603, 54331, 53957, 53730, 53864, 54408, 54964, 55917, 56975, 56738, 56424, 56280, 56433, 56228, 56708, 57457, 58169, 60012, 64260, 65278, 59910, 56320, 54712, 53596, 52281, 52264, 50831, 49802, 49052, 49318, 49743, 49357, 48871, 48425, 48721, 48647, 48357, 47907, 47464, 46949, 46821, 47254, 48116, 49403, 49414, 47918, 46749, 46355, 46266, 45138, 43942, 43385, 42957, 42661, 42964, 42435, 40628, 39093, 38538, 37769, 36533, 35351, 34579, 33951, 33388, 33178, 33182, 33097, 33240, 33584, 33591, 33046, 32525, 32277, 31979, 31669, 31383, 31009, 30779, 30543, 30231, 30244, 30147, 30057, 29865, 29484, 29482, 29267, 29172, 28996, 29051, 29013, 28620, 28590, 28392, 28339, 28323, 28274, 28313, 28199, 28159, 27865, 28065, 28048, 27930, 28005, 28015, 27834, 27769, 27975, 27892, 27959, 28116, 28349, 28875, 29642, 29491, 28872, 28568, 28479, 28541, 28533])
In the last example, we told the array to sum itself only over one dimension
data.max()
19936
data.max(axis=0)
array([ 57, 59, 57, 59, 58, 60, 61, 79, 62, 65, 267, 68, 68, 67, 69, 72, 100, 99, 78, 76, 92, 79, 80, 82, 85, 88, 89, 88, 90, 93, 97, 107, 215, 179, 227, 345, 302, 147, 117, 115, 113, 119, 124, 122, 291, 252, 272, 293, 261, 242, 225, 188, 155, 149, 141, 127, 197, 700, 1256, 1032, 460, 184, 185, 210, 251, 220, 278, 331, 451, 507, 330, 172, 161, 183, 221, 214, 176, 183, 183, 188, 226, 219, 197, 197, 207, 302, 255, 231, 222, 225, 259, 323, 425, 441, 372, 317, 288, 286, 275, 240, 263, 300, 272, 236, 215, 200, 187, 179, 247, 420, 365, 252, 195, 185, 189, 250, 370, 412, 814, 268, 236, 204, 218, 234, 263, 338, 345, 383, 409, 527, 749, 680, 438, 526, 514, 500, 437, 382, 360, 337, 345, 521, 542, 466, 483, 638, 649, 544, 476, 397, 430, 425, 419, 378, 353, 321, 335, 376, 391, 367, 586, 1064, 1122, 725, 377, 291, 285, 284, 298, 317, 319, 318, 352, 384, 461, 537, 469, 376, 388, 412, 386, 344, 338, 330, 327, 308, 294, 284, 303, 326, 326, 344, 362, 387, 406, 430, 411, 371, 320, 286, 287, 280, 284, 308, 287, 273, 506, 574, 416, 507, 584, 803, 1037, 730, 663, 563, 572, 1199, 1332, 975, 642, 492, 1382, 3047, 2402, 1068, 557, 486, 436, 482, 996, 1305, 1168, 856, 745, 733, 795, 750, 764, 788, 827, 913, 977, 896, 866, 930, 1064, 1132, 1114, 1146, 1239, 1452, 1683, 1917, 2430, 3981, 6687, 7734, 5852, 3545, 2338, 1819, 1535, 1350, 1243, 1263, 1219, 1118, 1083, 1036, 1059, 1093, 1118, 1027, 1063, 1050, 1005, 923, 851, 754, 667, 584, 570, 580, 597, 518, 427, 395, 364, 394, 444, 494, 571, 551, 524, 486, 435, 435, 361, 340, 338, 345, 310, 260, 230, 234, 229, 255, 245, 203, 199, 190, 197, 201, 204, 205, 227, 221, 357, 585, 389, 332, 302, 342, 383, 390, 395, 438, 459, 397, 283, 278, 295, 345, 397, 477, 470, 429, 548, 477, 312, 247, 273, 474, 1272, 6943, 19530, 19936, 9597, 2758, 717, 337, 253, 235, 237, 242, 255, 238, 214, 277, 469, 876, 1413, 1391, 913, 648, 589, 548, 497, 463, 549, 832, 1103, 1030, 652, 353, 605, 2300, 4026, 2853, 1052, 421, 502, 508, 549, 602, 580, 528, 425, 330, 266, 233, 232, 213, 198, 216, 232, 311, 240, 214, 232, 396, 1375, 3575, 3534, 1691, 575, 213, 168, 159, 157, 153, 153, 262, 477, 366, 213, 204, 277, 229, 158, 146, 146, 170, 202, 226, 182, 182, 165, 195, 263, 226, 155, 143, 136, 139, 160, 157, 164, 529, 2223, 3164, 1975, 706, 214, 158, 153, 157, 212, 254, 213, 156, 140, 128, 114, 110, 109, 107, 111, 115, 113, 115, 220, 956, 2195, 2172, 1000, 325, 168, 188, 154, 134, 129, 110, 163, 214, 191, 136, 107, 119, 107, 105, 115, 120, 128, 111, 100, 115, 134, 119, 100, 90, 88, 92, 109, 161, 190, 134, 99, 83, 76, 77, 153, 72, 87, 277, 877, 1001, 476, 174, 98, 76], dtype=int16)
As we will see, objects can have quite a lot of data and functionality attached to them.
The easiest way to learn what attributes and methods an object has is to use IPython's tab completion:
data.
To get information on a specific method use the same IPython help features we've already seen: data.mean?
or data.mean(
data.mean?
data.mean(
There is no metadata attached to attributes so to get more information on those it's best to check the general docstrings for an object:
data?
There are also help features built into Python, but the IPython ones are usually more convenient:
help(data)
dir(data)
Besides these tools, often the most powerful thing is to play with the object and see what happens when you try different things. You can learn quite a bit by playing. Many people fail to realize the power of the interactive command line to understand what is going on. This point will be reiterated throughout the course.
When Python encounters an error that isn't handled by the code, it will generate a traceback. The appearance of these tracebacks can be lengthy and quite offputting to the uninitiated. Do not panic! Often there is useful information in these tracebacks, usually in the last couple of lines. They show the state of the calls from one function (or method) to another (i.e., where are we in the sequence of functions calling others until the error occured.) The last line actually states the proximate cause of the error. Sometimes that is directly related to the error you made, sometimes it is indirect and not as helpful.
data + "hello there"
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-24-171801ac5b28> in <module>() ----> 1 data + "hello there" TypeError: unsupported operand type(s) for +: 'numpy.ndarray' and 'str'
In this case, the problem is that numeric arrays do not know how to be added to strings. The two "operands" are of incompatible types and thus there is a "TypeError"