CHAPTER 2

Python Data Types

2.1 Expressions, Variables, and Assignments

2.2 Strings

2.3 Lists

2.4 Objects and Classes

2.5 Python Standard Library

2.6 Case Study: Turtle Graphics Objects

Chapter Summary

Solutions to Practice Problems

Exercises

IN THIS CHAPTER, we introduce a very small subset of Python. While small, it is broad enough to start doing interesting things right away. In the next chapters we fill in the details. We begin by using Python as a calculator that evaluates algebraic expressions. We then introduce variables as a way to “remember” results of such evaluations. Finally we show how Python works with values other than numbers: values to represent logical values true and false, text values, and lists of values.

Having seen the core types of data supported by Python, we take a step back and define precisely the concept of a data type and that of an object that stores a value of a given type. With data stored in objects, we can ignore how the data is represented and stored in the computer and work only with the abstract but familiar properties that the object's type makes explicit. This idea of abstracting important properties is a central one in computer science to which we come back several times.

In addition to the core, built-in data types, Python comes with a large library of additional types organized into modules. In this chapter's case study, we use the turtle graphics module to visually illustrate the concepts introduced in this chapter: objects, types, and names; data abstraction and classes; and information hiding.

2.1 Expressions, Variables, and Assignments

Let's start with something familiar. We use the Python IDE interactive shell as a calculator to evaluate Python expressions, starting with simple algebraic expressions. Our goal is to illustrate how Python is intuitive and usually behaves the way you would expect.

Algebraic Expressions and Functions

At the interactive shell prompt >>>, we type an algebraic expression, such as 3 + 7, and hit the image key on the keyboard to view the result of evaluating the expression:

>>> 3 + 7
10

Let's try expressions that use different algebraic operators:

>>> 3 * 2
6
>>> 5 / 2
2.5
>>> 4 / 2
2.0

In the first two expressions, integers are added or multiplied and the result is an integer, which is what you expect. In the third expression, an integer is divided by another and the result is shown in decimal point notation. This is because when an integer is divided by another, the result is not necessarily an integer. The rule in Python is to return a number with a decimal point and a fractional part, even when the result is an integer. This is illustrated in the last expression, where integer 4 is divided by 2 and the result shown is 2.0 rather than 2.

Values without the decimal point are said to be of type integer or simply int. Values with decimal points and fractional parts are said to be of type floating point or simply float. Let us continue evaluating expressions using values of both types:

>>> 2 * 3 + 1
7
>>> (3 + 1) * 3
12
>>> 4.321 / 3 + 10
11.440333333333333
>>> 4.321 / (3 + 10)
0.3323846153846154

Multiple operators are used in these expressions, which raises the question: In what order should the operations be evaluated? The standard algebra precedence rules apply in Python: Multiplication and division take precedence over addition and subtraction and, just as in algebra, parentheses are used when we want to explicitly specify the order in which operations should take place. If all else fails, expressions are evaluated from using the left-to-right evaluation rule. This last rule is used in the next expression, where the addition is executed after the subtraction:

>>> 3 - 2 + 1
2

All the expressions we have evaluated so far are plain algebraic expressions involving number values (of type int or type float), algebraic operators (such as +, -, /, and *), and parentheses. When you hit the image key, the Python interpreter will read the expression and evaluate it in a way that you expect. Here is one more, slightly unusual, example of an algebraic expression:

>>> 3
3

Python evaluates expression 3 to… 3.

The two types of number values, int and float, have somewhat different properties. For example, when two int values are added, subtracted, or multiplied, the result is an int value. If at least one float value appears in the expression, however, the result is always a float value. Note that a float value is also obtained when two integer values (e.g., 4 and 2) are divided.

Several other algebraic operators are commonly used. To compute 24, you need to use the exponentiation operator **:

>>> 2**3
8
>>> 2**4
16

So xy is computed using the Python expression x**y.

In order to obtain the integer quotient and the remainder when two integer values are divided, operators // and % are used. The // operator in expression a//b returns the integer quotient obtained when integer a is divided by integer b. The % operator in expression a%b computes the remainder obtained when integer a is divided by integer b. For example:

>>> 14 // 3
4
>>> 14 % 3
2

In the first expression, 14 // 3 evaluates to 4 because 3 goes into 14 four times. In the second expression, 14 % 3 evaluates to 2 because 2 is the remainder when 14 is divided by 3.

Python also supports mathematical functions of the kind you have used in an algebra class. Recall that, in algebra, the notation

f(x) = x + 1

is used to define function f() that takes an input, denoted by x, and returns a value, which is x + 1 in this case. In order to use this function on input value 3, for example, you would use the notation f(3), which evaluates to 4.

Python functions are similar. For example, the Python function abs() can be used to compute the absolute value of a number value:

>>> abs(-4)
4
>>> abs(4)
4
>>> abs(-3.2)
3.2

Some other functions that Python makes available are min() and max(), which return the minimum or maximum, respectively, of the input values:

>>> min(6, -2)
-2
>>> max(6, -2)
6
>>> min(2, -4, 6, -2)
-4
>>> max(12, 26.5, 3.5)
26.5

Practice Problem 2.1

Write Python algebraic expressions corresponding to the following statements:

  1. The sum of the first 5 positive integers
  2. The average age of Sara (age 23), Mark (age 19), and Fatima (age 31)
  3. The number of times 73 goes into 403
  4. The remainder when 403 is divided by 73
  5. 2 to the 10th power
  6. The absolute value of the difference between Sara's height (54 inches) and Mark's height (57 inches)
  7. The lowest price among the following prices: $34.99, $29.95, and $31.50

Boolean Expressions and Operators

Algebraic expressions evaluate to a number, whether of type int or float or one of the other number types that Python supports. In an algebra class, expressions other than algebraic expressions are also common. For example, the expression 2 < 3 does not evaluate to a number; it evaluates to either True or False (True in this case). Python can also evaluate such expressions, which are called Boolean expressions. Boolean expressions are expressions that evaluate to one of two Boolean values: True or False. These values are said to be of Boolean type, a type just like int and float and denoted bool in Python.

Comparison operators (such as < or >) are commonly used operators in Boolean expressions. For example:

>>> 2 < 3
True
>>> 3 < 2
False
>>> 5 - 1 > 2 + 1
True

The last expression illustrates that algebraic expressions on either side of a comparison operators are evaluated before the comparison is made. As we will see later in this chapter, algebraic operators take precedence over comparison operators. For example, in 5 - 1 > 2 + 1, the operators - and + are evaluated first, and then the comparison is made between the resulting values.

In order to check equality between values, the comparison operator == is used. Note that the operator has two = symbols, not one. For example:

>>> 3 == 3
True
>>> 3 + 5 == 4 + 4
True
>>> 3 == 5 - 3
False

There are a few other logical comparison operators:

>>> 3 <= 4
True
>>> 3 >= 4
False
>>> 3 != 4
True

The Boolean expression 3 <= 4 uses the <= operator to test whether the expression on the left (3) is less than or equal to the expression of the right (4). The Boolean expression evaluates to True, of course. The >= operator is used to test whether the operand on the left is greater than or equal to the operand on the right. The expression 3 != 4 uses the != (not equal) operator to test whether the expressions on the left and right evaluate to different values.

Practice Problem 2.2

Translate the following statements into Python Boolean expressions and evaluate them:

  1. The sum of 2 and 2 is less than 4.
  2. The value of 7 // 3 is equal to 1 + 1.
  3. The sum of 3 squared and 4 squared is equal to 25.
  4. The sum of 2, 4, and 6 is greater than 12.
  5. 1,387 is divisible by 19.
  6. 31 is even. (Hint: what does the remainder when you divide by 2 tell you?)
  7. The lowest price among $34.99, $29.95, and $31.50 is less than $30.00.

