Skip to content

Commit 7eb7615

Browse files
authored
Merge pull request #7472 from duendeintemporal/main
#50 - javascript
2 parents 330cc00 + 4ec1710 commit 7eb7615

File tree

1 file changed

+270
-0
lines changed

1 file changed

+270
-0
lines changed
Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
//#50 { Retos para Programadores } PLANIFICADOR DE OBJETIVOS DE AÑO NUEVO
2+
/*
3+
* EJERCICIO:
4+
* El nuevo año está a punto de comenzar...
5+
* ¡Voy a ayudarte a planificar tus propósitos de nuevo año!
6+
*
7+
* Programa un gestor de objetivos con las siguientes características:
8+
* - Permite añadir objetivos (máximo 10)
9+
* - Calcular el plan detallado
10+
* - Guardar la planificación
11+
*
12+
* Cada entrada de un objetivo está formado por (con un ejemplo):
13+
* - Meta: Leer libros
14+
* - Cantidad: 12
15+
* - Unidades: libros
16+
* - Plazo (en meses): 12 (máximo 12)
17+
*
18+
* El cálculo del plan detallado generará la siguiente salida:
19+
* - Un apartado para cada mes
20+
* - Un listado de objetivos calculados a cumplir en cada mes
21+
* (ejemplo: si quiero leer 12 libros, dará como resultado
22+
* uno al mes)
23+
* - Cada objetivo debe poseer su nombre, la cantidad de
24+
* unidades a completar en cada mes y su total. Por ejemplo:
25+
*
26+
* Enero:
27+
* [ ] 1. Leer libros (1 libro/mes). Total: 12.
28+
* [ ] 2. Estudiar Git (1 curso/mes). Total: 1.
29+
* Febrero:
30+
* [ ] 1. Leer libros (1 libro/mes). Total: 12.
31+
* ...
32+
* Diciembre:
33+
* [ ] 1. Leer libros (1 libro/mes). Total: 12.
34+
*
35+
* - Si la duración es menor a un año, finalizará en el mes
36+
* correspondiente.
37+
*
38+
* Por último, el cálculo detallado debe poder exportarse a .txt
39+
* (No subir el fichero)
40+
*/
41+
42+
const fs = require('fs');
43+
const readline = require('readline');
44+
45+
const filePath = 'goals.txt';
46+
const maxGoals = 10;
47+
const log = console.log;
48+
49+
const rl = readline.createInterface({
50+
input: process.stdin,
51+
output: process.stdout
52+
});
53+
54+
let goals = [];
55+
56+
const monthNames = [
57+
"January", "February", "March", "April", "May", "June",
58+
"July", "August", "September", "October", "November", "December"
59+
];
60+
61+
const menu = () => {
62+
log('\n--- New Year Goals Planner ---');
63+
log('1. Add Goal');
64+
log('2. View Goals');
65+
log('3. Calculate Detailed Year Plan');
66+
log('4. Export Plan to .txt');
67+
log('5. Exit');
68+
rl.question('Select an option: ', handleMenuOption);
69+
};
70+
71+
const handleMenuOption = (option) => {
72+
switch (option) {
73+
case '1':
74+
addGoal();
75+
break;
76+
case '2':
77+
viewGoals();
78+
break;
79+
case '3':
80+
calculateDetailedYearPlan();
81+
break;
82+
case '4':
83+
exportPlan();
84+
break;
85+
case '5':
86+
exitProgram();
87+
break;
88+
default:
89+
log('Invalid option, choose a number between 1 and 5. Please try again.');
90+
menu();
91+
break;
92+
}
93+
};
94+
95+
const addGoal = () => {
96+
if (goals.length >= maxGoals) {
97+
log('Maximum number of goals reached.');
98+
return menu();
99+
}
100+
101+
askGoalName();
102+
};
103+
104+
const askGoalName = () => {
105+
log('Examples of goals: Learn, Read, Practice');
106+
rl.question('Goal Name: ', (name) => {
107+
if (!name) {
108+
log('Goal name cannot be empty. Please try again.');
109+
return askGoalName();
110+
}
111+
askQuantity(name);
112+
});
113+
};
114+
115+
const askQuantity = (name) => {
116+
log('Please enter a positive number for the quantity.');
117+
rl.question('Quantity: ', (quantity) => {
118+
const quantityNum = parseInt(quantity);
119+
if (isNaN(quantityNum) || quantityNum <= 0) {
120+
log('Quantity must be a positive number. Please try again.');
121+
return askQuantity(name);
122+
}
123+
askUnits(name, quantityNum);
124+
});
125+
};
126+
127+
const askUnits = (name, quantity) => {
128+
log('Examples of units: Books, Courses, Languages');
129+
rl.question('Units: ', (units) => {
130+
if (!units) {
131+
log('Units cannot be empty. Please try again.');
132+
return askUnits(name, quantity);
133+
}
134+
askDeadline(name, quantity, units);
135+
});
136+
};
137+
138+
const askDeadline = (name, quantity, units) => {
139+
log('Deadline must be a number between 1 and 12 months.');
140+
rl.question('Deadline (in months, max 12): ', (deadline) => {
141+
const deadlineNum = parseInt(deadline);
142+
if (isNaN(deadlineNum) || deadlineNum < 1 || deadlineNum > 12) {
143+
log('Deadline must be a number between 1 and 12. Please try again.');
144+
return askDeadline(name, quantity, units);
145+
}
146+
goals.push({ name, quantity, units, deadline: deadlineNum });
147+
log('Goal added!');
148+
menu();
149+
});
150+
};
151+
152+
const viewGoals = () => {
153+
if (goals.length === 0) {
154+
log('No goals registered.');
155+
} else {
156+
log('\nGoals:');
157+
goals.forEach((goal, index) => {
158+
log(`${index + 1}. ${goal.name} - ${goal.quantity} ${goal.units} over ${goal.deadline} months`);
159+
});
160+
}
161+
menu();
162+
};
163+
164+
const capitalizeFirstLetterOfEachWord = (string) => {
165+
return string.split(' ').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
166+
};
167+
168+
169+
const calculateDetailedYearPlan = () => {
170+
if (goals.length === 0) {
171+
log('No goals to calculate.');
172+
return menu();
173+
}
174+
175+
const plan = {};
176+
goals.forEach(goal => {
177+
const totalTasks = goal.quantity;
178+
const totalMonths = goal.deadline;
179+
const monthlyGoal = Math.floor(totalTasks / totalMonths);
180+
const remainder = totalTasks % totalMonths;
181+
182+
for (let month = 1; month <= totalMonths; month++) {
183+
if (!plan[month]) {
184+
plan[month] = [];
185+
}
186+
187+
// Calculate the number of tasks for the current month
188+
let tasksForMonth = monthlyGoal;
189+
if (month <= remainder) {
190+
tasksForMonth += 1; // Distribute the remainder tasks
191+
}
192+
193+
const capitalizedGoalName = capitalizeFirstLetterOfEachWord(goal.name);
194+
const capitalizeGoalUnits = capitalizeFirstLetterOfEachWord(goal.units);
195+
196+
plan[month].push(`${capitalizedGoalName} (${tasksForMonth} ${capitalizeGoalUnits}/month). Total: ${goal.quantity}. Deadline: ${monthNames[totalMonths - 1]}.`);
197+
}
198+
});
199+
200+
log('\n--- Detailed Year Plan ---');
201+
for (let month = 1; month <= 12; month++) {
202+
log(`${monthNames[month - 1]}:`);
203+
if (plan[month]) {
204+
plan[month].forEach((item, index) => {
205+
log(`[ ] ${index + 1}. ${item}`);
206+
});
207+
} else {
208+
log('No goals for this month.');
209+
}
210+
}
211+
menu();
212+
};
213+
214+
const exportPlan = () => {
215+
const plan = [];
216+
goals.forEach(goal => {
217+
const monthlyGoal = Math.ceil(goal.quantity / goal.deadline);
218+
for (let month = 1; month <= goal.deadline; month++) {
219+
plan.push(`Month ${month}: ${goal.name} (${monthlyGoal} ${goal.units}/month). Total: ${goal.quantity}.`);
220+
}
221+
});
222+
223+
fs.writeFile(filePath, plan.join('\n'), (err) => {
224+
if (err) throw err;
225+
log(`Plan exported to ${filePath}`);
226+
menu();
227+
});
228+
};
229+
230+
const exitProgram = () => {
231+
log('Exiting the program.');
232+
rl.close();
233+
};
234+
235+
menu();
236+
237+
/* Output example:
238+
239+
--- Detailed Year Plan ---
240+
January:
241+
[ ] 1. Learn Programing Languages (2 Languages/month). Total: 6. Deadline: April.
242+
[ ] 2. Read Fiction Books (1 Books/month). Total: 10. Deadline: November.
243+
[ ] 3. Practice Martial Arts (2 Kunfu Style/month). Total: 8. Deadline: April.
244+
February:
245+
[ ] 1. Learn Programing Languages (2 Languages/month). Total: 6. Deadline: April.
246+
[ ] 2. Read Fiction Books (1 Books/month). Total: 10. Deadline: November.
247+
[ ] 3. Practice Martial Arts (2 Kunfu Style/month). Total: 8. Deadline: April.
248+
March:
249+
[ ] 1. Learn Programing Languages (1 Languages/month). Total: 6. Deadline: April.
250+
[ ] 2. Read Fiction Books (1 Books/month). Total: 10. Deadline: November.
251+
[ ] 3. Practice Martial Arts (2 Kunfu Style/month). Total: 8. Deadline: April.
252+
April:
253+
[ ] 1. Learn Programing Languages (1 Languages/month). Total: 6. Deadline: April.
254+
[ ] 2. Read Fiction Books (1 Books/month). Total: 10. Deadline: November.
255+
[ ] 3. Practice Martial Arts (2 Kunfu Style/month). Total: 8. Deadline: April.
256+
May:
257+
[ ] 1. Read Fiction Books (1 Books/month). Total: 10. Deadline: November.
258+
June:
259+
[ ] 1. Read Fiction Books (1 Books/month). Total: 10. Deadline: November.
260+
July:
261+
[ ] 1. Read Fiction Books (1 Books/month). Total: 10. Deadline: November.
262+
August:
263+
[ ] 1. Read Fiction Books (1 Books/month). Total: 10. Deadline: November.
264+
September:
265+
[ ] 1. Read Fiction Books (1 Books/month). Total: 10. Deadline: November.
266+
October:
267+
[ ] 1. Read Fiction Books (1 Books/month). Total: 10. Deadline: November.
268+
November:
269+
[ ] 1. Read Fiction Books (0 Books/month). Total: 10. Deadline: November.
270+
*/

0 commit comments

Comments
 (0)