Each of the following loops is an attempt to sum up the numbers from 1 to n,
e.g.1+2+ ... +n
(you can assume n
is initialized to some value). For
each case, explain why the code doesn’t actually sum the numbers 1 through n.
a.
sum = 0
for i in range(n):
sum = sum + i
This is close, but recall that range(n)
is equivalent to range(0,n)
and
produce the sequence 0, 1, …, n-1 and so this loop sums 0, 1, …, n-1. It
can be fixed as:
sum = 0
for i in range(n):
sum = sum + (i + 1)
b.
sum = 0
for i in range(n):
temp = sum + (i+1)
sum = temp
Here we’re not updating sum
every time through the loop, so each time we
access sum
in temp = sum + (i+1)
the value will still be 0. The final
value of temp
(and therefor sum) when this code finishes will just be n
. It
can be fixed as shown above (eliminate temp
).
c.
sum = 0
for i in range(n):
sum = (i+1)
Here we’re are updating sum
, but we’re not accumulating. Instead, each time
sum will just get i+1
. Again, when we’re done, sum will just be n
. The
loop body needs to be changed to sum = sum + (i+1)
.
d.
sum = 0
for i in range(n):
temp = (i+1)
sum = temp
This is the same problem as c., except now we’ve broken it into two steps,
first assigning (i+1)
to temp
and then temp
to sum
. Again the loop body
needs to be change to accumulate.
Write a function named factorial
that has a single parameter, an integer
n
, and returns n!, i.e. 1*2*3* ... n
.
def factorial(n):
"""
Return n factorial for integer argument
"""
result = 1
for i in range(n):
result = result * (i + 1)
return result
Recall that range(n)
starts with 0. Alternately recall that range
allows you to specify the start value, so you could implement factorial
as:
def factorial2(n):
"""
Return n factorial for integer argument
"""
result = 1
for i in range(1, n+1):
result = result * i
return result
Write a docstring for the following function
Recall from lecture that a docstring should include a brief description of what the function does, what, if any, arguments it expects (i.e. what are its parameters), and what, if any, it returns.
def mystery():
"""
Print the first 5 even numbers, one per line
Args:
None
Returns:
None
"""
for i in range(5):
print(2 + 2*i)
Write a function named rand_time
that returns a random valid time in HH:MM
format as a string. The result can have only a single hour digit, i.e.
1:01
and 10:15
are valid results, but must have two minutes digits,
i.e. 1:1
is not a valid result. As a trickier extension, adapt your
function to always generate two hour digits, i.e. 1:01 should be represented
as 01:01
.
def rand_time():
"""
Generate a random time in HH:MM format
Args:
None
Returns:
Time as a string
"""
return str(randint(1, 12)) + ":" + str(randint(0, 5)) + str(randint(0, 9))
Note that we need to generate each minutes digit separately to ensure we always get two digits. If we want to do the same for the hours digits as well, we will need to be more sophisticated because the range of the “ones place” depends on the tens place. We can use floor division and modulus to extract those two digits from a randomly generated hour.
def rand_time2():
"""
Generate a random time in HH:MM format
Args:
None
Returns:
Time as a string
"""
hours = randint(1, 12)
return str(hours // 10) + str(hours % 10) + ":" + str(randint(0, 5)) + str(randint(0, 9))