knit-graphs 0.0.10__py3-none-any.whl → 0.0.11__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
knit_graphs/Loop.py CHANGED
@@ -3,6 +3,7 @@
3
3
  This module defines the Loop class which represents individual loops in a knitting pattern.
4
4
  Loops are the fundamental building blocks of knitted structures and maintain relationships with parent loops, yarn connections, and float positions.
5
5
  """
6
+
6
7
  from __future__ import annotations
7
8
 
8
9
  from typing import TYPE_CHECKING
@@ -225,7 +226,7 @@ class Loop:
225
226
  """
226
227
  return self.loop_id
227
228
 
228
- def __eq__(self, other: Loop) -> bool:
229
+ def __eq__(self, other: object) -> bool:
229
230
  """Check equality with another base loop based on loop_id and type.
230
231
 
231
232
  Args:
@@ -234,7 +235,7 @@ class Loop:
234
235
  Returns:
235
236
  bool: True if both loops have the same class and loop_id, False otherwise.
236
237
  """
237
- return isinstance(other, other.__class__) and self.loop_id == other.loop_id
238
+ return isinstance(other, Loop) and isinstance(other, other.__class__) and self.loop_id == other.loop_id
238
239
 
239
240
  def __lt__(self, other: Loop | int) -> bool:
240
241
  """Compare loop_id with another loop or integer for ordering.
@@ -2,6 +2,7 @@
2
2
 
3
3
  This module defines the Pull_Direction enumeration which represents the two ways a loop can be pulled through other loops in knitting: from back to front (knit) or from front to back (purl).
4
4
  """
5
+
5
6
  from __future__ import annotations
6
7
 
7
8
  from enum import Enum
@@ -13,6 +14,7 @@ class Pull_Direction(Enum):
13
14
  This enumeration represents the two directions that yarn can be pulled through loops to create different stitch types.
14
15
  BtF (Back to Front) creates knit stitches, while FtB (Front to Back) creates purl stitches.
15
16
  """
17
+
16
18
  BtF = "Knit"
17
19
  FtB = "Purl"
18
20
 
knit_graphs/Yarn.py CHANGED
@@ -3,10 +3,12 @@
3
3
  This module contains the Yarn class and Yarn_Properties dataclass which together represent the physical yarn used in knitting patterns.
4
4
  The Yarn class manages the sequence of loops along a yarn and their floating relationships.
5
5
  """
6
+
6
7
  from __future__ import annotations
7
8
 
9
+ from collections.abc import Iterator
8
10
  from dataclasses import dataclass
9
- from typing import TYPE_CHECKING, Iterator, cast
11
+ from typing import TYPE_CHECKING, cast
10
12
 
11
13
  from networkx import DiGraph, dfs_edges, dfs_preorder_nodes
12
14
 
@@ -22,6 +24,7 @@ class Yarn_Properties:
22
24
 
23
25
  This frozen dataclass contains all the physical and visual properties that characterize a yarn, including its structure, weight, and appearance.
24
26
  """
27
+
25
28
  name: str = "yarn" # name (str): The name or identifier for this yarn type.
26
29
  plies: int = 2 # plies (int): The number of individual strands twisted together to form the yarn.
27
30
  weight: float = 28 # weight (float): The weight category or thickness of the yarn.
@@ -52,7 +55,7 @@ class Yarn_Properties:
52
55
  """
53
56
  return Yarn_Properties()
54
57
 
55
- def __eq__(self, other: Yarn_Properties) -> bool:
58
+ def __eq__(self, other: object) -> bool:
56
59
  """Check equality with another Yarn_Properties instance.
57
60
 
58
61
  Args:
@@ -61,7 +64,13 @@ class Yarn_Properties:
61
64
  Returns:
62
65
  bool: True if all properties (name, plies, weight, color) are equal, False otherwise.
63
66
  """
64
- return self.name == other.name and self.plies == other.plies and self.weight == other.weight and self.color == other.color
67
+ return (
68
+ isinstance(other, Yarn_Properties)
69
+ and self.name == other.name
70
+ and self.plies == other.plies
71
+ and self.weight == other.weight
72
+ and self.color == other.color
73
+ )
65
74
 
66
75
  def __hash__(self) -> int:
67
76
  """Get hash value for use in sets and dictionaries.
@@ -82,10 +91,15 @@ class Yarn:
82
91
  loop_graph (DiGraph): The directed graph loops connected by yarn-wise float edges.
83
92
  properties (Yarn_Properties): The physical and visual properties of this yarn.
84
93
  """
