Home > Blockchain >  Why does my nested loop repeat the same data and/or doesn't append all the things I want it to?
Why does my nested loop repeat the same data and/or doesn't append all the things I want it to?

Time:05-06

So I am trying to simulate an animal hunting and resting. When the animal rests it can either digest or stay the same based on probabilities. When the animal is hunting it can either hunt successfully or not or stay the same based on probabilities. I want the outer nested loop to be the number of animals and the inner loop be the lifespan. The animals has a lower gut limit when the animal is resting if it reaches that level it automatically starts to hunt. The animal also has an upper gut level during hunting and when it reaches it it rests. In addition if the animal reaches a negative state it breaks out of the loop and continues on to the next animal.

I am am trying to run the nested loop and I do not understand what is wrong! Please help me! I noticed when I printed the alist and I looked at the states, there would be weird jumps from like: [0,4,i ] to [1,2,i] and it just skipped over the belly being 4-1! So I want to start of with an initial state then append the list as conditions are met then, I tried to say if the belly reaches a negative I want to record that state then break out and start all over with the next animal .

I also need to count the number of times the animal was successful at hunting, not successful at hunting, times the belly digested, and the number of times the animal stayed the same. I haven't gotten this far yet

Thank you in advance! Sorry if it is confusing! I am not that great at python Here is my code:

import random
initial_state=[0,4,0]#means it is resting, at full belly of 4 these two values also vary 
alist=[initial_state]
died=0
u,s=2,4 #u is the lower belly limit, s is the upper belly limit
a,b,d=1/8,1/3,1/2 #a is the probability for not catching food, b is the probability for getting food,d is the probability for digestion these values also vary 
for i in range (100000):
    digest=random.random()
    hunts=random.random()
    for i in range(1,501):#each animal has a 500 lifespan
        digest=random.random()
        hunts=random.random()
        if alist[i-1][1]==-1:
            died =1
            break #the animal died
        if alist[i-1][0]==0:#If the animal is resting
            if digest<=d:
                belly=alist[i-1][1]-1
                if belly <= u:
                    alist.append([1,belly,i])
                else:
                    alist.append([0,belly,i])
            if digest>1-d:#the animal remains the same 
                belly=alist[i-1][1]
                alist.append([0,belly,i])
        if alist[i-1][0]==1:#if the animal is hunting
            if alist[i-1][1]>=1:
                if hunts<=a:
                    belly=alist[i-1][1]-1
                    alist.append([1,belly,i])
                if a<hunts<=a b:
                    belly=alist[i-1][1] 1
                    if belly==s:#if the animal has a full belly it rests
                        alist.append([0,belly,i])
                    else:
                        alist.append([1,belly,i])
                if hunts>a b:
                    belly=alist[i-1][1]
                    alist.append([alist[i-1][0],belly,i])
            elif alist[i-1][1]==0:#When the belly is empty while hunting
                if hunts<=a:
                    belly=alist[i-1][1]-1
                    alist.append([0,belly,i])
                if a<hunts<=a b:
                    belly=alist[i-1][1] 1
                    alist.append([1,belly,i])
                if hunts>a b:
                    belly=alist[i-1][1]
                    alist.append([alist[i-1][0],belly,i])

Heading

CodePudding user response:

I refactored your code massively so that we can see more clearly what variables actually represent.

Tested a few times, I did not notice the jump in belly level that you mentionned in the comments.


# Imports.
import random

# Constants.
ANIMALS = 3
ANIMAL_LIFESPAN = 30
BELLY_EMPTY = 2 # Will always trigger a hunt next cycle.
BELLY_FULL = 4  # Will always trigger a rest next cycle.
FOOD_CATCHING_PROBABILITY = 1/3
DIGESTION_PROBABILITY = 1/2

initial_state = [False, 4, 0] # Means it is resting, at full belly of 4 these two values also vary.
animals_states = {}
death_counter = 0

for n in range(1, ANIMALS   1):
    states = animals_states[n] = [initial_state]

    for i in range(1, ANIMAL_LIFESPAN   1):
        digest = random.random()
        hunts = random.random()
        is_hunting, belly, _ = states[-1]

        # The animal died.
        if belly < 0:
            death_counter  = 1
            break

        if not is_hunting: # If the animal is resting.
            if digest <= DIGESTION_PROBABILITY:
                belly -= 1
                hunt_next = True if belly <= BELLY_EMPTY else False # Empty belly is triggering a hunt on the next cycle.
            else: # The animal remains the same.
                hunt_next = False

        else: # If the animal is hunting.
            if hunts <= FOOD_CATCHING_PROBABILITY:
                belly  = 1
                hunt_next = False if belly == BELLY_FULL else True # Fully belly is triggering a rest on the next cycle.
            else:
                belly -= 1
                hunt_next = True

        states.append((hunt_next, belly, i))

# For testing purpose.
for n, s in animals_states.items():
    print(f"\nAnimal {n} states:")
    for is_hunting, belly, _ in s:
        print(is_hunting, belly)

Output:

Animal 1 states:
False 4
False 4
False 3
True 2
True 1
True 2
True 1
True 0
True -1

Animal 2 states:
False 4
False 4
False 4
False 3
False 3
True 2
True 1
True 2
True 1
True 0
True -1

Animal 3 states:
False 4
False 4
False 3
True 2
True 1
True 0
True 1
True 0
True -1

  • Related