Just as algebraic expression can be combined into larger algebraic expression, Boolean expressions can be combined together using Boolean operators and, or, and not to form larger Boolean expressions. The and operator applied to two Boolean expressions will evaluate to True if both expressions evaluate to True; if either expression evaluates to False, then it will evaluate to False:

>>> 2 < 3 and 4 > 5
False
>>> 2 < 3 and True
True

Both expressions illustrate that comparison operators are evaluated before Boolean operators. This is because comparison operators take precedence over Boolean operators, as we will see later in this chapter.

The or operator applied to two Boolean expressions evaluates to False only when both expressions are false. If either one is true or if both are true, then it evaluates to True.

>>> 3 < 4 or 4 < 3
True
>>> 3 < 2 or 2 < 1
False

The not operator is a unary Boolean operator, which means that it is applied to a single Boolean expression (as opposed to the binary Boolean operators and and or). It evaluates to False if the expression is true or to True if the expression is false.

>>> not (3 < 4)
False

image George Boole and Boolean Algebra

George Boole (1815–1864) developed Boolean algebra, the foundation upon which the digital logic of computer hardware and the formal specification of programming languages are built.

Boolean algebra is the algebra of values true and false. Boolean algebra includes operators and, or, and not, which can be used to create Boolean expressions, expressions that evaluate to true or false. The truth tables below define how these operators evaluate.

image

Variables and Assignments

Let us continue with our algebra theme for a bit more. As we already know from algebra, it is useful to assign names to values, and we call those names variables. For example, value 3 may be assigned to variable x in an algebra problem as follows: x = 3. The variable x can be thought of as a name that enables us to retrieve value 3 later on. In order to retrieve it, we just need to evaluate x in an expression.

The same can be done in Python. A value can be assigned to a variable:

>>> x = 4

The statement x = 4 is called an assignment statement. The general format of an assignment statement is:

<variable> = <expression>

An expression we refer to as <expression> lies on the right-hand side of the = operator; it can be an algebraic, Boolean, or other kind of expression. On the left-hand side is a variable referred to as <variable>. The assignment statement assigns to <variable> the value that <expression> evaluates to. In the last example, x is assigned value 4.

Once a value has been assigned to a variable, the variable can be used in a Python expression:

>>> x
4

When Python evaluates an expression containing a variable, it will evaluate the variable to its assigned value and then perform the operations in the expression:

>>> 4 * x
16

An expression involving variables may appear on the right side of an assignment statement:

>>> counter = 4 * x

In statement counter = 4 * x, x is first evaluated to 4, then the expression 4 * 4 is evaluated to 16, and then 16 gets assigned to variable counter:

>>> counter
16

So far, we have defined two variable names: x with value 4 and counter with value 16. What about, say, the value of variable z that has not been assigned yet? Let's see:

>>> z
Traceback (most recent call last):
  File “<pyshell#1>”, line 1, in <module>
    z
NameError: name ‘z’ is not defined

Not sure what we expected… but here we got our first (an, unfortunately, not the last) error message. It turns out that if a variable—z in this case—has not been assigned a value, it just does not exist. When Python tries to evaluate an unassigned name, an error will occur and a message (such as name ‘z’ is not defined) is printed out. We will learn more about errors (also called exceptions) in Chapter 4.

Practice Problem 2.3

Write Python statements that correspond to the below actions and execute them:

  1. Assign integer value 3 to variable a.
  2. Assign 4 to variable b.
  3. Assign to variable c the value of expression a * a + b * b.

You may remember from algebra that the value of a variable can change. The same is true with Python variables. For example, suppose that the value of variable x is initially 4:

>>> x
4

Now let's assign value 7 to variable x:

>>> x = 7
>>> x
7

So the assignment statement x = 7 changed the value of x from 4 to 7.

image Assignment and Equality Operators

Be careful to distinguish the assignment statement = and the equality operator ==. This is an assignment statement that assigns 7 to variable x:

>>> x = 7

The following, however, is a Boolean expression that compares the value of variable x with number 7 and returns True if they are equal:

>>> x == 7
True

The expression evaluates to True because variable x has value 7.

Variable Names

The characters making up a variable name can be lowercase and uppercase letters from the alphabet (a through z and A through Z), the underscore character (_), and, except for the first character, digits 0 through 9:

  • myList and _list are OK, but 5list is not.
  • list6 and l_2 are OK, but list-3 is not.
  • mylist and myList are different variable names.

Even when a variable name is “legal” (i.e., follows the rules), it might not be a “good” name. Here are some generally accepted conventions for designing good names:

  • A name should be meaningful: Name price is better than name p.
  • For a multiple-word name, use either the underscore as the delimiter (e.g., temp_var and interest_rate) or use camelCase capitalization (e.g., tempVar, TempVar, interestRate or InterestRate); pick one style and use it consistently throughout your program.
  • Shorter meaningful names are better than longer ones.

In this textbook, all variable names start with a lowercase character.

image Variable Names in Python 3 and Beyond

The restriction on the characters used for variable names is true only for Python versions before 3.0. Those versions of Python use the ASCII character encoding (which includes characters in the English alphabet only and is described in more detail in Chapter 6) as the default character set.

Starting with Python 3.0, the Unicode character encoding (also discussed in Chapter 6) is the default character encoding. With this change, many more characters (e.g., Cyrillic, Chinese, or Arabic characters) can be used in variable names. The change reflects the important social and economic role that globalization has in today's world.

At this moment, most programming languages still require names of variables and other objects to use the ASCII character encoding. For this reason, while this textbook follows the Python 3.0 and later standards, we restrict ourselves to the ASCII character encoding when devising variable names.

The below names are used as reserved keywords of the Python language. You cannot use them other than as Python commands.

False   break      else      if         not    while
None    class      except    import     or     with
True    continue   finally   in         pass   yield
and     def        for       is         raise
as      del        from      lambda     return
assert  elif       global    nonlocal   try

2.2 Strings

In addition to number and Boolean types, Python supports a large number of other, more complex, types. The Python string type, denoted str, is used to represent and manipulate text data or, in other words, a sequence of characters, including blanks, punctuation, and various symbols. A string value is represented as a sequence of characters that is enclosed within quotes:

>>> ‘Hello,   World!’
‘Hello,   World!’
>>> s =  ‘hello’
>>> s
‘hello’

The first expression, ‘Hello, world!’, is an expression that contains just one string value and it evaluates to itself, just as expression 3 evaluates to 3. The statement s = ‘hello’ assigns string value ‘hello’ to variable s. Note that s evaluates to its string value when used in an expression.

String Operators

Python provides operators to process text (i.e., string values). Like numbers, strings can be compared using comparison operators: ==, !=, <, >, and so on. Operator ==, for example, returns True if the strings on either side of the operator have the same value:

>>> s ==  ‘hello’
True
>>> t =  ‘world’
>>> s != t
True
>>> s == t
False

While == and != test whether two strings are equal or not, the comparison operators < and > compare strings using the dictionary order:

>>> s < t
True
>>> s > t
False

(For now, we appeal to intuition when referring to dictionary order; we define it precisely in Section 6.3.)

The + operator, when applied to two strings, evaluates to a new string that is the concatenation (i.e., the joining) of the two strings:

>>> s + t
‘helloworld’
>>> s +  ‘ ’  + t
‘hello world’

In the second example, the names s and t are evaluated to the string values ‘hello’ and ‘world’, respectively, which are then concatenated with the single blank space string ‘ ’. If we can add two strings, can we, perhaps, multiply them?

>>> ‘hello ’ * ‘world’

Traceback (most recent call last):
  File “<pyshell#146>”, line 1, in <module>
    ‘hello ’ * ‘world’
TypeError: cannot multiply sequence by non-int of type ‘str’

