Note: this is not a language course! Though I'll cover the important bits of the language (and standard library) that are relevant to class material, I expect you to master the language on your own time.
Python ...
# python can be used as a calculator
5+6
3*9
11
27
_
27
a=3.14159
b="matt"
c=5
a
b
c
d=a/c
print(d)
print(c/a)
a/c
3.14159
'matt'
5
0.6283179999999999 1.5915507752443827
0.6283179999999999
# by default, only the result of the last expression in a cell is displayed after evaluation.
# the following forces display of *all* self-standing expressions in a cell.
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
Python has no beginning/end block markers! Blocks must be correctly indented (4 spaces is the convention) to delineate them.
if True:
print('In if-clause')
print('hi')
else:
print('In else-clause')
In if-clause hi
if not True:
print('In if-clause')
print('hi')
else:
print('In else-clause')
In else-clause
for x in range(5):
print(x,'In for loop body')
0 In for loop body 1 In for loop body 2 In for loop body 3 In for loop body 4 In for loop body
def foo():
print('In function definition')
foo()
In function definition
In Python, variables do not have types. Values have types (though they are not explicitly declared). A variable can be assigned different types of values over its lifetime.
a = 2 # starts out an integer
print(type(a)) # the `type` function tells us the type of a value
a = 1.5
print(type(a))
a = 'hello'
print(type(a))
<class 'int'> <class 'float'> <class 'str'>
dir(5)
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'as_integer_ratio', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']
a=6
b=8
a.__add__(b) # same as a+b
14
a
b
c
d
6
8
5
0.6283179999999999
Note that all the types reported are classes. I.e., even types we are accustomed to thinking of as "primitives" (e.g., integers in Java) are actually instances of classes. All values in Python are objects!
There is no dichotomy between "primitive" and "reference" types in Python. All variables in Python store references to objects.
# int: integers, unlimited precision
1
500
-123456789
6598293784982739874982734
1
500
-123456789
6598293784982739874982734
# basic operations
1 + 2
1 - 2
2 * 3
2 * 3 + 2 * 4
2 / 5
2 ** 3 # exponentiation
abs(-25)
2 // 5
3
-1
6
14
0.4
8
25
0
# modulus (remainder) and integer division
10 % 3
10 // 3
1
3
# floating point is based on the IEEE double-precision standard (limit to precision!)
2.5
-3.14159265358924352345
1.000000000000000000000001
2.5
-3.1415926535892433
1.0
# mixed arithmetic "widens" ints to floats
3 * 2.5
1 / 0.3
7.5
3.3333333333333335
True
False
True
False
not True
False
True and True
False and True
True and False
False and False
True
False
False
False
True or True
False or True
True or False
False or False
True
True
True
False
# relational operators
1 == 1
1 != 2
1 < 2
1 <= 1
1 > 0
1 >= 1
1.0 == 1
1.0000000000000000001 == 1
type(1) == type(1.0)
True
True
True
True
True
True
True
True
False
#// java
#String a="matt";
#String b="matt";
#a==b comapring addresses of object
# a.equals(b) comparing values of object
# object identity (reference) testing
x = 1000
y = 1000
x == x #compares values of objects, not addresses
x is x # compares addresses of objects
x is not x
True
True
False
x == y # compare values
x is y # compare addresses
x is not y #comapre addresses
True
False
True
x=1000
y=x # y is now the same object as x
x==y
x is y
True
True
y=5 # y is now a new object, but it does not change x
x
y
x is y
1000
5
False
x=1000
y=x # x and y are same object
y=y+1 # get a new object for y
x
y
1000
1001
# but Python caches small integers! so ...
x = 5 # x is a new object
y = 5 # since 5 is small and already an object for 5 exists, reuse it
x == y
x is y
True
True
# whatever strings you want
'hello world!'
"hello world!"
'hello world!'
'hello world!'
dir("matt")
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
# convenient for strings with quotes:
print('she said, "how are you?"')
print("that's right!")
she said, "how are you?" that's right!
'hello' + ' ' + 'world'
'thinking... ' * 3
'*' * 80
'hello world'
'thinking... thinking... thinking... '
'********************************************************************************'
Strings are an example of a sequence type; https://docs.python.org/3.5/library/stdtypes.html#typesseq
Other sequence types are: ranges, tuples (both also immutable), and lists (mutable).
All immutable sequences support the common sequence operations, and mutable sequences additionally support the mutable sequence operations
z="matt"
z[0]
#z[10] error, index out of range
#z[0]='n' # 'str' object does not support item assignment
z="natt" # creates a new object, strings are immutable
z
'm'
'natt'
# indexing
greeting = 'hello there'
# 01234567890
# -2-1
greeting[0]
greeting[6]
len(greeting)
greeting[len(greeting)-1]
'h'
't'
11
'e'
# negative indexes greeting = 'hello there'
greeting[-1]
greeting[-2]
greeting[-len(greeting)]
'e'
'r'
'h'
# index in [] must between 0 and length-1
# or negative index between last index is -1 to first index -length
#greeting[len(greeting)]
#greeting[11]
greeting[-12]
--------------------------------------------------------------------------- IndexError Traceback (most recent call last) <ipython-input-6-527669a626be> in <module> 3 #greeting[len(greeting)] 4 #greeting[11] ----> 5 greeting[-12] IndexError: string index out of range
# "slices" subset of sequence type
# [ fromIndex : toIndex] but it only goes up to toIndex-1
greeting[0:11] # 0 to 10
greeting[0:5] #0 to 4
greeting[6:11] # 6 to 10
greeting
'hello there'
'hello'
'there'
'hello there'
# default slice ranges 'hello there'
# 01234567890
greeting[:11] # don't specify the fromIndex, you get index 0
greeting[6:] # don't specify the toIndex, you get all the way to the end
greeting[:]
'hello there'
'there'
'hello there'
# slice "steps" increment on the index positions to get
# [ fromIndex : toIndex : increment] 'hello there'
greeting[::2] #0 2 4 6 8
greeting[::3] #0 3 6 9
greeting[6:11:2] #6 8 10
'hlotee'
'hltr'
'tee'
# negative steps
greeting[::-1]
'ereht olleh'
greeting[5:9:-1]
''
# other sequence ops
greeting
greeting.count('e')
greeting.index('e')
greeting.index('e', 2)
'e' in greeting
'z' not in greeting
min(greeting)
max(greeting)
'hello there'
3
1
8
True
True
' '
't'
Strings also support a large number of type-specific methods.
Constructors for most built-in types exist that create values of those types from other types:
# making ints
int('123')
int(12.5)
int(True)
# floats
float('123.123')
# strings
str(123)
123
12
1
123.123
'123'
int('matt')
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-14-5f434c59baab> in <module> ----> 1 int('matt') ValueError: invalid literal for int() with base 10: 'matt'
5 + 6
(5).__add__(6)
11
11
class MyInt(int): # defining my own class "MyInt" inheriting from int
def __add__(self, other): #override the __add__ method
# don;t use the __add__ inherited from int, use this one instead
return self * other
# if you want an instance method of a class, you must have "self" as the first argument
a = MyInt(5)
b = MyInt(6)
a + b # calling a.__add__(b)
# self. other
30
abs(-2.8)
(-2.8).__abs__()
2.8
2.8
'hello' + ' ' + 'world'
'hello'.__add__(' ').__add__('world')
'hello world'
'hello world'
None
¶None
is like "null" in other languages
# often use as a default, initial, or "sentinel" value
x = None
x
note: notebooks do not display the result of expressions that evaluate to None
None
a = None
b = 100
c = None
a
b
c
100
some functions return None
, so when we call them, there is no "Out" cell
print('Hello')
Hello
All objects in Python can be evaluated in a Boolean context (e.g., as the condition for an if
statement). Values for most types act as True
, but some act (conveniently, usually) as False
.
if True: # try numbers, strings, other values here
print('tests as True')
else:
print('tests as False')
tests as True
What tests as False
?
if 'matt': # try numbers, strings, other values here
print('tests as True')
else:
print('tests as False')
if 3.14159: # try numbers, strings, other values here
print('tests as True')
else:
print('tests as False')
if 5: # try numbers, strings, other values here
print('tests as True')
else:
print('tests as False')
if -1: # try numbers, strings, other values here
print('tests as True')
else:
print('tests as False')
if None: # try numbers, strings, other values here
print('tests as True')
else:
print('tests as False')
if 0: # try numbers, strings, other values here
print('tests as True')
else:
print('tests as False')
tests as True tests as True tests as True tests as True tests as False tests as False
if ' ': # try numbers, strings, other values here
print('tests as True')
else:
print('tests as False')
if '': # try numbers, strings, other values here
print('tests as True')
else:
print('tests as False')
tests as True tests as False
# simple, single target assignment
# right hand side fully evaluted first, then assigned to left hand side
a = 0
b = 'hello' # assignment statements return a None if successful
# b <- 5 pascal?
a
b
0
'hello'
# can also assign to target "lists"
a, b, c = 0, 'hello', True
a
b
c
0
'hello'
True
# note: expression on right is fully evaluated, then are assigned to
# elements in the "target" list, from left to right
x, y, z = 1, 2, 3
x, y, z = x+y, y+z, x+y+z
# 1+2 2+3 1+2+3
x
y
z
3
5
6
# easy python "swap"
a, b = 'apples', 'bananas'
a
b
a, b = b, a
a
b
'apples'
'bananas'
'bananas'
'apples'
# note: order matters!
a, b, a = 1, 2, 3
a
b
3
2
# can also have multiple assignments in a row -- consistent with
# above: expression is evaluated first, then assigned to all targets
# from left to right (note: order matters!)
x = y = z = None
x
y
z
a = 0
a
a += 2
a
a *= 3
a
0
2
6
pass
¶pass
is the "do nothing" statement
pass
def foo():
pass
foo()