miércoles, 27 de enero de 2021

Mi primera infografía ¿o infograma?

La infografía es la ciencia que trata acerca de los infogramas. Y un infograma es un diagrama visual que resume o explica figurativamente informaciones o textos, empleando más variados medios visuales e incluso auditivos que el mero esquema o diagrama. Pero he notado que a veces se usa la palabra “Infografía” como sinónimo de “infograma”.

De todas formas he tenido la experiencia de crear mi primer infograma a partir de una herramienta en línea llamada Canva. En el pasado sí había usado muchas representaciones visuales pero este es el primer Infograma propiamente dicho.



viernes, 8 de enero de 2021

Los Miserables.

Había escuchado alguna vez un resumen de esta obra literaria en Mi novela favorita. En aquella ocasión no logró llamar mi atención. Pasado el tiempo, por casualidad encontré en un servicio de streaming la pelicula-musical del año 2012 y los primeros segundos fueron como un puñetazo en la cara con la escena de los reos remolcando el barco. De ahí en adelante me quedé enganchado hasta verla por completa.

Decididamente me emocioné. Investigué y encontré que es una novela de la cual se han hecho un sin fin de adaptaciones en la televisión, el cine y como musical. En YouTube se pueden encontrar varios musicales en español como este.

Finalmente, escuché la obra completa en audio-libro y me encantó. Es larga, pero por lo general me mantuvo atento, tuve algunas gratas sorpresas y a veces me conmoví hasta casi soltar una lagrimita. La escena donde se describe a Cossette de niña en la posada de los Thenardier me partió el corazón. Sin embargo, hubo dos escenas en donde se requiere discreción por su contenido un poco fuerte para los más pequeños: La caida de Fantine y la toma de la barricada. Pero en general, me gustó.

miércoles, 6 de enero de 2021

Intérprete para Logo

Hace ya varios años desarrollé un rústico interprete para el lenguaje de programación Logo. Lo bueno es que funciona. Lo malo es que usa demasiados recursos del sistema ya que se abusa de la recursividad. Hay que tener en cuenta que este programa lo creé cuando estaba mucho más crudo en programación. Para evitar tener que usar la recursividad se pueden usar pilas.

Las instrucciones que reconoce el interprete son las siguientes:

TO Marca el inicio de la función / archivo
END Marca el fin de la función / archivo
IF [condición] Ejecuta la linea si la condición se cumple.
FD [pasos] Fordward. Avanza la cantidad de pasos.
BK [pasos] Back. Retrocede la cantidad de pasos.
LT [grados] Left. Gira a la izquierda una cantidad de grados.
RT [grados] Right. Gira a la derecha una cantidad de grados.
CC [radio] Dibuja una circunferencia de acuerdo al radio
[archivo/función] Invoca una función / archivo
BYE Sale de la aplicación.

El programa llama el codigo fuente de logo que se encuentra almacenado en archivos. Los archivos no tienen extensiones. los siguientes los usé para probar el interprete:


El siguiente ejemplo pinta un cuadro en la pantalla. Se debe invocar como cuadro desde la pantalla.

CUADRO
TO :L
FD :L
RT 90
FD :L
RT 90
FD :L
RT 90
FD :L
END

Otro ejemplo más robusto de lo que puede ejecutar este interprete se llama copo y dibuja una imagen fractal de un copo de nieve . Nótese que es una función recursiva.

COPO
TO :T
IF ( :T > 2 ) FD :T , COPO ( :T / 2 ), BK :T , RT 60
IF ( :T > 2 ) FD :T , COPO ( :T / 3 ), BK :T , RT 60
IF ( :T > 2 ) FD :T , COPO ( :T / 3 ), BK :T , RT 60
IF ( :T > 2 ) FD :T , COPO ( :T / 2 ), BK :T , RT 60
IF ( :T > 2 ) FD :T , COPO ( :T / 3 ), BK :T , RT 60
IF ( :T > 2 ) FD :T , COPO ( :T / 3 ), BK :T , RT 60
END

Para ejecutarlo habría que escribir desde la aplicación lo siguiente: copo [valor del parámetro]; por ejemplo escribir copo 100.

Fotografía del resultado de ejecutar el archivo copo que muestra un copo de nieve generado de forma recursiva. ¿Por que no se usó una captura de pantalla? Porque el programa no lo permitió o más bien no se encontró la forma de dejarse capturar un pantallazo que hubiese sido más nitido. 

El siguiente es el código fuente del interprete. Fue creado en Borland C++ y requiere la librería grafica para funcionar por consiguiente requiere acceso al driver correspondiente de la carpeta bgi.

logo.cpp
#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <math.h>

#define ANCHOLINEA 100
#define ALTO 20

struct { char nombre[30];
	 char variable[30];
	 int tope;
	 char M[ALTO][ANCHOLINEA];
	 } bloque;

// declaraci¢n de las funciones
int ejecutalinea(char c[]);
int buscaarchivo(char archivo[]);
int ejecutaarchivo(char archivo[], char param[]);
void cambiar(char linea[],char variable[], char param[]);
void operar(char linea[]);
void haceroperacion(char c[]);
int estavacio(char c[]);
int hacerif(char c[]);
int determinarsi(char comp[]);
int ejecutabloque(char param[]);
int buscabloque(char c[]);


// variables globales
float or;
float xmax, ymax,cx,cy,fx,fy;
char error[400];

void main(void)
{
   int gdriver = DETECT, gmode, errorcode;
   char c1[ANCHOLINEA];
   or=90;
   initgraph(&gdriver, &gmode, "\\borlandc\\bgi");
   errorcode = graphresult();
   if (errorcode != grOk)
   {  printf("Error: %s\n", grapherrormsg(errorcode));
      getch();
      exit(1); }
   xmax = getmaxx();
   ymax = getmaxy();
   cx = xmax/2+50;
   cy = ymax/2;
   outtextxy(5,5," ::Bienvenido a LOGO:: ");
   do
   {
    strcpy(error,"");
    gotoxy(3,2);
    setviewport(5,15,280,100,1);  //estas instrucciones
    clearviewport();             //borran un pedazo
    setviewport(0,0,xmax,ymax,1);//de la pantalla
    printf(">> ");
    gets(c1);
    if (!ejecutalinea(c1))
     {
     printf(" %s\n Presione una tecla",error);
     getch();
     }
   }while((strcmp(c1,"BYE")!=0));
   closegraph();
}/* main */



int ejecutalinea( char c[])
{
   char c1[ANCHOLINEA],p2[ANCHOLINEA];
   float c2;
   int j=0,i=0;
   strupr(c);
   if (estavacio(c)) return 1;
   while ( c[i]!= ' ' && i<=strlen(c) && c[i]!= 10 && c[i]!= 13)
     {
     c1[i]=c[i];
     i++;
     }
   c1[i]=0;
   i++;
   while (i<=strlen(c))
    {
    p2[j]=c[i];
    i++;
    j++;
    }
   p2[j]=0;
   if (strcmp(c1,"BYE")==0) return (1);
   if (strcmp(c1,"IF")==0)
       return (hacerif(p2));
   else
     if (strcmp(c1,"FD")==0)
    	{
    	c2 = atof(p2);
    	fy = cy - (sin(M_PI * or / 180 ) * c2);  // se usan las funciones sin() y cos() para calcular los nuevos puntos de acuerdo a la orientacion y el avance
    	fx = cx + (cos(M_PI* or / 180 ) * c2);  // sin() y cos() trabajan en radianes no en grados es necesario convertir
    	line(cx,cy,fx,fy); // se dibuja el avance con una linea
    	cx = fx;
    	cy = fy;
    	}
     else
       if (strcmp(c1,"BK")==0)
        	{
        	c2 = atof(p2);
        	fy = cy + (sin(M_PI * or / 180 ) * c2);  // se usan las funciones sin() y cos() para calcular los nuevos puntos de acuerdo a la orientacion y el avance
        	fx = cx - (cos(M_PI* or / 180 ) * c2);  // sin() y cos() trabajan en radianes no en grados es necesario convertir
        	line(cx,cy,fx,fy); // se dibuja el avance con una linea
        	cx = fx;
        	cy = fy;
        	}
       else
	 if (strcmp(c1,"LT")==0)
	    {
	    c2 = atof(p2);
	    or = or+c2;
	    }
	 else
	   if (strcmp(c1,"CC")==0)
	    {
	    c2 = atof(p2);
	    circle(cx,cy,c2);
	    }
	   else
	    if (strcmp(c1,"RT")==0)
	     {
	     c2 = atof(p2);
	     or = or-c2;
	     }
	    else
	       if (buscabloque(c1))
		  {
		  return (ejecutabloque(p2));
		  }
	       else
		 if (buscaarchivo(c1))
		    {
		    return (ejecutaarchivo(c1,p2));
		    }
		 else
		    {
		    strcat(error,"\n No se reconoce este comando: ");
		    strcat(error,c1);
		    return(0);
		    }
return(1);
}


int buscaarchivo(char archivo[])
{
FILE *ma;
if ((ma = fopen(archivo, "r+")) == NULL)
   {
   strcat(error,"\n No se encuentra este archivo: ");
   strcat(error,archivo);
   return 0;
   }
fclose(ma);
return 1;
}


int ejecutaarchivo(char archivo[], char param[])
  {
  int i;
  FILE *in;
  char encabezado[ANCHOLINEA],variable[ANCHOLINEA];
  char M[ALTO][ANCHOLINEA];
  int res,j,l,tope=0;
  in = fopen(archivo, "r+");
  if (in == NULL) return (0);
  fgets(encabezado,sizeof(encabezado),in);
  j=0;
  for (i=3;i<strlen(encabezado);i++)
     {
     variable[j]=encabezado[i];
     j++;
     }
  variable[j-1]=0;
  strcpy(bloque.nombre,archivo);
  strcpy(bloque.variable,variable);
  do {
     fgets(M[tope],sizeof(M[tope]),in);
     if (!feof(in))
        {
        l = strlen(M[tope]);
        M[tope][l-1]=0;
        strcpy(bloque.M[tope],M[tope]);
        cambiar(M[tope],variable,param);
        operar(M[tope]);
        tope++;
        }
    } while (!feof(in));
  fclose(in);
  bloque.tope = tope;
  i=0;
  do {
      if ((strcmp(M[i],"END ")!=0)&&(strcmp(M[i],"END")!=0))
        {
        res = ejecutalinea(M[i]);
        }
      i++;
     } while ((i<tope)&&(res));
  if (!res)
     {
     strcat(error,"\n Error en : [");
     strcat(error,M[i-1]);
     strcat(error,"]");
     }
  return(res);
}


void cambiar(char linea[],char variable[], char param[])
{  int i,j,k;
   char linres[ANCHOLINEA];
   char temp[ANCHOLINEA];
   k=0;
   strcat(linea," ");
   for(i=0;i<=strlen(linea);i++)
     {
     if (linea[i]==':')
      	{
      	j=0;
      	while(((linea[i]!= ' ')&&(i<=strlen(linea)))&&(linea[i]!= ')') && (linea[i]!= EOF) )
      	   {
      	     temp[j]=linea[i];
      	     linea[i]= ' ';
      	     i++;
      	     j++;
      	   }
      	temp[j]=0;
      	if (strcmp(temp,variable)==0)
      		{
      		for(j=0;j< strlen(param);j++)
      		  {
      		  linres[k]=param[j];
      		  k++;
      		  }
      		linres[k]=0;
      		}
      	}
     else
        {
        linres[k] = linea[i];
        k++;
        }
    }
   linres[k]=0;
   strcpy(linea,linres);
}


void operar(char linea[])
  {  
  int i,j,k;
  char linres[ANCHOLINEA];
  char operacion[ANCHOLINEA];
  k=0;
  for(i=0;i<=strlen(linea);i++)
     {
     if (linea[i]=='(')
      	{
      	j=0;
      	i++;
      	while((linea[i]!= ')')&&(i<=strlen(linea)))
      	   {
      	     operacion[j]=linea[i];
      	     linea[i]= ' ';
      	     i++;
      	     j++;
      	   }
      	operacion[j]=0;
      	linea[i]=' ';
      	haceroperacion(operacion);
      	for(j=0;j< strlen(operacion);j++)
      	  {
      	  linres[k]=operacion[j];
      	  k++;
      	  }
      	}
     linres[k] = linea[i];
     k++;
    }
  strcpy(linea,linres);
}


void haceroperacion(char c[])
  {
   char c1[ANCHOLINEA];
   char c2[ANCHOLINEA];
   char c3[ANCHOLINEA];
   char signo;
   int j=0,i=0;
   int num1,num2,res=0;
   while ((((c[i]!= '+')&&(c[i]!='-'))&&((c[i]!= '*')&&(c[i]!= '/')))&&i<=strlen(c))
     {
     c1[i]=c[i];
     i++;
     }
   if (! (i<=strlen(c)))
    	{
    	strcpy(c3,"( ");
    	strcat(c3,c);
    	strcat(c3," )");
    	strcpy(c,c3);
    	return;
    	}
   signo = c[i];
   c1[i]=0;
   i++;
   while (i<=strlen(c))
      {
      c2[j]=c[i];
      i++;
      j++;
      }
   c2[j]=0;
   num1 = atoi(c1);
   num2 = atoi(c2);
   switch(signo)
     {
     case '+':res = num1 + num2;
  	    break;
     case '-':res = num1 - num2;
  	    break;
     case '*':res = num1 * num2;
  	    break;
     case '/':if (num2 != 0)
  		 res = num1 / num2;
  	    else
  		 {
  		 strcpy(c,"NaN"); // Not a Number
  		 return;
  		 }
  	    break;
     }
   itoa(res,c,10);
}


int estavacio(char c[])
{
int i;
for(i=0;i<strlen(c);i++)
   {
   if (c[i] !=' ') return 0;
   }
return 1;
}


int hacerif(char c[])
  {
   char c1[ANCHOLINEA],p2[ANCHOLINEA];
   char M[ALTO][ANCHOLINEA];
   int tope,res=0;
   int j=0,i=1;

   while ( c[i]!= ')' && i<=strlen(c) )
     {
     c1[i-1]=c[i];
     i++;
     }
   c1[i]=0;
   i+=3;
   while (i<=strlen(c))
      {
      p2[j]=c[i];
      i++;
      j++;
      }
   p2[j]=0;
   j=0;
   if (determinarsi(c1))
      {
      tope = 0;
      for(i=0;i<=strlen(p2);i++)
      	{
      	if (p2[i] == ',')
      	    {
      	    tope++;
      	    j=0;
      	    i++;
      	    }
      	else
      	    {
      	    M[tope][j]=p2[i];
      	    j++;
      	    M[tope][j]=0;
      	    }
      	}
	tope++;
	i=0;
	do {
	  res = ejecutalinea(M[i]);
	  i++;
	}while ((i<tope)&&(res));
	if (!res)
	   {
	   strcat(error,"\n Error en : [");
	   strcat(error,M[i-1]);
	   strcat(error,"]");
	   }
      }
      else
	 res = 1;
return(res);
}


int determinarsi(char c[])
{
   char c1[ANCHOLINEA];
   char c2[ANCHOLINEA];
   char oper[3];
   int j=0,i=0;
   int num1,num2,ret=0;
   while ( c[i]!= '>' && c[i]!='<' && c[i]!= '=' && i<=strlen(c))
     {
     c1[i]=c[i];
     i++;
     }
   c1[i]=0;
   oper[0] = c[i];
   i++;
   oper[1] = c[i];
   oper[2] = 0;
   i++;
   while (i<=strlen(c))
    {
    c2[j]=c[i];
    i++;
    j++;
    }
   c2[j]=0;
   num1 = atoi(c1);
   num2 = atoi(c2);
   if (strcmp(oper,"> ")==0)
	    if (num1 > num2)
		 ret = 1;
	    else
		 ret = 0;
   else
   if (strcmp(oper,"< ")==0)
	    if (num1 < num2)
		 ret = 1;
	    else
		 ret = 0;
   else
   if (strcmp(oper,"= ")==0)
	    if (num1 == num2)
		 ret = 1;
	    else
		 ret = 0;
   else
   if (strcmp(oper,">=")==0)
	    if (num1 >= num2)
		 ret = 1;
	    else
		 ret = 0;
   else
   if (strcmp(oper,"<=")==0)
	    if (num1 == num2)
		 ret = 1;
	    else
		 ret = 0;
return ret;
}


int buscabloque(char c[])
{
int ret=0;
if (strcmp(c,bloque.nombre)==0)
     {
     ret = 1;
     }
return (ret);
}


int ejecutabloque(char param[])
{
char M[ALTO][ANCHOLINEA];
int i=0,res=0;
do {
  strcpy(M[i],bloque.M[i]);
  cambiar(M[i],bloque.variable,param);
  operar(M[i]);
  res = ejecutalinea(M[i]);
  i++;
}while ((i< bloque.tope)&&(res));
  if (!res)
     {
     strcat(error,"\n Error en : [");
     strcat(error,M[i-1]);
     strcat(error,"]");
     }
return(res);
}

lunes, 4 de enero de 2021

Obras literarias que han pasado por mi vida

Estas son obras de la literatura, libros, publicaciones que recuerdo haber leido completas. Anoto la impresión que me ha producido cada una de ellas.

  • Cien años de soledad. Leida de principio a fin cuando era un adolescente. Me parece que el personaje principal es Ursula. Trata del ascenso y caida del linaje Buendía. Es interesante la descripción que hace del entorno y las costumbres de antaño de la zona caribe. Y, por supuesto, es una ejemplo de una obra perteneciente al realismo mágico. Al lector de esta obra debe tener en cuenta el lenguaje que algunas veces se usa y algunas escenas bastante fuertes.
  • Alguien desordena estas Rosas. La parte que más me gustó, desde el punto de vista literario, es esta: 

"Yo estaba cubierto de polvo y telaraña cuando ella abrió la puerta y en alguna parte de la habitación guardó silencio el grillo que había estado cantando durante veinte años."

  • La idea que da vueltas. Otro cuento de Gabriel García Marquez.
  • Crónica de una muerte anunciada. Esta novela tiene una película. Siempre quedaré con la duda si Santiago Nazar fue culpable o no. Según la pelicula si lo era, pero el libro no lo deja claro. Nuevamente, el lenguaje puede ser bastante altisonante y la descripción de la muerte bastante gráfica.
  • El coronel no tiene quie le escriba. Me parece que esta es la novela más triste y desesperanzadoras del autor.
  • La increíble y triste historia de la Cándida Eréndira y de su abuela desalmada. El título lo dice todo. Misma anotación en cuanto a lenguaje y descripciones.
  • Los funerales de la mamá grande. Otro cuento corto con descripciones costumbristas.

Llegado a este punto me estoy sorprendiendo de todas la literatura de este autor que leí durante mi juventud. Sin embargo, no es un autor favorito debido al lenguaje usado, a las descripciones y a la misma temáticas. Pero no niego que desde un punto de vista estrictamente literario es un excelente autor.

  • Otro de esos autores que leí en mi juventud: Edgar allan Poe. Aunque literariamente fue muy bueno ocurre algo parecido que con el anterior. Recuerdo que pensé que tuvo que estar loco. El hundimiento de la casa Husher, El Cuervo, El corazón delator  Las aventuras de Arthur Gordon Pym.
    • Cuentos de la selva. Horacio Quiroga. Siempre pensé que un Yacaré era una especie de cocodrilo. No estaba tan mal: Es una especie de caimán. (La guerra de los yacarés).
    • María. Jorge Isaac. Esta novela me enseño lo que es una garúa.
    • Las aventuras de Alicia en el país de las maravillas. Lewis Carroll.

    • La cabaña del tío Tom. Novela de Harriet Beecher Stowe. Después de leer la novela fue una grata sorpresa enterarme que Harriet Beecher Stowe fue una mujer.
    • Manual de Automoviles. Manuel Arias Paz. Es que una vez quise ser mecánico. 
    • La divina comedia. Dante Alighieri. Que lo haya leido todo no significa que esté de acuerdo con su contenido.
    • la Odisea. Homero. Una de las primeras lecturas sobre aventuras.
    • Lazarillo de Tormes. Anónimo.
    • La isla del tesoro. Novela de Robert Louis Stevenson. 
    • Las aventuras de Tom Sawyer.  Mark Twain.
    • Las aventuras de Huckleberry Finn. Mark Twain.
    • La vuelta al mundo en ochenta días.  Julio Verne.
    • Crimen y Castigo. Fedor Dostoiewski. Un lento descenso hacia la mente de un asesino. Lamento haberla leído.
    • Orgullo y prejuicio. Jane Austen. Creo que es la novela más hermosa que he leído.
    • Sentido y sensibilidad. Jane Austen.  
    • Don Quijote de la Mancha (Parte I y II). Miguel de Cervantes. Para ser honesto no la leí directamente y creo que mi paciencia no habría dado para tanto. La primera parte la escuché en audiolibro y la segunda la escuche en forma de resumen - analisis.
    • La Biblia. La mejor de todas.

    miércoles, 23 de diciembre de 2020

    Colorear código fuente en una página HTML

    Siento verguenza al ver la forma como se muestra el código fuente en la anotación sobre las multas de tránsito. Pero ya me he reivindicado en la anotación sobre la calculadora cientifica en donde se muestra el código fuente de una manera más estética y profesional.

    Para colorear el código fuente se ha usado la información del sitio web: https://www.tecnoblog.guru/2015/02/resalta-el-codigo-fuente-de-tu-web.html

    En la sección HEAD del documento HTML agregar la siguiente línea. (En el caso de blog hay que ir y modificar el código HTML del Tema).

    <script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js?autoload=true&amp;skin=sunburst" defer="defer"></script>
    

    Luego, es necesario incluir el código a resaltar dentro de la etiqueta PRE

    <pre class="prettyprint">
    Este es el código fuente a colorear
    </pre>
    

    Algo importante: hay que reemplazar todos los < por &lt; y los > por &gt; para no tener inconvenientes en la visualización.

    La plantilla que se muestra es: sunburst pero hay otras: default, sons-of-obsidian, desert y doxy.

    sábado, 19 de diciembre de 2020

    Lenguaje C: Calculadora didáctica

    Uno de los proyectos que ha sobrevivido hasta ahora y que recoje lo que se puede hacer en lenguaje C es el llamado calculadora didáctica que consiste en tomar una expresión matematica en forma de texto, como por ejemplo:  34  * 2 / ( 4 - 2) y mostrar el resultado. 

    Para ello se usa un analizador sintactico que funciona de esta manera: la expresión se pasa de infijo a postfijo y luego se evalúa usando una pila para dar un resultado. Pero para hacer todo esto se vale de listas enlazadas simples que se usan para almacenar la expresión. La pila se implementa bajo una lista enlazada simple. 

    El programa pretende mostrar lo que ocurre cuando la calculadora está realizando el proceso. Así que muestra la expresión en infijo y en posfijo, tal como está implementada en la lista enlazada, tambien muestra el contenido de la pila mientras se evalua la expresión y, por supuesto, muestra el resultado.

    Como se puede ver, es un programa en modo texto o consola, al estilo de los programas que se hacian para DOS. Inicialmente fue creado para ser compilado Borland C++. El siguiente código fue ajustado para ser compilado en Dev C++. 

    Los ajustes tienen que ver con algunas funciones de las librerías conio.h y dos.h que por no ser librerías estandar no se incluyen en Dev C++. Hubo que prescindir del color y reemplazar unas funciones por otras:

    • La función iraxy() se declara e implementa en el código y reemplaza a la función gotoxy().  
    • La función Sleep() reemplaza a la función delay().
    • La función system("cls") reemplaza a clrscr();

    El programa aún tiene los siguientes bugs:

    1. Cuando se evalúa una expresión los resultados parciales se van guardando en una variable tipo entera pero cuando se realizan divisiones se obtienen valores decimales o el valor es muy grande y se desborda y ocasionando error en el resultado. Es mejor usar variables de tipo float o double para este proceso.
    2. No se realiza una validación de lo que se ingresa. Si se ingresa un valor diferente a número o a los signos +, -, *, /, ( o) lo más probable es que el programa estalle.

    El siguiente es el codigo fuente. Recordar que este código está escrito en C y que la extensión del archivo debe ser "c". 


    calculadora.c

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    #include <windows.h>
    
    /* Estructuras de datos usadas para los nodos y  la  lista enlazada simple. */
    typedef struct ListaNodo
      {
      char info[30];
      struct ListaNodo *sig;
      }TNodo,*pListaNodo;
    
    typedef struct
      {
      pListaNodo primero, ventana;
      int longitud;
      } TLista, *Lista;
    
    /* Declaración de las funciones para el manejo de la lista enlazada simple */
    Lista inicLista (void);
    void anxLista(Lista lst, char elem[]);
    void elimLista(Lista lst);
    void primLista(Lista lst);
    void sigLista(Lista lst);
    void ultLista(Lista lst);
    void posLista(Lista lst,int pos);
    void infoLista(Lista lst,char s[]);
    int longLista(Lista lst);
    int finLista(Lista lst);
    void destruirLista(Lista lst);
    void insLista(Lista lst, char elem[]);
    void mostrarpos(Lista pos);
    
    /* Declaración de la función que pasa la la expresion de la lista de infijo a postfijo */
    Lista infijo_a_posfijo (Lista L);
    
    /* Evalua la expresión */
    int eval(Lista exp);
    
    /* declaración de un apuntador global al comienzo de pila */
    typedef Lista Pila;
    
    /* Declaracion de las funciones de pilas */
    Pila InicPila(void);
    void AdicPila(Pila Pil, char elem[]);
    void ElimPila(Pila Pil);
    void InfoPila(Pila Pil, char s[]);
    int VaciaPila(Pila Pil);
    void DestruirPila(Pila Pil);
    
    /* declaración de función que muestra el contenido de la pila */
    void mostrarpila(Pila P);
    
    /* Declaración de función que pasa de string a la lista */
    Lista char2list( char s[]);
    
    /* Declaración de la función que dibuja un cuadro en la pantalla de acuerdo aunas corrdenadas */
    void CC(int C1,int F1, int C2, int F2);
    
    /* Declaración de una función que dibuja un cuadro externo en la pantalla */
    void incuadro ();
    
    /* Declaración de la función que reemplaza a gotoxy() */
    void iraxy(int x,int y);
    
    /* SECCIÓN DE IMPLEMENTACIÓN DE LAS FUNCIONES ANTES DECLARADAS */
    
    /* Funciones para el manejo de la lista enlazada simple */
    Lista inicLista(void)
      {
      Lista nuevaLista;
      nuevaLista = malloc(sizeof(TLista));
      nuevaLista->primero=NULL;
      nuevaLista->ventana=NULL;
      nuevaLista->longitud=0;
      return (nuevaLista);
      }
    
    void anxLista(Lista lst, char elem[])
      {
      pListaNodo nuevoNodo;
      nuevoNodo = malloc(sizeof(TNodo));
      strcpy(nuevoNodo->info,elem);
      nuevoNodo->sig = NULL;
      if (lst->primero==NULL)
        lst->primero = nuevoNodo;
      else
        {
        nuevoNodo->sig = lst->ventana->sig;
        lst->ventana->sig = nuevoNodo;
        }
      lst->longitud++;
      lst->ventana=nuevoNodo;
      }
    
    void insLista(Lista lst, char elem[])
      {
      pListaNodo nuevoNodo, p;
      nuevoNodo = malloc(sizeof(TNodo));
      strcpy(nuevoNodo->info,elem);
      nuevoNodo->sig = NULL;
      if (lst->primero==NULL)
        lst->primero=nuevoNodo;
      else
        if (lst->primero==lst->ventana)
          {
          nuevoNodo->sig = lst->primero;
          lst->primero =nuevoNodo;
          }
        else
          {
          p=lst->primero;
          while(p->sig!=lst->ventana)
    	p=p->sig;
          nuevoNodo->sig = lst->ventana;
          p->sig=nuevoNodo;
          }
      lst->longitud++;
      lst->ventana = nuevoNodo;
      }
    
    void elimLista(Lista lst)
      {
      pListaNodo p;
      if (lst->ventana == lst->primero)
        {
        lst->primero = lst->primero->sig;
        free(lst->ventana);
        lst->ventana=lst->primero;
        }
      else
        {
        p=lst->primero;
        while(p->sig!=lst->ventana)
          p=p->sig;
        p->sig =lst->ventana->sig;
        free(lst->ventana);
        if(p->sig==NULL) /* ¿el ultimo nodo fue el eliminado?*/
          lst->ventana = p;
        else
          lst->ventana=p->sig;
        }
      lst->longitud--;
      }
    
    void primLista(Lista lst)
      {
      lst->ventana = lst->primero;
      }
    
    void sigLista(Lista lst)
      {
      if (lst->ventana!=NULL)
        lst->ventana = lst->ventana->sig;
      }
    
    void ultLista(Lista lst)
      {
      int l;
      l= longLista(lst);
      posLista(lst,l);
      }
    
    void posLista(Lista lst,int pos)
      {
      pListaNodo p;
      int i;
      if (lst->longitud >0)
        {
        i=1;
        p=lst->primero;
        while((i<pos)&&(p!=NULL))
          {
          p=p->sig;
          i++;
          }
        if((i==pos)&&(p!=NULL))
          lst->ventana =p;
        }
      }
    
    void infoLista(Lista lst,char s[])
      {
      strcpy(s,lst->ventana->info);
      }
    
    int longLista(Lista lst)
      {
      return(lst->longitud);
      }
    
    int finLista(Lista lst)
      {
      if (lst->ventana==NULL)
        return 1;
      else
        return 0;
      }
    
    void destruirLista(Lista lst)
      {
      primLista(lst);
      while(!finLista(lst))
        elimLista(lst);
      }
    
    /* Funciones para el manejo de la Pila */
    
    Pila InicPila(void)
    	     {
    	      return inicLista();
    	     }
    
    void AdicPila(Pila Pil, char elem[])
    	     {
    	      primLista(Pil);
    	      insLista(Pil, elem);
    	     }
    
    void ElimPila(Pila Pil)
    	     {
    	      primLista(Pil);
    	      elimLista(Pil);
    	     }
    
    void InfoPila(Pila Pil,char s[])
    	      {
    	       primLista(Pil);
    	       infoLista(Pil,s);
    	      }
    
    int VaciaPila(Pila Pil)
    	     {
    	      return longLista(Pil)==0;
    	     }
    
    void DestruirPila(Pila Pil)
    		 {
    		  destruirLista(Pil);
    		 }
    
    /* Pasa de string a una lista enlazada simple */
    Lista char2list( char s[])
    {
    Lista L;
    int i=0,largo;
    char dato[30],linea[20];
    L = inicLista();
    largo = strlen(s);
    do  {
      if (s[i]!=32){
        if (strchr(")(",s[i]))
           {
           dato[0]=s[i];
           dato[1]='\0';
           anxLista(L,dato);
           i++;
           }
        else
           if (strchr("+-*/^",s[i]))
    	  {
    	  dato[0]=s[i];
    	  dato[1]='\0';
    	  anxLista(L,dato);
    	  i++;
    	  }
           else
    	  {
    	  strcpy(linea,"");
    	  while(!(strchr("+-*/()",s[i]))&&(i<largo))
    	    {
    	     dato[0]=s[i];
    	     dato[1]='\0';
    	     strcat(linea,dato);
    	     i++;
    	     }
    	     anxLista(L,linea);
    	  }
       }
       else
         i++;
        }while(i<largo);
    return (L);
    }
    
    /* Pasa de infijo a posfijo */
    Lista infijo_a_posfijo (Lista L)
    {
     char x[20],elem[20];
     int i;
     Pila Pil;
     Lista Pos;
     Pil = InicPila();
     Pos = inicLista();
     for(primLista(L);!finLista(L);sigLista(L))
        {
    		mostrarpila(Pil);
    		mostrarpos( Pos);
    		Sleep(1000);
    		infoLista(L,x);
    		if (isdigit(x[0])) // Si es operando
    		{
    		ultLista(Pos);
    		anxLista(Pos,x);
    		infoLista(Pos,x);
    		}
    		else
    		{
    		    switch (x[0])
    		    {
    			// Los parentesis abiertos siempre se apilan
    			case '(':
    			    AdicPila(Pil,x);
    			    break;
    			// Los parentesis cerrados desapilan todos los elementos
    			// hasta encontrar un parentesis abierto.
    			case ')':
    			    do {
    				InfoPila(Pil,x);
    				if (x[0]!= '(')
    				    {
    				    ultLista(Pos);
    				    anxLista(Pos,x);
    				     }
    				ElimPila(Pil);
    			    }while ((x[0] != '('));     //&& (!VaciaPila(Pil))) ;
    
    			    break;
    			case '+':
    			case '-':
    			case '*':
    			case '/':
    			    AdicPila(Pil,x);
    			    break;
    		    }
    		}
        }
        while (!VaciaPila(Pil))
        {
    	InfoPila(Pil,x);
    	ElimPila(Pil);
    	ultLista(Pos);
    	anxLista(Pos,x);
    	mostrarpila(Pil);
    	mostrarpos( Pos);
    	Sleep(1000);
        }
    return Pos;
    }
    
    /* Evalúa la expresión */
    int eval(Lista L)
    {
    char elem[20],res[20];
    int op1,op2;
    char cop1[20], cop2[20];
    Pila Pos=InicPila();
    for(primLista(L);!finLista(L);sigLista(L))
    {
    	infoLista(L,elem);
    	if(isdigit(elem[0]))
    		AdicPila(Pos, elem);
    	else{
    		InfoPila(Pos,cop1);
    		ElimPila(Pos);
    		InfoPila(Pos,cop2);
    		ElimPila(Pos);
    		op1=atoi(cop1);
    		op2=atoi(cop2);
    		switch (elem[0]){
    		case '+': itoa( op1+op2,res,10);
    			  AdicPila(Pos,res);
    		break;
    		case '-': itoa( op2-op1,res,10);
    			  AdicPila(Pos,res);
    		break;
    		case '*': itoa( op1*op2,res,10);
    			  AdicPila(Pos,res);
    		break;
    		case '/': itoa( op2/op1,res,10);
    			  AdicPila(Pos,res);
    		break;
    		}
    	}
    	mostrarpila(Pos);
    	Sleep(500);
    }
    InfoPila(Pos,res);
    return atoi(res);
    }
    
    /* Función que muestra el contenido de la pila */
    void mostrarpila(Pila P)
    {
    int i,col=40,fila =25;
    char elem[20];
    iraxy(col-2,14);
    printf("Pila:");
    iraxy(col-3,24);printf("ÀÄÄÄÄÄÙ");
    for (i=15;i<=23;i++) {
      iraxy(col-3,i); printf("³     ³");}
    for (primLista(P);!finLista(P);sigLista(P))
      {
      infoLista(P,elem);
      iraxy(col,fila-2);
      printf("%s",elem);
      fila--;
      }
    }
    
    /* Muestra en orden Postfijo */
    void mostrarpos(Lista p)
    {
    char elem[20];
    iraxy(2,8);printf("   ORDEN POSTFIJA");
    iraxy(2,10);
    for(primLista(p);!finLista(p);sigLista(p))
    	{
    	infoLista(p,elem);
    	printf("[");
    	printf("%s",elem);
    	printf("]->");
    	}
    printf(" ² \n \n");
    }
    
    /* Dibuja un cuadro alrededor de la pantalla */
     void incuadro ()
     {
     system("cls");
     CC(1,1,75,25);
      }
    
    /* Dibuja un cuadrado de acuerdo a unas coordenadas dadas
      Se llama CC porque antes dibujaba un Cuadro con Color */
     void CC( int C1,int F1, int C2, int F2)
     {
     int C1AUM,C2DIS,F1AUM,F2DIS,I;
     C1AUM=C1+1;
     C2DIS=C2-1;
     F1AUM=F1+1;
     F2DIS=F2-1;
     iraxy(C1,F1);printf("Ú");
     iraxy(C1,F2);printf("À");
     iraxy(C2,F1);printf("¿");
     iraxy(C2,F2);printf("Ù");
     for (I=C1AUM;I<=C2DIS;I++) { iraxy(I,F1);printf("Ä");
    			     iraxy(I,F2);printf("Ä"); }
     for (I=F1AUM;I<=F2DIS;I++) { iraxy(C1,I);printf("³");
    			     iraxy(C2,I);printf("³"); }
     }
    
    /* Equivale a la función gotoxy() */
    void iraxy(int x,int y){
          HANDLE hcon;
          hcon = GetStdHandle(STD_OUTPUT_HANDLE);
          COORD dwPos;
          dwPos.X = x;
          dwPos.Y= y;
          SetConsoleCursorPosition(hcon,dwPos);
     }
    
    void main(void)
    {
    Lista l,p;
    char exp[30],elem[20];
    int resul,respuesta;
    do{
    	system("cls");
    	incuadro ();
    	iraxy(2,2);
    	printf("    Escriba la Expresion Use +-*/^() y numeros :  ");
    	gets(exp);
    	l= inicLista();
    	l = char2list(exp);
    	iraxy(2,4); printf("    ORDEN INFIJA \n ");
    	iraxy(2,6);
    	for(primLista(l);!finLista(l);sigLista(l))
    		{
    		infoLista(l,elem);
    		printf("[");
    		printf("%s",elem);
    		printf("]->");
    		Sleep(500);
    		}
    	printf(" ²\n \n");
    	p=infijo_a_posfijo (l);
    	resul= eval(p);
    	iraxy(8,16);
    	printf("resultado: %d",resul);
    	iraxy(4,22);
    	printf(" desea continuar S/N?");
    	respuesta=getch();
    } while((respuesta =='s')||(respuesta =='S'));
    
    }
    
    
    

    jueves, 17 de diciembre de 2020

    Software que ha pasado por mi vida

    En el año 1997 obtuve mi certificado como operador y programador de computadores luego de realizar un curso técnico por módulos. Mi intención era inicialmente aprender a manejar un computador ya que sospechaba que en el futuro sería necesario tener esa habilidad en cualquier trabajo. Al día de hoy quisiera hacer un recorrido por el software que he podido manejar durante estos veintitrés años de andar por el mundo de la computación. Solo coloco dos categorías y dejo por fuera otras como la Ofimática con sus procesadores de texto y gestores de hojas de cálculo.


    SISTEMAS OPERATIVOS


    • La generación de sistemas operativos de Microsoft lo resumiría así:
      • DOS .... El papá de los pollitos ... Bueno
      • Windows 95 ... Primer sistema operativo de entorno gráfico de Microsoft ... Bueno
      • Windows 98 ... Tuvo problemas ... Malo
      • Windows 98 SE (Segunda Edición) Bueno
      • Windows Millenium ... Le decían Malenium ... Malo
      • Windows NT ... Para redes y empresas ... Bueno
      • Windows XP  ... Bueno
      • Windows Vista ... Malo
      • Windows 7 ... Bueno
      • Windows 8 y 8.1 ... Malos
      • Windows 10 ... Bueno

    • El sistema operativo Unix ´puro´ solo lo vi una vez en vivo instalado en un servidor del SENA en una visita guiada.

    • El sistema operativo GNU/Linux ha tenido una larga evolución desde sus inicios y su historia es fascinante. Las distribuciones de este sistema son variadas aunque solo he usado las siguientes:
      • Red Hat ... Sombrero rojo.
      • Ubuntu ... Lo más cerca a un entorno Windows.
      • Knoppix ... Aún lo uso para mantenimiento de computadores en su versión de Live CD (en USB)

    • El sistema operativo Macintosh (Mac) es una especie rara y escurridiza pero no imposible de admirar.

    • Finalmente, el hijo de Linux, el que hizo lo que su papá no pudo: Android. Este sistema operativo ha logrado ser el principal sistema operativo de los Smartphone actuales.



    LENGUAJES DE PROGRAMACIÓN, SISTEMAS MANEJADORES DE BASE DE DATOS Y PROGRAMAS SIMILARES.


    • FoxPro fue el primer lenguaje de programación y gestor de base de datos que manejé. Ejecutaba en DOS y luego en Windows. Es primo hermano de DBase y Clipper. Evolucionó en Visual FoxPro. Estuve muy encariñado con este lenguaje. Me parece que hoy día casi nadie lo usa.

    • Lenguaje C. Este lenguaje fue el segundo lenguaje con el que me encariñé. Provee la sintaxis que usan muchos lenguajes actuales. Su versión orientada a objetos es C++. El compilador preferido fue Borland C que ejecutaba en DOS. Luego, cuando los entornos con ventana estuvieron de moda surgieron algunas versiones como Visual C++ pero perdió su atractivo para mí por tener una estructura muy compleja.

    • Basic es un lenguaje de programación con una historia interesante. La versión más usada fue QBASIC que funcionaba en DOS. Actualmente Microsoft es su propietario. El lenguaje evolucionó en Visual Basic y de allí se integró a la tecnología .NET. Existe una versión llamada Visual Basic Script que añadía interactividad a las páginas Web y digo que añadía porque hace rato no escucho nada de él. Microsoft Office tiene integrada en sus programas una versión llamada Visual Basic para aplicaciones con la que se crean macros, por ejemplo, en Excel o Word. Finalmente, Access implementa una versión de Basic para sus formularios y reportes.

    • Logo es un lenguaje que se usaba hace muchos años para aprender geometría. Un lenguaje especial y tristemente olvidado. Fue el único lenguaje al que logré hacerle un pequeño intérprete con algunas variaciones en la sintaxis. 

    • Pascal es un lenguaje para el entorno académico. Tuvimos una relación tormentosa de amor - conveniencia (Lo aprendí solo para pasar una asignatura). Borland Pascal corría en DOS. Pascal evolucionó en DELPHI, una versión para entornos de ventanas.

    • ProLog o programación lógica. Es un lenguaje de programación que aprendí con el fin crear un sistema experto. ProLog, al igual que otros lenguajes, evolucionó para un entorno con ventanas: Visual ProLog. Pero creo que Visual ProLog pierde la esencia de su antecesor.

    • Turbo Assembler (TASM) y Macro Assembler (MASM) son los dos ensambladores usados para programar los procesadores 286 y 386.

    • HTML es un lenguaje de marcado de Hipertexto con el que se crean las páginas web. A este lenguaje lo acompaña JavaScript que es propiamente un lenguaje de programación que se usa para añadir interactividad a las páginas Web (Después me enteré que tambien se usa del lado del servidor) y finalmente, para el diseño de las páginas se usa CSS  que es un lenguaje de diagramación para páginas web. Estos tres son amigos íntimos.

    • SQL es un lenguaje no procedimental que usan actualmente la mayoría de los sistemas gestores o manejadores de base de datos.

    • MySQL es un sistema gestor de base de datos usado mucho actualmente a la hora de crear aplicaciones Web.

    • Java. Este lenguaje de programación tiene una sintaxis derivada de C. Se puede crear casi cualquier cosa con él. El mejor IDE (Entorno de desarrollo integrado) para trabajar Java, a mi parecer es NetBeans.
      • Aplicaciones Stand-Alone. Aplicación típica para ejecutarse en el computador con ventanas o solo en modo texto.
      • Applets. Un programa visual que se incrusta en una página web.
      • Midlets. Una aplicación para dispositivos móviles que soporten java.
      • Servlets. Una aplicación que se ejecuta del lado del servidor. Se usa para crear aplicaciones Web. Necesita un contenedor de Servlets como Apache TomCat.

    • MatLab significa Laboratorio de matrices, es básicamente un entorno complejo para realizar simulaciones y gráficos matemáticos, entre otros.

    • PHP es mi lenguaje actual. Permite crear aplicaciones cliente -servidor haciendo uso de MySQL, generando código HTML de manera dinámica.

    • AppInventor es un entorno desarrollado por el MIT para crear aplicaciones para dispositivos Android. A mi parecer es la forma más fácil de hacerlo aunque hay otras opciones.  


    lunes, 14 de diciembre de 2020

    Solución al problema de las multas mediante un Algoritmo

     PROBLEMA PRINCIPAL

    En la Secretaría de Tránsito de la ciudad requieren de un ingeniero en formación como usted para que diseñe un algoritmo que permita registrar los datos de cada una de las multas por infracciones de tránsito que han sido generadas. Existe actualmente cuatro tipos infracciones a saber:

    • Tipo A: Sancionado con multa equivalente a cuatro (4) salarios mínimos legales diarios vigentes, es decir, $117.040

    • Tipo B: Sancionado con multa equivalente a ocho (8) salarios mínimos legales diarios vigentes, es decir, $234.080

    • Tipo C: Sancionado con multa equivalente a quince (15) salarios mínimos legales diarios vigentes, es decir, $438.900

    • Tipo D: Sancionado con multa equivalente a treinta (30) salarios mínimos legales diarios vigentes, es decir, $877.800

    El algoritmo principal (o proceso) deberá leer la cantidad de multas a registrar, y, posteriormente, por cada multa la cédula del infractor y el tipo de multa, y deberá imprimir el valor que debe pagar. Así mismo, deberá acumular la cantidad de multas por cada tipo de infracción existente.

    De otra parte, una vez se han registrado todas las multas, es necesario que el algoritmo calcule los siguientes resultados haciendo uso de llamado a funciones:

    • El valor total en pesos que la Secretaría de Tránsito va a percibir por todas las multas registradas. 

    • El tipo de infracción más cometida. En caso de igualdad se mostrará la primera encontrada.


    DESARROLLO DE LA SOLUCIÓN

    Estrategia: Resolver un problema grande y dificil dividiendolo en varios problemas más pequeños y más sencillos. A cada solución de un problema pequeño se va integrando una nueva solución.

    Problema 1: Leer la cantidad de multas a registrar y luego, procesarlas una a una.

    Problema 2: Por cada multa, capturar la cédula del infractor y el tipo de multa

    Problema 3: Por cada multa, Calcular lo que debe pagar de acuerdo a al tipo de multa 

    Problema 4: Por cada multa, imprimir el valor que debe pagar.

    Problema 5: Calcular y mostrar al final El valor total en pesos que la Secretaría de Tránsito va a percibir por todas las multas registradas.

    Problema 6: Contar la cantidad de multas por cada tipo de infracción existente. 

    Problema 7: Calcular al final El tipo de infracción más cometida. En caso de igualdad se mostrará la primera encontrada.


    Solución al problema 1:

    Problema 1: Leer la cantidad de multas a registrar y luego, procesarlas una a una.

    Método: Uso de un Para para hacer un Ciclo.


    Algoritmo multas

    Escribir "Indica la cantidad de multas a procesar: "

    Leer cantidad_multas 

    para i<- 1 hasta cantidad_multas Con Paso 1 Hacer

    FinPara

    FinAlgoritmo


    Solucion a los problemas 1 y 2:

    Problema 2: Por cada multa, capturar la cédula del infractor y el tipo de multa

    Método: Uso de Escribir y Leer


    Algoritmo multas

    Escribir "Indica la cantidad de multas a procesar: "

    Leer cantidad_multas

    para i<- 1 hasta cantidad_multas 

    Escribir "Diga la cedula del infractor: "

    Leer cedula

    Escribir "Diga el tipo de infracción "

    Leer tipo

    FinPara

    FinAlgoritmo


    Solucion a los problemas 1, 2 y 3:

    Problema 3: Por cada multa, Calcular lo que debe pagar de acuerdo a al tipo de multa.

    Método: Uso de preguntas (SI) anidadas.


    Algoritmo multas

    Escribir "Indica la cantidad de multas a procesar: "

    Leer cantidad_multas

    Para i <- 1 Hasta cantidad_multas Con Paso 1 Hacer

    Escribir "Diga la cedula del infractor: "

    Leer cedula

    Escribir "Diga el tipo de infracción "

    Leer tipo

    valor = 0

    Si tipo = "A" Entonces

    valor = 117040

    SiNo

    Si tipo = "B" Entonces

    valor = 234080

    SiNo

    Si tipo = "C" Entonces

    valor = 438900

    SiNo

    Si tipo = "D" Entonces

    valor = 877800

    Fin Si

    Fin Si

    Fin Si

    Fin Si

    Fin Para

    FinAlgoritmo


    Solución a los problemas 1, 2, 3 y 4:

    Problema 4: Por cada multa, imprimir el valor que debe pagar.

    Método: Uso de Escribir para mostrar texto y variables.


    Algoritmo multas

    Escribir "Indica la cantidad de multas a procesar: "

    Leer cantidad_multas

    Para i <- 1 Hasta cantidad_multas Con Paso 1 Hacer

    Escribir "Diga la cedula del infractor: "

    Leer cedula

    Escribir "Diga el tipo de infracción "

    Leer tipo

    valor = 0

    Si tipo = "A" Entonces

    valor = 117040

    SiNo

    Si tipo = "B" Entonces

    valor = 234080

    SiNo

    Si tipo = "C" Entonces

    valor = 438900

    SiNo

    Si tipo = "D" Entonces

    valor = 877800

    Fin Si

    Fin Si

    Fin Si

    Fin Si

    Escribir "El usuario con cedula ", cedula , " debe pagar por valor de multa: $",valor

    Fin Para

    FinAlgoritmo


    Solución a los problemas 1, 2, 3, 4 y 5:

    Problema 5: Calcular y mostrar al final El valor total en pesos que la Secretaría de Tránsito va a percibir por todas las multas registradas.

    Método: Uso de la variable acumuladora Total.

    Algoritmo multas

    Escribir "Indica la cantidad de multas a procesar: "

    Leer cantidad_multas

            Total = 0

    Para i <- 1 Hasta cantidad_multas Con Paso 1 Hacer

    Escribir "Diga la cedula del infractor: "

    Leer cedula

    Escribir "Diga el tipo de infracción "

    Leer tipo

    valor = 0

    Si tipo = "A" Entonces

    valor = 117040

    SiNo

    Si tipo = "B" Entonces

    valor = 234080

    SiNo

    Si tipo = "C" Entonces

    valor = 438900

    SiNo

    Si tipo = "D" Entonces

    valor = 877800

    Fin Si

    Fin Si

    Fin Si

    Fin Si

    Total = Total + valor

    Escribir "El usuario con cedula ", cedula , " debe pagar por valor de multa: $",valor

    Fin Para

    Escribir "El valor total que se recibe por todas las multas es: $", Total

    FinAlgoritmo


    Solución a los problemas 1, 2, 3, 4, 5 y 6:

    Problema 6: Contar la cantidad de multas por cada tipo de infracción existente. 

    Método: Uso de variables contadoras.


    Algoritmo multas

    Escribir "Indica la cantidad de multas a procesar: "

    Leer cantidad_multas

    Total = 0

    cant_A = 0

    cant_B = 0

    cant_C = 0

    cant_D = 0

    Para i <- 1 Hasta cantidad_multas Con Paso 1 Hacer

    Escribir "Diga la cedula del infractor: "

    Leer cedula

    Escribir "Diga el tipo de infracción "

    Leer tipo

    valor = 0

    Si tipo = "A" Entonces

    valor = 117040

    cant_A = cant_A +1

    SiNo

    Si tipo = "B" Entonces

    valor = 234080

    cant_B = cant_B +1

    SiNo

    Si tipo = "C" Entonces

    valor = 438900

    cant_C = cant_C +1

    SiNo

    Si tipo = "D" Entonces

    valor = 877800

    cant_D = cant_D +1

    Fin Si

    Fin Si

    Fin Si

    Fin Si

    Total = Total + valor

    Escribir "El usuario con cedula ", cedula , " debe pagar por valor de multa: $",valor

    Fin Para

    Escribir "El valor total de las multas es: $", Total

    FinAlgoritmo


    Solución a los problemas 1, 2, 3, 4, 5, 6  y 7:

    Problema 7: Calcular al final El tipo de infracción más cometida. En caso de igualdad se mostrará la primera encontrada.

    Método: Subdividir este problema en dos:

    Problema 7.1 : Averiguar si hay cantidades iguales.

    Problema 7.2 : Si no hay cantidades iguales, calcular el valor más alto.


    Solución a los problemas 1, 2, 3, 4, 5, 6 y 7.1

    Método: Uso de preguntas anidadas y operadores booleanos.


    Algoritmo multas

    Escribir "Indica la cantidad de multas a procesar: "

    Leer cantidad_multas

    Total = 0

    cant_A = 0

    cant_B = 0

    cant_C = 0

    cant_D = 0

    Para i <- 1 Hasta cantidad_multas Con Paso 1 Hacer

    Escribir "Diga la cedula del infractor: "

    Leer cedula

    Escribir "Diga el tipo de infracción "

    Leer tipo

    valor = 0

    Si tipo = "A" Entonces

    valor = 117040

    cant_A = cant_A +1

    SiNo

    Si tipo = "B" Entonces

    valor = 234080

    cant_B = cant_B +1

    SiNo

    Si tipo = "C" Entonces

    valor = 438900

    cant_C = cant_C +1

    SiNo

    Si tipo = "D" Entonces

    valor = 877800

    cant_D = cant_D +1

    Fin Si

    Fin Si

    Fin Si

    Fin Si

    Total = Total + valor

    Escribir "El usuario con cedula ", cedula , " debe pagar por valor de multa: $",valor

    Fin Para

    Escribir "El valor total de las multas es: $", Total

    Si cant_A = cant_B O cant_A = cant_C O cant_A = cant_D Entonces

    Escribir "El tipo de multa más cometida es la A (con Iguales)"

    Si cant_B = cant_C O cant_B = cant_D Entonces

    Escribir "El tipo de multa más cometida es la B (Con iguales)"

    Si cant_C = cant_D Entonces

    Escribir "El tipo de multa más cometida es la C (Con iguales)"

    SiNo


    Fin Si

    Fin Si

    Fin Si

    FinAlgoritmo


    Solución a los problemas 1, 2, 3, 4, 5, 6 , 7.1, 7.2 y, por consiguiente, a todo el problema principal:
    Método: Uso de preguntas anidadas y operadores booleanos.

    Algoritmo multas
    Escribir "Indica la cantidad de multas a procesar: "
    Leer cantidad_multas
    Total = 0
    cant_A = 0
    cant_B = 0
    cant_C = 0
    cant_D = 0
    Para i <- 1 Hasta cantidad_multas Con Paso 1 Hacer
    Escribir "Diga la cedula del infractor: "
    Leer cedula
    Escribir "Diga el tipo de infracción "
    Leer tipo
    valor = 0
    Si tipo = "A" Entonces
    valor = 117040
    cant_A = cant_A +1
    SiNo
    Si tipo = "B" Entonces
    valor = 234080
    cant_B = cant_B +1
    SiNo
    Si tipo = "C" Entonces
    valor = 438900
    cant_C = cant_C +1
    SiNo
    Si tipo = "D" Entonces
    valor = 877800
    cant_D = cant_D +1
    Fin Si
    Fin Si
    Fin Si
    Fin Si
    Total = Total + valor
    Escribir "El usuario con cedula ", cedula , " debe pagar por valor de multa: $",valor
    Fin Para
    Escribir "El valor total de las multas es: $", Total
    Si cant_A = cant_B O cant_A = cant_C O cant_A = cant_D Entonces
    Escribir "El tipo de multa más cometida es la A (Hay otras cantidades iguales)"
    Si cant_B = cant_C O cant_B = cant_D Entonces
    Escribir "El tipo de multa más cometida es la B (Hay otras cantidades iguales)"
    Si cant_C = cant_D Entonces
    Escribir "El tipo de multa más cometida es la C (Hay otras cantidades iguales)"
    SiNo
    Si cant_A > cant_B Y cant_A > cant_C Y cant_A > cant_D Entonces
    Escribir "El tipo de multa más cometida es la A"
    SiNo
    Si cant_B > cant_C Y cant_B > cant_D Entonces
    Escribir "El tipo de multa más cometida es la B"
    SiNo
    Si cant_C > cant_D Entonces
    Escribir "El tipo de multa más cometida es la C"
    SiNo
    Escribir "El tipo de multa más cometida es la D"
    Fin Si
    Fin Si
    Fin Si
    Fin Si
    Fin Si
    Fin Si
    FinAlgoritmo