Search code examples
python-3.xnumpymatplotlibtiming

Numpy Array Lists not successfully appending all integers


Code:

import matplotlib.pyplot as plt
import numpy as np

poslist = []
numlist = []
i = 1

num = int(input('Number to check?'))
plt.title(str(num) + ': Collatz Graph')
plt.xlabel('Step')
plt.ylabel('Value')
print(num)
poslist.append(poslist, i)
numlist.append(numlist, num)

while True:
    i = i + 1
    if num % 2 == 0:
        num = num // 2
        print(num)
    elif num == 1:
        break
    else:
        num = num * 3
        num = num + 1
        print(num)
        poslist.append(poslist, i)
        numlist.append(numlist, num)

print('Number Array:', numlist)
print('Position Array', poslist)
plt.plot(*(poslist, numlist))
plt.show()

When I use the listname.append(listname, var) NumPy functions, it skips over most of the variables. It only adds every 3rd or 4th variable to the list. The same is true for the step counter array. Even when adding a time.sleep(4) function, it appears to calcuate 3 or 4 numbers at once - only logging the first one.


Solution

  • There appear to be two issues.

    1. Your append command is for a np.array but poslist and numlist are list types. For those it would just be numlist.append(num) and poslist.append(i). Instead of numpy.append you want the list version.
    2. As diggusbickus pointed out, your append statements in your while loop are inside an if statement and you need to push them back so they are outside of it.
    import matplotlib.pyplot as plt
    #import numpy as np <--- You are not using numpy
    
    poslist = []
    numlist = []
    i = 1
    
    num = int(input('Number to check?'))
    plt.title(str(num) + ': Collatz Graph')
    plt.xlabel('Step')
    plt.ylabel('Value')
    print(num)
    poslist.append(i) # <--- Change append statement for list
    numlist.append(num) # <--- Same as above
    
    while True:
        i = i + 1
        if num % 2 == 0:
            num = num // 2
            print(num)
        elif num == 1:
            break
        else:
            num = num * 3
            num = num + 1
            print(num)
        poslist.append(i) # <--- Shift out of if/else statement and change append
        numlist.append(num) # <--- Same as above
    
    print('Number Array:', numlist)
    print('Position Array', poslist)
    plt.plot(*(poslist, numlist))
    plt.show()
    

    The other option if you want to use numpy arrays would be to change your lists. If one wanted to use np.append, you would use something like poslist = np.append(poslist, i). However, as recommended in the comments to this answer by hpaulj, if you want to use np.concatenate it would look like more like poslist = np.concatenate((poslist, [i,])). (This post compares the two methods.)

    import matplotlib.pyplot as plt
    import numpy as np 
    
    poslist = np.array([]) # <--- change list to array
    numlist = np.array([]) # <--- change list to array
    i = 1
    
    num = int(input('Number to check?'))
    plt.title(str(num) + ': Collatz Graph')
    plt.xlabel('Step')
    plt.ylabel('Value')
    print(num)
    
    #poslist = np.append(poslist, i) # <--- Fix syntax of np.append
    poslist = np.concatenate((poslist, [i,])) # <-- Or use concatenate instead
    numlist = np.concatenate((numlist, [num,])) # <-- Or use concatenate instead
    
    while True:
        i = i + 1
        if num % 2 == 0:
            num = num // 2
            print(num)
        elif num == 1:
            break
        else:
            num = num * 3
            num = num + 1
            print(num)
        poslist = np.concatenate((poslist, [i,])) # <--- Move out of if/else statement
        numlist = np.concatenate((numlist, [num,])) 
    
    print('Number Array:', numlist)
    print('Position Array', poslist)
    plt.plot(*(poslist, numlist))
    plt.show()