Python Intro¶
Preliminaries¶
What is Python?¶
Python is a high-level, interpreted programming language, which in recent years has become the leading tool for analysis and visualization of Astronomical data sets.
What is Anaconda?¶
Anaconda is a free-to-use software bundle that includes Python, Jupyter (a web-based interface to Python), plus many supporting packages. It is produced by Anaconda, Inc.
What is Jupyter?¶
Jupyter allows Python to be run from within a web-browser, via interactive documents known as notebooks. A notebook is built from a number of discrete fragments called cells; each cell may contain either textual narrative or Python code.
A First Notebook¶
Creating a Folder¶
Your first step is to create a new folder, named astro_310
,
where you will store all of your class-related work. After installing
Anaconda and firing up Jupyter in your web-browser, follow these
steps:
Selecting Folder from the Other section of the New drop-down menu (on the right in the Jupyter window).
Scroll down to the new folder in the file list (it will be named
Untitled Folder
).Click on the check mark to the left of the new folder to select it.
Click on the Rename button at the top of the file list.
Type the name for the folder,
astro_310
, into the pop-up window, and click the Rename button.Finally, click on the
astro_310
folder to open it (it will be initially empty).
Creating a Notebook¶
The next step is to create a new notebook. Selecting Python 3 from
the Notebook section of the New drop-down menu. Then, click on the
title of the notebook and rename it from Untitled
to
python_intro
.
You’re going to use this notebook to explore Python’s basic functionality. A few points to bear in mind about notebooks:
To select a cell, click anywhere inside it.
To execute the currently-selected cell (i.e., pass its contents to Python for interpretation), press Shift+Enter (or Shift+Return) on your keyboard, or click the ▶ Run icon at the top of the notebook.
To execute all cells in the notebook, select Cell→Run All from the menu at the top.
To insert a new cell below the currently-selected cell, click the ➕ icon at the top.
To delete the currently-selected cell, click the ✂ icon at the top.
To interrupt the execution of a cell, click the ⬛ icon at the top.
By default, newly created cells are interpreted as code. However, you can change them to text cells by clicking the Code drop-down menu at the top and selecting Markdown.
A further, important point to bear in mind about Python in general, is that indentation and capitalization are significant — if you get them wrong, then Python will complain!
Importing Modules¶
Modules are add-ons that extend Python’s basic functionality. To use them we need to import them. Cut and paste the following code into the first cell of your notebook:
# Lines like this, beginning with '#', are comments that are ignored
# by Python. It's a good idea to comment your code to make it clear
# what's going on
# Import the numpy module to provide numerical functionality
import numpy as np
# Import the matplotlib.pyplot module to provide plotting functionality
import matplotlib.pyplot as plt
# Tell matplotlib.pyplot to do inline plots
%matplotlib inline
Then, execute the cell (Shift+Enter or Shift+Return).
Variables¶
Variables are named locations where data can be stored. A variable has both a type (integer, float, list, etc.) and a value. In Python, types are ‘dynamic’ — they can change during program execution. This can be convenient, but it can also be a pitfall if you’re not aware. A variable name must start with a letter, it can’t contain any illegal symbols or spaces, and it can’t be one of the few words Python reserves. In a Jupyter notebook, when you type a word that Python reserves, it will change color.
Create a new cell in your notebook, and execute this code in it:
# Create an integer variable
x = 5
# Print it out and then print its type. print() is a built-in
# Python functions that prints out a value; type() is another
# built-in function that returns the type of a variable
print(x)
print(type(x))
# Create a float variable (for representing real numbers). Note the
# decimal point!
x = 5.
print(x)
print(type(x))
Numerical Operations¶
Numerical variables (integers, floats and complex numbers) support the four standard arithmetic operations (+, -, * and /) together with more-sophisticated functions. Try out the following code, executing each block in a separate cell:
# Addition with integers and floats (math on mixed types will
# convert integers to float)
myInteger = 2
myFloat = 2.
print(myInteger + 3)
print(myInteger + 3.)
print(myFloat + 3)
print(myFloat + 3.)
# Multiplication and division with integers and floats
print(myInteger*6)
print(myInteger/6) # Converts myInteger to float
print(myInteger//6) # Doesn't convert myInteger to float
print(myFloat*6)
print(myFloat/6)
# Some other math operators and functions
print(myFloat**2) # The ** operator raises to a power
print(np.exp(myFloat)) # Exponentiation (provided by numpy module)
print(np.log(myFloat)) # Natural logarithm (provided by numpy module)
print(np.log10(myFloat)) # Base-10 logarithm (provided by numpy module)
print(np.sin(myFloat)) # Sine (provided by numpy module)
print(np.sqrt(myFloat)) # Square root (provided by numpy module)
print(np.sqrt(-myFloat)) # This should produce a 'nan' (Not-a-Number)
# Create a complex variable
myComplex = complex(-1.,2.) # The complex() function returns a complex number
myComplex = -1. + 2.*1j # Same effect as previous command
print(myComplex)
print(type(myComplex))
print(np.sqrt(myComplex)) # The sqrt() function works as it should with complex numbers
Strings¶
Variables can store more than just numerical data. For instance, variables with the string type contain sequences of characters:
# Create a string
myString = 'This is my string' # Note quotes ''
print(myString)
print(type(myString))
print(len(myString)) # The len() function returns the length of a string
Strings support indexing operations using square brackets []
,
allowing individual characters of a string to be accessed by their
integer index. Indices start at 0
and run through to L-1
,
where L
is the length of the string:
# String indexing
print(myString[0]) # Print the first character (index 0)
print(myString[1]) # Print the second character (index 1)
L = len(myString)
print(myString[L-1]) # Print the last character
print(myString[-1]) # Easier way to print the last character
print(myString[-2]) # Print the second-to-last character
Square brackets can also be used to for slicing operations, where we access a sequence of characters within a string (known as a substring):
# String slicing
print(myString[5:10]) # Print characters with indices from 5 (inclusive) to 10 (exclusive)
print(myString[:10]) # Print charcters from the start to index 10 (exclusive)
print(myString[5:]) # Print characters from index 5 (inclusive) to the end
print(myString[:]) # Print all characters
Strings can be concatenated together using the +
operator:
# String concatenation
num = 7
numString = str(num) # The str() function converts a number to a string
anotherString = 'My lucky number is ' + numString
print(anotherString)
Lists & Tuples¶
Sometimes we want to store not just a single value in a variable, but a sequence of values. This is what lists are for:
# Create a list
myList = ['eggs', 'potatoes', 42, 180., 'bucky'] # Note square brackets []
print(myList)
print(type(myList))
print(len(myList)) # The len() function returns the length of a list
Lists can be indexed, sliced and concatenated the same way as strings:
# List indexing, slicing and concatenation
print(myList[1])
print(myList[-2])
print(myList[1:3])
print(myList[:3])
print(myList[3:])
anotherList = myList + [1+3*1j, 'eureka!']
print(anotherList)
You can modify lists by indexing or slicing on the left-hand side of an assignment:
# Modify a list using indexing and slicing
anotherList[0] = 'Ostrich eggs'
anotherList[4:6] = [-1, -2]
print(anotherList)
Tuples are like lists in almost all respects, but they are created using a slightly different syntax, and can’t be modified after creation:
# Create a tuple
myTuple = (0, 1, 2., 3., 'four', 'five') # Note parentheses ()
print(myTuple)
print(type(myTuple))
myTuple[0] = 'Nought' # Will cause an error
Arrays¶
Arrays are a type provided by the numpy
module. They are
similar to lists, but support multidimensional indexing. They can,
however, only contain numbers:
# Create an array
myArray = np.array([0, 1, 2, 3, 4, 5]) # The np.array() function creates an array from a list
print(myArray)
print(type(myArray))
print(type(myArray[0]))
print(myArray.shape) # The .shape operator returns the dimensions of an array
Unlike lists, arrays support array arithmetic where operations apply to each array element in turn:
# Array arithmetic
print(myArray*2)
print(myArray + myArray)
print(np.exp(myArray))
The numpy
module provides a variety of alternative ways to create
arrays:
# Alternative ways to create arrays
anotherArray = np.arange(0., 6., 1.5) # From 0 (inclusive) to 6 (exclusive) in steps of 1.5
print(anotherArray)
anotherArray = np.linspace(10., 20., 5) # From 10 to 20 (inclusive) with 5 values
print(anotherArray)
Dicts¶
Dicts (short for ‘dictionaries’) are Python’s most flexible type. They store a group of values, but indexed by a ‘key’ (a string) rather than an integer:
# Define a dict using a sequence of key-value pairs
myDict = {'width': 8.5, 'height': 11, 'shape':'rectangle'} # Note braces {}
print(myDict)
print(type(myDict))
# Print out keys and values (note that ordering is arbitrary)
print(myDict.keys())
print(myDict.values())
Dicts support indexing via their key:
# Dict indexing
print(myDict['width'])
print(myDict['shape'])
Loops¶
Often, we wish to iterate through the elements of an indexable type. We can do this using loops:
# Iterate through the elements of a list
for item in myList: # This sets the variable 'item' to each of the elements in turn
print(item)
# Do the same using indexing
for i in range(len(myList)): # The range() function returns a list of indices
print(i, myList[i])
# Iterate through the elements of a dict
for key, value in myDict.items():
print(key, value)
Plotting¶
As the final step of this lab, let’s use some functions from the
matplotlib
module to make a plot. First, let’s create data for the plot:
# Create plot data
x = np.linspace(0., 2.*np.pi, 25) # 0 to 2pi in 25 steps
y = np.sin(x)
Now create the plot plus all-important labels:
# Create a new figure
plt.figure()
# Plot y versus x
plt.plot(x, y, color='b', label='line') # Line plot
plt.scatter(x, y, color='r', label='scatter') # Scatter plot
# Add axis labels and annotation
plt.xlabel('x')
plt.ylabel('sin(x)')
plt.legend()