# ThinkPython exercise solutions

contents

## Exercise 3.3

**Write a function named right_justify that takes a string named s as a parameter and prints the string with enough leading spaces so that the last letter of the string is in column 70 of the display.**

### Solution

```
def right_justify(s):
lspace = 70-len(s)
s = ' '*lspace+s
return s
t='hello'
print right_justify(t)
```

### Output

```
hello
```

## Exercise 3.5

Write a function that draws a grid like the following:

```
+ - - - - + - - - - +
| | |
| | |
| | |
| | |
+ - - - - + - - - - +
| | |
| | |
| | |
| | |
+ - - - - + - - - - +
```

### Solution

```
def two_times(f):
f()
f()
def four_times(f):
two_times(f)
two_times(f)
def print_space_n_beam():
i=0
while(i<2):
print '|'+' '*8,
i=i+1
print '|'
def print_plus_n_hyphen():
i=0
while(i<2):
print '+'+' -'*4,
i=i+1
print '+'
print_plus_n_hyphen()
four_times(print_space_n_beam)
print_plus_n_hyphen()
four_times(print_space_n_beam)
print_plus_n_hyphen()
```

## Exercise 5.1.1

Write a function named check_fermat that takes four parameters—a, b, c and n—and that checks to see if Fermat's theorem holds. If n is greater than 2 and it turns out to be true that a^{n} + b^{n} = c^{n}, the program should print, "Holy smokes, Fermat was wrong!" Otherwise the program should print, "No, that doesn't work."

### Solution

```
def check_fermat(a,b,c,n):
if n <= 2:
print "n has to greater than 2"
else:
if a**n+b**n == c**n:
print 'Holy smokes, Fermat was wrong!'
else:
print 'No, that doesn\'t work.'
check_fermat(3,5,3,3)
```

### Output

```
No, that doesn't work.
```

## Exercise 5.1.2

Write a function that prompts the user to input values for a, b, c and n, converts them to integers, and uses check_fermat to check whether they violate Fermat's theorem.

### Solution

```
def check_fermat(a,b,c,n):
if n <= 2:
print "n has to greater than 2"
else:
if a**n+b**n == c**n:
print 'Holy smokes, Fermat was wrong!'
else:
print 'No, that doesn\'t work.'
a = raw_input("a: ")
b = raw_input("b: ")
c = raw_input("c: ")
n = raw_input("n: ")
a,b,c,n = int(a),int(b),int(c),int(n)
check_fermat(a,b,c,n)
```

## Exercise 5.2.1

Write a function named is_triangle that takes three integers as arguments, and that prints either "Yes" or "No," depending on whether you can or cannot form a triangle from sticks with the given lengths.

### Solution

```
def is_triangle(a,b,c):
if c == 0 or b == 0 or a == 0:
print "A side cannot be of zero length!"
else:
if c > a+b or b > c+a or a > b+c:
print "No"
else:
print "Yes"
is_triangle(1,2,3)
is_triangle(1,2,0)
is_triangle(1,2,6)
```

### Output

```
Yes
A side cannot be of zero length!
No
```

## Exercise 6.3

Write a function is*between(x, y, z) that returns True if x *= *y *= _z or False otherwise.

### Solution

```
def is_between(x,y,z):
return x <= y <= z
print is_between(1,2,3)
print is_between(1,3,2)
print is_between(3,2,1)
```

### Output

```
True
False
False
```

## Exercise 6.5

The Ackermann function, A(m, n), is defined as

```
⎧ n+1 if m = 0
⎪
A(m, n) = ⎨ A(m−1, 1) if m > 0 and n = 0
⎪
⎩ A(m−1, A(m, n−1)) if m > 0 and n > 0.
```

Write a function named `ack`

that evaluates Ackerman’s function. Use your function to evaluate `ack(3, 4)`

, which should be 125. What happens for larger values of `m`

and `n`

?

### Solution

```
def ack(m,n):
if m == 0:
return n+1
elif m > 0 and n == 0:
return ack(m-1,1)
elif m > 0 and n > 0:
return ack(m-1,ack(m,n-1))
print ack(3,4)
```

### Output

125

Results for values of m,n from 0,0 to 4,4

```
ack(m,n) Output
==================
ack(0,0) 1
ack(0,1) 2
ack(0,2) 3
ack(0,3) 4
ack(0,4) 5
ack(1,0) 2
ack(1,1) 3
ack(1,2) 4
ack(1,3) 5
ack(1,4) 6
ack(2,0) 3
ack(2,1) 5
ack(2,2) 7
ack(2,3) 9
ack(2,4) 11
ack(3,0) 5
ack(3,1) 13
ack(3,2) 29
ack(3,3) 61
ack(3,4) 125
ack(4,0) 13
ack(4,1) max recursion depth exceeded
ack(4,2) max recursion depth exceeded
ack(4,3) max recursion depth exceeded
ack(4,4) max recursion depth exceeded
```

## Exercise 6.6.2

`Write a function called _is*palindrome* that takes a string argument and returns True if it is a palindrome and False otherwise. Remember that you can use the built-in function len to check the length of a string.

### Solution

```
def is_palindrome(w):
if not isinstance(w, str):
return "ERROR: input is not a string."
elif len(w) > 2:
if w[0] == w[-1]:
while len(w) > 2:
w = w[1:-1]
is_palindrome(w)
if len(w) == 1:
return True
else:
return False
else:
return "ERROR: input contains two or less characters."
print is_palindrome('aibohphobia')
print is_palindrome('definitely')
```

## Output

```
True
False
```

## Exercise 10.1

Write a function that takes a list of numbers and returns the cumulative sum; that is, a new list where the ith element is the sum of the first i+1 elements from the original list. For example, the cumulative sum of [1, 2, 3] is [1, 3, 6].

### Solution

```
def cumul_sum(t):
u=[]
s=0
for i in range(len(t)):
s += t[i]
u.append(s)
return u
lst = [1,2,3,4]
print cumul_sum(lst)
```

### Output

```
[1,3,6,10]
```

## Exercise 10.2

Write a function called chop that takes a list and modifies it, removing the first and last elements, and returns None. Then write a function called middle that takes a list and returns a new list that contains all but the first and last elements.

### Solution

```
def chop(t):
t[:] = t[1:-1]
def middle(t):
return t[1:-1]
lst = [1,'a',3,4,5,6,7,8,'b']
chop(lst)
print lst
print middle(lst)
```

### Output

```
['a', 3, 4, 5, 6, 7, 8]
[3, 4, 5, 6, 7]
```

## Exercise 10.3

Write a function called is_sorted that takes a list as a parameter and returns True if the list is sorted in ascending order and False otherwise. You can assume (as a precondition) that the elements of the list can be compared with the relational operators <, >, etc.

For example, is_sorted([1,2,2]) should return True and is_sorted(['b','a']) should return False.

### Solution

```
def is_sorted(t):
return t[0] < t[1]
t1 = [1,2,3]
t2 = [5,4,3]
t3 = ['a','b']
t4 = ['z','t']
print is_sorted(t1)
print is_sorted(t2)
print is_sorted(t3)
print is_sorted(t4)
```

### Output

```
True
False
True
False
```