oh-my-oop 0.2.0

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 (660) hide show
  1. package/MCP_STRUCTURE.md +301 -0
  2. package/README.md +167 -0
  3. package/SCOPE.md +27 -0
  4. package/dist/application/discovery.d.ts +133 -0
  5. package/dist/application/discovery.js +62 -0
  6. package/dist/application/discovery.js.map +1 -0
  7. package/dist/cli.d.ts +2 -0
  8. package/dist/cli.js +80 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/config.d.ts +16 -0
  11. package/dist/config.js +32 -0
  12. package/dist/config.js.map +1 -0
  13. package/dist/domain/collaborators.d.ts +2 -0
  14. package/dist/domain/collaborators.js +26 -0
  15. package/dist/domain/collaborators.js.map +1 -0
  16. package/dist/domain/ids.d.ts +4 -0
  17. package/dist/domain/ids.js +23 -0
  18. package/dist/domain/ids.js.map +1 -0
  19. package/dist/domain/model.d.ts +71 -0
  20. package/dist/domain/model.js +2 -0
  21. package/dist/domain/model.js.map +1 -0
  22. package/dist/domain/schemas.d.ts +213 -0
  23. package/dist/domain/schemas.js +79 -0
  24. package/dist/domain/schemas.js.map +1 -0
  25. package/dist/domain/stereotypes.d.ts +7 -0
  26. package/dist/domain/stereotypes.js +65 -0
  27. package/dist/domain/stereotypes.js.map +1 -0
  28. package/dist/index.d.ts +2 -0
  29. package/dist/index.js +21 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/io/classStore.d.ts +9 -0
  32. package/dist/io/classStore.js +39 -0
  33. package/dist/io/classStore.js.map +1 -0
  34. package/dist/io/collaborationStore.d.ts +7 -0
  35. package/dist/io/collaborationStore.js +32 -0
  36. package/dist/io/collaborationStore.js.map +1 -0
  37. package/dist/io/design.d.ts +3 -0
  38. package/dist/io/design.js +22 -0
  39. package/dist/io/design.js.map +1 -0
  40. package/dist/io/designIndex.d.ts +6 -0
  41. package/dist/io/designIndex.js +49 -0
  42. package/dist/io/designIndex.js.map +1 -0
  43. package/dist/io/frontmatter.d.ts +8 -0
  44. package/dist/io/frontmatter.js +31 -0
  45. package/dist/io/frontmatter.js.map +1 -0
  46. package/dist/io/history.d.ts +10 -0
  47. package/dist/io/history.js +38 -0
  48. package/dist/io/history.js.map +1 -0
  49. package/dist/io/useCaseStore.d.ts +8 -0
  50. package/dist/io/useCaseStore.js +36 -0
  51. package/dist/io/useCaseStore.js.map +1 -0
  52. package/dist/io/workspace.d.ts +14 -0
  53. package/dist/io/workspace.js +82 -0
  54. package/dist/io/workspace.js.map +1 -0
  55. package/dist/oop/commands.d.ts +446 -0
  56. package/dist/oop/commands.js +319 -0
  57. package/dist/oop/commands.js.map +1 -0
  58. package/dist/oop/conformance.d.ts +16 -0
  59. package/dist/oop/conformance.js +30 -0
  60. package/dist/oop/conformance.js.map +1 -0
  61. package/dist/prompts/discovery.d.ts +2 -0
  62. package/dist/prompts/discovery.js +41 -0
  63. package/dist/prompts/discovery.js.map +1 -0
  64. package/dist/prompts/imagineWithoutController.d.ts +2 -0
  65. package/dist/prompts/imagineWithoutController.js +75 -0
  66. package/dist/prompts/imagineWithoutController.js.map +1 -0
  67. package/dist/prompts/index.d.ts +2 -0
  68. package/dist/prompts/index.js +17 -0
  69. package/dist/prompts/index.js.map +1 -0
  70. package/dist/prompts/phasePressureTest.d.ts +2 -0
  71. package/dist/prompts/phasePressureTest.js +69 -0
  72. package/dist/prompts/phasePressureTest.js.map +1 -0
  73. package/dist/prompts/rddIntro.d.ts +2 -0
  74. package/dist/prompts/rddIntro.js +53 -0
  75. package/dist/prompts/rddIntro.js.map +1 -0
  76. package/dist/prompts/review.d.ts +2 -0
  77. package/dist/prompts/review.js +45 -0
  78. package/dist/prompts/review.js.map +1 -0
  79. package/dist/prompts/stateMachineIntrospect.d.ts +2 -0
  80. package/dist/prompts/stateMachineIntrospect.js +80 -0
  81. package/dist/prompts/stateMachineIntrospect.js.map +1 -0
  82. package/dist/prompts/tellDontAskRephrase.d.ts +2 -0
  83. package/dist/prompts/tellDontAskRephrase.js +66 -0
  84. package/dist/prompts/tellDontAskRephrase.js.map +1 -0
  85. package/dist/render/diff.d.ts +21 -0
  86. package/dist/render/diff.js +84 -0
  87. package/dist/render/diff.js.map +1 -0
  88. package/dist/render/mermaid.d.ts +24 -0
  89. package/dist/render/mermaid.js +53 -0
  90. package/dist/render/mermaid.js.map +1 -0
  91. package/dist/render/sideBySide.d.ts +14 -0
  92. package/dist/render/sideBySide.js +91 -0
  93. package/dist/render/sideBySide.js.map +1 -0
  94. package/dist/resources/index.d.ts +2 -0
  95. package/dist/resources/index.js +349 -0
  96. package/dist/resources/index.js.map +1 -0
  97. package/dist/server.d.ts +2 -0
  98. package/dist/server.js +22 -0
  99. package/dist/server.js.map +1 -0
  100. package/dist/tools/alternatives.d.ts +2 -0
  101. package/dist/tools/alternatives.js +9 -0
  102. package/dist/tools/alternatives.js.map +1 -0
  103. package/dist/tools/classes.d.ts +2 -0
  104. package/dist/tools/classes.js +13 -0
  105. package/dist/tools/classes.js.map +1 -0
  106. package/dist/tools/collaborations.d.ts +2 -0
  107. package/dist/tools/collaborations.js +8 -0
  108. package/dist/tools/collaborations.js.map +1 -0
  109. package/dist/tools/compare.d.ts +2 -0
  110. package/dist/tools/compare.js +9 -0
  111. package/dist/tools/compare.js.map +1 -0
  112. package/dist/tools/conformance.d.ts +3 -0
  113. package/dist/tools/conformance.js +11 -0
  114. package/dist/tools/conformance.js.map +1 -0
  115. package/dist/tools/diagram.d.ts +2 -0
  116. package/dist/tools/diagram.js +9 -0
  117. package/dist/tools/diagram.js.map +1 -0
  118. package/dist/tools/discovery.d.ts +2 -0
  119. package/dist/tools/discovery.js +23 -0
  120. package/dist/tools/discovery.js.map +1 -0
  121. package/dist/tools/index.d.ts +2 -0
  122. package/dist/tools/index.js +27 -0
  123. package/dist/tools/index.js.map +1 -0
  124. package/dist/tools/init.d.ts +2 -0
  125. package/dist/tools/init.js +9 -0
  126. package/dist/tools/init.js.map +1 -0
  127. package/dist/tools/oop.d.ts +9 -0
  128. package/dist/tools/oop.js +26 -0
  129. package/dist/tools/oop.js.map +1 -0
  130. package/dist/tools/responsibilities.d.ts +2 -0
  131. package/dist/tools/responsibilities.js +13 -0
  132. package/dist/tools/responsibilities.js.map +1 -0
  133. package/dist/tools/state.d.ts +2 -0
  134. package/dist/tools/state.js +8 -0
  135. package/dist/tools/state.js.map +1 -0
  136. package/dist/tools/useCases.d.ts +2 -0
  137. package/dist/tools/useCases.js +18 -0
  138. package/dist/tools/useCases.js.map +1 -0
  139. package/dist/tools/validate.d.ts +2 -0
  140. package/dist/tools/validate.js +9 -0
  141. package/dist/tools/validate.js.map +1 -0
  142. package/dist/tradeoff/engine.d.ts +61 -0
  143. package/dist/tradeoff/engine.js +171 -0
  144. package/dist/tradeoff/engine.js.map +1 -0
  145. package/dist/tradeoff/heuristics/classSplit.d.ts +3 -0
  146. package/dist/tradeoff/heuristics/classSplit.js +94 -0
  147. package/dist/tradeoff/heuristics/classSplit.js.map +1 -0
  148. package/dist/tradeoff/heuristics/collaborationShape.d.ts +2 -0
  149. package/dist/tradeoff/heuristics/collaborationShape.js +82 -0
  150. package/dist/tradeoff/heuristics/collaborationShape.js.map +1 -0
  151. package/dist/tradeoff/heuristics/collectionShape.d.ts +2 -0
  152. package/dist/tradeoff/heuristics/collectionShape.js +113 -0
  153. package/dist/tradeoff/heuristics/collectionShape.js.map +1 -0
  154. package/dist/tradeoff/heuristics/dualSubjectComparison.d.ts +2 -0
  155. package/dist/tradeoff/heuristics/dualSubjectComparison.js +114 -0
  156. package/dist/tradeoff/heuristics/dualSubjectComparison.js.map +1 -0
  157. package/dist/tradeoff/heuristics/errorHandling.d.ts +2 -0
  158. package/dist/tradeoff/heuristics/errorHandling.js +110 -0
  159. package/dist/tradeoff/heuristics/errorHandling.js.map +1 -0
  160. package/dist/tradeoff/heuristics/responsibilitySplit.d.ts +23 -0
  161. package/dist/tradeoff/heuristics/responsibilitySplit.js +183 -0
  162. package/dist/tradeoff/heuristics/responsibilitySplit.js.map +1 -0
  163. package/dist/tradeoff/heuristics/stereotypeChoice.d.ts +2 -0
  164. package/dist/tradeoff/heuristics/stereotypeChoice.js +23 -0
  165. package/dist/tradeoff/heuristics/stereotypeChoice.js.map +1 -0
  166. package/dist/tradeoff/heuristics/strategyOrPolicy.d.ts +2 -0
  167. package/dist/tradeoff/heuristics/strategyOrPolicy.js +110 -0
  168. package/dist/tradeoff/heuristics/strategyOrPolicy.js.map +1 -0
  169. package/dist/tradeoff/heuristics/valueObjectShape.d.ts +2 -0
  170. package/dist/tradeoff/heuristics/valueObjectShape.js +111 -0
  171. package/dist/tradeoff/heuristics/valueObjectShape.js.map +1 -0
  172. package/dist/tradeoff/templates.d.ts +2 -0
  173. package/dist/tradeoff/templates.js +33 -0
  174. package/dist/tradeoff/templates.js.map +1 -0
  175. package/dist/util/log.d.ts +1 -0
  176. package/dist/util/log.js +7 -0
  177. package/dist/util/log.js.map +1 -0
  178. package/dist/util/mcp.d.ts +4 -0
  179. package/dist/util/mcp.js +18 -0
  180. package/dist/util/mcp.js.map +1 -0
  181. package/dist/validate/cohesion.d.ts +3 -0
  182. package/dist/validate/cohesion.js +88 -0
  183. package/dist/validate/cohesion.js.map +1 -0
  184. package/dist/validate/collectionWrapper.d.ts +3 -0
  185. package/dist/validate/collectionWrapper.js +131 -0
  186. package/dist/validate/collectionWrapper.js.map +1 -0
  187. package/dist/validate/coupling.d.ts +3 -0
  188. package/dist/validate/coupling.js +47 -0
  189. package/dist/validate/coupling.js.map +1 -0
  190. package/dist/validate/cycle.d.ts +3 -0
  191. package/dist/validate/cycle.js +101 -0
  192. package/dist/validate/cycle.js.map +1 -0
  193. package/dist/validate/dataDuplication.d.ts +3 -0
  194. package/dist/validate/dataDuplication.js +150 -0
  195. package/dist/validate/dataDuplication.js.map +1 -0
  196. package/dist/validate/dependencyDirection.d.ts +3 -0
  197. package/dist/validate/dependencyDirection.js +106 -0
  198. package/dist/validate/dependencyDirection.js.map +1 -0
  199. package/dist/validate/dualUseKnowing.d.ts +3 -0
  200. package/dist/validate/dualUseKnowing.js +137 -0
  201. package/dist/validate/dualUseKnowing.js.map +1 -0
  202. package/dist/validate/emptyObjectFill.d.ts +3 -0
  203. package/dist/validate/emptyObjectFill.js +119 -0
  204. package/dist/validate/emptyObjectFill.js.map +1 -0
  205. package/dist/validate/findings.d.ts +22 -0
  206. package/dist/validate/findings.js +12 -0
  207. package/dist/validate/findings.js.map +1 -0
  208. package/dist/validate/functionDecompositionExcess.d.ts +3 -0
  209. package/dist/validate/functionDecompositionExcess.js +120 -0
  210. package/dist/validate/functionDecompositionExcess.js.map +1 -0
  211. package/dist/validate/functionNotObject.d.ts +3 -0
  212. package/dist/validate/functionNotObject.js +80 -0
  213. package/dist/validate/functionNotObject.js.map +1 -0
  214. package/dist/validate/godObject.d.ts +6 -0
  215. package/dist/validate/godObject.js +76 -0
  216. package/dist/validate/godObject.js.map +1 -0
  217. package/dist/validate/presentationInDomain.d.ts +3 -0
  218. package/dist/validate/presentationInDomain.js +57 -0
  219. package/dist/validate/presentationInDomain.js.map +1 -0
  220. package/dist/validate/primitiveWrapper.d.ts +3 -0
  221. package/dist/validate/primitiveWrapper.js +106 -0
  222. package/dist/validate/primitiveWrapper.js.map +1 -0
  223. package/dist/validate/rules.d.ts +24 -0
  224. package/dist/validate/rules.js +269 -0
  225. package/dist/validate/rules.js.map +1 -0
  226. package/dist/validate/singletonStatefulHolder.d.ts +3 -0
  227. package/dist/validate/singletonStatefulHolder.js +128 -0
  228. package/dist/validate/singletonStatefulHolder.js.map +1 -0
  229. package/dist/validate/strategyAsymmetry.d.ts +3 -0
  230. package/dist/validate/strategyAsymmetry.js +131 -0
  231. package/dist/validate/strategyAsymmetry.js.map +1 -0
  232. package/dist/validate/testability.d.ts +5 -0
  233. package/dist/validate/testability.js +157 -0
  234. package/dist/validate/testability.js.map +1 -0
  235. package/dist/validate/vagueName.d.ts +3 -0
  236. package/dist/validate/vagueName.js +136 -0
  237. package/dist/validate/vagueName.js.map +1 -0
  238. package/dist/validate/validationLocation.d.ts +3 -0
  239. package/dist/validate/validationLocation.js +120 -0
  240. package/dist/validate/validationLocation.js.map +1 -0
  241. package/lessons/STYLE_GUIDE.md +304 -0
  242. package/lessons/woowacourse-kotlin-blackjack/2chang5/33-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +293 -0
  243. package/lessons/woowacourse-kotlin-blackjack/Choisehyeon/52-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +106 -0
  244. package/lessons/woowacourse-kotlin-blackjack/Choisehyeon/9-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +282 -0
  245. package/lessons/woowacourse-kotlin-blackjack/DYGames/14-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +182 -0
  246. package/lessons/woowacourse-kotlin-blackjack/DYGames/37-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +122 -0
  247. package/lessons/woowacourse-kotlin-blackjack/EmilyCh0/12-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +117 -0
  248. package/lessons/woowacourse-kotlin-blackjack/EmilyCh0/38-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +291 -0
  249. package/lessons/woowacourse-kotlin-blackjack/HANDOVER.md +1475 -0
  250. package/lessons/woowacourse-kotlin-blackjack/HamBeomJoon/119-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +251 -0
  251. package/lessons/woowacourse-kotlin-blackjack/HamBeomJoon/137-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +459 -0
  252. package/lessons/woowacourse-kotlin-blackjack/Hevton/100-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +282 -0
  253. package/lessons/woowacourse-kotlin-blackjack/Hevton/82-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +303 -0
  254. package/lessons/woowacourse-kotlin-blackjack/Hogu59/71-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +134 -0
  255. package/lessons/woowacourse-kotlin-blackjack/Hogu59/96-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +323 -0
  256. package/lessons/woowacourse-kotlin-blackjack/JoYehyun99/66-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +210 -0
  257. package/lessons/woowacourse-kotlin-blackjack/Junyoung-WON/101-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +191 -0
  258. package/lessons/woowacourse-kotlin-blackjack/Junyoung-WON/80-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +253 -0
  259. package/lessons/woowacourse-kotlin-blackjack/Leeyerin0210/108-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +516 -0
  260. package/lessons/woowacourse-kotlin-blackjack/Leeyerin0210/133-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +541 -0
  261. package/lessons/woowacourse-kotlin-blackjack/RightHennessy/22-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +278 -0
  262. package/lessons/woowacourse-kotlin-blackjack/RightHennessy/48-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +188 -0
  263. package/lessons/woowacourse-kotlin-blackjack/SeongHoonC/16-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +228 -0
  264. package/lessons/woowacourse-kotlin-blackjack/SeongHoonC/54-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +227 -0
  265. package/lessons/woowacourse-kotlin-blackjack/Yunseok-Nam/76-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +279 -0
  266. package/lessons/woowacourse-kotlin-blackjack/Yunseok-Nam/86-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +203 -0
  267. package/lessons/woowacourse-kotlin-blackjack/aprilgom/105-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +162 -0
  268. package/lessons/woowacourse-kotlin-blackjack/aprilgom/64-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +279 -0
  269. package/lessons/woowacourse-kotlin-blackjack/boogi-woogi/18-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +188 -0
  270. package/lessons/woowacourse-kotlin-blackjack/boogi-woogi/36-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +769 -0
  271. package/lessons/woowacourse-kotlin-blackjack/briandr97/19-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +226 -0
  272. package/lessons/woowacourse-kotlin-blackjack/briandr97/59-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +193 -0
  273. package/lessons/woowacourse-kotlin-blackjack/chaehyuns/70-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +175 -0
  274. package/lessons/woowacourse-kotlin-blackjack/chaehyuns/98-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +206 -0
  275. package/lessons/woowacourse-kotlin-blackjack/chanho0908/123-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +277 -0
  276. package/lessons/woowacourse-kotlin-blackjack/chanho0908/150-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +219 -0
  277. package/lessons/woowacourse-kotlin-blackjack/chws0508/26-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +259 -0
  278. package/lessons/woowacourse-kotlin-blackjack/chws0508/43-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +189 -0
  279. package/lessons/woowacourse-kotlin-blackjack/cucumber99/109-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +351 -0
  280. package/lessons/woowacourse-kotlin-blackjack/cucumber99/149-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +147 -0
  281. package/lessons/woowacourse-kotlin-blackjack/devfeijoa/121-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +168 -0
  282. package/lessons/woowacourse-kotlin-blackjack/devfeijoa/153-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +116 -0
  283. package/lessons/woowacourse-kotlin-blackjack/doabletuple/126-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +680 -0
  284. package/lessons/woowacourse-kotlin-blackjack/doabletuple/142-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +739 -0
  285. package/lessons/woowacourse-kotlin-blackjack/donghyun81/116-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +297 -0
  286. package/lessons/woowacourse-kotlin-blackjack/donghyun81/147-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +244 -0
  287. package/lessons/woowacourse-kotlin-blackjack/dpcks0509/78-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +232 -0
  288. package/lessons/woowacourse-kotlin-blackjack/dpcks0509/88-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +137 -0
  289. package/lessons/woowacourse-kotlin-blackjack/etama123/112-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +269 -0
  290. package/lessons/woowacourse-kotlin-blackjack/etama123/148-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +240 -0
  291. package/lessons/woowacourse-kotlin-blackjack/gaeun5744/102-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +146 -0
  292. package/lessons/woowacourse-kotlin-blackjack/gaeun5744/69-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +224 -0
  293. package/lessons/woowacourse-kotlin-blackjack/gahyunkim/118-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +397 -0
  294. package/lessons/woowacourse-kotlin-blackjack/gahyunkim/141-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +215 -0
  295. package/lessons/woowacourse-kotlin-blackjack/giovannijunseokim/106-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +395 -0
  296. package/lessons/woowacourse-kotlin-blackjack/giovannijunseokim/134-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +219 -0
  297. package/lessons/woowacourse-kotlin-blackjack/haeum808/62-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +230 -0
  298. package/lessons/woowacourse-kotlin-blackjack/haeum808/89-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +169 -0
  299. package/lessons/woowacourse-kotlin-blackjack/hwannow/110-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +221 -0
  300. package/lessons/woowacourse-kotlin-blackjack/hwannow/132-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +573 -0
  301. package/lessons/woowacourse-kotlin-blackjack/hxeyexn/103-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +188 -0
  302. package/lessons/woowacourse-kotlin-blackjack/hxeyexn/81-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +301 -0
  303. package/lessons/woowacourse-kotlin-blackjack/hyemdooly/21-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +613 -0
  304. package/lessons/woowacourse-kotlin-blackjack/hyemdooly/35-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +691 -0
  305. package/lessons/woowacourse-kotlin-blackjack/hyunji1203/13-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +206 -0
  306. package/lessons/woowacourse-kotlin-blackjack/ii2001/79-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +153 -0
  307. package/lessons/woowacourse-kotlin-blackjack/ii2001/85-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +318 -0
  308. package/lessons/woowacourse-kotlin-blackjack/ijh1298/128-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +250 -0
  309. package/lessons/woowacourse-kotlin-blackjack/ijh1298/135-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +269 -0
  310. package/lessons/woowacourse-kotlin-blackjack/inseonyun/28-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +346 -0
  311. package/lessons/woowacourse-kotlin-blackjack/inseonyun/49-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +360 -0
  312. package/lessons/woowacourse-kotlin-blackjack/ippnsj/30-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +152 -0
  313. package/lessons/woowacourse-kotlin-blackjack/ippnsj/42-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +213 -0
  314. package/lessons/woowacourse-kotlin-blackjack/jaeyeongjo/73-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +247 -0
  315. package/lessons/woowacourse-kotlin-blackjack/jaeyeongjo/87-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +900 -0
  316. package/lessons/woowacourse-kotlin-blackjack/jerry8282/125-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +248 -0
  317. package/lessons/woowacourse-kotlin-blackjack/jerry8282/151-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +243 -0
  318. package/lessons/woowacourse-kotlin-blackjack/jinuemong/63-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +281 -0
  319. package/lessons/woowacourse-kotlin-blackjack/jinuemong/92-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +283 -0
  320. package/lessons/woowacourse-kotlin-blackjack/jiyuneel/113-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +348 -0
  321. package/lessons/woowacourse-kotlin-blackjack/jiyuneel/140-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +265 -0
  322. package/lessons/woowacourse-kotlin-blackjack/junjange/61-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +270 -0
  323. package/lessons/woowacourse-kotlin-blackjack/junjange/93-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +465 -0
  324. package/lessons/woowacourse-kotlin-blackjack/junseo511/107-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +296 -0
  325. package/lessons/woowacourse-kotlin-blackjack/junseo511/145-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +316 -0
  326. package/lessons/woowacourse-kotlin-blackjack/ki960213/11-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +175 -0
  327. package/lessons/woowacourse-kotlin-blackjack/kimhm0728/72-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +458 -0
  328. package/lessons/woowacourse-kotlin-blackjack/kimhm0728/97-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +225 -0
  329. package/lessons/woowacourse-kotlin-blackjack/kkosang/68-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +221 -0
  330. package/lessons/woowacourse-kotlin-blackjack/kkosang/94-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +158 -0
  331. package/lessons/woowacourse-kotlin-blackjack/kmkim2689/65-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +252 -0
  332. package/lessons/woowacourse-kotlin-blackjack/kmkim2689/90-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +460 -0
  333. package/lessons/woowacourse-kotlin-blackjack/krrong/32-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +216 -0
  334. package/lessons/woowacourse-kotlin-blackjack/krrong/46-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +285 -0
  335. package/lessons/woowacourse-kotlin-blackjack/m6z1/122-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +177 -0
  336. package/lessons/woowacourse-kotlin-blackjack/m6z1/144-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +155 -0
  337. package/lessons/woowacourse-kotlin-blackjack/medAndro/130-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +683 -0
  338. package/lessons/woowacourse-kotlin-blackjack/medAndro/143-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +678 -0
  339. package/lessons/woowacourse-kotlin-blackjack/moondev03/114-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +262 -0
  340. package/lessons/woowacourse-kotlin-blackjack/moondev03/131-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +498 -0
  341. package/lessons/woowacourse-kotlin-blackjack/murjune/77-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +287 -0
  342. package/lessons/woowacourse-kotlin-blackjack/murjune/91-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +280 -0
  343. package/lessons/woowacourse-kotlin-blackjack/no1msh/31-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +250 -0
  344. package/lessons/woowacourse-kotlin-blackjack/otter66/24-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +302 -0
  345. package/lessons/woowacourse-kotlin-blackjack/otter66/58-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +391 -0
  346. package/lessons/woowacourse-kotlin-blackjack/oungsi2000/111-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +253 -0
  347. package/lessons/woowacourse-kotlin-blackjack/oungsi2000/136-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +540 -0
  348. package/lessons/woowacourse-kotlin-blackjack/parkjiminnnn/117-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +819 -0
  349. package/lessons/woowacourse-kotlin-blackjack/parkjiminnnn/139-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +683 -0
  350. package/lessons/woowacourse-kotlin-blackjack/pingu244/20-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +258 -0
  351. package/lessons/woowacourse-kotlin-blackjack/pingu244/41-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +171 -0
  352. package/lessons/woowacourse-kotlin-blackjack/re4rk/34-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +289 -0
  353. package/lessons/woowacourse-kotlin-blackjack/re4rk/8-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +297 -0
  354. package/lessons/woowacourse-kotlin-blackjack/rhkrwngud445/17-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +279 -0
  355. package/lessons/woowacourse-kotlin-blackjack/rhkrwngud445/50-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +145 -0
  356. package/lessons/woowacourse-kotlin-blackjack/rhthrhrl0/23-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +253 -0
  357. package/lessons/woowacourse-kotlin-blackjack/rhthrhrl0/39-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +238 -0
  358. package/lessons/woowacourse-kotlin-blackjack/rosemin928/129-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +726 -0
  359. package/lessons/woowacourse-kotlin-blackjack/rosemin928/138-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +845 -0
  360. package/lessons/woowacourse-kotlin-blackjack/s6m1n/67-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +220 -0
  361. package/lessons/woowacourse-kotlin-blackjack/s6m1n/99-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +229 -0
  362. package/lessons/woowacourse-kotlin-blackjack/s9hn/10-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +284 -0
  363. package/lessons/woowacourse-kotlin-blackjack/sh1mj1/75-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +224 -0
  364. package/lessons/woowacourse-kotlin-blackjack/songpink/74-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +238 -0
  365. package/lessons/woowacourse-kotlin-blackjack/songpink/95-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +216 -0
  366. package/lessons/woowacourse-kotlin-blackjack/sujin9/15-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +132 -0
  367. package/lessons/woowacourse-kotlin-blackjack/sujin9/47-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +265 -0
  368. package/lessons/woowacourse-kotlin-blackjack/tmdgh1592/29-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +305 -0
  369. package/lessons/woowacourse-kotlin-blackjack/tmdgh1592/51-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +278 -0
  370. package/lessons/woowacourse-kotlin-blackjack/tobae-time/115-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +305 -0
  371. package/lessons/woowacourse-kotlin-blackjack/tobae-time/154-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +298 -0
  372. package/lessons/woowacourse-kotlin-blackjack/whk06061/25-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +235 -0
  373. package/lessons/woowacourse-kotlin-blackjack/whk06061/53-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +130 -0
  374. package/lessons/woowacourse-kotlin-blackjack/wondroid-world/124-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +486 -0
  375. package/lessons/woowacourse-kotlin-blackjack/wondroid-world/152-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +482 -0
  376. package/lessons/woowacourse-kotlin-blackjack/yrsel/120-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +194 -0
  377. package/lessons/woowacourse-kotlin-blackjack/yrsel/146-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +444 -0
  378. package/lessons/woowacourse-kotlin-lotto/2chang5/27-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +155 -0
  379. package/lessons/woowacourse-kotlin-lotto/2chang5/52-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +187 -0
  380. package/lessons/woowacourse-kotlin-lotto/Choisehyeon/14-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +206 -0
  381. package/lessons/woowacourse-kotlin-lotto/Choisehyeon/47-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +119 -0
  382. package/lessons/woowacourse-kotlin-lotto/DYGames/2-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +83 -0
  383. package/lessons/woowacourse-kotlin-lotto/DYGames/34-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +88 -0
  384. package/lessons/woowacourse-kotlin-lotto/EmilyCh0/12-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +107 -0
  385. package/lessons/woowacourse-kotlin-lotto/EmilyCh0/40-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +135 -0
  386. package/lessons/woowacourse-kotlin-lotto/HANDOVER.md +217 -0
  387. package/lessons/woowacourse-kotlin-lotto/HamBeomJoon/121-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +66 -0
  388. package/lessons/woowacourse-kotlin-lotto/HamBeomJoon/139-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +75 -0
  389. package/lessons/woowacourse-kotlin-lotto/Hevton/76-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +21 -0
  390. package/lessons/woowacourse-kotlin-lotto/Hevton/92-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +122 -0
  391. package/lessons/woowacourse-kotlin-lotto/Hogu59/100-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +110 -0
  392. package/lessons/woowacourse-kotlin-lotto/Hogu59/68-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +84 -0
  393. package/lessons/woowacourse-kotlin-lotto/JoYehyun99/60-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +176 -0
  394. package/lessons/woowacourse-kotlin-lotto/JoYehyun99/96-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +71 -0
  395. package/lessons/woowacourse-kotlin-lotto/Junyoung-WON/61-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +143 -0
  396. package/lessons/woowacourse-kotlin-lotto/Junyoung-WON/93-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +16 -0
  397. package/lessons/woowacourse-kotlin-lotto/Leeyerin0210/109-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +57 -0
  398. package/lessons/woowacourse-kotlin-lotto/Leeyerin0210/135-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +115 -0
  399. package/lessons/woowacourse-kotlin-lotto/PROGRESS.md +160 -0
  400. package/lessons/woowacourse-kotlin-lotto/README.md +77 -0
  401. package/lessons/woowacourse-kotlin-lotto/RightHennessy/32-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +178 -0
  402. package/lessons/woowacourse-kotlin-lotto/RightHennessy/5-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +149 -0
  403. package/lessons/woowacourse-kotlin-lotto/SUMMARY.md +369 -0
  404. package/lessons/woowacourse-kotlin-lotto/SeongHoonC/25-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +129 -0
  405. package/lessons/woowacourse-kotlin-lotto/SeongHoonC/37-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +27 -0
  406. package/lessons/woowacourse-kotlin-lotto/Yunseok-Nam/72-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +137 -0
  407. package/lessons/woowacourse-kotlin-lotto/Yunseok-Nam/86-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +17 -0
  408. package/lessons/woowacourse-kotlin-lotto/aprilgom/102-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +62 -0
  409. package/lessons/woowacourse-kotlin-lotto/aprilgom/64-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +146 -0
  410. package/lessons/woowacourse-kotlin-lotto/boogi-woogi/11-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +26 -0
  411. package/lessons/woowacourse-kotlin-lotto/boogi-woogi/29-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +26 -0
  412. package/lessons/woowacourse-kotlin-lotto/briandr97/26-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +52 -0
  413. package/lessons/woowacourse-kotlin-lotto/briandr97/51-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +123 -0
  414. package/lessons/woowacourse-kotlin-lotto/chaehyuns/71-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +115 -0
  415. package/lessons/woowacourse-kotlin-lotto/chaehyuns/97-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +107 -0
  416. package/lessons/woowacourse-kotlin-lotto/chanho0908/124-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +51 -0
  417. package/lessons/woowacourse-kotlin-lotto/chanho0908/129-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +149 -0
  418. package/lessons/woowacourse-kotlin-lotto/chws0508/24-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +117 -0
  419. package/lessons/woowacourse-kotlin-lotto/chws0508/50-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +167 -0
  420. package/lessons/woowacourse-kotlin-lotto/cucumber99/116-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +155 -0
  421. package/lessons/woowacourse-kotlin-lotto/cucumber99/147-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +223 -0
  422. package/lessons/woowacourse-kotlin-lotto/devfeijoa/125-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +68 -0
  423. package/lessons/woowacourse-kotlin-lotto/devfeijoa/153-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +107 -0
  424. package/lessons/woowacourse-kotlin-lotto/doabletuple/119-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +157 -0
  425. package/lessons/woowacourse-kotlin-lotto/doabletuple/138-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +77 -0
  426. package/lessons/woowacourse-kotlin-lotto/donghyun81/111-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +67 -0
  427. package/lessons/woowacourse-kotlin-lotto/donghyun81/152-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +124 -0
  428. package/lessons/woowacourse-kotlin-lotto/dpcks0509/80-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +141 -0
  429. package/lessons/woowacourse-kotlin-lotto/dpcks0509/87-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +134 -0
  430. package/lessons/woowacourse-kotlin-lotto/etama123/112-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +170 -0
  431. package/lessons/woowacourse-kotlin-lotto/etama123/148-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +183 -0
  432. package/lessons/woowacourse-kotlin-lotto/gaeun5744/101-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +21 -0
  433. package/lessons/woowacourse-kotlin-lotto/gaeun5744/78-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +158 -0
  434. package/lessons/woowacourse-kotlin-lotto/gahyunkim/107-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +83 -0
  435. package/lessons/woowacourse-kotlin-lotto/gahyunkim/136-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +51 -0
  436. package/lessons/woowacourse-kotlin-lotto/giovannijunseokim/106-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +171 -0
  437. package/lessons/woowacourse-kotlin-lotto/giovannijunseokim/137-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +111 -0
  438. package/lessons/woowacourse-kotlin-lotto/haeum808/67-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +52 -0
  439. package/lessons/woowacourse-kotlin-lotto/haeum808/95-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +97 -0
  440. package/lessons/woowacourse-kotlin-lotto/hwannow/113-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +235 -0
  441. package/lessons/woowacourse-kotlin-lotto/hwannow/132-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +149 -0
  442. package/lessons/woowacourse-kotlin-lotto/hxeyexn/77-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +141 -0
  443. package/lessons/woowacourse-kotlin-lotto/hxeyexn/98-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +162 -0
  444. package/lessons/woowacourse-kotlin-lotto/hyemdooly/17-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +19 -0
  445. package/lessons/woowacourse-kotlin-lotto/hyemdooly/28-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +23 -0
  446. package/lessons/woowacourse-kotlin-lotto/hyunji1203/15-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +171 -0
  447. package/lessons/woowacourse-kotlin-lotto/hyunji1203/48-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +150 -0
  448. package/lessons/woowacourse-kotlin-lotto/ii2001/62-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +104 -0
  449. package/lessons/woowacourse-kotlin-lotto/ii2001/88-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +20 -0
  450. package/lessons/woowacourse-kotlin-lotto/ijh1298/122-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +179 -0
  451. package/lessons/woowacourse-kotlin-lotto/ijh1298/133-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +153 -0
  452. package/lessons/woowacourse-kotlin-lotto/inseonyun/3-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +222 -0
  453. package/lessons/woowacourse-kotlin-lotto/inseonyun/49-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +166 -0
  454. package/lessons/woowacourse-kotlin-lotto/ippnsj/16-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +154 -0
  455. package/lessons/woowacourse-kotlin-lotto/ippnsj/55-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +145 -0
  456. package/lessons/woowacourse-kotlin-lotto/jaeyeongjo/59-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +68 -0
  457. package/lessons/woowacourse-kotlin-lotto/jaeyeongjo/83-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +53 -0
  458. package/lessons/woowacourse-kotlin-lotto/jerry8282/115-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +97 -0
  459. package/lessons/woowacourse-kotlin-lotto/jerry8282/134-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +145 -0
  460. package/lessons/woowacourse-kotlin-lotto/jinuemong/63-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +144 -0
  461. package/lessons/woowacourse-kotlin-lotto/jinuemong/89-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +148 -0
  462. package/lessons/woowacourse-kotlin-lotto/jiyuneel/128-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +52 -0
  463. package/lessons/woowacourse-kotlin-lotto/jiyuneel/144-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +149 -0
  464. package/lessons/woowacourse-kotlin-lotto/junjange/58-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +148 -0
  465. package/lessons/woowacourse-kotlin-lotto/junjange/81-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +178 -0
  466. package/lessons/woowacourse-kotlin-lotto/junseo511/120-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +153 -0
  467. package/lessons/woowacourse-kotlin-lotto/junseo511/131-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +188 -0
  468. package/lessons/woowacourse-kotlin-lotto/ki960213/43-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +24 -0
  469. package/lessons/woowacourse-kotlin-lotto/ki960213/8-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +159 -0
  470. package/lessons/woowacourse-kotlin-lotto/kimhm0728/74-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +50 -0
  471. package/lessons/woowacourse-kotlin-lotto/kimhm0728/94-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +176 -0
  472. package/lessons/woowacourse-kotlin-lotto/kkosang/85-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +145 -0
  473. package/lessons/woowacourse-kotlin-lotto/kmkim2689/70-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +97 -0
  474. package/lessons/woowacourse-kotlin-lotto/kmkim2689/82-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +157 -0
  475. package/lessons/woowacourse-kotlin-lotto/krrong/19-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +161 -0
  476. package/lessons/woowacourse-kotlin-lotto/krrong/41-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +73 -0
  477. package/lessons/woowacourse-kotlin-lotto/m6z1/105-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +67 -0
  478. package/lessons/woowacourse-kotlin-lotto/m6z1/151-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +104 -0
  479. package/lessons/woowacourse-kotlin-lotto/medAndro/127-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +186 -0
  480. package/lessons/woowacourse-kotlin-lotto/medAndro/130-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +132 -0
  481. package/lessons/woowacourse-kotlin-lotto/moondev03/110-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +66 -0
  482. package/lessons/woowacourse-kotlin-lotto/moondev03/141-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +155 -0
  483. package/lessons/woowacourse-kotlin-lotto/murjune/69-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +143 -0
  484. package/lessons/woowacourse-kotlin-lotto/murjune/90-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +177 -0
  485. package/lessons/woowacourse-kotlin-lotto/no1msh/20-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +69 -0
  486. package/lessons/woowacourse-kotlin-lotto/no1msh/46-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +143 -0
  487. package/lessons/woowacourse-kotlin-lotto/otter66/13-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +178 -0
  488. package/lessons/woowacourse-kotlin-lotto/otter66/53-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +160 -0
  489. package/lessons/woowacourse-kotlin-lotto/oungsi2000/126-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +71 -0
  490. package/lessons/woowacourse-kotlin-lotto/oungsi2000/149-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +56 -0
  491. package/lessons/woowacourse-kotlin-lotto/parkjiminnnn/117-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +129 -0
  492. package/lessons/woowacourse-kotlin-lotto/parkjiminnnn/146-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +173 -0
  493. package/lessons/woowacourse-kotlin-lotto/pingu244/33-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +21 -0
  494. package/lessons/woowacourse-kotlin-lotto/pingu244/54-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +30 -0
  495. package/lessons/woowacourse-kotlin-lotto/pingu244/7-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +19 -0
  496. package/lessons/woowacourse-kotlin-lotto/re4rk/31-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +143 -0
  497. package/lessons/woowacourse-kotlin-lotto/re4rk/4-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +66 -0
  498. package/lessons/woowacourse-kotlin-lotto/rhkrwngud445/23-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +26 -0
  499. package/lessons/woowacourse-kotlin-lotto/rhkrwngud445/38-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +129 -0
  500. package/lessons/woowacourse-kotlin-lotto/rhthrhrl0/21-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +146 -0
  501. package/lessons/woowacourse-kotlin-lotto/rhthrhrl0/36-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +150 -0
  502. package/lessons/woowacourse-kotlin-lotto/rosemin928/123-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +179 -0
  503. package/lessons/woowacourse-kotlin-lotto/rosemin928/140-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +126 -0
  504. package/lessons/woowacourse-kotlin-lotto/s6m1n/103-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +119 -0
  505. package/lessons/woowacourse-kotlin-lotto/s6m1n/66-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +118 -0
  506. package/lessons/woowacourse-kotlin-lotto/s9hn/18-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +112 -0
  507. package/lessons/woowacourse-kotlin-lotto/sh1mj1/75-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +104 -0
  508. package/lessons/woowacourse-kotlin-lotto/sh1mj1/91-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +140 -0
  509. package/lessons/woowacourse-kotlin-lotto/songpink/65-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +96 -0
  510. package/lessons/woowacourse-kotlin-lotto/songpink/99-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +64 -0
  511. package/lessons/woowacourse-kotlin-lotto/sujin9/10-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +20 -0
  512. package/lessons/woowacourse-kotlin-lotto/sujin9/35-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +124 -0
  513. package/lessons/woowacourse-kotlin-lotto/tmdgh1592/22-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +30 -0
  514. package/lessons/woowacourse-kotlin-lotto/tmdgh1592/30-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +20 -0
  515. package/lessons/woowacourse-kotlin-lotto/tobae-time/114-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +158 -0
  516. package/lessons/woowacourse-kotlin-lotto/tobae-time/145-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +120 -0
  517. package/lessons/woowacourse-kotlin-lotto/whk06061/42-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +21 -0
  518. package/lessons/woowacourse-kotlin-lotto/whk06061/9-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +89 -0
  519. package/lessons/woowacourse-kotlin-lotto/wondroid-world/118-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +100 -0
  520. package/lessons/woowacourse-kotlin-lotto/wondroid-world/150-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +142 -0
  521. package/lessons/woowacourse-kotlin-lotto/yrsel/108-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +124 -0
  522. package/lessons/woowacourse-kotlin-lotto/yrsel/143-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +108 -0
  523. package/lessons/woowacourse-racingcar/2chang5/33-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +56 -0
  524. package/lessons/woowacourse-racingcar/2chang5/75-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  525. package/lessons/woowacourse-racingcar/CFalws/85-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +56 -0
  526. package/lessons/woowacourse-racingcar/Choisehyeon/46-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +61 -0
  527. package/lessons/woowacourse-racingcar/DYGames/49-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +62 -0
  528. package/lessons/woowacourse-racingcar/EmilyCh0/40-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +64 -0
  529. package/lessons/woowacourse-racingcar/EmilyCh0/57-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  530. package/lessons/woowacourse-racingcar/HamBeomJoon/137-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  531. package/lessons/woowacourse-racingcar/HamBeomJoon/170-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
  532. package/lessons/woowacourse-racingcar/Hevton/106-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  533. package/lessons/woowacourse-racingcar/Hevton/118-/353/246/254/355/214/251/355/204/260/353/247/201.md +51 -0
  534. package/lessons/woowacourse-racingcar/Hogu59/108-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +56 -0
  535. package/lessons/woowacourse-racingcar/Hogu59/125-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
  536. package/lessons/woowacourse-racingcar/JoYehyun99/111-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
  537. package/lessons/woowacourse-racingcar/JoYehyun99/88-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +45 -0
  538. package/lessons/woowacourse-racingcar/Junyoung-WON/127-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
  539. package/lessons/woowacourse-racingcar/Junyoung-WON/90-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
  540. package/lessons/woowacourse-racingcar/Leeyerin0210/133-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
  541. package/lessons/woowacourse-racingcar/Leeyerin0210/159-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  542. package/lessons/woowacourse-racingcar/PROGRESS.md +94 -0
  543. package/lessons/woowacourse-racingcar/README.md +69 -0
  544. package/lessons/woowacourse-racingcar/RightHennessy/51-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  545. package/lessons/woowacourse-racingcar/RightHennessy/58-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
  546. package/lessons/woowacourse-racingcar/RunaNam/81-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +44 -0
  547. package/lessons/woowacourse-racingcar/SUMMARY.md +339 -0
  548. package/lessons/woowacourse-racingcar/SeongHoonC/37-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
  549. package/lessons/woowacourse-racingcar/SeongHoonC/66-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
  550. package/lessons/woowacourse-racingcar/Songusika/84-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
  551. package/lessons/woowacourse-racingcar/Yunseok-Nam/114-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +43 -0
  552. package/lessons/woowacourse-racingcar/Yunseok-Nam/96-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  553. package/lessons/woowacourse-racingcar/aprilgom/130-/353/246/254/355/214/251/355/204/260/353/247/201.md +52 -0
  554. package/lessons/woowacourse-racingcar/aprilgom/97-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
  555. package/lessons/woowacourse-racingcar/awesomeo184/23-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
  556. package/lessons/woowacourse-racingcar/boogi-woogi/35-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +62 -0
  557. package/lessons/woowacourse-racingcar/boogi-woogi/59-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  558. package/lessons/woowacourse-racingcar/briandr97/54-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
  559. package/lessons/woowacourse-racingcar/chaehyuns/131-/353/246/254/355/214/251/355/204/260/353/247/201.md +49 -0
  560. package/lessons/woowacourse-racingcar/chaehyuns/99-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +52 -0
  561. package/lessons/woowacourse-racingcar/chanho0908/147-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  562. package/lessons/woowacourse-racingcar/chanho0908/160-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
  563. package/lessons/woowacourse-racingcar/chws0508/45-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +61 -0
  564. package/lessons/woowacourse-racingcar/chws0508/73-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +46 -0
  565. package/lessons/woowacourse-racingcar/cucumber99/132-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  566. package/lessons/woowacourse-racingcar/cucumber99/177-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  567. package/lessons/woowacourse-racingcar/devfeijoa/146-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
  568. package/lessons/woowacourse-racingcar/doabletuple/149-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  569. package/lessons/woowacourse-racingcar/doabletuple/175-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  570. package/lessons/woowacourse-racingcar/donghyun81/154-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +58 -0
  571. package/lessons/woowacourse-racingcar/dpcks0509/103-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
  572. package/lessons/woowacourse-racingcar/dpcks0509/112-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
  573. package/lessons/woowacourse-racingcar/drunkenhw/82-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
  574. package/lessons/woowacourse-racingcar/etama123/145-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
  575. package/lessons/woowacourse-racingcar/gaeun5744/124-/353/246/254/355/214/251/355/204/260/353/247/201.md +53 -0
  576. package/lessons/woowacourse-racingcar/gaeun5744/93-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
  577. package/lessons/woowacourse-racingcar/gahyunkim/134-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  578. package/lessons/woowacourse-racingcar/gahyunkim/164-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  579. package/lessons/woowacourse-racingcar/giovannijunseokim/140-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  580. package/lessons/woowacourse-racingcar/haeum808/101-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  581. package/lessons/woowacourse-racingcar/haeum808/129-/353/246/254/355/214/251/355/204/260/353/247/201.md +46 -0
  582. package/lessons/woowacourse-racingcar/hwannow/141-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +56 -0
  583. package/lessons/woowacourse-racingcar/hwannow/157-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +45 -0
  584. package/lessons/woowacourse-racingcar/hxeyexn/109-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +61 -0
  585. package/lessons/woowacourse-racingcar/hxeyexn/128-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
  586. package/lessons/woowacourse-racingcar/hyemdooly/50-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
  587. package/lessons/woowacourse-racingcar/hyemdooly/68-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  588. package/lessons/woowacourse-racingcar/hyunji1203/29-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  589. package/lessons/woowacourse-racingcar/hyunji1203/60-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
  590. package/lessons/woowacourse-racingcar/ii2001/102-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +42 -0
  591. package/lessons/woowacourse-racingcar/ii2001/122-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
  592. package/lessons/woowacourse-racingcar/ijh1298/144-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
  593. package/lessons/woowacourse-racingcar/injoon2019/24-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +58 -0
  594. package/lessons/woowacourse-racingcar/inseonyun/44-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
  595. package/lessons/woowacourse-racingcar/inseonyun/76-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  596. package/lessons/woowacourse-racingcar/ippnsj/36-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  597. package/lessons/woowacourse-racingcar/ippnsj/67-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
  598. package/lessons/woowacourse-racingcar/jaeyeongjo/110-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +39 -0
  599. package/lessons/woowacourse-racingcar/jaeyeongjo/89-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +46 -0
  600. package/lessons/woowacourse-racingcar/jinuemong/104-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
  601. package/lessons/woowacourse-racingcar/jinuemong/117-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +42 -0
  602. package/lessons/woowacourse-racingcar/jiyuneel/142-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
  603. package/lessons/woowacourse-racingcar/junjange/113-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +41 -0
  604. package/lessons/woowacourse-racingcar/junjange/87-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +39 -0
  605. package/lessons/woowacourse-racingcar/junseo511/148-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +52 -0
  606. package/lessons/woowacourse-racingcar/junseo511/165-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +51 -0
  607. package/lessons/woowacourse-racingcar/ki960213/32-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  608. package/lessons/woowacourse-racingcar/ki960213/63-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +51 -0
  609. package/lessons/woowacourse-racingcar/kimhm0728/100-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +52 -0
  610. package/lessons/woowacourse-racingcar/kimhm0728/116-/353/246/254/355/214/251/355/204/260/353/247/201.md +54 -0
  611. package/lessons/woowacourse-racingcar/kkosang/105-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  612. package/lessons/woowacourse-racingcar/kkosang/126-/353/246/254/355/214/251/355/204/260/353/247/201.md +53 -0
  613. package/lessons/woowacourse-racingcar/kmkim2689/123-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
  614. package/lessons/woowacourse-racingcar/kmkim2689/92-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  615. package/lessons/woowacourse-racingcar/krrong/34-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +63 -0
  616. package/lessons/woowacourse-racingcar/m6z1/150-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  617. package/lessons/woowacourse-racingcar/m6z1/156-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +40 -0
  618. package/lessons/woowacourse-racingcar/medAndro/153-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  619. package/lessons/woowacourse-racingcar/moondev03/135-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
  620. package/lessons/woowacourse-racingcar/moondev03/161-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +52 -0
  621. package/lessons/woowacourse-racingcar/murjune/121-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
  622. package/lessons/woowacourse-racingcar/murjune/95-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  623. package/lessons/woowacourse-racingcar/no1msh/43-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  624. package/lessons/woowacourse-racingcar/no1msh/69-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
  625. package/lessons/woowacourse-racingcar/otter66/48-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  626. package/lessons/woowacourse-racingcar/otter66/77-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +52 -0
  627. package/lessons/woowacourse-racingcar/oungsi2000/152-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +56 -0
  628. package/lessons/woowacourse-racingcar/oungsi2000/187-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  629. package/lessons/woowacourse-racingcar/parkjiminnnn/143-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +58 -0
  630. package/lessons/woowacourse-racingcar/parkjiminnnn/158-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  631. package/lessons/woowacourse-racingcar/pingu244/38-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +58 -0
  632. package/lessons/woowacourse-racingcar/pingu244/62-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
  633. package/lessons/woowacourse-racingcar/re4rk/28-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
  634. package/lessons/woowacourse-racingcar/re4rk/55-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  635. package/lessons/woowacourse-racingcar/rhkrwngud445/42-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  636. package/lessons/woowacourse-racingcar/rhkrwngud445/74-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +47 -0
  637. package/lessons/woowacourse-racingcar/rhthrhrl0/31-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +43 -0
  638. package/lessons/woowacourse-racingcar/rosemin928/138-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  639. package/lessons/woowacourse-racingcar/rosemin928/171-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +38 -0
  640. package/lessons/woowacourse-racingcar/s6m1n/120-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  641. package/lessons/woowacourse-racingcar/s6m1n/91-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +62 -0
  642. package/lessons/woowacourse-racingcar/s9hn/53-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +44 -0
  643. package/lessons/woowacourse-racingcar/s9hn/78-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +43 -0
  644. package/lessons/woowacourse-racingcar/sh1mj1/107-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  645. package/lessons/woowacourse-racingcar/sh1mj1/115-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +61 -0
  646. package/lessons/woowacourse-racingcar/songpink/119-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +51 -0
  647. package/lessons/woowacourse-racingcar/songpink/98-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  648. package/lessons/woowacourse-racingcar/sujin9/52-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
  649. package/lessons/woowacourse-racingcar/sujin9/61-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +47 -0
  650. package/lessons/woowacourse-racingcar/tmdgh1592/47-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
  651. package/lessons/woowacourse-racingcar/tmdgh1592/64-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  652. package/lessons/woowacourse-racingcar/tobae-time/151-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +51 -0
  653. package/lessons/woowacourse-racingcar/tobae-time/167-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +43 -0
  654. package/lessons/woowacourse-racingcar/whk06061/41-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +58 -0
  655. package/lessons/woowacourse-racingcar/wondroid-world/136-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
  656. package/lessons/woowacourse-racingcar/wondroid-world/166-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
  657. package/lessons/woowacourse-racingcar/yrsel/139-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  658. package/lessons/woowacourse-racingcar/yujamint/83-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
  659. package/package.json +46 -0
  660. package/skills/oh-my-oop/SKILL.md +39 -0
