This notebook was put together by [Jake Vanderplas](http://www.vanderplas.com) for UW's [Astro 599](http://www.astro.washington.edu/users/vanderplas/Astr599/) course. Source and licensing info is on [GitHub](https://github.com/jakevdp/2013_fall_ASTR599/).

Basic Training

Much of this material thanks to http://www.pythonbootcamp.info/

Outline

  • ### Python is easy! Hello world revisited
  • ### Calculator / basic math
  • ### Strings
  • ### Variables
  • ### Basic control statements (indentation!)

Hello World!

We saw before how easy a hello world script is to create in Python:


In [1]:
print "Hello World!"


Hello World!

Some other languages...

http://www.roesler-ac.de/wolfram/hello.htm

Python

file: hello.py

print "Hello World!"


[~]> python hello.py

Java

file: hello.java

class HelloWorld {
  static public void main( String args[] ) {
    System.out.println( "Hello World!" );
  }
}


[~]> javac hello.java
[~]> java HelloWorld
Hello World!

C++

file: hello.cpp

#include <iostream>
int main()
{
  std::cout << "Hello World!" << std::endl;
}


[~]> g++ -o hello hello.cpp
[~]> ./hello
Hello World!

Fortran

file: hello.f

    PROGRAM HELLO
    WRITE (*,100)
    STOP
100 FORMAT (' Hello World! ' /)
    END


[~]> g77 -o hello hello.f
[~]> ./hello
Hello World!

Two Points

  • Python provides interaction in both development and execution
  • Executing interactively is basically the same thing as executing a script, line-by-line

Types and Operations: Python as a Calculator

We'll talk about a few types here:

  • int: integer
  • float: floating point (decimal)
  • long: long integer
  • complex: complex number (decimal, not integer)

We'll also introduce the basic arithmetic operations

  • + : addition
  • -: subtraction
  • /: division
  • *: multiplication
  • %: modulus (remainder)
  • **: exponentiation

As we go through this, note carefully how these operations interact with various types


In [2]:
print 2 + 2


4

In [3]:
2 + 2


Out[3]:
4

In [1]:
print 2.1 + 2


4.1

Careful: floats are limited by their 16-bit representation (same as in other languages)


In [8]:
print 4.0999999999999995


4.1

In [6]:
2.1 + 2 == 4.0999999999999995


Out[6]:
True

In [19]:
4 * 2


Out[19]:
8

In [14]:
4 / 2


Out[14]:
2

In [15]:
5 / 2


Out[15]:
2

Integer operations result in integers (floor of the float result): this can cause unexpected problems!

Fix this by using floats when dividing.


In [43]:
9 / 5


Out[43]:
1

In [44]:
9.0 / 5  # result will be a float


Out[44]:
1.8

In [17]:
5 % 2  # modulus (remainder after division)


Out[17]:
1

In [18]:
5 ** 2


Out[18]:
25

In [105]:
# or you can use the pow() function
pow(5, 2)


Out[105]:
25

Indentation Matters!


In [11]:
print 2 + 2
   3 + 3


  File "<ipython-input-11-a75d2b16761f>", line 2
    3 + 3
    ^
IndentationError: unexpected indent

Use # for comments

  • Everything after the # will be ignored

In [12]:
print 1 + 1  # easy arithmetic


4

Longs and complex types


In [6]:
2L


Out[6]:
2L

In [7]:
2L + 2


Out[7]:
4L

In [8]:
2L/2


Out[8]:
1L

In [9]:
2L/2.0


Out[9]:
1.0

In [10]:
complex(1,2)


Out[10]:
(1+2j)

In [11]:
1+2j


Out[11]:
(1+2j)

In [12]:
1 + 2j - 2j


Out[12]:
(1+0j)

In [13]:
(3.0*10.0 - 25.0)/5.0


Out[13]:
1.0

In [14]:
print 3.085e18 * 1e6  # this is a Megaparsec in units of cm!


3.085e+24

Assigning variables


In [15]:
t = 1.0  # declare a variable t (time)
accel = 9.8  # acceleration in units of m/s^2

# distance travelled in time t seconds is 1/2 a*t**2
dist = 0.5*accel*t*t
print dist # this is the distance in meters


4.9

In [16]:
dist1 = accel*(t**2)/2
print dist1


4.9

In [17]:
dist2 = 0.5*accel*pow(t,2)
print dist2


4.9

A nice trick that other languages can't do:


In [3]:
x, y = 4, 50
print x
print y


4
50

In [4]:
x, y = y, x  # easy swap!
print x
print y


50
4

Each operator has an operate-and-assign version


In [52]:
x = 4
x += 8  # same as x = x + 8
print x


12

In [53]:
x *= 0.2  # x is upgraded to a float!
print x


2.4

In [55]:
x %= 1
print x


0.4

Bitwise Operators

You might also come across bitwise operators:

  • &: bitwise and
  • |: bitwise or
  • ^: bitwise xor
  • <<: bit-shift left
  • >>: bit-shift right

All these make more sense if you think about binary representations:


In [26]:
bin(14)  # print binary representation


Out[26]:
'0b1110'

In [27]:
14 << 1


Out[27]:
28

In [28]:
bin(14 << 1)


Out[28]:
'0b11100'

In [29]:
14 >> 1


Out[29]:
7

In [38]:
bin(14 >> 1)


Out[38]:
'0b111'

In [31]:
14 & 4


Out[31]:
4

In [39]:
print bin(14), bin(4), bin(14&4)


0b1110 0b100 0b100

In [32]:
14 & 1


Out[32]:
0

In [36]:
14 | 1


Out[36]:
14

In [40]:
print bin(14), bin(1), bin(14|1)


0b1110 0b1 0b1111

In [41]:
14 | 4


Out[41]:
14

In [35]:
14 ^ 4


Out[35]:
10

In [42]:
print bin(14), bin(4), bin(14^4)


0b1110 0b100 0b1010

In [56]:
x = 14
x <<= 1  # bit-shift and assign
print x


28

Comparison operators

  • ==, !=: equal, not equal
  • <, <=: less than, less than or equal
  • >, >=: greater than, greater than or equal

In [57]:
2 < 4


Out[57]:
True

In [58]:
3 >= 3


Out[58]:
True

In [59]:
5 == 4


Out[59]:
False

In [60]:
5 != 4


Out[60]:
True

In [90]:
5 < 2 + 4j


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-90-22831f5cf00f> in <module>()
----> 1 5 < 2 + 4j

TypeError: no ordering relation is defined for complex numbers

Comparisons can also be strung together and behave as expected:


In [76]:
x = 4
y = 6
print 2 < x <= 4
print 2 < y <= 4


True
False

In [80]:
# This allows strange/confusion expressions
# don't do things like this!
8 > x <= 5


Out[80]:
True

Warning about Floating Point Equality

Precision issues can lead to seemingly strange results (again, this is the same in any modern programming language)


In [65]:
0.1 + 0.2 == 0.3


Out[65]:
False

In [70]:
# this is a string formatting command (we'll cover this later)
# it says to print 20 places after the decimal
print "%.20f" % (0.1 + 0.2)
print "%.20f" % 0.3


0.30000000000000004441
0.29999999999999998890

Moral of the story: in any language you use, be careful using equality comparisons on floating point!

Boolean variables and logical operations

Python has two built-in boolean values, True and False which we've seen above.

There are also built-in logical operations to test these

  • A or B : True if either A or B or both are True
  • A and B : True only if both A and B are True
  • not A: True only if A is False

In [81]:
x = 4
(x > 2) and (x < 10)


Out[81]:
True

In [84]:
(x <= 4) or not (x > 10)


Out[84]:
True

Built-in types can be coerced to booleans.


In [91]:
0 == False


Out[91]:
True

In [95]:
not False


Out[95]:
True

In [96]:
not 0


Out[96]:
True

In [86]:
not -1


Out[86]:
False

zero is evaluated to False, every other number to True


In [98]:
print None  # None is a special object


None

In [102]:
print None == True
print None == False
print None == None
print bool(None)


False
False
True
False

Special comparators: is and is not


In [114]:
x = 1
y = 1
print x is y


True

In [120]:
False is not 2


Out[120]:
True

In [119]:
False is (not 2)


Out[119]:
True

In [126]:
x = 1111
y = 1111
print x is y


False

Takeaway: "is" and "is not" refer to the memory being used by the object. If x and y point to the same location in memory, then x is y will be True.

Probably their most common use is in comparisons to None. All variables equal to None are guaranteed to point to the same memory location (i.e. it acts as a Singleton).


In [127]:
x = None
print x is None


True

You don't need to fully understand this, but just be aware that teh is and is not operators should generally not be used unless you do!

More on Variables & Types


In [42]:
print type(1)


<type 'int'>

In [43]:
x = 2 ; print type(x)


<type 'int'>

In [44]:
type(2) == type(1)


Out[44]:
True

In [45]:
print type(True)


<type 'bool'>

In [103]:
print type(None)


<type 'NoneType'>

In [46]:
print type(type(1))


<type 'type'>

In [104]:
print type(pow)


<type 'builtin_function_or_method'>

we can test whether something is a certain type with isinstance()


In [48]:
print isinstance(1, int)
print isinstance("spam", str)
print isinstance(1.212, int)


True
True
False

builtin-types: int, bool, str, float, complex, long....

Strings


In [49]:
x = "spam" ; type(x)


Out[49]:
str

In [50]:
print "hello!\n...my sire."


hello!
...my sire.

In [51]:
"hello!\n...my sire."


Out[51]:
'hello!\n...my sire.'

In [52]:
"wah?!" == 'wah?!'


Out[52]:
True

In [53]:
print "'wah?!' said the student"


'wah?!' said the student

In [54]:
print "\"wah?!\" said the student"


"wah?!" said the student

backslashes (\) start special (escape) characters:

 \n   = newline  (\r = return)
 \t   = tab
 \a   = bell

string literals are defined with double quotes or quotes. the outermost quote type cannot be used inside the string (unless it's escaped with a backslash)


In [55]:
# raw strings (marked with r) don't escape characters
print r'This is a raw string...newlines \r\n are ignored.'


This is a raw string...newlines \r\n are ignored.

In [106]:
# Triple quotes are real useful for multiple line strings
y = """For score and seven minutes ago,
    you folks all learned some basic mathy stuff with Python
    and boy were you blown away!"""
print y


For score and seven minutes ago,
    you folks all learned some basic mathy stuff with Python
    and boy were you blown away!
  • prepending r makes that string "raw"
  • triple quotes allow you to compose long strings
  • prepending u makes that string "unicode"

http://docs.python.org/reference/lexical_analysis.html#string-literals

Arithmetic with Strings


In [57]:
s = "spam" ; e = "eggs"
print s + e


spameggs

In [58]:
print s + " and " + e


spam and eggs

In [59]:
print "green " + e + " and\n " + s


green eggs and
 spam

In [60]:
print s*3 + e


spamspamspameggs

In [61]:
print "*" * 50


**************************************************

In [1]:
print "spam" == "good" ; print "spam" == "spam"


False
True

In [63]:
"spam" < "zoo"


Out[63]:
True

In [64]:
"s" < "spam"


Out[64]:
True
  • you can concatenate strings with + sign
  • you can do multiple concatenations with the * sign
  • strings can be compared

In [65]:
print 'I want' + 3 + ' eggs and no ' + s


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/Users/jbloom/Classes/python-bootcamp/DataFiles_and_Notebooks/01_BasicTraining/<ipython-input-65-91d89321074a> in <module>()
----> 1 print 'I want' + 3 + ' eggs and no ' + s

TypeError: cannot concatenate 'str' and 'int' objects

In [66]:
print 'I want ' + str(3) + ' eggs and no ' + s


I want 3 eggs and no spam

In [67]:
pi = 3.14159
print 'I want ' + str(pi) + ' eggs and no ' + s


I want 3.14159 eggs and no spam

In [68]:
print str(True) + ":" + ' I want ' + str(pi) + ' eggs and no ' + s


True: I want 3.14159 eggs and no spam

you must concatenate only strings, coercing ("casting") other variable types to str

Getting input from the user


In [4]:
# Note that raw_input does not work in IPython notebook version < 1.0
# You can always do this from a file or from the command line, though
faren = raw_input("enter a temperature (in Fahrenheit): ")
print faren


enter a temperature (in F): 234
234

In [5]:
cent = (faren - 32) / 1.8


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-5-692d7634602b> in <module>()
----> 1 cent = (faren - 32) / 1.8

TypeError: unsupported operand type(s) for -: 'str' and 'int'

In [7]:
cent = (float(faren) - 32) / 1.8
print cent


112.222222222

In [9]:
# Or in one line:
faren = float(raw_input("enter a temperature (in Fahrenheit): "))
print (faren - 32) / 1.8


enter a temperature (in Fahrenheit): 212
100.0

Strings as arrays

We can think of strings as arrays (although, unlike in C you never really need to deal with directly addressing character locations in memory)


In [13]:
s = 'spam'
len(s)


Out[13]:
4

In [14]:
len("eggs\n")


Out[14]:
5

In [15]:
len("")


Out[15]:
0

Indexing in Python is zero-based


In [16]:
print s[0]
print s[-1]


s
m

In [17]:
print s[0:1]


s

In [18]:
print s[1:4]


pam

In [19]:
print s[-2:]


am

In [21]:
print s[0:100]  # if the slice goes past the end, no complaints!


spam

In [22]:
print s[0:4:2]


sa

In [25]:
print s[::2]


sa

In [26]:
print s[::-1]


maps
  • len() gives us the length of an array
  • strings are zero indexed
  • can also count backwards

Flow control: conditionals and loops


In [72]:
x = 1
if x > 0:
    print "yo"
else:
    print "dude"


yo

One liners


In [74]:
print "yo" if x > 0 else "dude"


yo

In [29]:
x = 1
y = 0
while y < 10:
    print "yo" if x > 0 else "dude"
    x *= -1
    y += 1


yo
dude
yo
dude
yo
dude
yo
dude
yo
dude

In [5]:
# Could also do this with a break statement
x = 1
y = 0
while True:
    print "yo" if x > 0 else "dude"
    x *= -1
    y += 1
    if y >= 10:
        break


yo
dude
yo
dude
yo
dude
yo
dude
yo
dude

case statements can be constructed with just a bunch of if, elif,...else


In [75]:
if x < 1:
    print "t"
elif x > 100:
    print "yo"
elif x == 42:
    print "bingo"
else:
    print "dude"


dude

Note: ordering matters. The first block of True in an if/elif gets executed then everything else does not.

Blocks cannot be empty!


In [76]:
x = "fried goldfish"
if x == "spam for dinner":
    print "I will destroy the universe"
else:
    # I'm fine with that. I'll do nothing


IndentationError: expected an indented block

In [77]:
x = "fried goldfish"
if x == "spam for dinner":
    print "I will destroy the universe"
else:
    # I'm fine with that. I'll do nothing
    pass

pass is a "do nothing"/NOP statement

Example: putting it all together


In [38]:
%%file number_game.py
# The above "magic" command saves the contents
# of the current cell to file.  We'll see more of these later

x = 0
max_tries = 10
count = 0

while True:
    x_new = int(raw_input("Enter a new number: "))
    if x_new > x:
        print " -> it's bigger than the last!"
    elif x_new < x:
        print " ->it's smaller than the last!"
    else:
        print " -> no change!  I'll exit now"
        break
        
    x = x_new
        
    count += 1
    if count > max_tries:
        print "too many tries..."
        break


Overwriting number_game.py

In [39]:
%run number_game.py
# this magic command runs the given file


Enter a new number: 0
 -> no change!  I'll exit now

Breakout #1: getting your code on

Create a program (a .py file) which repeatedly asks the user for a word. The program should append all the words together. When the user types a "!", "?", or a ".", the program should print the resulting sentence and exit.

For example, a session might look like this:

[~]$ python breakout01.py
Enter a word (. ! or ? to end): My
Enter a word (. ! or ? to end): name
Enter a word (. ! or ? to end): is
Enter a word (. ! or ? to end): Walter
Enter a word (. ! or ? to end): White
Enter a word (. ! or ? to end): !

My name is Walter White!