Infinite while loop - python

1

This exercise is a simulation of a ship arrival system playing with random numbers. Initially, a random number is run to know how many ships arrive during the day. immediately another is generated to see how many ships from which they arrived can unload merchandise. Those who could not download that day, may do so the next day, and it will accumulate to the next day's boats. an example of what the program would be:

#   ALEAT   BARCOS  ACUM    ALEAT2  DESCARGADOS RESTANTE
1   0.678     3       0     0.823       2          1
2   0.806     4       1     0.401       3          2
3   0.967     5       2     0.785       5          2
4   0.116     1       2     0.463       2          1
5   0.760     4       1     0.850       4          1
6   0.103     0       1     0.019       0          1
7   0.849     4       1     0.524       2          3
8   0.566     3       3     0.215       3          3
9   0.567     4       3     0.936       4          3
10  0.122     5       3     0.398       4          4
11  0.455     1       4     0.533       1          4
12  0.165     1       4     0.883       1          4
13  0.031     2       4     0.983       2          4
14  0.571     5       4     0.357       3          6
15  0.513     1       6     0.835       1          6

In the code I have, I generate a random # to know how many ships come to download, the downloaded variable should not be greater than the number of ships that arrive. my idea was to do a while to generate another random # until a smaller amount was generated to arriving ships.

When I run the program, it freezes trying to generate a random number that is less than the variable barcos , but there are times when it runs normally.

from random import random

i=1
Acum = 0
count = 0
barcos = 0
sumaacum = 0

print("#\tALEAT\tBARCOS\tACUM\tSumaAcum\tALEAT\tBdESCAR\tREST")
while i <= 15:
    aleat=random()
    if aleat < 0.13:
        barcos = 0
    elif aleat < 0.3:
        barcos = 1
    elif aleat < 0.45:
        barcos = 2
    elif aleat < 0.7:
        barcos = 3
    elif aleat < 0.9:
        barco = 4
    else:
        barcos = 5

    while True:
        aleat2 = random()
        if aleat2 < 0.05:
            descargados = 1
        elif aleat2 < 0.2:
            descargados = 2
        elif aleat2 < 0.7:
            descargados = 3
        elif aleat2 < 0.9:
            descargados = 4
        else:
            descargados = 5
        if descargados > barcos:
            aleat2 = random()  
        else:
            break

    sumaacum = barcos + Acum
    restan = sumaacum - descargados
    count += restan
    print("{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}".format(i,str(aleat)[0:5],barcos,Acum,sumaacum,str(aleat2)[0:5],descargados,restan))

    Acum = restan
    i+=1
print("el total de barcos con retardo son: {}".format(count))

the output of the program is:

#       ALEAT   BARCOS  ACUM    SumaAcum        ALEAT   BdESCAR REST
1       0.426   2       0       2       0.199   2       0
2       0.866   2       0       2       0.000   1       1
3       0.536   3       1       4       0.066   2       2
4       0.679   3       2       5       0.154   2       3
5       0.857   3       3       6       0.673   3       3
6       0.983   5       3       8       0.646   3       5
7       0.772   5       5       10      0.028   1       9
8       0.520   3       9       12      0.516   3       9
9       0.748   3       9       12      0.109   2       10
Traceback (most recent call last):
  File "c:\Users\cisco\Desktop\tempCodeRunnerFile.py", line 30, in <module>
    descargados = 2
KeyboardInterrupt

On this occasion, the program is trying to generate a random # talque boats descargados is less than barcos that arrive. I had to stop the program by pressing Ctrl + c to run the program again.

#       ALEAT   BARCOS  ACUM    SumaAcum        ALEAT   BdESCAR REST
1       0.335   2       0       2       0.052   2       0
2       0.490   3       0       3       0.605   3       0
3       0.830   3       0       3       0.643   3       0
4       0.492   3       0       3       0.657   3       0
5       0.360   2       0       2       0.169   2       0
6       0.503   3       0       3       0.560   3       0
7       0.752   3       0       3       0.327   3       0
8       0.508   3       0       3       0.518   3       0
9       0.500   3       0       3       0.407   3       0
10      0.971   5       0       5       0.003   1       4
11      0.503   3       4       7       0.522   3       4
12      0.581   3       4       7       0.170   2       5
13      0.549   3       5       8       0.103   2       6
14      0.183   1       6       7       0.035   1       6
15      0.767   1       6       7       0.006   1       6
el total de barcos con retardo son: 31

In this run, the program ran smoothly.

How else can I validate so that it does not form infinite loops and avoid these incidents? Thanks

    
asked by JUAN RAMIREZ 02.11.2018 в 19:31
source

2 answers

1

As I mentioned above, the infinite loop is given when the variable barcos is 0 . Then the comparison you make in if descargados > barcos: will always be fulfilled.

I'll give you a solution to see if it's a little simpler than what you do.

from random import randint

i = 1
acum = 0
count = 0
barcos = 0
sumaacum = 0

print("#\tALEAT\tBARCOS\tACUM\tSumaAcum\tALEAT\tBdESCAR\tREST")
while i <= 15:
    barcos = randint(0, 5)

    descargados = randint(0, barcos)

    sumaacum = barcos + acum
    restan = sumaacum - descargados
    count += restan
    print("{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}".format(i, str(barcos)[0:5], barcos, acum, sumaacum, str(descargados)[0:5],
                                                  descargados, restan))

    acum = restan
    i += 1
print("el total de barcos con retardo son: {}".format(count))

I hope it serves you.

    
answered by 02.11.2018 / 20:42
source
1

The fundamental problem is that you have a cycle that will become infinite in case that barcos == 0 , you are not controlling this situation. I also believe that the problem can be posed in a simpler way. The idea would be

  • Each day you get x boats and that particular day you have a capacity to download y boats
  • If you download more of those that arrive you will reduce the eventual slopes but only until you reach 0, obviously you can not have negative slopes

The other thing that adds complexity is how to get the two random values with a non-uniform distribution. Luckily from version 3.6, Python incorporates in choices() the possibility of add a weight for each element of a list of values to be randomized, and better yet, you can indicate the accumulated weights cum_weights which are the values you have defined.

Let's see:

from random import choices

barcos_probs = [.13, .3, .45, .7, .9, 1]
descargas_probs = [.05, .2, .7, .9,  1]

pendientes = 0
print("#\tBARCOS\tDESC\tPEND")

for i in range(1,16):

  barcos_hoy = choices([0,1,2,3,4,5], cum_weights = barcos_probs)[0]
  descarga_hoy = choices([1,2,3,4,5], cum_weights = descargas_probs)[0]

  descargados = descarga_hoy if descarga_hoy < (pendientes + barcos_hoy) else (pendientes + barcos_hoy)
  pendientes = (pendientes + barcos_hoy) - descargados

  print("{}\t{}\t{}\t{}".format(i, barcos_hoy, descarga_hoy, pendientes))

Explanation:

  • We simulate about 15 days for i in range(1,16)
  • Every day different amounts of ships arrive and we have different download capacities
  • They can reach from 0 to 5 boats and we can download from 1 to 5 of these
  • We have an accumulation of pending boats
  • How many can we download during the day? the capacity that we have up to the amount of pending. We can not download more than we have pending.

Obviously this is a quick and simple approach, you should validate it.

    
answered by 02.11.2018 в 22:02