domingo, 31 de octubre de 2010

Erlang

Laboratorio

Erlang
Es un lenguaje funcional y de programación concurrente, fue diseñado por la compañía Ericsson con el propósito de hacer aplicaciones que puedan soportar fallos, funcionamiento ininterrumpido, aplicaciones distribuidas, entre otras cosas.
Tiene una característica muy importante "el cambio de código en caliente" el cual se refiere a poder modificar el código aun cuando la aplicación esta corriendo. Erlang no seguía la filosofía de código abierto hasta 1998 cuando Ericsson lo cedió como tal.
Erlang es un lenguaje interpretado, aunque también se puede compila usando el compilador HiPE, aunque este compilador solo es para algunas plataformas es muy bueno porque pude soportar la concurrencia característica muy distintiva del lenguaje. Esta es la pagina oficial de HiPE.
Es posible que pensemos que entender este proceso de concurrencia es complicado y más aun aplicarlo en algún programa pero en Erlang la concurrencia es explicita y no implícita con en otros lenguajes.
El nombre de Erlang viene de las palabras Ericsson y Language.

Erlang lenguaje funcional
Los programa en Erlang están compuestos de bloques "funciones" y las identificamos por su nombre y el numero de argumentos de entrada también llamado "aridad". Por ejemplo las funciones multiplicacion/2, multiplicacion/3, multipicacion/4 pueden existir perfectamente juntas y llamándose a cada una según el numero de datos que se introduzca por el usuario, los resultados que devuelven las funcione son puede ser de cualquier elemento soportado por Erlang flotante, tupla, entero, lista, etc.
mi_funcion(dato1, dato2, ...) ->
instrucción,
instrucción,
resultado_a_devolver
También podemos escribir alguna condición antes de ">" podemos poner que si se cumple algo entonces se lleve acabo determinada instrucción esto lo hacemos con "when" una forma de implementarlo seria seria:
mi_funcion(dato1, dato2) when dato1 > 0 ->
y algo muy importante en Erlang aprender a escribir el ".".
Hice un programa en Erlang que muestra su característica como lenguaje funcional, bueno primero que nada abro el terminal y escribo:
cecy@cecy-desktop:~$ emacs -nw geom.erl
Notemos los programas escritos en Erlang tienen la extensión .erl y lo estoy llamando geom, ahora escribo mi programa que obtiene el perímetro de diferentes figuras geométricas el circulo, rectángulo, triángulo y cuadrado, podemos ver que para calcular el perímetro de cada figura se necesitan determinados números de datos de entrada por ejemplo para calcular el área del circulo solo ocupamos la medida del radio es por eso que se declara -export([circulo/1])., pero para calcular el perímetro de un rectángulo se necesitan dos por consiguiente se declara así: -export([rectangulo/2])., vemos que antes de declarar las funciones se escribe module(algo), ese "algo" no es cualquier cualquier cosa siempre debe ser el mismo nombre que el del programa en mi caso "geom" y otra cosa muy importante las variables se escriben en mayúsculas :D que no se te olvide.
Código:

-module(geom).
-export([circulo/1]).
-export([cuadrado/1]).
-export([rectangulo/2]).
-export([triangulo/3]).

circulo(R) ->
2*R*3.1416.

cuadrado(L) ->
L*4.

rectangulo(A,B) ->
2*A+2*B.

triangulo(A,B,C) ->
A+B+C.

Ahora que ya escribí mi programa tengo que compilar el modulo desde Erlang para ver si no marca ningún error, la manera de hacerlo es escribimos erl en el terminal y luego c(geom)., esta es la captura de pantalla:



Como todo esta bien en el código podemos ver "{ok, geom}", ahora si podemos obtener el perímetro de las figuras de esta manera escribimos el nombre_del_modulo:nombre_funcion(dato1, dato2...datox). en mi caso escribo:


y cuando escribimos más datos de entrada a alguna función de los que acepta nos marca error por ejemplo:



Las características mas destacadas de Erlang son:
  • Lenguaje funcional
  • Soporte de concurrencia
  • Tolerancia a fallas
  • Cambio de código en caliente
  • Posibilidad de conectar con código C, Java y otros lenguajes
La concurrencia es una característica importantísima del lenguaje fue creada especialmente para las aplicaciones de telecomunicaciones: gran disponibilidad, cambiar código sin detener la aplicación, etc.

La información la obtuve leyendo estos sitios:
Ejemplos en Erlang
Lenguaje Erlang
Erlang: un lenguaje declarativo, concurrente y distribuido para aplicaciones de telecomunicaciones

sábado, 30 de octubre de 2010

Máquina de Turing

Laboratorio

La máquina de Turing es un modelo computacional ideado por Alan Turing en el trabajo "On computable numbers, with an application to the Entscheidungs problem", publicado en 1936 para resolver cualquier operación matemática computable; es decir que se pueda realizar en forma mecánica. Su función es definir los cálculos a partir de las operaciones más sencillas posibles.
Las funciones que si pueden calcularse se llaman funciones computables o calculables.


La máquina de Turing universal es una máquina que puede ser capaz de simular el comportamiento de otro máquina Turing, gracias a la existencia de esta máquina ahora podemos disponer de ordenadores electrónicos que pueden realizar cualquier calculo computable.
La maquina de Turing es computacionalmente completa porque puede resolver cualquier problema recursivamente enumerable.
Ha encontrado su aplicaron en el campo de la complejidad de algoritmos en problemas que comparan las resoluciones de un problema, para detectar la dificultad de cada método.
El tipo de problemas NP-completos son imposibles de resolver en tiempo razonable cuando el numero de elementos es muy grande. Los campos de problemas P(sencillos) y NP(complejos), tienen relación con las maquinas Turing ya que sus nombres significan los que se pueden resolver en un tiempo polinómico(P) en una maquina de Turing determinista y los segundos los que se pueden resolver en una maquina de Turing no determinista(N)

Definición y funcionamiento

Las máquinas de Turing constan de una cinta dividida en casillas, hay un dispositivo que se encarga de desplazarse de casilla en casilla una a la vez, este dispositivo tiene un cabezal que lee el símbolo de la cinta, lo puede borrar e imprimir uno nuevo.

También tiene un registro que almacena los símbolos de los estados de las casillas, estos símbolos no tiene que ser iguales a los símbolos de lectura o escritura. En los ejemplos que voy a presentar más adelante los símbolos de lectura van a ser 0 y 1, aunque bien podrían ser cualquiera otros y los símbolos de estado los represento con letras también pueden ser cualquieras otros.
Su manera de funcionar es mecánica y secuencial, se obtiene el símbolo que hay en la casilla y el símbolo de estado, con estos dos datos se puede acceder a una tabla que va a indicar cuál va a ser el nuevo símbolo que se escribirá en la lista , el símbolo del estado y la dirección a desplazarse.
Aquí un ejemplo:
Lo que nos dice el primer renglón es que cuando se está en estado A y la casilla contiene un 0, este pasa a ser estado B y el 0 ahora es un 1, se desplaza hacia la derecha y ahora tenemos que cuando se está en estado A con un 1 en la casilla pasa a ser estado B y el uno se hace 0 y se desplaza a la izquierda.

El segundo renglón indica que cuando está en estado B y con un 0 en la casilla pasa a ser estado A y el 0 se hace 1 y se desplaza hacia la derecha, ahora cuando es estado B y contiene un 1 en la casilla pasa ser estado C y el 1 se hace 0 y el desplazamiento es hacia la derecha.

Y en el tercer renglón cuando tenemos estado C con un 0 en la casilla este pasa a ser estado A y el 0 se queda en 0 con un desplazamiento hacia la izquierda y cuando está en estado C con un 1 en la casilla se queda en estado C pero el 0 se 1 se convierte en 0.

