diff options
Diffstat (limited to 'es-es')
| -rw-r--r-- | es-es/forth-es.html.markdown | 226 | ||||
| -rw-r--r-- | es-es/hack-es.html.markdown | 307 | ||||
| -rw-r--r-- | es-es/javascript-es.html.markdown | 4 | ||||
| -rw-r--r-- | es-es/objective-c-es.html.markdown | 851 | ||||
| -rw-r--r-- | es-es/r-es.html.markdown | 717 | ||||
| -rw-r--r-- | es-es/rust-es.html.markdown | 324 | ||||
| -rw-r--r-- | es-es/yaml-es.html.markdown | 189 | 
7 files changed, 2560 insertions, 58 deletions
| diff --git a/es-es/forth-es.html.markdown b/es-es/forth-es.html.markdown new file mode 100644 index 00000000..05dc0cc5 --- /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/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/javascript-es.html.markdown b/es-es/javascript-es.html.markdown index 9ef0c63e..34428f42 100644 --- a/es-es/javascript-es.html.markdown +++ b/es-es/javascript-es.html.markdown @@ -23,7 +23,9 @@ Aunque JavaScript no sólo se limita a los navegadores web: Node.js, Un proyecto  [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 */ 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/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/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/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) | 