Well… it doesn't look like we can. If you take a moment and think about it, it is not really clear what multiplying two strings would mean anyway. Adding them (i.e., concatenating them) makes more sense. Overall, the design of the Python programming language and the meaning of the standard operators (+, *, /, etc.) for various types of values (integer, floating point, Boolean, string, etc.) is intuitive. So, intuitively, what do you think should happen when a string gets multiplied by an integer? Let's try it:

>>> 3 * ‘A’
‘AAA’
>>> ‘hello ’ * 2
‘hello hello ’
>>> 30 * ‘-’
‘------------------------------ ’

Multiplying a string s by an integer k gives us a string obtained by concatenating k copies of string s. Note how we easily obtained a line (useful for presenting your simple text output, say) by multiplying string ‘-’ 30 times.

With the in operator, we can check whether a character appears in a string:

>>> s =  ‘hello’
>>> ‘h’  in s
True
>>> ‘g’  in s
False

Table 2.1 String operators. Only a few commonly used string operators are shown; many more are available. To obtain the full list in your interactive shell, use the help() documentation function: >>> help(str)

Usage Explanation
x in s True if string x is a substring of string s, and false otherwise
x not in s False if string x is a substring of string s, and true otherwise
s + t Concatenation of string s and string t
s * n, n * s Concatenation of n copies of s
s[i] Character of string s at index i
len(s) Length of string s

The in operator also can be used to check whether a string appears in another:

>>> ‘ll’ in s
True

Since ‘ll’ appears in string s, we say that ‘ll’ is a substring of s.

The length of a string can be computed using the len() function:

>>> len(s)
5

In Table 2.1, we summarize the usage and explanation for commonly used string operators.

Practice Problem 2.4

Start by executing the assignment statements:

>>> s1 = ‘ant’
>>> s2 = ‘bat’
>>> s3 = ‘cod’

Write Python expressions using s1, s2, and s3 and operators + and * that evaluate to:

  1. ‘ant bat cod’
  2. ‘ant ant ant ant ant ant ant ant ant ant ’
  3. ‘ant bat bat cod cod cod’
  4. ‘ant bat ant bat ant bat ant bat ant bat ant bat ant bat ’
  5. ‘batbatcod batbatcod batbatcod batbatcod batbatcod ’

Indexing Operator

The individual characters of a string can be accessed using the indexing operator []. We define the concept of an index first. The index of a character in a string is the character's offset (i.e., position in the string) with respect to the first character. The first character has index 0, the second has index 1 (because it is one away from the first character), the third character has index 2, and so on. The indexing operator [] takes a nonnegative index i and returns a string consisting of the single character at index i (see Figure 2.1):

>>> s[0]
‘h’
>>> s[1]
‘e’
>>> s[4]
‘o’

image

Figure 2.1 The string index and index operator. Index 0 refers to the first character, while index i refers to the character that is i positions to the right of the first character. Expression s[0], using the indexing operator [], evaluates to string ‘h’; s[1] evaluates to ‘e’; s[4] evaluates to ‘o’.

Practice Problem 2.5

Start by executing the assignment:

s = ‘0123456789’

Now write expressions using string s and the indexing operator that evaluate to:

  1. ‘0’
  2. ‘1’
  3. ‘6’
  4. ‘8’
  5. ‘9’

Negative indexes may be used to access the characters from the back (right side) of the string. For example, the last character and second to last can be retrieved using negative indexes -1 and -2, respectively (see also Figure 2.2):

>>> s[-1]
‘o’
>>> s[-2]
‘l’

image

Figure 2.2 Index operator using negative indexes. The index -1 refers to the last character; so s[-1] evaluates to string ‘o’. s[-2] evaluates to ‘l’.

We have only scratched the surface of the text-processing capabilities of Python. We will come back to strings and text processing several times in this textbook. For now, we continue our tour of Python's data types.

2.3 Lists

In many situations we organize data into a list: a shopping list, a list of courses, a list of contacts on your cell phone, a list of songs in your audio player, and so on. In Python, lists are usually stored in a type of object called a list. A list is a sequence of objects. The objects can be of any type: numbers, strings, even other lists. For example, here is how we would assign to the variable pets the list of strings representing several pets:

>>> pets = [‘goldfish’, ‘cat’, ‘dog’]

The variable pets evaluates to the list:

>>> pets
[‘goldfish’, ‘cat’, ‘dog’]

In Python, a list is represented as a comma-separated sequence of objects enclosed within square brackets. An empty list is represented as []. Lists can contain items of different types. For example, the list named things in

>>> things = [‘one’, 2, [3, 4]]

has three items: the first is string ‘one’, the second is integer 2, and the third item is list [3, 4].

List Operators

Most of the string operators we have seen in the previous section can be used on lists in similar ways. For example, the items in the list may be accessed individually using the indexing operator, just as individual characters can be accessed in a string:

>>> pets[0]
‘goldfish’
>>> pets[2]
‘dog’

Figure 2.3 illustrates the list pets along with the indexing of the list items. Negative indexes can be used too:

>>> pets[-1]
‘dog’

image

Figure 2.3 A list of string objects. List pets is a sequence of objects. The first object, at index 0, is string ‘goldfish’. Positive and negative indexes can be used, just like for strings.

Table 2.2 List operators and functions. Only some of the commonly used list operators are shown here. To obtain the full list in your interactive shell, use the help() documentation function: >>> help(list)

Usage Explanation
x in lst True if object x is in list lst, false otherwise
x not in lst False if object x is in list lst, true otherwise
lstA + lstB Concatenation of lists lstA and lstB
lst * n, n * lst Concatenation of n copies of list lst
lst[i] Item at index i of list lst
len(lst) Length of list lst
min(lst) Smallest item in list lst
max(lst) Largest item in list lst
sum(lst) Sum of items in list lst

The length of a list (i.e., the number of items in it) is computed using function len():

>>> len(pets)
3

Like strings, lists can be “added,” meaning that they can be concatenated. They can also be “multiplied” by an integer k, which means that k copies of the list are concatenated:

>>> pets + pets
[‘goldfish’,  ‘cat’ , ‘dog’ , ‘goldfish’ , ‘cat’ , ‘dog’ ]
>>> pets * 2
[‘goldfish’,  ‘cat’ , ‘dog’ , ‘goldfish’ , ‘cat’ , ‘dog’ ]

If you want to check whether string ‘rabbit’ is in the list, you can use the in operator in a Boolean expression that evaluates to True if string ‘rabbit’ appears in list pets:

>>> ‘rabbit’ in pets
False
>>> ‘dog’ in pets
True

In Table 2.2 we summarize the usage of some of the string operators. We include in the table functions min(), max(), and sum(), which can take a list as input and return the smallest item, the largest item, or the sum of the items, respectively, in the list:

>>> lst = [23.99, 19.99, 34.50, 120.99]
>>> min(lst)
19.99
>>> max(lst)
120.99
>>> sum(lst)
199.46999999999997

Practice Problem 2.6

First execute the assignment

words = [‘bat’, ‘ball’, ‘barn’, ‘basket’, ‘badminton’]

Now write two Python expressions that evaluate to the first and last, respectively, word in words, in dictionary order.

Lists Are Mutable, Strings Are Not

An important property of lists is that they are mutable. What that means is that the content of a list can be changed. For example, suppose that we want to be more specific about the type of cat in list pets. We would like pets[1] to evaluate to ‘cymric cat’ instead of just plain ‘cat’. To do this, we assign ‘cymric cat’ to pets[1]:

>>> pets[1] = ‘cymric cat’
>>> pets
[‘goldfish’, ‘cymric cat’, ‘dog’]

So, the list no longer contains the string ‘cat’ at index 1; instead, it contains the string ‘cymric cat’.

While lists are mutable, string are not. What that means is that we cannot change the individual characters of a string value. For example, suppose that we misspelled the type of cat:

>>> myCat = ‘cymric bat’

We would like to correct the mistake by changing the character at index 7 from a ‘b’ to a ‘c’. Let's try:

>>> myCat[7] =  ‘c’
Traceback (most recent call last):
  File  “<pyshell#35>”, line 1, in <module>
    myCat[7] =  ‘c’
TypeError:  ‘str’  object does not support item assignment

The error message essentially says that individual characters (items) of a string cannot be changed (assigned to). We say that strings are immutable. Does that mean that we are stuck with a misspelled value for myCat? No, not at all. We can simply reassign a brand new value to variable myCat:

>>> myCat = ‘cymric cat’
>>> myCat
‘cymric cat’

We will discuss assignments to strings and list—and other immutable and mutable types—further in Section 3.4.

List Methods

We have seen functions that operate on lists such as, for example, the min() function:

>>> numbers = [6, 9, 4, 22]
>>> min(numbers)
4

In expression min(numbers), we say that function min() is called with one input argument, the list numbers.

There are also functions that are called on lists. For example, to add ‘guinea pig’ to list pets, we would call function append() on list pets as follows:

>>> pets.append(‘guinea pig’)
>>> pets
[‘goldfish’, ‘cymric cat’, ‘dog’, ‘guinea pig’]

Let's do this again and add another ‘dog’ to list pets:

>>> pets.append(‘dog’)
>>> pets
[‘goldfish’, ‘cymric cat’, ‘dog’, ‘guinea pig’, ‘dog’]

Note the special way the function append() is called:

pets.append(‘guinea pig’)

What this notation means is that function append() is called on list pets with input ‘guinea pig’. The effect of executing the statement pets.append('guinea pig') is that the input argument ‘guinea pig’ is added at the end of list pets.

The function append() is a list function. What this means is that function append() cannot be called on its own; it always has to be called on some list lst, using the notation lst.append(). We will refer to such functions as methods.

Another example of a list method is the count() method. When called on a list with an input argument, it returns the number of times the input argument appears in the list:

>>> pets.count(‘dog’)
2

Again, we say that method count() is called on list pets (with input argument ‘dog’).

To remove the first occurrence of ‘dog’, we can use the list method remove():

>>> pets.remove(‘dog’)
>>> pets
[‘goldfish’, ‘cymric cat’, ‘guinea pig’, ‘dog’]

The list method reverse() reverses the order of the objects:

>>> pets.reverse()
>>> pets
[‘dog’, ‘guinea pig’, ‘cymric cat’, ‘goldfish’]

Some commonly used list methods are shown in Table 2.3. You can view a listing of all list methods in the interactive shell using the help() documentation function:

>>> help(list)
Help on class list in module builtins:
…

Table 2.3 Some list methods. Functions append(), insert(), pop(), remove(), reverse(), and sort() modify the list lst. To obtain the full listing of list methods in your interactive shell, use the help() documentation function: >>> help(list)

Usage Explanation
lst.append(item) Adds item to the end of list lst
lst.count(item) Returns the number of occurrences of item in list lst
lst.index(item) Returns the index of the first occurrence of item in list lst
lst.insert(index, item) Inserts item into list just before index index
lst.pop() Removes last item in the list
lst.remove(item) Removes first occurrence of item in the list
lst.reverse() Reverses the order of items in the list
lst.sort() Sorts the list

The sort() method sorts the items in the list in increasing order, using the ordering that “naturally” applies to the objects in the list. Since list pets contains string objects, the order will be lexicographical (i.e., dictionary order):

>>> pets.sort()
>>> pets
[‘cymric cat’, ‘dog’, ‘goldfish’, ‘guinea pig’]

A list of numbers would be sorted using the usual increasing number order:

>>> lst = [4, 2, 8, 5]
>>> lst.sort()
>>> lst
[2, 4, 5, 8]

What would happen if we tried to sort a list containing numbers and strings? Since strings and integers cannot be compared, the list cannot be sorted and an error would occur. Check it.

Practice Problem 2.7

Given the list of student homework grades

>>> grades = [9, 7, 7, 10, 3, 9, 6, 6, 2]

write:

  1. An expression that evaluates to the number of 7 grades
  2. A statement that changes the last grade to 4
  3. An expression that evaluates to the maximum grade
  4. A statement that sorts the list grades
  5. An expression that evaluates to the average grade

2.4 Objects and Classes

We have so far seen how to use several types of values that Python supports: int, float, bool, str, and list. Our presentation has been informal to emphasize the often-intuitive approach Python uses to manipulate values. Intuition takes us only so far, though. At this point, we step back for a moment to understand more formally what we mean by a type, and by operators and methods supported by the type.

In Python, every value, whether a simple integer value (such as 3) or a more complex value (such as the string ‘Hello, World!’ or the list [‘hello’, 4, 5]) is stored in memory as an object. It is useful to think of an object as a container for the value that sits inside your computer's memory.

The container idea captures the motivation behind objects. The actual representation and processing of, say, integer values on a computer system is quite complicated. Doing arithmetic with integer values, however, is quite straightforward. Objects are containers for values, integer or other, that hide the complexity of integer storage and processing and provide the programmer with the only the information that she needs: the value of the object and what kind of operations can be applied to it.

Object Type

Every object has associated with it a type and a value. We illustrate this in Figure 2.4 with four objects: an integer object with value 3, a floating point object with value 3.0, a string object with value ‘Hello World’, and a list object with value [1, 1, 2, 3, 5, 8].

image

Figure 2.4 Four objects. Illustrated are four objects of different types. Each object has a type and a value.

An object's type indicates what kind of values the object can hold and what kind of operations can be performed on the object. The types we have seen so far include the integer (int), floating point (float), Boolean (bool), string (str), and list (list) types. The Python type() function can be used to determine an object's type:

>>> type(3)
<class ‘int’>
>>> type(3.0)
<class ‘float’>
>>> type(‘Hello World’)
<class ‘str’>
>>> type([1, 1, 2, 3, 5, 8])
<class ‘list’>

When used on a variable, the type() function will return the type of the object the variable refers to:

>>> a = 3
>>> type(a)
<class ‘int’>

image Variables Do Not Have a Type

It is important to note that a variable does not have a type. A variable is just a name. Only the object it refers to has a type. So, when we see

>>> type(a)
<class ‘int’>

it really means that the object that variable a currently refers to is of type integer.

We emphasize currently because the type of object that a refers to may change. For example, if we assign 3.0 to a:

a = 3.0

then a will refer to a float value:

>>> type(a)
<class ‘float’>

The Python programming language is said to be object-oriented because values are always stored in objects. In programming languages other than Python, values of certain types are not stored in abstract entities such as objects but explicitly in memory. The term class is used to refer to types whose values are stored in objects. Because every value in Python is stored in an object, every Python type is a class. In this book, we will use class and type interchangeably.

Earlier in this chapter, we introduced several Python number types informally. To illustrate the concept of the object's type, we now discuss their behaviors more precisely.

Valid Values for Number Types

Every object has a value that must be legal for the object's type. For example, an integer object can have value 3 but not 3.0 or ‘three’. The integer values can be arbitrarily large. For example, we can create an integer object whose value is 21024:

>>> x = 2**1024
>>> x
17976931348623159077293051907890247336179769789423065727343008
…
7163350510684586298239947245938479716304835356329624224137216

Actually, there is a limit to how large the value stored in an integer object can be: The value is limited by the available computer memory. This is simply because it is not possible to store an integer value that has more digits than can be stored in the computer memory.

The Python floating point (float) type is is used to represent real numbers as fractions with finite decimal representations:

>>> pi = 3.141592653589793
>>> 2.0**30
1073741824.0

While integer values can have an arbitrarily large number of digits (limited only by the size of the computer memory), the number of bits used to represent float values is limited, typically to 64 bits on today's laptop and desktop computers. This implies several things. First, this means that very, very large numbers cannot be represented:

>>> 2.0**1024
Traceback (most recent call last):
  File “<pyshell#92>”, line 1, in <module>
    2.0**1024
