EXCEL / VBA - function #VALUE error in spreadsheet - excel

(I want to calculate the number of possible ways of getting 'sum' out of 'n' dice throws (dices have 'k' faces from 1..k).)
When i want to use this function in an excel spreadsheet, I get a #VALUE error no matter what inputs i try.
I have other functions in the same module, used in the same sheet that work fine\
Function how_many_ways(n, k, sum)
If n = 0 Then
If sum = 0 Then
how_many_ways = 1
Else
how_many_ways = 0
End If
End If
If sum < 0 Or k * n < sum Or n > sum Then
how_many_ways = 0
End If
res = 0
For i = 1 To k
res = res + how_many_ways(n - 1, k, sum - i)
Next i
how_many_ways = res
End Function

It always runs the for loop so it recurs infinitely. Try this.
Function how_many_ways(n, k, sum)
If n = 0 Then
If sum = 0 Then
how_many_ways = 1
Else
how_many_ways = 0
End If
ElseIf sum < 0 Or k * n < sum Or n > sum Then
how_many_ways = 0
Else
res = 0
For i = 1 To k
res = res + how_many_ways(n - 1, k, sum - i)
Next i
how_many_ways = res
End If
End Function

Related

python: copy values of big array in smaller arrays

I have a problem,
where I would like to copy values of X a ( n x n ) array into smaller array A, B , C, D
here is my current code.
X = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]
n = len(X)
n_by_2 = n // 2
A = [[]]
B = [[]]
C = [[]]
D = [[]]
"""
X = [
A<-- B<--
[1,2, | 3,4],
[5,6, | 7,8],
-------|-------
D<-- | C<--
[9,10, | 11,12],
[13,14,| 15,16]
]
"""
for i in range(len(X)):
for j in range(len(X[i])):
if (i >= 0 and i < n_by_2) and (j >= 0 and j < n_by_2):
#copy 1st quadrent values to A
#A[i][j] = X[i][j]
if (i >= 0 and i < n_by_2) and (j >= n_by_2 and j < n):
#copy 2nd quadrent values to B
#B[i][j] = X[i][j]
if (i >= n_by_2 and i < n) and (j >= 0 and j < n_by_2):
#copy 3rd quadrent values to C
#C[i][j] = X[i][j]
if (i >= n_by_2 and i < n) and (j >= n_by_2 and j < n):
#copy 4th quadrent values to D
#D[i][j] = X[i][j]
Be careful that you cannot add a new item x to an empty list l by doing.
l[0] = x. This only works if the list already has a length greater than 0. In that situation, you can use the append method instead.
For your problem, this code will do the job:
X = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]
n = len(X)
n_by_2 = n // 2
A = []
B = []
C = []
D = []
for i in range(n_by_2):
A.append(X[i][:n_by_2])
B.append(X[i][n_by_2-1:-1])
for i in range(n_by_2):
C.append(X[i + n_by_2][:n_by_2])
D.append(X[i + n_by_2][n_by_2-1:-1])
print(A)
print(B)
print(C)
print(D)

VBA results in #VALUE! only when For loop is used

