pascal number using while loop - python-3.x

I need to print the pascal number
1
1 1
1 2 1
1 3 3 1
etc.
import math
i = 0
j = 1
while j<6:
while i<6:
print(int(math.factorial(5)/(math.factorial(i)*math.factorial(5-i))), end=" ")
i += 1
print(int(math.factorial(j)/(math.factorial(i)*math.factorial(j-i))))
j += 1
it is stated that factorial cannot be negative, although I don't think it is negative.

Take a look at this code, this gives the correct output, even though you can work on making it pretty
n = 5
for j in range(1, n + 1):
row = 1
for i in range(1, j + 1):
print(row)
row = row * (j - i) // i
print(" ")
We know that ith entry in a row of the triange is binomial coefficiant of (j, i) and that all the rows must start with the number 1, and that's why this works. And ofcourse we do integer division.
The for loops can be replace with while loops as you see fit.

Related

Given a number N, print sum of all even numbers from 1 to N. Using While loop in python

number = int(input())
count = 2
sum = 0
while count <= number:
if count%2 == 0:
sum = sum + count
count = count + 1
print(sum)
I did this but still, the code is wrong.
Given the code above, your main issue is indentation:
number = int(input())
count = 2
sum = 0
...
count and sum should start where number starts as well:
number = int(input())
count = 2
sum = 0
...
Also, you could make your code more efficient by incrementing your count by 2, therefore getting rid of the if statement:
number = int(input())
count = 2
Sum = 0
while count <= number:
Sum += count
count += 2
print(Sum)
And of course, as Alex P said, avoid using sum as a variable name as it is bad practice. Use Sum, or any other variation that doesn't look like the method sum().

python matrix multiplication check if number of rows of 1st matrix is equal to number of columns of 2nd matrix

I need to perform a matrix multiplication between 2 matrices by taking user input. The below code works fine for the multiplication part but if the no. of rows of 1st matrix are not equal to the no. of columns of the 2nd matrix then it should print NOT POSSIBLE and exit. But it still goes on to add the elements of the matrices. What could possibly be wrong in this code & what could be the solution for the same. Any help would be greatly appreciated
def p_mat(M,row_n,col_n):
for i in range(row_n):
for j in range(col_n):
print(M[i][j],end=" ")
print()
def mat_mul(A_rows,A_cols,A,B_rows,B_cols,B):
if A_cols != B_rows:
print("NOT POSSIBLE")
else:
C = [[0 for i in range(B_cols)] for j in range(A_rows)]
for i in range(A_rows) :
for j in range(B_cols) :
C[i][j] = 0
for k in range(B_rows) :
C[i][j] += A[i][k] * B[k][j]
p_mat(C, A_rows, B_cols)
if __name__== "__main__":
A_rows = int(input("Enter number of rows of 1st matrix: "))
A_cols = int(input("Enter number of columns of 1st matrix: "))
B_rows = int(input("Enter number of rows of 2nd matrix: "))
B_cols = int(input("Enter number of columns of 2nd matrix: "))
##### Initialization of matrix A and B #####
A = [[0 for i in range(B_cols)] for j in range(A_rows)]
B = [[0 for i in range(B_cols)] for j in range(A_rows)]
print("Enter the elements of the 1st matrix: ")
for i in range(A_rows):
for j in range(A_cols):
A[i][j] = int(input("A[" + str(i) + "][" + str(j) + "]: "))
print("Enter the elements of the 2nd matrix: ")
for i in range(B_rows):
for j in range(B_cols):
B[i][j] = int(input("B[" + str(i) + "][" + str(j) + "]:"))
##### Print the 1st & 2nd matrices #####
print("First Matrix : ")
p_mat(A,A_rows,A_cols)
print("Second Matrix : ")
p_mat(B,B_rows,B_cols)
### Function call to multiply the matrices ###
mat_mul(A_rows,A_cols,A,B_rows,B_cols,B)
For matrix multiplication, the number of columns in the first matrix must be equal to the number of rows in the second matrix.
If you want to check the no of rows of 1st matrix and the no. of columns of the 2nd matrix then change the if A_cols != B_rows to if A_rows != B_cols
With your current code, it will print NOT POSSIBLE when A_cols != B_rows which is right.
Ex.
Enter number of rows of 1st matrix: 2
Enter number of columns of 1st matrix: 3
Enter number of rows of 2nd matrix: 2
Enter number of columns of 2nd matrix: 3
Enter the elements of the 1st matrix:
A[0][0]: 1
A[0][1]: 2
A[0][2]: 3
A[1][0]: 4
A[1][1]: 5
A[1][2]: 6
Enter the elements of the 2nd matrix:
B[0][0]:1
B[0][1]:2
B[0][2]:3
B[1][0]:4
B[1][1]:5
B[1][2]:6
First Matrix :
1 2 3
4 5 6
Second Matrix :
1 2 3
4 5 6
NOT POSSIBLE
Another mistake in the code is when you are initialize the Matrices.You are doing
A = [[0 for i in range(B_cols)] for j in range(A_rows)]
B = [[0 for i in range(B_cols)] for j in range(A_rows)]
If the B_cols are smaller than the A_cols when you adding elements in A it will raise IndexError
The same if the B_cols are greater than A_cols when you are adding elements to B will raise IndexError.
Change it to
A = [[0 for i in range(A_cols)] for j in range(A_rows)]
B = [[0 for i in range(B_cols)] for j in range(B_rows)]

