Different results when using != or > in loop condition

Asked

Viewed 444 times

1

I was doing Python exercises and came across the following problem.

Assuming that the population of a country A is on the order of 80000 inhabitants with an annual growth rate of 3% and that the population of B is 200000 inhabitants with a growth rate of 1.5%. Make a program that calculates and writes the number of years necessary for the population of the country A to exceed or equal the population of the country B, maintained growth rates. So I tried to solve it this way:

A = population 1 = 80000

B = population 2 = 200000

time = 0

while A != B:
A = A + A*(0.03)
B = B + B*(0.015)
tempo = tempo + 1
else:
print(A,B,tempo)

Conduit, when I run the program, appears 'inf inf'' for A and B and the time gives a very large number. I found a solution on the internet, but I do not understand why there is difference. The solution only modifies the operator != by the operator <:

while A < B:
    A = A + A*(0.03)
    B = B + B*(0.015)
    tempo = tempo + 1
    else:
    print(A,B,tempo)

I understand that if A is smaller than B the solution also works. But why if A is different from B the solution doesn’t work?

  • 1

    Why perhaps the variables being compared never reach an exactly equal value, even because the floating point data type is inherently inaccurate and should not be used in strict equality tests.

3 answers

4

Modifying your program a little, putting the print within the while, we can understand what is happening:

a = 80000
b = 200000
tempo = 0
while a != b:
    a += a * 0.03
    b += b * 0.015
    tempo += 1
    print(a, b, tempo)

This program will print many lines, but I separated these two in particular:

500032.13864656974 503413.2186819931 62
515033.10280596686 510964.41696222295 63

That is the point at which the value of a becomes bigger than b (when tempo is 62, a is smaller, but in the next iteration, it becomes larger).

So if the condition is while a < b, it will stop at iteration 62 (for in the 63, the value of a will be bigger, causing the loop stop).

But if the condition is while a != b, it will not stop at this iteration, because the values of a and b are still different. And as now a is greater than b and a is growing at a higher rate, the values will remain different.
The loop will only stop when a and b are the same. And when will they be the same? In the last lines of the program we can see:

inf 1.7702779365710949e+308 46852
inf 1.7968321056196613e+308 46853
inf inf 46854

As you can see, there comes a time when the values of a and b go beyond the maximum permitted for a float and become "infinite". At this point, a and b become equal and the loop closes.


Another detail is that else is unnecessary. A block else associated with a loop is executed whenever the loop ends without being interrupted by a break, but as in this case there is no break, it will always run. So you can simply do:

a = 80000
b = 200000
tempo = 0
while a < b:
    a *= 1.03
    b *= 1.015
    tempo += 1

print(a, b, tempo)

Note that I also changed the calculation of the increase of a and b (if it increases by 3%, just multiply by 1.03, the same goes for an increase of 1.5%).

3

The condition you put "!=" or A other than B makes the program tending to infinity. When using "A < B", the condition stops the program by having A equal to or greater than B.

3

There is a noniterative approach to this problem.

import math

a = 80000
b = 200000

t = math.ceil(math.log(a/b, 1.015 / 1.03))


print(a * 1.03 ** t, b * 1.015 ** t, t)

Test in Repl.it

To understand, a little calculation comes in handy.

Looking at its problem carefully it is possible to identify that it is the expansion composed of two population vectors given a common temporal frequency to both.

Equação da expansão populacional

where:

  • Pa is initial population of A.
  • Pb is initial population of B.
  • Ca is the growth rate of A.
  • Cb is the growth rate of B.
  • t is the time it takes for the two populations to match

This is the formula of Bernoulli, is the same formula used to calculate compound interest, is also used to calculate expansion through rate versus frequency.

So to take advantage of this formula within the programming language we must isolate the unknown t. Continuing:

inserir a descrição da imagem aqui
inserir a descrição da imagem aqui
inserir a descrição da imagem aqui
inserir a descrição da imagem aqui
inserir a descrição da imagem aqui

In other words, the moment of intersection of the two populations is given by math.log(a/b, 1.015 / 1.03) and is rounded up with ceil() because the year asks for the date in years and to calculate each population in the period of use the formula already presented P x (1 + C) ^ T.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.