Table of Tribonacci sequence using NumPy and PANDAS What I am trying to accomplish is calculate the Tribonacci numbers and the ratio. I can do this in Excel easy like this.





So I tried do the same using Python 3 now.
It works and gives such output.



But would you be so kind to review the code and see what obvious mistakes you see in it and advise on what is a better approach as I do not want to continue coding if my logic to tackle such problem is fundamentally flawed somewhere.

Priorities for me are execution time and readability I guess

What would you have done differently and why?
I know it may look like a mess.
From what I heard using exec and eval (code as string) are the bad ideas and also that function calls are expensive?

I don't like my code at all especially how next() is used so many times but hopefully you can see how I was thinking trying to replicate the Excel spreadsheet

To run the code you need numpy and pandas

import pandas as pd
import numpy as np

column_names = ["Number sequence", "Ratio"]
column_counter = len(column_names) -1
header_columns = ['']
while column_counter &gt;= 0:
    column_counter = column_counter - 1
    header_columns.append(column_names[column_counter])

tribonacci_numbers = [0,1]    
tribonacci_counter = 19 #Reach
while tribonacci_counter -1 &gt;= 0:
    tribonacci_counter = tribonacci_counter - 1
    tribonacci_numbers.append(sum(tribonacci_numbers[-3:]))
tribonaccis_list_length = len(tribonacci_numbers)-1

index_builder = 1
rows = []
while index_builder &lt;= tribonaccis_list_length:
    try:
        index_builder = index_builder + 1
        rows.append((["Number: "+str(index_builder),tribonacci_numbers[index_builder],tribonacci_numbers[index_builder]/tribonacci_numbers[index_builder-1]]))       
    except IndexError:
        continue

def get_row():
    the_row = [x for x in rows]
    row_counter = 0
    while row_counter &lt;= len(the_row):
        try:
            row_counter = row_counter + 1
            yield (the_row[row_counter])            
        except IndexError:
            continue

a = get_row()
def therow():
    for q in a:
        yield q

datas = np.array([
header_columns,
next(therow()),
next(therow()),
next(therow()),
next(therow()),
next(therow()),
next(therow()),
next(therow()),
next(therow()),
next(therow()),
next(therow()),
next(therow()),
next(therow()),
next(therow()),
next(therow()),
next(therow()),
next(therow()),
next(therow()),
next(therow())])

df = pd.DataFrame(data=datas[1:,1:],index=datas[1:,0],columns=datas[0,1:])
print(df)


If you want to provide an example that does the same and produces a Pandas dataframe like this it would be very useful for me to study your code.
You’re using the wrong tool for the job. Basically, you do all the computation in Python, use numpy for intermediate storage and pandas for display.

Instead, you should compute the list of tribonacci numbers and from there on use pandas for anything else as it would be much more efficient / readable. I’d keep building the tribonacci numbers in Python as I don't know enough pandas to be able to come up with an efficient way that wouldn't involve Dataframe.append and also because it can be expressed very nicely as a generator:

def tribonacci_sequence():
    a, b, c = 0, 1, 1
    yield a
    yield b
    while True:
        yield c
        a, b, c = b, c, a + b + c


You can then select the amount of numbers you like using itertools.islice and give them to a pandas.Dataframe.

From there on, you can easily compute the ratio by shifting the dataframe and dividing element-wise:

def compute_tribonacci(upper_limit, skip_first_rows=3):
    tribonacci = list(islice(tribonacci_sequence(), upper_limit + 1))
    df = pd.DataFrame({'Number sequence': tribonacci})
    df['Ratio'] = df['Number sequence'] / df.shift(1)['Number sequence']
    df.index = df.index.map('Number: {}'.format)
    return df.iloc[skip_first_rows:]


Last thing to do is to actually ask for a certain amount of rows. Full code:

from itertools import islice
import pandas as pd


def tribonacci_sequence():
    a, b, c = 0, 1, 1
    yield a
    yield b
    while True:
        yield c
        a, b, c = b, c, a + b + c


def compute_tribonacci(upper_limit, skip_first_rows=3):
    tribonacci = list(islice(tribonacci_sequence(), upper_limit + 1))
    df = pd.DataFrame({'Number sequence': tribonacci})
    df['Ratio'] = df['Number sequence'] / df.shift(1)['Number sequence']
    df.index = df.index.map('Number: {}'.format)
    return df.iloc[skip_first_rows:]


if __name__ == '__main__':
    df = compute_tribonacci(50)
    print(df)