pythonlings 0.3.0__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 (942) hide show
  1. pythonlings/__init__.py +0 -0
  2. pythonlings/__main__.py +4 -0
  3. pythonlings/app.py +84 -0
  4. pythonlings/cli.py +318 -0
  5. pythonlings/core/__init__.py +0 -0
  6. pythonlings/core/curriculum.py +106 -0
  7. pythonlings/core/docs.py +68 -0
  8. pythonlings/core/exercise.py +33 -0
  9. pythonlings/core/manifest.py +110 -0
  10. pythonlings/core/reset.py +43 -0
  11. pythonlings/core/runner.py +114 -0
  12. pythonlings/core/solutions.py +17 -0
  13. pythonlings/core/state.py +86 -0
  14. pythonlings/curriculum/checks/async/async1.py +4 -0
  15. pythonlings/curriculum/checks/async/async10.py +4 -0
  16. pythonlings/curriculum/checks/async/async2.py +4 -0
  17. pythonlings/curriculum/checks/async/async3.py +4 -0
  18. pythonlings/curriculum/checks/async/async4.py +4 -0
  19. pythonlings/curriculum/checks/async/async5.py +4 -0
  20. pythonlings/curriculum/checks/async/async6.py +4 -0
  21. pythonlings/curriculum/checks/async/async7.py +4 -0
  22. pythonlings/curriculum/checks/async/async8.py +2 -0
  23. pythonlings/curriculum/checks/async/async9.py +4 -0
  24. pythonlings/curriculum/checks/classes/classes1.py +3 -0
  25. pythonlings/curriculum/checks/classes/classes10.py +5 -0
  26. pythonlings/curriculum/checks/classes/classes11.py +5 -0
  27. pythonlings/curriculum/checks/classes/classes12.py +16 -0
  28. pythonlings/curriculum/checks/classes/classes2.py +3 -0
  29. pythonlings/curriculum/checks/classes/classes3.py +4 -0
  30. pythonlings/curriculum/checks/classes/classes4.py +4 -0
  31. pythonlings/curriculum/checks/classes/classes5.py +5 -0
  32. pythonlings/curriculum/checks/classes/classes6.py +4 -0
  33. pythonlings/curriculum/checks/classes/classes7.py +3 -0
  34. pythonlings/curriculum/checks/classes/classes8.py +3 -0
  35. pythonlings/curriculum/checks/classes/classes9.py +4 -0
  36. pythonlings/curriculum/checks/collections/collections1.py +4 -0
  37. pythonlings/curriculum/checks/collections/collections10.py +15 -0
  38. pythonlings/curriculum/checks/collections/collections2.py +4 -0
  39. pythonlings/curriculum/checks/collections/collections3.py +5 -0
  40. pythonlings/curriculum/checks/collections/collections4.py +4 -0
  41. pythonlings/curriculum/checks/collections/collections5.py +5 -0
  42. pythonlings/curriculum/checks/collections/collections6.py +6 -0
  43. pythonlings/curriculum/checks/collections/collections7.py +4 -0
  44. pythonlings/curriculum/checks/collections/collections8.py +5 -0
  45. pythonlings/curriculum/checks/collections/collections9.py +9 -0
  46. pythonlings/curriculum/checks/comprehensions/comprehensions1.py +3 -0
  47. pythonlings/curriculum/checks/comprehensions/comprehensions10.py +5 -0
  48. pythonlings/curriculum/checks/comprehensions/comprehensions2.py +3 -0
  49. pythonlings/curriculum/checks/comprehensions/comprehensions3.py +3 -0
  50. pythonlings/curriculum/checks/comprehensions/comprehensions4.py +6 -0
  51. pythonlings/curriculum/checks/comprehensions/comprehensions5.py +3 -0
  52. pythonlings/curriculum/checks/comprehensions/comprehensions6.py +3 -0
  53. pythonlings/curriculum/checks/comprehensions/comprehensions7.py +4 -0
  54. pythonlings/curriculum/checks/comprehensions/comprehensions8.py +5 -0
  55. pythonlings/curriculum/checks/comprehensions/comprehensions9.py +3 -0
  56. pythonlings/curriculum/checks/conditionals/conditionals1.py +2 -0
  57. pythonlings/curriculum/checks/conditionals/conditionals10.py +10 -0
  58. pythonlings/curriculum/checks/conditionals/conditionals2.py +5 -0
  59. pythonlings/curriculum/checks/conditionals/conditionals3.py +9 -0
  60. pythonlings/curriculum/checks/conditionals/conditionals4.py +7 -0
  61. pythonlings/curriculum/checks/conditionals/conditionals5.py +9 -0
  62. pythonlings/curriculum/checks/conditionals/conditionals6.py +7 -0
  63. pythonlings/curriculum/checks/conditionals/conditionals7.py +7 -0
  64. pythonlings/curriculum/checks/conditionals/conditionals8.py +9 -0
  65. pythonlings/curriculum/checks/conditionals/conditionals9.py +7 -0
  66. pythonlings/curriculum/checks/context_managers/context_managers1.py +15 -0
  67. pythonlings/curriculum/checks/context_managers/context_managers2.py +10 -0
  68. pythonlings/curriculum/checks/context_managers/context_managers3.py +2 -0
  69. pythonlings/curriculum/checks/context_managers/context_managers4.py +3 -0
  70. pythonlings/curriculum/checks/context_managers/context_managers5.py +5 -0
  71. pythonlings/curriculum/checks/context_managers/context_managers6.py +4 -0
  72. pythonlings/curriculum/checks/context_managers/context_managers7.py +16 -0
  73. pythonlings/curriculum/checks/context_managers/context_managers8.py +15 -0
  74. pythonlings/curriculum/checks/dataclasses/dataclasses1.py +3 -0
  75. pythonlings/curriculum/checks/dataclasses/dataclasses2.py +5 -0
  76. pythonlings/curriculum/checks/dataclasses/dataclasses3.py +4 -0
  77. pythonlings/curriculum/checks/dataclasses/dataclasses4.py +3 -0
  78. pythonlings/curriculum/checks/dataclasses/dataclasses5.py +9 -0
  79. pythonlings/curriculum/checks/dataclasses/dataclasses6.py +6 -0
  80. pythonlings/curriculum/checks/dataclasses/dataclasses7.py +6 -0
  81. pythonlings/curriculum/checks/dataclasses/dataclasses8.py +5 -0
  82. pythonlings/curriculum/checks/datetime/datetime1.py +4 -0
  83. pythonlings/curriculum/checks/datetime/datetime2.py +4 -0
  84. pythonlings/curriculum/checks/datetime/datetime3.py +6 -0
  85. pythonlings/curriculum/checks/datetime/datetime4.py +2 -0
  86. pythonlings/curriculum/checks/datetime/datetime5.py +2 -0
  87. pythonlings/curriculum/checks/datetime/datetime6.py +2 -0
  88. pythonlings/curriculum/checks/datetime/datetime7.py +2 -0
  89. pythonlings/curriculum/checks/datetime/datetime8.py +5 -0
  90. pythonlings/curriculum/checks/decorators/decorators1.py +8 -0
  91. pythonlings/curriculum/checks/decorators/decorators10.py +12 -0
  92. pythonlings/curriculum/checks/decorators/decorators2.py +5 -0
  93. pythonlings/curriculum/checks/decorators/decorators3.py +4 -0
  94. pythonlings/curriculum/checks/decorators/decorators4.py +7 -0
  95. pythonlings/curriculum/checks/decorators/decorators5.py +5 -0
  96. pythonlings/curriculum/checks/decorators/decorators6.py +8 -0
  97. pythonlings/curriculum/checks/decorators/decorators7.py +12 -0
  98. pythonlings/curriculum/checks/decorators/decorators8.py +20 -0
  99. pythonlings/curriculum/checks/decorators/decorators9.py +4 -0
  100. pythonlings/curriculum/checks/dictionaries/dictionaries1.py +3 -0
  101. pythonlings/curriculum/checks/dictionaries/dictionaries10.py +5 -0
  102. pythonlings/curriculum/checks/dictionaries/dictionaries2.py +2 -0
  103. pythonlings/curriculum/checks/dictionaries/dictionaries3.py +5 -0
  104. pythonlings/curriculum/checks/dictionaries/dictionaries4.py +5 -0
  105. pythonlings/curriculum/checks/dictionaries/dictionaries5.py +11 -0
  106. pythonlings/curriculum/checks/dictionaries/dictionaries6.py +4 -0
  107. pythonlings/curriculum/checks/dictionaries/dictionaries7.py +5 -0
  108. pythonlings/curriculum/checks/dictionaries/dictionaries8.py +4 -0
  109. pythonlings/curriculum/checks/dictionaries/dictionaries9.py +4 -0
  110. pythonlings/curriculum/checks/enums/enums1.py +4 -0
  111. pythonlings/curriculum/checks/enums/enums2.py +3 -0
  112. pythonlings/curriculum/checks/enums/enums3.py +3 -0
  113. pythonlings/curriculum/checks/enums/enums4.py +2 -0
  114. pythonlings/curriculum/checks/enums/enums5.py +4 -0
  115. pythonlings/curriculum/checks/enums/enums6.py +3 -0
  116. pythonlings/curriculum/checks/exceptions/exceptions1.py +4 -0
  117. pythonlings/curriculum/checks/exceptions/exceptions10.py +39 -0
  118. pythonlings/curriculum/checks/exceptions/exceptions2.py +5 -0
  119. pythonlings/curriculum/checks/exceptions/exceptions3.py +8 -0
  120. pythonlings/curriculum/checks/exceptions/exceptions4.py +5 -0
  121. pythonlings/curriculum/checks/exceptions/exceptions5.py +10 -0
  122. pythonlings/curriculum/checks/exceptions/exceptions6.py +17 -0
  123. pythonlings/curriculum/checks/exceptions/exceptions7.py +15 -0
  124. pythonlings/curriculum/checks/exceptions/exceptions8.py +6 -0
  125. pythonlings/curriculum/checks/exceptions/exceptions9.py +16 -0
  126. pythonlings/curriculum/checks/file_io/file_io1.py +15 -0
  127. pythonlings/curriculum/checks/file_io/file_io10.py +16 -0
  128. pythonlings/curriculum/checks/file_io/file_io2.py +10 -0
  129. pythonlings/curriculum/checks/file_io/file_io3.py +15 -0
  130. pythonlings/curriculum/checks/file_io/file_io4.py +14 -0
  131. pythonlings/curriculum/checks/file_io/file_io5.py +15 -0
  132. pythonlings/curriculum/checks/file_io/file_io6.py +10 -0
  133. pythonlings/curriculum/checks/file_io/file_io7.py +15 -0
  134. pythonlings/curriculum/checks/file_io/file_io8.py +12 -0
  135. pythonlings/curriculum/checks/file_io/file_io9.py +10 -0
  136. pythonlings/curriculum/checks/functional/functional1.py +4 -0
  137. pythonlings/curriculum/checks/functional/functional10.py +7 -0
  138. pythonlings/curriculum/checks/functional/functional2.py +5 -0
  139. pythonlings/curriculum/checks/functional/functional3.py +3 -0
  140. pythonlings/curriculum/checks/functional/functional4.py +4 -0
  141. pythonlings/curriculum/checks/functional/functional5.py +6 -0
  142. pythonlings/curriculum/checks/functional/functional6.py +8 -0
  143. pythonlings/curriculum/checks/functional/functional7.py +8 -0
  144. pythonlings/curriculum/checks/functional/functional8.py +7 -0
  145. pythonlings/curriculum/checks/functional/functional9.py +8 -0
  146. pythonlings/curriculum/checks/functions/functions1.py +9 -0
  147. pythonlings/curriculum/checks/functions/functions10.py +12 -0
  148. pythonlings/curriculum/checks/functions/functions2.py +4 -0
  149. pythonlings/curriculum/checks/functions/functions3.py +6 -0
  150. pythonlings/curriculum/checks/functions/functions4.py +6 -0
  151. pythonlings/curriculum/checks/functions/functions5.py +6 -0
  152. pythonlings/curriculum/checks/functions/functions6.py +8 -0
  153. pythonlings/curriculum/checks/functions/functions7.py +7 -0
  154. pythonlings/curriculum/checks/functions/functions8.py +6 -0
  155. pythonlings/curriculum/checks/functions/functions9.py +7 -0
  156. pythonlings/curriculum/checks/generators/generators1.py +4 -0
  157. pythonlings/curriculum/checks/generators/generators10.py +7 -0
  158. pythonlings/curriculum/checks/generators/generators2.py +3 -0
  159. pythonlings/curriculum/checks/generators/generators3.py +4 -0
  160. pythonlings/curriculum/checks/generators/generators4.py +9 -0
  161. pythonlings/curriculum/checks/generators/generators5.py +10 -0
  162. pythonlings/curriculum/checks/generators/generators6.py +8 -0
  163. pythonlings/curriculum/checks/generators/generators7.py +11 -0
  164. pythonlings/curriculum/checks/generators/generators8.py +8 -0
  165. pythonlings/curriculum/checks/generators/generators9.py +13 -0
  166. pythonlings/curriculum/checks/itertools/itertools1.py +2 -0
  167. pythonlings/curriculum/checks/itertools/itertools2.py +2 -0
  168. pythonlings/curriculum/checks/itertools/itertools3.py +2 -0
  169. pythonlings/curriculum/checks/itertools/itertools4.py +2 -0
  170. pythonlings/curriculum/checks/itertools/itertools5.py +2 -0
  171. pythonlings/curriculum/checks/itertools/itertools6.py +2 -0
  172. pythonlings/curriculum/checks/itertools/itertools7.py +2 -0
  173. pythonlings/curriculum/checks/itertools/itertools8.py +3 -0
  174. pythonlings/curriculum/checks/json/json1.py +3 -0
  175. pythonlings/curriculum/checks/json/json2.py +2 -0
  176. pythonlings/curriculum/checks/json/json3.py +2 -0
  177. pythonlings/curriculum/checks/json/json4.py +2 -0
  178. pythonlings/curriculum/checks/json/json5.py +2 -0
  179. pythonlings/curriculum/checks/json/json6.py +2 -0
  180. pythonlings/curriculum/checks/json/json7.py +3 -0
  181. pythonlings/curriculum/checks/json/json8.py +4 -0
  182. pythonlings/curriculum/checks/lists/lists1.py +2 -0
  183. pythonlings/curriculum/checks/lists/lists10.py +5 -0
  184. pythonlings/curriculum/checks/lists/lists2.py +3 -0
  185. pythonlings/curriculum/checks/lists/lists3.py +4 -0
  186. pythonlings/curriculum/checks/lists/lists4.py +3 -0
  187. pythonlings/curriculum/checks/lists/lists5.py +4 -0
  188. pythonlings/curriculum/checks/lists/lists6.py +3 -0
  189. pythonlings/curriculum/checks/lists/lists7.py +4 -0
  190. pythonlings/curriculum/checks/lists/lists8.py +7 -0
  191. pythonlings/curriculum/checks/lists/lists9.py +4 -0
  192. pythonlings/curriculum/checks/loops/loops1.py +2 -0
  193. pythonlings/curriculum/checks/loops/loops10.py +6 -0
  194. pythonlings/curriculum/checks/loops/loops2.py +2 -0
  195. pythonlings/curriculum/checks/loops/loops3.py +2 -0
  196. pythonlings/curriculum/checks/loops/loops4.py +3 -0
  197. pythonlings/curriculum/checks/loops/loops5.py +2 -0
  198. pythonlings/curriculum/checks/loops/loops6.py +2 -0
  199. pythonlings/curriculum/checks/loops/loops7.py +2 -0
  200. pythonlings/curriculum/checks/loops/loops8.py +2 -0
  201. pythonlings/curriculum/checks/loops/loops9.py +3 -0
  202. pythonlings/curriculum/checks/modules/modules1.py +2 -0
  203. pythonlings/curriculum/checks/modules/modules2.py +2 -0
  204. pythonlings/curriculum/checks/modules/modules3.py +5 -0
  205. pythonlings/curriculum/checks/modules/modules4.py +8 -0
  206. pythonlings/curriculum/checks/modules/modules5.py +7 -0
  207. pythonlings/curriculum/checks/modules/modules6.py +4 -0
  208. pythonlings/curriculum/checks/modules/modules7.py +4 -0
  209. pythonlings/curriculum/checks/modules/modules8.py +15 -0
  210. pythonlings/curriculum/checks/oop_advanced/oop_advanced1.py +4 -0
  211. pythonlings/curriculum/checks/oop_advanced/oop_advanced10.py +3 -0
  212. pythonlings/curriculum/checks/oop_advanced/oop_advanced11.py +3 -0
  213. pythonlings/curriculum/checks/oop_advanced/oop_advanced12.py +4 -0
  214. pythonlings/curriculum/checks/oop_advanced/oop_advanced2.py +4 -0
  215. pythonlings/curriculum/checks/oop_advanced/oop_advanced3.py +3 -0
  216. pythonlings/curriculum/checks/oop_advanced/oop_advanced4.py +3 -0
  217. pythonlings/curriculum/checks/oop_advanced/oop_advanced5.py +3 -0
  218. pythonlings/curriculum/checks/oop_advanced/oop_advanced6.py +2 -0
  219. pythonlings/curriculum/checks/oop_advanced/oop_advanced7.py +3 -0
  220. pythonlings/curriculum/checks/oop_advanced/oop_advanced8.py +3 -0
  221. pythonlings/curriculum/checks/oop_advanced/oop_advanced9.py +4 -0
  222. pythonlings/curriculum/checks/pathlib/pathlib1.py +5 -0
  223. pythonlings/curriculum/checks/pathlib/pathlib2.py +4 -0
  224. pythonlings/curriculum/checks/pathlib/pathlib3.py +6 -0
  225. pythonlings/curriculum/checks/pathlib/pathlib4.py +4 -0
  226. pythonlings/curriculum/checks/pathlib/pathlib5.py +4 -0
  227. pythonlings/curriculum/checks/pathlib/pathlib6.py +5 -0
  228. pythonlings/curriculum/checks/recursion/recursion1.py +5 -0
  229. pythonlings/curriculum/checks/recursion/recursion2.py +5 -0
  230. pythonlings/curriculum/checks/recursion/recursion3.py +6 -0
  231. pythonlings/curriculum/checks/recursion/recursion4.py +6 -0
  232. pythonlings/curriculum/checks/recursion/recursion5.py +7 -0
  233. pythonlings/curriculum/checks/recursion/recursion6.py +7 -0
  234. pythonlings/curriculum/checks/recursion/recursion7.py +7 -0
  235. pythonlings/curriculum/checks/recursion/recursion8.py +15 -0
  236. pythonlings/curriculum/checks/regex/regex1.py +3 -0
  237. pythonlings/curriculum/checks/regex/regex10.py +17 -0
  238. pythonlings/curriculum/checks/regex/regex2.py +3 -0
  239. pythonlings/curriculum/checks/regex/regex3.py +2 -0
  240. pythonlings/curriculum/checks/regex/regex4.py +4 -0
  241. pythonlings/curriculum/checks/regex/regex5.py +4 -0
  242. pythonlings/curriculum/checks/regex/regex6.py +6 -0
  243. pythonlings/curriculum/checks/regex/regex7.py +5 -0
  244. pythonlings/curriculum/checks/regex/regex8.py +6 -0
  245. pythonlings/curriculum/checks/regex/regex9.py +8 -0
  246. pythonlings/curriculum/checks/sets/sets1.py +3 -0
  247. pythonlings/curriculum/checks/sets/sets10.py +15 -0
  248. pythonlings/curriculum/checks/sets/sets2.py +5 -0
  249. pythonlings/curriculum/checks/sets/sets3.py +5 -0
  250. pythonlings/curriculum/checks/sets/sets4.py +3 -0
  251. pythonlings/curriculum/checks/sets/sets5.py +3 -0
  252. pythonlings/curriculum/checks/sets/sets6.py +3 -0
  253. pythonlings/curriculum/checks/sets/sets7.py +5 -0
  254. pythonlings/curriculum/checks/sets/sets8.py +5 -0
  255. pythonlings/curriculum/checks/sets/sets9.py +3 -0
  256. pythonlings/curriculum/checks/strings/strings1.py +3 -0
  257. pythonlings/curriculum/checks/strings/strings10.py +5 -0
  258. pythonlings/curriculum/checks/strings/strings2.py +3 -0
  259. pythonlings/curriculum/checks/strings/strings3.py +3 -0
  260. pythonlings/curriculum/checks/strings/strings4.py +2 -0
  261. pythonlings/curriculum/checks/strings/strings5.py +4 -0
  262. pythonlings/curriculum/checks/strings/strings6.py +3 -0
  263. pythonlings/curriculum/checks/strings/strings7.py +3 -0
  264. pythonlings/curriculum/checks/strings/strings8.py +3 -0
  265. pythonlings/curriculum/checks/strings/strings9.py +3 -0
  266. pythonlings/curriculum/checks/testing/testing1.py +2 -0
  267. pythonlings/curriculum/checks/testing/testing10.py +9 -0
  268. pythonlings/curriculum/checks/testing/testing11.py +7 -0
  269. pythonlings/curriculum/checks/testing/testing12.py +19 -0
  270. pythonlings/curriculum/checks/testing/testing2.py +2 -0
  271. pythonlings/curriculum/checks/testing/testing3.py +12 -0
  272. pythonlings/curriculum/checks/testing/testing4.py +6 -0
  273. pythonlings/curriculum/checks/testing/testing5.py +6 -0
  274. pythonlings/curriculum/checks/testing/testing6.py +14 -0
  275. pythonlings/curriculum/checks/testing/testing7.py +14 -0
  276. pythonlings/curriculum/checks/testing/testing8.py +27 -0
  277. pythonlings/curriculum/checks/testing/testing9.py +14 -0
  278. pythonlings/curriculum/checks/tuples/tuples1.py +3 -0
  279. pythonlings/curriculum/checks/tuples/tuples10.py +6 -0
  280. pythonlings/curriculum/checks/tuples/tuples2.py +3 -0
  281. pythonlings/curriculum/checks/tuples/tuples3.py +4 -0
  282. pythonlings/curriculum/checks/tuples/tuples4.py +3 -0
  283. pythonlings/curriculum/checks/tuples/tuples5.py +4 -0
  284. pythonlings/curriculum/checks/tuples/tuples6.py +5 -0
  285. pythonlings/curriculum/checks/tuples/tuples7.py +3 -0
  286. pythonlings/curriculum/checks/tuples/tuples8.py +4 -0
  287. pythonlings/curriculum/checks/tuples/tuples9.py +5 -0
  288. pythonlings/curriculum/checks/type_hints/type_hints1.py +3 -0
  289. pythonlings/curriculum/checks/type_hints/type_hints2.py +5 -0
  290. pythonlings/curriculum/checks/type_hints/type_hints3.py +5 -0
  291. pythonlings/curriculum/checks/type_hints/type_hints4.py +5 -0
  292. pythonlings/curriculum/checks/type_hints/type_hints5.py +6 -0
  293. pythonlings/curriculum/checks/type_hints/type_hints6.py +7 -0
  294. pythonlings/curriculum/checks/type_hints/type_hints7.py +9 -0
  295. pythonlings/curriculum/checks/type_hints/type_hints8.py +9 -0
  296. pythonlings/curriculum/checks/variables/variables1.py +7 -0
  297. pythonlings/curriculum/checks/variables/variables10.py +4 -0
  298. pythonlings/curriculum/checks/variables/variables2.py +19 -0
  299. pythonlings/curriculum/checks/variables/variables3.py +4 -0
  300. pythonlings/curriculum/checks/variables/variables4.py +2 -0
  301. pythonlings/curriculum/checks/variables/variables5.py +2 -0
  302. pythonlings/curriculum/checks/variables/variables6.py +4 -0
  303. pythonlings/curriculum/checks/variables/variables7.py +3 -0
  304. pythonlings/curriculum/checks/variables/variables8.py +4 -0
  305. pythonlings/curriculum/checks/variables/variables9.py +3 -0
  306. pythonlings/curriculum/exercises/async/async1.py +7 -0
  307. pythonlings/curriculum/exercises/async/async10.py +14 -0
  308. pythonlings/curriculum/exercises/async/async2.py +10 -0
  309. pythonlings/curriculum/exercises/async/async3.py +10 -0
  310. pythonlings/curriculum/exercises/async/async4.py +15 -0
  311. pythonlings/curriculum/exercises/async/async5.py +13 -0
  312. pythonlings/curriculum/exercises/async/async6.py +14 -0
  313. pythonlings/curriculum/exercises/async/async7.py +13 -0
  314. pythonlings/curriculum/exercises/async/async8.py +11 -0
  315. pythonlings/curriculum/exercises/async/async9.py +13 -0
  316. pythonlings/curriculum/exercises/classes/classes1.py +13 -0
  317. pythonlings/curriculum/exercises/classes/classes10.py +22 -0
  318. pythonlings/curriculum/exercises/classes/classes11.py +24 -0
  319. pythonlings/curriculum/exercises/classes/classes12.py +33 -0
  320. pythonlings/curriculum/exercises/classes/classes2.py +13 -0
  321. pythonlings/curriculum/exercises/classes/classes3.py +13 -0
  322. pythonlings/curriculum/exercises/classes/classes4.py +16 -0
  323. pythonlings/curriculum/exercises/classes/classes5.py +18 -0
  324. pythonlings/curriculum/exercises/classes/classes6.py +15 -0
  325. pythonlings/curriculum/exercises/classes/classes7.py +18 -0
  326. pythonlings/curriculum/exercises/classes/classes8.py +14 -0
  327. pythonlings/curriculum/exercises/classes/classes9.py +18 -0
  328. pythonlings/curriculum/exercises/collections/collections1.py +11 -0
  329. pythonlings/curriculum/exercises/collections/collections10.py +37 -0
  330. pythonlings/curriculum/exercises/collections/collections2.py +18 -0
  331. pythonlings/curriculum/exercises/collections/collections3.py +17 -0
  332. pythonlings/curriculum/exercises/collections/collections4.py +26 -0
  333. pythonlings/curriculum/exercises/collections/collections5.py +14 -0
  334. pythonlings/curriculum/exercises/collections/collections6.py +18 -0
  335. pythonlings/curriculum/exercises/collections/collections7.py +20 -0
  336. pythonlings/curriculum/exercises/collections/collections8.py +23 -0
  337. pythonlings/curriculum/exercises/collections/collections9.py +21 -0
  338. pythonlings/curriculum/exercises/comprehensions/comprehensions1.py +10 -0
  339. pythonlings/curriculum/exercises/comprehensions/comprehensions10.py +15 -0
  340. pythonlings/curriculum/exercises/comprehensions/comprehensions2.py +12 -0
  341. pythonlings/curriculum/exercises/comprehensions/comprehensions3.py +12 -0
  342. pythonlings/curriculum/exercises/comprehensions/comprehensions4.py +14 -0
  343. pythonlings/curriculum/exercises/comprehensions/comprehensions5.py +12 -0
  344. pythonlings/curriculum/exercises/comprehensions/comprehensions6.py +12 -0
  345. pythonlings/curriculum/exercises/comprehensions/comprehensions7.py +12 -0
  346. pythonlings/curriculum/exercises/comprehensions/comprehensions8.py +15 -0
  347. pythonlings/curriculum/exercises/comprehensions/comprehensions9.py +13 -0
  348. pythonlings/curriculum/exercises/conditionals/conditionals1.py +15 -0
  349. pythonlings/curriculum/exercises/conditionals/conditionals10.py +18 -0
  350. pythonlings/curriculum/exercises/conditionals/conditionals2.py +13 -0
  351. pythonlings/curriculum/exercises/conditionals/conditionals3.py +18 -0
  352. pythonlings/curriculum/exercises/conditionals/conditionals4.py +20 -0
  353. pythonlings/curriculum/exercises/conditionals/conditionals5.py +17 -0
  354. pythonlings/curriculum/exercises/conditionals/conditionals6.py +15 -0
  355. pythonlings/curriculum/exercises/conditionals/conditionals7.py +18 -0
  356. pythonlings/curriculum/exercises/conditionals/conditionals8.py +20 -0
  357. pythonlings/curriculum/exercises/conditionals/conditionals9.py +12 -0
  358. pythonlings/curriculum/exercises/context_managers/context_managers1.py +18 -0
  359. pythonlings/curriculum/exercises/context_managers/context_managers2.py +19 -0
  360. pythonlings/curriculum/exercises/context_managers/context_managers3.py +24 -0
  361. pythonlings/curriculum/exercises/context_managers/context_managers4.py +30 -0
  362. pythonlings/curriculum/exercises/context_managers/context_managers5.py +30 -0
  363. pythonlings/curriculum/exercises/context_managers/context_managers6.py +26 -0
  364. pythonlings/curriculum/exercises/context_managers/context_managers7.py +30 -0
  365. pythonlings/curriculum/exercises/context_managers/context_managers8.py +45 -0
  366. pythonlings/curriculum/exercises/dataclasses/dataclasses1.py +14 -0
  367. pythonlings/curriculum/exercises/dataclasses/dataclasses2.py +23 -0
  368. pythonlings/curriculum/exercises/dataclasses/dataclasses3.py +21 -0
  369. pythonlings/curriculum/exercises/dataclasses/dataclasses4.py +25 -0
  370. pythonlings/curriculum/exercises/dataclasses/dataclasses5.py +25 -0
  371. pythonlings/curriculum/exercises/dataclasses/dataclasses6.py +21 -0
  372. pythonlings/curriculum/exercises/dataclasses/dataclasses7.py +27 -0
  373. pythonlings/curriculum/exercises/dataclasses/dataclasses8.py +30 -0
  374. pythonlings/curriculum/exercises/datetime/datetime1.py +8 -0
  375. pythonlings/curriculum/exercises/datetime/datetime2.py +9 -0
  376. pythonlings/curriculum/exercises/datetime/datetime3.py +9 -0
  377. pythonlings/curriculum/exercises/datetime/datetime4.py +9 -0
  378. pythonlings/curriculum/exercises/datetime/datetime5.py +10 -0
  379. pythonlings/curriculum/exercises/datetime/datetime6.py +10 -0
  380. pythonlings/curriculum/exercises/datetime/datetime7.py +10 -0
  381. pythonlings/curriculum/exercises/datetime/datetime8.py +11 -0
  382. pythonlings/curriculum/exercises/decorators/decorators1.py +19 -0
  383. pythonlings/curriculum/exercises/decorators/decorators10.py +32 -0
  384. pythonlings/curriculum/exercises/decorators/decorators2.py +22 -0
  385. pythonlings/curriculum/exercises/decorators/decorators3.py +18 -0
  386. pythonlings/curriculum/exercises/decorators/decorators4.py +24 -0
  387. pythonlings/curriculum/exercises/decorators/decorators5.py +25 -0
  388. pythonlings/curriculum/exercises/decorators/decorators6.py +19 -0
  389. pythonlings/curriculum/exercises/decorators/decorators7.py +25 -0
  390. pythonlings/curriculum/exercises/decorators/decorators8.py +25 -0
  391. pythonlings/curriculum/exercises/decorators/decorators9.py +26 -0
  392. pythonlings/curriculum/exercises/dictionaries/dictionaries1.py +6 -0
  393. pythonlings/curriculum/exercises/dictionaries/dictionaries10.py +17 -0
  394. pythonlings/curriculum/exercises/dictionaries/dictionaries2.py +9 -0
  395. pythonlings/curriculum/exercises/dictionaries/dictionaries3.py +16 -0
  396. pythonlings/curriculum/exercises/dictionaries/dictionaries4.py +15 -0
  397. pythonlings/curriculum/exercises/dictionaries/dictionaries5.py +15 -0
  398. pythonlings/curriculum/exercises/dictionaries/dictionaries6.py +18 -0
  399. pythonlings/curriculum/exercises/dictionaries/dictionaries7.py +17 -0
  400. pythonlings/curriculum/exercises/dictionaries/dictionaries8.py +17 -0
  401. pythonlings/curriculum/exercises/dictionaries/dictionaries9.py +25 -0
  402. pythonlings/curriculum/exercises/enums/enums1.py +12 -0
  403. pythonlings/curriculum/exercises/enums/enums2.py +11 -0
  404. pythonlings/curriculum/exercises/enums/enums3.py +14 -0
  405. pythonlings/curriculum/exercises/enums/enums4.py +13 -0
  406. pythonlings/curriculum/exercises/enums/enums5.py +14 -0
  407. pythonlings/curriculum/exercises/enums/enums6.py +15 -0
  408. pythonlings/curriculum/exercises/exceptions/exceptions1.py +15 -0
  409. pythonlings/curriculum/exercises/exceptions/exceptions10.py +19 -0
  410. pythonlings/curriculum/exercises/exceptions/exceptions2.py +12 -0
  411. pythonlings/curriculum/exercises/exceptions/exceptions3.py +13 -0
  412. pythonlings/curriculum/exercises/exceptions/exceptions4.py +17 -0
  413. pythonlings/curriculum/exercises/exceptions/exceptions5.py +20 -0
  414. pythonlings/curriculum/exercises/exceptions/exceptions6.py +13 -0
  415. pythonlings/curriculum/exercises/exceptions/exceptions7.py +15 -0
  416. pythonlings/curriculum/exercises/exceptions/exceptions8.py +17 -0
  417. pythonlings/curriculum/exercises/exceptions/exceptions9.py +20 -0
  418. pythonlings/curriculum/exercises/file_io/file_io1.py +18 -0
  419. pythonlings/curriculum/exercises/file_io/file_io10.py +25 -0
  420. pythonlings/curriculum/exercises/file_io/file_io2.py +16 -0
  421. pythonlings/curriculum/exercises/file_io/file_io3.py +18 -0
  422. pythonlings/curriculum/exercises/file_io/file_io4.py +21 -0
  423. pythonlings/curriculum/exercises/file_io/file_io5.py +19 -0
  424. pythonlings/curriculum/exercises/file_io/file_io6.py +22 -0
  425. pythonlings/curriculum/exercises/file_io/file_io7.py +20 -0
  426. pythonlings/curriculum/exercises/file_io/file_io8.py +18 -0
  427. pythonlings/curriculum/exercises/file_io/file_io9.py +19 -0
  428. pythonlings/curriculum/exercises/functional/functional1.py +7 -0
  429. pythonlings/curriculum/exercises/functional/functional10.py +19 -0
  430. pythonlings/curriculum/exercises/functional/functional2.py +8 -0
  431. pythonlings/curriculum/exercises/functional/functional3.py +11 -0
  432. pythonlings/curriculum/exercises/functional/functional4.py +11 -0
  433. pythonlings/curriculum/exercises/functional/functional5.py +11 -0
  434. pythonlings/curriculum/exercises/functional/functional6.py +14 -0
  435. pythonlings/curriculum/exercises/functional/functional7.py +12 -0
  436. pythonlings/curriculum/exercises/functional/functional8.py +13 -0
  437. pythonlings/curriculum/exercises/functional/functional9.py +15 -0
  438. pythonlings/curriculum/exercises/functions/functions1.py +8 -0
  439. pythonlings/curriculum/exercises/functions/functions10.py +19 -0
  440. pythonlings/curriculum/exercises/functions/functions2.py +9 -0
  441. pythonlings/curriculum/exercises/functions/functions3.py +8 -0
  442. pythonlings/curriculum/exercises/functions/functions4.py +8 -0
  443. pythonlings/curriculum/exercises/functions/functions5.py +11 -0
  444. pythonlings/curriculum/exercises/functions/functions6.py +16 -0
  445. pythonlings/curriculum/exercises/functions/functions7.py +11 -0
  446. pythonlings/curriculum/exercises/functions/functions8.py +10 -0
  447. pythonlings/curriculum/exercises/functions/functions9.py +16 -0
  448. pythonlings/curriculum/exercises/generators/generators1.py +13 -0
  449. pythonlings/curriculum/exercises/generators/generators10.py +16 -0
  450. pythonlings/curriculum/exercises/generators/generators2.py +17 -0
  451. pythonlings/curriculum/exercises/generators/generators3.py +19 -0
  452. pythonlings/curriculum/exercises/generators/generators4.py +12 -0
  453. pythonlings/curriculum/exercises/generators/generators5.py +24 -0
  454. pythonlings/curriculum/exercises/generators/generators6.py +20 -0
  455. pythonlings/curriculum/exercises/generators/generators7.py +14 -0
  456. pythonlings/curriculum/exercises/generators/generators8.py +17 -0
  457. pythonlings/curriculum/exercises/generators/generators9.py +26 -0
  458. pythonlings/curriculum/exercises/itertools/itertools1.py +10 -0
  459. pythonlings/curriculum/exercises/itertools/itertools2.py +8 -0
  460. pythonlings/curriculum/exercises/itertools/itertools3.py +10 -0
  461. pythonlings/curriculum/exercises/itertools/itertools4.py +12 -0
  462. pythonlings/curriculum/exercises/itertools/itertools5.py +9 -0
  463. pythonlings/curriculum/exercises/itertools/itertools6.py +9 -0
  464. pythonlings/curriculum/exercises/itertools/itertools7.py +10 -0
  465. pythonlings/curriculum/exercises/itertools/itertools8.py +18 -0
  466. pythonlings/curriculum/exercises/json/json1.py +10 -0
  467. pythonlings/curriculum/exercises/json/json2.py +9 -0
  468. pythonlings/curriculum/exercises/json/json3.py +10 -0
  469. pythonlings/curriculum/exercises/json/json4.py +13 -0
  470. pythonlings/curriculum/exercises/json/json5.py +9 -0
  471. pythonlings/curriculum/exercises/json/json6.py +10 -0
  472. pythonlings/curriculum/exercises/json/json7.py +10 -0
  473. pythonlings/curriculum/exercises/json/json8.py +12 -0
  474. pythonlings/curriculum/exercises/lists/lists1.py +7 -0
  475. pythonlings/curriculum/exercises/lists/lists10.py +28 -0
  476. pythonlings/curriculum/exercises/lists/lists2.py +13 -0
  477. pythonlings/curriculum/exercises/lists/lists3.py +16 -0
  478. pythonlings/curriculum/exercises/lists/lists4.py +16 -0
  479. pythonlings/curriculum/exercises/lists/lists5.py +16 -0
  480. pythonlings/curriculum/exercises/lists/lists6.py +15 -0
  481. pythonlings/curriculum/exercises/lists/lists7.py +13 -0
  482. pythonlings/curriculum/exercises/lists/lists8.py +15 -0
  483. pythonlings/curriculum/exercises/lists/lists9.py +19 -0
  484. pythonlings/curriculum/exercises/loops/loops1.py +8 -0
  485. pythonlings/curriculum/exercises/loops/loops10.py +22 -0
  486. pythonlings/curriculum/exercises/loops/loops2.py +10 -0
  487. pythonlings/curriculum/exercises/loops/loops3.py +10 -0
  488. pythonlings/curriculum/exercises/loops/loops4.py +12 -0
  489. pythonlings/curriculum/exercises/loops/loops5.py +13 -0
  490. pythonlings/curriculum/exercises/loops/loops6.py +10 -0
  491. pythonlings/curriculum/exercises/loops/loops7.py +13 -0
  492. pythonlings/curriculum/exercises/loops/loops8.py +11 -0
  493. pythonlings/curriculum/exercises/loops/loops9.py +11 -0
  494. pythonlings/curriculum/exercises/modules/modules1.py +10 -0
  495. pythonlings/curriculum/exercises/modules/modules2.py +10 -0
  496. pythonlings/curriculum/exercises/modules/modules3.py +13 -0
  497. pythonlings/curriculum/exercises/modules/modules4.py +18 -0
  498. pythonlings/curriculum/exercises/modules/modules5.py +17 -0
  499. pythonlings/curriculum/exercises/modules/modules6.py +12 -0
  500. pythonlings/curriculum/exercises/modules/modules7.py +16 -0
  501. pythonlings/curriculum/exercises/modules/modules8.py +23 -0
  502. pythonlings/curriculum/exercises/oop_advanced/oop_advanced1.py +11 -0
  503. pythonlings/curriculum/exercises/oop_advanced/oop_advanced10.py +18 -0
  504. pythonlings/curriculum/exercises/oop_advanced/oop_advanced11.py +13 -0
  505. pythonlings/curriculum/exercises/oop_advanced/oop_advanced12.py +12 -0
  506. pythonlings/curriculum/exercises/oop_advanced/oop_advanced2.py +13 -0
  507. pythonlings/curriculum/exercises/oop_advanced/oop_advanced3.py +22 -0
  508. pythonlings/curriculum/exercises/oop_advanced/oop_advanced4.py +12 -0
  509. pythonlings/curriculum/exercises/oop_advanced/oop_advanced5.py +11 -0
  510. pythonlings/curriculum/exercises/oop_advanced/oop_advanced6.py +12 -0
  511. pythonlings/curriculum/exercises/oop_advanced/oop_advanced7.py +14 -0
  512. pythonlings/curriculum/exercises/oop_advanced/oop_advanced8.py +14 -0
  513. pythonlings/curriculum/exercises/oop_advanced/oop_advanced9.py +9 -0
  514. pythonlings/curriculum/exercises/pathlib/pathlib1.py +9 -0
  515. pythonlings/curriculum/exercises/pathlib/pathlib2.py +9 -0
  516. pythonlings/curriculum/exercises/pathlib/pathlib3.py +11 -0
  517. pythonlings/curriculum/exercises/pathlib/pathlib4.py +9 -0
  518. pythonlings/curriculum/exercises/pathlib/pathlib5.py +9 -0
  519. pythonlings/curriculum/exercises/pathlib/pathlib6.py +10 -0
  520. pythonlings/curriculum/exercises/recursion/recursion1.py +12 -0
  521. pythonlings/curriculum/exercises/recursion/recursion2.py +12 -0
  522. pythonlings/curriculum/exercises/recursion/recursion3.py +12 -0
  523. pythonlings/curriculum/exercises/recursion/recursion4.py +12 -0
  524. pythonlings/curriculum/exercises/recursion/recursion5.py +14 -0
  525. pythonlings/curriculum/exercises/recursion/recursion6.py +13 -0
  526. pythonlings/curriculum/exercises/recursion/recursion7.py +20 -0
  527. pythonlings/curriculum/exercises/recursion/recursion8.py +27 -0
  528. pythonlings/curriculum/exercises/regex/regex1.py +16 -0
  529. pythonlings/curriculum/exercises/regex/regex10.py +31 -0
  530. pythonlings/curriculum/exercises/regex/regex2.py +16 -0
  531. pythonlings/curriculum/exercises/regex/regex3.py +16 -0
  532. pythonlings/curriculum/exercises/regex/regex4.py +19 -0
  533. pythonlings/curriculum/exercises/regex/regex5.py +19 -0
  534. pythonlings/curriculum/exercises/regex/regex6.py +23 -0
  535. pythonlings/curriculum/exercises/regex/regex7.py +24 -0
  536. pythonlings/curriculum/exercises/regex/regex8.py +19 -0
  537. pythonlings/curriculum/exercises/regex/regex9.py +22 -0
  538. pythonlings/curriculum/exercises/sets/sets1.py +6 -0
  539. pythonlings/curriculum/exercises/sets/sets10.py +21 -0
  540. pythonlings/curriculum/exercises/sets/sets2.py +12 -0
  541. pythonlings/curriculum/exercises/sets/sets3.py +15 -0
  542. pythonlings/curriculum/exercises/sets/sets4.py +14 -0
  543. pythonlings/curriculum/exercises/sets/sets5.py +14 -0
  544. pythonlings/curriculum/exercises/sets/sets6.py +14 -0
  545. pythonlings/curriculum/exercises/sets/sets7.py +16 -0
  546. pythonlings/curriculum/exercises/sets/sets8.py +16 -0
  547. pythonlings/curriculum/exercises/sets/sets9.py +15 -0
  548. pythonlings/curriculum/exercises/strings/strings1.py +6 -0
  549. pythonlings/curriculum/exercises/strings/strings10.py +11 -0
  550. pythonlings/curriculum/exercises/strings/strings2.py +9 -0
  551. pythonlings/curriculum/exercises/strings/strings3.py +9 -0
  552. pythonlings/curriculum/exercises/strings/strings4.py +8 -0
  553. pythonlings/curriculum/exercises/strings/strings5.py +10 -0
  554. pythonlings/curriculum/exercises/strings/strings6.py +10 -0
  555. pythonlings/curriculum/exercises/strings/strings7.py +10 -0
  556. pythonlings/curriculum/exercises/strings/strings8.py +9 -0
  557. pythonlings/curriculum/exercises/strings/strings9.py +10 -0
  558. pythonlings/curriculum/exercises/testing/testing1.py +16 -0
  559. pythonlings/curriculum/exercises/testing/testing10.py +21 -0
  560. pythonlings/curriculum/exercises/testing/testing11.py +27 -0
  561. pythonlings/curriculum/exercises/testing/testing12.py +51 -0
  562. pythonlings/curriculum/exercises/testing/testing2.py +15 -0
  563. pythonlings/curriculum/exercises/testing/testing3.py +19 -0
  564. pythonlings/curriculum/exercises/testing/testing4.py +19 -0
  565. pythonlings/curriculum/exercises/testing/testing5.py +18 -0
  566. pythonlings/curriculum/exercises/testing/testing6.py +27 -0
  567. pythonlings/curriculum/exercises/testing/testing7.py +27 -0
  568. pythonlings/curriculum/exercises/testing/testing8.py +29 -0
  569. pythonlings/curriculum/exercises/testing/testing9.py +30 -0
  570. pythonlings/curriculum/exercises/tuples/tuples1.py +7 -0
  571. pythonlings/curriculum/exercises/tuples/tuples10.py +26 -0
  572. pythonlings/curriculum/exercises/tuples/tuples2.py +11 -0
  573. pythonlings/curriculum/exercises/tuples/tuples3.py +9 -0
  574. pythonlings/curriculum/exercises/tuples/tuples4.py +8 -0
  575. pythonlings/curriculum/exercises/tuples/tuples5.py +12 -0
  576. pythonlings/curriculum/exercises/tuples/tuples6.py +15 -0
  577. pythonlings/curriculum/exercises/tuples/tuples7.py +14 -0
  578. pythonlings/curriculum/exercises/tuples/tuples8.py +13 -0
  579. pythonlings/curriculum/exercises/tuples/tuples9.py +18 -0
  580. pythonlings/curriculum/exercises/type_hints/type_hints1.py +9 -0
  581. pythonlings/curriculum/exercises/type_hints/type_hints2.py +13 -0
  582. pythonlings/curriculum/exercises/type_hints/type_hints3.py +13 -0
  583. pythonlings/curriculum/exercises/type_hints/type_hints4.py +21 -0
  584. pythonlings/curriculum/exercises/type_hints/type_hints5.py +15 -0
  585. pythonlings/curriculum/exercises/type_hints/type_hints6.py +16 -0
  586. pythonlings/curriculum/exercises/type_hints/type_hints7.py +19 -0
  587. pythonlings/curriculum/exercises/type_hints/type_hints8.py +27 -0
  588. pythonlings/curriculum/exercises/variables/variables1.py +10 -0
  589. pythonlings/curriculum/exercises/variables/variables10.py +14 -0
  590. pythonlings/curriculum/exercises/variables/variables2.py +11 -0
  591. pythonlings/curriculum/exercises/variables/variables3.py +11 -0
  592. pythonlings/curriculum/exercises/variables/variables4.py +9 -0
  593. pythonlings/curriculum/exercises/variables/variables5.py +11 -0
  594. pythonlings/curriculum/exercises/variables/variables6.py +9 -0
  595. pythonlings/curriculum/exercises/variables/variables7.py +10 -0
  596. pythonlings/curriculum/exercises/variables/variables8.py +12 -0
  597. pythonlings/curriculum/exercises/variables/variables9.py +10 -0
  598. pythonlings/curriculum/info.toml +1755 -0
  599. pythonlings/curriculum/solutions/.keep +1 -0
  600. pythonlings/curriculum/solutions/_answers.py +1654 -0
  601. pythonlings/curriculum/solutions/async1.py +2 -0
  602. pythonlings/curriculum/solutions/async10.py +2 -0
  603. pythonlings/curriculum/solutions/async2.py +2 -0
  604. pythonlings/curriculum/solutions/async3.py +2 -0
  605. pythonlings/curriculum/solutions/async4.py +2 -0
  606. pythonlings/curriculum/solutions/async5.py +2 -0
  607. pythonlings/curriculum/solutions/async6.py +2 -0
  608. pythonlings/curriculum/solutions/async7.py +2 -0
  609. pythonlings/curriculum/solutions/async8.py +2 -0
  610. pythonlings/curriculum/solutions/async9.py +2 -0
  611. pythonlings/curriculum/solutions/classes1.py +2 -0
  612. pythonlings/curriculum/solutions/classes10.py +2 -0
  613. pythonlings/curriculum/solutions/classes11.py +2 -0
  614. pythonlings/curriculum/solutions/classes12.py +2 -0
  615. pythonlings/curriculum/solutions/classes2.py +2 -0
  616. pythonlings/curriculum/solutions/classes3.py +2 -0
  617. pythonlings/curriculum/solutions/classes4.py +2 -0
  618. pythonlings/curriculum/solutions/classes5.py +2 -0
  619. pythonlings/curriculum/solutions/classes6.py +2 -0
  620. pythonlings/curriculum/solutions/classes7.py +2 -0
  621. pythonlings/curriculum/solutions/classes8.py +2 -0
  622. pythonlings/curriculum/solutions/classes9.py +2 -0
  623. pythonlings/curriculum/solutions/collections1.py +2 -0
  624. pythonlings/curriculum/solutions/collections10.py +2 -0
  625. pythonlings/curriculum/solutions/collections2.py +2 -0
  626. pythonlings/curriculum/solutions/collections3.py +2 -0
  627. pythonlings/curriculum/solutions/collections4.py +2 -0
  628. pythonlings/curriculum/solutions/collections5.py +2 -0
  629. pythonlings/curriculum/solutions/collections6.py +2 -0
  630. pythonlings/curriculum/solutions/collections7.py +2 -0
  631. pythonlings/curriculum/solutions/collections8.py +2 -0
  632. pythonlings/curriculum/solutions/collections9.py +2 -0
  633. pythonlings/curriculum/solutions/comprehensions1.py +2 -0
  634. pythonlings/curriculum/solutions/comprehensions10.py +2 -0
  635. pythonlings/curriculum/solutions/comprehensions2.py +2 -0
  636. pythonlings/curriculum/solutions/comprehensions3.py +2 -0
  637. pythonlings/curriculum/solutions/comprehensions4.py +2 -0
  638. pythonlings/curriculum/solutions/comprehensions5.py +2 -0
  639. pythonlings/curriculum/solutions/comprehensions6.py +2 -0
  640. pythonlings/curriculum/solutions/comprehensions7.py +2 -0
  641. pythonlings/curriculum/solutions/comprehensions8.py +2 -0
  642. pythonlings/curriculum/solutions/comprehensions9.py +2 -0
  643. pythonlings/curriculum/solutions/conditionals1.py +2 -0
  644. pythonlings/curriculum/solutions/conditionals10.py +2 -0
  645. pythonlings/curriculum/solutions/conditionals2.py +2 -0
  646. pythonlings/curriculum/solutions/conditionals3.py +2 -0
  647. pythonlings/curriculum/solutions/conditionals4.py +2 -0
  648. pythonlings/curriculum/solutions/conditionals5.py +2 -0
  649. pythonlings/curriculum/solutions/conditionals6.py +2 -0
  650. pythonlings/curriculum/solutions/conditionals7.py +2 -0
  651. pythonlings/curriculum/solutions/conditionals8.py +2 -0
  652. pythonlings/curriculum/solutions/conditionals9.py +2 -0
  653. pythonlings/curriculum/solutions/context_managers1.py +2 -0
  654. pythonlings/curriculum/solutions/context_managers2.py +2 -0
  655. pythonlings/curriculum/solutions/context_managers3.py +2 -0
  656. pythonlings/curriculum/solutions/context_managers4.py +2 -0
  657. pythonlings/curriculum/solutions/context_managers5.py +2 -0
  658. pythonlings/curriculum/solutions/context_managers6.py +2 -0
  659. pythonlings/curriculum/solutions/context_managers7.py +2 -0
  660. pythonlings/curriculum/solutions/context_managers8.py +2 -0
  661. pythonlings/curriculum/solutions/dataclasses1.py +2 -0
  662. pythonlings/curriculum/solutions/dataclasses2.py +2 -0
  663. pythonlings/curriculum/solutions/dataclasses3.py +2 -0
  664. pythonlings/curriculum/solutions/dataclasses4.py +2 -0
  665. pythonlings/curriculum/solutions/dataclasses5.py +2 -0
  666. pythonlings/curriculum/solutions/dataclasses6.py +2 -0
  667. pythonlings/curriculum/solutions/dataclasses7.py +2 -0
  668. pythonlings/curriculum/solutions/dataclasses8.py +2 -0
  669. pythonlings/curriculum/solutions/datetime1.py +2 -0
  670. pythonlings/curriculum/solutions/datetime2.py +2 -0
  671. pythonlings/curriculum/solutions/datetime3.py +2 -0
  672. pythonlings/curriculum/solutions/datetime4.py +2 -0
  673. pythonlings/curriculum/solutions/datetime5.py +2 -0
  674. pythonlings/curriculum/solutions/datetime6.py +2 -0
  675. pythonlings/curriculum/solutions/datetime7.py +2 -0
  676. pythonlings/curriculum/solutions/datetime8.py +2 -0
  677. pythonlings/curriculum/solutions/decorators1.py +2 -0
  678. pythonlings/curriculum/solutions/decorators10.py +2 -0
  679. pythonlings/curriculum/solutions/decorators2.py +2 -0
  680. pythonlings/curriculum/solutions/decorators3.py +2 -0
  681. pythonlings/curriculum/solutions/decorators4.py +2 -0
  682. pythonlings/curriculum/solutions/decorators5.py +2 -0
  683. pythonlings/curriculum/solutions/decorators6.py +2 -0
  684. pythonlings/curriculum/solutions/decorators7.py +2 -0
  685. pythonlings/curriculum/solutions/decorators8.py +2 -0
  686. pythonlings/curriculum/solutions/decorators9.py +2 -0
  687. pythonlings/curriculum/solutions/dictionaries1.py +2 -0
  688. pythonlings/curriculum/solutions/dictionaries10.py +2 -0
  689. pythonlings/curriculum/solutions/dictionaries2.py +2 -0
  690. pythonlings/curriculum/solutions/dictionaries3.py +2 -0
  691. pythonlings/curriculum/solutions/dictionaries4.py +2 -0
  692. pythonlings/curriculum/solutions/dictionaries5.py +2 -0
  693. pythonlings/curriculum/solutions/dictionaries6.py +2 -0
  694. pythonlings/curriculum/solutions/dictionaries7.py +2 -0
  695. pythonlings/curriculum/solutions/dictionaries8.py +2 -0
  696. pythonlings/curriculum/solutions/dictionaries9.py +2 -0
  697. pythonlings/curriculum/solutions/enums1.py +2 -0
  698. pythonlings/curriculum/solutions/enums2.py +2 -0
  699. pythonlings/curriculum/solutions/enums3.py +2 -0
  700. pythonlings/curriculum/solutions/enums4.py +2 -0
  701. pythonlings/curriculum/solutions/enums5.py +2 -0
  702. pythonlings/curriculum/solutions/enums6.py +2 -0
  703. pythonlings/curriculum/solutions/exceptions1.py +2 -0
  704. pythonlings/curriculum/solutions/exceptions10.py +2 -0
  705. pythonlings/curriculum/solutions/exceptions2.py +2 -0
  706. pythonlings/curriculum/solutions/exceptions3.py +2 -0
  707. pythonlings/curriculum/solutions/exceptions4.py +2 -0
  708. pythonlings/curriculum/solutions/exceptions5.py +2 -0
  709. pythonlings/curriculum/solutions/exceptions6.py +2 -0
  710. pythonlings/curriculum/solutions/exceptions7.py +2 -0
  711. pythonlings/curriculum/solutions/exceptions8.py +2 -0
  712. pythonlings/curriculum/solutions/exceptions9.py +2 -0
  713. pythonlings/curriculum/solutions/file_io1.py +2 -0
  714. pythonlings/curriculum/solutions/file_io10.py +2 -0
  715. pythonlings/curriculum/solutions/file_io2.py +2 -0
  716. pythonlings/curriculum/solutions/file_io3.py +2 -0
  717. pythonlings/curriculum/solutions/file_io4.py +2 -0
  718. pythonlings/curriculum/solutions/file_io5.py +2 -0
  719. pythonlings/curriculum/solutions/file_io6.py +2 -0
  720. pythonlings/curriculum/solutions/file_io7.py +2 -0
  721. pythonlings/curriculum/solutions/file_io8.py +2 -0
  722. pythonlings/curriculum/solutions/file_io9.py +2 -0
  723. pythonlings/curriculum/solutions/functional1.py +2 -0
  724. pythonlings/curriculum/solutions/functional10.py +2 -0
  725. pythonlings/curriculum/solutions/functional2.py +2 -0
  726. pythonlings/curriculum/solutions/functional3.py +2 -0
  727. pythonlings/curriculum/solutions/functional4.py +2 -0
  728. pythonlings/curriculum/solutions/functional5.py +2 -0
  729. pythonlings/curriculum/solutions/functional6.py +2 -0
  730. pythonlings/curriculum/solutions/functional7.py +2 -0
  731. pythonlings/curriculum/solutions/functional8.py +2 -0
  732. pythonlings/curriculum/solutions/functional9.py +2 -0
  733. pythonlings/curriculum/solutions/functions1.py +2 -0
  734. pythonlings/curriculum/solutions/functions10.py +2 -0
  735. pythonlings/curriculum/solutions/functions2.py +2 -0
  736. pythonlings/curriculum/solutions/functions3.py +2 -0
  737. pythonlings/curriculum/solutions/functions4.py +2 -0
  738. pythonlings/curriculum/solutions/functions5.py +2 -0
  739. pythonlings/curriculum/solutions/functions6.py +2 -0
  740. pythonlings/curriculum/solutions/functions7.py +2 -0
  741. pythonlings/curriculum/solutions/functions8.py +2 -0
  742. pythonlings/curriculum/solutions/functions9.py +2 -0
  743. pythonlings/curriculum/solutions/generators1.py +2 -0
  744. pythonlings/curriculum/solutions/generators10.py +2 -0
  745. pythonlings/curriculum/solutions/generators2.py +2 -0
  746. pythonlings/curriculum/solutions/generators3.py +2 -0
  747. pythonlings/curriculum/solutions/generators4.py +2 -0
  748. pythonlings/curriculum/solutions/generators5.py +2 -0
  749. pythonlings/curriculum/solutions/generators6.py +2 -0
  750. pythonlings/curriculum/solutions/generators7.py +2 -0
  751. pythonlings/curriculum/solutions/generators8.py +2 -0
  752. pythonlings/curriculum/solutions/generators9.py +2 -0
  753. pythonlings/curriculum/solutions/itertools1.py +2 -0
  754. pythonlings/curriculum/solutions/itertools2.py +2 -0
  755. pythonlings/curriculum/solutions/itertools3.py +2 -0
  756. pythonlings/curriculum/solutions/itertools4.py +2 -0
  757. pythonlings/curriculum/solutions/itertools5.py +2 -0
  758. pythonlings/curriculum/solutions/itertools6.py +2 -0
  759. pythonlings/curriculum/solutions/itertools7.py +2 -0
  760. pythonlings/curriculum/solutions/itertools8.py +2 -0
  761. pythonlings/curriculum/solutions/json1.py +2 -0
  762. pythonlings/curriculum/solutions/json2.py +2 -0
  763. pythonlings/curriculum/solutions/json3.py +2 -0
  764. pythonlings/curriculum/solutions/json4.py +2 -0
  765. pythonlings/curriculum/solutions/json5.py +2 -0
  766. pythonlings/curriculum/solutions/json6.py +2 -0
  767. pythonlings/curriculum/solutions/json7.py +2 -0
  768. pythonlings/curriculum/solutions/json8.py +2 -0
  769. pythonlings/curriculum/solutions/lists1.py +2 -0
  770. pythonlings/curriculum/solutions/lists10.py +2 -0
  771. pythonlings/curriculum/solutions/lists2.py +2 -0
  772. pythonlings/curriculum/solutions/lists3.py +2 -0
  773. pythonlings/curriculum/solutions/lists4.py +2 -0
  774. pythonlings/curriculum/solutions/lists5.py +2 -0
  775. pythonlings/curriculum/solutions/lists6.py +2 -0
  776. pythonlings/curriculum/solutions/lists7.py +2 -0
  777. pythonlings/curriculum/solutions/lists8.py +2 -0
  778. pythonlings/curriculum/solutions/lists9.py +2 -0
  779. pythonlings/curriculum/solutions/loops1.py +2 -0
  780. pythonlings/curriculum/solutions/loops10.py +2 -0
  781. pythonlings/curriculum/solutions/loops2.py +2 -0
  782. pythonlings/curriculum/solutions/loops3.py +2 -0
  783. pythonlings/curriculum/solutions/loops4.py +2 -0
  784. pythonlings/curriculum/solutions/loops5.py +2 -0
  785. pythonlings/curriculum/solutions/loops6.py +2 -0
  786. pythonlings/curriculum/solutions/loops7.py +2 -0
  787. pythonlings/curriculum/solutions/loops8.py +2 -0
  788. pythonlings/curriculum/solutions/loops9.py +2 -0
  789. pythonlings/curriculum/solutions/modules1.py +2 -0
  790. pythonlings/curriculum/solutions/modules2.py +2 -0
  791. pythonlings/curriculum/solutions/modules3.py +2 -0
  792. pythonlings/curriculum/solutions/modules4.py +2 -0
  793. pythonlings/curriculum/solutions/modules5.py +2 -0
  794. pythonlings/curriculum/solutions/modules6.py +2 -0
  795. pythonlings/curriculum/solutions/modules7.py +2 -0
  796. pythonlings/curriculum/solutions/modules8.py +2 -0
  797. pythonlings/curriculum/solutions/oop_advanced1.py +2 -0
  798. pythonlings/curriculum/solutions/oop_advanced10.py +2 -0
  799. pythonlings/curriculum/solutions/oop_advanced11.py +2 -0
  800. pythonlings/curriculum/solutions/oop_advanced12.py +2 -0
  801. pythonlings/curriculum/solutions/oop_advanced2.py +2 -0
  802. pythonlings/curriculum/solutions/oop_advanced3.py +2 -0
  803. pythonlings/curriculum/solutions/oop_advanced4.py +2 -0
  804. pythonlings/curriculum/solutions/oop_advanced5.py +2 -0
  805. pythonlings/curriculum/solutions/oop_advanced6.py +2 -0
  806. pythonlings/curriculum/solutions/oop_advanced7.py +2 -0
  807. pythonlings/curriculum/solutions/oop_advanced8.py +2 -0
  808. pythonlings/curriculum/solutions/oop_advanced9.py +2 -0
  809. pythonlings/curriculum/solutions/pathlib1.py +2 -0
  810. pythonlings/curriculum/solutions/pathlib2.py +2 -0
  811. pythonlings/curriculum/solutions/pathlib3.py +2 -0
  812. pythonlings/curriculum/solutions/pathlib4.py +2 -0
  813. pythonlings/curriculum/solutions/pathlib5.py +2 -0
  814. pythonlings/curriculum/solutions/pathlib6.py +2 -0
  815. pythonlings/curriculum/solutions/recursion1.py +2 -0
  816. pythonlings/curriculum/solutions/recursion2.py +2 -0
  817. pythonlings/curriculum/solutions/recursion3.py +2 -0
  818. pythonlings/curriculum/solutions/recursion4.py +2 -0
  819. pythonlings/curriculum/solutions/recursion5.py +2 -0
  820. pythonlings/curriculum/solutions/recursion6.py +2 -0
  821. pythonlings/curriculum/solutions/recursion7.py +2 -0
  822. pythonlings/curriculum/solutions/recursion8.py +2 -0
  823. pythonlings/curriculum/solutions/regex1.py +2 -0
  824. pythonlings/curriculum/solutions/regex10.py +2 -0
  825. pythonlings/curriculum/solutions/regex2.py +2 -0
  826. pythonlings/curriculum/solutions/regex3.py +2 -0
  827. pythonlings/curriculum/solutions/regex4.py +2 -0
  828. pythonlings/curriculum/solutions/regex5.py +2 -0
  829. pythonlings/curriculum/solutions/regex6.py +2 -0
  830. pythonlings/curriculum/solutions/regex7.py +2 -0
  831. pythonlings/curriculum/solutions/regex8.py +2 -0
  832. pythonlings/curriculum/solutions/regex9.py +2 -0
  833. pythonlings/curriculum/solutions/sets1.py +2 -0
  834. pythonlings/curriculum/solutions/sets10.py +2 -0
  835. pythonlings/curriculum/solutions/sets2.py +2 -0
  836. pythonlings/curriculum/solutions/sets3.py +2 -0
  837. pythonlings/curriculum/solutions/sets4.py +2 -0
  838. pythonlings/curriculum/solutions/sets5.py +2 -0
  839. pythonlings/curriculum/solutions/sets6.py +2 -0
  840. pythonlings/curriculum/solutions/sets7.py +2 -0
  841. pythonlings/curriculum/solutions/sets8.py +2 -0
  842. pythonlings/curriculum/solutions/sets9.py +2 -0
  843. pythonlings/curriculum/solutions/strings1.py +2 -0
  844. pythonlings/curriculum/solutions/strings10.py +2 -0
  845. pythonlings/curriculum/solutions/strings2.py +2 -0
  846. pythonlings/curriculum/solutions/strings3.py +2 -0
  847. pythonlings/curriculum/solutions/strings4.py +2 -0
  848. pythonlings/curriculum/solutions/strings5.py +2 -0
  849. pythonlings/curriculum/solutions/strings6.py +2 -0
  850. pythonlings/curriculum/solutions/strings7.py +2 -0
  851. pythonlings/curriculum/solutions/strings8.py +2 -0
  852. pythonlings/curriculum/solutions/strings9.py +2 -0
  853. pythonlings/curriculum/solutions/testing1.py +2 -0
  854. pythonlings/curriculum/solutions/testing10.py +2 -0
  855. pythonlings/curriculum/solutions/testing11.py +2 -0
  856. pythonlings/curriculum/solutions/testing12.py +2 -0
  857. pythonlings/curriculum/solutions/testing2.py +2 -0
  858. pythonlings/curriculum/solutions/testing3.py +2 -0
  859. pythonlings/curriculum/solutions/testing4.py +2 -0
  860. pythonlings/curriculum/solutions/testing5.py +2 -0
  861. pythonlings/curriculum/solutions/testing6.py +2 -0
  862. pythonlings/curriculum/solutions/testing7.py +2 -0
  863. pythonlings/curriculum/solutions/testing8.py +2 -0
  864. pythonlings/curriculum/solutions/testing9.py +2 -0
  865. pythonlings/curriculum/solutions/tuples1.py +2 -0
  866. pythonlings/curriculum/solutions/tuples10.py +2 -0
  867. pythonlings/curriculum/solutions/tuples2.py +2 -0
  868. pythonlings/curriculum/solutions/tuples3.py +2 -0
  869. pythonlings/curriculum/solutions/tuples4.py +2 -0
  870. pythonlings/curriculum/solutions/tuples5.py +2 -0
  871. pythonlings/curriculum/solutions/tuples6.py +2 -0
  872. pythonlings/curriculum/solutions/tuples7.py +2 -0
  873. pythonlings/curriculum/solutions/tuples8.py +2 -0
  874. pythonlings/curriculum/solutions/tuples9.py +2 -0
  875. pythonlings/curriculum/solutions/type_hints1.py +2 -0
  876. pythonlings/curriculum/solutions/type_hints2.py +2 -0
  877. pythonlings/curriculum/solutions/type_hints3.py +2 -0
  878. pythonlings/curriculum/solutions/type_hints4.py +2 -0
  879. pythonlings/curriculum/solutions/type_hints5.py +2 -0
  880. pythonlings/curriculum/solutions/type_hints6.py +2 -0
  881. pythonlings/curriculum/solutions/type_hints7.py +2 -0
  882. pythonlings/curriculum/solutions/type_hints8.py +2 -0
  883. pythonlings/curriculum/solutions/variables1.py +2 -0
  884. pythonlings/curriculum/solutions/variables10.py +2 -0
  885. pythonlings/curriculum/solutions/variables2.py +2 -0
  886. pythonlings/curriculum/solutions/variables3.py +2 -0
  887. pythonlings/curriculum/solutions/variables4.py +2 -0
  888. pythonlings/curriculum/solutions/variables5.py +2 -0
  889. pythonlings/curriculum/solutions/variables6.py +2 -0
  890. pythonlings/curriculum/solutions/variables7.py +2 -0
  891. pythonlings/curriculum/solutions/variables8.py +2 -0
  892. pythonlings/curriculum/solutions/variables9.py +2 -0
  893. pythonlings/docs/NOTICE.md +9 -0
  894. pythonlings/docs/__init__.py +1 -0
  895. pythonlings/docs/index.json +160 -0
  896. pythonlings/docs/topics/__init__.py +1 -0
  897. pythonlings/docs/topics/async.md +97 -0
  898. pythonlings/docs/topics/classes.md +97 -0
  899. pythonlings/docs/topics/collections.md +96 -0
  900. pythonlings/docs/topics/comprehensions.md +97 -0
  901. pythonlings/docs/topics/conditionals.md +88 -0
  902. pythonlings/docs/topics/context_managers.md +97 -0
  903. pythonlings/docs/topics/dataclasses.md +97 -0
  904. pythonlings/docs/topics/datetime.md +97 -0
  905. pythonlings/docs/topics/decorators.md +91 -0
  906. pythonlings/docs/topics/dictionaries.md +96 -0
  907. pythonlings/docs/topics/enums.md +96 -0
  908. pythonlings/docs/topics/exceptions.md +96 -0
  909. pythonlings/docs/topics/file_io.md +96 -0
  910. pythonlings/docs/topics/functional.md +96 -0
  911. pythonlings/docs/topics/functions.md +97 -0
  912. pythonlings/docs/topics/generators.md +97 -0
  913. pythonlings/docs/topics/itertools.md +96 -0
  914. pythonlings/docs/topics/json.md +97 -0
  915. pythonlings/docs/topics/lists.md +97 -0
  916. pythonlings/docs/topics/loops.md +95 -0
  917. pythonlings/docs/topics/modules.md +97 -0
  918. pythonlings/docs/topics/oop_advanced.md +71 -0
  919. pythonlings/docs/topics/pathlib.md +79 -0
  920. pythonlings/docs/topics/recursion.md +73 -0
  921. pythonlings/docs/topics/regex.md +96 -0
  922. pythonlings/docs/topics/sets.md +97 -0
  923. pythonlings/docs/topics/strings.md +96 -0
  924. pythonlings/docs/topics/testing.md +97 -0
  925. pythonlings/docs/topics/tuples.md +97 -0
  926. pythonlings/docs/topics/type_hints.md +97 -0
  927. pythonlings/docs/topics/variables.md +97 -0
  928. pythonlings/pythonlings.tcss +123 -0
  929. pythonlings/screens/__init__.py +0 -0
  930. pythonlings/screens/docs.py +93 -0
  931. pythonlings/screens/topic_picker.py +107 -0
  932. pythonlings/screens/track.py +234 -0
  933. pythonlings/widgets/__init__.py +0 -0
  934. pythonlings/widgets/editor_pane.py +33 -0
  935. pythonlings/widgets/exercise_tree.py +33 -0
  936. pythonlings/widgets/output_panel.py +180 -0
  937. pythonlings/widgets/progress.py +15 -0
  938. pythonlings-0.3.0.dist-info/METADATA +259 -0
  939. pythonlings-0.3.0.dist-info/RECORD +942 -0
  940. pythonlings-0.3.0.dist-info/WHEEL +4 -0
  941. pythonlings-0.3.0.dist-info/entry_points.txt +2 -0
  942. pythonlings-0.3.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,1755 @@
