# Lecture 8 — Tuples, Modules, Images¶

## Overview¶

• Material for this lecture is drawn from Chapter 4 of Practical Programming.
• We will concentrate on a few topics:
• tuple data type
• image data type
• functions that modify containers
• making use of existing modules
• We will NOT use the media module discussed in the text, opting instead for the more widely-used PILLOW (Python Imaging Library), comprised of multiple modules.
• We will also talk about writing our own modules, and the difference between running and exporting modules.

## Tuple Data Type¶

• A tuple is simply a container like a list. The main distinctions are:

• It uses parantheses instead of square brackets
• More importantly, its entries can not be changed
```>>> x = (4, 5, 10)   # note the parentheses rather than [ ]
>>> print x[0]
4
>>> print x[2]
10
>>> print x[-1]
10
>>> len(x)
3
>>> x[1] = 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment```
• A list can be converted to a tuple, and vice versa.

```>>> L = [ 'a', 6 ]
>>> T = tuple(L)   # T is a copy of L that can not be changed.
>>> print T[0]
a
>>> L[0] = 'b'
>>> print L     # The original list is changed.
['b', 6]
>>> print T     # The tuple created from the list has not.
('a', 6)
>>> L2 = list(T)  # L2 is copy of T as a list object
>>> L2
['a', 6]
```

## What are tuples good for?¶

• Tuples are Python’s way of making multiple assignments.

```>>> 2,3
(2, 3)
>>> x = 2,3
>>> x
(2, 3)
>>> a,b=x
>>> a
2
>>> b
3
>>> c,d=3,4
```
• You can write functions that return multiple values.

```def next_population(bpop, fpop):
bpop_next = (10*bpop)/(1+0.1*bpop) - 0.05*bpop*fpop
bpop_next = int( max(0,bpop_next) )
fpop_next = 0.4 * fpop + 0.02 * fpop * bpop
fpop_next = int( max(0,fpop_next) )
return bpop_next, fpop_next

b = 100
f = 5

bnext, fnext = next_population(b,f)
print bnext, fnext
```

## Example 1: Finding distance between two points¶

• Write a function that takes as input two tuples representing points: (x,y) and returns the distance between them.

## Basics of modules¶

• A collection of Python variables, functions and objects, all stored in a file

• Modules allow code to be shared across many different programs.

• Before we can use a module, we need to import it:

```>>> import module_name
>>> module_name.function()
```
• This means, the functions in the module in the program are known by its name. We can change the name:

```>>> import module_name as new_name
>>> new_name.function()
```
• Finally, we can also import functions in a module like they were defined in our program.

```>>> from module_name import function
>>> function()
```
• Let’s try this with the log() function from math.

## PIL/PILLOW — Python Image Library¶

• PILLOW is a series of modules built around the Image type, our first object type that is not part of the main Python language

• We will use images as a continuing example of what can be done in programming beyond numbers and beyond text.

• See

for more details.

## Images¶

• An image is a two-dimensional matrix of pixel values

• The origin is in the upper left corner, see below:

• Pixel values stored in an image can be:

• RGB — a “three-tuple” consisting of the red, green and blue values, all non-negative integers
• L — a single “gray-scale” integer value representing the brightness of each pixel
• Some basic colors:

Color (red,green,blue) value
Black (0,0,0)
Red (255,0,0)
Green (0,255,0)
Blue (0,0,255)
White (255,255,255)
Light Gray (122,122,122)

## Some important image modules¶

• Image module contains main functions to manipulate images: open, save, resize, crop, paste, create new images, change pixels, etc.
• ImageDraw module contains functions to touch up images by adding text to it, draw ellipses, rectangles, etc.
• ImageFont contains functions to create images of text for a specific font.

## Image Type and Methods¶

• Let us now see some very useful image methods
• im = Image.open(filename) reads an image with the given filename and returns an image object. It assumes the file is stored in the same directory as your script.
• im.show() displays the image
• im.save(filename) saves the image to the given file
• Images have the following constants: im.format, im.size, im.mode
• im.resize((width,height)) resizes an image to a given size.
• im.convert(mode) changes the mode of an image.
• im.crop((w1,h1,w2,h2)) creates a new image by cropping the given box from the current image
• im.transpose(flip_position) creates the mirror reflection of the image in the given direction
• Image.new("RGB",(width,height)) create a new image of given dimensions.

## Our First Image Program¶

```from PIL import Image

filename = "chipmunk.jpg"
im = Image.open(filename)
print '\n' '********************'
print "Here's the information about", filename
print im.format, im.size, im.mode

gray_im = im.convert('L')
scaled = gray_im.resize( (128,128) )
print "After converting to gray scale and resizing,"
print "the image information has changed to"
print scaled.format, scaled.size, scaled.mode

scaled.show()
scaled.save(filename + "_scaled.jpg")
```
• The Image.open function:
• Opens the file and creates an image (new type, remember), and associates it with the variable name im
• format, size, mode are all variables associated with the image, describing
• the image file format — JPG in this case
• the width and height of an image, as a “tuple” (a new Python type we have not yet used)
• the mode of the pixel data in the image — RGB values or gray scale values (indicated by 'L')
• Note that 'RGB' and 'L' are both strings.
• image methods used in this example
• convert to change the mode of the image from RGB to gray
• resize to create a new image of a different size
• The new size is given by the tuple
• show to display the image
• save to output it.

## Example 2: Cut and pasting parts of an image¶

• This example crops three boxes from an image, creates a new image and pastes the boxes at different locations of this new image.

```import Image

im = Image.open("lego_movie.jpg")
w,h = im.size

# Crop out three columns from the image
## Note: the crop function returns a new image
part1 = im.crop((0,0,w/3,h))
part2 = im.crop((w/3,0,2*w/3,h))
part3 = im.crop((2*w/3,0,w,h))

## Create a new image
newim = Image.new("RGB",(w,h))
## Paste the image in different order
## Note: the paste function changes the image it is applied to
newim.paste(part3, (0,0))
newim.paste(part1, (w/3,0))
newim.paste(part2, (2*w/3,0))
newim.show()
```
• Important image methods used (note the distinction of how they work):

• crop — extracts a region of the image given by the upper left and lower right corners represented as a four-tuple, and returns a new image
• paste — overwrites one image with another, starting at the upper left corner. It modifies the image it operates on, but does not return a new image.
• Note that many of the PILLOW functions actually change the image object we are working with

• This is an implementation decision made by the designers of PIL, mostly because images are so large and copying is therefore time consuming.

## Summary¶

• Tuples are similar to strings and numbers in many ways. You cannot change a part of a tuple. However, unlike other simple data types, tuples allow access to the individual components using the list notation.

• Modules contain a combination of functions, variables, object definitions, and other code, all designed for use in other Python programs and modules

• After they are imported, the functions in a module can be executed by a call of the form:

```module_name.function_name(arguments)
```
• PILLOW provides a set of modules that define the Image object type and associated methods.