La rutina borracintas
Se trata de escribir puros ceros en la cinta y que no quede niun uno, podría pensarse en hacer que se borren todos los unos que se encuentren y se remplacen por el 0
Pero esto solamente borraría un lado de la cinta el derecho a partir del punto de partida, entonces se tendría que modificar ese método:


Aunque este método aún tiene un problema, ¿Qué pasaría si hay más unos de un lado que del otro?, en este caso cuando la maquina termine de borrar todos los unos de un lado, se termina el proceso y quedarían los unos del otro lado sin ser borrado, entonces lo que se debe hacer para conseguir eliminar todos los unos es que cada vez que la maquina encuentre un uno le ponga un cero y escriba un uno en la posición siguiente y cambie su sentido, estos unos sirven como barreras así cada vez que la máquina encuentra un uno se desplaza una posición e invierte su sentido y así es como la máquina recorrerá por igual del lado derecho y el izquierdo.

Enlaces:

martes, 26 de octubre de 2010

Flujo de Control

Laboratorio

El control de flujo se refiere al orden en que se ejecutan las instrucciones que tenemos en el programa.
El orden puede ser ascendente, descendente o podemos ejecutar un conjunto de instrucciones alguna determinada cantidad de veces en donde se modifique algunos valores y hasta que el valor cumple alguna condición se dejen de ejecutar esas instrucciones.
Determinar el orden de las instrucciones depende primordialmente de el algoritmo que queremos desarrollar en el programa.

Flujo secuencial
Se refiere a la ejecución de instrucciones una trás otra, es decir de una línea, a la siguiente sin saltarse ninguna, es en dónde la salida de una es la entrada de otra.
El flujo secuencial es casi inexistente, ya que en muchos programas se hacen llamadas a funciones y esto hace que no sea secuencial.
Función
Cuando se llama a una función se hace un salto ya sea condicional o incondicional, se ejecuta el "bloque de código" determinado, y cuando finaliza el bloque se regresa a la dirección que se guardado en la memoria antes de realizar el salto, la función hace que se regrese a esa dirección con la instrucción "volver". Esto es a lo que podemos llamar función, subrutinas o subprogramas.

Flujo alternativo
Es cuando el contador del programa no sigue la siguiente instrucción(como en el flujo secuencial) y se salta directamente a otra aunque este en una dirección de memoria más alejada, puede ser que se salte a otra linea incondicionalmente, es decir de manera obligatoria, o que se haga condicionalmente que es cuando alguna expresión cumple alguna determinada condición y se brinca a otra instrucción. También se pueden combinar los saltos condicionales e incondicionales, es decir que se haga un salto a un bloque de código si la expresión resultara ser verdadera o otro bloque si es falsa.
Para conseguir el flujo alternativo se debe calcular la dirección de la instrucción que sigue.

Flujo selectivo
Se utiliza cuando para realizar algún programa se tienen diferentes casos y que los podemos identificar con algún valor, este valor nos va a ayudar a saber si es cierto caso a que bloque de código se debe de brincar. Es como tener un tipo directorio en el que tenemos registrado el identificador del caso que puede ser un valor "x" con el correspondiente bloque de código que debe ejecutar.
Cuando se tienen muchos diferentes casos es más ventajoso utilizar el flujo selectivo que el flujo alternativo ya en el flujo alternativo seria ir checando si determinado valor coincide con cada uno de los bloques de código.

Flujo repetitivo
Por ejemplo cuando en un bloque de código se tiene una instrucción incondicional que salte al principio de ese bloque de código diríamos que estamos teniendo un flujo repetitivo aunque en este caso infinito, pero si en cambio tenemos nuestro bloque de código, con alguna variable que vaya cambiando su valor y al final una instrucción condicional en la que se finalice ese bloque de código si el valor de la variable cumple cierta condición y si no lo cumple se regrese al principio del bloque, entonces tenemos un flujo de control en el que el bloque del código se ejecuta al menos una vez. Podría ser distinto, hay algunas ocasiones en las que puede que no se ejecute ni una sola vez, esto se logra escribiendo la instrucción condicional al principio de la misma en donde el bloque se ejecuta siempre y cuando se cumpla con la condición.
En resumen el flujo repetitivo consiste en ejecutar cierto bloque de código hasta que se cierta una situación determinada.



