## Practice Problems 4 Solutions

1. [PP Problem 5.1] What value does each expression produce?

a. True
b. Name error: name ‘false’ is not defined
c. True
d. True
e. True
f. True
g. False
h. False

2. [PP Problem 5.6] Write a function named different that has two parameters, a and b. The function should return True if a and b refer to different values and should return False otherwise.

 def different(a, b):
return a != b


An alternative solution that while correct is less readable and therefore not “best practice”:

 def different(a, b):
if (a == b):
return False
else:
return True

3. Assume we want to print a strong warning message if a pH value is below 3.0 and otherwise simply report on the acidity. We try this if statement:

 >>> ph = 2
>>> if ph < 7.0:
...     print(ph, "is acidic.")
... elif ph < 3.0:
...     print(ph, "is VERY acidic! Be careful.")
...
2 is acidic.


This prints the wrong message when a pH of 2 is entered. What is the problem, and how can you fix it?

< 3.0 is a subset of < 7.0 and so any inputs that satisfy the former would also satisfy the latter and so would get “caught” by the first if. To fix, reverse the order of the conditional statements so the most specific statement is considered first.

 >>> ph = 2
>>> if ph < 3.0:
...   print(ph, "is VERY acidic! Be careful.")
...	elif ph < 7.0:
...   print(ph, "is acidic.")
...

4. Your colleague wrote a program to describe the temperature, specifically it reports if the temperature is below freezing (in degrees fahrenheit), at freezing or above freezing. Their code is not working when the temperature is exactly 32 degrees. What is wrong and how could you fix it?

 if temp == 32:
print("At freezing")
if temp <= 32:
print("Below freezing")
if temp >= 32:
print("Above freezing")


Each if statement is evaluated independently, so if the temp is exactly 32, all three conditionals will be tested and since all are True, all three statements would be printed. You could fix this by making the relational operators greater than and less than so all three conditions were mutually exclusive. However, since we only want to execute one branch, a better approach is to use a single if-elif-else statement (which guarantees that only one branch will be executed). For example:

 if temp == 32:
print("At freezing")
elif temp < 32:
print("Below freezing")
else:
print("Above freezing")

5. Modify the firstprimes function (included below) to print out all the prime numbers less than or equal to the input parameter, num.

 def firstprimes(num):
"""Prints out prime numbers <= num"""
current = 1  # the current number we're checking

while current <= num:
if isprime(current):
print(current)

current += 1


Notice that count < num is replaced by current <= num.

6. Write two functions, one using a for loop and one using a while loop that print all the numbers from 1 to 20, inclusive, that are evenly divisible by 3. Your function should print one number per line.

There are number of ways to accomplish this with both styles of loops.

 def for3():
# Note that we carefully start range at 3 and then stride by 3
for i in range(3, 21, 3):
print(i)

 def for3():
for i in range(1, 21):
# Use modulus (remainder) to test if number is evenly divisble by 3
if i % 3 == 0:
print(i)

 def while3():
i = 1
while i <= 20:
if i % 3 == 0:
print(i)
i += 1

7. Extend both of your functions from the previous problem to accept the inclusive start and stop as parameters, i.e. instead of the fixed range of 1 to 20, allow the caller to specify the range.

 def for3(start, stop):
for i in range(start, stop+1):
if i % 3 == 0:
print(i)

 def while3(start, stop):
i = start
while i <= stop:
if i % 3 == 0:
print(i)
i += 1

8. [Computing for Biologists] DNA is composed of four nucleotides, A, C, G, and T. Although we might expect the four nucleotides to be equally common in the genome that is not the case. On average, the GC fraction, the percentage of nucleotides that are ‘G’ or ‘C’, of the human genome is less than 40%. The GC fraction is also not evenly distributed. Some regions of the genome, including where genes are found, have a higher GC fraction. Thus regions of high GC content can be used as a signal to detect genes or other features of interest. Write a function named gc_fraction that takes a DNA string as a parameter and returns the GC fraction as a floating point number (that is the fraction of all the nucleotides in the string that are ‘G’ or ‘C’). Your function should work for upper or lower case strings, i.e. ‘acgt’ and ‘AGTC’, should both generate a result of 0.5.

 def gc_fraction(dna):
"""
Return gc fraction for dna string
"""
gc = 0
# Normalize character to lower case before iterating
for base in dna.lower():
if base == 'g' or base == 'c':
gc += 1
return gc / len(dna)