sábado, 25 de enero de 2020

Como levantar una base de datos Oracle en Docker?


Vamos a correr una base de datos oracle en un contenedor docker.

Antes que nada vamos instalar docker : https://docs.docker.com/install/

Luego de instalar docker, se debe hacer una cuenta y aceptar los términos y condiciones de uso de la imagen de Oracle 12.2.1c en el siguiente link:

https://hub.docker.com/u/emanuelpeg/content/sub-58a32504-c6af-4941-8558-061121a0243d

Luego debemos correr docker, para ello podemos ejecutar esta comando en Fedora :

sudo systemctl start docker

Luego debemos loguearnos por consola con el siguiente comando:

docker login

Con este comando, nos logiamos, y docker va a saber que aceptamos los términos y condiciones.

Luego debemos bajar la imagen con :

docker pull store/oracle/database-enterprise:12.2.0.1

Con este comando, bajamos la imagen de oracle, la imagen sería un template con el cual podemos crear containers que tengan base de datos propiamente dichas.

Luego tenemos que crear un container que es la instancia propia de la base, vamos a llamar ejemplo a nuestro container.

docker run -d -it --name ejemplo -p 1521:1521 store/oracle/database-enterprise:12.2.0.1

Como se puede ver se mapeo el puerto 1521 con el 1521 del equipo, esto se puede cambiar si el puerto esta siendo utilizado.

Con docker ps podemos ver si levanto el container con :

docker ps

CONTAINER ID        IMAGE                                      COMMAND                 CREATED             STATUS                             PORTS                              NAMES

c8aea60c0230       store/oracle/database-enterprise:12.2.0.1   "/bin/sh -c '/bin/ba…"   38 seconds ago      Up 36 seconds (health: starting)   0.0.0.0:1521->1521/tcp, 5500/tcp   ejemplo

Docker creo un container con la base de datos oracle y publico el puerto 1521 para que podamos conectarnos.

Los datos de conexión son :

User : SYS (dba user)
Password : Oradoc_db1
Oracle-sid : ORCLCDB

Estos datos son creados a partir de la imagen de oracle, y simplemente son datos por defecto.

Debemos conectarnos con estos datos para utilizar la base. Para ello utilizamos sqlplus :

$ docker exec -it ejemplo bash -c "source /home/oracle/.bashrc; sqlplus  sys/Oradoc_db1@ORCLCDB as sysdba"

Con sqlplus podemos crear usuarios, base de datos, tablas, etc...

Para importar base de datos necesitamos tener un .dmp de la base a importar, yo importaré baseDeEjemplo.dmp

Creamos una carpeta para guardar los backups :

docker exec -it ejemplo mkdir /home/oracle/backups

Debemos copiar este archivo al container :

docker cp baseDeEjemplo.dmp ejemplo:/home/oracle/backups

Ahora debemos importar el dump, con el siguiente comando:

docker exec -it ejemplo bash -c "source /home/oracle/.bashrc; impdp usario/pass@ORCLCDB remap_schema=origen:destino directory= backups dumpfile=baseDeEjemplo.dmp logfile=unLog.log”

Se debe tener la carpeta backup registrada en oracle.

Para conectarnos con un cliente debemos utilizar los siguientes datos :

host=0.0.0.0:1521
SID=ORCLCDB
password = sys
username = Oradoc_db1

Por último, si dejamos de utilizar docker podemos parar el container con

docker stop ejemplo

y podemos iniciar la instancia con start

docker start ejemplo

Dejo link: https://hub.docker.com/u/emanuelpeg/content/sub-58a32504-c6af-4941-8558-061121a0243d?ref=login

jueves, 23 de enero de 2020

Sextos pasos en GIT


Seguimos con GIT. 

Administrando branches : Si deseamos lista todas las branches :

$ git branch

Siempre hay una branch llamada ”master”, y es en la que comienzas por defecto.

Algunos aconsejan dejar la rama ”master” sin tocar y el crear nuevas branches para tus propios cambios. El branch ”master” es una convención útil. Otros pueden asumir que tu repositorio tiene un branch con este nombre, y que contiene la versión oficial del proyecto. Puedes renombrar o destruir la branch ”master”, pero también podrías respetar esta costumbre.