Enlaces:
http://maxus.fis.usal.es/FICHAS_C.WEB/00xx_PAGS/0006.html
http://teleformacion.edu.aytolacoruna.es/PASCAL/document/flujo.htm#intro

lunes, 25 de octubre de 2010

Lenguajes funcionales

Laboratorio

Haskell

Haskell es otro lenguaje funcional, entre sus características más notables están en manejo de tipos de datos, funciones recursivas, listas , tuplas, guardas y calce de patrones.
En 1990 se definió la primera versión de Haskell(Haskell 1.0), después en 1997 "Haskell 98" con el que se intentó hacer una versión del lenguaje mínima estable y portable. A inicios del 2006 se se empezó el proceso de Haskell' que es una nueva versión de Haskell 98.

Tipos de datos

  • Bool
    Este tipo de datos puede ser true o false.

  • Int
    Son los números enteros que pueden estar en el intervalo [-2^29, 2^29 - 1]

  • Integer
    Son iguales al tipo "int" solo varía en en que tiene precisión ilimitada y los int limitada.

  • Float
    Son los números reales.

  • Double
    También son números reales solo que con aproximaciones más precisas que float.

  • Char
    Son caracteres.

  • Tuplas
    Es una lista con un número ilimitado de objetos, sus elementos pueden ser de distintos tipos.

  • Listas
    Es una colección de elementos del mismo tipo.

    Para empezar a programar en Haskell necesitamos un interprete "Hugs" para poder correr los scripts, trabaja con archivos de extensión .hs.
    Primero que nada debemos instalar el interprete Hugs:

    • cecy@cecy-desktop:~$ sudo apt-get install hugs

      ya que se termina de instalar tecleamos en el terminal:

      cecy@cecy-desktop:~$ hugs

      y aparecerá algo como esto:


      ahora tenemos esto en el terminal "Hugs>" lo que significa que podemos empezar a programar en Haskell.

      Las instrucciones en Haskell van precedidas de : por ejemplo cuando queremos salir del interprete hugs se escribe :quit o simplemente :q.

      Los programas en Haskell tienen la extensión .hs, para llamar algún archivo .hs se escribe :loads nombredelarchivo.hs

      Dos grandes ventajas de Haskell:

      Poliformismo
      Esto significa que las funciones pueden ser definidas para trabajar con distintos tipos de datos.

      Listas infinitas
      Lo que en muchos lenguajes se llama arreglos, en Haskell se trabaja con listas que contienen elementos "infinitos".

      Ahora algunos ejercicios para empezar a practicar con Haskell:

      Voy a hacer el programa potencia con distintas definiciones:

      Con condicionales:

      pot1 :: Num a => a -> Int -> a
      pot1 b e = if e == 0 then 1
      else b * pot1 b (e-1)

      Ejecución:


      Mediante guardas, las guardas se utilizan para evaluar alguna condición hasta que alguna sea true y "otherwise" se utiliza cuando no se cumplo la condición anterior:

      pot2 :: Num a => a -> Int -> a
      pot2 b e
      | e == 0 = 1
      | otherwise = b * pot2 b (e-1)

      Ejecución:


      Mediante patrones:

      pot3 :: Num a => a -> Int -> a
      pot3 b 0 = 1
      pot3 b e = b * pot3 b (e-1)

      Ejecución:


      Restricción del dominio mediante guardas:

      pot4 :: Num a => a -> Int -> a
      pot4 b e
      | e == 0 =1
      | e >= 1 = b * pot4 b (e-1)

      Ejecución:

domingo, 24 de octubre de 2010

Lenguajes funcionales