Selecting rows where a numeric column value change sign through openpyxl

I'm learning Python and openpyxl for data analysis on a large xlsx workbook. I have a for loop that can iterate down an entire column. Here's some example data:
ROW: VALUE:
1 1
2 2
3 3
4 4
5 -4
6 -1
7 -6
8 2
9 3
10 -3
I want to print out the row in which the value changes from positive to negative, and vice versa. So in the above example, row number 5, 8, and 10 would print in the console. How can I use an if statement within a for loop to iterate through a column on openpyxl?
So far I can print all of the cells in a column:
import openpyxl
wb = openpyxl.load_workbook('ngt_log.xlsx')
sheet = wb.get_sheet_by_name('sheet1')
for i in range(1, 10508, 1): # 10508 is the length of the column
print(i, sheet.cell(row=i, column=6).value)
My idea was to just add an if statement inside of the for loop:
for i in range(1, 10508, 1): # 10508 is the length of the column
if(( i > 0 and (i+1) < 0) or (i < 0 and (i+1) > 0)):
print((i+1), sheet.cell(row=i, column=6).value)
But that doesn't work. Am I formulating the if statement correctly?
It looks to me as though your statement is contradicting itself
for i in range(1, 10508, 1): # 10508 is the length of the column
if(( i greater than 0 and (i+1) less than 0) or (i less than 0 and (i+1) greater than
0)):
print((i+1), sheet.cell(row=i, column=6).value)
I wrote the > and < symbols in plain English but if i is greater than 0 then i + 1 is never less than 0 and vise versa so they will never work as both cannot be true
You need to get the sheet.cell values first, and then do the comparisons:
end_range = 10508
for i in range(1, end_range):
current, next = sheet.cell(row=i, column=6).value, sheet.cell(row=i+1, column=6).value
if current > 0 and next < 0 or current < 0 and next > 0:
print(i+1, next)
I am pretty sure there's a sign() function in the math library, but kinda overkill. You may also want to figure out what you want to do if the values are 0.
You can use a flag to check for positive and negative.
ws = wb['sheet1'] # why people persist in using long deprecated syntax is beyond me
flag = None
for row in ws.iter_rows(max_row=10508, min_col=6, max_col=6):
cell = row[0]
sign = cell.value > 0 and "positive" or "negative"
if flag is not None and sign != flag:
print(cell.row)
flag = sign
You can write the rules to select the rows where the sign has changed and put them in a generator expression without using extra memory, like this:
pos = lambda x: x>=0
keep = lambda s, c, i, v: pos(s[c][x].value)!=pos(v.value)
gen = (x+1 for x, y in enumerate(sheet['f']) if x>0 and keep(sheet, 'f', x-1, y))
Then, when you need to know the rows where the sign has changed, you just iterate on gen as below:
for row in gen:
# here you use row

