@icarusmx/creta 0.9.2 → 0.10.1
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.
- package/bin/creta.js +33 -2
- package/lessons/lesson1-system-decomposition.js +249 -0
- package/package.json +1 -1
package/bin/creta.js
CHANGED
|
@@ -6,6 +6,7 @@ import fs from 'fs'
|
|
|
6
6
|
import path from 'path'
|
|
7
7
|
import { fileURLToPath } from 'url'
|
|
8
8
|
import { CretaCodeSession } from '../lib/session.js'
|
|
9
|
+
import { Lesson1SystemDecomposition } from '../lessons/lesson1-system-decomposition.js'
|
|
9
10
|
import { Lesson6InterfaceDesign } from '../lessons/lesson6-interface-design.js'
|
|
10
11
|
|
|
11
12
|
const ENUNCIADOS = [
|
|
@@ -812,7 +813,21 @@ async function startEnunciadosSelectorInteractive() {
|
|
|
812
813
|
console.log(`📚 Nivel: ${enunciadoSeleccionado.nivel}`)
|
|
813
814
|
|
|
814
815
|
// Check if we have a lesson implementation for this enunciado
|
|
815
|
-
if (enunciadoSeleccionado.id ===
|
|
816
|
+
if (enunciadoSeleccionado.id === 1) {
|
|
817
|
+
console.log("\n🚀 ¡Lección disponible! Iniciando sesión de estudio dirigida...")
|
|
818
|
+
await new Promise(resolve => setTimeout(resolve, 1500)) // Brief pause
|
|
819
|
+
|
|
820
|
+
try {
|
|
821
|
+
const lesson1 = new Lesson1SystemDecomposition()
|
|
822
|
+
await lesson1.start()
|
|
823
|
+
} catch (error) {
|
|
824
|
+
console.error("\n❌ Error al ejecutar la lección:", error.message)
|
|
825
|
+
console.log("\n🚀 Próximamente:")
|
|
826
|
+
console.log("- Sesiones de estudio dirigidas basadas en este enunciado")
|
|
827
|
+
console.log("- Ejercicios prácticos que ilustren el concepto")
|
|
828
|
+
console.log("- Proyectos específicos para internalizar la idea")
|
|
829
|
+
}
|
|
830
|
+
} else if (enunciadoSeleccionado.id === 6) {
|
|
816
831
|
console.log("\n🚀 ¡Lección disponible! Iniciando sesión de estudio dirigida...")
|
|
817
832
|
await new Promise(resolve => setTimeout(resolve, 1500)) // Brief pause
|
|
818
833
|
|
|
@@ -895,7 +910,23 @@ async function startEnunciadosSelectorFallback() {
|
|
|
895
910
|
console.log(`📚 Nivel: ${enunciadoSeleccionado.nivel}`)
|
|
896
911
|
|
|
897
912
|
// Check if we have a lesson implementation for this enunciado
|
|
898
|
-
if (enunciadoSeleccionado.id ===
|
|
913
|
+
if (enunciadoSeleccionado.id === 1) {
|
|
914
|
+
console.log("\n🚀 ¡Lección disponible! Iniciando sesión de estudio dirigida...")
|
|
915
|
+
rl.close()
|
|
916
|
+
await new Promise(resolve => setTimeout(resolve, 1500)) // Brief pause
|
|
917
|
+
|
|
918
|
+
try {
|
|
919
|
+
const lesson1 = new Lesson1SystemDecomposition()
|
|
920
|
+
await lesson1.start()
|
|
921
|
+
} catch (error) {
|
|
922
|
+
console.error("\n❌ Error al ejecutar la lección:", error.message)
|
|
923
|
+
console.log("\n🚀 Próximamente:")
|
|
924
|
+
console.log("- Sesiones de estudio dirigidas basadas en este enunciado")
|
|
925
|
+
console.log("- Ejercicios prácticos que ilustren el concepto")
|
|
926
|
+
console.log("- Proyectos específicos para internalizar la idea")
|
|
927
|
+
}
|
|
928
|
+
return
|
|
929
|
+
} else if (enunciadoSeleccionado.id === 6) {
|
|
899
930
|
console.log("\n🚀 ¡Lección disponible! Iniciando sesión de estudio dirigida...")
|
|
900
931
|
rl.close()
|
|
901
932
|
await new Promise(resolve => setTimeout(resolve, 1500)) // Brief pause
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// LECCIÓN 1: La parte difícil del diseño orientado a objetos es descomponer un sistema como un conjunto de objetos que interactúan entre sí
|
|
4
|
+
// Enfoque práctico: Dos definiciones de sistema y su descomposición en objetos
|
|
5
|
+
|
|
6
|
+
import { createInterface } from 'readline'
|
|
7
|
+
|
|
8
|
+
export class Lesson1SystemDecomposition {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.rl = createInterface({
|
|
11
|
+
input: process.stdin,
|
|
12
|
+
output: process.stdout
|
|
13
|
+
})
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async start() {
|
|
17
|
+
console.log("LECCIÓN 1: Descomposición de Sistemas")
|
|
18
|
+
console.log("=" .repeat(50))
|
|
19
|
+
console.log("Concepto: La parte difícil del diseño orientado a objetos es descomponer un sistema como un conjunto de objetos que interactúan entre sí.")
|
|
20
|
+
|
|
21
|
+
await this.waitForEnter("\nPresiona Enter para comenzar...")
|
|
22
|
+
|
|
23
|
+
await this.practicalExercise()
|
|
24
|
+
await this.conclusion()
|
|
25
|
+
|
|
26
|
+
this.rl.close()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async practicalExercise() {
|
|
30
|
+
console.clear()
|
|
31
|
+
console.log("Comenzaremos con dos definiciones de sistema y posteriormente")
|
|
32
|
+
console.log("ejemplificaremos la descomposición en objetos.")
|
|
33
|
+
|
|
34
|
+
await this.waitForEnter("\nPresiona Enter para continuar...")
|
|
35
|
+
|
|
36
|
+
await this.step1_SystemDefinitions()
|
|
37
|
+
await this.step2_ApplyDefinitions()
|
|
38
|
+
await this.step3_ObjectIdentification()
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async step1_SystemDefinitions() {
|
|
42
|
+
console.clear()
|
|
43
|
+
console.log("DEFINICIÓN 1:")
|
|
44
|
+
console.log("El sistema es una totalidad deductiva de discurso")
|
|
45
|
+
|
|
46
|
+
console.log("\nDEFINICIÓN 2:")
|
|
47
|
+
console.log("El sistema es un conjunto de cosas que relacionadas")
|
|
48
|
+
console.log("entre sí ordenadamente contribuyen a un determinado propósito")
|
|
49
|
+
|
|
50
|
+
await this.waitForEnter("\nPresiona Enter para ver la biblioteca digital...")
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async step2_ApplyDefinitions() {
|
|
54
|
+
console.clear()
|
|
55
|
+
console.log("Sistema: Biblioteca Digital")
|
|
56
|
+
|
|
57
|
+
console.log("\nReglas del dominio:")
|
|
58
|
+
console.log("• Un libro puede estar disponible o prestado")
|
|
59
|
+
console.log("• Un usuario puede tener máximo N libros prestados")
|
|
60
|
+
console.log("• Un préstamo tiene fecha de inicio y vencimiento")
|
|
61
|
+
console.log("• Solo usuarios registrados pueden solicitar préstamos")
|
|
62
|
+
console.log("• Un libro prestado no puede prestarse a otro usuario")
|
|
63
|
+
console.log("• Los préstamos vencidos generan multas")
|
|
64
|
+
|
|
65
|
+
await this.waitForEnter("\nPresiona Enter para ver los componentes...")
|
|
66
|
+
|
|
67
|
+
console.log("\nComponentes que colaboran:")
|
|
68
|
+
console.log("• Catálogo de libros disponibles")
|
|
69
|
+
console.log("• Sistema de usuarios registrados")
|
|
70
|
+
console.log("• Proceso de préstamos y devoluciones")
|
|
71
|
+
console.log("• Control de fechas y multas")
|
|
72
|
+
console.log("• Búsqueda y recomendaciones")
|
|
73
|
+
console.log("• Reportes de uso y estadísticas")
|
|
74
|
+
|
|
75
|
+
await this.waitForEnter("\nPresiona Enter para ver la descomposición...")
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async step3_ObjectIdentification() {
|
|
79
|
+
console.clear()
|
|
80
|
+
console.log("Descomposición en objetos:")
|
|
81
|
+
|
|
82
|
+
console.log("\nclass Book {")
|
|
83
|
+
console.log(" constructor(title, author, isbn) {")
|
|
84
|
+
console.log(" this.title = title")
|
|
85
|
+
console.log(" this.author = author")
|
|
86
|
+
console.log(" this.isbn = isbn")
|
|
87
|
+
console.log(" this.isLoaned = false")
|
|
88
|
+
console.log(" }")
|
|
89
|
+
console.log("")
|
|
90
|
+
console.log(" isAvailable() {")
|
|
91
|
+
console.log(" return !this.isLoaned")
|
|
92
|
+
console.log(" }")
|
|
93
|
+
console.log("")
|
|
94
|
+
console.log(" markAsLoaned() {")
|
|
95
|
+
console.log(" this.isLoaned = true")
|
|
96
|
+
console.log(" }")
|
|
97
|
+
console.log("")
|
|
98
|
+
console.log(" markAsReturned() {")
|
|
99
|
+
console.log(" this.isLoaned = false")
|
|
100
|
+
console.log(" }")
|
|
101
|
+
console.log("}")
|
|
102
|
+
|
|
103
|
+
await this.waitForEnter("\nPresiona Enter para ver User...")
|
|
104
|
+
|
|
105
|
+
console.log("\nclass User {")
|
|
106
|
+
console.log(" constructor(name, email, maxLoans = 3) {")
|
|
107
|
+
console.log(" this.name = name")
|
|
108
|
+
console.log(" this.email = email")
|
|
109
|
+
console.log(" this.maxLoans = maxLoans")
|
|
110
|
+
console.log(" this.currentLoans = []")
|
|
111
|
+
console.log(" }")
|
|
112
|
+
console.log("")
|
|
113
|
+
console.log(" canBorrow() {")
|
|
114
|
+
console.log(" return this.currentLoans.length < this.maxLoans")
|
|
115
|
+
console.log(" }")
|
|
116
|
+
console.log("")
|
|
117
|
+
console.log(" addLoan(loan) {")
|
|
118
|
+
console.log(" this.currentLoans.push(loan)")
|
|
119
|
+
console.log(" }")
|
|
120
|
+
console.log("")
|
|
121
|
+
console.log(" removeLoan(loan) {")
|
|
122
|
+
console.log(" const index = this.currentLoans.indexOf(loan)")
|
|
123
|
+
console.log(" if (index > -1) this.currentLoans.splice(index, 1)")
|
|
124
|
+
console.log(" }")
|
|
125
|
+
console.log("}")
|
|
126
|
+
|
|
127
|
+
await this.waitForEnter("\nPresiona Enter para ver Loan...")
|
|
128
|
+
|
|
129
|
+
console.log("\nclass Loan {")
|
|
130
|
+
console.log(" constructor(user, book, durationDays = 14) {")
|
|
131
|
+
console.log(" this.user = user")
|
|
132
|
+
console.log(" this.book = book")
|
|
133
|
+
console.log(" this.startDate = new Date()")
|
|
134
|
+
console.log(" this.dueDate = new Date(Date.now() + durationDays * 24 * 60 * 60 * 1000)")
|
|
135
|
+
console.log(" this.returned = false")
|
|
136
|
+
console.log(" }")
|
|
137
|
+
console.log("")
|
|
138
|
+
console.log(" isOverdue() {")
|
|
139
|
+
console.log(" return !this.returned && new Date() > this.dueDate")
|
|
140
|
+
console.log(" }")
|
|
141
|
+
console.log("")
|
|
142
|
+
console.log(" calculateFine() {")
|
|
143
|
+
console.log(" if (!this.isOverdue()) return 0")
|
|
144
|
+
console.log(" const daysLate = Math.ceil((new Date() - this.dueDate) / (24 * 60 * 60 * 1000))")
|
|
145
|
+
console.log(" return daysLate * 5 // $5 por día")
|
|
146
|
+
console.log(" }")
|
|
147
|
+
console.log("")
|
|
148
|
+
console.log(" returnBook() {")
|
|
149
|
+
console.log(" this.returned = true")
|
|
150
|
+
console.log(" this.book.markAsReturned()")
|
|
151
|
+
console.log(" this.user.removeLoan(this)")
|
|
152
|
+
console.log(" }")
|
|
153
|
+
console.log("}")
|
|
154
|
+
|
|
155
|
+
await this.waitForEnter("\nPresiona Enter para ver Library...")
|
|
156
|
+
|
|
157
|
+
console.log("\nclass Library {")
|
|
158
|
+
console.log(" constructor() {")
|
|
159
|
+
console.log(" this.books = []")
|
|
160
|
+
console.log(" this.users = []")
|
|
161
|
+
console.log(" this.loans = []")
|
|
162
|
+
console.log(" }")
|
|
163
|
+
console.log("")
|
|
164
|
+
console.log(" lendBook(user, book) {")
|
|
165
|
+
console.log(" if (!user.canBorrow()) return null")
|
|
166
|
+
console.log(" if (!book.isAvailable()) return null")
|
|
167
|
+
console.log("")
|
|
168
|
+
console.log(" const loan = new Loan(user, book)")
|
|
169
|
+
console.log(" book.markAsLoaned()")
|
|
170
|
+
console.log(" user.addLoan(loan)")
|
|
171
|
+
console.log(" this.loans.push(loan)")
|
|
172
|
+
console.log(" return loan")
|
|
173
|
+
console.log(" }")
|
|
174
|
+
console.log("")
|
|
175
|
+
console.log(" returnBook(loan) {")
|
|
176
|
+
console.log(" loan.returnBook()")
|
|
177
|
+
console.log(" return loan.calculateFine()")
|
|
178
|
+
console.log(" }")
|
|
179
|
+
console.log("")
|
|
180
|
+
console.log(" getOverdueLoans() {")
|
|
181
|
+
console.log(" return this.loans.filter(loan => loan.isOverdue())")
|
|
182
|
+
console.log(" }")
|
|
183
|
+
console.log("}")
|
|
184
|
+
|
|
185
|
+
await this.waitForEnter("\nPresiona Enter para ver la interacción...")
|
|
186
|
+
|
|
187
|
+
console.clear()
|
|
188
|
+
console.log("Ejemplo de uso:")
|
|
189
|
+
console.log("")
|
|
190
|
+
console.log("const library = new Library()")
|
|
191
|
+
console.log("const book = new Book('1984', 'George Orwell', '978-0451524935')")
|
|
192
|
+
console.log("const user = new User('Ana García', 'ana@email.com')")
|
|
193
|
+
console.log("")
|
|
194
|
+
console.log("// Los objetos interactúan entre sí")
|
|
195
|
+
console.log("const loan = library.lendBook(user, book)")
|
|
196
|
+
console.log("console.log(book.isAvailable()) // false")
|
|
197
|
+
console.log("console.log(user.canBorrow()) // true (2 préstamos disponibles)")
|
|
198
|
+
console.log("")
|
|
199
|
+
console.log("// Simular libro vencido")
|
|
200
|
+
console.log("loan.dueDate = new Date(Date.now() - 24 * 60 * 60 * 1000)")
|
|
201
|
+
console.log("console.log(loan.isOverdue()) // true")
|
|
202
|
+
console.log("console.log(loan.calculateFine()) // 5")
|
|
203
|
+
console.log("")
|
|
204
|
+
console.log("// Devolver libro")
|
|
205
|
+
console.log("const fine = library.returnBook(loan)")
|
|
206
|
+
console.log("console.log(book.isAvailable()) // true")
|
|
207
|
+
|
|
208
|
+
await this.waitForEnter("\nPresiona Enter para la conclusión...")
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
async conclusion() {
|
|
212
|
+
console.clear()
|
|
213
|
+
console.log("CONCLUSIÓN")
|
|
214
|
+
console.log("=" .repeat(50))
|
|
215
|
+
console.log("Vimos cómo un sistema puede entenderse desde dos perspectivas:")
|
|
216
|
+
console.log("1. Como totalidad deductiva de discurso (reglas lógicas)")
|
|
217
|
+
console.log("2. Como conjunto de cosas que colaboran hacia un propósito")
|
|
218
|
+
|
|
219
|
+
console.log("\nLa biblioteca digital se descompuso en objetos que:")
|
|
220
|
+
console.log("• Book - maneja su propio estado de disponibilidad")
|
|
221
|
+
console.log("• User - controla sus límites de préstamo")
|
|
222
|
+
console.log("• Loan - calcula multas y fechas de vencimiento")
|
|
223
|
+
console.log("• Library - coordina las interacciones entre todos")
|
|
224
|
+
|
|
225
|
+
console.log("\nCada objeto encapsula parte de las reglas del sistema")
|
|
226
|
+
console.log("y colabora con otros para cumplir el propósito general.")
|
|
227
|
+
|
|
228
|
+
console.log("\nConexión con lecciones siguientes:")
|
|
229
|
+
console.log("• Lección 2: Cómo estos objetos interactúan")
|
|
230
|
+
console.log("• Lección 3: El mecanismo de las solicitudes")
|
|
231
|
+
console.log("• Lección 4-6: Cómo definir esas interacciones")
|
|
232
|
+
|
|
233
|
+
await this.waitForEnter("\nLección 1 completada. Presiona Enter para salir...")
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
async waitForEnter(message) {
|
|
237
|
+
return new Promise((resolve) => {
|
|
238
|
+
this.rl.question(message, () => {
|
|
239
|
+
resolve()
|
|
240
|
+
})
|
|
241
|
+
})
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Para usar la lección independientemente
|
|
246
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
247
|
+
const lesson = new Lesson1SystemDecomposition()
|
|
248
|
+
await lesson.start()
|
|
249
|
+
}
|