OverflowError: (34, ‘Result too large’)

An error occurs when we attempt to define a float value that requires more bits than is available to represent float values. (Note that this can occur only with floating point values; the integer value 2**1024 is OK, as we have already seen.) Also, smaller fractional values will only be approximated rather than represented exactly:

>>> 2.0**100
1.2676506002282294e+30

What does this notation mean? This notation is called scientific notation, and it represents the value 1.2676506002282294 · 1030. Compare this with the full precision of the corresponding integer value:

>>> 2**100
1267650600228229401496703205376

Small fractional values will also be approximated:

>>> 2.0**-100
7.888609052210118e-31

and very small values are approximated by 0:

>>> 2.0**-1075
0.0

Operators for Number Types

Python provides operators and built-in mathematical functions like abs() and min() to construct algebraic expressions. Table 2.4 lists the arithmetic expression operators available in Python.

Table 2.4 Number-type operators. Listed are the operators that can be used on number objects (e.g., bool, int, float). If one of the operands is a float, the result is always a float value; otherwise, the result is an int value, except for the division (/) operator, which always gives a float value.

image

For every operation other than division (/), the following holds: If both operands x and y (or just x for unary operations - and abs()) are integers, the result is an integer. If one of the operands is a float value, the result is a float value. For division (/), the result is a float value, regardless of the operands.

Comparison operators are used to compare values. There are six comparison operations in Python, as shown in Table 2.5. Note that in Python, comparisons can be chained arbitrarily:

>>> 3 <= 3 < 4
True

When an expression contains more than one operator, evaluating the expression requires that an order is specified. For example, does the expression 2 * 3 + 1 evaluate to 7 or 8?

>>> 2 * 3 + 1
7

Table 2.5 Comparison operators. Two numbers of the same or different type can be compared with the comparison operators.

Operation Description
< Less than
<= Less than or equal
> Greater than
>= Greater than or equal
== Equal
!= Not equal

Table 2.6 Operator precedence. The operators are listed in order of precedence from highest on top to lowest at the bottom; operators in the same row have the same precedence. Higher-precedence operations are performed first, and equal precedence operations are performed in left-to-right order.

Operator Description
[expressions…] List definition
x[], x[index:index] Indexing operator
** Exponentiation
+x, -x Positive, negative signs
*, /, //, % Product, division, integer division, remainder
+, - Addition, subtraction
in, not in, <, <=, >, >=, <>, !=, == Comparisons, including membership and identity tests
not x Boolean NOT
and Boolean AND
or Boolean OR

The order in which operators are evaluated is defined either explicitly using parentheses or implicitly using either the operator precedence rules or the left-to-right evaluation rule if the operators have the same precedence. The operator precedence rules in Python follow the usual algebra rules and are illustrated in Table 2.6. Note that relying on the left-to-right rule is prone to human error, and good developers prefer to use parentheses instead. For example, rather than relying on the left-to-right rule to evaluate expression:

>>> 2 - 3 + 1
0

a good developer would use parentheses to clearly indicate her intent:

>>> (2 - 3) + 1
0

Practice Problem 2.8

In what order are the operators in the below expressions evaluated?

  1. 2 + 3 == 4 or a >= 5
  2. lst[1] * -3 < -10 == 0
  3. (lst[1] * -3 < -10) in [0, True]
  4. 2 * 3**2
  5. 4 / 2 in [1, 2, 3]

Creating Objects

To create an integer object with value 3 (and assign it to variable x), we can use this statement:

>>> x = 3

Note that the type of the integer object that is created is not explicitely specified. Python also supports a way to create objects that makes the object type explicit:

>>> x = int(3)
>>> x
3

The function int() is called a constructor; it is used to explicitly instantiate an integer object. The value of the object is determined by the function argument: The object created with int(3) has value 3. If no argument is given, a default value is given to the object.

>>> x = int()
>>> x
0

So the default value for integers is 0.

The constructor functions for the floating point, list, and string types are float(), list(), and str(), respectively. We illustrate their usage with no argument to determine the default values for those types. For float objects, the default value is 0.0:

>>> y = float()
>>> y
0.0

The default values for strings and lists are, respectively, ‘’ (the empty string) and [] (the empty list):

>>> s = str()
>>> s
‘’
>>> lst = list()
>>> lst
[]

Implicit Type Conversions

If an algebraic or logical expression involves operands of different types, Python will convert each operand to the type that contains the others. For example, True is converted to 1 before integer addition is executed to give an integer result:

>>> True + 5
6

The reason for this seemingly strange behavior is that the Boolean type is really just a “subtype” of the integer type, as illustrated in Figure 2.5. Boolean values True and False typically behave like values 1 and 0, respectively, in almost all contexts.

image

Figure 2.5 Number types conversions. In an arithmetic expression with operands of different types, values are converted to the type that contains the others, where containment is as shown. Conversion from integer to float may result in an overflow.

Because integers can be written using decimal-point notation (3 is 3.0) but not vice versa (2.65 cannot be represented as an integer), the int type is contained in the float type, as shown in Figure 2.5. Consider, for example, the expression 3 + 0.35 in which an int value and a float value are added. The float type contains the int type so 3 is converted to 3.0 before floating point addition of two float values is done:

>>> 3 + 0.35
3.35

Conversion from int to float image

Recall that the range of values that int objects can have is much larger than the range of float objects. While the int type is contained in the float type, this doesn't imply that int values can always be converted to a float value. For example, the expression 2**10000+3 evaluates without difficulties to an int value, but its conversion to float results in an overflow:

>>> 2**10000+3.0
Traceback (most recent call last):
  File  “<pyshell#139>”, line 1, in <module>
    2**10000+3.0
OverflowError: Python int too large to convert to C double

Explicit Type Conversions

Type conversions can also be done explicitly using the constructor functions we just introduced. For example, the int() constructor creates an integer from a float input argument; it does so by removing the fractional part of the argument:

>>> int(3.4)
3
>>> int(-3.6)
-3

The float() constructor applied to an integer will change the representation to a floating point one, unless an overflow occurs.

>>> float(3)
3.0

The conversion from string to a number type will work only if it makes sense (i.e., the string is a valid representation of a value of the type); otherwise it results in an error:

>>> int(‘3.4’)
Traceback (most recent call last):
  File “<pyshell#123>”, line 1, in <module>
    int(‘3.4’)
ValueError: invalid literal for int() with base 10: ‘3.4’
>>> float(‘3.4’)
3.4

The string constructor str(), when applied to a number, returns the string representation of the number:

>>> str(2.72)
‘2.72’

Practice Problem 2.9

What is the type of the object that these expressions evaluate to?

  1. False + False
  2. 2 * 3**2.0
  3. 4 // 2 + 4 % 2
  4. 2 + 3 == 4 or 5 >= 5

Class Methods and Object-Oriented Programming

One way to think of a type (i.e., class) is to see it as the set of all operators and methods that can be applied to objects of the class. The list class, for example, can be defined by the operators and methods of the list class, some of which were shown in Figures 2.2 and 2.3. We have used, for example, list methods append(), count(), and remove() as follows:

>>> pets = [‘goldfish’, ‘cat’, ‘dog’]
>>> pets.append(‘guinea pig’)
>>> pets.append(‘dog’)
>>> pets
[‘goldfish’, ‘cat’, ‘dog’, ‘guinea pig’, ‘dog’]
>>> pets.count(‘dog’)
2
>>> pets.remove(‘dog’)
>>> pets
[‘goldfish’, ‘cat’, ‘guinea pig’, ‘dog’]
>>> pets.reverse()
>>> pets
[‘dog’, ‘guinea pig’, ‘cat’, ‘goldfish’]

To see all the methods supported by the class list, use the help() documentation tool:

>>> help(list)