array from continuous data?

I have a quite difficult problem that i cant wrap my head around.. hope you can help me!
Lets say my data is in A1:G1 for example:
A1 B1 C1 D1 E1 F1 G1
X X 0 X X X 0
or
Y X X X X Z X
The thing i would need to come up with is how to get array from this data according to the X, BUT if like in example 1 there is 2 times X in the beginning and 3 x next to each other so the array should come out like {2;2;0;3;3;3;0} so i want the array to be 7 long and the array should show the x as number how many are next to each other.
example 2 should come out like {0;4;4;4;4;0;1}
if you can figure this out would really help me alot!
Edit:
Trying to give out better, more bigger picture of what i mean..
if data is :
A B C
1 X X
2 X X
3 X
it should come out as
A B C
1: 2 4 0
2: 0 4 2
3: 1 0 0
or in array {2\4\0;0\4\2;1\0\0}
on B1 and B2 there should be 4 because the formula should count horizontal but also vertical continuum. I tried to use usmanhaqs formula but i was not able to modify it so the count resets on every line.
Real size of the table is 7 times 7 cells.
I will use the array with another array (scoreboard which is also 7 times 7 cells, and has numbers 1, 2 or 3 on every cell) using sumproduct and it will give out the points of that player.
I appreciate your efforts on helping out a newbie learner on vba :)
For a formula solution, I can only come up with one for the special case where you have just X's and zeroes (example 1) so far:
=SUM(IF(A1:G1<>"X",0,INDEX(FREQUENCY(IF(A1:G1="X",COLUMN(A1:G1)),IF(A1:G1<>"X",COLUMN(A1:G1))),N(IF({1},SUBTOTAL(2,OFFSET(A1,0,0,1,COLUMN(A1:G1)))))+1,1)))
entered as an array formula using CtrlShiftEnter
I have wrapped it in a SUM function to demonstrate that it generates an array which can be passed to another function (result: 13) or it can be array-entered across several cells:
You can test this code
Function get_array(r As Range, match_chr As String)
Dim check_val
Dim array_value
array_value = "{"
For i = 1 To r.Count
check_value = r.Item(i)
If (check_value = match_chr) Then
j = i + 1
Do While (j <= r.Count) And (check_value = r.Item(j))
j = j + 1
Loop
array_value = array_value & WorksheetFunction.Rept(j - i & ", ", j - i)
i = j - 1
Else
array_value = array_value & "0, "
End If
Next
array_value = Left(array_value, Len(array_value) - 2) & "}"
get_array = array_value
End Function
You can use it as below
EDIT
find below another function to return an array of values that can be used in the formulae
Function get_number_array(r As Range, match_chr As String)
Dim check_val
Dim array_value
Dim number_array(1 To 50) As Long
For i = 1 To r.Count
check_value = r.Item(i)
If (check_value = match_chr) Then
j = i + 1
Do While (j <= r.Count) And (check_value = r.Item(j))
j = j + 1
Loop
For k = 1 To j - i
number_array(i + k - 1) = j - i
Next k
i = j - 1
Else
number_array(i) = 0
End If
Next
get_number_array = number_array
End Function
You have to use it same as the previous one, but it will return excel array.

Different output in for loop

I made a simple program to generate prime numbers but It shows 10 as a prime number. In debugging the for loop incremented i from 2 to 4 in single step when number went from 9 to 10.
for i in range (2, int( number / 2) + 1):
if number % i == 0:
number += 1
i = 2
yield number
number += 1`

Resources