You may find the Troubleshooting section helpful if you run into problems. It contains a list of the frequent problems previous students have encountered when following this tutorial.
python
at the Unix command prompt.
$ python3
Python 3.6.8 (default, Jan 14 2019, 11:02:34)
[GCC 8.0.1 20180414 (experimental) [trunk revision 259383]] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> exit()
>>>
) they will
be evaluated and the result wil be returned on the next line.
>>> 1 + 1
2
>>> 2 * 3
6
Boolean operators also exist in Python to manipulate the primitive True
and False
values.
>>> 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.
>>> 'artificial' + "intelligence"
'artificialintelligence'
>>> 'artificial'.upper()
'ARTIFICIAL'
>>> 'HELP'.lower()
'help'
>>> len('Help')
4
' '
or double quotes " "
to surround string. This allows for easy nesting of strings.
>>> 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:
Try out some of the string functions listed in
>>> 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:
>> s.find('b')
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.
1
dir
(ignore those with underscores '_' around the method name).
>>> 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:
>>> fruits[-1]
'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']]
dir
and
get information about them via the help
command:
>>> dir(list)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__',
'__delslice__', '__doc__', '__eq__', '__ge__', '__getattribute__',
'__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__',
'__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__',
'__rmul__', '__setattr__', '__setitem__', '__setslice__', '__str__',
'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse',
'sort']
>>> help(list.reverse) Help on built-in function reverse: reverse(...) L.reverse() -- reverse *IN PLACE*
>>> lst = ['a','b','c']
>>> lst.reverse()
>>> ['c','b','a']
Note: Ignore functions with underscores "_" around the names; these are private helper methods.
>>> 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. Exceptions indicate errors: index out of bounds errors, type errors, and so on will all report exceptions in this way.
>>> 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.
Exercise: Use dir
and help
to learn about the functions you can call on dictionaries.
for
loop. Open a file in your favorite editor
called foreach.py
and enter the following code:
# This is what a comment looks like
# Here is a list of fruits for sale
fruits = ['apples','oranges','pears','bananas']
for fruit in fruits:
print(fruit + ' for sale')
# Here is a dictionary mapping fruit names to prices
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!')
At the command line, use the following command in the directory
containing foreach.py
:
$ python foreach.py
apples for sale
oranges for sale
pears for sale
bananas for sale
oranges cost 1.500000 a pound
pears cost 1.750000 a pound
apples are too expensive!
if else
and for
loops) in Python, check out the official Python tutorial section on this topic.
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 is in a file called listcomp.py
. Then you can run it like this:
$ python3 listcomp.py
[1,3,5]
[2,4,6]
Exercise: Write a list comprehension which, from a
list of strings, generates a lowercased version of each string that has length
greater than five. Call your solution listcomp2.py
.
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 program 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!
def
as
shown below. Notice that all of the commands indented under
the def
become part of the function definition. In a file
called fruit.py
, save this program:
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))
def main():
buyFruit('apples',2.4)
buyFruit('coconuts',2)
main()
Then execute this program:
$ python3 fruit.py
That'll be 4.800000 please
Sorry we don't have coconuts
Exercise: Implement
the buyLotsOfFruit(orderList)
function in a program
called buyLotsOfFruit.py
which takes a list
of (fruit,pound)
tuples and returns the cost of your
list. If there is some fruit
in the list which doesn't
appear in fruitPrices
it should print an error message
and return None
, which is a special value in Python,
like null in C or C++.
Test Case: Check your code by testing that the program correctly outputs:
Cost of [('apples', 3.0), ('pears', 1.0), ('oranges', 2.0)] is 10.75
FruitShop
.
All of the methods are indented beneath the initial line that defines
the class. Each method has comments, enclosed within a triple quoted
block, describing its parameters and purpose. The first method,
called __init__
, is the constructor for the class. Notice
that all of the methods have a first parameter
named self
, which will be explained when we test this
class.
Copy this code into a file called shop.py
.
class FruitShop(object):
def __init__(self, name, fruitPrices):
"""
name: Name of the fruit shop
fruitPrices: Dictionary with keys as fruit strings and
prices for values, such as:
{'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 it is in the dictionary
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 for all available fruit
"""
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?
import
shop
, since shop.py
is the name of the file.
Then, we can create FruitShop
objects as follows:
import shop
shopName = 'the Berkeley Bowl'
fruitPrices = {'apples': 1.00, 'oranges': 1.50, 'pears': 1.75}
berkeleyShop = shop.FruitShop(shopName, fruitPrices)
applePrice = berkeleyShop.getCostPerPound('apples')
print(applePrice)
print('Apples cost $%.2f at %s.' % (applePrice, shopName))
otherName = 'the Stanford Mall'
otherFruitPrices = {'kiwis':6.00, 'apples': 4.50, 'peaches': 8.75}
otherFruitShop = shop.FruitShop(otherName, otherFruitPrices)
otherPrice = otherFruitShop.getCostPerPound('apples')
print(otherPrice)
print('Apples cost $%.2f at %s.' % (otherPrice, otherName))
print("My, that's expensive!")
Copy the above code into a file called shopTest.py
. Then
you can execute it like this:
$ python3 shopTest.py
Welcome to the Berkeley Bowl fruit shop
1.0
Apples cost $1.00 at the Berkeley Bowl.
Welcome to the Stanford Mall fruit shop
4.5
Apples cost $4.50 at the Stanford Mall.
My, that's expensive!
So what just happended? The import shop
statement told
Python to load all of the functions and classes
in shop.py
. The line berkeleyShop =
shop.FruitShop(shopName, fruitPrices)
constructs
an instance of the FruitShop
class defined
in shop.py, by calling the __init__
function in
that class. Note that we only passed two arguments in,
while __init__
seems to take three
arguments: (self, name, fruitPrices)
. The reason for this
is that all methods in a class have self
as the first
argument. The self
variable's value is automatically set
to the object itself; when calling a method, you only supply the
remaining arguments. The self
variable contains all the
data (name
and fruitPrices
) for the current
specific instance.
shopSmart.py
, that contains a
function shopSmart(orders,shops)
, which takes
an orderList
(like the kind passed in
to FruitShop.getPriceOfOrder
) and a list
of FruitShop
objects and returns
the FruitShop
where your order costs the least amount in
total.
Test Case: Check that, with the following variable definitions:
order1 = [('apples',1.0), ('oranges',3.0)]
order2 = [('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(order1, shops).getName() == 'shop1'
and
shopSmart(order2, shops).getName() == 'shop2'
range
to generate a sequence of integers, useful for generating traditional indexed for
loops:
for index in range(3): print lst[index]
try
and except
to catch errors.
For example, suppose you have a dictionary that is keyed on strings
with integer values. The following snippet of code will produce an
error:d = {} d['a'] = 1 d['b'] = 2 d['c'] = 3 for letter in ['a', 'b', 'c', 'd', 'e']: print letter, "is a key with value", d[letter]One option for handling this problem is to wrap the problematic code in a try-except as shown below:
for letter in ['a', 'b', 'c', 'd', 'e']: print letter, try: value = d[letter] print "is a key with value", value except: print "is NOT a key"You can also catch an error and do nothing as shown here:
for letter in ['a', 'b', 'c', 'd', 'e']: try: value = d[letter] print letter, "is a key with value", value except: passYou can read more about handling exceptions.
reload
command:
>>> reload(shop)
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 ModuleName.MemberName
, where ModuleName
is the name of the .py
file, and MemberName
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(NameOfList)
.
Solution:
reload(YourModule)
to guarantee your changes are being reflected.
reload
works similar to import
.