From 4d0e8252ab809e5f7e450d9ae242df372a6bb8ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 11 Sep 2023 00:43:26 +0200 Subject: [PATCH] add check for E221,E222,E227,E228 to the linter and extend it to dev/ (#53) --- .github/workflows/lint.yml | 3 +- dev/DTcodes.py | 45 +++++++++---------- dev/dev_malik/mutation/tangle_patch.py | 31 ++++++------- .../petal_diagram/random_petaluma.py | 16 ++++--- dev/dev_malik/random_knot.py | 19 ++++---- dev/dev_malik/thompson/graphknotter.py | 41 ++++++++--------- dev/old/braidclosure.py | 8 ++-- dev/old/fastalex/exhaust.py | 9 ++-- dev/old/seifert_patch.py | 33 +++++++------- dev/orthogonal/orthogonal.py | 2 +- dev/tangle_patch.py | 40 +++++++++-------- 11 files changed, 131 insertions(+), 116 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index fd05a90..374b070 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -20,7 +20,8 @@ jobs: - name: Run pycodestyle shell: bash -l {0} # We currently only check for some warnings. We should enable & fix more of them. - run: pycodestyle --select=E111,E225,E302,E306,E401,E701,E702,E703,E704,W391,W605,E711,E713,E721 spherogram_src/ + run: pycodestyle --select=E111,E221,E222,E225,E227,E228,E302,E306,E401,E701,E702,E703,E704,W391,W605,E711,E713,E721 spherogram_src/ + run: pycodestyle --select=E111,E221,E222,E225,E227,E228,E306,E401,E701,E702,E703,E704,W391,W605,E711,E713,E721 dev/ - name: Run cython-lint shell: bash -l {0} run: cython-lint . diff --git a/dev/DTcodes.py b/dev/DTcodes.py index 500d8d0..21072fb 100644 --- a/dev/DTcodes.py +++ b/dev/DTcodes.py @@ -144,6 +144,7 @@ def next(self): __next__ = next + class DTFatEdge(FatEdge): """ A fat edge which can be marked and belongs to a link component. @@ -161,17 +162,17 @@ def PD_index(self): This method returns the edge label. """ v = self[0] - if self.slot(v)%2 == 0: + if self.slot(v) % 2 == 0: return v[0] - else: - return v[1] + return v[1] + class DTFatGraph(FatGraph): edge_class = DTFatEdge def __init__(self, pairs=[], singles=[]): FatGraph.__init__(self, pairs, singles) - self.marked_valences = dict( (v,0) for v in self.vertices ) + self.marked_valences = {v: 0 for v in self.vertices} self.stack = [] self.pushed = False @@ -290,7 +291,7 @@ def marked_arc(self, vertex): raise ValueError('Marked graph is a circle') edges = [e for e in self(V) if e.marked and e != edge] if len(edges) == 0: - raise ValueError('Marked graph has a dead end at %s.'%V) + raise ValueError('Marked graph has a dead end at %s.' % V) if len(edges) > 1: break else: @@ -402,7 +403,6 @@ def _boundary_slots(self, edge, side): """ if not edge.marked: raise ValueError('Must begin at a marked edge.') - result = set() first_vertex = vertex = edge[1] while True: end = 0 if edge[0] is vertex else 1 @@ -412,7 +412,7 @@ def _boundary_slots(self, edge, side): interior_edge = self(vertex)[slot] if not interior_edge.marked: # For lookups, slot values must be in 0,1,2,3 - yield vertex, slot%4 + yield vertex, slot % 4 else: break if k == 0: @@ -441,9 +441,8 @@ def flip(self, vertex): Move the edge at the North slot to the South slot, and move the edge in the South slot to the North slot. """ - #print 'flipping %s'%vertex if self.marked_valences[vertex] > 2: - msg = 'Cannot flip %s with marked valence %d.'%( + msg = 'Cannot flip %s with marked valence %d.' % ( vertex, self.marked_valences[vertex]) raise FlippingError(msg) self.reorder(vertex, (North, East, South, West)) @@ -462,7 +461,7 @@ def flipped(self, vertex): Has this vertex been flipped? """ return bool(len([e for e in self(vertex) - if e[1] is vertex and e.slots[1] in (2,3)])%2) + if e[1] is vertex and e.slots[1] in (2, 3)]) % 2) def sign(self, vertex): """ @@ -507,14 +506,14 @@ def KLP_dict(self, vertex, indices): edges = self(vertex) neighbors = self[vertex] strands = [self.KLP_strand(vertex, edge) for edge in edges] - ids = [ indices[v] for v in neighbors ] + ids = [indices[v] for v in neighbors] KLP['sign'] = 'R' if self.sign(vertex) == 1 else 'L' slot = 1 if flipped else 0 KLP['Xbackward_neighbor'] = ids[slot] KLP['Xbackward_strand'] = strands[slot] slot = 3 if flipped else 2 - KLP['Xforward_neighbor'] = ids[slot] + KLP['Xforward_neighbor'] = ids[slot] KLP['Xforward_strand'] = strands[slot] KLP['Xcomponent'] = edges[slot].component slot = 2 if flipped else 1 @@ -568,7 +567,7 @@ def decode(self, dt, flips=None): if dt[:2] == '0x': dt_bytes = [int(dt[n:n+2], 16) for n in range(2,len(dt),2)] self.code, self.flips = self.unpack_signed_DT(dt_bytes) - elif ord(dt[-1]) & 1<<7: + elif ord(dt[-1]) & 1 << 7: dt_bytes = bytearray(dt) self.code, self.flips = self.unpack_signed_DT(dt) else: @@ -628,12 +627,12 @@ def unpack_signed_DT(self, signed_dt): component = [] flips = [] for byte in bytearray(signed_dt): - flips.append(bool(byte & 1<<6)) - label = (1 + byte & 0x1f)<<1 - if byte & 1<<5: + flips.append(bool(byte & 1 << 6)) + label = (1 + byte & 0x1f) << 1 + if byte & 1 << 5: label = -label component.append(label) - if byte & 1<<7: + if byte & 1 << 7: dt.append(tuple(component)) component = [] return dt, flips @@ -642,7 +641,7 @@ def convert_alpha(self, code): code = string_to_ints(code) num_crossings, components = code[:2] comp_lengths = code[2:2+components] - crossings = [x<<1 for x in code[2+components:]] + crossings = [x << 1 for x in code[2+components:]] assert len(crossings) == num_crossings return partition_list(crossings, comp_lengths) @@ -810,20 +809,20 @@ def signed_DT(self): for component in self.code: for label in component: byte = abs(label) - byte = (byte>>1) - 1 + byte = (byte >> 1) - 1 if label < 0: - byte |= 1<<5 + byte |= 1 << 5 if next_flip(): - byte |= 1<<6 + byte |= 1 << 6 code_bytes.append(byte) - code_bytes[-1] |= 1<<7 + code_bytes[-1] |= 1 << 7 return bytes(code_bytes) def hex_signed_DT(self): """ Return the hex encoding of the signed DT byte sequence. """ - return '0x'+''.join('%.2x'%b for b in bytearray(self.signed_DT())) + return '0x' + ''.join('%.2x' % b for b in bytearray(self.signed_DT())) def PD(self, KnotTheory=False): G = self.fat_graph diff --git a/dev/dev_malik/mutation/tangle_patch.py b/dev/dev_malik/mutation/tangle_patch.py index 3c0c5ec..e7a4b39 100644 --- a/dev/dev_malik/mutation/tangle_patch.py +++ b/dev/dev_malik/mutation/tangle_patch.py @@ -46,7 +46,7 @@ def add_random_crossing(self,label): new_strand = randint(0,3) old_crossing[old_strand] = new_crossing[new_strand] for i in range(1,4): - adj.insert(old_position,(new_crossing,(new_strand-i)%4)) + adj.insert(old_position,(new_crossing,(new_strand-i) % 4)) adj[len(adj)/2:] = reversed(adj[len(adj)/2:]) tangle_copy.crossings.append(new_crossing) tangle_copy.n = self.n+1 @@ -299,13 +299,13 @@ def _is_injection(pairs): a strand on the boundary of a tangle and moving to the other end of that strand. """ -def cross_strand(self,i): +def cross_strand(self, i): if i >= 2*self.n: raise Exception("Not a valid start position for strand") cs = self.adjacent[i] strand = [cs] - while (cs[0],(cs[1]+2)%4) not in self.adjacent: - cs = cs[0].adjacent[(cs[1]+2)%4] + while (cs[0], (cs[1] + 2) % 4) not in self.adjacent: + cs = cs[0].adjacent[(cs[1] + 2) % 4] strand.append(cs) return strand @@ -314,11 +314,11 @@ def cross_strand(self,i): """ def loop_strand(cs): strand = [cs] - cs = cs[0].adjacent[(cs[1]+2)%4] + cs = cs[0].adjacent[(cs[1] + 2) % 4] while cs not in strand: # print(strand) strand.append(cs) - cs = cs[0].adjacent[(cs[1]+2)%4] + cs = cs[0].adjacent[(cs[1] + 2) % 4] return strand """ @@ -337,7 +337,7 @@ def all_cross_strands(self): if i not in other_ends_seen: strand = self.cross_strand(i) cs = strand[-1] - end = self.adjacent.index((cs[0],(cs[1]+2)%4)) + end = self.adjacent.index((cs[0],(cs[1]+2) % 4)) if end not in other_ends_seen: strands.append(strand) strands_with_ends.append((strand,end)) @@ -350,7 +350,7 @@ def all_cross_strands(self): for strand in strands: for cs in strand: if cs[0] in seen_once: - loop = loop_strand((cs[0],(cs[1]+1)%4)) + loop = loop_strand((cs[0],(cs[1]+1) % 4)) loops.append(loop) cs_seen.extend(loop) for loop_cs in loop: @@ -370,14 +370,14 @@ def all_cross_strands(self): for loop in loops: for cs in loop: if cs[0] in seen_once: - loop = loop_strand((cs[0],(cs[1]+1)%4)) + loop = loop_strand((cs[0],(cs[1]+1) % 4)) loops.append(loop) cs_seen.extend(loop) for loop_cs in loop: if loop_cs[0] in seen_once: for seen_cs in cs_seen: if loop_cs[0] == seen_cs[0]: - orientation = (loop_cs[1]-seen_cs[1])%4 + orientation = (loop_cs[1]-seen_cs[1]) % 4 if orientation == 3: orientation = -1 orientations[loop_cs[0]] = orientation @@ -413,9 +413,10 @@ def cycle_basis(G): vert_cycles = nx.cycle_basis(Gx) return [edge_cycle(vert_cycle,G) for vert_cycle in vert_cycles] + def is_trivial(four_cycle): crossings = map(lambda x: map(lambda y: y.crossing,x.interface), four_cycle) - return len(set(crossings[0])&set(crossings[1])&set(crossings[2])&set(crossings[3])) != 0 + return bool(len(set(crossings[0]) & set(crossings[1]) & set(crossings[2]) & set(crossings[3]))) def all_four_cycles_at_vertex(G, start_vertex): @@ -813,12 +814,12 @@ def tangle_cut(link, cycle): clear_orientations(crossings0) clear_orientations(crossings1) - #One of the tangles is the 'outside', and needs to be flipped - #Just check side0 + # One of the tangles is the 'outside', and needs to be flipped + # Just check side0 side0_needs_flip = False - c,i = side0[0] + c, i = side0[0] while True: - next_cep = c.crossing_strands()[(i+1)%4] + next_cep = c.crossing_strands()[(i+1) % 4] c,i = next_cep.crossing,next_cep.strand_index # print(c,i) # print(side0) diff --git a/dev/dev_malik/petal_diagram/random_petaluma.py b/dev/dev_malik/petal_diagram/random_petaluma.py index d298806..e05104a 100644 --- a/dev/dev_malik/petal_diagram/random_petaluma.py +++ b/dev/dev_malik/petal_diagram/random_petaluma.py @@ -57,21 +57,23 @@ def petaluma_knot(height_perm): visited_dict[a,b] = True old_crossing = next_crossing - first = crossing_dict[0,1] - last = crossing_dict[size-2,size-1] - first_open = first.adjacent.index(None) #last open spot + first = crossing_dict[0, 1] + last = crossing_dict[size-2, size-1] + first_open = first.adjacent.index(None) # last open spot last_open = last.adjacent.index(None) first[first_open] = last[last_open] return sg.Link(crossing_dict.values()) -def strands_to_cross(size,i): - mid = (size-1)/2 + +def strands_to_cross(size, i): + mid = (size - 1) / 2 L = [] for j in range(mid): - L.insert(0,(i-(2*(j+1)))%size) - L.append( (i+(2*(j+1)))%size ) + L.insert(0, (i-(2*(j+1))) % size) + L.append((i+(2*(j+1))) % size) return L + def permutation(size): L = range(size) random.shuffle(L) diff --git a/dev/dev_malik/random_knot.py b/dev/dev_malik/random_knot.py index 2564eb6..0f8e66d 100644 --- a/dev/dev_malik/random_knot.py +++ b/dev/dev_malik/random_knot.py @@ -30,9 +30,9 @@ def random_knot(n, method='close_under', alternate=False, available = available_strands(loose_cs) strand_to_cross = choice(available) if alternate: - over_or_under = 1-(i%2) + over_or_under = 1 - (i % 2) else: - over_or_under = randint(0,1) + over_or_under = randint(0, 1) loose_cs = cross_strand(crossings, loose_cs, strand_to_cross, str(i+1), over_or_under) same_face = set(available_strands(loose_cs)) == set(available_strands(final_cs)) @@ -57,17 +57,18 @@ def random_open_string(n, alternate=False, bias=False): else: strand_to_cross = choice(available) if alternate: - over_or_under = 1-(i%2) + over_or_under = 1 - (i % 2) else: - over_or_under = randint(0,1) + over_or_under = randint(0, 1) loose_cs = cross_strand(crossings, loose_cs, strand_to_cross, str(i+1), over_or_under) return crossings, loose_cs, final_cs + def bias_middle(start_list): biased_list = [] num_copies = range(len(start_list)/2) - if len(start_list)%2 == 1: + if len(start_list) % 2: num_copies.append(len(start_list)/2) num_copies.extend(reversed(range(len(start_list)/2))) for i, x in enumerate(num_copies): @@ -159,12 +160,13 @@ def function_evolution(n, function, simplify='level', skip_first=0): values.append(open_string_evaluation(crossings, function, simplify)) return values + def turn_list_from_open_string(crossings, loose_cs, final_cs): turn_list = [] while len(crossings) > 1: # print(turn_list) - old_position_crossing, old_position_index = loose_cs.crossing.adjacent[(loose_cs.strand_index-1)%4] - old_crossing_sign = loose_cs.strand_index%2 + old_position_crossing, old_position_index = loose_cs.crossing.adjacent[(loose_cs.strand_index-1) % 4] + old_crossing_sign = loose_cs.strand_index % 2 if old_crossing_sign == 0: old_crossing_sign = -1 else: @@ -480,6 +482,7 @@ def knot_from_turn_list(turn_list): # if c != loose_cs.crossing and c != final_cs.crossing: # c.rotate(randint(0,1)) + def cross_strand(crossings, loose_cs, strand_to_cross, new_label, over_vs_under): opposite = strand_to_cross.opposite() new_crossing = Crossing(new_label) @@ -492,7 +495,7 @@ def cross_strand(crossings, loose_cs, strand_to_cross, new_label, over_vs_under) css = new_crossing.crossing_strands() connect_crossing_strands(css[0+over_vs_under], loose_cs) connect_crossing_strands(css[1+over_vs_under], strand_to_cross) - connect_crossing_strands(css[(3+over_vs_under)%4], opposite) + connect_crossing_strands(css[(3+over_vs_under) % 4], opposite) return css[2+over_vs_under] diff --git a/dev/dev_malik/thompson/graphknotter.py b/dev/dev_malik/thompson/graphknotter.py index 74ddd73..c1ea2cd 100644 --- a/dev/dev_malik/thompson/graphknotter.py +++ b/dev/dev_malik/thompson/graphknotter.py @@ -37,17 +37,16 @@ def faces(G): def link_diagram(G): face_list = faces(G) - #print(face_list) crossing_dict = {} - for edge in G.edges: #create one crossing per edge + for edge in G.edges: # create one crossing per edge l = label(edge) crossing_dict[l] = spherogram.Crossing(l) - for face in face_list: #connect along faces + for face in face_list: # connect along faces for n, direction in enumerate(face): edge = direction[0] - next_edge = face[(n+1)%len(face)][0] + next_edge = face[(n + 1) % len(face)][0] c = crossing_dict[label(edge)] cnext = crossing_dict[label(next_edge)] o = open_overposition(c) @@ -58,7 +57,7 @@ def link_diagram(G): # print(cnext,u) c[o] = cnext[u] - for edge in G.edges: #switch twisted edges + for edge in G.edges: # switch twisted edges c = crossing_dict[label(edge)] if edge.twisted: c.rotate_by_90() @@ -97,19 +96,19 @@ def link_to_fat_graph(link, alternate_around_crossing=False, B = link.black_graph() visited_slots = [] for c in link.crossings: - for i,adj in enumerate(c.adjacent): - if (c.label,i) not in visited_slots: + for i, adj in enumerate(c.adjacent): + if (c.label, i) not in visited_slots: label = str(c.label) adjlabel = str(adj[0].label) if alternate_around_crossing: - G.add_edge((label,i),(adjlabel,adj[1]),i%2) + G.add_edge((label, i), (adjlabel, adj[1]), i % 2) elif alternate_strand: - diff = (i*adj[1])%2 - G.add_edge((label,i),(adjlabel,adj[1]),diff) + diff = (i * adj[1]) % 2 + G.add_edge((label, i), (adjlabel, adj[1]), diff) else: - G.add_edge((label,i),(adjlabel,adj[1]),0) - visited_slots.append((c.label,i)) - visited_slots.append((adj[0].label,adj[1])) + G.add_edge((label, i), (adjlabel, adj[1]), 0) + visited_slots.append((c.label, i)) + visited_slots.append((adj[0].label, adj[1])) return G @@ -256,26 +255,28 @@ def clasp(): return Tangle(2,[c,d],[d2, d3, c3, c2]) -def random_four_connect(link1,link2): +def random_four_connect(link1, link2): from random import choice, sample - css1 = sample(choice(link1.faces()),2) - css2 = sample(choice(link2.faces()),2) - return four_connect(link1,css1,link2,css2) + css1 = sample(choice(link1.faces()), 2) + css2 = sample(choice(link2.faces()), 2) + return four_connect(link1, css1, link2, css2) def find_face_color(e, colors): pair = doubled_edge_to_str_pair(e) for face in colors: - edges = [edge_to_str_pair(edge) for edge,v in face] + edges = [edge_to_str_pair(edge) for edge, v in face] if pair[0] in edges and pair[1] in edges: return colors[face] + def relabel(link): - for i,c in enumerate(link.crossings): + for i, c in enumerate(link.crossings): c.label = i + def cycle(n, signs): G = FatGraph() for i in range(n): - G.add_edge( (str(i),0), (str((i+1)%n),1), signs[i]) + G.add_edge((str(i), 0), (str((i + 1) % n), 1), signs[i]) return G diff --git a/dev/old/braidclosure.py b/dev/old/braidclosure.py index 40dd247..672aacd 100644 --- a/dev/old/braidclosure.py +++ b/dev/old/braidclosure.py @@ -2,16 +2,18 @@ from spherogram import * from sage.all import * + def braid_closure_via_tangles(braid): - n = max(-min(braid),max(braid))+1 + n = max(-min(braid), max(braid)) + 1 l = len(braid) B = IdentityBraid(n) for i in range(l): v = braid[i] - nextpiece = IdentityBraid(abs(v)-1)|RationalTangle(sign(v))|IdentityBraid(n-abs(v)-1) + nextpiece = IdentityBraid(abs(v)-1) | RationalTangle(sign(v)) | IdentityBraid(n-abs(v)-1) B = B*nextpiece return B.braid_closure() + def braid_closure_via_crossings(braid): """ Compute the braid closure of a word given in the form of a list of integers, @@ -23,7 +25,7 @@ def braid_closure_via_crossings(braid): for i in range(l): foundleftstrand = False foundrightstrand = False - j = (i+1)%l + j = (i+1) % l while ((not foundleftstrand) or (not foundrightstrand)): if (not foundleftstrand) and (abs(braid[j]) == abs(braid[i])-1): diff --git a/dev/old/fastalex/exhaust.py b/dev/old/fastalex/exhaust.py index c1bf835..edf6027 100644 --- a/dev/old/fastalex/exhaust.py +++ b/dev/old/fastalex/exhaust.py @@ -90,6 +90,7 @@ def strand_matrix_merge(A, a, b): A = A.delete_columns([j]) return A + def test_meta_associativity(): """ Tests strand_matrix_merge for required invariance properties. @@ -101,10 +102,10 @@ def eval_merges(merges): A = strand_matrix_merge(A, a, b) return A - associative_merges = [ - ([(0,1), (0,1)], [(1,2), (0,1)]), - ([(0,1), (0,2)], [(1,3), (0,1)]), - ([(2,5), (2,3)], [(5,3), (2,3)]) + associative_merges = [ + ([(0, 1), (0, 1)], [(1, 2), (0, 1)]), + ([(0, 1), (0, 2)], [(1, 3), (0, 1)]), + ([(2, 5), (2, 3)], [(5, 3), (2, 3)]) ] for m1, m2 in associative_merges: assert eval_merges(m1) == eval_merges(m2) diff --git a/dev/old/seifert_patch.py b/dev/old/seifert_patch.py index 9dd69b9..46dd840 100644 --- a/dev/old/seifert_patch.py +++ b/dev/old/seifert_patch.py @@ -22,7 +22,7 @@ def seifert_circles(link): def seifert_crossing_entry(crossing_strand): - d = (crossing_strand.strand_index,(crossing_strand.strand_index+2)%4) + d = (crossing_strand.strand_index, (crossing_strand.strand_index + 2) % 4) if d in crossing_strand.crossing.directions: return crossing_strand else: @@ -123,22 +123,23 @@ def isotope_to_braid(link): while remove_admissible_move(link): pass + def is_chain(tree): tails = [e[0] for e in tree] heads = [e[1] for e in tree] - if len(set(tails)) == len(tails) and len(set(heads)) == len(heads): - return True - else: - return False + return len(set(tails)) == len(tails) and len(set(heads)) == len(heads) + + +def connect_head_to_tail(e1, e2): + e1[1] = e1[1] | e2[0] + e2[0] = e1[1] | e2[0] -def connect_head_to_tail(e1,e2): - e1[1] = e1[1]|e2[0] - e2[0] = e1[1]|e2[0] def connect_vertices(e1, v1, e2, v2): e1[v1] = e1[v1] | e2[v2] e2[v2] = e1[v1] | e2[v2] + def braid_word(link): """ Return a list of integers which defines a braid word whose closure is the @@ -147,7 +148,7 @@ def braid_word(link): """ arrows = braid_arrows(link) word = [] - for position, strand,over_or_under in arrows: + for position, strand, over_or_under in arrows: if over_or_under == 0: word.append(-strand-1) else: @@ -188,21 +189,23 @@ def braid_arrows(link): if found_next: break - for i in range(len(ordered_strands)-1): + for i in range(len(ordered_strands) - 1): positions = {} for n, cep in enumerate(ordered_strands[i]): - for m, next_cep in enumerate(ordered_strands[i+1]): + for m, next_cep in enumerate(ordered_strands[i + 1]): if cep.crossing == next_cep.crossing: - positions[n] = ((m,cep.strand_index%2)) + positions[n] = ((m, cep.strand_index % 2)) break positions_in_next_strand.append(positions) ordered_strands = ordered_strands[::-1] - arrows = [[i,positions[i][0],n,positions[i][1]] for n, positions in enumerate(positions_in_next_strand) for i in positions] + arrows = [[i, positions[i][0], n, positions[i][1]] + for n, positions in enumerate(positions_in_next_strand) + for i in positions] straighten_arrows(arrows) - arrows = sorted(arrows,key=lambda x: x[0]) + arrows = sorted(arrows, key=lambda x: x[0]) for arrow in arrows: - arrow.pop(1) #start and end positions are now the same + arrow.pop(1) # start and end positions are now the same return arrows diff --git a/dev/orthogonal/orthogonal.py b/dev/orthogonal/orthogonal.py index 7373faa..bbe59bb 100644 --- a/dev/orthogonal/orthogonal.py +++ b/dev/orthogonal/orthogonal.py @@ -148,7 +148,7 @@ def _add_turns(self): if e0.kind == e1.kind: turns.append(0) else: - t = (e0.tail == v0)^(e1.head == v0)^(e0.kind == 'horizontal') + t = (e0.tail == v0) ^ (e1.head == v0) ^ (e0.kind == 'horizontal') turns.append(-1 if t else 1) rotation = sum(turns) diff --git a/dev/tangle_patch.py b/dev/tangle_patch.py index 7307932..a5b99b9 100644 --- a/dev/tangle_patch.py +++ b/dev/tangle_patch.py @@ -24,22 +24,21 @@ def clear_orientations(crossings): c.sign = 0 -def add_random_crossing(self,label): +def add_random_crossing(self, label): """ Randomly chooses position on boundary of the tangle and splits into a new crossing. """ - tangle_copy = self.copy() adj = tangle_copy.adjacent adj[len(adj)/2:] = reversed(adj[len(adj)/2:]) new_crossing = spherogram.Crossing(label) - old_position = randint(0,len(adj)-1) + old_position = randint(0, len(adj)-1) old_crossing, old_strand = adj.pop(old_position) - new_strand = randint(0,3) + new_strand = randint(0, 3) old_crossing[old_strand] = new_crossing[new_strand] - for i in range(1,4): - adj.insert(old_position,(new_crossing,(new_strand-i)%4)) + for i in range(1, 4): + adj.insert(old_position, (new_crossing, (new_strand-i) % 4)) adj[len(adj)/2:] = reversed(adj[len(adj)/2:]) tangle_copy.crossings.append(new_crossing) tangle_copy.n = self.n+1 @@ -130,6 +129,7 @@ def min_isosig_with_gluings(self, gluings, root=None): Tangle.all_circular_sums = all_circular_sums Tangle.add_random_crossing = add_random_crossing + def cycle_basis(G): """ Uses networkx's cycle basis function on dual graph and converts to @@ -138,14 +138,16 @@ def cycle_basis(G): Gx = G.to_networkx() vert_cycles = nx.cycle_basis(Gx) - return [edge_cycle(vert_cycle,G) for vert_cycle in vert_cycles] + return [edge_cycle(vert_cycle, G) for vert_cycle in vert_cycles] + def is_trivial(four_cycle): """ A trivial four cycle in the dual graph bounds a single quadrilateral """ - crossings = map(lambda x: map(lambda y: y.crossing,x.interface), four_cycle) - return len(set(crossings[0])&set(crossings[1])&set(crossings[2])&set(crossings[3])) != 0 + crossings = map(lambda x: map(lambda y: y.crossing, x.interface), + four_cycle) + return bool(len(set(crossings[0]) & set(crossings[1]) & set(crossings[2]) & set(crossings[3]))) def all_four_cycles_at_vertex(G, start_vertex): @@ -158,7 +160,7 @@ def all_four_cycles_at_vertex(G, start_vertex): new_adj = G.children(v).intersection(G.children(w)) new_adj.remove(start_vertex) for opposite_vertex in new_adj: - for e1 in G.edges_between(start_vertex,v): + for e1 in G.edges_between(start_vertex, v): for e2 in G.edges_between(v, opposite_vertex): for e3 in G.edges_between(opposite_vertex, w): for e4 in G.edges_between(w,start_vertex): @@ -503,27 +505,27 @@ def tangle_cut(link, cycle): crossings0 = [crossing_from_name(link,c) for c in crossing_sides if crossing_sides[c] == 0] crossings1 = [crossing_from_name(link,c) for c in crossing_sides if crossing_sides[c] == 1] - #clear crossing info + # clear crossing info clear_orientations(crossings0) clear_orientations(crossings1) - #One of the tangles is the 'outside', and needs to be flipped - #Just check side0 + # One of the tangles is the 'outside', and needs to be flipped + # Just check side0 side0_needs_flip = False - c,i = side0[0] + c, i = side0[0] while True: - next_cep = c.crossing_strands()[(i+1)%4] - c,i = next_cep.crossing,next_cep.strand_index + next_cep = c.crossing_strands()[(i+1) % 4] + c, i = next_cep.crossing, next_cep.strand_index # print(c,i) # print(side0) - if (c,i) in side0: + if (c, i) in side0: # print('hit_end') # print(c,i) # print(side0[1]) # print((c,i)==side0[1]) - side0_needs_flip = (c,i) != (side0[1]) + side0_needs_flip = (c, i) != (side0[1]) break - c,i = next_cep.opposite().crossing,next_cep.opposite().strand_index + c, i = next_cep.opposite().crossing,next_cep.opposite().strand_index if side0_needs_flip: # print('flipped side 0') flip(side0)