diff options
Diffstat (limited to 'es-es')
26 files changed, 5909 insertions, 128 deletions
diff --git a/es-es/asymptotic-notation-es.html.markdown b/es-es/asymptotic-notation-es.html.markdown new file mode 100644 index 00000000..f3fe1614 --- /dev/null +++ b/es-es/asymptotic-notation-es.html.markdown @@ -0,0 +1,170 @@ +--- +category: Algorithms & Data Structures +name: Asymptotic Notation +contributors: + - ["Jake Prather", "http://github.com/JakeHP"] +translators: + - ["Gerson Lázaro", "https://gersonlazaro.com"] +lang: es-es +--- + +# Notaciones asintóticas + +## ¿Qué son? + +Las notaciones asintóticas son lenguajes que nos permitan analizar el tiempo de +ejecución de un algoritmo identificando su comportamiento si el tamaño de +entrada para el algoritmo aumenta. Esto también se conoce como la tasa de +crecimiento de un algoritmo. ¿El algoritmo de repente se vuelve increíblemente +lento cuando el tamaño de entrada crece? ¿Tiende a mantener un rápido tiempo de +ejecución a medida que el tamaño de entrada aumenta? La notación asintótica nos +da la capacidad para responder a estas preguntas. + +## ¿Hay alternativas que respondan a estas preguntas? + +Una manera sería contar el número de operaciones primitivas en diferentes +tamaños de entrada. Aunque esta es una solución válida, la cantidad de trabajo +que esto conlleva, incluso para los algoritmos simples, no justifica su uso. + +Otra manera es medir físicamente la cantidad de tiempo que un algoritmo toma +para completar su ejecución dados diferentes tamaños de entrada. Sin embargo, +la exactitud y la relatividad (los tiempos obtenidos sólo serían relativos a la +máquina sobre la cual se calcularon) de este método está ligado a variables +ambientales tales como especificaciones de hardware, capacidad de procesamiento, +etc. + +## Tipos de Notación Asintótica + +En la primera sección de este documento hemos descrito cómo una notación +asintótica identifica el comportamiento de un algoritmo ante los cambios en el +tamaño de la entrada. Imaginemos un algoritmo como una función f, con tamaño de +entrada n, y f(n) siendo el tiempo de ejecución. Así que para un algoritmo f +dado, con el tamaño de entrada n obtenemos algún tiempo de ejecución resultante +f(n). Esto resulta en un gráfico donde el eje Y es el tiempo de ejecución, el +eje X es el tamaño de la entrada y los puntos en el gráfico son los resultantes +de la cantidad de tiempo para un tamaño de entrada dado. + +Puedes etiquetar una función, o un algoritmo, con una notación asintótica de +muchas maneras diferentes. Algunos ejemplos son describir un algoritmo por su +mejor caso, su peor caso, o el caso promedio. Lo más común es analizar un +algoritmo por su peor caso. Por lo general, no se evalúa el mejor caso, porque +no planeas el algoritmo para estas condiciones. Un muy buen ejemplo de esto son +los algoritmos de ordenamiento; específicamente, añadir elementos a un árbol. +El mejor caso para la mayoría de los algoritmos podría ser tan bajo como una +sola operación. Sin embargo, en la mayoría de los casos, el elemento que está +añadiendo tendrá que ser ordenado adecuadamente a través del árbol, lo que +podría significar examinar toda una rama. Este es el peor de los casos, y +para estos casos es que planeamos el algoritmo. + + +### Tipos de funciones, límites, y simplificación + +``` +Función logarítmica - log n +Función lineal - an + b +Función cuadrática - an^2 + bn + c +Función polinomicas - an^z + . . . + an^2 + a*n^1 + a*n^0, donde z es constante +Función exponencial - a^n, donde a es constante +``` + +Estas son algunas clasificaciones de funciones de crecimiento básicos utilizados +en varias notaciones. La lista comienza en la función de crecimiento menor +(logarítmica, el tiempo de ejecución mas rápido) y pasa a la de mayor +crecimiento (exponencial, el tiempo de ejecución mas lento). Observe como al +crecer 'n', o la entrada, en cada una de estas funciones, el resultado aumenta +claramente mucho más rápido en las cuadráticas, polinómicas y exponenciales, +en comparación con las logarítmicas y lineales. + +Una anotación muy importante es que en las notaciones que se discutirán debes +hacer tu mejor esfuerzo por utilizar los términos más simples. Esto significa +hacer caso omiso de las constantes y terminos de orden inferior, porque a medida +que el tamaño de entrada (o n en f(n)) aumenta hacia el infinito (límites +matemáticos), los términos y constantes de orden inferior se vuelven de poca o +ninguna importancia. Dicho esto, si tienes constantes que son 2^9001, +o alguna otra cantidad ridícula, inimaginable, te daras cuenta de que la +simplificación sesgará la exactitud de la notación. + +Como queremos algo simplificado, vamos a modificarlo un poco... + +``` +Logarítmico - log n +Lineal - n +Cuandrático - n^2 +Polinómico - n^z, donde z es constante +Exponencial - a^n, donde a es constante +``` + +### O-grande (Big-O) +O-grande (Big-O), comúnmente escrito como O, es una notación asintótica para el +peor caso, o el techo de crecimiento para una función determinada. Si `f (n)` +es el tiempo de ejecución del algoritmo, y `g (n)` es un tiempo de complejidad +arbitraria que relacionas con el algoritmo, entonces `f (n)` es O(g(n)), si por +cualquier constante real c (c > 0), `f (n)` <= `c g(n)` para cada tamaño de +entrada n (n > 0 ). + + +*Ejemplo 1* + +``` +f(n) = 3log n + 100 +g(n) = log n +``` + +`f(n)` es O(g(n))? +`3 log n + 100` es O(log n)? +Echemos un vistazo a la definición de O-grande. + +``` +3log n + 100 <= c * log n +``` +¿Hay alguna constante c que satisface esto para todo n? + +``` +3log n + 100 <= 150 * log n, n > 2 (indefinido en n = 1) +``` + +¡Sí! La definición de O-grande se cumple, por lo tanto `f (n)` es O(g(n)). + +*Ejemplo 2* + +``` +f(n) = 3*n^2 +g(n) = n +``` + +`f(n)` es O(g(n))? +`3 * n^2` es O(n)? +Echemos un vistazo a la definición de O-grande. + +``` +3 * n^2 <= c * n +``` + +¿Hay alguna constante c que satisface esto para todo n? +No, no la hay. `f(n)` no es O(g(n)). + +### Big-Omega +Big-Omega, comunmente escrito como Ω, es una notación asintótica para el mejor +caso, o el piso en el crecimiento para una función dada. + +`f(n)` es Ω(g(n)), si para cualquier constante real c (c > 0), +`f(n)` es >= `c g(n)` para cualquier tamaño de entrada n (n > 0). + +No dudes en dirigirte a los recursos adicionales para ejemplos sobre esto. +O-grande es la notación principal utilizada para la complejidad general de +tiempo algoritmico. + +### Notas finales +Es difícil mantener este tipo de tema corto, y sin duda deberias revisar los +libros y recursos en línea en la lista. Entran en mucha mayor profundidad con +definiciones y ejemplos. + +## Libros + +* [Algoritmos (Algorithms)](http://www.amazon.com/Algorithms-4th-Robert-Sedgewick/dp/032157351X) +* [Diseño de algoritmos (Algorithm Design)](http://www.amazon.com/Algorithm-Design-Foundations-Analysis-Internet/dp/0471383651) + +## Recursos Online + +* [MIT](http://web.mit.edu/16.070/www/lecture/big_o.pdf) +* [KhanAcademy](https://www.khanacademy.org/computing/computer-science/algorithms/asymptotic-notation/a/asymptotic-notation) diff --git a/es-es/brainfuck-es.html.markdown b/es-es/bf-es.html.markdown index e33d672d..c93b8c3a 100644 --- a/es-es/brainfuck-es.html.markdown +++ b/es-es/bf-es.html.markdown @@ -1,5 +1,5 @@ --- -language: brainfuck +language: bf contributors: - ["Prajit Ramachandran", "http://prajitr.github.io/"] - ["Mathias Bynens", "http://mathiasbynens.be/"] @@ -9,8 +9,10 @@ lang: es-es --- Brainfuck (con mayúscula sólo al inicio de una oración) es un -lenguaje de programación mínimo, computacionalmente universal -en tamaño con sólo 8 comandos. +lenguaje de programación extremadamente pequeño, Turing completo con sólo 8 comandos. + +Puedes probar brainfuck en tu navegador con [brainfuck-visualizer](http://fatiherikli.github.io/brainfuck-visualizer/). + ``` @@ -18,7 +20,7 @@ Cualquier caracter que no sea "><+-.,[]" (sin incluir las comillas) será ignorado. Brainfuck es representado por un arreglo de 30,000 celdas inicializadas -en cero y un apuntador en la celda actual. +en cero y un puntero apuntando la celda actual. Existen ocho comandos: @@ -26,7 +28,7 @@ Existen ocho comandos: - : Decrementa 1 al valor de la celda actual. > : Mueve el apuntador a la siguiente celda. (a la derecha) < : Mueve el apuntador a la celda anterior. (a la izquierda) -. : Imprime el valor en ASCII de la celda actual (i.e. 65 = 'A') +. : Imprime el valor en ASCII de la celda actual (p.e. 65 = 'A') , : Lee un caracter como input y lo escribe en la celda actual. [ : Si el valor en la celda actual es cero mueve el apuntador hasta el primer ']' que encuentre. Si no es cero sigue a la @@ -37,7 +39,7 @@ Existen ocho comandos: [ y ] forman un while. Obviamente, deben estar balanceados. -Ahora unos ejemplos de programas escritos con brainfuck. +Estos son algunos ejemplos de programas escritos con brainfuck. ++++++ [ > ++++++++++ < - ] > +++++ . @@ -63,7 +65,7 @@ Esto continúa hasta que la celda #1 contenga un cero. Cuando #1 contenga un cero la celda #2 tendrá el valor inicial de #1. Como este ciclo siempre terminara en la celda #1 nos movemos a la celda #2 e imprimimos (.). -Ten en mente que los espacios son sólo para fines de legibilidad. +Ten en cuenta que los espacios son sólo para fines de legibilidad. Es lo mismo escribir el ejemplo de arriba que esto: ,[>+<-]>. @@ -81,7 +83,7 @@ hasta la próxima vez. Para resolver este problema también incrementamos la celda #4 y luego copiamos la celda #4 a la celda #2. La celda #3 contiene el resultado. ``` -Y eso es brainfuck. ¿No tan difícil o sí? Como diversión, puedes escribir +Y eso es brainfuck. No es tan difícil, ¿verdad? Como diversión, puedes escribir tu propio intérprete de brainfuck o tu propio programa en brainfuck. El intérprete es relativamente sencillo de hacer, pero si eres masoquista, -intenta construir tu proprio intérprete de brainfuck... en brainfuck. +puedes intentar construir tu propio intérprete de brainfuck... en brainfuck. diff --git a/es-es/c++-es.html.markdown b/es-es/c++-es.html.markdown index bcc775e5..07c8bc03 100644 --- a/es-es/c++-es.html.markdown +++ b/es-es/c++-es.html.markdown @@ -1,6 +1,6 @@ --- language: c++ -filename: learncpp.cpp +filename: learncpp-es.cpp contributors: - ["Steven Basart", "http://github.com/xksteven"] - ["Matt Kline", "https://github.com/mrkline"] diff --git a/es-es/c-es.html.markdown b/es-es/c-es.html.markdown index 5d3aae0c..8bc1eabb 100644 --- a/es-es/c-es.html.markdown +++ b/es-es/c-es.html.markdown @@ -418,8 +418,18 @@ typedef void (*my_fnp_type)(char *); ## Otras lecturas -Lo mejor que puedes en contrar es una copia de [K&R, aka "The C Programming Language"](https://en.wikipedia.org/wiki/The_C_Programming_Language) +Lo mejor que puedes encontrar es una copia de [K&R, aka "The C Programming Language"](https://en.wikipedia.org/wiki/The_C_Programming_Language). Es *el* +libro de C, escrito por Dennis Ritchie, creador de C y Brian Kernighan. Aún así, +se cuidadoso, es antiguo, contiene algunas inexactitudes, y algunas prácticas +han cambiado. -Otro buen recurso es [Learn C the hard way](http://c.learncodethehardway.org/book/) +Otro buen recurso es [Learn C the hard way](http://c.learncodethehardway.org/book/). + +Si tienes una pregunta, lee [compl.lang.c Frequently Asked Questions](http://c-faq.com). + +Es muy importante utilizar el espaciado y la sangría apropiados y ser coherente +con su estilo de codificación en general. El código legible es mejor que el +código rápido. Para adoptar un buen estilo de codificación, vea el +[Estilo de codificación del kernel Linux] (https://www.kernel.org/doc/Documentation/CodingStyle). Aparte de eso, Google es tu amigo. diff --git a/es-es/css-es.html.markdown b/es-es/css-es.html.markdown index 31000785..6395f5fd 100644 --- a/es-es/css-es.html.markdown +++ b/es-es/css-es.html.markdown @@ -233,12 +233,21 @@ en todos los navegadores y dispositivos. Pero siempre es vital tener en mente la compatibilidad y disponibilidad del CSS que uses con respecto a los navegadores y dispositivos para los que desarrolles. - [QuirksMode CSS](http://www.quirksmode.org/css/) es una excelente referencia para esto. -## Referencias +## Recursos + +* Para ejecutar un test de compatibilidad, revisa [CanIUse](http://caniuse.com). +* CSS Playground [Dabblet](http://dabblet.com/). +* [Mozilla Developer Network's CSS documentation](https://developer.mozilla.org/en-US/docs/Web/CSS). +* [Codrops' CSS Reference](http://tympanus.net/codrops/css_reference/). + +## Otras lecturas -* [Understanding Style Precedence in CSS: Specificity, Inheritance, and the Cascade](http://www.vanseodesign.com/css/css-specificity-inheritance-cascaade/) -* [QuirksMode CSS](http://www.quirksmode.org/css/) +* [Understanding Style Precedence in CSS: Specificity, Inheritance, and the Cascade](http://www.vanseodesign.com/css/css-specificity-inheritance-cascaade/). +* [Selecting elements using attributes](https://css-tricks.com/almanac/selectors/a/attribute/). +* [QuirksMode CSS](http://www.quirksmode.org/css/). * [Z-Index - The stacking context](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context) +* [SASS](http://sass-lang.com/) y [LESS](http://lesscss.org/) para preprocesamiento CSS. +* [CSS-Tricks](https://css-tricks.com). diff --git a/es-es/forth-es.html.markdown b/es-es/forth-es.html.markdown new file mode 100644 index 00000000..edc5d38c --- /dev/null +++ b/es-es/forth-es.html.markdown @@ -0,0 +1,226 @@ +--- +language: forth +contributors: + - ["Horse M.D.", "http://github.com/HorseMD/"] +translators: + - ["Zach Larsen", "http://zachariahlarsen.com/"] +lang: es-es +filename: learnforth-es.fs +--- + +Forth fue criado por Charles H. Moore en los 70s. Forth es un lenguaje imperativo, basado en pila y entorno de programación, siendo usado en proyectos como Open Firmware. También esta usado por NASA. + +Nota: Este articulo enfoca predominantemente en la Gforth implementación de Forth, pero casi todo +de lo que esta escrito aquí debe funcionar en otro sitio. + +``` +\ Este es un comentario +( Este es un comentario también pero solo esta usado cuando definiendo palabras. ) + +\ --------------------------------- Precursor ---------------------------------- + +\ Todo programación en Forth se hace manipulando el parámetro pila (mas +\ común se refiere como "el pila"). +5 2 3 56 76 23 65 \ ok + +\ estos números se añadieron al pila desde izquierda a derecho. +.s \ <7> 5 2 3 56 76 23 65 ok + +\ En Forth, todo es o una palabra o un numero. + +\ ------------------------------ Básico Aritmética ------------------------------ + +\ Aritmética (de hecho casi todas palabras que requieren datos) funciona manipulando datos +\ en el pila. +5 4 + \ ok + +\ `.` saca lo alto resulto desde el pila: +. \ 9 ok + +\ Mas ejemplos de aritmética: +6 7 * . \ 42 ok +1360 23 - . \ 1337 ok +12 12 / . \ 1 ok +13 2 mod . \ 1 ok + +99 negate . \ -99 ok +-99 abs . \ 99 ok +52 23 max . \ 52 ok +52 23 min . \ 23 ok + +\ ----------------------------- Pila Manipulación ----------------------------- + +\ Naturalmente, cuando trabajaremos con el pila, querremos algunos metidos útiles: + +3 dup - \ duplicar el primero articulo (1ra ahora igual a 2da): 3 - 3 +2 5 swap / \ intercambiar la primera con la segunda elemento: 5 / 2 +6 4 5 rot .s \ rotar los tres primero elementos: 4 5 6 +4 0 drop 2 / \ sacar el primero articulo (no imprima a la pantalla): 4 / 2 +1 2 3 nip .s \ sacar el segundo articulo (similar a drop): 1 3 + +\ ---------------------- Mas Avanzado Pila Manipulación ---------------------- + +1 2 3 4 tuck \ duplicar el primero articulo en el segundo hueco: 1 2 4 3 4 ok +1 2 3 4 over \ duplicar el segundo articulo a la primera del pila: 1 2 3 4 3 ok +1 2 3 4 2 roll \ *mover* el articulo en este posición a la primera del pila: 1 3 4 2 ok +1 2 3 4 2 pick \ *duplicar* el articulo en este posición a la primera del pila: 1 2 3 4 2 ok + +\ Cuando refiere a pila indices, ellos son basado en cero. + +\ ------------------------------ Creando Palabras -------------------------------- + +\ La `:` palabra hace que Forth entra modo de compilar hasta que se ve la `;` palabra. +: cuadrado ( n -- n ) dup * ; \ ok +5 cuadrado . \ 25 ok + +\ Podemos ver lo que hace una palabra también.: +see cuadrado \ : cuadrado dup * ; ok + +\ -------------------------------- Condicionales -------------------------------- + +\ -1 == cierto, 0 == falso. No obstante, valores que no son cero es usualmente tratado como +\ siendo cierto: +42 42 = \ -1 ok +12 53 = \ 0 ok + +\ `if` es una palabra que solamente compila. `if` <cosas para hacer> `then` <los de mas del programa>. +: ?>64 ( n -- n ) dup 64 > if ." Mas que 64!" then ; \ ok +100 ?>64 \ Mas que 64! ok + +\ Else: +: ?>64 ( n -- n ) dup 64 > if ." Mas que 64!" else ." Menos que 64!" then ; +100 ?>64 \ Mas que 64! ok +20 ?>64 \ Menos que 64! ok + +\ ------------------------------------ Loops ----------------------------------- + +\ `do` también es una palabra que solamente compila. +: miloop ( -- ) 5 0 do cr ." Hola!" loop ; \ ok +miloop +\ Hola! +\ Hola! +\ Hola! +\ Hola! +\ Hola! ok + +\ `do` espera dos números en el pila: el último numero y el primero numero. + +\ Podemos recibir el valor del indice mientras damos vuelta con `i`: +: uno-a-12 ( -- ) 12 0 do i . loop ; \ ok +uno-a-12 \ 0 1 2 3 4 5 6 7 8 9 10 11 12 ok + +\ `?do` funciona similarmente, pero salta el loop si el último y primero +\ números son iguales. +: cuadrados ( n -- ) 0 ?do i cuadrado . loop ; \ ok +10 cuadrado \ 0 1 4 9 16 25 36 49 64 81 ok + +\ cambiar el "paso" con `+loop`: +: treces ( n n -- ) ?do i . 3 +loop ; \ ok +15 0 treces \ 0 3 6 9 12 ok + +\ Indefinido loops empiezan `begin` <cosas para hacer> <bandera> `until`: +: death ( -- ) begin ." Ya hemos llegado?" 0 until ; \ ok + +\ ---------------------------- Variables y Memoria ---------------------------- + +\ Use `variable` declarar `edad` ser un variable. +variable edad \ ok + +\ Ahora escribimos 21 a edad con la palabra `!`. +21 edad ! \ ok + +\ Por fin podemos imprimir nuestro variable usando la "leer" palabra `@`, que agregue el +\ valor a la pila, or usa `?` que lee y imprime todo juntos. +edad @ . \ 21 ok +edad ? \ 21 ok + +\ Constantes son muy similar, pero no nos importa los direcciones de memoria: +100 constant PUNTA-QUE-AQUA-HIERVA \ ok +PUNTA-QUE-AQUA-HIERVA . \ 100 ok + +\ ----------------------------------- Arrays ----------------------------------- + +\ Creando arrays es similar a variables, pero necesitamos alocar mas +\ memoria a ellos. + +\ Puede usar `2 cells allot` para crear un array que es sea 3 cédulas de tamaño: +variable minumeros 2 cells allot \ ok + +\ Inicializar todos los valores a 0 +minumeros 3 cells erase \ ok + +\ Alternativamente podemos usar `fill`: +minumeros 3 cells 0 fill + +\ o podemos saltar todo arriba y inicializar con valores específicos: +create minumeros 64 , 9001 , 1337 , \ ok (el último `,` es importante!) + +\ ...que es equivalente a: + +\ Manualmente escribiendo valores a cada indice: +64 minumeros 0 cells + ! \ ok +9001 minumeros 1 cells + ! \ ok +1337 minumeros 2 cells + ! \ ok + +\ Leyendo valores en particular array indices: +0 cells minumeros + ? \ 64 ok +1 cells minumeros + ? \ 9001 ok + +\ Podemos simplificar un poco cuando hacemos una palabra que ayuda cuando manipulando arrays: +: de-arr ( n n -- n ) cells + ; \ ok +minumeros 2 de-arr ? \ 1337 ok + +\ Que podemos usar cuando escribimos también: +20 minumeros 1 de-arr ! \ ok +minumeros 1 de-arr ? \ 20 ok + +\ ------------------------------ El Pila de Regreso ------------------------------ + +\ El pila de regreso se usa para retener punteros a cosas cuando palabras están +\ ejecutando otras palabras como loops. + +\ Ya hemos visto un uso de esto: `i`, que duplica el primero del pila +\ de regreso. `i` es equivalente a `r@`. +: miloop ( -- ) 5 0 do r@ . loop ; \ ok + +\ También como leyendo, podemos agregar al pila de regreso y sacarlo: +5 6 4 >r swap r> .s \ 6 5 4 ok + +\ NOTA: Porque Forth usa el pila de regreso por punteros de palabras, `>r` debe +\ siempre ser seguido por un `r>`. + +\ ------------------------- Flotante Punto Operaciones -------------------------- + +\ La mayoría Forths evitan el uso de flotante punto operaciones. +8.3e 0.8e f+ f. \ 9.1 ok + +\ Usualmente agregamos al frente palabras con 'f' cuando usando flotantes: +variable miflotantevar \ ok +4.4e miflotantevar f! \ ok +miflotantevar f@ f. \ 4.4 ok + +\ --------------------------------- Notas al Final -------------------------------- + +\ Usando una palabra que no existe vaciara el pila. No obstante, también hay una palabra +\ específicamente por esto: +clearstack + +\ vaciar la pantalla: +page + +\ Cargando Forth archivos: +\ s" archivodeforth.fs" included + +\ Puede listar cada palabra en el diccionario de Forth (pero es una lista gigante!): +\ words + +\ Terminando Gforth: +\ bye + +``` + +##Listo Para Mas? + +* [Starting Forth](http://www.forth.com/starting-forth/) +* [Simple Forth](http://www.murphywong.net/hello/simple.htm) +* [Thinking Forth](http://thinking-forth.sourceforge.net/) diff --git a/es-es/git-es.html.markdown b/es-es/git-es.html.markdown index 18b544b4..1a8e275a 100644 --- a/es-es/git-es.html.markdown +++ b/es-es/git-es.html.markdown @@ -18,11 +18,11 @@ versionar y administrar nuestro código fuente. ## Versionamiento, conceptos. -### Qué es el control de versiones? +### ¿Qué es el control de versiones? El control de versiones es un sistema que guarda todos los cambios realizados en uno o varios archivos, a lo largo del tiempo. -### Versionamiento centralizado vs Versionamiento Distribuido. +### Versionamiento centralizado vs versionamiento distribuido. + El versionamiento centralizado se enfoca en sincronizar, rastrear, y respaldar archivos. @@ -33,9 +33,9 @@ uno o varios archivos, a lo largo del tiempo. [Información adicional](http://git-scm.com/book/es/Empezando-Acerca-del-control-de-versiones) -### Por qué usar Git? +### ¿Por qué usar Git? -* Se puede trabajar sin conexion. +* Se puede trabajar sin conexión. * ¡Colaborar con otros es sencillo!. * Derivar, crear ramas del proyecto (aka: Branching) es fácil. * Combinar (aka: Merging) @@ -47,7 +47,7 @@ uno o varios archivos, a lo largo del tiempo. ### Repositorio Un repositorio es un conjunto de archivos, directorios, registros, cambios (aka: -comits), y encabezados (aka: heads). Imagina que un repositorio es una clase, +commits), y encabezados (aka: heads). Imagina que un repositorio es una clase, y que sus atributos otorgan acceso al historial del elemento, además de otras cosas. @@ -62,12 +62,12 @@ y mas. ### Directorio de trabajo (componentes del repositorio) -Es basicamente los directorios y archivos dentro del repositorio. La mayoría de +Es básicamente los directorios y archivos dentro del repositorio. La mayoría de las veces se le llama "directorio de trabajo". ### Índice (componentes del directorio .git) -El índice es el área de inicio en git. Es basicamente la capa que separa el +El índice es el área de inicio en git. Es básicamente la capa que separa el directorio de trabajo del repositorio en git. Esto otorga a los desarrolladores más poder sobre lo que se envía y se recibe del repositorio. @@ -398,6 +398,10 @@ $ git rm /directorio/del/archivo/FooBar.c * [tryGit - Una forma entretenida y rapida de aprender Git.](http://try.github.io/levels/1/challenges/1) +* [Udemy tutorial de Git: Una guía completa](https://blog.udemy.com/git-tutorial-a-comprehensive-guide/) + +* [Inmersión Git - Una visita guiada caminando a través de los fundamentos de git](http://gitimmersion.com/) + * [git-scm - Video-tutoriales](http://git-scm.com/videos) * [git-scm - Documentacion](http://git-scm.com/book/es) @@ -407,3 +411,9 @@ $ git rm /directorio/del/archivo/FooBar.c * [SalesForce Chuleta](https://na1.salesforce.com/help/doc/en/salesforce_git_developer_cheatsheet.pdf) * [GitGuys](http://www.gitguys.com/) + +* [Git - La guía simple](http://rogerdudler.github.io/git-guide/index.html) + +* [Pro Git](http://www.git-scm.com/book/en/v2) + +* [Una introducción a Git y Github para principiantes (Tutorial)](http://product.hubspot.com/blog/git-and-github-tutorial-for-beginners) diff --git a/es-es/groovy-es.html.markdown b/es-es/groovy-es.html.markdown new file mode 100644 index 00000000..799fc609 --- /dev/null +++ b/es-es/groovy-es.html.markdown @@ -0,0 +1,434 @@ +--- +language: Groovy +contributors: + - ["Roberto Pérez Alcolea", "http://github.com/rpalcolea"] +translators: + - ["Jhoon Saravia", "https://github.com/jhoon"] +lang: es-es +filename: groovy-es.html +--- + +Groovy - Un lenguaje dinámico para la plataforma Java [Leer más aquí.](http://www.groovy-lang.org/) + +```groovy + +/* + Hora de configurar: + + 1) Instala GVM - http://gvmtool.net/ + 2) Instala Groovy: gvm install groovy + 3) Inicia la consola de groovy escribiendo: groovyConsole + +*/ + +// Los comentarios de una sola línea inician con dos barras inclinadas +/* +Los comentarios multilínea se ven así. +*/ + +// Hola Mundo +println "Hola mundo!" + +/* + Variables: + + Puedes asignar valores a variables para usarlas después +*/ + +def x = 1 +println x + +x = new java.util.Date() +println x + +x = -3.1499392 +println x + +x = false +println x + +x = "Groovy!" +println x + +/* + Mapas y Colecciones +*/ + +// Creando una lista vacía +def technologies = [] + +/*** Agregando elementos a la lista ***/ + +// Como si fuera Java +technologies.add("Grails") + +// Doble símbolo de menor agrega un elemento y, además, retorna la lista +technologies << "Groovy" + +// Agregando múltiples elementos +technologies.addAll(["Gradle","Griffon"]) + +/*** Quitando elementos de la lista ***/ + +// Como si fuera Java +technologies.remove("Griffon") + +// La resta también funciona +technologies = technologies - 'Grails' + +/*** Iterando Listas ***/ + +// Para iterar sobre los elementos de una Lista +technologies.each { println "Technology: $it"} +technologies.eachWithIndex { it, i -> println "$i: $it"} + +/*** Revisando los contenidos de una Lista ***/ + +// Evaluar si la lista contiene elemento(s) (boolean) +contained = technologies.contains( 'Groovy' ) + +// O +contained = 'Groovy' in technologies + +// Evaluar por múltiples contenidos +technologies.containsAll(['Groovy','Grails']) + +/*** Ordenando Listas ***/ + +// Para ordenar una Lista (modifica la lista original) +technologies.sort() + +// Para ordenarla sin modificar la original, se puede hacer: +sortedTechnologies = technologies.sort( false ) + +/*** Manipulando Listas ***/ + +// Reemplazar todos los elementos en la lista +Collections.replaceAll(technologies, 'Gradle', 'gradle') + +// Mezclar una lista +Collections.shuffle(technologies, new Random()) + +// Limpiar una lista +technologies.clear() + +// Creando un mapa vacío +def devMap = [:] + +// Agregando valores +devMap = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy'] +devMap.put('lastName','Perez') + +// Iterar sobre los elementos del mapa +devMap.each { println "$it.key: $it.value" } +devMap.eachWithIndex { it, i -> println "$i: $it"} + +// Evaluar si el mapa contiene una llave +assert devMap.containsKey('name') + +// Evaluar si el mapa contiene un valor +assert devMap.containsValue('Roberto') + +// Para obtener las llaves del mapa +println devMap.keySet() + +// Para obtener los valores del mapa +println devMap.values() + +/* + Groovy Beans + + GroovyBeans son JavaBeans pero usando una sintaxis mucho más simple + + Cuando Groovy es compilado a código de bytes, las siguientes reglas son usadas: + + * Si el nombre es declarado con un modificador de acceso (public, private o + protected), entonces se genera un campo. + + * Un nombre declarado sin modificador de acceso genera un campo privado con + un getter y un setter públicos (ej: una propiedad) + + * Si una propiedad es declarada como final, entonces el campo privado es creado + como final y no se genera un setter. + + * Puedes declarar una propiedad y también sus propios getter y setter. + + * Puedes declarar una propiedad y un campo del mismo nombre, en ese caso, la + propiedad usará ese campo. + + * Si quieres una propiedad private o proteceted, tienes que proveer tus propios + getter y setter, los cuales deben ser declarados private o protected. + + * Si accedes a una propiedad desde dentro de la clase, la propiedad es definida + en tiempo de compilación con this implícito o explícito (por ejemplo, this.foo + o simplemente foo), Groovy accederá al campo directamente en vez de usar el + getter y setter. + + * Si accedes a una propiedad que no existe usando foo explícito o implícito, entonces + Groovy accederá a la propiedad a través de la clase meta, que puede fallar en + tiempo de ejecución. + +*/ + +class Foo { + // propiedad de solo lectura + final String name = "Roberto" + + // propiedad de solo lectura, con getter público y setter como protected + String language + protected void setLanguage(String language) { this.language = language } + + // propiedad de tipo dinámico + def lastName +} + +/* + Derivación Lógica e Iteraciones +*/ + +// Groovy soporta la clásica sintaxis de if - else +def x = 3 + +if(x==1) { + println "One" +} else if(x==2) { + println "Two" +} else { + println "X greater than Two" +} + +// Groovy también soporta el uso del operador ternario: +def y = 10 +def x = (y > 1) ? "worked" : "failed" +assert x == "worked" + +// ¡Groovy también soporta 'El Operador Elvis'! +// En lugar de usar el operador ternario: + +displayName = user.name ? user.name : 'Anonymous' + +// Podemos escribirlo así: +displayName = user.name ?: 'Anonymous' + +// Iteración con For +// Iterando en un rango numérico +def x = 0 +for (i in 0 .. 30) { + x += i +} + +// Iterando sobre una lista +x = 0 +for( i in [5,3,2,1] ) { + x += i +} + +// Iterando sobre un arreglo +array = (0..20).toArray() +x = 0 +for (i in array) { + x += i +} + +// Iterando sobre un mapa +def map = ['name':'Roberto', 'framework':'Grails', 'language':'Groovy'] +x = 0 +for ( e in map ) { + x += e.value +} + +/* + Operadores + + Para la lista de los operadores que Groovy soporta, visita: + http://www.groovy-lang.org/operators.html#Operator-Overloading + + Operadores Groovy útiles +*/ +// Operador de propagación: invocar una acción en todos los elementos de un objeto agregado. +def technologies = ['Groovy','Grails','Gradle'] +technologies*.toUpperCase() // equivale a: technologies.collect { it?.toUpperCase() } + +// Operador de navegación segura: usado para evitar un NullPointerException. +def user = User.get(1) +def username = user?.username + + +/* + Closures + Un Closure en Groovy es como un "bloque de código" o un puntero a un método. Es una + porci´øn de código que es definida y ejecutada en un punto futuro en el tiempo. + + Más información en: http://www.groovy-lang.org/closures.html +*/ +// Ejemplo: +def clos = { println "Hello World!" } + +println "Executing the Closure:" +clos() + +// Pasando parámetros a un closure +def sum = { a, b -> println a+b } +sum(2,4) + +// Los Closures pueden referir a variables no listadas en sus listas de parámetros +def x = 5 +def multiplyBy = { num -> num * x } +println multiplyBy(10) + +// Si tienes un Closure que toma un solo argumento, puedes omitir la +// definición del parámetro en el Closure +def clos = { print it } +clos( "hi" ) + +/* + Groovy puede memorizar los resultados de un Closure [1][2][3] +*/ +def cl = {a, b -> + sleep(3000) // simula algún proceso que consume tiempo + a + b +} + +mem = cl.memoize() + +def callClosure(a, b) { + def start = System.currentTimeMillis() + mem(a, b) + println "Inputs(a = $a, b = $b) - took ${System.currentTimeMillis() - start} msecs." +} + +callClosure(1, 2) +callClosure(1, 2) +callClosure(2, 3) +callClosure(2, 3) +callClosure(3, 4) +callClosure(3, 4) +callClosure(1, 2) +callClosure(2, 3) +callClosure(3, 4) + +/* + Expando + + La clase Expando es un bean dinámico para que podamos agregar propiedades y closures + como métodos a una instancia de esta clase + + http://mrhaki.blogspot.mx/2009/10/groovy-goodness-expando-as-dynamic-bean.html +*/ + def user = new Expando(name:"Roberto") + assert 'Roberto' == user.name + + user.lastName = 'Pérez' + assert 'Pérez' == user.lastName + + user.showInfo = { out -> + out << "Name: $name" + out << ", Last name: $lastName" + } + + def sw = new StringWriter() + println user.showInfo(sw) + + +/* + Metaprogramación (MOP) +*/ + +// Usando ExpandoMetaClass para agregar comportamiento +String.metaClass.testAdd = { + println "we added this" +} + +String x = "test" +x?.testAdd() + +// Interceptando llamadas a métodos +class Test implements GroovyInterceptable { + def sum(Integer x, Integer y) { x + y } + + def invokeMethod(String name, args) { + System.out.println "Invoke method $name with args: $args" + } +} + +def test = new Test() +test?.sum(2,3) +test?.multiply(2,3) + +// Groovy soporta propertyMissing para lidiar con intentos de resolución de propiedades. +class Foo { + def propertyMissing(String name) { name } +} +def f = new Foo() + +assertEquals "boo", f.boo + +/* + TypeChecked y CompileStatic + Groovy, por naturaleza, es y siempre será un lenguaje dinámico pero soporta + typechecked y compilestatic + + Más información: http://www.infoq.com/articles/new-groovy-20 +*/ +// TypeChecked +import groovy.transform.TypeChecked + +void testMethod() {} + +@TypeChecked +void test() { + testMeethod() + + def name = "Roberto" + + println naameee + +} + +// Otro ejemplo: +import groovy.transform.TypeChecked + +@TypeChecked +Integer test() { + Integer num = "1" + + Integer[] numbers = [1,2,3,4] + + Date date = numbers[1] + + return "Test" + +} + +// ejemplo de CompileStatic: +import groovy.transform.CompileStatic + +@CompileStatic +int sum(int x, int y) { + x + y +} + +assert sum(2,5) == 7 + + +``` + +## Más recursos + +[Documentación de Groovy](http://www.groovy-lang.org/documentation.html) + +[Consola Web de Groovy](http://groovyconsole.appspot.com/) + +Únete a un [Groovy user group](http://www.groovy-lang.org/usergroups.html) + +## Libros + +* [Groovy Goodness] (https://leanpub.com/groovy-goodness-notebook) + +* [Groovy in Action] (http://manning.com/koenig2/) + +* [Programming Groovy 2: Dynamic Productivity for the Java Developer] (http://shop.oreilly.com/product/9781937785307.do) + +[1] http://roshandawrani.wordpress.com/2010/10/18/groovy-new-feature-closures-can-now-memorize-their-results/ +[2] http://www.solutionsiq.com/resources/agileiq-blog/bid/72880/Programming-with-Groovy-Trampoline-and-Memoize +[3] http://mrhaki.blogspot.mx/2011/05/groovy-goodness-cache-closure-results.html diff --git a/es-es/hack-es.html.markdown b/es-es/hack-es.html.markdown new file mode 100644 index 00000000..1059117a --- /dev/null +++ b/es-es/hack-es.html.markdown @@ -0,0 +1,307 @@ +--- +language: Hack +contributors: + - ["Stephen Holdaway", "https://github.com/stecman"] + - ["David Lima", "https://github.com/davelima"] +translators: + - ["César Suárez", "https://github.com/csuarez"] +lang: es-es +filename: learnhack-es.hh +--- + +Hack es un superconjunto de PHP que se ejecuta en una máquina virtual llamada HHVM. Hack es casi totalmente compatible con código PHP ya existente y añade varias características típicas de los lenguajes de programación estáticamente tipados. + +En este artículo sólo se cubren las características específicas de Hack. Los detalles sobre la sintaxis de PHP están en el [artículo sobre PHP](http://learnxinyminutes.com/docs/php/) de esta misma web. + +```php +<?hh + +// La sintaxis de Hack sólo se habilita para los ficheros que comienzan con +// un marcador <?hh. Estos marcadores no pueden intercalarse con código HTML, +// tal como se puede hacer con <?php. Al usar el marcador "<?hh //strict" el +// comprobador de tipado en modo estricto se pone en modo estricto. + +// Indicando el tipo de parámetros escalares +function repeat(string $word, int $count) +{ + $word = trim($word); + return str_repeat($word . ' ', $count); +} + +// Indicando el tipo que devuelve una función +function add(...$numbers) : int +{ + return array_sum($numbers); +} + +// Las funciones que no devuelven nada usan el tipo "void" +function truncate(resource $handle) : void +{ + // ... +} + +// Al determinar un tipo, hay que indicar explícitamente si permite el valor +// NULL +function identity(?string $stringOrNull) : ?string +{ + return $stringOrNull; +} + +// Se puede especificar el tipo de las propiedades de una clase +class TypeHintedProperties +{ + public ?string $name; + + protected int $id; + + private float $score = 100.0; + + // El comprobador de tipos de Hack fuerza que las propiedades tipadas + // tengan un valor por defecto o que estén asignadas en el constructor + public function __construct(int $id) + { + $this->id = $id; + } +} + + +// Funciones anónimas concisas (lambdas) +$multiplier = 5; +array_map($y ==> $y * $multiplier, [1, 2, 3]); + + +// Genéricos +class Box<T> +{ + protected T $data; + + public function __construct(T $data) { + $this->data = $data; + } + + public function getData(): T { + return $this->data; + } +} + +function openBox(Box<int> $box) : int +{ + return $box->getData(); +} + + +// Shapes +// +// Hack añade el concepto de shape para definir estructuras similares a +// vectores, pero con un conjunto de claves garantizado y tipado +type Point2D = shape('x' => int, 'y' => int); + +function distance(Point2D $a, Point2D $b) : float +{ + return sqrt(pow($b['x'] - $a['x'], 2) + pow($b['y'] - $a['y'], 2)); +} + +distance( + shape('x' => -1, 'y' => 5), + shape('x' => 2, 'y' => 50) +); + + +// Alias de tipos +// +// Hack permite crear alias para hacer que los tipos complejos sean más legibles +newtype VectorArray = array<int, Vector<int>>; + +// Una tupla que contiene dos enteros +newtype Point = (int, int); + +function addPoints(Point $p1, Point $p2) : Point +{ + return tuple($p1[0] + $p2[0], $p1[1] + $p2[1]); +} + +addPoints( + tuple(1, 2), + tuple(5, 6) +); + + +// Enumerados de primera clase +enum RoadType : int +{ + Road = 0; + Street = 1; + Avenue = 2; + Boulevard = 3; +} + +function getRoadType() : RoadType +{ + return RoadType::Avenue; +} + + +// Promoción de argumentos en constructores +// +// Para evitar repetir una y otra vez la definición de constructores que +// sólo asignan propiedades, Hack añade una sintaxis concisa para definir +// propiedades junto al constructor. +class ArgumentPromotion +{ + public function __construct(public string $name, + protected int $age, + private bool $isAwesome) {} +} + +class WithoutArgumentPromotion +{ + public string $name; + + protected int $age; + + private bool $isAwesome; + + public function __construct(string $name, int $age, bool $isAwesome) + { + $this->name = $name; + $this->age = $age; + $this->isAwesome = $isAwesome; + } +} + + +// Multitarea cooperativa +// +// "async" y "await" son dos palabras claves nuevas para realizar multi-tarea. +// Esto no implica que se usen hilos, sólo permiten transferir el control de la +// ejecución. +{ + for ($i = $start; $i <= $end; $i++) { + echo "$i "; + + // Da a otras tareas la oportunidad de hacer algo + await RescheduleWaitHandle::create(RescheduleWaitHandle::QUEUE_DEFAULT, 0); + } +} + +// Esto imprime "1 4 7 2 5 8 3 6 9" +AwaitAllWaitHandle::fromArray([ + cooperativePrint(1, 3), + cooperativePrint(4, 6), + cooperativePrint(7, 9) +])->getWaitHandle()->join(); + + +// Atributos +// +// Los atributos son una especie de metadatos para funciones. Hack implementa +// algunos atributos especiales para introducir esta característica. + +// El atributo especial __Memoize hace que el resultado de la función se cacheé. +<<__Memoize>> +function doExpensiveTask() : ?string +{ + return file_get_contents('http://example.com'); +} + +// Esta función se va a ejecutar sólo una vez: +doExpensiveTask(); +doExpensiveTask(); + + +// El atributo __ConsistentConstruct indica al comprobador de tipos de Hack que +// asegure que la signatura de __construct sea la misma para todas las +// subclases. +<<__ConsistentConstruct>> +class ConsistentFoo +{ + public function __construct(int $x, float $y) + { + // ... + } + + public function someMethod() + { + // ... + } +} + +class ConsistentBar extends ConsistentFoo +{ + public function __construct(int $x, float $y) + { + // El comprobador de tipos de Hack fuerza que los constructores de + // los padres sean llamados. + parent::__construct($x, $y); + + // ... + } + + // La anotación __Override es un atributo opcional para que el comprobador + // de tipos fuerce que ese método esté sobrecargando un método de un padre + // o de un trait. Sino, fallará. + <<__Override>> + public function someMethod() + { + // ... + } +} + +class InvalidFooSubclass extends ConsistentFoo +{ + // Este constructor no coincide con el padre y causará el siguiente error: + // + // "This object is of type ConsistentBaz. It is incompatible with this + // object of type ConsistentFoo because some of their methods are + // incompatible" + public function __construct(float $x) + { + // ... + } + + // Usando la anotación __Override en un método que no sobrecarga nada se + // producirá el siguiente error: + // + // "InvalidFooSubclass::otherMethod() is marked as override; no non-private + // parent definition found or overridden parent is defined in non-<?hh + // code" + <<__Override>> + public function otherMethod() + { + // ... + } +} + + +// Los traits pueden implementar interfaces (PHP no soporta esto). +interface KittenInterface +{ + public function play() : void; +} + +trait CatTrait implements KittenInterface +{ + public function play() : void + { + // ... + } +} + +class Samuel +{ + use CatTrait; +} + + +$cat = new Samuel(); +$cat instanceof KittenInterface === true; // True + +``` + +## Más información + +Para obtener una explicación más detallada de las características que añade Hack a PHP visita la página de [referencia de Hack](http://docs.hhvm.com/manual/en/hacklangref.php) o la [página oficial de Hack](http://hacklang.org/) para información de caracter más general. + +Visita la [página oficial de HHVM](http://hhvm.com/) para ver las instrucciones de su instalación. + +También puedes visitar la [sección de características de PHP no soportadas por Hack](http://docs.hhvm.com/manual/en/hack.unsupported.php) para más detalles sobre la retrocompatibilidad entre Hack y PHP. diff --git a/es-es/haskell-es.html.markdown b/es-es/haskell-es.html.markdown new file mode 100644 index 00000000..babb1060 --- /dev/null +++ b/es-es/haskell-es.html.markdown @@ -0,0 +1,437 @@ +--- +language: Haskell +contributors: + - ["Adit Bhargava", "http://adit.io"] +translators: + - ["Jorge Antonio Atempa", "http://www.twitter.com/atempa09"] +filename: haskell-es.md +lang: es-es +--- + +Haskell fue diseñado como lenguaje de programación funcional práctico y puro. Es famoso por sus mónadas y su sistema de tipos, pero siempre regreso a él debido a su elegancia. Haskell hace la codificación una verdadera alegría para mí. + +```haskell +-- Para comentar una sola línea utiliza dos guiones. +{- Para comentar múltiples líneas puedes encerrarlas +en un bloque como este. +-} + +---------------------------------------------------- +-- 1. Tipos de datos primitivos y Operadores +---------------------------------------------------- + +-- Tienes números a tu disposición +3 -- 3 + +-- Matématicas, es lo que esperas +1 + 1 -- 2 +8 - 1 -- 7 +10 * 2 -- 20 +35 / 5 -- 7.0 + +-- Por defecto la división no devuelve un entero +35 / 4 -- 8.75 + +-- Para la división entera utiliza +35 `div` 4 -- 8 + +-- Valores booleanos +True +False + +-- Operaciones booleanas +not True -- False +not False -- True +1 == 1 -- True +1 /= 1 -- False +1 < 10 -- True + +-- En los ejemplos superiores, `not` es una función que toma un valor. +-- Haskell no necesita paréntisis para las llamadas a funciones...todos los argumentos +-- son enlistados después de la función. Entonces el patrón general es: +-- func arg1 arg2 arg3... +-- Observa la sección de funciones para obtener información de como escribir tu propia función. + +-- Cadenas y caracteres +"Esto es una cadena." +'a' -- caracter +'No puedes utilizar comillas simples para cadenas.' -- ¡error! + +-- Concatenación de cadenas +"¡Hola " ++ "mundo!" -- "¡Hola mundo!" + +-- Una cadena es una lista de caracteres +['H', 'o', 'l', 'a'] -- "Hola" +"Esto es una cadena" !! 0 -- 'E' + + +---------------------------------------------------- +-- Listas y Tuplas +---------------------------------------------------- + +-- Cada elemento en una lista debe ser del mismo tipo. +-- Estas dos listas son iguales: +[1, 2, 3, 4, 5] +[1..5] + +-- Los rangos son versátiles. +['A'..'F'] -- "ABCDEF" + +-- Puedes crear un paso en un rango. +[0,2..10] -- [0, 2, 4, 6, 8, 10] +[5..1] -- Esto no funciona debido a que Haskell incrementa por defecto. +[5,4..1] -- [5, 4, 3, 2, 1] + +-- indexación en una lista +[0..] !! 5 -- 5 + +-- También tienes listas infinitas en Haskell! +[1..] -- una lista de todos los números naturales + +-- Las listas infinitas funcionan porque Haskell tiene "lazy evaluation". Esto significa +-- que Haskell solo evalúa las cosas cuando lo necesita. Así que puedes pedir +-- el elemento 1000 de tú lista y Haskell te devolverá: + +[1..] !! 999 -- 1000 + +-- Y ahora Haskell ha evaluado elementos 1 - 1000 de esta lista...pero el +-- resto de los elementos de esta lista "infinita" ¡no existen todavía! Haskell no lo hará +-- en realidad los evalúa hasta que los necesita. + +-- uniendo dos listas +[1..5] ++ [6..10] + +-- añadiendo a la cabeza de la lista +0:[1..5] -- [0, 1, 2, 3, 4, 5] + +-- más operaciones con listas +head [1..5] -- 1 +tail [1..5] -- [2, 3, 4, 5] +init [1..5] -- [1, 2, 3, 4] +last [1..5] -- 5 + +-- Listas por comprensión +[x*2 | x <- [1..5]] -- [2, 4, 6, 8, 10] + +-- Listas por comprensión utilizando condicionales +[x*2 | x <- [1..5], x*2 > 4] -- [6, 8, 10] + +-- Cada elemento en una tupla puede ser de diferente tipo, pero una tupla tiene +-- longitud fija. +-- Ejemplo de una tupla: +("haskell", 1) + +-- acceder a los elementos (por ejemplo una tupla de longitud 2) +fst ("haskell", 1) -- "haskell" +snd ("haskell", 1) -- 1 + +---------------------------------------------------- +-- 3. Funciones +---------------------------------------------------- +-- Una función simple que recibe dos variables +add a b = a + b + +-- Nota: Si estas utilizando ghci (el interprete de Haskell) +-- Necesitas utilizar `let`, por ejemplo +-- let add a b = a + b + +-- Utilizando la función +add 1 2 -- 3 + +-- También puedes llamar a la función enmedio de dos argumentos +-- con acentos abiertos: +1 `add` 2 -- 3 + +-- ¡También puedes definir funciones sin tener que utilizar letras! De este modo +-- ¡Tú defines tus propios operadores! Aquí esta un operador que realiza +-- una división entera +(//) a b = a `div` b +35 // 4 -- 8 + +-- Guardas: son una manera fácil para ramificar funciones +fib x + | x < 2 = 1 + | otherwise = fib (x - 1) + fib (x - 2) + +-- La coincidencia de patrones es similar. Aquí hemos dado tres diferentes +-- definiciones para fib. Haskell llamará automáticamente la primer +-- función que coincide con el patrón del valor. +fib 1 = 1 +fib 2 = 2 +fib x = fib (x - 1) + fib (x - 2) + +-- Coincidencia de patrones en tuplas: +foo (x, y) = (x + 1, y + 2) + +-- Coincidencia de patrones en listas. Aquí `x` es el primer elemento +-- en una lista, y `xs` es el resto de la lista. Podemos escribir +-- nuestra propia función map: +myMap func [] = [] +myMap func (x:xs) = func x:(myMap func xs) + +-- Funciones anónimas son creadas con una diagonal invertida seguido de +-- todos los argumentos. +myMap (\x -> x + 2) [1..5] -- [3, 4, 5, 6, 7] + +-- utilizando pliegues (llamado `inject` en algunos lenguajes) con una función +-- anónima. foldl1 significa pliegue por la izquierda, y usa el primer valor +-- en la lista como el valor inicial para el acumulador. +foldl1 (\acc x -> acc + x) [1..5] -- 15 + +---------------------------------------------------- +-- 4. Más funciones +---------------------------------------------------- + +-- aplicación parcial: si no quieres pasar todos los argumentos a una función, +-- esta es "parcialmente aplicada". Esto significa que retorna una función que toma +-- el resto de los argumentos. + +add a b = a + b +foo = add 10 -- foo es actualmente una función que toma un número y suma 10 a esta +foo 5 -- 15 + +-- Otra manera de escribir los mismo +foo = (+10) +foo 5 -- 15 + +-- composición de funciones +-- el (.) encadena funciones. +-- Por ejemplo, aquí foo es una función que toma un valor. Y se le suma 10, +-- posteriormente multiplica el resultado por 5, y devuelve el resultado final. +foo = (*5) . (+10) + +-- (5 + 10) * 5 = 75 +foo 5 -- 75 + +-- fijación de precedencia +-- Haskell tiene otro operador llamado `$`. Este operador aplica a una función +-- para un parámetro dado. En contraste a la aplicación de función estándar, +-- la cúal tiene prioridad más alta posible de 10 y es asociativa por la izquierda, +-- el operador `$` tiene prioridad de 0 y es asociativa por la derecha. Tal que +-- una baja prioridad significa que la expresión a su derecha es aplicada como parámetro a la función a su izquierda. + +-- antes +even (fib 7) -- false + +-- equivalentemente +even $ fib 7 -- false + +-- composición de funciones +even . fib $ 7 -- false + + +---------------------------------------------------- +-- 5. Firma de tipos +---------------------------------------------------- + +-- Haskell tiene un fuerte sistema de tipado, y cada cosa tiene una firma de tipo. + +-- Algunos tipos básicos: +5 :: Integer +"hola" :: String +True :: Bool + +-- Las funciones tienen muchos tipos. +-- `not` toma un booleano y devuelve un booleano: +-- not :: Bool -> Bool + +-- Aquí, esta función toma dos argumentos: +-- add :: Integer -> Integer -> Integer + +-- Cuando defines un valor, es una buena práctica escribir su tipo en una línea superior: +double :: Integer -> Integer +double x = x * 2 + +---------------------------------------------------- +-- 6. Control de flujo y Expresiones If +---------------------------------------------------- + +-- expressiones if en una sola línea +haskell = if 1 == 1 then "awesome" else "awful" -- haskell = "awesome" + +-- expressiones if en múltiples líneas, la identación es importante +haskell = if 1 == 1 + then "awesome" + else "awful" + +-- expressiones case: Aquí se muestra como analizar los argumentos +-- desde línea de comandos +case args of + "help" -> printHelp + "start" -> startProgram + _ -> putStrLn "bad args" + +-- Haskell no tiene ciclos; en lugar de esto utiliza recursión. +-- map aplica una función sobre cada elemento en un arreglo + +map (*2) [1..5] -- [2, 4, 6, 8, 10] + +-- tú puedes crear una función utilizando map +for array func = map func array + +-- y entonces utilizarla +for [0..5] $ \i -> show i + +-- también podríamos haberlo escrito de esta manera: +for [0..5] show + +-- Puedes utilizar foldl o foldr para reducir una lista +-- foldl <fn> <valor inicial> <lista> +foldl (\x y -> 2*x + y) 4 [1,2,3] -- 43 + +-- Esto es lo mismo que +(2 * (2 * (2 * 4 + 1) + 2) + 3) + +-- foldl es izquierda, foldr es derecha +foldr (\x y -> 2*x + y) 4 [1,2,3] -- 16 + +-- Esto es los mismo que +(2 * 1 + (2 * 2 + (2 * 3 + 4))) + +---------------------------------------------------- +-- 7. Tipos de datos +---------------------------------------------------- + +-- Por ejemplo, para crear tu propio tipo de dato en Haskell + +data Color = Rojo | Azul | Verde + +-- Ahora puedes utilizarlo en una función: + + +say :: Color -> String +say Rojo = "¡Es Rojo!" +say Azul = "¡Es Azul!" +say Verde = "¡Es Verde!" + +-- Tus tipos de datos pueden tener parámetros también: + +data Maybe a = Nothing | Just a + +-- Estos son todos de tipo Maybe +Just "hello" -- de tipo `Maybe String` +Just 1 -- de tipo `Maybe Int` +Nothing -- de tipo `Maybe a` para cualquier `a` + +---------------------------------------------------- +-- 8. Haskell IO +---------------------------------------------------- + +-- Mientras que IO no puede ser explicado plenamente sin explicar las mónadas, +-- no es difícil explicar lo suficiente para ponerse en marcha. + +-- Cuando un programa en Haskell se ejecuta, `main` es +-- llamado. Este debe devolver un valor de tipo `IO ()`. Por ejemplo: + +main :: IO () +main = putStrLn $ "¡Hola, cielo! " ++ (say Blue) +-- putStrLn tiene tipo String -> IO () + +-- Es más fácil de hacer IO si puedes implementar tu programa como +-- una función de String a String. La función +-- interact :: (String -> String) -> IO () +-- recibe como entrada un texto, ejecuta una función e imprime +-- una salida. + +countLines :: String -> String +countLines = show . length . lines + +main' = interact countLines + +-- Puedes pensar en el valor de tipo `IO ()` como la representación +-- de una secuencia de acciones que la computadora hace, al igual que +-- un programa escrito en un lenguaje imperativo. Podemos utilizar +-- la notación `do` para encadenar acciones. Por ejemplo: + +sayHello :: IO () +sayHello = do + putStrLn "¿Cual es tu nombre?" + name <- getLine -- obtenemos un valor y lo proporcionamos a "name" + putStrLn $ "Hola, " ++ name + +-- Ejercicio: escribe tu propia version de `interact` que solo lea +-- una linea como entrada. + +-- Nunca se ejecuta el código en `sayHello`, sin embargo. La única +-- acción que siempre se ejecuta es el valor de `main`. +-- Para ejecutar `sayHello` comenta la definición anterior de `main` +-- y sustituyela por: +-- main = sayHello + +-- Vamos a entender mejor como funciona la función `getLine` cuando +-- la utilizamos. Su tipo es: +-- getLine :: IO String +-- Puedes pensar en el valor de tipo `IO a` como la representación +-- programa que generará un valor de tipo `a` +-- cuando es ejecutado (además de cualquier otra cosa que haga). Podemos +-- almacenar y reutilizar el valor usando `<-`. También podemos +-- crear nuestra propia acción de tipo `IO String`: + +action :: IO String +action = do + putStrLn "Esta es una linea." + input1 <- getLine + input2 <- getLine + -- El tipo de la sentencia `do` es la de su última línea. + -- `return` no es una palabra clave, sino simplemente una función + return (input1 ++ "\n" ++ input2) -- return :: String -> IO String + +-- Podemos usar esto sólo como usabamos `getLine`: + +main'' = do + putStrLn "¡Volveré a repetir dos líneas!" + result <- action + putStrLn result + putStrLn "Esto es todo, ¡amigos!" + +-- El tipo `IO` es un ejemplo de una "mónada". La forma en que Haskell utiliza una monada +-- permite que sea un lenguaje puramente funcional. Cualquier función que +-- interactue con el mundo exterior (por ejemplo usar IO) obtiene una marca `IO` +-- como su firma de tipo. Esto nos permite pensar qué funciones son "puras" +-- (que no interactuan con el mundo exterior o modifican el estado) y que funciones no lo son. + +-- Esta es una poderosa característica, porque es una manera fácil de ejecutar funciones puras +-- concurrentemente; entonces, la concurrencia en Haskell es muy fácil. + + +---------------------------------------------------- +-- 9. El interprete de comandos de Haskell +---------------------------------------------------- + +-- Para comenzar escribe desde la terminal `ghci`. +-- Ahora puede escribir código en Haskell. Para cualquier valor nuevo +-- que necesites crear utiliza `let`: + +let foo = 5 + +-- Puedes inspeccionar el tipo de cualquier valor con `:t`: + +>:t foo +foo :: Integer + +-- Puedes ejecutar acciones de tipo `IO ()` + +> sayHello +¿Cual es tu nombre? +Amigo +Hola, Amigo + +``` + +Existe mucho más de Haskell, incluyendo clases de tipos y mónadas. Estas son +las grandes ideas que hacen a Haskell divertido. Te dejamos un ejemplo final +de Haskell: una implementación del algoritmo QuickSort: + +```haskell +qsort [] = [] +qsort (p:xs) = qsort lesser ++ [p] ++ qsort greater + where lesser = filter (< p) xs + greater = filter (>= p) xs +``` + +Haskell es fácil de instalar. Obtenlo [aquí](http://www.haskell.org/platform/). + +Usted puede encontrar más información en: +[Learn you a Haskell](http://learnyouahaskell.com/) o +[Real World Haskell](http://book.realworldhaskell.org/) o +[Aprende Haskell por el bien de todos](http://aprendehaskell.es/) diff --git a/es-es/javascript-es.html.markdown b/es-es/javascript-es.html.markdown index d475cf42..31512dc4 100644 --- a/es-es/javascript-es.html.markdown +++ b/es-es/javascript-es.html.markdown @@ -16,21 +16,23 @@ con Java para aplicaciones más complejas. Debido a su integracion estrecha con web y soporte por defecto de los navegadores modernos se ha vuelto mucho más común para front-end que Java. -Aunque JavaScript no sólo se limita a los navegadores web: Node.js, Un proyecto que proporciona un entorno de ejecución independiente para el motor V8 de Google Chrome, se está volviendo más y más popular. +Sin embargo, JavaScript no sólo se limita a los navegadores web: Node.js, un proyecto que proporciona un entorno de ejecución independiente para el motor V8 de Google Chrome, se está volviendo más y más popular. ¡La retroalimentación es bienvenida! Puedes encontrarme en: [@adambrenecki](https://twitter.com/adambrenecki), o [adam@brenecki.id.au](mailto:adam@brenecki.id.au). ```js -// Los comentarios son como en C. Los comentarios de una sola línea comienzan con //, +// Los comentarios en JavaScript son los mismos como comentarios en C. + +//Los comentarios de una sola línea comienzan con //, /* y los comentarios multilínea comienzan y terminan con */ // Cada sentencia puede ser terminada con punto y coma ; hazAlgo(); -// ... aunque no es necesario, ya que el punto y coma se agrega automaticamente +// ... aunque no es necesario, ya que el punto y coma se agrega automáticamente // cada que se detecta una nueva línea, a excepción de algunos casos. hazAlgo() @@ -80,13 +82,13 @@ false; !true; // = false !false; // = true -// Para comprobar una igualdad se usa == -1 == 1; // = true -2 == 1; // = false +// Para comprobar una igualdad se usa === +1 === 1; // = true +2 === 1; // = false -// Para comprobar una desigualdad se usa != -1 != 1; // = false -2 != 1; // = true +// Para comprobar una desigualdad se usa !== +1 !== 1; // = false +2 !== 1; // = true // Más comparaciones 1 < 10; // = true @@ -109,7 +111,7 @@ null == undefined; // = true null === undefined; // false // Los Strings funcionan como arreglos de caracteres -// Puedes accesar a cada caracter con la función charAt() +// Puedes acceder a cada caracter con la función charAt() "Este es un String".charAt(0); // = 'E' // ...o puedes usar la función substring() para acceder a pedazos más grandes @@ -186,7 +188,7 @@ miObjeto.miLlave; // = "miValor" // agregar nuevas llaves. miObjeto.miTerceraLlave = true; -// Si intentas accesar con una llave que aún no está asignada tendrás undefined. +// Si intentas acceder con una llave que aún no está asignada tendrás undefined. miObjeto.miCuartaLlave; // = undefined /////////////////////////////////// @@ -301,7 +303,7 @@ i; // = 5 - en un lenguaje que da ámbitos por bloque esto sería undefined, per //inmediatamente", que preveé variables temporales de fugarse al ámbito global (function(){ var temporal = 5; - // Podemos accesar al ámbito global asignando al 'objeto global', el cual + // Podemos acceder al ámbito global asignando al 'objeto global', el cual // en un navegador siempre es 'window'. El objeto global puede tener // un nombre diferente en ambientes distintos, por ejemplo Node.js . window.permanente = 10; @@ -321,7 +323,7 @@ function decirHolaCadaCincoSegundos(nombre){ alert(texto); } setTimeout(interna, 5000); - // setTimeout es asíncrono, así que la funcion decirHolaCadaCincoSegundos + // setTimeout es asíncrono, así que la función decirHolaCadaCincoSegundos // terminará inmediatamente, y setTimeout llamará a interna() a los cinco segundos // Como interna está "cerrada dentro de" decirHolaCadaCindoSegundos, interna todavía tiene // acceso a la variable 'texto' cuando es llamada. @@ -339,7 +341,7 @@ var miObjeto = { }; miObjeto.miFuncion(); // = "¡Hola Mundo!" -// Cuando las funciones de un objeto son llamadas, pueden accesar a las variables +// Cuando las funciones de un objeto son llamadas, pueden acceder a las variables // del objeto con la palabra clave 'this'. miObjeto = { miString: "¡Hola Mundo!", @@ -401,11 +403,11 @@ var MiConstructor = function(){ miNuevoObjeto = new MiConstructor(); // = {miNumero: 5} miNuevoObjeto.miNumero; // = 5 -// Todos los objetos JavaScript tienen un 'prototipo'. Cuando vas a accesar a una +// Todos los objetos JavaScript tienen un 'prototipo'. Cuando vas a acceder a una // propiedad en un objeto que no existe en el objeto el intérprete buscará en // el prototipo. -// Algunas implementaciones de JavaScript te permiten accesar al prototipo de +// Algunas implementaciones de JavaScript te permiten acceder al prototipo de // un objeto con la propiedad __proto__. Mientras que esto es útil para explicar // prototipos, no es parte del estándar; veremos formas estándar de usar prototipos // más adelante. @@ -440,7 +442,7 @@ miPrototipo.sentidoDeLaVida = 43; miObjeto.sentidoDeLaVida; // = 43 // Mencionabamos anteriormente que __proto__ no está estandarizado, y que no -// existe una forma estándar de accesar al prototipo de un objeto. De todas formas. +// existe una forma estándar de acceder al prototipo de un objeto. De todas formas. // hay dos formas de crear un nuevo objeto con un prototipo dado. // El primer método es Object.create, el cual es una adición reciente a JavaScript, @@ -476,7 +478,7 @@ typeof miNumero; // = 'number' typeof miNumeroObjeto; // = 'object' miNumero === miNumeroObjeyo; // = false if (0){ - // Este código no se ejecutara porque 0 es false. + // Este código no se ejecutará porque 0 es false. } // Aún así, los objetos que envuelven y los prototipos por defecto comparten diff --git a/es-es/json-es.html.markdown b/es-es/json-es.html.markdown index fff678eb..c98049f9 100644 --- a/es-es/json-es.html.markdown +++ b/es-es/json-es.html.markdown @@ -21,22 +21,22 @@ JSON en su forma más pura no tiene comentarios, pero la mayoría de los parsead "llaves": "siempre debe estar entre comillas (ya sean dobles o simples)", "numeros": 0, "strings": "Høla, múndo. Todo el unicode está permitido, así como \"escapar\".", - "soporta booleanos?": true, - "vacios": null, + "¿soporta booleanos?": true, + "vacíos": null, "numero grande": 1.2e+100, "objetos": { - "comentario": "La mayoria de tu estructura vendra de objetos.", + "comentario": "La mayoría de tu estructura vendrá de objetos.", "arreglo": [0, 1, 2, 3, "Los arreglos pueden contener cualquier cosa.", 5], "otro objeto": { - "comentario": "Estas cosas pueden estar anidadas, muy util." + "comentario": "Estas cosas pueden estar anidadas, muy útil." } }, - "tonteria": [ + "tontería": [ { "fuentes de potasio": ["bananas"] }, @@ -50,10 +50,10 @@ JSON en su forma más pura no tiene comentarios, pero la mayoría de los parsead "estilo alternativo": { "comentario": "Mira esto!" - , "posicion de la coma": "no importa - mientras este antes del valor, entonces sera valido" - , "otro comentario": "que lindo" + , "posición de la coma": "no importa - mientras este antes del valor, entonces sera válido" + , "otro comentario": "qué lindo" }, - "eso fue rapido": "Y, estas listo. Ahora sabes todo lo que JSON tiene para ofrecer." + "eso fue rapido": "Y, estás listo. Ahora sabes todo lo que JSON tiene para ofrecer." } ``` diff --git a/es-es/latex-es.html.markdown b/es-es/latex-es.html.markdown new file mode 100644 index 00000000..aff3c603 --- /dev/null +++ b/es-es/latex-es.html.markdown @@ -0,0 +1,213 @@ +--- +language: latex +lang: es-es +contributors: + - ["Chaitanya Krishna Ande", "http://icymist.github.io"] + - ["Colton Kohnke", "http://github.com/voltnor"] + - ["Sricharan Chiruvolu", "http://sricharan.xyz"] +translators: + - ["Mario Pérez", "https://github.com/MarioPerezEsteso"] +filename: learn-latex-es.tex +--- + +```tex +% Todas las líneas comentadas comienzan con % +% No existen los comentarios multilínea + +% LaTeX NO es un software de procesamiento de texto que cumple con +% "Lo que ves es lo que tienes" como MS Word u OpenOffice + +% Todos los comandos de LaTeX comienzan con una contrabarra (\) + +% Los documentos LaTeX comienzan definiendo el tipo de documento que se va a +% compilar. Algunos tipos de documentos son libros, informes, presentaciones, +% etc. Las opciones para el documento comienzan en los corchetes []. En este +% caso, se especifica que queremos utilizar una fuente de tamaño 12pt. +\documentclass[12pt]{article} + +% A continuación, definimos los paquetes que utilizará el documento. +% Si quieres incluir gráficos, texto coloreado o código fuente de otro lenguaje, +% debes extender las funciones de LaTeX. Esto se consigue añadiendo paquetes. +% A continuación se incluirán los paquetes float y caption para figuras. +\usepackage{caption} +\usepackage{float} + +% También podemos definir otras propiedades en el documento +\author{Chaitanya Krishna Ande, Colton Kohnke \& Sricharan Chiruvolu} +\date{\today} +\title{Learn LaTeX in Y Minutes!} + +% Ahora estamos preparados para comenzar el documento +% Todo lo que se encuentre antes de esta línea se llama "El Preámbulo" +\begin{document} +% Si especificamos el autor, fecha y título, LaTeX creará una página como título +% por nosotros +\maketitle + +% La mayoría de los artículos de investigación tienen un abstract. Es posible +% utilizar comandos predefinidos para ello. +% Esto debería aparecer en su orden lógico. Tras el título pero antes de las +% secciones principales del cuerpo. +% Este comando está disponible en los tipos de documentos article y report. +\begin{abstract} + Documentación de LaTex escrita en LaTex. +\end{abstract} + +% Los comandos de sección son intuitivos. +% Todos los títulos de secciones son añadidos automáticamente a la tabla de contenidos. +\section{Introducción} +Hola, mi nombre es Mario Pérez y estoy traduciendo este documento para aprender LaTex. + +\section{Otra sección} +Este es el texto de otra sección. Creo que necesitará una subsección. + +\subsection{Esto es una subsección} % Las subsecciones también son fáciles. +Creo que necesitamos otra más. + +\subsubsection{Pitágoras} +Mejor ahora. +\label{subsec:pitagoras} + +% Utilizando el asterisco podemos decirle a LaTeX que no ponga los números de secciones y subsecciones. +% Esto también funciona con otros comandos de LaTeX. +\section*{Esto es una sección no numerada} +¡No todas las secciones tienen que estar numeradas! + +\section{Algunas notas} +LaTeX es generalmente bastante bueno situando el texto donde debe ir. Si una lína \\ necesita \\ ser \\ rota \\ puedes poner \textbackslash\textbackslash en el código fuente. \\ + +\section{Listas} +Las listas son de las cosas más fáciles de crear en LaTeX. Necesito ir a comprar mañana, así que vamos a crear una lista de la compra. +\begin{enumerate} % Esto crea una lista numerada. + % \item crea un elemento + \item Ensalada. + \item 27 sandías. + \item Pescado. + % podemos incluso sobreescribir el número del ítem usando [] + \item[cuántos?] Plátanos. + + No es un ítem de la lista, pero sigue siendo parte de la enumeración. + +\end{enumerate} % Todos los contextos deben tener un final. + +\section{Matemáticas} + +Uno de los usos principales de LaTeX es la producción de artículos académicos o técnicos. Normalmente relacionados con la ciencia y las matemáticas. Debido a esto, necesitamos poder añadir símbolos especiales a nuestro artículo.\\ + +En matemáticas hay muchos símbolos. Más de los que podemos encontrar en un teclado. Flechas o letras por nombrar un par.\\ + +Algunos símbolos juegan un papel fundamental en muchos artículos de investigación matemática. Así es como se establece que todo Y pertenece a X: $\forall$ x $\in$ X. \\ +He necesitado añadir el signo $ antes de los símbolos. Esto se debe a que cuando escribimos, estamos en modo texto. Sin embargo, los símbolos solo pueden utilizarse en modo matemático, al cual se entra con el signo $. +% Lo opuesto también se cumple. Una variable también puede ser mostrada en modo matemático, al que también se puede entrar con \[\] + +\[a^2 + b^2 = c^2 \] + +Mi letra griega favorita es $\xi$. También me gustan $\beta$, $\gamma$ y $\sigma$. +Todavía no he encontrado una letra griega que LaTeX no conozca. + +Los operadores son también una parte esencial de un documento matemático: +funciones trigonométricas ($\sin$, $\cos$, $\tan$), logaritmos y exponenciales ($\log$, $\exp$), límites ($\lim$), etc. tienen comandos predefinidos en LaTeX. + +Vamos a escribir una ecuación para ver cómo se hace: \\ + +$\cos(2\theta) = \cos^{2}(\theta) - \sin^{2}(\theta)$ + +Las fracciones (numeradores-denominadores) pueden escribirse de la siguiente forma: + +% 10 / 7 +$^{10}/_{7}$ + +% Las fracciones relativamente complejas pueden escribirse como +% \frac{numerador}{denominador} +$\frac{n!}{k!(n - k)!}$ \\ + +También podemos insertar ecuaciones en un contexto de ecuación. + +% Mostrar matemáticas en el contexto de ecuaciones +\begin{equation} % entra en modo matemático + c^2 = a^2 + b^2. + \label{eq:pitagoras} % para referencias +\end{equation} % Todos los contextos deben tener un final. + +Podemos referenciar nuestra nueva ecuación. +Ecuación ~\ref{eq:pythagoras} también se conoce como el Teorema de Pitágoras, el cual también se encuentra en la sección ~\ref{subsec:pythagoras}. Muchas cosas pueden ser etiquetadas: figures, equations, sections, etc. + +Los sumatorios e integrales son escritor son los comandos sum e int: + +% Algunos compiladores de LaTeX se quejarán si hay líneas en blanco +% En un contexto de ecuación. +\begin{equation} + \sum_{i=0}^{5} f_{i} +\end{equation} +\begin{equation} + \int_{0}^{\infty} \mathrm{e}^{-x} \mathrm{d}x +\end{equation} + +\section{Figuras} + +Vamos a insertar una figura. Situarla puede ser algo complicado. + +\begin{figure}[H] % H aquí establece la situación de la figura. + \centering % centra la figura en la página + % Inserta una figura escalada por 0.8 el ancho de la página. + %\includegraphics[width=0.8\linewidth]{right-triangle.png} + % La línea anterior ha sido comentada para poder compilar este archivo. Por favor, usa tu imaginación. + \caption{Triángulo con lados $a$, $b$, $c$} + \label{fig:right-triangle} +\end{figure} + +\subsection{Tablas} +También podemos insertar tablas de la misma manera que las figuras. + +\begin{table}[H] + \caption{Título para la tabla.} + % los argumentos en {} describen cómo cada fila va a ser representada. + \begin{tabular}{c|cc} + Número & Nombre & Apellido \\ + \hline % una línea horizontal + 1 & Biggus & Dickus \\ + 2 & Monty & Python + \end{tabular} +\end{table} + +% \section{Hyperlinks} % En construcción + +\section{Haciendo que LaTeX no compile algo (por ejemplo, código fuente)} +Digamos que queremos incluir código fuente dentro de nuestro documento LaTex. En ese caso, debemos indicarle a LaTeX que no trate de compilarlo y simplemente lo muestre en el documento. Esto lo realizamos en el contexto verbatim. + +% Hay otros paquetes para esta misma tarea, pero verbatim es el más básico. +\begin{verbatim} + print("Hola Mundo!") + a%b; % Podemos usar los signos % en verbatim. + aleatorio = 4; # Número aleatorio +\end{verbatim} + +\section{Compilación} + +Ahora mismo te estarás preguntando cómo compilar este fabuloso documento y obtener un documento PDF.\\ +Para obtener el documento final utilizando LaTeX hay que seguir los siguientes pasos: + \begin{enumerate} + \item Escribe el documento en texto plano. + \item Compila el código para producir un PDF. + Los pasos de compilación serán algo parecido a esto (en Linux): \\ + \begin{verbatim} + $pdflatex learn-latex.tex learn-latex.pdf + \end{verbatim} + \end{enumerate} + +Un gran número de editores LaTeX combinan ambos pasos para que sea más sencillo obtener el documento. + +Escribe toda la información de formato en el paso 1 y con el paso 2 obtendrás el documento que has definido en el paso anterior. + +\section{End} + +Esto es todo por ahora. + +% fin del documento +\end{document} +``` + +## Más información sobre LaTeX + +* El wikilibro LaTeX: [https://es.wikibooks.org/wiki/Manual_de_LaTeX](https://es.wikibooks.org/wiki/Manual_de_LaTeX) +* Un tutorial real: [http://www.latex-tutorial.com/](http://www.latex-tutorial.com/) diff --git a/es-es/markdown-es.html.markdown b/es-es/markdown-es.html.markdown index d90e3eb5..0505b4cb 100644 --- a/es-es/markdown-es.html.markdown +++ b/es-es/markdown-es.html.markdown @@ -11,7 +11,7 @@ lang: es-es Markdown fue creado por John Gruber en 2004. Su propósito es ser una sintaxis fácil de leer y escribir que se convierta fácilmente a HTML (y, actualmente, otros formatos también). -¡Denme todo la retroalimentación que quieran! / ¡Sientanse en la libertad de hacer forks o pull requests! +¡Denme toda la retroalimentación que quieran! / ¡Sientanse en la libertad de hacer forks o pull requests! ```markdown @@ -44,7 +44,7 @@ Esto es un h2 ------------- <!-- Estilos para texto plano --> -<!-- El texto puede ser fácilmente estilizaedo con italicas, negritas o tachado +<!-- El texto puede ser fácilmente estilizado con italicas, negritas o tachado usando markdown --> *Este texto está en itálicas.* @@ -57,12 +57,12 @@ __Al igual que este texto.__ **_Al igual que este!_** *__¡Y este!__* -<!-- En Github Flavored Markdown, el cual es usado para mostrar archivos -Markdown en Github, también tenemos: --> +<!-- En GitHub Flavored Markdown, el cual es usado para mostrar archivos +Markdown en GitHub, también tenemos: --> ~~Este texto está tachado.~~ -<!-- Los párrafos son una o múltuples líneas de texto adyacentes separadas por +<!-- Los párrafos son una o múltiples líneas de texto adyacentes separadas por una o múltiples líneas en blanco--> Este es un párrafo. Estoy escribiendo un párrafo, ¿No es divertido? @@ -150,7 +150,7 @@ para indentar dentro del código --> ¡John no sabía lo que la función `go_to()` hacía! -<!-- Con Github Flavored Markdown, puedes usar una sintaxis especial para código --> +<!-- Con GitHub Flavored Markdown, puedes usar una sintaxis especial para código --> \`\`\`ruby <!-- quita esas comillas cuando lo hagas, deja sólo ```ruby ! --> def foobar @@ -158,7 +158,7 @@ def foobar end \`\`\` <!-- aquí también, sin comillas, sólo ``` --> -<!-- El texto de arriba no necesita indentación, aparte Github usará +<!-- El texto de arriba no necesita indentación, aparte GitHub usará resaltará la sintaxis del lenguaje que especifiques después de ``` --> <!-- Regla horizontal (<hr />) --> @@ -231,7 +231,7 @@ Quiero escribir *este texto rodeado por asteriscos* pero no quiero que esté en así que hago esto: \*Este texto está rodeado de asteriscos\*. <!-- Tablas --> -<!-- Las tablas sólo están disponibles en Github Flavored Markdown y son un poco pesadas, +<!-- Las tablas sólo están disponibles en GitHub Flavored Markdown y son un poco pesadas, pero si de verdad las quieres: --> | Col1 | Col2 | Col3 | diff --git a/es-es/objective-c-es.html.markdown b/es-es/objective-c-es.html.markdown new file mode 100644 index 00000000..bdbce524 --- /dev/null +++ b/es-es/objective-c-es.html.markdown @@ -0,0 +1,851 @@ +--- +language: Objective-C +contributors: + - ["Eugene Yagrushkin", "www.about.me/yagrushkin"] + - ["Yannick Loriot", "https://github.com/YannickL"] + - ["Levi Bostian", "https://github.com/levibostian"] +translators: + - ["David Hsieh", "http://github.com/deivuh"] +lang: es-es +filename: LearnObjectiveC-es.m +--- +Objective C es el lenguaje de programación principal utilizado por Apple para los sistemas operativos OS X y iOS y sus respectivos frameworks, Cocoa y Cocoa Touch. +Es un lenguaje de programación para propósito general que le agrega al lenguaje de programación C una mensajería estilo "Smalltalk". + + +```objective_c +// Los comentarios de una sola línea inician con // + +/* +Los comentarios de múltiples líneas se ven así. +*/ + +// Importa los encabezados de Foundation con #import +// Utiliza <> para importar archivos globales (generalmente frameworks) +// Utiliza "" para importar archivos locales (del proyecto) +#import <Foundation/Foundation.h> +#import "MyClass.h" + +// Si habilitas módulos para proyectos de iOS >= 7.0 u OS X >= 10.9 en +// Xcode 5, puedes importarlos de la siguiente manera: +@import Foundation; + +// El punto de entrada de tu programa es una función llamada +// main con un tipo de retorno entero. +int main (int argc, const char * argv[]) +{ + // Crear un autorelease pool para manejar la memoria al programa + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + // Si se utiliza el conteo automático de referencias (ARC), + // utiliza @autoreleasepool: + @autoreleasepool { + + // Utiliza NSLog para imprimir líneas a la consola + NSLog(@"Hello World!"); // Imprimir el string "Hello World!" + + /////////////////////////////////////// + // Tipos y variables + /////////////////////////////////////// + + // Declaraciones de primitivos + int myPrimitive1 = 1; + long myPrimitive2 = 234554664565; + + // Declaraciones de objetos + // Pon el * como prefijo de los nombre de las variables para declaraciones + // de objetos de tipos fuertes + MyClass *myObject1 = nil; // Tipo fuerte + id myObject2 = nil; // Tipo débil + // %@ es un objeto + // 'description' es una convención para mostrar el valor de los objetos + NSLog(@"%@ and %@", myObject1, [myObject2 description]); + // imprime => "(null) and (null)" + + // String + NSString *worldString = @"World"; + NSLog(@"Hello %@!", worldString); // imprime => "Hello World!" + // NSMutableString es una versión mutable del objeto NSString + NSMutableString *mutableString = [NSMutableString stringWithString:@"Hello"]; + [mutableString appendString:@" World!"]; + NSLog(@"%@", mutableString); // imprime => "Hello World!" + + // Literales de caracteres + NSNumber *theLetterZNumber = @'Z'; + char theLetterZ = [theLetterZNumber charValue]; // o 'Z' + NSLog(@"%c", theLetterZ); + + // Literales de enteros + NSNumber *fortyTwoNumber = @42; + int fortyTwo = [fortyTwoNumber intValue]; // o 42 + NSLog(@"%i", fortyTwo); + + NSNumber *fortyTwoUnsignedNumber = @42U; + unsigned int fortyTwoUnsigned = [fortyTwoUnsignedNumber unsignedIntValue]; // o 42 + NSLog(@"%u", fortyTwoUnsigned); + + NSNumber *fortyTwoShortNumber = [NSNumber numberWithShort:42]; + short fortyTwoShort = [fortyTwoShortNumber shortValue]; // o 42 + NSLog(@"%hi", fortyTwoShort); + + NSNumber *fortyOneShortNumber = [NSNumber numberWithShort:41]; + unsigned short fortyOneUnsigned = [fortyOneShortNumber unsignedShortValue]; // o 41 + NSLog(@"%u", fortyOneUnsigned); + + NSNumber *fortyTwoLongNumber = @42L; + long fortyTwoLong = [fortyTwoLongNumber longValue]; // o 42 + NSLog(@"%li", fortyTwoLong); + + NSNumber *fiftyThreeLongNumber = @53L; + unsigned long fiftyThreeUnsigned = [fiftyThreeLongNumber unsignedLongValue]; // o 53 + NSLog(@"%lu", fiftyThreeUnsigned); + + // Literales de punto flotante + NSNumber *piFloatNumber = @3.141592654F; + float piFloat = [piFloatNumber floatValue]; // o 3.141592654f + NSLog(@"%f", piFloat); // imprime => 3.141592654 + NSLog(@"%5.2f", piFloat); // imprime => " 3.14" + + NSNumber *piDoubleNumber = @3.1415926535; + double piDouble = [piDoubleNumber doubleValue]; // o 3.1415926535 + NSLog(@"%f", piDouble); + NSLog(@"%4.2f", piDouble); // imprime => "3.14" + + // NSDecimalNumber es una clase de punto-fijo que es más preciso que float o double + NSDecimalNumber *oneDecNum = [NSDecimalNumber decimalNumberWithString:@"10.99"]; + NSDecimalNumber *twoDecNum = [NSDecimalNumber decimalNumberWithString:@"5.002"]; + // NSDecimalNumber no tiene la capacidad de utilizar los operadores estándares + // +, -, * , /, por lo que cuenta con sus propios operadores: + [oneDecNum decimalNumberByAdding:twoDecNum]; + [oneDecNum decimalNumberBySubtracting:twoDecNum]; + [oneDecNum decimalNumberByMultiplyingBy:twoDecNum]; + [oneDecNum decimalNumberByDividingBy:twoDecNum]; + NSLog(@"%@", oneDecNum); // imprime => 10.99 como NSDecimalNumber es inmutable + + // Literales BOOL + NSNumber *yesNumber = @YES; + NSNumber *noNumber = @NO; + // o + BOOL yesBool = YES; + BOOL noBool = NO; + NSLog(@"%i", yesBool); // prints => 1 + + // Objecto arreglo + // Puede contener diferentes tipos de datos, pero deben de ser un objeto de + // Objective-C + NSArray *anArray = @[@1, @2, @3, @4]; + NSNumber *thirdNumber = anArray[2]; + NSLog(@"Third number = %@", thirdNumber); // imprime => "Third number = 3" + // NSMutableArray es una versión mutable de NSArray, permitiendo el cambio + // de los elementos del arreglo y el agrandado o encojimiento del objeto arreglo. + // Conveniente, pero no tan eficiente como NSArray en cuanto a rendimiento. + NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:2]; + [mutableArray addObject:@"Hello"]; + [mutableArray addObject:@"World"]; + [mutableArray removeObjectAtIndex:0]; + NSLog(@"%@", [mutableArray objectAtIndex:0]); // imprime => "World" + + // Objecto Diccionario + NSDictionary *aDictionary = @{ @"key1" : @"value1", @"key2" : @"value2" }; + NSObject *valueObject = aDictionary[@"A Key"]; + NSLog(@"Object = %@", valueObject); // imprime => "Object = (null)" + // NSMutableDictionary también está disponible como un objeto mutable + NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithCapacity:2]; + [mutableDictionary setObject:@"value1" forKey:@"key1"]; + [mutableDictionary setObject:@"value2" forKey:@"key2"]; + [mutableDictionary removeObjectForKey:@"key1"]; + + // Objeto de Set + NSSet *set = [NSSet setWithObjects:@"Hello", @"Hello", @"World", nil]; + NSLog(@"%@", set); // imprime => {(Hello, World)} (el orden puede variar) + // NSMutableSet también está disponible como un objeto mutable + NSMutableSet *mutableSet = [NSMutableSet setWithCapacity:2]; + [mutableSet addObject:@"Hello"]; + [mutableSet addObject:@"Hello"]; + NSLog(@"%@", mutableSet); // prints => {(Hello)} + + /////////////////////////////////////// + // Operadores + /////////////////////////////////////// + + // Los operadores funcionan como en el lenguaje C + // Por ejemplo: + 2 + 5; // => 7 + 4.2f + 5.1f; // => 9.3f + 3 == 2; // => 0 (NO) + 3 != 2; // => 1 (YES) + 1 && 1; // => 1 (and lógico) + 0 || 1; // => 1 (or lógico) + ~0x0F; // => 0xF0 (negación bitwise) + 0x0F & 0xF0; // => 0x00 (AND bitwise) + 0x01 << 1; // => 0x02 (acarreamiento a la izquierda bitwise (por 1)) + + /////////////////////////////////////// + // Estructuras de control + /////////////////////////////////////// + + // Declaraciones If-Else + if (NO) + { + NSLog(@"I am never run"); + } else if (0) + { + NSLog(@"I am also never run"); + } else + { + NSLog(@"I print"); + } + + // Declaración Switch + switch (2) + { + case 0: + { + NSLog(@"I am never run"); + } break; + case 1: + { + NSLog(@"I am also never run"); + } break; + default: + { + NSLog(@"I print"); + } break; + } + + // Declaración de ciclos While + int ii = 0; + while (ii < 4) + { + NSLog(@"%d,", ii++); // ii++ incrementa ii en la misma línea, luego de + // utilizar su valor + } // imprime => "0," + // "1," + // "2," + // "3," + + // Declaración de ciclos For + int jj; + for (jj=0; jj < 4; jj++) + { + NSLog(@"%d,", jj); + } // imprime => "0," + // "1," + // "2," + // "3," + + // Declaraciones foreach + NSArray *values = @[@0, @1, @2, @3]; + for (NSNumber *value in values) + { + NSLog(@"%@,", value); + } // imprime => "0," + // "1," + // "2," + // "3," + + // Objeto de ciclos For. Puede ser utilizado con cualquier tipo de objecto de + // Objective-C + for (id item in values) { + NSLog(@"%@,", item); + } // imprime => "0," + // "1," + // "2," + // "3," + + // Declaraciones Try-Catch-Finally + @try + { + // Tus declaraciones aquí + @throw [NSException exceptionWithName:@"FileNotFoundException" + reason:@"File Not Found on System" userInfo:nil]; + } @catch (NSException * e) // utiliza: @catch (id exceptionName) para atrapar + // todos los objetos + { + NSLog(@"Exception: %@", e); + } @finally + { + NSLog(@"Finally. Time to clean up."); + } // imprime => "Exception: File Not Found on System" + // "Finally. Time to clean up." + + // Los objetos NSError son útiles para argumentos de función para los + // errores de usuario. + NSError *error = [NSError errorWithDomain:@"Invalid email." code:4 userInfo:nil]; + + /////////////////////////////////////// + // Objetos + /////////////////////////////////////// + + // Crea una instancia de objeto alocando memoria e inicializándola + // Un objeto no es completamente funcional hasta que ambos pasos hayan sido + // completados + MyClass *myObject = [[MyClass alloc] init]; + + // El modelo de programación orientada a objetos de Objective-C es basada en + // el envío de mensajes a instancias de objetos + // En Objective-C no se llama a un método; se envía un mensaje + [myObject instanceMethodWithParameter:@"Steve Jobs"]; + + // Limpiar la memoria que se utilizó en el programa + [pool drain]; + + // Fin de @autoreleasepool + } + + // Fin del programa + return 0; +} + +/////////////////////////////////////// +// Clases y funciones +/////////////////////////////////////// + +// Declara tu clase en archivo de encabezado (MyClass.h) +// Sintaxis de declaración de clase: +// @interface NombreDeClase : NombreDeClasePadre <ProtocolosImplementados> +// { +// type nombre; <= declaraciones de variables; +// } +// @property tipo nombre; <= declaración de propiedades +// -/+ (tipo) Declaración de método; <= Declaración de método +// @end +@interface MyClass : NSObject <MyProtocol> // NSObject es la clase de objeto + // base de Objective-C. +{ + // Declaraciones de variables de instancia (puede existir en el archivo de + // interfaz o de implementación) + int count; // Acceso protegido por defecto. + @private id data; // Acceso privado (Más conveniente de declarar en el + // archivo de implementación) + NSString *name; +} +// Notación conveneinte para acceso público de las variables para generar un +// método setter +// Por defecto, el nombre del método setter 'set' seguido del nombre de +// variable @property +@property int propInt; // Nombre del método 'setter' = 'setPropInt' +@property (copy) id copyId; // (copy) => Copia el objeto durante la asignación +// (readonly) => No se le puede asignar un valor fuera de @interface +@property (readonly) NSString *roString; // utiliza @synthesize en + // @implementation para crear un accesor +// Puedes personalizar el nombre del getter y del setter en lugar de utilizar +// el nombre por defecto "set". +@property (getter=lengthGet, setter=lengthSet:) int length; + +// Métodos ++/- (return type)methodSignature:(Parameter Type *)parameterName; + +// + Para métodos de clase: ++ (NSString *)classMethod; ++ (MyClass *)myClassFromHeight:(NSNumber *)defaultHeight; + +// - Para métodos de instancia: +- (NSString *)instanceMethodWithParameter:(NSString *)string; +- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number; + +// Métodos de constructor con argumentos +- (id)initWithDistance:(int)defaultDistance; +// Los nombres de los métodos de Objective-C son muy descriptivos. +// Siempre nombra los métodos de acuerdo con sus argumentos + +@end // Define el final de la interfaz + + +// Para acceder a las variables públicas desde el archivo de implementación, +// @property genera un método setter automáticamente. El nombre del método +// es 'set' seguido de un nombre de variable @property: +MyClass *myClass = [[MyClass alloc] init]; // Crea una instancia del objeto MyClass +[myClass setCount:10]; +NSLog(@"%d", [myClass count]); // imprime => 10 +// O utilizando los métodos getter y setter personalizados en @interface: +[myClass lengthSet:32]; +NSLog(@"%i", [myClass lengthGet]); // imprime => 32 +// Por conveniencia, puedes utilizar la notación de punto para asignar y +// acceder a las variables de una instancia de objeto. +myClass.count = 45; +NSLog(@"%i", myClass.count); // imprime => 45 + +// Llama a métodos de clase: +NSString *classMethodString = [MyClass classMethod]; +MyClass *classFromName = [MyClass myClassFromName:@"Hello"]; + +// Llama a métodos de instancia: +MyClass *myClass = [[MyClass alloc] init]; // Crea una instancia de objeto Myclass +NSString *stringFromInstanceMethod = [myClass instanceMethodWithParameter:@"Hello"]; + +// Selectors +// Una forma dinámica de representar métodos. Utilizados para llamar métodos +// de una clase, pasar métodos a través de funciones para avisar a otras clases +// para que lo llamen, y para guardar métodos como una variable. +// SEL es el tipo de dato. @selector() devuelve un selector del nombre de +// método proveído methodAparameterAsString:andAParameterAsNumber: es un nombre +// para un método en MyClass +SEL selectorVar = @selector(methodAParameterAsString:andAParameterAsNumber:); +if ([myClass respondsToSelector:selectorVar]) { // Revisa si la clase contiene el método + // Debe de poner todos los argumentos de método en un solo objeto para mandar una + // función performSelector. + NSArray *arguments = [NSArray arrayWithObjects:@"Hello", @4, nil]; + [myClass performSelector:selectorVar withObject:arguments]; // Calls the method +} else { + // NSStringFromSelector() devuelve un NSString del nombre de método de un selector dado + NSLog(@"MyClass does not have method: %@", NSStringFromSelector(selectedVar)); +} + +// Implementa los métodos de un archivo de implementación (MyClass.m): +@implementation MyClass { + long distance; // Variable de instancia de acceso privado + NSNumber height; +} + +// Para acceder a una variable pública del archivo de interfaz, utiliza '_' seguido del +// nombre de la variable: +_count = 5; // Hace referencia a "int count" de la interfaz de MyClass +// Accede variables definidas en el archivo de implementación: +distance = 18; // Hace referencia a "long distance" de la implementación de MyClass +// Para utilizar una variable @property en el archivo de implementación, utiliza +// @synthesize para crear una variable de acceso: +@synthesize roString = _roString; // _roString ahora está disponible en @implementation + +// Lamado antes de llamar algún método o instanciar cualquier objeto ++ (void)initialize +{ + if (self == [MyClass class]) { + distance = 0; + } +} + +// Contraparte para inicializar un método. Llamado cuando el contador de referencias +// del objeto es cero +- (void)dealloc +{ + [height release]; // Si no utilizas ARC, asegúrate de liberar las variables de + // objeto de las clases + [super dealloc]; // y llama el método dealloc de la clase padre +} + +// Los constructores son una manera de crear instancias de una clase +// Este es el constructor por defecto que es llamado cuando el objeto es inicializado. +- (id)init +{ + if ((self = [super init])) // 'super' es utilizado para acceder a los + // métodos de la clase padre. + { + self.count = 1; // 'self' es utilizado para que el objeto se llame a sí mismo. + } + return self; +} +// Se pueden crear constructores que contiene argumentos +- (id)initWithDistance:(int)defaultDistance +{ + distance = defaultDistance; + return self; +} + ++ (NSString *)classMethod +{ + return @"Some string"; +} + ++ (MyClass *)myClassFromHeight:(NSNumber *)defaultHeight +{ + height = defaultHeight; + return [[self alloc] init]; +} + +- (NSString *)instanceMethodWithParameter:(NSString *)string +{ + return @"New string"; +} + +- (NSNumber *)methodAParameterAsString:(NSString*)string andAParameterAsNumber:(NSNumber *)number +{ + return @42; +} + +// Objective-C no tiene declaraciones de métodos privados, pero pueden ser simulados. +// Para simular un método privado, crea un método en @implementation pero no en @interface. +- (NSNumber *)secretPrivateMethod { + return @72; +} +[self secretPrivateMethod]; // Calls private method + +// Métodos declarados dentro de MyProtocol +- (void)myProtocolMethod +{ + // statements +} + +@end // Declara el final de la implementación + +/////////////////////////////////////// +// Categorías +/////////////////////////////////////// +// Una categoría es un grupo de métodos diseñados para extender una clase. +// Te permiten agregar nuevos métodos a una clase existente por propósitos +// de organización. Éstos no deben de serconfundidos con subclases. +// Las subclases existen para CAMBIAR la funcionalidad de un objeto mientras +// que las categoríasle AGREGAN funcionalidad de un objeto. +// Las categorías te permiten: +// -- Agregar métodos a una clase existente por propósitos de oganización. +// -- Extender clases de objetos de Objective-C (ejemplo: NSString) para +// agregar tus propios métodos. +// -- Agregar la habilidad de crear métodos protegidos y privados para las clases. +// NOTA: No sobreescribas los métodos de las clases base en una categoría +// aunque tengas la habilidad de poder hacerlo. Sobreescribir métodos puede +// causar errores en la compilación después entre diferentes categorías y +// puede arruinar el propósito de las categorías de solo AGREGAR funcionalidad. +// Utiliza subclass para sobreescribir métodos. + +// Aquí una clase base simple, Car. +@interface Car : NSObject + +@property NSString *make; +@property NSString *color; + +- (void)turnOn; +- (void)accelerate; + +@end + +// Y la implementación de la clase simple, Car +#import "Car.h" + +@implementation Car + +@synthesize make = _make; +@synthesize color = _color; + +- (void)turnOn { + NSLog(@"Car is on."); +} +- (void)accelerate { + NSLog(@"Accelerating."); +} + +@end + +// Ahora, si quisieramos crear un objeto Truck (Camión), crearíamos una +// subclase de Car (Carro) como si le cambiaramos de funcionalidad de Car +// para que se comporte como un camión. Pero digamos que únicamente queremos +// agregar funcionalidad al Car (Carro) existente. Un buen ejemplo sería +// limpiar el carro. Así que crearíamos una cateog®iea para agregar los +// métodos de limpieza: +// Archivo @interface: Car+Clean.h (NombreBaseDeClase+NombreDeCategoria.h) +#import "Car.h" // Asegúrate de improtar la clase que deseas extener. + +@interface Car (Clean) // El nombre de la categoría está dentro de (), + // seguido del nombre de la clase base + +- (void)washWindows; // Nombres de los nuevos métodos que le agregamos + // a nuestro objeto Car +- (void)wax; + +@end + +// Archivo @implementation: Car+Clean.m (NombreBaseDeClase+NombreDeCategoria.m) +#import "Car+Clean.h" // Importa el archivo de @interface de la categoría Clean + +@implementation Car (Clean) + +- (void)washWindows { + NSLog(@"Windows washed."); +} +- (void)wax { + NSLog(@"Waxed."); +} + +@end + +// Cualquier instancia del objeto Car tiene la habilidad de utilizar una +// categoría. Todo lo que necesitan es importarlo: +#import "Car+Clean.h" // Importa todas las diferentes categorías que + // necesites utilizar +#import "Car.h" // También debes de importar la clase base para su + // funcionalidad original + +int main (int argc, const char * argv[]) { + @autoreleasepool { + Car *mustang = [[Car alloc] init]; + mustang.color = @"Red"; + mustang.make = @"Ford"; + + [mustang turnOn]; // Utiliza métodos de la clase base Car. + [mustang washWindows]; // Utiliza métodos de la categoría Clean de Car. + } + return 0; +} + +// Objective-C no tiene declaraciones para métodos protegidos, pero los puedes +// simular. Crea una categoría conteniendo todos los métodos protegidos, +// luego importa ÚNICAMENTE al archivo @implementation de una clase que +// pertenece a la clase Car. +@interface Car (Protected) // Nombrando la categoría 'Protected' para + // recordar que los métodos están protegidos + +- (void)lockCar; // Los métodos enlistados aquí solo puedens ser creados + // por objetos Car + +@end +// Para utilizar los métodos protegidos, importa la categoría, +// luego implementa sus métodos: +#import "Car+Protected.h" // Recuerda, importa únicamente el archivo + // de @implementation + +@implementation Car + +- (void)lockCar { + NSLog(@"Car locked."); // Las instancias de Car no puede utilizar + // lockCar porque no se encuentra en @interface +} + +@end + +/////////////////////////////////////// +// Extensiones +/////////////////////////////////////// +// Las Extensions te permiten sobreescribir atributos de propiedades de +// acceso público y métodos de un @interface +// Archivo @interface: Shape.h +@interface Shape : NSObject + +@property (readonly) NSNumber *numOfSides; + +- (int)getNumOfSides; + +@end +// Puedes sobreescribir la variable numOfSides o el métodos getNumOfSlides +// para modificarlos con una extensión: +// Archivo @implementation: Shape.m +#import "Shape.h" +// Las extensiones se encuentran en el mismo archivo que el archivo +// de @implementation +@interface Shape () // () después del nombre de la clase base declara + // una extensión + +@property (copy) NSNumber *numOfSides; // Hacer numOfSlides copy en lugar + // de readonly. +-(NSNumber)getNumOfSides; // Hacer que getNumOfSides devuelva un NSNumber + // en lugar de un int. +-(void)privateMethod; // También puedes crear una nuevos métodos privados + // dentro de las extensiones + +@end +// @implementation principal: +@implementation Shape + +@synthesize numOfSides = _numOfSides; + +-(NSNumber)getNumOfSides { // Todas las declaraciones dentro de extensions + // deben de ser dentro de @implementation + return _numOfSides; +} +-(void)privateMethod { + NSLog(@"Private method created by extension. Shape instances cannot call me."); +} + +@end + +/////////////////////////////////////// +// Protocolos +/////////////////////////////////////// +// Un protocolo declara métodos que pueden ser implementados por cualquier otra +// clase. Los protocolos no son clases. Simplementen define una interfaz que +// otros objetos deben de implementar. +// Archivo @protocol: "CarUtilities.h" +@protocol CarUtilities <NSObject> // <NSObject> => Nombre de otro protocolo + // que se incluye en éste + @property BOOL engineOn; // La clase que lo adopta debe de utilizar + // @synthesize para todas las @properties definidas + - (void)turnOnEngine; // y todos los métodos definidos +@end +// A continuación una clase ejemplo que implementa el protcolo +#import "CarUtilities.h" // Importar el archivo @protocol. + +@interface Car : NSObject <CarUtilities> // El nombre del protocolo dentro de <> + // No necesitas los nombres de @property o métodos aquí para CarUtilities. + // Estos solo es requerido por @implementation. +- (void)turnOnEngineWithUtilities:(id <CarUtilities>)car; // También Puedes + // utilizar protocolos + // como datos. +@end +// El @implementation necesita que se implementen @properties y métodos +// del protocolo. +@implementation Car : NSObject <CarUtilities> + +@synthesize engineOn = _engineOn; // Crear una declaración @synthesize para el + // @property engineOn. + +- (void)turnOnEngine { // Implementa turnOnEngine como quieras. Los + // protocolos no definen + _engineOn = YES; // cómo implementas un método, con tal de que lo implementes. +} +// Puedes utilizar un protocolo como data mientras sepas quee métodos y variables +// tiene implementado. +- (void)turnOnEngineWithCarUtilities:(id <CarUtilities>)objectOfSomeKind { + [objectOfSomeKind engineOn]; // Tienes acceso a las variables + [objectOfSomeKind turnOnEngine]; // y los métodos del objeto + [objectOfSomeKind engineOn]; // Puede o no puede ser YES. La clase lo + // implementa como se quiera. +} + +@end +// Las instancias de Car ahora tienen acceso al protocolo. +Car *carInstance = [[Car alloc] init]; +[carInstance setEngineOn:NO]; +[carInstance turnOnEngine]; +if ([carInstance engineOn]) { + NSLog(@"Car engine is on."); // imprime => "Car engine is on." +} +// Asegúrate de revisar si un objeto de tipo 'id' implementa un protocolo antes +// de llamar a sus métodos: +if ([myClass conformsToProtocol:@protocol(CarUtilities)]) { + NSLog(@"This does not run as the MyClass class does not implement the CarUtilities protocol."); +} else if ([carInstance conformsToProtocol:@protocol(CarUtilities)]) { + NSLog(@"This does run as the Car class implements the CarUtilities protocol."); +} +// Las categorías también pueden implementar protcolos: @interface Car +// (CarCategory) <CarUtilities> +// Puedes implementar varios protocolos: +// @interface Car : NSObject <CarUtilities, CarCleaning> +// NOTA: Si dos o más protocolos dependen entre sí, asegúrate de declararlos +// de manera adelantada: +#import "Brother.h" + +@protocol Brother; // Declaración adelantada. Sin ésto, el compilador + // tira un error. + +@protocol Sister <NSObject> + +- (void)beNiceToBrother:(id <Brother>)brother; + +@end + +// Ver si el problema es que Sister depende de Brother, +// y Brother dependa de Sister. +#import "Sister.h" + +@protocol Sister; // Estas líneas detienen la recursión, resolviendo el problema. + +@protocol Brother <NSObject> + +- (void)beNiceToSister:(id <Sister>)sister; + +@end + + +/////////////////////////////////////// +// Bloques +/////////////////////////////////////// +// Los bloques son declaraciones de código, tal como una función, pueden +// ser utilizados como data. +// A continuación un bloque simple con un argumento entero que devuelve +// un el argumento más 4. +int (^addUp)(int n); // Declarar una variable para almacenar el bloque. +void (^noParameterBlockVar)(void); // Ejemplo de una declaración de variable + // de bloque sin argumentos. +// Los bloques tienen acceso a variables del mismo ámbito. Pero las variables +// son solo readonly y el valor pasado al bloque es el valor de la variable +// cuando el bloque es creado. +int outsideVar = 17; // Si modificamos outsideVar después de declarar addUp, + // outsideVar AÚN es 17. +__block long mutableVar = 3; // __block hace que las variables se puedan + // escribir en bloques. +addUp = ^(int n) { // Remueve (int n) para tener un bloque que no recibe + // ningún parámetro + NSLog(@"You may have as many lines in a block as you would like."); + NSSet *blockSet; // También puedes declarar variables locales. + mutableVar = 32; // Asignar un nuevo valor a la variable __block. + return n + outsideVar; // Declaraciones de retorno son opcionales. +} +int addUp = add(10 + 16); // Llama al bloque de código con argumentos. +// Los bloques son usualmente utilizados como argumentos a funciones que +// son llamados más adelante o para callbacks. +@implementation BlockExample : NSObject + + - (void)runBlock:(void (^)(NSString))block { + NSLog(@"Block argument returns nothing and takes in a NSString object."); + block(@"Argument given to block to execute."); // Calling block. + } + + @end + + +/////////////////////////////////////// +// Manejo de memoria +/////////////////////////////////////// +/* +Para cada objeto utilizado en una aplicación, la memoria debe de ser alocada +para ese objeto. Cuando la aplicación termina de utilizar ese objeto, la +memoria debe de ser desalocada para asegurar la eficiencia de la aplicación. +Objetive-C no utiliza garbage collection, y en lugar de eso utiliza conteos +de referencias. Mientras haya al menos una referencia del objeto (también +conocido como tener un objeto de adueñado), entonces el objeto estará +disponible para su uso. + +Cuando una instancia es dueña un objeto, su contador de referencia incrementa +por uno. Cuando el objeto es liberado, el contador de referencia decrementa uno. +Cuando el conteo de referencia es cero, el objeto es removido de la memoria. + +Con todas las interacciones de los objetos, sigue el patrón de: +(1) Crear e lobjeto, (2) utiliza el objeto, (3) libera el objeto de la memoria. +*/ + +MyClass *classVar = [MyClass alloc]; // 'alloc' asigna uno al conteo de + // referencias de classVar. Devuelve un + // puntero al objeto +[classVar release]; // Decrementa el conteo de referencias de classVar's +// 'retain' +// 'retain' adueña la instancia de objeto existente e incrementa el conteo de +// referencia por uno. Devuelve un puntero al objeto. +MyClass *newVar = [classVar retain]; // Si classVar es liberado, el objeto + // aún se queda en memoria porque newVar + // es el dueño. +[classVar autorelease]; // Remueve el adueñamiento de un objeto al final del + // bloque @autoreleasepool. Devuelve un puntero al objeto. + +// @property puede utilizar 'retain' y 'assign' también para pequeñas +// definiciones convenientes +@property (retain) MyClass *instance; // Libera el valor viejo y retiene + // uno nuevo (referencia fuerte) +@property (assign) NSSet *set; // Apunta a un nuevo valor sin retener/liberar + // una referencia vieja (débil) + +// Conteo Automático de Referencias (ARC) +// Debido a que el manejo de memoria puede ser un dolor, en Xcode 4.2 y iOS 4 +// se introdujo el Conteo Automático de Referencias (ARC). +// ARC es una funcionalidad del compilador que agrega retain, release y +// autorealase automáticamente, así que al +// utilizar ARC, no se debe de utilizar retain, release o autorelease. +MyClass *arcMyClass = [[MyClass alloc] init]; +// ... código utilizando arcMyClass +// Sin ARC, necesitarás llamar: [arcMyClass release] luego de terminar de +// utilizar arcMyClass. Pero con ARC, no hay necesidad. Insertará +// automáticamente la declaración de liberación. + +// Mientras que para los atributos de @property 'assign' y 'retain', con ARC +// utilizarás 'weak' y 'strong' +@property (weak) MyClass *weakVar; // 'weak' no adueña el objeto. El conteo de + // referencias de la instancia original +// es fijado a ceor, weakVar automáticamente recibe el valor de nil para +// evitar cualquier 'crashing'. +@property (strong) MyClass *strongVar; // 'strong' se adueña del objeto. + // Asegura que el objeto se quede en memoria. + +// Para variables regulares (no variables de @property), utiliza lo siguiente: +__strong NSString *strongString; // Por defecto. La variables de retenida en + // memoria hasta que se salga del ámbito. +__weak NSSet *weakSet; // Referencia débil a un objeto existente. Cuando el + // objeto existente es liberado, weakSet le es asginado + // un valor nil +__unsafe_unretained NSArray *unsafeArray; // Como __weak, pero unsafeArray no + // es asginado a nil cuando el objeto + // existente es liberado. + +``` +## Lecturas sugeridas + +[Wikipedia Objective-C](http://es.wikipedia.org/wiki/Objective-C) + +[Programming with Objective-C. Libro PDF de Apple](https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/ProgrammingWithObjectiveC.pdf) + +[iOS For High School Students: Getting Started](http://www.raywenderlich.com/5600/ios-for-high-school-students-getting-started) diff --git a/es-es/php-es.html.markdown b/es-es/php-es.html.markdown new file mode 100644 index 00000000..fa52353c --- /dev/null +++ b/es-es/php-es.html.markdown @@ -0,0 +1,825 @@ +--- +language: PHP +contributors: + - ["Malcolm Fell", "http://emarref.net/"] + - ["Trismegiste", "https://github.com/Trismegiste"] +translators: + - ["Mario Pérez", "https://github.com/MarioPerezEsteso"] +lang: es-es +filename: learnphp-es.php +--- + +Este documento explica el funcionamiento de PHP 5+. + +```php +<?php // El código PHP debe estar dentro de etiquetas <?php + +// Si tu fichero php solo contiene código php, es una buena práctica +// omitir la etiqueta de cierre php para prevenir salidas acidentales. + +// Dos barras comienzan un comentario de una línea. + +# También lo hará una almohadilla, pero // es más común + +/* + Escribir texto entre una barra-asterisco y asterisco-barra + crea un comentario multilínea. +*/ + +// Utiliza "echo" o "print" para imprimir por pantalla +print('Hola '); // Imprime "Hola " sin salto de línea + +// () son opcionales para print y echo +echo "Mundo\n"; // Imprime "Mundo" con un salto de línea +// (todas las sentencias deben finalizar con un punto y coma) + +// Cualquier cosa fuera de las etiquetas <?php se imprime automáticamente +?> +¡Hola Mundo de nuevo! +<?php + + +/************************************ + * Tipos y variables + */ + +// Las variables comienzan con el símbolo $. +// Una variable válida comienza con una letra o guión bajo, +// seguida de cualquier cantidad de letras, números o guiones bajos. + +// Las variables booleanas no distinguen entre mayúsculas o minúsculas +$boolean = true; // o TRUE o True +$boolean = false; // o FALSE o False + +// Enteros +$int1 = 12; // => 12 +$int2 = -12; // => -12 +$int3 = 012; // => 10 (un 0 al comienzo declara un número octal) +$int4 = 0x0F; // => 15 (un 0x al comienzo declara un hexadecimal) + +// Floats (también conocidos como doubles) +$float = 1.234; +$float = 1.2e3; +$float = 7E-10; + +// Eliminar variable +unset($int1); + +// Operaciones aritméticas +$suma = 1 + 1; // 2 +$diferencia = 2 - 1; // 1 +$producto = 2 * 2; // 4 +$cociente = 2 / 1; // 2 + +// Operaciones aritméticas de escritura rápida +$numero = 0; +$numero += 1; // Incrementa $numero en 1 +echo $numero++; // Imprime 1 (incremento después la evaluación) +echo ++$numero; // Imprime 3 (incremento antes de la evaluación) +$numero /= $float; // Divide y asigna el cociente a $numero + +// Las cadenas de caracteres deben declararse entre comillas simples +$sgl_quotes = '$String'; // => '$String' + +// Evita utilizar comillas dobles excepto para embeber otras variables +$dbl_quotes = "This is a $sgl_quotes."; // => 'This is a $String.' + +// Los caracteres especiales solo son válidos entre comillas dobles +$escaped = "Esto contiene \t un caracter tabulador."; +$unescaped = 'Esto solo contiene una barra y una t: \t'; + +// Rodea una variable entre corchetes si es necesario +$dinero = "Tengo $${numero} en el banco."; + +// Desde PHP 5.3, los nowdocs pueden ser utilizados para multilíneas no interpoladas +$nowdoc = <<<'END' +Multi line +string +END; + +// Heredocs interpola cadenas de caracteres +$heredoc = <<<END +Multi line +$sgl_quotes +END; + +// La concatenación de cadenas de caracteres se realiza con . +echo 'Esta cadena de caracteres ' . 'está concatenada'; + +// Las cadenas de caracteres pueden ser pasadas como parámetros en un echo +echo 'Multiples', 'Parametros', 'Validos'; // Devuelve 'MultiplesParametrosValidos' + + +/******************************** + * Constantes + */ + +// Una constante se define utilizando define() +// y nunca puede ser cambiada en tiempo de ejecución + +// un nombre válido para una constante debe comenzar con una letra o guión bajo, +// seguido por cualquier número de letras, números o guiones bajos. +define("FOO", "algo"); + +// el acceso a una constante se puede realizar llamando a la variable elegida sin un símbolo de $ +echo FOO; // Devuelve 'algo' +echo 'Esto imprime '.FOO; // Devuelve 'Esto imprime algo' + + + +/******************************** + * Arrays + */ + +// Todos los arrays en PHP son asociativos (hashmaps), + +// Los arrays asociativos son conocidos como hashmaps en algunos lenguajes. + +// Funciona con todas las versiones de php +$asociativo = array('Uno' => 1, 'Dos' => 2, 'Tres' => 3); + +// PHP 5.4 introdujo una nueva sintaxis +$asociativo = ['Uno' => 1, 'Dos' => 2, 'Tres' => 3]; + +echo $asociativo['Uno']; // imprime 1 + +// Lista literales implícitamente asignados con claves enteras +$array = ['Uno', 'Dos', 'Tres']; +echo $array[0]; // => "Uno" + +// Añadir un elemento al final de un array +$array[] = 'Cuatro'; +// o +array_push($array, 'Cinco'); + +// Eliminar un elemento de un array +unset($array[3]); + +/******************************** + * Salidas por pantalla + */ + +echo('¡Hola Mundo!'); +// Imprime ¡Hola Mundo! en stdout. +// Stdout es la página web si se está ejecutando en un navegador. + +print('!Hola Mundo!'); // Es lo mismo que echo + +// No es necesario el paréntesis en echo y print +echo '¡Hola Mundo!'; +print '¡Hola Mundo!'; + +$parrafo = 'parrafo'; + +echo 100; // Haz echo de escalares directamente +echo $parrafo; // o de variables + +// Si las etiquetas cortas estás configuradas y tu versión de PHP es +// la 5.4.0 o superior, puede utilizar la sintaxis abreviada de echo +?> +<p><?= $parrafo?></p> +<?php + +$x = 1; +$y = 2; +$x = $y; // $x ahora contiene el mismo valor que $y +$z = &$y; +// $z contiene ahora una referencia a $y. Un cambio en el valor de +// $z cambiará también el valor de $y, y viceversa. +// $x sin embargo, tendrá el valor original de $y + +echo $x; // => 2 +echo $z; // => 2 +$y = 0; +echo $x; // => 2 +echo $z; // => 0 + +// Dump muestra el tipo y valor de una variable en stdout +var_dump($z); // imprime int(0) + +// Para mostrar el valor de una variable en un formato legible para humanos +print_r($array); // imprime: Array ( [0] => Uno [1] => Dos [2] => Tres ) + +/******************************** + * Lógica + */ +$a = 0; +$b = '0'; +$c = '1'; +$d = '1'; + +// assert lanza una advertencia si su argumento no es verdadero + +// Estas comparaciones siempre serán verdaderas, incluso si los tipos no son los mismos. +assert($a == $b); // igualdad +assert($c != $a); // desigualdad +assert($c <> $a); // desigualdad alternativa +assert($a < $c); +assert($c > $b); +assert($a <= $b); +assert($c >= $d); + +// Los siguiente solo será verdadero si los valores coinciden y son del mismo tipo. +assert($c === $d); +assert($a !== $d); +assert(1 === '1'); +assert(1 !== '1'); + +// Operador 'Spaceship' (desde PHP 7) +// Devuelve 0 si ambos valores son iguales +// Devuelve 1 si el valor de la izquierda es mayor +// Devuelve -1 si el valor de la derecha es mayor + +$a = 100; +$b = 1000; + +echo $a <=> $a; // 0 porque son iguales +echo $a <=> $b; // -1 porque $a < $b +echo $b <=> $a; // 1 porque $b > $a + +// Las variables pueden ser convertidas entre tipos, dependiendo de su uso. + +$entero = 1; +echo $entero + $entero; // => 2 + +$string = '1'; +echo $string + $string; // => 2 (los strings son convertidos a enteros) + +$string = 'uno'; +echo $string + $string; // => 0 +// Muestra un 0 porque el operador + no puede convertir la cadena de caracteres 'uno' a un número + +// La conversión de tipos puede ser utilizada para tratar a una variable como otro tipo + +$boolean = (boolean) 1; // => true + +$cero = 0; +$boolean = (boolean) $cero; // => false + +// También hay funciones dedicadas a la conversión de tipos +$entero = 5; +$string = strval($entero); + +$var = null; // Valor nulo + + +/******************************** + * Estructuras de control + */ + +if (true) { + print 'He sido imprimido'; +} + +if (false) { + print 'Yo no'; +} else { + print 'He sido imprimido'; +} + +if (false) { + print 'No se imprime'; +} elseif(true) { + print 'Sí se imprime'; +} + +// operador ternario +print (false ? 'No se imprime' : 'Sí se imprime'); + +// atajo para el operador ternario desde PHP 5.3 +// equivalente de "$x ? $x : 'Sí'"" +$x = false; +print($x ?: 'Sí'); + +// operador 'no definido' desde php 7 +$a = null; +$b = 'Imprime'; +echo $a ?? 'a no está definido'; // imprime 'a no está definido' +echo $b ?? 'b no está definido'; // imprime 'Imprime' + + +$x = 0; +if ($x === '0') { + print 'No imprime'; +} elseif($x == '1') { + print 'No imprime'; +} else { + print 'Imprime'; +} + + + +// Esta sintaxis alternativa se utiliza para plantillas: +?> + +<?php if ($x): ?> +Esto se muestra si la evaluación es verdadera. +<?php else: ?> +En otro caso, se muestra esto. +<?php endif; ?> + +<?php + +// Utiliza el switch para tener algo más de lógica. +switch ($x) { + case '0': + print 'Switch does type coercion'; + break; // Debes incluir un break para no seguir con los casos 'Dos' y 'Tres' + case 'Dos': + case 'Tres': + // Hacer algo si la variables es 'Dos' o 'Tres' + break; + default: + // Hacer algo por defecto +} + +// Los bucles While, do...while y for te serán familiares +$i = 0; +while ($i < 5) { + echo $i++; +}; // Imprime "01234" + +echo "\n"; + +$i = 0; +do { + echo $i++; +} while ($i < 5); // Imprime "01234" + +echo "\n"; + +for ($x = 0; $x < 10; $x++) { + echo $x; +} // Imprime "0123456789" + +echo "\n"; + +$ruedas = ['bicicleta' => 2, 'coche' => 4]; + +// Los bucles foreach pueden iterar por arrays +foreach ($ruedas as $numero_ruedas) { + echo $numero_ruedas; +} // Imprime "24" + +echo "\n"; + +// También se puede iterar sobre las claves, así como sobre los valores +foreach ($ruedas as $vehiculo => $numero_ruedas) { + echo "Un $vehiculo tiene $numero_ruedas ruedas"; +} + +echo "\n"; + +$i = 0; +while ($i < 5) { + if ($i === 3) { + break; // Sale fuera del bucle while + } + echo $i++; +} // Imprime "012" + +for ($i = 0; $i < 5; $i++) { + if ($i === 3) { + continue; // Se salta esta iteración del bucle + } + echo $i; +} // Imprime "0124" + + +/******************************** + * Funciones + */ + +// Define una función con "function": +function mi_funcion () { + return 'Hola'; +} + +echo mi_funcion(); // => "Hola" + +// Un nombre válido de función comienza con una letra o guión bajo, seguido de cualquier +// número de letras, números o guiones bajos. + +function anadir ($x, $y = 1) { // $y es opcional y por defecto es 1 + $resultado = $x + $y; + return $resultado; +} + +echo anadir(4); // => 5 +echo anadir(4, 2); // => 6 + +// $resultado no es accesible fuera de la función +// print $resultado; // Devuelve una advertencia. + +// Desde PHP 5.3 se pueden declarar funciones anónimas +$inc = function ($x) { + return $x + 1; +}; + +echo $inc(2); // => 3 + +function foo ($x, $y, $z) { + echo "$x - $y - $z"; +} + +// Las funciones pueden devolver funciones +function bar ($x, $y) { + // Utiliza 'use' para meter variables de fuera de la función + return function ($z) use ($x, $y) { + foo($x, $y, $z); + }; +} + +$bar = bar('A', 'B'); +$bar('C'); // Imprime "A - B - C" + +// Puedes llamar a funciones utilizando cadenas de caracteres +$nombre_funcion = 'add'; +echo $nombre_funcion(1, 2); // => 3 +// Es útil para determinarl qué función ejecutar. +// O, utiliza call_user_func(callable $callback [, $parameter [, ... ]]); + + +// Puedes obtener todos los parámetros pasados a una función +function parametros() { + $numero_argumentos = func_num_args(); + if ($numero_argumentos > 0) { + echo func_get_arg(0) . ' | '; + } + $args_array = func_get_args(); + foreach ($args_array as $key => $arg) { + echo $key . ' - ' . $arg . ' | '; + } +} + +parametros('Hola', 'Mundo'); // Hola | 0 - Hola | 1 - Mundo | + +// Desde PHP 5.6 se puede obtener un número variable de argumentos +function variable($palabra, ...$lista) { + echo $palabra . " || "; + foreach ($lista as $item) { + echo $item . ' | '; + } +} + +variable("Separa", "Hola", "Mundo") // Separa || Hola | Mundo | + +/******************************** + * Includes + */ + +<?php +// Los ficheros PHP incluidos deben comenzar también con la etiqueta de <?php + +include 'mi-fichero.php'; +// El código de mi-fichero.php ya está disponible en el entorno actual. +// Si el fichero no puede ser incluido (por ejemplo porque no se ha encontrado), +// se muestra una advertencia. + +include_once 'mi-fichero.php'; +// Si el código del fichero mi-fichero.php ya ha sido incluido, ya no se +// incluirá de nuevo. Este previene errores por múltiples declaraciones. + +require 'mi-fichero.php'; +require_once 'mi-fichero.php'; +// Es lo mismo que el include(), pero require() causará un error fatal si el archivo +// no ha podido ser incluido. + +// Contenido de mi-include.php: +<?php + +return 'Cualquier cosa.'; +// acabar archivo + +// Los include y require también pueden devolver un valor. +$valor = include 'mi-include.php'; + +// Los archivos son incluidos en función de la ruta data o, si ninguna ruta es +// especificada se utilizará la directiva de configuración de include_path. Si el +// fichero no se encuentra en el include_path, include comprobará la ruta del código +// que lo llama antes de fallar. +/* */ + +/******************************** + * Clases + */ + +// Las clases son definidas con la palabra clave class + +class MiClase +{ + const MI_CONSTANTE = 'valor'; // Una constante + + static $staticVar = 'static'; + + // Las variables estáticas y su visibilidad + public static $publicStaticVar = 'publicStatic'; + // Accesible solo dentro de su clase + private static $privateStaticVar = 'privateStatic'; + // Accesible desde la clase y las subclases + protected static $protectedStaticVar = 'protectedStatic'; + + // Las propiedades deben declarar su visibilidad + public $propiedad = 'public'; + public $instanceProp; + protected $prot = 'protected'; // Accesible desde la clase y las subclases + private $priv = 'private'; // Accesible solo desde la clase + + // Crear un constructor con __construct + public function __construct($instanceProp) { + // Accede a las variables de la instancia con $this + $this->instanceProp = $instanceProp; + } + + // Los métodos son declarados como funciones dentro de una clase + public function miMetodo() + { + print 'MiClase'; + } + + // la palabra clave final hará una función no sobreescribible + final function noMePuedesSobreEscribir() + { + } + +/* + * Declarar propiedades de clase o métodos como estáticos los hace accesibles sin + * necesidad de instanciar la clase. Una propiedad declarada como estática no + * puede ser accedida mediante una instancia de la clase, pero sí mediante un + * método estático. + */ + + public static function miMetodoEstatico() + { + print 'Soy estático'; + } +} + +// Las constantes de una clase siempre pueden ser accedidas estáticamente +echo MiClase::MI_CONSTANTE; // Muestra 'valor'; + +echo MiClase::$staticVar; // Muestra 'static'; +MiClase::miMetodoEstatico(); // Muestra 'Soy estático'; + +// Instancia una clase usando new +$mi_clase = new MiClase('Una instancia'); +// Los paréntesis son opcionales si no se pasa ningún argumento. + +// Accede a los miembros de una clase utilizando -> +echo $mi_clase->propiedad; // => "public" +echo $mi_clase->instanceProp; // => "Una instancia" +$mi_clase->miMetodo(); // => "MiClase" + + +// Extender clases utilizando "extends" +class MiOtraClase extends MiClase +{ + function imprimePropiedadProtegida() + { + echo $this->prot; + } + + // Sobreescribe un método + function miMetodo() + { + parent::miMetodo(); + print ' > MiOtraClase'; + } +} + +$mi_otra_clase = new MiOtraClase('Propiedad de instancia'); +$mi_otra_clase->imprimePropiedadProtegida(); // => Imprime "protected" +$mi_otra_clase->miMetodo(); // Imprime "MiClase > MiOtraClase" + +final class NoMePuedesExtender +{ +} + +// Puedes utilizar "métodos mágicos" para crear los getters y setters +class MiClaseMapeada +{ + private $propiedad; + + public function __get($key) + { + return $this->$key; + } + + public function __set($key, $value) + { + $this->$key = $value; + } +} + +$x = new MiClaseMapeada(); +echo $x->propiedad; // Utilizará el método __get() +$x->propiedad = 'Algo'; // Utilizará el método __set() + +// Las clases pueden ser abstractas (utilizando la palabra clave abstract) o +// implementando interfaces (utilizando la palabra clave implements). +// Una interfaz puede ser declarada con la palabra clave interface. + +interface InterfazUno +{ + public function hazAlgo(); +} + +interface InterfazDos +{ + public function hazOtraCosa(); +} + +// las interfaces pueden ser extendidas +interface InterfazTres extends InterfazDos +{ + public function hazCualquierOtraCosa(); +} + +abstract class MiClaseAbstracta implements InterfazUno +{ + public $x = 'hazAlgo'; +} + +class MiOtraClase extends MiClaseAbstracta implements InterfazDos +{ + public function hazAlgo() + { + echo $x; + } + + public function hazOtraCosa() + { + echo 'hazOtraCosa'; + } +} + + +// Las clases pueden implementar más de una interfaz +class CualquierOtraClase implements InterfazUno, InterfazDos +{ + public function hazAlgo() + { + echo 'hazAlgo'; + } + + public function hazOtraCosa() + { + echo 'hazOtraCosa'; + } +} + + +/******************************** + * Traits + */ + +// Los traits están disponibles desde PHP 5.4.0 y son declarados utilizando "trait" + +trait MiTrait +{ + public function miMetodoTrait() + { + print 'Tengo trait'; + } +} + +class MiClaseTrait +{ + use MiTrait; +} + +$cls = new MiClaseTrait(); +$cls->miMetodoTrait(); // Imprime "Tengo trait" + + +/******************************** + * Namespaces + */ + +// Esta sección está separada porque una declaración de namespace debe +// ser la primera sentencia en un archivo. Vamos a suponer que no es el caso + +<?php + +// Por defecto, las clases existen en el namespace global y pueden ser llamadas +// explícitamente con una contrabarra. + +$cls = new \MiClase(); + + + +// Estableder el namespace para un archivo +namespace Mi\Namespace; + +class MiClase +{ +} + +// (de otro archivo) +$cls = new Mi\Namespace\MiClase; + +// O de otro namespace. +namespace Mi\Otro\Namespace; + +use Mi\Namespace\MiClase; + +$cls = new MiClase(); + +// O se puede asignar un ales al namespace + +namespace Mi\Otro\Namespace; + +use Mi\Namespace as OtroNamespace; + +$cls = new OtroNamespace\MiClase(); + + +/********************** +* Late Static Binding +* +*/ + +class ClasePadre { + public static function quien() { + echo "Soy una " . __CLASS__ . "\n"; + } + public static function test() { + // Auto referencia a la clase en la que el método está definido + self::quien(); + // Referencia estáticamente a la clase donde el método ha sido llamado + static::quien(); + } +} + +ClasePadre::test(); +/* +Soy una ClasePadre +Soy una ClasePadre +*/ + +class ClaseHija extends ClasePadre { + public static function quien() { + echo "Pero soy una " . __CLASS__ . "\n"; + } +} + +ClaseHija::test(); +/* +Soy una ClasePadre +Pero soy una ClaseHija +*/ + + +/********************** +* Manejo de errores +* +*/ + +// Una simple gestión de errores puede ser realizada con un bloque try catch + +try { + // Haz algo +} catch (Exception $e) { + // Maneja la excepción +} + +// Cuando se utilicen bloques try catch en un entorno con namespaces hay que +// usar lo siguiente + +try { + // Haz algo +} catch (\Exception $e) { + // Maneja la excepción +} + +// Excepciones personalizadas + +class MiExcepcion extends Exception {} + +try { + + $condicion = true; + + if ($condicion) { + throw new MiExcepcion('Ha pasado algo'); + } + +} catch (MiExcepcion $e) { + // Manejar la excepción +} + +``` + +## Más información + +Visita la [documentación oficial de PHP](http://www.php.net/manual/) para más referencias +y apoyo de la comunidad. + +Si estás interesado en buenas prácticas, visita +[PHP The Right Way](http://www.phptherightway.com/). + +Si vienes de un lenguaje con una buena gestión de paquetes, visita +[Composer](http://getcomposer.org/). + +Para estándares comunes, visita el PHP Framework Interoperability Group +[PSR standards](https://github.com/php-fig/fig-standards). diff --git a/es-es/python-es.html.markdown b/es-es/python-es.html.markdown index 4930eebc..a27203d1 100644 --- a/es-es/python-es.html.markdown +++ b/es-es/python-es.html.markdown @@ -9,8 +9,8 @@ lang: es-es filename: learnpython-es.py --- -Python fue creado por Guido Van Rossum en el principio de los 90'. Ahora es uno -de los lenguajes más populares en existencia. Me enamoré de Python por su claridad sintáctica. +Python fue creado por Guido Van Rossum en el principio de los 90. Ahora es uno +de los lenguajes más populares que existen. Me enamoré de Python por su claridad sintáctica. Es básicamente pseudocódigo ejecutable. ¡Comentarios serán muy apreciados! Pueden contactarme en [@louiedinh](http://twitter.com/louiedinh) o louiedinh [at] [servicio de email de google] @@ -19,8 +19,8 @@ Nota: Este artículo aplica a Python 2.7 específicamente, pero debería ser apl ```python # Comentarios de una línea comienzan con una almohadilla (o signo gato) -""" Strings multilinea pueden escribirse - usando tres "'s, y comunmente son usados +""" Strings multilínea pueden escribirse + usando tres "'s, y comúnmente son usados como comentarios. """ @@ -48,7 +48,7 @@ Nota: Este artículo aplica a Python 2.7 específicamente, pero debería ser apl # Resultado de la división de enteros truncada para positivos y negativos 5 // 3 # => 1 -5.0 // 3.0 # => 1.0 # funciona con números en coma flotante +5.0 // 3.0 # => 1.0 # funciona con números de coma flotante -5 // 3 # => -2 -5.0 // 3.0 # => -2.0 @@ -436,7 +436,7 @@ class Humano(object): def get_especie(cls): return cls.especie - # Un metodo estatico es llamado sin la clase o instancia como referencia + # Un metodo estático es llamado sin la clase o instancia como referencia @staticmethod def roncar(): return "*roncar*" @@ -507,7 +507,7 @@ def duplicar_numeros(iterable): # Nota: xrange es un generador que hace lo mismo que range. # Crear una lista de 1 a 900000000 lleva mucho tiempo y ocupa mucho espacio. # xrange crea un generador, mientras que range crea toda la lista. -# Añadimos un guion bajo a los nombres de variable que coinciden con palabras +# Añadimos un guión bajo a los nombres de variable que coinciden con palabras # reservadas de python. xrange_ = xrange(1, 900000000) diff --git a/es-es/python3-es.html.markdown b/es-es/python3-es.html.markdown index 1c69481a..05fd7065 100644 --- a/es-es/python3-es.html.markdown +++ b/es-es/python3-es.html.markdown @@ -97,7 +97,7 @@ not False # => True None # => None # No uses el símbolo de igualdad `==` para comparar objetos con None -# Usa `is` en lugar de +# Usa `is` en su lugar "etc" is None #=> False None is None #=> True @@ -383,7 +383,7 @@ def keyword_args(**kwargs): keyword_args(pie="grande", lago="ness") #=> {"pie": "grande", "lago": "ness"} -# You can do both at once, if you like# Puedes hacer ambas a la vez si quieres +# Puedes hacer ambas a la vez si quieres def todos_los_argumentos(*args, **kwargs): print args print kwargs @@ -478,7 +478,7 @@ Humano.roncar() #=> "*roncar*" # Puedes importar módulos import math -print(math.sqrt(16)) #=> 4 +print(math.sqrt(16)) #=> 4.0 # Puedes obtener funciones específicas desde un módulo from math import ceil, floor @@ -511,7 +511,7 @@ def duplicar_numeros(iterable): for i in iterable: yield i + i -# Un generador cera valores sobre la marcha. +# Un generador crea valores sobre la marcha. # En vez de generar y retornar todos los valores de una vez, crea uno en cada iteración. # Esto significa que valores más grandes que 15 no serán procesados en 'duplicar_numeros'. # Fíjate que 'range' es un generador. Crear una lista 1-900000000 tomaría mucho tiempo en crearse. diff --git a/es-es/pythonstatcomp-es.html.markdown b/es-es/pythonstatcomp-es.html.markdown new file mode 100644 index 00000000..0130b72a --- /dev/null +++ b/es-es/pythonstatcomp-es.html.markdown @@ -0,0 +1,238 @@ +--- +language: Statistical computing with Python +contributors: + - ["e99n09", "https://github.com/e99n09"] +filename: pythonstatcomp-es.py +translators: + - ["Damaso Sanoja", "https://github.com/damasosanoja"] +lang: es-es +--- + +Este es un tutorial de como realizar tareas típicas de programación estadística usando Python. Está destinado a personas con cierta familiaridad con Python y con experiencia en programación estadística en lenguajes como R, Stata, SAS, SPSS, or MATLAB. + +```python + +# 0. Cómo configurar ==== + +""" Configurar con IPython y pip install lo siguiente: numpy, scipy, pandas, + matplotlib, seaborn, requests. + Asegúrese de realizar este tutorial con el IPython notebook para tener fácil + acceso a las ayudas en tiempo real y la documentación respectiva. +""" + +# 1. Captura de datos ==== + +""" Muchos prefieren Python sobre R ya que quieren interactuar mucho + con la web, bien sea haciendo webscraping o solicitando datos mediante + un API. Esto se puede hacer en R, pero en el contexto de un proyecto + que ya usa Python, existen beneficios al mantener un solo lenguaje. +""" + +import requests # para llamados HTTP (webscraping, APIs) +import os + +# webscraping +r = requests.get("https://github.com/adambard/learnxinyminutes-docs") +r.status_code # si es 200, el llamado ha sido exitoso +r.text # código fuente de la página +print(r.text) # formateado y embellecido +# graba el código fuente en un fichero: +os.getcwd() # verifica cual es el directorio de trabajo +f = open("learnxinyminutes.html","wb") +f.write(r.text.encode("UTF-8")) +f.close() + +# descargando un csv +fp = "https://raw.githubusercontent.com/adambard/learnxinyminutes-docs/master/" +fn = "pets.csv" +r = requests.get(fp + fn) +print(r.text) +f = open(fn,"wb") +f.write(r.text.encode("UTF-8")) +f.close() + +""" para saber más del módulo de peticiones, incluyendo APIs, ver + http://docs.python-requests.org/en/latest/user/quickstart/ +""" + +# 2. Leyendo un fichero CSV ==== + +""" El paquete pandas de Wes McKinney brinda objetos 'DataFrame' en Python. Si + has usado R, ya estarás familiarizado con la idea de "data.frame". +""" + +import pandas as pd, numpy as np, scipy as sp +pets = pd.read_csv(fn) +pets +# nombre edad peso especies +# 0 fluffy 3 14 cat +# 1 vesuvius 6 23 fish +# 2 rex 5 34 dog + +""" Usuarios de R: notar que Python, al igual que otros lenguajes de programación + normales, comienza indexando desde 0. R de forma inusual comienza desde 1. +""" + +# dos formas distintas de imprimir una columna +pets.age +pets["age"] + +pets.head(2) # imprime las primeras dos filas +pets.tail(1) # imprime la última fila + +pets.name[1] # 'vesuvius' +pets.species[0] # 'cat' +pets["weight"][2] # 34 + +# en R, puedes esperar obtener 3 filas haciendo esto, pero aquí obtienes 2: +pets.age[0:2] +# 0 3 +# 1 6 + +sum(pets.age)*2 # 28 +max(pets.weight) - min(pets.weight) # 20 + +""" Si estás procesando grandes cantidades de cálculos de álgebra lineal, podrías + querer usar matrices, no DataFrames. Los DataFrames son ideales para combinar + columnas de diferentes tipos. +""" + +# 3. Gráficas ==== + +import matplotlib as mpl, matplotlib.pyplot as plt +%matplotlib inline + +# Para hacer virtualización de datos en Python, usa matplotlib + +plt.hist(pets.age); + +plt.boxplot(pets.weight); + +plt.scatter(pets.age, pets.weight); plt.xlabel("age"); plt.ylabel("weight"); + +# seaborn está por encima de matplotlib y logra mejores gráficos + +import seaborn as sns + +plt.scatter(pets.age, pets.weight); plt.xlabel("age"); plt.ylabel("weight"); + +# también hay algunas funciones gráficas específicas de seaborn +# nota como seaborn etiqueta automáticamente el eje x en este gráfico de barras +sns.barplot(pets["age"]) + +# los veteranos de R pueden seguir usando ggplot +from ggplot import * +ggplot(aes(x="age",y="weight"), data=pets) + geom_point() + labs(title="pets") +# fuente: https://pypi.python.org/pypi/ggplot + +# incluso hay un porteo d3.js: https://github.com/mikedewar/d3py + +# 4. Limpieza simple de datos y análisis exploratorio ==== + +""" Tenemos ahora un ejemplo más complicado que demuestra un flujo básico para + limpieza de datos que lleva a la creación de algunos gráficos exploratorios + y la ejecución de una regresión lineal. + El conjunto de datos fue transcrito de Wikipedia a mano. Contiene + todos los Emperadores Romanos Sagrados y fechas claves en sus vidas + (nacimiento, muerte, coronación, etc.). + El objetivo del análisis es explorar si existe alguna relación + entre el año de nacimiento del Emperador y su tiempo de vida. + fuente de datos: https://en.wikipedia.org/wiki/Holy_Roman_Emperor +""" + +# cargar algunos datos de los Emperadores Romanos Sagrados +url = "https://raw.githubusercontent.com/e99n09/R-notes/master/data/hre.csv" +r = requests.get(url) +fp = "hre.csv" +f = open(fp,"wb") +f.write(r.text.encode("UTF-8")) +f.close() + +hre = pd.read_csv(fp) + +hre.head() +""" + Ix Dynasty Name Birth Death Election 1 +0 NaN Carolingian Charles I 2 April 742 28 January 814 NaN +1 NaN Carolingian Louis I 778 20 June 840 NaN +2 NaN Carolingian Lothair I 795 29 September 855 NaN +3 NaN Carolingian Louis II 825 12 August 875 NaN +4 NaN Carolingian Charles II 13 June 823 6 October 877 NaN + + Election 2 Coronation 1 Coronation 2 Ceased to be Emperor +0 NaN 25 December 800 NaN 28 January 814 +1 NaN 11 September 813 5 October 816 20 June 840 +2 NaN 5 April 823 NaN 29 September 855 +3 NaN Easter 850 18 May 872 12 August 875 +4 NaN 29 December 875 NaN 6 October 877 + + Descent from whom 1 Descent how 1 Descent from whom 2 Descent how 2 +0 NaN NaN NaN NaN +1 Charles I son NaN NaN +2 Louis I son NaN NaN +3 Lothair I son NaN NaN +4 Louis I son NaN NaN +""" + +# limpiar las columnas de Nacimiento y Muerte + +import re # módulo para expresiones regulares + +rx = re.compile(r'\d+$') # coincidencia de últimos dígitos + +""" Esta función aplica una expresión regular a una columna de entrada (Birth, + Death), nivela la lista resultante, la convierte en un objeto Series, y + finalmente convierte el tipo del objeto Series de string a entero. Para + más información sobre que hace cada parte del código, ver: + - https://docs.python.org/2/howto/regex.html + - http://stackoverflow.com/questions/11860476/how-to-unlist-a-python-list + - http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.html +""" +def extractYear(v): + return(pd.Series(reduce(lambda x,y: x+y,map(rx.findall,v),[])).astype(int)) + +hre["BirthY"] = extractYear(hre.Birth) +hre["DeathY"] = extractYear(hre.Death) + +# hacer una columna decir la edad estimada +hre["EstAge"] = hre.DeathY.astype(int) - hre.BirthY.astype(int) + +# gráfica de dispersión simple, sin línea de tendencia, el color representa dinastía +sns.lmplot("BirthY", "EstAge", data=hre, hue="Dynasty", fit_reg=False); + +# usa scipy para hacer regresiones lineales +from scipy import stats +(slope,intercept,rval,pval,stderr)=stats.linregress(hre.BirthY,hre.EstAge) +# código fuente: http://wiki.scipy.org/Cookbook/LinearRegression + +# verifica la pendiente (slope) +slope # 0.0057672618839073328 + +# verifica el valor R^2 : +rval**2 # 0.020363950027333586 + +# verifica el valor p +pval # 0.34971812581498452 + +# usa seaborn para hacer un gráfico de dispersión y dibujar una regresión lineal +# de la tendencia +sns.lmplot("BirthY", "EstAge", data=hre); + +""" Para más información sobre seaborn, ver + - http://web.stanford.edu/~mwaskom/software/seaborn/ + - https://github.com/mwaskom/seaborn + Para más información sobre SciPy, ver + - http://wiki.scipy.org/SciPy + - http://wiki.scipy.org/Cookbook/ + Para ver una versión del análisis de los Emperadores Romanos usando R, ver + - http://github.com/e99n09/R-notes/blob/master/holy_roman_emperors_dates.R +""" +``` + +Si quieres aprender más, obtén _Python for Data Analysis_ por Wes McKinney. Es un extraordinario recurso usado como referencia para escribir este tutorial. + +También puedes encontrar gran cantidad de tutoriales interactivos de IPython en temas específicos a tus intereses, como Pilon de Cam Davidson <a href="http://camdavidsonpilon.github.io/Probabilistic-Programming-and-Bayesian-Methods-for-Hackers/" Title="Probabilistic Programming and Bayesian Methods for Hackers">Probabilistic Programming and Bayesian Methods for Hackers</a>. + +Ver más módulos para investigar: + - análisis de texto y procesamiento natural del lenguaje: nltk, http://www.nltk.org + - análisis de redes sociales: igraph, http://igraph.org/python/ diff --git a/es-es/r-es.html.markdown b/es-es/r-es.html.markdown new file mode 100644 index 00000000..2b710b27 --- /dev/null +++ b/es-es/r-es.html.markdown @@ -0,0 +1,717 @@ +--- +language: R +contributors: + - ["e99n09", "http://github.com/e99n09"] + - ["isomorphismes", "http://twitter.com/isomorphisms"] +translators: + - ["David Hsieh", "http://github.com/deivuh"] +lang: es-es +filename: learnr-es.r +--- + +R es un lenguaje de computación estadística. Tiene muchas librerías para cargar +y limpiar sets de datos, ejecutar procedimientos estadísticos y generar +gráficas. También puedes ejecutar comandos `R` dentro de un documento de +LaTeX. + +```r + +# Los comentariso inician con símbolos numéricos. + +# No puedes hacer comentarios de múltiples líneas +# pero puedes agrupar múltiples comentarios de esta manera. + +# En Windows puedes utilizar CTRL-ENTER para ejecutar una línea. +# En Mac utilizas COMMAND-ENTER + + +############################################################################# +# Cosas que puedes hacer sin entender nada acerca de programación +############################################################################# + +# En esta sección, mostramos algunas cosas chileras / cool que puedes hacer en +# R sin entender nada de programación. No te preocupes en entender nada +# de lo que hace este código. Solo disfruta! + +data() # Examinar sets de datos pre-cargados +data(rivers) # Obtiene este: Lengths of Major North American Rivers" +ls() # Fijarse que "rivers" ahora aparece en el workspace +head(rivers) # Echarle un ojo al set de datos +# 735 320 325 392 524 450 + +length(rivers) # ¿Cuántos ríos fueron medidos? +# 141 +summary(rivers) # ¿Cuáles son algunas estadísticas generales? +# Min. 1st Qu. Median Mean 3rd Qu. Max. +# 135.0 310.0 425.0 591.2 680.0 3710.0 + +# Generar una gráfica tallo-y-hoja (Visualización de datos tipo histograma) +stem(rivers) + +# El punto decimal son 2 dígitos a la derecha de | +# +# 0 | 4 +# 2 | 011223334555566667778888899900001111223333344455555666688888999 +# 4 | 111222333445566779001233344567 +# 6 | 000112233578012234468 +# 8 | 045790018 +# 10 | 04507 +# 12 | 1471 +# 14 | 56 +# 16 | 7 +# 18 | 9 +# 20 | +# 22 | 25 +# 24 | 3 +# 26 | +# 28 | +# 30 | +# 32 | +# 34 | +# 36 | 1 + +stem(log(rivers)) # Fijarse que la data no es normal ni log-normal! +# Toma eso, fundamentalistas de la curva de campana! + +# El punto decimal está a 1 dígito a la izquierda del | +# +# 48 | 1 +# 50 | +# 52 | 15578 +# 54 | 44571222466689 +# 56 | 023334677000124455789 +# 58 | 00122366666999933445777 +# 60 | 122445567800133459 +# 62 | 112666799035 +# 64 | 00011334581257889 +# 66 | 003683579 +# 68 | 0019156 +# 70 | 079357 +# 72 | 89 +# 74 | 84 +# 76 | 56 +# 78 | 4 +# 80 | +# 82 | 2 + +# Generar un histograma: +hist(rivers, col="#333333", border="white", breaks=25) # Juega con los estos parámetros +hist(log(rivers), col="#333333", border="white", breaks=25) # Generarás más gráficas después + +# Aquí hay otro set de datos pre-cargado. R tiene bastantes de éstos. +data(discoveries) +plot(discoveries, col="#333333", lwd=3, xlab="Year", + main="Number of important discoveries per year") +plot(discoveries, col="#333333", lwd=3, type = "h", xlab="Year", + main="Number of important discoveries per year") + +# En lugar de dejar el orden por defecto (por año), +# podemos ordenar de tal manera que muestre qué es típico: +sort(discoveries) +# [1] 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 +# [26] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 +# [51] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 +# [76] 4 4 4 4 5 5 5 5 5 5 5 6 6 6 6 6 6 7 7 7 7 8 9 10 12 + +stem(discoveries, scale=2) +# +# El punto decimal se encuentra en | +# +# 0 | 000000000 +# 1 | 000000000000 +# 2 | 00000000000000000000000000 +# 3 | 00000000000000000000 +# 4 | 000000000000 +# 5 | 0000000 +# 6 | 000000 +# 7 | 0000 +# 8 | 0 +# 9 | 0 +# 10 | 0 +# 11 | +# 12 | 0 + +max(discoveries) +# 12 +summary(discoveries) +# Min. 1st Qu. Median Mean 3rd Qu. Max. +# 0.0 2.0 3.0 3.1 4.0 12.0 + +# Tirar los dados varias veces +round(runif(7, min=.5, max=6.5)) +# 1 4 6 1 4 6 4 +# Tus números será diferente de los míos, a menos que tengamos el mismo valor +# de random.seed(31337) + +# Dibuja de un Gaussian 9 veces +rnorm(9) +# [1] 0.07528471 1.03499859 1.34809556 -0.82356087 0.61638975 -1.88757271 +# [7] -0.59975593 0.57629164 1.08455362 + + + +################################################## +# Tipos de datos y aritmética básica +################################################## + +# Ahora para la parte de programación orientada a objetos del tutorial. +# En esta sección conocerás los tipos de datos importantes de R: +# Enteros, numéricos, caracteres, lógicos, y factores. +# Hay otros, pero esos son los que menos necesitas para empezar. + +# ENTEROS +# Enteros de almacenamiento largo son escritos con L +5L # 5 +class(5L) # "integer" +# (Try ?class para más información en la función class().) +# En R, cada valor único, como 5L, es considerado un vector de logitud 1 +length(5L) # 1 +# También puedes tener un vector de enteros con longitud > 1: +c(4L, 5L, 8L, 3L) # 4 5 8 3 +length(c(4L, 5L, 8L, 3L)) # 4 +class(c(4L, 5L, 8L, 3L)) # "integer" + +# NUMÉRICOS +# Un "numérico" es un número de punto flotante de doble precisión. +5 # 5 +class(5) # "numeric" +# Nuevamente, todo en R es un vector; +# puedes hacer un vector numérico con más de un elemento +c(3,3,3,2,2,1) # 3 3 3 2 2 1 +# También puedes utilizar el notación científica +5e4 # 50000 +6.02e23 # Número de Avogadro +1.6e-35 # Logintud Planck +# También puedes tener números infinitamente grandes o pequeños +class(Inf) # "numeric" +class(-Inf) # "numeric" +# Puede que uses "Inf", por ejemplo, en integrate(dnorm, 3, Inf); +# esto obvia las tablas de puntos Z. + +# ARITMÉTICA BÁSICA +# Puedes hacer aritmética con números +# Haciendo aritmética en un mix de enteros y numéricos, te da otro numérico +10L + 66L # 76 # entero mas entero da entero +53.2 - 4 # 49.2 # entero menos entero da numérico +2.0 * 2L # 4 # numérico veces entero da numérico +3L / 4 # 0.75 # entero sobre numérico da numérico +3 %% 2 # 1 # el residuo de dos numéricos es otro numérico +# La aritmética ilegal rinde un "not-a-number" +0 / 0 # NaN +class(NaN) # "numeric" +# Puedes hacer aritmética con dos vectores con longitud mayor a 1, +# siempre que la longitud del vector mayor es un entero múltiplo del menor. +c(1,2,3) + c(1,2,3) # 2 4 6 + +# CARACTERES +# No hay diferencia entre strings y caracteres en R +"Horatio" # "Horatio" +class("Horatio") # "character" +class('H') # "character" +# Ambos eran vectores de caracteres de longitud 1 +# Aquí hay uno más largo: +c('alef', 'bet', 'gimmel', 'dalet', 'he') +# => +# "alef" "bet" "gimmel" "dalet" "he" +length(c("Call","me","Ishmael")) # 3 +# Puedes hacer operaciones regex en vectores de caracteres: +substr("Fortuna multis dat nimis, nulli satis.", 9, 15) # "multis " +gsub('u', 'ø', "Fortuna multis dat nimis, nulli satis.") # "Fortøna møltis dat nimis, nølli satis." +# R tiene varios vectores predefinidos de caracteres +letters +# => +# [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" +# [20] "t" "u" "v" "w" "x" "y" "z" +month.abb # "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec" + +# LÓGICOS +# En R, un "logical" es un boolean +class(TRUE) # "logical" +class(FALSE) # "logical" +# Ese comportamiento es normal +TRUE == TRUE # TRUE +TRUE == FALSE # FALSE +FALSE != FALSE # FALSE +FALSE != TRUE # TRUE +# El dato faltante (NA) es lógico también +class(NA) # "logical" +# Utiliza | y & para operaciones lógicas +# OR +TRUE | FALSE # TRUE +# AND +TRUE & FALSE # FALSE +# Puedes probar si x es TRUE (verdadero) +isTRUE(TRUE) # TRUE +# Aquí tenemos un vector lógico con varios elementos: +c('Z', 'o', 'r', 'r', 'o') == "Zorro" # FALSE FALSE FALSE FALSE FALSE +c('Z', 'o', 'r', 'r', 'o') == "Z" # TRUE FALSE FALSE FALSE FALSE + +# FACTORES +# La clase factor es para datos de categoría +# Los factores pueden ser ordenados (como las calificaciones de los niños) +# o sin orden (como el género) +factor(c("female", "female", "male", NA, "female")) +# female female male <NA> female +# Levels: female male +# Los "levels" son los valores que los datos categóricos pueden tener +# Tomar nota que los datos faltantes no entran a los niveles +levels(factor(c("male", "male", "female", NA, "female"))) # "female" "male" +# Si un vector de factores tiene longitud 1, sus niveles también tendrán +# una longitud de 1 también + +length(factor("male")) # 1 +length(levels(factor("male"))) # 1 +# Los factores son comúnmente vistos en marcos de dato, y una estructura de +# datos que cubriremos después +data(infert) # "Infertility after Spontaneous and Induced Abortion" +levels(infert$education) # "0-5yrs" "6-11yrs" "12+ yrs" + +# NULL +# "NULL" es uno raro; utilízalo para "limpiar" un vector +class(NULL) # NULL +parakeet = c("beak", "feathers", "wings", "eyes") +parakeet +# => +# [1] "beak" "feathers" "wings" "eyes" +parakeet <- NULL +parakeet +# => +# NULL + +# COERCIÓN DE TIPO +# La coerción de tipos es cuando forzas un valor diferente tipo al que puede tomar. +as.character(c(6, 8)) # "6" "8" +as.logical(c(1,0,1,1)) # TRUE FALSE TRUE TRUE +# Si pones elementos de diferentes tipos en un vector, coerciones raras pasan: +c(TRUE, 4) # 1 4 +c("dog", TRUE, 4) # "dog" "TRUE" "4" +as.numeric("Bilbo") +# => +# [1] NA +# Warning message: +# NAs introduced by coercion + +# También tomar nota: Esos solo eran datos de tipos básicos +# Hay mucho más tipos de datos, como las fechas, series de tiempo, etc. + + +################################################## +# Variables, ciclos, condiciones (if/else) +################################################## + +# A variable is like a box you store a value in for later use. +# We call this "assigning" the value to the variable. +# Having variables lets us write loops, functions, and if/else statements + +# VARIABLES +# Muchas maneras de asignar valores: +x = 5 # esto es posible +y <- "1" # esto es preferido +TRUE -> z # estos funciona pero es raro + +# CICLOS +# Tenemos ciclos 'for' +for (i in 1:4) { + print(i) +} +# Tenemos ciclos 'while' +a <- 10 +while (a > 4) { + cat(a, "...", sep = "") + a <- a - 1 +} +# Ten en mente que los ciclos 'for' y 'while' son lentos en R +# Operaciones con vectores enteros (i.e. una fila o columna completa) +# o tipos de función apply() (que discutiremos después) son preferidos + +# CONDICIONES (IF/ELSE) +# De nuevo, bastante normal +if (4 > 3) { + print("4 is greater than 3") +} else { + print("4 is not greater than 3") +} +# => +# [1] "4 is greater than 3" + +# FUNCIONES +# Definidos de la siguiente manera: +jiggle <- function(x) { + x = x + rnorm(1, sd=.1) #agregar un poco de ruido (controlado) + return(x) +} +# Llamados como cualquier otra función de R +jiggle(5) # 5±ε. luego de set.seed(2716057), jiggle(5)==5.005043 + + + +########################################################################### +# Estructura de datos: Vectores, matrices, marcos da datos y arreglos +########################################################################### + +# UNIDIMENSIONAL + +# Empecemos desde el principio, y con algo que ya conoces: vectores. +vec <- c(8, 9, 10, 11) +vec # 8 9 10 11 +# Preguntamos por elementos específicos poniendo un subconjunto en corchetes +# (Toma nota de que R empieza los conteos desde 1) +vec[1] # 8 +letters[18] # "r" +LETTERS[13] # "M" +month.name[9] # "September" +c(6, 8, 7, 5, 3, 0, 9)[3] # 7 +# También podes buscar por los índices de componentes específicos, +which(vec %% 2 == 0) # 1 3 +# obtener la primera o las últimas entradas de un vector, +head(vec, 1) # 8 +tail(vec, 2) # 10 11 +# o averiguar si cierto valor se encuentra dentro de un vector +any(vec == 10) # TRUE +# Si un índice "se pasa", obtendrás un NA: +vec[6] # NA +# Puedes encontrar la longitud de un vector con length() +length(vec) # 4 +# Puedes realizar operaciones con vectores enteros o con subconjuntos de vectores +vec * 4 # 16 20 24 28 +vec[2:3] * 5 # 25 30 +any(vec[2:3] == 8) # FALSE +# y R tiene muchas funciones pre-definidas para resumir vectores +mean(vec) # 9.5 +var(vec) # 1.666667 +sd(vec) # 1.290994 +max(vec) # 11 +min(vec) # 8 +sum(vec) # 38 +# Otras funciones pre-definidas: +5:15 # 5 6 7 8 9 10 11 12 13 14 15 +seq(from=0, to=31337, by=1337) +# => +# [1] 0 1337 2674 4011 5348 6685 8022 9359 10696 12033 13370 14707 +# [13] 16044 17381 18718 20055 21392 22729 24066 25403 26740 28077 29414 30751 + +# BIDIMENCIONAL (TODO EN UNA CLASE) + +# Puedes hacer una matriz de las entradas todos de un mismo tipo como: +mat <- matrix(nrow = 3, ncol = 2, c(1,2,3,4,5,6)) +mat +# => +# [,1] [,2] +# [1,] 1 4 +# [2,] 2 5 +# [3,] 3 6 +# A diferencia de un vector, una clase matriz es una 'matriz', +# sin importar qué contiene +class(mat) # => "matrix" +# Consulta la primera fila +mat[1,] # 1 4 +# Realiza una operación en la primera columna +3 * mat[,1] # 3 6 9 +# Consulta por una celda específica +mat[3,2] # 6 + +# Transpone una matriz entera +t(mat) +# => +# [,1] [,2] [,3] +# [1,] 1 2 3 +# [2,] 4 5 6 + +# Multiplicación de matrices +mat %*% t(mat) +# => +# [,1] [,2] [,3] +# [1,] 17 22 27 +# [2,] 22 29 36 +# [3,] 27 36 45 + +# cbind() une vectores como columnas para hacer una matriz +mat2 <- cbind(1:4, c("dog", "cat", "bird", "dog")) +mat2 +# => +# [,1] [,2] +# [1,] "1" "dog" +# [2,] "2" "cat" +# [3,] "3" "bird" +# [4,] "4" "dog" +class(mat2) # matrix +# De nuevo, ten en cuenta lo que sucedió +# Debido a que las matrices deben de contener todas las entradas del mismo tipo, +# todo fue convertido a la clase caracter +c(class(mat2[,1]), class(mat2[,2])) + +# rbind() une vectores como filas para hacer una matriz +mat3 <- rbind(c(1,2,4,5), c(6,7,0,4)) +mat3 +# => +# [,1] [,2] [,3] [,4] +# [1,] 1 2 4 5 +# [2,] 6 7 0 4 +# Ah, todo es de la misma clase. No hay coerciones. Mucho mejor. + +# BIDIMENSIONAL (DIFERENTES CLASES) + +# Para columnas de tipos diferentes, utiliza un data frame +# Esta estructura de datos es muy útil para programación estadística, +# una versión de ésta fue agregada a Python en el paquete "pandas". + +students <- data.frame(c("Cedric","Fred","George","Cho","Draco","Ginny"), + c(3,2,2,1,0,-1), + c("H", "G", "G", "R", "S", "G")) +names(students) <- c("name", "year", "house") # name the columns +class(students) # "data.frame" +students +# => +# name year house +# 1 Cedric 3 H +# 2 Fred 2 G +# 3 George 2 G +# 4 Cho 1 R +# 5 Draco 0 S +# 6 Ginny -1 G +class(students$year) # "numeric" +class(students[,3]) # "factor" +# encontrar las dimensiones +nrow(students) # 6 +ncol(students) # 3 +dim(students) # 6 3 +# La función data.frame() convierte vectores de caracteres en vectores +# de factores por defecto; deshabilita este atributo +# stringsAsFactors = FALSE cuando vayas a crear el data.frame +?data.frame + +# Hay otras formas de hacer subconjuntos de data frames +students$year # 3 2 2 1 0 -1 +students[,2] # 3 2 2 1 0 -1 +students[,"year"] # 3 2 2 1 0 -1 + +# Una versión aumentada de la estructura data.frame es el data.table +# Si estás trabajando huge o panel data, o necesitas unificar algunos +# subconjuntos de datos, data.table puede ser una buena elección. +# Aquí un tour: +install.packages("data.table") # Descarga el paquete de CRAN +require(data.table) # Cárgalo +students <- as.data.table(students) +students # Tomar en cuenta la diferencia de la impresión +# => +# name year house +# 1: Cedric 3 H +# 2: Fred 2 G +# 3: George 2 G +# 4: Cho 1 R +# 5: Draco 0 S +# 6: Ginny -1 G +students[name=="Ginny"] # obtener filas con name == "Ginny" +# => +# name year house +# 1: Ginny -1 G +students[year==2] # obtener filas con year == 2 +# => +# name year house +# 1: Fred 2 G +# 2: George 2 G +# data.table hace que la unificación de dos sets de datos sea fácil +# Hagamos otro data.table para unifiar a los estudiantes +founders <- data.table(house=c("G","H","R","S"), + founder=c("Godric","Helga","Rowena","Salazar")) +founders +# => +# house founder +# 1: G Godric +# 2: H Helga +# 3: R Rowena +# 4: S Salazar +setkey(students, house) +setkey(founders, house) +students <- founders[students] # Unifica los dos sets de datos comparando "house" +setnames(students, c("house","houseFounderName","studentName","year")) +students[,order(c("name","year","house","houseFounderName")), with=F] +# => +# studentName year house houseFounderName +# 1: Fred 2 G Godric +# 2: George 2 G Godric +# 3: Ginny -1 G Godric +# 4: Cedric 3 H Helga +# 5: Cho 1 R Rowena +# 6: Draco 0 S Salazar + +# data.table hace que sea fácil obtener resúmenes de las tablas +students[,sum(year),by=house] +# => +# house V1 +# 1: G 3 +# 2: H 3 +# 3: R 1 +# 4: S 0 + +# Para eliminar una columna de un data.frame o data.table, +# asignarle el valor NULL. +students$houseFounderName <- NULL +students +# => +# studentName year house +# 1: Fred 2 G +# 2: George 2 G +# 3: Ginny -1 G +# 4: Cedric 3 H +# 5: Cho 1 R +# 6: Draco 0 S + +# Elimina una fila poniendo un subconjunto +# Usando data.table: +students[studentName != "Draco"] +# => +# house studentName year +# 1: G Fred 2 +# 2: G George 2 +# 3: G Ginny -1 +# 4: H Cedric 3 +# 5: R Cho 1 +# Usando data.frame: +students <- as.data.frame(students) +students[students$house != "G",] +# => +# house houseFounderName studentName year +# 4 H Helga Cedric 3 +# 5 R Rowena Cho 1 +# 6 S Salazar Draco 0 + +# MULTI-DIMENSIONAL (TODOS LOS ELEMENTOS DE UN TIPO) + +# Arreglos crean una tabla de dimensión n +# Todos los elementos deben de ser del mismo tipo +# Puedes hacer una tabla bi-dimensional (como una matriz) +array(c(c(1,2,4,5),c(8,9,3,6)), dim=c(2,4)) +# => +# [,1] [,2] [,3] [,4] +# [1,] 1 4 8 3 +# [2,] 2 5 9 6 +# Puedes utilizar un arreglo para hacer una matriz tri-dimensional también +array(c(c(c(2,300,4),c(8,9,0)),c(c(5,60,0),c(66,7,847))), dim=c(3,2,2)) +# => +# , , 1 +# +# [,1] [,2] +# [1,] 2 8 +# [2,] 300 9 +# [3,] 4 0 +# +# , , 2 +# +# [,1] [,2] +# [1,] 5 66 +# [2,] 60 7 +# [3,] 0 847 + +# LISTAS (MULTI-DIMENSIONAL, POSIBLEMENTE DESIGUALES, DE DIFERENTES TIPOS) + +# Finalmente, R tiene listas (de vectores) +list1 <- list(time = 1:40) +list1$price = c(rnorm(40,.5*list1$time,4)) # aleatorio +list1 +# Puedes obtener elementos de una lista de la siguiente manera +list1$time # Una manera +list1[["time"]] # Otra manera +list1[[1]] # Y otra manera +# => +# [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 +# [34] 34 35 36 37 38 39 40 +# Puedes crear una lista de subconjuntos como cualquier otro vector +list1$price[4] + +# Las listas no son la estructura de datos más eficiente para trabajar en R; +# a menos de que tengas una buena razón, deberías de quedarte con data.frames +# Las listas son usualmente devueltas por funciones que realizan regresiones +# lineales + +################################################## +# La familia de funciones apply() +################################################## + +# Te recuerdas de mat? +mat +# => +# [,1] [,2] +# [1,] 1 4 +# [2,] 2 5 +# [3,] 3 6 +# Utiliza apply(X, MARGIN, FUN) paraaplicar una función FUN a la matriz X +# sobre las filas (MAR = 1) o las columnas (MAR = 2) +# Eso es, R aplica FUN sobre cada fila (o columna) de X, mucho más rápido que +# lo que haría un ciclo 'for' o 'loop' +apply(mat, MAR = 2, jiggle) +# => +# [,1] [,2] +# [1,] 3 15 +# [2,] 7 19 +# [3,] 11 23 +# Otras funciones: ?lapply, ?sapply + +# No te sientas muy intimidado; todos están de acuerdo que son confusas + +# El paquete plyr busca reemplazar (y mejorar) la familiar *apply() +install.packages("plyr") +require(plyr) +?plyr + + + +######################### +# Carga de datos +######################### + +# "pets.csv" es un archivo en internet +# (pero puede ser tan fácil como tener el archivo en tu computadora) +pets <- read.csv("http://learnxinyminutes.com/docs/pets.csv") +pets +head(pets, 2) # primeras dos filas +tail(pets, 1) # última fila + +# Para guardar un data frame o una matriz como un archivo .csv +write.csv(pets, "pets2.csv") # para hacer un nuevo archivo .csv +# definir el directorio de trabajo con setwd(), búscalo con getwd() + +# Prueba ?read.csv ?write.csv para más información + + +######################### +# Gráficas +######################### + +# FUNCIONES PREDEFINIDAS DE GRAFICACIÓN +# Gráficos de dispersión! +plot(list1$time, list1$price, main = "fake data") +# Regresiones! +linearModel <- lm(price ~ time, data = list1) +linearModel # Muestra el resultado de la regresión +# Grafica la línea de regresión +abline(linearModel, col = "red") +# Obtiene una veridad de diagnósticos +plot(linearModel) +# Histogramas! +hist(rpois(n = 10000, lambda = 5), col = "thistle") +# Barras! +barplot(c(1,4,5,1,2), names.arg = c("red","blue","purple","green","yellow")) + +# GGPLOT2 +# Pero éstas no son las gráficas más bonitas de R +# Prueba el paquete ggplot2 para mayor variedad y mejores gráficas +install.packages("ggplot2") +require(ggplot2) +?ggplot2 +pp <- ggplot(students, aes(x=house)) +pp + geom_histogram() +ll <- as.data.table(list1) +pp <- ggplot(ll, aes(x=time,price)) +pp + geom_point() +# ggplot2 tiene una excelente documentación +# (disponible en http://docs.ggplot2.org/current/) + + + +``` + +## ¿Cómo obtengo R? + +* Obtén R y R GUI de [http://www.r-project.org/](http://www.r-project.org/) +* [RStudio](http://www.rstudio.com/ide/) es otro GUI diff --git a/es-es/ruby-es.html.markdown b/es-es/ruby-es.html.markdown index d8b67fe7..e3e43c18 100644 --- a/es-es/ruby-es.html.markdown +++ b/es-es/ruby-es.html.markdown @@ -29,7 +29,7 @@ Nadie los usa. Tu tampoco deberías =end -# Lo primero y principal: Todo es un objeto +# En primer lugar: Todo es un objeto # Los números son objetos @@ -128,7 +128,7 @@ ruta = '/mal/nombre/' # Los símbolos (son objetos) # Los símbolos son inmutables, constantes reusables representadas internamente por un -# valor entero. Son usalmente usados en vez de strings para expresar eficientemente +# valor entero. Son normalmente usados en vez de strings para expresar eficientemente # valores específicos y significativos :pendiente.class #=> Symbol @@ -156,7 +156,7 @@ arreglo[0] #=> 1 arreglo.first #=> 1 arreglo[12] #=> nil -# Tal como la aritmética, el acceso como variable[índice] +# Al igual que en aritmética, el acceso como variable[índice] # es sólo azúcar sintáctica # para llamar el método [] de un objeto arreglo.[] 0 #=> 1 diff --git a/es-es/rust-es.html.markdown b/es-es/rust-es.html.markdown new file mode 100644 index 00000000..b43cb815 --- /dev/null +++ b/es-es/rust-es.html.markdown @@ -0,0 +1,324 @@ +--- +language: rust +contributors: + - ["P1start", "http://p1start.github.io/"] +translators: + - ["Razican", "https://www.razican.com/"] +filename: learnrust-es.rs +lang: es-es +--- + +Rust es un lenguaje de programación desarrollado por Mozzilla Research. Rust +combina el control del rendimiento a bajo nivel con la comodidad del alto nivel +y garantías de seguridad. + +Consigue cumplir estos objetivos sin necesidad de un recolector de basura o +runtime, haciendo posible usar las librerías de Rust como sustituto de C. + +La primera versión de Rust, la 0.1, fue lanzada en enero de 2012, y durante 3 +años el desarrollo fue tan rápido que hasta hace poco el uso de las versiones +estables no era recomendable, y se aconsejaba usar las compilaciones nocturnas. + +El 15 de mayo de 2015 se lanzó Rust 1.0, con una garantía completa de +retrocompatibilidad. A día de hoy los tiempos de compilación han mejorado mucho +desde ese lanzamiento, así como otros aspectos del lenguaje y el compilador. +Rust ha adoptado un modelo de desarrollo por series de publicaciones periódicas, +con lanzamientos cada 6 semanas. Junto con cada lanzamiento, se lanza la beta de +la siguiente versión. + +A pesar de que Rust es un lenguaje relativamente de bajo nivel, tiene conceptos +funcionales que generalmente se encuentran en lenguajes de más alto nivel. Esto +hace que Rust sea rápido y al mismo tiempo fácil y eficiente a la hora de +programar. + +```rust +// Esto es un comentario. Los comentarios de una sola línea se hacen así... +/* ...y los de múltiples líneas así */ + +////////////////////////// +// 1. Conceptos básicos // +////////////////////////// + +// Funciones +// `i32` es el tipo para enteros de 32 bits con signo +fn suma2(x: i32, y: i32) -> i32 { + // Retorno implícito (sin punto y coma) + x + y +} + +// Función principal +fn main() { + // N;umeros // + + // Bindings (variables) inmutables + let x: i32 = 1; + + // Sufijos para enteros / floats + let y: i32 = 13i32; + let f: f64 = 1.3f64; + + // Inferencia de tipos + // La mayor parte del tiempo, el compilador de Rust puede inferir el tipo de + // una variable, por lo que no necesitas escribir una anotación de tipo + // explícita. A lo largo de este tutorial, los tipos están anotados + // explícitamente en varios sitios, pero solo con propósito demostrativo. La + // inferencia de tipos puede manejar esto por ti la mayor parte del tiempo. + let x_implicita = 1; + let f_implicita = 1.3; + + // Aritmética + let sum = x + y + 13; + + // Variable mutable + let mut mutable = 1; + mutable = 4; + mutable += 2; + + // Strings (cadenas de caracteres) // + + // Strings literales + let x: &str = "hola mundo!"; + + // Impresión por consola + println!("{} {}", f, x); // 1.3 hola mundo! + + // Un `String` – una cadena en memoria dinámica (heap) + let s: String = "hola mundo".to_string(); + + // Una porión de cadena (slice) – una vista inmutable a otra cadena + // Esto es básicamente un puntero inmutable a un string string – en realidad + // no contiene los caracteres de la cadena, solo un puntero a algo que los + // tiene (en este caso, `s`) + let s_slice: &str = &s; + + println!("{} {}", s, s_slice); // hola mundo hola mundo + + // Vectores/arrays // + + // A fixed-size array + let cuatro_enteros: [i32; 4] = [1, 2, 3, 4]; + + // Un array dinámico (vector) + let mut vector: Vec<i32> = vec![1, 2, 3, 4]; + vector.push(5); + + // Una porción (slice) – una vista inmutable a un vector o array + // Esto es parecido a un slice de un string, pero para vectores + let slice: &[i32] = &vector; + + // Usa `{:?}` para imprimir algo en estilo debug + println!("{:?} {:?}", vector, slice); // [1, 2, 3, 4, 5] [1, 2, 3, 4, 5] + + // Tuplas // + + // Una tupla es un conjunto de tamaño fijo de valores. Pueden ser de diferente tipo. + let x: (i32, &str, f64) = (1, "hola", 3.4); + + // Desestructurando `let` + let (a, b, c) = x; + println!("{} {} {}", a, b, c); // 1 hola 3.4 + + // Indexando + println!("{}", x.1); // hola + + ////////////// + // 2. Tipos // + ////////////// + + // Estructuras + struct Punto { + x: i32, + y: i32, + } + + let origen: Punto = Punto { x: 0, y: 0 }; + + // Una estructura con campos sin nombre, una ‘estructura de tupla’ + struct Punto2(i32, i32); + + let origen2 = Punto2(0, 0); + + // Enums básicos como en C + enum Direccion { + Izquierda, + Derecha, + Arriba, + Abajo, + } + + let arriba = Direccion::Arriba; + + // Enum con campos + enum OpcionalI32 { + UnI32(i32), + Nada, + } + + let dos: OpcionalI32 = OpcionalI32::UnI32(2); + let nada = OpcionalI32::Nada; + + // Genéricos // + + struct Foo<T> { bar: T } + + // Esto está definido en la librería estándar como `Option` + enum Opcional<T> { + AlgunVal(T), + SinVal, + } + + // Métodos // + + impl<T> Foo<T> { + // Los métodos reciben un parámetro explícito `self` + fn get_bar(self) -> T { + self.bar + } + } + + let un_foo = Foo { bar: 1 }; + println!("{}", un_foo.get_bar()); // 1 + + // Traits (conocidos como interfaces o typeclasses en otros lenguajes) // + + trait Frobnicate<T> { + fn frobnicate(self) -> Option<T>; + } + + impl<T> Frobnicate<T> for Foo<T> { + fn frobnicate(self) -> Option<T> { + Some(self.bar) + } + } + + let otro_foo = Foo { bar: 1 }; + println!("{:?}", otro_foo.frobnicate()); // Some(1) + + ///////////////////////////////// + // 3. Comparación con patrones // + ///////////////////////////////// + + let foo = OpcionalI32::UnI32(1); + match foo { + OpcionalI32::UnI32(n) => println!("es un i32: {}", n), + OpcionalI32::Nada => println!("no es nada!"), + } + + // comparación de patrones avanzada + struct FooBar { x: i32, y: OpcionalI32 } + let bar = FooBar { x: 15, y: OpcionalI32::UnI32(32) }; + + match bar { + FooBar { x: 0, y: OpcionalI32::UnI32(0) } => + println!("Los números son cero!"), + FooBar { x: n, y: OpcionalI32::UnI32(m) } if n == m => + println!("Los números son iguales"), + FooBar { x: n, y: OpcionalI32::UnI32(m) } => + println!("Números diferentes: {} {}", n, m), + FooBar { x: _, y: OpcionalI32::Nada } => + println!("El segudo número no es nada!"), + } + + ///////////////////////// + // 4. Flujo de control // + ///////////////////////// + + // bucles `for` + let array = [1, 2, 3]; + for i in array.iter() { + println!("{}", i); + } + + // Rangos + for i in 0u32..10 { + print!("{} ", i); + } + println!(""); + // imprime `0 1 2 3 4 5 6 7 8 9 ` + + // `if` + if 1 == 1 { + println!("Las matemáticas funcionan!"); + } else { + println!("Oh no..."); + } + + // `if` como una expresión + let valor = if true { + "bueno" + } else { + "malo" + }; + + // bucle `while` + while 1 == 1 { + println!("El universo está funcionando correctamente."); + } + + // Bucle infinito + loop { + println!("Hola!"); + } + + //////////////////////////////////////// + // 5. Seguridad de memoria y punteros // + //////////////////////////////////////// + + // Posesión de punteros – solo uno puede ‘poseer’ un puntero en cada momento + // Esto significa que cuando la `Box` queda fuera del ámbito, puede ser + // liberada automáticamente de manera segura. + let mut mio: Box<i32> = Box::new(3); + *mio = 5; // dereferenciar + // Aquí, `ahora_es_mio`, toma posesión de `mio`. En otras palabras, `mio` se + // mueve. + let mut ahora_es_mio = mio; + *ahora_es_mio += 2; + + println!("{}", ahora_es_mio); // 7 + // println!("{}", mio); // esto no compilaría, porque `now_its_mine` es el + // que posee el puntero + + // Referencia – un puntero inmutable que referencia a otro dato + // Cuando se crea una referencia a un valor, decimos que el valor ha sido + // ‘tomado prestado’. + // Mientras un valor está prestado como inmutable, no puede ser modificado o + // movido. + // Una prestación dura hasta el fin del ámbito en el que se creó. + let mut var = 4; + var = 3; + let ref_var: &i32 = &var; + + println!("{}", var); // A diferencia de `mio`, `var` se puede seguir usando + println!("{}", *ref_var); + // var = 5; // esto no compilaría, porque `var` está prestada + // *ref_var = 6; // esto tampoco, porque `ref_var` es una referencia + // inmutable + + // Referencia mutable + // Mientras que un valor está prestado como mutable, no puede ser accedido + // desde ningún otro sitio. + let mut var2 = 4; + let ref_var2: &mut i32 = &mut var2; + *ref_var2 += 2; // '*' se usa para apuntar al var2 prestado como mutable + + println!("{}", *ref_var2); // 6 , //var2 no compilaría. //ref_var2 es de + // tipo &mut i32, por lo que guarda una + // referencia a un i32 no el valor. + // var2 = 2; // esto no compilaría porque `var2` está prestado +} +``` + +## Lectura adicional + +Rust es mucho más que esto. Esto es solo lo más básico para que puedas entender +las cosas más importantes. Para aprender más sobre Rust, lee [The Rust +Programming Language](http://doc.rust-lang.org/book/index.html) y echa un +vistazo al subreddit [/r/rust](http://reddit.com/r/rust). Los compañeros en el +canal #rust en irc.mozilla.org también son muy buenos con los recien llegados. +También puedes acceder a [Rust users](https://users.rust-lang.org/) a pedir +ayuda o a [Rust internals](https://internals.rust-lang.org/) para aprender más +sobre el lenguaje y colaborar en su desarrollo. + +También puedes probar Rust con un compilador online en el oficial [Rust +playpen](http://play.rust-lang.org) o en la [web principal de +Rust](http://rust-lang.org). diff --git a/es-es/self-es.html.markdown b/es-es/self-es.html.markdown new file mode 100644 index 00000000..11972214 --- /dev/null +++ b/es-es/self-es.html.markdown @@ -0,0 +1,163 @@ +--- +language: self +contributors: + - ["Russell Allen", "http://github.com/russellallen"] +filename: learnself-es.self +translators: + - ["Damaso Sanoja", "https://github.com/damasosanoja"] +lang: es-es +--- + +Self es un lenguaje OO basado en prototipo rápido que corre en su propio vm JIT. La mayoría del desarrollo se hace a través de la interacción con objetos vivos en un entorno de desarrollo visual llamado *morphic* que tiene integrado navegador y depurador. + +Todo en Self es un objeto. Todos los cómputos son hechos enviando mensajes a los objetos. En Self se puede entender por Objetos a los conjuntos de pares clave-valor. + +# Construyendo objetos + +El intérprete incorporado de Self puede construir objetos, incluyendo objetos-métodos. + +``` +"Esto es un comentario" + +"Una cadena de caracteres (string):" +'Esto es un string con \'caracteres\' escapados.\n' + +"Un entero de 30 bits" +23 + +"Un decimal de 30 bits" +3.2 + +"-20" +-14r16 + +"Un objeto que solo entiende un mensaje, 'x' que regresa 20" +(| + x = 20. +|) + +"Un objeto que además entiende 'x:' que establece la posición x" +(| + x <- 20. +|) + +"Un objeto que entiende el método 'doubleX' el cual +duplica el valor de x y luego regresa el objeto" +(| + x <- 20. + doubleX = (x: x * 2. self) +|) + +"Un objeto que entiende todos los mensajes +que 'traits point' entiende". El intérprete +mira a 'traits point' enviando los mensajes +'traits' y luego 'point' a un objeto conocido llamado +el 'lobby'. El mira el objeto 'true' enviando +también el mensaje 'true' al lobby." +(| parent* = traits point. + x = 7. + y <- 5. + isNice = true. +|) +``` + +# Enviando mensajes a los objetos + +Los mensajes pueden ser unarios, binarios o palabras clave. La precedencia es en ese orden. A diferencia de Smalltalk, la precedencia de los mensajes binarios debe ser especificada, y todas las palabras clave después de la primera deben comenzar con una letra mayúscula. Los mensajes se separan de sus destinos mediante espacios en blanco. + +``` +"mensaje unario, envía 'printLine' al objeto '23' +que imprime el string '23' en stdout y regresa el objeto recibido (ejem 23)" +23 printLine + +"envía el mensaje '+' con '7' para '23', luego el mensaje '*' con '8' para el resultado" +(23 + 7) * 8 + +"envía 'power:' para '2' con '8' regresa 256" +2 power: 8 + +"envía 'keyOf:IfAbsent:' para 'hello' con los argumentos 'e' y '-1'. +Regresa 1, el índice de 'e' en 'hello'." +'hello' keyOf: 'e' IfAbsent: -1 +``` + +# Bloques + +Self define el control de flujo como Smalltalk y Ruby mediante bloques Los bloques son cómputos demorados de la forma.: + +``` +[|:x. localVar| x doSomething with: localVar] +``` + +Ejemplos del uso de bloques: + +``` +"regresa 'HELLO'" +'hello' copyMutable mapBy: [|:c| c capitalize] + +"regresa 'Nah'" +'hello' size > 5 ifTrue: ['Yay'] False: ['Nah'] + +"regresa 'HaLLO'" +'hello' copyMutable mapBy: [|:c| + c = 'e' ifTrue: [c capitalize] + False: ['a']] +``` + +Las expresiones múltiples son separadas por un punto. ^ retorna inmediatamente. + +``` +"returns An 'E'! How icky!" +'hello' copyMutable mapBy: [|:c. tmp <- ''| + tmp: c capitalize. + tmp = 'E' ifTrue: [^ 'An \'E\'! How icky!']. + c capitalize + ] +``` + +Los bloques son ejecutados al enviales el mensaje 'value' y son inherentes (delegados a) sus contextos: +``` +"returns 0" +[|x| + x: 15. + "Envía repetidamente 'value' al primer bloque mientras el resultado de enviar 'value' al segundo bloque es el objeto 'true'" + [x > 0] whileTrue: [x: x - 1]. + x +] value +``` + +# Métodos + +Los métodos son como los bloques pero no están dentro de un contexto sino que son almacenados como valores de ranuras. A diferencia de Smalltalk, los métodos no regresan por defecto 'self' sino su valor final. + +``` +"Aquí tenemos un objeto con una ranura asignable 'x' y un método 'reduceXTo: y'. +Enviando el mensaje 'reduceXTo: 10' a este objeto pondrá +el objeto '10' en la ranura 'x' y regresará el objeto original" +(| + x <- 50. + reduceXTo: y = ( + [x > y] whileTrue: [x: x - 1]. + self) +|) +. +``` + +# Prototipos + +Self no posee clases. La forma de acceder a un objeto es encontrando un prototipo y copiándolo. + +``` +| d | +d: dictionary copy. +d at: 'hello' Put: 23 + 8. +d at: 'goodbye' Put: 'No!. +"Prints No!" +( d at: 'goodbye' IfAbsent: 'Yes! ) printLine. +"Prints 31" +( d at: 'hello' IfAbsent: -1 ) printLine. +``` + +# Para mayor información + +El [Manual de Self](http://handbook.selflanguage.org) tiene mucha más información, y nada mejor que experiencia de primera mano con Self descargándolo de su [página web](http://www.selflanguage.org). diff --git a/es-es/swift-es.html.markdown b/es-es/swift-es.html.markdown new file mode 100644 index 00000000..c04ab02b --- /dev/null +++ b/es-es/swift-es.html.markdown @@ -0,0 +1,596 @@ +--- +language: swift +contributors: + - ["Grant Timmerman", "http://github.com/grant"] + - ["Christopher Bess", "http://github.com/cbess"] + - ["Joey Huang", "http://github.com/kamidox"] + - ["Anthony Nguyen", "http://github.com/anthonyn60"] +translators: + - ["David Hsieh", "http://github.com/deivuh"] +lang: es-es +filename: learnswift-es.swift +--- + +Swift es un lenguaje de programación para el desarrollo en iOS y OS X creado +por Apple. Diseñado para coexistir con Objective-C y ser más resistente contra +el código erroneo, Swift fue introducido en el 2014 en el WWDC, la conferencia +de desarrolladores de Apple. + +Véase también la guía oficial de Apple, [getting started guide](https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/DevelopiOSAppsSwift/), el cual tiene un completo tutorial de Swift. + + +```swift +// Importar un módulo +import UIKit + +// +// MARK: Básicos +// + +// XCode soporta referencias para anotar tu código y agregarlos a lista de la +// barra de saltos. +// MARK: Marca de sección +// TODO: Hacer algo pronto +// FIXME: Arreglar este código + +// En Swift 2, println y print fueron combinados en un solo método print. +// Print añade una nueva línea automáticamente. +print("Hola, mundo") // println ahora es print +print("Hola, mundo", appendNewLine: false) // print sin agregar nueva línea + +// Valores de variables (var) pueden cambiar después de ser asignados +// Valores de constrantes (let) no pueden cambiarse después de ser asignados + +var myVariable = 42 +let øπΩ = "value" // nombres de variable unicode +let π = 3.1415926 +let convenience = "keyword" // nombre de variable contextual +// Las declaraciones pueden ser separadas por punto y coma (;) +let weak = "keyword"; let override = "another keyword" +// Los acentos abiertos (``) permiten utilizar palabras clave como nombres de +// variable +let `class` = "keyword" +let explicitDouble: Double = 70 +let intValue = 0007 // 7 +let largeIntValue = 77_000 // 77000 +let label = "some text " + String(myVariable) // Conversión (casting) +let piText = "Pi = \(π), Pi 2 = \(π * 2)" // Interpolación de string + +// Valores específicos de la compilación (build) +// utiliza la configuración -D +#if false + print("No impreso") + let buildValue = 3 +#else + let buildValue = 7 +#endif +print("Build value: \(buildValue)") // Build value: 7 + +/* + Las opcionales son un aspecto del lenguaje Swift que permite el + almacenamiento de un valor `Some` (algo) o `None` (nada). + + Debido a que Swift requiere que cada propiedad tenga un valor, + hasta un valor 'nil' debe de ser explicitamente almacenado como un + valor opcional. + + Optional<T> es un enum. +*/ +var someOptionalString: String? = "opcional" // Puede ser nil +// Al igual que lo anterior, pero ? es un operador postfix (sufijo) +var someOptionalString2: Optional<String> = "opcional" + +if someOptionalString != nil { + // No soy nil + if someOptionalString!.hasPrefix("opt") { + print("Tiene el prefijo") + } + + let empty = someOptionalString?.isEmpty +} +someOptionalString = nil + +// Opcional implícitamente desenvuelto +var unwrappedString: String! = "Un valor esperado." +// Al igual que lo anterior, pero ! es un operador postfix (sufijo) +var unwrappedString2: ImplicitlyUnwrappedOptional<String> = "Un valor esperado." + +if let someOptionalStringConstant = someOptionalString { + // tiene valor `Some` (algo), no nil + if !someOptionalStringConstant.hasPrefix("ok") { + // No tiene el prefijo + } +} + +// Swift tiene soporte de almacenamiento para cualquier tipo de valor. +// AnyObject == id +// A diferencia de Objective-C `id`, AnyObject funciona con cualquier +// valor (Class, Int, struct, etc) +var anyObjectVar: AnyObject = 7 +anyObjectVar = "Cambiado a un valor string, no es buena práctica, pero posible." + +/* + Comentar aquí + + /* + Comentarios anidados también son soportados + */ +*/ + +// +// MARK: Colecciones +// + +/* + Tipos Array (arreglo) y Dictionary (diccionario) son structs (estructuras). + Así que `let` y `var` también indican si son mudables (var) o + inmutables (let) durante la declaración de sus tipos. +*/ + +// Array (arreglo) +var shoppingList = ["catfish", "water", "lemons"] +shoppingList[1] = "bottle of water" +let emptyArray = [String]() // let == inmutable +let emptyArray2 = Array<String>() // igual que lo anterior +var emptyMutableArray = [String]() // var == mudable + + +// Dictionary (diccionario) +var occupations = [ + "Malcolm": "Captain", + "kaylee": "Mechanic" +] +occupations["Jayne"] = "Public Relations" +let emptyDictionary = [String: Float]() // let == inmutable +let emptyDictionary2 = Dictionary<String, Float>() // igual que lo anterior +var emptyMutableDictionary = [String: Float]() // var == mudable + + +// +// MARK: Flujo de control +// + +// Ciclo for (array) +let myArray = [1, 1, 2, 3, 5] +for value in myArray { + if value == 1 { + print("Uno!") + } else { + print("No es uno!") + } +} + +// Ciclo for (dictionary) +var dict = ["uno": 1, "dos": 2] +for (key, value) in dict { + print("\(key): \(value)") +} + +// Ciclo for (range) +for i in -1...shoppingList.count { + print(i) +} +shoppingList[1...2] = ["steak", "peacons"] +// Utilizar ..< para excluir el último valor + +// Ciclo while +var i = 1 +while i < 1000 { + i *= 2 +} + +// Ciclo do-while +do { + print("Hola") +} while 1 == 2 + +// Switch +// Muy potente, se puede pensar como declaraciones `if` con _azúcar sintáctico_ +// Soportan String, instancias de objetos, y primitivos (Int, Double, etc) +let vegetable = "red pepper" +switch vegetable { +case "celery": + let vegetableComment = "Add some raisins and make ants on a log." +case "cucumber", "watercress": + let vegetableComment = "That would make a good tea sandwich." +case let localScopeValue where localScopeValue.hasSuffix("pepper"): + let vegetableComment = "Is it a spicy \(localScopeValue)?" +default: // obligatorio (se debe cumplir con todos los posibles valores de entrada) + let vegetableComment = "Everything tastes good in soup." +} + + +// +// MARK: Funciones +// + +// Funciones son un tipo de primera-clase, quiere decir que pueden ser anidados +// en funciones y pueden ser pasados como parámetros + +// Función en documentación de cabeceras Swift (formato reStructedText) + +/** + Una operación de saludo + + - Una viñeta en la documentación + - Otra viñeta en la documentación + + :param: name Un nombre + :param: day Un día + :returns: Un string que contiene el valor de name y day +*/ +func greet(name: String, day: String) -> String { + return "Hola \(name), hoy es \(day)." +} +greet("Bob", "Martes") + +// Similar a lo anterior, a excepción del compartamiento de los parámetros +// de la función +func greet2(requiredName: String, externalParamName localParamName: String) -> String { + return "Hola \(requiredName), hoy es el día \(localParamName)" +} +greet2(requiredName:"John", externalParamName: "Domingo") + +// Función que devuelve múltiples valores en una tupla +func getGasPrices() -> (Double, Double, Double) { + return (3.59, 3.69, 3.79) +} +let pricesTuple = getGasPrices() +let price = pricesTuple.2 // 3.79 +// Ignorar tupla (u otros) valores utilizando _ (guión bajo) +let (_, price1, _) = pricesTuple // price1 == 3.69 +print(price1 == pricesTuple.1) // true +print("Gas price: \(price)") + +// Cantidad variable de argumentos +func setup(numbers: Int...) { + // Es un arreglo + let number = numbers[0] + let argCount = numbers.count +} + +// Pasando y devolviendo funciones +func makeIncrementer() -> (Int -> Int) { + func addOne(number: Int) -> Int { + return 1 + number + } + return addOne +} +var increment = makeIncrementer() +increment(7) + +// Pasando como referencia +func swapTwoInts(inout a: Int, inout b: Int) { + let tempA = a + a = b + b = tempA +} +var someIntA = 7 +var someIntB = 3 +swapTwoInts(&someIntA, &someIntB) +print(someIntB) // 7 + + +// +// MARK: Closures (Clausuras) +// +var numbers = [1, 2, 6] + +// Las funciones son un caso especial de closure ({}) + +// Ejemplo de closure. +// `->` Separa los argumentos del tipo de retorno +// `in` Separa la cabecera del cuerpo del closure +numbers.map({ + (number: Int) -> Int in + let result = 3 * number + return result +}) + +// Cuando se conoce el tipo, como en lo anterior, se puede hacer esto +numbers = numbers.map({ number in 3 * number }) +// o esto +//numbers = numbers.map({ $0 * 3 }) + +print(numbers) // [3, 6, 18] + +// Closure restante +numbers = sorted(numbers) { $0 > $1 } + +print(numbers) // [18, 6, 3] + +// Bastante corto, debido a que el operador < infiere los tipos + +numbers = sorted(numbers, < ) + +print(numbers) // [3, 6, 18] + +// +// MARK: Estructuras +// + +// Las estructuras y las clases tienen capacidades similares +struct NamesTable { + let names = [String]() + + // Subscript personalizado + subscript(index: Int) -> String { + return names[index] + } +} + +// Las estructuras tienen un inicializador designado autogenerado (implícitamente) +let namesTable = NamesTable(names: ["Me", "Them"]) +let name = namesTable[1] +print("Name is \(name)") // Name is Them + +// +// MARK: Clases +// + +// Las clases, las estructuras y sus miembros tienen tres niveles de control de acceso +// Éstos son: internal (predeterminado), public, private + +public class Shape { + public func getArea() -> Int { + return 0; + } +} + +// Todos los métodos y las propiedades de una clase son public (públicas) +// Si solo necesitas almacenar datos en un objecto estructurado, +// debes de utilizar `struct` + +internal class Rect: Shape { + var sideLength: Int = 1 + + // Getter y setter personalizado + private var perimeter: Int { + get { + return 4 * sideLength + } + set { + // `newValue` es una variable implícita disponible para los setters + sideLength = newValue / 4 + } + } + + // Lazily loading (inicialización bajo demanda) a una propiedad + // subShape queda como nil (sin inicializar) hasta que getter es llamado + lazy var subShape = Rect(sideLength: 4) + + // Si no necesitas un getter y setter personalizado + // pero aún quieres ejecutar código antes y después de hacer get o set + // a una propiedad, puedes utilizar `willSet` y `didSet` + var identifier: String = "defaultID" { + // El argumento `willSet` será el nombre de variable para el nuevo valor + willSet(someIdentifier) { + print(someIdentifier) + } + } + + init(sideLength: Int) { + self.sideLength = sideLength + // Siempre poner super.init de último al momento de inicializar propiedades + // personalizadas + super.init() + } + + func shrink() { + if sideLength > 0 { + --sideLength + } + } + + override func getArea() -> Int { + return sideLength * sideLength + } +} + +// Una clase simple `Square` que extiende de `Rect` +class Square: Rect { + convenience init() { + self.init(sideLength: 5) + } +} + +var mySquare = Square() +print(mySquare.getArea()) // 25 +mySquare.shrink() +print(mySquare.sideLength) // 4 + +// Conversión de tipo de instancia +let aShape = mySquare as Shape + +// Comparar instancias, no es igual a == que compara objetos (equal to) +if mySquare === mySquare { + print("Yep, it's mySquare") +} + +// Inicialización (init) opcional +class Circle: Shape { + var radius: Int + override func getArea() -> Int { + return 3 * radius * radius + } + + // Un signo de interrogación como sufijo después de `init` es un init opcional + // que puede devolver nil + init?(radius: Int) { + self.radius = radius + super.init() + + if radius <= 0 { + return nil + } + } +} + +var myCircle = Circle(radius: 1) +print(myCircle?.getArea()) // Optional(3) +print(myCircle!.getArea()) // 3 +var myEmptyCircle = Circle(radius: -1) +print(myEmptyCircle?.getArea()) // "nil" +if let circle = myEmptyCircle { + // no será ejecutado debido a que myEmptyCircle es nil + print("circle is not nil") +} + + +// +// MARK: Enums +// + + +// Los enums pueden ser opcionalmente de un tipo específico o de su propio tipo +// Al igual que las clases, pueden contener métodos + +enum Suit { + case Spades, Hearts, Diamonds, Clubs + func getIcon() -> String { + switch self { + case .Spades: return "♤" + case .Hearts: return "♡" + case .Diamonds: return "♢" + case .Clubs: return "♧" + } + } +} + +// Los valores de enum permite la sintaxis corta, sin necesidad de poner +// el tipo del enum cuando la variable es declarada de manera explícita +var suitValue: Suit = .Hearts + +// Enums de tipo no-entero requiere asignaciones de valores crudas directas +enum BookName: String { + case John = "John" + case Luke = "Luke" +} +print("Name: \(BookName.John.rawValue)") + +// Enum con valores asociados +enum Furniture { + // Asociación con Int + case Desk(height: Int) + // Asociación con String e Int + case Chair(String, Int) + + func description() -> String { + switch self { + case .Desk(let height): + return "Desk with \(height) cm" + case .Chair(let brand, let height): + return "Chair of \(brand) with \(height) cm" + } + } +} + +var desk: Furniture = .Desk(height: 80) +print(desk.description()) // "Desk with 80 cm" +var chair = Furniture.Chair("Foo", 40) +print(chair.description()) // "Chair of Foo with 40 cm" + + +// +// MARK: Protocolos +// + +// `protocol` puede requerir que los tipos tengan propiedades +// de instancia específicas, métodos de instancia, métodos de tipo, +// operadores, y subscripts + + +protocol ShapeGenerator { + var enabled: Bool { get set } + func buildShape() -> Shape +} + +// Protocolos declarados con @objc permiten funciones opcionales, +// que te permite evaluar conformidad +@objc protocol TransformShape { + optional func reshaped() + optional func canReshape() -> Bool +} + +class MyShape: Rect { + var delegate: TransformShape? + + func grow() { + sideLength += 2 + + // Pon un signo de interrogación después de la propiedad opcional, + // método, o subscript para ignorar un valor nil y devolver nil + // en lugar de tirar un error de tiempo de ejecución + // ("optional chaining") + if let allow = self.delegate?.canReshape?() { + // test for delegate then for method + self.delegate?.reshaped?() + } + } +} + + +// +// MARK: Otros +// + +// `extension`: Agrega funcionalidades a tipos existentes + +// Square ahora se "conforma" al protocolo `Printable` +extension Square: Printable { + var description: String { + return "Area: \(self.getArea()) - ID: \(self.identifier)" + } +} + +print("Square: \(mySquare)") + +// También puedes hacer extend a tipos prefabricados (built-in) +extension Int { + var customProperty: String { + return "This is \(self)" + } + + func multiplyBy(num: Int) -> Int { + return num * self + } +} + +print(7.customProperty) // "This is 7" +print(14.multiplyBy(3)) // 42 + +// Generics: Similar Java y C#. Utiliza la palabra clave `where` para +// especificar los requerimientos de los genéricos. + +func findIndex<T: Equatable>(array: [T], valueToFind: T) -> Int? { + for (index, value) in enumerate(array) { + if value == valueToFind { + return index + } + } + return nil +} +let foundAtIndex = findIndex([1, 2, 3, 4], 3) +print(foundAtIndex == 2) // true + +// Operadores: +// Operadores personalizados puede empezar con los siguientes caracteres: +// / = - + * % < > ! & | ^ . ~ +// o +// Caracteres unicode: math, symbol, arrow, dingbat, y line/box. +prefix operator !!! {} + +// Un operador prefix que triplica la longitud del lado cuando es utilizado +prefix func !!! (inout shape: Square) -> Square { + shape.sideLength *= 3 + return shape +} + +// Valor actual +print(mySquare.sideLength) // 4 + +// Cambiar la longitud del lado utilizando el operador !!!, +// incrementa el tamaño por 3 +!!!mySquare +print(mySquare.sideLength) // 12 +``` diff --git a/es-es/typescript-es.html.markdown b/es-es/typescript-es.html.markdown new file mode 100644 index 00000000..c42da4a4 --- /dev/null +++ b/es-es/typescript-es.html.markdown @@ -0,0 +1,172 @@ +--- +language: TypeScript +contributors: + - ["Philippe Vlérick", "https://github.com/pvlerick"] +filename: learntypescript-es.ts +translators: + - ["Damaso Sanoja", "https://github.com/damasosanoja"] +lang: es-es +--- + +TypeScript es un lenguaje cuyo objetivo es facilitar el desarrollo de aplicaciones a gran escala escritas en JavaScript. +TypeScript añade conceptos comunes como clases, módulos, interfaces, genéricos y (opcionalmente) tipeo estático a JavaScript. +Es un superset de JavaScript: todo el código JavaScript es código válido en TypeScript de manera que se puede integrar fácilmente a cualquier proyecto . El compilador TypeScript emite JavaScript. + +Este artículo se enfocará solo en la sintáxis extra de TypeScript, y no en [JavaScript] (../javascript/). + +Para probar el compilador de TypeScript, diríjase al [Área de Pruebas] (http://www.typescriptlang.org/Playground) donde podrá tipear código, y ver como se auto-completa al tiempo que ve el código emitido JavaScript. + +```js +// Existen 3 tipos básicos en TypeScript +var isDone: boolean = false; +var lines: number = 42; +var name: string = "Anders"; + +// Cuando es imposible de saber, tenemos el tipo "Any" +var notSure: any = 4; +notSure = "maybe a string instead"; +notSure = false; // okey, definitivamente un boolean + +// Para colecciones, hay matrices de tipos y matrices genéricas +var list: number[] = [1, 2, 3]; +// Alternativamente, usando la matriz genérica +var list: Array<number> = [1, 2, 3]; + +// Para enumeradores: +enum Color {Red, Green, Blue}; +var c: Color = Color.Green; + +// Finalmente, "void" es usado para el caso especial de una función que no retorna nada +function bigHorribleAlert(): void { + alert("I'm a little annoying box!"); +} + +// Las funciones son ciudadanos de primera clase, soportan la sintáxis lambda "fat arrow" y +// usan el tipo inferencia + +// Lo siguiente es equivalante, la misma firma será inferida por el +// compilador, y el mismo JavaScript será emitido +var f1 = function(i: number): number { return i * i; } +// Retorna tipo inferido +var f2 = function(i: number) { return i * i; } +var f3 = (i: number): number => { return i * i; } +// Retorna tipo inferido +var f4 = (i: number) => { return i * i; } +// Retorna tipo inferido, one-liner significa que no es necesario que regresen palabras claves +var f5 = (i: number) => i * i; + +// Las interfaces son estructurales, todo lo que tenga las propiedades cumple con +// la interfase +interface Person { + name: string; + // Propiedades opcionales, marcadas con un "?" + age?: number; + // Y por supuesto funciones + move(): void; +} + +// Objeto que implementa la interfase "Persona" +// Puede ser tratada como Persona ya que posee las propiedades name y move +var p: Persona = { name: "Bobby", move: () => {} }; +// Objetos que tienen propiedades opcionales: +var validPersona: Persona = { name: "Bobby", age: 42, move: () => {} }; +// No es una persona porque su edad no es un número +var invalidPersona: Persona = { name: "Bobby", age: true }; + +// Las interfases también pueden describir un tipo de función +interface SearchFunc { + (source: string, subString: string): boolean; +} +// Solo los tipos de parámetros son importantes, los nombres no son importantes. +var mySearch: SearchFunc; +mySearch = function(src: string, sub: string) { + return src.search(sub) != -1; +} + +// Clases - los miembros son públicos por defecto +class Point { + // Properties + x: number; + + // Constructor - las palabras clave public/private en este contexto generarán + // un código boiler plate para la propiedad y la inicialización en el + // constructor. + // En este ejemplo, "y" debe ser definida al igual que "x" lo es, pero con menos código + // También son soportados valores por defecto + + constructor(x: number, public y: number = 0) { + this.x = x; + } + + // Funciones + dist() { return Math.sqrt(this.x * this.x + this.y * this.y); } + + // Miembros estáticos + static origin = new Point(0, 0); +} + +var p1 = new Point(10 ,20); +var p2 = new Point(25); //y será 0 + +// Herencia +class Point3D extends Point { + constructor(x: number, y: number, public z: number = 0) { + super(x, y); // Un llamado explícito al constructor de la super clase es indispensable + } + + // Sobrescribir + dist() { + var d = super.dist(); + return Math.sqrt(d * d + this.z * this.z); + } +} + +// Módulos, los "." pueden ser usados como separadores para los submódulos +module Geometry { + export class Square { + constructor(public sideLength: number = 0) { + } + area() { + return Math.pow(this.sideLength, 2); + } + } +} + +var s1 = new Geometry.Square(5); + +// Un alias local para referirse a un módulo +import G = Geometry; + +var s2 = new G.Square(10); + +// Genéricos +// Clases +class Tuple<T1, T2> { + constructor(public item1: T1, public item2: T2) { + } +} + +// Interfases +interface Pair<T> { + item1: T; + item2: T; +} + +// Y funciones +var pairToTuple = function<T>(p: Pair<T>) { + return new Tuple(p.item1, p.item2); +}; + +var tuple = pairToTuple({ item1:"hello", item2:"world"}); + +// Incluyendo referencias a un archivo de definición: +/// <reference path="jquery.d.ts" /> + +``` + +## Para mayor información + * [Sitio Oficial de TypeScript] (http://www.typescriptlang.org/) + * [Especificaciones del lenguaje TypeScript (pdf)] (http://go.microsoft.com/fwlink/?LinkId=267238) + * [Anders Hejlsberg - Introduciendo TypeScript en Canal 9] (http://channel9.msdn.com/posts/Anders-Hejlsberg-Introducing-TypeScript) + * [Código fuente en GitHub] (https://github.com/Microsoft/TypeScript) + * [Definitely Typed - repositorio para definiciones de tipo] (http://definitelytyped.org/) diff --git a/es-es/yaml-es.html.markdown b/es-es/yaml-es.html.markdown index a5157b5d..cd3143fb 100644 --- a/es-es/yaml-es.html.markdown +++ b/es-es/yaml-es.html.markdown @@ -4,6 +4,7 @@ lang: es-es filename: learnyaml-es.yaml contributors: - ["Adam Brenecki", "https://github.com/adambrenecki"] + - ["Everardo Medina","https://github.com/everblut"] translators: - ["Daniel Zendejas","https://github.com/DanielZendejas"] --- @@ -14,7 +15,7 @@ leído y escrito por humanos. Basa su funcionalidad en JSON, con la adición de líneas nuevas e indentación inspirada en Python. A diferencia de Python, YAML -no permite tabs literales. +no permite tabulaciones literales. ```yaml # Los comentarios en YAML se ven así. @@ -38,97 +39,177 @@ llave con espacios: valor llave: "Un string, entre comillas." "Las llaves tambien pueden estar entre comillas.": "valor entre comillas" -# Los strings de líneas múltiples pueden ser escritos +# Los strings de líneas múltiples pueden ser escritos # como un 'bloque literal' (usando pipes |) # o como un 'bloque doblado' (usando >) bloque_literal: | Este bloque completo de texto será preservado como el valor de la llave 'bloque_literal', incluyendo los saltos de línea. - - Se continúa guardando la literal hasta que se cese la indentación. + + Se continúa guardando la literal hasta que se cese la indentación. Cualquier línea que tenga más indentación, mantendrá los espacios dados (por ejemplo, estas líneas se guardarán con cuatro espacios) -nloque_doblado: > +bloque_doblado: > De la misma forma que el valor de 'bloque_literal', todas estas líneas se guardarán como una sola literal, pero en esta ocasión todos los saltos de línea serán reemplazados por espacio. - Las líneas en blanco, como la anterior, son convertidos a un salto de línea. + Las líneas en blanco, como la anterior, son convertidas a un salto de línea. Las líneas con mayor indentación guardan sus saltos de línea. Esta literal ocuparán dos líneas. -######################## -# TIPOS DE COLECCIONES # -######################## - -# La indentación se usa para anidar. +# La indentación se usa para anidar elementos un_mapa_indentado: llave: valor otra_llave: otro valor otro_mapa_indentado: llave_interna: valor_interno -# Las llaves de los mapas no deben ser strings necesariamente +# Las llaves de los mapas no requieren ser strings necesariamente 0.25: una llave numérica -# Las llaves también pueden ser objetos de multi línea, usando ? para indicar -# el inicio de una llave +# Las llaves también pueden ser objetos de multiples líneas, +# usando ? para indicar el inicio de una llave ? | Esto es una llave que tiene múltiples líneas : y este es su valor -# YAML tambien permite colecciones como llaves, pero muchos lenguajes de +######################## +# TIPOS DE COLECCIONES # +######################## + +# Las colecciones en YAML usan la indentación para delimitar el alcance +# y cada elemento de la colección inicia en su propia línea. +# YAML tambien permite colecciones como llaves, pero muchos lenguajes de # programación se quejarán. # Las secuencias (equivalentes a listas o arreglos) se ven así: -una_secuencia: - - Item 1 - - Item 2 - - 0.5 # las secuencias pueden tener distintos tipos en su contenido. - - Item 4 - - llave: valor - otra_llave: otro_valor +- Amarillo +- Verde +- Azul + +# Se puede usar una secuencia como valor para una llave. +secuencia: + - Elemento 1 + - Elemento 2 + - Elemento 3 + - Elemento 4 + +# Las secuencias pueden contener secuencias como elementos. +- [Uno, Dos, Tres] +- [Domingo, Lunes, Martes] +- [Luna, Marte, Tierra] + +# Las secuencias pueden tener distintos tipos en su contenido. +secuencia_combinada: + - texto + - 5 + - 0.6 + - llave: valor # se convierte en un json dentro de la secuencia - - Esta es una secuencia - ...dentro de otra secuencia -# Dado que todo JSON está incluído dentro de YAML, también puedes escribir -# mapas con la sintaxis de JSON y secuencias: -mapa_de_json: {"llave": "valor"} -secuencia_de_json: [3, 2, 1, "despegue"] +# Dado que todo JSON está incluído dentro de YAML, también puedes escribir +# mapas con la sintaxis de JSON y secuencias: +mapa_de_json_1: {"llave": "valor"} +mapa_de_json_2: + llave: valor + +# Las secuencias tambien se pueden escribir como un arreglo al estilo JSON +secuencia_de_json_1: [3, 2, 1, "despegue"] +secuencia_de_json_2: + - 3 + - 2 + - 1 + - "despegue" + +# YAML también soporta conjuntos usando el simbolo ? +# y se ven de la siguiente forma: +set: + ? item1 + ? item2 + ? item3 + +# Se puede usar el tag !!set +# Al igual que Python, los conjuntos sólo son mapas con valores nulos. +# El ejemplo de arriba es equivalente a: +set2: + item1: null + item2: null + item3: null ################################## # CARACTERÍSTICAS EXTRAS DE YAML # ################################## +# YAML usa tres guiones (---) para diferenciar entre directivas +# y contenido del documento. +# Por otra parte, tres puntos (...) se utilizan para indicar +# el final del documento en casos especiales. + # YAML tiene funciones útiles llamadas 'anchors' (anclas), que te permiten -# duplicar fácilmente contenido a lo largo de tu documento. En el ejemplo -# a continuación, ambas llaves tendrán el mismo valor: -contenido_anclado: &nombre_del_ancla Este string será el valor de las llaves -otra_ancla: *nombre_del_ancla - -# YAML también tiene tags, que puedes usar para declarar tipos explícitamente. -string_explícito: !!str 0.5 -# Algunos parseadores implementar tags específicas del lenguaje, como el +# duplicar fácilmente contenido a lo largo de tu documento. +# El ampersand indica la declaración del ancla, +declara_ancla: &texto texto de la llave +# el asterisco indica el uso de dicha ancla. +usa_ancla: *texto # tendrá el valor "texto de la llave" + +################ +# TAGS EN YAML # +################ + +# En YAML, los nodos que no tienen un tag obtienen su tipo +# según la aplicación que los use, al usar un tag +# se pueden declarar tipos explícitamente. +string_explicito: !!str 0.5 # !!str para declarar un string +integer_explicito: !!int 5 # !!int para declarar un integer +float_explicito: !!float 1.2 # !!float para declarar un float +conjunto_explicito: !!set # !!set para declarar un conjunto + ? Uno + ? Dos + ? Tres +mapa_ordenado_explicito: !!omap # !!omap para declarar un mapa ordenado +- Primero: 1 +- Segundo: 2 +- Tercero: 3 +- Cuarto: 4 + +# Tags para los numeros enteros +llave_canonica: 5222 +llave_decimal: +5222 +llave_octal: 010 +llave_hexadecimal: 0xC + +#Tags para los numeros flotantes +llave_canonica: 1.215e+3 +llave_exponencial: 12.3555e+02 +llave_fija: 12.15 +llave_negativa_infinita: -.inf +llave_numero_invalido: .NaN + +# Tags para las fechas y horas +llave_canonica: 2001-12-15T02:59:43.1Z +llave_iso8601: 2001-12-14t21:59:43.10-05:00 +llave_con_espacios: 2001-12-14 21:59:43.10 -5 +llave_fecha: 2002-12-14 + +# Además existen tags para +null: #valor nulo +booleans: [ true, false ] # Valores booleanos +string: '012345' # Valor en string + + +# Algunos parseadores implementan tags específicas del lenguaje, como el # que se muestra a continuación, encargado de manejar números complejos en # Python: numero_complejo_python: !!python/complex 1+2j -######################## -# TIPOS EXTRAS EN YAML # -######################## - -# Stirngs y números no son los únicos escalares que YAML puede entener. -# YAML también puede parsear fechas en formato ISO . -fechaHora: 2001-12-15T02:59:43.1Z -fechaHora_con_espacios: 2001-12-14 21:59:43.10 -5 -fecha: 2002-12-14 - -# La tag !!binary indica que un string es, en realidad, un blob +# El tag !!binary indica que un string es en realidad un blob # representado en base-64. archivo_gif: !!binary | R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5 @@ -136,16 +217,10 @@ archivo_gif: !!binary | +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs= -# YAML también tiene un tipo set, que se ve de la siguiente forma: -set: - ? item1 - ? item2 - ? item3 - -# Al igual que Python, los sets sólo son mapas con valores nulos. -# El ejemplo de arriba es equivalente a: -set2: - item1: null - item2: null - item3: null ``` + +### Recursos adicionales + ++ [Sitio oficial de YAML](http://yaml.org/) ++ [Parser en línea de de YAML](http://yaml-online-parser.appspot.com/) ++ [Validador en línea de YAML](http://codebeautify.org/yaml-validator) |