94
+
85
95
  FRONT_LOOPS: str = "Front_Loops"
86
96
  _BACK_LOOPS: str = "Back_Loops"
87
97
 
88
- def __init__(self, yarn_properties: None | Yarn_Properties = None, knit_graph: None | Knit_Graph = None):
98
+ def __init__(
99
+ self,
100
+ yarn_properties: None | Yarn_Properties = None,
101
+ knit_graph: None | Knit_Graph = None,
102
+ ):
89
103
  """Initialize a yarn with the specified properties and optional knit graph association.
90
104
 
91
105
  Args:
@@ -304,7 +318,7 @@ class Yarn:
304
318
  KeyError: The given loop does not exist in the yarn.
305
319
  """
306
320
  if loop not in self:
307
- raise KeyError(f'Loop {loop} does not exist on yarn {self}.')
321
+ raise KeyError(f"Loop {loop} does not exist on yarn {self}.")
308
322
  prior_loop = self.prior_loop(loop)
309
323
  next_loop = self.next_loop(loop)
310
324
  if isinstance(prior_loop, Loop) and isinstance(next_loop, Loop): # Loop is between two floats to be merged.
@@ -313,7 +327,12 @@ class Yarn:
313
327
  back_of_float_loops = self.get_loops_behind_float(prior_loop, loop)
314
328
  back_of_float_loops.update(self.get_loops_behind_float(loop, next_loop))
315
329
  self.loop_graph.remove_node(loop)
316
- self.loop_graph.add_edge(prior_loop, next_loop, Front_Loops=front_of_float_loops, Back_Loops=back_of_float_loops)
330
+ self.loop_graph.add_edge(
331
+ prior_loop,
332
+ next_loop,
333
+ Front_Loops=front_of_float_loops,
334
+ Back_Loops=back_of_float_loops,
335
+ )
317
336
  for front_loop in front_of_float_loops:
318
337
  front_loop.add_loop_in_front_of_float(prior_loop, next_loop)
319
338
  for back_loop in back_of_float_loops:
@@ -433,8 +452,11 @@ class Yarn:
433
452
  list[tuple[Loop, Loop, set[Loop]]]: List of tuples containing the two loops defining each float and the set of loops positioned in front of that float.
434
453
  Only includes floats that have loops in front of them.
435
454
  """
436
- return [(u, v, self.get_loops_in_front_of_float(u, v)) for u, v in self.edge_iter()
437
- if len(self.get_loops_in_front_of_float(u, v)) > 0]
455
+ return [
456
+ (u, v, self.get_loops_in_front_of_float(u, v))
457
+ for u, v in self.edge_iter()
458
+ if len(self.get_loops_in_front_of_float(u, v)) > 0
459
+ ]
438
460
 
439
461
  def loops_behind_floats(self) -> list[tuple[Loop, Loop, set[Loop]]]:
440
462
  """Get all float segments with loops positioned behind them.
@@ -443,8 +465,11 @@ class Yarn:
443
465
  list[tuple[Loop, Loop, set[Loop]]]: List of tuples containing the two loops defining each float and the set of loops positioned behind that float.
444
466
  Only includes floats that have loops behind them.
445
467
  """
446
- return [(u, v, self.get_loops_behind_float(u, v)) for u, v in self.edge_iter()
447
- if len(self.get_loops_behind_float(u, v)) > 0]
468
+ return [
469
+ (u, v, self.get_loops_behind_float(u, v))
470
+ for u, v in self.edge_iter()
471
+ if len(self.get_loops_behind_float(u, v)) > 0
472
+ ]
448
473
 
449
474
  def __getitem__(self, item: int) -> Loop:
450
475
  """Get a loop by its ID from this yarn.
@@ -2,6 +2,7 @@
2
2
 
3
3
  This module defines the Crossing_Direction enumeration which represents the different ways loops can cross over or under each other in cable knitting patterns.
4
4
  """
5
+
5
6
  from __future__ import annotations
6
7
 
7
8
  from enum import Enum
@@ -13,6 +14,7 @@ class Crossing_Direction(Enum):
13
14
  This enumeration represents the three possible crossing relationships between loops: crossing over to the right, crossing under to the right, or no crossing at all.
14
15
  These directions are fundamental to representing cable structures in knitted fabrics.
15
16
  """
