Computational Methods in Physics ASU Physics PHY 494

04 Introduction to Python I — Variables and Python data types

The Python programming language is used widely in the sciences, the computational physics, biology, and economics/quantitative finance communities, and in big companies such as Google and Facebook.

For this class we are using Python 3 (e.g. Python 3.5/3.6/3.7), which is the current standard. A lot of older code is still only available for Python 2.7 (and there are a number of sometimes subtle incompatibilities between 2 and 3) but once you know Python 3 you will have no problems dealing with Python 2 code.

  1. Resources
  2. Starting Python
  3. Today's lesson: Python Fundamentals

Resources

Keep the Python documentation close by and have a look at Python questions on StackOverflow.

Getting started …

work directory

  1. Open a terminal.
  2. Create our "work directory" ~/PHY494/04_python
  3. cd into ~/PHY494/04_python

ipython

For interactive work we will use the ipython interpreter. Start it in a terminal window with

ipython

Check that you are in the ~/PHY494/04_python directory by typing in ipython (note the percentage sign in %pwd):

%pwd

You should see

Out[1]: '/Users/YOUR_USERNAME/PHY494/04_python'

or similar.

editor

You will also edit files with your editor (see the lesson on creating text files with a text editor). If you use a point-and-click editor, make sure that you can find the work directory.

python

We will run programs. It is convenient to do this in a second terminal (and keep the one with ipython open).

  1. open a second terminal
  2. go to the work dir

Python Fundamentals

Work interactively in ipython.

Comments

Comments start with #

# This is a comment.
# Comments are VERY useful

answer = 42     # code with trailing comment

Variables and assignment

Variables have names:

answer = 42

(Must start with letters or underscores, cannot contain spaces or other reserved characters (e.g., operators).)

and content

print(answer)

shows 42

Note: In interactive work, you can also just type the variable name to see its content:

In [1]: answer = 42

In [2]: answer
Out[2]: 42

Activity: assignment

Try variable assignments

counts = 33
half = 1/2
h_bar = 1.05457e-34
pi = 3.14159
h = 2 * pi * h_bar
label = "energy (MeV)"
2thirds = 2/3
one = 1.
symmetrical = True
threehalfpi = 0.5 - 0.5j

Make sure that each variable contains what you expect.

Did you get a SyntaxError? Why?

Variable types

Each variable has a type:

Variables are dynamically typed, i.e., Python figures out by itself what type it should be (different from languages such as C, C++, Fortran, java).

x = 42
x = 1.5
x = "something"
print(x)

will print something.

Determine the type of a variable with the type() function:

type(counts)

returns int.

Activity: types

Determine the type of the variables from the previous activity: half, h_bar, h, label, one, symmetrical, threehalfpi.

Type conversion

float(42)     # --> 42.
int("42")     # --> 42

but

float("pi")

raises a ValueError.

Activity: True or False

Work with your neighbor. Try the following code and figure out why the following expressions return True or False:

True
False
bool(True)
bool(False)
bool(0)
bool(1)
bool(2)
bool("True")
bool("true")
bool("False")
bool("")
bool(" ")
bool(None)

Operators

  • unary: +x, -x, not x
  • binary

    • comparison operators, e.g., x == y, x != y, x > y, x <= y, …

      A comparison has a boolean value.

    • numerical operators, e.g., x + y, x - y, x * y, x / y, x ** y (power), x // y (floor division), x % y (remainder).

      Also in-place operations, which combine numerical operation with assignment (x += y is the same as x = x + y)

  • ternary (x < y < z, x if y else z)

Use parentheses ( and ) for grouping and change of precedence.

Activity: operators

Compute the temperature in Kelvin from a temperature in Fahrenheit using

Container data types

Lists ("arrays") and tuples are sequences and support a broad set of common operations. Dictionaries (dicts) contain key-value pairs.1

Lists

A list (uses square brackets [] or list()):

temperatures = [60.1, 78.3, 98.8, 97.1, 101.3, 110.0]
stuff = ["dog", 42, -1.234, "cat", [3, 2, 1]]
empty = []
two = [[], []]

Important list operations:

Indexing

Each element has an index:

temperatures = [60.1, 78.3, 98.8, 97.1, 101.3, 110.0]   elements
               |    |     |     |     |      |      |
               |  0 |   1 |   2 |   3 |    4 |    5 |   index

First element

temperatures[0]

Arbitrary elements

temperatures[3]

Note: Python indices are 0-based.

For example, the third element is at index 2:

temperatures[2]

Negative indices count from the last element to the first:

temperatures = [60.1, 78.3, 98.8, 97.1, 101.3, 110.0]   elements
               |    |     |     |     |      |      |
               |  0 |   1 |   2 |   3 |    4 |    5 |   index
               | -6 |  -5 |  -4 |  -3 |   -2 |   -1 |   negative index

