I have a problem and I think it's a PSeInt error, I'll tell you what happens...
I have created an algorithm (somewhat extensive), practically everything works ok, however I find a slight bug and it is that when exiting a single condition (Validate if the database is full) in a single thread (enter()), PSeInt it does not exit but after the line (EndSubProcess), it continues within the same process and returns 4 lines above, thus remaining within a "Repeat" cycle where it indicates the end of a registration process. It should be clarified that by giving it the correct option to exit this cycle, then there it does exit the Subprocess and go to the menu in the main process.
All other threads work fine for me even the same thread as long as it doesn't enter the conditional indicating that the database (Vector in this case) is full.
If anyone can check it out in their PSeInt and tell me if the same thing happens to them and maybe if there is a way to handle this event, I would really appreciate it. I will copy the code separated by threads since it is very long and it depends on all the sub-algorithms, that is why I do not copy only the error part.
MAIN ALGORITHM
Algoritmo tiendaComercial
Definir opciones, cantRegistros Como Entero;
Escribir "Defina cuantos registros que tendrá la base de datos.";
Leer cantRegistros;
Escribir "===== > Creando la base de datos. < =====";
Escribir "";
Dimension documento[cantRegistros], nombres[cantRegistros], saldo[cantRegistros], activo[cantRegistros];
Repetir
Limpiar Pantalla;
Escribir "************* MENÚ PRINCIPAL *************";
Escribir "===== > Seleccione una opción (Número). < =====";
Escribir "1. Consultar.";
Escribir "2. Ordenar de menor a mayor.";
Escribir "3. Eliminar.";
Escribir "4. Ingresar.";
Escribir "9. Terminar.";
Leer opciones;
Segun opciones
1:
consultar(documento, nombres, saldo, activo, cantRegistros);
2:
ordenar(documento, nombres, saldo, activo, cantRegistros);
3:
eliminar(documento, nombres, saldo, activo, cantRegistros);
4:
ingresar(documento, nombres, saldo, activo, cantRegistros);
9:
Escribir "Finalizando sesión...";
De Otro Modo:
Limpiar Pantalla;
Escribir "************* MENÚ PRINCIPAL *************";
Escribir "Opción no válida!, ingrese una opción válida...";
Esperar 2 Segundos;
FinSegun
Hasta Que opciones = 9
FinAlgoritmo
SUBALGORITHM FOR QUERYING RECORDS
//Creando Subproceso para consultar registros
SubProceso consultar (documento Por Referencia, nombres Por Referencia, saldo Por Referencia, activo Por Referencia, cantRegistros Por Valor)
Definir option, registro Como Entero;
Definir respuesta Como Logico;
Limpiar Pantalla;
Escribir "===== CONSULTANDO UN REGISTRO =====";
Escribir "Seleccione 1. Consultar por documento.";
Escribir "Seleccione 2. Listar todos los registros.";
Escribir "Seleccione 3. Salir.";
Leer option;
Escribir "";
Repetir
Segun option
1:
Escribir "Ingrese el documento a consultar";
Leer registro;
//Buscamos en los registros el documento ingresado
Para i = 0 Hasta cantRegistros-1 Con Paso 1 Hacer
si registro = documento[i] Entonces
respuesta = Verdadero;
FinSi
FinPara
// Verificamos si la búsqueda arrojó algun resultado
si respuesta = Verdadero Entonces
// Si lo encontró mostramos la información del registro
Para i = 0 Hasta cantRegistros-1 Con Paso 1 Hacer
si registro = documento[i] Entonces
Limpiar Pantalla;
Escribir "";
Escribir "===== CONSULTANDO UN REGISTRO =====";
Escribir "Documento: ", documento[i];
Escribir "Nombres: ", nombres[i];
Escribir "Saldo: $", saldo[i];
si activo[i] = "1" Entonces
Escribir "Activo: SI";
SiNo
Escribir "Activo: NO";
FinSi
Escribir "";
Escribir "Presione ENTER para regresar al menú principal";
Esperar Tecla;
FinSi
FinPara
SiNo
Repetir
// Si el registro no existe, informamos que no se encontró
Limpiar Pantalla;
Escribir "===== CONSULTANDO UN REGISTRO =====";
Escribir "Ooops!! Registro no encontrado ¿Desea registrarlo?";
Escribir "1. Si";
Escribir "2. No";
Leer option;
Segun option
1:
ingresar(documento, nombres, saldo, activo, cantRegistros);
2:
Limpiar Pantalla;
Escribir "===== CONSULTANDO UN REGISTRO =====";
Escribir "Saliendo del proceso de consulta...";
Esperar 2 Segundos;
De Otro Modo:
Escribir "Opción incorrecta! elige una opción válida...";
Esperar 2 Segundos;
FinSegun
Hasta Que option = 2
FinSi
option = 3;
2:
// Verificamos posiciones llenas en el vector
cantReg = disponibilidad (documento, cantRegistros);
si cantReg > 0 Entonces
Limpiar Pantalla;
Escribir "===== LISTANDO TODOS REGISTROS =====";
// Listamos todos los registros de la base datos
listar(documento, nombres, saldo, activo, cantReg);
Escribir "";
Escribir "Presione ENTER para continuar...";
Esperar Tecla;
option = 3;
SiNo
Limpiar Pantalla;
Escribir "===== LISTANDO TODOS REGISTROS =====";
Escribir "La base de datos está vacía!";
Escribir "";
Esperar 2 Segundos;
option = 3;
FinSi
3:
Escribir "Regresando al menú principal...";
Escribir "";
Esperar 2 Segundos;
De Otro Modo:
Limpiar Pantalla;
Escribir "===== LISTANDO TODOS REGISTROS =====";
Escribir "Opción incorrecta!, elige una opción válida...";
Escribir "";
Esperar 2 Segundos;
consultar(documento, nombres, saldo, activo, cantRegistros);
FinSegun
Hasta Que option = 3
FinSubProceso
SUBALGORITHM TO ENTER RECORDS
//Creando Subproceso para ingresar registros
SubProceso ingresar (documento Por Referencia, nombres Por Referencia, saldo Por Referencia, activo Por Referencia, cantRegistros Por Valor)
Definir option, indice, cantReg, nDocumento Como Entero;
Definir detener, dupliDocumento, dupliNombre, continuar Como Logico;
Definir nNombre Como Caracter;
continuar = Falso;
// Verificamos posiciones llenas en el vector
cantReg = disponibilidad (documento, cantRegistros);
si cantReg > 0 Entonces
indice = (cantReg + 1)-1;
SiNo
indice = 0;
FinSi
si cantReg = cantRegistros Entonces
Repetir
Limpiar Pantalla;
Escribir "===== CREANDO NUEVO REGISTRO =====";
Escribir "No hay espacios libres en la base de datos...";
Escribir "=== > ¿Desea eliminar un registro?.. ";
Escribir "1. Si";
Escribir "2. No";
Leer option;
segun option
1:
eliminar(documento, nombres, saldo, activo, cantRegistros);
2:
Escribir "Regresando al menú principal...";
Esperar 2 Segundos;
De Otro Modo:
Escribir "Opción no válida!, elige una opción válida...";
Esperar 2 Segundos;
FinSegun
Hasta Que option = 2;
FinSi
Si cantReg < cantRegistros Entonces
Repetir
Limpiar Pantalla;
Escribir "===== CREANDO NUEVO REGISTRO =====";
Repetir
Escribir "Escriba documento a registrar...";
Leer nDocumento;
dupliDocumento = validador(documento, nombres, cantRegistros, nDocumento, 1);
si dupliDocumento = Verdadero Entonces
Escribir "Este documento ya existe!...";
Escribir "";
continuar = Falso;
SiNo
Repetir
Escribir "Escriba el nombre del cliente...";
Leer nNombre;
dupliNombre = validador(documento, nombres, cantRegistros, nNombre, 2);
Si dupliNombre = Verdadero Entonces
Escribir "";
Escribir "Nombre ya existe con documento diferente, ¿desea registrarlo?.";
Escribir "Escriba 1. Si quiero registrarlo";
Escribir "Escriba 2. No quiero elegir otro nombre";
Leer option;
segun option
1:
continuar = Verdadero;
De Otro Modo:
continuar = Falso;
FinSegun
SiNo
continuar = Verdadero;
FinSi
Hasta Que continuar = Verdadero;
FinSi
Hasta Que continuar = Verdadero;
documento[indice] = nDocumento;
nombres[indice] = nNombre;
Escribir "Escriba el saldo del cliente...";
Leer saldo[indice];
Repetir
Escribir "¿Cliente activo? 1= SI 2= NO...";
Leer activo[indice];
Hasta Que activo[indice] = "2" o activo[indice] = "1"
ordenados(documento, nombres, saldo, activo, cantRegistros, 1);
Repetir
Limpiar Pantalla;
Escribir "===== REGISTRO EXITOSO =====";
Escribir "¿Desea agregar otro registro?.. 1 = SI, 2 = NO";
Leer option;
Segun option
1:
ingresar(documento, nombres, saldo, activo, cantRegistros);
2:
detener = Verdadero;
Escribir "Regresando al menú principal...";
Esperar 2 Segundos;
De Otro Modo:
Escribir "Opción incorrecta!, regresando al menú principal...";
Esperar 2 Segundos;
FinSegun
Hasta Que option =2;
Hasta Que detener = Verdadero;
FinSi
FinSubProceso
SUBALGORITHM TO DELETE RECORDS
//Creando Subproceso para eliminar registros
SubProceso eliminar (documento Por Referencia, nombres Por Referencia, saldo Por Referencia, activo Por Referencia, cantRegistros Por Valor)
Definir option, auxiliar, totalRegistros, cantReg Como Entero;
// Verificamos posiciones llenas en el vector
cantReg = disponibilidad (documento, cantRegistros);
Escribir "===== ELIMINAR UN REGISTRO =====";
Escribir "Actualmente estos son los registros de la base de datos, ¿Cual desea eliminar?...";
listar(documento, nombres, saldo, activo, cantReg);
Leer option;
si option-1 >= cantReg Entonces
Limpiar Pantalla;
Escribir "===== ELIMINAR UN REGISTRO =====";
Escribir "El registro a eliminar no existe!.. Regresando";
Esperar 2 Segundos;
SiNo
auxiliar = option;
Mientras auxiliar <= cantReg-1 Hacer
// Eliminando el registro
documento[option-1] = documento[auxiliar];
nombres[option-1] = nombres[auxiliar];
saldo[option-1] = saldo[auxiliar];
activo[option-1] = activo[auxiliar];
auxiliar = auxiliar+1;
Fin Mientras
documento[auxiliar-1] = 0;
nombres[auxiliar-1] = "";
saldo[auxiliar-1] = 0;
activo[auxiliar-1] = "";
// Reordenamos la lista de la base de datos
ordenados(documento, nombres, saldo, activo, cantRegistros, 1);
// Verificamos posiciones llenas en el vector
cantReg = disponibilidad (documento, cantRegistros);
Limpiar Pantalla;
// Mostramos los registros restantes
Escribir "===== Registro eliminado con éxito. =====";
Si cantReg > 0 Entonces
listar(documento, nombres, saldo, activo, cantReg);
Escribir "";
Escribir "Presione ENTER para salir";
Esperar Tecla;
SiNo
Escribir "¡URRAAA!.. La base de datos ahora está vacía!";
Escribir "";
Escribir "Presione ENTER para regresar al menú Principal";
Esperar Tecla;
FinSi
FinSi
FinSubProceso
SUBALGORITHM TO ESTABLISH AN ORDER IN THE RECORDS
//Creando Subproceso para ordenar los registros
SubProceso ordenar (documento Por Referencia, nombres Por Referencia, saldo Por Referencia, activo Por Referencia, cantRegistros Por Valor)
Definir orden, cantReg Como Entero;
// Verificamos posiciones llenas en el vector
cantReg = disponibilidad (documento, cantRegistros);
Si cantReg > 1 Entonces
Repetir
Limpiar Pantalla;
Escribir "===== Orden actual de la base de datos =====";
listar(documento, nombres, saldo, activo, cantReg);
Escribir "";
Escribir "Seleccione 1. Para ordenar de MENOR a MAYOR por Documento";
Escribir "Seleccione 2. Para ordenar de MAYOR a MENOR por Documento";
Leer orden;
Si orden < 1 o orden > 2 Entonces
Escribir "";
Escribir "Opción incorrecta!, elige una opción válida...";
Esperar 2 Segundos;
FinSi
Hasta Que orden <= 2
ordenados(documento, nombres, saldo, activo, cantRegistros, orden);
Escribir "";
Escribir "===== Base de datos Ordenada =====";
listar(documento, nombres, saldo, activo, cantReg);
Escribir "";
Escribir "Presione ENTER para volver al menú principal...";
Esperar Tecla;
SiNo
Si cantReg = 1 Entonces
Limpiar Pantalla;
Escribir "===== ORDENAR BASE DE DATOS =====";
listar(documento, nombres, saldo, activo, cantReg);
Escribir "";
Escribir "No hay suficientes registros para ordenar.";
Escribir "Presione ENTER para regresar al menú princial...";
Esperar Tecla;
SiNo
Limpiar Pantalla;
Escribir "===== ORDENAR BASE DE DATOS =====";
Escribir "Esta base de datos no tiene registros para ordenar...";
Esperar 2 Segundos;
FinSi
FinSi
FinSubProceso
SUBALGORITHM TO SORT RECORDS ACCORDING TO SENT ORDER
// Estableciendo orden general
SubProceso ordenados (documento Por Referencia, nombres Por Referencia, saldo Por Referencia, activo Por Referencia, cantRegistros Por Valor, nOrden Por Valor)
Definir cantReg Como Entero;
Segun nOrden
1:
// Ordeno de Mayor a menor segun la cantidad total de cupos
Para i=0 Hasta cantRegistros-1 Con Paso 1 Hacer
Para j=i+1 Hasta cantRegistros-1 Con Paso 1 Hacer
si documento[i] < documento[j] Entonces
//Ordenando los documentos
tmpDocumento = documento[i];
documento[i] = documento[j];
documento[j] = tmpDocumento;
//Ordenando los nombres
tmpNombre = nombres[i];
nombres[i] = nombres[j];
nombres[j] = tmpNombre;
//Ordenando los saldos
tmpSaldo = saldo[i];
saldo[i] = saldo[j];
saldo[j] = tmpSaldo;
//Ordenando los activos
tmpActivo = activo[i];
activo[i] = activo[j];
activo[j] = tmpActivo;
FinSi
FinPara
FinPara
// Verifico cuantos cupos hay llenos
cantReg = disponibilidad (documento, cantRegistros);
// Ordeno de Menor a Mayor unicamente los cupos que contienen datos en el vector
Para i=0 Hasta cantReg-1 Con Paso 1 Hacer
Para j=i+1 Hasta cantReg-1 Con Paso 1 Hacer
si documento[i] > documento[j] Entonces
//Ordenando los documentos
tmpDocumento = documento[i];
documento[i] = documento[j];
documento[j] = tmpDocumento;
//Ordenando los nombres
tmpNombre = nombres[i];
nombres[i] = nombres[j];
nombres[j] = tmpNombre;
//Ordenando los saldos
tmpSaldo = saldo[i];
saldo[i] = saldo[j];
saldo[j] = tmpSaldo;
//Ordenando los activos
tmpActivo = activo[i];
activo[i] = activo[j];
activo[j] = tmpActivo;
FinSi
FinPara
FinPara
2:
// Ordeno de Mayor a menor segun la cantidad total de cupos
Para i=0 Hasta cantRegistros-1 Con Paso 1 Hacer
Para j=i+1 Hasta cantRegistros-1 Con Paso 1 Hacer
si documento[i] < documento[j] Entonces
//Ordenando los documentos
tmpDocumento = documento[i];
documento[i] = documento[j];
documento[j] = tmpDocumento;
//Ordenando los nombres
tmpNombre = nombres[i];
nombres[i] = nombres[j];
nombres[j] = tmpNombre;
//Ordenando los saldos
tmpSaldo = saldo[i];
saldo[i] = saldo[j];
saldo[j] = tmpSaldo;
//Ordenando los activos
tmpActivo = activo[i];
activo[i] = activo[j];
activo[j] = tmpActivo;
FinSi
FinPara
FinPara
FinSegun
FinSubProceso
SUBALGORITHM FOR COUNTING RECORDS IN THE VECTOR
// Creamos función para contar las posiciones llenas en el vector
Funcion totalRegistros <- disponibilidad (documento Por Referencia, cantRegistros Por Valor)
// Verificamos posiciones llenas en el vector
Para i=0 hasta cantRegistros-1 Con Paso 1 Hacer
si documento[i] <> 0 Entonces
totalRegistros = totalRegistros+1;
FinSi
FinPara
FinFuncion
SUBALGORITHM TO LIST THE RECORDS OF THE VECTORS
// Proceso para listar todos los registros de la base de datos
SubProceso listar (documento Por Referencia, nombres Por Referencia, saldo Por Referencia, activo Por Referencia, cantRegistros Por Valor)
Para i=0 Hasta cantRegistros-1 Con Paso 1 Hacer
si activo[i] = "1" Entonces
Escribir i+1,". Documento: ", documento[i], ", Nombre: ", nombres[i], ", Saldo: ", saldo[i], ", ¿Activo?: SI";
SiNo
Escribir i+1,". Documento: ", documento[i], ", Nombre: ", nombres[i], ", Saldo: ", saldo[i], ", ¿Activo?: NO";
FinSi
FinPara
FinSubProceso
SUBALGORITMO PARA VALIDAR REGISTROS DUPLICADOS
Funcion duplicado <- validador (documento Por Referencia, nombres Por Referencia, cantRegistros Por Valor, regValidar Por Valor, vectorValidar Por Valor)
Segun vectorValidar
1:
Para i=0 Hasta cantRegistros-1 Con Paso 1 Hacer
si regValidar = documento[i] Entonces
duplicado = Verdadero;
FinSi
FinPara
2:
Para i=0 Hasta cantRegistros-1 Con Paso 1 Hacer
si regValidar = nombres[i] Entonces
duplicado = Verdadero;
FinSi
FinPara
FinSegun
FinFuncion
Desde ya, gracias por tomarte el tiempo de revisarlo y decirme si te sucede el mismo fallo que me presenta.
RECUERDA: El fallo es cuando intentas hacer un nuevo registro estando los vectores llenos, puedes establecer un tamaño de vector de 1 elementos, registrarlo e intentar registrar de nuevo otro, te dirá que la base de datos está llena y te pregunta si quieres eliminar 1 registro, al indicar la opción 2, justo ahí es cuando no se sale del subproceso y se devuelve a la línea que indico al inicio de la pregunta.
Adjunto algunas capturas que describen la falla.
1.Muestra cuando llega al final del Subproceso
2.Muestra la línea a la que salta sin salir del subproceso
3.Muestra el ciclo en el que queda luego de fallar la salida del subproceso
No es un bug en pseint, sino un error en cómo interpreta lo que ocurre en el paso a paso. Invoca por primera vez a la función "ingresar" desde el menú; y luego cuando pregunta si hay que ingresar otro y el usuario dice que sí, la función se invoca nuevamente a sí misma (linea 238 según su captura de pantalla). Entonces, la 1er invocación queda en esa linea a la espera de que se resuelva la 2da. Cuando dice que la ejecución vuelve 4 lineas para atrás, lo que ocurre en realidad es que termina la ejecución de la 2da llamada a ingresar y retorna a la 1ra (y allí la instrucción que sigue es el finsegun).
Por otro lado, para reportar un error es buena práctica tratar de reducir el código a la mínima expresión posible donde se manifieste, para facilitar su reproducción y depuración.
Pensé en esta solución que funciona, pero continúo creyendo que PSeInt presenta fallas, ya que he realizado pruebas y el error se puede omitir pero sigue estando...
SOLUCIÓN PARCIAL Hice el proceso para mostrar el menú en un subalgoritmo aparte, le pasé los vectores como parámetros incluyendo el tamaño de los mismos, luego he llamado al subproceso en cada una de las partes de los demás subprocesos donde requiero regresar al menú principal, de esta manera evitaría el bache o la falla que me estaba presentando al salir de determinado subproceso y regresar al algoritmo principal. Así ha quedado.
SUBALGORITMO PARA MOSTRAR EL MENU PRINCIPAL
En la siguiente parte observamos como hago uso de este nuevo subalgoritmo en la parte donde se me presentaba el error, y es que cuando se iba a ingresar un nuevo registro en los vectores pero el mismo no tenía índices vacíos, nos dice que la base de datos está llena y nos sugiere eliminar un registro, si la opción era 2, entonces no se salía del subproceso, sino que retornaba dentro del mismo 4 líneas de código quedando en dentro de un ciclo que al dar nuevamente la opción 2 entonces si se salía del subproceso.
Con la solución lo que hago es invocar directamente el subproceso al que quiero regresar.
USO DEL SUBALGORITMO PARA MOSTRAR EL MENU PRINCIPAL
EL ERROR PERSISTE Luego de invocar el subalgoritmo para mostrar el menú principal después de ir desde de la línea de código donde estaba el error, al presionar en este caso la opción 9. si que sale del subalgoritmo
menuPrincipal()
pero me regresa al mismo subalgoritmo anterioringresar()
y se puede evidenciar de nuevo la falla.