¿Para qué sirve PSeInt?

PSeInt está pensado para asistir a los estudiantes que se inician en la construcción de programas o algoritmos computacionales. El pseudocódigo se suele utilizar como primer contacto para introducir conceptos básicos como el uso de estructuras de control, expresiones, variables, etc, sin tener que lidiar con las particularidades de la sintaxis de un lenguaje real. Este software pretende facilitarle al principiante la tarea de escribir algoritmos en este pseudolenguaje presentando un conjunto de ayudas y asistencias, y brindarle ademas algunas herramientas adicionales que le ayuden a encontrar errores y comprender la lógica de los algoritmos.

Características y Funcionalidades de PSeInt:
• • • Presenta herramientas de edición básicas para escribir algoritmos en pseudocodigo en español Permite la edición simultánea de múltiple algoritmos Presenta ayudas para la escritura o Autocompletado o Ayudas Emergentes o Plantillas de Comandos o Coloreado de Sintaxis o Indentado Inteligente Puede ejecutar los algoritmos escritos Permite ejecutar el algoritmo paso a paso controlando la velocidad e inspeccionando expresiones Puede confeccionar automáticamente la tabla de prueba de escritorio Determina y marca los errores de sintaxis y en tiempo de ejecución Genera diagramas de flujo a partir del algoritmo escrito Convierte el algoritmo de pseudocodigo a código C++ Ofrece un sistema de ayuda integrado acerca del pseudocódigo y el uso del programa (esta última, aún en construcción) Incluye un conjunto de ejemplos de diferentes niveles de dificultad Es multiplataforma (probado en Microsoft Windows y GNU/Linux) Es totalmente libre y gratuito (licencia GPL)

• • • • • • • • • •

El Pseudo-código

Las características del este pseudolenguaje fueron propuestas en 2001 por el responsable de la asignatura Fundamentos de Programación (Horacio Loyarte) de la carrera de Ingeniería Informática de la FICH-UNL. Las premisas son: • Sintaxis sencilla • Manejo de las estructuras básicas de control • Solo 3 tipos de datos básicos: numérico, caracter /cadenas de caracteres y lógico (verdadero-falso). • Estructuras de datos: arreglos Todo algoritmo en pseudocógido tiene la siguiente estructura general: Proceso SinTitulo accion 1; accion 1; . . . accion n; FinProceso Comienza con la palabra clave Proceso seguida del nombre del programa, luego le sigue una secuencia de instrucciones y finaliza con la palabra FinProceso. Una secuencia de instrucciones es una lista de una o más instrucciones, cada una terminada en punto y coma. Las acciones incluyen operaciones de entrada y salida, asignaciones de variables, condicionales si-entonces o de selección múltiple y/o lazos mientras, repetir o para.

Asignación
La instrucción de asignación permite almacenar un valor en una variable. <variable> <- <expresión> ; Al ejecutarse la asignación, primero se evalúa la expresión de la derecha y luego se asigna el resultado a la variable de la izquierda. El tipo de la variable y el de la expresión deben coincidir.

mostrará uno o más valores. Dimension <ident1> (<max11>.... Condicional Si-Entonces La secuencia de instrucciones ejecutadas por la instrucción Si-Entonces-Sino depende del valor de una condición lógica. <identM> (<maxM1>. Dado que puede incluir una o más expresiones... <variableN> . En ese caso.<max1N>).. o las instrucciones que le siguen al Sino si la condición es falsa. por lo tanto el comando leerá uno o más valores. Pueden incluirse una o más variables. . <exprN> . que al ser evaluada retorna Verdadero o Falso. La condición debe ser una expresión lógica.. <expr2> . Los N parámetros indican la cantidad de dimensiones y el valor máximo de cada una de ellas.... .<maxMN>) Es importante notar que es necesario definir un arreglo antes de utilizarlo. Dimensionamiento La instrucción Dimension permite definir un arreglo. Leer <variablel> ... separándolos con una coma (. La cantidad de dimensiones puede ser una o más.). . . Salidas La instrucción Escribir permite mostrar valores al ambiente.. <variable2> . Dimesion <identificador> (<maxl>.. Esta instrucción imprime al ambiente (en este caso en la pantalla) los valores obtenidos de evaluar N expresiones. Se pueden definir más de un arreglo en una misma instrucción. pero la cláusla Sino puede no estar.. .. Esta instrucción define un arreglo con el nombre indicado en <indentificador> y N dimensiones. La cláusula Entonces debe aparecer siempre. Si <condición> Entonces <instrucciones> Sino <instrucciones> FinSi Al ejecutarse esta instrucción. se evalúa la condición y se ejecutan las instrucciones que correspondan: las instrucciones que le siguen al Entonces si la condición es verdadera...<maxN>). y la máxima cantidad de elementos debe ser una expresión numérica positiva. Escribir <exprl> . si la condición es falsa no se ejecuta ninguna instrucción y la ejecución del programa continúa con la instrucción siguiente. Esta instrucción lee N valores desde el ambiente (en este caso el teclado) y los asigna a las N variables mencionadas. indicando sus dimensiones.Entradas La instrucción Leer permite ingresar información desde el ambiente...

