## Python package simplifies algebraic equations

#### Beautiful and Colorful

To demonstrate how the two faucets interact while filling the tub, the three bar graphs in Figure 4 represent the respective fill levels by minute. In the graph on the left, the bath user only turns on the slow faucet, which fills the tub in 15 minutes; in the middle, the 10-minute fast faucet is active; and, on the right, both faucets are active together.

In Listing 4, starting in line 5, the `fill_tub()`

function takes the tub fill rate per minute (`per_min`

) as well as the number of values on the *X* axis displayed (i.e., the minute ticker). Although the scenarios presented each cover different sets of minute values, the `matplotlib`

functions insist that *X* and *Y* values be arrays of equal size, or else they will provoke non-intuitive error messages from the depths of the library. The `fill_tub()`

function returns two arrays `lx`

and `ly`

that contain values for the *X* and *Y* axes in the bar graph. The two arrays are the same length, and unoccupied *Y* values with the tub already full are simply set to zero for initialization purposes in line 7.

Listing 4

bars.py

01 #!/usr/bin/env python3 02 from matplotlib import pyplot as plt 03 from fractions import Fraction 04 05 def fill_tub(per_min,xmax): 06 lx=list(range(1,xmax+1)) 07 ly=[0] * xmax 08 sum=0 09 for i in range(xmax): 10 sum+=per_min 11 if sum > 1: 12 break 13 ly[i]=sum 14 15 return lx,ly 16 17 xmax=15 18 19 plt.style.use('ggplot') 20 fig,ax = plt.subplots(nrows=1,ncols=3,figsize=(15,5)) 21 fig.suptitle("Filling a bath tub") 22 23 lx,ly = fill_tub(Fraction(1,15),xmax) 24 ax[0].bar(lx,ly,color='tab:red') 25 ax[0].set_xlabel("Minutes") 26 ax[0].set_ylabel("Fill Level") 27 ax[0].set_title("15min faucet") 28 29 lx,ly = fill_tub(Fraction(1,10),xmax) 30 ax[1].bar(lx,ly,color='tab:orange') 31 ax[1].set_xlabel("Minutes") 32 ax[1].set_ylabel("Fill Level") 33 ax[1].set_title("10min faucet") 34 35 lx,ly = fill_tub(Fraction(1,10)+Fraction(1/15),xmax) 36 ax[2].bar(lx, ly, color='tab:green') 37 ax[2].set_xlabel("Minutes") 38 ax[2].set_ylabel("Fill Level") 39 ax[2].set_title("Both 15min and 10min faucet") 40 41 plt.savefig("bars.png")

Painting three different graphs side by side in an image file is a piece of cake for `matplotlib`

: The `subplots()`

function simply creates a graph grid with one row as well as three columns in line 20 and returns an array of three graph objects in `ax`

. With these settings, `matplotlib`

manages to arrange the three graphs beautifully, without any manual intervention. Finally, the last line writes the image data to a newly created image file `bars.png`

.

#### Exact Fraction Calculation

To prevent the program from immediately turning a fraction like 1/15 into a floating-point number, Listing 4 pulls in the *fractions* package, which handles real fractional arithmetic. Thus, line 23 with `Fraction(1, 15)`

can actually pass 1/15 to `fill_tub()`

rather than, say, `0.066666666667`

. The latter would cause nasty rounding errors when summing up fractional values later and possibly even cause the tub to overflow. The *fractions* package, on the other hand, overloads operators like `+`

or `>`

. Therefore, `sum += per_min`

in line 10 actually adds 1/15 to the amount of water in the tub, and `sum`

inside the `if`

condition in line 11 is later exactly `1`

when the tub is full, rather than some close, but not quite right floating-point value.

Infos

- Listings for this article: ftp://ftp.linux-magazine.com/pub/listings/linux-magazine.com/248/
- Virtual environments: https://docs.python.org/3/tutorial/venv.html

« Previous 1 2

## Buy this article as PDF

(incl. VAT)