Chapter 3 Computing with Numbers When computers were first developed,they were seen primarily as number crunchers,and that is still an important application.As you have seen,problems that involve mathematical formulas are easy to translate into Python programs.This chapter takes a closer look at computations involving numeric calculations. 3.1 Numeric Data Types The information that is stored and manipulated by computer programs is generically referred to as data. Different kinds of data will be stored and manipulated in different ways.Consider this program that calculates the value of loose change. change.py #A program to calculate the value of some change in dollars def main(): print "Change Counter" print print "Please enter the count of each coin type." quarters input("Quarters:" dimes input ("Dimes:" nickels input("Nickels:" pennies input("Pennies:" total quarters *.25 dimes *.10 nickels *.05 pennies *.01 print print "The total value of your change is",total main() Here is an example of the output. Change Counter Please enter the count of each coin type. Quarters:5 Dimes:3 Nickels:4 Pennies:6 The total value of your change is 1.81 This program actually manipulates two different kinds of numbers.The values entered by the user(5,3, 4,6)areare whole numbers;they don't have any fractional part.The values of the coins(.25,.10,.05,.01) 25
Chapter 3 Computing with Numbers When computers were first developed, they were seen primarily as number crunchers, and that is still an important application. As you have seen, problems that involve mathematical formulas are easy to translate into Python programs. This chapter takes a closer look at computations involving numeric calculations. 3.1 Numeric Data Types The information that is stored and manipulated by computer programs is generically referred to as data. Different kinds of data will be stored and manipulated in different ways. Consider this program that calculates the value of loose change. # change.py # A program to calculate the value of some change in dollars def main(): print "Change Counter" print print "Please enter the count of each coin type." quarters = input("Quarters: ") dimes = input("Dimes: ") nickels = input("Nickels: ") pennies = input("Pennies: ") total = quarters * .25 + dimes * .10 + nickels * .05 + pennies * .01 print print "The total value of your change is", total main() Here is an example of the output. Change Counter Please enter the count of each coin type. Quarters: 5 Dimes: 3 Nickels: 4 Pennies: 6 The total value of your change is 1.81 This program actually manipulates two different kinds of numbers. The values entered by the user (5, 3, 4, 6) are are whole numbers; they don’t have any fractional part. The values of the coins (.25, .10, .05, .01) 25
26 CHAPTER 3.COMPUTING WITH NUMBERS are decimal fractions.Inside the computer,whole numbers and numbers that have fractional components are represented differently.Technically,we say that these are two different data types. The data type of an object determines what values it can have and what operations can be performed on it. Whole numbers are represented using the integer data type(int for short).Values of type int can be positive or negative whole numbers.Numbers that can have fractional parts are represented as floating point(or floar) values.So how do we tell whether a number is an int or a float?A numeric literal that does not contain a decimal point produces an int value,while a literal that has a decimal point is represented by a float(even if the fractional part is 0). Python provides a special function called type that tells us the data type of any value.Here is an interaction with the Python interpreter showing the difference between int and float literals. >>>type(3) <type 'int'> >>>type(3.14) <type 'float'> >>>type(3.0) <type 'float'> >>myInt =-32 >>type(myInt) <type 'int'> >>>myF1oat=32.0 >>type(myFloat) <type 'float'> You may be wondering why there are two different data types for numbers.One reason has to do with program style.Values that represent counts can't be fractional;we can't have 3 quarters,for example.Using an int value tells the reader of a program that the value can't be a fraction.Another reason has to do with the efficiency of various operations.The underlying algorithms that perform computer arithmetic are simpler, and therefore faster,for ints than the more general algorithms required for float values. You should be warned that the float type only stores approximations.There is a limit to the precision,or accuracy,of the stored values.Since float values are not exact,while ints always are,your general rule of thumb should be:if you don't absolutely need fractional values,use an int. operator operation + addition subtraction multiplication / division 米米 exponentiation % remainder abs ( absolute value Table 3.1:Python built-in numeric operations. A value's data type determines what operations can be used on it.As we have seen,Python supports the usual mathematical operations on numbers.Table 3.1 summarizes these operations.Actually,this table is somewhat misleading since the two numeric data types have their own operations.When addition is performed on floats,the computer performs a floating point addition.Whereas,with ints,the computer performs an integer addition. Consider the following interaction with Python: >>>3.0+4.0 7.0 >>>3+4 7
26 CHAPTER 3. COMPUTING WITH NUMBERS are decimal fractions. Inside the computer, whole numbers and numbers that have fractional components are represented differently. Technically, we say that these are two different data types. The data type of an object determines what values it can have and what operations can be performed on it. Whole numbers are represented using the integer data type (int for short). Values of type int can be positive or negative whole numbers. Numbers that can have fractional parts are represented as floating point (or float) values. So how do we tell whether a number is an int or a float? A numeric literal that does not contain a decimal point produces an int value, while a literal that has a decimal point is represented by a float (even if the fractional part is 0). Python provides a special function called type that tells us the data type of any value. Here is an interaction with the Python interpreter showing the difference between int and float literals. >>> type(3) <type ’int’> >>> type(3.14) <type ’float’> >>> type(3.0) <type ’float’> >>> myInt = -32 >>> type(myInt) <type ’int’> >>> myFloat = 32.0 >>> type(myFloat) <type ’float’> You may be wondering why there are two different data types for numbers. One reason has to do with program style. Values that represent counts can’t be fractional; we can’t have 3 1 2 quarters, for example. Using an int value tells the reader of a program that the value can’t be a fraction. Another reason has to do with the efficiency of various operations. The underlying algorithms that perform computer arithmetic are simpler, and therefore faster, for ints than the more general algorithms required for float values. You should be warned that the float type only stores approximations. There is a limit to the precision, or accuracy, of the stored values. Since float values are not exact, while ints always are, your general rule of thumb should be: if you don’t absolutely need fractional values, use an int. operator operation ✂ addition ✂ subtraction multiplication ✁ division ✁ exponentiation % remainder abs() absolute value Table 3.1: Python built-in numeric operations. A value’s data type determines what operations can be used on it. As we have seen, Python supports the usual mathematical operations on numbers. Table 3.1 summarizes these operations. Actually, this table is somewhat misleading since the two numeric data types have their own operations. When addition is performed on floats, the computer performs a floating point addition. Whereas, with ints, the computer performs an integer addition. Consider the following interaction with Python: >>> 3.0 + 4.0 7.0 >>> 3 + 4 7
3.2.USING THE MATH LIBRARY 27 >>3.0*4.0 12.0 >>>3*4 12 >>>10.0/3.0 3.33333333333 >>>10/3 3 >>>10号3 1 >>>abs(5) 5 >>>abs(-3.5) 3.5 Notice how operations on floats produce floats,and operations on ints produce ints.Most of the time,we don't have to worry about what type of operation is being performed,for example,integer addition produces pretty much the same result as floating point addition. However,in the case of division,the results are quite different.Integer division always produces an integer,discarding any fractional result.Think of integer division as"gozinta."The expression,10 /3 produces 3 because three gozinta(goes into)ten three times (with a remainder of one).The third to last example shows the remainder operation()in action.The remainder of dividing 10 by 3 is 1.The last two examples illustrate taking the absolute value of an expression. You may recall from Chapter 2 that Suzie Programmer used the expression 9.0 /5.0 in her tempera- ture conversion program rather than 9 /5.Now you know why.The former gives the correct multiplier of 1.8.while the latter yields just 1.since 5 gozinta 9 just once. 3.2 Using the Math Library Besides the operations listed in Table 3.1,Python provides many other useful mathematical functions in a special math library.A library is just a module that contains some useful definitions.Our next program illustrates the use of this library to compute the roots of quadratic equations. A quadratic equation has the form ax2+bx+c.0.Such an equation has two solutions for the value of x given by the quadratic formula: -b±V6-4ac x. 2a Let's write a program that can find the solutions to a quadratic equation.The input to the program will be the values of the coefficients a,b,and c.The outputs are the two values given by the quadratic formula.Here's a program that does the job. #quadratic.py A program that computes the real roots of a quadratic equation. Illustrates use of the math library. Note:this program crashes if the equation has no real roots. import math Makes the math library available. def main(): print "This program finds the real solutions to a quadratic" print a,b,c input ("Please enter the coefficients (a,b,c):" discRoot math.sgrt(b b-4 a c)
3.2. USING THE MATH LIBRARY 27 >>> 3.0 * 4.0 12.0 >>> 3 * 4 12 >>> 10.0 / 3.0 3.33333333333 >>> 10 / 3 3 >>> 10 % 3 1 >>> abs(5) 5 >>> abs(-3.5) 3.5 Notice how operations on floats produce floats, and operations on ints produce ints. Most of the time, we don’t have to worry about what type of operation is being performed; for example, integer addition produces pretty much the same result as floating point addition. However, in the case of division, the results are quite different. Integer division always produces an integer, discarding any fractional result. Think of integer division as “gozinta.” The expression, 10 / 3 produces 3 because three gozinta (goes into) ten three times (with a remainder of one). The third to last example shows the remainder operation (%) in action. The remainder of dividing 10 by 3 is 1. The last two examples illustrate taking the absolute value of an expression. You may recall from Chapter 2 that Suzie Programmer used the expression 9.0 / 5.0 in her temperature conversion program rather than 9 / 5. Now you know why. The former gives the correct multiplier of 1 8, while the latter yields just 1, since 5 gozinta 9 just once. 3.2 Using the Math Library Besides the operations listed in Table 3.1, Python provides many other useful mathematical functions in a special math library. A library is just a module that contains some useful definitions. Our next program illustrates the use of this library to compute the roots of quadratic equations. A quadratic equation has the form ax2 ✂ bx ✂ c 0. Such an equation has two solutions for the value of x given by the quadratic formula: x ✂b ✂✁b 2 ✂ 4ac 2a Let’s write a program that can find the solutions to a quadratic equation. The input to the program will be the values of the coefficients a, b, and c. The outputs are the two values given by the quadratic formula. Here’s a program that does the job. # quadratic.py # A program that computes the real roots of a quadratic equation. # Illustrates use of the math library. # Note: this program crashes if the equation has no real roots. import math # Makes the math library available. def main(): print "This program finds the real solutions to a quadratic" print a, b, c = input("Please enter the coefficients (a, b, c): ") discRoot = math.sqrt(b * b - 4 * a * c)
28 CHAPTER 3.COMPUTING WITH NUMBERS root1 (-b discRoot)/(2 a) root2 (-b-discRoot)/(2 a) print print "The solutions are:"root1,root2 main() This program makes use of the square root function sqrt from the math library module.The line at the top of the program: import math tells Python that we are using the math module.Importing a module makes whatever is defined in it available to the program.To compute vx,we use math.sqrt (x).You may recall this dot notation from Chapter 1. This tells Python to use the sqrt function that"lives"in the math module.In the quadratic program we calculate vb2-4*ac with the line discRoot math.sgrt(b b-4 a c) Here is how the program looks in action: This program finds the real solutions to a quadratic Please enter the coefficients (a,b,c):3,4,-2 The so1 utions are:0.387425886723-1.72075922006 This program is fine as long as the quadratics we try to solve have real solutions.However,some inputs will cause the program to crash.Here's another example run: This program finds the real solutions to a quadratic Please enter the coefficients (a,b,c):1,2,3 Traceback (innermost last): File "<stdin>",line 1,in File "quadratic.py",line 13,in discRoot math.sqrt(b b-4 a c) OverflowError:math range error The problem here is that b2-4*a*c<0,and the sgrt function is unable to compute the square root of a negative number.Python prints a math range error.Right now,we don't have the tools to fix this problem,so we will just have to assume that the user gives us solvable equations. Actually,quadratic.py did not need to use the math library.We could have taken the square root using exponentiation **.(Can you see how?)Using math.sqrt is somewhat more efficient and allowed me to illustrate the use of the math library.In general,if your program requires a common mathematical function,the math library is the first place to look.Table 3.2 shows some of the other functions that are available in the math library. 3.3 Accumulating Results:Factorial Suppose you have a root beer sampler pack containing six different kinds of root beer.Drinking the various flavors in different orders might affect how good they taste.If you wanted to try out every possible ordering, how many different orders would there be?It turns out the answer is a surprisingly large number,720.Do you know where this number comes from?The value 720 is the factorial of 6. In mathematics,factorial is often denoted with an exclamation("").The factorial of a whole number n is defined as n!=n(n-1)(n-2)...(1).This happens to be the number of distinct arrangements for n items. Given six items,we compute 6!=(6)(5)(4)(3)(2)(1)=720 possible arrangements
28 CHAPTER 3. COMPUTING WITH NUMBERS root1 = (-b + discRoot) / (2 * a) root2 = (-b - discRoot) / (2 * a) print print "The solutions are:", root1, root2 main() This program makes use of the square root function sqrt from the math library module. The line at the top of the program: import math tells Python that we are using the math module. Importing a module makes whatever is defined in it available to the program. To compute ✁ x, we use math.sqrt(x). You may recall this dot notation from Chapter 1. This tells Python to use the sqrt function that “lives” in the math module. In the quadratic program we calculate ✁ b 2 ✂ 4 ac with the line discRoot = math.sqrt(b * b - 4 * a * c) Here is how the program looks in action: This program finds the real solutions to a quadratic Please enter the coefficients (a, b, c): 3, 4, -2 The solutions are: 0.387425886723 -1.72075922006 This program is fine as long as the quadratics we try to solve have real solutions. However, some inputs will cause the program to crash. Here’s another example run: This program finds the real solutions to a quadratic Please enter the coefficients (a, b, c): 1, 2, 3 Traceback (innermost last): File "<stdin>", line 1, in ? File "quadratic.py", line 13, in ? discRoot = math.sqrt(b * b - 4 * a * c) OverflowError: math range error The problem here is that b 2 ✂ 4 a c 0, and the sqrt function is unable to compute the square root of a negative number. Python prints a math range error. Right now, we don’t have the tools to fix this problem, so we will just have to assume that the user gives us solvable equations. Actually, quadratic.py did not need to use the math library. We could have taken the square root using exponentiation **. (Can you see how?) Using math.sqrt is somewhat more efficient and allowed me to illustrate the use of the math library. In general, if your program requires a common mathematical function, the math library is the first place to look. Table 3.2 shows some of the other functions that are available in the math library. 3.3 Accumulating Results: Factorial Suppose you have a root beer sampler pack containing six different kinds of root beer. Drinking the various flavors in different orders might affect how good they taste. If you wanted to try out every possible ordering, how many different orders would there be? It turns out the answer is a surprisingly large number, 720. Do you know where this number comes from? The value 720 is the factorial of 6. In mathematics, factorial is often denoted with an exclamation (“!”). The factorial of a whole number n is defined as n! n n ✂ 1 ✁ n ✂ 2✁ 1 ✁ . This happens to be the number of distinct arrangements for n items. Given six items, we compute 6! 6✁ 5✁ 4✁ 3✁ 2✁ 1 ✁ 720 possible arrangements
3.3.ACCUMULATING RESULTS:FACTORIAL 29 Python Mathematics English pi 元 An approximation of pi. e An approximation ofe. sin(x) sinx The sine of x. cos(x) cOSx The cosine of x tan(x) tanx The tangent of x. asin(x) arcsinx The inverse of sine x. acos(x) arccosx The inverse of cosine x. atan (x) arctanx The inverse of tangent x log(x) Inx The natural (base e)logarithm of x 1og10(x) giox The common(base 10)logarithm of x exp(x) R) The exponential of x. ceil(x) x The smallest whole number<x floor(x) The largest whole number<x Table 3.2:Some math library functions. Let's write a program that will compute the factorial of a number entered by the user.The basic outline of our program follows an Input-Process-Output pattern. Input number to take factorial of,n Compute factorial of n,fact Output fact Obviously,the tricky part here is in the second step. How do we actually compute the factorial?Let's try one by hand to get an idea for the process.In computing the factorial of 6,we first multiply 6*5<30.Then we take that result and do another multipli- cation 30*4<120.This result is multiplied by three 120*3<360.Finally,this result is multiplied by 2 360*2<720.According to the definition,we then multiply this result by 1,but that won't change the final value of 720. Now let's try to think about the algorithm more generally.What is actually going on here?We are doing repeated multiplications,and as we go along,we keep track of the running product.This is a very common algorithmic pattern called an accumulator.We build up,or accumulate,a final value piece by piece.To accomplish this in a program,we will use an accumulator variable and a loop structure.The general pattern looks like this. Initialize the accumulator variable Loop until final result is reached update the value of accumulator variable Realizing this is the pattern that solves the factorial problem,we just need to fill in the details.We will be accumulating the factorial.Let's keep it in a variable called fact.Each time through the loop,we need to multiply fact by one of the factors n,n-1),1.It looks like we should use a for loop that iterates over this sequence of factors.For example,to compute the factorial of6,we need a loop that works like this fact =1 for factor in [6,5,4,3,2,1]: fact fact factor Take a minute to trace through the execution of this loop and convince yourself that it works.When the loop body first executes,fact has the value 1 and factor is 6.So,the new value of fact is 1*6<6. The next time through the loop,factor will be 5,and fact is updated to 6*5<30.The pattern continues for each successive factor until the final result of 720 has been accumulated. The initial assignment of 1 to fact before the loop is essential to get the loop started.Each time through the loop body (including the first),the current value of fact is used to compute the next value.The
3.3. ACCUMULATING RESULTS: FACTORIAL 29 Python Mathematics English pi π An approximation of pi. e e An approximation of e. sin(x) sinx The sine of x. cos(x) cosx The cosine of x. tan(x) tanx The tangent of x. asin(x) arcsinx The inverse of sine x. acos(x) arccosx The inverse of cosine x. atan(x) arctanx The inverse of tangent x. log(x) lnx The natural (base e) logarithm of x log10(x) log10 x The common (base 10) logarithm of x. exp(x) e x The exponential of x. ceil(x) x✁ The smallest whole number x floor(x) ✂x✄ The largest whole number x Table 3.2: Some math library functions. Let’s write a program that will compute the factorial of a number entered by the user. The basic outline of our program follows an Input-Process-Output pattern. Input number to take factorial of, n Compute factorial of n, fact Output fact Obviously, the tricky part here is in the second step. How do we actually compute the factorial? Let’s try one by hand to get an idea for the process. In computing the factorial of 6, we first multiply 6 5 30. Then we take that result and do another multiplication 30 4 120. This result is multiplied by three 120 3 360. Finally, this result is multiplied by 2 360 2 720. According to the definition, we then multiply this result by 1, but that won’t change the final value of 720. Now let’s try to think about the algorithm more generally. What is actually going on here? We are doing repeated multiplications, and as we go along, we keep track of the running product. This is a very common algorithmic pattern called an accumulator. We build up, or accumulate, a final value piece by piece. To accomplish this in a program, we will use an accumulator variable and a loop structure. The general pattern looks like this. Initialize the accumulator variable Loop until final result is reached update the value of accumulator variable Realizing this is the pattern that solves the factorial problem, we just need to fill in the details. We will be accumulating the factorial. Let’s keep it in a variable called fact. Each time through the loop, we need to multiply fact by one of the factors n ☎ n ✂ 1✁✆☎ ✝☎ 1. It looks like we should use a for loop that iterates over this sequence of factors. For example, to compute the factorial of 6, we need a loop that works like this. fact = 1 for factor in [6,5,4,3,2,1]: fact = fact * factor Take a minute to trace through the execution of this loop and convince yourself that it works. When the loop body first executes, fact has the value 1 and factor is 6. So, the new value of fact is 1 6 6. The next time through the loop, factor will be 5, and fact is updated to 6 5 30. The pattern continues for each successive factor until the final result of 720 has been accumulated. The initial assignment of 1 to fact before the loop is essential to get the loop started. Each time through the loop body (including the first), the current value of fact is used to compute the next value. The