python function to simplify fraction - python-3.x

I am trying to write a function that will help me break down a fraction into simple components like so
I wrote this function
from fractions import Fraction
def lowest_fraction(frac):
num = frac[0]
den = frac[-1]
if frac == (1, den):
yield frac
while frac != (1, den):
new_num = num - num//2
rem = num - new_num
new_frac = Fraction(new_num, den)
frac = (new_frac.numerator, new_frac.denominator)
num = rem
yield frac
I ran the below
for each in [(1, 2), (3, 4), (3, 8), (5, 8), (7, 8), (7, 16), (9, 32)]:
print('{}: '.format(each))
for k in lowest_fraction(each):
print('\t{}'.format(k))
Here's the output
(1, 2):
(1, 2)
(3, 4):
(1, 2)
(1, 4)
(3, 8):
(1, 4)
(1, 8)
(5, 8):
(3, 8)
(1, 8)
(7, 8):
(1, 2)
(1, 4)
(1, 8)
(7, 16):
(1, 4)
(1, 8)
(1, 16)
(9, 32):
(5, 32)
(1, 16)
(1, 32)
You can see that the output for (3, 8) and (9, 32) is not in their simplest form. I think what I want to do can be accomplished by writing a recursive code but I cannot presently write one because I don't fully grab the concept of recursion yet.

Related

Multidirected Graph in NetworkX?

does anyone know how to make a multidirected graph in NetworkX? My problem is, that the node 3 here does not return to node 2 as I wrote in the edgelist... Here is my code:
import networkx as nx
G = nx.MultiDiGraph(directed = True)
G.add_nodes_from(range(1, 11))
edgelist = [(1, 2), (2, 3), (3, 2), (3, 9), (9, 4), (4, 5), (5, 7), (7, 6), (6, 4), (7, 8), (7, 10), (10, 11), (11, 5)]
G = nx.from_edgelist(edgelist)
nx.draw_networkx(G,
with_labels = True,
arrows = True,
arrowstyle = '-|>',
node_size = 100,
node_color = 'yellow',
edge_color = 'black',
width = 3,
arrowsize = 10)
This is the image I get from this code. There should be two edges on node 2 and 3, but there is just one
The G = nx.from_edgelist(edgelist) line uses a constructor that replaces the original object, so it's drawing a standard Graph instead of a multidigraph (but still mimics the arrows since forced in the draw-call).
Try replacing that line with G = nx.from_edgelist(edgelist, create_using = nx.MultiDiGraph()) and you should at least get two arrows drawn on the desired edge. You can also check the output of nx.info(G) to verify the graph type in case you're unsure if it worked.
You also don't need the initial variables as the constructor handles that as well. Minimal code to get this working:
import networkx as nx
edgelist = [(1, 2), (2, 3), (3, 2), (3, 9), (9, 4), (4, 5), (5, 7), (7, 6), (6, 4), (7, 8), (7, 10), (10, 11), (11, 5)]
G = nx.from_edgelist(edgelist, create_using = nx.MultiDiGraph())
nx.draw_networkx(G,
with_labels = True,
arrows = True,
arrowstyle = '-|>',
node_size = 100,
node_color = 'yellow',
edge_color = 'black',
width = 3,
arrowsize = 10)

Find coordinates that are outside a radius

I'm a beginner with Python. I need to get the number of arrows (points) that are outside the radius. I do know what the answer is, but how do I get that output in Python?
This is what I have:
points = [(4, 5), (-0, 2), (4, 7), (1, -3), (3, -2), (4, 5), (3, 2), (5, 7), (-5, 7), (2, 2), (-4, 5), (0, -2),(-4, 7), (-1, 3), (-3, 2), (-4, -5), (-3, 2), (5, 7), (5, 7), (2, 2), (9, 9), (-8, -9)]
center = (0,0)
radius = 9
You could use a list comprehension:
import math
points = [(4, 5), (-0, 2), (4, 7), (1, -3), (3, -2), (4, 5), (3, 2), (5, 7),
(-5, 7), (2, 2), (-4, 5), (0, -2), (-4, 7), (-1, 3), (-3, 2), (-4, -5),
(-3, 2), (5, 7), (5, 7), (2, 2), (9, 9), (-8, -9)]
center = (0, 0)
radius = 9
points_outside_radius = [
p
for p in points
if math.sqrt((p[0] - center[0]) ** 2 + (p[1] - center[1]) ** 2) > radius
]
num_points_outside_radius = len(points_outside_radius)
print(f'There are {num_points_outside_radius} points outside the radius:')
print(points_outside_radius)
Output:
There are 2 points outside the radius:
[(9, 9), (-8, -9)]
Note I used the full euclidian distance formula in case you need to change the center to something other than the origin.

