diff options
Diffstat (limited to 'es-es')
-rw-r--r-- | es-es/c-es.html.markdown | 425 | ||||
-rw-r--r-- | es-es/elisp-es.html.markdown | 378 | ||||
-rw-r--r-- | es-es/java-es.html.markdown | 410 | ||||
-rw-r--r-- | es-es/python-es.html.markdown | 490 | ||||
-rw-r--r-- | es-es/ruby-es.html.markdown | 377 |
5 files changed, 2080 insertions, 0 deletions
diff --git a/es-es/c-es.html.markdown b/es-es/c-es.html.markdown new file mode 100644 index 00000000..b109f761 --- /dev/null +++ b/es-es/c-es.html.markdown @@ -0,0 +1,425 @@ +--- +language: c +filename: learnc-es.c +contributors: + - ["Adam Bard", "http://adambard.com/"] +translators: + - ["Francisco García", "http://flaskbreaker.tumblr.com/"] +lang: es-es +--- + +¡Ah!, C. Aun hoy en día sigue siendo el lenguaje por excelencia de la +computación moderna de alto rendimiento. + +C es el lenguaje de más bajo nivel que la mayoría de los programadores +llegarán a usar, pero lo compensa de sobra con pura velocidad. Solo +ten en cuenta el manejo manual de memoria y te llevará tan lejos como +necesites. + +```c +// Los comentarios de una sola línea comienzan con // + +/* +Los comentarios multilínea tienen este aspecto. +*/ + +// Importa cabeceras con #include +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +// Declara por adelantado las armaduras de las funciones en un archivo .h, +// o al principio de tu archivo .c . +void function_1(); +void function_2(); + +// El punto de entrada de tu programa es una función llamada main con +// retorno de tipo entero (integer). +int main() { + +// Muestra la salida usando printf, para el "formato print" +// %d es un entero, \n es una nueva línea +printf("%d\n", 0); // => Muestra 0 +// Todas las sentencias deben terminar con un punto y coma. + +/////////////////////////////////////// +// Tipos +/////////////////////////////////////// + +// Tienes que declarar una variable antes de usarla. La declaración de una +// variable necesites que especifiques su tipo; el tipo de una variable +// determina su tamaño en bytes. + +// 'ints' (enteros) son normalmente de 4 bytes +int x_int = 0; + +// 'shorts' son normalmente de 2 bytes +short x_short = 0; + +// 'chars' son fijo de 1 byte +char x_char = 0; +char y_char = 'y'; // Los caracteres literales se entrecomillan con '' + +// 'longs' son a menudo de 4 a 8 bytes; 'long longs' son fijo de por lo +// menos 64 bits +long x_long = 0; +long long x_long_long = 0; + +// 'floats' son normalmente números de coma flotante de 32 bits +float x_float = 0.0; + +// 'doubles' son normalmente números de coma flotante de 64 bits +double x_double = 0.0; + +// Todos los tipos enteros pueden ser 'unsigned'. Esto significa que no +// pueden ser negativos, pero el valor máximo de una variable 'unsigned' +// es mayor que el de una no 'unsigned' del mismo tamaño. +unsigned char ux_char; +unsigned short ux_short; +unsigned int ux_int; +unsigned long long ux_long_long; + +// Todos menos 'char', que es siempre de 1 byte, varían el tamaño +// dependiendo de tu máquina. sizeof(T) te dice el tamaño de una variable +// de tipo T en bytes por lo que podemos expresar el tamaño de estos tipos +// portatilmente. +// Por ejemplo, +printf("%lu\n", sizeof(int)); // => 4 (en máquinas con 'words' de 4 bytes) + +// Los arrays deben ser inicializados con un tamaño concreto. +char my_char_array[20]; // Este array ocupa 1 * 20 = 20 bytes +int my_int_array[20]; // Este array ocupa 4 * 20 = 80 bytes + // (suponiendo que tenemos 'words' de 4-byte) + + +// Puedes inicializar un array a 0 así: +char my_array[20] = {0}; + +// Indexar un array es como en otros lenguajes -o, más bien, otros +// lenguajes son como C- +my_array[0]; // => 0 + +// Los arrays varían; ¡son sólo memoria! +my_array[1] = 2; +printf("%d\n", my_array[1]); // => 2 + +// Las cadenas (strings) son sólo arrays de 'chars' (caracteres) +// terminados en un byte NUL (0x00), representado en las cadenas como el +// carácter especial '\0'. +// (No tenemos porqué añadir el byte nulo en cadenas literales; el +// compilador lo añade al final por nosotros.) +char a_string[20] = "Esto es una cadena"; +printf("%s\n", a_string); // %s se sutituye por una cadena. + +/* +Te habrás dado cuenta de que a_string es solo de 18 caracteres. +El 'char' #19 es el byte nulo. +El 'char' #20 es de valor indefinido. +*/ + +printf("%d\n", a_string[18]); // => 0 + +/////////////////////////////////////// +// Operadores +/////////////////////////////////////// + +int i1 = 1, i2 = 2; // Forma corta de declaración múltiple +float f1 = 1.0, f2 = 2.0; + +// La aritmética es sencilla +i1 + i2; // => 3 +i2 - i1; // => 1 +i2 * i1; // => 2 +i1 / i2; // => 0 (0.5, pero es truncado tras el 0) + +f1 / f2; // => 0.5, más o menos épsilon +// Módulo está también +11 % 3; // => 2 + +// Los operadores de comparación te resultaran familiares, pero no hay +// booleanos en C. Usamos enteros (ints) en su lugar. 0 es falso, +// cualquier otra cosa es verdadero. (Los operadores de comparación +// siempre devuelven 0 o 1) +3 == 2; // => 0 (Falso) +3 != 2; // => 1 (Verdadero) +3 > 2; // => 1 +3 < 2; // => 0 +2 <= 2; // => 1 +2 >= 2; // => 1 + +// La lógica funiona en enteros +!3; // => 0 (not lógico) +!0; // => 1 +1 && 1; // => 1 (and lógico) +0 && 1; // => 0 +0 || 1; // => 1 (or lógico) +0 || 0; // => 0 + +// ¡Operadores de bits! +~0x0F; // => 0xF0 (Negación) +0x0F & 0xF0; // => 0x00 (AND) +0x0F | 0xF0; // => 0xFF (OR) +0x04 ^ 0x0F; // => 0x0B (XOR) +0x01 << 1; // => 0x02 (desplazar hacia la izquierda (por 1)) +0x02 >> 1; // => 0x01 (desplazar hacia la derecha (por 1)) + +/////////////////////////////////////// +// Estructuras de Control +/////////////////////////////////////// + +if (0) { + printf("Yo nunca ocurro\n"); +} else if (0) { + printf("Yo tampoco ocurro nunca\n"); +} else { + printf("Yo me muestro\n"); +} + +// Mientras el bucle exista +int ii = 0; +while (ii < 10) { + printf("%d, ", ii++); // ii++ incrementa ii en uno, después de usar su valor. +} // => muestra "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, " + +printf("\n"); + +int kk = 0; +do { + printf("%d, ", kk); +} while (++kk < 10); // ++kk incrementa kk en uno, antes de usar su valor. +// => muestra "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, " + +printf("\n"); + +// Bucles 'for' también +int jj; +for (jj=0; jj < 10; jj++) { + printf("%d, ", jj); +} // => muestra "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, " + +printf("\n"); + +/////////////////////////////////////// +// Cambios de Tipo +/////////////////////////////////////// + +// Cada valor en C tiene un tipo, pero tu puedes ingresar un valor en +// otro tipo si quieres. + +int x_hex = 0x01; // Puedes asignar hexadecimales a variables + +// El cambio de tipos intentará mantener sus valores numéricos +printf("%d\n", x_hex); // => Muestra 1 +printf("%d\n", (short) x_hex); // => Muestra 1 +printf("%d\n", (char) x_hex); // => Muestra 1 + +// Los tipos se desbordan sin aviso +printf("%d\n", (char) 257); // => 1 (El valor máximo de un 'char' es 255) + +// Los tipos enteros puden cambiarse a tipos de coma flotante, y viceversa +printf("%f\n", (float)100); // %f se sustituye por un 'float' +printf("%lf\n", (double)100); // %lf se sustituye por un 'double' +printf("%d\n", (char)100.0); + +/////////////////////////////////////// +// Punteros +/////////////////////////////////////// + +// Un puntero es una variable declarada para almacenar una dirección de +// memoria. Su declaración además nos dirá el tipo de dato al que apunta. +// Puedes obtener la dirección de memoria de tus variables, y después +// enlazarlas con ellos. + +int x = 0; +printf("%p\n", &x); // Usa & para obtener la dirección de una variable. +// (%p se sustituye por un puntero) +// => Muestra alguna dirección de memoria; + +// Los tipos de puntero terminan con * en su declaración +int* px; // px es un puntero a un 'int' +px = &x; // Almacena la dirección de x en px +printf("%p\n", px); // => Muestra alguna dirección de memoria + +// Para obtener el valor de la dirección a la que apunta un puntero, pon +// * delante para desreferenciarle. +printf("%d\n", *px); // => Muestra 0, el valor de x y de la dirección a la + // que apunta px + +// También puedes cambiar el valor al que está apuntando el puntero. +// Tenemos que meter la desreferencia entre paréntesis porque ++ tiene +// prioridad frente a *. +(*px)++; // Incrementa el valor al que apunta px en 1 +printf("%d\n", *px); // => Muestra 1 +printf("%d\n", x); // => Muestra 1 + +int x_array[20]; // Los arrays son una buena manera de distribuir bloques +int xx; // continuos de memoria. +for (xx=0; xx<20; xx++) { + x_array[xx] = 20 - xx; +} // Inicializa x_array a 20, 19, 18,... 2, 1 + +// Declara un puntero de tipo 'int' y lo inicializa para apuntar a x_array +int* x_ptr = x_array; +// x_ptr ahira apunta al primer elemento del 'array' (el entero 20). +// Esto funciona porque las 'arrays' actualmente son solo punteros a su +// primer elemento. + +// Los 'arrays' son punteros a su primer elemento. +printf("%d\n", *(x_ptr)); // => Muestra 20 +printf("%d\n", x_array[0]); // => Muestra 20 + +// Los punteros aumentan y disminuyen en función de su tipo. +printf("%d\n", *(x_ptr + 1)); // => Muestra 19 +printf("%d\n", x_array[1]); // => Muestra 19 + +// Puedes también asigner dinamicamente bloques contiguos de memoria con +// la función malloc de la librería estándard, que toma un entero como +// argumento representando el número de bytes a asignar de la pila. +int* my_ptr = (int*) malloc(sizeof(int) * 20); +for (xx=0; xx<20; xx++) { + *(my_ptr + xx) = 20 - xx; // my_ptr[xx] = 20-xx funcionaría también aquí +} // Inicializa la memoria a 20, 19, 18, 17... 2, 1 (como 'ints') + +// Desreferenciando la memoria que no has asignado te dará resultados +// impredecibles +printf("%d\n", *(my_ptr + 21)); // => Prints who-knows-what? + +// Cuando hallas acabado con el bloque de memoría malloc, necesitas +// liberarlo o sino nadie más podrá usarlo hasta que tu programa se cierre +free(my_ptr); + +// Las cadenas pueden ser 'arrays' de chars, pero normalmente se +// representan con punteros 'char': +char* my_str = "This is my very own string"; + +printf("%c\n", *my_str); // => 'T' + +function_1(); +} // fin de la función main + +/////////////////////////////////////// +// Funciones +/////////////////////////////////////// + +// Sintexis de la declaración de funciones: +// <tipo de retorno> <nombre>(<argumentos>) + +int add_two_ints(int x1, int x2){ + return x1 + x2; // Usa 'return' para dar una salida +} + +/* +Las funciones son de paso por valor, pero puedes hacer tus propias +referencias con punteros de manera que las funciones puedan cambiar sus +valores. + +Ejemplo: invertidor de cadenas in-situ +*/ + +// Una función 'void' no retorna valor +void str_reverse(char* str_in){ + char tmp; + int ii=0, len = strlen(str_in); // Strlen es parte de la librería + for(ii=0; ii<len/2; ii++){ // estándard + tmp = str_in[ii]; + str_in[ii] = str_in[len - ii - 1]; // ii-th último 'char' + str_in[len - ii - 1] = tmp; + } +} + +/* +char c[] = "Esto es una prueba."; +str_reverse(c); +printf("%s\n", c); // => ".abeurp anu se otsE" +*/ + +/////////////////////////////////////// +// Definición de tipos y estructuras +/////////////////////////////////////// + +// Los 'Typedefs' pueden ser utilizados para crear alias de tipos. +typedef int my_type; +my_type my_type_var = 0; + +// Las estructuras son sólo grupos de datos. +struct rectangle { + int width; + int height; +}; + + +void function_1(){ + + struct rectangle my_rec; + + // Utiliza los miembros de una estructura con . + my_rec.width = 10; + my_rec.height = 20; + + // Puedes declarar punteros a estructuras + struct rectangle* my_rec_ptr = &my_rec; + + // Usa la desreferencia para modificar sus miembros... + (*my_rec_ptr).width = 30; + + // ... o usa la abreviatura -> + my_rec_ptr->height = 10; // Lo mismo que (*my_rec_ptr).height = 10; +} + +// Puedes aplicar un 'typedef' a una estructura por conveniencía. +typedef struct rectangle rect; + +int area(rect r){ + return r.width * r.height; +} + +/////////////////////////////////////// +// Punteros a Funciones +/////////////////////////////////////// +/* +En tiempo de ejecución, las funciones se localizan en unas direcciones de +memoria concretas. Los punteros a funciones son como cualquier otro +puntero (almacenan una dirección de memoria), pero pueden ser usados para +utilizar funciones directamente, o para pasar 'handlers' (o funciones +'callback') por todos lados. +Sin embargo, la sintaxis de definición parecera confusa al principio. + +Ejemplo: usar str_reverse desde un puntero +*/ +void str_reverse_through_pointer(char * str_in) { + // Define un puntero a una función, llamado f. + void (*f)(char *); + // La armadura debe coincidir exactamente con al función objetivo. + + // Assigna la dirección de la función (determinado en tiempo de ejecuión) + f = &str_reverse; + + // Llamando la función desde el puntero + (*f)(str_in); + + // Esta es una alternativa para llamarla pero con una sintaxis igual de válida. + // f(str_in); +} + +/* +Tanto tiempo como las armaduras de las funciones coincidan, podrás asignar +cualquier función al mismo puntero. +Los punteros a funciones son normalmente envueltos en 'typedef' para +simplificar su legibilidad, como sigue: +*/ + +typedef void (*my_fnp_type)(char *); + +// Es usado para declarar la variable puntero actual: +// ... +// my_fnp_type f; + +``` + +## 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) + +Otro buen recurso es [Learn C the hard way](http://c.learncodethehardway.org/book/) + +Aparte de eso, Google es tu amigo. diff --git a/es-es/elisp-es.html.markdown b/es-es/elisp-es.html.markdown new file mode 100644 index 00000000..a6cd3934 --- /dev/null +++ b/es-es/elisp-es.html.markdown @@ -0,0 +1,378 @@ +--- +language: elisp +contributors: + - ["Bastien Guerry", "http://bzg.fr"] +translators: + - ["Guillermo Vayá", "http://willyfrog.es"] +lang: es-es +filename: learn-emacs-lisp-es.el +--- + +```scheme +;; Introduccion a Emacs Lisp en 15 minutos (v0.2d) +;; +;; Autor: Bastien / @bzg2 / http://bzg.fr +;; Traducción: Guillermo Vayá / @Driadan / http://willyfrog.es +;; +;; Antes de nada, lee este texto de Peter Norvig: +;; Traducido: http://loro.sourceforge.net/notes/21-dias.html +;; Original: http://norvig.com/21-days.html +;; +;; Ahora instala GNU Emacs 24.3: +;; +;; Debian: apt-get install emacs +;; (o sigue las instrucciones de tu distribución preferida) +;; OSX: http://emacsformacosx.com/emacs-builds/Emacs-24.3-universal-10.6.8.dmg +;; Windows: http://ftp.gnu.org/gnu/windows/emacs/emacs-24.3-bin-i386.zip +;; +;; Puedes encontrar información general sobre Emacs en: +;; http://www.gnu.org/software/emacs/#Obtaining + +;; Aviso importante: +;; +;; Seguir este tutorial no provocará daños en tu ordenador a menos que +;; te enfades tanto que que acabes tirándolo al suelo. En tal caso +;; declino cualquier responsabilidad. ¡A divertirse! + + +;; "N. del. T.": Algunos términos comunes de la informática se han dejado +;; sin traducir ya que es mucho más probable que el lector los conozca en +;; su forma en inglés, siendo la versión en español de muy raro uso. +;; Además "sexps" se ha decidido traducir por sexpresión. +;; Por último, añadir que no se han traducido los ejemplos de código ya que no +;; es necesario entender qué dice el string para comprender el funcionamiento +;; y podría llevar a error. + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Inicia Emacs. +;; +;; Pulsa la tecla `q' para pasar el mensaje de bienvenida. +;; +;; Mira a la línea gris en la parte inferior de la ventana: +;; +;; "*scratch*" es el nombre del espacio editable donde estás. +;; A este espacio editable se le llama "buffer". +;; +;; Scratch es el buffer por defecto cuando abres Emacs. +;; En Emacs nunca editas ficheros, sino que editas buffers que +;; posteriormente pueden grabarse a un fichero. +;; can save to a file. +;; +;; "Lisp interaction" indica el conjunto de ordenes disponibles. +;; +;; Emacs dispone de un set de comandos disponibles en cualquier buffer +;; ("built-ins") y aparte varios conjuntos de ordenes disponibles +;; según el modo específico que esté activo. En nuestro caso +;; estamos usando `lisp-interaction-mode', el cual incluye las +;; ordenes necesarias para evaluar y navegar código Elisp. + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Un punto y coma comienza un comentario. Pueden ponerse en cualquier +;; posicion de la linea. +;; +;; Los programas en Elisp se componen de expresiones simbólicas +;; tambien llamadas "sexps": +(+ 2 2) + +;; Esta expresión simbólica se lee tal que "Suma 2 y 2" + +;; Las sexpresiones se rodean por paréntesis, y pueden anidarse: +(+ 2 (+ 1 1)) + +;; Una expresion simbólica está formada bien por átomos o bien por otras +;; expresiones simbólicas. En el ejemplo de arriba, 1 y 2 son átomos, +;; mientras que (+ 2 (+ 1 1)) y (+ 1 1) son expresiones simbólicas. + +;; Gracias a `lisp-interaction-mode' puedes evaluar las sexpresiones. +;; Coloca el cursor justo despues del paréntesis de cierre y +;; mantén pulsada la tecla Control y la j (para abreviar usaremos "C-j"). + +(+ 3 (+ 1 2)) +;; ^ pon aquí el cursor +;; `C-j' => 6 + +;; `C-j' añade el resultado de la evaluación al buffer. + +;; `C-xC-e' muestra el mismo resultado pero en la linea inferior +;; la cual se llama "minibuffer". Este será el metodo que usaremos +;; normalmente para no llenar el buffer con texto inútil. + +;; `setq' guarda un valor en una variable: +(setq my-name "Bastien") +;; `C-xC-e' => "Bastien" (aparece en el mini-buffer) + +;; `insert' añade "Hello!" en el punto donde esté tu cursor: +(insert "Hello!") +;; `C-xC-e' => "Hello!" + +;; Aunque hemos usado `insert' con solo un parámetro "Hello!", se +;; pueden pasar más. Por ejemplo, en esta otra sexpresión usamos dos: + +(insert "Hello" " world!") +;; `C-xC-e' => "Hello world!" + +;; Se pueden usar variables en lugar de strings: +(insert "Hello, I am " my-name) +;; `C-xC-e' => "Hello, I am Bastien" + +;; Puedes combinar sexpresiones en funciones: +(defun hello () (insert "Hello, I am " my-name)) +;; `C-xC-e' => hello + +;; Evaluemos la funcion: +(hello) +;; `C-xC-e' => Hello, I am Bastien + +;; Los parentesis vacios en la definicion de una funcion indican +;; que no acepta parámetros. En cualquier caso, usar `my-name' siempre +;; es aburrido, asi que vamos a hacer que la función accepte un parámetro +;; (en este caso el parametro se llama "name"): +(defun hello (name) (insert "Hello " name)) +;; `C-xC-e' => hello + +;; Ahora vamos a llamar a la funcion con el string "you" como valor para +;; el único parámetro que posee. +(hello "you") +;; `C-xC-e' => "Hello you" + +;; ¡Genial! + +;; Descansa un poco y respira. + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Ahora cambiaremos al nuevo buffer, llamado "*test*", en una nueva ventana. + +(switch-to-buffer-other-window "*test*") +;; `C-xC-e' +;; => [La pantalla ahora tiene dos ventanas y el cursor está en el buffer *test*] + +;; Mueve el ratón sobre la ventana superior y pulsa el boton izdo. para volver. +;; Otra forma es usando `C-xo' (pulsa simultaneamente control y x y luego la o) +;; para ir a la otra ventana. + +;; Se pueden combinar varias sexpresiones mediante `progn': +(progn + (switch-to-buffer-other-window "*test*") + (hello "you")) +;; `C-xC-e' +;; => [De las dos ventanas de la pantalla, el cursor está en la marcada como *test*] + +;; A partir de ahora, si no te importa, dejaremos de decir que pulses `C-xC-e': +;; tendrás que hacerlo para ejecutar cada sexpresión que siga. + +;; También tendrás que volver al buffer *scratch* bien con el ratón o con `C-xo'. + +;; En ocasiones será util limpiar el buffer: +(progn + (switch-to-buffer-other-window "*test*") + (erase-buffer) + (hello "there")) + +;; O volver a la ventana anterior: +(progn + (switch-to-buffer-other-window "*test*") + (erase-buffer) + (hello "you") + (other-window 1)) + +;; Puedes enlazar un valor a una variable local con `let': +(let ((local-name "you")) + (switch-to-buffer-other-window "*test*") + (erase-buffer) + (hello local-name) + (other-window 1)) + +;; En este caso, no hace falta añadir `progn' ya que `let' permite combinar +;; varias sexpresiones. + +;; Vamos a darle formato a un string: +(format "Hello %s!\n" "visitor") + +;; Cada %s indica la posicion donde irá un string, el cual será reemplazado +;; por "visitor". "\n" es el caracter de nueva línea. + +;; Mejoremos nuestra funcion usando `format': +(defun hello (name) + (insert (format "Hello %s!\n" name))) + +(hello "you") + +;; Creemos una nueva funcion que utililce `let': +(defun greeting (name) + (let ((your-name "Bastien")) + (insert (format "Hello %s!\n\nI am %s." + name ; the argument of the function + your-name ; the let-bound variable "Bastien" + )))) + +;; Y ahora la evaluamos: +(greeting "you") + +;; Algunas funciones son interactivas: +(read-from-minibuffer "Enter your name: ") + +;; Al evaluar esta función, ésta devuelve lo que hayas introducido. + +;; Ahora hagamos nuestra función `greeting' preguntar por tu nombre: +(defun greeting (from-name) + (let ((your-name (read-from-minibuffer "Enter your name: "))) + (insert (format "Hello!\n\nI am %s and you are %s." + from-name ; the argument of the function + your-name ; the let-bound var, entered at prompt + )))) + +(greeting "Bastien") + +;; Y ahora la completamos mostrando el resultado en la otra ventana: +(defun greeting (from-name) + (let ((your-name (read-from-minibuffer "Enter your name: "))) + (switch-to-buffer-other-window "*test*") + (erase-buffer) + (insert (format "Hello %s!\n\nI am %s." your-name from-name)) + (other-window 1))) + +;; Probémosla: +(greeting "Bastien") + +;; Descansa un poco y respira. + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Creemos una lista de nombres: +(setq list-of-names '("Sarah" "Chloe" "Mathilde")) + +;; Para coger el primer elemento de la lista usaremos `car': +(car list-of-names) + +;; Para coger todos menos el primer elemento de la lista +;; usaremos `cdr': +(cdr list-of-names) + +;; Para añadir un elemento al comienzo de la lista utilizamos `push': +(push "Stephanie" list-of-names) + +;; OJO: `car' y `cdr' no modifican la lista, mientras que `push' sí. +;; ¡Es una diferencia importante! Algunas funciones no tienen efectos +;; colaterales (como `car') mientras que otras sí (como `push'). +;; "N. del T.": estos efectos colaterales se les llama `side-effects' en +;; las distintas variantes de lisp. + +;; Llamemos a `hello' con cada elemento de `list-of-names': +(mapcar 'hello list-of-names) + +;; Retocamos `greeting' para que salude a todos los que estén en `list-of-names': +(defun greeting () + (switch-to-buffer-other-window "*test*") + (erase-buffer) + (mapcar 'hello list-of-names) + (other-window 1)) + +(greeting) + +;; ¿Te acuerdas de la función `hello' definida un poco más arriba? +;; Recibía un parámetro: `name'. Así que `mapcar' llama a `hello' con cada +;; elemento de `list-of-names' como parámetro de `hello'. + +;; Ahora ordenaremos un poco lo que tenemos en el buffer: + +(defun replace-hello-by-bonjour () + (switch-to-buffer-other-window "*test*") + (goto-char (point-min)) + (while (search-forward "Hello") + (replace-match "Bonjour")) + (other-window 1)) + +;; (goto-char (point-min)) mueve el cursor al principio del buffer. +;; (search-forward "Hello") busca un string "Hello". +;; (while x y) evalua la/s sexpresion/es y mientras que x devuelva +;; alguna cosa. +;; En el momento que x devuelva `nil' (es decir nada), sale del +;; bucle `while'. + +(replace-hello-by-bonjour) + +;; Observamos que todas las veces que teníamos la palabra "Hello" en el buffer *test* +;; han sido reemplazadas por "Bonjour". + +;; Y además, hemos obtenido un error: "Search failed: Hello". +;; +;; Para evitar este error, hay que decirle a `search-forward' si debería dejar de +;; buscar en el buffer en algún momento y si debería fallar sin quejarse cuando +;; no encuentra nada. + +;; (search-forward "Hello" nil t) justo hace eso: + +;; El argumento `nil' significa que la busqueda no está ligada a ninguna posición. +;; Y el argumento `t' le pide que no diga nada si no encuentra el string. + +;; Usaremos esta sexpresión en la función siguiente, la cual ya +;; no muestra ningún error: + +(defun hello-to-bonjour () + (switch-to-buffer-other-window "*test*") + (erase-buffer) + ;; Say hello to names in `list-of-names' + (mapcar 'hello list-of-names) + (goto-char (point-min)) + ;; Replace "Hello" by "Bonjour" + (while (search-forward "Hello" nil t) + (replace-match "Bonjour")) + (other-window 1)) + +(hello-to-bonjour) + +;; Añadamos algo de color a los nombres: + +(defun boldify-names () + (switch-to-buffer-other-window "*test*") + (goto-char (point-min)) + (while (re-search-forward "Bonjour \\(.+\\)!" nil t) + (add-text-properties (match-beginning 1) + (match-end 1) + (list 'face 'bold))) + (other-window 1)) + +;; Esta función nos presenta `re-search-forward': en vez de +;; buscar el string "Bonjour" exacto, se busca por un patrón +;; usando una "expresión regular" (lo cual se muestra abreviado +;; en el prefijo "re-" del inglés "Regular Expression"). + +;; La expresión regular a utilizar es "Bonjour \\(.+\\)!" y se traduce como: +;; el string "Bonjour ", seguido de +;; un grupo de | representado por \\( ... \\) +;; cualquier caracter | representado por . +;; al menos una vez | representado por + +;; y el string "!". + +;; ¿Preparado? ¡Probemoslo! + +(boldify-names) + +;; `add-text-properties' añade propiedades al texto, como una fuente. + +;; ¡Hale! ¡Ya lo tenemos! ¡Feliz hacking! + +;; Si quieres saber más sobre una función o una variable: +;; +;; C-h v la-variable RET +;; C-h f la-funcion RET +;; +;; Si quieres leer el manual de Emacs Lisp desde dentro de Emacs: +;; +;; C-h i m elisp RET +;; +;; Para leer una introducción en linea de Emacs Lisp: +;; https://www.gnu.org/software/emacs/manual/html_node/eintr/index.html + +;; Me gustaría agradecer a las siguientes personas su feedback y sugerencias: +;; - Wes Hardaker +;; - notbob +;; - Kevin Montuori +;; - Arne Babenhauserheide +;; - Alan Schmitt +;; - LinXitoW +;; - Aaron Meurer +``` diff --git a/es-es/java-es.html.markdown b/es-es/java-es.html.markdown new file mode 100644 index 00000000..b34dca8d --- /dev/null +++ b/es-es/java-es.html.markdown @@ -0,0 +1,410 @@ +--- +language: java +contributors: + - ["Jake Prather", "http://github.com/JakeHP"] +translators: + - ["Camilo Garrido", "http://www.twitter.com/hirohope"] +lang: es-es +filename: LearnJava-es.java +--- + +Java es un lenguage de programación de propósito general, concurrente, basado en clases y +orientado a objetos. +[Lee más aquí.](http://docs.oracle.com/javase/tutorial/java/index.html) + +```java +// Comentarios de una sóla línea comienzan con // +/* +Comentarios multilínea lucen así +*/ +/** +Comentarios JavaDoc lucen así. Suelen describir la clase o varios atributos +de una clase. +*/ + +// Importa la clase ArrayList dentro del paquete java.util +import java.util.ArrayList; +// Importa todas las clases dentro del paquete java.security +import java.security.*; + +// Cada archivo .java contiene una clase pública, con el mismo nombre del archivo. +public class AprendeJava { + + // Un programa debe tener un método 'main' como punto de entrada + public static void main (String[] args) { + + // Usa System.out.println para imprimir líneas + System.out.println("¡Hola mundo!"); + System.out.println( + "Entero (int): " + 10 + + " Doble (double): " + 3.14 + + " Booleano (boolean): " + true); + + // Para imprimir sin el salto de línea, usa System.out.print + System.out.print("Hola "); + System.out.print("Mundo"); + + + /////////////////////////////////////// + // Tipos & Variables + /////////////////////////////////////// + + // Declara una variable usando <tipo> <nombre> [ + // Byte - Entero complemento a dos con signo de 8-bit + // (-128 <= byte <= 127) + byte fooByte = 100; + + // Short - Entero complemento a dos con signo de 16-bit + // (-32,768 <= short <= 32,767) + short fooShort = 10000; + + // Integer - Entero complemento a dos con signo de 32-bit + // (-2,147,483,648 <= int <= 2,147,483,647) + int fooInt = 1; + + // Long - Entero complemento a dos con signo de 64-bit + // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807) + long fooLong = 100000L; + // L es usado para denotar que el valor de esta variable es del tipo Long; + // cualquier cosa sin ella es tratado como un entero por defecto. + + // Nota: Java no tiene tipos sin signo + + // Float - Número de coma flotante IEEE 754 de precisión simple de 32-bit + float fooFloat = 234.5f; + // f es usado para denotar qeu el valor de esta variable es del tipo float; + // de otra manera es tratado como un double. + + // Double - Número de coma flotante IEEE 754 de precisión doble de 64-bit + double fooDouble = 123.4; + + // Boolean - true & false + boolean fooBoolean = true; + boolean barBoolean = false; + + // Char - Un simple carácter unicode de 16-bit + char fooChar = 'A'; + + // Usa 'final' para hacer inmutable las variables + final int HORAS_QUE_TRABAJO_POR_SEMANA = 9001; + + // Strings + String fooString = "¡Mi String está aquí!"; + + // \n es un carácter escapado que inicia una nueva línea + String barString = "¿Imprimiendo en una nueva linea?\n¡Ningun problema!"; + // \t es un carácter escapado que añade un carácter tab + String bazString = "¿Quieres añadir un 'tab'?\t¡Ningun problema!"; + System.out.println(fooString); + System.out.println(barString); + System.out.println(bazString); + + // Arreglos + //El tamaño del arreglo debe decidirse en la declaración + //El formato para la declaración de un arreglo es la siguiente: + //<tipo_de_dato> [] <nombre_variable> = new <tipo_de_dato>[<tamaño_arreglo>]; + int [] arreglo_de_enteros = new int[10]; + String [] arreglo_de_strings = new String[1]; + boolean [] arreglo_de_booleanos = new boolean[100]; + + // Otra forma de declarar & inicializar un arreglo + int [] y = {9000, 1000, 1337}; + + // Indexación de un arreglo - Accediendo un elemento + System.out.println("arreglo_de_enteros @ 0: " + arreglo_de_enteros[0]); + + // Arreglos comienzan su indexación en cero y son mutables + arreglo_de_enteros[1] = 1; + System.out.println("arreglo_de_enteros @ 1: " + arreglo_de_enteros[1]); // => 1 + + // Otros para echar un vistazo + // ArrayLists - Son como arreglos excepto que ofrecen más funcionalidades + // y el tamaño es mutable + // LinkedLists + // Maps + // HashMaps + + /////////////////////////////////////// + // Operadores + /////////////////////////////////////// + System.out.println("\n->Operadores"); + + int i1 = 1, i2 = 2; // Abreviación para múltiples declaraciones + + // La aritmética es directa + System.out.println("1+2 = " + (i1 + i2)); // => 3 + System.out.println("2-1 = " + (i2 - i1)); // => 1 + System.out.println("2*1 = " + (i2 * i1)); // => 2 + System.out.println("1/2 = " + (i1 / i2)); // => 0 (0.5 truncado) + + // Módulo + System.out.println("11%3 = "+(11 % 3)); // => 2 + + // Operadores de comparación + System.out.println("3 == 2? " + (3 == 2)); // => false + System.out.println("3 != 2? " + (3 != 2)); // => true + System.out.println("3 > 2? " + (3 > 2)); // => true + System.out.println("3 < 2? " + (3 < 2)); // => false + System.out.println("2 <= 2? " + (2 <= 2)); // => true + System.out.println("2 >= 2? " + (2 >= 2)); // => true + + // ¡Operaciones a nivel de bits! + /* + ~ Complemento unario bit a bit + << Deplazamiento hacia la izquierda con signo + >> Deplazamiento hacia la derecha con signo + >>> Deplazamiento hacia la derecha sin signo + & AND lógico + ^ OR lógico exclusivo + | OR lógico inclusivo + */ + + // Incrementos + int i = 0; + System.out.println("\n->Incrementos y reducciones"); + System.out.println(i++); //i = 1. Post-incremento + System.out.println(++i); //i = 2. Pre-incremento + System.out.println(i--); //i = 1. Post-reducción + System.out.println(--i); //i = 0. Pre-reducción + + /////////////////////////////////////// + // Estructuras de Control + /////////////////////////////////////// + System.out.println("\n->Estructuras de Control"); + + // Condiciones 'if' son como en c + int j = 10; + if (j == 10){ + System.out.println("Me imprimieron"); + } else if (j > 10) { + System.out.println("A mi no"); + } else { + System.out.println("A mi tampoco"); + } + + // Ciclos 'while' + int fooWhile = 0; + while(fooWhile < 100) + { + //System.out.println(fooWhile); + //Incrementar el contador + //Iteró 99 veces, fooWhile 0->99 + fooWhile++; + } + System.out.println("Valor fooWhile: " + fooWhile); + + // Ciclos 'do while' + int fooDoWhile = 0; + do + { + //System.out.println(fooDoWhile); + //Incrementar el contador + //Iteró 99 veces, fooDoWhile 0->99 + fooDoWhile++; + }while(fooDoWhile < 100); + System.out.println("Valor fooDoWhile: " + fooDoWhile); + + // Ciclos 'for' + int fooFor; + //Estructura del ciclo 'for' => for(<declaración_de_inicio>; <condicional>; <paso>) + for(fooFor=0; fooFor<10; fooFor++){ + //System.out.println(fooFor); + //Iteró 10 veces, fooFor 0->9 + } + System.out.println("Valor fooFor: " + fooFor); + + // Switch Case + // Un 'switch' funciona con un tipo de dato byte, short, char e int + // También funciona con tipos enumerados (discutido en tipos Enum), + // la clase String y unas pocas clases especiales que envuelven + // tipos primitivos: Character, Byte, Short e Integer. + int mes = 3; + String mesString; + switch (mes){ + case 1: + mesString = "Enero"; + break; + case 2: + mesString = "Febrero"; + break; + case 3: + mesString = "Marzo"; + break; + default: + mesString = "Algun otro mes"; + break; + } + System.out.println("Resultado switch Case: " + mesString); + + + /////////////////////////////////////// + // Convirtiendo Tipos de Datos y Conversión de Tipos + /////////////////////////////////////// + + // Convirtiendo datos + + // Convertir String a Integer + Integer.parseInt("123");//retorna una versión entera de "123" + + // Convertir Integer a String + Integer.toString(123);//retorna una versión string de 123 + + // Para otras conversiones fíjate en las siguientes clases + // Double + // Long + // String + + // Conversión de tipos + // También puedes convertir objetos java, hay muchos detalles + // con unos pocos conceptos intermedios + // No dudes en verlos acá + // http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html + + + /////////////////////////////////////// + // Clases y Funciones + /////////////////////////////////////// + + System.out.println("\n->Clases & Funciones"); + + // (A continuación la definición de una clase Bicicleta) + + // Usa 'new' para instanciar una clase + Bicicleta excursion = new Bicicleta(); + + // Llama métodos del objeto + excursion.aumentarVelocidad(3); // Siempre deberías usar metodos 'set' (establecer) y 'get' (obtener) + excursion.setRitmo(100); + + // 'toString' es una convención para mostrar los valores de este objeto. + System.out.println("informacion de la excursion: " + excursion.toString()); + + } // Fin del método 'main' +} // Fin de la clase AprendeJava + + +// Puedes incluir otras clases no públicas en un archivo .java + + +// Sintaxis de declaración de clases: +// <public/private/protected> class <nombre_de_la_clase>{ +// //variables_de_clase, constructores, todas las funciones. +// //las funciones son llamadas como métodos en Java. +// } + +class Bicicleta { + + // Campos/Variables de Bicicleta + public int ritmo; // Public: Puede ser accedido desde cualquier parte + private int velocidad; // Private: Accesible sólo desde esta clase + protected int engranaje; // Protected: Accesible desde esta clases y sus subclases + String nombre; // default: Sólo accesible desde este paquete + + // Constructores son la manera de crear clases + // Este es un constructor por defecto + public Bicicleta() { + engranaje = 1; + ritmo = 50; + velocidad = 5; + nombre = "Bontrager"; + } + + // Este es un constructor específico (contiene argumentos) + public Bicicleta(int ritmoInicial, int velocidadInicial, int engranajeInicial, String nombre) { + this.engranaje = engranajeInicial; + this.ritmo = ritmoInicial; + this.velocidad = velocidadInicial; + this.nombre = nombre; + } + + // Sintaxis de función: + // <public/private/protected> <tipo_de_retorno> <nombre_funcion>(<argumentos>) + + // Las clases de Java usualmente implementan métodos 'get' (obtener) y 'set' (establecer) para sus campos + + // Sintaxis de declaración de métodos + // <alcance> <tipo_de_retorno> <nombre_metodo>(<argumentos>) + public int getRitmo() { + return ritmo; + } + + // Métodos void no requieren retornar + public void setRitmo(int nuevoValor) { + ritmo = nuevoValor; + } + + public void setEngranaje(int nuevoValor) { + engranaje = nuevoValor; + } + + public void aumentarVelocidad(int incremento) { + velocidad += incremento; + } + + public void disminuirVelocidad(int reduccion) { + velocidad -= reduccion; + } + + public void setNombre(String nuevoNombre) { + nombre = nuevoNombre; + } + + public String getNombre() { + return nombre; + } + + //Método para mostrar los valores de los atributos de este objeto. + @Override + public String toString() { + return "engranaje: " + engranaje + + " ritmo: " + ritmo + + " velocidad: " + velocidad + + " nombre: " + nombre; + } +} // fin clase Bicicleta + +// PennyFarthing es una subclase de Bicicleta +class PennyFarthing extends Bicicleta { + // (Penny Farthings son esas bicicletas con una gran rueda forntal. + // No tienen engranajes.) + + public PennyFarthing(int ritmoInicial, int velocidadInicial){ + // Llama al constructor del padre con super + super(ritmoInicial, velocidadInicial, 0, "PennyFarthing"); + } + + // Deberías marcar un método que estás sobre escribiendo con una @anotacion + // Para aprender más sobre que son y el propósito de las anotaciones + // echa un vistazo acá: http://docs.oracle.com/javase/tutorial/java/annotations/ + @Override + public void setEngranaje(int engranaje) { + engranaje = 0; + } + +} + +``` + +## Más Lectura + +Estos links son sólo para tener un entendimiento del tema, no dudes en +usar Google y encontrar ejemplos más específicos + +Otros temas a investigar: + +* [Java Tutorial Trail from Sun / Oracle](http://docs.oracle.com/javase/tutorial/index.html) + +* [Java Access level modifiers](http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html) + +* [Object-Oriented Programming Concepts](http://docs.oracle.com/javase/tutorial/java/concepts/index.html): + * [Inheritance](http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html) + * [Polymorphism](http://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html) + * [Abstraction](http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html) + +* [Exceptions](http://docs.oracle.com/javase/tutorial/essential/exceptions/index.html) + +* [Interfaces](http://docs.oracle.com/javase/tutorial/java/IandI/createinterface.html) + +* [Generics](http://docs.oracle.com/javase/tutorial/java/generics/index.html) + +* [Java Code Conventions](http://www.oracle.com/technetwork/java/codeconv-138413.html) diff --git a/es-es/python-es.html.markdown b/es-es/python-es.html.markdown new file mode 100644 index 00000000..f92f5cde --- /dev/null +++ b/es-es/python-es.html.markdown @@ -0,0 +1,490 @@ +--- +language: python +contributors: + - ["Louie Dinh", "http://ldinh.ca"] +translators: + - ["Camilo Garrido", "http://www.twitter.com/hirohope"] +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. +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] + +Nota: Este artículo aplica a Python 2.7 específicamente, pero debería ser aplicable a Python 2.x. ¡Pronto un recorrido por Python 3! + +```python +# Comentarios de una línea comienzan con una almohadilla (o signo gato) +""" Strings multilinea pueden escribirse + usando tres "'s, y comunmente son usados + como comentarios. +""" + +#################################################### +## 1. Tipos de datos primitivos y operadores. +#################################################### + +# Tienes números +3 #=> 3 + +# Matemática es lo que esperarías +1 + 1 #=> 2 +8 - 1 #=> 7 +10 * 2 #=> 20 +35 / 5 #=> 7 + +# La división es un poco complicada. Es división entera y toma la parte entera +# de los resultados automáticamente. +5 / 2 #=> 2 + +# Para arreglar la división necesitamos aprender sobre 'floats' +# (números de coma flotante). +2.0 # Esto es un 'float' +11.0 / 4.0 #=> 2.75 ahhh...mucho mejor + +# Refuerza la precedencia con paréntesis +(1 + 3) * 2 #=> 8 + +# Valores 'boolean' (booleanos) son primitivos +True +False + +# Niega con 'not' +not True #=> False +not False #=> True + +# Igualdad es == +1 == 1 #=> True +2 == 1 #=> False + +# Desigualdad es != +1 != 1 #=> False +2 != 1 #=> True + +# Más comparaciones +1 < 10 #=> True +1 > 10 #=> False +2 <= 2 #=> True +2 >= 2 #=> True + +# ¡Las comparaciones pueden ser concatenadas! +1 < 2 < 3 #=> True +2 < 3 < 2 #=> False + +# Strings se crean con " o ' +"Esto es un string." +'Esto también es un string' + +# ¡Strings también pueden ser sumados! +"Hola " + "mundo!" #=> "Hola mundo!" + +# Un string puede ser tratado como una lista de caracteres +"Esto es un string"[0] #=> 'E' + +# % pueden ser usados para formatear strings, como esto: +"%s pueden ser %s" % ("strings", "interpolados") + +# Una forma más reciente de formatear strings es el método 'format'. +# Este método es la forma preferida +"{0} pueden ser {1}".format("strings", "formateados") +# Puedes usar palabras claves si no quieres contar. +"{nombre} quiere comer {comida}".format(nombre="Bob", comida="lasaña") + +# None es un objeto +None #=> None + +# No uses el símbolo de igualdad `==` para comparar objetos con None +# Usa `is` en lugar de +"etc" is None #=> False +None is None #=> True + +# El operador 'is' prueba la identidad del objeto. Esto no es +# muy útil cuando se trata de datos primitivos, pero es +# muy útil cuando se trata de objetos. + +# None, 0, y strings/listas vacíos(as) todas se evalúan como False. +# Todos los otros valores son True +0 == False #=> True +"" == False #=> True + + +#################################################### +## 2. Variables y Colecciones +#################################################### + +# Imprimir es muy fácil +print "Soy Python. ¡Encantado de conocerte!" + + +# No hay necesidad de declarar las variables antes de asignarlas. +una_variable = 5 # La convención es usar guiones_bajos_con_minúsculas +una_variable #=> 5 + +# Acceder a variables no asignadas previamente es una excepción. +# Ve Control de Flujo para aprender más sobre el manejo de excepciones. +otra_variable # Levanta un error de nombre + +# 'if' puede ser usado como una expresión +"yahoo!" if 3 > 2 else 2 #=> "yahoo!" + +# Listas sobre secuencias +lista = [] +# Puedes empezar con una lista prellenada +otra_lista = [4, 5, 6] + +# Añadir cosas al final de una lista con 'append' +lista.append(1) #lista ahora es [1] +lista.append(2) #lista ahora es [1, 2] +lista.append(4) #lista ahora es [1, 2, 4] +lista.append(3) #lista ahora es [1, 2, 4, 3] +# Remueve del final de la lista con 'pop' +lista.pop() #=> 3 y lista ahora es [1, 2, 4] +# Pongámoslo de vuelta +lista.append(3) # Nuevamente lista ahora es [1, 2, 4, 3]. + +# Accede a una lista como lo harías con cualquier arreglo +lista[0] #=> 1 +# Mira el último elemento +lista[-1] #=> 3 + +# Mirar fuera de los límites es un error 'IndexError' +lista[4] # Levanta la excepción IndexError + +# Puedes mirar por rango con la sintáxis de trozo. +# (Es un rango cerrado/abierto para ustedes los matemáticos.) +lista[1:3] #=> [2, 4] +# Omite el inicio +lista[2:] #=> [4, 3] +# Omite el final +lista[:3] #=> [1, 2, 4] + +# Remueve elementos arbitrarios de una lista con 'del' +del lista[2] # lista ahora es [1, 2, 3] + +# Puedes sumar listas +lista + otra_lista #=> [1, 2, 3, 4, 5, 6] - Nota: lista y otra_lista no se tocan + +# Concatenar listas con 'extend' +lista.extend(otra_lista) # lista ahora es [1, 2, 3, 4, 5, 6] + +# Chequea la existencia en una lista con +1 in lista #=> True + +# Examina el largo de una lista con 'len' +len(lista) #=> 6 + + +# Tuplas son como listas pero son inmutables. +tupla = (1, 2, 3) +tupla[0] #=> 1 +tupla[0] = 3 # Levanta un error TypeError + +# También puedes hacer todas esas cosas que haces con listas +len(tupla) #=> 3 +tupla + (4, 5, 6) #=> (1, 2, 3, 4, 5, 6) +tupla[:2] #=> (1, 2) +2 in tupla #=> True + +# Puedes desempacar tuplas (o listas) en variables +a, b, c = (1, 2, 3) # a ahora es 1, b ahora es 2 y c ahora es 3 +# Tuplas son creadas por defecto si omites los paréntesis +d, e, f = 4, 5, 6 +# Ahora mira que fácil es intercambiar dos valores +e, d = d, e # d ahora es 5 y e ahora es 4 + + +# Diccionarios almacenan mapeos +dicc_vacio = {} +# Aquí está un diccionario prellenado +dicc_lleno = {"uno": 1, "dos": 2, "tres": 3} + +# Busca valores con [] +dicc_lleno["uno"] #=> 1 + +# Obtén todas las llaves como una lista +dicc_lleno.keys() #=> ["tres", "dos", "uno"] +# Nota - El orden de las llaves del diccionario no está garantizada. +# Tus resultados podrían no ser los mismos del ejemplo. + +# Obtén todos los valores como una lista +dicc_lleno.values() #=> [3, 2, 1] +# Nota - Lo mismo que con las llaves, no se garantiza el orden. + +# Chequea la existencia de una llave en el diccionario con 'in' +"uno" in dicc_lleno #=> True +1 in dicc_lleno #=> False + +# Buscar una llave inexistente deriva en KeyError +dicc_lleno["cuatro"] # KeyError + +# Usa el método 'get' para evitar la excepción KeyError +dicc_lleno.get("uno") #=> 1 +dicc_lleno.get("cuatro") #=> None +# El método 'get' soporta un argumento por defecto cuando el valor no existe. +dicc_lleno.get("uno", 4) #=> 1 +dicc_lleno.get("cuatro", 4) #=> 4 + +# El método 'setdefault' es una manera segura de añadir nuevos pares +# llave-valor en un diccionario +dicc_lleno.setdefault("cinco", 5) #dicc_lleno["cinco"] es puesto con valor 5 +dicc_lleno.setdefault("cinco", 6) #dicc_lleno["cinco"] todavía es 5 + + +# Sets (conjuntos) almacenan ... bueno, conjuntos +conjunto_vacio = set() +# Inicializar un conjunto con montón de valores +un_conjunto = set([1,2,2,3,4]) # un_conjunto ahora es set([1, 2, 3, 4]) + +# Desde Python 2.7, {} puede ser usado para declarar un conjunto +conjunto_lleno = {1, 2, 2, 3, 4} # => {1 2 3 4} + +# Añade más valores a un conjunto +conjunto_lleno.add(5) # conjunto_lleno ahora es {1, 2, 3, 4, 5} + +# Haz intersección de conjuntos con & +otro_conjunto = {3, 4, 5, 6} +conjunto_lleno & otro_conjunto #=> {3, 4, 5} + +# Haz unión de conjuntos con | +conjunto_lleno | otro_conjunto #=> {1, 2, 3, 4, 5, 6} + +# Haz diferencia de conjuntos con - +{1,2,3,4} - {2,3,5} #=> {1, 4} + +# CHequea la existencia en un conjunto con 'in' +2 in conjunto_lleno #=> True +10 in conjunto_lleno #=> False + + +#################################################### +## 3. Control de Flujo +#################################################### + +# Hagamos sólo una variable +una_variable = 5 + +# Aquí está una declaración de un 'if'. ¡La indentación es significativa en Python! +# imprime "una_variable es menor que 10" +if una_variable > 10: + print "una_variable es completamente mas grande que 10." +elif una_variable < 10: # Este condición 'elif' es opcional. + print "una_variable es mas chica que 10." +else: # Esto también es opcional. + print "una_variable es de hecho 10." + + +""" +For itera sobre listas +imprime: + perro es un mamifero + gato es un mamifero + raton es un mamifero +""" +for animal in ["perro", "gato", "raton"]: + # Puedes usar % para interpolar strings formateados + print "%s es un mamifero" % animal + +""" +`range(número)` retorna una lista de números +desde cero hasta el número dado +imprime: + 0 + 1 + 2 + 3 +""" +for i in range(4): + print i + +""" +While itera hasta que una condición no se cumple. +imprime: + 0 + 1 + 2 + 3 +""" +x = 0 +while x < 4: + print x + x += 1 # versión corta de x = x + 1 + +# Maneja excepciones con un bloque try/except + +# Funciona desde Python 2.6 en adelante: +try: + # Usa raise para levantar un error + raise IndexError("Este es un error de indice") +except IndexError as e: + pass # Pass no hace nada. Usualmente harias alguna recuperacion aqui. + + +#################################################### +## 4. Funciones +#################################################### + +# Usa 'def' para crear nuevas funciones +def add(x, y): + print "x es %s y y es %s" % (x, y) + return x + y # Retorna valores con una la declaración return + +# Llamando funciones con parámetros +add(5, 6) #=> imprime "x es 5 y y es 6" y retorna 11 + +# Otra forma de llamar funciones es con argumentos de palabras claves +add(y=6, x=5) # Argumentos de palabra clave pueden ir en cualquier orden. + +# Puedes definir funciones que tomen un número variable de argumentos +def varargs(*args): + return args + +varargs(1, 2, 3) #=> (1,2,3) + + +# Puedes definir funciones que toman un número variable de argumentos +# de palabras claves +def keyword_args(**kwargs): + return kwargs + +# Llamémosla para ver que sucede +keyword_args(pie="grande", lago="ness") #=> {"pie": "grande", "lago": "ness"} + +# Puedes hacer ambas a la vez si quieres +def todos_los_argumentos(*args, **kwargs): + print args + print kwargs +""" +todos_los_argumentos(1, 2, a=3, b=4) imprime: + (1, 2) + {"a": 3, "b": 4} +""" + +# ¡Cuando llames funciones, puedes hacer lo opuesto a varargs/kwargs! +# Usa * para expandir tuplas y usa ** para expandir argumentos de palabras claves. +args = (1, 2, 3, 4) +kwargs = {"a": 3, "b": 4} +todos_los_argumentos(*args) # es equivalente a foo(1, 2, 3, 4) +todos_los_argumentos(**kwargs) # es equivalente a foo(a=3, b=4) +todos_los_argumentos(*args, **kwargs) # es equivalente a foo(1, 2, 3, 4, a=3, b=4) + +# Python tiene funciones de primera clase +def crear_suma(x): + def suma(y): + return x + y + return suma + +sumar_10 = crear_suma(10) +sumar_10(3) #=> 13 + +# También hay funciones anónimas +(lambda x: x > 2)(3) #=> True + +# Hay funciones integradas de orden superior +map(sumar_10, [1,2,3]) #=> [11, 12, 13] +filter(lambda x: x > 5, [3, 4, 5, 6, 7]) #=> [6, 7] + +# Podemos usar listas por comprensión para mapeos y filtros agradables +[add_10(i) for i in [1, 2, 3]] #=> [11, 12, 13] +[x for x in [3, 4, 5, 6, 7] if x > 5] #=> [6, 7] + +#################################################### +## 5. Clases +#################################################### + +# Heredamos de object para obtener una clase. +class Humano(object): + + # Un atributo de clase es compartido por todas las instancias de esta clase + especie = "H. sapiens" + + # Constructor basico + def __init__(self, nombre): + # Asigna el argumento al atributo nombre de la instancia + self.nombre = nombre + + # Un metodo de instancia. Todos los metodos toman self como primer argumento + def decir(self, msg): + return "%s: %s" % (self.nombre, msg) + + # Un metodo de clase es compartido a través de todas las instancias + # Son llamados con la clase como primer argumento + @classmethod + def get_especie(cls): + return cls.especie + + # Un metodo estatico es llamado sin la clase o instancia como referencia + @staticmethod + def roncar(): + return "*roncar*" + + +# Instancia una clase +i = Humano(nombre="Ian") +print i.decir("hi") # imprime "Ian: hi" + +j = Humano("Joel") +print j.decir("hello") #imprime "Joel: hello" + +# Llama nuestro método de clase +i.get_especie() #=> "H. sapiens" + +# Cambia los atributos compartidos +Humano.especie = "H. neanderthalensis" +i.get_especie() #=> "H. neanderthalensis" +j.get_especie() #=> "H. neanderthalensis" + +# Llama al método estático +Humano.roncar() #=> "*roncar*" + + +#################################################### +## 6. Módulos +#################################################### + +# Puedes importar módulos +import math +print math.sqrt(16) #=> 4 + +# Puedes obtener funciones específicas desde un módulo +from math import ceil, floor +print ceil(3.7) #=> 4.0 +print floor(3.7) #=> 3.0 + +# Puedes importar todas las funciones de un módulo +# Precaución: Esto no es recomendable +from math import * + +# Puedes acortar los nombres de los módulos +import math as m +math.sqrt(16) == m.sqrt(16) #=> True + +# Los módulos de Python son sólo archivos ordinarios de Python. +# Puedes escribir tus propios módulos e importarlos. El nombre del módulo +# es el mismo del nombre del archivo. + +# Puedes encontrar que funciones y atributos definen un módulo. +import math +dir(math) + + +``` + +## ¿Listo para más? + +### Gratis y en línea + +* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/) +* [Dive Into Python](http://www.diveintopython.net/) +* [The Official Docs](http://docs.python.org/2.6/) +* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/) +* [Python Module of the Week](http://pymotw.com/2/) + +### Encuadernados + +* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20) +* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20) +* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20) + diff --git a/es-es/ruby-es.html.markdown b/es-es/ruby-es.html.markdown new file mode 100644 index 00000000..66a5d0fe --- /dev/null +++ b/es-es/ruby-es.html.markdown @@ -0,0 +1,377 @@ +--- +language: ruby +filename: learnruby-es.rb +contributors: + - ["David Underwood", "http://theflyingdeveloper.com"] + - ["Joel Walden", "http://joelwalden.net"] + - ["Luke Holder", "http://twitter.com/lukeholder"] +translators: + - ["Camilo Garrido", "http://www.twitter.com/hirohope"] +lang: es-es +--- + +```ruby +# Esto es un comentario + +=begin +Este es un comentario multilínea +Nadie los usa. +Tu tampoco deberías +=end + +# Lo primero y principal: Todo es un objeto + +# Los números son objetos + +3.class #=> Fixnum + +3.to_s #=> "3" + + +# Un poco de aritmética básica +1 + 1 #=> 2 +8 - 1 #=> 7 +10 * 2 #=> 20 +35 / 5 #=> 7 + +# La aritmética es sólo azúcar sintáctico +# para llamar un método de un objeto +1.+(3) #=> 4 +10.* 5 #=> 50 + +# Los valores especiales son objetos +nil # Nada que ver aqui +true # Verdadero +false # Falso + +nil.class #=> NilClass +true.class #=> TrueClass +false.class #=> FalseClass + +# Igualdad +1 == 1 #=> true +2 == 1 #=> false + +# Desigualdad +1 != 1 #=> false +2 != 1 #=> true +!true #=> false +!false #=> true + +# Además de 'false', 'nil' es otro valor falso + +!nil #=> true +!false #=> true +!0 #=> false + +# Más comparaciones +1 < 10 #=> true +1 > 10 #=> false +2 <= 2 #=> true +2 >= 2 #=> true + +# Los strings son objetos + +'Soy un string'.class #=> String +"Soy un string también".class #=> String + +referente = "usar interpolacion de strings" +"Yo puedo #{referente} usando strings de comillas dobles" +#=> "Yo puedo usar interpolacion de strings usando strings de comillas dobles" + + +# Imprime a la salida estándar +puts "¡Estoy imprimiendo!" + +# Variables +x = 25 #=> 25 +x #=> 25 + +# Nota que la asignación retorna el valor asignado +# Esto significa que puedes hacer múltiples asignaciones: + +x = y = 10 #=> 10 +x #=> 10 +y #=> 10 + +# Por convención, usa snake_case para nombres de variables +snake_case = true + +# Usa nombres de variables descriptivos +ruta_para_la_raiz_de_un_projecto = '/buen/nombre/' +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 +# valores específicos y significativos + +:pendiente.class #=> Symbol + +status = :pendiente + +status == :pendiente #=> true + +status == 'pendiente' #=> false + +status == :aprovado #=> false + +# Arreglos + +# Esto es un arreglo +[1, 2, 3, 4, 5] #=> [1, 2, 3, 4, 5] + +# Arreglos pueden contener elementos de distintos tipos + +arreglo = [1, "hola", false] #=> => [1, "hola", false] + +# Arreglos pueden ser indexados +# Desde el frente +arreglo[0] #=> 1 +arreglo[12] #=> nil + +# Tal como la 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 +arreglo.[] 12 #=> nil + +# Desde el final +arreglo[-1] #=> 5 + +# Con un índice de inicio y final +arreglo[2, 4] #=> [3, 4, 5] + +# O con rango +arreglo[1..3] #=> [2, 3, 4] + +# Añade elementos a un arreglo así +arreglo << 6 #=> [1, 2, 3, 4, 5, 6] + +# Hashes son los diccionarios principales de Ruby con pares llave/valor. +# Hashes se denotan con llaves: +hash = {'color' => 'verde', 'numero' => 5} + +hash.keys #=> ['color', 'numero'] + +# Hashes pueden buscar rápidamente una llave: +hash['color'] #=> 'verde' +hash['numero'] #=> 5 + +# Preguntarle a un hash por una llave que no existe retorna 'nil': +hash['nada aqui'] #=> nil + +# Itera sobre un hash con el método 'each': +hash.each do |k, v| + puts "#{k} is #{v}" +end + +# Desde Ruby 1.9, hay una sintaxis especial cuando se usa un símbolo como llave: + +nuevo_hash = { defcon: 3, accion: true} + +nuevo_hash.keys #=> [:defcon, :accion] + +# Tip: Tanto los arreglos como los hashes son Enumerable (enumerables) +# Comparten muchos métodos útiles tales como 'each', 'map', 'count', y más + +# Estructuras de Control + +if true + "declaracion 'if'" +elsif false + "else if, opcional" +else + "else, tambien opcional" +end + +for contador in 1..5 + puts "iteracion #{contador}" +end +#=> iteracion 1 +#=> iteracion 2 +#=> iteracion 3 +#=> iteracion 4 +#=> iteracion 5 + +# Aunque +# Nadie usa los ciclos `for` +# Usa `each`, así: + +(1..5).each do |contador| + puts "iteracion #{contador}" +end +#=> iteracion 1 +#=> iteracion 2 +#=> iteracion 3 +#=> iteracion 4 +#=> iteracion 5 + +counter = 1 +while counter <= 5 do + puts "iteracion #{counter}" + counter += 1 +end +#=> iteracion 1 +#=> iteracion 2 +#=> iteracion 3 +#=> iteracion 4 +#=> iteracion 5 + +nota = 'B' + +case nota +when 'A' + puts "Muy bien muchacho" +when 'B' + puts "Mejor suerte para la proxima" +when 'C' + puts "Puedes hacerlo mejor" +when 'D' + puts "Sobreviviendo" +when 'F' + puts "¡Reprobaste!" +else + puts "Sistema alternativo de notas, ¿eh?" +end + +# Funciones + +def doble(x) + x * 2 +end + +# Funciones (y todos los bloques) implícitamente retornan el valor de la última instrucción +doble(2) #=> 4 + +# Paréntesis son opcionales cuando el resultado es ambiguo +doble 3 #=> 6 + +doble doble 3 #=> 12 + +def suma(x,y) + x + y +end + +# Arguméntos del método son separados por coma +suma 3, 4 #=> 7 + +suma suma(3,4), 5 #=> 12 + +# yield +# Todos los métodos tienen un parámetro de bloqueo opcional e implícitp +# puede llamarse con la palabra clave 'yield' + +def alrededor + puts "{" + yield + puts "}" +end + +alrededor { puts 'hola mundo' } + +# { +# hola mundo +# } + + +# Define una clase con la palabra clave 'class' +class Humano + + # Una variable de clase. Es compartida por todas las instancias de la clase. + @@species = "H. sapiens" + + # Inicializador Básico + def initialize(nombre, edad=0) + # Asigna el argumento a la variable de instancia 'nombre' + @nombre = nombre + # Si no dan edad, se usará el valor por defecto en la lista de argumentos. + @edad = edad + end + + # Método 'setter' (establecer) básico + def nombre=(nombre) + @nombre = nombre + end + + # Método 'getter' (obtener) básico + def nombre + @nombre + end + + # Un método de clase usa 'self' (sí mismo) para distinguirse de métodos de instancia. + # Sólo puede ser llamado en la clase, no por una instancia. + def self.decir(mensaje) + puts "#{mensaje}" + end + + def especie + @@especie + end + +end + + +# Instancia una clase +jim = Humano.new("Jim Halpert") + +dwight = Humano.new("Dwight K. Schrute") + +# Llamemos un par de métodos +jim.especie #=> "H. sapiens" +jim.nombre #=> "Jim Halpert" +jim.nombre = "Jim Halpert II" #=> "Jim Halpert II" +jim.nombre #=> "Jim Halpert II" +dwight.especie #=> "H. sapiens" +dwight.nombre #=> "Dwight K. Schrute" + +# Llama el método de clase +Humano.decir("Hi") #=> "Hi" + +# Las clases también son un objeto en ruby. Por lo cual, las clases también pueden tener variables de instancia. +# Variables de clase son compartidas a través de la clase y todos sus descendientes. + +# clase base +class Humano + @@foo = 0 + + def self.foo + @@foo + end + + def self.foo=(valor) + @@foo = valor + end +end + +# clase derivada +class Trabajador < Humano +end + +Humano.foo # 0 +Trabajador.foo # 0 + +Humano.foo = 2 # 2 +Trabajador.foo # 2 + +# Las variables de instancia de la clase no son compartidas por los descendientes de la clase. + +class Humano + @bar = 0 + + def self.bar + @bar + end + + def self.bar=(valor) + @bar = valor + end +end + +class Doctor < Humano +end + +Human.bar # 0 +Doctor.bar # nil + +``` |