knit-graphs 0.0.5__py3-none-any.whl → 0.0.7__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.
Files changed (33) hide show
  1. knit_graphs-0.0.5.dist-info/licenses/LICENSE → LICENSE +21 -21
  2. README.md +75 -0
  3. docs/Makefile +20 -0
  4. docs/make.bat +35 -0
  5. docs/source/api/knit_graphs.artin_wale_braids.rst +58 -0
  6. docs/source/api/knit_graphs.rst +74 -0
  7. docs/source/conf.py +335 -0
  8. docs/source/index.rst +71 -0
  9. docs/source/installation.rst +67 -0
  10. knit_graphs/Course.py +156 -104
  11. knit_graphs/Knit_Graph.py +249 -186
  12. knit_graphs/Knit_Graph_Visualizer.py +680 -0
  13. knit_graphs/Loop.py +141 -155
  14. knit_graphs/Pull_Direction.py +68 -23
  15. knit_graphs/Yarn.py +424 -267
  16. knit_graphs/__init__.py +3 -3
  17. knit_graphs/_base_classes.py +173 -0
  18. knit_graphs/artin_wale_braids/Crossing_Direction.py +74 -15
  19. knit_graphs/artin_wale_braids/Loop_Braid_Graph.py +95 -62
  20. knit_graphs/artin_wale_braids/Wale.py +169 -93
  21. knit_graphs/artin_wale_braids/Wale_Braid.py +50 -30
  22. knit_graphs/artin_wale_braids/Wale_Braid_Word.py +99 -54
  23. knit_graphs/artin_wale_braids/Wale_Group.py +136 -88
  24. knit_graphs/{knit_graph_generators/basic_knit_graph_generators.py → basic_knit_graph_generators.py} +302 -248
  25. knit_graphs-0.0.7.dist-info/LICENSE +21 -0
  26. {knit_graphs-0.0.5.dist-info → knit_graphs-0.0.7.dist-info}/METADATA +33 -25
  27. knit_graphs-0.0.7.dist-info/RECORD +29 -0
  28. {knit_graphs-0.0.5.dist-info → knit_graphs-0.0.7.dist-info}/WHEEL +1 -1
  29. knit_graphs/__about__.py +0 -4
  30. knit_graphs/knit_graph_generators/__init__.py +0 -0
  31. knit_graphs/knit_graph_visualizer/Stitch_Visualizer.py +0 -427
  32. knit_graphs/knit_graph_visualizer/__init__.py +0 -0
  33. knit_graphs-0.0.5.dist-info/RECORD +0 -22