Entrada para la materia de Lenguajes de Programación
Y de nuevo R

Hacer un programa que muestre los N primeros términos de la serie. 1, 2, 4, 8, 16, 32, 64, 128, ? N es un valor que va ha de entrar desde el teclado.

En este programa hice uso del for, if/else, pero no es igual que mis programas hechos anteriormente ya que este lo realicé en un archivo.R es decir, fuera del terminal

Primero que nada abrí mi archivo en emacs que llamé serie.R y escribí:

n <- scan() #leo cuantos numeros se quieren ver de la serie
numeros[1]<-1
for(i in 1:n){ #estructura for
if(i == 1){ numeros[i] <- 1} #estructura if
else {numeros[i] <- numeros[i-1]*2}
}

Ahora guardo mi archivo y escribo R en el terminal, luego escribo source("serie.R") para ejecutar las ordenes que vienen en ese archivo:
> source("serie.R")
1: 10
2:
Read 1 item
Luego se van a escribir las salidas en un archivo aparte con la extensión.lis y enseguida escribo las variables que quiero que aparezcan en el archivo (yo escribí números):
> sink("serie.lis")
> numeros

y este es mi archivo serie.lis:

El ejercicio lo obtuve de una página en la que proponen ejercicios simples en C.

Espero que les sea útil esta entrada, batalle en hallar como se podían escribir las instrucciones en un archivo.r, es decir con la forma de ejecutarse, si alguien encontrara otra forma más simple agradecería sus comentarios, saludos a todos.

Lenguajes funcionales

Entrada para laboratorio

Suma de vectores en R

Función sum() Bastante fácil!!
En estos programas utilizo scan() que sirve para leer valores, esta es su forma de funcionar, aparece un 1: para que escribas el primer valor, luego 2: mientras sigas dando enter y escribiendo valores se seguirán guardando, pero cuando presiones dos veces enter deja de leerlos. Después la función sum(x) que suma todos los valores que contiene x.

Ejemplo:
> 
x <- scan()
1: 5
2: 1
3: 10
4: 8
5: 14
6: 7
7: Read 6 items
> sum(x)
[1] 45
Sumar con for
Aquí hago uso de un for para ir sumando cada elemento de x, la función length(x) sirve para obtener cuantos elementos tiene x.

Ejemplo suma:

> x <- scan()
1: 5
2: 1
3: 10
4: 8
5: 14
6: 7
7: Read 6 items
> for(i in 1:length(x))
{ y <- y + (x[i])}
> y
[1] 45

Más ejemplos con for

Ejemplo factorial:

Factorial de 5

> factorial <- 1
> x <- scan()
1: 5
2: Read 1 item
> for(i in 1:x) { factorial <- factorial*i }
> factorial
[1] 120

Factorial de 100

> factorial <- 1
> x <- scan()
1: 100
2: Read 1 item
> for(i in 1:x)
{ factorial <- factorial*i }
> factorial
[1] 9.332622e+157

Lenguajes funcionales

Laboratorio de Lenguajes de programación

Más de R

Asignación de valores
La asignaciones de valores se hace por medio de "<-" y la función ls() sirve para ver los objetos en memoria:

> x<-1
> y<-5
> ls()
[1] "x" "y"
También podemos usar ls(pat = "x") para ver los objetos que contengan el carácter "x":
> ls(pat = "x")
[1] "x"
Para ver más detalles de los objetos podemos usar:
> ls.str()
x : num 1
y : num 5

Las cadenas de caracteres se delimitan con "":

> mi_cadena <- "esta es la cadena"
> mi_cadena
[1] "esta es la cadena"
> cat(mi_cadena)
esta es la cadena
La función cat() sirve para mostrar la cadena sin las ""

