kunyi 0.1.0__tar.gz

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.
kunyi-0.1.0/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ # Data
2
+ Calc2
3
+
4
+ # Python
5
+ __pycache__/
6
+ *.py[cod]
7
+ *.egg-info/
8
+ dist/
9
+ build/
10
+ .venv/
11
+ *.apkg.DS_Store
@@ -0,0 +1,260 @@
1
+ {
2
+ "deck_name": "Cloud Computing - Quiz 5",
3
+ "cards": [
4
+ {
5
+ "question": "What is the primary role of the client in a client-server architecture?",
6
+ "choices": [
7
+ "security",
8
+ "business logic",
9
+ "user interaction",
10
+ "data modeling"
11
+ ],
12
+ "correct_answer": "user interaction",
13
+ "explanation": "In a client-server model, the client is mainly responsible for user-facing interactions, such as input and display."
14
+ },
15
+ {
16
+ "question": "Which term refers to dividing an application into multiple layers or tiers?",
17
+ "choices": [
18
+ "standalone",
19
+ "client-server",
20
+ "load balancing",
21
+ "n-tier layered"
22
+ ],
23
+ "correct_answer": "n-tier layered",
24
+ "explanation": "N-tier layering separates an application into distinct layers (presentation, business logic, data access, etc.), improving maintainability and scalability."
25
+ },
26
+ {
27
+ "question": "What does MTTF stand for in the context of availability?",
28
+ "choices": [
29
+ "Mean Time To Failure",
30
+ "Mean Time To Fix",
31
+ "Mean Time To Function",
32
+ "Mean Time To Finish"
33
+ ],
34
+ "correct_answer": "Mean Time To Failure",
35
+ "explanation": "MTTF (Mean Time To Failure) is the average time a system operates before failing, often used as a measure of reliability."
36
+ },
37
+ {
38
+ "question": "What is the process of distributing tasks over resources according to a set of criteria called?",
39
+ "choices": ["scaling", "load balancing", "elasticity", "auto scaling"],
40
+ "correct_answer": "load balancing",
41
+ "explanation": "Load balancing is the technique of efficiently distributing network or application traffic across multiple servers."
42
+ },
43
+ {
44
+ "question": "Which load balancing algorithm distributes tasks equally among resources?",
45
+ "choices": [
46
+ "least connections",
47
+ "source IP hash",
48
+ "round robin",
49
+ "least response time"
50
+ ],
51
+ "correct_answer": "round robin",
52
+ "explanation": "Round robin cycles through each resource in order, effectively distributing tasks evenly in turn."
53
+ },
54
+ {
55
+ "question": "Which load balancing algorithm distributes tasks based on the client's IP address?",
56
+ "choices": [
57
+ "least connections",
58
+ "source IP hash",
59
+ "round robin",
60
+ "least response time"
61
+ ],
62
+ "correct_answer": "source IP hash",
63
+ "explanation": "Source IP hash creates a unique hash of the client's IP and maps it to a specific server for consistent routing."
64
+ },
65
+ {
66
+ "question": "Which load balancing algorithm prioritizes tasks based on the time taken to respond to requests?",
67
+ "choices": [
68
+ "least connections",
69
+ "source IP hash",
70
+ "round robin",
71
+ "least response time"
72
+ ],
73
+ "correct_answer": "least response time",
74
+ "explanation": "Least response time forwards requests to the server with the fastest response measurement, helping to reduce latency."
75
+ },
76
+ {
77
+ "question": "Which load balancing algorithm distributes tasks based on the number of active connections each resource has?",
78
+ "choices": [
79
+ "least connections",
80
+ "source IP hash",
81
+ "round robin",
82
+ "least response time"
83
+ ],
84
+ "correct_answer": "least connections",
85
+ "explanation": "Least connections sends new requests to the resource currently handling the fewest active connections."
86
+ },
87
+ {
88
+ "question": "What is the ability of a system to change in order to meet application demands called?",
89
+ "choices": [
90
+ "elasticity",
91
+ "scalability",
92
+ "load balancing",
93
+ "availability"
94
+ ],
95
+ "correct_answer": "scalability",
96
+ "explanation": "Scalability is the system's capacity to handle increasing workloads by adding resources, without impact to performance."
97
+ },
98
+ {
99
+ "question": "Which type of auto scaling uses machine learning to predict demand?",
100
+ "choices": ["scheduled", "dynamic", "predictive", "manual"],
101
+ "correct_answer": "predictive",
102
+ "explanation": "Predictive auto scaling anticipates future resource needs using historical data or ML models."
103
+ },
104
+ {
105
+ "question": "Which type of auto scaling changes based on a pre-defined date/time setting?",
106
+ "choices": ["scheduled", "dynamic", "predictive", "manual"],
107
+ "correct_answer": "scheduled",
108
+ "explanation": "Scheduled auto scaling uses specific date/time triggers to scale out or in, perfect for known peak/off-peak times."
109
+ },
110
+ {
111
+ "question": "In the context of auto scaling, what does the parameter scale_in_cooldown set?",
112
+ "choices": [
113
+ "The target metric level",
114
+ "A cooldown period after a scale-in activity",
115
+ "A cooldown period after a scale-out activity",
116
+ "The desired capacity"
117
+ ],
118
+ "correct_answer": "A cooldown period after a scale-in activity",
119
+ "explanation": "scale_in_cooldown prevents immediate subsequent scaling actions, giving the system time to stabilize after shrinking capacity."
120
+ },
121
+ {
122
+ "question": "Which type of load balancer can request new resources when sensing a demand increase?",
123
+ "choices": [
124
+ "Static load balancer",
125
+ "Network load balancer",
126
+ "Elastic load balancer",
127
+ "DNS-based load balancer"
128
+ ],
129
+ "correct_answer": "Elastic load balancer",
130
+ "explanation": "An elastic load balancer integrates with auto scaling to dynamically provision or decommission resources based on current demand."
131
+ },
132
+ {
133
+ "question": "Which type of load balancer can be configured to perform name translations to targets based on a set of criteria?",
134
+ "choices": [
135
+ "Static load balancer",
136
+ "Network load balancer",
137
+ "Elastic load balancer",
138
+ "DNS-based load balancer"
139
+ ],
140
+ "correct_answer": "DNS-based load balancer",
141
+ "explanation": "DNS-based load balancers (e.g., AWS Route 53) use DNS responses to send clients to the appropriate server based on criteria like geo-location."
142
+ },
143
+ {
144
+ "question": "What is the primary goal of dynamic load balancers?",
145
+ "choices": [
146
+ "To distribute tasks equally among resources",
147
+ "To have real-time knowledge of the current load of each resource",
148
+ "To operate at the transport level",
149
+ "To perform name translations based on criteria"
150
+ ],
151
+ "correct_answer": "To have real-time knowledge of the current load of each resource",
152
+ "explanation": "Dynamic load balancers continually monitor server loads, connections, or response times to make smarter routing decisions."
153
+ },
154
+ {
155
+ "question": "What is serverless computing?",
156
+ "choices": [
157
+ "Computing without servers",
158
+ "A model of computation where resources are automatically allocated by the cloud provider",
159
+ "A type of physical server",
160
+ "A local computing model"
161
+ ],
162
+ "correct_answer": "A model of computation where resources are automatically allocated by the cloud provider",
163
+ "explanation": "Serverless computing abstracts away server management—resources are provisioned on demand by the cloud provider, so developers focus only on code."
164
+ },
165
+ {
166
+ "question": "What is another term for serverless computing?",
167
+ "choices": [
168
+ "Infrastructure as a Service (IaaS)",
169
+ "Platform as a Service (PaaS)",
170
+ "Software as a Service (SaaS)",
171
+ "Function as a Service (FaaS)"
172
+ ],
173
+ "correct_answer": "Function as a Service (FaaS)",
174
+ "explanation": "Serverless architectures are often called FaaS because individual functions are deployed and run without managing servers."
175
+ },
176
+ {
177
+ "question": "Which of the following is NOT an advantage of serverless computing?",
178
+ "choices": [
179
+ "No servers to manage",
180
+ "Easy pricing based on executions and CPU time",
181
+ "Maximum execution time limitations",
182
+ "Automatic scaling"
183
+ ],
184
+ "correct_answer": "Maximum execution time limitations",
185
+ "explanation": "Execution time limits (e.g., 15 minutes in AWS Lambda) are constraints, not benefits, making them a disadvantage."
186
+ },
187
+ {
188
+ "question": "How are customers (normally) billed in serverless computing?",
189
+ "choices": [
190
+ "Monthly subscription",
191
+ "During the time their code is executed",
192
+ "Number of servers used",
193
+ "Flat rate per function"
194
+ ],
195
+ "correct_answer": "During the time their code is executed",
196
+ "explanation": "Billing is usage‑based—seconds of execution and resources consumed—rather than fixed server counts or flat subscriptions."
197
+ },
198
+ {
199
+ "question": "What is a Lambda function?",
200
+ "choices": [
201
+ "A tiny function deployed in serverless computing",
202
+ "A type of server",
203
+ "A program language",
204
+ "A cloud storage service"
205
+ ],
206
+ "correct_answer": "A tiny function deployed in serverless computing",
207
+ "explanation": "AWS Lambda lets you run small, event‑driven functions without provisioning or managing servers."
208
+ },
209
+ {
210
+ "question": "Which of the following is a disadvantage of serverless computing?",
211
+ "choices": [
212
+ "No servers to manage",
213
+ "Easy pricing",
214
+ "Automatic scaling",
215
+ "Harder to test/debug"
216
+ ],
217
+ "correct_answer": "Harder to test/debug",
218
+ "explanation": "Because infrastructure is abstracted away and functions are event‑driven, replicating the environment locally can be challenging for testing and debugging."
219
+ },
220
+ {
221
+ "question": "What does synchronous invocation mean?",
222
+ "choices": [
223
+ "The callee waits for the response",
224
+ "The callee doesn’t wait for the response",
225
+ "The function is triggered by an event",
226
+ "The function runs indefinitely"
227
+ ],
228
+ "correct_answer": "The callee waits for the response",
229
+ "explanation": "With synchronous invocation, the caller blocks until the function finishes and returns a result."
230
+ },
231
+ {
232
+ "question": "Which of the following is an example of a trigger for a Lambda function?",
233
+ "choices": [
234
+ "A scheduled event",
235
+ "A new object uploaded to an S3 bucket",
236
+ "An HTTP request from an API",
237
+ "All of the above"
238
+ ],
239
+ "correct_answer": "All of the above",
240
+ "explanation": "Lambda can be triggered by many sources, including scheduled events (CloudWatch), S3 object uploads, or API Gateway HTTP requests."
241
+ },
242
+ {
243
+ "question": "What is the event object in serverless computing (in AWS)?",
244
+ "choices": [
245
+ "A JSON-formatted document containing data for a lambda function",
246
+ "A physical server",
247
+ "A programming language",
248
+ "A cloud storage service"
249
+ ],
250
+ "correct_answer": "A JSON-formatted document containing data for a lambda function",
251
+ "explanation": "When Lambda is invoked, AWS passes the triggering data as a JSON event object to the function handler."
252
+ },
253
+ {
254
+ "question": "What is the current maximum execution time set by AWS for Lambda functions in minutes?",
255
+ "choices": ["5", "10", "15", "30"],
256
+ "correct_answer": "15",
257
+ "explanation": "As of 2024, AWS Lambda allows a maximum execution timeout of 900 seconds (15 minutes) per invocation."
258
+ }
259
+ ]
260
+ }
kunyi-0.1.0/LICENSE ADDED
@@ -0,0 +1,129 @@
1
+ PolyForm Noncommercial License 1.0.0
2
+
3
+ https://polyformproject.org/licenses/noncommercial/1.0.0
4
+
5
+ Required Notice: Copyright Ta'taang (Ling Thang) (https://github.com/LingT03)
6
+
7
+ Acceptance
8
+
9
+ In order to get any license under these terms, you must agree
10
+ to them as both strict obligations and conditions to all
11
+ your licenses.
12
+
13
+ Copyright License
14
+
15
+ The licensor grants you a copyright license for the
16
+ software to do everything you might do with the software
17
+ that would otherwise infringe the licensor's copyright
18
+ in it for any permitted purpose. However, you may
19
+ only distribute the software according to Distribution License
20
+ and make changes or new works based on the software according
21
+ to Changes and New Works License.
22
+
23
+ Distribution License
24
+
25
+ The licensor grants you an additional copyright license
26
+ to distribute copies of the software. Your license
27
+ to distribute covers distributing the software with
28
+ changes and new works permitted by Changes and New Works License.
29
+
30
+ Notices
31
+
32
+ You must ensure that anyone who gets a copy of any part of
33
+ the software from you also gets a copy of these terms or the
34
+ URL for them above, as well as copies of any plain-text lines
35
+ beginning with "Required Notice:" that the licensor provided
36
+ with the software.
37
+
38
+ Changes and New Works License
39
+
40
+ The licensor grants you an additional copyright license to
41
+ make changes and new works based on the software for any
42
+ permitted purpose.
43
+
44
+ Patent License
45
+
46
+ The licensor grants you a patent license for the software that
47
+ covers patent claims the licensor can license, or becomes able
48
+ to license, that you would infringe by using the software.
49
+
50
+ Noncommercial Purposes
51
+
52
+ Any noncommercial purpose is a permitted purpose.
53
+
54
+ Personal Uses
55
+
56
+ Personal use for research, experiment, and testing for
57
+ the benefit of public knowledge, personal study, private
58
+ entertainment, hobby projects, amateur pursuits, or religious
59
+ observance, without any anticipated commercial application,
60
+ is use for a permitted purpose.
61
+
62
+ Noncommercial Organizations
63
+
64
+ Use by any charitable organization, educational institution,
65
+ public research organization, public safety or health
66
+ organization, environmental protection organization,
67
+ or government institution is use for a permitted purpose
68
+ regardless of the source of funding or obligations resulting
69
+ from the funding.
70
+
71
+ Fair Use
72
+
73
+ You may have "fair use" rights for the software under the
74
+ law. These terms do not limit them.
75
+
76
+ No Other Rights
77
+
78
+ These terms do not allow you to sublicense or transfer any of
79
+ your licenses to anyone else, or prevent the licensor from
80
+ granting licenses to anyone else. These terms do not imply
81
+ any other licenses.
82
+
83
+ Patent Defense
84
+
85
+ If you make any written claim that the software infringes or
86
+ contributes to infringement of any patent, your patent license
87
+ for the software granted under these terms ends immediately. If
88
+ your company makes such a claim, your patent license ends
89
+ immediately for work on behalf of your company.
90
+
91
+ Violations
92
+
93
+ The first time you are notified in writing that you have
94
+ violated any of these terms, or done anything with the software
95
+ not covered by your licenses, your licenses can nonetheless
96
+ continue if you come into full compliance with these terms,
97
+ and take practical steps to correct past violations, within
98
+ 32 days of receiving notice. Otherwise, all your licenses
99
+ end immediately.
100
+
101
+ No Liability
102
+
103
+ AS FAR AS THE LAW ALLOWS, THE SOFTWARE COMES AS IS, WITHOUT
104
+ ANY WARRANTY OR CONDITION, AND THE LICENSOR WILL NOT BE LIABLE
105
+ TO YOU FOR ANY DAMAGES ARISING OUT OF THESE TERMS OR THE USE
106
+ OR NATURE OF THE SOFTWARE, UNDER ANY KIND OF LEGAL CLAIM.
107
+
108
+ Definitions
109
+
110
+ The "licensor" is the individual or entity offering these
111
+ terms, and the "software" is the software the licensor makes
112
+ available under these terms.
113
+
114
+ "You" refers to the individual or entity agreeing to these
115
+ terms.
116
+
117
+ "Your company" is any legal entity, sole proprietorship,
118
+ or other kind of organization that you work for, plus all
119
+ organizations that have control over, are under the control of,
120
+ or are under common control with that organization. "Control"
121
+ means ownership of substantially all the assets of an entity,
122
+ or the power to direct its management and policies by vote,
123
+ contract, or otherwise. Control can be direct or indirect.
124
+
125
+ "Your licenses" are all the licenses granted to you for the
126
+ software under these terms.
127
+
128
+ "Use" means anything you do with the software requiring one
129
+ of your licenses.
kunyi-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,257 @@
1
+ Metadata-Version: 2.4
2
+ Name: kunyi
3
+ Version: 0.1.0
4
+ Summary: Generate Anki .apkg decks from JSON (MCQ) or TSV (basic) card data.
5
+ Project-URL: Homepage, https://github.com/LingT03/Kunyi
6
+ Project-URL: Bug Tracker, https://github.com/LingT03/Kunyi/issues
7
+ Project-URL: Changelog, https://github.com/LingT03/Kunyi/releases
8
+ License: PolyForm Noncommercial License 1.0.0
9
+
10
+ https://polyformproject.org/licenses/noncommercial/1.0.0
11
+
12
+ Required Notice: Copyright Ta'taang (Ling Thang) (https://github.com/LingT03)
13
+
14
+ Acceptance
15
+
16
+ In order to get any license under these terms, you must agree
17
+ to them as both strict obligations and conditions to all
18
+ your licenses.
19
+
20
+ Copyright License
21
+
22
+ The licensor grants you a copyright license for the
23
+ software to do everything you might do with the software
24
+ that would otherwise infringe the licensor's copyright
25
+ in it for any permitted purpose. However, you may
26
+ only distribute the software according to Distribution License
27
+ and make changes or new works based on the software according
28
+ to Changes and New Works License.
29
+
30
+ Distribution License
31
+
32
+ The licensor grants you an additional copyright license
33
+ to distribute copies of the software. Your license
34
+ to distribute covers distributing the software with
35
+ changes and new works permitted by Changes and New Works License.
36
+
37
+ Notices
38
+
39
+ You must ensure that anyone who gets a copy of any part of
40
+ the software from you also gets a copy of these terms or the
41
+ URL for them above, as well as copies of any plain-text lines
42
+ beginning with "Required Notice:" that the licensor provided
43
+ with the software.
44
+
45
+ Changes and New Works License
46
+
47
+ The licensor grants you an additional copyright license to
48
+ make changes and new works based on the software for any
49
+ permitted purpose.
50
+
51
+ Patent License
52
+
53
+ The licensor grants you a patent license for the software that
54
+ covers patent claims the licensor can license, or becomes able
55
+ to license, that you would infringe by using the software.
56
+
57
+ Noncommercial Purposes
58
+
59
+ Any noncommercial purpose is a permitted purpose.
60
+
61
+ Personal Uses
62
+
63
+ Personal use for research, experiment, and testing for
64
+ the benefit of public knowledge, personal study, private
65
+ entertainment, hobby projects, amateur pursuits, or religious
66
+ observance, without any anticipated commercial application,
67
+ is use for a permitted purpose.
68
+
69
+ Noncommercial Organizations
70
+
71
+ Use by any charitable organization, educational institution,
72
+ public research organization, public safety or health
73
+ organization, environmental protection organization,
74
+ or government institution is use for a permitted purpose
75
+ regardless of the source of funding or obligations resulting
76
+ from the funding.
77
+
78
+ Fair Use
79
+
80
+ You may have "fair use" rights for the software under the
81
+ law. These terms do not limit them.
82
+
83
+ No Other Rights
84
+
85
+ These terms do not allow you to sublicense or transfer any of
86
+ your licenses to anyone else, or prevent the licensor from
87
+ granting licenses to anyone else. These terms do not imply
88
+ any other licenses.
89
+
90
+ Patent Defense
91
+
92
+ If you make any written claim that the software infringes or
93
+ contributes to infringement of any patent, your patent license
94
+ for the software granted under these terms ends immediately. If
95
+ your company makes such a claim, your patent license ends
96
+ immediately for work on behalf of your company.
97
+
98
+ Violations
99
+
100
+ The first time you are notified in writing that you have
101
+ violated any of these terms, or done anything with the software
102
+ not covered by your licenses, your licenses can nonetheless
103
+ continue if you come into full compliance with these terms,
104
+ and take practical steps to correct past violations, within
105
+ 32 days of receiving notice. Otherwise, all your licenses
106
+ end immediately.
107
+
108
+ No Liability
109
+
110
+ AS FAR AS THE LAW ALLOWS, THE SOFTWARE COMES AS IS, WITHOUT
111
+ ANY WARRANTY OR CONDITION, AND THE LICENSOR WILL NOT BE LIABLE
112
+ TO YOU FOR ANY DAMAGES ARISING OUT OF THESE TERMS OR THE USE
113
+ OR NATURE OF THE SOFTWARE, UNDER ANY KIND OF LEGAL CLAIM.
114
+
115
+ Definitions
116
+
117
+ The "licensor" is the individual or entity offering these
118
+ terms, and the "software" is the software the licensor makes
119
+ available under these terms.
120
+
121
+ "You" refers to the individual or entity agreeing to these
122
+ terms.
123
+
124
+ "Your company" is any legal entity, sole proprietorship,
125
+ or other kind of organization that you work for, plus all
126
+ organizations that have control over, are under the control of,
127
+ or are under common control with that organization. "Control"
128
+ means ownership of substantially all the assets of an entity,
129
+ or the power to direct its management and policies by vote,
130
+ contract, or otherwise. Control can be direct or indirect.
131
+
132
+ "Your licenses" are all the licenses granted to you for the
133
+ software under these terms.
134
+
135
+ "Use" means anything you do with the software requiring one
136
+ of your licenses.
137
+ License-File: LICENSE
138
+ Requires-Python: >=3.10
139
+ Requires-Dist: genanki>=0.13
140
+ Description-Content-Type: text/markdown
141
+
142
+ # kunyi
143
+
144
+ Generate Anki `.apkg` decks from JSON (MCQ) or TSV (basic) card data.
145
+
146
+ _Part of the [Seya](https://github.com/LingT03/Seya) study ecosystem._
147
+
148
+ ---
149
+
150
+ ## Installation
151
+
152
+ ```bash
153
+ pip install kunyi
154
+ ```
155
+
156
+ Or for local development:
157
+
158
+ ```bash
159
+ git clone https://github.com/LingT03/Kunyi.git
160
+ cd Kunyi
161
+ pip install -e .
162
+ ```
163
+
164
+ ---
165
+
166
+ ## CLI usage
167
+
168
+ ```bash
169
+ # JSON — multiple-choice question cards
170
+ kunyi "Cloud Computing" cards.json
171
+
172
+ # TSV — basic front/back cards
173
+ kunyi "Calc 2 Formulas" formulas.tsv
174
+
175
+ # Explicit output path (recommended for subprocess callers)
176
+ kunyi "Cloud Computing" cards.json --output /path/to/deck.apkg
177
+
178
+ # Override format detection
179
+ kunyi "My Deck" cards.data --format tsv
180
+ ```
181
+
182
+ On success the resolved `.apkg` path is printed to stdout (exit 0).
183
+ On failure a human-readable message is printed to stderr (exit 1).
184
+
185
+ ---
186
+
187
+ ## Input formats
188
+
189
+ ### JSON — MCQ cards
190
+
191
+ ```json
192
+ {
193
+ "cards": [
194
+ {
195
+ "question": "What does CPU stand for?",
196
+ "choices": ["Central Processing Unit", "Core Power Unit", "Control Processing Unit"],
197
+ "correct_answer": "Central Processing Unit",
198
+ "explanation": "CPU stands for Central Processing Unit.",
199
+ "tags": ["chapter-1"]
200
+ }
201
+ ]
202
+ }
203
+ ```
204
+
205
+ `correct_answer` must be an element of `choices` — validated on parse.
206
+ `tags` is optional.
207
+
208
+ ### TSV — basic cards
209
+
210
+ Tab-delimited UTF-8. Optional header row (`front\tback`) is auto-detected and skipped.
211
+
212
+ ```
213
+ front back
214
+ What is spaced repetition? A technique that spaces reviews over time.
215
+ What is active recall? Actively retrieving information from memory.
216
+ ```
217
+
218
+ ---
219
+
220
+ ## Library usage
221
+
222
+ ```python
223
+ from pathlib import Path
224
+ from kunyi import AnkiCardDeck, MCQCard, BasicCard
225
+
226
+ deck = AnkiCardDeck(deck_name="My Deck")
227
+
228
+ deck.add_card(MCQCard(
229
+ question="What does RAM stand for?",
230
+ choices=["Random Access Memory", "Read Access Module"],
231
+ correct_answer="Random Access Memory",
232
+ explanation="RAM is the primary short-term memory of a computer.",
233
+ tags=["hardware"],
234
+ ))
235
+
236
+ deck.add_card(BasicCard(
237
+ front="What is a CPU?",
238
+ back="The central processing unit — the brain of a computer.",
239
+ ))
240
+
241
+ deck.save_deck(Path("output/my_deck.apkg"))
242
+ ```
243
+
244
+ ---
245
+
246
+ ## Running tests
247
+
248
+ ```bash
249
+ pip install pytest
250
+ pytest tests/
251
+ ```
252
+
253
+ ---
254
+
255
+ ## What is Anki?
256
+
257
+ [Anki](https://apps.ankiweb.net/) is a free flashcard program that uses spaced repetition and active recall to maximise long-term retention. `kunyi` generates `.apkg` files that can be imported directly into Anki.