17
+
16
18
  Over_Right = "+"
17
19
  Under_Right = "-"
18
20
  No_Cross = "|"
@@ -2,6 +2,7 @@
2
2
 
3
3
  This module provides the Loop_Braid_Graph class which tracks crossing relationships between loops in cable knitting patterns using a directed graph structure.
4
4
  """
5
+
5
6
  from typing import cast
6
7
 
7
8
  from networkx import DiGraph
@@ -19,6 +20,7 @@ class Loop_Braid_Graph:
19
20
  Attributes:
20
21
  loop_crossing_graph (DiGraph): A NetworkX directed graph storing loop crossing relationships with crossing direction attributes.
21
22
  """
23
+
22
24
  _CROSSING = "crossing"
23
25
 
24
26
  def __init__(self) -> None:
@@ -70,8 +72,11 @@ class Loop_Braid_Graph:
70
72
  if left_loop not in self:
71
73
  return []
72
74
  else:
73
- return [rl for rl in self.loop_crossing_graph.successors(left_loop)
74
- if self.get_crossing(left_loop, rl) is not Crossing_Direction.No_Cross]
75
+ return [
76
+ rl
77
+ for rl in self.loop_crossing_graph.successors(left_loop)
78
+ if self.get_crossing(left_loop, rl) is not Crossing_Direction.No_Cross
79
+ ]
75
80
 
76
81
  def right_crossing_loops(self, right_loop: Loop) -> list[Loop]:
77
82
  """Get all loops that cross with the given loop when it is on the right side.
@@ -85,8 +90,11 @@ class Loop_Braid_Graph:
85
90
  if right_loop not in self:
86
91
  return []
87
92
  else:
88
- return [l for l in self.loop_crossing_graph.predecessors(right_loop)
89
- if self.get_crossing(l, right_loop) is not Crossing_Direction.No_Cross]
93
+ return [
94
+ l
95
+ for l in self.loop_crossing_graph.predecessors(right_loop)
96
+ if self.get_crossing(l, right_loop) is not Crossing_Direction.No_Cross
97
+ ]
90
98
 
91
99
  def get_crossing(self, left_loop: Loop, right_loop: Loop) -> Crossing_Direction:
92
100
  """Get the crossing direction between two loops, creating a no-cross edge if none exists.
@@ -102,4 +110,7 @@ class Loop_Braid_Graph:
102
110
  """
103
111
  if not self.loop_crossing_graph.has_edge(left_loop, right_loop):
104
112
  self.add_crossing(left_loop, right_loop, Crossing_Direction.No_Cross)
105
- return cast(Crossing_Direction, self.loop_crossing_graph[left_loop][right_loop][self._CROSSING])
113
+ return cast(
114
+ Crossing_Direction,
115
+ self.loop_crossing_graph[left_loop][right_loop][self._CROSSING],
116
+ )
@@ -2,9 +2,11 @@
2
2
 
3
3
  This module defines the Wale class which represents a vertical column of stitches in a knitted structure, maintaining the sequence and relationships between loops in that column.
4
4
  """
5
+
5
6
  from __future__ import annotations
6
7
 
7
- from typing import TYPE_CHECKING, Iterator, cast
8
+ from collections.abc import Iterator
9
+ from typing import TYPE_CHECKING, cast
8
10
 
9
11
  from networkx import DiGraph, dfs_preorder_nodes
10
12
 
@@ -26,6 +28,7 @@ class Wale:
26
28
  last_loop (Loop | None): The last (top) loop in the wale sequence.
27
29
  stitches (DiGraph): Stores the directed graph of stitch connections within this wale.
28
30
  """
31
+
29
32
  _PULL_DIRECTION: str = "pull_direction"
30
33
 
31
34
  def __init__(self, first_loop: Loop, knit_graph: Knit_Graph, end_loop: Loop | None = None) -> None:
@@ -60,7 +63,11 @@ class Wale:
60
63
  Args:
61
64
  loop (Loop): The loop to add to the end of the wale.
62
65
  """
63
- self.stitches.add_edge(self.last_loop, loop, pull_direction=self._knit_graph.get_pull_direction(self.last_loop, loop))
66
+ self.stitches.add_edge(
67
+ self.last_loop,
68
+ loop,
69
+ pull_direction=self._knit_graph.get_pull_direction(self.last_loop, loop),
70
+ )
64
71
  self.last_loop = loop
