Obtaining the nth iteration of a nested loop? - python-3.x

I have this snippet that 'generates' the centers of figures in my GUI... The probem is that is too slow because the solution iterates too much. So I'm wondering how to implement a generator to take exacle value I need.
from pprint import pprint
def center(i, j):
s = 50
for k, v1 in enumerate(range(int(s / 2), s * 8, s)):
for n, v2 in enumerate(range(int(s / 2), s * 8, s)):
if (i, j) == (k, n):
return (v1, v2)
pprint(center(0,0)) # -> (25, 25)
pprint(center(6,3)) # -> (325, 175)
So I made this generator:
def centerGenerator():
s = 50
for k in range(int(s / 2), s * 8, s):
for n in range(int(s / 2), s * 8, s):
yield k, n
def center(i, j):
for c in centerGenerator():
pass # how to take only c(i,j) from the Generator?
pprint(center(0,0)) # -> (25, 25)
pprint(center(6,3)) # -> (325, 175)
But idk how to implements it. Any thoughts?

Related

NotImplementedError: You must implement the backward function for custom autograd.Function

class Layer(nn.Module):
...
def forward(self,pxo):
p, x, o = pxo # (n,3),(n,in_planes),(b)
n, c = x.shape
npoints = self.npoints
v = self.linear_v(x) # (n, c)
sampling_offsets = self.sampling_offsets(x) # (n,npoints * 3)
sampling_offsets = sampling_offsets.reshape(n * npoints, 3) # (n * npoints, 3)
sampling_offsets /= self.resolution # (n * npoints,3)
sampling_offsets = sampling_offsets.reshape(n, npoints, 3) # (n, npoints, 3)
sampling_positions = (sampling_offsets + p.unsqueeze(dim=1)).reshape(-1, 3) # (n * npoints, 3)
attention_weights = self.attention_weights(x) # (n,npoints)
attention_weights = self.softmax(attention_weights) # (n, npoints)
new_o = o * npoints
v = pointops.interpolation(p, sampling_positions, v, o, new_o).reshape(n,npoints,c)
v = v.transpose(1,2).contiguous() #(n, c, npoints)
h_v = torch.matmul(v, attention_weights.unsqueeze(-1)).reshape(n, c) # (n, nheads * c)
x = self.linear_output(h_v)
return x
Once I use this layer, there will be an error. If I switch to another network, there will be not. I am curious about how this model causes this error?
def interpolation(xyz, new_xyz, feat, offset, new_offset, k=3):
"""
input: xyz: (m, 3), new_xyz: (n, 3), feat: (m, c), offset: (b), new_offset: (b)
output: (n, c)
"""
assert xyz.is_contiguous() and new_xyz.is_contiguous() and feat.is_contiguous()
idx, dist = knnquery(k, xyz, new_xyz, offset, new_offset) # (n, 3), (n, 3)
dist_recip = 1.0 / (dist + 1e-8) # (n, 3)
norm = torch.sum(dist_recip, dim=1, keepdim=True)
weight = dist_recip / norm # (n, 3)
new_feat = torch.cuda.FloatTensor(new_xyz.shape[0], feat.shape[1]).zero_()
for i in range(k):
new_feat += feat[idx[:, i].long(), :] * weight[:, i].unsqueeze(-1)
return new_feat
What I use is nn.CrossEntropyLoss().
I can get the loss, but loss.backward() will report error.

multiples of k below n (recursively)

I don't understand how to make the program as described.
I can do it in a non-generalized form, where I know what k is beforehand, but I don't know how to generalize it.
So if i know k is 7, then i can do it. But if i have to generalize it it doesn't work that way. What I need is a generalized version of what I have below
def multiples(k, n):
"""prints multiples of 7 below 500
"""
if k<=n:
print(k)
k+=7
multiples(k, n)
multiples(7, 500)
You can add a start parameter to your function, which defaults to 0:
def multiples(k, n, start=0):
if (start <= n):
print(start)
start += k
multiples(k, n, start)
multiples(7, 500)
Output:
0
7
14
...
497
You just need to keep track of the original value of k, which you wrote as 7 in your attempt.
I'd add a helper function, and do my recursion with that:
def multiples(k0, n):
def _multiples(k):
if k > n: return []
return [k] + _multiples(k + k0)
return _multiples(0)
print(multiples(7, 500)) # [0, 7, 14, 21, 28, ..., 497]

identifying leaves and ancestors of a tree - Python