docs/source/index.rst ADDED
@@ -0,0 +1,71 @@
1
+ knit-graphs
2
+ ===========
3
+
4
+ A graph representation of knitted structures where each loop is a node and edges represent yarn and stitch relationships.
5
+
6
+ .. image:: https://img.shields.io/github/workflow/status/mhofmann-Khoury/knit-graphs/CI
7
+ :target: https://github.com/mhofmann-Khoury/knit-graphs/actions
8
+ :alt: Build Status
9
+
10
+ .. image:: https://img.shields.io/pypi/v/knit-graphs
11
+ :target: https://pypi.org/project/knit-graphs/
12
+ :alt: PyPI Version
13
+
14
+ .. image:: https://img.shields.io/pypi/pyversions/knit-graphs
15
+ :target: https://pypi.org/project/knit-graphs/
16
+ :alt: Python Versions
17
+
18
+ Quick Start
19
+ -----------
20
+
21
+ Installation
22
+ ~~~~~~~~~~~~
23
+
24
+ Install from PyPI:
25
+
26
+ .. code-block:: bash
27
+
28
+ pip install knit-graphs
29
+
30
+ Or install from source:
31
+
32
+ .. code-block:: bash
33
+
34
+ git clone https://github.com/mhofmann-Khoury/knit-graphs.git
35
+ cd your-repo
36
+ poetry install
37
+
38
+ Documentation Contents
39
+ ----------------------
40
+
41
+ .. toctree::
42
+ :maxdepth: 2
43
+ :caption: User Guide
44
+
45
+ installation
46
+
47
+
48
+ .. toctree::
49
+ :maxdepth: 4
50
+ :caption: API Reference
51
+
52
+ api/knit_graphs
53
+
54
+ Support and Community
55
+ ---------------------
56
+
57
+ * **GitHub Repository**: https://github.com/mhofmann-Khoury/knit-graphs
58
+ * **Issue Tracker**: https://github.com/mhofmann-Khoury/knit-graphs/issues
59
+ * **PyPI Package**: https://pypi.org/project/knit-graphs/
60
+
61
+ License
62
+ -------
63
+
64
+ This project is licensed under the MIT License.
65
+
66
+ Indices and tables
67
+ ==================
68
+
69
+ * :ref:`genindex`
70
+ * :ref:`modindex`
71
+ * :ref:`search`
@@ -0,0 +1,67 @@
1
+ Installation
2
+ ============
3
+
4
+ Requirements
5
+ ------------
6
+
7
+ * Python 3.11 or higher
8
+ * pip or Poetry package manager
9
+ * networkx for Graph data structures.
10
+ * plotly for Knit Graph visualization
11
+
12
+ Install from PyPI
13
+ -----------------
14
+
15
+ The easiest way to install the package is from PyPI:
16
+
17
+ .. code-block:: bash
18
+
19
+ pip install knit-graphs
20
+
21
+ Or using Poetry:
22
+
23
+ .. code-block:: bash
24
+
25
+ poetry add knit-graphs
26
+
27
+ Install from Source
28
+ -------------------
29
+
30
+ To install the latest development version from source:
31
+
32
+ .. code-block:: bash
33
+
34
+ git clone https://github.com/mhofmann-Khoury/knit-graphs.git
35
+ cd your-repo
36
+ pip install -e .
37
+
38
+ Or with Poetry:
39
+
40
+ .. code-block:: bash
41
+
42
+ git clone https://github.com/mhofmann-Khoury/knit-graphs.git
43
+ cd your-repo
44
+ poetry install
45
+
46
+ Development Installation
47
+ ------------------------
48
+
49
+ For development and contributing:
50
+
51
+ .. code-block:: bash
52
+
53
+ git clone https://github.com/mhofmann-Khoury/knit-graphs.git
54
+ cd your-repo
55
+ poetry install --with dev,docs
56
+
57
+ This installs the package with all development dependencies including testing and documentation tools.
58
+
59
+ Verify Installation
60
+ -------------------
61
+
62
+ To verify the installation worked correctly:
63
+
64
+ .. code-block:: python
65
+
66
+ import knit-graphs
67
+ print(knit-graphs.__version__)
knit_graphs/Course.py CHANGED
@@ -1,104 +1,156 @@
1
- """Course representation of a section of knitting with no parent loops."""
2
- from knit_graphs.Loop import Loop
3
-
4
-
5
- class Course:
6
- """
7
- Course object for organizing loops into knitting rows
8
- """
9
-
10
- def __init__(self):
11
- self.loops_in_order: list[Loop] = []
12
- self._loop_set: dict[Loop, Loop] = {}
13
-
14
- def add_loop(self, loop: Loop, index: int | None = None):
15
- """
16
- Add the loop at the given index or to the end of the course
17
- :param loop: loop to add
18
- :param index: index to insert at or None if adding to end
19
- """
20
- for parent_loop in loop.parent_loops:
21
- assert parent_loop not in self, f"{loop} has parent {parent_loop}, cannot be added to same course"
22
- self._loop_set[loop] = loop
23
- if index is None:
24
- self.loops_in_order.append(loop)
25
- else:
26
- self.loops_in_order.insert(index, loop)
27
-
28
- def has_increase(self) -> bool:
29
- """
30
- :return: True if course has at least one yarn over to start new wales.
31
- """
32
- for loop in self:
33
- if not loop.has_parent_loops(): # Yarn over
34
- return True
35
- return False
36
-
37
- def has_decrease(self) -> bool:
38
- """
39
- :return: True if course has at least one decrease, merging two wales
40
- """
41
- for loop in self:
42
- if len(loop.parent_loops) > 1:
43
- return True
44
- return False
45
-
46
- def has_terminal_loop(self, knit_graph) -> bool:
47
- """\
48
- :param knit_graph: Knit graph to get child loop data from
49
- :return: True if this course contains a terminal loop with no child
50
- """
51
- for loop in self:
52
- if knit_graph.get_child_loop(loop) is None:
53
- return True
54
- return False
55
-
56
- def __getitem__(self, index: int | slice) -> Loop | list[Loop]:
57
- return self.loops_in_order[index]
58
-
59
- def index(self, loop: Loop) -> int:
60
- """
61
- Searches for index of given loop_id
62
- :param loop: loop_id or loop to find
63
- :return: index of the loop_id
64
- """
65
- return self.loops_in_order.index(loop)
66
-
67
- def in_round_with(self, next_course) -> bool:
68
- """
69
- :param next_course: another course who should follow this course
70
- :return: True if the next course starts at the beginning of this course
71
- """
72
- next_start = next_course[0]
73
- i = 1
74
- while not next_start.has_parent_loops():
75
- next_start = next_course[i]
76
- i += 1
77
- return self[0] in next_start.parent_loops
78
-
79
- def in_row_with(self, next_course) -> bool:
80
- """
81
- :param next_course: another course that should follow this course.
82
- :return: True if the next course starts at the end of this course.
83
- """
84
- next_start = next_course[0]
85
- i = 1
86
- while not next_start.has_parent_loops():
87
- next_start = next_course[i]
88
- i += 1
89
- return self[-1] in next_start.parent_loops
90
-
91
- def __contains__(self, loop: Loop) -> bool:
92
- return loop in self._loop_set
93
-
94
- def __iter__(self):
95
- return self.loops_in_order.__iter__()
96
-
97
- def __len__(self):
98
- return len(self.loops_in_order)
99
-
100
- def __str__(self):
101
- return str(self.loops_in_order)
102
-
103
- def __repr__(self):
104
- return str(self)
1
+ """Course representation of a section of knitting with no parent loops.
2
+
3
+ This module contains the Course class which represents a horizontal row of loops in a knitting pattern.
4
+ """
5
+ from __future__ import annotations
6
+
7
+ from typing import Iterator, cast
8
+
9
+ from knit_graphs._base_classes import _Base_Knit_Graph
10
+ from knit_graphs.Loop import Loop
11
+
12
+
13
+ class Course:
14
+ """Course object for organizing loops into knitting rows.
15
+
16
+ A Course represents a horizontal row of loops in a knitting pattern.
17
+ It maintains an ordered list of loops and provides methods for analyzing the structure and relationships between courses in the knitted fabric.
18
+ """
19
+
20
+ def __init__(self, _knit_graph: _Base_Knit_Graph) -> None:
21
+ """Initialize an empty course associated with a knit graph.
22
+
23
+ Args:
24
+ _knit_graph (Knit_Graph): The knit graph that this course belongs to.
25
+ """
26
+ self.loops_in_order: list[Loop] = []
27
+ self._loop_set: set[Loop] = set()
28
+
29
+ def add_loop(self, loop: Loop, index: int | None = None) -> None:
30
+ """Add a loop to the course at the specified index or at the end.
31
+
32
+ Args:
33
+ loop (Loop): The loop to add to this course.
34
+ index (int | None, optional): The index position to insert the loop at. If None, appends to the end.
35
+ """
36
+ for parent_loop in loop.parent_loops:
37
+ assert parent_loop not in self, f"{loop} has parent {parent_loop}, cannot be added to same course"
38
+ self._loop_set.add(loop)
39
+ if index is None:
40
+ self.loops_in_order.append(loop)
41
+ else:
42
+ self.loops_in_order.insert(index, loop)
43
+
44
+ def has_increase(self) -> bool:
45
+ """Check if this course contains any yarn overs that start new wales.
46
+
47
+ Returns:
48
+ bool: True if the course has at least one yarn over (loop with no parent loops) to start new wales.
49
+ """
50
+ return any(not loop.has_parent_loops() for loop in self)
51
+
52
+ def has_decrease(self) -> bool:
53
+ """Check if this course contains any decrease stitches that merge wales.
54
+
55
+ Returns:
56
+ bool: True if the course has at least one decrease stitch (loop with multiple parent loops) merging two or more wales.
57
+ """
58
+ return any(len(loop.parent_loops) > 1 for loop in self)
59
+
60
+ def __getitem__(self, index: int | slice) -> Loop | list[Loop]:
61
+ """Get loop(s) at the specified index or slice.
62
+
63
+ Args:
64
+ index (int | slice): The index or slice to retrieve from the course.
65
+
66
+ Returns:
67
+ Loop | list[Loop]: The loop at the specified index, or list of loops for a slice.
68
+ """
69
+ return self.loops_in_order[index]
70
+
71
+ def in_round_with(self, next_course: Course) -> bool:
72
+ """Check if the next course connects to this course in a circular pattern.
73
+
74
+ This method determines if the courses are connected in the round (circular knitting) by checking if the next course starts at the beginning of this course.
75
+
76
+ Args:
77
+ next_course (Course): The course that should follow this course in circular knitting.
78
+
79
+ Returns:
80
+ bool: True if the next course starts at the beginning of this course, indicating circular knitting.
81
+ """
82
+ next_start: Loop = cast(Loop, next_course[0])
83
+ i = 1
84
+ while not next_start.has_parent_loops():
85
+ next_start = cast(Loop, next_course[i])
86
+ i += 1
87
+ return self[0] in next_start.parent_loops
88
+
89
+ def in_row_with(self, next_course: Course) -> bool:
90
+ """Check if the next course connects to this course in a flat/row pattern.
91
+
92
+ This method determines if the courses are connected in flat knitting (back and forth) by checking if the next course starts at the end of this course.
93
+
94
+ Args:
95
+ next_course (Course): The course that should follow this course in flat knitting.
96
+
97
+ Returns:
98
+ bool: True if the next course starts at the end of this course, indicating flat/row knitting.
99
+ """
100
+ next_start: Loop = cast(Loop, next_course[0])
101
+ i = 1
102
+ while not next_start.has_parent_loops():
103
+ next_start = cast(Loop, next_course[i])
104
+ i += 1
105
+ return self[-1] in next_start.parent_loops
106
+
107
+ def __contains__(self, loop: Loop) -> bool:
108
+ """Check if a loop is contained in this course.
109
+
110
+ Args:
111
+ loop (Loop): The loop to check for membership in this course.
112
+
113
+ Returns:
114
+ bool: True if the loop is in this course, False otherwise.
115
+ """
116
+ return loop in self._loop_set
117
+
118
+ def __iter__(self) -> Iterator[Loop]:
119
+ """Iterate over loops in this course in order.
120
+
121
+ Returns:
122
+ Iterator[Loop]: An iterator over the loops in this course in their natural order.
123
+ """
124
+ return iter(self.loops_in_order)
125
+
126
+ def __reversed__(self) -> Iterator[Loop]:
127
+ """Iterate over loops in this course in reverse order.
128
+
129
+ Returns:
130
+ Iterator[Loop]: An iterator over the loops in this course in reverse order.
131
+ """
132
+ return reversed(self.loops_in_order)
133
+
134
+ def __len__(self) -> int:
135
+ """Get the number of loops in this course.
136
+
137
+ Returns:
138
+ int: The total number of loops in this course.
139
+ """
140
+ return len(self.loops_in_order)
141
+
142
+ def __str__(self) -> str:
143
+ """Get string representation of this course.
144
+
145
+ Returns:
146
+ str: String representation showing the ordered list of loops.
147
+ """
148
+ return str(self.loops_in_order)
149
+
150
+ def __repr__(self) -> str:
151
+ """Get string representation of this course for debugging.
152
+
153
+ Returns:
154
+ str: String representation showing the ordered list of loops.
155
+ """
156
+ return str(self)