Last element

temperatures[-1]

Third element from the end

temperatures[-3]

Python built-in function to determine the length of a list: len():

len(temperatures)

gives 6.

Slicing

Slicing produces a new list by extracting a subset of elements as determined by the "slice" start:stop:step. The general slicing syntax for a list a:

a[start:stop:step]

where

  • index start is included and
  • stop is excluded;
  • start, stop, step are each optional:
    • default for start: first element (index 0)
    • default for stop: after last element
    • default for step is 1, i.e., include every element.

Negative values are also allowed for indices and negative step counts backwards.

First 3 elements

temperatures[0:3]
temperatures[:3]

(start defaults to 0 and can be omitted).

Omitting parameters:

temperatures[::2] == [60.1, 98.8, 101.3]
temperatures[2::2] == [98.8, 101.3]
temperatures[:2:2] == [60.1]
Example: slicing

A list with the first 6 letters of the English alphabet:

letters = ['A', 'B', 'C', 'D', 'E', 'F']
+---+---+---+---+---+---+
|'A'|'B'|'C'|'D'|'E'|'F'|  elements 
+---+---+---+---+---+---+
| 0 | 1 | 2 | 3 | 4 | 5 |  index
+---+---+---+---+---+---+
|-6 |-5 |-4 |-3 |-2 |-1 |  index
+---+---+---+---+---+---+

Refer to the schema above to understand which part of the list the following slices extract:

letters[:3] == ['A', 'B', 'C']
letters[0:3] == ['A', 'B', 'C']
letters[1:3] == ['B', 'C']
letters[-3] == 'D'
letters[-3:-1] == ['D', 'E']
letters[-3:] == ['D', 'E', 'F']
letters[1::2] == ['B', 'D', 'F']
Activity: extracting from lists
  1. extract the letter 'E' from letters
  2. extract the letter 'E' from letters (in a different way)
  3. extract the letters 'C', 'D' from letters
  4. extract the letters 'A', 'D' from letters
  5. extract the letters 'E', 'F' from letters (use negative indices)
  6. extract the letters 'D', 'E' from letters (use negative indices)
  7. extract the second element from stuff
  8. extract the first two values from temperatures
  9. extract the second-but last value from temperatures
  10. extract the last two values from temperatures
  11. extract the last element of the last element from stuff (should be 1)
  12. What do you get from stuff[3:4]? (Should be an animal)
  13. What do you get from stuff[3:3]? What is the length of the new list?
  14. BONUS: reverse the order of temperatures (note the step argument)

List construction

Lists are mutable, which means that they can be changed:

stuff = []              # empty list
stuff.append("dog")     # append
stuff.append("mouse")
stuff[1] = 42           # replace element
stuff.extend([-1.234, "cat", [3, 2, 1]])  # extend with sequence
print(stuff)

gives ['dog', 42, -1.234, 'cat', [3, 2, 1]] as above.

You can also replace parts of a list (continuing):

stuff[1:3] = ['python', 'swallow']
stuff[-1:] = ['Hund', 'Python', 'Schwalbe', 'Katze']
print(stuff)

gives ['dog', 'python', 'swallow', 'cat', 'Hund', 'Python', 'Schwalbe', 'Katze'] (note that the last list was inserted).

One can also insert into a list without deleting an element by assigning to an empty slice:

stuff[2:2] = ['parrot', 'llama']
print(stuff)

gives ['dog', 'python', 'parrot', 'llama', 'swallow', 'cat', 'Hund', 'Python', 'Schwalbe', 'Katze'].

Alternatively (and more clearly), use

stuff.insert(2, ['parrot', 'llama'])

Tuples

A tuple is a list-like container("sequence"), defined by comma , (but often parentheses are added for clarity or when defining a 1-tuple or an empty tuple) or use tuple():

point = -3, 5
point = (-3, 5)
onetuple = ("lonely", )
empty = ()

Indexing and slicing works the same way as for lists but tuples are immutable:

In [18]: point[0] = 4
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-18-14b93c6014c9> in <module>()
----> 1 point[0] = 4

TypeError: 'tuple' object does not support item assignment

Often used for compact assignment statements

x, y, z = 0, 0, 1

Dictionaries

A dict is a mutable container with arbitrary (constant) keys (uses curly braces {} or dict()):

ages = {'Einstein': 42, 'Dirac': 31, 'Feynman': 47}

Access elements by key:

ages['Dirac']

prints 31.

Create new entries on the fly:

ages['Heisenberg'] = 1932 - 1901

The content of a dict has no defined order (unlike lists and tuples):

In [21]: print(ages)
{'Einstein': 42, 'Dirac': 31, 'Heisenberg': 31, 'Feynman': 47}

Footnotes

  1. There are more container types available in Python (e.g., set and the collections module in the Standard Library) but understanding list, tuple, and dict will already get you a long way.