I have a tree as shown below:
I need to find leaves such that they have the same ancestor. For an example, in the above tree, we have two nodes with the same ancestor. Can someone suggest me a way to do that?
With the help of those two answers, I tried the following to find the pair of leaves with the common parent and then I need to join those two leaves and update the tree. But, that did not give me the correct pair of leaves and did not update the tree correctly. Can you please find the mistake here and help me with that?
def common_parent(T, n1, n2):
for n1 in N:
for n2 in N:
if T.neighbors(n1) == T.neighbors(n2):
return (n1, n2)
nodes_pairs = []
for n1 in N:
for n2 in N:
if n1 != n2 and common_parent(T, n1,n2):
nodes_pairs.append(common_ancestor(T, n1,n2))
print(nodes_pairs)
for n1 in N:
for n2 in N:
if T.neighbors(n1) == T.neighbors(n2):
T.add_edge(n1, n2, weight='distance')
print(T.edges())
Can be done like that:
import networkx as nx
import matplotlib.pyplot as plt
from collections import defaultdict
G = nx.Graph()
## setup, borrowed from https://necromuralist.github.io/data_science/posts/distance-in-social-networks/
left = tuple("AAKBCCFEDEIE")
right = tuple("KBBCFEGFEIJH")
G.add_edges_from(list(zip(left, right)))
##
# retrieve nodes of degree=1
k1corona = list(nx.k_corona(G, 1))
# and their parents
nodes = { node: list(G[node])[0] for _set in k1corona for node in _set }
# counting leaves for each parent
parents = defaultdict(int)
for node,parent in nodes.items():
parents[parent]+=1
# filtering out loners
leaves = [ node for node,parent in nodes.items() if parents[parent]>=2 ]
# drawing
pos = nx.spring_layout(G,random_state=0)
nx.draw_networkx(G, pos=pos, with_labels=True)
nx.draw_networkx_nodes(G.subgraph(leaves), pos=pos, with_labels=True, node_color='blue')
plt.show()
Find nodes with a common ancestor
create tree
G = nx.balanced_tree(2, 2, create_using=None)
plotting
pos = nx.spring_layout(G)
nx.draw_networkx_nodes(G, pos)
nx.draw_networkx_edges(G,pos)
nx.draw_networkx_labels(G,pos, font_color='w')
plt.axis('off')
plt.show()
def common_ancestor(G, n1, n2):
if nx.shortest_path_length(G, n1, n2) == 2:
return (n1, n2)
nodes_pairs = []
for n1 in G.nodes():
for n2 in G.nodes():
if n1 != n2 and common_ancestor(G, n1,n2):
nodes_pairs.append(common_ancestor(G, n1,n2))
nodes_pairs
[out]:
[(0, 3),
(0, 4),
(0, 5),
(0, 6),
(1, 2),
(2, 1),
(3, 0),
(3, 4),
(4, 0),
(4, 3),
(5, 0),
(5, 6),
(6, 0),
(6, 5)]

How to use exponents under special criteria

I am new to python and was trying to find a way to organize a specific function so I can take a list, apply special criteria to it, and then return another list.
I want to:
1) square a number if it is even
2) cube a number if it is odd
3) and then store those results in a list and return that list
Here is my code:
def square_function(x):
if i % 2 == 0:
x = [i ** (2)]
else:
y = [i ** (3)]
func = [x, y]
return func
I am very new to programming with python so any help you can give would be fantastic.
take a list - apply special criteria to it - and then return another list.
You're looking for the map() function
def foo(x):
return x**2 if x%2==0 else x**3
l = [1,2,3]
I = list(map(foo, l))
Using list comprehension:
>>> a = [1,2,3,4,5]
>>> [x ** 2 if x % 2 == 0 else x ** 3 for x in a]
[1, 4, 27, 16, 125]
I think that this could be what you are looking for:
from math import sqrt
def square_or_cube_function(x):
result = []
for i in x:
if i % 2 == 0:
result.append(sqrt(i))
else:
result.append(i ** 3)
return result
print(square_or_cube_function([1, 4, 5, 8]))
print(square_or_cube_function([5, 7, 16, 32]))
OUTPUT:
[1, 2.0, 125, 2.8284271247461903]
[125, 343, 4.0, 5.656854249492381]
A shorter solution could be:
from math import sqrt
def square_or_cube_function(x):
return [sqrt(i) if i % 2 == 0 else i **3 for i in x]
print(square_or_cube_function([1, 4, 5, 8]))
print(square_or_cube_function([5, 7, 16, 32]))
Same output.
Another LC solution, but using a bit of cleverness:
[x ** (x % 2 + 2) for x in L]

Getting the wrong output (Ramanujan)

Essentially what I want the function to do is this:
Take an integer input and save it as n
Print a list of vectors with two entries (a,b), where
For example, when I input n = 443889, I should get an output of [(76,17),(38,73)], because the only two solutions to this problem are: , and
But with my code, when I give the input n=443889, I get the output [(76, 17), (75, 28), (74, 34), (73, 38), (72, 41)], even though some of these vectors doesn't give a solution to my equation.
def ramanujans(n):
lista = []
counter = 0
for a in range(1,n):
b = (n- (a**3))**(1/3)
result = a**3 + b**3
if isinstance(b,complex):
break
elif result == n:
b = int(round(b))
lista.insert(0,(a, b))
return (lista)
with a little different checking for complex results and a different check if result == n (integer comparison only) i seem to be getting the correct results:
def ramanujans(n):
res = []
for a in range(1, n):
s = n - a**3
if s < 0:
break
b = round(s**(1/3))
result = a**3 + b**3
if result == n:
res.append((a, b))
return res
with:
[(17, 76), (38, 73), (73, 38), (76, 17)]
as results for n=443889
you could stop the loop earlier; if a is around (n/2)**(1/3) you just get the results you already have with the a and b interchanged; this could then look like (did not carefully check the edge cases...):
from math import ceil
def ramanujans(n):
res = []
limit = ceil(((n/2)**(1/3)))
for a in range(1, limit+1):
s = n - a**3
b = round(s**(1/3))
result = a**3 + b**3
if result == n:
if a <= b: # this is to cover the edge cases...
res.append((a, b))
return res
print(ramanujans(n=443889)) # [(17, 76), (38, 73)]
print(ramanujans(n=2000)) # [(10, 10)]
print(ramanujans(n=1729)) # [(1, 12), (9, 10)]
and would only return 'half' the results.

Resources