I am writing a function with a For loop, and ultimately the value of the function will depend on the output of the For loop. For now as a test, the value of the function is a constant. If the For loop is in the code, the function results in #Value!. If I remove the For loop, the output is the specified constant value. How does the For loop need to be specified to avoid this? Good values for Tc and Th as a test would be 100 and 300, respectively.
Function kndT(material As Integer, Tc As Double, Th As Double) As Variant
Dim x As Double
Select Case material
Case 4
If Th > 300 Then
Tmax = 300
Else
Tmax = Th
End If
A = 0.07918
b = 1.0957
c = -0.07277
D = 0.08084
e = 0.02803
f = -0.09464
g = 0.04179
h = -0.00571
i = 0
End Select
hh = (Tmax - Tc) / 999
fi = 0
nc = 1
For i = 1 To 999
Temp = (Tc + i * hh)
x = Log(Temp) / Log(10#)
y = A + b * x + c * x ^ 2 + D * x ^ 3 + e * x ^ 4 + f * x ^ 5 + g * x ^ 6 + h * x ^ 7 + i * x ^ 8
fn = 10 ^ y
If nc = 3 Then
fi = fi + 2 * fn
nc = 1
Else
fi = fi + 3 * fn
nc = nc + 1
End If
Next i
kndT = 2
End Function

How to compare the elements of a nested list?

I have some kind of matrix:
[[1,2,3],[1,2,3],[0,2,1],[1,2,3]] and I would like to be able to determine how many times I have the sequence 1,2,3 diagonally, vertically and horizontally but I have problems of index out of range for the last two loops. Thank you in advance for your answers!!
lista = [[1,2,3],[1,2,3],[0,2,1],[1,2,3]]
compteur_horizontal = 0
for i in range(len(lista)):
for c in range(len(lista[i])-2):
if lista[i][c] == 1 and lista[i][c+1] == 2 and lista[i][c+2] == 3:
compteur_horizontal += 1
print("ok")
compteur_vertical = 0
for c in range(len(lista)):
for j in range(len(lista[c])):
print(lista[j][c])
compteur_diagonale = 0
for j in range(len(lista)):
print(lista[i][i])
For the first counter, I would like it to be 3 since we have 3 times the sequence 1,2,3 horizontally. For the second counter, I would like it to be 0 because vertically there is no 1,2,3 sequence. And I'm waiting for a counter with 0 also since there's no 1,2,3 sequence in diagonal
Your code will not work even if you correct the current error. You need to change j and c in the second loop to resolve the error.
For horizontal and vertical here's the code. I'll add how to count diagonal ones later.
#lista = [[1, 2, 3],[1, 2, 3],[0, 2, 1],[1, 2, 3]]
lista = [[1,2,2],
[1,2,4],
[4,2,3],
[5,6,3]]
ptrn = [1, 2, 3]
# returns True is lst (1d array) has ptrn (1d array).
# e.g. lst[1,2,4,6,1,2,3,7], ptrn=[1,2,3] return True
# e.g. lst[1,2,4,6,1,4,3,7], ptrn=[1,2,3] return False
def is_pattern_in_a_list(lst, ptrn):
if ptrn[0] in lst:
idx = lst.index(ptrn[0])
for i in range(1, len(ptrn)):
if idx + i < len(lst):
if ptrn[i] != lst[idx+i]:
return False
else:
return False
return True
else:
return False
# counting horizontal occurances
count_h = 0
for row in lista:
if is_pattern_in_a_list(row, ptrn):
count_h += 1
# counting vertical occurances
# we first transpose the 2d array and use the same
# method of counting horizontal occurances.
def transpose_2d_array(a):
return [[a[j][i] for j in range(len(a))] for i in range(len(a[0]))]
lista_transpose = transpose_2d_array(lista)
count_v = 0
for row in lista_transpose:
if is_pattern_in_a_list(row, ptrn):
count_v += 1
# for diagonal occurances first we need to extract the diagonals
# with len >= len(ptrn).
# diagonals for the upper right triangle of the matrix:
count_d = 0
for i in range(len(lista[0])):
diag = []
j = 0
k = i
while j < len(lista)-i and k < len(lista[0]):
diag.append(lista[j][k])
j += 1
k += 1
if is_pattern_in_a_list(diag, ptrn):
count_d += 1
# diagonals for the lower left triangle of the matrix
i = len(lista) - 1
while i >= 1:
j = i
k = 0
diag = []
while j < len(lista) and k <= len(lista)+1-i:
diag.append(lista[j][k])
j += 1
k += 1
i -= 1
if is_pattern_in_a_list(diag, ptrn):
count_d += 1
print(diag)
print("Horizontal %d" % count_h)
print("Vertical %d" % count_v)
print("Diagonal %d" % count_d)

Recursion function inn python

I am trying to understand the recursion function. I would like to know how that answer is coming with steps
def tri_recursion(k):
if(k>0):
result = k+tri_recursion(k-1)
print(result)
else:
result = 0
return result
print("\n\nRecursion Example Results")
tri_recursion(6)
results are this just want to know how its coming
1
3
6
10
15
21
The function computes the sum of all numbers between 0 and n, and prints intermediate results. The first 1 is 0+1, the 3 = 0+1+2, 6 = 0+1+2+3, 10 = 0+1+2+3+4, ...
To understand a recursive function, you need 2 points : how is the recursive call done, and when does the recursion stop.
The recursive call is given by result = k+tri_recursion(k-1)and the recursion stops when k <= 0and returns 0. So if we assume only positive numbers, we could describe tri_recursion so:
tri_recursion(k) = k + tri_recursion(k-1) if k > 0
tri_recursion(0) = 0
So tri_recursion(k) = k + tri_recursion(k-1) = k + (k-1) + tri_recursion(k-2) = k + (k-1) + (k-2) + tri_recursion(k-3) ... = k + (k-1) + (k-2) + ... + 0
So tri_recursion(k) is the sum of all numbers between 0 and k.
Note that the sum on all numbers between 0 and k equals k*(k+1) / 2 so tri_recursion(6) = 6 * 7 / 2 = 21

Run Time error 9:Array

I am new to VBA programming and am trying to develop a simple code for RCC design. Most of the values are assigned directly from the excel sheet. I am getting this error that says "division by zero".The line within ** ** is highlighted while debugging. it seems there is some problem with declaration or looping but i am not being able to identify. Pls help. Thanx in advance. The code is as follows:
Private Sub CommandButton1_Click()
Dim a As Double, b As Double, result As String, Mu As Double
Dim i As Integer, j As Integer, c As Integer, Xu1, Xu, es, d, f, fs As Double
Dim strain1(1 To 6) As Double, stress1(1 To 6) As Double
a = Range("E30").Value
b = Range("O30").Value
If a < b Then
result = "Under Reinforced Section"
Mu = Range("E32").Value * Range("E34").Value
ElseIf a = b Then
result = "Balanced Secction"
Mu = Range("E32").Value * Range("E34").Value
ElseIf a > b Then
result = "Over Reinforced Section"
j = 31
For i = 1 To 6
strain1(i) = Cells(j, 7)// loop to assign values in array from excel sheet
j = j + 1
Next
j = 31
For i = 1 To 6
stress1(i) = Cells(j, 8)
j = j + 1
Next
c = 1
Xu1 = Range("O30").Value
d = Range("E31").Value
Do While c = 1
Xu = Xu1
**es = 0.0035 * (d - Xu) / (Xu)**// Shows error apparently Xu is taking value zero
If Range("E22").Value = 250 Then
fs = es * Range("E23").Value
f = 0.87 * Range("E22").Value
If fs > f Then
fs = f
End If
ElseIf Range("E22").Value = 415 Then
f = 0.696 * Range("E22").Value / Range("E23").Value
If es > f Then
For i = 1 To 6
If es > strain1(i) And es < strain1(i + 1) Then// to locate es in the array and then interpolate
fs = stress1(i) + ((stress1(i + 1) - stress1(i)) / (strain1(i + 1) - strain1(i))) * (es - strain1(i))// linear interpolation formulae
End If
Next
ElseIf es < f Then
fs = es * Range("E23").Value
End If
Xu1 = Range("O29").Value * fs / (0.36 * Range("E21").Value * Range("E16").Value)
If Xu1 = Xu Then
c = 0
End If
Mu = 0.36 * Range("E21").Value * Range("E16").Value * Xu1 * Range("E34").Value
End If
Loop
End If
Range("O21").Value = Mu
MsgBox result
End Sub
strain1(1 To 6) has 6 elements 1 to 6, for i=6 you're trying to access a 7th element (strain1(i + 1)) in the highlighted row. (the same holds true for stress1 in the next line)

Resources