Calculating and Outputting Pascal's Triangle with only Indices

I'm relatively new to Python, and decided to write this program that outputs Pascal's Triangle to test myself. About halfway through, I realized that it's a lot of work to find the value of Pascal's Triangle from an index instead of a (row, column) formula, and ended up taking a journey to StackExchange Math for an answer.

If anyone could provide some guidance on improving the code's readability or efficiency, I would be very appreciative. I'm sure that my code doesn't complete its task in the most pythonic way. Two specific examples of possibly inefficient code are the way that the code checks user inputs and the way that the triangle is displayed.

Thanks in advance for the help.

"""Prompts the user for a number of rows, then displays that many rows of Pascal's Triangle"""

import numpy
import math

# Used for simplifying FindValueFromIndex
def PlusOne(index):
return numpy.floor((numpy.sqrt(8*index+1)-1)/2)
def MinusOne(index):
return numpy.floor((numpy.sqrt(8*index+1)+1)/2)

# Finds the Value of a particular index of Pascal's Triangle
def FindValueFromIndex(index):
return math.factorial(MinusOne(index))/(math.factorial(index-(MinusOne(index)*PlusOne(index))/2)
*math.factorial(MinusOne(index)+(MinusOne(index)*PlusOne(index))/2-index))

# Determines whether a number is triangular
def IsTriangular(index):
currtrinum = 0
n=0
while currtrinum < index:
currtrinum += n
n+=1
if currtrinum != index:
return False
else:
return True

# Variable Declaration
rows = 'a'
while not rows.isdigit():
rows = input("Enter number of rows: ")
rows = int(rows)
count = rows
onesindex = []
nononesindex = 1

# The left-side ones values of Pascal's Triangle can be defined as a summation
# The right-side ones values of Pascal's Triangle can be found by subtracting one from the index from the left side
# The range starts at 2 because the first value is considered as part of the right side
for i in range(2,rows+1):
onesindex.append(sum(range(i)))
onesindex.append(sum(range(i))-1)

# The ones values can be populated from the onesindex values found in the previous section
# The non-one values can be calculated using the equation found in FindValueFromIndex()
triangle = [0 for x in range(sum(range(rows)))]
for i in range(len(triangle)):
if i in onesindex:
triangle[i] = 1
else:
while triangle[i] == 1 or triangle[i] == 0:
triangle[i] = int(FindValueFromIndex(nononesindex))
nononesindex += 1

# Prints out the result
rows -= 1
for i in range(rows-1):
print('    ',end='')

for i in range(len(triangle)):
print('{:^4}'.format(str(triangle[i])),end='    ')
if IsTriangular(i+1):
rows -= 1
print('\n',end='')
[print('    ',end='') for j in range(rows-1)]

This is SUPER bulky for what you actually need to be doing. I did this same project about a year ago in python3. You're thinking too hard about something that's a lot more simple than it looks.

while True:
def num():
n=input("Type however many rows you want (or 'info' for info about Pascal’s Triangle): ")
if n=="quit":
exit()
if n.isnumeric():
n = int(n)
if n>1000:
print("That's too many. Try again.")
return
else:
a=[]
for i in range(n):
a.append([])
a[i].append(1)
for j in range(1,i):
a[i].append(a[i-1][j-1]+a[i-1][j])
if(n!=0):
a[i].append(1)
for i in range(n):
print("   "*(n-i),end=" ",sep=" ")
for j in range(0,i+1):
print('{0:6}'.format(a[i][j]),end=" ",sep=" ")
print()
else:
return
num()

The indentation may be wrong (copy and paste is challenging) but it is a lot shorter and more efficient than all the checks you're doing. Hopefully this helps!