We now formally explain the notation used in the previous method calls. In every case, we have a list object, pets, followed by a dot (.), followed by the method (function) call. The meaning of, say,

pets.append(‘guinea pig’)

is: The list method append() is called on the list object pets with string input ‘guinea pig’. In general, the notation

o.m(x,y)

means that method m is called on object o with inputs x and y. The method m should be a method of the class object o belongs to.

Every operation done in Python is a method invocation of this format. You may wonder because expression x + y does not seem to fit this format, but as we will see in Chapter 8, it does. This approach to manipulating data, where the data is stored in objects and methods are invoked on objects, is called object-oriented programming (OOP). OOP is a powerful approach to code organization and development. We will learn a lot more about it in Chapter 8.

2.5 Python Standard Library

The core Python programming language comes with functions such as max() and sum() and classes such as int, str, and list. While those are by no means all the built-in Python functions and classes, the core Python language is deliberately small for efficiency and ease-of-use purposes. In addition to the core functions and classes, Python has many, many more functions and classes defined in the Python Standard Library. The Python Standard Library consists of thousands of functions and classes organized into components called modules.

Each module contains a set of functions and/or classes related to a particular application domain. More than 200 built-in modules together form the Python Standard Library. Each module in the Standard Library contains functions and classes to support application programming in a certain domain. The Standard Library includes modules to support, among others:

  • Network programming
  • Web application programming
  • Graphical user interface (GUI) development
  • Database programming
  • Mathematical functions
  • Pseudorandom number generators

We will eventually use all of these modules. Right now we will see how to use the math and fraction modules.

Module math

The core Python language supports only basic mathematical operators; we have learned about them earlier in this chapter. For other mathematical functions such as the square root function or the trigonometric functions, the math module is required. The math module is a library of mathematical constants and functions. To use a math module function, the module must first be explicitly imported:

>>> import math

The import statement makes available all the math functions defined in module math. (We leave the more detailed explanation of how the import statement works for the next chapter and also Chapter 6.)

The square root function sqrt() is defined in module math, but we cannot use it like this:

>>> sqrt(3)
Traceback (most recent call last):
  File “<pyshell#28>”, line 1, in <module>
    sqrt(3)
NameError: name  ‘sqrt’  is not defined

Clearly, the Python interpreter doesn't know about sqrt, the name of the square root function. We must tell the interpreter explicitly where (i.e., which module) to look for it:

>>> math.sqrt(3)
1.7320508075688772

Table 2.7 Module math. Listed are some functions and constants in the module. After importing the module, you can obtain the full list in your interactive shell using the help() function: >>> help(math)

Function Explanation
sqrt(x) image
ceil(x) image (i.e., the smallest integer ≥ x)
floor(x) image (i.e., the largest integer ≤ x)
cos(x) cos(x)
sin(x) sin(x)
log(x, base) logbase(x)
pi 3.141592653589793
e 2.718281828459045

Table 2.7 lists some of the commonly used functions defined in the math module. Also shown are two mathematical constants defined in the module. The value of variable math.pi is an approximation for the mathematical constant π, and the value of math.e is an approximation for the Euler constant e.

Practice Problem 2.10

Write Python expressions corresponding to the following:

  1. The length of the hypotenuse in a right triangle whose other two sides have lengths a and b
  2. The value of the expression that evaluates whether the length of the above hypotenuse is 5
  3. The area of a disk of radius a
  4. The value of the Boolean expression that checks whether a point with coordinates x and y is inside a circle with center (a, b) and radius r

Module fractions

The fractions module makes available a new type of number: the Fraction type. The Fraction type is used to represent fractions and do rational arithmetic, such as:

image

To use the fractions module, we first need to import it:

>>> import fractions

To create a Fraction object, we use the Fraction() constructor with two arguments: a numerator and a denominator. Here is how we can define image and image:

>>> a = fractions.Fraction(3, 4)
>>> b = fractions.Fraction(1, 2)

Note how we must specify where the class Fractions is defined: in the fractions module. When we evaluate expression a, we get

>>> a
Fraction(3, 4)

Note that a does not evaluate to 0.75.

As with other numbers, Fraction objects can be added, and the result is a Fraction object:

>>> c = a + b
>>> c
Fraction(5, 4)

What is the difference between the float type and the fractions.Fraction type? We mentioned earlier that float values are stored in the computer using a limited number of bits, typically 64 of them. That means that the range of values that float objects can store is limited. For example, 0.51075 cannot be represented as a float value and thus evaluates to 0:

>>> 0.5**1075
0.0

The range of values representable with fractions.Fraction objects is much, much larger and limited only by the available memory, just as for the int type. So we can easily compute image:

>>> fractions.Fraction(1, 2)**1075
Fraction(1, 404804506614621236704990693437834614099113299528284236 713802716054860679135990693783920767402874248990374155728633623822 779617474771586953734026799881477019843034848553132722728933815484 186432682479535356945490137124014966849385397236206711298319112681 620113024717539104666829230461005064372655017292012526615415482186 989568)

Why not always use the fractions.Fraction type? Because expressions involving float values evaluate much, much faster than expressions involving fractions.Fraction values.

2.6 Case Study: Turtle Graphics Objects

In our first case study, we will use a graphics tool to (visually) illustrate the concepts covered in this chapter: objects, classes and class methods, object-oriented programming, and modules. The tool, Turtle graphics, allows a user to draw lines and shapes in a way that is similar to using a pen on paper.

Turtle Graphics image

Turtle graphics has a long history all the way back to the time when the field of computer science was developing. It was part of the Logo programming language developed by Daniel Bobrow, Wally Feurzig, and Seymour Papert in 1966. The Logo programming language and its most popular feature, turtle graphics, was developed for the purpose of teaching programming.

The turtle was originally a robot, that is, a mechanical device controlled by a computer operator. A pen was attached to the robot and it left a trace on the surface as the robot moved according to functions input by the operator.

Turtle graphics is available to Python developers through the turtle module. In the module are defined 7 classes and more than 80 class methods and functions. We will not exhaustively cover all the features of the module turtle. We only introduce a sufficient number to allow us to do interesting graphics while cementing our understanding of objects, classes, class methods, functions, and modules. Feel free to explore this fun tool on your own.

We start by importing the turtle module and then instantiating a Screen object.

>>> import turtle
>>> s = turtle.Screen()

You will note that a new window appears with a white background after executing the second statement. The Screen object is the canvas on which we draw. The Screen class is defined in the turtle module. Later we will introduce some Screen methods that change the background color or close the window. Right now, we just want to start drawing.

To create our pen or, using the turtle graphics terminology, our turtle, we instantiate a Turtle object we name t:

>>> t = turtle.Turtle()

A Turtle object is essentially a pen that is initially located at the center of the screen, at coordinates (0,0). The Turtle class, defined in the turtle module, provides many methods for moving the turtle. As we move the turtle, it leaves a trace behind. To make our first move, we will use the forward() method of the Turtle class. So, to move forward 100 pixels, the method forward() is invoked on Turtle object t with 100 (pixels) as the distance:

>>> t.forward(100)

The effect is shown in Figure 2.6.

image

Figure 2.6 Turtle graphics. The black arrow tip represents the Turtle object. The line is the trace left by the turtle after moving forward 100 pixels.

Note that the move is to the right. When instantiated, the turtle faces right (i.e., to the east). To make the turtle face a new direction, you can rotate it counterclockwise or clockwise using the left() or right() methods, both Turtle class methods. To rotate 90 degrees counterclockwise, the method left() is invoked on Turtle object t with the argument 90:

>>> t.left(90)

We can have several Turtle objects simultaneously on the screen. Next, we create a new Turtle instance that we name u and make both turtles do some moves:

>>> u = turtle.Turtle()
>>> u.left(90)
>>> u.forward(100)
>>> t.forward(100)
>>> u.right(45)

The current state of the two turtles and the trace they made is shown in Figure 2.7.