1
+ format_version = 1
2
+ welcome_message = "Welcome to pythonlings! Save a file to re-run its checks."
3
+ final_message = "All exercises complete. 🐍 Nice work."
4
+
5
+ [[exercises]]
6
+ name = "variables1"
7
+ path = "exercises/variables/variables1.py"
8
+ hint = "Declare a, b, c with concrete values of the right type. A bare 0 is an int; 0.0 is a float; \"\" is the empty string."
9
+ docs = "https://docs.python.org/3/tutorial/introduction.html"
10
+
11
+ [[exercises]]
12
+ name = "variables2"
13
+ path = "exercises/variables/variables2.py"
14
+ hint = "a and b are ints; c is a string. Pick values so a + b == 13 and a % b == 1, then check that str(a) + c equals \"10hello\"."
15
+ docs = "https://docs.python.org/3/tutorial/introduction.html"
16
+
17
+ [[exercises]]
18
+ name = "variables3"
19
+ path = "exercises/variables/variables3.py"
20
+ hint = "Python literal types: 7 is an int, 0.5 is a float, and True is a bool."
21
+ docs = "https://docs.python.org/3/tutorial/introduction.html"
22
+
23
+ [[exercises]]
24
+ name = "variables4"
25
+ path = "exercises/variables/variables4.py"
26
+ hint = "A variable can be reassigned any number of times; each new assignment replaces the old value."
27
+ docs = "https://docs.python.org/3/tutorial/introduction.html"
28
+
29
+ [[exercises]]
30
+ name = "variables5"
31
+ path = "exercises/variables/variables5.py"
32
+ hint = "Augmented assignment: += adds, -= subtracts, *= multiplies. Replace each ??? with the right operator."
33
+ docs = "https://docs.python.org/3/tutorial/introduction.html"
34
+
35
+ [[exercises]]
36
+ name = "variables6"
37
+ path = "exercises/variables/variables6.py"
38
+ hint = "Multiple assignment lets you unpack a tuple in one line: x, y = 1, 2"
39
+ docs = "https://docs.python.org/3/tutorial/introduction.html"
40
+
41
+ [[exercises]]
42
+ name = "variables7"
43
+ path = "exercises/variables/variables7.py"
44
+ hint = "Python's tuple-swap idiom: a, b = b, a swaps both values in one statement."
45
+ docs = "https://docs.python.org/3/tutorial/introduction.html"
46
+
47
+ [[exercises]]
48
+ name = "variables8"
49
+ path = "exercises/variables/variables8.py"
50
+ hint = "type(x) returns the type object; int(), str(), and float() convert between types."
51
+ docs = "https://docs.python.org/3/tutorial/introduction.html"
52
+
53
+ [[exercises]]
54
+ name = "variables9"
55
+ path = "exercises/variables/variables9.py"
56
+ hint = "Convention: name constants in ALL_CAPS. Then use TAX_RATE in the price expression."
57
+ docs = "https://docs.python.org/3/tutorial/introduction.html"
58
+
59
+ [[exercises]]
60
+ name = "variables10"
61
+ path = "exercises/variables/variables10.py"
62
+ hint = "Compute each result as a single expression using width and height: area, perimeter, and the Pythagorean diagonal."
63
+ docs = "https://docs.python.org/3/tutorial/introduction.html"
64
+
65
+ [[exercises]]
66
+ name = "strings1"
67
+ path = "exercises/strings/strings1.py"
68
+ hint = "A string literal is written with quotes: greeting = \"hello\""
69
+ docs = "https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str"
70
+
71
+ [[exercises]]
72
+ name = "strings2"
73
+ path = "exercises/strings/strings2.py"
74
+ hint = "Concatenate with +: first + \" \" + last gives you the full name."
75
+ docs = "https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str"
76
+
77
+ [[exercises]]
78
+ name = "strings3"
79
+ path = "exercises/strings/strings3.py"
80
+ hint = "word[0] gives the first character; word[-1] gives the last."
81
+ docs = "https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str"
82
+
83
+ [[exercises]]
84
+ name = "strings4"
85
+ path = "exercises/strings/strings4.py"
86
+ hint = "sentence[4:9] extracts characters at indices 4, 5, 6, 7, 8."
87
+ docs = "https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str"
88
+
89
+ [[exercises]]
90
+ name = "strings5"
91
+ path = "exercises/strings/strings5.py"
92
+ hint = "len(text) counts characters; text.upper() and text.lower() change case."
93
+ docs = "https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str"
94
+
95
+ [[exercises]]
96
+ name = "strings6"
97
+ path = "exercises/strings/strings6.py"
98
+ hint = "raw.strip() removes surrounding whitespace; .replace(old, new) swaps substrings."
99
+ docs = "https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str"
100
+
101
+ [[exercises]]
102
+ name = "strings7"
103
+ path = "exercises/strings/strings7.py"
104
+ hint = "csv_line.split(\",\") splits on commas; \", \".join(items) reassembles with a separator."
105
+ docs = "https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str"
106
+
107
+ [[exercises]]
108
+ name = "strings8"
109
+ path = "exercises/strings/strings8.py"
110
+ hint = "An f-string looks like: f\"Hello, {name}! You are {age} years old.\""
111
+ docs = "https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str"
112
+
113
+ [[exercises]]
114
+ name = "strings9"
115
+ path = "exercises/strings/strings9.py"
116
+ hint = "\"fox\" in sentence returns a bool; sentence.find(\"fox\") returns the start index."
117
+ docs = "https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str"
118
+
119
+ [[exercises]]
120
+ name = "strings10"
121
+ path = "exercises/strings/strings10.py"
122
+ hint = "Use f\"...{price:.2f}\" to format the price to two decimal places."
123
+ docs = "https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str"
124
+
125
+ [[exercises]]
126
+ name = "conditionals1"
127
+ path = "exercises/conditionals/conditionals1.py"
128
+ hint = "Replace ??? with the variable name `is_sunny` — when it is True, the if-block runs."
129
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#if-statements"
130
+
131
+ [[exercises]]
132
+ name = "conditionals2"
133
+ path = "exercises/conditionals/conditionals2.py"
134
+ hint = "Add an `else:` branch after the if-block that returns \"non-positive\"."
135
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#if-statements"
136
+
137
+ [[exercises]]
138
+ name = "conditionals3"
139
+ path = "exercises/conditionals/conditionals3.py"
140
+ hint = "Add `elif score >= 80: return \"B\"` and `elif score >= 70: return \"C\"` before the final `return \"F\"`."
141
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#if-statements"
142
+
143
+ [[exercises]]
144
+ name = "conditionals4"
145
+ path = "exercises/conditionals/conditionals4.py"
146
+ hint = "Replace the two ???s with the comparison operators `<` and `==`."
147
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#if-statements"
148
+
149
+ [[exercises]]
150
+ name = "conditionals5"
151
+ path = "exercises/conditionals/conditionals5.py"
152
+ hint = "Use `and` to require both conditions in can_ride, and `or` to accept either in gets_discount."
153
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#if-statements"
154
+
155
+ [[exercises]]
156
+ name = "conditionals6"
157
+ path = "exercises/conditionals/conditionals6.py"
158
+ hint = "is_closed should return `not is_open`; neither_zero should return `a != 0 and b != 0` or use `not` on each."
159
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#if-statements"
160
+
161
+ [[exercises]]
162
+ name = "conditionals7"
163
+ path = "exercises/conditionals/conditionals7.py"
164
+ hint = "Inside the else block, nest `if is_member: return 8` and `else: return 12`."
165
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#if-statements"
166
+
167
+ [[exercises]]
168
+ name = "conditionals8"
169
+ path = "exercises/conditionals/conditionals8.py"
170
+ hint = "Write `if value:` to test truthiness; add an `else: return \"empty\"` branch."
171
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#if-statements"
172
+
173
+ [[exercises]]
174
+ name = "conditionals9"
175
+ path = "exercises/conditionals/conditionals9.py"
176
+ hint = "The ternary form is: `return n if n >= 0 else -n`."
177
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#if-statements"
178
+
179
+ [[exercises]]
180
+ name = "conditionals10"
181
+ path = "exercises/conditionals/conditionals10.py"
182
+ hint = "Use `if n > 100`, `elif n > 0`, `elif n == 0`, `elif n >= -100`, `else` for the five cases."
183
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#if-statements"
184
+
185
+ [[exercises]]
186
+ name = "loops1"
187
+ path = "exercises/loops/loops1.py"
188
+ hint = "Write `for n in range(1, 6): total += n` to add 1 through 5."
189
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#for-statements"
190
+
191
+ [[exercises]]
192
+ name = "loops2"
193
+ path = "exercises/loops/loops2.py"
194
+ hint = "Loop `for fruit in fruits:` and append `fruit.upper()` to `upper_fruits`."
195
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#for-statements"
196
+
197
+ [[exercises]]
198
+ name = "loops3"
199
+ path = "exercises/loops/loops3.py"
200
+ hint = "Write `while n > 0:`, append `n`, then `n -= 1` to count down."
201
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#for-statements"
202
+
203
+ [[exercises]]
204
+ name = "loops4"
205
+ path = "exercises/loops/loops4.py"
206
+ hint = "Inside one loop use `total += num` and `product *= num` to accumulate both values."
207
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#for-statements"
208
+
209
+ [[exercises]]
210
+ name = "loops5"
211
+ path = "exercises/loops/loops5.py"
212
+ hint = "Inside `while i < len(values):`, check `if values[i] > 10:`, set `found`, then `break`; always increment `i`."
213
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#for-statements"
214
+
215
+ [[exercises]]
216
+ name = "loops6"
217
+ path = "exercises/loops/loops6.py"
218
+ hint = "Inside the loop, `if num % 2 != 0: continue` skips odds; then `evens.append(num)` collects evens."
219
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#for-statements"
220
+
221
+ [[exercises]]
222
+ name = "loops7"
223
+ path = "exercises/loops/loops7.py"
224
+ hint = "Outer loop `for i in range(1, 4)`, inner loop `for j in range(1, 4)`, build each row then append it to table."
225
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#for-statements"
226
+
227
+ [[exercises]]
228
+ name = "loops8"
229
+ path = "exercises/loops/loops8.py"
230
+ hint = "Use `for i, word in enumerate(words, start=1):` and append `f\"{i}: {word}\"` to labeled."
231
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#for-statements"
232
+
233
+ [[exercises]]
234
+ name = "loops9"
235
+ path = "exercises/loops/loops9.py"
236
+ hint = "Use `for name, score in scores.items():` and update top_name/top_score whenever score > top_score."
237
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#for-statements"
238
+
239
+ [[exercises]]
240
+ name = "loops10"
241
+ path = "exercises/loops/loops10.py"
242
+ hint = "Use `for i, tx in enumerate(transactions, start=1):`, skip zero-amounts with `continue`, update balance, and append the summary dict."
243
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#for-statements"
244
+
245
+ [[exercises]]
246
+ name = "functions1"
247
+ path = "exercises/functions/functions1.py"
248
+ hint = "The function is called as average(2, 4) — give it two parameters."
249
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#defining-functions"
250
+
251
+ [[exercises]]
252
+ name = "functions2"
253
+ path = "exercises/functions/functions2.py"
254
+ hint = "Use `def greet():` with no parameters and `return \"hello\"`, then set `message = greet()`."
255
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#defining-functions"
256
+
257
+ [[exercises]]
258
+ name = "functions3"
259
+ path = "exercises/functions/functions3.py"
260
+ hint = "Add a parameter name (e.g. `n`) inside the parentheses of `def double()`."
261
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#defining-functions"
262
+
263
+ [[exercises]]
264
+ name = "functions4"
265
+ path = "exercises/functions/functions4.py"
266
+ hint = "Add the `return` keyword before `n * n` so the function hands a value back to the caller."
267
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#defining-functions"
268
+
269
+ [[exercises]]
270
+ name = "functions5"
271
+ path = "exercises/functions/functions5.py"
272
+ hint = "Give `greeting` a default value in the signature: `def make_greeting(name, greeting=\"Hello\"):`."
273
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#defining-functions"
274
+
275
+ [[exercises]]
276
+ name = "functions6"
277
+ path = "exercises/functions/functions6.py"
278
+ hint = "Use keyword arguments to fix the call order: `describe_pet(name=\"Buddy\", animal_type=\"dog\")`."
279
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#defining-functions"
280
+
281
+ [[exercises]]
282
+ name = "functions7"
283
+ path = "exercises/functions/functions7.py"
284
+ hint = "Replace `pass` with `return sum(args)` — `args` is a tuple of all positional arguments."
285
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#defining-functions"
286
+
287
+ [[exercises]]
288
+ name = "functions8"
289
+ path = "exercises/functions/functions8.py"
290
+ hint = "Replace `pass` with `return dict(kwargs)` — `kwargs` is already a dict of the keyword arguments."
291
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#defining-functions"
292
+
293
+ [[exercises]]
294
+ name = "functions9"
295
+ path = "exercises/functions/functions9.py"
296
+ hint = "Unpack the returned tuple with `lo, hi = min_max(numbers)` instead of assigning the whole tuple to both variables."
297
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#defining-functions"
298
+
299
+ [[exercises]]
300
+ name = "functions10"
301
+ path = "exercises/functions/functions10.py"
302
+ hint = "Inside `is_palindrome`, compare `s.lower()` with `s.lower()[::-1]` and return the result."
303
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#defining-functions"
304
+
305
+ [[exercises]]
306
+ name = "lists1"
307
+ path = "exercises/lists/lists1.py"
308
+ hint = "A list literal is written with square brackets: colors = [\"red\", \"green\", \"blue\"]"
309
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#more-on-lists"
310
+
311
+ [[exercises]]
312
+ name = "lists2"
313
+ path = "exercises/lists/lists2.py"
314
+ hint = "Index 0 is the first element; use numbers[0] for first and numbers[2] = 99 to update."
315
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#more-on-lists"
316
+
317
+ [[exercises]]
318
+ name = "lists3"
319
+ path = "exercises/lists/lists3.py"
320
+ hint = "items.append(\"cherry\") adds to the end; items.insert(1, \"mango\") inserts at position 1."
321
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#more-on-lists"
322
+
323
+ [[exercises]]
324
+ name = "lists4"
325
+ path = "exercises/lists/lists4.py"
326
+ hint = "items.remove(\"banana\") deletes by value; last = items.pop() removes and returns the last element."
327
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#more-on-lists"
328
+
329
+ [[exercises]]
330
+ name = "lists5"
331
+ path = "exercises/lists/lists5.py"
332
+ hint = "Slice syntax: letters[0:3] gives the first three; letters[-2:] gives the last two; letters[2:5] gives indices 2-4."
333
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#more-on-lists"
334
+
335
+ [[exercises]]
336
+ name = "lists6"
337
+ path = "exercises/lists/lists6.py"
338
+ hint = "scores.sort() sorts in-place; desc = sorted(scores, reverse=True) builds a new descending list."
339
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#more-on-lists"
340
+
341
+ [[exercises]]
342
+ name = "lists7"
343
+ path = "exercises/lists/lists7.py"
344
+ hint = "len(fruits) counts elements; \"kiwi\" in fruits checks membership; fruits.count(\"apple\") counts occurrences."
345
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#more-on-lists"
346
+
347
+ [[exercises]]
348
+ name = "lists8"
349
+ path = "exercises/lists/lists8.py"
350
+ hint = "Inside the loop, compute F = temp * 9 / 5 + 32 and append it to fahrenheit."
351
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#more-on-lists"
352
+
353
+ [[exercises]]
354
+ name = "lists9"
355
+ path = "exercises/lists/lists9.py"
356
+ hint = "matrix[row][col] accesses a cell; row 1 col 1 is matrix[1][1], row 2 col 2 is matrix[2][2]."
357
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#more-on-lists"
358
+
359
+ [[exercises]]
360
+ name = "lists10"
361
+ path = "exercises/lists/lists10.py"
362
+ hint = "Filter with `if record[\"units\"] > 10`, compute revenue as units * price_per_unit, then sum(revenue_list)."
363
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#more-on-lists"
364
+
365
+ [[exercises]]
366
+ name = "tuples1"
367
+ path = "exercises/tuples/tuples1.py"
368
+ hint = "A tuple literal uses parentheses and commas: point = (3, 4)"
369
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences"
370
+
371
+ [[exercises]]
372
+ name = "tuples2"
373
+ path = "exercises/tuples/tuples2.py"
374
+ hint = "Use index 0 for the first element and index -1 (or 2) for the last element of rgb."
375
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences"
376
+
377
+ [[exercises]]
378
+ name = "tuples3"
379
+ path = "exercises/tuples/tuples3.py"
380
+ hint = "Replace the three ???s with the variable names x, y, z: x, y, z = coordinates"
381
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences"
382
+
383
+ [[exercises]]
384
+ name = "tuples4"
385
+ path = "exercises/tuples/tuples4.py"
386
+ hint = "A single-element tuple needs a trailing comma: solo = (42,)"
387
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences"
388
+
389
+ [[exercises]]
390
+ name = "tuples5"
391
+ path = "exercises/tuples/tuples5.py"
392
+ hint = "Build a new tuple using slicing and concatenation: original[:1] + (99,) + original[2:]"
393
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences"
394
+
395
+ [[exercises]]
396
+ name = "tuples6"
397
+ path = "exercises/tuples/tuples6.py"
398
+ hint = "Use the built-ins min() and max() and return both as a tuple: return (min(numbers), max(numbers))"
399
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences"
400
+
401
+ [[exercises]]
402
+ name = "tuples7"
403
+ path = "exercises/tuples/tuples7.py"
404
+ hint = "The tuple-swap idiom is a single line: a, b = b, a"
405
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences"
406
+
407
+ [[exercises]]
408
+ name = "tuples8"
409
+ path = "exercises/tuples/tuples8.py"
410
+ hint = "Inside the for loop, add `if score >= 60: passing.append(score)` to collect qualifying scores."
411
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences"
412
+
413
+ [[exercises]]
414
+ name = "tuples9"
415
+ path = "exercises/tuples/tuples9.py"
416
+ hint = "Tuple keys go directly in the dict literal: {(0, 0): \"origin\", ...}; look up a key with grid[(1, 0)]."
417
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences"
418
+
419
+ [[exercises]]
420
+ name = "tuples10"
421
+ path = "exercises/tuples/tuples10.py"
422
+ hint = "Unpack each tuple with `for name, score in results`. Use max() with a key for top_student, sum()/len() for average, and a list comprehension for passed."
423
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#tuples-and-sequences"
424
+
425
+ [[exercises]]
426
+ name = "dictionaries1"
427
+ path = "exercises/dictionaries/dictionaries1.py"
428
+ hint = "A dict literal uses curly braces and colons: ages = {\"alice\": 30, \"bob\": 25}"
429
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#dictionaries"
430
+
431
+ [[exercises]]
432
+ name = "dictionaries2"
433
+ path = "exercises/dictionaries/dictionaries2.py"
434
+ hint = "Access a value by its key using square brackets: capitals[\"france\"]"
435
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#dictionaries"
436
+
437
+ [[exercises]]
438
+ name = "dictionaries3"
439
+ path = "exercises/dictionaries/dictionaries3.py"
440
+ hint = "Add or update a key with assignment: scores[\"diana\"] = 91 and scores[\"alice\"] = 88"
441
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#dictionaries"
442
+
443
+ [[exercises]]
444
+ name = "dictionaries4"
445
+ path = "exercises/dictionaries/dictionaries4.py"
446
+ hint = "Remove with del: `del basket[\"banana\"]`; remove and capture with .pop(): `cherry_count = basket.pop(\"cherry\")`"
447
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#dictionaries"
448
+
449
+ [[exercises]]
450
+ name = "dictionaries5"
451
+ path = "exercises/dictionaries/dictionaries5.py"
452
+ hint = "Convert each view to a list: list(inventory.keys()), list(inventory.values()), list(inventory.items())"
453
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#dictionaries"
454
+
455
+ [[exercises]]
456
+ name = "dictionaries6"
457
+ path = "exercises/dictionaries/dictionaries6.py"
458
+ hint = "Use .get() with a second argument as the default: config.get(\"timeout\", 30)"
459
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#dictionaries"
460
+
461
+ [[exercises]]
462
+ name = "dictionaries7"
463
+ path = "exercises/dictionaries/dictionaries7.py"
464
+ hint = "Iterate with `for item, price in prices.items():` then set `discounted[item] = round(price * 0.9, 2)`"
465
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#dictionaries"
466
+
467
+ [[exercises]]
468
+ name = "dictionaries8"
469
+ path = "exercises/dictionaries/dictionaries8.py"
470
+ hint = "The `in` operator checks keys: `\"read\" in permissions` returns True if the key exists."
471
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#dictionaries"
472
+
473
+ [[exercises]]
474
+ name = "dictionaries9"
475
+ path = "exercises/dictionaries/dictionaries9.py"
476
+ hint = "Chain square-bracket access for nested dicts: school[\"students\"][\"alice\"][\"grade\"]"
477
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#dictionaries"
478
+
479
+ [[exercises]]
480
+ name = "dictionaries10"
481
+ path = "exercises/dictionaries/dictionaries10.py"
482
+ hint = "Use `freq[word] = freq.get(word, 0) + 1` inside a `for word in words:` loop to count occurrences."
483
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#dictionaries"
484
+
485
+ [[exercises]]
486
+ name = "sets1"
487
+ path = "exercises/sets/sets1.py"
488
+ hint = "A set literal uses curly braces: primes = {2, 3, 5, 7}"
489
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#sets"
490
+
491
+ [[exercises]]
492
+ name = "sets2"
493
+ path = "exercises/sets/sets2.py"
494
+ hint = "colors.add(\"purple\") adds an element; colors.discard(\"orange\") removes it without raising an error."
495
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#sets"
496
+
497
+ [[exercises]]
498
+ name = "sets3"
499
+ path = "exercises/sets/sets3.py"
500
+ hint = "The `in` operator returns a bool: has_apple = \"apple\" in fruits"
501
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#sets"
502
+
503
+ [[exercises]]
504
+ name = "sets4"
505
+ path = "exercises/sets/sets4.py"
506
+ hint = "Use `a | b` or `a.union(b)` to get every element that appears in either set."
507
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#sets"
508
+
509
+ [[exercises]]
510
+ name = "sets5"
511
+ path = "exercises/sets/sets5.py"
512
+ hint = "Use `a & b` or `a.intersection(b)` to get only the elements present in both sets."
513
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#sets"
514
+
515
+ [[exercises]]
516
+ name = "sets6"
517
+ path = "exercises/sets/sets6.py"
518
+ hint = "Use `a - b` or `a.difference(b)` to get elements that are in `a` but not in `b`."
519
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#sets"
520
+
521
+ [[exercises]]
522
+ name = "sets7"
523
+ path = "exercises/sets/sets7.py"
524
+ hint = "Pass the list to set(): unique = set(numbers), then use len(unique) for the count."
525
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#sets"
526
+
527
+ [[exercises]]
528
+ name = "sets8"
529
+ path = "exercises/sets/sets8.py"
530
+ hint = "Use `small <= big` (or small.issubset(big)) and `big >= small` (or big.issuperset(small))."
531
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#sets"
532
+
533
+ [[exercises]]
534
+ name = "sets9"
535
+ path = "exercises/sets/sets9.py"
536
+ hint = "A set comprehension looks like: {n**2 for n in numbers if n % 2 == 0}"
537
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#sets"
538
+
539
+ [[exercises]]
540
+ name = "sets10"
541
+ path = "exercises/sets/sets10.py"
542
+ hint = "Convert lists to sets first, then use &, |, and - for intersection, union, and difference."
543
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#sets"
544
+
545
+ [[exercises]]
546
+ name = "comprehensions1"
547
+ path = "exercises/comprehensions/comprehensions1.py"
548
+ hint = "A list comprehension collects expressions: [x for x in range(5)] gives [0, 1, 2, 3, 4]."
549
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions"
550
+
551
+ [[exercises]]
552
+ name = "comprehensions2"
553
+ path = "exercises/comprehensions/comprehensions2.py"
554
+ hint = "Add an if clause to filter: [x for x in values if x % 2 == 0] keeps only even numbers."
555
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions"
556
+
557
+ [[exercises]]
558
+ name = "comprehensions3"
559
+ path = "exercises/comprehensions/comprehensions3.py"
560
+ hint = "Transform the expression: [x * 2 for x in values] multiplies every element by 2."
561
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions"
562
+
563
+ [[exercises]]
564
+ name = "comprehensions4"
565
+ path = "exercises/comprehensions/comprehensions4.py"
566
+ hint = "Use two for clauses: [(r, c) for r in rows for c in cols] iterates every row-column pair."
567
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions"
568
+
569
+ [[exercises]]
570
+ name = "comprehensions5"
571
+ path = "exercises/comprehensions/comprehensions5.py"
572
+ hint = "A dict comprehension uses {key: val for item in iterable}: {x: x**2 for x in numbers}."
573
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions"
574
+
575
+ [[exercises]]
576
+ name = "comprehensions6"
577
+ path = "exercises/comprehensions/comprehensions6.py"
578
+ hint = "A set comprehension uses {expr for item in iterable}: {len(w) for w in words}."
579
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions"
580
+
581
+ [[exercises]]
582
+ name = "comprehensions7"
583
+ path = "exercises/comprehensions/comprehensions7.py"
584
+ hint = "Iterate over a string directly: [c for c in sentence if c in 'aeiou'] extracts vowels."
585
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions"
586
+
587
+ [[exercises]]
588
+ name = "comprehensions8"
589
+ path = "exercises/comprehensions/comprehensions8.py"
590
+ hint = "Put the ternary inside: ['even' if x % 2 == 0 else 'odd' for x in values]."
591
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions"
592
+
593
+ [[exercises]]
594
+ name = "comprehensions9"
595
+ path = "exercises/comprehensions/comprehensions9.py"
596
+ hint = "Flatten with two for clauses: [item for sublist in matrix for item in sublist]."
597
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions"
598
+
599
+ [[exercises]]
600
+ name = "comprehensions10"
601
+ path = "exercises/comprehensions/comprehensions10.py"
602
+ hint = "Use enumerate to get index-value pairs: {word: idx for idx, word in enumerate(words)}."
603
+ docs = "https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions"
604
+
605
+ [[exercises]]
606
+ name = "exceptions1"
607
+ path = "exercises/exceptions/exceptions1.py"
608
+ hint = "Wrap the division in try/except ZeroDivisionError and return 'error' in the except branch."
609
+ docs = "https://docs.python.org/3/tutorial/errors.html"
610
+
611
+ [[exercises]]
612
+ name = "exceptions2"
613
+ path = "exercises/exceptions/exceptions2.py"
614
+ hint = "Catch the specific exception: except ValueError: return -1."
615
+ docs = "https://docs.python.org/3/tutorial/errors.html"
616
+
617
+ [[exercises]]
618
+ name = "exceptions3"
619
+ path = "exercises/exceptions/exceptions3.py"
620
+ hint = "Use 'except ValueError as e:' and return str(e) to surface the built-in error message."
621
+ docs = "https://docs.python.org/3/tutorial/errors.html"
622
+
623
+ [[exercises]]
624
+ name = "exceptions4"
625
+ path = "exercises/exceptions/exceptions4.py"
626
+ hint = "Add an else clause after the except block: else: return value * 2."
627
+ docs = "https://docs.python.org/3/tutorial/errors.html"
628
+
629
+ [[exercises]]
630
+ name = "exceptions5"
631
+ path = "exercises/exceptions/exceptions5.py"
632
+ hint = "Add a finally clause after the except block: finally: log.append('done')."
633
+ docs = "https://docs.python.org/3/tutorial/errors.html"
634
+
635
+ [[exercises]]
636
+ name = "exceptions6"
637
+ path = "exercises/exceptions/exceptions6.py"
638
+ hint = "Use 'raise ValueError' (no message needed) when n is not positive."
639
+ docs = "https://docs.python.org/3/tutorial/errors.html"
640
+
641
+ [[exercises]]
642
+ name = "exceptions7"
643
+ path = "exercises/exceptions/exceptions7.py"
644
+ hint = "Use 'raise ValueError(\"age must be between 0 and 120\")' when age is out of range."
645
+ docs = "https://docs.python.org/3/tutorial/errors.html"
646
+
647
+ [[exercises]]
648
+ name = "exceptions8"
649
+ path = "exercises/exceptions/exceptions8.py"
650
+ hint = "Add 'except ValueError:', 'except TypeError:', and 'except Exception:' clauses returning the right string."
651
+ docs = "https://docs.python.org/3/tutorial/errors.html"
652
+
653
+ [[exercises]]
654
+ name = "exceptions9"
655
+ path = "exercises/exceptions/exceptions9.py"
656
+ hint = "Define 'class InsufficientFundsError(Exception): pass', then raise it with a descriptive message."
657
+ docs = "https://docs.python.org/3/tutorial/errors.html"
658
+
659
+ [[exercises]]
660
+ name = "exceptions10"
661
+ path = "exercises/exceptions/exceptions10.py"
662
+ hint = "Check type first (TypeError), then length (ValueError), then .isalnum() (ValueError); return name.lower() on success."
663
+ docs = "https://docs.python.org/3/tutorial/errors.html"
664
+
665
+ [[exercises]]
666
+ name = "file_io1"
667
+ path = "exercises/file_io/file_io1.py"
668
+ hint = "Replace ??? with the string \"hello, file!\". open(path, \"w\") opens for writing; .write(text) writes the text."
669
+ docs = "https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files"
670
+
671
+ [[exercises]]
672
+ name = "file_io2"
673
+ path = "exercises/file_io/file_io2.py"
674
+ hint = "Replace ??? with open(note_path).read() to read the whole file as a string."
675
+ docs = "https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files"
676
+
677
+ [[exercises]]
678
+ name = "file_io3"
679
+ path = "exercises/file_io/file_io3.py"
680
+ hint = "Replace ??? with the string \"first entry\". The with-block handles opening and closing automatically."
681
+ docs = "https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files"
682
+
683
+ [[exercises]]
684
+ name = "file_io4"
685
+ path = "exercises/file_io/file_io4.py"
686
+ hint = "Change .read() to .readlines() — it returns a list of strings, one per line (newlines included)."
687
+ docs = "https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files"
688
+
689
+ [[exercises]]
690
+ name = "file_io5"
691
+ path = "exercises/file_io/file_io5.py"
692
+ hint = "Change the mode from \"w\" (overwrite) to \"a\" (append) so the first line is preserved."
693
+ docs = "https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files"
694
+
695
+ [[exercises]]
696
+ name = "file_io6"
697
+ path = "exercises/file_io/file_io6.py"
698
+ hint = "Replace `total += line` with `total += int(line.strip())` to convert each text line to an integer."
699
+ docs = "https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files"
700
+
701
+ [[exercises]]
702
+ name = "file_io7"
703
+ path = "exercises/file_io/file_io7.py"
704
+ hint = "Pass a list with newlines appended: fh.writelines(w + \"\\n\" for w in words), or use a for-loop with fh.write(w + \"\\n\")."
705
+ docs = "https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files"
706
+
707
+ [[exercises]]
708
+ name = "file_io8"
709
+ path = "exercises/file_io/file_io8.py"
710
+ hint = "Chain .strip() onto the read call: result = fh.read().strip()"
711
+ docs = "https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files"
712
+
713
+ [[exercises]]
714
+ name = "file_io9"
715
+ path = "exercises/file_io/file_io9.py"
716
+ hint = "Split before counting: word_count = len(fh.read().split())"
717
+ docs = "https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files"
718
+
719
+ [[exercises]]
720
+ name = "file_io10"
721
+ path = "exercises/file_io/file_io10.py"
722
+ hint = "Change dst.write(line) to dst.write(line.upper()) to uppercase every line as it is copied."
723
+ docs = "https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files"
724
+
725
+ [[exercises]]
726
+ name = "classes1"
727
+ path = "exercises/classes/classes1.py"
728
+ hint = "Replace ??? with `pass` — a class body must have at least one statement."
729
+ docs = "https://docs.python.org/3/tutorial/classes.html"
730
+
731
+ [[exercises]]
732
+ name = "classes2"
733
+ path = "exercises/classes/classes2.py"
734
+ hint = "Inside __init__, add `self.name = name` to store the argument on the instance."
735
+ docs = "https://docs.python.org/3/tutorial/classes.html"
736
+
737
+ [[exercises]]
738
+ name = "classes3"
739
+ path = "exercises/classes/classes3.py"
740
+ hint = "Add `self.y = y` after `self.x = x` inside __init__."
741
+ docs = "https://docs.python.org/3/tutorial/classes.html"
742
+
743
+ [[exercises]]
744
+ name = "classes4"
745
+ path = "exercises/classes/classes4.py"
746
+ hint = "Change `return 0` to `return self.width * self.height` in the area method."
747
+ docs = "https://docs.python.org/3/tutorial/classes.html"
748
+
749
+ [[exercises]]
750
+ name = "classes5"
751
+ path = "exercises/classes/classes5.py"
752
+ hint = "Replace `pass` in increment with `self.count += 1`."
753
+ docs = "https://docs.python.org/3/tutorial/classes.html"
754
+
755
+ [[exercises]]
756
+ name = "classes6"
757
+ path = "exercises/classes/classes6.py"
758
+ hint = "Change `def __init__(self, brand, speed):` to `def __init__(self, brand, speed=0):`."
759
+ docs = "https://docs.python.org/3/tutorial/classes.html"
760
+
761
+ [[exercises]]
762
+ name = "classes7"
763
+ path = "exercises/classes/classes7.py"
764
+ hint = "Replace ??? with `self.get_name()` — call the other method on self."
765
+ docs = "https://docs.python.org/3/tutorial/classes.html"
766
+
767
+ [[exercises]]
768
+ name = "classes8"
769
+ path = "exercises/classes/classes8.py"
770
+ hint = "Add `def __str__(self): return f\"Book: {self.title} by {self.author}\"` to the class."
771
+ docs = "https://docs.python.org/3/tutorial/classes.html"
772
+
773
+ [[exercises]]
774
+ name = "classes9"
775
+ path = "exercises/classes/classes9.py"
776
+ hint = "Add `def __repr__(self): return f\"Color(r={self.r}, g={self.g}, b={self.b})\"` to the class."
777
+ docs = "https://docs.python.org/3/tutorial/classes.html"
778
+
779
+ [[exercises]]
780
+ name = "classes10"
781
+ path = "exercises/classes/classes10.py"
782
+ hint = "Move `pi = 3.14159` to be a class-level attribute (one indent level inside the class, not inside __init__), and remove the local `pi = 3.14159` line from __init__."
783
+ docs = "https://docs.python.org/3/tutorial/classes.html"
784
+
785
+ [[exercises]]
786
+ name = "classes11"
787
+ path = "exercises/classes/classes11.py"
788
+ hint = "Add a @classmethod `from_string(cls, s)` that does `return cls(float(s[:-1]))`."
789
+ docs = "https://docs.python.org/3/tutorial/classes.html"
790
+
791
+ [[exercises]]
792
+ name = "classes12"
793
+ path = "exercises/classes/classes12.py"
794
+ hint = "Add __init__(self, owner, balance) to store both attributes; fix deposit to add amount; fix withdraw to subtract (raise ValueError if overdraft); fix __str__ to return the formatted string."
795
+ docs = "https://docs.python.org/3/tutorial/classes.html"
796
+
797
+ [[exercises]]
798
+ name = "functional1"
799
+ path = "exercises/functional/functional1.py"
800
+ hint = "Replace ??? with `lambda x: x * x` (or `lambda x: x ** 2`)."
801
+ docs = "https://docs.python.org/3/howto/functional.html"
802
+
803
+ [[exercises]]
804
+ name = "functional2"
805
+ path = "exercises/functional/functional2.py"
806
+ hint = "Replace ??? with `lambda x: x if x >= 0 else -x`."
807
+ docs = "https://docs.python.org/3/howto/functional.html"
808
+
809
+ [[exercises]]
810
+ name = "functional3"
811
+ path = "exercises/functional/functional3.py"
812
+ hint = "Replace ??? with `lambda x: x * 2` — pass that lambda as the first argument to map()."
813
+ docs = "https://docs.python.org/3/howto/functional.html"
814
+
815
+ [[exercises]]
816
+ name = "functional4"
817
+ path = "exercises/functional/functional4.py"
818
+ hint = "Replace ??? with `lambda x: x % 2 == 0` — pass that lambda as the first argument to filter()."
819
+ docs = "https://docs.python.org/3/howto/functional.html"
820
+
821
+ [[exercises]]
822
+ name = "functional5"
823
+ path = "exercises/functional/functional5.py"
824
+ hint = "Replace ??? with `lambda w: len(w)` to sort words by their length."
825
+ docs = "https://docs.python.org/3/howto/functional.html"
826
+
827
+ [[exercises]]
828
+ name = "functional6"
829
+ path = "exercises/functional/functional6.py"
830
+ hint = "Replace `pass` with `return func(func(value))` — call func on value, then call func on the result."
831
+ docs = "https://docs.python.org/3/howto/functional.html"
832
+
833
+ [[exercises]]
834
+ name = "functional7"
835
+ path = "exercises/functional/functional7.py"
836
+ hint = "Replace `pass` with `return lambda x: x * n` — return a new function that captures n."
837
+ docs = "https://docs.python.org/3/howto/functional.html"
838
+
839
+ [[exercises]]
840
+ name = "functional8"
841
+ path = "exercises/functional/functional8.py"
842
+ hint = "Replace ??? with `lambda a, b: a * b` — reduce multiplies pairs cumulatively to give the product."
843
+ docs = "https://docs.python.org/3/howto/functional.html"
844
+
845
+ [[exercises]]
846
+ name = "functional9"
847
+ path = "exercises/functional/functional9.py"
848
+ hint = "Replace the first ??? with `x < 0 for x in numbers` and the second with `x > 0 for x in positives`."
849
+ docs = "https://docs.python.org/3/howto/functional.html"
850
+
851
+ [[exercises]]
852
+ name = "functional10"
853
+ path = "exercises/functional/functional10.py"
854
+ hint = "Three lambdas: `lambda x: x * 2` for map, `lambda x: x > 10` for filter, `lambda a, b: a + b` for reduce."
855
+ docs = "https://docs.python.org/3/howto/functional.html"
856
+
857
+ [[exercises]]
858
+ name = "decorators1"
859
+ path = "exercises/decorators/decorators1.py"
860
+ hint = "Replace `pass` with `return func()` — call the function that was passed in and return its result."
861
+ docs = "https://docs.python.org/3/glossary.html#term-decorator"
862
+
863
+ [[exercises]]
864
+ name = "decorators2"
865
+ path = "exercises/decorators/decorators2.py"
866
+ hint = "Change `return result` to `return result.upper()` inside the wrapper."
867
+ docs = "https://docs.python.org/3/glossary.html#term-decorator"
868
+
869
+ [[exercises]]
870
+ name = "decorators3"
871
+ path = "exercises/decorators/decorators3.py"
872
+ hint = "Add `@stamp` on the line directly above `def get_message():` — this applies the decorator automatically."
873
+ docs = "https://docs.python.org/3/glossary.html#term-decorator"
874
+
875
+ [[exercises]]
876
+ name = "decorators4"
877
+ path = "exercises/decorators/decorators4.py"
878
+ hint = "Capture the return value: `result = func()` then `return result * 2`."
879
+ docs = "https://docs.python.org/3/glossary.html#term-decorator"
880
+
881
+ [[exercises]]
882
+ name = "decorators5"
883
+ path = "exercises/decorators/decorators5.py"
884
+ hint = "Change `def wrapper():` to `def wrapper(*args, **kwargs):` and `return func()` to `return func(*args, **kwargs)`."
885
+ docs = "https://docs.python.org/3/glossary.html#term-decorator"
886
+
887
+ [[exercises]]
888
+ name = "decorators6"
889
+ path = "exercises/decorators/decorators6.py"
890
+ hint = "Add `import functools` at the top, then add `@functools.wraps(func)` on the line above `def wrapper`."
891
+ docs = "https://docs.python.org/3/glossary.html#term-decorator"
892
+
893
+ [[exercises]]
894
+ name = "decorators7"
895
+ path = "exercises/decorators/decorators7.py"
896
+ hint = "Add `wrapper.call_count += 1` as the first line inside the wrapper body, before calling func."
897
+ docs = "https://docs.python.org/3/glossary.html#term-decorator"
898
+
899
+ [[exercises]]
900
+ name = "decorators8"
901
+ path = "exercises/decorators/decorators8.py"
902
+ hint = "Inside `repeat(n)`, define a `decorator(func)` that returns a `wrapper(*args, **kwargs)` calling func n times in a loop and returning the last result."
903
+ docs = "https://docs.python.org/3/glossary.html#term-decorator"
904
+
905
+ [[exercises]]
906
+ name = "decorators9"
907
+ path = "exercises/decorators/decorators9.py"
908
+ hint = "Add `@add_b` then `@add_a` above `def get_value():`; the decorator nearest the def is applied first, so `add_a` runs first, then `add_b` wraps that."
909
+ docs = "https://docs.python.org/3/glossary.html#term-decorator"
910
+
911
+ [[exercises]]
912
+ name = "decorators10"
913
+ path = "exercises/decorators/decorators10.py"
914
+ hint = "Check `if args in wrapper.cache: return wrapper.cache[args]`, otherwise compute, store in `wrapper.cache[args]`, and return the result."
915
+ docs = "https://docs.python.org/3/glossary.html#term-decorator"
916
+
917
+ [[exercises]]
918
+ name = "generators1"
919
+ path = "exercises/generators/generators1.py"
920
+ hint = "Inside the for loop replace `pass` with `yield i` to turn the function into a generator."
921
+ docs = "https://docs.python.org/3/tutorial/classes.html#generators"
922
+
923
+ [[exercises]]
924
+ name = "generators2"
925
+ path = "exercises/generators/generators2.py"
926
+ hint = "Replace `None` with `list(squares(5))` — calling list() on a generator drains it into a list."
927
+ docs = "https://docs.python.org/3/tutorial/classes.html#generators"
928
+
929
+ [[exercises]]
930
+ name = "generators3"
931
+ path = "exercises/generators/generators3.py"
932
+ hint = "Add `if i % 2 == 0:` before the pass, then change `pass` to `yield i` so only even numbers are yielded."
933
+ docs = "https://docs.python.org/3/tutorial/classes.html#generators"
934
+
935
+ [[exercises]]
936
+ name = "generators4"
937
+ path = "exercises/generators/generators4.py"
938
+ hint = "Replace `None` with `(i ** 3 for i in range(1, 6))` — parentheses make a generator expression, not a list."
939
+ docs = "https://docs.python.org/3/tutorial/classes.html#generators"
940
+
941
+ [[exercises]]
942
+ name = "generators5"
943
+ path = "exercises/generators/generators5.py"
944
+ hint = "Replace each `None` with `next(gen)` — every call advances the generator by one step."
945
+ docs = "https://docs.python.org/3/tutorial/classes.html#generators"
946
+
947
+ [[exercises]]
948
+ name = "generators6"
949
+ path = "exercises/generators/generators6.py"
950
+ hint = "Add `while True:` with `yield a` and `a += 1` (starting at 1) inside `natural_numbers`; remove the bare `return`."
951
+ docs = "https://docs.python.org/3/tutorial/classes.html#generators"
952
+
953
+ [[exercises]]
954
+ name = "generators7"
955
+ path = "exercises/generators/generators7.py"
956
+ hint = "Wrap the yield in `while True:` and add `a, b = b, a + b` after the yield to advance the sequence."
957
+ docs = "https://docs.python.org/3/tutorial/classes.html#generators"
958
+
959
+ [[exercises]]
960
+ name = "generators8"
961
+ path = "exercises/generators/generators8.py"
962
+ hint = "Add `def __iter__(self):` that uses `yield` in a `for i in range(self.start, 0, -1):` loop."
963
+ docs = "https://docs.python.org/3/tutorial/classes.html#generators"
964
+
965
+ [[exercises]]
966
+ name = "generators9"
967
+ path = "exercises/generators/generators9.py"
968
+ hint = "At the top of `__next__`, add `if self.current >= self.stop: raise StopIteration` before incrementing."
969
+ docs = "https://docs.python.org/3/tutorial/classes.html#generators"
970
+
971
+ [[exercises]]
972
+ name = "generators10"
973
+ path = "exercises/generators/generators10.py"
974
+ hint = "Add `total += n` before the yield, then change `yield n` to `yield total` to emit the running sum."
975
+ docs = "https://docs.python.org/3/tutorial/classes.html#generators"
976
+
977
+ [[exercises]]
978
+ name = "context_managers1"
979
+ path = "exercises/context_managers/context_managers1.py"
980
+ hint = "Replace the open/write lines with `with open(data_path, 'w') as f:` and indent `f.write('hello, context!')` inside."
981
+ docs = "https://docs.python.org/3/reference/compound_stmts.html#the-with-statement"
982
+
983
+ [[exercises]]
984
+ name = "context_managers2"
985
+ path = "exercises/context_managers/context_managers2.py"
986
+ hint = "Use `with open(data_path, 'w') as f:` so Python closes the file automatically; then `f.closed` will be True."
987
+ docs = "https://docs.python.org/3/reference/compound_stmts.html#the-with-statement"
988
+
989
+ [[exercises]]
990
+ name = "context_managers3"
991
+ path = "exercises/context_managers/context_managers3.py"
992
+ hint = "Add `def __enter__(self): return self` and `def __exit__(self, exc_type, exc_val, exc_tb): self.finished = True`."
993
+ docs = "https://docs.python.org/3/reference/compound_stmts.html#the-with-statement"
994
+
995
+ [[exercises]]
996
+ name = "context_managers4"
997
+ path = "exercises/context_managers/context_managers4.py"
998
+ hint = "Inside `__exit__`, replace `pass` with `self.log.append('done')` to record cleanup."
999
+ docs = "https://docs.python.org/3/reference/compound_stmts.html#the-with-statement"
1000
+
1001
+ [[exercises]]
1002
+ name = "context_managers5"
1003
+ path = "exercises/context_managers/context_managers5.py"
1004
+ hint = "Change `return None` in `__enter__` to `return self.connection` so the `as` target receives the dict."
1005
+ docs = "https://docs.python.org/3/reference/compound_stmts.html#the-with-statement"
1006
+
1007
+ [[exercises]]
1008
+ name = "context_managers6"
1009
+ path = "exercises/context_managers/context_managers6.py"
1010
+ hint = "Inside `managed_counter`: create `counter = []`, then `yield counter`, then `counter.append('finished')`."
1011
+ docs = "https://docs.python.org/3/reference/compound_stmts.html#the-with-statement"
1012
+
1013
+ [[exercises]]
1014
+ name = "context_managers7"
1015
+ path = "exercises/context_managers/context_managers7.py"
1016
+ hint = "In `__exit__`, check `if exc_type is ZeroDivisionError: return True` to swallow that error type."
1017
+ docs = "https://docs.python.org/3/reference/compound_stmts.html#the-with-statement"
1018
+
1019
+ [[exercises]]
1020
+ name = "context_managers8"
1021
+ path = "exercises/context_managers/context_managers8.py"
1022
+ hint = "Fill in Resource.__init__/__enter__/__exit__ to track acquired/release_log, then ManagedPool to acquire, yield, and release."
1023
+ docs = "https://docs.python.org/3/reference/compound_stmts.html#the-with-statement"
1024
+
1025
+ [[exercises]]
1026
+ name = "dataclasses1"
1027
+ path = "exercises/dataclasses/dataclasses1.py"
1028
+ hint = "Add `@dataclass` above `class Point:` and declare `x: int` and `y: int` as class-level typed fields."
1029
+ docs = "https://docs.python.org/3/library/dataclasses.html"
1030
+
1031
+ [[exercises]]
1032
+ name = "dataclasses2"
1033
+ path = "exercises/dataclasses/dataclasses2.py"
1034
+ hint = "Change `Color(0, 0, 0)` to `Color(255, 128, 0)` and replace each `???` in the f-string with `orange.red`, `orange.green`, `orange.blue`."
1035
+ docs = "https://docs.python.org/3/library/dataclasses.html"
1036
+
1037
+ [[exercises]]
1038
+ name = "dataclasses3"
1039
+ path = "exercises/dataclasses/dataclasses3.py"
1040
+ hint = "Change `unit: str` to `unit: str = \"m/s²\"` to give the field a default value."
1041
+ docs = "https://docs.python.org/3/library/dataclasses.html"
1042
+
1043
+ [[exercises]]
1044
+ name = "dataclasses4"
1045
+ path = "exercises/dataclasses/dataclasses4.py"
1046
+ hint = "Import `field` from `dataclasses` and change the declaration to `items: list = field(default_factory=list)`."
1047
+ docs = "https://docs.python.org/3/library/dataclasses.html"
1048
+
1049
+ [[exercises]]
1050
+ name = "dataclasses5"
1051
+ path = "exercises/dataclasses/dataclasses5.py"
1052
+ hint = "Remove the hand-written `__init__` method and add field declarations `x: float`, `y: float`, `z: float` at class body level."
1053
+ docs = "https://docs.python.org/3/library/dataclasses.html"
1054
+
1055
+ [[exercises]]
1056
+ name = "dataclasses6"
1057
+ path = "exercises/dataclasses/dataclasses6.py"
1058
+ hint = "Add `from dataclasses import dataclass`, the `@dataclass` decorator, and declare `title: str` and `pages: int` as fields."
1059
+ docs = "https://docs.python.org/3/library/dataclasses.html"
1060
+
1061
+ [[exercises]]
1062
+ name = "dataclasses7"
1063
+ path = "exercises/dataclasses/dataclasses7.py"
1064
+ hint = "Change `@dataclass` to `@dataclass(frozen=True)` to make the class immutable."
1065
+ docs = "https://docs.python.org/3/library/dataclasses.html"
1066
+
1067
+ [[exercises]]
1068
+ name = "dataclasses8"
1069
+ path = "exercises/dataclasses/dataclasses8.py"
1070
+ hint = "Replace `pass` in `area` with `return self.width * self.height` and in `perimeter` with `return 2 * (self.width + self.height)`."
1071
+ docs = "https://docs.python.org/3/library/dataclasses.html"
1072
+
1073
+ [[exercises]]
1074
+ name = "type_hints1"
1075
+ path = "exercises/type_hints/type_hints1.py"
1076
+ hint = "Add `: int` between the variable name and `=`: write `count: int = 0`."
1077
+ docs = "https://docs.python.org/3/library/typing.html"
1078
+
1079
+ [[exercises]]
1080
+ name = "type_hints2"
1081
+ path = "exercises/type_hints/type_hints2.py"
1082
+ hint = "Add `: str` and `: int` to the parameters and `-> str` before the colon: `def greet(name: str, times: int) -> str:`."
1083
+ docs = "https://docs.python.org/3/library/typing.html"
1084
+
1085
+ [[exercises]]
1086
+ name = "type_hints3"
1087
+ path = "exercises/type_hints/type_hints3.py"
1088
+ hint = "Use parameterized built-in types: `list[int]` and `dict[str, int]` as parameter annotations, and `int` as the return type."
1089
+ docs = "https://docs.python.org/3/library/typing.html"
1090
+
1091
+ [[exercises]]
1092
+ name = "type_hints4"
1093
+ path = "exercises/type_hints/type_hints4.py"
1094
+ hint = "Use the union syntax `int | None` for the return type to express that the function may return an int or nothing."
1095
+ docs = "https://docs.python.org/3/library/typing.html"
1096
+
1097
+ [[exercises]]
1098
+ name = "type_hints5"
1099
+ path = "exercises/type_hints/type_hints5.py"
1100
+ hint = "Fixed-length tuples are written as `tuple[T1, T2, ...]`. Annotate points as `list[tuple[float, float]]` and the return as `tuple[float, float, float, float]`."
1101
+ docs = "https://docs.python.org/3/library/typing.html"
1102
+
1103
+ [[exercises]]
1104
+ name = "type_hints6"
1105
+ path = "exercises/type_hints/type_hints6.py"
1106
+ hint = "Write `Vector = list[float]` as a type alias, then use `Vector` as the annotation for `v` and the return type, and `float` for `factor`."
1107
+ docs = "https://docs.python.org/3/library/typing.html"
1108
+
1109
+ [[exercises]]
1110
+ name = "type_hints7"
1111
+ path = "exercises/type_hints/type_hints7.py"
1112
+ hint = "Import `Callable` from `typing` and annotate `func` as `Callable[[int], int]` — a one-argument int-to-int function."
1113
+ docs = "https://docs.python.org/3/library/typing.html"
1114
+
1115
+ [[exercises]]
1116
+ name = "type_hints8"
1117
+ path = "exercises/type_hints/type_hints8.py"
1118
+ hint = "Combine generics and union types: `list[dict[str, int]]`, `str`, `int | None`, and `dict[str, int | None]` for the four annotations."
1119
+ docs = "https://docs.python.org/3/library/typing.html"
1120
+
1121
+ [[exercises]]
1122
+ name = "regex1"
1123
+ path = "exercises/regex/regex1.py"
1124
+ hint = "Set pattern to `\"hello\"` — re.match checks whether the string starts with the pattern."
1125
+ docs = "https://docs.python.org/3/library/re.html"
1126
+
1127
+ [[exercises]]
1128
+ name = "regex2"
1129
+ path = "exercises/regex/regex2.py"
1130
+ hint = "Set pattern to `\"python\"` — re.search finds the pattern anywhere in the string."
1131
+ docs = "https://docs.python.org/3/library/re.html"
1132
+
1133
+ [[exercises]]
1134
+ name = "regex3"
1135
+ path = "exercises/regex/regex3.py"
1136
+ hint = "Replace ??? with `r\"\\d+\"` — \\d matches a digit and + means one or more."
1137
+ docs = "https://docs.python.org/3/library/re.html"
1138
+
1139
+ [[exercises]]
1140
+ name = "regex4"
1141
+ path = "exercises/regex/regex4.py"
1142
+ hint = "Replace ??? with `r\"[a-z]+\"` — the character class [a-z] matches only lowercase letters."
1143
+ docs = "https://docs.python.org/3/library/re.html"
1144
+
1145
+ [[exercises]]
1146
+ name = "regex5"
1147
+ path = "exercises/regex/regex5.py"
1148
+ hint = "Replace ??? with `r\"\\d+\\.\\d+\"` — \\d+ matches digits, \\. matches a literal dot."
1149
+ docs = "https://docs.python.org/3/library/re.html"
1150
+
1151
+ [[exercises]]
1152
+ name = "regex6"
1153
+ path = "exercises/regex/regex6.py"
1154
+ hint = "Replace ??? with `r\"[A-Z]{5}\\d{3}\"` — {n} means exactly n repetitions."
1155
+ docs = "https://docs.python.org/3/library/re.html"
1156
+
1157
+ [[exercises]]
1158
+ name = "regex7"
1159
+ path = "exercises/regex/regex7.py"
1160
+ hint = "Replace ??? with `r\"\\((\\d{3})\\)\"` — wrap the three digits in () to create a capturing group."
1161
+ docs = "https://docs.python.org/3/library/re.html"
1162
+
1163
+ [[exercises]]
1164
+ name = "regex8"
1165
+ path = "exercises/regex/regex8.py"
1166
+ hint = "Replace ??? with `r\"spam|junk\"` — the pipe | means OR in regex."
1167
+ docs = "https://docs.python.org/3/library/re.html"
1168
+
1169
+ [[exercises]]
1170
+ name = "regex9"
1171
+ path = "exercises/regex/regex9.py"
1172
+ hint = "Replace ??? with `r\"(?P<year>\\d{4})-(?P<month>\\d{2})-(?P<day>\\d{2})\"` to name each group."
1173
+ docs = "https://docs.python.org/3/library/re.html"
1174
+
1175
+ [[exercises]]
1176
+ name = "regex10"
1177
+ path = "exercises/regex/regex10.py"
1178
+ hint = "Use `r\"\\[(?P<level>\\w+)\\] (?P<logger>[\\w.]+): (?P<message>.+)\"` to capture all three named groups."
1179
+ docs = "https://docs.python.org/3/library/re.html"
1180
+
1181
+ [[exercises]]
1182
+ name = "testing1"
1183
+ path = "exercises/testing/testing1.py"
1184
+ hint = "double(2) returns 4 — replace ??? with the value that makes the assertion true."
1185
+ docs = "https://docs.python.org/3/library/unittest.html"
1186
+
1187
+ [[exercises]]
1188
+ name = "testing2"
1189
+ path = "exercises/testing/testing2.py"
1190
+ hint = "5 * 5 == 25; replace the first ??? with 25 and the second with a helpful message string."
1191
+ docs = "https://docs.python.org/3/library/unittest.html"
1192
+
1193
+ [[exercises]]
1194
+ name = "testing3"
1195
+ path = "exercises/testing/testing3.py"
1196
+ hint = "Add two assert statements inside test_add: assert add(2, 3) == 5 and assert add(0, 0) == 0."
1197
+ docs = "https://docs.python.org/3/library/unittest.html"
1198
+
1199
+ [[exercises]]
1200
+ name = "testing4"
1201
+ path = "exercises/testing/testing4.py"
1202
+ hint = "Add four assert statements inside test_is_even, one for each case listed in the goal comment."
1203
+ docs = "https://docs.python.org/3/library/unittest.html"
1204
+
1205
+ [[exercises]]
1206
+ name = "testing5"
1207
+ path = "exercises/testing/testing5.py"
1208
+ hint = "Add five assert statements for clamp: inside range, below lo, above hi, and both boundary values."
1209
+ docs = "https://docs.python.org/3/library/unittest.html"
1210
+
1211
+ [[exercises]]
1212
+ name = "testing6"
1213
+ path = "exercises/testing/testing6.py"
1214
+ hint = "Assert the happy path, then wrap parse_positive('-1') in try/except ValueError: pass."
1215
+ docs = "https://docs.python.org/3/library/unittest.html"
1216
+
1217
+ [[exercises]]
1218
+ name = "testing7"
1219
+ path = "exercises/testing/testing7.py"
1220
+ hint = "In the except clause, capture the exception with `as e` and assert 'zero' in str(e)."
1221
+ docs = "https://docs.python.org/3/library/unittest.html"
1222
+
1223
+ [[exercises]]
1224
+ name = "testing8"
1225
+ path = "exercises/testing/testing8.py"
1226
+ hint = "Replace `cases = []` with a list of four (fahrenheit, celsius) tuples matching the goal comment."
1227
+ docs = "https://docs.python.org/3/library/unittest.html"
1228
+
1229
+ [[exercises]]
1230
+ name = "testing9"
1231
+ path = "exercises/testing/testing9.py"
1232
+ hint = "Call user = make_user() at the top of the test, then assert greet(user) == 'Hello, Alice!'"
1233
+ docs = "https://docs.python.org/3/library/unittest.html"
1234
+
1235
+ [[exercises]]
1236
+ name = "testing10"
1237
+ path = "exercises/testing/testing10.py"
1238
+ hint = "Write five assertions: [], [0], [-1,-2], [1,-1], [1,2,3] — cover every edge case listed."
1239
+ docs = "https://docs.python.org/3/library/unittest.html"
1240
+
1241
+ [[exercises]]
1242
+ name = "testing11"
1243
+ path = "exercises/testing/testing11.py"
1244
+ hint = "Create c = Counter(), then assert c.value after each method call: 0, 1, 2, then 0 after reset()."
1245
+ docs = "https://docs.python.org/3/library/unittest.html"
1246
+
1247
+ [[exercises]]
1248
+ name = "testing12"
1249
+ path = "exercises/testing/testing12.py"
1250
+ hint = "Replace each `pass` with real assertions; each test function needs at least 2-3 assert statements."
1251
+ docs = "https://docs.python.org/3/library/unittest.html"
1252
+
1253
+ [[exercises]]
1254
+ name = "recursion1"
1255
+ path = "exercises/recursion/recursion1.py"
1256
+ hint = "Return [n] + countdown(n - 1) as the recursive case."
1257
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#defining-functions"
1258
+
1259
+ [[exercises]]
1260
+ name = "recursion2"
1261
+ path = "exercises/recursion/recursion2.py"
1262
+ hint = "Return n * factorial(n - 1) as the recursive case."
1263
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#defining-functions"
1264
+
1265
+ [[exercises]]
1266
+ name = "recursion3"
1267
+ path = "exercises/recursion/recursion3.py"
1268
+ hint = "Return lst[0] + recursive_sum(lst[1:]) as the recursive case."
1269
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#defining-functions"
1270
+
1271
+ [[exercises]]
1272
+ name = "recursion4"
1273
+ path = "exercises/recursion/recursion4.py"
1274
+ hint = "The base case returns 0 — replace ??? with the correct value for an empty list."
1275
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#defining-functions"
1276
+
1277
+ [[exercises]]
1278
+ name = "recursion5"
1279
+ path = "exercises/recursion/recursion5.py"
1280
+ hint = "fibonacci(1) should return 1 — replace ??? with that base-case value."
1281
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#defining-functions"
1282
+
1283
+ [[exercises]]
1284
+ name = "recursion6"
1285
+ path = "exercises/recursion/recursion6.py"
1286
+ hint = "Return reverse_string(s[1:]) + s[0] as the recursive case."
1287
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#defining-functions"
1288
+
1289
+ [[exercises]]
1290
+ name = "recursion7"
1291
+ path = "exercises/recursion/recursion7.py"
1292
+ hint = "Replace ??? with deep_sum(rest) to sum the remaining elements after recursing into the first list."
1293
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#defining-functions"
1294
+
1295
+ [[exercises]]
1296
+ name = "recursion8"
1297
+ path = "exercises/recursion/recursion8.py"
1298
+ hint = "tree_depth: return 1 + max(tree_depth(c) for c in tree['children']). tree_search: return any(tree_search(c, target) for c in tree['children'])."
1299
+ docs = "https://docs.python.org/3/tutorial/controlflow.html#defining-functions"
1300
+
1301
+ [[exercises]]
1302
+ name = "modules1"
1303
+ path = "exercises/modules/modules1.py"
1304
+ hint = "Add `import math` at the top, then set result = math.sqrt(144)."
1305
+ docs = "https://docs.python.org/3/tutorial/modules.html"
1306
+
1307
+ [[exercises]]
1308
+ name = "modules2"
1309
+ path = "exercises/modules/modules2.py"
1310
+ hint = "Add `from math import sqrt` so you can call sqrt() without the math. prefix."
1311
+ docs = "https://docs.python.org/3/tutorial/modules.html"
1312
+
1313
+ [[exercises]]
1314
+ name = "modules3"
1315
+ path = "exercises/modules/modules3.py"
1316
+ hint = "Use `import math as m`, then replace both ??? with m."
1317
+ docs = "https://docs.python.org/3/tutorial/modules.html"
1318
+
1319
+ [[exercises]]
1320
+ name = "modules4"
1321
+ path = "exercises/modules/modules4.py"
1322
+ hint = "Add `import random`, call `random.seed(42)`, then set pick = random.randint(1, 10)."
1323
+ docs = "https://docs.python.org/3/tutorial/modules.html"
1324
+
1325
+ [[exercises]]
1326
+ name = "modules5"
1327
+ path = "exercises/modules/modules5.py"
1328
+ hint = "Add `import string`, then assign digits = string.digits and letters = string.ascii_letters."
1329
+ docs = "https://docs.python.org/3/tutorial/modules.html"
1330
+
1331
+ [[exercises]]
1332
+ name = "modules6"
1333
+ path = "exercises/modules/modules6.py"
1334
+ hint = "When run as a script, __name__ equals the string \"__main__\". Assign that string to module_name."
1335
+ docs = "https://docs.python.org/3/tutorial/modules.html"
1336
+
1337
+ [[exercises]]
1338
+ name = "modules7"
1339
+ path = "exercises/modules/modules7.py"
1340
+ hint = "Inside the `if __name__ == \"__main__\":` block, replace ??? with True."
1341
+ docs = "https://docs.python.org/3/tutorial/modules.html"
1342
+
1343
+ [[exercises]]
1344
+ name = "modules8"
1345
+ path = "exercises/modules/modules8.py"
1346
+ hint = "Add `import math` and `import statistics`. Set data with a list comprehension using random.randint(1, 100), then use statistics.mean and math.sqrt."
1347
+ docs = "https://docs.python.org/3/tutorial/modules.html"
1348
+
1349
+ [[exercises]]
1350
+ name = "collections1"
1351
+ path = "exercises/collections/collections1.py"
1352
+ hint = "Counter takes any iterable: counts = Counter(words)."
1353
+ docs = "https://docs.python.org/3/library/collections.html"
1354
+
1355
+ [[exercises]]
1356
+ name = "collections2"
1357
+ path = "exercises/collections/collections2.py"
1358
+ hint = "Call tally.most_common(2) to get the two highest-count entries as a list of (element, count) pairs."
1359
+ docs = "https://docs.python.org/3/library/collections.html"
1360
+
1361
+ [[exercises]]
1362
+ name = "collections3"
1363
+ path = "exercises/collections/collections3.py"
1364
+ hint = "Set char_counts = defaultdict(int), then loop over text and do char_counts[ch] += 1."
1365
+ docs = "https://docs.python.org/3/library/collections.html"
1366
+
1367
+ [[exercises]]
1368
+ name = "collections4"
1369
+ path = "exercises/collections/collections4.py"
1370
+ hint = "Set by_grade = defaultdict(list), then loop and call by_grade[grade].append(name)."
1371
+ docs = "https://docs.python.org/3/library/collections.html"
1372
+
1373
+ [[exercises]]
1374
+ name = "collections5"
1375
+ path = "exercises/collections/collections5.py"
1376
+ hint = "Define the type with namedtuple('Point', ['x', 'y']), then create an instance: p = Point(3, 4)."
1377
+ docs = "https://docs.python.org/3/library/collections.html"
1378
+
1379
+ [[exercises]]
1380
+ name = "collections6"
1381
+ path = "exercises/collections/collections6.py"
1382
+ hint = "Create card = Card('K', 'spades'), then upgraded = card._replace(rank='A')."
1383
+ docs = "https://docs.python.org/3/library/collections.html"
1384
+
1385
+ [[exercises]]
1386
+ name = "collections7"
1387
+ path = "exercises/collections/collections7.py"
1388
+ hint = "Call d.appendleft(1), d.append(2), d.appendleft(0); then right_val = d.pop() and left_val = d.popleft()."
1389
+ docs = "https://docs.python.org/3/library/collections.html"
1390
+
1391
+ [[exercises]]
1392
+ name = "collections8"
1393
+ path = "exercises/collections/collections8.py"
1394
+ hint = "Enqueue with queue.append(...) for each job; dequeue in order with queue.popleft()."
1395
+ docs = "https://docs.python.org/3/library/collections.html"
1396
+
1397
+ [[exercises]]
1398
+ name = "collections9"
1399
+ path = "exercises/collections/collections9.py"
1400
+ hint = "combined = monday + tuesday adds counts; remainder = combined - sold drops non-positive results."
1401
+ docs = "https://docs.python.org/3/library/collections.html"
1402
+
1403
+ [[exercises]]
1404
+ name = "collections10"
1405
+ path = "exercises/collections/collections10.py"
1406
+ hint = "Build grouped with defaultdict(list) then hit_counts = Counter(cat for cat, _ in log). top_category is most_common(1)[0][0]. avg_times maps each key to sum(v)/len(v)."
1407
+ docs = "https://docs.python.org/3/library/collections.html"
1408
+
1409
+ [[exercises]]
1410
+ name = "itertools1"
1411
+ path = "exercises/itertools/itertools1.py"
1412
+ hint = "Pass both iterables to chain, then wrap it with list(...)."
1413
+ docs = "https://docs.python.org/3/library/itertools.html"
1414
+
1415
+ [[exercises]]
1416
+ name = "itertools2"
1417
+ path = "exercises/itertools/itertools2.py"
1418
+ hint = "Use islice(count(10), 4) and convert the result to a list."
1419
+ docs = "https://docs.python.org/3/library/itertools.html"
1420
+
1421
+ [[exercises]]
1422
+ name = "itertools3"
1423
+ path = "exercises/itertools/itertools3.py"
1424
+ hint = "product(xs, ys) yields tuples for every left/right combination."
1425
+ docs = "https://docs.python.org/3/library/itertools.html"
1426
+
1427
+ [[exercises]]
1428
+ name = "itertools4"
1429
+ path = "exercises/itertools/itertools4.py"
1430
+ hint = "The key function should return row[0], the category part of each tuple."
1431
+ docs = "https://docs.python.org/3/library/itertools.html"
1432
+
1433
+ [[exercises]]
1434
+ name = "itertools5"
1435
+ path = "exercises/itertools/itertools5.py"
1436
+ hint = "accumulate(values) yields each running sum."
1437
+ docs = "https://docs.python.org/3/library/itertools.html"
1438
+
1439
+ [[exercises]]
1440
+ name = "itertools6"
1441
+ path = "exercises/itertools/itertools6.py"
1442
+ hint = "Wrap cycle(colors) in islice(..., 6), then convert to a list."
1443
+ docs = "https://docs.python.org/3/library/itertools.html"
1444
+
1445
+ [[exercises]]
1446
+ name = "itertools7"
1447
+ path = "exercises/itertools/itertools7.py"
1448
+ hint = "zip_longest(left, right, fillvalue='?') keeps going after the short iterable ends."
1449
+ docs = "https://docs.python.org/3/library/itertools.html"
1450
+
1451
+ [[exercises]]
1452
+ name = "itertools8"
1453
+ path = "exercises/itertools/itertools8.py"
1454
+ hint = "pairwise(flattened) yields overlapping pairs from the flattened list."
1455
+ docs = "https://docs.python.org/3/library/itertools.html"
1456
+
1457
+ [[exercises]]
1458
+ name = "json1"
1459
+ path = "exercises/json/json1.py"
1460
+ hint = "Use json.loads(raw) to turn the JSON string into a dictionary."
1461
+ docs = "https://docs.python.org/3/library/json.html"
1462
+
1463
+ [[exercises]]
1464
+ name = "json2"
1465
+ path = "exercises/json/json2.py"
1466
+ hint = "Use json.dumps(payload, sort_keys=True)."
1467
+ docs = "https://docs.python.org/3/library/json.html"
1468
+
1469
+ [[exercises]]
1470
+ name = "json3"
1471
+ path = "exercises/json/json3.py"
1472
+ hint = "Index through profile['user']['address']['city']."
1473
+ docs = "https://docs.python.org/3/library/json.html"
1474
+
1475
+ [[exercises]]
1476
+ name = "json4"
1477
+ path = "exercises/json/json4.py"
1478
+ hint = "json.dump writes the payload object into the buffer."
1479
+ docs = "https://docs.python.org/3/library/json.html"
1480
+
1481
+ [[exercises]]
1482
+ name = "json5"
1483
+ path = "exercises/json/json5.py"
1484
+ hint = "Call data.get('timezone', 'UTC') so missing values have a default."
1485
+ docs = "https://docs.python.org/3/library/json.html"
1486
+
1487
+ [[exercises]]
1488
+ name = "json6"
1489
+ path = "exercises/json/json6.py"
1490
+ hint = "Use a list comprehension that keeps users where user['active'] is true."
1491
+ docs = "https://docs.python.org/3/library/json.html"
1492
+
1493
+ [[exercises]]
1494
+ name = "json7"
1495
+ path = "exercises/json/json7.py"
1496
+ hint = "Assign the string 'dark' before dumping the settings again."
1497
+ docs = "https://docs.python.org/3/library/json.html"
1498
+
1499
+ [[exercises]]
1500
+ name = "json8"
1501
+ path = "exercises/json/json8.py"
1502
+ hint = "Use json.loads(encoded) to decode the serialized object."
1503
+ docs = "https://docs.python.org/3/library/json.html"
1504
+
1505
+ [[exercises]]
1506
+ name = "datetime1"
1507
+ path = "exercises/datetime/datetime1.py"
1508
+ hint = "Call date(2026, 5, 23)."
1509
+ docs = "https://docs.python.org/3/library/datetime.html"
1510
+
1511
+ [[exercises]]
1512
+ name = "datetime2"
1513
+ path = "exercises/datetime/datetime2.py"
1514
+ hint = "Use start + timedelta(days=7)."
1515
+ docs = "https://docs.python.org/3/library/datetime.html"
1516
+
1517
+ [[exercises]]
1518
+ name = "datetime3"
1519
+ path = "exercises/datetime/datetime3.py"
1520
+ hint = "Use datetime.strptime(raw, '%Y-%m-%d %H:%M')."
1521
+ docs = "https://docs.python.org/3/library/datetime.html"
1522
+
1523
+ [[exercises]]
1524
+ name = "datetime4"
1525
+ path = "exercises/datetime/datetime4.py"
1526
+ hint = "Use day.strftime('%d/%m/%Y')."
1527
+ docs = "https://docs.python.org/3/library/datetime.html"
1528
+
1529
+ [[exercises]]
1530
+ name = "datetime5"
1531
+ path = "exercises/datetime/datetime5.py"
1532
+ hint = "Date objects can be compared directly with > and <."
1533
+ docs = "https://docs.python.org/3/library/datetime.html"
1534
+
1535
+ [[exercises]]
1536
+ name = "datetime6"
1537
+ path = "exercises/datetime/datetime6.py"
1538
+ hint = "Subtract two dates and read the .days attribute from the timedelta."
1539
+ docs = "https://docs.python.org/3/library/datetime.html"
1540
+
1541
+ [[exercises]]
1542
+ name = "datetime7"
1543
+ path = "exercises/datetime/datetime7.py"
1544
+ hint = "Use datetime.combine(day, clock)."
1545
+ docs = "https://docs.python.org/3/library/datetime.html"
1546
+
1547
+ [[exercises]]
1548
+ name = "datetime8"
1549
+ path = "exercises/datetime/datetime8.py"
1550
+ hint = "Use min(parsed) and max(parsed)."
1551
+ docs = "https://docs.python.org/3/library/datetime.html"
1552
+
1553
+ [[exercises]]
1554
+ name = "enums1"
1555
+ path = "exercises/enums/enums1.py"
1556
+ hint = "Enum member values can be ordinary strings like 'red' and 'blue'."
1557
+ docs = "https://docs.python.org/3/library/enum.html"
1558
+
1559
+ [[exercises]]
1560
+ name = "enums2"
1561
+ path = "exercises/enums/enums2.py"
1562
+ hint = "Assign auto() to each member when the exact values do not matter."
1563
+ docs = "https://docs.python.org/3/library/enum.html"
1564
+
1565
+ [[exercises]]
1566
+ name = "enums3"
1567
+ path = "exercises/enums/enums3.py"
1568
+ hint = "Use selected.name and selected.value."
1569
+ docs = "https://docs.python.org/3/library/enum.html"
1570
+
1571
+ [[exercises]]
1572
+ name = "enums4"
1573
+ path = "exercises/enums/enums4.py"
1574
+ hint = "Use a list comprehension over Size and read member.value."
1575
+ docs = "https://docs.python.org/3/library/enum.html"
1576
+
1577
+ [[exercises]]
1578
+ name = "enums5"
1579
+ path = "exercises/enums/enums5.py"
1580
+ hint = "Check whether state is in {TicketState.CLOSED, TicketState.CANCELLED}."
1581
+ docs = "https://docs.python.org/3/library/enum.html"
1582
+
1583
+ [[exercises]]
1584
+ name = "enums6"
1585
+ path = "exercises/enums/enums6.py"
1586
+ hint = "Inside an Enum method, self.value is the value assigned to that member."
1587
+ docs = "https://docs.python.org/3/library/enum.html"
1588
+
1589
+ [[exercises]]
1590
+ name = "pathlib1"
1591
+ path = "exercises/pathlib/pathlib1.py"
1592
+ hint = "Use Path('notes/today.txt')."
1593
+ docs = "https://docs.python.org/3/library/pathlib.html"
1594
+
1595
+ [[exercises]]
1596
+ name = "pathlib2"
1597
+ path = "exercises/pathlib/pathlib2.py"
1598
+ hint = "Use project / 'src' / 'main.py'."
1599
+ docs = "https://docs.python.org/3/library/pathlib.html"
1600
+
1601
+ [[exercises]]
1602
+ name = "pathlib3"
1603
+ path = "exercises/pathlib/pathlib3.py"
1604
+ hint = "Use path.parent, path.stem, and path.suffix."
1605
+ docs = "https://docs.python.org/3/library/pathlib.html"
1606
+
1607
+ [[exercises]]
1608
+ name = "pathlib4"
1609
+ path = "exercises/pathlib/pathlib4.py"
1610
+ hint = "Use a list comprehension and keep paths whose suffix is '.py'."
1611
+ docs = "https://docs.python.org/3/library/pathlib.html"
1612
+
1613
+ [[exercises]]
1614
+ name = "pathlib5"
1615
+ path = "exercises/pathlib/pathlib5.py"
1616
+ hint = "with_name('final.txt') keeps the same parent directory."
1617
+ docs = "https://docs.python.org/3/library/pathlib.html"
1618
+
1619
+ [[exercises]]
1620
+ name = "pathlib6"
1621
+ path = "exercises/pathlib/pathlib6.py"
1622
+ hint = "Use source.with_suffix('.json')."
1623
+ docs = "https://docs.python.org/3/library/pathlib.html"
1624
+
1625
+ [[exercises]]
1626
+ name = "oop_advanced1"
1627
+ path = "exercises/oop_advanced/oop_advanced1.py"
1628
+ hint = "Put Animal inside Dog's parentheses."
1629
+ docs = "https://docs.python.org/3/tutorial/classes.html"
1630
+
1631
+ [[exercises]]
1632
+ name = "oop_advanced2"
1633
+ path = "exercises/oop_advanced/oop_advanced2.py"
1634
+ hint = "Call super().__init__(name) before assigning role."
1635
+ docs = "https://docs.python.org/3/tutorial/classes.html"
1636
+
1637
+ [[exercises]]
1638
+ name = "oop_advanced3"
1639
+ path = "exercises/oop_advanced/oop_advanced3.py"
1640
+ hint = "Sum shape.area() for each shape in shapes."
1641
+ docs = "https://docs.python.org/3/tutorial/classes.html"
1642
+
1643
+ [[exercises]]
1644
+ name = "oop_advanced4"
1645
+ path = "exercises/oop_advanced/oop_advanced4.py"
1646
+ hint = "A property method can return self._name."
1647
+ docs = "https://docs.python.org/3/tutorial/classes.html"
1648
+
1649
+ [[exercises]]
1650
+ name = "oop_advanced5"
1651
+ path = "exercises/oop_advanced/oop_advanced5.py"
1652
+ hint = "Return len(self.songs) from __len__."
1653
+ docs = "https://docs.python.org/3/tutorial/classes.html"
1654
+
1655
+ [[exercises]]
1656
+ name = "oop_advanced6"
1657
+ path = "exercises/oop_advanced/oop_advanced6.py"
1658
+ hint = "Return an f-string that includes self.x and self.y."
1659
+ docs = "https://docs.python.org/3/tutorial/classes.html"
1660
+
1661
+ [[exercises]]
1662
+ name = "oop_advanced7"
1663
+ path = "exercises/oop_advanced/oop_advanced7.py"
1664
+ hint = "Compare self.isbn with other.isbn."
1665
+ docs = "https://docs.python.org/3/tutorial/classes.html"
1666
+
1667
+ [[exercises]]
1668
+ name = "oop_advanced8"
1669
+ path = "exercises/oop_advanced/oop_advanced8.py"
1670
+ hint = "Return cls(int(x_text), int(y_text))."
1671
+ docs = "https://docs.python.org/3/tutorial/classes.html"
1672
+
1673
+ [[exercises]]
1674
+ name = "oop_advanced9"
1675
+ path = "exercises/oop_advanced/oop_advanced9.py"
1676
+ hint = "A valid percentage is between 0 and 100 inclusive."
1677
+ docs = "https://docs.python.org/3/tutorial/classes.html"
1678
+
1679
+ [[exercises]]
1680
+ name = "oop_advanced10"
1681
+ path = "exercises/oop_advanced/oop_advanced10.py"
1682
+ hint = "Return self.side * self.side from Square.area."
1683
+ docs = "https://docs.python.org/3/tutorial/classes.html"
1684
+
1685
+ [[exercises]]
1686
+ name = "oop_advanced11"
1687
+ path = "exercises/oop_advanced/oop_advanced11.py"
1688
+ hint = "Return dict(self.__dict__) from the mixin method."
1689
+ docs = "https://docs.python.org/3/tutorial/classes.html"
1690
+
1691
+ [[exercises]]
1692
+ name = "oop_advanced12"
1693
+ path = "exercises/oop_advanced/oop_advanced12.py"
1694
+ hint = "Return a new Vector with coordinates added pairwise."
1695
+ docs = "https://docs.python.org/3/tutorial/classes.html"
1696
+
1697
+ [[exercises]]
1698
+ name = "async1"
1699
+ path = "exercises/async/async1.py"
1700
+ hint = "An async function can return a normal string value."
1701
+ docs = "https://docs.python.org/3/library/asyncio.html"
1702
+
1703
+ [[exercises]]
1704
+ name = "async2"
1705
+ path = "exercises/async/async2.py"
1706
+ hint = "Use await get_message() inside main."
1707
+ docs = "https://docs.python.org/3/library/asyncio.html"
1708
+
1709
+ [[exercises]]
1710
+ name = "async3"
1711
+ path = "exercises/async/async3.py"
1712
+ hint = "Call await asyncio.sleep(0) before the return."
1713
+ docs = "https://docs.python.org/3/library/asyncio.html"
1714
+
1715
+ [[exercises]]
1716
+ name = "async4"
1717
+ path = "exercises/async/async4.py"
1718
+ hint = "await asyncio.gather(first(), second()) returns a list-like result of both values."
1719
+ docs = "https://docs.python.org/3/library/asyncio.html"
1720
+
1721
+ [[exercises]]
1722
+ name = "async5"
1723
+ path = "exercises/async/async5.py"
1724
+ hint = "Use asyncio.create_task(compute())."
1725
+ docs = "https://docs.python.org/3/library/asyncio.html"
1726
+
1727
+ [[exercises]]
1728
+ name = "async6"
1729
+ path = "exercises/async/async6.py"
1730
+ hint = "Append each value to result inside the async for loop."
1731
+ docs = "https://docs.python.org/3/library/asyncio.html"
1732
+
1733
+ [[exercises]]
1734
+ name = "async7"
1735
+ path = "exercises/async/async7.py"
1736
+ hint = "Return await asyncio.wait_for(quick(), timeout=1)."
1737
+ docs = "https://docs.python.org/3/library/asyncio.html"
1738
+
1739
+ [[exercises]]
1740
+ name = "async8"
1741
+ path = "exercises/async/async8.py"
1742
+ hint = "Use asyncio.run(answer()) at top level."
1743
+ docs = "https://docs.python.org/3/library/asyncio.html"
1744
+
1745
+ [[exercises]]
1746
+ name = "async9"
1747
+ path = "exercises/async/async9.py"
1748
+ hint = "Use asyncio.gather with a generator expression that calls double(value)."
1749
+ docs = "https://docs.python.org/3/library/asyncio.html"
1750
+
1751
+ [[exercises]]
1752
+ name = "async10"
1753
+ path = "exercises/async/async10.py"
1754
+ hint = "Gather fetch_name(name) for each name, then join the returned list."
1755
+ docs = "https://docs.python.org/3/library/asyncio.html"