python
at the command prompt.
>>>
) they will
be evaluated and the result will be returned on the next line.
Boolean operators also exist in Python.
>>> 1 + 1
2
>>> 2 * 3
6
>>> 2 ** 3
8
>>> 1==0
False
>>> not (1==0)
True
>>> (2==2) and (2==3)
False
>>> (2==2) or (2==3)
True
+
operator is overloaded
to do string concatenation on string values.
>>> 'machine' + "learning"
'machinelearning'
>>> 'machine'.upper()
'MACHINE'
>>> 'HELP'.lower()
'help'
>>> len('Help')
4
' '
or double quotes " "
to surround string.
>>> s = 'hello world'
>>> print s
hello world
>>> s.upper()
'HELLO WORLD'
>>> len(s.upper())
11
>>> num = 8.0
>>> num += 2.5
>>> print num
10.5
To see what methods Python provides for a datatype, use the dir
and help
commands:
>>> s = 'abc'
>>> dir(s)
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__ge__',
'__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__','__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__','__repr__', '__rmod__', '__rmul__', '__setattr__', '__str__', 'capitalize', 'center',
'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'replace', 'rfind','rindex', 'rjust', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
>>> help(s.find)
Help on built-in function find:
find(...)
S.find(sub [,start [,end]]) -> int
Return the lowest index in S where substring sub is found,
such that sub is contained within s[start,end]. Optional
arguments start and end are interpreted as in slice notation.
Return -1 on failure.
>> s.find('b')
1
>>> fruits = ['apple','orange','pear','banana']
>>> fruits[0]
'apple'
We can use the +
operator to do list concatenation:
>>> otherFruits = ['kiwi','strawberry']
>>> fruits + otherFruits
>>> ['apple', 'orange', 'pear', 'banana', 'kiwi', 'strawberry']
Python also allows negative-indexing from the back of the list.
For instance, fruits[-1]
will access the last
element 'banana'
:
>>> fruits[-2]
'pear'
>>> fruits.pop()
'banana'
>>> fruits
['apple', 'orange', 'pear']
>>> fruits.append('grapefruit')
>>> fruits
['apple', 'orange', 'pear', 'grapefruit']
>>> fruits[-1] = 'pineapple'
>>> fruits
['apple', 'orange', 'pear', 'pineapple']
fruits[1:3]
which returns a list containing
the elements at position 1 and 2. In general fruits[start:stop]
will get the elements in start, start+1, ..., stop-1
. We can
also do fruits[start:]
which returns all elements starting from the start
index. Also fruits[:end]
will return all elements before the element at position end
:
>>> fruits[0:2]
['apple', 'orange']
>>> fruits[:3]
['apple', 'orange', 'pear']
>>> fruits[2:]
['pear', 'pineapple']
>>> len(fruits)
4
The items stored in lists can be any Python data type. So for instance
we can have lists of lists:
>>> lstOfLsts = [['a','b','c'],[1,2,3],['one','two','three']]
>>> lstOfLsts[1][2]
3
>>> lstOfLsts[0].pop()
'c'
>>> lstOfLsts
[['a', 'b'],[1, 2, 3],['one', 'two', 'three']]
>>> lst = ['a','b','c']
>>> lst.reverse()
>>> ['c','b','a']
>>> pair = (3,5)
>>> pair[0]
3
>>> x,y = pair
>>> x
3
>>> y
5
>>> pair[1] = 6
TypeError: object does not support item assignment
The attempt to modify an immutable structure raised an exception. This is how many errors will manifest: index out of bounds errors, type errors, and so on will all report exceptions in this way.
>>> shapes = ['circle','square','triangle','circle']
>>> setOfShapes = set(shapes)
>>> setOfShapes
set(['circle','square','triangle'])
>>> setOfShapes.add('polygon')
>>> setOfShapes
set(['circle','square','triangle','polygon'])
>>> 'circle' in setOfShapes
True
>>> 'rhombus' in setOfShapes
False
>>> favoriteShapes = ['circle','triangle','hexagon']
>>> setOfFavoriteShapes = set(favoriteShapes)
>>> setOfShapes - setOfFavoriteShapes
set(['square','polyon'])
>>> setOfShapes & setOfFavoriteShapes
set(['circle','triangle'])
>>> setOfShapes | setOfFavoriteShapes
set(['circle','square','triangle','polygon','hexagon'])
>>> studentIds = {'knuth': 42.0, 'turing': 56.0, 'nash': 92.0 }
>>> studentIds['turing']
56.0
>>> studentIds['nash'] = 'ninety-two'
>>> studentIds
{'knuth': 42.0, 'turing': 56.0, 'nash': 'ninety-two'}
>>> del studentIds['knuth']
>>> studentIds
{'turing': 56.0, 'nash': 'ninety-two'}
>>> studentIds['knuth'] = [42.0,'forty-two']
>>> studentIds
{'knuth': [42.0, 'forty-two'], 'turing': 56.0, 'nash': 'ninety-two'}
>>> studentIds.keys()
['knuth', 'turing', 'nash']
>>> studentIds.values()
[[42.0, 'forty-two'], 56.0, 'ninety-two']
>>> studentIds.items()
[('knuth',[42.0, 'forty-two']), ('turing',56.0), ('nash','ninety-two')]
>>> len(studentIds)
3
As with nested lists, you can also create dictionaries of dictionaries.
# This is what a comment looks like
fruits = ['apples','oranges','pears','bananas']
for fruit in fruits:
print fruit + ' for sale'
fruitPrices = {'apples': 2.00, 'oranges': 1.50, 'pears': 1.75}
for fruit, price in fruitPrices.items():
if price < 2.00:
print '%s cost %f a pound' % (fruit, price)
else:
print fruit + ' are too expensive!'
nums = [1,2,3,4,5,6]
plusOneNums = [x+1 for x in nums]
oddNums = [x for x in nums if x % 2 == 1]
print oddNums
oddNumsPlusOne = [x+1 for x in nums if x % 2 ==1]
print oddNumsPlusOne
Put this code into a file called listcomp.py and run the script:
$ python listcomp.py
[1,3,5]
[2,4,6]
if 0 == 1: print 'We are in a world of arithmetic pain' print 'Thank you for playing'will output
Thank you for playing
But if we had written the script as
if 0 == 1:
print 'We are in a world of arithmetic pain'
print 'Thank you for playing'
there would be no output. The moral of the story: be careful how you indent! It's best to use a single tab for
indentation.
fruitPrices = {'apples':2.00, 'oranges': 1.50, 'pears': 1.75}
def buyFruit(fruit, numPounds):
if fruit not in fruitPrices:
print "Sorry we don't have %s" % (fruit)
else:
cost = fruitPrices[fruit] * numPounds
print "That'll be %f please" % (cost)
# Main Function
if __name__ == '__main__':
buyFruit('apples',2.4)
buyFruit('coconuts',2)
$ python fruit.py
That'll be 4.800000 please
Sorry we don't have coconuts
FruitShop
:
class FruitShop:
def __init__(self, name, fruitPrices):
"""
name: Name of the fruit shop
fruitPrices: Dictionary with keys as fruit
strings and prices for values e.g.
{'apples':2.00, 'oranges': 1.50, 'pears': 1.75}
"""
self.fruitPrices = fruitPrices
self.name = name
print 'Welcome to the %s fruit shop' % (name)
def getCostPerPound(self, fruit):
"""
fruit: Fruit string
Returns cost of 'fruit', assuming 'fruit'
is in our inventory or None otherwise
"""
if fruit not in self.fruitPrices:
print "Sorry we don't have %s" % (fruit)
return None
return self.fruitPrices[fruit]
def getPriceOfOrder(self, orderList):
"""
orderList: List of (fruit, numPounds) tuples
Returns cost of orderList. If any of the fruit are
"""
totalCost = 0.0
for fruit, numPounds in orderList:
costPerPound = self.getCostPerPound(fruit)
if costPerPound != None:
totalCost += numPounds * costPerPound
return totalCost
def getName(self):
return self.name
The FruitShop
class has some data, the name of the shop and the prices per pound
of some fruit, and it provides functions, or methods, on this data. What advantage is there to wrapping this data in a class? There are two
reasons: 1) Encapsulating the data prevents it from being altered or used
inappropriately and 2) The abstraction that objects provide make it
easier to write general-purpose code.
FruitShop
implementation from here and save it to a file called shop.py
. We then import the file using import shop
, since shop.py
is the name of the file, and make instances of the FruitShop
by calling shop.FruitShop('MyFruitShop', myDictionary)
(i.e., filename.className([args])
). We can use the FruitShop
as follows:
import shop
name = 'Best Fruits'
fruitPrices = {'apples':2.00, 'oranges': 1.50, 'pears': 1.75}
myFruitShop = shop.FruitShop(name, fruitPrices)
print myFruitShop.getCostPerPound('apples')
otherName = 'Fruits R Us'
otherFruitPrices = {'kiwis':1.00, 'bananas': 1.50, 'peaches': 2.75}
otherFruitShop = shop.FruitShop(otherName, otherFruitPrices)
print otherFruitShop.getCostPerPound('bananas')
Copy the code above into a file called shopTest.py (in the same
directory as shop.py) and run it:
$ python shopTest.py
Welcome to the Best Fruits fruit shop
2.0
Welcome to the Fruits R Us fruit shop
1.5
person_class.py
containing the following code:
class Person:
population = 0
def __init__(self, myAge):
self.age = myAge
Person.population += 1
def get_population(self):
return Person.population
def get_age(self):
return self.age
We first compile the script:
$ python person_class.py
>>> import person_class
>>> p1 = person_class.Person(12)
>>> p1.get_population()
1
>>> p2 = person_class.Person(63)
>>> p1.get_population()
2
>>> p2.get_population()
2
>>> p1.get_age()
12
>>> p2.get_age()
63
In the code above, age
is an instance variable and population
is a static variable.
population
is shared by all instances of the Person
class whereas each instance has its own age
variable.
shopSmart(orders,shops)
which takes an orderList
(like the kind passed in to FruitShop.getPriceOfOrder
) and a list of FruitShop
and returns the FruitShop
where your order costs
the least amount in total.
This function should be defined in a file called shopSmart.py
.
A stub implementation is provided here.
Use the shop.py
implementation as a "support" file.
Test Case:
orders1 = [('apples',1.0), ('oranges',3.0)]
orders2 = [('apples',3.0)]
dir1 = {'apples': 2.0, 'oranges':1.0}
shop1 = shop.FruitShop('shop1',dir1)
dir2 = {'apples': 1.0, 'oranges': 5.0}
shop2 = shop.FruitShop('shop2',dir2)
shops = [shop1, shop2]
The following are true:
shopSmart.shopSmart(orders1, shops).getName() == 'shop1'
and
shopSmart.shopSmart(orders2, shops).getName() == 'shop2'
reload
command:
>>> reload(shop)
>>> from numpy import *
>>> array([1,2,3,4,5])
array([1, 2, 3, 4, 5])
>>> array([1,2,3,4,5]) / 5
array([0, 0, 0, 0, 1])
>>> array([1.0,2,3,4,5])
array([ 1., 2., 3., 4., 5.])
>>> array([1.0,2,3,4,5]) / 5.0
array([ 0.2, 0.4, 0.6, 0.8, 1. ])
NumPy differentiates between integer vectors (called arrays) and real vectors. You can also specify the type directly:
>>> array([1,2,3,4,5], dtype='f') / 5
array([0.2, 0.4, 0.6, 0.8, 1.], dtype=float32)
We can do dot products:
>>> dot(array([1,2,3,4,5]), array([2,3,4,5,6]))
70
And matrix operations:
>>> array([[1,2,3],[4,5,6],[7,8,9]])
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
>>> array([[1,2,3],[4,5,6],[7,8,9]]).T
array([[1, 4, 7],
[2, 5, 8],
[3, 6, 9]])
>>> array([[1,2,3],[4,5,6],[7,8,9]]) * array([1,10,20])
array([[ 1, 20, 60],
[ 4, 50, 120],
[ 7, 80, 180]])
>>> dot(array([[1,2,3],[4,5,6],[7,8,9]]), array([1,10,20]))
array([ 81, 174, 267])
Here,
Indexing is straightforward:
>>> x = array([[1,2,3,4],[5,6,7,8]])
>>> x
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
>>> x[1,1]
6
>>> x[0,3]
4
>>> x[0,:]
array([1, 2, 3, 4])
>>> x[:,0]
array([1, 5])
>>> x[:,0:2]
array([[1, 2],
[5, 6]])
You can use arrays to index into other arrays. For instance, perhaps we want to extract all values of x that are greater than 5 and maybe sum them up:
>>> x>5
array([[False, False, False, False],
[False, True, True, True]], dtype=bool)
>>> x[x>5]
array([6, 7, 8])
>>> sum(x[x>5])
21
>>> (x>2) & (x<7)
array([[False, False, True, True],
[ True, True, False, False]], dtype=bool)
>>> x[(x>2) & (x<7)]
array([3, 4, 5, 6])
You can even do assignment within slices:
>>> x
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
>>> x[x>5]
array([6, 7, 8])
>>> x[x>5] = 5
>>> x
array([[1, 2, 3, 4],
[5, 5, 5, 5]])
>>> from pylab import randn, hist
>>> x = randn(10000)
>>> hist(x, 100)
>>> show()
This should pop up a histogram showing something that looks
approximately Gaussian. The randn function is generating 10k
random values from a standard normal and hist is generating
the histogram.
>>> plot(x,sin(x/50*math.pi),'b-', x,cos(x/50*math.pi),'r--');
>>> legend( ('sin','cos') )
>>> show()
Solution:
When using import
, do not include the ".py" from the filename.
For example, you should say: import shop
NOT: import shop.py
Solution:
To access a member of a module, you have to type MODULE_NAME.MEMBER_NAME
, where MODULE_NAME
is the name of the .py
file, and MEMBER_NAME
is the name of the variable (or function) you are trying to access.
Solution:
Dictionary looks up are done using square brackets: [ and ]. NOT parenthesis: ( and ).
Solution:
Make sure the number of variables you are assigning in a for
loop matches the number of elements in each item of the list.
Similarly for working with tuples.
For example, if pair
is a tuple of two elements (e.g. pair =('apple', 2.0)
) then the following code would cause the "too many values to unpack error":
(a,b,c) = pair
Here is a problematic scenario involving a for
loop:
pairList = [('apples', 2.00), ('oranges', 1.50), ('pears', 1.75)] for fruit, price, color in pairList: print '%s fruit costs %f and is the color %s' % (fruit, price, color)
Solution:
Finding length of lists is done using len(NAME OF LIST)
.
Solution:
reload(YOUR_MODULE)
to guarantee your changes are being reflected.
reload
works similar to import
.