Preparation

Boot up your computer into Mac OSX, open up a Terminal, and open Brackets. You may save your work anywhere on your computer, but it is a good habit to store your code on the COURSES drive in your StuWork directory. After mounting it by double clicking the icon on your desktop, you can change directories to it in the Terminal with:

$ cd /Volumes/COURSES/cs111-03-s19/StuWork/USERNAME/
$ mkdir lab-04-08
$ cd lab-04-08

Exercise 1

In the reading, we learned how the // operator performs “integer division” and throws away the remainder after dividing, and the % operator returns the remainder. We will explore this in this exercise.

a. With your partner, predict what the following expressions will evaluate to.

  • 5 // 3
  • 5 % 3
  • 10 // 2
  • 10 % 2

b. Verify your predictions in the REPL.

c. What do you think happens if we use negative numbers?

  • -3 // 2
  • -3 % 2
  • 3 // -2
  • 3 % -2

d. Verify your predictions in the REPL.

e. Try running // and % on a variety of other numbers to see if it outputs what you expect.

(If you are curious, you can read more about these operators here.)

Exercise 2

In this exercise we will write a program that is akin to how a vending machine computes how many coins to dispense to a customer when they need change.

a. Create a new file called make_change.py with the following starter code.

# make_change.py
# Titus Klinge, YOUR NAME(S) GO HERE
# 2019-04-08
#
# A simple program that computes what coins to dispense in a vending machine
def main():
    change = int(input("Enter how much change you need in cents: "))

    quarters_needed = change // 25
    change = change % 25
    print("Here are", quarters_needed, "quarters.")
    print("I still need to give you", change, "cents of change.")

    dimes_needed = change // 10
    change = change % 10
    print("Here are", dimes_needed, "dimes.")
    print("I still need to give you", change, "cents of change.")

    nickels_needed = change // 5
    change = change % 5
    print("Here are", nickels_needed, "nickels.")
    print("I still need to give you", change, "cents of change.")

    print("Here are", change, "pennies.")

main()

b. Try running the program on a variety of inputs to see what it is doing.

c. Try deleting the main() at the very bottom and try running the program again. Does it still work?

d. What happens if you end the program with two calls to main()?

Putting the entry point of your program inside a “main” function is required in most languages but not required in Python. Many programmers think it is good practice to do so, however, it requires that you actually call the function exactly once after everything is defined.

e. Modify your program so that instead of taking the input as an int representing cents, it takes a float representing dollars. (You may delete the print statements that say “I still need to give you…” if you prefer. They were included to help you see how the change variable is being modified throughout the program.) HINT: You only need to modify one line of code!

f. Modify your program so that it also can give dollar bills back to the customer. HINT: This requires computing a dollars needed number before computing how many quarters you need.

Exercise 3

Remember that max(a,b) is a function that returns the maximum of the numbers a and b and min(a,b) returns the minimum. Now consider the following expression where val, lower, and upper are numeric variables:

min(max(val,lower), upper)

a. Suppose that val = 30, lower = 0, and upper = 100. Predict the value the above expression would evaluate to.

b. Verify your prediction by executing the following in the REPL.

>>> val = 30
>>> lower = 0
>>> upper = 100
>>> min(max(val,lower), upper)

c. What do you think the expression would evaluate to if val = 150 instead? Test your guess in the REPL. What about if val = -50?

d. Explain in your own words what the expression is computing when lower = 0 and upper = 100.

e. What about if lower = 20 and upper = 30?

f. Explain in your own words what the expression is computing in terms of generic lower and upper numeric values.

Exercise 4

We discussed how ints are precise and can be arbitrarily large, but floats are only approximations and there are limits to what numbers they can represent.

a. Try experimenting with large integers by typing expressions like the following into the REPL. (Remember that 2 ** 3 computes “two raised to the third power.”)

>>> 2 ** 100
>>> 2 ** 1000
>>> 2 ** 10000

b. Now try doing the same except with floats.

>>> 2.0 ** 100
>>> 2.0 ** 1000
>>> 2.0 ** 10000

c. We know that if you take the square root of a number, then square it, we should get the same number back. Let’s try this out. Try the following commands in the REPL.

>>> import math
>>> x = math.sqrt(2)
>>> x * x

You should always keep in mind that floats are limited in the numbers they can represent and will always accumulate errors!

d. Have you ever wondered what happens if you take the sqrt of a negative number in Python? Try it!

>>> x = math.sqrt(-2)

Exercise 5

Recall that the round function rounds a decimal number to the nearest whole number.

a. Play around with the round function by executing it on the following inputs.

>>> round(5.7)
>>> round(5)
>>> round(5.0)
>>> round(-13.9)
>>> round(7.91227, 2)
>>> round(7.91227, 3)
>>> round(math.pi, 2)

b. Ever wonder how some of these built-in functions are implemented? Let’s try to implement round by ourselves without using it directly. Write an expression that rounds a number to the nearest whole number without using round. HINT: the int() function does something very similar to round(). Think about how you could use int() and the + operator to compute round.

c. Let’s go even further by rounding to certain decimal places! Create a new file called round.py with the following starter code.

# round.py
# Titus Klinge, YOUR NAME(S) GO HERE
# 2019-04-08
#
# A simple program that rounds a number to a certain number of decimal places
def main():
    num = float(input("Enter a float to be rounded: "))
    precision = int(input("Enter the decimal point precision you want: "))

    # rounded_num = ...
    # print("Your number rounded is:", rounded_num)

main()

d. Uncomment the last two lines of code in the main() function by deleting the # in front of them. (Make sure that these lines of code line up horizontally with the first two lines of the main() function.)

e. Finish writing the program by filling in the “…” of the rounded_num definition. Remember that you cannot use round directly—you must come up with your own expression for it. HINT: how can you modify your idea from part c. to work with decimal places? You might want to use / and * operations here to “shift” the decimal place around.

f. Test your program on a variety of inputs until you are satisfied that it is correct.

Exercise 6

Sometimes it is useful to add and subtract clock times together. For example, if you are observing a runner’s lap time, you might measure the start time and the end time and subtract them.

a. Write a program called subtract_times.py that asks the user for four integer inputs:

  1. The minutes of the start time
  2. The seconds of the start time
  3. The minutes of the end time
  4. The seconds of the end time

It should then compute the difference of the end time and start time and output the elapsed time in minutes and seconds. (Note that the seconds should be a value between 0 and 59! Therefore simply subtracting minutes and seconds will not work.)

b. Test your program on a variety of inputs.