CPSC120B
Fundamentals of Computer Science I

Lab 18

While Loops

Rewrite the following function that uses a for loop to use a while loop instead.

    def even_total(maximum):
        total = 0
        for i in range(2, maximum, 2):
            total += i
        return total
  


Write a function count(number), which counts the number of times that number can be divided by 10 before the result of the division is less than 1. Specifically:

$$count(number) = i, \mbox{ where } \frac{number}{10 ^ i} < 1$$


Grade Averaging

For loops are great if you know exactly how many times you want to do some repeated task. However, we often don't know that critical piece of information. We know when we want to stop, but not necessarily the number of executions that requires. While loops allow us to execute some block of code while a specific condition holds.

Details

Create a Python program in a file called grade_average.py. This program should repeatedly ask the user for a grade to include in the average. This will continue until the user types a \(-1\) value to your program. This function should then print the arithmetic mean of all of the grades the user input.

Make sure you test your program well. How many test cases do you need? Make sure you follow all of the course's coding conventions.

Example

$ python3 grade_average.py
Enter a grade, -1 to quit: 100
Enter a grade, -1 to quit: 80
Enter a grade, -1 to quit: -1
The average grade is 90

Hint

  • You are using a while loop, but you can still use the accumulator pattern. You actually need two different accumulators: one that holds the sum of all the input grades, and another that holds a count of how many grades were entered.

  • Remember that input always returns a string. To get an integer from this string, you must use the int function.

  • Recall that the arithmetic mean is simply the sum of all of the values divided by the number of elements in the sum. Mathematically speaking, the arithmetic mean is:

    $$ mean = \frac{\sum\limits_{i=0}^n x_i}{n} $$
    Where \(x_i\) are the grades the user input, and \(n\) is the total number of grades input.

Challenge

This program could have been written using a for loop, if the user provided you with some additional information to begin with. Create a file called input_average_for.py, which behaves exactly the same as the above program except using a for loop instead.

Babylonian Square Root

One use of loops is to perform approximations of slightly complicated mathematical operations. One such operation is square roots. While it may seem impossible to figure out a square root without a calculator, one of the earliest known methods for approximating a square root was in use by the Babylonians in the 5th century B.C.E.

Details

Create a function called babylonian_approximation(n) in a file called babylonian_roots.py. This function takes a positive integer \(n\) as a parameter, and returns an approximation of the square root of \(n\).

To find the square root of \(n\), we start out with \(s = \frac{n}{2}\), which is our current approximation for the square root of \(n\). We can iteratively compute a new value:

$$s = \frac{1}{2} \times (s + \frac{n}{s})$$

Which computes our new esitmate of the square root of \(n\). We can continue to perform this computation until our current value \(s^2\) is close enough to \(n\) that the difference is negligible. Consider \(s^2\) within \(0.001\) of \(n\) as close enough.

Make sure you test your program well. How many test cases do you need? Make sure you follow all of the course's coding conventions.

Example

>>> sqrt_approx = babylonian_approximation(25)
>>> print(sqrt_approx)
5.000012953048684
>>> print(sqrt_approx ** 2 - 25)
0.00012953065462539826
>>> sqrt_approx = babylonian_approximation(81)
>>> print(sqrt_approx)
9.000009415515176
>>> print(sqrt_approx ** 2 - 81)
0.00016947936182987178

Hint

  • You are going to iteratively jump back and forth between the actual value of the square root defined. Your while loop condition should check to see if your current estimate \(s\) is within \(0.001\) of \(n\).

  • You aren't exactly using the accumulator pattern in this exercise. However, you must reuse the variable storing \(s\).

Challenge

You can use any value of \(s\) to get to some approximation. However, choosing a better starting value will cause your code to get better approximations more quickly. If you can figure out how many digits are in \(n\), you can use the following formula to compute a "good" starting value, where \(d\) is the number of digits in \(n\):

$$s = 4 \times 10 ^ {\frac{(d - 1)}{2}}$$

Write a function that given a positive integer returns the number of digits in the integer. Use this function to initialize the first approximate square root value in the babylonian_approximation function using the above equation.

Submission

Please show your source code and run your programs for the instructor or lab assistant. Only a programs that have perfect style and flawless functionality will be accepted as complete.