jueves, 29 de octubre de 2015

Fibonaccis y coálgebras en Haskell


Este es un archivo en modo "Haskell literario"

> x = 2
> y = (\x -> x+2) 2

"Naked expression... ", manejo de este tipo de errores.

Veamos la siguiente álgebra:
<<(+,1)>> = Naturales.
El elemento primigenio, seminal o generador es el 1, y la operación de generación
es el +.

1, 1+1=2, 1+1+1=3, 3+1, ...
1, 2, 3, ...                          
-- #N Cardinalidad de N: El tamaño del conjunto generado. La ocurrencia de un $n$
dentro de la sucesión es su orden (como conjunto ordinal).

Otro ejemplo:
<<({o, y, no},{F,T})>> = Proposiciones lógicas simples con constantes T y F.

F,T,T o F, (T o F) y (no F),...
Cfr. con Prolog.

?- false.
false.

?- true,false.
false.

?- true,true.
true.

?- \+ (true).
false.

?- false < true.
ERROR: </2: Arithmetic: `false/0' is not a function -- ya que < es definido para aritmética
?- false @< true.
true.  --ya que @< compara términos

-----------------------------------------------------------------------------

Para coálgebras:

[1],  %Primer elemento
[1,1], % segundo elemento
[1,1,1]...

en el paso al límite en el crecimiento de esta sucesión tenemos un
elemento "infinito": sería el "último" de una unión de elementos previos:

A1={[1]}
A2= A1 U {[1,1]}
A3= A2 U {[1,1,1]}
....
An = A(n-1) U {[1...replicado n veces]} (U representa la unión de conjuntos)
 A1 C A2 C A3 C A4 C A5 C ... ----> infinito (C representa la contención de conjuntos)

En el paso al límite (cuando n tiende a infinito), tenemos un conjunto infinito, cuyo
´ultimo elemento se dice que ésta en la coálgebra generada por la sucesión An.

Para el ejemplo tratado, se especifica en Haskell así:

> o = 1:o

En el modelo de computación de Haskell que es por medio de evaluación perezosa
un elemento solo se crea si se requiere en un paso de cómputo.

Así se crean los números naturales  a partir de un número n:

> nat n = n: nat(n+1)

Y así se crean todos los números naturales

> l = nat 1

Tomando l, tenemos
[1,2,3,4,5,6...] (infinitamente.

Consideremos ahora la función de Fibonacci y observemos que
si desplazamos la sucesión de Fibonacci con respecto a sí misma y
sumamos columna a columna tenemos otra vez la función de Fibonacci:
1,1,2,3,5,8...
   1,1,2,3,5,8...
____________
1 2 3 5 8 13...
Esto diría que la sucesión  de Fibonacci es más fácil de crear subcreando
dos sucesiones de Fibonacci que creando una sola! Paradójico,  no?


> fibs0 = [1,1,2,3]
> fibs1 = 1:1:[]
> fibs2 = 1:1:[x+y| x <- fibs0, y <- tail fibs0]

x valor 1 y valor 1
x valor 1 y valor 1

Tarea: Generar los números primos por medio de un flujo (comento el cofinal
de una coálgebra).


Si ahora tenemos:
fibs
obtenemos
[1,1,2,3,4,2,3,4,3,4,5,4,5,6]
que no es lo que se desea.

*Main> [x+y | x<-[1,2,3,4],y<-[5,6,7]]
[6,7,8,7,8,9,8,9,10,9,10,11]
*Main> [(x,y) | x<-[1,2,3,4],y<-[5,6,7]]
[(1,5),(1,6),(1,7),(2,5),(2,6),(2,7),(3,5),(3,6),(3,7),(4,5),(4,6),(4,7)]

Hagamos justa (fair) la selección de elementos (1 elemento por lista en cada
ocasión). Utilizamos para ello la función zip:

*Main> zip [1,2,3,4] [5,6,7]
[(1,5),(2,6),(3,7)]

*Main> [(x,y) | (x,y)<-zip [1,2,3,4] [5,6,7]]
[(1,5),(2,6),(3,7)]

*Main> [x+y | (x,y)<-zip [1,2,3,4] [5,6,7]]
[6,8,10]

Finalmente, esta es la función requerida:

> fibs = 1:1:[x+y | (x,y) <- zip fibs (tail fibs)]

He aquí algunas ejecuciones:

*Main> take 5 fibs
[1,1,2,3,5]
*Main> take 8 fibs
[1,1,2,3,5,8,13,21]
*Main> take 12 fibs
[1,1,2,3,5,8,13,21,34,55,89,144]
*Main> take 15 fibs
[1,1,2,3,5,8,13,21,34,55,89,144,233,377,610]
*Main> take 20 fibs
[1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765]
*Main> fibs!!100
573147844013817084101
*Main> fibs!!200
453973694165307953197296969697410619233826

etc.

miércoles, 28 de octubre de 2015

Haskell es especial



*.lhs: Hacen a Haskell intensivamente comentado.

Haskell: Su fundamento es el Cálculo Lambda (Alonzo Church, 1930s).
Haskell: Bloque de trabajo son las funciones (brazo derecho).
Haskell: Los tipos son su brazo izquierdo de trabajo: Char, Int, Float, Double...
              tipos curriados o compuestos vía productos cartesianos.
Haskell: Mónadas: La manera de Haskell de modelar el mundo exterior
               disciplinadamente.
Haskell: Funciones de mayor orden y funciones curriadas.
Haskell: Estrategia genérica de evaluación perezosa (lazy evaluation), lo que
         origina coálgebras: Las coálgebras son estructuras duales a las álgebras.
         En una álgebra queremos la intersección de inclusión; en una coálgebra
         queremos la unión de la inclusión. Las coálgebras permiten justificar la
         introducción y utilizamiento de algo conocido como objetos computacionales
         infinitos.


Ejemplos:
1) Cálculo lambda:

> (\x -> x+1) 2
> map (\x -> (4:)) [[1],[2],[3]]

>  map (\x -> x*x) [1,2,3]

> let s = sin . cos in s 2
> let f = tan . cos . sin in f 10

(Haciendo eco de las palabras del Premio Turing John Backus, de que las
variables son inútiles en la programación.)
El operador punto es composición de funciones.

2) Bloques (sin variables)

> longitud  = sum . unos
> unos = map (\x -> 1)


3) Tipos:

> lonCad :: String -> Int
> lonCad = length

Aquí se enfatiza que lonCad calcula la longitud de cadenas.

4) Visto como el programa Hello.hs.

> filter (\x -> x> 10) [1..100]

A las funciones que toman como argumento a otras funciones se les llama
funciones de mayor orden.

> productoInterno:: ((Float,Float),(Float,Float)) -> Float
> productoInterno ((x1,y1),(x2,y2)) = x1*x2+y1*y2




> productoInterno':: (Float,Float) -> (Float,Float) -> Float
> productoInterno' (x1,y1) (x2,y2) = x1*x2+y1*y2

> productoInterno'':: Float ->Float -> Float -> Float -> Float
> productoInterno''  x1 y1 x2 y2 = x1*x2+y1*y2

> mul2 :: (Float, Float) -> Float
> mul2 (x,y) = x*y+2

Versión curriada (Haskell Curry)

> mul2' :: Float -> Float -> Float
> mul2' x y = x*y+2

map (mul2 2) [1,2,3,4,5]

map (\x -> (mul2 (2,x))) [1,2,3,4,5]
La diferencia es que mul2 trabaja en el dominio (Float,Float) y
y mul2' trabaja en el dominio Funciones: Float -> Float

Esta es la versión (infame) de un programa para crear los
números de Fibonacci.
> fib 1 = 1
> fib 2 = 1
> fib n | n> 2 = fib             (n-1) + fib                 (n-2)
En una próxima ocasión generaremos su versión de flujo.


Mientras, la siguiente función genera un flujo infinito de filas del triángulo de Pascal:

> pascal = p
>   where
> p = [1] : [next a | a <- p]
> next x =  addRows (0:x) x
>                  where
>            addRows (a:x) (b:y) =  (a + b):(addRows x y)
>            addRows [a]   []    =  [a]
>            addRows []    []    =  []

Como ejemplos de ejecución tenemos:

Main> take 5 pascal
[[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]
*Main> take 15 pascal
[[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1],[1,5,10,10,5,1],[1,6,15,20,15,6,1],[1,7,21,35,35,21,7,1],[1,8,28,56,70,56,28,8,1],[1,9,36,84,126,126,84,36,9,1],[1,10,45,120,210,252,210,120,45,10,1],[1,11,55,165,330,462,462,330,165,55,11,1],[1,12,66,220,495,792,924,792,495,220,66,12,1],[1,13,78,286,715,1287,1716,1716,1287,715,286,78,13,1],[1,14,91,364,1001,2002,3003,3432,3003,2002,1001,364,91,14,1]]
*Main> pascal!!4
[1,4,6,4,1]
*Main> (pascal!!4)!!3
4

lunes, 26 de octubre de 2015

Es sencillo, con mónadas



---------------- Y ahora lo siguiente
main :: IO ()
main = do
  putStrLn "Cuál es tu nombre?"
  name <- getLine
  putStrLn ("Gusto en conocerte, " ++ name ++ "!")

--- main tiene tipo IO (): las acciones posibles para cambiar un mundo.
--- do permite realizar acciones secuencialmente
--- Cada acción es ejecutada dentro de la mónada

--- ¿Por qué esto tendría que ser tan difícil? ¿No es este programa una nadería en la
--- programación imperativa?

--- La respuesta es: Se requiere controlar cada efecto lateral, se requiere que el programador
--- sea consciente de cada valor de una expresión, y además se requiere que haya un orden
--- para realizar consecutivamente cada acción. En resumen, se requiere control.
--- Y es que de otra forma la programación (de computadoras) permite fácilmente, sin disciplina,
--- la creación de monstruos amorfos, gelatinosos, escurridizos y fantasmagóricos: son esos
--- programas convencionales que de pronto fallan sin saber por qué, que son difíciles de dar
--- mantenimiento, de actualizar o de ampliar. Sin control, un programador entra fácilmente en
--- un terreno minado.

Los números de Fibonacci, en una infinita lista


---Lo siguiente es una pequeña perla de la programación funcional, en Haskell:

>let fibs = 1:1:[x+y|(x,y) <- zip fibs (tail fibs)] in take 17 fibs
>[1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597]

jueves, 15 de octubre de 2015

Esta vez, Scheme

; Lo siguiente es una codificación de una interfaz ejemplificando las capacidades de
; interfaz gráficas tal como están disponibles en Racket,
; de www.racket-lang.org

mh@zas:$ cat racketNombre01.rkt
#lang racket/gui
; Creación de un diálogo

(define dialog (instantiate dialog% ("Ejemplo de diálogo")))

; Agrega un campo de texto a
(define tf (new text-field% [parent dialog] [label "Escribe tu nombre, por favor"]))

; Agrega un panel horizontal al diálogo
(define panel (new horizontal-panel% [parent dialog]
                                     [alignment '(center center)]))
; Pega un mensaje estático al diálogo
(define msg (new message% [parent dialog]
                          [label "No hay acción..."]))

; Agrega los botones de Cancel y Ok al panel horizontal
(new button% [parent panel] [label "Cancel"]
     [callback (lambda (button event)
                 (message-box "....." "NoNoNNNo  me canceles :("))])
(new button% [parent panel]
     [label "Ok"]
     [callback (lambda (button event)
                         (message-box "Respuesta"
                               (string-append "Hola  "
                                (send tf get-value)
                                )))])
(when (system-position-ok-before-cancel?)
  (send panel change-children reverse))

; Mostrar el diálogo
(send dialog show #t)


Mónadas en Haskell


---De una explicación preliminar de mónadas en Haskell
import Control.Monad
--- data Maybe t = Just t | Nothing


add :: Maybe Int -> Maybe Int -> Maybe Int
add mx my =
  case mx of
    Nothing -> Nothing
    Just x  -> case my of
                 Nothing -> Nothing
                 Just y  -> Just (x + y)

sol n =
    case n of
      2 -> 3
      4 -> 4
      5 -> 6
      _ -> 10

sol2 2 = 3
sol2 4 = 4
sol2 6 = 6
sol2 _ = 10

sol3 n | n== 2 = 3
           | n==4  = 4
           | n==5  = 6
           | otherwise = 10

add2 :: Maybe Int -> Maybe Int -> Maybe Int
add2 mx my =      
    -- Adds two values of type (Maybe Int), where each input value can be Nothing
  mx >>= (\x ->
      -- Extracts value x if mx is not Nothing
    my >>= (\y ->
     -- Extracts value y if my is not Nothing
      return (x + y)))
 -- Wraps value (x+y), returning the sum as a value of type (Maybe Int)

add3 :: Maybe Int -> Maybe Int -> Maybe Int
add3 mx my = do
  x <- mx
  y <- my
  return (x + y)

add4 :: Maybe Int -> Maybe Int -> Maybe Int
add4 = liftM2 (+)

con4 :: Maybe String -> Maybe String -> Maybe String
con4 = liftM2 (++)

lunes, 13 de abril de 2015

Cuestionario de salvamento.

Complejidad

Complejidad

Lea cuidadosamente. a**n se lee como "a elevado a la n".
  1. Se sabe que P=NP.

  2. Verdadero
    Falso

  3. Todo algoritmo ejecutable en espacio constante es lineal en tiempo total de ejecución.

  4. Falso
    Verdadero

  5. O(n) contiene O(n**2).

  6. Falso
    Verdadero

  7. Existen 2**n-2 subconjuntos propios de un conjunto de n elementos.

  8. Verdadero
    Falso

  9. Prolog es el único lenguaje de programación determinista.

  10. Falso
    Verdadero

  11. Toda función periódica de los naturales a los naturales expresa una función recursiva primitiva.

  12. Verdadero
    Falso

  13. Con f(1)=1, y f(n) = f(n-1) se tiene una función recursiva primitiva, con valor f(n)=n.

  14. Verdadero
    Falso

  15. Es bueno utilizar apuntadores en el análisis de complejidad de un algoritmo.

  16. Verdadero
    Falso

  17. El polinomio h(x) = a+b*x+c*x**2 es una función computable según Kleene.

  18. Verdadero, si a,b,c y x toman valores enteros.
    Falso, si a, b, c y x son números reales.

  19. Considera la cadena "abaaaaabbbac".

  20. Puedo formar con esto un palíndromo.
    No puedo formar un palíndromo.

Después de terminar tu cuestionario,mantén durante un periodo de tiempo la pantalla. Salva tu resultado mediante PrScr.

s

Verdadero o falso?

1) P=NP.
2). Todo algoritmo ejecutable en espacio constante es lineal en tiempo total de ejecución
3) O(n) contiene a O(n**2).
4) Existen 2**n-2 subconjuntos propios de un conjunto de n elementos.
5) Con f(1)=1,  y f(n) = f(n-1) se tiene una función recursiva primitiva, con valor f(n)=n.
6) Toda función periódica de los naturales a los naturales puede expresarse como una función recursiva primitiva.
7) Considera la cadena "abaaaaabbbac". Halla un palíndromo con los caracteres (todos) de esta cadena. 
Te costó lo mismo hallar el palíndromo que verificar que lo es.
8) Es bueno utilizar apuntadores en el análisis de complejidad de un algoritmo.
9) Es bueno utilizar Python en el análisis de complejidad de un algoritmo.
10) El polinomio h(x) = a+b*x+c*x**2 es una función computable según Kleene (a,b,c: constantes enteras, x variable entera).

jueves, 19 de marzo de 2015

Micro-repaso conceptual en relaciones, funciones e inducción

Intermedio: Relaciones, funciones e inducción

Intermedio: Relaciones, funciones e inducción

  1. ¿Es la composición de dos funciones inyectivas una función inyectiva?


  2. No

  3. Si existe una función biyectiva entre los conjuntos A y B, estos tienen la misma cardinalidad.


  4. No

  5. El principio de inducción matemática permite probar propiedades definidas sobre los números reales


  6. No

  7. La conversa de una relación en unión con la relación misma es una relación simétrica.


  8. No

  9. La relación <= (menor que o igual) es una relación de equivalencia.


  10. No

  11. La composición de dos funciones biyectivas es una función biyectiva.


  12. No

  13. Existen exactamente (n+1)! funciones biyectivas de un conjunto en sí mismo.


  14. No

  15. El complemento de la relación a<b (menor que) es la relación a>b.

  16. No


  17. Sea f(x)=1/x, con f(0)=0. Esta función es total, de R a R.


  18. No

  19. La inducción matemática consiste en probar que para un predicado P, P(k) implica P((k+1)+1).

  20. No.
    Sí.

miércoles, 18 de marzo de 2015

De unas propuestas de tesis de maestría en sistemas distribuidos.

En esta entrada planteo unas cuantas posibles vertientes de investigación que serían adecuadas para lograr una tesis de maestría en sistemas distribuidos. Los temas están enfocados en el tratamiento de cómputo distribuido, aunque no es de descartar su enfoque económico, social, de e-gobierno, o administrativo en general, aunque para ello se requiere de una co-asesoría de alguien experto en el tema lateral. Tales colaboraciones son deseables, pero no siempre posibles, al no existir tales expertos dentro del personal académico de este tipo de maestrías, orientadas a aspectos tecnológicos computacionales.

Para comenezar y de manera genérica, se tendría que adoptar un lenguaje de programación para actividades prácticas tal como Erlang (www.erlang.org). ¿Por qué? Por que es un lenguaje diseñado para tratar con concurrencia desde su diseño original, principalmente, y tiene además un esquema de trabajo basado en paso de mensajes muy limpio. Eso sí, no es un lenguaje ni muy conocido ni muy comercial. Inspeccionando en la red, en lo primero, apenas hay una docena de libros, todos de publicación reciente, que tratan de Erlang. En lo segundo, solo ocasionalmente se escucha que Erlang da vida al chat de Facebook o que Amazon lo incorpora de forma accesoria en algunos de sus servicios. Lejos de ser desventajas, la falta de popularidad de Erlang no es objeción contra la calidad de su diseño, y brinda un nicho de exploración académica en contraposición a un papel que tradicionalmente ha sido adjudicado a, por ejemplo, Java. La comparación en este momento se vuelve injusta, ya que Java tiene apoyos monetarios estratosféricos para proyectos de enorme impacto comercial, haciendo que su lado académico languidezca, al no permitirse compartir el código y ni siquiera los generales de diseño. Para esto de las aplicaciones, la comunidad de Erlang es proclive a aceptar nuevas posibles aplicaciones de Erlang como casos de estudio que muestren las bondades del lenguajes, por lo que siempre están dispuestos a ayudar y son promovedores del código fuente libre.

Para manejar la parte de complejidad conceptual de los sistemas distribuidos la idea es utilizar los conceptos plasmados en SCEL:

http://dl.acm.org/citation.cfm?id=2642710.2619998&coll=DL&dl=GUIDE&CFID=645236426&CFTOKEN=35421267

SCEL es un lenguaje de especificación de sistemas distribuidos basados en
componentes autónomos que se comunican mediante envío y recepción de mensajes. Cada componente tiene cierto grado de capacidad de procesamiento para formar parte de grupos, así como tomar decisiones básicas basadas en su "estado de salud" actual, entre otros factores.

La parte principal de este amplio esquema teórico radica en estudiar
componentes autonómicos de sistemas distribuidos basados en mensajes, pero sin restricciones que pudieran ocurrir en primera instancia. Se utilizan para ello sistemas de transición etiquetados, con una buena dosis
de cálculo pi. Una ventaja de este amplio esquema es que puede adaptarse
a un tema sencillo o específico, sirviendo así como de "almacén conceptual"
para el tratamiento adecuado de instancias distribuidas.  A la gente de SCEL
esta parte le llama mucho la atención por que conforma las "pruebas de
ácido" de su propuesta teórica, e inclusive se les puede escribir para resolver
dudas concretas (conozco personalmente a algunos de sus creadores, y son
gente sencilla y accesible ---realmente sabias).

Finalmente, antes de detallar los posibles tópicos de investigación, tenemos
el tema de los agentes. Un agente tiene un modelo muy particular de
cómputo que no sigue necesariamente aquel tradicional de resolución de  problemas
basados en máquinas de Turing (el principal proponente de este enfoque es Peter Wegner, junto con la idea de interacción: http://cs.brown.edu/~pw/).
El punto esencial de un "nodo-agente" distribuido es que siempre debe estar "atento" de lo que pasa a su alrededor o en su interior: eso incluye el tiempo, el estado de la batería, la temperatura, el buen funcionamiento del sistema, el
adecuado estado de sus llantas, o bien, atento a organizarse adecuadamente para lograr un objetivo común con otros nodos-agentes, o bien manejar con
la debida respuesta el intento de hackeo de intrusos o en general, las
perturbaciones externas al sistema. Este tipo de tareas se complementa
con aquellas llamadas "self-*" en SCEL, junto con otras tradicionales de agentes relacionadas con su inmersión en un ambiente. Los agentes son a su vez instancias de un enfoque de resolución de problemas basado en la constante interacción con el ambiente, a diferencia de una máquina de Turing que sólo toma una entrada y vuelve a interactuar con el ambiente (incluido un usuario) sino hasta brindar (posiblemente) una salida. La intermitencia de aspectos sensoriales y de guía hace que estos agentes resuelvan problemas que una máquina de Turing con su enfoque cerrado no podría.

Ahora, teniendo ya algunas cartas sobre la mesa, propongo unos tres temas como posibles tesis de maestría en sistemas distribuidos:

* El primer tema tiene que ver con construir un escenario virtual donde unos
robots deambulan, comunicándose entre sí y teniendo una noción de cooperación, y en su caso, de competencia. Con la robótica en el estado actual (microcontroladores programables, servos, y sensores), tal simulación sería trasladable a un escenario realista en principio, aunque con objetivos concretos en mente y posiblemente una inversión monetaria alta.

* El segundo tema es con respecto al tratamiento del tiempo de unos
agentes que monitorean y dan mantenimiento a un sitio virtual. Los agentes que actualmente actúan de esta forma (con algunas otras funciones más) están presentes en las redes sociales y los comercios internacionales tales como Amazon. Tal tecnología está en una etapa madura, pero todavía faltan algunos aspectos a tratar que impiden cierta flexibilidad de los agentes actuales.
 
* El tercer tema es para validar redes distribuidas mediante "model checking"
(construcción de modelos sencillos para verificar que las redes funcionan
como se debe). La ventaja de un enfoque como éste es que se puede partir de un sistema distribuido complejo y analizarlo con herramientas sencillas, o bien comenezar con una red sencilla y por capas de provisión de riqueza en servicios ir ampliándolo siempre bajo una disciplina de creación de modelos.

Cabe mencionar que esta no es una lista exhaustiva de posibles temas: más bien digo que los temas aquí presentados indican la incorporación en su desarrollo de las anteriores herramientas mencionadas. Llegado el caso, se aceptarían propuestas que involucraran al menos dos de
tres siguientes aspectos: Erlang, cálculo-pi, y  distribución de carga computacional.

A reserva de otras consideraciones metodológicas, es necesario enfatizar que
la selección de una herramienta computacional para implementar algoritmos
o simulaciones es ya un avance sustancial en el logro de un proyecto de tesis
de maestría. La misma observación en el ámbito teórico: si nos ponemos a
pensar al respecto, es enorme la variedad de "ofertas teóricas" que se
presentarían. Al delimitar algunas de ellas basadas en los criterios de pertinencia, asequibilidad, comprensibilidad y complejidad notaremos que
las herramientas teóricas mencionadas ya poseen de entrada ciertas ventajas.

Una nota importante: El manejo del tiempo entre el comienzo de una tesis
de maestría y su final es algo digno de consideración, y requiere tanta atención  como lo es el considerar la desventaja de la distancia geográfica entre los participantes en el caso de estudios a distancia. Una buena actitud de parte del estudiante es fundamental: si el estudiante solo tiene un interés mediano en el tema (o peor, ninguno), los tiempos se ampliarán como si fueran por descripción recursiva (notemos, jocosamente, que 1+1/2+1/3+1/4+.. es una serie divergente, como cuando un estudiante dice: "En un semestre haré la mitad de la tesis; en el otro semestre la mitad de la otra mitad; etc."). Tan importante como el interés en el tema, por lo tanto, es plantearse tiempos cortos de avances efectivos de tesis y tácticas para sortear el distanciamiento geográfico en comunicación. Suerte. 

miércoles, 11 de marzo de 2015

Micro-cuestionario (versión de familiarización)

Intermedio de Conjuntos y Relaciones

Intermedio de Conjuntos y Relaciones

  1. Es el mismo conjunto {{}}={{{}}} ?


  2. No

  3. Si A es {1,2,3}, esta bien P(A)={{},{1},{2},{1},{2,3},{3,1},{2,3},{1,2,3}} ?


  4. No

  5. Está bien {x | x es 1 o 0}={0} ?


  6. No

  7. Si R = {(1,2),(1,3)} y S={(2,1),(3,1)}, es R o S ={(1,1),(1,1)}?


  8. No

  9. Si R = {(x,y) | x pertenece a {1,2} y y pertenece a {1,2} con x < y} Es R={(1,1),(1,2),(2,2)}?


  10. No

Conserven su pantalla de evaluación por un momento. Gracias.

martes, 10 de marzo de 2015

Un mini-cuestionario


Basico


  1. Vas comprendiendo el material de Python?


  2. No

  3. Conoces la diferencia entre una función y una relación?


  4. No

  5. Sabes qué es una relación identidad?


  6. No

Pequeñas definiciones en Python

#Ejemplos en Python.

>>> def fib(n):
...     if n==0 or n==1: return 1
...     else: return fib(n-1)+fib(n-2)
...
>>> fib(5)
8
>>> map(fib,range(0,11))
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> def fastfib(n):
...     a,b=1,1
...     while (b<n):
...             a,b=b,a+b
...     return b
...
>>> fastfib(10)
13
>>> fastfib(11)
13
>>> fastfib(15)
21
>>> fastfib(80)
89
#Pregunta: ¿qué hace fastfib con respecto a n?

>>> def nthfib(n):
...     a,b=1,1
...     for i in range(1,n+1):
...             a,b=b,a+b
...     return b
...
>>> nthfib(1)
2
>>> nthfib(2)
3
>>> nthfib(3)
5
>>> nthfib(4)
8
>>> map(nthfib,range(0,11))
[1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]

# Pregunta: ¿coincide este resultado con aquel de fib? Corregir.
#Notar para grandes valores:
>>> nthfib(100)
927372692193078999176L
>>> nthfib(1000)
113796925398360272257523782552224175572745930353730513145086634176691092536145985470146129334641866902783673042322088625863396052888690096969577173696370562180400527049497109023054114771394568040040412172632376L
#Dándole una oportunidad al factorial de un número:
>>> def fact(n):
...     if n==0: return 1
...     else: return n*fact(n-1)
...
>>> fact(10)
3628800
>>> fact(30)
265252859812191058636308480000000L
#Miscelánea, listas y cadenas:
>>> ls="hola"
>>> ms=ls
>>> ls.reverse()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'reverse'
>>> ls=list("hola")
>>> ls.reverse()
>>> ls
['a', 'l', 'o', 'h']
>>> ms+ms
'holahola'
>>> ms*5
'holaholaholaholahola'
>>> ms[2]
'l'
>>> ms[2:]
'la'
>>> ms[:2]
'ho'
>>> ms=ms+ms
>>> ms[3:4]
'a'
>>> ms[3:7]
'ahol'


lunes, 9 de marzo de 2015

Notas acerca de estos programas y del blog.

Los anteriores programas funcionan módulo la provisión de los archivos de gráficas y audio faltantes. Se pueden poner tentativamente algún audio en formato .wav, por ejemplo. La idea es seguir el bosquejo descrito en cada uno de estos programas para un posible proyecto posterior. Me parece que en algún lugar del blog se puede poner en activo la opción de "Seguir", para ser notificados de nuevas entradas o de entradas que se modifiquen. Cordiales saludos.

domingo, 8 de marzo de 2015

Ejemplo de sonido (gruñido de puerco)


import pygame,time

#-----------------------------------------------------------------------

#Más información de Pygame en http://www.pygame.org

#-----------------------------------------------------------------------

pygame.init()
#Necesario tener pig.wav, es fácil hallar sonidos de este tipo en la red...
sonidoPuerco = pygame.mixer.Sound('pig.wav')

sonidoPuerco.play()
pygame.mixer.music.load('claps.wav') #Musica de fondo
pygame.mixer.music.play(3,0.0) #-1, infinito; 0.0, inicio del rebobinado.

sonidoPuerco.play()
sonidoPuerco.stop()

time.sleep(10)
pygame.mixer.music.stop()

Ejemplo para poner fuentes en Pygame

# -*- coding: latin-1 -*-

import pygame, sys
from pygame.locals import *

pygame.init()
DISPLAYSURF = pygame.display.set_mode((400, 300))
pygame.display.set_caption('Hello World!')

WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
BLUE = (0, 0, 128)

fontObj = pygame.font.Font('freesansbold.ttf', 64)
textSurfaceObj = fontObj.render('Gran ocasión!', True, GREEN, BLUE)
textRectObj = textSurfaceObj.get_rect()
textRectObj.center = (200, 150)

while True: # main game loop
   DISPLAYSURF.fill(WHITE)
   DISPLAYSURF.blit(textSurfaceObj, textRectObj)
   for event in pygame.event.get():
       if event.type == QUIT:
           pygame.quit()
           sys.exit()
   pygame.display.update()

Animación en Pygame

# -*- coding: latin-1 -*-
#Requiere un archivo pequeño .jpg . Yo puse un gato.

import pygame, sys
from pygame.locals import *

pygame.init()

FPS = 24 # frames per second setting
fpsClock = pygame.time.Clock()

# set up the window
DISPLAYSURF = pygame.display.set_mode((600, 600), 0, 32)
pygame.display.set_caption('Animation')

WHITE = (255, 255, 255)
#catImg = pygame.image.load('cat.png')
#catImg = pygame.image.load('apple.jpg')
catImg = pygame.image.load('catBig.jpg')
#Así se carga una imagen, por cierto.
catx = 10
caty = 10
direction = 'right'

while True: # the main game loop
    DISPLAYSURF.fill(WHITE)

    if direction == 'right':
        catx += 5
        if catx == 280:
            direction = 'down'
    elif direction == 'down':
        caty += 5
        if caty == 220:
            direction = 'left'
    elif direction == 'left':
        catx -= 5
        if catx == 10:
            direction = 'up'
    elif direction == 'up':
        caty -= 5
        if caty == 10:
            direction = 'right'

    DISPLAYSURF.blit(catImg, (catx, caty))

    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

    pygame.display.update()
    fpsClock.tick(FPS)

Dibujo de figuras

import pygame, random, sys
from pygame.locals import *
pygame.init()
disp=pygame.display.set_mode((500,500),0,32)
Black = (0,0,0)
White = (255,255,255)
Red = (255,0,0)
Green = (0,255,0)
Blue = (0,0,255)

disp.fill(White)
pygame.draw.line(disp,Blue,(0,0),(100,100),4)
pygame.draw.polygon(disp,Green,
            ((10,0),(30,40),(50,80),(80,30)))
pygame.draw.lines(disp,Green,True,
            ((10,100),(330,40),(250,80),(80,230)),4)

pygame.draw.circle(disp,Blue,(200,200),50,2)
pygame.draw.circle(disp,Blue,(200,200),random.randint(2,4)*50,2)
pygame.draw.circle(disp,Blue,(200,300),50,2)
pygame.draw.ellipse(disp,Blue,(200,200,30,60),1)
pygame.draw.rect(disp,Red,(200,210,400,420))
pygame.draw.circle(disp,Blue,(250,400),50,2)
pixObj = pygame.PixelArray(disp)
for i in range(100):
    pixObj[80][i+1] = Black
del pixObj

while True:
     for event in pygame.event.get():
         if event.type == QUIT:
             pygame.quit()
             sys.exit()
     pygame.display.update()

Pantalla inicial en Pygame

import pygame, random, sys
from pygame.locals import * #Nombres de constantes
pygame.init()
disp = pygame.display.set_mode((400, 300))
pygame.display.set_caption('Hola mundo!')
while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
    pygame.display.update()

Generación de subconjuntos


def todos(ls):
    if ls==[]:
        return [[]]
    else:
        a=ls.pop()
        ds=todos(ls)
        return ds + map(lambda ts: [a]+ts,[m for m in ds])

Graficación de relaciones

import random,sys
import pygame
from pygame.locals import *
      
pygame.display.init()
disp=pygame.display.set_mode((400,400))


r1 = [(x,x) for x in range(1,9)]
r2 = [(x,y) for x in range(1,9) for y in range(1,9) ]
r3 = [(x,y) for x in range(1,9) for y in range(1,9) if  x<y]
r4 = [(x,y) for x in range(1,9) for y in range(1,9) if  x>=y]
r4Conversa=[(y,x) for (x,y) in r4]

radius=6

print "Relacion a graficar: " , r4Conversa

Black = (0,0,0)
White = (255,255,255)
Red = (255,0,0)
Green = (0,255,0)
Blue = (0,0,255)

disp.fill(White)
mx=300
escala=30

for point in r4Conversa:
    (x,y)=point
    pointG=(escala*x+10,mx-escala*y)
    pygame.draw.circle(disp,Red,pointG,radius)

pygame.draw.line(disp,Green,(10,10),(10,300),10)
pygame.draw.line(disp,Green,(10,mx),(300,mx),10)

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
    pygame.display.update()


# print todos([])
# print todos([1])
# print todos([1,2,3])
# print len(todos([1,2,3]))