Después de un rato puedes notar que estás creando branches de corta vida de manera frecuente por razones similares: cada branch sirve simplemente para salvar el estado actual y permitirte saltar a un estado anterior para solucionar un bug de alta prioridad o algo.

Es análogo a cambiar el canal de la TV temporalmente, para ver que otra cosa están dando. Pero en lugar de apretar un par de botones, tienes que crear, hacer checkout y eliminar branches y commits temporales. Por suerte, Git tiene un atajo que es tan conveniente como un control remoto de TV:

$ git stash

Esto guarda el estado actual en un lugar temporal (un stash) y restaura el estado anterior. Tu directorio de trabajo se ve idéntico a como estaba antes de que comenzaras a editar, y puedes solucionar bugs, traer cambios desde otros repositorios, etc. Cuando quieras volver a los cambios del stash, escribe:

$ git stash apply

Puedes tener varios stashes, y manipularlos de varias maneras. Como es de imaginar, Git mantiene branches de manera interna para lograr este truco mágico.

Aplicaciones como Mozilla Firefox permiten tener varias pestañas y ventanas abiertas. Cambiar de pestaña te da diferente contenido en la misma ventana.

Los branches en git son como pestañas para tu directorio de trabajo. Siguiendo esta analogía, el clonar es como abrir una nueva ventana. La posibilidad de ambas cosas es lo que mejora la experiencia del usuario.

En un nivel más alto, varios window managers en Linux soportan múltiples escritorios. Usar branches en Git es similar a cambiar a un escritorio diferente, mientras clonar es similar a conectar otro monitor para ganar un nuevo escritorio.

Otro ejemplo es el programa screen. Esta joya permite crear, destruir e intercambiar entre varias sesiones de terminal sobre la misma terminal. En lugar de abrir terminales nuevas (clone), puedes usar la misma si ejecutas screen (branch). De hecho, puedes hacer mucho más con screen, pero eso es un asunto para otro manual.

Usar clone, branch y merge, es rápido y local en Git, animándote a usar la combinación que más te favorezca. Git te permite trabajar exactamente como prefieras.


miércoles, 22 de enero de 2020

C++ 17 en detalle

Quiero recomendarles el siguiente libro gratuito de C++ 17 :

Free ebook for every developer
Free tools for every developer
Download your copy of the eBook "C++17 IN DETAIL - Part 1"
Explore the Exciting Features of the New C++ Standard

What you will learn:
  • What was removed from the language and what is deprecated
  • How the language is more precise: for example, thanks to expression evaluation order guarantees
  • What the new features of templates are, like if constexpr or fold expressions
  • What the new standard attributes are
  • How you can write cleaner and more expressive code thanks to structured binding, inline variables, compile-time if or template argument deduction for classes

lunes, 20 de enero de 2020

El lenguaje de programación V, Parte 5




Seguimos con V

Al igual que Go, podemos definir métodos para estructuras :

struct User {
age int
}

fn (u User) can_register() bool {
return u.age > 16
}

user := User{age: 10}
println(user.can_register()) // "false"

user2 := User{age: 20}
println(user2.can_register()) // "true"

V no tiene clases. Pero puede definir métodos de tipos.

Un método es una función con un argumento receptor especial.

El receptor aparece en su propia lista de argumentos entre la palabra clave fn y el nombre del método.

En este ejemplo, el método can_register tiene un receptor de tipo Usuario llamado u. La convención no es usar nombres de receptores como self o this, sino un nombre corto, preferiblemente de una letra.

Las funciones V son puras por defecto, lo que significa que sus valores de retorno solo están determinados por sus argumentos, y su evaluación no tiene efectos secundarios.

Esto se logra por falta de variables globales y todos los argumentos de función son inmutables por defecto, incluso cuando se pasan referencias.

Sin embargo, V no es un lenguaje funcional puro. Es posible modificar los argumentos de la función utilizando la misma palabra clave mut:

struct User {
mut:
is_registered bool
}

fn (u mut User) register() {
u.is_registered = true
}

mut user := User{}
println(user.is_registered) // "false"
user.register()
println(user.is_registered) // "true"