65
72
 
66
73
  def get_stitch_pull_direction(self, u: Loop, v: Loop) -> Pull_Direction:
@@ -91,12 +98,14 @@ class Wale:
91
98
  * The second wale (from split_loop to end). This will be None if the split_loop is not found.
92
99
  """
93
100
  if split_loop in self:
94
- return (Wale(self.first_loop, self._knit_graph, end_loop=split_loop),
95
- Wale(split_loop, self._knit_graph, end_loop=self.last_loop))
101
+ return (
102
+ Wale(self.first_loop, self._knit_graph, end_loop=split_loop),
103
+ Wale(split_loop, self._knit_graph, end_loop=self.last_loop),
104
+ )
96
105
  else:
97
106
  return self, None
98
107
 
99
- def __eq__(self, other: Wale) -> bool:
108
+ def __eq__(self, other: object) -> bool:
100
109
  """
101
110
  Args:
102
111
  other (Wale): The wale to compare.
@@ -104,9 +113,9 @@ class Wale:
104
113
  Returns:
105
114
  bool: True if all the loops in both wales are present and in the same order. False, otherwise.
106
115
  """
107
- if len(self) != len(other):
116
+ if not isinstance(other, Wale) or len(self) != len(other):
108
117
  return False
109
- return not any(l != o for l, o in zip(self, other))
118
+ return not any(l != o for l, o in zip(self, other, strict=False))
110
119
 
111
120
  def __len__(self) -> int:
112
121
  """Get the number of loops in this wale.
@@ -3,6 +3,7 @@
3
3
  This module provides the Wale_Braid class which represents complex cable knitting patterns as mathematical braid structures,
4
4
  using concepts from algebraic topology to model how wales cross over and under each other.
5
5
  """
6
+
6
7
  from knit_graphs.artin_wale_braids.Wale_Braid_Word import Wale_Braid_Word
7
8
  from knit_graphs.artin_wale_braids.Wale_Group import Wale_Group
8
9
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  This module provides the Wale_Braid_Word class which represents a single step in a braid operation, describing how loops cross over each other within a course of knitting.
4
4
  """
5
+
5
6
  from __future__ import annotations
6
7
 
7
8
  from knit_graphs.artin_wale_braids.Crossing_Direction import Crossing_Direction
@@ -59,7 +60,7 @@ class Wale_Braid_Word:
59
60
  new_crossings = {i: ~c for i, c in self.crossings.items()}
60
61
  return Wale_Braid_Word(new_loops, new_crossings)
61
62
 
62
- def __eq__(self, other: Wale_Braid_Word) -> bool:
63
+ def __eq__(self, other: object) -> bool:
63
64
  """Check equality with another wale braid word.
64
65
 
65
66
  Two braid words are equal if they have the same loops in the same order and the same crossing operations at the same indices.
@@ -70,13 +71,13 @@ class Wale_Braid_Word:
70
71
  Returns:
71
72
  bool: True if both braid words have identical loops, loop ordering, and crossing operations, False otherwise.
72
73
  """
73
- if (len(self) != len(other)
74
- or any(l != o for l, o in zip(self.loops, other.loops))
75
- or any(i not in other.crossings for i in self.crossings)
76
- or any(other.crossings[i] != cd for i, cd in self.crossings.items())):
77
- return False
78
- else:
79
- return True
74
+ return (
75
+ isinstance(other, Wale_Braid_Word)
76
+ and len(self) == len(other)
77
+ and all(l == o for l, o in zip(self.loops, other.loops, strict=False))
78
+ and all(i in other.crossings for i in self.crossings)
79
+ and all(other.crossings[i] == cd for i, cd in self.crossings.items())
80
+ )
80
81
 
81
82
  def is_inversion(self, other: Wale_Braid_Word) -> bool:
82
83
  """Check if another braid word is the inverse of this braid word.
@@ -2,6 +2,7 @@
2
2
 
3
3
  This module provides the Wale_Group class which represents a collection of interconnected wales that are joined through decrease operations, forming a tree-like structure of vertical stitch columns.
4
4
  """
5
+
5
6
  from __future__ import annotations
6
7
 
7
8
  from typing import TYPE_CHECKING, cast
@@ -57,14 +58,16 @@ class Wale_Group:
57
58
  for wale in full_wales:
58
59
  u_loops: list[Loop] = cast(list[Loop], wale[:-1])