Leer datos de un archivo
Para esto voy a utilizar la función read.table() que es la manera más usual de leer datos, asigna por default a as columnas el nombre $V1, $V2, etc., y podemos acceder a ellas escribiendo nombredevariable$V1, la función read.table() tiene algunas características definidas:
read.table(file, header = FALSE, sep = "", quote = "\"’", dec = ".",
row.names, col.names, as.is = FALSE, na.strings = "NA",
colClasses = NA, nrows = -1,
skip = 0, check.names = TRUE, fill = !blank.lines.skip,
strip.white = FALSE, blank.lines.skip = TRUE,
comment.char = "#")
Voy a explicar algunas:

file:
Se refiere al nombre del archivo que vamos a leer.

header:
Sirve para definir si el nombre de la columna ya esta especificado en el archivo en la primera línea.

sep:
la separación de la columnas.

row.name :
Nombre de las filas por defecto 1,2,3....

col.name :
Nombre de las columnas por defecto (V1, V2..).

skip :
El número de lineas ignoradas antes de leerlas.

fill :
Si es true agrega espacios en blanco a las variables que falten en la línea.

strip.white :
Borra espacios blancos antes y después de la línea de caracteres.

blank.lines.skip :
Si es true ignora las líneas en blanco.

Para explicarlo mejor cree un ejemplo, primero que nada hice una pequeña "base de datos" la cual llame ejemplo1.txt, este archivo será el que leeré con la variable contenido:

> contenido <- read.table("ejemplo1.txt")
> contenido
V1 V2 V3
1 computadoras 7000 dell
2 teclados 100 dell
3 bocinas 150 toshiba
4 computadoras 4000 acer
Vemos que en el ejemplo anterior no modifiqué las características definidas de las tablas, ahora voy a mostrar uno en el que si lo haga, voy a darle nombre a las columnas cambiando el valor de header "falso" a "verdadero" ahora podemos ver que toma los nombres de las columnas de la primera línea.

> contenido <- read.table("ejemplo1.txt", header = TRUE)
> contenido
computadoras X7000 dell
1 teclados 100 dell
2 bocinas 150 toshiba
3 computadoras 4000 acer

También esta la función read.fwf("ejemplo2.txt", widths=c(1, 4, 3)) la cual da un valor especifico a las columnas, en donde estoy diciendo que quiero que la columna 1 tenga 1 carácter, la columna 2 tenga 4 caracteres y la columna 3 contenga 3 caracteres, el archivo que voy a leer llamé ejemplo2 y contiene lo siguiente:

unodostrescuatro
cincoseissieteoc
nuevediezoncedoc
trececatorcequin

y la lectura del archivo se ve como sigue:

> contenido <- read.fwf("ejemplo2.txt", widths=c(1, 4, 3))
> contenido
V1 V2 V3
1 u nodo str
2 c inco sei
3 n ueve die
4 t rece cat
Guardar datos en un archivo
También podemos guardar el contenido de algún objeto en algún archivo con la función write(objeto, file), en el ejemplo siguiente mi objeto se sigue llamando "contenido" y todo lo voy a guardar en mi archivo ejemplo3.txt:

> contenido <- "estoy guardando datos desde R"
> write(contenido, file="ejemplo3.txt")
Y el archivo que genera:


Escribir los valores
Podemos escribir los valores de un objeto con la función c(valor1, valor2, valor3), o también la función scan() ejemplos:

> x<-c(1, 2, 5, 10)
> x
[1] 1 2 5 10
> y<-scan()
1: 41
2: 52
3: 32
4: Read 3 items
> y
[1] 41 52 32
Operaciones
Podemos obtener la suma, el producto, el valor máximo, mínimo, promedio y la mediana utilizando funciones como sum(x), prod(x), max(), min(), mean(), median(), también sort() para ordenar elementos de mayor a menor o para hacer lo contrario rev(sort()), entre muchas otras funciones.

> x
[1] 1 2 5 10
> sum(x)
[1] 18
> max(x)
[1] 10
> median(x)
[1] 3.5
> mean(x)
[1] 4.5
> prod(x)
[1] 100
> rev(sort(x))
[1] 10 5 2 1