image

Figure 2.7 Two Turtle objects. The Turtle object on the left is facing northeast whereas the Turtle object on the right is facing north.

In the example we just completed, we used three methods of class Turtle: forward(), left(), and right(). In Table 2.8, we list those and some other methods (but by no means all). To illustrate some of the additional methods listed in the table, we go through the steps necessary to draw a smiley face emoticon shown in Figure 2.8.

Table 2.8 Some methods of the Turtle class. After importing the module turtle, you can obtain the full list of Turtle methods in your interactive shell using help(turtle.Turtle)

Usage Explanation
t.forward(distance) Move turtle in the direction the turtle is headed by distance pixels
t.left(angle) Rotate turtle counterclockwise by angle degrees
t.right(angle) Rotate turtle clockwise by angle degrees
t.undo() Undo the previous move
t.goto(x, y) Move turtle to coordinates defined by x and y; if pen is down, draw line
t.setx(x) Set the turtle's first coordinate to x
t.sety(y) Set the turtle's second coordinate to y
t.setheading(angle) Set orientation of turtle to angle, given in degrees; Angle 0 means east, 90 is north, and so on
t.circle(radius) Draw a circle with given radius; the center of the circle is radius pixels to the left of the turtle
t.circle(radius, angle) Draw only the part the circle (see above) corresponding to angle
t.dot(diameter, color) Draw a dot with given diameter and color
t.penup() Pull pen up; no drawing when moving
t.pendown() Put pen down; drawing when moving
t.pensize(width) Set the pen line thickness to width
t.pencolor(color) Set the pen color to color described by string color

image

Figure 2.8 A Turtle smiley face drawing.

We start by instantiating a Screen and a Turtle object and setting the pen size.

>>> import turtle
>>> s = turtle.Screen()
>>> t = turtle.Turtle()
>>> t.pensize(3)

We then define the coordinates where the chin of the smiley face will be located, and then move to that location.

>>> x = -100
>>> y = 100
>>> t.goto(x, y)

Oooops! We drew a line from coordinate (0, 0) to coordinate (-100, 100); all we wanted was to move the pen, without leaving a trace. So we need to undo the last move, lift the pen, and then move it.

>>> t.undo()
>>> t.penup()
>>> t.goto(x, y)
>>> t.pendown()

Now we want to draw the circle outlining the face of our smiley face. We call the method circle() of the class Turtle with one argument, the radius of the circle. The circle is drawn as follows: The current turtle position will be a point of the circle, and the center of the circle is defined to be to the turtle's left, with respect to the current turtle heading.

>>> t.circle(100)

Now we want to draw the left eye. We choose the left eye coordinates relative to (x, y) (i.e., the chin position) and “jump” to that location. We then use the dot function to draw a black dot of diameter 10.

>>> t.penup()
>>> t.goto(x - 35, y + 120)
>>> t.pendown()
>>> t.dot(25)

Next, we jump and draw the right eye.

>>> t.penup()
>>> t.goto(x + 35, y + 120)
>>> t.pendown()
>>> t.dot(25)

Finally, we draw the smile. I chose the exact location of the left endpoint of the smile using trial and error. You could also use geometry and trigonometry to get it right if you prefer. We use here a variant of the method circle() that takes a second argument in addition to the radius: an angle. What is drawn is just a section of the circle, a section corresponding to the given angle. Note that we again have to jump first.

>>> t.penup()
>>> t.goto(x - 60.62, y + 65)
>>> t.pendown()
>>> t.setheading(-60)
>>> t.circle(70, 120)

Table 2.9 Methods of the Screen class. Shown are only some of the Screen class methods. After importing module turtle, you can obtain the full list of Screen methods in your interactive shell using help(turtle.Screen)

Usage Explanation
s.bgcolor(color) Changes the background color of screen s to color described by string color
s.clearscreen() Clears screen s
s.turtles() Returns the list of all turtles in the screen s
s.bye() Closes the screen s window

We're done! As we end this case study, you may wonder how to close cleanly your turtle graphics window. The Screen method bye() closes it:

>>> s.bye()

This method and several other Screen methods are listed in Table 2.9.

Practice Problem 2.11

Start by executing these statements:

>>> s = turtle.Screen()
>>> t = turtle.Turtle(shape=‘turtle’)
>>> t.penup()
>>> t.goto(-300, 0)
>>> t.pendown()

A turtle pen will appear on the left side of the screen. Then execute a sequence of Python turtle graphics statements that will produce this image:

image

Chapter Summary

This chapter is an overview of Python concepts and its core built-in data types.

We introduce the interactive shell as a way to evaluate expressions. We start first with algebraic expressions that evaluate to a number and then Boolean expressions that evaluate to values True or False. We also introduce variables and the assignment statement, which is used to give a variable name to a value.

This chapter introduces the core Python built-in types: int, float, bool, str, and list. We go over the built-in number operators and explain the difference between the number types int, float, and bool. We introduce the string (str) operators (we leave string methods for Chapter 4); we cover, in particular, the important indexing operator. For the list type, we introduce both its operators and its methods.

After defining several built-in classes, we step back and define the concept of an object and of a class. We then use those concepts to define class constructors and type conversion.

Python‘s Standard Library includes many modules that contain functions and types beyond the built-in ones. We introduce the useful math module that gives us access to many classic math functions. Finally, in the chapter’s case study, we introduce the fun drawing module turtle.

Solutions to Practice Problems

2.1 The expressions are:

  1. 1 + 2 + 3 + 4 + 5
  2. (23 + 19 + 31) / 3)
  3. 403 // 73
  4. 403 % 73
  5. 2**10
  6. abs(54 - 57)
  7. min(34.99, 29.95, 31.50)

2.2 The Boolean expressions are:

  1. 2 + 2 < 4 which evaluates to False
  2. 7 // 3 == 1 + 1 which evaluates to True
  3. 3**2 + 4**2 == 25 which evaluates to True
  4. 2 + 4 + 6 > 12 which evaluates to False
  5. 1387 % 19 == 0 which evaluates to True
  6. 31 % 2 == 0 which evaluates to False
  7. min(34.99, 29.95, 31.50) < 30.00 evaluates to True

2.3 The sequence of statements in the interactive shell is:

>>> a = 3
>>> b = 4
>>> c = a * a + b * b

2.4 The expressions are:

  1. s1 + ‘’+ s2 + ‘’+ s3
  2. 10 * (s1 + ‘’)
  3. s1 + ‘’ + 2 * (s2 + ‘’) + 2 * (s3 + ‘’) + s3
  4. 7 * (s1 + ‘’+ s2 + ‘’)
  5. 3 * (2 * s2 + s3 + ‘’)

2.5 The expressions are:

(a) s[0], (b) s[1], (c) s[6], (d) s[8], and (e) s[9].

2.6 The expressions are min(words) and max(words).

2.7 The method calls are:

  1. grades.count(7)
  2. grades[-1] = 4
  3. max(grades)
  4. grades.sort()
  5. sum(grades) / len(grades)

2.8 The order is indicated using parentheses:

  1. ((2 + 3) == 4) or (a >= 5)
  2. (((lst[1]) * (-3)) < (-10)) == 0
  3. (((lst[1]) * (-3)) < (-10)) in [0, True]
  4. 2 * (3**2)
  5. (4 / 2) in [1, 2, 3]

2.9 Check these solutions for yourself by evaluating all the expressions in the interactive shell.

  1. While the two operands are Boolean, the + operator is an int operator, not a bool operator. The result (0) is an int value.
  2. A float value.
  3. An int value.
  4. The expressions on both sides of the or operator evaluate to bool values so the result is a bool value.

2.10 The expressions are:

  1. math.sqrt(a**2 + b**2)
  2. math.sqrt(a**2 + b**2) == 5
  3. math.pi * a**2
  4. (x - a)**2 + (y - b)**2 < r**2