59
60
  v_loops: list[Loop] = cast(list[Loop], wale[1:])
60
- for u, v in zip(u_loops, v_loops):
61
+ for u, v in zip(u_loops, v_loops, strict=False):
61
62
  self.stitch_graph.add_edge(u, v, pull_direction=self._knit_graph.get_pull_direction(u, v))
62
63
  wales_to_split = full_wales
63
64
  while len(wales_to_split) > 0:
64
65
  wale_to_split = wales_to_split.pop()
65
66
  split = False
66
67
  upper_loops = cast(list[Loop], wale_to_split[1:])
67
- for loop in upper_loops: # skip first loop in each wale as it may be already connected to a discovered decrease.
68
+ for (
69
+ loop
70
+ ) in upper_loops: # skip first loop in each wale as it may be already connected to a discovered decrease.
68
71
  if len(loop.parent_loops) > 1: # Focal of a decrease.
69
72
  clean_wale, remaining_wale = wale_to_split.split_wale(loop)
70
73
  if not self.wale_graph.has_node(clean_wale):
@@ -75,7 +78,7 @@ class Wale_Group:
75
78
  break
76
79
  if not split:
77
80
  self._add_wale(wale_to_split)
78
- for bot_loop, lower_wale in self.bottom_loops.items():
81
+ for _bot_loop, lower_wale in self.bottom_loops.items():
79
82
  if lower_wale.last_loop in self.bottom_loops:
80
83
  self.wale_graph.add_edge(lower_wale, self.bottom_loops[lower_wale.last_loop])
81
84
 
@@ -111,7 +114,7 @@ class Wale_Group:
111
114
  int: The height of the wale group from the base loops to the tallest terminal, measured in total number of loops.
112
115
  """
113
116
  max_len = 0
114
- for bot_loop, wale in self.bottom_loops.items():
117
+ for _bot_loop, wale in self.bottom_loops.items():
115
118
  path_len = sum(len(successor) for successor in dfs_preorder_nodes(self.wale_graph, wale))
116
119
  max_len = max(max_len, path_len)
117
120
  return max_len
@@ -131,7 +134,7 @@ class Wale_Group:
131
134
  Returns:
132
135
  bool: True if the given loop, loop_id (int), or wale is in this group.
133
136
  """
134
- if isinstance(item, Loop) or isinstance(item, int):
137
+ if isinstance(item, (Loop, int)):
135
138
  return item in self.stitch_graph.nodes
136
139
  else: # isinstance(item, Wale):
137
140
  return item in self.wale_graph
@@ -3,6 +3,7 @@
3
3
  This module provides utility functions for creating common knitting patterns and structures as knit graphs.
4
4
  These functions serve as building blocks for testing and demonstration purposes.
