A range is an array of numbers in increasing or decreasing order, each separated by a regular interval. Ranges are useful in a surprisingly large number of situations, so it’s worthwhile to learn about them.
Ranges are defined using the
np.arange function, which takes either one, two, or three arguments: a start, and end, and a ‘step’.
If you pass one argument to
np.arange, this becomes the
end value, with
step=1 assumed. Two arguments give the
step=1 assumed. Three arguments give the
A range always includes its
start value, but does not include its
end value. It counts up by
step, and it stops before it gets to the
np.arange(end): An array starting with 0 of increasing consecutive integers, stopping before end.
array([0, 1, 2, 3, 4])
Notice how the array starts at 0 and goes only up to 4, not to the end value of 5.
np.arange(start, end): An array of consecutive increasing integers from start, stopping before end.
array([3, 4, 5, 6, 7, 8])
np.arange(start, end, step): A range with a difference of step between each pair of consecutive values, starting from start and stopping before end.
np.arange(3, 30, 5)
array([ 3, 8, 13, 18, 23, 28])
This array starts at 3, then takes a step of 5 to get to 8, then another step of 5 to get to 13, and so on.
When you specify a step, the start, end, and step can all be either positive or negative and may be whole numbers or fractions.
np.arange(1.5, -2, -0.5)
array([ 1.5, 1. , 0.5, 0. , -0.5, -1. , -1.5])
5.2.1. Example: Leibniz’s formula for \(\pi\)#
The great German mathematician and philosopher Gottfried Wilhelm Leibniz (1646 - 1716) discovered a wonderful formula for \(\pi\) as an infinite sum of simple fractions. The formula is
Though some math is needed to establish this, we can use arrays to convince ourselves that the formula works. Let’s calculate the first 5000 terms of Leibniz’s infinite sum and see if it is close to \(\pi\).
We will calculate this finite sum by adding all the positive terms first and then subtracting the sum of all the negative terms :
The positive terms in the sum have 1, 5, 9, and so on in the denominators. The array
by_four_to_20 contains these numbers up to 17:
by_four_to_20 = np.arange(1, 20, 4) by_four_to_20
array([ 1, 5, 9, 13, 17])
To get an accurate approximation to \(\pi\), we’ll use the much longer array
positive_term_denominators = np.arange(1, 10000, 4) positive_term_denominators
array([ 1, 5, 9, ..., 9989, 9993, 9997])
The positive terms we actually want to add together are just 1 over these denominators:
positive_terms = 1 / positive_term_denominators
The negative terms have 3, 7, 11, and so on on in their denominators. This array is just 2 added to
negative_terms = 1 / (positive_term_denominators + 2)
The overall sum is
4 * ( sum(positive_terms) - sum(negative_terms) )
This is very close to \(\pi = 3.14159\dots\). Leibniz’s formula is looking good!
 Surprisingly, when we add infinitely many positive and negative fractions, the order can matter! But our approximation to \(\pi\) uses only a large finite number of fractions, so it’s okay to add the terms in any convenient order.