Create co-occurrence matrix from edges of the graph

I have graphs with parallels edges(more than one edges) as shown below
G=nx.read_edgelist('file.txt',create_using=nx.MultiGraph(), nodetype=int)
Example output
(1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 2), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 3), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4), (1, 4)
now here I want to create the co-occurrence matrix from this graph
example output
1 2 3 4
1 0 13 17 24
2 13 0
etc
How can i do so? Most of the solutions from stack overflow are for word co-occurrence
Any help will be much appreciated
You could use the Counter from the collections module:
from collections import Counter
G = ...
cocounts = Counter(list(G.edges()))
# Then just allocate a list (2x4) or something and create the matrix:
res = [[0 for c in range(4)] for r in range(2)]
for cocount, count in cocounts.items():
res[cocount[0]-1][cocount[1]-1] = count

Connectivity between two items having an intermediate item as the connection in python

This is the code that i have written which basically describes the flight connectivity having one city in common between the source and the destination. It seems right for most of the test cases but isn't satisfying this particular one.
def onehop(lis):
hop=[]
for (i,j) in lis:
for (k,l) in lis:
if i==k and j!=l:
return sorted(lis)
if (i!=k and j!=l)and(i==l or j==k) and (((i,j) not in hop) and ((k,l) not in hop)):
m=lis.pop(lis.index((i,j)))
n=lis.pop(lis.index((k,l)))
hop.extend([m,n])
for i in range(len(hop)):
if hop[i][0]>hop[i][1]:
hop[i]=(hop[i][1],hop[i][0])
ans=sorted(hop,key=lambda item: (item[0],item[1]))
return ans
onehop([(2,3),(1,2),(3,1),(1,3),(3,2),(2,4),(4,1)])
Output I expected:
[(1, 2), (1, 3), (1, 4), (2, 1), (3, 2), (3, 4), (4, 2), (4, 3)]
Output I obtained:
[(1, 2), (1, 3), (2, 3), (2, 4), (3, 1), (3, 2), (4, 1)]
def onehop(lis):
hop=[]
for (i,j) in lis:
for (k,l) in lis:
if j==k and i!=l :
hop.append([i,l])
unique = [list(x) for x in set(tuple(x) for x in hop)]
ans=sorted(unique,key=lambda item: (item[0],item[1]))
ans1 = [tuple(l) for l in ans]
return(ans1)

Python: Split list into list of lists

Suppose that I have list:
list = [(4, 7), (3, 7), (5, 7), (4, 6), (4, 8), (2, 7), (3, 6), (3, 8), (6, 7)]
That I want to divide the list into sublists of lengths: [2, 3, 4] (these lengths can vary)
To produce: sublist_list = [[(4, 7), (3, 7)],[(5, 7), (4, 6), (4, 8)], [(2, 7), (3, 6), (3, 8), (6, 7)]]
What's the quickest way that I can do this? Thanks in advance.
myList = [(4, 7), (3, 7), (5, 7), (4, 6), (4, 8), (2, 7), (3, 6), (3, 8), (6, 7)]
listOfLengths = [2, 3, 4]
def getSublists(listOfLengths,myList):
listOfSublists = []
for i in range(0,len(listOfLengths)):
if i == 0:
listOfSublists.append(myList[:listOfLengths[i]])
else:
listOfSublists.append(myList[listOfLengths[i-1]:listOfLengths[i-1]+listOfLengths[i]])
return listOfSublists
Then if you call getSublists on your myList (original list input) and listOfLengths (a list containing the length of your sublists), you get
#In: getSublists(listOfLengths,myList)
#Out: [[(4, 7), (3, 7)], [(5, 7), (4, 6), (4, 8)], [(4, 6), (4, 8), (2, 7), (3, 6)]]
You can user list[i:j] feature in python which returns a new list contains
list[i] to list[j-1] elements of original list.
base = 0
Lengths =[] #list of lengths
for num in Length:
sub_list.append(List[base:num+base])
base += num #jump to next length
What about simply iterating the list and appending to the new lists?
c = 0
for sublist in list:
sublistlist[len(sublistlist)-1].append(sublist)
c += 1
if c % 2:
sublistlist.append([])

Resources