Graficando
Ahora podemos graficar un conjunto de datos, combinandolo con lo explicado anteriormente "leer archivos":

> contenido<-read.table("ejemplo4.txt", header = TRUE)
> plot(contenido$nombre, contenido$calif)
Resultado:


Cualquier sugerencia pueden hacerla con confianza, tratare de responder lo más pronto posible.

Detección palíndromos

Materia Lenguajes de Programación

Hola compañeros, esta semana todos presentamos nuestro pseudocódigo imperativo de temas distintos, yo elegí Detección de palíndromos para profundizar más en el tema me dí a la tarea de implementar el código en C y Python

Bueno este es el código en C


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

int main(){
char* cadena = (char*)malloc(100);
char* cadena1 = (char*)malloc(100);
printf("Escribe la cadena\n");
gets(cadena);
int n, numero, es, i, j;
es = 1;
j = 0;
char x = ' ';
n=strlen(cadena);
for(i=0;i<=n;i++){
if (isupper(cadena[i]))
cadena[i] = tolower(cadena[i]);
if(cadena[i] != x){
cadena1[j] = cadena[i];
j++;
}
}
printf("%s\n", cadena1);
numero = strlen(cadena1);
printf("%d\n", numero);
for(i=0;i<=numero/2;i++){
if(cadena1[i] != cadena1[numero-i-1])
es = 0;

}
if(es)
printf("Si es palindromo\n");
else
printf("No es palindromo\n");

free(cadena);
free(cadena1);

}


Primero que nada agregué las librerías:
stdio.h
Es para las entradas y salidas estándar.

string.h
Está librería es para poder agregar la función strlen() que me dice cuantos caracteres tiene la frase.

stdlib.h
Se agrega para poder usar malloc y free.

ctype.h
Me permite usar las funciones para saber si hay mayúsculas (isupper) y la función para convertir mayúsculas a minúsculas(tolower).

Después uso punteros para reservar memoria para la frase que se va a introducir ya que no se sabe cuantas letras tendrá, se pide la frase al usuario y se obtiene el tamaño de la cadena para saber cuantas veces se repetirá el ciclo for y empezar a checar si hay alguna palabra que contenga mayúsculas para así convertirla a minúscula y también eliminar los espacios en blanco.

Después de que se eliminaron todos los espacios en blancos y toda la frase esta en minúsculas podemos empezar a hacer la comparación de el primer carácter con el ultimo, el segundo con el penúltimo y así hasta haber comparado todos los caracteres y saber si es o no un palíndromo.

Ejecución cuando sí es palíndromo:


Y cuando no:


Y el código en python:


#!/usr/bin/python
cadena = raw_input("Introduce la cadena\n")
print(len(cadena))
cont = 0
cadena2="";
es = 1

for i in cadena:
if i.isupper():
i = i.lower()
if i != " ":
cadena2 = cadena2 + i
cont = cont + 1

for i in range(cont/2):
if cadena2[i] != cadena2[cont-i-1]:
es = 0
break

if (es):
print "es palindromo"
else:
print "no es palindromo"



Ejecución:


Es exactamente lo mismo que en C, solo que un poco más fácil :D, antes de haber desarrollado este código python había hecho otro que me creaba otra cadena pero con el contenido de la primera al revés, y eso me sirve para así comparar la cadena original con la segunda cadena, aunque me pareció muy fácil su desarrollo, esta no es la forma óptima de detección de palíndromos, la mejor es la que publiqué anteriormente, de todas formas aquí les dejo también el código como práctica.


#!/usr/bin/python
frase1 = ""
frase2 = ""
cadena = raw_input("Introduce la cadena")
for i in cadena:
if i.isupper():
i = i.lower()
if i != " ":
frase1 = frase1 + i #creo dos cadenas innecesarias
frase2 = i + frase2
if frase1 == frase2:
print "es palindromo"
else:
print "no es palindromo"

lunes, 18 de octubre de 2010