How to avoid used many if statements in definition? - python
I have a function which create list of url. Function works fine. But I do not like what this function looks like:
def prepareadres(city,y,m,d):
month = [31,28,31,30,31,30,31,31,30,31,30,31]
d = d + 1
d0 = 0
m0 = 0
if (d > month[0]):
d = d - month[0]
m = m + 1
if (d > month[1]):
d = d - month[1]
m = m + 1
if (d > month[2]):
d = d - month[2]
m = m + 1
if (d > month[3]):
d = d - month[3]
m = m + 1
if (d > month[4]):
d = d - month[4]
m = m + 1
if (d > month[5]):
d = d - month[5]
m = m + 1
if (d > month[6]):
d = d - month[6]
m = m + 1
if (d > month[7]):
d = d - month[7]
m = m + 1
if (d > month[8]):
d = d - month[8]
m = m + 1
if (d > month[9]):
d = d - month[9]
m = m + 1
if (d > month[10]):
d = d - month[10]
m = m + 1
if (d > month[11]):
d = d - month[11]
m = m + 1
if d == sum(month):
print("year complete")
#print(df.iloc[0, :-2])
if (m < 10) and (d < 10):
adres = "https://sinoptik.ua/погода-" + city + "/" + str(y) + "-" + str(m0) + str(m) + "-" + str(d0) + str(d)
elif (m < 10) and (d >= 10):
adres = "https://sinoptik.ua/погода-" + city + "/" + str(y) + "-"+ str(m0) + str(m) + "-" + str(d)
elif (m >= 10) and (d < 10):
adres = "https://sinoptik.ua/погода-" + city + "/" + str(y) + "-" + str(m) + "-" + str(d0) + str(d)
else:
adres = "https://sinoptik.ua/погода-" + city + "/" + str(y) + "-" + str(m) + "-" + str(d)
#print(adres)
return adres
Code looks awful as I mention.I used many if statements and want to simplify this. Can you suggest more elegant ways of writing this definition, avoiding the use of if statements?
Use a for loop to iterate over the months:
def prepareadres(city,y,m,d):
months = [31,28,31,30,31,30,31,31,30,31,30,31]
d = d + 1
d0 = 0
m0 = 0
for month in months:
if d > month:
d = d - month
m += 1
if d == sum(months):
print("year complete")
#print(df.iloc[0, :-2])
if (m < 10) and (d < 10):
adres = "https://sinoptik.ua/погода-" + city + "/" + str(y) + "-" + str(m0) + str(m) + "-" + str(d0) + str(d)
elif (m < 10) and (d >= 10):
adres = "https://sinoptik.ua/погода-" + city + "/" + str(y) + "-"+ str(m0) + str(m) + "-" + str(d)
elif (m >= 10) and (d < 10):
adres = "https://sinoptik.ua/погода-" + city + "/" + str(y) + "-" + str(m) + "-" + str(d0) + str(d)
else:
adres = "https://sinoptik.ua/погода-" + city + "/" + str(y) + "-" + str(m) + "-" + str(d)
#print(adres)
return adres
Related
Fastest way to solve non-negative linear diophantine equations
Let A be a list of n lists of m non-negative integers, such that for all j there is i with A[i][j] nonzero. Let V be a list of m positive integers. Question: What is the fastest way to find all the lists X of n non-negative integers such that for all i then sum_j A[i][j] X[j] = V[i]? The assumptions implies that the number of solutions is finite. See below an example of A and V, with 5499 solutions X. Let me reformulate the problem using matrix and vector. Let A be a n-by-m matrix with non-negative integral entries and without zero column. Let V be a vector with positive integral entries. What is the fastest way to find all the vectors X, with non-negative integral entries, such that AX=V? The usual functions for solving such a system may underuse the non-negativity. To prove so, I wrote a brute-force code finding all the solutions of such a system and applied it to an example (see below, and these crossposts on mathoverflow and on ask.sagemath), but I'm still looking for something significantly faster than this; in fact I'm looking for the fastest way. Example Here is the kind of system I need to solve (where x_i is non-negative integral), but with possibly more equations and variables. [ 5*x0 + 5*x1 + 5*x2 + 6*x3 + 7*x4 + 7*x5 == 24, 5*x1 + 7*x10 + 5*x6 + 5*x7 + 6*x8 + 7*x9 == 25, 5*x11 + 6*x12 + 7*x13 + 7*x14 + 5*x2 + 5*x7 == 25, 5*x12 + 6*x15 + 7*x16 + 7*x17 + 5*x3 + 5*x8 == 30, 5*x13 + 6*x16 + 7*x18 + 7*x19 + 5*x4 + 5*x9 == 35, 5*x10 + 5*x14 + 6*x17 + 7*x19 + 7*x20 + 5*x5 == 35, 5*x1 + 7*x10 + 5*x6 + 5*x7 + 6*x8 + 7*x9 == 25, 5*x21 + 5*x22 + 6*x23 + 7*x24 + 7*x25 + 5*x6 == 24, 5*x22 + 5*x26 + 6*x27 + 7*x28 + 7*x29 + 5*x7 == 25, 5*x23 + 5*x27 + 6*x30 + 7*x31 + 7*x32 + 5*x8 == 30, 5*x24 + 5*x28 + 6*x31 + 7*x33 + 7*x34 + 5*x9 == 35, 5*x10 + 5*x25 + 5*x29 + 6*x32 + 7*x34 + 7*x35 == 35, 5*x11 + 6*x12 + 7*x13 + 7*x14 + 5*x2 + 5*x7 == 25, 5*x22 + 5*x26 + 6*x27 + 7*x28 + 7*x29 + 5*x7 == 25, 5*x11 + 5*x26 + 5*x36 + 6*x37 + 7*x38 + 7*x39 == 24, 5*x12 + 5*x27 + 5*x37 + 6*x40 + 7*x41 + 7*x42 == 30, 5*x13 + 5*x28 + 5*x38 + 6*x41 + 7*x43 + 7*x44 == 35, 5*x14 + 5*x29 + 5*x39 + 6*x42 + 7*x44 + 7*x45 == 35, 5*x12 + 6*x15 + 7*x16 + 7*x17 + 5*x3 + 5*x8 == 30, 5*x23 + 5*x27 + 6*x30 + 7*x31 + 7*x32 + 5*x8 == 30, 5*x12 + 5*x27 + 5*x37 + 6*x40 + 7*x41 + 7*x42 == 30, 5*x15 + 5*x30 + 5*x40 + 6*x46 + 7*x47 + 7*x48 == 35, 5*x16 + 5*x31 + 5*x41 + 6*x47 + 7*x49 + 7*x50 == 42, 5*x17 + 5*x32 + 5*x42 + 6*x48 + 7*x50 + 7*x51 == 42, 5*x13 + 6*x16 + 7*x18 + 7*x19 + 5*x4 + 5*x9 == 35, 5*x24 + 5*x28 + 6*x31 + 7*x33 + 7*x34 + 5*x9 == 35, 5*x13 + 5*x28 + 5*x38 + 6*x41 + 7*x43 + 7*x44 == 35, 5*x16 + 5*x31 + 5*x41 + 6*x47 + 7*x49 + 7*x50 == 42, 5*x18 + 5*x33 + 5*x43 + 6*x49 + 7*x52 + 7*x53 == 48, 5*x19 + 5*x34 + 5*x44 + 6*x50 + 7*x53 + 7*x54 == 49, 5*x10 + 5*x14 + 6*x17 + 7*x19 + 7*x20 + 5*x5 == 35, 5*x10 + 5*x25 + 5*x29 + 6*x32 + 7*x34 + 7*x35 == 35, 5*x14 + 5*x29 + 5*x39 + 6*x42 + 7*x44 + 7*x45 == 35, 5*x17 + 5*x32 + 5*x42 + 6*x48 + 7*x50 + 7*x51 == 42, 5*x19 + 5*x34 + 5*x44 + 6*x50 + 7*x53 + 7*x54 == 49, 5*x20 + 5*x35 + 5*x45 + 6*x51 + 7*x54 + 7*x55 == 48 ] Here are explicit A and V from above system (in list form): A=[ [5,5,5,6,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,5,0,0,0,0,5,5,6,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,5,0,0,0,0,5,0,0,0,5,6,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,5,0,0,0,0,5,0,0,0,5,0,0,6,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,5,0,0,0,0,5,0,0,0,5,0,0,6,0,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,5,0,0,0,0,5,0,0,0,5,0,0,6,0,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,5,0,0,0,0,5,5,6,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,6,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,5,6,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,5,0,0,6,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,5,0,0,6,0,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,5,0,0,6,0,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,5,0,0,0,0,5,0,0,0,5,6,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,5,6,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,5,6,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,5,0,0,6,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,5,0,0,6,0,7,7,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,5,0,0,6,0,7,7,0,0,0,0,0,0,0,0,0,0], [0,0,0,5,0,0,0,0,5,0,0,0,5,0,0,6,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,5,0,0,6,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,5,0,0,6,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,6,7,7,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,6,0,7,7,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,6,0,7,7,0,0,0,0], [0,0,0,0,5,0,0,0,0,5,0,0,0,5,0,0,6,0,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,5,0,0,6,0,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,5,0,0,6,0,7,7,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,6,0,7,7,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,6,0,0,7,7,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,6,0,0,7,7,0], [0,0,0,0,0,5,0,0,0,0,5,0,0,0,5,0,0,6,0,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,5,0,0,6,0,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,5,0,0,6,0,7,7,0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,6,0,7,7,0,0,0,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,6,0,0,7,7,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,6,0,0,7,7] ] V=[24,25,25,30,35,35,25,24,25,30,35,35,25,25,24,30,35,35,30,30,30,35,42,42,35,35,35,42,48,49,35,35,35,42,49,48] Computation I wrote a brute-force code finding all the solutions of such a system, then applied it to A, V above. It took 12 seconds to find all 5499 solutions. I'm looking for something significantly faster than this. sage: %time LX=NonnegativeSolverPartition(A,V) CPU times: user 11.8 s, sys: 0 ns, total: 11.8 s Wall time: 11.8 s sage: len(LX) 5499 Note that the time reduces to 3 seconds with PyPy3, but it is still too slow for other (bigger) such systems I need to solve. Code Here is my (python) code, improved by Peter Taylor (see his comment): def NonnegativeSolverPartition(A,V): WB = WeakBasis(A) VB = VarBound(A,V) PP = [] for i, ll in WB: L = tuple(A[i][j] for j in ll) B = tuple(VB[j] for j in ll) PP.append(WeightedPartitionSolver(L, B, V[i])) return list(NonnegativeSolverPartitionInter(A, V, PP, WB, [-1] * len(A[0]))) def NonnegativeSolverPartitionInter(A, V, PP, WB, X): if any(len(P) > 1 for P in PP): _, ii = min((len(P), i) for i, P in enumerate(PP) if len(P) > 1) for p in PP[ii]: PPP = PP[:ii] + [[p]] + PP[ii+1:] Fi = Filter(PPP, list(X), WB) if Fi: PPPP, XX = Fi yield from NonnegativeSolverPartitionInter(A, V, PPPP, WB, XX) else: assert -1 not in X yield X def WeakBasis(A): return tuple(enumerate([j for j, tmp in enumerate(row) if tmp] for row in A)) def WeightedPartitions(ws, n): def inner(ws, n): if n == 0: yield (0,) * len(ws) elif ws: w = ws[0] lim = n // w ws = ws[1:] for i in range(lim + 1): for tl in inner(ws, n - w * i): yield (i,) + tl return list(inner(ws, n)) def VarBound(A,V): nvars = len(A[0]) # Solve the individual constraints and then intersect the solutions. possible_values = [None] * nvars row_solns = [] for row, v in zip(A, V): lut = [] ws = [] var_assignments = [] for j, val in enumerate(row): if val: lut.append(j) ws.append(val) var_assignments.append(set()) for soln in WeightedPartitions(ws, v): for i, w in enumerate(soln): var_assignments[i].add(w) for j, assignments in zip(lut, var_assignments): if possible_values[j] is None: possible_values[j] = assignments else: possible_values[j] &= assignments return tuple(frozenset(x) for x in possible_values) def WeightedPartitionSolver(L, B, n): # the entries of L must be non-negative # B gives valid values coming from other equations (see VarBound) def inner(L, B, n): if n == 0: yield (0,) * len(L) elif L: w, allowed = L[0], B[0] L, B = L[1:], B[1:] for i in range(n // w + 1): if i in allowed: for tl in inner(L, B, n - w * i): yield (i,) + tl return list(inner(L, B, n)) def Filter(PP, X, W): if [] in PP: return None while True: for Wi, P in zip(W, PP): F = FixedPoints(P) for j in F: P0j = P[0][j] Wij = Wi[1][j] if X[Wij] == -1: X[Wij] = P0j elif X[Wij] != P0j: return None LL=[] for Wi, P in zip(W, PP): LL.append([p for p in P if not any(X[idx] not in (-1, pval) for idx, pval in zip(Wi[1], p))]) if not LL[-1]: return None if PP == LL: return LL, X PP = LL def FixedPoints(P): # This would prefer P to be transposed m=len(P) n=len(P[0]) return tuple(i for i in range(n) if all(P[j][i] == P[0][i] for j in range(m))) A simpler brute-force code by Max Alekseyev is available in this answer.
Exif date taken for multiple photos - Python
My Exif code failed in my project so the photos came out without a "date taken" field. Luckly ive saved them with the date taken as the tittle eg. "-Forward14-07-2021-08-23-25.jpg". I have thousands of photos like this. I can add that individually using this python code. from datetime import datetime import piexif s = "13" m = "17" h = "09" dd = "14" mm = "07" yyyy = "2021" name = "-Forward" filename = str(name) + str(dd) + "-" + str(mm) + "-" + str(yyyy) + "-" + str(h) + "-" + str(m) + "-" + str(s) + ".jpg" exif_dict = piexif.load(filename) new_date = datetime(int(yyyy), int(mm), int(dd), int(h), int(m), int(s)).strftime("%Y:%m:%d %H:%M:%S") exif_dict['0th'][piexif.ImageIFD.DateTime] = new_date exifif_dict['Exif'][piexif.ExifIFD.DateTimeOriginal] = new_date exif_dict['Exif'][piexif.ExifIFD.DateTimeDigitized] = new_date exif_bytes = piexif.dump(exif_dict) piexif.insert(exif_bytes, filename) As soon as I try it as a loop it does not work. import PIL.Image import piexif from datetime import datetime from PIL import Image #import os #do not change these: s = "0" m = "0" h = "07" #change these: dd = "14" mm = "07" yyyy = "2021" Dir = "D:\Python codes\test" #insert file directory here## #run code twice, once for pavement and once for forward photos name = "-Forward" #"-Pavement" #for filename in os.listdir(dir): for h in range (7,17): for m in range (1,61): for s in range (1,61): if (int(s) < 10): s = "0" + str(s) if (int(m) < 10): m = "0" + str(m) if (int(h) < 10): h = "0" + str(h) else: s = int(s) m = int(m) h = int(h) try: filename = str(name) + str(dd) + "-" + str(mm) + "-" + str(yyyy) + "-" + str(h) + "-" + str(m) + "-" + str(s) + ".jpg" exif_dict = piexif.load(filename) new_date = datetime(int(yyyy), int(mm), int(dd), int(h), int(m), int(s)).strftime("%Y:%m:%d %H:%M:%S") exif_dict['0th'][piexif.ImageIFD.DateTime] = new_date exif_dict['Exif'][piexif.ExifIFD.DateTimeOriginal] = new_date exif_dict['Exif'][piexif.ExifIFD.DateTimeDigitized] = new_date exif_bytes = piexif.dump(exif_dict) piexif.insert(exif_bytes, filename) ##insert right directory # im = Image.open(Dir + name + str(dd) + "-" + str(mm) + "-" + str(yyyy) + "-" + str(h) + "-" +str(m) + "-" +str(s)) #im.save(Dir + name + str(dd) + "-" + str(mm) + "-" + str(yyyy) + "-" + str(h) + "-" +str(m) + "-" +str(s), exif=exif_bytes, quality="keep", optimize=True) s = int(s) + 1 except: s = int(s) + 1 m = int(m) + 1 h = int(h) + 1
I've done some more research and found out that the try: and except: were the problem. The working code can be seen below for those who are interested. Thanks for the help! import PIL.Image from os import path import piexif from datetime import datetime from PIL import Image import os # do not change these: s = 0 M = 0 h = 7 # change these: dd = "14" mm = "07" yyyy = "2021" # run code twice, once for pavement and once for forward photos name = "-Forward" # "-Pavement" # for filename in os.listdir(dir): for a in range(7, 17): M = 0 for b in range(1, 61): s = 0 for c in range(1, 61): ss = str(s) MM = str(M) hh = str(h) if s < 10: ss = "0" + str(s) if M < 10: MM = "0" + str(M) if h < 10: hh = "0" + str(h) filename = str(name) + str(dd) + "-" + str(mm) + "-" + str(yyyy) + "-" + str(hh) + "-" + str( MM) + "-" + str(ss) + ".jpg" #try: if path.exists(filename): # filename = str(name) + str(dd) + "-" + str(mm) + "-" + str(yyyy) + "-" + str(h) + "-" + str(m) + # "-" + str(s) + ".jpg" exif_dict = piexif.load(filename) new_date = datetime(int(yyyy), int(mm), int(dd), h, M, s).strftime("%Y:%m:%d %H:%M:%S") exif_dict['0th'][piexif.ImageIFD.DateTime] = new_date exif_dict['Exif'][piexif.ExifIFD.DateTimeOriginal] = new_date exif_dict['Exif'][piexif.ExifIFD.DateTimeDigitized] = new_date exif_bytes = piexif.dump(exif_dict) piexif.insert(exif_bytes, filename) # #insert right directory im = Image.open(Dir + name + str(dd) + "-" + str(mm) + "-" + str(yyyy) + # "-" + str(h) + "-" +str(m) + "-" +str(s)) im.save(Dir + name + str(dd) + "-" + str(mm) + "-" + str( # yyyy) + "-" + str(h) + "-" +str(m) + "-" +str(s), exif=exif_bytes, quality="keep", optimize=True) s += 1 #except: s += 1 M += 1 h += 1
numpy.ndarray lambda is not callable within loop when using scipy.minimize_scalar, works fine single-run
I'm working on a piece of code that calculates surface wave velocities. When I run this as a single-shot in my Jupyter notebook it works fine, however when I try to start looping over the phi1 angle, I end up with the 'numpy.ndarray is not callable error' after the zero iteration of the loop. It seems to be focused on the lambda (g) I am using, but I am not sure the best way to go about debugging it. Any help/review would be greatly appreciated as Google searches aren't helping too much. I do apologize for the novel of code, but this is trimmed down to where it should be easily reproducible. ## This code is an implementation of the framework described by M. Cherry et al. in ## Cherry, Matthew R., Shamachary Sathish, and Ramana Grandhi. "A numerical method for predicting Rayleigh surface wave ## velocity in anisotropic crystals." Journal of Computational Physics 351 (2017): 108-120. ## The logic of this code is as follows. ## (1) It then calculates R, T, and Qv (which is the velocity independent Q, needed to determine the velocity range ## over which to search. ## (2) It then iterates to determine the velocity range by changing a variable called 'angle'. ## (3) It then finds a minimum vL, and solves for Q (with velocity as a term), N, A, B, and Z matrices. ## (4) It stores the three Euler angles (p1, P, p2) and RSW_vel ## This does not deal with pseudowaves yet. import matplotlib.pyplot as plt import numpy as np import scipy as sp import scipy.optimize as spo import scipy.linalg as la from scipy.linalg import eig, eigvals import math from decimal import * import time ts1 = time.time() # Setup material properties # Setup the Cij matrix of Ni (units in Pa) C11 = C22 = C33 = 2.41e11 C12 = C13 = C23 = C21 = C31 = C32 = 1.47e11 C14 = C15 = C16 = C24 = C25 = C26 = C34 = C35 = C36 = C41 = C42 = C43 = C51 = C52 = C53 = C61 = C62 = C63 = 0 C44 = C55 = C66 = 1.26e11 C45 = C46 = C56 = C54 = C64 = C65 = 0 Cij_list = np.array([C11,C12,C13,C14,C15,C16,C21,C22,C23,C24,C25,C26,C31,C32,C33,C34,C35,C36,C41,C42,C43,C44,C45,C46,C51,C52,C53,C54,C55,C56,C61,C62,C63,C64,C65,C66]) Cij=Cij_list.reshape(6,6) print('Cij =') print(Cij) # Setup density of Ni (units are in kg/m3) rho = 8910 RSW_matrix = np.array([0,0,0,0]) ## This is where the setting up of the loop for p1, P, and p2 should be. # Setup Euler Angles in Bunge's active notation (one time only - demo, will need to be iterated over), angles in degrees. p1 = phi1, P = Phi, p2 = phi2 #p1 = 15 P = 45 p2 = 8 for rotation in range(0, 180): ## Below this point, everything must be done for every Euler calculation. p1_rad = np.radians(rotation) P_rad = np.radians(P) p2_rad = np.radians(p2) Eul_Ang_deg = np.array([p1,P,p2]) Eul_Ang_rad = np.array([p1_rad,P_rad,p2_rad]) c1 = np.cos(p1_rad) c2 = np.cos(P_rad) c3 = np.cos(p2_rad) s1 = np.sin(p1_rad) s2 = np.sin(P_rad) s3 = np.sin(p2_rad) # Solve Rotation Matrix from Bunge's active notation, and m and n (m is wave propagation vector, n is plane normal) Rot_mat = np.array([[c1*c3-c2*s1*s3,-c1*s3-c2*c3*s1,s1*s2], [c3*s1+c1*c2*s3,c1*c2*c3-s1*s3,-c1*s2], [s2*s3,c3*s2,c2]]) #- could fill in the rest here and just extract col 1 and col 3 print('Rotation Matrix =') print(Rot_mat) m_vec = Rot_mat[[0],:] m1 = Rot_mat[[0],[0]] m2 = Rot_mat[[0],[1]] m3 = Rot_mat[[0],[2]] n_vec = Rot_mat[[2],:] n1 = Rot_mat[[2],[0]] n2 = Rot_mat[[2],[1]] n3 = Rot_mat[[2],[2]] # Below, we calculate R, T and Q matrices # CORRECT R matrix calculations Rij = np.ndarray(shape=(3,3)) Rij[0,0] = C11*m1*n1 + C61*m2*n1 + C51*m3*n1 + C16*m1*n2 + C66*m2*n2 + C56*m3*n2 + C15*m1*n3 + C65*m2*n3 + C55*m3*n3 Rij[0,1] = C16*m1*n1 + C66*m2*n1 + C56*m3*n1 + C12*m1*n2 + C62*m2*n2 + C52*m3*n2 + C14*m1*n3 + C64*m2*n3 + C54*m3*n3 Rij[0,2] = C15*m1*n1 + C65*m2*n1 + C55*m3*n1 + C14*m1*n2 + C64*m2*n2 + C54*m3*n2 + C13*m1*n3 + C63*m2*n3 + C53*m3*n3 Rij[1,0] = C61*m1*n1 + C21*m2*n1 + C41*m3*n1 + C66*m1*n2 + C26*m2*n2 + C46*m3*n2 + C65*m1*n3 + C25*m2*n3 + C45*m3*n3 Rij[1,1] = C66*m1*n1 + C26*m2*n1 + C46*m3*n1 + C62*m1*n2 + C22*m2*n2 + C42*m3*n2 + C64*m1*n3 + C24*m2*n3 + C44*m3*n3 Rij[1,2] = C65*m1*n1 + C25*m2*n1 + C45*m3*n1 + C64*m1*n2 + C24*m2*n2 + C44*m3*n2 + C63*m1*n3 + C23*m2*n3 + C43*m3*n3 Rij[2,0] = C51*m1*n1 + C41*m2*n1 + C31*m3*n1 + C56*m1*n2 + C46*m2*n2 + C36*m3*n2 + C55*m1*n3 + C45*m2*n3 + C35*m3*n3 Rij[2,1] = C56*m1*n1 + C46*m2*n1 + C36*m3*n1 + C52*m1*n2 + C42*m2*n2 + C32*m3*n2 + C54*m1*n3 + C44*m2*n3 + C34*m3*n3 Rij[2,2] = C55*m1*n1 + C45*m2*n1 + C35*m3*n1 + C54*m1*n2 + C44*m2*n2 + C34*m3*n2 + C53*m1*n3 + C43*m2*n3 + C33*m3*n3 Rij_trans = np.transpose(Rij) Rij_inv = np.linalg.inv(Rij) # CORRECT T matrix calculations Tij = np.ndarray(shape=(3,3)) Tij[0,0] = C11*n1*n1 + C16*n2*n1 + C51*n3*n1 + C16*n1*n2 + C66*n2*n2 + C56*n3*n2 + C15*n1*n3 + C65*n2*n3 + C55*n3*n3 Tij[0,1] = C16*n1*n1 + C66*n2*n1 + C56*n3*n1 + C12*n1*n2 + C62*n2*n2 + C52*n3*n2 + C14*n1*n3 + C64*n2*n3 + C54*n3*n3 Tij[0,2] = C15*n1*n1 + C65*n2*n1 + C55*n3*n1 + C14*n1*n2 + C64*n2*n2 + C54*n3*n2 + C13*n1*n3 + C63*n2*n3 + C53*n3*n3 Tij[1,0] = C61*n1*n1 + C21*n2*n1 + C41*n3*n1 + C66*n1*n2 + C26*n2*n2 + C46*n3*n2 + C65*n1*n3 + C25*n2*n3 + C45*n3*n3 Tij[1,1] = C66*n1*n1 + C26*n2*n1 + C46*n3*n1 + C62*n1*n2 + C22*n2*n2 + C42*n3*n2 + C64*n1*n3 + C24*n2*n3 + C44*n3*n3 Tij[1,2] = C65*n1*n1 + C25*n2*n1 + C45*n3*n1 + C64*n1*n2 + C24*n2*n2 + C44*n3*n2 + C63*n1*n3 + C23*n2*n3 + C43*n3*n3 Tij[2,0] = C51*n1*n1 + C41*n2*n1 + C31*n3*n1 + C56*n1*n2 + C46*n2*n2 + C36*n3*n2 + C55*n1*n3 + C45*n2*n3 + C35*n3*n3 Tij[2,1] = C56*n1*n1 + C46*n2*n1 + C36*n3*n1 + C52*n1*n2 + C42*n2*n2 + C32*n3*n2 + C54*n1*n3 + C44*n2*n3 + C34*n3*n3 Tij[2,2] = C55*n1*n1 + C45*n2*n1 + C35*n3*n1 + C54*n1*n2 + C44*n2*n2 + C34*n3*n2 + C53*n1*n3 + C43*n2*n3 + C33*n3*n3 Tij_trans = np.transpose(Tij) Tij_inv = np.linalg.inv(Tij) ## R and T defined as above. Q needs to be new - and not remove the rv2. Thus, we introduce Qv for "Q to determine ## critical velocity" Qv = np.ndarray(shape=(3,3)) Qv[0,0] = C11*m1*m1 + C61*m2*m1 + C51*m3*m1 + C16*m1*m2 + C66*m2*m2 + C56*m3*m2 + C15*m1*m3 + C65*m2*m3 + C55*m3*m3 Qv[0,1] = C16*m1*m1 + C66*m2*m1 + C56*m3*m1 + C12*m1*m2 + C62*m2*m2 + C52*m3*m2 + C14*m1*m3 + C64*m2*m3 + C54*m3*m3 Qv[0,2] = C15*m1*m1 + C65*m2*m1 + C55*m3*m1 + C14*m1*m2 + C64*m2*m2 + C54*m3*m2 + C13*m1*m3 + C63*m2*m3 + C53*m3*m3 Qv[1,0] = C61*m1*m1 + C21*m2*m1 + C41*m3*m1 + C66*m1*m2 + C26*m2*m2 + C46*m3*m2 + C65*m1*m3 + C25*m2*m3 + C45*m3*m3 Qv[1,1] = C66*m1*m1 + C26*m2*m1 + C46*m3*m1 + C62*m1*m2 + C22*m2*m2 + C42*m3*m2 + C64*m1*m3 + C24*m2*m3 + C44*m3*m3 Qv[1,2] = C65*m1*m1 + C25*m2*m1 + C45*m3*m1 + C64*m1*m2 + C24*m2*m2 + C44*m3*m2 + C63*m1*m3 + C23*m2*m3 + C43*m3*m3 Qv[2,0] = C51*m1*m1 + C41*m2*m1 + C31*m3*m1 + C56*m1*m2 + C46*m2*m2 + C36*m3*m2 + C55*m1*m3 + C45*m2*m3 + C35*m3*m3 Qv[2,1] = C56*m1*m1 + C46*m2*m1 + C36*m3*m1 + C52*m1*m2 + C42*m2*m2 + C32*m3*m2 + C54*m1*m3 + C44*m2*m3 + C34*m3*m3 Qv[2,2] = C55*m1*m1 + C45*m2*m1 + C35*m3*m1 + C54*m1*m2 + C44*m2*m2 + C34*m3*m2 + C53*m1*m3 + C43*m2*m3 + C33*m3*m3 res = [] res = spo.minimize_scalar(lambda x: ((min(eigvals(Qv * np.cos(np.radians(x)) * np.cos(np.radians(x)) + (Rij + Rij_trans) * np.cos(np.radians(x)) * np.sin(np.radians(x)) + Tij * np.sin(np.radians(x)) * np.sin(np.radians(x)))) / rho)**(0.5))*(1/(np.abs(np.cos(np.radians(x))))), bracket=(-90,0,90), method='Golden') vel_L = res.fun.real vel_L_int = int(vel_L) print('velocity limit') print(vel_L) print(vel_L_int) Det_B_try = 1 Qij = np.zeros(shape=(3,3)) Qij[0,1] = C16*m1*m1 + C66*m2*m1 + C56*m3*m1 + C12*m1*m2 + C62*m2*m2 + C52*m3*m2 + C14*m1*m3 + C64*m2*m3 + C54*m3*m3 Qij[0,2] = C15*m1*m1 + C65*m2*m1 + C55*m3*m1 + C14*m1*m2 + C64*m2*m2 + C54*m3*m2 + C13*m1*m3 + C63*m2*m3 + C53*m3*m3 Qij[1,0] = C61*m1*m1 + C21*m2*m1 + C41*m3*m1 + C66*m1*m2 + C26*m2*m2 + C46*m3*m2 + C65*m1*m3 + C25*m2*m3 + C45*m3*m3 Qij[1,2] = C65*m1*m1 + C25*m2*m1 + C45*m3*m1 + C64*m1*m2 + C24*m2*m2 + C44*m3*m2 + C63*m1*m3 + C23*m2*m3 + C43*m3*m3 Qij[2,0] = C51*m1*m1 + C41*m2*m1 + C31*m3*m1 + C56*m1*m2 + C46*m2*m2 + C36*m3*m2 + C55*m1*m3 + C45*m2*m3 + C35*m3*m3 Qij[2,1] = C56*m1*m1 + C46*m2*m1 + C36*m3*m1 + C52*m1*m2 + C42*m2*m2 + C32*m3*m2 + C54*m1*m3 + C44*m2*m3 + C34*m3*m3 for v in range(1, vel_L_int): # Calculate rho vel-squared rv2 = rho * v ** 2 # CORRECT Q matrix calculations Qij[0,0] = C11*m1*m1 + C61*m2*m1 + C51*m3*m1 + C16*m1*m2 + C66*m2*m2 + C56*m3*m2 + C15*m1*m3 + C65*m2*m3 + C55*m3*m3 - rv2 Qij[1,1] = C66*m1*m1 + C26*m2*m1 + C46*m3*m1 + C62*m1*m2 + C22*m2*m2 + C42*m3*m2 + C64*m1*m3 + C24*m2*m3 + C44*m3*m3 - rv2 Qij[2,2] = C55*m1*m1 + C45*m2*m1 + C35*m3*m1 + C54*m1*m2 + C44*m2*m2 + C34*m3*m2 + C53*m1*m3 + C43*m2*m3 + C33*m3*m3 - rv2 Qij_trans = np.transpose(Qij) Qij_inv = np.linalg.inv(Qij) # Create a new Nik matrix TR_ik = -1*np.matmul(Tij_inv, Rij_trans) TI_ik = Tij_inv QRTR_ik = -Qij + np.matmul(np.matmul(Rij, Tij_inv), Rij_trans) RT_ik = -1*np.matmul(Rij, Tij_inv) # Nik Creation Nik_r1to3 = np.concatenate((TR_ik,TI_ik),axis=1) Nik_r4to6 = np.concatenate((QRTR_ik,RT_ik),axis=1) Nik_whole = np.concatenate((Nik_r1to3,Nik_r4to6)) # Eigenvalues and Eigenvectors of Nik eigvals, eigvecs = eig(Nik_whole) ## The following code sorts the eigenvalues for those with negative imaginary numbers, and conducts the matrix ## operations to generate the B, A, and Z matrices from the COLUMNS in Pythons representation of eigenvectors eigvecsT = np.transpose(eigvecs) output_ab = output_ab_neg_imag = eigvecsT[eigvals.imag < 0] output_abT = np.transpose(output_ab) ### This is the B matrix (bottom 3 vectors assumed as b) B_matrix = output_b = np.delete(output_abT, [0,1,2], axis=0) B_matrixT = np.transpose(B_matrix) ### This is the A matrix (these are the displacement vectors, and when A is combined with B, the surface impedance (Z) matrix can be found) A_matrix = output_a = np.delete(output_abT, [3,4,5], axis=0) det_B = np.linalg.det(B_matrix) det_cc_B = det_B.conjugate() det_B_x_det_cc_B = det_B*det_cc_B v_real = v.real det_B_x_det_cc_B_real = det_B_x_det_cc_B.real if det_B_x_det_cc_B_real < Det_B_try: RSW_vel = v_real Det_B_try = det_B_x_det_cc_B_real print('RSW =') print(RSW_vel) print('Min |B|x|B|* =') print(Det_B_try) col_to_be_added2 = np.array([p1, P, p2, RSW_vel]) RSW_matrix = np.column_stack((RSW_matrix,col_to_be_added2)) print('RSW vel matrix is') print(RSW_matrix)
Python function gets stuck (no error) but I can't understand why
The function does what I want it to, but when it's done it just sits there rather than continuing from where I called it and I can't figure out why. The code is: x = 9 y = 9 n = 10 ty = 1 tx = 1 while ty <= y: while tx <= x: vars()["p" + str(ty) + str(tx)] = 0 tx += 1 ty += 1 tx = 1 tn = 1 while tn <= n: vars()["m" + str(tn)] = tn tn += 1 t = x * y tm = n def recursion(z): global tm if z < n: for x in range(n): recursion(z + 1) else: if tm > 0: tv = "m" + str(tm) otm = eval(tv) while eval(tv) < t - n + tm: vars()[tv] = eval(tv) + 1 print(tv + " = " + str(eval(tv))) vars()[tv] = otm + 1 print(tv + " = " + str(eval(tv))) if tm > 1: vars()["m" + str(tm - 1)] = eval("m" + str(tm - 1)) + 1 print(str("m" + str(tm - 1) + " = " + str(eval("m" + str(tm -1))))) tm -= 1 recursion(1) print("done") I've put the return in where I would expect it to end but as far as I know it shouldn't actually need it. Can anyone see what I've done to cause it to get stuck? Thanks
Note for people not going through the change history: This is based on the comments on other answers. UPDATE: Better version. import itertools def permutations(on, total): all_indices = range(total) for indices in itertools.combinations(all_indices, on): board = ['0'] * total for index in indices: board[index] = '1' yield ''.join(board)
If anyone is interested in what the original code did, I rearranged the conditionals to prune the tree of function calls: x = 9 y = 9 n = 10 ty = 1 tx = 1 while ty <= y: while tx <= x: vars()["p" + str(ty) + str(tx)] = 0 tx += 1 ty += 1 tx = 1 tn = 1 while tn <= n: vars()["m" + str(tn)] = tn tn += 1 t = x * y tm = n def recursion(z): global tm if tm > 0: if z < n: for x in range(n): recursion(z + 1) else: tv = "m" + str(tm) otm = eval(tv) while eval(tv) < t - n + tm: vars()[tv] = eval(tv) + 1 print(tv + " = " + str(eval(tv))) vars()[tv] = otm + 1 print(tv + " = " + str(eval(tv))) if tm > 1: vars()["m" + str(tm - 1)] = eval("m" + str(tm - 1)) + 1 print(str("m" + str(tm - 1) + " = " + str(eval("m" + str(tm -1))))) tm -= 1 recursion(1) print("done") This could be made much clearer through the use of lists and range objects, but that takes effort.
I wasn't able to work out what was happening (turns out if I left it for a few minutes it would actually finish though), instead, I realised that I didn't need to use recursion to achieve what I wanted (and I also realised the function didn't actually do what I want to do). For anyone interested, I simplified and rewrote it to be a few while loops instead: x = 9 y = 9 t = x * y n = 10 tt = 1 while tt <= t: vars()["p" + str(tt)] = 0 tt += 1 tn = 1 while tn <= n: vars()["m" + str(tn)] = tn vars()["p" + str(tn)] = 1 tn += 1 def cl(): w = "" tt = 1 while tt <= t: w = w + str(eval("p" + str(tt))) tt += 1 p.append(w) tm = n tv = "m" + str(tm) p = [] while m1 < t - n + tm - 1: cl() while tm == n and eval(tv) < t - n + tm: vars()["p" + str(eval(tv))] = 0 vars()[tv] = eval(tv) + 1 vars()["p" + str(eval(tv))] = 1 cl() tm -= 1 tv = "m" + str(tm) while tm < n and tm > 0: if eval(tv) < t - n + tm: vars()["p" + str(eval(tv))] = 0 vars()[tv] = eval(tv) + 1 vars()["p" + str(eval(tv))] = 1 while tm < n: tm += 1 ptv = tv tv = "m" + str(tm) vars()["p" + str(eval(tv))] = 0 vars()[tv] = eval(ptv) + 1 vars()["p" + str(eval(tv))] = 1 else: tm -= 1 tv = "m" + str(tm)
integrate cos(x)*cos(2x)*...*cos(mx) via SAGE
I'm going to find $I_m=\int_0^{2\pi} \prod_{k=1}^m cos(kx){}dx$, where $m=1,2,3\ldots$ Simple SAGE code: x=var('x') f = lambda m,x : prod([cos(k*x) for k in range(1,m+1)]) for m in range(1,15+1): print m, numerical_integral(f(m,x), 0, 2*pi)[0],integrate(f(m,x),x,0,2*pi).n() Output: 1 -1.47676658757e-16 0.000000000000000 2 -5.27735962315e-16 0.000000000000000 3 1.57079632679 1.57079632679490 4 0.785398163397 0.785398163397448 5 -2.60536121164e-16 0.000000000000000 6 -1.81559273097e-16 0.000000000000000 7 0.392699081699 0.392699081698724 8 0.343611696486 0.147262155637022 9 -1.72448482421e-16 0.294524311274043 10 -1.8747663502e-16 0.196349540849362 11 0.214757310304 0.312932080728671 12 0.190213617698 0.177941771394734 13 -1.30355375996e-16 0.208621387152447 14 -1.25168280013e-16 0.0859029241215959 15 0.138441766107 0.134223318939994 As you can see numerical answer is right, but result of integrate(...) is right for $m=1,2,\ldots,7$ and then there is some bug. We can print indefinite integral: for m in range(7,11+1): print 'm=',m print 'Indef_I_m=',integrate(f(m,x),x) And Output: m = 7 Indef_I_m = 1/16*x + 1/16*sin(2*x) + 1/32*sin(4*x) + 7/384*sin(6*x) + 7/512*sin(8*x) + 3/320*sin(10*x) + 5/768*sin(12*x) + 5/896*sin(14*x) + 1/256*sin(16*x) + 1/384*sin(18*x) + 1/640*sin(20*x) + 1/704*sin(22*x) + 1/1536*sin(24*x) + 1/1664*sin(26*x) + 1/1792*sin(28*x) m = 8 Indef_I_m = 3/128*x + 5/256*sin(2*x) + 1/32*sin(3*x) + 5/512*sin(4*x) + 5/768*sin(6*x) + 1/256*sin(8*x) + 1/256*sin(10*x) + 1/256*sin(12*x) + 1/256*sin(14*x) + 1/256*sin(16*x) + 7/2304*sin(18*x) + 3/1280*sin(20*x) + 5/2816*sin(22*x) + 1/768*sin(24*x) + 3/3328*sin(26*x) + 1/1792*sin(28*x) + 1/1920*sin(30*x) + 1/4096*sin(32*x) + 1/4352*sin(34*x) + 1/4608*sin(36*x) + 3/32*sin(x) m = 9 Indef_I_m = 3/64*x + 3/128*sin(2*x) + 23/768*sin(3*x) + 3/256*sin(4*x) + 3/640*sin(5*x) + 1/128*sin(6*x) + 5/1792*sin(7*x) + 5/2304*sin(9*x) + 3/2816*sin(11*x) + 1/832*sin(13*x) + 1/1280*sin(15*x) + 3/4352*sin(17*x) + 5/4864*sin(19*x) + 1/1344*sin(21*x) + 3/2944*sin(23*x) + 7/6400*sin(25*x) + 1/1152*sin(27*x) + 3/3712*sin(29*x) + 5/7936*sin(31*x) + 1/2112*sin(33*x) + 3/8960*sin(35*x) + 1/4736*sin(37*x) + 1/4992*sin(39*x) + 1/10496*sin(41*x) + 1/11008*sin(43*x) + 1/11520*sin(45*x) + 23/256*sin(x) m = 10 Indef_I_m = 1/32*x + 1/64*sin(2*x) + 17/512*sin(3*x) + 1/128*sin(4*x) + 7/2560*sin(5*x) + 1/192*sin(6*x) + 3/1792*sin(7*x) + 1/1152*sin(9*x) + 5/5632*sin(11*x) + 3/6656*sin(13*x) + 1/2560*sin(15*x) + 5/8704*sin(17*x) + 3/9728*sin(19*x) + 1/2688*sin(21*x) + 1/2944*sin(23*x) + 1/6400*sin(25*x) + 1/4608*sin(27*x) + 3/14848*sin(29*x) + 3/15872*sin(31*x) + 5/16896*sin(33*x) + 3/8960*sin(35*x) + 3/9472*sin(37*x) + 1/3328*sin(39*x) + 5/20992*sin(41*x) + 1/5504*sin(43*x) + 1/7680*sin(45*x) + 1/12032*sin(47*x) + 1/12544*sin(49*x) + 1/26112*sin(51*x) + 1/27136*sin(53*x) + 1/28160*sin(55*x) + 13/128*sin(x) m = 11 Indef_I_m = 51/1024*x + 53/2048*sin(2*x) + 13/768*sin(3*x) + 53/4096*sin(4*x) + 13/1536*sin(6*x) + 1/2048*sin(8*x) + 1/2560*sin(10*x) + 1/3072*sin(12*x) + 5/14336*sin(14*x) + 1/4096*sin(16*x) + 5/18432*sin(18*x) + 1/4096*sin(20*x) + 1/5632*sin(22*x) + 5/24576*sin(24*x) + 5/26624*sin(26*x) + 5/28672*sin(28*x) + 1/5120*sin(30*x) + 3/16384*sin(32*x) + 5/34816*sin(34*x) + 1/9216*sin(36*x) + 5/38912*sin(38*x) + 1/10240*sin(40*x) + 1/10752*sin(42*x) + 3/22528*sin(44*x) + 3/23552*sin(46*x) + 1/8192*sin(48*x) + 3/25600*sin(50*x) + 5/53248*sin(52*x) + 1/13824*sin(54*x) + 3/57344*sin(56*x) + 1/29696*sin(58*x) + 1/30720*sin(60*x) + 1/63488*sin(62*x) + 1/65536*sin(64*x) + 1/67584*sin(66*x) + 13/256*sin(x) so for $m=7$ answer is right compare with Indef_I_7 via WolframAlpha and for $m=8$ answer is incorrect Indef_I_8 via WolframAlpha There should be Indef_I_8=$\frac{7x}{128}+\ldots$ and no $\sin(x)$, $\sin(3x)$ in summation, only $\sin(2k)$ for $k=1,2,3,\ldots 18$ Sorry for volumetric calculations ! The question is - Am I right that it is the bug in the symbolic integration?
Well, apparently setting algorithm='mathematica_free' solved the issue; this is probably a bug in the default algorithm used bye SAGE ('maxima').
So the answer is - Yes. It is a bug in algorithm='maxima', so use algorithm='mathematica_free' (def new function to find definite integral) or simplify_full() for such product of cos(kx) and than integrate. f(8,x).simplify_full().integral(x,0,2pi) == 7/64pi and (7/64*pi).n() == 0.343611696486384 is correct