Note que las instrucciones del cuerpo del ciclo pueden no ejecutarse nunca. dependiendo del valor almacenado en una variable de tipo numérico. Lazos Repetir La instrucción Repetir-Hasta Que ejecuta una secuencia de instrucciones hasta que la condición sea verdadera. Segun <variable> Hacer <número1>: <instrucciones> <número2>. dos puntos y una secuencia de instrucciones. las instrucciones del cuerpo del ciclo serán ejecutadas al menos una vez. dado que la condición se evalúa al final. denominada De Otro Modo. cuya secuencia de instrucciones asociada se ejecutará sólo si el valor almacenado en la variable no coincide con ninguna de las opciones anteriores. Opcionalmente. . la ejecución se repite. si es verdadera. el cuerpo del ciclo se ejecuta nuevamente y se vuelve a evaluar la condición.. Al ejecutarse. al ejecutar esta instrucción se produce un ciclo infinito.> De Otro Modo: <instrucciones> FinSegun Esta instrucción permite ejecutar opcionalmente varias acciones posibles.<número3>: <instrucciones> <. Mientras <condición> Hacer <instrucciones> FinMientras Al ejecutarse esta instrucción. a fin de evitar ciclos infinitos. Al finalizar la ejecución del cuerpo del ciclo se vuelve a evaluar la condición y. la secuencia de instrucciones que forma el cuerpo del ciclo se ejecuta una vez y luego se evalúa la condición. se evalúa el contenido de la variable y se ejecuta la secuencia de instrucciones asociada con dicho valor. Además. se ejecuta una vez la secuencia de instrucciones que forman el cuerpo del ciclo. la secuencia de instrucciones asociada se debe ejecutar cuando el valor de la variable es uno de esos números. Si la condición es falsa.Selección Multiple La secuencia de instrucciones ejecutada por una instrucción Segun depende del valor de una variable numérica. la condición es evaluada. Si la condición resulta verdadera. las instrucciones del cuerpo del ciclo deben contener alguna instrucción que modifique la o las variables involucradas en la condición. Cada opción está formada por uno o más números separados por comas. Si la condición siempre es verdadera.. A fin de evitarlo. si al evaluar por primera vez la condición resulta ser falsa. Estos pasos se repiten mientras la condición sea verdadera. se puede agregar una opción final. Esto se repite hasta que la condición sea verdadera. el cuerpo del ciclo debe contener alguna instrucción que modifique la o las variables involucradas en la condición de modo que en algún momento la condición sea verdadera y se finalice la ejecución del ciclo. Note que. Lazos Mientras La instrucción Mientras ejecuta una secuencia de instrucciones mientras una condición sea verdadera. Si una opción incluye varios números. de modo que ésta sea falsificada en algún momento y así finalice la ejecución del ciclo. Repetir <instrucciones> Hasta Que <condición> Al ejecutarse esta instrucción.

mediante el uso de la doble barra ( // ). la variable <variable> se incrementará en 1. hasta el fin de la línea. la variable <variable> recibe el valor <inicial> y se ejecuta la secuencia de instrucciones que forma el cuerpo del ciclo. • Note que no puede haber instrucciones fuera del programa. aunque puede alterarse mediante el uso de paréntesis. no será tomado en cuenta al interpretar el algoritmo. Si se omite la cláusula Con Paso <paso>. Todo lo que precede a //. Algebraicos + Suma * Multiplicación / División ^ Potenciación Ejemplo 3>2 'ABC'<'abc' 4=3 'a'<='b' 4>=5 (7>4) & (2=1) //falso (1=1 | 2=1) //verdadero ~(2<5) //falso La jerarquía de los operadores matemáticos es igual a la del álgebra. Para <variable> <. Algunas Observaciones . o en líneas separadas. | Disyunción (o). A continuación se listan las funciones integradas disponibles: Función RC(X) ABS(X) LN(X) EXP(X) SEN(X) COS(X) ATAN(X) Significado Raíz Cuadrada de X Valor Absoluto de X Logaritmo Natural de X Función Exponencial de X Seno de X Coseno de X Arcotangente de X TRUNC(X) Parte entera de X REDON(X) Entero más cercano a X • Se pueden introducir comentarios luego de una instrucción. Luego se incrementa la variable <variable> en <paso> unidades y se evalúa si el valor almacenado en <variable> superó al valor <final>.Lazos Para La instrucción Para ejecuta una secuencia de instrucciones un número determinado de veces. Si esto es falso se repite hasta que <variable> supere a <final>. Operadores y Funciones Este pseudolenguaje dispone de un conjunto básico de operadores y funciones que pueden ser utilizados para la construcción de expresiones más o menos complejas.<inicial> Hasta <final> ( Con Paso <paso> ) Hacer <instrucciones> FinPara Al ingresar al bloque. ~ Negación (no). aunque si comentarios. Las siguientes tablas exhiben la totalidad de los operadores de este lenguaje reducido: Operador Significado Relacionales > Mayor que < Menor que = Igual que <= Menor o igual que >= Mayor o igual que Lógicos & Conjunción (y).

o nombres de variables. verificando primero que lo sea mediante el teorema de Pitágoras. reales distintas. Leer num.11-intentos. FinMientras Si intentos=0 Entonces Escribir "El numero era: ". Ejemplos de algoritmos en PSeudoCodigo • • • • • • • • • AdivinaNumero: simple juego en el que hay que adivinar un nro aleatorio entre 1 y 100 en menos de 10 intentos. Sucursales: se obtienen datos acerca de las ventas de una empresa ingresando las cantidades vendidas por artículo y sucursal. Sino Escribir "Muy alto". • Los identificadores.• Las estructuras no secuenciales pueden anidarse. hasta colocarlos todos en la última torre. intentos <. comenzando siempre con una letra. Sino Escribir "Exacto! Usted adivino en ". calcular valor absoluto.psc Proceso Factorizacion Escribir "Ingrese el numero: ". Si num/2 = trunc(num/2) Entonces Escribir 2. pueden contener otras adentro. deben constar sólo de letras y números. • Las constantes lógicas son Verdadero y Falso. FinSi Escribir "Le quedan ". num_secreto <. determinar si es primo. Factorización: descompone un número en sus factores primos.azar(100)+1. Promedio: calcula el promedio de una lista de datos. Hanoi: juego de las torres de Hanoi. o complejas conjugadas). AdivinaNumero.psc // Juego simple que pide al usuario que adivine un numero en 10 intentos Proceso Adivina_Numero intentos<-9.intentos. Matematicas: presenta un menú que permite realizar diferentes operaciones matemáticas sobre un número (funciones trigonométricas. etc.". hallar la raíz cuadrada. ) es el separador decimal. Mientras num_secreto<>num_ingresado & intentos>0 Hacer Si num_secreto>num_ingresado Entonces Escribir "Muy bajo".intentos-1." intentos. Escribir "Adivine el numero (de 1 a 100):". considerando los tres casos (reales iguales. donde se deben mover discos entre tres torres cumpliendo ciertas limitaciones. • En las constantes numéricas. pero la estructura contenida debe comenzar y finalizar dentro de la contenedora. Mientras factorizar & num>1 hacer div<-0. Leer num_ingresado. truncar. Escribir "Factorizacion: ". junto con el listado de precios. OrdenaLista: ordena una lista de nombres alfabéticamente. ." intentos:". Resolvente: calcula e informa las raíces de una ecuación de cuadrática. Leer num_ingresado. • Las constantes de tipo carácter se escriben entre comillas ( " ). Triangulo: calcula el área de un triángulo rectángulo. factorizar<-verdadero. hallar el factorial. el punto ( .num_secreto. FinSi FinProceso Factorizacion.). Es decir.

j] Hacer // dibujar cada disco 1: escribir " XX".div+2. cada columna contiene nros que representan los tamanios de los discos en esas torres (solo interesan los valores hasta la cantidad de discos de esa torre). 3: escribir " XXXXXXXXXX". sino escribir div. Proceso Hanoi Dimension torres[3. factorizar<-falso.i]<-discos-i+1. sino para j<-cant_discos[i] hasta 1 con paso -1 Hacer //recorrer los discos de la torre. FinSi FinMientras Si factor_primo Entonces escribir num. // jugar! mientras (cant_discos[3]<>discos) Hacer //mientras no esten todos los discos en la tercer torre. // pedir y validar cuantos discos colocar en la primer torre Escribir "Ingrese el nro de discos (1-5):". Cuantos discos tiene cada torre lo dice el vector cant_discos. finmientras // inicializar los datos cant_discos[1]<-discos. 2: escribir " XXXXXX". finpara cant_movs<-0. FinSi FinSi FinMientras FinProceso Hanoi. Mientras div<=rc(num) & factor_primo Hacer div <. No se puede colocar un disco de // un tamanio sobre otro mas chico // // // // Hay una matriz que representa las torres. .Falso. escribir "Torre ". cant_discos[2]<-0. factor_primo<-verdadero. para i<-1 hasta discos hacer torres[1. de arriba hacia abajo segun torres[i. leer discos.i. el juego sigue para i<-1 hasta 3 Hacer // dibujar las tres torres escribir "". leer discos. Sino div<-1.num<-num/2. cant_discos[3].psc // El objetivo del juego es mover los discos de la torre 1 a la 3 en la // menor cantidad de movimientos posible. 4: escribir " XXXXXXXXXXXXXX". Si num/div = trunc(num/div) Entonces factor_primo <. factor_primo<-Verdadero. cant_discos[3]<-0.10]. num<-num/div. mientras discos<1 | discos>8 Hacer Escribir "El numero de discos debe ser mayor a 0 y menor a 5:". si cant_discos[i]=0 Entonces Escribir "".

torres[t2. escribir "". Escribir 'Ingresar Numero:'.cant_movs+1. si t1<0 | t1>3 | t2<0 | t2>3 Entonces // controlar que el nro de torre sea valido escribir "Movimiento invalido".5: escribir " XXXXXXXXXXXXXXXXXX". Escribir '3 . cant_discos[t1]<-cant_discos[t1]-1. si cant_discos[t2]<>0 entonces //controlar que la torre dos no tenga discos o tenga discos mas grandes si torres[t2.Seno. Escribir "hacia la torre: ". finsegun FinPara finsi Escribir " ----------------------------------".Raiz Cuadrada'. cant_discos[t2]<-cant_discos[t2]+1. Escribir '7 . 8: escribir " XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX". Funcion Exponencial'." movimientos!". sino si cant_discos[t1]=0 Entonces // controlar que la torre 1 tengo al menos un disco escribir "Movimiento invalido". finsi FinSi finsi finmientras // mostrar resultado escribir "".Lograritmo Natural. FinSi FinSi si puede_mover Entonces // si paso todos los controles.Hallar Factorial'. escribir "Juego finalizado en ". Escribir '6 . Escribir '1 . escribir "". Redondear'. Sino escribir "Movimiento invalido".disco_a_mover. 7: escribir " XXXXXXXXXXXXXXXXXXXXXXXXXX". ArcoTangente'.cant_discos[t2]] <. leer t1. Coseno. . leer t2.psc // Este ejemplo muestra el uso de expresiones.cant_discos[t2]]<disco_a_mover Entonces puede_mover<-Falso. escribir "".torres[t1. Escribir '2 . FinProceso Matematicas.Separar parte entera y decimal'. Escribir '4 .Valor Absoluto'. operadores y funciones matemáticas Proceso Matematicas Salir<-0. Sino disco_a_mover <. Escribir 'Presione Enter para continuar'. Repetir Escribir ' '. FinPara // solicitar movimiento Escribir "Mover desde la torre: ". // obtener tamanio del disco que se quiere mover puede_mover<-verdadero.cant_movs. 6: escribir " XXXXXXXXXXXXXXXXXXXXXX". mover cant_movs <. Leer x. Escribir '5 .Truncar. Leer N.cant_discos[t1]].

FinSi FinSi 8: Si N<>Trunc(N) Entonces Escribir 'El numero debe ser entero!'.Trunc(n). Sino r<-f*r. Si N/2=trunc(N/2) Entonces Primo<-'No'.Averiguar si es primo'. FinMientras Escribir 'Numero Primo:'. f<-3. FinSi f<-f+1. Escribir 'Coseno:'.rc(N). Sino Primo<-'Si'. 2: Si N<=0 Entonces Escribir 'El numero debe ser mayor a cero!'. Escribir ' '.exp(N).:'. sino Nu<-N.Cos(N). Escribir '9 .ln(N). 7: Si N<>Trunc(N) Entonces Escribir 'El numero debe ser entero!'. Mientras f<=Nu & Primo='Si' Hacer Si N/F=trunc(N/F) Entonces Primo<-'No'. Escribir '0 . FinMientras Escribir 'Factorial:'. Escribir 'ArcTangente:'.Sen(N). FinSi Si N<0 entonces Nu<-N*-1.n-Trunc(n).Ingresar Otro Numero'. Segun Opcion Hacer 1: Escribir 'Seno:'.:'. Mientras f<=abs(N) Hacer Si N<0 Entonces r<-(-f)*r.r. f<-1. Leer Opcion. Escribir ' '. Sino r<-1. FinSi f<-f+2. Escribir 'Parte Decimal:'. .Atan(N).para Salir'. Sino Escribir 'Log Nat.trunc(N).:'. Si f=3 Entonces F<-4.redon(N).abs(N).:'.Primo. Sino Si abs(N)>50 Entonces Escribir 'Resultado muy grande!'. FinSi 3: Escribir 'Turncar:'. Escribir 'Redondear:'.Escribir '8 . FinSi Nu<-RC(Nu). 6: Escribir 'Parte Entera:'. Escribir 'Func Expon. 5: Escribir 'Valor Abs. 4: Escribir 'Raiz Cuad.

Leer nombre.psc // Se ingresa una lista de nombres (la lista termina // cuando se ingresa un nombre en blanco) no permitiendo // ingresar repetidos y luego se ordena y muestra Proceso OrdenaLista Dimension lista[200]. Escribir "Ingrese los nombres (enter en blanco para terminar):".lista[i]. De Otro Modo: Escribir 'Opcion No Valida!'. FinPara FinProceso . FinSegun Hasta que Salir=1 FinProceso OrdenaLista. lista[pos_menor]<-aux.'x'.N/(f-2). Leer N. FinSi FinPara // intercambia el que estaba en i con el menor que encontro aux<-lista[i]. FinPara // mostrar como queda la lista Escribir "La lista ordenada es:".f-2. FinSi FinSi 9: Escribir 'Ingrese Numero:'. Para i<-1 Hasta cant Hacer Si nombre=lista[i] Entonces se_repite<-Verdadero. FinSi FinPara Hasta Que ~se_repite FinMientras // ordenar Para i<-1 Hasta cant-1 Hacer // busca el menor entre i y cant pos_menor<-i. lista[cant]<-nombre. Mientras nombre<>"" Hacer cant<-cant+1. se_repite<-Falso. Para i<-1 Hasta cant Hacer Escribir " ".FinSi Si Primo='No' Entonces Escribir N. lista[i]<-lista[pos_menor]. Repetir // leer un nombre y ver que no este ya en la lista Leer nombre. // leer la lista cant<-0.'='. 0: Salir<-1. Para j<-i+1 Hasta cant Hacer Si lista[j]<lista[pos_menor] Entonces pos_menor<-j.

Escribir "Raiz 2: "."i".psc // calcula las raices de una ecuacion de segundo grado Proceso Resolvente // cargar datos Escribir "Ingrese el coeficiente A:".r1. r2 <. Escribir "El promedio es: ".Promedio.preal.((-b)+rc(disc))/(2*a). Para i<-1 Hasta n Hacer Escribir "Ingrese el dato ".preal. acum<-acum+dato. Leer a. * La cantidad de articulos en la sucursal 2.r2. // determinar si son reales o imaginarias disc <.rc(-disc)/(2*a). Informar: * Las cantidades totales de cada articulo. Escribir "Raiz 2: ". Si disc<0 Entonces // si son imaginarias preal<. Escribir "Ingrese el coeficiente C:".r.pimag. Leer dato. Sino r1 <. Escribir "Raiz 1: ". FinProceso Resolvente. FinSi FinSi FinProceso Sucursales. Leer n. Leer b. * La cantidad del articulo 3 en la sucursal 1.":". Sino Si disc=0 Entonces // ver si son iguales o distintas r <."+".b^2-4*a*c.psc // Calcula el promedio de una lista de N datos Proceso Promedio Escribir "Ingrese la cantidad de datos:". Leer c. FinPara prom<-acum/n.(-b)/(2*a)."i". * La recaudación total de cada sucursal.(-b)/(2*a).((-b)-rc(disc))/(2*a). acum<-0."-". Escribir "Raiz 1 = Raiz 2: ". pimag<.pimag.prom. Escribir "Ingrese el coeficiente B:".i. Escribir "Raiz 1: ". .psc // Problema Ejemplo: // // // // // // Se ingresan los precios de 5 articulos y las cantidades vendidas por una empresa en sus 4 sucursales.

Cant[1. FinPara // Leer Cantidades Para J<-1 Hasta 4 Hacer Para I<-1 Hasta 5 Hacer Escribir 'Ingrese Cant. Para J<-1 Hasta 4 Hacer TotSuc<-0.// * La recaudación total de la empresa. NumMayor<-0. FinPara Escribir 'Total Sucursal 2:'.I.':'. // Informar Sucursal 1. determina // si corresponden (por Pitargoras) y en caso afirmativo // calcula el area Proceso TrianguloRectangulo // cargar datos Escribir "Ingrese el lado 1:". Leer l1.Suma.':'.I]*Prec[i]).J. Articulo 3: Escribir 'Sucursal 1. Cant[4.I]. // Leer Precios Para I<-1 Hasta 5 Hacer Escribir 'Ingrese Precio Articulo '.I. FinPara Escribir 'Recaudacion total de la empresa:'.'.':'. de Articulo '. en Sucursal '. Si TotSuc>MayorRec entonces MayorRec<-TotSuc. Para I<-1 Hasta 5 Hacer TotSuc<-TotSuc+(Cant[J.':'. // * La sucursal de mayor recaudación.I]. . FinPara // Informar Total de Articulos Sucursal 2 Suc2<-0.TotSuc. Leer Prec[I].J. // Acumular total de cada sucursal (TotSuc) y // total de la empresa (TotEmp) MayorRec<-0.NumMayor. NumMayor<-J. Escribir 'Total articulo '. Proceso Sucursales // Inicializar Prec=Arreglo de precios y Cant=Arreglo para cantidades Dimension Prec[5]. FinPara Escribir 'Recaudaciones Sucursal '.I]+Cant[3.I]. Articulo 3:'. Para I<-1 Hasta 5 Hacer Suma<-Cant[1. Para I<-1 Hasta 5 Hacer Suc2<-Suc2+Cant[2. FinPara FinPara // Sumar cantidades por articulos Escribir 'Cantidades por articulos:'.I]+Cant[2.I.psc // Lee los tres lados de un triangulo rectangulo. FinSi TotEmp<-TotEmp+TotSuc.5].3].TotEmp. TotEmp<-0. FinProceso Triangulo.I]+Cant[4. Escribir 'Sucursal de Mayor Recaudacion:'.Suc2. Leer Cant[J.

Escribir "Ingrese el lado 3:".". FinSi FinSi // ver si cumple con Pitagoras Si hip^2 = cat1^2 + cat2^2 Entonces // calcualar area area<-(cat1*cat2)/2. FinSi FinProceso . cat2<-l3. cat2<-l3. Si l2>l3 Entonces hip<-l2. Sino Escribir "No es un triangulo rectangulo. Si l1>l3 Entonces hip<-l1. Leer l2. cat2<-l1. FinSi Sino cat1<-l1.area. Leer l3. Sino hip<-l3.Escribir "Ingrese el lado 2:". Sino hip<-l3. cat2<-l2. // encontrar la hipotenusa (mayor lado) Si l1>l2 Entonces cat1<-l2. Escribir "El area es: ".

Sign up to vote on this title
UsefulNot useful