2.11 We assume the starting position is the leftmost point of the “wave” curve. To draw the first “valley,” we need to make the turtle point southeast and then draw a 90° section of the circle:

>>> t.seheading(-45)
>>> t.circle(50, 90)

We then repeat this pair of statements eight times. To draw the sun, we need to lift the pen, move it, put the pen down, and draw a circle:

>>> t.penup()
>>> t.goto(-100, 200)
>>> t.pendown()
>>> t.circle(50)
>>> t.penup()
>>> t.goto(0, -50)

We end by moving the turtle so it can swim in the sea.

Exercises

2.12 Write Python expressions corresponding to these statements:

  1. The sum of the first seven positive integers
  2. The average age of Sara (age 65), Fatima (57), and Mark (age 45)
  3. 2 to the 20th power
  4. The number of times 61 goes into 4356
  5. The remainder when 4365 is divided by 61

2.13 Start by evaluating, in the interactive shell, the assignment:

>>> s1 = ‘-’
>>> s2 = ‘+’

Now write string expressions involving s1 and s2 and string operators + and * that evaluate to:

  1. ‘-+’
  2. ‘–+’
  3. ‘+––’
  4. ‘+––+––’
  5. ‘+––+––+––+––+––+––+––+––+––+––+’
  6. ‘+–+++––+–+++––+–+++––+–+++––+–+++––’

Try to make your string expressions as succinct as you can.

2.14 Start by running, in the shell, the following assignment statement:

>>> s = ‘abcdefghijklmnopqrstuvwxyz’

Now write expressions using string s and the indexing operator that evaluate to ‘a’, ‘c’, ‘z’, ‘y’, and ‘q’.

2.15 Start by executing

s = ‘goodbye’

Then write a Boolean expression that check whether:

  1. The first character of string s is ‘g’
  2. The seventh character of s is g
  3. The first two characters of s are g and a
  4. The next to last character of s is x
  5. The midle character of s is d
  6. The first and last characters of string s are equal
  7. The last 4 characters of string s match the string ‘tion’

Note: These seven statements should evaluate to True, False, False, False, True, False, and False, respectively.

2.16 Write the corresponding Python assignment statements:

  1. Assign 6 to variable a and 7 to variable b.
  2. Assign to variable c the average of variables a and b.
  3. Assign to variable inventory the list containing strings ‘paper’, ‘staples’, and ‘pencils’.
  4. Assign to variables first, middle and last the strings ‘John’, ‘Fitzgerald’, and ‘Kennedy’.
  5. Assign to variable fullname the concatenation of string variables first, middle, and last. Make sure you incorporate blank spaces appropriately.

2.17 Write Boolean expressions corresponding to the following logical statements and evaluate the expressions:

  1. The sum of 17 and -9 is less than 10.
  2. The length of list inventory is more than five times the length of string fullname.
  3. c is no more than 24.
  4. 6.75 is between the values of integers a and b.
  5. The length of string middle is larger than the length of string first and smaller than the length string last.
  6. Either the list inventory is empty or it has more than 10 objects in it.

2.18 Write Python statements corresponding to the following:

  1. Assign to variable flowers a list containing strings ‘rose’, ‘bougainvillea’, ‘yucca’, ‘marigold’, ‘daylilly’, and ‘lilly of the valley’.
  2. Write a Boolean expression that evaluates to True if string ‘potato’ is in list flowers, and evaluate the expression.
  3. Assign to list thorny the sublist of list flowers consisting of the first three objects in the list.
  4. Assign to list poisonous the sublist of list flowers consisting of just the last object of list flowers.
  5. Assign to list dangerous the concatenation of lists thorny and poisonous.

2.19 A dartboard of radius 10 and the wall it is hanging on are represented using the two-dimensional coordinate system, with the board's center at coordinate (0,0). Variables x and y store the x- and y-coordinate of a dart hit. Write an expression using variables x and y that evaluates to True if the dart hits (is within) the dartboard, and evaluate the expression for these dart coordinates:

  1. (0,0)
  2. (10,10)
  3. (6,6)
  4. (7,8)

2.20 A ladder put up right against a wall will fall over unless put up at a certain angle less than 90 degrees. Given variables length and angle storing the length of the ladder and the angle that it forms with the ground as it leans against the wall, write a Python expression involving length and angle that computes the height reached by the ladder. Evaluate the expression for these values of length and angle:

  1. 16 feet and 75 degrees
  2. 20 feet and 0 degrees
  3. 24 feet and 45 degrees
  4. 24 feet and 80 degrees

Note: You will need to use the trig formula:

image

The math module sin() function takes its input in radians. You will thus need to convert the angle given in degrees to the angle given in radians using:

image

2.21 Write an expression involving a three-letter string s that evaluates to a string whose characters are the characters of s in reverse order. If s is ‘top’, the expression should evaluate to ‘pot’.

2.22 Write an expression involving string s containing the last and first name of a person—separated by a blank space—that evaluates to the person's initials. If the string contained my first and last name, the expression would evaluate to ‘LP’.

2.23 The range of a list of numbers is the largest difference between any two numbers in the list. Write a Python expression that computes the range of a list of numbers lst. If the list lst is, say, [3, 7, -2, 12], the expression should evaluate to 14 (the difference between 12 and -2).

2.24 Write the relevant Python expression or statement, involving a list of numbers lst and using list operators and methods for these specifications:

  1. An expression that evaluates to the index of the middle element of lst
  2. An expression that evaluates to the middle element of lst
  3. A statement that sorts the list lst in descending order
  4. A statement that removes the first number of list lst and puts it at the end

2.25 Add a pair of parentheses to each expression so that it evaluates to True.

  1. 0==1==2
  2. 2+3==4+5==7
  3. 1<-1==3>4

For each expression, explain in what order the operators were evaluated.

2.26 Write Python statements that draw a square of side length 100 pixels using Turtle graphics. Make sure you import the module turtle first. Your first two and last statement should be as shown:

>>> s = turtle.Screen()   # create screen
>>> t = turtle.Turtle()   # create turtle

…                         # now write a sequence of statements
…                         # that draw the square

>>> s.bye()               # delete the Screen when done

2.27 Using the approach from Problem 2.26, write Python statements that draw a diamond of side length 100 pixels using Turtle graphics.

2.28 Using the approach from Problem 2.26, write Python statements that draw a pentagon of side length 100 pixels using Turtle graphics. Then do a hexagon, a heptagon, and an octogon.

2.29 Using the approach from Problem 2.26, write Python statements that draw the intersecting circles of radius 100 pixels shown using Turtle graphics:

image

The sizes of the circles do not matter; their centers should be, more or less, the points of an equilateral triangle.

2.30 Using the approach from Problem 2.26, write Python statements that draw four concentric circles similar to the concentric circles of a dartboard.

2.31 Add three more swimming turtles to the picture shown in Practice Problem 2.11.

2.32 Using Turtle graphics, illustrate the relative size of the sun and the earth by drawing two circles. The circle representing earth should have a radius of 1 pixel. The circle representing the sun should have a radius of 109 pixels.

2.33 Using Turtle graphics, draw a five-pointed star by repeating the following five times: move the turtle a 100 pixels and then rotate it right 144 degrees. When done, consider how to draw the six-pointed star (commonly referred to as the Star of David).

2.34 Using Turtle graphics, draw an image showing the six sides of a dice. You may represent each side inside a separate square.

2.35 Using Turtle graphics, draw the lines of a basketball field. You may choose the National Basketball Association (NBA) or International Basketball Federation (FIBA) specifications, which you can easily find on the web.

2.36 Using Turtle graphics, draw an image showing the (visible) phases of the moon as seen from your hemisphere: waxing crescent, first quarter, waxing gibbous, full, waning gibbous, third quarter, and waning crescent. You can find illustrations of the phases of the moon on the web.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset