Learning Machine #8 - Funciones y procedimientos.

Hola de nuevo a todos, el día de hoy vamos a continuar con el aprendizaje de Pascal. El tema de hoy corresponde a procedimientos y funciones.


Las funciones y procedimientos, son bloques de código que están separados del código que se ejecuta en la parte principal, además se distinguen porque estos se pueden ejecutar tantas veces mientras se les "llame", cuando lo hacemos, todo el código contenido en estos se ejecutará y al terminar, la ejecución continuará en la linea inmediata a la cual fue llamada la función/procedimiento.

Procedimientos.

Los procedimientos, son bloques de código que se ejecutan y no devuelven ningún tipo de resultado (o no que sea utilizable).
Veamos el siguiente código:

program Procedimiento;
uses crt;
var Number1, Number2 : integer;
procedure suma(N1 : integer; N2 : integer);
var Resultado : integer;
begin
	Resultado := N1 + N2;
	writeln('El Resultado es ', Resultado);
end;
begin
	clrscr;
	writeln('Ingresa el primer numero');
	readln(Number1);
	writeln('Ingresa el segundo numero');
	readln(Number2);
	suma(Number1,Number2);
	readln();
end.


Para definir un procedimiento, debemos de hacer uso de la palabra reservada "procedure", seguida del nombre que queramos darle al procedimiento. En el caso del código anterior, al procedimiento le dimos el nombre "suma", entre paréntesis, deben de ir los parámetros que el procedimiento vaya a usar, se pueden usar tantos cómo uno desee, pero cada uno debe de  ser definido con el tipo de datos que se usen y cada parámetro debe de ir separado por ";". Para abrir un procedimiento usamos "begin" y para cerrarlo usaremos "end;". Todo el código que se encuentre en medio de las palabras reservadas de apertura y cierre, sera el que se ejecute cada vez que se llame a la función; en este caso "suma". Para hacer uso de los parámetros, solamente debemos de llamarlos. para usar variables, debemos de declararlas en seguida de la creación del procedimiento, usando la palabra reservada "var", al igual cómo lo hacemos con las variables globales.

Funciones.

Las funciones son bastante similares a los procedimientos, es decir, van a ejecutar un bloque de código cada vez que se mande a llamar. La diferencia principal con los procedimientos, es que estas, devolverán un valor que se puede usar para otras cosas. Veamos el siguiente bloque de código:

program Funciones;
uses crt;
var Number1, Number2 : integer;
function suma(N1 : integer; N2 : integer) : integer;
var Resultado : integer;
begin
	Resultado := N1 + N2;
	{ suma:=Resultado; }
	exit(Resultado);
end;
begin
	clrscr;
	writeln('Ingresa el primer numero');
	readln(Number1);
	writeln('Ingresa el segundo numero');
	readln(Number2);
	writeln('La suma da ', suma(Number1,Number2));
	readln();
end.

Para definir una función, debemos de hacer uso de la palabra reservada "function", seguida del nombre del nombre que queramos darle a la función. Al igual que al procedimiento, en este caso le dimos el nombre de "suma", entre paréntesis deben de ir los parámetros y ademas, le debemos de dar un tipo, puede ser cualquiera de los soportados por Pascal (Boolean, integer, string, etc.).
Sabiendo que la función debe de devolver un dato que sea utilizable, debemos de ver la forma que este la regrese, para eso se hace uso de la palabra reservada "exit" y el valor que queramos regresar, deberá de ir entre paréntesis o podemos asignar el valor que queramos devolver a la función, en el caso del código anterior, es lo mismo "exit(Resultado)" que "suma:=Resultado", en ambos casos le estamos diciendo que el valor que la función regresará, será el que tenga la variable "Resultado".

Diferencias.

Al revisar el código del procedimiento y el de la función, verás que al momento de llamar al procedimiento, simplemente lo hacemos y cómo definimos en el procedimiento que escriba el resultado de sumar los parámetros, lo hará y se mostrará en pantalla, pero si no lo hacemos y queremos hacer uso del valor de la suma que se hace en el procedimiento, simplemente no podremos.
Ahora en el caso de la función, vemos que hacemos uso de ella cómo parámetro para "writeln" y está es la importancia de usar las funciones, todos los valores que estas generen se pueden usar cómo parámetros para otras funciones, para cambiar valores de variables, imaginemos que tenemos una función que hace un calculo grande y a ese valor lo queremos dividir a la mitad, simplemente definimos la función y directamente a la llamada de está dividirla.
Si quisiéramos hacer uso de un procedimiento y pasarlo cómo parámetro de un función (por ejemplo), el compilador nos marcaría un error como el de la imagen siguiente:
Si la tarea no es muy compleja se puede hacer uso de los procedimientos, en caso contrario, se recomiendan las funciones. En ambos casos, se recomienda su uso para llevar a cabo tareas que se repitan, siempre resulta más fácil llamar a una función/procedimiento en una linea que escribir diez lineas de código cada vez.

Y bien, por ahora es todo, todos los programas que se han hecho para Pascal, en breve, subire el código fuente para que lo revises.

Los leo luego.

Vamos a programar #39 - La conjetura de Collatz (Números maravillosos) Versión Android.

Hola de nuevo a todos, el día de hoy vamos a continuar con la conjetura de Collatz.
En el post anterior de "Vamos a programar", hicimos la versión de C#, cosa que resulto realmente fácil ya que en C# se puede hacer uso del tipo "BigInteger". En java para android, también existe el tipo "BigInteger" y en esta ocasión veremos un poco de cómo usarlo.

El código.

El código que hace funcionar la aplicación de la conjetura de Collatz en java para android es el siguiente:
package com.mdev.collatz;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

import java.math.BigInteger;
import java.util.ArrayList;


import static android.R.attr.button;

public class MainActivity extends AppCompatActivity {

	Button BtnCalculate;
	TextView TxtNumberIn;
	ListView LVResultados;

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		BtnCalculate = (Button) findViewById(R.id.BtnCalculate);
		TxtNumberIn = (TextView) findViewById(R.id.TXTNumberIn);
		LVResultados = (ListView) findViewById(R.id.LVResults);

		BtnCalculate.setOnClickListener(new View.OnClickListener()
		{
			@Override
			public void onClick(View view) {
				CalculateCollatz(TxtNumberIn.getText().toString());
			}
		});

	}
	private void CalculateCollatz(String Number)
	{
		ArrayList Items = new ArrayList();
		BigInteger MyNumber = new BigInteger(Number);
		while (MyNumber.compareTo(BigInteger.ONE) > 0)
		{
			if (IsEven(MyNumber)) {
				MyNumber = MyNumber.divide(BigInteger.valueOf(2));
				Items.add(MyNumber.toString());
			}else{
				MyNumber = MyNumber.multiply(BigInteger.valueOf(3));
				MyNumber = MyNumber.add(BigInteger.valueOf(1));
				Items.add(MyNumber.toString());
			}
		}
		final ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1,Items);
		LVResultados.setAdapter(adapter);
	}

	private boolean IsEven(BigInteger Number){
		BigInteger Result = Number.remainder(BigInteger.valueOf(2));
		int CompareResult = Result.compareTo(BigInteger.ZERO);
			if(CompareResult == 0)
			{
				return true;
			}else{
				return false;
			}
	}
}

Para empezar crearemos los controles que vamos a necesitar, está aplicación consta únicamente de 4 controles (5 en realidad, puedes revisarlo en el código completo).

  • 1 Textview.
  • 1 EditText
  • 1 Button
  • 1 Listview
Solo vamos a interactuar con los últimos tres pos lo que solo esos son los que crearemos tambien en el código.
Para tratar de simplificar un poco el código, hice lo traté de hacer lo mismo que en c#. Primero, iba a pedir un numero en formato de texto, luego crear una funcion que calcule la conjetura de Collatz y mostrar cada paso que se dio en un "ListView".
La cosa es sencilla, y podemos repetir lo que ya habíamos hecho, pero en java, a diferencia de c#, el tipo BigInteger no es tan simple de manejar.
En Java, el tipo BigInteger dispone de sus operaciones por separado, las comparaciones se deben de hacer desde los métodos contenidos en el tipo BigInteger. Eso quiere decir que si queremos comparar el número "1" con el valor BigInteger "1", no podemos realizarlo porque a diferencia de C#, aquí no se hace una conversión implícita; nosotros debemos de hacerla de forma explicita haciendo uso de los métodos contenidos en el tipo "BigInteger".

Retomando nuestro código, primero veremos la función "IsEven". la función "IsEven" recibe un parámetro del tipo "BigInteger", este, es el numero de cual queremos determinar si es par o no. Para hacerlo, hacemos uso de dos variables; la primera, llamada "Result" del tipo "BigInteger", se crea y se le asigna el valor que resulta del uso del método del parámetro de entrada "Number", el método que se usa es ".remainder()", este método lo que hace, es devolver el residuo de la división entre el numero "Number" y el parámetro que se le asigne; para este caso, debemos de dividir entre dos, pero cómo no se puede usar directamente "2", usamos otro procedimiento del tipo "BigInteger". el método que usamos es "BigInteger.valueOf()", este procedimiento lo que hace, es crear una versión del número que se pasa cómo parámetro en tipo "BigInteger".
Lo anterior se hace para determinar si un número es par o no (hay que recordar que los número pares, son aquellos que al ser divididos entre dos, dan un número entero). El resultado que obtenemos es 1 o 0 (cualquiera de los dos del tipo BigInteger).
Solo nos queda hacer la comparación, si el resultado es "0" entonces el número es par, para hacer la comparación, usamos otro procedimiento más del tipo "BigInteger". Hacemos uso de la función ".compareTo", lo hacemos en la variable resultado y le pasamos cómo parámetro una constante llamada "BigInteger.ZERO"; la constante vale 0. la función regresa un valor del tipo int con cualquiera de los 3 valores posibles:

  1. -1 si el valor es menor que el BigInteger desde el cual se llama.
  2. 0 si el valor es igual que el BigInteger desde el cual se llama.
  3. 1 si el valor es mayor que el BigInteger desde el cual se llama.
Para determinar si la función "IsEven" devuelve "true" o "false", creamos una variable del tipo "int" llamada "CompareResult" a la que le asignamos el valor de la función "Result.compareTo" con parámetro "BigInteger.ZERO".
Si el valor de la variable "result" es "0", la función IsEven devuelve "true", en caso contrario, "false".

El procedimiento "CalculateCollatz", es el encargado de hacer los cálculos, para eso, primero creamos la variable del tipo "BigIntger" llamada "MyNumber". Al usar el constructor del tipo "BigInteger", le podemos pasar un valor del tipo "String", en este caso le asignamos el parámetro "Number", con eso creamos un valor del tipo "BigInteger" con valor del "String" del parámetro.
Después creamos un bucle "while" con la condición "Number" sea mayor que "BigInteger.ONE". Con la función "IsEven", podemos replicar lo que hicimos en c# y dentro del bucle, verificamos si el número es par o no y dependiendo del caso, hacer los cálculos.
Para multiplicar un valor "BigInteger", debemos de hacer uso del método "BigInteger.multiply", este recibe cómo parámetro un "BigInteger" que será el multiplicador y el resultado, sera un valor BigInteger con el valor de la multiplicación. Para dividir un valor "BigInteger", debemos de hacer uso del método "BigInteger.divide", este recibe cómo parámetro un "BigInteger" que será el divisor y el resultado, sera un valor "BigInteger" con el valor de la división. lo mismo para la suma, debemos de hacer uso de "BigInteger.add".
Finalmente creamos un "ArrayAdapter" al que agregaremos todos los pasos que se hicieron y este se asina al control "ListView".

El resultado. Puedes descargar la APK con la aplicación ya compilada, el código completo lo subiré en breve, agregare threads para que la interfaz no se bloquee (aunque así como esta funciona bien), aunque con el código anterior, se cubre toda la parte lógica de la aplicación.

Bien, por ahora es todo.
Los leo luego

Learning Machine #7 - Select.

Hola a todos, el día de hoy vamos a continuar con más del aprendizaje del lenguaje de programación Pascal, continuaremos con las instrucción "Select"

Algunas veces debemos de elegir una opción entre un numero finito de ellas, cuando son reducidas o podemos predecirlas, la instrucción "select" nos servirá para llevar esa tarea.

La instrucción "select" en Pascal, tiene la siguiente forma:

	case MiRespuesta of
		Respuesta1:
		Código que se ejecuta por la respuesta1;
		Respuesta2:
		Código que se ejecuta por la respuesta2;
		else
		Código que se ejecuta si ninguna respuesta anterior se cumple;
	end;


Para cada sentencia posible, se pueden usar números o cadenas de texto, es conveniente utilizar solo un tipo, ya que a veces las conversiones de una cadena de texto por ejemplo: "7"; no se puede convertir directamente a 7, entonces si estamos esperando un valor numérico, siempre debemos de usar 7 en la sentencia.
Cada sentencia debe de ir seguida por ":" (dos puntos), cuando terminamos de escribir el código que se ejecutará, pondremos ";" para indicar que es el fin de esa parte.

Supongamos que queremos crear un programa que pase un número a su correspondiente día de la semana de la siguiente forma:


  • 1 -> Domingo.
  • 2 -> Lunes.
  • 3 -> Martes.
  • 4 -> Miércoles.
  • 5 -> Jueves.
  • 6 -> Viernes.
  • 7 -> Sábado.
Usando "Select", lo podemos hacer de la siguiente manera:

program Casos;
uses crt;
var MiRespuesta : integer;
begin
	writeln('ingresa un numero del 1 al 7');
	readln(MiRespuesta);
	case MiRespuesta of
		1:
		writeln('El dia 1 corresponde al domingo');
		2:
		writeln('El dia 2 corresponde al lunes');
		3:
		writeln('El dia 3 corresponde al martes');
		4:
		writeln('El dia 4 corresponde al miercoles');
		5:
		writeln('El dia 5 corresponde al jueves');
		6:
		writeln('El dia 6 corresponde al viernes');
		7:
		writeln('El dia 7 corresponde al sabado');
		else
		writeln('Dia desconocido');
	end;
	readln;
end.

Cómo veras, esta definida una respuesta para cada día de la semana, si el usuario escribe 1, el programa mostrará que ese día corresponde al domingo, en este ejemplo, se hace uso de la conversión implícita, para empezar funciona, pero no en todos los casos se puede convertir un fragmento de texto (que parezca número) a un número.
También hacemos uso de "else", esta, se debe de usar al final de todos los casos y será utilizada cuando ninguno de los casos definidos se cumpla, en el caso del programa anterior, si el usuario introduce un valor fuera del rango 1-7, se mostrará: "Día desconocido".

Y bien, por ahora es todo, en futuros post, veremos cuando es conveniente el uso de "if" y cuando el uso de "case", el ejemplo anterior puede ser hecho usando solo "if" en lugar de "Select".

Los leo luego.

Vamos a programar #38 - La conjetura de Collatz (Números maravillosos) versión C#.

Hola de nuevo a todos, el día de hoy vamos a hacer un pequeño receso a la programación en Pascal y vamos a ver un poco de C#.

La conjetura de Collatz dice que todos aquellos números son "maravillosos", siempre y cuando al aplicar las siguientes operaciones de forma recursiva, nos resulte 1.

El enunciado dice:

Sea la siguiente operación, aplicable a cualquier número entero positivo:
  • Si el número es par, se divide entre 2.
  • Si el número es impar, se multiplica por 3 y se suma 1.
El problema en si, es fácil, pero al momento de crear la aplicación, debemos de recordar que estamos limitados en el numero máximo que podemos usar. Para solucionarlo, vamos a usar el tipo "BigInteger".
En .net 4.0 se introdujo este nuevo tipo de dato, que permite utilizar enteros de longitud arbitraria, mas que suficiente para poder calcular la conjetura. Actualmente el número mas grande calculado tiene mas de 60 mil millones de cifras.

El código.

El codigo en c# que calcula la conjetura de Colltaz es el siguiente (la lista de controles no se incluye, todo el código fuente lo puedes descargar de dropbox):

using System;
using System.Windows.Forms;
using System.Numerics;
using System.Threading;

namespace ConjeturaDeCollatz
{
	public partial class FrmMain : Form
	{
		private delegate void UpdateListDelegate(string Value);

		private void UpdateList(string Value)
		{
			if (LBResults.InvokeRequired)
			{
				LBResults.Invoke(new UpdateListDelegate(UpdateList), Value);
			}
			else
			{
				LBResults.Items.Add(Value);
			}
		}
		private void CalculateCollatz(string Number)
		{
			BigInteger MyNumber;
			BigInteger.TryParse(Number, out MyNumber);
			while (MyNumber > 1)
			{
				if (MyNumber.IsEven == false)
				{
					MyNumber = MyNumber * 3 + 1;
					UpdateList(MyNumber.ToString());
				}
				else
				{
					MyNumber = MyNumber / 2;
					UpdateList(MyNumber.ToString());
				}
			}
		}
		private void RunWork(string Number)
		{
			Thread DoWork = new Thread(new ThreadStart(() => CalculateCollatz(Number)));
			DoWork.Start();
		}
		public FrmMain()
		{
			InitializeComponent();
		}

		private void BtnStart_Click(object sender, EventArgs e)
		{
			LBResults.Items.Clear();
			RunWork(TxtNumberIn.Text);

		}
	}
}


El código es realmente simple, ya que solo hacemos, para empezar, un bucle "while", que se ejecutará mientras la variable "MyNumber", sea mayor que uno. Después comprobamos si el numero es par, dentro de la estructura del "BigInteger", hay una función llamada "IsEven", la cual sirve para comprobar si un número es par. La utilizamos y si el resultado es "true", hacemos la división entre dos (cómo dice el enunciado), en caso contrario multiplicamos por 3 y le sumamos uno.
Para poder agilizar un poco, todo el proceso, se hace en un "thread" diferente, con lo cual la aplicación no se bloquea.
Por ahora, es todo. Desde mi punto de vista, parece que todos los numero son maravillosos, puesto que al ser impar (que usualmente son números raros), al multiplicar y sumarle uno, en algún punto, siempre nos dará un numero par. Aunque la conjetura no se ha probado (de ahí lo de conjetura), resulta un buen ejercicio para todo programador.
En el siguiente post de C#, agregaremos funciones para obtener más datos que son relevantes para la conjetura, Además, veremos un poco mas a fondo el tipo "BigInteger" y extenderemos el uso de threads para hacer cálculos un poco más "masivos". Cómo de costumbre, el código completo lo dejo en mi dropbox para que lo descargues.

Los leo luego.

Learning Machine #6 - Bucle while.

Hola de nuevo a todos, el dia de hoy vamos a ver un poco mas de programacion en pascal. Hoy toca ver cómo se usa el bucle "while".


El bucle "while" cómo su nombre lo indica, es una palabra reservada que sirve para indicar que queremos hacer un proceso y que este se repita hasta que cierta condición se cumpla.
Supongamos que queremos comprobar un numero que el usuario escriba con un numero que nosotros tengamos almacenados en una variable, para evitar que se la pase todo el día escribiendo números, vamos a darle un numero limitados de intentos; supongamos 5.
Para llevar a cabo la tarea mencionada antes, podemos usar código como el que sigue:

program Bucle;
uses crt;
var Oportunidades, MiNumero, TuNumero : integer;
begin
 MiNumero := 64;
 clrscr;
 while Oportunidades <= 5 do
 begin
  writeln('Ingresa un numero');
  readln(TuNumero);
  if TuNumero <> MiNumero then
   Oportunidades := Oportunidades + 1
  else
   break;
 end;
 writeln('Fin del programa');
 readln();
end.

Para empezar veamos cómo es que funciona la palabra reservada while. Esta palabra va seguida de una condición, en el código anterior, la condición es: "Oportunidades <= 5" después sigue la palabra reservada "do". todo el bloque de código que se usa debe ir en medio de las palabras reservadas "begin" y "end;". Todo el código que se quiera ejecutar debe de ir en esta sección. Una representación de cualquier bucle "while", puede ser el siguiente:

while "Condicion No se cumple" do
begin
 { ... }
 { ... }
 { ... }
 { ... }
end

Algo que se debe de tener muy en cuenta, es el cómo se plantea la condición. Al ir avanzando linea por linea, cuando en la ejecución se encuentra "while" evaluara la expresión y si al hacerlo esta ya se cumple, simplemente avanzara hasta la linea donde se encuentre el "end" del cierre del bucle.
Para el caso del primer código,  primero le asignamos un valor a la variable "MiNumero" y después viene el bucle "while" con la condición que mientras la variable "Oportunidades" sea menor o igual que 5, haga lo que está dentro del bucle.
Adentro del bucle, le vamos a preguntar un numero  al usuario y lo almacenaremos en la variable "TuNumero", luego compararemos la variable "TuNumero" con la variable "MiNumero" y si son diferentes, a la variable "Oportunidades" le sumaremos 1. Si escribimos 5 veces un numero que no sea 64, llegaremos al final de la ejecución, pero si solo escribimos el numero 64, esto nos llevara al final del programa, porque la palabra reservada "break", sirve para salir del bucle sin importar que la condición se haya cumplido o no, en el caso anterior, en el "if", solo hay dos posibles vias, una es cuando "TuNumero" y "MiNumero" son diferentes y la otra es cuando el número es igual, cuando se escribe 64 no tiene sentido que le sigamos preguntando cual es nuestro numero porque ya lo ha averiguado, entonces hacemos uso de "break" y con eso iremos al final del programa.
Solo para probar que funciona, puedes cambiar el "<=" por ">=". Con esto, el programa ira directamente a la penúltima linea ("readln"), porque se habrá brincado todo el bucle.

Y bien, por ahora es todo, la semana que viene continuaremos con mas de la programación en Pascal.

Learning Machine #5 - Estructura de control if y else.

Hola de nuevo a todas, el día de hoy vamos a  continuar con el aprendizaje del lenguaje de programación Pascal. Hoy toca ver la estructura de control if.

Parte fundamental de cualquier programa, es tomar una decisión en base a algo, en el caso de la programación, podemos por ejemplo: decidir si hacer algo o no si un numero es tan grande; o tan pequeño en comparación a otro, juntar todas las cosas que el usuario escriba que empiecen por una letra.


IF

La estructura de control "if" sirve para redireccionar el flujo de un programa, para hacerlo, primero hará una comprobación y si el resultado es cierto, el programa ejecutará cierto código.

Para usar "if" en Pascal, primero hay que escribir la palabra reservada "if", depues viene la parte de la comprobación lógica en la cual si el resultado es "verdadero", ejecutara código dentro de la instrucción if. una vez escrita la condición, debemos de incluir la palabra reservada "then".

Para hacer las comparaciones disponemos de los siguientes simbolos de comparacacion:

  • < Menor que
  • <= Menor o igual que 
  • > Mayor que
  • >= Mayor o igual que
  • = Igual que
  • <> Distinto que
Los símbolos anteriores los usaremos de la siguiente forma, supongamos que queremos comparar un numero que el usuario ingrese, y mostraremos 3 frases dependiendo de los siguientes casos:
Si el número es mas grande, Si es mas pequeño o si es igual.
Entonces tenemos que usar: ">", "<" y "=".
Ahora tenemos el siguiente código

Program HelloWorld(output);
uses crt;
var MiNumero, TuNumero : integer;
begin
 MiNumero := 20;
 clrscr;
 writeln('Escribe un numero');
 readln(TuNumero);
 if TuNumero < MiNumero then
  writeln('Mi numero es mas grande');
 if TuNumero > MiNumero then
  writeln('Tu numero es mas grande');
 if TuNumero = MiNumero then
  writeln('Los numeros son iguales');
 readln;
end.

Como verás, primero creamos dos variables del tipo "integer", luego le preguntamos al usuario por un número que vamos a almacenar en la variable "TuNumero", luego vienen las comparaciones. La primera vamos a comprobar si el numero que el usuario escribió es mas pequeño que el que nosotros le asignamos a la variable "MiNumnero", si es así, le mostraremos un mensaje que dice: "Mi número es mas grande". Para el segundo caso, vamos a comprobar si le número que escribió es más grande y para el tercer caso solo comprobaremos si el número es igual.

El código de arriba tambien se puede plantear de la siguiente manera
Program HelloWorld(output);
uses crt;
var MiNumero, TuNumero : integer;
begin
 MiNumero := 20;
 clrscr;
 writeln('Escribe un numero');
 readln(TuNumero);
 if TuNumero < MiNumero then
  writeln('Mi numero es mas grande')
 else if TuNumero > MiNumero then
  writeln('Tu numero es mas grande')
 else if TuNumero = MiNumero then
  writeln('Los numeros son iguales');
 readln;
end.

Para hacerlo de la forma anterior hacemos uso de la palabra reservada "else", seguida de la palabra reservada "if" y después la condición (cómo en el primer caso). Ademas, no hacemos uso de ";" porque cuando lo hacemos, indicamos que es el final de la instrucción "if", entonces solo hay que ponerlo para indicar que terminamos.

Else

Para hacer uso de la palabra else, debemos de seguir los mismo pasos que para "else if", ademas debemos de usarlo siempre al final de la instruccion if.
Ahora supongamos que solo queremos saber si el numero es igual o diferente al que nosotros almacenamos en nuestra variable, podemos hacer lo mismo que al inicio o podemos hacer uso de "else" (un tanto inpractico pero sirve para demostrar lo que queremos).
Entonces podemos usar código como el que sigue:

Program HelloWorld(output);
uses crt;
var MiNumero, TuNumero : integer;
begin
 MiNumero := 20;
 clrscr;
 writeln('Escribe un numero');
 readln(TuNumero);
 if TuNumero = MiNumero then
  writeln('Los numeros son iguales')
 else
  writeln('Los numeros son diferentes');
 readln;
end.

A veces resulta realmente dificil poder listar todas las posibles situaciones, pero con el uso de "else" nos podemos ahorrar un poco.
Y bien, por ahora es todo, en el sigueinte post continuaremos con mas de programacion en pascal.

Los leo luego.

Learning Machine #4 - Programando en Pascal - Declaraciones, ámbitos y constantes.

Hola a todos, el día de hoy vamos a continuar con la programación es Pascal. En el post anterior, vimos cuales son los tipos de datos que se pueden usar, pero olvide algo realmente fundamental, el cómo declararlas.



Para declarar una variable en Pascal, es necesario usar la palabra reservada "var", la mayorías de las variables globales que van a ser usadas por el programa, deben de ser declaradas justo antes del inicio del programa, siempre es bueno declarar la mayor parte de estas en este punto, así el programa al iniciar, cargará la mayor parte de los recursos necesarios al inicio.
En pascal la forma de declarar las variables es la siguiente:
NombreDeLaVariable : tipo;
El nombre de la variable debe de empezar por una letra y puede incluir números y símbolos que no sean usados por el lenguaje de ":" y finalmente el tipo del cual será.
Por ejemplo, vamos a crear 5 variables:

var
Valor1 : integer;
Valor2 : integer;
Valor3 : integer;
Nombre1 : string;
Nombre2 : string;
begin
...

Con el fragmento de código anterior, hemos creado 3 variables del tipo integer llamadas: "Valor1", "Valor2" y "Valor3", además de 2 variables del tipo string llamadas: "Nombre1" y "Nombre2".
Se puede ahorrar un poco de espacio si en lugar de crear una variable del mismo tipo por linea, se declaran todas las variables similares en una sola. Para hacer eso, hay que escribir el nombre de la variable seguido de una coma ",", cuando se hallan declarado todas la variables que queramos que pertenezcan al mismo tipo, se pondrá ":" seguido por el tipo al cual pertenecerán. Entonces, el fragmento de código anterior puede crearse de la siguiente manera:


var
Valor1, Valor2, Valor3 : integer;
Nombre1, Nombre2 : string;
begin
...


Constantes.

Las constantes son valores que se declaran y se les asigna un valor al mismo tiempo, una vez que el valor a sido establecido, ya no es posible cambiarlo. Cuando queremos hacer uso del la constante, basta con mandarla a llamar por su nombre y entonces se usará el valor que está posea.
Si se intenta cambiar el valor de una constante en algún punto del programa, este producirá un error en tiempo de compilación.
Los siguientes son ejemplos de declaración de variables:
Const
e = 2.7182818;
MyName = 'XWork';
El uso de constantes es realmente útil cuando trabajemos con valores conocidos que no se van a modificar.

Visibilidad de los datos.

Algo muy importante que hay que tomar en cuenta, es la visibilidad de los datos, cuando creamos las variables en esta parte del programa, al estar en la parte principal, estos serán visibles para todo el programa, es decir estos valores podrán ser leídos y escritos desde cualquier lugar de la aplicación. Lo importante de esto, es que hay que tener muy en mente que es lo que vamos a hacer y cómo vamos a hacerlo, supongamos que creamos variables al inicio del programa y llegamos al punto en que el programa es tan grande y tiene tantas variables que por error escribimos el nombre de una variable que no es la que estamos usando. Al haber modificado los datos de una variable sin darnos cuenta, el programa producirá un error en algún momento. Aunque en pascal solo hay ámbitos, local y global. Cuando una variable se crea dentro de una función o procedimiento (cosas que veremos un poco después), esta solo sera visible dentro de la funcion (o procedimiento) en el cual se haya creado.
En lenguajes que sean orientados a objetos (c#, delphi, etc), existen palabras reservadas que sirven para indicar directamente si una variable es privada o no, es decir si se puede usar más allá del ámbito en el cual fue creada.

Y bien, por ahora es todo, en el siguiente post continuaremos con más programación para Pascal

Los leo luego

Learning Machine #3 - Programando en Pascal - Variables.

Hola de nuevo a todos, el día de hoy vamos a continuar con más de programación en Pascal. En el post del día de hoy vamos a ver los tipos de datos que se pueden usar. En algunos post anteriores hemos visto algo similar, pero hoy veremos el caso concreto para pascal, ademas es importante repetir esto tantas veces cómo sea necesario para que nuestros programas estén lo más optimizados posibles en el uso de memoria.



Variables y sus tipos.

Al igual que en los otros lenguajes de programacion, en Pascal haremos uso de variables. Estas serán las encargadas de almacenar valores que posteriormente usaremos, pero dependiendo de cómo sea declarada, será el tipo de "datos" que se le pueda asignar.

Los datos y los valores que pueden almacenar son los siguientes:
TipoRangoTamańo en bytes
Byte0 .. 2551
Shortint-128 .. 1271
Smallint-32768 .. 327672
Word0 .. 655352
Integer******
Longint-2147483648 .. 21474836474
Longword0 .. 42949672954
Int64-9223372036854775808 .. 92233720368547758078
Qword0 .. 184467440737095516158
Char***1

Los datos anteriores solo corresponden a las variables del tipo "numérico" o tipos simples. Antes de avanzar hay que ver un poco sobre el tipo integer.
Cuando Pascal compila, el tipo integer dependerá de cual fue el objetivo de la compilación, usualmente, la mayoría de la gente está familiarizado con máquinas de 32 bits, pero existen 3 tipos de estándares, 16,32,64. Cuando se compila una aplicación cuyo objetivo es una máquina de 16 bits, pascal usará 16 bits (2 bytes) para almacenar los valores del tipo integer, esto nos dará una capacidad de -32,768 a 32,767, pero en cambio si nuestro objetivo es una máquina de 32 bits, se usaran 32 bits(valga la redundancia) y podrá almacenar desde  -2,147,483,648 a 2,147,683,647. En el caso de las máquinas de 64 bits ocurre exactamente lo mismo.

El otro caso que debemos de revisar es el tipo "Char", este puede almacenar un valor entre 0 a 255, pero solo es en teoría, porque este se usa para hacer referencia a un elemento del estándar ASCII y por ejemplo, si tratamos de hacer una operación matemática sobre una variable declarada cómo "char", el compilador nos marcará un error.

Para los tipos complejos, por ahora solo veremos el tipo "String". Este tipo se usa para almacenar cadenas de texto con una longitud de hasta 255 caracteres (aunque se puede ampliar), este es el tipo que se usara para poder trabajar con cadenas de texto.

Y bien, por ahora es todo, si bien aún hay algunos tipos más, por ahora estos serán más que suficiente para empezar a programar con pascal.

Los leo luego

Cumplimos un año!!

Hola a todos, el día de hoy solo escribo para agradecer a todos los que nos visitaron, visitan y visitaran.



Ha sido un largo trayecto desde el primer día hasta hoy. Solo me resta agradecer a las personas que me motivaron a iniciar con este proyecto (muy particularmente a una ;) ).

Continuaremos con los proyectos y actualizaciones pendientes y todos juntos avanzaremos hacia adelante.

Gracias a todos, Nos leeremos luego.

Learning Machine #2 - Programando en pascal - Fundamentos del lenguaje.

Hola de nuevo a todos, el día de hoy vamos a continuar con el aprendizaje del lenguaje de programación en pascal. En el post anterior vimos un poco sobre el ciclo de vida de un programa (para este y todo los lenguajes). En este post vamos a ver un poco más sobre Pascal.


Palabras reservadas.

Al igual que todos los otros lenguajes de programación, en Pascal se usan una serie de palabras que tienen una función en especifico y no puede ser usadas como nombres para variables.
La siguiente lista muestra las palabras reservadas en Free Pascal (su uso las veremos más adelante):

  • absolute
  • and
  • array
  • asm
  • begin
  • case
  • const
  • constructor
  • destructor
  • div
  • do
  • downto
  • else
  • end
  • file
  • for
  • function
  • goto
  • if
  • implementation
  • in
  • inherited
  • inline
  • interface
  • label
  • mod
  • nil
  • not
  • object
  • of
  • operator
  • or
  • packed
  • procedure
  • program
  • record
  • reintroduce
  • repeat
  • self
  • set
  • shl
  • shr
  • string
  • then
  • to
  • type
  • unit
  • until
  • uses
  • var
  • while
  • with
  • xor

Simbolos.

En el lenguaje de programación Pascal, se reconocen todos los símbolos en el estandar ASCII, pero ademas, los siguiente símbolos tienen un uso especial:
  • +
  • -
  • *
  • /
  • =
  • <
  • >
  • [ ]
  • .
  • ,
  • ( )
  • :
  • ^
  • @
  • { }
  • $
  • #
  • &
  • %
Y los siguientes pares de símbolos también:
  • <<
  • >>
  • **
  • <>
  • ><
  • <=
  • >=
  • :=
  • +=
  • -=
  • *=
  • /=
  • (*
  • *)
  • (.
  • .)
  • //

Comentarios.

Los comentarios son partes de código que van a ser omitidos por el compilador al momento de generar el ejecutable. Principalmente se usan para proporcionar información adicional en el código, en pascal, se puede comentar de tres maneras distintas. supongamos el siguiente código:
Program HelloWorld(output);
	uses crt;
(* Aqui empieza la parte principal *)
begin
	clrscr;
	writeln('Hello World');
(* Usamos readln() para esperar que se presione enter *)
	readln();
end.

Ahora el siguiente:
Program HelloWorld(output);
	uses crt;
{ Aqui empieza la parte principal }
begin
	clrscr;
	writeln('Hello World');
{ Usamos readln() para esperar que se presione enter }
	readln();
end.
	
Y el siguiente:
Program HelloWorld(output);
	uses crt;
//Aqui empieza la parte principal 
begin
	clrscr;
	writeln('Hello World');
//Usamos readln() para esperar que se presione enter 
	readln();
end.
	

En todos los casos anteriores, el código es exactamente igual, solo que se usan todas las formas de comentar disponibles.
Y bien, por ahora es todo, en el siguiente post seguiremos viendo más sobre el lenguaje de programación Pascal.

Los leo luego.

Learning machine #1 - Programando en Pascal.

Hola de nuevo a todos, el día de hoy vamos a ver una introduccion al mundo de la programación.
Varios usuarios me han preguntado (atraves del formulario de contacto) sobre la posibilidad de crear "tutoriales" para aprender a programar, al inicio no me gustaba la idea, porque no soy bueno explicando, pero alguien alguna vez dijo: "Cuando enseñas tu tambien aprendes", entonces, trataré de hacer algunos post en donde mostraré las cuestiones básicas (y un poco más).
Al inicio no se me ocurria en que programa empezar así que en vez de ir a C#; porque hay mucho código en el post o java (para android), decidí empezar con lo que yo empecé: Pascal.


Si bien no es un lenguaje muy popular ni mucho menos nuevo, creo que sirve para sentar las bases que cualquier programador necesita.

Para empezar, descargaremos el IDE de Pascal desde su página. Antes de empezar vamos a ver el ciclo de vida de un programa.

Ciclo de vida de un programa/aplicación.

El ciclo de vida consiste basicamente de cuatro partes:

  • Analisis.
  • Diseño.
  • Pruebas.
  • Implementacion.
El analisis, cómo su nombre lo dice, consiste en buscar que es lo que qeuremos lograr y cómo hacerlo (creacion del algoritmo en resumidas cuentas). Suponiendo que qeuremos hacer una aplicacion que haga las cuatro operaciones básicas: Suma, Resta, Multiplicación y División. Lo primero que hacemos es ver que funciones tenemos disponibles para llevar a cabo las tareas antes dichas, planear cómo es que se va a interactuar con el usuario (tanto de entrada y salida) y cómo debe de lucir la aplicación (aunque en pascal son "limitadas" las opciones para interactuar con el usuario). En pocas palabras, debemos de buscar una forma de resolver el problema

El diseño, este consiste en tratar de pasar el algoritmo que se concebi antes al código, esta parte es esencial y muy importante, dado que el programa resultante será la implementación del código que nosotros hayamos escrito. Un buen código producirá una buena ejecución.

Las pruebas, estas deben de realizarse para corregir errores y tratar de evitarlos lo más que se pueda. En está etapa debemos de probar las cosas más absurdas. Es importante probar la mayoría de los escenarios posibles, en algunas ocasiones, lo errores serán producto de las propias limitantes del lenguaje de programación, otras serán producto de nuestro propio descuido, y finalmente vendrán lo errores que el usuario pueda causar. Es importante que tratemos de no asumir, por más absurdo que algo nos pueda parecer, hay que manejarlo cómo es debido. Supongamos que seguimos con el programa de la calculadora, el usuario la ejecuta y quiere hacer una división; 13/0. Todos los lenguajes producirán un error si se quiere dividir cualquier número entre 0 y si no hay un manejo adecuado, la aplicación simplemente se cerrará (o peor, puede comprometer todo el sistema, eso dependiendo de que es lo que hacemos). La manera de evitarlo, sera comprobar cual es el valor del divisor y si es 0 simplemente no hacer la operación y decirle al usuario cual fue la razón por la que no se pudo resolver su operación.

Finalmente la implementacion, esta parte corresponde a la ejecucion, cuando ya se han hecho las debidas pruebas y hemos minimizado los errores, si es cierto, siempre, cualquier programa será propenso a los errores (aun si llevas decadas programando), pero siempre (y aunque suene repetitivo) debemos de probar la mayoria de escenarios posibles.

Estructura de un programa en pascal.


Un programa en pascal consiste de 5 partes:

  • Titulo del programa.
  • Declaracion de librerias.
  • Declaracion de variables.
  • Cuerpo del programa
    • Implementacion.
  • Fin del programa.
Observando la imagen, el titulo del programa es HelloWorld. La palabra reservada "Program" se usa para indicar el inicio del programa.
Para hacer la declaración de las librerías que vamos a usar, debemos de hacer uso de la palabra reservada "uses" seguida del nombre de la librería (por ahora solo usamos crt que proporciona funciones básicas).
Después vendría la declaración de las variables que vayamos a usar, la palabra reservada "begin" indica el inicio del programa en sí, seguido de está, debemos de escribir el código de la aplicación.
"clrscr;"limpia la pantalla, es decir borra todo el contenido previo y deja lista la ventana en "blanco". "writeln("Hello World");" la función "writeln" se usa para mostrar texto pero además, inserta un linea nueva al final. "readln();" se usa para que el programa reciba texto por parte del usuario, en programas simples, es recomendable usar un "readln();" al final del programa, porque cuando acaba la ejecución, el programa se cierra de manera inmediata, en el código anterior, si no usáramos la función, al ejecutar la aplicación solo veríamos una ventana negra que se cierra de inmediato. "end." se usa para indicar que es el fin del programa.

Y bien, por ahora es todo, en el siguiente post veremos cómo usar librerías y ademas vernos cuales son las más comunes y las funciones que ofrecen, además de los tipos de datos que podemos usar en Pascal.
Los leo luego.

Back to basics #4 - Eligiendo al mejor tipo.

Hola de nuevo a todos, el día de hoy vamos  a continuar con lo básico. En el post anterior, vimos cómo al elegir un tipo de variable, puede ser determinante a la hora de que se producen los errores.

Antes que nada vamos a ver cuales son los tipos disponibles en C# y Java en la siguiente tabla:

Nombre cortoClase .NETTipoAnchoIntervalo (bits)
byteByteEntero sin signo80 a 255
sbyteSByteEntero con signo8-128 a 127
intInt32Entero con signo32-2.147.483.648 a 2.147.483.647
uintUInt32Entero sin signo320 a 4294967295
shortInt16Entero con signo16-32.768 a 32.767
ushortUInt16Entero sin signo160 a 65535
longInt64Entero con signo64-922337203685477508 a 922337203685477507
ulongUInt64Entero sin signo640 a 18446744073709551615
floatSingleTipo de punto flotante de precisión simple32-3,402823e38 a 3,402823e38
doubleDoubleTipo de punto flotante de precisión doble64-1,79769313486232e308 a 1,79769313486232e308
charCharUn carácter Unicode16Símbolos Unicode utilizados en el texto
boolBooleanTipo Boolean lógico8True o false
objectObjectTipo base de todos los otros tipos
stringStringUna secuencia de caracteres
decimalDecimalTipo preciso fraccionario o integral, que puede representar números decimales con 29 dígitos significativos128ą1.0 × 10e?28 a ą7.9 × 10e28
La tabla anterior está disponible en la página de ayuda de MSDN,
Ahora, que es lo que debemos antes de empezar a crear una aplicación, bueno, debemos de tener muy claro que es lo que queremos lograr, si no tenemos eso muy claro desde el principio, es muy posible que a medio programa encontremos algunas dificultades. En C# disponemos de 15 tipos de variables y es necesario saber que tipo de datos se almacenan en cada una.

¿Cómo aplicar el tamaño adecuado a las variables?

Muchas veces hay que elegir que tipo de variables son la que debemos de usar en determinada parte de nuestro programa, generalmente siempre se buscará usar la variable más grande disponible, eso siempre y cuando no sepamos cual será el valor que está poseerá. Pero es recomendables hacer eso?, por supuesto que no! siempre debemos de tratar de tener el menor consumo de memoria.
Imaginemos que tenemos un programa en el cual una variable va a recibir el valor que el usuario introduzca, así que creamos una variable del tipo long (cuyo valor máximo es 922337203685477507), en tiempos modernos funciona de maravilla y nos ahorra muchos dolores de cabeza, finalmente que son 64 bits de 32,000,000,000 que hay disponibles en la mayoria de las computadoras (64 de 8,000,000,000 de los móviles). Pero la cosa no siempre fue así, hace no mucho tiempo, la cantidad de memoria era mucho más limitada, los computadores más potentes solamente tenían 64MBytes de RAM, por lo que administrar de manera prudente los recursos era primordial para el buen desarrollador de software. Entonces asumir no era una opcion, en ese caso lo que se hacia limitar al usuario, poner las condiciones pertinentes para que todo este dentro de los esperado. Podemos concluir que siempre debemos de usar la variable del tipo mas razonablemente pequeña y condicionar al usuario a que se ajuste, solo en casos realmente específicos es cuando debemos de adecuar el programa al usuario.

¿Cuando si debemos de ajustarnos?

En tiempos recientes es difícil citar un caso en el cual el programa deba de ajustarse a las condiciones del usuario. Hace no mucho tiempo una canción coreana se volvió inmensamente popular y la plataforma de videos más popular no estaba lista para poder llevar la cuenta, entonces un día, este video hizo lo impensable (por esas fechas) paso las 2,147,483,647 vistas y cómo vimos en el post anterior, un valor del tipo "int" no puede mostrar un número mas allá de ese y pasó lo que tenía que pasar, los desarrolladores se vieron en la necesidad de actualizar su código y ahora en lugar de usar una variable del tipo "int", optaron por usar valores de tipo long. Es una buena solución, ya que 922,337,203,685,477,507 es aproximadamente 131,762,457 la población de la tierra, más que suficiente en mi opinión.
Otro problema de este tipo surge con los equipos relativamente viejos, en ellos el tiempo se mide en segundos y se almacena en una espacio de 32 bits, haciendo cálculos, en el 2038 habrán alcanzado el limite que se puede almacenar en 32bits, pero este a diferencia del caso anterior es un poco mas complejo en su resolución. Muchos dirán que se puede arreglar con solo usar 64 bits para almacenar el tiempo, pero cuando se realizan operaciones de forma binaria se perdería compatibilidad con el software viejo. Muchos de los que previeron el problema hicieron que el hardware fuera compatible con 64bits y crearon software especifico para la plataforma, por lo que se evitarían el problema.

En el caso de las aplicaciones que he hecho para el blog, lo admito, he sido flojo, pero muchos de los errores que tienen son de los más básicos y por más simple que sea, siempre se debe de entregar software lo mas completo y listo posible. A partir de eso, la mayoría de programas se van a actualizar para quitar todas las partes "flojas".

Y bien por ahora es todo, los leo luego.

Back to basics #3 - Variables y sus tipos.

Hola de nuevo a todos, el día de hoy vamos a ver un poco más de las nociones básicas de programación.
En los post anteriores, hemos visto que resulta relativamente fácil portar un pedazo de código que hace algo, de una plataforma a otra, en el caso particular de C# y java, el código es especialmente parecido.
Al momento de crear código, uno debe de tener en mente que es lo que desea crear, pero no solo eso, también debe de imagina el cómo lo va a hacer, eso incluye: procedimientos,funciones y variables.
El caso de la variables es donde debemos de prestar especial atención ya que en ellas es donde se almacenarán los resultados de la ejecución, entonces si escogemos mal el tipo de variable, podemos echar a perder una buena ejecución.


El caso concreto: DecToAny.

Recientemente publiqué un par de programas que se encargaban de convertir un número decimal a cualquier base en el rango 2-35, todo parecía funcionar bien, eso al menos hasta el número 2,147,483,647, intentar convertir el número 2,147,483,648 produce un fallo que causa que la aplicación se detenga.
Al inspeccionar la imagen, podemos ver que el error es: OverflowException (en el caso de C#, pero te aseguro que es el mismo para java). Este tipo de errores/excepciones, se producen cuando intentamos asignar un valor más grande del que la variable puede manejar. hay que recordar que para almacenar el valor de entrada en la función que convierte el numero, usamos una variable del tipo "int" y si buscamos el valor máximo que este tipo de variable puede almacenar tenemos que es 2,147,483,647 y el mínimo es -2,147,483,648, eso quiere decir que se intentamos guardar un numero por arriba (o por abajo), simplemente no podremos hacerlo.

Un poco más del tipo int.

El tipo int es uno de los más comunes que usaremos, en la vida real hay muy pocas cosas que requieran un numero tan grande, pero porque solo puede almacenar ese numero? Bueno, la razón es porque utiliza un espacio de 32 bytes, pero no todos están disponibles para almacenar el valor del número, el primer byte (de izquierda a derecha), se usará para almacenar el signo, cuando este byte tenga 1, indicará que es un número negativo, para el caso contrario, será positivo.
Si cuentas los unos, verás 31 de ellos, el 32 está reservado para el signo.
Para solucionar el error, debemos de escoger una variable que pueda contener un valor más grande, pero que tenga características similares a la que usamos actualmente y la más parecida es "long" que puede almacenar un valor de -922337203685477508 a 922337203685477507, más que suficiente para nosotros. Por ahora queda de tarea ajustar el programa en C#.

Y bien, por ahora es todo, en el transcurso de la semana actualizaré los programas.
Por ahora es todo, los leo luego.

Vamos a programar #37 - DecToAny, Versión java (Android).

Hola a todos, el día de hoy vamos a ver una tercera entrega de la aplicación DecToAny, en los últimos dos post, vimos cómo crear una versión para Windows (hecha en C#), una versión para la web (hecha en javascript) y finalmente el día de hoy vamos a ver una versión para Android (hecha en Java).

Creando la interfaz.

La interfaz principal está compuesta por 4 componentes:
  • 1 TextView.
  • 1 EditText (Numérico).
  • 1 Button.
  • 1 ListView.
Todos los componentes se pueden crear con el siguiente código:

 <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
	xmlns:app="http://schemas.android.com/apk/res-auto"
	xmlns:tools="http://schemas.android.com/tools"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	tools:context="com.mdev.com.dectoany.MainActivity">

	<LinearLayout
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:orientation="vertical"
		tools:layout_editor_absoluteX="8dp"
		tools:layout_editor_absoluteY="8dp">

		<TextView
			android:id="@+id/lblNumberIn"
			android:layout_width="match_parent"
			android:layout_height="wrap_content"
			android:text="Número a convertir" />

		<EditText
			android:id="@+id/TXTNumberIn"
			android:layout_width="match_parent"
			android:layout_height="wrap_content"
			android:ems="10"
			android:inputType="number" />

		<Button
			android:id="@+id/BtnConvert"
			android:layout_width="match_parent"
			android:layout_height="wrap_content"
			android:text="Convertir" />

		<ListView
			android:id="@+id/LVResults"
			android:layout_width="match_parent"
			android:layout_height="match_parent" />
	</LinearLayout>
</android.support.constraint.ConstraintLayout>

Con esto, tendremos todos los controles necesarios para que el usuario interactue con la aplicación, ahora solo queda implementar el código que hace funcionar las cosas.

El Código que hace funcionar las cosas.

El código es muy parecido al que usamos para la versión de C#. Solo que en este caso, vamos a usar el control ListView para mostrar los resultados de las conversiones.
El código java de DecToAny es el siguiente:

package com.mdev.com.dectoany;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class MainActivity extends Activity {

	Button BtnConvert;
	ListView LVResults;
	TextView TxtNumberIn;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		BtnConvert = (Button) findViewById(R.id.BtnConvert);
		TxtNumberIn = (TextView) findViewById(R.id.TXTNumberIn);
		LVResults = (ListView) findViewById(R.id.LVResults);

		BtnConvert.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View view) {
				DoConvert();
			}
		});
	}

	private void DoConvert(){
		ArrayList Items = new ArrayList();
		String CurrentNumber = TxtNumberIn.getText().toString();
		int MyNumber = Integer.parseInt(CurrentNumber);
		for (int I = 2; I < 30; I++){
			Items.add(ListToString(NumbersList(MyNumber, I))+"\n"+"Base "+ I);
		}
		final ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1,Items);
		LVResults.setAdapter(adapter);
	}
	private String ListToString(List<Integer> Numbers)
	{
		Collections.reverse(Numbers);
		String Result = "";
		for (int i = 0; i < Numbers.size(); i++){
			int CurrentNumber = Numbers.get(i);
			if (CurrentNumber < 10)
				Result += CurrentNumber;
			else
				Result += NumberToChar(Numbers.get(i));
		}
		return Result;
	}
	private char NumberToChar(int Number){
			return (char)(Number + 55);
	}

	private List<Integer> NumbersList(Integer InNumber, int Base) {
		Integer LastNumber = InNumber;
		Integer Garbage;
		List<Integer> result = new ArrayList<Integer>();
		if (LastNumber < Base) {
			result.add(LastNumber);
		}
		else         {
			if (LastNumber >= Base) {
				do {
					Garbage = LastNumber % Base;
					LastNumber = LastNumber / Base;
					if (LastNumber < Base) {
						result.add(Garbage);
						result.add(LastNumber);
					} else {
						result.add(Garbage);
					}
				} while (LastNumber >= Base);
			}
		}
		return result;
	}
}

Para esta aplicación vamos usar 4 funciones, la primera de ellas en orden de uso (no de aparicion) es "NumberList", esta es la función que va a realizar los cálculos; cómo parámetros de entrada, recibirá un parámetro del tipo "Integer" llamado "InNumber" que es el número decimal que queremos convertir; seguido de una valor del tipo "int" llamado "Base", este; cómo su nombre lo indica; es la base de destino a la cual queremos convertir nuestro número decimal. La función regresa una lista del tipo "List<Integer>" con los valores de los dígitos para formar el número, pero en orden inverso.
Después tenemos la función "ListToString" que será la encargada de formar un número y devolverlo en forma de "String". Esta función recibe cómo parámetro un lista del tipo "List<Integer>". Esta función se encarga primero; en invertir el orden de la lista que se ingresa cómo parámetro. Después comprueba si el valor es menor a 10 (decimal), si es así, simplemente agrega al string "Result" (variable interna de la función) el valor actual, en caso contrario, manda a llamar a la función "NumberToChar" que se encargara de asignar una letra de la A a la Z a los valores mayores a 10. Finalmente devuelve un "string" que contiene la representación de los resultados de la función "NumberToList" en el formato adecuado para que cualquier persona lo pueda entender.
La función "NumberToChar" simplemente devuelve el numero que se ingresa cómo parámetro + 55.
Para la aplicación de Android también usamos un procedimiento llamado "DoConvert"; en el cual se manda a llamar a las otras funciones dentro de un bucle que va del 2 al 29. En este procedimiento se crea un "ArrayAdapter" que se llenará con los valores que se crean en el ciclo "for" y finalmente se asignan al "ListView".
Con esto podemos obtener de forma fácil el valor de un numero decimal en 27 bases diferentes. En todas las aplicaciones (Android, Windows, Web)no he revisado los errores que puedan haber, no porque sea perezoso o algo similar), pero un error critico existe en la version Web, en esta al poder escoger cual es la base a la que queremos convertir nuestro numero, podemos introducir base 1, pero esta base es imposible de usar, ya que solo disponemos del numero 0, entonces al hacer las divisiones, entramos al bucle "while", pero nunca podremos salir de el, y en algún momento la memoria se acabará hasta que finalmente el navegador en el cual se usa falle. Aunque el sentido común dice que no se debe de hacer lo antes descrito, nunca falta aquel que lo haga solo para saber que pasa. Para evitarlo basta con comprobar las base de destino, si es menor a 2, simplemente hay que informarle al usuario y terminar la ejecución.
Y bien, por ahora es todo, la aplicación compilada la puedes descargar de mi dropbox, el código lo subiré un poco después, primero voy a corregir un error minusculo en el proyecto. (Debería de ser com.mdev.dectoany, en su lugar puse com.mdev.com.dectoany ).

Los leo luego

Vamos a programar #36 - DecToAny, versión Javascript.

Hola de nuevo a todos, el día de hoy vamos a ver el mismo programa que vimos en el post anterior.
Te preguntarás, lo mismo, otra vez? En esencia es lo mismo, lo único que cambia es el lenguaje en el cual se ejecuta.

Inicialmente iba a hacer la aplicacion para andoid, pero gente me pidio una version en javascript, entonces por eso decidi hace primero esta versióm (y adivinaste, la semana que viene publicaré la version android).

El código.

El código en javascript que convierte de decimal a otras bases es el siguiente:
<html>
	<head>
	<title>Convertidor de decimal a otras bases</title>
	<style type="text/css">
	.h1Cal
	{
	   font-size: 14px;
	}
	.formDecToAny{
		font: 95% Arial, Helvetica, sans-serif;
		max-width: 400px;
		margin: 10px auto;
		padding: 16px;
		background: #F9F9F9;
	}
	.TextCal
	{
		width: 100%;
		box-sizing: border-box;
		border: 2px solid #999;
		border-radius: 4px;
	}

	.ButtonCal
	{
	width: 100%;
		background-color: #26c6da;
		border: none;
		color: white;
		padding: 15px 32px;
		text-align: center;
		text-decoration: none;
		display: inline-block;
		-webkit-transition-duration: 0.4s; /* Safari */
		transition-duration: 0.4s;
	}

	.ButtonCal:hover
	{
	width: 100%;
		background-color: #35d5e5;
		border: none;
		color: white;
		padding: 15px 32px;
		text-align: center;
		text-decoration: none;
		display: inline-block;
	}
	</style>
	<script type="text/javascript">

	function DecToAny(Number, Base){
		var LastNumber = parseInt(Number, 10);
		var Garbage;
		var result = []
		debugger;
		if (LastNumber < Base)
		{
			result.push(LastNumber);
		}
		else
		{
			while (LastNumber >= Base) {
				Garbage = LastNumber % Base;
				LastNumber = Math.floor(LastNumber / Base);
				if (LastNumber < Base)
				{
					result.push(Garbage.toString());
					result.push(LastNumber.toString());
				}
				else
				{
					result.push(Garbage.toString());
				}
			}
		}
		return result;
	}

	function NumberToChar(Number){
		if(Number < 10)
			return Number;
		else
			return String.fromCharCode(parseInt(Number, 10) + 55);
	}

	function ArrayToString(){
		var GetNumber = document.getElementById('InputNumber').value;
		var GetBase = document.getElementById('InputBase').value;
		if(GetNumber.length < 1 || GetBase.length < 1)
		{
			alert('El numero/base no puede estar en blanco');
			return;
		}
		var Convert = DecToAny(GetNumber,GetBase);
		var Out = "";
		Convert.reverse()
		for(var i = 0; i < Convert.length; i++)
		{
			Out = Out + NumberToChar(Convert[i])
		}
		document.getElementById('Result').value = Out;
	}
	</script>
	</head>
	<body>
		<form class="formDecToAny">
			<span class="h1Cal">Numero decimal a convertir:</span>
			<input class="TextCal" id="InputNumber" type="text"></input><br />
			<span class="h1Cal">Base a la cual convertir:</span>
			<input class="TextCal" id="InputBase" type="text"></input><br />
			<br />
			<input class="ButtonCal" id="ToAny" onclick="ArrayToString()" type="button" value="Convertir" /><br />
			<br />
			<span class="h1Cal">Resultado:</span>
			<input class="TextCal" id="Result" type="text"></input><br />
			<br />
		</form>
	</body>
</html>

El código esta formado por 3 funciones. La priera es "DecToAny", esta será la encargada de hacer los cálculos, hay que recordar que todo el proceso se lleva a cabo por una sucesión de divisiones. Esta función recibe dos parámetros, el primero es el número que queremos convertir, el segundo es la base objetivo. Devuelve una matriz que contiene los valores en orden inverso.

La segunda función es "NumberToChar", esta recibe un número cómo parámetro y lo único que hace es comprobar si el número es menor a 10, si es así, entonces solo devuelve el número que se ingreso, en caso contrario, convertirá el número ingresado cómo parámetro y lo devolverá con el valor correcto, hay que recordar que cuando usamos el décimo dígito en una base 12; por ejemplo; no podemos poner 0,2,3,4,5,6,7,8,9,10,11,12 (que serian los doce dígitos necesarios para representar todos los números simples hasta la base), en su lugar, debemos de recurrir a letras: 0,1,2,3,4,5,6,7,8,9,0,A,B. Con está función tenemos disponible hasta el dígito Z (base 35).
Finalmente tenemos la función "ArrayToString" que se encarga de convertir todos los datos de la matriz devuelta por la función "DecToAny" a un formato legible para las personas, internamente también llama a la función "NumberToChar" para que el resultado contenga letras cuando se hace uso del décimo o más. Cuando se quiera convertir un número, esta es la función que se debe mandar a llamar.

Para el formulario, solamente se hace uso de tres Textbox(text), uno servirá para introducir el número a convertir, otro recibirá la base de destino y el tercero mostrará el resultado. Ademas se hace el uso de un boton(button) que al hacer clic sobre el, mandará a llamar a la función "ArrayToString".

Cómo podrás ver, el código es realmente similar al de la versión C# que hicimos en el post anterior, con esto quiero demostrar que resulta relativamente fácil portar un programa de un lenguaje a otro, ahora solo queda pendiente la versión para android, pero eso será la semana que viene. Cómo siempre, el código completo lo puedes descargar de mi dropbox, pero además la versión online también esta disponible para su ejecución en este blog.

Por ahora es todo. Los leo luego.

Vamos a programar #35 - DecToAny.

Hola de nuevo a todos, el día de hoy vamos a ver código en C# que se encargará de convertir de un número decimal a cualquier base (en realidad hasta base 20). Al igual que en las ocasiones anteriores, gran parte del código, será una adaptación de lo que hemos hecho en post anteriores.

Haciendo un poco de memoria.

Para empezar recordemos que las conversión de un número decimal a un número en otra base, se realiza mediante divisiones sucesivas de el numero resultante de la división anterior entre la base. Si tenemos el numero X decimal y lo queremos pasar a la base B, debemos de dividir X/B y al resultado R, en la siguiente división lo dividiremos entre la base (B), este proceso se repite mientras que el resultado R sea mayor que la base.

Portando el código a c#.

Sabiendo lo anterior, podemos crear una funcion cómo la que sigue:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace DecToAny
{
 public partial class FrmMain : Form
 {
  private List<TextBox> TextBoxes = new List<TextBox>();
  private List<int> DecToAny(int Number, int Base)
  {
   int LastNumber = Number;
   int Garbage;
   List<int> result = new List<int>();
   if (LastNumber < Base)
   {
    result.Add(LastNumber);
   }
   else
   {
   while (LastNumber >= Base) {
    Garbage = LastNumber % Base;
    LastNumber = LastNumber / Base;
    if (LastNumber < Base)
    {
     result.Add(Garbage);
     result.Add(LastNumber);
    }
    else
    {
     result.Add(Garbage);
    }
   }
   }

   return result;
  }
  private string ListToString(List<int> Lista)
  {
   string Out = "";
   Lista.Reverse();
   foreach (int Numero in Lista) {
    if (Numero < 10)
    {
     Out += Numero.ToString();
    }
    else
    {
     Out += NumberToLetra(Numero);
    }
   }
   return Out;
  }
  public FrmMain()
  {
   InitializeComponent();
  }
  private char NumberToLetra(int Number)
  {
   return (char)(Number + 55);
  }
  private void FrmMain_Load(object sender, EventArgs e)
  {
   TextBoxes.Add(txtBase2);
   TextBoxes.Add(txtBase3);
   TextBoxes.Add(txtBase4);
   TextBoxes.Add(txtBase5);
   TextBoxes.Add(txtBase6);
   TextBoxes.Add(txtBase7);
   TextBoxes.Add(txtBase8);
   TextBoxes.Add(txtBase9);
   TextBoxes.Add(txtBase10);
   TextBoxes.Add(txtBase11);
   TextBoxes.Add(txtBase12);
   TextBoxes.Add(txtBase13);
   TextBoxes.Add(txtBase14);
   TextBoxes.Add(txtBase15);
   TextBoxes.Add(txtBase16);
   TextBoxes.Add(txtBase17);
   TextBoxes.Add(txtBase18);
   TextBoxes.Add(txtBase19);
   TextBoxes.Add(txtBase20);

  }

  private void BtnConvert_Click(object sender, EventArgs e)
  {
   for (int T = 0; T < TextBoxes.Count; T++)
   {
    TextBoxes[T].Text = ListToString(DecToAny(int.Parse(TxtNIn.Text), (T + 2)));
   }
  }
 }
}
El código anterior consta de 3 funciones. La función que hace gran parte del trabajo es "DecToAny", en ella se crean dos variables. La variable "LastNumber" será la encargada de almacenar el resultado de las divisiones anteriores. La variable "Garbage" será utilizada para guardar los "residuos" de las divisiones, estos son usados para formar el número final. Antes de siquiera empezar con el ciclo while, se hace una comprobación; si el número es menor que la base, simplemente se regresa una lista del tipo "int" con un solo elemento, en este caso, el mismo numero que se ingreso cómo parámetro para "Number". Si por el contrario el numero es igual o mayor que la base; se entra en el bucle while y  se comienzan a hacer las divisiones. En el bucle, se comprueba que el resultado de la división que esta almacenado en "LastNumber" sea mayor que la base. Cuando la base es mayor que el resultado de la división, el residuo de esta se agrega a la lista "result", pero cuando la condición ya no se cumple, entonces agrega a la misma lista el valor residual de la división y además el resultado de la misma. Finalmente devuelve una lista del tipo "int" con todos los valores.
La funcion "ListToString" se usa para convertir la lista del tipo "int" en un string (valga la redundancia). Para empezar, primero se invierte el orden en el cual están los elementos, hay que recordar que el resultado de las divisiones se usa en orden inverso en donde el primer digito, sera el residuo de la ultima division seguido del resultado entero de la misma seguido de los residuos del resto de las otras divisiones. Para devolver el resultado final, tambien se hace uso interno de la funcion "NumberToLetra", hay que recordar que para el decimo digito se usa la letra A.
Una vez que se ejecuta la función "DecToAny" hay que pasársela cómo parámetro a la función "ListToString" y el resultado será un string con una cadena equivalente al numero en la base especificada.

A tomar en cuenta.

Algo muy importante a tomar en cuenta es que las letras que se usan representan los valores más allá del decimo digito. Para el decimo digito usamos la A y asi sucesivamente hasta la Z (incluso más) La siguiente tabla muestra los valores disponibles.
ABCDEFGHIJKLMNOPQRSTUVWXYZ
1011121314151617181920212223242526272829303132333435
Entonces la base más grande que podemos usar es 35, pero eso solo para mantener humanamente legible cualquier número,pero podríamos seguir con el siguiente carácter ascii (que es el que usamos) y así el número Z0 sera algo totalmente diferente a z0.

Cómo de costumbre el código fuente completo lo puedes descargar de mi dropbox.
Por ahora es todo, los leo luego

Back to basics #2 - Convirtiendo decimal a otras bases.

Hola de nuevo a todos, el día de hoy vamos ver cómo convertir números de decimal a las bases más comunes.

Antes de empezar, cuales son las bases más comunes? Las bases más comunes son: binario, octal, decimal y hexadecimal.
Prácticamente todas las conversiones se hacen mediante divisiones sucesivas entre el número base. por ejemplo vamos a convertir el número 7956 decimal a octal.

Para empezar dividiremos entre 8, pero solo haremos una división entera. Al hacerla obtenemos el número 994, ademas hacemos la operación MOD (obtenemos el residuo de la división) y obtenemos 4, este numero lo guardamos a parte. Al resultado de la división entera lo vamos a dividir nuevamente; es decir, a 994 los dividimos entre 8 y además hacemos la operación MOD, las divisiones se repetirán mientras el número de resultante de la división previa sea mayor que la base a la cual queremos convertir. Entonces tenemos algo cómo lo que sigue:

  • 7956/8 = 994; 7956 mod 8 = 4.
  • 994/8 = 124; 994 mod 8 = 2.
  • 124/8 = 15; 124 mod 8 = 4.
  • 15/8 = 1; 15 mod 8 = 7.

Cuando llegamos a la ultima division, solo nos resta organizar los números, para hacerlo, vamos a tomar el resultado de la ÚLTIMA y solo de la última y lo pondremos cómo el primer dígito del resultado, en este caso el numero es 1, luego tomaremos el residuo (o resultado de la operación mod) y los escribiremos a continuación, entonces tenemos 17, luego solo anotaremos los residuos en orden de penúltimo a primero, y tendremos 17424. Con las operaciones anteriores tenemos que el número 7956 en base decimal, es igual a 17424 en base octal.

Para convertir un numero a base hexadecimal repetiremos los pasos anteriores solo que en está ocasión dividiremos entre 16.

  • 7956/16 = 497; 7956 mod 16 = 4.
  • 497/16 = 31; 497 mod 16 = 1.
  • 31/16 = 1; 31 mod 16 = 15.
  • Acomodando tenemos 1F14.
Y ahora que sabemos el proceso, podemos convertir a cualquier base, por ejemplo a base 3. solo tenemos que repetir los pasos anteriores. Tomando cómo ejemplo el mismo número tenemos:

  • 7956/3 = 2652; 7956 mod 3 = 0
  • 2652/3 =  884; 2652 mod 3 = 0
  • 884/3 = 294; 884 mod 3 = 2
  • 294/3 = 98; 294 mod 3 = 0
  • 98/3 = 32; 98 mod 3 = 2
  • 32/3 = 10; 32 mod 3 = 2
  • 10/3 = 3; 10 mod 3 = 1
  • 3/3 = 1; 3 mod 3 = 0.
  • Acomodando tenemos 101220200.


La semana que viene vamos a hacer una calculadora para convertir de decimal a cualquier base (hasta 20).Por ahora es todo, los leo luego.

Back To basics #1 - Convirtiendo números en diferentes bases a decimal..

Hola de nuevo a todos el día de hoy vamos a ver un tema un tanto sencillo.

Hace algunos días, mientras navegaba por un foro de programación, me encontré con alguien que mostraba cómo hacer la conversión de un numero hexadecimal a decimal, al entrar todo estaba bien, o al menos eso era en apariencia, ya que al momento de explicar cual era el sentido de hacer la conversión no supo que decir (aun teniendo el internet a la mano), entonces una lluvia de criticas le cayeron. El único argumento que pudo dar en su defensa fue: "Pues háganlo ustedes". Y bueno aquí vamos.

Por qué usar una base diferente a 10?

En compactan hay que recordar que internamente se usan solo dos números: el 1 y el 0, que son la cantidad mínima representable (encendido o apagado). Para trabajar en la computadora se usan Bytes y cada Byte esta compuesto de ocho bits, entonces el numero máximo que se puede representar usando ocho bits es 11111111 (hay que tener algunas consideraciones con respecto a como se interpretan los datos en una computadora, pero por ahora solo convertiremos ese numero en "crudo").
La computadora entenderá perfectamente esos numero, pero que pasa si un humano quiere saber cual es el numero que representa 10010001? Para eso es necesario convertirlo a una base con la que ya estemos familiarizados.
Los números se pueden representar en cualquier base a partir de 2, puede ser base 3, base 5, incluso base 20. La base con la que estamos familiarizados es la base 10, pero antes de seguir, de seguro te preguntas: que es una base? Bien, la explicación mas sencilla es, la cantidad de números disponibles para representar un valor mas grande. Por ejemplo, en un numero de base dos, solo se dispone de los números 0 y 1. En un numero de base diez, se disponen de los números 1,2,3,4,5,6,7,9,0. Para representar un número más grande que diez, se empiezan a usar las potencias de diez y para el caso de la base dos, para representar un numero más grande que dos se usaran potencias de dos.

Para continuar con el meollo del asunto, ahora sabemos que ocho bits pueden representar el numero 11111111 en base dos, para convertirlo, solo vamos a multiplicar el valor de cada numero por su potencia correspondiente empezando de izquierda hacia la derecha y se empezara por la base elevada a la potencia cero.
2^7 (128)2^6 (64)2^5 (32)2^4 (16)2^3 (8)2^2 (4)2^1 (2)2^0 (1)
11111111
Mirando la tabla anterior tenemos que el valor de 11111111 en base dos es igual a la suma de 2^0 hasta 2^7, haciendo la cuenta esto resulta en 255 decimal. Para convertir el numero 10010001 de base dos a base 10, debemos de hacer lo mismo que hicimos antes, debemos de multiplicar el valor del dígito por si potencia y tendriamos algo cómo lo que sigue:
2^7 (128)2^6 (64)2^5 (32)2^4 (16)2^3 (8)2^2 (4)2^1 (2)2^0 (1)
10010001
Al hacer las sumas obtenemos que el número 10010001 de base dos es igual a 145 en base 10.

Y ahora la pregunta del millon, por que usar la base 16? La base 16 es muy comun usarla para representar los numero en computacion, si recuerdas los post: "Cómo extraer una imagen embebida en un mp3", usabamos un visor hexadecimal para ver la informacion dentro del mp3.
Esto es así debido a que el número 11111111 (255) es equivalente a FF en hexadecimal. Antes de seguir hay que saber esto. Para evita confusiones, cuando usamos una base que tiene digitos más alla de nuestro 9, debemos de usar símbolos, asi evitamos confundir números, en el caso del hexadecimal, se deben de usar 16 caracteres para representar, entonces empezamos desde el 0 hasta la F, despues del 9 seguiría el 10, para evitar confusiones usamos la letra A(10), B(11), C(12), D(13), E(14) y F(15).
Al igual que con la base dos, se usaran potencias, pero en este caso serán potencia del número 16
16^1 (16)16^0 (1)
FF

entonces para representar el el numero 11111111 solo debemos de usar dos dígitos en base 16, basta con usar FF para representar cada valor posible de un byte. para valores hexadecimales más grandes, bastará con usar la siguientes potencias.
Y bien, por ahora es todo, en el siguiente post vamos a hacer el proceso inverso y más adelante una aplicación para android que convierta entre cualquier base.

Los leo luego.