I have a function defintion -
Now I have to create a function like this-
The problem is that since there are 4 combinations of (t,c)(where t is the feature and c is the class) which can occur that is (t,c) , (t',c) , (t,c') , (t', c'). So according to the values of t,c the function defintion will also change.
Is there any method apart from calculating a , b ,c ,d 4 times and then summing the function values?
The dataset looks like this-
feature file_frequency_M file_frequency_B
abc 2 5
my attempt-
dataset = pd.read_csv('.csv')
score = []
###list =[(t,c) ,(t,c0),(t0,c),(t0,c0)] ##representation of the combination of (t,c)
l=152+1394
for index, row in dataset.iterrows():
a = row['file_frequency_M']
b = row['file_frequency_B']
c = 152 - a
d = 1394 - b
temp_score = 0
tmp1 = 0
tmp2 = 0
tmp3 = 0
tmp4 = 0
for i in range(4):
if i == 0:
if a == 0:
tmp1 = 0
else:
tmp1 = log10(((a * l) / (a + c) * (a + b)))
temp_score += tmp1
if i == 1:
if b == 0:
tmp2 = 0
else:
tmp2 = log10(((b * l) / (b + d) * (b + a)))
temp_score += tmp2
if i == 2:
if c == 0:
tmp3 = 0
else:
tmp3 = log10(((c * l) / (c + a) * (c + d)))
temp_score += tmp3
if i == 3:
if d == 0:
tmp4 = 0
else:
tmp4 = log10(((d * l) / (d + b) * (d + c)))
temp_score += tmp4
score.append(temp_score)
np.savetxt("m.csv", score, delimiter=",")
You can save a lot of code repetition by creating a function representation of I(t,c):
import numpy as np
import pandas as pd
from math import log10
dataset = pd.read_csv('.csv')
score = []
###list =[(t,c) ,(t,c0),(t0,c),(t0,c0)] ##representation of the combination of (t,c)
l=152+1394
def I(a,b,c,n):
"""Returns I(t,c) = A*N/((A+C)*(A+B))"""
if a == 0:
return 0
return log10((a * n) / ((a + c) * (a + b)))
for index, row in dataset.iterrows():
a = row['file_frequency_M']
b = row['file_frequency_B']
c = 152 - a
d = 1394 - b
tmp1 = I(a,b,c,l)
tmp2 = I(b,a,d,l)
tmp3 = I(c,d,a,l)
tmp4 = I(d,c,b,l)
temp_score = sum(tmp1,tmp2,tmp3,tmp4)
score.append(temp_score)
np.savetxt("m.csv", score, delimiter=",")
Note: you appear to have an error in your code, according to the image of your function definition, it should be:
log10((a * n) / ((a + c) * (a + b)))
not
log10(((a * l) / (a + c) * (a + b)))
(note the parentheses placement).
Related
num_pixels_per_cell_one_axis = 5
num_cells_per_module_one_axis = 3
inter_cell_sep = 4
max_items_in_list = num_cells_per_module_one_axis * num_pixels_per_cell_one_axis + (num_cells_per_module_one_axis-1) * inter_cell_sep
print(max_items_in_list)
indices_to_retain = list(range(max_items_in_list))
indices_to_remove = indices_to_retain[num_pixels_per_cell_one_axis :: num_pixels_per_cell_one_axis + inter_cell_sep]
if inter_cell_sep == 2:
for k in range(0,len(indices_to_remove)):
indices_to_remove.append(indices_to_remove[k]+1)
if inter_cell_sep == 3:
for k in range(0,len(indices_to_remove)):
indices_to_remove.append(indices_to_remove[k]+1)
indices_to_remove.append(indices_to_remove[k]+2)
for k in indices_to_remove:
indices_to_retain.remove(k)
print(indices_to_remove)
print(indices_to_retain)
I want to find a way to loop inter_cell_sep for any positive number and as it increases the lines for appending the list also increases. The expected answer should be [0,1,2,3,4,9,10,11,12,17,18,19,20]
I think instead of using if statements for each value of inter_cell_sep you could loop through a range of inter_cell_sep. Here is what I came up with.
num_pixels_per_cell_one_axis = 5
num_cells_per_module_one_axis = 3
inter_cell_sep = 3
max_items_in_list = num_cells_per_module_one_axis * num_pixels_per_cell_one_axis + (num_cells_per_module_one_axis - 1) * inter_cell_sep
print(max_items_in_list)
indices_to_retain = list(range(max_items_in_list))
indices_to_remove = indices_to_retain[num_pixels_per_cell_one_axis:: num_pixels_per_cell_one_axis + inter_cell_sep]
for k in range(0, len(indices_to_remove)):
indices_to_remove.extend([indices_to_remove[k] + x for x in range(1, inter_cell_sep)])
for k in indices_to_remove:
indices_to_retain.remove(k)
print(indices_to_remove)
print(indices_to_retain)
import sys
t=(int(sys.stdin.readline()))
for i in range(0,t):
n=int(sys.stdin.readline())
c=0
s=n*(n+1)/2
if s%2!=0:
print(0)
else:
c=0
i=-1
a=[i for i in range(1,n+1)]
h=s//2
m=0
s1=0
for i in range(n-1,-1,-1):
s1+=a[i]
c+=1
if s1==h:
m=1
break
if s1>h:
break
if m==1:
s1=((c+1)*(2+((c-1)-1)))//2+((n-c-1)*(2+((n-c-1)-1)))//2
print(s1)
else:
print(c)
I am new to python , How can i write this code with using for loop? i don't want to use for loop because i get TLE error. Thanks in advance
Here is the question :
N. Consider the sequence sequence=(1,2,…,N). You should choose two elements of this sequence and swap them.
A swap is perfect if there is an integer o (1≤o<N) such that the sum of the first M elements of the resulting sequence is equal to the sum of its last N−o elements. Find the number of perfect swaps.
i got interested in the problem and found this so far:
a slow version that creates list and really does swap elements is this:
from itertools import combinations
def slow(N):
found = 0
for i, j in combinations(range(N), 2):
lst = list(range(1, N + 1))
lst[i], lst[j] = lst[j], lst[i]
for m in range(1, N):
a = m * (m + 1) // 2
b = (N - m) * (N + m + 1) // 2
if i < m <= j:
a = a - i + j
b = b - j + i
assert a == sum(lst[:m])
assert b == sum(lst[m:])
if sum(lst[:m]) == sum(lst[m:]):
found += 1
if i < m <= j:
assert 2 * m * (m + 1) + 4 * j == N * (N + 1) + 4 * i
else:
assert 2 * m * (m + 1) == N * (N + 1)
else:
if i < m <= j:
assert 2 * m * (m + 1) + 4 * j != N * (N + 1) + 4 * i
else:
assert 2 * m * (m + 1) != N * (N + 1)
return found
as you see i found criteria the indices have to fulfill in order for the sum to be correct:
if i < m <= j:
assert 2 * m * (m + 1) + 4 * j == N * (N + 1) + 4 * i
else:
assert 2 * m * (m + 1) == N * (N + 1)
i also found the direct formula to calculate the sum up to m and the one starting from m:
a = m * (m + 1) // 2
b = (N - m) * (N + m + 1) // 2
if i < m <= j:
a = a - i + j
b = b - j + i
all of that can can be calculated using some basic mathematics.
starting from that you can do some more maths and see that there are 2 cases to consider:
there is an m such that the sum of the original list [1, 2, 3, ..., m, m+1, ..., N] up to m equals the sum of the rest of the list (e.g. N = 20; m = 14). two cases again:
all the swaps that do not cross the m boundary are valid (there are comb(m, 2) + comb((N - m), 2)) of them.
when you split at m-1 you will find more swaps; this time you have to swap accross the m-1 boundary.
the m in that case is calculated from
m = - 1 + sqrt(1 + 2 * N * (N + 1)) / 2
the calculation for m in the first case is not an integer (i.e. 1 + 2 * N * (N + 1) is not a perfect square). the m to consider is then then the floor of the result of the formula above (i use int instead of math.floor). two cases again for the difference of the sum of the two splits:
the difference is even: there are more swaps that need to go over the m boundary.
the difference is odd: no additional swaps (swapping will always result in an even difference)
this is the code:
from math import sqrt, comb
def fast(N):
found = 0
arg = (1 + 2 * N * (N + 1))
sq = round(sqrt(arg))
if sq ** 2 == arg and sq & 1:
m = (-1 + sq) // 2
found += comb(m, 2) + comb((N - m), 2)
m -= 1
found += N - m - 1
else:
m = int((-1 + sqrt(arg)) // 2)
diff = ((m + 1 + N) * (N - m) - m * (m + 1)) // 2
if diff & 1 == 0:
found += N - m
return found
I'm a bit stuck on a python problem.
I'm suppose to write a function that takes a positive integer n and returns the number of different operations that can sum to n (2<n<201) with decreasing and unique elements.
To give an example:
If n = 3 then f(n) = 1 (Because the only possible solution is 2+1).
If n = 5 then f(n) = 2 (because the possible solutions are 4+1 & 3+2).
If n = 10 then f(n) = 9 (Because the possible solutions are (9+1) & (8+2) & (7+3) & (7+2+1) & (6+4) & (6+3+1) & (5+4+1) & (5+3+2) & (4+3+2+1)).
For the code I started like that:
def solution(n):
nb = list(range(1,n))
l = 2
summ = 0
itt = 0
for index in range(len(nb)):
x = nb[-(index+1)]
if x > 3:
for index2 in range(x-1):
y = nb[index2]
#print(str(x) + ' + ' + str(y))
if (x + y) == n:
itt = itt + 1
for index3 in range(y-1):
z = nb[index3]
if (x + y + z) == n:
itt = itt + 1
for index4 in range(z-1):
w = nb[index4]
if (x + y + z + w) == n:
itt = itt + 1
return itt
It works when n is small but when you start to be around n=100, it's super slow and I will need to add more for loop which will worsen the situation...
Do you have an idea on how I could solve this issue? Is there an obvious solution I missed?
This problem is called integer partition into distinct parts. OEIS sequence (values are off by 1 because you don't need n=>n case )
I already have code for partition into k distinct parts, so modified it a bit to calculate number of partitions into any number of parts:
import functools
#functools.lru_cache(20000)
def diffparts(n, k, last):
result = 0
if n == 0 and k == 0:
result = 1
if n == 0 or k == 0:
return result
for i in range(last + 1, n // k + 1):
result += diffparts(n - i, k - 1, i)
return result
def dparts(n):
res = 0
k = 2
while k * (k + 1) <= 2 * n:
res += diffparts(n, k, 0)
k += 1
return res
print(dparts(201))
The function f is defined as such:
def f(a, b):
if a <= 0 or b <= 0:
return a + b
else:
s = 0
if b * b % (a + b) != 0:
s += f(a, b - 3)
if a * a % (a + b) != 0:
s += f(a - 2, b)
if a == b - 1:
s += f(a - 3, b - 2)
return s
The question is: "How many times will a function "f" be executed, given f(4, 9)?" For example, for f(0, 0) function "f" will be executed once, since the first time is taken into account as well. Can someone explain to me, how I can find the number of executions? (Examples will be ideal.) Than you in advance!
You can attach an attribute to the function:
def f(a, b):
f.num += 1
if a <= 0 or b <= 0:
...
Result:
>>> f.num = 0
>>> f(0, 0)
0
>>> print(f.num)
1
>>> f.num = 0
>>> f(3, 5)
4
>>> print(f.num)
13
You can increment a global counter, an int wrapped in a list, incrementing it in the function and printing the result after you call it:
i = [0]
def f(a, b):
i[0] += 1
if a <= 0 or b <= 0:
return a + b
else:
s = 0
if b * b % (a + b) != 0:
s += f(a, b - 3)
if a * a % (a + b) != 0:
s += f(a - 2, b)
if a == b - 1:
s += f(a - 3, b - 2)
return s
f(2, 34)
print(i[0])
I don't trust Global variable because of the highly available scope i.e. global variables are accessible to everyone. Instead, you can keep a recursion variable which counts the number of times the function has been called.
def f(a, b, count=0):
count+=1
if a <= 0 or b <= 0:
return [a + b, count]
else:
s = 0
if b * b % (a + b) != 0:
l = f(a, b - 3,count)
s += l[0]
count+=l[1]
if a * a % (a + b) != 0:
l = f(a - 2, b, count)
s += l[0]
count+=l[1]
if a == b - 1:
l = f(a - 3, b - 2, count)
s += l[0]
count+=l[1]
return [s,count]
I'm trying to merge this 2 tuples (t,n), so it returns a tuple that is the sorted combination of t and n.
Can't find what's wrong with this:
def junta(t,n):
a = ()
b = ()
minimo = t[0]
for x in t:
if x < minimo:
minimo = x
a = a + (minimo)
t = t - (minimo)
minimo2 = n[0]
for y in n:
if y < minimo2:
minimo2 = y
b = b + (minimo2)
n = n - (minimo2)
c = a + b
return c
This should do the same as this:
def juntas(a,b):
return tuple(sorted(a+b))
The parenthesis operator has two conflicting meanings: one of them is as a grouping operator. The other one is a tuple creation. (minimo) in your code means evaluate minimo with higher precedence. You want(minimo,) to create a 1-length tuple.
thanks to your answers, i got to a solotion:
def junta(t,n):
a = ()
b = ()
d =()
while len(t)>0:
minimo = t[0]
for x in t:
if x < minimo:
minimo = x
a = a + (minimo,)
minimo_index = t.index(minimo)
t = t[:minimo_index] + t[minimo_index+1:]
while len(n)>0:
minimo2 = n[0]
for y in n:
if y < minimo2:
minimo2 = y
b = b + (minimo2,)
minimo2_index = n.index(minimo2)
n = n[:minimo2_index] + n[minimo2_index+1:]
c = a + b
while len(c)>0:
minimo3 = c[0]
for z in c:
if z < minimo3:
minimo3 = z
d = d + (minimo3,)
minimo3_index = c.index(minimo3)
c = c[:minimo3_index] + c[minimo3_index+1:]
return d