En este ejemplo, el receptor (que es simplemente el primer argumento) se marca como mutable, por lo que register() puede cambiar el objeto de usuario. Lo mismo funciona con argumentos no receptores:

fn multiply_by_2(arr mut []int) {
for i := 0; i < arr.len; i++ {
arr[i] *= 2
}
}

mut nums := [1, 2, 3]
multiply_by_2(mut nums)
println(nums) // "[2, 4, 6]"

Tengamos en cuenta que debe agregar mut antes de nums cuando llamemos a esta función. Esto deja en claro que la función que se llama modificará el valor.

Es preferible devolver valores en lugar de modificar argumentos. La modificación de argumentos solo debe hacerse en partes críticas de su aplicación para reducir las asignaciones y la copia.

Por esta razón, V no permite modificar argumentos primitivos como enteros, solo tipos complejos como matrices y mapas.

Se debe usarr user.register() o user = register (user) en lugar de register (mut user).

V facilita la devolución de una versión modificada de un objeto:

fn register(u User) User {
return { u | is_registered: true }
}

user = register(user)

Dejo link: https://vlang.io/

domingo, 19 de enero de 2020

El lenguaje de programación V, Parte 4

Seguimos con V 


Veamos un ejemplo de macheo:

os := 'windows'
print('V is running on ')
match os {
'darwin' { println('macOS.') }
'linux'  { println('Linux.') }
else     { println(os) }
}

s := match number {
1    { 'one' }
2    { 'two' }
else {
println('this works too')
'many'
}
}

Una declaración de coincidencia es una forma más corta de escribir una secuencia de declaraciones if - else. Cuando se encuentra una rama coincidente, se ejecutará el siguiente bloque de instrucciones y se devolverá la expresión final. La rama else se evaluará cuando ninguna otra rama coincida.

Tambien podemos utilizar enums:

enum Color {
red
blue
green
}

fn is_red_or_blue(c Color) bool {
return match c {
.red { true }
.blue { true }
else { false }
}
}


También tenemos structs : 

struct Point {
x int
y int
}

p := Point{
x: 10
y: 20
}
println(p.x) // Se accede a los campos de estructura utilizando un punto

Las estructuras se asignan en la pila. Para asignar una estructura en el montón y obtener una referencia a ella, use el prefijo &:

  // Sintaxis de inicialización alternativa para estructuras con 3 campos o menos
p: = &Point {10, 10}

// Las referencias tienen la misma sintaxis para acceder a los campos
println (p.x)

El tipo de p es &Point. Es una referencia a Point. Las referencias son similares a los punteros Go y las referencias de C ++.

V no tiene subclases, pero admite estructuras incrustadas como Go:

struct Button {
Widget
title string
}

button := new_button('Click me')
button.set_pos(x, y)

button.widget.set_pos(x,y)

Los campos de estructura son privados e inmutables por defecto (haciendo que las estructuras también sean inmutables). Sus modificadores de acceso se pueden cambiar con pub y mut. En total, hay 5 opciones posibles:

struct Foo {
a int     // privado inmutable (predeterminado)
mut:
b int     // privado mutable
c int     // (puede enumerar varios campos con el mismo modificador de acceso)
pub:
d int     // público inmutable (solo lectura)
pub mut:
e int     // público, pero mutable solo en el módulo principal
__global:
f int   // público y mutable tanto dentro como fuera del módulo principal
}               // (no se recomienda usar, es por eso que la palabra clave 'global'
                 // comienza con __)

Por ejemplo, aquí está el tipo de cadena definido en el módulo integrado:

struct string {
str byteptr
pub:
len int
}

Es fácil ver a partir de esta definición que la cadena es un tipo inmutable.

El puntero de byte con los datos de la cadena no es accesible fuera de la construcción. El campo de len es público, pero no mutable:

fn main() {
str := 'hello'
len := str.len // OK 
str.len++      // Compilation error 
}

Dejo link:


jueves, 16 de enero de 2020

El lenguaje de programación V, Parte 3


Seguimos con V 

Veamos un ejemplo del condicional :