5
5
  """
6
+
6
7
  from knit_graphs.artin_wale_braids.Crossing_Direction import Crossing_Direction
7
8
  from knit_graphs.Knit_Graph import Knit_Graph
8
9
  from knit_graphs.Loop import Loop
@@ -69,15 +70,19 @@ def jersey_tube(tube_width: int, height: int) -> Knit_Graph:
69
70
  """Internal helper function to set up float connections between front and back of tube."""
70
71
  front_loops = last_course[0:tube_width]
71
72
  back_loops = last_course[tube_width:]
72
- for first_front, second_front, back in zip(front_loops[0:-1], front_loops[1:], reversed(back_loops)):
73
+ for first_front, second_front, back in zip(
74
+ front_loops[0:-1], front_loops[1:], reversed(back_loops), strict=False
75
+ ):
73
76
  yarn.add_loop_behind_float(back, first_front, second_front)
74
- for (first_back, second_back, front) in zip(back_loops[0:-1], back_loops[1:], reversed(front_loops)):
77
+ for first_back, second_back, front in zip(
78
+ back_loops[0:-1], back_loops[1:], reversed(front_loops), strict=False
79
+ ):
75
80
  yarn.add_loop_in_front_of_float(front, first_back, second_back)
76
81
 
77
82
  _set_tube_floats()
78
83
  for _ in range(0, height):
79
84
  next_course = [yarn.make_loop_on_end() for _p in last_course]
80
- for parent_loop, child_loop in zip(last_course, next_course):
85
+ for parent_loop, child_loop in zip(last_course, next_course, strict=False):
81
86
  knit_graph.connect_loops(parent_loop, child_loop, pull_direction=Pull_Direction.BtF)
82
87
  last_course = next_course
83
88
  _set_tube_floats()
@@ -181,19 +186,44 @@ def lace_mesh(width: int, height: int) -> Knit_Graph:
181
186
  for i, parent_loop in enumerate(reversed(last_course)):
182
187
  child_loop = yarn.make_loop_on_end()
183
188
  if i % 3 == 0: # Just knit every third stitch
184
- knit_graph.connect_loops(parent_loop, child_loop, pull_direction=Pull_Direction.BtF, stack_position=0)
189
+ knit_graph.connect_loops(
190
+ parent_loop,
191
+ child_loop,
192
+ pull_direction=Pull_Direction.BtF,
193
+ stack_position=0,
194
+ )
185
195
  elif i % 6 == 1: # Second of every 6 stitches (0 indexed) is yarn over before a decrease.
186
196
  yo_parent = parent_loop
187
197
  elif i % 6 == 2: # Third of every 6 stitches is bottom of decrease with prior yarn-over's parent
188
- knit_graph.connect_loops(parent_loop, child_loop, pull_direction=Pull_Direction.BtF, stack_position=0)
198
+ knit_graph.connect_loops(
199
+ parent_loop,
200
+ child_loop,
201
+ pull_direction=Pull_Direction.BtF,
202
+ stack_position=0,
203
+ )
189
204
  assert isinstance(yo_parent, Loop)
190
- knit_graph.connect_loops(yo_parent, child_loop, pull_direction=Pull_Direction.BtF, stack_position=1)
205
+ knit_graph.connect_loops(
206
+ yo_parent,
207
+ child_loop,
208
+ pull_direction=Pull_Direction.BtF,
209
+ stack_position=1,
210
+ )
191
211
  elif i % 6 == 4: # Fifth of every six stitches is bottom of decrease with next yarn-over's parent
192
- knit_graph.connect_loops(parent_loop, child_loop, pull_direction=Pull_Direction.BtF, stack_position=0)
212
+ knit_graph.connect_loops(
213
+ parent_loop,
214
+ child_loop,
215
+ pull_direction=Pull_Direction.BtF,
216
+ stack_position=0,
217
+ )
193
218
  prior_child = child_loop
194
219
  elif i % 6 == 5: # The last of six stitches is the top of the prior decrease and new yarn-over
195
220
  assert isinstance(prior_child, Loop)
196
- knit_graph.connect_loops(parent_loop, prior_child, pull_direction=Pull_Direction.BtF, stack_position=1)
221
+ knit_graph.connect_loops(
222
+ parent_loop,
223
+ prior_child,
224
+ pull_direction=Pull_Direction.BtF,
225
+ stack_position=1,
226
+ )
197
227
  next_course.append(child_loop)
198
228
  last_course = next_course
199
229
  # Make a basic jersey course
@@ -226,7 +256,12 @@ def twist_cable(width: int, height: int) -> Knit_Graph:
226
256
  knit_graph, yarn = co_loops(width)
227
257
  last_course = knit_graph.get_courses()[0]
228
258
  next_course = []
229
- pull_directions = [Pull_Direction.FtB, Pull_Direction.BtF, Pull_Direction.BtF, Pull_Direction.FtB]
259
+ pull_directions = [
260
+ Pull_Direction.FtB,
261
+ Pull_Direction.BtF,
262
+ Pull_Direction.BtF,
263
+ Pull_Direction.FtB,
264
+ ]
230
265
  for i, parent_loop in enumerate(reversed(last_course)):
231
266
  child_loop = yarn.make_loop_on_end()
232
267
  knit_graph.connect_loops(parent_loop, child_loop, pull_direction=pull_directions[i % 4])
@@ -244,7 +279,7 @@ def twist_cable(width: int, height: int) -> Knit_Graph:
244
279
  child_loop = next_course[i - 1]
245
280
  knit_graph.connect_loops(parent_loop, child_loop, pull_direction=pull_directions[i % 4])
246
281
  if r % 2 == 1: # cable row
247
- for left_loop, right_loop in zip(next_course[1::4], next_course[2::4]):
282
+ for left_loop, right_loop in zip(next_course[1::4], next_course[2::4], strict=False):
248
283
  knit_graph.add_crossing(left_loop, right_loop, crossing)
249
284
  crossing = ~crossing
250
285
  last_course = next_course
knit_graphs/py.typed ADDED
File without changes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: knit-graphs
3
- Version: 0.0.10
3
+ Version: 0.0.11
4
4
  Summary: A graph representation of knitted structures where each loop is a node and edges represent yarn and stitch relationships.
5
5
  Home-page: https://mhofmann-khoury.github.io/knit_graph/
6
6
  License: MIT
@@ -20,8 +20,9 @@ Classifier: Programming Language :: Python :: 3.11
20
20
  Classifier: Programming Language :: Python :: 3.12
21
21
  Classifier: Programming Language :: Python :: 3.13
22
22
  Classifier: Topic :: Scientific/Engineering
23
+ Classifier: Typing :: Typed
23
24
  Requires-Dist: networkx (>=3.5)
24
- Requires-Dist: plotly (>=6.3.0,<7.0.0)
25
+ Requires-Dist: plotly (>=6.3.0)
25
26
  Project-URL: Documentation, https://mhofmann-khoury.github.io/knit_graph/
26
27
  Project-URL: Repository, https://github.com/mhofmann-Khoury/knit_graph/
27
28
  Description-Content-Type: text/markdown
@@ -17,25 +17,26 @@ docs/source/api/knit_graphs.artin_wale_braids.Wale_Group.rst,sha256=bAGHs3s8dW6l
17
17
  docs/source/api/knit_graphs.artin_wale_braids.rst,sha256=ESKgE9gg830yJ6w5mKuv3MHgH3tMZ-Ee2y3b-bSnU4Y,547
18
18
  docs/source/api/knit_graphs.basic_knit_graph_generators.rst,sha256=OgV2jkEMY0LfRq8v0cNhJUk3fbUOS9VcP8zRv4VBvC4,213
19
19
  docs/source/api/knit_graphs.rst,sha256=w9HIhWI8P0_gG0H_efRUMHYBtWbgCprcS9moclgM_3I,499
20
- docs/source/conf.py,sha256=TZK8Rz0JNgQs2J_cUhVX5_4tmMBvRdGtILJsnAnAFWo,13350
21
- docs/source/index.rst,sha256=D4KmCX1_d2-WrPgxSeggHHsc9-TeQwSUGYOkehRQWrw,1462
20
+ docs/source/conf.py,sha256=qfKxtgms3gNDSoXGpOzWEDMzKJH20ovRMqTC57LkYF4,13282
21
+ docs/source/index.rst,sha256=E82Y_wpDU2hR8w6bSt2k6ZstslCe7u63Ld6ZFgT70RY,1284
22
22
  docs/source/installation.rst,sha256=GyNRk_oXKVgOZ4KFLAgkXLwjHYzDYsx8gcokLRrS0ZI,1247
23
- knit_graphs/Course.py,sha256=hO768vPM0KFRsjCYsBTUgasqMzlvl0gsuSrsBX0UUSs,6280
24
- knit_graphs/Knit_Graph.py,sha256=tzJlHGwIboItz9jg6m6vch4UX3L8vYy2EYNmYpxStkg,12367
25
- knit_graphs/Knit_Graph_Visualizer.py,sha256=s2zp6Z7-ZF_52x3zTx8oQr__tQScpkGthIoWck57ykE,40227
26
- knit_graphs/Loop.py,sha256=zAVz4HtbfBTlihMppcF8E1wWI95bkGjcgQ69o59rdlc,9716
27
- knit_graphs/Pull_Direction.py,sha256=8xRLN-j7V1mExgmt3YjcJcTDa5rLedA2bF4wI8gd-DE,2334
28
- knit_graphs/Yarn.py,sha256=CRTFAA77_v6Z2xg1lhH6DWxRFn2HDokn_L7l_8Lxyc0,18089
23
+ knit_graphs/Course.py,sha256=dcJvWtTYc66iiVpxtYzULDD2ttWuvuGnlahWpWs1wAY,6308
24
+ knit_graphs/Knit_Graph.py,sha256=ys4-oeu23_8yZ8yjun-QngeiErUK0l3F8lnNlg7cB70,12442
25
+ knit_graphs/Knit_Graph_Visualizer.py,sha256=R-iSEEq5_hDi3NLDjP0hVrArrynKUASHs7vA7MAccJg,42108
26
+ knit_graphs/Loop.py,sha256=B1YU6bjTsGYZ8QrBZN52vg1btf7jvzeviCAH-Exrmw8,9747
27
+ knit_graphs/Pull_Direction.py,sha256=3QW_TKEF3fb-Y7I8xDOHHTe6vCYK-ADi3_SDtqr5uSU,2336
28
+ knit_graphs/Yarn.py,sha256=RaU0_At-V6Yk0TGgrRbsKeWJsI4WMoHkZHzUfs7txAE,18391
29
29
  knit_graphs/__init__.py,sha256=qzZAOxTqjgLkhoGnKNZwOkuYbKEyzfWKkKpKkV6lVfk,111
30
- knit_graphs/artin_wale_braids/Crossing_Direction.py,sha256=71ckmEFfL0s25NJb8lfYwH2zku0uM1C5X9gGM7PYC5A,2820
31
- knit_graphs/artin_wale_braids/Loop_Braid_Graph.py,sha256=hmZVe34V6dqfV8_JzuyIUkg2SaznyIZEpr3aDayG-PQ,4876
32
- knit_graphs/artin_wale_braids/Wale.py,sha256=vsM6zvTCLIBKDsX60r19KCJbl1ZGL2ZdINf7AJt0pBI,7109
33
- knit_graphs/artin_wale_braids/Wale_Braid.py,sha256=Ws0QmU7s63nrBKe69acDza-r-LozDyyaKVDNxQMy10Y,2662
34
- knit_graphs/artin_wale_braids/Wale_Braid_Word.py,sha256=4YBlVMUZkqp85r46ETQSbFVS_WrT4PsWthHmFv5Ny9M,4587
35
- knit_graphs/artin_wale_braids/Wale_Group.py,sha256=1RTGIbO_nmyKOBmQzoFcZNsl1sHRG9p4isoUztkI0jY,6665
30
+ knit_graphs/artin_wale_braids/Crossing_Direction.py,sha256=qQCxgsI5L_PMY16bX7_W_C0YG2SKTVcq05RO5eNcZDA,2822
31
+ knit_graphs/artin_wale_braids/Loop_Braid_Graph.py,sha256=A4KoqjBBw8mqvUyzXwCZcwSDDIePtUqgnVVKAWXTa-w,4997
32
+ knit_graphs/artin_wale_braids/Wale.py,sha256=G7Uci5wkE5y7gHGK2bbTpRyswGRSWhVXFxyIUYOprlo,7259
33
+ knit_graphs/artin_wale_braids/Wale_Braid.py,sha256=p2SsFQW6nQZTO89TtCnFSWTWkYAFDm6kykvhb9G7chg,2663
34
+ knit_graphs/artin_wale_braids/Wale_Braid_Word.py,sha256=rY1cB_PpAfz4vFGPh2qUaLf0yNDczk2l6pgxtYA6Sqg,4593
35
+ knit_graphs/artin_wale_braids/Wale_Group.py,sha256=Px-3yxKAUCeqI52IE6t6L2aSCFwgTTsVbN0bWdhQ518,6696
36
36
  knit_graphs/artin_wale_braids/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
- knit_graphs/basic_knit_graph_generators.py,sha256=doDH2MiXbMzGU9b3enEr3KdY8Fw90cssHi_lkts6VpY,11720
38
- knit_graphs-0.0.10.dist-info/LICENSE,sha256=Oazk3oiRu5ZN7b-EdYNYh0vu-I3Av2uIPQ-9L_cZ6Oo,1070
39
- knit_graphs-0.0.10.dist-info/METADATA,sha256=vU8ehebXJzejk8YwClxn5an0V8dhh-8yk631cvq_3Es,5194
40
- knit_graphs-0.0.10.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
41
- knit_graphs-0.0.10.dist-info/RECORD,,
37
+ knit_graphs/basic_knit_graph_generators.py,sha256=x1zHC2PYbzkmjE40xe5_3k2vDsT749L9iufUIfC2QUw,12353
38
+ knit_graphs/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
+ knit_graphs-0.0.11.dist-info/LICENSE,sha256=Oazk3oiRu5ZN7b-EdYNYh0vu-I3Av2uIPQ-9L_cZ6Oo,1070
40
+ knit_graphs-0.0.11.dist-info/METADATA,sha256=I8Kkhsuu02YB0UX9W7Gzwzrq5Y9PrXmWvqo1j8JwUJA,5215
41
+ knit_graphs-0.0.11.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
42
+ knit_graphs-0.0.11.dist-info/RECORD,,