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.
Would the following code execute without an error? If so, what would it print?
for i in range(0):
print("In the loop")
print("After the loop")
This code would execute without an error and would just print
After the loop
range(0)
would return an empty sequence (recall the argument is the exclusive end). With an empty sequence the loop body will execute 0 times (i.e., not execute), so print("In the loop")
will never execute.
It is little weird to explicitly specify a loop that will not execute, but imagine the argument to range
was not a fixed value but the result of another computation. We could imagine situations were sometimes we want to loop the execute and sometimes we don’t.
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
.
from random import randint
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))
Write a function dice_pair
that returns the sum of “rolling” two six sided dice, i.e., simulate rolling to two dice and return the sum of the rolled numbers.
from random import randint
def dice_pair():
"""Return sum of 'rolling' two six sided dice"""
return randint(1, 6) + randint(1, 6)
Recall that unlike range
, both arguments to randint
, including the “stop”, are inclusive (whereas range
has an exclusive end).