a := 10
b := 20
if a < b {
println('$a < $b')
} else if a > b {
println('$a > $b')
} else {
println('$a == $b')
}

Si las declaraciones son bastante directas y similares a la mayoría de los otros lenguajes.

A diferencia de otros lenguajes tipo C, no hay paréntesis que rodeen la condición, y las llaves siempre son necesarias.

si, se puede usar como una expresión:

num := 777
s := if num % 2 == 0 {
'even'
}
else {
'odd'
}
println(s) // "odd"

in permite verificar si una matriz o un mapa contiene un elemento.

nums := [1, 2, 3]
println(1 in nums) // true

m := {'one': 1, 'two': 2}
println('one' in m) // true

También es útil para escribir expresiones booleanas más claras y compactas:

if parser.token == .plus || parser.token == .minus ||
parser.token == .div || parser.token == .mult {
...
}

if parser.token in [.plus, .minus, .div, .mult] {
...
}

V optimiza tales expresiones, por lo tanto, si las declaraciones anteriores producen el mismo código de máquina, no se crean matrices.

V tiene solo una construcción de bucle: for.

numbers := [1, 2, 3, 4, 5]
for num in numbers {
println(num)
}
names := ['Sam', 'Peter']
for i, name in names {
println('$i) $name')  // Output: 0) Sam
}     

El valor en el bucle se usa para recorrer elementos de una matriz. Si se requiere un índice, se puede usar una forma alternativa para el índice.

Tengamos en cuenta que el valor es de solo lectura. Si necesita modificar la matriz mientras realiza el bucle, debe usar la indexación:

mut numbers := [1, 2, 3, 4, 5]
for i, num in numbers {
println(num)
numbers[i] = 0
}

mut sum := 0
mut i := 0
for i <= 100 {
sum += i
i++
}
println(sum) // "5050"

Esta forma del bucle es similar a los bucles while en otros lenguajes.

El bucle dejará de iterar una vez que la condición booleana se evalúe como falsa.

No hay paréntesis que rodeen la condición, y siempre se requieren llaves.

mut num := 0
for {
num++
if num >= 10 {
break
}
}
println(num) // "10"

La condición puede omitirse, esto da como resultado un bucle infinito.

for i := 0; i < 10; i++ {
// Don't print 6
if i == 6 {
continue
}
println(i)
}

Finalmente, está el estilo tradicional C para loop. Es más seguro que la forma `while` porque con esta última es fácil olvidarse de actualizar el contador y quedarse atascado en un bucle infinito.

Aquí no necesito ser declarado con mut ya que siempre será mutable por definición.

Dejo link:
https://vlang.io/

miércoles, 15 de enero de 2020

Libros Gratis de Java Geeks

Download IT Guides!

 
The first specification of JAXB was done in March 2003 and the work process is tracked in the Java Specification Request 31. In this specification request you can find a lot of...
 
 
JavaFX 2.0 and later is implemented as a native Java library, and applications using JavaFX are written in native Java code. JavaFX Script has been scrapped by Oracle, but development is...
 
 
A servlet can almost be thought of as an applet that runs on the server side-without a face. Java servlets make many Web applications possible.
Java...
 
 
Groovy 1.0 was released on January 2, 2007, and Groovy 2.0 in July, 2012. Since version 2, Groovy can also be compiled statically, offering type inference and performance very close to...
 

El lenguaje de programación V, Parte 2

Seguimos con V 


fn main() {
age = 21
}

Esto no compila porque age no esta declarada, pero podemos arreglarlo : 

fn main() {
age := 21
}

En el modo de desarrollo, este código generará una advertencia de "variable no utilizada". En el modo de producción (v -prod foo.v) no se compilará en absoluto, como en Go:

fn main() {
a := 10
if true {
a := 20
}
}

A diferencia de la mayoría de los lenguajes, V no permite sobre escribir una variable por el ámbito de las variables, lo anterior  no está permitido. Declarar una variable con un nombre que ya se utiliza en un ámbito primario dará como resultado un error de compilación.

Los tipos que tenemos son :

string

i8    i16  int  i64      i128 (soon)
byte  u16  u32  u64      u128 (soon)

rune // represents a Unicode code point 

f32 f64