@@ -0,0 +1,129 @@
1
+ # PR #38 — [코비] 2단계 로또
2
+
3
+ - **Reviewee:** [@rhkrwngud445](https://github.com/rhkrwngud445)
4
+ - **PR:** https://github.com/woowacourse/kotlin-lotto/pull/38
5
+ - **단계:** 2단계 (수동 로또 추가)
6
+ - **리뷰어:** @BeokBeok
7
+ - **라인 코멘트:** 20
8
+
9
+ ## 잘한 점 (설계 관점)
10
+
11
+ - **`purchaseManualLottos`/`purchaseAutoLottos` 분리**.
12
+ - **`toIntOrNull() ?: return retry()` 재시도 흐름**.
13
+ - **`PurchasedLotto` 도메인 객체** — Lotto와 *발행된 Lotto* 구분.
14
+
15
+ ## 못한 점 (설계 관점)
16
+
17
+ ### 1. `mutableListOf().apply` — `as`로 가변 변환 위험
18
+
19
+ ```kotlin
20
+ fun purchaseAutoLottos(money: Money): List<PurchasedLotto> = mutableListOf<PurchasedLotto>().apply {
21
+ .
22
+ }
23
+ ```
24
+
25
+ 리뷰어: "mutableList를 함수의 리턴 타입을 활용하여, List 타입으로 전달하도록 구현해 주셨네요. 하지만, `as`를 통해 *Mutable로 변환이 가능*하며, 이로 인하여 원본을 훼손시킬 수 있습니다. *방어적 복사*를 활용하여, 원본을 훼손하지 않도록 코드를 개선해 보면 어떨까요?" 후속: "컬렉션과 관련된 함수들은(filter, map 등) 연산을 한 후에 *원본이 아닌 복사본*을 리턴." — `toList()` 또는 `.map`.
26
+
27
+ ### 2. 함수명 *너무 김*
28
+
29
+ ```kotlin
30
+ fun getRemainingMoneyAfterManualLottoPurchase(manualLottoCount: Int): Money {. }
31
+ ```
32
+
33
+ 리뷰어: "함수명이 너무 길어서 잘 읽히지가 않네요. 함수명의 단어의 수를 조금 줄여 보면 어떨까요?"
34
+
35
+ ### 3. `validateNumeric` — 커스텀 < 시스템 함수
36
+
37
+ ```kotlin
38
+ fun validateNumeric(value: String): Int = value.toInt()
39
+ ```
40
+
41
+ 리뷰어: "String 타입을 Int로 변환하는 로직을 구현해 주셨네요. 다만, *대체로 커스텀한 함수보다는 시스템 함수가 더 가독성*이 좋습니다." — `toIntOrNull()` 직접 호출.
42
+
43
+ ### 4. `runCatching + lateinit + result =` 패턴
44
+
45
+ ```kotlin
46
+ fun inputPurchasingMoney(): Money {
47
+ lateinit var result: Money
48
+ runCatching {. }.onSuccess { result = Money(it) }.onFailure { return inputPurchasingMoney() }
49
+ return result
50
+ }
51
+ ```
52
+
53
+ 리뷰어: "코틀린에서 예외를 처리하는 방법은 크게 두 종류가 있습니다. *오류가 예상되는 경우*, *오류가 예상되지 않는 경우*. 위 경우는 어떤 경우일까요? 일반적인 코틀린 코드에서 *try-catch를 사용하지 않는다*." → `toIntOrNull() ?: return retry()`.
54
+
55
+ ### 5. `nullable List` vs *빈 컬렉션*
56
+
57
+ ```kotlin
58
+ private fun inputLottoNumbers(): List<Int>? {. }
59
+ ```
60
+
61
+ 리뷰어: "List와 같은 컬렉션은 내부적으로 데이터를 추가하거나 삭제할 수 있습니다. 또한 *데이터가 없다면, null이 아닌 빈 컬렉션*을 활용할 수 있습니다." 학생 의문: "리스트가 비어 있는지 체크하는 것보다 받아온 list가 null인지 체크하는 것이 효율적이라고 생각이 되어서." 리뷰어: "null이라는 의미는 *객체를 신뢰할 수 없다*. 그렇기 때문에 null을 참조하게 되면 exception이 발생. 하지만 *빈 컬렉션은 nullable하지 않기 때문에 신뢰할 수 있으며*…"
62
+
63
+ ### 6. `inputManualLottos`가 *입력 + 변환 + 검증*
64
+
65
+ ```kotlin
66
+ fun inputManualLottos(manualLottoCount: Int): List<Lotto> {
67
+ repeat(manualLottoCount) {
68
+ val manualLotto = inputLottoNumbers() ?: return inputManualLottos(manualLottoCount)
69
+ manualLottos.add(Lotto(manualLotto.map { LottoNumber(it) }))
70
+ }
71
+ return manualLottos
72
+ }
73
+ ```
74
+
75
+ 리뷰어: "이 함수는 *두 가지 일*을 하고 있어요. (입력값 받기, 수동 로또 생성하기) *하나의 함수는 한 가지 일만* 하도록." 학생: "모델에 사용되는 객체를 inputview에서 받는 것보다 *controller에서 매핑*하는 게 적절하다고 판단되어 수정." → 학생이 List<List<Int>> 반환으로 변경.
76
+
77
+ ### 7. 재귀 호출 = *영문 모를 무한 루프*
78
+
79
+ 리뷰어: "함수의 재귀 호출은 신중하게 하는 것을 권장합니다. 이와 같이 *재귀 호출*을 하게 되면, 사용자의 입장에서는 *영문도 모른 채 프로그램이 종료되지 않는 부정적인 경험*을 하게 됩니다. 사용자가 유효한 값을 입력할 때까지 반복을 하고 싶으시다면, *사용자에게 어떤 것이 잘못 되었는지 알려*주어야 합니다." + "참고로, *프로그래밍 요구사항에는 입력값이 유효할 때까지 계속해서 입력을 받는다*와 같은 요구사항은 없습니다."
80
+
81
+ ### 8. 테스트명에 *내부 정보* 노출
82
+
83
+ ```kotlin
84
+ fun `manualLottoList와 금액이 주어졌을 때, purchasedLottos() 호출시, 구매금액 만큼의 PurchasedLotto를 반환한다`() {. }
85
+ ```
86
+
87
+ 리뷰어: "테스트 코드에는 가급적이면 *내부 정보를 드러내지 않고*, *어떤 것을 테스트하고자 하는지*를 나타내는 것이 좋습니다. 만약 몇 개월이 지난 후 purchasedLottos 함수명을 변경하게 된다면, 이 함수명도 변경할 수 있을까요?"
88
+
89
+ ### 9. Kotlin 중괄호 컨벤션
90
+
91
+ ```kotlin
92
+ if (checkRankIsThird(.)) return THIRD // ⚠ 컨벤션
93
+ ```
94
+
95
+ 리뷰어: "코틀린에서는 중괄호를 넣어 주는 것이 컨벤션입니다."
96
+
97
+ ## 리뷰어 의견 요지
98
+
99
+ - **방어적 복사** — `toList()`/`.map` 등 *복사본 반환*.
100
+ - **함수명 *짧고 의도 명확***.
101
+ - **커스텀 함수 < 시스템 함수**.
102
+ - **`try-catch`/`runCatching` 회피** — Kotlin idiomatic 코드는 *조건 분기*로.
103
+ - **null vs 빈 컬렉션** — 컬렉션은 *빈 컬렉션*이 신뢰 가능.
104
+ - **함수 한 가지 일** — 입력 + 변환 + 검증 분리.
105
+ - **재귀 호출 = *무한 루프 위험*** — 사용자 안내 + 종료 조건.
106
+ - **테스트명 = 의도, 구현 메서드명 X**.
107
+ - **Kotlin 컨벤션 = 중괄호**.
108
+
109
+ - **대표 인용:**
110
+ > `as`를 통해 Mutable로 변환이 가능하며, 이로 인하여 원본을 훼손시킬 수 있습니다. *방어적 복사*를 활용하여, 원본을 훼손하지 않도록.
111
+ > — @BeokBeok on `src/main/kotlin/domain/game/LottoMachine.kt`
112
+
113
+ > null이라는 의미는 객체를 신뢰할 수 없다라는 의미입니다. 그렇기 때문에 null을 참조하게 되면 exception이 발생. 하지만, *빈 컬렉션은 nullable하지 않기 때문에 신뢰할 수 있으며*…
114
+ > — @BeokBeok on `src/main/kotlin/view/InputView.kt`
115
+
116
+ > 함수의 재귀 호출은 신중하게 하는 것을 권장합니다. … 영문도 모른 채 프로그램이 종료되지 않는 부정적인 경험. 참고로, *프로그래밍 요구사항에는 입력값이 유효할 때까지 계속해서 입력을 받는다와 같은 요구사항은 없습니다*.
117
+ > — @BeokBeok on `src/main/kotlin/view/InputView.kt`
118
+
119
+ ## 얻은 교훈
120
+
121
+ - **방어적 복사** = 외부 mutable 변환 차단. `toList()`/`.map`이 *복사본 반환*.
122
+ - **null vs 빈 컬렉션** — *컬렉션은 빈 컬렉션*이 표준 — null 참조 위험 회피.
123
+ - **함수 한 가지 일** — InputView는 *입력만*, 변환은 *Controller/Mapper*.
124
+ - **재귀 호출 = *무한 루프 가능성*** — 사용자 안내 + 종료 조건. *요구사항에 없으면 도입 신중*.
125
+ - **테스트명 = 의도** — 함수명/객체명 노출은 *리네임 시 테스트 깨짐*.
126
+ - **Kotlin 컨벤션 = 중괄호** — 단일 라인이라도 `if` 본문에 중괄호.
127
+ - **시스템 함수 > 커스텀** — 추가 정보가 없는 wrapping은 제거.
128
+ - **`try-catch`보다 *조건 분기*** — `toIntOrNull() ?:.`.
129
+ - ***요구사항에 없으면 도입 신중*** — *안정성*과 *요구사항 충실*은 별개.
@@ -0,0 +1,146 @@
1
+ # PR #21 — [멘델] 1단계 로또
2
+
3
+ - **Reviewee:** [@rhthrhrl0](https://github.com/rhthrhrl0)
4
+ - **PR:** https://github.com/woowacourse/kotlin-lotto/pull/21
5
+ - **단계:** 1단계
6
+ - **리뷰어:** @galcyurio
7
+ - **라인 코멘트:** 15
8
+
9
+ ## 잘한 점 (설계 관점)
10
+
11
+ - **`LottoController(inputView: InputViewInterface, resultView: ResultViewInterface)` 인터페이스 주입** — 리뷰어 칭찬: "*생성자로 interface를 주입해서 LottoController도 테스트 가능*하군요 :+1:".
12
+ - **`Set<Int>` 사용** — 리뷰어 칭찬: "Set 활용 :+1:".
13
+ - **`PurchaseLottoMoney`, `LottoNumber` 원시값 포장** — 리뷰어 칭찬: "금액을 나타내는 *래퍼 클래스* :+1:".
14
+ - **`LottoNumber` Flyweight** — `lottoNumbers: Map<Int, LottoNumber>`.
15
+
16
+ ## 못한 점 (설계 관점)
17
+
18
+ ### 1. *View 검증* vs *도메인 require* — 학생 자가 의문
19
+
20
+ 학생: "저번 과제에서는 *일급 컬렉션을 이용하는 조건이 없어서 모든 데이터에 대한 검증을 인풋뷰 영역에서 수행*했습니다. 이렇게 *최소한의 타입 변환에 대한 유효성 검증은 뷰 영역에서 수행하고, 그 받은 데이터들을 활용해서 데이터 유효성(데이터의 range 등)에 대한 검증은 그 클래스에서 담당*해야 한다면, 보시는 것처럼 *컨트롤러에서 재입력 받기 위해서 코드를 구성하면 가독성도 떨어지고 너무 많은 보일러플레이트 코드가 발생*한다고 생각합니다(반복문을 돌면서 runCatching을 사용하는 메소드가 너무 많이 생기는 것 같습니다). 아니면 *컨트롤러 쪽 말고 인풋뷰 쪽에서 일급 컬렉션을 지닌 객체를 생성까지 하고 반환하는 것*이 나을까요?"
21
+
22
+ 리뷰어: "*View에서 처리하는 경우와 객체 안에서 require 처리하는 경우는 다릅니다*. 보통 요구사항으로 *입력이 잘못된 경우에 다시 유저에게 입력을 받아야 하므로 View에서 다시 입력받도록* 만들어야 합니다. 그런데 여기를 지나쳐서 *만약 로또 번호가 45보다 큰 48이 만들어지는 경우 논리 오류가 발생*하게 됩니다. *논리 오류는 컴파일 오류도 없고 런타임에 예외도 발생하지 않아서 디버깅하기가 어려우므로 빠르게 실패하도록 만들어 줘야 합니다*. 저는 오히려 지금과 같이 *InputView에서 바로 재입력을 받는 게 더 안전*하다고 생각해요." + "객체에서 *require()를 호출하는 건 논리 오류를 만들지 않기 위한 목적*이 큽니다. InputView에서 한 번 검증이 끝났다면 그대로 사용해 주시면 되고 그래도 거슬린다면 *바로 LottoNumber를 만들어 주셔도 상관없*습니다. *의존성 측면에서 보았을 때, presentation layer가 domain layer에 의존하는 것은 문제 없*습니다."
23
+
24
+ → View 검증 = *재입력 가능*, Domain `require` = *논리 오류 방지 안전망*. *두 위치 모두 정당*.
25
+
26
+ ### 2. *일급 컬렉션 활용* 학생 자가 의문
27
+
28
+ 학생: "*일급 컬렉션에서 다른 곳에서 자신이 가진 컬렉션을 활용하는 공통적인 비즈니스 로직을 담은 메소드를 만들어서 최대한 해당 컬렉션들을 활용하는 중복 코드를 다른 영역에서 줄이고 통일성 있는 메소드를 제공하는 것이 목적* 같은데, 이번 과제에서는 마땅히 *그런 메소드(일급 컬렉션을 활용해서 특별한 연산을 수행해서 결과를 반환하는 메소드)가 생각이 나지 않아서 일급 컬렉션을 어떻게 잘 활용할 수 있을지 고민*입니다." + "*LottoStatistics 클래스의 역할을 Lotto에게 위임해도 되는 걸까요*?"
29
+
30
+ 리뷰어: "*중복 코드를 줄이는 것보다도 더 중요한 목적이 바로 객체 지향적인 코드*가 되기 때문입니다. *List<Int>를 로또로 처리하는 것보다는 Lotto를 로또로 처리하는 게 훨씬 더 좋은 가독성*을 가지게 됩니다." + "큰 문제는 없어 보입니다. 저는 오히려 *수익률을 계산하는 책임을 WinningLotto로부터 분리하여 하나의 책임만 맡도록 처리되어 더 좋은 코드*라고 생각해요." — *일급 컬렉션의 목적*은 *중복 제거*가 아니라 *도메인 어휘*.
31
+
32
+ ### 3. TDD에서 *private이 안 됨* — 학생 자가 의문
33
+
34
+ 학생: "TDD를 하다 보니 *작은 메소드들이 private으로 감싸지지 않습니다*. 그 *작은 메소드들까지 모두 미리 생각해서 테스트 코드를 설계하고 큰 역할의 메소드들만 테스트하도록 테스트 코드를 잘 설계하고 클래스 작성에 들어가야 하는 것이 맞는 건가요*? TDD를 하다 보니 살짝 *분할 정복의 느낌*이 강했습니다."
35
+
36
+ 리뷰어: "*테스트를 위해 private 함수를 public으로 만들어 주는 것은 지양*해 주세요. *가능한 한 공개되어 있는 함수를 통해 간접적으로 테스트*해 주셔야 합니다. 그 이유는 *private 함수의 경우에는 해당 클래스의 내부 구현체라고 볼 수 있고 public 함수는 해당 클래스의 API*라고도 볼 수 있는데, *private 함수를 테스트한다는 것은 내부 구현을 건드린다는 것과 마찬가지*입니다. 따라서 *현재는 문제가 없을 수 있더라도 추후에 요구사항이 변경되면 테스트 케이스가 깨지게 되는 가장 큰 원인*이 됩니다."
37
+
38
+ ### 4. *MethodSource로 테스트 의도 분산*
39
+
40
+ ```kotlin
41
+ @ParameterizedTest(name = "{1}개가 일치하는 경우")
42
+ @MethodSource("provideLottoAndMatchCount")
43
+ ```
44
+
45
+ 리뷰어: "*좋은 테스트 코드는 테스트 본문만 보아도 테스트하는 의도를 모두 알 수 있어야* 합니다. *MethodSource는 테스트 본문에서 분리되므로 두 곳을 모두 확인*해야 합니다. *테스트 본문만 보아도 어떻게 했을 때, 어떻게 되어야 하는지를 명확하게 알 수 있도록* 만들어 보세요." — *지역성*이 *테스트 가독성*의 핵심.
46
+
47
+ ### 5. 상수 `MINIMUM_LOTTO_RANGE` *common 패키지*
48
+
49
+ ```kotlin
50
+ // common/const.kt
51
+ const val MINIMUM_LOTTO_RANGE = 1
52
+ const val MAXIMUM_LOTTO_RANGE = 45
53
+ ```
54
+
55
+ 리뷰어: "*Lotto의 범위이므로 Lotto에 위치*시키는 게 어떨까요?" — *상수 위치 = 도메인 책임*. *common god-folder* 회피.
56
+
57
+ ### 6. *상수 위치 후 다시 하드코딩* — 메시지 본문에
58
+
59
+ ```kotlin
60
+ private const val ERROR_LOTTO_RANGE = "로또 번호는 1이상 45이하여야 합니다." // ⚠ 다시 1, 45
61
+ ```
62
+
63
+ 리뷰어: "*1, 45가 변경되는 경우 이 부분의 하드코딩된 부분도 변경*해야 합니다. *기존 상수가 있다면 해당 상수를 참조하는 방식*으로 만들어 주세요.".
64
+
65
+ ### 7. `LottoNumber.from` *Range 재검사* 후 Flyweight 조회
66
+
67
+ ```kotlin
68
+ fun from(number: Int): LottoNumber {
69
+ require(number in MINIMUM_LOTTO_RANGE..MAXIMUM_LOTTO_RANGE) { ERROR_LOTTO_RANGE }
70
+ return lottoNumbers[number]!! // ⚠ Range 재검사 후 !!
71
+ }
72
+ ```
73
+
74
+ 리뷰어: "*유효성 검사할 때, Range를 한 번 더 만들 필요 없이 null인지를 체크*하시면 됩니다. *만약 lottoNumber를 만드는 로직이 변경되었는데 유효성 검사하는 로직은 변경하지 않으면 그대로 오류가 발생*하기 때문이에요."
75
+ ```kotlin
76
+ return requireNotNull(lottoNumbers[number]) { ERROR_LOTTO_RANGE }
77
+ ```
78
+ → *검증 일원화*: *맵에 없으면 잘못된 값*. 두 곳에 두면 *동기화 오류* 위험.
79
+
80
+ ### 8. 에러 메시지에 *변수 값 포함 안 함*
81
+
82
+ ```kotlin
83
+ private const val ERROR_LOTTO_RANGE = "로또의 숫자는 ${MINIMUM_LOTTO_RANGE}에서 ${MAXIMUM_LOTTO_RANGE}사이의 숫자여야 합니다."
84
+ // ⚠ 실제 입력값 number는 메시지에 없음
85
+ ```
86
+
87
+ 리뷰어: "*number를 에러 메시지에 포함*시켜 주세요. 로그를 보았을 때 *stacktrace가 남아있으니 어느 코드에서 발생했는지는 알 수 있*습니다. *하지만 변수는 메시지에 담지 않는 한 데이터가 사라지게* 됩니다. *실제로 배포가 되는 경우에는 로그만 따로 수집해 주는 툴을 사용하시게 될* 겁니다. 그런 경우에 *로그를 보았는데 메시지에 필요한 정보가 담겨 있지 않으면 디버깅이 너무 힘들어*집니다." — *Production 로그 수집* 시나리오.
88
+
89
+ ### 9. 테스트 전용 함수 *main에*
90
+
91
+ ```kotlin
92
+ // common/open_func.kt
93
+ fun Set<Int>.convertToLottoNumberSet(): Set<LottoNumber> = this.map { LottoNumber.from(it) }.toSet()
94
+ ```
95
+
96
+ 리뷰어: "*이 함수는 테스트 코드에서만 쓰이므로 test SourceSet으로 옮겨* 주세요." — *프로덕션 코드 오염* 방지.
97
+
98
+ ### 10. `companion object`의 `const val` *불필요한 public*
99
+
100
+ ```kotlin
101
+ companion object {
102
+ const val ONE_LOTTO_MONEY = 1000 // ⚠ 외부 미사용
103
+ const val ERROR_LOTTO_PURCHASE_MONEY = "." // ⚠ 외부 미사용
104
+ }
105
+ ```
106
+
107
+ 리뷰어: "이 상수는 *이 클래스 외에서는 쓰이지 않*습니다. *기본적으로 private으로 선언하고 꼭 필요한 경우에만 풀어주도록 습관*을 가져 보세요." — *가시성 최소화* 원칙.
108
+
109
+ ## 리뷰어 의견 요지
110
+
111
+ - ***View 검증* + *도메인 require* 둘 다 정당** — View = 재입력, require = 논리 오류 안전망.
112
+ - **일급 컬렉션 = *도메인 어휘* (객체지향)** — 중복 제거는 부수효과.
113
+ - **테스트를 위한 *public 노출 X*** — 내부 구현이 아닌 *API*만 테스트.
114
+ - **테스트 본문 *지역성*** — MethodSource 분리는 *두 곳 보기* 강요.
115
+ - **상수 위치 = 도메인 책임**.
116
+ - ***Range 검증과 Flyweight 조회 일원화*** — `requireNotNull(map[x])`.
117
+ - **에러 메시지에 *변수 값 포함*** — 로그 수집 시 *데이터 사라짐* 방지.
118
+ - **테스트 전용 함수 *test SourceSet*에**.
119
+ - **상수 *private 기본***.
120
+
121
+ - **대표 인용:**
122
+ > 논리 오류는 *컴파일 오류도 없고 런타임에 예외도 발생하지 않아서 디버깅하기가 어려우므로 빠르게 실패하도록* 만들어 줘야 합니다.
123
+ > — @galcyurio on `src/main/kotlin/view/InputView.kt`
124
+
125
+ > 중복 코드를 줄이는 것보다도 더 중요한 목적이 바로 *객체 지향적인 코드*가 되기 때문입니다. *List<Int>를 로또로 처리하는 것보다는 Lotto를 로또로 처리하는 게 훨씬 더 좋은 가독성*을 가지게 됩니다.
126
+ > — @galcyurio on `src/main/kotlin/domain/LottoStatistics.kt`
127
+
128
+ > private 함수를 테스트한다는 것은 *내부 구현을 건드린다는 것과 마찬가지*입니다. *현재는 문제가 없을 수 있더라도 추후에 요구사항이 변경되면 테스트 케이스가 깨지게 되는 가장 큰 원인*이 됩니다.
129
+ > — @galcyurio on `src/test/kotlin/domain/LottoSellerTest.kt`
130
+
131
+ > 변수는 *메시지에 담지 않는 한 데이터가 사라지게* 됩니다. *실제로 배포가 되는 경우에는 로그만 따로 수집해 주는 툴을 사용*하시게 될 겁니다.
132
+ > — @galcyurio on `src/main/kotlin/domain/LottoNumber.kt`
133
+
134
+ ## 얻은 교훈
135
+
136
+ - **View 검증 ≠ Domain `require`** — *View 검증*은 *사용자 재입력*, *Domain require*는 *논리 오류 안전망*. *두 위치 모두 정당*하며 *목적이 다름*.
137
+ - ***인터페이스 주입 = Controller 단위 테스트***. `InputViewInterface`, `ResultViewInterface`로 *Fake View* 주입 가능.
138
+ - **일급 컬렉션 = *도메인 어휘*** — 중복 제거는 부수효과. *Lotto*가 *List<Int>*보다 *가독성/객체지향* 우위.
139
+ - **TDD에서 *private이 안 됨* = 책임 설계 부족**. *기능 명세 → 객체 협력 → 테스트* 순서.
140
+ - **테스트는 *공개 API*만** — *private을 public화*는 *내부 구현 결합*. 요구사항 변경 시 테스트 깨짐.
141
+ - **테스트 본문 *지역성*** — `MethodSource`는 *데이터-of-tests*만 추출하되 *의도*는 본문에.
142
+ - **상수 위치 = *도메인***. `common`은 *진짜 공통*만. *Lotto 범위*는 *Lotto*.
143
+ - **에러 메시지에 *입력값 동봉*** — *로그 수집 툴* 시대에 *변수 데이터*는 *메시지 안*이 유일한 보존 위치.
144
+ - **테스트 전용 함수 = *test SourceSet*** — main 오염 회피.
145
+ - **`const val` *private 기본*** — 가시성 최소화. *꼭 필요할 때만 노출*.
146
+ - **`requireNotNull(map[x])` 패턴** — *Flyweight + 검증 일원화*. *Range 재검사 + !!*는 *동기화 오류 위험*.
@@ -0,0 +1,150 @@
1
+ # PR #36 — [멘델] 2단계 로또
2
+
3
+ - **Reviewee:** [@rhthrhrl0](https://github.com/rhthrhrl0)
4
+ - **PR:** https://github.com/woowacourse/kotlin-lotto/pull/36
5
+ - **단계:** 2단계 (수동 로또)
6
+ - **리뷰어:** @galcyurio
7
+ - **라인 코멘트:** 16
8
+
9
+ ## 잘한 점 (설계 관점)
10
+
11
+ - **`@JvmInline value class LottoNumber`** — 리뷰어 칭찬: "value class 활용 👍".
12
+ - **`Validator` object 후속 도입** — `validateMakeXxx` 패턴으로 *null 반환 + 객체 생성* 책임 합침.
13
+ - **`OutputView`가 *도메인 데이터 받아 렌더링*** — 리뷰어 칭찬: "UI에서 domain의 데이터를 받아서 *렌더링 👍*".
14
+ - **학생의 *추가 질문 라운드*** — `runCatching` 제거 의도를 *두 가지 해석*으로 캡처 + 이미지 첨부 ("이런 식으로 분리하는 것을 말씀하신 건가요?").
15
+
16
+ ## 못한 점 (설계 관점)
17
+
18
+ ### 1. *상수 private 해제* — *책임 위치* 잘못
19
+
20
+ ```diff
21
+ companion object {
22
+ - private const val ONE_LOTTO_MONEY = 1000
23
+ + const val ONE_LOTTO_MONEY = 1000
24
+ }
25
+ ```
26
+
27
+ 학생 자가 코멘트: "LottoSeller 클래스의 *sellManualLottos 메소드에서 1000이라는 숫자가 필요해서 private 해제*해 줬습니다 ㅜ" — *다른 클래스가 상수 필요*하면 *private 해제*가 아니라 *그 책임을 어디 둘지* 재검토. 결국 `sellAutoLottos`가 `PurchaseLottoMoney(count * ONE_LOTTO_MONEY)`를 만드는 것 자체가 *위치 의심*. 학생도 후속에서 알아챔.
28
+
29
+ ### 2. *정상 Flow에 `runCatching`* — try-catch 남용
30
+
31
+ ```kotlin
32
+ override fun getMoney(): PurchaseLottoMoney {
33
+ while (true) {
34
+ println(INPUT_MESSAGE_FOR_PURCHASE_MONEY)
35
+ val money = validateMoney(readln().toIntOrNull()) ?: continue
36
+ runCatching { PurchaseLottoMoney(money) }
37
+ .onSuccess {. return it }
38
+ .onFailure { println(it.message) }
39
+ }
40
+ }
41
+ ```
42
+
43
+ 리뷰어: "전체적으로 *runCatching()을 사용*해 주셨는데 *프로그램의 정상 Flow에 해당되는 경우들은 모두 제거*해 주세요." + "프로그램의 *정상적인 Flow에서 예외를 던지고 try-catch를 통해 처리하는 방법은 지양*해야 합니다. *논리 오류일 때 예외를 던지라는 것은 런타임에 예외도 발생하지 않아서 로그로도 안 남는 최악의 상황을 그나마 예외라도 던지게 만들어서 로그에 수집되게 만들라는 의미*입니다."
44
+
45
+ 학생 질문 (좋은 메타-질문): "생성자 호출 부분에서 *runCatching을 모두 사용*해 주었는데 *이렇게 하면 안 되는 걸까요*? 아니면 *runCatching 로직을 함수 매개변수를 가진 메소드로 분리해서 생성자를 호출할 때 재활용*해서 코드의 중복을 줄이라는 말씀이신가요??" 리뷰어: "*잘못된 입력이 들어왔을 때, 재입력을 받는 것은 충분히 예상 가능한 정상적인 Flow*입니다. 그렇기 때문에 *예외를 던져서 그것을 try-catch하는 식으로 코드를 작성하는 것은 예외 처리 기능을 잘못 사용*하는 것입니다. *유효성 검사를 한 뒤에 제대로 된 응답인 경우에만 생성자를 호출*하도록 만들어 보세요." + "*논리 오류인 경우에 예외를 던지는 것들은 프로그램 전역적으로 설정된 예외 처리기를 통해 로그가 남도록* 만들면 좋습니다. 코틀린에서는 *Thread.setUncaughtExceptionHandler()를 이용*해서 catch 되지 않은 Exception들을 잡아서 추가 처리를 해 줄 수 있습니다." + [Roman Elizarov - Kotlin and Exceptions](https://medium.com/@elizarov/kotlin-and-exceptions-8062f589d07) 링크.
46
+
47
+ ### 3. `LottoSeller.sellManualAndAuto` — *예외 던지는 검증*
48
+
49
+ ```kotlin
50
+ fun sellManualAndAuto(purchaseInfo: LottoPurchaseInfo, requestManualNumbers: List<Lotto>): Ticket {
51
+ require(purchaseInfo.manualCount == requestManualNumbers.size) {
52
+ ERROR_MANUAL_COUNT_NOT_EQUAL.format(.)
53
+ }
54
+ .
55
+ }
56
+ ```
57
+
58
+ 학생: "LottoPurchaseInfo 객체랑 *수동 발급 로또인 List<Lotto>를 다시 래핑해서 생성자 쪽에서 검증해 주는 클래스를 만들어야 할까요*? 지금은 *[구매하려 하는 수동 로또의 개수]와 [발급을 요청한 List<Lotto>] 둘의 크기가 같다는 검증을 LottoSeller가 가진 메소드 쪽에서 수행*하고 있습니다." 리뷰어: "이 부분도 마찬가지로 *예측할 수 없는 비정상적인 case가 아니라 충분히 발생할 수 있는 정상 Flow*입니다. *잘못된 입력을 했을 때, 다시 재입력을 받을 수 있는 구조*로 변경해 보세요." — *경계 검증을 View*에서.
59
+
60
+ ### 4. `if`/`when` *중괄호 생략* — 공식 컨벤션
61
+
62
+ ```kotlin
63
+ private fun sellAutoLottos(count: Int): Ticket =
64
+ if (count == 0) Ticket(emptyList())
65
+ else sellLottos(PurchaseLottoMoney(count * ONE_LOTTO_MONEY))
66
+ ```
67
+
68
+ 리뷰어: "[공식 컨벤션](https://kotlinlang.org/docs/coding-conventions.html#control-flow-statements)에 따르면 *if문과 when문은 2줄 이상이면 중괄호를 사용*합니다."
69
+
70
+ ### 5. `Lotto.toString()` — *View 로직 도메인 침투*
71
+
72
+ ```kotlin
73
+ override fun toString(): String {
74
+ val sb = StringBuilder("[")
75
+ numbers.forEach { lottoNumber -> sb.append("${lottoNumber.number}, ") }
76
+ sb.delete(sb.length - 2, sb.length)
77
+ sb.append("]")
78
+ return sb.toString()
79
+ }
80
+ ```
81
+
82
+ 리뷰어: "*UI 로직*에 해당됩니다. *View에서 Lotto의 정보를 받아서 UI를 그리도록* 만들어 보세요." 학생 후속: `OutputView.printLottoNumbers(lotto: Lotto)`로 이동 — *대괄호 포맷*은 View 책임.
83
+
84
+ ### 6. `LottoStatistics`가 *Map* 반환 — Tell, Don't Ask
85
+
86
+ ```kotlin
87
+ fun matchTicket(ticket: Ticket): Map<Rank, Int> {. } // ⚠ 컬렉션 반환
88
+ fun yield(result: Map<Rank, Int>, purchaseLottoMoney: PurchaseLottoMoney): String {. }
89
+ ```
90
+
91
+ 리뷰어: "*UI 단에 데이터를 넘겨주는 것과 같이 꼭 필요한 경우가 아니라면 외부로 데이터에 넘겨서 처리하는 방식은 지양*해 주세요. *객체에 메시지를 전달하여 객체 내부에서 처리한 뒤 값을 반환*하도록 만들어 보세요." 학생: `LottoResult` 도입 — *결과 객체*로 캡슐화.
92
+
93
+ ### 7. `Ticket` *역할 없음* — 단순 래퍼
94
+
95
+ ```kotlin
96
+ class Ticket(val lottos: List<Lotto>)
97
+ ```
98
+
99
+ 리뷰어: "*Ticket이 사실상 아무 역할도 하지 않고 있*습니다. *외부에서 Ticket의 값을 꺼내서 쓰는 대신에 Ticket 내부에서 lottos를 이용하여 처리한 뒤 값을 반환*하도록 만들어 보세요." 학생: `Ticket.matchTicketCount(winningLotto)`, `Ticket.forEach` 등 *컬렉션 방법론을 객체 내부에서*.
100
+
101
+ ### 8. `deepCopy` vs `copy` — 명시적 네이밍
102
+
103
+ ```kotlin
104
+ class Ticket(lottos: List<Lotto>) {
105
+ private val _lottos = lottos.toList()
106
+ val lottos: List<Lotto> get() = _lottos.toList()
107
+ }
108
+ ```
109
+
110
+ 리뷰어: "코틀린에서는 *data class로 선언하면 자동으로 얕은 복사가 되는 copy() 함수가 만들어집니다*. *깊은 복사를 제공해 주고 싶을 때는 명시적으로 deepCopy()와 같이 함수명으로 드러내* 주면 좋습니다." — *복사 의미*를 *이름*에.
111
+
112
+ ### 9. `validateXxx()` *Boolean 관행*
113
+
114
+ 리뷰어: "별개로 *validateXxx()와 같은 네이밍의 함수들을 보통 Boolean을 반환*하도록 만듭니다. 현재 구현도 나쁘지 않지만 *validateXxx()를 호출하고 true이면 객체를 생성하고 아니면 다시 재입력을 받는 구조*로 만들어도 좋습니다." — *검증과 생성을 한 함수*로 합치는 것보다 *책임 분리*가 관행.
115
+
116
+ ## 리뷰어 의견 요지
117
+
118
+ - **`runCatching` = *정상 Flow가 아닌 경우*만**. 입력 재시도는 *명시적 null 반환 + while*.
119
+ - **논리 오류의 예외 = *로그 + UncaughtExceptionHandler***.
120
+ - **`if/when` 2줄 = *중괄호 필수***.
121
+ - **`toString()` View 침투 금지** — *대괄호 포맷*도 View.
122
+ - **컬렉션 반환 vs *객체 메시지*** — `Ticket.matchTicketCount(winningLotto)`.
123
+ - **단순 래퍼 클래스는 *행동 추가*가 정상**.
124
+ - **`deepCopy` 명시적 네이밍**.
125
+ - **`validateXxx` = Boolean 관행**.
126
+
127
+ - **대표 인용:**
128
+ > 프로그램의 정상적인 Flow에서 예외를 던지고 try-catch를 통해 처리하는 방법은 *지양*해야 합니다.
129
+ > — @galcyurio on `src/main/kotlin/view/InputView.kt`
130
+
131
+ > 논리 오류일 때 예외를 던지라는 것은 *런타임에 예외도 발생하지 않아서 로그로도 안 남는 최악의 상황을 그나마 예외라도 던지게 만들어서 로그에 수집*되게 만들라는 의미입니다.
132
+ > — @galcyurio on `src/main/kotlin/view/InputView.kt`
133
+
134
+ > UI 단에 데이터를 넘겨주는 것과 같이 꼭 필요한 경우가 아니라면 *외부로 데이터에 넘겨서 처리하는 방식은 지양*해 주세요.
135
+ > — @galcyurio on `src/main/kotlin/domain/LottoStatistics.kt`
136
+
137
+ > Ticket이 *사실상 아무 역할도 하지 않고* 있습니다. *외부에서 Ticket의 값을 꺼내서 쓰는 대신에 Ticket 내부에서 lottos를 이용하여 처리한 뒤 값을 반환*하도록 만들어 보세요.
138
+ > — @galcyurio on `src/main/kotlin/domain/Ticket.kt`
139
+
140
+ ## 얻은 교훈
141
+
142
+ - **다른 클래스가 상수 필요 → *책임 위치 재검토*** — *private 해제*는 결합도 신호. `1000원`이 *판매소* 책임인가 *금액 도메인* 책임인가.
143
+ - **`runCatching`은 *예측 불가 오류*에만** — *재입력*은 *정상 Flow*이므로 *null 반환 + while*.
144
+ - **논리 오류 = *예외 + 전역 핸들러*** — 로깅을 위한 *최후 안전망*.
145
+ - **`if/when` 2줄 이상 = 중괄호** — Kotlin 공식 컨벤션. PR #49 잭슨도 같은 지적.
146
+ - **`toString()`은 View 책임** — *대괄호 포맷*도 도메인이 알면 *다국어/A-B 테스트* 시 도메인 변경.
147
+ - **컬렉션 반환 vs *결과 객체*** — `Map<Rank, Int>` 노출보다 `LottoResult.profitRate()`가 *Tell, Don't Ask*.
148
+ - **단순 래퍼 = *행동 추가 가능 신호*** — `Ticket`이 *값만 보유*하면 `lottos.count { winning.match(it) }`이 외부에 흩어짐.
149
+ - **`deepCopy` 명시** — `copy()`는 *얕은*. *깊은*은 이름으로 드러내야.
150
+ - **`validateXxx` = Boolean** — *검증 + 생성*을 한 함수에 두는 것은 *책임 결합*. 분리가 관행.
@@ -0,0 +1,179 @@
1
+ # PR #123 — [비비] 1단계 로또
2
+
3
+ - **Reviewee:** [@rosemin928](https://github.com/rosemin928)
4
+ - **PR:** https://github.com/woowacourse/kotlin-lotto/pull/123
5
+ - **단계:** 1단계
6
+ - **리뷰어:** @Gyuil-Hwnag (규일)
7
+ - **라인 코멘트:** 45 (리뷰어 27 + 학생 18)
8
+
9
+ ## 잘한 점 (설계 관점)
10
+
11
+ - **`LottoGenerator` interface** — Strategy.
12
+ - **README 작성** — 칭찬: "README 작성 정말 좋네요~👍".
13
+ - **테스트 fixture 도입** — 후속 라운드에서 학생이 적용. 리뷰어: "*test fixture를 적용해 주신 내용을 보니, 해당 코멘트는 넘어가도 될 것* 같습니다ㅎㅎ".
14
+ - **후속 라운드 칭찬 빈출** — "Profit 객체가 정말 *이익률을 계산하는 객체로 변경*되었군요~👍" / "*non-nullable하던 것에 대한 처리 좋네요*~👍" / "LottoApplication이라고 *네이밍을 변경해 주셨군요*~👍".
15
+
16
+ ## 못한 점 (설계 관점)
17
+
18
+ ### 1. `main()` 이름 모호 — *다게임 확장 시*
19
+
20
+ 리뷰어: "추후 *게임 종류가 많아진다면, main()이라는 네이밍이 다소 애매하게 느껴질* 수 있겠네요~ *이를 로또에 맞게 바꾸려면 어떻게 바꿔 보는 것이 좋을까요*?🤔" 학생 후속: `LottoApplication`. 칭찬 받음.
21
+
22
+ ### 2. *하드 코딩 문구* 다수
23
+
24
+ 리뷰어: "*하드 코딩된 문구들에 대해서, 상수화를 해 보는 것은 어떨까* 라는 생각이 듭니다~💪" + 전체 코멘트: "전반적인 코멘트입니다! 위에서 남겨 둔 코멘트처럼 *하드코딩된 내용들에 대해서 상수화를 진행해 보는 것*은 어떨까 라는 생각이 듭니다~"
25
+
26
+ ### 3. *결과를 Map으로 반환* — `WinningStatistics` 객체화
27
+
28
+ ```kotlin
29
+ fun calculateResult(.): Map<Rank, Int> =. // ⚠ 원시 컬렉션 반환
30
+ ```
31
+
32
+ 리뷰어: "*Map으로 리턴되는 값들을 WinningXXX or Lottos 등으로 묶어 보는 것은 어떨까* 라는 생각이 듭니다~🤔 그렇다면 *OutputView.printResult() 내의 로직 등 여러 가지 책임을 가질 수 있겠다*는 생각이 드네요!"
33
+
34
+ ### 4. `Profit` *원시값 노출* — 객체 책임화
35
+
36
+ ```kotlin
37
+ val profit: Double =.
38
+ ```
39
+
40
+ 리뷰어: "*원시값 포장을 한다면, Profit이라는 객체도 책임을 가지게 해 볼 수도 있겠군요*!" 학생 후속: `Profit` 클래스에 *이익률 계산 책임* 부여. 리뷰어 칭찬: "*Profit 객체가 정말 이익률을 계산하는 객체로 변경*되었군요~👍".
41
+
42
+ ### 5. *Interface 사용 의도* 메타-질문
43
+
44
+ 리뷰어: "*Interface를 사용해 주셨군요!!👍 interface를 사용하신 이유*가 궁금합니다~🤔"
45
+
46
+ ### 6. *문자 입력 → 폭파* (주석으로 표시)
47
+
48
+ ```kotlin
49
+ // 문자가 들어오면.
50
+ ```
51
+
52
+ 리뷰어: "주석에 *남겨주셨네요😅 문자가 들어오면. 서비스는 폭파되겠군요..!*" — *알면서도 안 한 것*은 *기술 부채 명시화*인 점은 좋으나 *해결*이 더 좋음.
53
+
54
+ ### 7. *함수가 너무 많은 기능*
55
+
56
+ 리뷰어: "*하나의 함수가 많은 기능을 담당하고 있는 것* 같은데, *이를 어떻게 분리를 해 볼 수 있을까요*~🤔"
57
+
58
+ ### 8. *다국어 시나리오* — Controller 적용?
59
+
60
+ 리뷰어: "*만약 한국 로또 / 미국 로또 / 일본 로또된다면 언어마다의 Input/Output이 있을 텐데, 이는 어떻게 LottoController에 적용을 해 볼 수 있을까요*??🤔 한 번 고민해 보면 좋을 내용인 것 같아서 코멘트 남겨 두었습니다! *수정이 필요한 것은 아닙니다*"
61
+
62
+ ### 9. *1000원 단위 강제 vs 거스름돈*
63
+
64
+ 리뷰어: "*로또 구매 금액을 무조건 1000원 단위로 받아야 할까요*..? 비비의 의견을 알려 주세요! 요구사항에는 없기는 하지만, *물가 인상률이 반영되어 로또가 1100원이 된다면 동전이 없다면 10장 단위를 꼭 맞춰야 할까요*?" — *현실 메타포*. *물가 인상*은 *우테코 리뷰어 공통 가르침*.
65
+
66
+ ### 10. *분리 책임 다국어/지역화* — LottoNumber에 응집
67
+
68
+ 리뷰어: "*해당 내용은 만약 LottoNumber라는 객체가 있다면, 해당 객체의 책임으로 볼 수도 있겠*군요!" — *책임을 도메인 객체에 부착*.
69
+
70
+ ### 11. *`Profit` 생성자에 lottoBundle, winningLotto* — 의존 깊이
71
+
72
+ ```kotlin
73
+ class Profit(
74
+ private val lottoBundle: LottoBundle,
75
+ private val winningLotto: WinningLotto,
76
+ val profit: Double
77
+ )
78
+ ```
79
+
80
+ 리뷰어: "*profit이 생성자로 있는 이유*가 궁금합니다!" + "해당 객체에서도 *lottoBundle, winningLotto가 반드시 있어야 할까요*?🤔 현재의 *댑스를 보면 Controller → Profit → WinningStatistics으로 객체 간의 의존성이 생기고 있는 것* 같아서, *Controller → Profit & WinningStatistics 형태*로도 변경을 해 보는 것은 어떤가 라는 생각이 듭니다! *현재 구조를 보면 객체 간의 결합이 강하게 되어 있다*는 생각이 드네요" — *직렬 의존* → *병렬 의존*으로 결합도 낮춤.
81
+
82
+ ### 12. *non-nullable 강제* → 오류 위험
83
+
84
+ ```kotlin
85
+ result[rank] = result[rank] + 1 // ⚠ null 가능
86
+ ```
87
+
88
+ 리뷰어: "*non-nullable하다고 강제하는 것은 오류를 발생시킬 수 있*습니다!"
89
+ ```kotlin
90
+ result[rank] = result[rank] ?: (0 + 1)
91
+ ```
92
+ — `Map<K, V>` getter는 *nullable*. *!!*이나 *non-null 단언*은 *Map 초기화 가정* 의존.
93
+
94
+ ### 13. *InputView 네이밍*
95
+
96
+ 리뷰어: "Application 때와 동일하게, *InputView한테 좀 더 유의미한 네이밍을 어떤 방식으로 지어 줄 수 있을까요*?"
97
+
98
+ ### 14. *테스트 네이밍 + given/when/result*
99
+
100
+ 리뷰어: "*테스트 코드의 경우 어떤 테스트인지 확실하게 알 수 있게 네이밍*을 정해 주는 것도 좋은 것 같습니다!"
101
+ ```kotlin
102
+ @Test
103
+ fun `자동차가 1칸 이동하면 거리는 1이다`() {
104
+ // given
105
+ val myCar = Car("Duru")
106
+ // when
107
+ myCar.move(1)
108
+ // result
109
+ assertThat(myCar.distance).isEqualTo(1)
110
+ }
111
+ ```
112
+ + "*주어진 것 / 어떤 액션 / 액션의 결과 구분*으로입니다. 여러 객체들 간에 유기적으로 연결이 되어 있는 테스트를 할 경우에는 *코드 라인 수도 늘어나고, 어떤 것을 테스트하는지 명확히 알아보기 힘든 경우가 있었어서 주어진 것 / 어떤 액션 / 액션의 결과로 테스트 함수 내에서 분리*해 보는 것도 좋을 것 같습니다." — *Arrange-Act-Assert* 또는 *Given-When-Then* 패턴.
113
+
114
+ ### 15. *테스트 커버리지 IDE 지원*
115
+
116
+ 리뷰어: "테스트 코드 잘 작성해 주셨네요~👍 참고해 보면 좋을 내용인 것 같아서 남겨 두었습니다! https://developer.android.com/studio/test/test-in-android-studio#view_test_coverage *테스트 코드를 어느 정도로 작성했는지 확인하는 방법으로 테스트 커버리지라는 개념*이 있습니다. 물론 *IDEA에서 기능을 지원*해 주고 있습니다~"
117
+
118
+ ### 16. *일급 컬렉션* 학생 자가 의문
119
+
120
+ 학생: "*일급 컬렉션을 사용해 보려고 했습니다.! 이렇게 사용하는 것이 맞는지 확신이 서지 않아서 더 공부*해 보고 싶습니다!"
121
+
122
+ 리뷰어: "*저랑 이번 미션을 진행하면서 같이 얘기해 보면 좋을 것 같습니다*! 우선 *비비가 생각하시는 '원시값 포장 & 일급 컬렉션'은 무엇인가요*? (정답을 원하는 게 아니라 비비가 *문득 생각해 봤을 때 드는 생각을 남겨* 주세요. *아무말 대잔치여도 좋습니다*~) 일급 컬렉션에 대해서 참고해 보면 좋을 내용들이 있어서 남겨 두었습니다 - https://jojoldu.tistory.com/412".
123
+
124
+ ### 17. `LottoTicketCounter` vs `LottoStore` *동일 목표*
125
+
126
+ 리뷰어: "*LottoTicketCounter와 LottoStore는 돈을 받고 로또를 발행한다는 동일한 목표를 바라보고 있는 것 같은데, 하나로 합쳐 보는 것도* 좋을 것 같습니다~💪" — *유사 책임 객체 통합*.
127
+
128
+ ### 18. *문자열 검증 후 Double로* — InputView가 형 변환 책임
129
+
130
+ 리뷰어: "*input에 대한 검증은 inputView에서 하였으니, String 말고 Double 형으로 받아 볼 수 있겠*군요!" — *View가 검증 + 변환*, *Controller/Domain은 검증된 타입* 수용.
131
+
132
+ ### 19. *winningStatics 자체 받기* — 플로우 명확화
133
+
134
+ 리뷰어: "현재는 *winningStatics 자체를 받고 있어서, 헷갈릴 수도 있겠*다는 생각이 드네요! 아래와 같은 *흐름*으로 해 보면 좀 더 구현이 깔끔해질 수도 있겠다는 생각이 드네요~ *WinningLotto를 구한다 → WinningLottoStatics의 함수를 통해서 몇 개가 당첨 Or 결과를 리턴한다 → 결과를 Profit에 넣어준다.* 이렇게 한다면, *WinningLotto → 당첨 로또 → WinningLottoStatics → 나의 당첨 내역 → Profit → 내 이익률* 이런 순서로 *구현의 플로우가 잘 드러날 수 있겠*다는 생각이 듭니다!"
135
+
136
+ ## 리뷰어 의견 요지
137
+
138
+ - **`main()` 이름 → *애플리케이션 도메인***.
139
+ - **하드코딩 문구 → *상수화***.
140
+ - **`Map<Rank, Int>` → *WinningStatistics 객체***.
141
+ - **`Profit` *원시값 → 책임 객체***.
142
+ - **다국어 시나리오로 *interface 정당화***.
143
+ - **1000원 단위 강제 → *거스름돈 / 자율***.
144
+ - **`!!` 회피** — Map nullable 인식.
145
+ - **`Profit` *직렬 의존* → *Controller가 병렬 의존***.
146
+ - **`LottoTicketCounter` + `LottoStore` *통합* 가능**.
147
+ - **`InputView`가 *Double 형*까지 변환**.
148
+ - **`given/when/result` 테스트 구조**.
149
+ - **테스트 커버리지 IDE 지원**.
150
+ - **일급 컬렉션 *책 참고*** — jojoldu 블로그.
151
+
152
+ - **대표 인용:**
153
+ > 만약 한국 로또 / 미국 로또 / 일본 로또된다면 *언어마다의 Input/Output이 있을 텐데, 이는 어떻게 LottoController에 적용을 해 볼 수 있을까요*?
154
+ > — @Gyuil-Hwnag on `src/main/kotlin/lotto/LottoController.kt`
155
+
156
+ > 물가 인상률이 반영되어 *로또가 1100원이 된다면 동전이 없다면 10장 단위를 꼭 맞춰야 할까요*?
157
+ > — @Gyuil-Hwnag on `src/main/kotlin/lotto/domain/PurchaseAmount.kt`
158
+
159
+ > 현재 구조를 보면 *객체 간의 결합이 강하게 되어 있다*는 생각이 드네요.
160
+ > — @Gyuil-Hwnag on `src/main/kotlin/lotto/domain/Profit.kt`
161
+
162
+ > 우선 비비가 생각하시는 *'원시값 포장 & 일급 컬렉션'은 무엇인가요*? (정답을 원하는 게 아니라 비비가 문득 생각해 봤을 때 드는 생각을 남겨 주세요 *아무말 대잔치여도 좋습니다*~)
163
+ > — @Gyuil-Hwnag on `src/main/kotlin/lotto/domain/Lottos.kt`
164
+
165
+ ## 얻은 교훈
166
+
167
+ - **`main()` 이름 = *애플리케이션 진입점*** — *다게임 확장* 시 `LottoApplication`처럼 *도메인 명시*.
168
+ - **`Map<Rank, Int>` → *WinningStatistics 객체*** — *원시 컬렉션 반환*은 *호출자가 자료구조 직접 다룸*. 객체 캡슐화 = *책임 위임 + 출력 책임* 단순화.
169
+ - **`Profit` *원시값 → 책임 객체*** — *Double 노출*은 *계산식이 호출자*에. *수익률 계산까지 객체* 책임화.
170
+ - **다국어 시나리오 = interface 정당화** — PR #64 *키오스크*, PR #80 *Quest/Task/ToDo A-B*와 같은 패턴. *국제화*는 *우테코 리뷰어 공통 가르침*.
171
+ - **1000원 단위 = *거스름돈 시나리오***
172
+ - **`!!` 회피** — `Map` getter *nullable* 인식. *non-null 단언*은 *초기화 가정* 의존.
173
+ - **`Profit` 직렬 의존 → 병렬 의존** — *Controller → Profit → WinningStatistics*는 *결합도 강*. *Controller → Profit & WinningStatistics* 동등하게.
174
+ - **`LottoTicketCounter` + `LottoStore` *동일 책임* 통합** — *클래스 분리 ≠ 책임 분리*.
175
+ - **`InputView` *Double 변환까지*** — *검증 + 형 변환*은 *View 책임 한계*에.
176
+ - **`given/when/result`** — 테스트 *3구역 분리*. *유기적 객체 테스트*는 *시각적 구분*이 가독성.
177
+ - **테스트 커버리지 *IDE 지원*** — IDEA *기능 활용*. *기계 측정*에 의존, *수치*는 *추적*만.
178
+ - **일급 컬렉션 = *책 + 블로그 참고*** — jojoldu 블로그는 *우테코 공통 자료*.
179
+ - **객체 흐름 = *도메인 어휘 시퀀스*** — `WinningLotto → 당첨 → WinningLottoStatics → 내역 → Profit → 이익률` 식의 *시퀀스 다이어그램*.