byteptr
voidptr

Veamos ejemplo de String : 

name := 'Bob'
println('Hello, $name!')  // `$` is used for string interpolation
println(name.len)

bobby := name + 'by' // + is used to concatenate strings
println(bobby) // "Bobby" 

println(bobby[1..3]) // "ob" 
mut s := 'hello '
s += 'world' // `+=` is used to append to a string
println(s) // "hello world" 

En V, una cadena es una matriz de bytes de solo lectura. Los datos de cadena se codifican con UTF-8.

Los Strings son inmutables.

Las comillas simples y dobles se pueden usar para denotar cadenas. Por coherencia, vfmt convierte las comillas dobles en comillas simples a menos que la cadena contenga un carácter de comilla simple.

La sintaxis de interpolación es bastante simple. También funciona con campos: 'age = $ user.age'. Si necesita expresiones más complejas, use $ {}: 'puede registrarse = $ {user.age> 13}'.

Todos los operadores en V deben tener valores del mismo tipo en ambos lados. Este código no se compilará si age es un int:

println ('edad =' + edad)
Tenemos que convertir la edad en una cadena:
println ('edad =' + edad.str ())
o use la interpolación de cadenas (preferido):
println ('edad = $ edad')

Para denotar literales de caracteres, usemos `

a := `a`
assert 'aloha!'[0] == `a`
 
Para cadenas sin escapar, anteponer r:

s := r'hello\nworld'
println(s) // "hello\nworld"

Veamos unos ejemplos de arreglos :

mut nums := [1, 2, 3]
println(nums) // "[1, 2, 3]"
println(nums[1]) // "2"

nums << 4
println(nums) // "[1, 2, 3, 4]"

nums << [5, 6, 7]
println(nums) // "[1, 2, 3, 4, 5, 6, 7]"

mut names := ['John']
names << 'Peter'
names << 'Sam'
// names << 10  <-- No compila. `names` es un arreglo de tipo strings.
println(names.len) // "3"
println('Alex' in names) // "false"

names = [] // names ahora es vacío. 

// También podemos preasignar una cierta cantidad de elementos.
ids := [0].repeat(50) 

El tipo de matriz está determinado por el primer elemento: [1, 2, 3] es una matriz de entradas.
['a', 'b'] es una matriz de cadenas ([] cadena).

Todos los elementos deben tener el mismo tipo. [1, 'a'] si no, no se compilará.

<< es un operador que agrega un valor al final de la matriz. También puede agregar una matriz completa.

El campo .len devuelve la longitud de la matriz. Tenga en cuenta que es un campo de solo lectura y que el usuario no puede modificarlo. Todos los campos exportados son de solo lectura por defecto en V.

val en la matriz devuelve verdadero si la matriz contiene val.

Todos los arreglos pueden imprimirse fácilmente con println (arr) y convertirse en una cadena con s: = arr.str ().

Las matrices se pueden filtrar y asignar de manera eficiente con los métodos .filter () y .map ():

nums := [1, 2, 3, 4, 5, 6]
even := nums.filter(it % 2 == 0)
println(even) // [2, 4, 6]

words := ['hello', 'world']
upper := words.map(it.to_upper())
println(upper) // ['HELLO', 'WORLD']

Es una variable especial que se refiere a un elemento en los métodos de filter o map.

Unos ejemplo de mapa : 

mut m := map[string]int //definimos el mapa.
m['one'] = 1
m['two'] = 2
println(m['one']) // "1" 
println(m['bad_key']) // "0" 
println('bad_key' in m) // Use `in` para detectar si dicha clave existe
m.delete('two')

numbers := {
'one': 1,
'two': 2,
}

Puff me quedo largo el post, en un rato sigo...

Dejo link:


martes, 14 de enero de 2020

El lenguaje de programación V

0


V provee código simple, legible y mantenible.

A pesar de ser simple, V le da mucho poder al desarrollador. Cualquier cosa que puedas hacer en otros lenguajes, puedes hacerlo en V.

V tiene o no tiene :
  • No nulo
  • No hay variables globales.
  • Sin valores indefinidos
  • Sin comportamiento indefinido
  • Comprobación de límites
  • Opciones / tipos de resultados
  • Genéricos
  • Variables inmutables por defecto
  • Funciones puras por defecto
  • Estructuras inmutables por defecto
  • Tan rápido como C
  • interoperabilidad con C sin ningún costo
  • Cantidad mínima de asignaciones
  • Compila a binarios nativos sin dependencias: un servidor web simple es solo 65 KB

V es un lenguaje de programación compilado, estáticmente tipado, diseñado para construir software mantenible.

Es similar a Go y también está influenciado por Oberon, Rust, Swift.

Veamos el "hola mundo" en V:

fn main() {
println('hello world')
}

Las funciones se declaran con fn. El tipo de retorno va después del nombre de la función. En este caso, main no devuelve nada, por lo que se omite el tipo.

Al igual que en C y todos los lenguajes relacionados, main es un punto de entrada.

println es una de las pocas funciones integradas. Imprime el valor a la salida estándar.

La declaración fn main () se puede omitir en programas de un archivo. Esto es útil cuando se escriben pequeños programas, "scripts" o simplemente se aprende el lenguaje.

Esto significa que un programa "hello world" puede ser tan simple como :

println('hello world')

// Esto es un comentario

/* Y ahora que lo saben, veamos ejemplos
   /* y esto tambien se puede hacer ... */
*/

fn main() {
println(add(77, 33))
println(sub(100, 50))
}

fn add(x int, y int) int {
return x + y
}

fn sub(x, y int) int {
return x - y
}

//La Funciones pueden retornar múltiples valores.

fn foo() (int, int) {
return 2, 3
}

a, b := foo()
println(a) // 2
println(b) // 3

/* Las funciones, como consts y tipos, son privadas de forma predeterminada. Para permitir que otros módulos los usen, anteponga pub. */

pub fn public_function() {
}

fn private_function() {
}

Las variables se declaran e inicializan con: =. Esta es la única forma de declarar variables en V. Esto significa que las variables siempre tienen un valor inicial.

El tipo de la variable se infiere del valor en el lado derecho. Para forzar un tipo diferente, use la conversión de tipo.

A diferencia de la mayoría de los otros lenguajes, V solo permite definir variables en las funciones. No se permiten variables globales (nivel de módulo). No hay estado global en V.

Veamos ejemplos :

mut age := 20
println(age)
age = 21
println(age)

Para cambiar el valor de la variable podemos usar =. En V, las variables son inmutables por defecto. Para poder cambiar el valor de la variable, debe declararla con mut.

Tenga en cuenta la diferencia entre: = y =
: = se usa para declarar e inicializar, = se usa para asignar.

Puff me quedo largo el post, en un rato sigo...

Dejo link:
https://vlang.io/

sábado, 11 de enero de 2020

Empezando con Rust, parte 5

Vamos a hacer un pequeño juego en el cual el usuario elige un número y si es igual a un número que se calcula aleatoriamente, gana de otro modo pierde.


use std::io;
use rand::Rng;

fn main() {
    println!("Guess the number!");

    let secret_number = rand::thread_rng().gen_range(1, 101);

    println!("The secret number is: {}", secret_number);

    println!("Please input your guess.");

    let mut guess = String::new();

    io::stdin().read_line(&mut guess)
        .expect("Failed to read line");

    println!("You guessed: {}", guess);
}



Primero, importamos rand :: Rng que define los métodos que implementan los generadores de números aleatorios.

La función rand :: thread_rng nos dará el generador de números aleatorios en particular que vamos a utilizar: uno que sea local al hilo de ejecución actual y que el sistema operativo sembró. Luego llamamos al método gen_range en el generador de números aleatorios. El método gen_range toma dos números como argumentos y genera un número aleatorio entre ellos. Es inclusivo en el límite inferior pero exclusivo en el límite superior, por lo que debemos especificar 1 y 101 para solicitar un número entre 1 y 100.

La segunda línea que agregamos a la mitad del código imprime el número secreto. Esto es útil mientras desarrollamos el programa para poder probarlo, pero lo eliminaremos de la versión final.

Al Intenta ejecutar el programa varias veces:

$ cargo run
   Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
    Finished dev [unoptimized + debuginfo] target(s) in 2.53 secs
     Running `target/debug/guessing_game`
Guess the number!
The secret number is: 7
Please input your guess.
4
You guessed: 4
$ cargo run
     Running `target/debug/guessing_game`
Guess the number!
The secret number is: 83
Please input your guess.
5
You guessed: 5

Ahora que tenemos la entrada del usuario y un número aleatorio, podemos compararlos:

use std::io;
use std::cmp::Ordering;
use rand::Rng;

fn main() {

    println!("Guess the number!");

    let secret_number = rand::thread_rng().gen_range(1, 101);
   
    let mut guess = String :: new ();

    io :: stdin (). read_line (& mut guess) .expect ("Error al leer la línea");

    let guess: u32 = guesss.trim (). parse ().expect ("¡Escriba un número!");

    match guess.cmp(&secret_number) {
        Ordering::Less => println!("Too small!"),
        Ordering::Greater => println!("Too big!"),
        Ordering::Equal => println!("You win!"),
    }
}


Con : let guess: u32 = guesss.trim(). parse().expect ("¡Escriba un número!"); creamos una variable llamada guess. Pero espera, ¿el programa ya no tiene una variable llamada guess? Lo hace, pero Rust nos permite sobreescribir el valor anterior. Esta característica se usa a menudo en situaciones en las que desea convertir un valor de un tipo a otro. Esto nos permite reutilizar el nombre de la variable de guess en lugar de obligarnos a crear dos variables únicas, como por ejemplo, guess_str y guess.

Ojo, tenemos que hacer esto porque no podemos comparar números con String por lo que llevamos todo a números.

La expresión guesss.trim(). parse(). El método trim eliminará cualquier espacio en blanco al principio y al final.

Aquí podemos ver un tipo llamado std :: cmp :: Ordering que es de la biblioteca estándar. Ordering es otra enumeración, pero las variantes para Ordenar son Menor, Mayor e Igual. Estos son los tres resultados que son posibles cuando compara dos valores.

Veamos un ejemplo de lo que sucedería con la expresión de coincidencia utilizada aquí. Digamos que el usuario pone 50 y el número secreto generado aleatoriamente esta vez es 38. Cuando el código compara 50 a 38, el método cmp devolverá Ordering :: Greater, porque 50 es mayor que 38. La expresión de coincidencia obtiene el Ordering: : Mayor valor y comienza a verificar el patrón.

¡Ejecutemos el programa ahora!

$ cargo run
   Compiling guessing_game v0.1.0 (file:///projects/guessing_game)
    Finished dev [unoptimized + debuginfo] target(s) in 0.43 secs
     Running `target/debug/guessing_game`
Guess the number!
Please input your guess.
  76
You guessed: 76
Too big!

Y con este pequeño juego me despido hasta la próxima!

miércoles, 8 de enero de 2020

Quintos pasos en GIT


Seguimos con GIT. 

Supongamos que estás trabajando en alguna prestación, y que por alguna razón, necesitas volver a una versión vieja y poner temporalmente algunos ”print” para ver como funciona algo. Entonces:

$ git commit -a
$ git checkout HASH_SHA1

Ahora puedes agregar cualquier código temporal horrible por todos lados. Incluso puedes hacer commit de estos cambios. Cuando termines,

$ git checkout master

para volver a tu trabajo original. Observa que arrastrarás cualquier cambio del que no hayas hecho commit.

¿Que pasa si quisieras cambiar los cambios temporales? Fácil:

$ git checkout -b sucio

y haz commit antes de volver a la branch master. Cuando quieras volver a los cambios sucios, simplemente escribe:

$ git checkout sucio

Al fin podemos contar toda la historia:los archivos cambian al estado pedido, pero debemos dejar al branch master. Cualquier commit de aquí en adelante, llevan tus archivos por un nuevo camino, el podrá ser nombrado posteriormente.

En otras palabras, luego de traer un estado viejo, Git automáticamente te pone en una nueva branch sin nombre, la cual puede ser nombrada y salvada con git checkout -b.

Algunos proyectos requieren que tu código sea evaluado antes de que puedas subirlo. Para hacer la vida más fácil para aquellos que revisan tu código, si tienes algún cambio grande para hacer, puedes partirlo en dos o mas partes, y hacer que cada parte sea evaluada por separado.

¿Que pasa si la segunda parte no puede ser escrita hasta que la primera sea aprobada y subida? En muchos sistemas de control de versiones, deberías enviar primero el código a los evaluadores, y luego esperar hasta que esté aprobado antes de empezar con la segunda parte.

En realidad, eso no es del todo cierto, pero en estos sistemas, editar la Parte II antes de subir la Parte I involucra sufrimiento e infortunio. En Git, los branches y merges son indoloros (un termino técnico que significa rápidos y locales). Entonces, luego de que hayas hecho commit de la primera parte y la
hayas enviado a ser revisada:

$ git checkout -b parte2

Luego, escribe la segunda parte del gran cambio sin esperar a que la primera sea aceptada. Cuando la primera parte sea aprobada y subida,

$ git checkout master
$ git merge parte2
$ git branch -d parte2  # ya no se necesita esta branch

y la segunda parte del cambio está lista para la evaluación. ¡Pero esperen! ¿Qué pasa si no fuera tan simple? Digamos que tuviste un error en la primera parte, el cual hay que corregir antes de subir los cambios. ¡No hay problema! Primero, vuelve a la branch master usando

$ git checkout master

Soluciona el error en la primera parte del cambio y espera que sea aprobado. Si no lo es, simplemente repite este paso. Probablemente quieras hacer un merge de la versión arreglada de la Parte I con la Parte II:

$ git checkout parte2
$ git merge master

Ahora es igual que lo anterior. Una vez que la primera parte sea aprobada:

$ git checkout master
$ git merge parte2
$ git branch -d parte2

y nuevamente, la segunda parte está lista para ser revisada. Es fácil extender este truco para cualquier cantidad de partes.

Quizás quieras trabajar en todos los aspectos de un proyecto sobre la misma branch. Quieres dejar los trabajos-en-progreso para ti y quieres que otros vean tus commits solo cuando han sido pulcramente organizados. Inicia un par de branches:

$ git checkout -b prolijo
$ git checkout -b mezcla

A continuación, trabaja en lo que sea: soluciona bugs, agrega prestaciones, agrega código temporal o lo que quieras, haciendo commits seguidos a medida que avanzas. Entonces:

$ git checkout prolijo
$ git cherry-pick HASH_SHA1

aplica un commit dado a la branch ”prolijo”. Con cherry-picks apropiados, puedes construir una rama que contenga solo el código permanente, y los commits relacionados juntos en un grupo.



domingo, 5 de enero de 2020

Probando Fedora KDE


Bueno, reinstale mi notebook y opte por Fedora KDE. Por que? que se yo, estaba un tanto aburrido de las distros basadas en Debian, que son mis preferidas. Me daba curiosidad y KDE se ve cada vez mejor.

Que paso? Como puntos débiles tengo:

  • No pude hacer andar Samba 
  • El market place no es tan completo como otras distros, use mucho la consola para instalar cosas que en otras distros lo puedo hacer en unos cuantos clicks. 
  • Antes del login, por alguna razón demora minutos en levantar (si alguien me ayuda con esto sería genial)
  • En el centro de aplicaciones no vi ni skype, ni spotify, etc...


Puntos fuertes:

  • KDE la rompe, me gusto mucho, fácil de usar y rápido. 
  • Tiene un montón de herramientas para red y se siente orgánico. 
  • Es rápido y fachero
  • Me gusta!


Mi opinión personal es que Fedora crecería mucho más si le daría más bola a la usabilidad, es decir un tanto más amigable como Ubuntu. Y ustedes dirán, si dijiste que era fácil de usar, eso no es ser amigable? y yo les contestaría, si pero no solo eso... Le falta algo como para sentirte en tu casa, por ejemplo el centro de aplicaciones, no vi los comentarios de los usuarios muy fácilmente, para mandar el feedback de un error me pidio una cuenta a no se que y así...

Sin más dejo algunos screenshot y el link al final:






Dejo link: https://spins.fedoraproject.org/es/kde/