Go y Golang

Leer archivo de texto con Go

En este post voy a explicar cómo leer el contenido de un archivo de texto usando Go. Es decir, obtener todo el contenido del archivo y pasarlo a una variable de tipo cadena o string.

De esta manera, se podrá imprimir el contenido de un archivo fácilmente. Se especifican dos formas: una en donde se lee todo el contenido de un archivo, y otra en donde, a través de un búfer, se leen fragmentos o bytes del archivo; especialmente cuando se trata de archivos o ficheros grandes.

Continue reading…

Conectar Go y MySQL. Crud y ejemplos de conexión

Conectar GoLang y MySQL

Hoy veremos cómo consumir una base de datos de MySQL o MariaDB (crear un CRUD) utilizando uno de mis lenguajes de programación favoritos: Go, también conocido como GoLang.

Lo que haremos será un CRUD a través de la consola; esto para mantener la simplicidad, pero recuerda que Go sirve para muchísimas cosas más (Sublime POS está escrito en Go).

Conectar Go y MySQL. Crud y ejemplos de conexión

Conectar Go y MySQL. Crud y ejemplos de conexión

Recuerda que para esto debes tener instalado MySQL, si lo deseas, puedes instalarlo con XAMPP. También recuerda instalar y configurar Go.

Por otro lado, te invito a leer algunos ejercicios de MySQL y cómo conectarte a la CLI del servidor MySQL.

Continue reading…

Servir fuera de la carpeta raíz

Servidor web completo en Go

Vamos a ver cómo crear un servidor web en el lenguaje de programación Go, también conocido como Golang. Lo que haremos será crear un servidor simple que responderá a peticiones GET, es decir, a las direcciones URL y que servirá archivos.

Explicado de otra manera, nuestro server hará esto:

  • Responder a peticiones dependiendo de la URL
  • Leer parámetros que pasamos por la URL
  • Servir un directorio y archivos, por ejemplo HTML, imágenes, vídeos, etcétera; algo así como lo hace el buen Apache o el servidor en Python.

No necesitaremos librerías extras ni frameworks, pues el maravilloso lenguaje provee todo lo que necesitamos.

Por cierto, si no lo tienes, mira cómo instalar Go en Windows.

Este tutorial es completo, explicaré a detalle cada cosa, te aseguro que aunque es un poco largo te enseñará lo robusto que es el lenguaje Go en cuanto a la web.

¿Interesado en algo más robusto? conoce mux.

Continue reading…

Algoritmo de búsqueda binaria en muchos lenguajes de programación

Introducción

Ya estamos aquí con una nueva serie de tutoriales. Esta vez el tema a tratar es la búsqueda binaria en un arreglo, tanto secuencial como recursiva o con recursión. También veremos cómo buscar sin importar si son números o cadenas.

Los enlaces a cada post están al final. Disfruta, comenta y comparte 🙂

Continue reading…

Búsqueda binaria recursiva Golang

Golang: algoritmo de búsqueda binaria

Introducción

Ya fue el turno de PHP, JavaScript, Java (con strings y números) y Python.

Hoy es el turno de uno de mis lenguajes de programación favoritos: Go. Veremos cómo se puede implementar la búsqueda binaria en los arreglos del lenguaje, tanto en cadenas como en números.

Al igual que en los otros ejercicios, veremos:

  • Búsqueda binaria recursiva en arreglos de números
  • Búsqueda binaria secuencial en arreglos de números
  • Implementación de búsqueda binaria recursiva en arreglos de strings o cadenas
  • Algoritmo de búsqueda binaria secuencial en arreglos de cadenas
Búsqueda binaria recursiva Golang

Búsqueda binaria recursiva Golang

Continue reading…

Formatear código fuente de Go con gofmt

Introducción

Go (también conocido como Golang) incorpora un formateador de código en el comando gofmt para, como su nombre lo dice, formatear código fuente de Go. Este comando le agrega indentaciones, espacios en donde son necesarios y cosas de esas. En resumen, hace el código bonito, algo así como beautifier.io hace con JavaScript.

Para usar este comando necesitamos tener instalado Go y agregar sus ejecutables a la variable PATH, justo como explico aquí.

Continue reading…

Solución a algoritmo para determinar número narcisista en muchos lenguajes

Introducción

Función esNarcisista en CPP

Función esNarcisista en CPP

Un número narcisista es aquel que es igual a la suma de cada uno de sus dígitos elevados a la “n” potencia (donde “n” es el número de cifras del número). La metáfora de su nombre alude a lo mucho que parecen “quererse a sí mismos” estas cifras. Por ejemplo, el 153 es un número narcisista puesto que 13 + 53 + 33 = 1 + 125 + 27 = 153. Los primeros números narcisistas son: 1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407, 1634, 8208, 9474 y 54748.

Fuente: Muy interesante

Solución al algoritmo para determinar si tenemos un número narcisista

Pero bueno, no vamos a ver la definición de un número narcisista porque si vienes buscando el algoritmo significa que ya sabes lo que es. Pues bien, aquí pondré la solución al algoritmo (que al final de cuentas es muy simple) en múltiples lenguajes de programación.

Si quieres que resuelva el algoritmo en otro lenguaje de programación eres libre de dejar un comentario 🙂

Algoritmo

Sin importar el lenguaje de programación, lo que tenemos que hacer es tomar la longitud del número. Esa longitud será a la que elevaremos cada cifra.

Luego recorremos todo el número, tomamos una cifra, la elevamos a la potencia mencionada anteriormente y el resultado lo vamos sumando a otra variable.

Al final comprobamos si la suma y el número que recibimos son iguales; en caso de que sí entonces el número es narcisista.

Soluciones

Por cierto, he puesto mi mayor esfuerzo para solucionar este ejercicio. Sin embargo no prometo que sean los métodos más rápidos (hablando de rendimiento en milisegundos y esas cosas); puede haber mejores. Lo que sí prometo es que:

  • Los algoritmos funcionan perfectamente y resuelven el problema
  • Siguen las mejores prácticas para que sean entendibles por seres humanos

Dicho esto, aquí está la lista.

  1. Número narcisista en JavaScript
  2. Número narcisista en C#
  3. Algoritmo programado en el lenguaje de programación C++
  4. Ejercicio resuelto en PHP
  5. Solución en Java
  6. Determinarlo con Go & Golang
  7. Algoritmo en Python
  8. Número narcisista en Rust

Recuerda que puedes pedir la implementación en otro lenguaje usando los comentarios.

Faker en Go: generador de datos falsos

Introducción

Hace algún tiempo desarrollé un seeder en Go, y para ello tuve que usar un faker o generador de datos falsos. Un faker, como yo lo defino, es algo que genera datos aleatorios falsos pero que parecen reales. Por ejemplo, generar un nombre como Marta Pérez Hernández o un número de teléfono como 2116258745. Pues hoy veremos un ejemplo de faker en Go.

Estos datos aunque parecen reales, no se sabe a ciencia cierta si lo son. Pero la mayoría de veces sirven para llenar bases de datos, así no nos quebramos la cabeza en inventar cosas.

Pues bien, hice un faker que genera nombres de productos, fechas entre años, números de teléfonos y nombres de personas. Está escrito en Go y no necesita ninguna librería adicional.

Faker en Go

Probar

He puesto este código en el Go Playground. Puedes ejecutarlo (haciendo click en Run) antes de ver el post: Click aquí

Por cierto, en el playground siempre dará los mismos resultados debido a la fecha y hora del servidor, pero si ejecutas el código en tu máquina por ti mismo debe funcionar correctamente.

Funcionamiento

Lo que hace este pequeño faker es tomar datos de un arreglo (tomándolos de manera aleatoria) y combinándolos. Por ejemplo, aquí tengo un arreglo de nombres masculinos:

nombresMasculinos := []string{"Aaron", "Adam", "Adrián", "Aitor", "Alberto", "Aleix", "Alejandro", "Alex", "Alonso", "Álvaro", "Ander", "Andrés",
		"Ángel", "Antonio", "Arnau", "Asier", "Biel", "Bruno", "Carlos", "César", "Cristian", "Daniel", "Dario", "David",
		"Diego", "Eduardo", "Enrique", "Eric", "Erik", "Fernando", "Francisco", "Francisco Javier", "Gabriel", "Gael", "Gerard", "Gonzalo",
		"Guillem", "Guillermo", "Héctor", "Hugo", "Ian", "Ignacio", "Iker", "Isaac", "Ismael", "Iván", "Izan", "Jaime",
		"Jan", "Javier", "Jesús", "Joel", "Jon", "Jordi", "Jorge", "José", "José Antonio", "José Manuel", "Juan", "Juan José",
		"Leo", "Lucas", "Luis", "Manuel", "Marc", "Marco", "Marcos", "Mario", "Martín", "Mateo", "Miguel", "Miguel Ángel",
		"Nicolás", "Oliver", "Omar", "Oriol", "Óscar", "Pablo", "Pedro", "Pol", "Rafael", "Raúl", "Rayan",
		"Roberto", "Rodrigo", "Rubén", "Samuel", "Santiago", "Saúl", "Sergio", "Unai", "Víctor", "Yago", "Yeray",}

Y hay otro arreglo de nombres femeninos (para que no se quejen las feministas):

nombresFemeninos := []string{"Abril", "Adriana", "Africa", "Aina", "Ainara", "Ainhoa", "Aitana", "Alba", "Alejandra", "Alexandra", "Alexia", "Alicia", "Alma",
		"Ana", "Andrea", "Ane", "Angela", "Anna", "Ariadna", "Aroa", "Aya", "Beatriz", "Berta", "Blanca", "Candela",
		"Carla", "Carlota", "Carmen", "Carolina", "Celia", "Clara", "Claudia", "Cristina", "Daniela", "Diana", "Elena", "Elsa",
		"Emma", "Erika", "Eva", "Fátima", "Gabriela", "Helena", "Inés", "Irene", "Iria", "Isabel", "Jana", "Jimena",
		"Joan", "Julia", "Laia", "Lara", "Laura", "Leire", "Leyre", "Lidia", "Lola", "Lucía", "Luna", "Malak",
		"Manuela", "Mar", "Mara", "María", "Marina", "Marta", "Martí", "Martina", "Mireia", "Miriam", "Nadia", "Nahia",
		"Naia", "Naiara", "Natalia", "Nayara", "Nerea", "Nil", "Noa", "Noelia", "Nora", "Nuria", "Olivia", "Ona",
		"Paola", "Patricia", "Pau", "Paula", "Raquel", "Rocío", "Salma", "Sandra", "Sara", "Silvia", "Sofía", "Teresa",
		"Valentina", "Valeria", "Vega", "Vera", "Victoria", "Yaiza", "Zoe",}

También hay apellidos.

Entonces con Go seleccionamos un número aleatorio que esté entre 0 y la longitud del arreglo. Para esto usamos Intn del paquete rand. Lo que hace esta función es que devuelve un número entre 0 y el argumento que le pasemos.

Por ejemplo, si llamamos a Intn con 5, puede dar un 0, un 1, un 2, 3 o 4. Pero cuidado aquí: no puede darnos un 5, pues devuelve el número en un intervalo [0, n) en donde, como recordemos, devolverá un número mayor o igual a 0 pero menor a n.

Entonces elegimos un dato aleatorio así:

nombre := nombres[seeder.Intn(len(nombres))]

Si tenemos 5 nombres, la función len devolverá 5, pero si intentamos acceder a esa posición (nombres[5]) marcará un error, pues los arreglos comienzan en 0. Así que está bien que usemos Intn, pues devolverá siempre un número menor al que le damos.

Muéstrame el código

Y bien, aquí el código. Es un struct, que podríamos abstraer como una clase.

package main

import (
	"fmt"
	"math/rand"
	"time"
)

type Faker struct {
	seed *rand.Rand
}

func (f *Faker) fechaAleatoriaEntreAnios(minimo, maximo int) time.Time {
	min := time.Date(minimo, 1, 0, 0, 0, 0, 0, time.UTC).Unix()
	max := time.Date(maximo, 1, 0, 0, 0, 0, 0, time.UTC).Unix()
	delta := max - min
	sec := f.seed.Int63n(delta) + min
	t := time.Unix(sec, 0)
	return t
}

func (f *Faker) numerosAleatorios(cuantos int) string {
	letras := "0123456789"
	b := make([]byte, cuantos)
	for i := range b {
		b[i] = letras[f.seed.Intn(len(letras))]
	}
	return string(b)
}

func (f *Faker) verdura() string {
	verduras := []string{"Jitomate", "Sandía", "Limón", "Tomate", "Zanahoria", "Papaya", "Piña", "Manzana", "Pera"}
	descriptores := []string{"Japonés", "Agrio", "Rojo", "Verde", "Fresco", "Bola", "Maradol", "Prémium"}
	return fmt.Sprintf("%s %s", verduras[f.seed.Intn(len(verduras))], descriptores[f.seed.Intn(len(descriptores))])
}

func (f *Faker) botana() string {
	nombres := []string{"Galletas chokis", "Sabritas", "Fritos", "Crujitos", "Doritos", "Rufles"}
	sabores := []string{"chocolate", "queso", "picante", "chorizo", "sal y limón", "habanero", "jalapeño"}
	return fmt.Sprintf("%s sabor %s %d gramos", nombres[f.seed.Intn(len(nombres))], sabores[f.seed.Intn(len(sabores))], f.seed.Intn(999))
}

func (f *Faker) refresco() string {
	nombres := []string{"Coca cola", "Pepsi", "Fanta", "Delaware punch", "Boing"}
	sabores := []string{"Guayaba", "Fresa", "Naranja", "Tamarindo", "Mango"}
	return fmt.Sprintf("%s %d ml sabor %s", nombres[f.seed.Intn(len(nombres))], f.seed.Intn(500), sabores[f.seed.Intn(len(sabores))])
}

func (f *Faker) electronico() string {
	nombres := []string{"Tableta", "Teléfono", "Computadora", "Procesador", "Mouse", "Teclado",}
	marcas := []string{"Samsung", "Xiaomi", "Nokia", "Blackberry", "Intel", "AMD", "Compaq", "HP", "Mac"}
	colores := []string{"Dorado", "Plateado", "Azul", "Blanco", "Rosa"}
	return fmt.Sprintf("%s %s color %s", nombres[f.seed.Intn(len(nombres))], marcas[f.seed.Intn(len(marcas))], colores[f.seed.Intn(len(colores))])
}

func (f *Faker) producto() string {
	numero := f.seed.Intn(4)
	switch numero {
	case 1:
		return f.verdura()
		break
	case 2:
		return f.botana()
		break
	case 3:
		return f.refresco()
		break
	case 4:
		return f.electronico()
		break
	}
	return f.electronico()
}

func (f *Faker) nombre() string {
	nombresMasculinos := []string{"Aaron", "Adam", "Adrián", "Aitor", "Alberto", "Aleix", "Alejandro", "Alex", "Alonso", "Álvaro", "Ander", "Andrés",
		"Ángel", "Antonio", "Arnau", "Asier", "Biel", "Bruno", "Carlos", "César", "Cristian", "Daniel", "Dario", "David",
		"Diego", "Eduardo", "Enrique", "Eric", "Erik", "Fernando", "Francisco", "Francisco Javier", "Gabriel", "Gael", "Gerard", "Gonzalo",
		"Guillem", "Guillermo", "Héctor", "Hugo", "Ian", "Ignacio", "Iker", "Isaac", "Ismael", "Iván", "Izan", "Jaime",
		"Jan", "Javier", "Jesús", "Joel", "Jon", "Jordi", "Jorge", "José", "José Antonio", "José Manuel", "Juan", "Juan José",
		"Leo", "Lucas", "Luis", "Manuel", "Marc", "Marco", "Marcos", "Mario", "Martín", "Mateo", "Miguel", "Miguel Ángel",
		"Nicolás", "Oliver", "Omar", "Oriol", "Óscar", "Pablo", "Pedro", "Pol", "Rafael", "Raúl", "Rayan",
		"Roberto", "Rodrigo", "Rubén", "Samuel", "Santiago", "Saúl", "Sergio", "Unai", "Víctor", "Yago", "Yeray",}

	nombresFemeninos := []string{"Abril", "Adriana", "Africa", "Aina", "Ainara", "Ainhoa", "Aitana", "Alba", "Alejandra", "Alexandra", "Alexia", "Alicia", "Alma",
		"Ana", "Andrea", "Ane", "Angela", "Anna", "Ariadna", "Aroa", "Aya", "Beatriz", "Berta", "Blanca", "Candela",
		"Carla", "Carlota", "Carmen", "Carolina", "Celia", "Clara", "Claudia", "Cristina", "Daniela", "Diana", "Elena", "Elsa",
		"Emma", "Erika", "Eva", "Fátima", "Gabriela", "Helena", "Inés", "Irene", "Iria", "Isabel", "Jana", "Jimena",
		"Joan", "Julia", "Laia", "Lara", "Laura", "Leire", "Leyre", "Lidia", "Lola", "Lucía", "Luna", "Malak",
		"Manuela", "Mar", "Mara", "María", "Marina", "Marta", "Martí", "Martina", "Mireia", "Miriam", "Nadia", "Nahia",
		"Naia", "Naiara", "Natalia", "Nayara", "Nerea", "Nil", "Noa", "Noelia", "Nora", "Nuria", "Olivia", "Ona",
		"Paola", "Patricia", "Pau", "Paula", "Raquel", "Rocío", "Salma", "Sandra", "Sara", "Silvia", "Sofía", "Teresa",
		"Valentina", "Valeria", "Vega", "Vera", "Victoria", "Yaiza", "Zoe",}

	apellidos := []string{"Abad", "Abeyta", "Abrego", "Abreu", "Acevedo", "Acosta", "Acuña", "Adame", "Adorno", "Agosto", "Aguado",
		"Aguayo", "Aguilar", "Aguilera", "Aguirre", "Alanis", "Alaniz", "Alarcón", "Alba", "Alcala", "Alcaráz", "Alcántar", "Alejandro",
		"Alemán", "Alfaro", "Alfonso", "Alicea", "Almanza", "Almaráz", "Almonte", "Alonso", "Alonzo", "Altamirano", "Alva", "Alvarado",
		"Amador", "Amaya", "Anaya", "Andreu", "Andrés", "Anguiano", "Angulo", "Antón", "Aparicio", "Apodaca", "Aponte", "Aragón",
		"Aranda", "Araña", "Arce", "Archuleta", "Arellano", "Arenas", "Arevalo", "Arguello", "Arias", "Armas", "Armendáriz", "Armenta",
		"Armijo", "Arredondo", "Arreola", "Arriaga", "Arribas", "Arroyo", "Arteaga", "Asensio", "Atencio", "Avilés", "Ayala", "Baca",
		"Badillo", "Baeza", "Bahena", "Balderas", "Ballesteros", "Banda", "Barajas", "Barela", "Barragán", "Barraza", "Barrera",
		"Barreto", "Barrientos", "Barrios", "Barroso", "Batista", "Bautista", "Bañuelos", "Becerra", "Beltrán", "Benavides",
		"Benavídez", "Benito", "Benítez", "Bermejo", "Bermúdez", "Bernal", "Berríos", "Blanco", "Blasco", "Blázquez", "Bonilla",
		"Borrego", "Botello", "Bravo", "Briones", "Briseño", "Brito", "Bueno", "Burgos", "Bustamante", "Bustos", "Báez", "Betancourt",
		"Caballero", "Cabello", "Cabrera", "Cabán", "Cadena", "Caldera", "Calderón", "Calero", "Calvillo", "Calvo", "Camacho",
		"Camarillo", "Campos", "Canales", "Candelaria", "Cano", "Cantú", "Caraballo", "Carbajal", "Carballo", "Carbonell",
		"Cárdenas", "Cardona", "Carmona", "Caro", "Carranza", "Carrasco", "Carrasquillo", "Carrera", "Carrero", "Carretero",
		"Carreón", "Carrillo", "Carrión", "Carvajal", "Casado", "Casanova", "Casares", "Casas", "Casillas", "Castañeda", "Castaño",
		"Castellano", "Castellanos", "Castillo", "Castro", "Casárez", "Cavazos", "Cazares", "Ceballos", "Cedillo", "Ceja", "Centeno",
		"Cepeda", "Cerda", "Cervantes", "Cervántez", "Chacón", "Chapa", "Chavarría", "Chávez", "Cintrón", "Cisneros", "Clemente",
		"Cobo", "Collado", "Collazo", "Colunga", "Colón", "Concepción", "Conde", "Contreras", "Cordero", "Cornejo", "Corona",
		"Coronado", "Corral", "Corrales", "Correa", "Cortés", "Cortez", "Cortés", "Costa", "Cotto", "Covarrubias", "Crespo",
		"Cruz", "Cuellar", "Cuenca", "Cuesta", "Cuevas", "Curiel", "Córdoba", "Córdova", "De la Cruz", "De la Fuente",
		"De la Torre", "Del Río", "Delacrúz", "Delafuente", "Delagarza", "Delao", "Delapaz", "Delarosa", "Delatorre", "Deleón",
		"Delgadillo", "Delgado", "Delrío", "Delvalle", "Díez", "Domenech", "Domingo", "Domínguez", "Domínquez", "Duarte",
		"Dueñas", "Duran", "Dávila", "Díaz", "Echevarría", "Elizondo", "Enríquez", "Escalante", "Escamilla", "Escobar", "Escobedo",
		"Escribano", "Escudero", "Esparza", "Espinal", "Espino", "Espinosa", "Espinoza", "Esquibel", "Esquivel", "Esteban", "Esteve",
		"Estrada", "Estévez", "Expósito", "Fajardo", "Farías", "Feliciano", "Fernández", "Ferrer", "Fierro", "Figueroa", "Flores",
		"Flórez", "Fonseca", "Font", "Franco", "Frías", "Fuentes", "Gaitán", "Galarza", "Galindo", "Gallardo", "Gallego", "Gallegos",
		"Galván", "Galán", "Gamboa", "Gámez", "Gaona", "Garay", "García", "Garibay", "Garica", "Garrido", "Garza", "Gastélum",
		"Gaytán", "Gil", "Gimeno", "Giménez", "Girón", "Godoy", "Godínez", "Gonzáles", "González", "Gracia", "Granado", "Granados",
		"Griego", "Grijalva", "Guajardo", "Guardado", "Guerra", "Guerrero", "Guevara", "Guillen", "Gurule", "Gutiérrez", "Guzmán",
		"Gálvez", "Gómez", "Haro", "Henríquez", "Heredia", "Hernándes", "Hernando", "Hernádez", "Hernández", "Herrera", "Herrero",
		"Hidalgo", "Hinojosa", "Holguín", "Huerta", "Hurtado", "Ibarra", "Ibáñez", "Iglesias", "Irizarry", "Izquierdo", "Jaime",
		"Jaimes", "Jaramillo", "Jasso", "Jiménez", "Jimínez", "Juan", "Jurado", "Juárez", "Jáquez", "Laboy", "Lara", "Laureano",
		"Leal", "Lebrón", "Ledesma", "Leiva", "Lemus", "Lerma", "Leyva", "León", "Limón", "Linares", "Lira", "Llamas", "Llorente",
		"Loera", "Lomeli", "Longoria", "Lorente", "Lorenzo", "Lovato", "Loya", "Lozada", "Lozano", "Lucas", "Lucero", "Lucio",
		"Luevano", "Lugo", "Luis", "Luján", "Luna", "Luque", "Lázaro", "López", "Macias", "Macías", "Madera", "Madrid", "Madrigal",
		"Maestas", "Magaña", "Malave", "Maldonado", "Manzanares", "Manzano", "Marco", "Marcos", "Mares", "Marrero", "Marroquín",
		"Martos", "Martí", "Martín", "Martínez", "Marín", "Más", "Mascareñas", "Mata", "Mateo", "Mateos", "Matos", "Matías",
		"Maya", "Mayorga", "Medina", "Medrano", "Mejía", "Melgar", "Meléndez", "Mena", "Menchaca", "Mendoza", "Menéndez",
		"Meraz", "Mercado", "Merino", "Mesa", "Meza", "Miguel", "Millán", "Miramontes", "Miranda", "Mireles", "Mojica", "Molina",
		"Mondragón", "Monroy", "Montalvo", "Montañez", "Montaño", "Montemayor", "Montenegro", "Montero", "Montes", "Montez",
		"Montoya", "Mora", "Moral", "Morales", "Morán", "Moreno", "Mota", "Moya", "Munguía", "Murillo", "Muro", "Muñiz", "Muñoz",
		"Márquez", "Méndez", "Naranjo", "Narváez", "Nava", "Navarrete", "Navarro", "Navas", "Nazario", "Negrete", "Negrón", "Nevárez",
		"Nieto", "Nieves", "Niño", "Noriega", "Nájera", "Núñez", "Ocampo", "Ocasio", "Ochoa", "Ojeda", "Oliva", "Olivares",
		"Olivas", "Oliver", "Olivera", "Olivo", "Olivárez", "Olmos", "Olvera", "Ontiveros", "Oquendo", "Ordoñez", "Ordóñez",
		"Orellana", "Ornelas", "Orosco", "Orozco", "Orta", "Ortega", "Ortíz", "Osorio", "Otero", "Ozuna", "Pabón", "Pacheco",
		"Padilla", "Padrón", "Pagan", "Palacios", "Palomino", "Palomo", "Pantoja", "Pardo", "Paredes", "Parra", "Partida",
		"Pascual", "Pastor", "Patiño", "Paz", "Pedraza", "Pedroza", "Pelayo", "Peláez", "Perales", "Peralta", "Perea", "Pereira",
		"Peres", "Peña", "Pichardo", "Pineda", "Pizarro", "Piña", "Piñeiro", "Plaza", "Polanco", "Polo", "Ponce", "Pons", "Porras",
		"Portillo", "Posada", "Pozo", "Prado", "Preciado", "Prieto", "Puente", "Puga", "Puig", "Pulido", "Páez", "Pérez", "Quesada",
		"Quezada", "Quintana", "Quintanilla", "Quintero", "Quiroz", "Quiñones", "Quiñónez", "Rael", "Ramos", "Ramírez",
		"Ramón", "Rangel", "Rascón", "Raya", "Razo", "Redondo", "Regalado", "Reina", "Rendón", "Rentería", "Requena", "Reséndez",
		"Rey", "Reyes", "Reyna", "Reynoso", "Rico", "Riera", "Rincón", "Riojas", "Rivas", "Rivera", "Rivero", "Robledo", "Robles",
		"Roca", "Rocha", "Rodarte", "Rodrigo", "Rodríguez", "Rodríquez", "Roig", "Rojas", "Rojo", "Roldán", "Rolón", "Romero",
		"Romo", "Román", "Roque", "Ros", "Rosa", "Rosado", "Rosales", "Rosario", "Rosas", "Roybal", "Rubio", "Rueda", "Ruelas",
		"Ruiz", "Ruvalcaba", "Ruíz", "Ríos", "Saavedra", "Saiz", "Salas", "Salazar", "Salcedo", "Salcido", "Saldaña", "Saldivar",
		"Salgado", "Salinas", "Salvador", "Samaniego", "Sanabria", "Sánchez", "Sancho", "Sandoval", "Santacruz", "Santamaría",
		"Santana", "Santiago", "Santillán", "Santos", "Sanz", "Sarabia", "Sauceda", "Saucedo", "Sedillo", "Segovia", "Segura",
		"Sepúlveda", "Serna", "Serra", "Serrano", "Serrato", "Sevilla", "Sierra", "Silva", "Simón", "Sisneros", "Sola", "Solano",
		"Soler", "Soliz", "Solorio", "Solorzano", "Solís", "Soria", "Soriano", "Sosa", "Sotelo", "Soto", "Suárez", "Sáenz",
		"Sáez", "Sánchez", "Tafoya", "Tamayo", "Tamez", "Tapia", "Tejada", "Tejeda", "Tello", "Terrazas", "Terán", "Tijerina",
		"Tirado", "Toledo", "Toro", "Torres", "Tovar", "Trejo", "Treviño", "Trujillo", "Téllez", "Tórrez", "Ulibarri", "Ulloa",
		"Urbina", "Ureña", "Uribe", "Urrutia", "Urías", "Vaca", "Valadez", "Valdez", "Valdivia", "Valdés", "Valencia",
		"Valentín", "Valenzuela", "Valero", "Valladares", "Valle", "Vallejo", "Valles", "Valverde", "Vanegas", "Varela",
		"Vargas", "Vega", "Vela", "Velasco", "Velásquez", "Velázquez", "Venegas", "Vera", "Verdugo", "Verduzco", "Vergara",
		"Vicente", "Vidal", "Viera", "Vigil", "Vila", "Villa", "Villagómez", "Villalba", "Villalobos", "Villalpando", "Villanueva",
		"Villar", "Villareal", "Villarreal", "Villaseñor", "Villegas", "Vásquez", "Vázquez", "Vélez", "Véliz", "Ybarra",
		"Yáñez", "Zambrano", "Zamora", "Zamudio", "Zapata", "Zaragoza", "Zarate", "Zavala", "Zayas", "Zelaya", "Zepeda",
		"Zúñiga", "de Anda", "de Jesús", "Águilar", "Álvarez", "Ávalos", "Ávila",}
	var nombre string
	if f.seed.Intn(2) == 1 {
		nombre = nombresFemeninos[f.seed.Intn(len(nombresFemeninos))]
	} else {
		nombre = nombresMasculinos[f.seed.Intn(len(nombresMasculinos))]
	}
	return fmt.Sprintf("%s %s %s", nombre, apellidos[f.seed.Intn(len(apellidos))], apellidos[f.seed.Intn(len(apellidos))])
}

Para usarlo simplemente creamos una instancia, le pasamos el seeder y listo. Así:

func main() {

	//Necesitamos alimentar el seeder sólo una vez antes de usarlo
	fuente := rand.NewSource(time.Now().Unix())
	random := rand.New(fuente)

	//Creamos una instancia y le pasamos la semilla para poder elegir cosas aleatorias
	faker := Faker{
		seed: random,
	}

	// Hora de usar el faker :-)
	fmt.Printf("Un producto: %s\n", faker.producto())

	//También se puede dentro de un ciclo
	for x := 0; x <= 10; x++ {
		fmt.Printf("Alguna fecha aleatoria entre 2010 y 2020: %v\n", faker.fechaAleatoriaEntreAnios(2010, 2020))
	}

	//Un nombre
	nombre := faker.nombre()
	fmt.Printf("El nombre: %s\n", nombre)

	//Número aleatorio. Como un número telefónico o un código de barras
	numero := faker.numerosAleatorios(10)
	fmt.Printf("Un número aleatorio de 10 dígitos: %s", numero)
}

En mi caso puse todo en el mismo archivo, y al ejecutarlo con go run faker.go obtengo esto:

Probando nuestro faker en Go

Probando nuestro faker en Go

Yo lo utilicé para un seeder y trabaja muy bien. Obviamente tiene algunos “errores” que podemos ver, por ejemplo, no hay tabletas AMD, pero como lo dije, es un faker: datos falsos.

Espero mejorarlo con el tiempo.

 

Obtener lista de impresoras compartidas en Windows usando Golang

Introducción

Trabajando en un proyecto con Go, tuve que obtener la lista de impresoras compartidas en Windows. Básicamente hacer lo mismo que ya hice aquí con PHP.

Ahora le tocó el turno a Go, y aunque al principio no fue fácil, lo conseguí.

Hace falta mencionar que utilicé un método distinto, que por el momento sólo he probado en Windows 10 pero bueno, ¿quién usa un Windows atrasado en pleno 2018? aunque creo que funciona hasta en Windows 7.

Nota: si no quieres leer todo el proceso, simplemente ve hasta abajo en donde está la función final.

Comando

Lo que tenemos que hacer es ejecutar el siguiente comando en Windows:

cmd /C wmic printer get name

Que nos da una salida como esta:

Esto es muy, muy fácil. Lo complicado es:

  1. Ejecutar el comando en Go
  2. Obtener la salida
  3. Limpiar la salida

Veamos cómo hacerlo 🙂

Código fuente en Go

Simplemente ejecutamos el comando, aquí vino la primer cosa difícil, pues hay que pasar todos los argumentos separados, no juntos.

Es decir, no hay que hacer esto:

  salida, err := exec.Command("cmd", "/C wmic printer get name").Output()

Sino esto:

  salida, err := exec.Command("cmd", "/C", "wmic", "printer", "get", "name").Output()

Esperamos la salida y la convertimos a cadena. Hora de convertirla a un array de tipo string.

El primer problema fue que Windows trata los saltos de línea como \r en lugar de \n. Al principio tuve que hacer un split con \n pero no funcionaba, entonces imprimí la cadena con fmt.Printf y el formateador %q, en donde me di cuenta de que utilizaba \r\r\n.

Así que quedó así:

salidaCadena := string(salida)
listaDeImpresoras := strings.Split(salidaCadena, "\r\r\n")

Pero incluso después de eso tenía que remover los espacios. Así que en un ciclo for recorrí el ciclo, limpié el nombre (con TrimRight para remover los espacios en blanco) y omití los vacíos o aquellos que dijeran “Name”, pues “Name” es el encabezado del comando.

var listaDeImpresorasLimpias []string
  for _, impresora := range listaDeImpresoras {
    nombreLimpio := strings.TrimRight(impresora, " ")
    if len(nombreLimpio) > 0 && nombreLimpio != "Name" {
      listaDeImpresorasLimpias = append(listaDeImpresorasLimpias, nombreLimpio)
    }
  }

Listo. Al final encerré todo en una función y se ve así:

func obtenerListaDeImpresorasCompartidasWindows() []string {
  salida, err := exec.Command("cmd", "/C", "wmic", "printer", "get", "name").Output()
  if err != nil {
    log.Fatal(err)
  }
  salidaCadena := string(salida)
  listaDeImpresoras := strings.Split(salidaCadena, "\r\r\n")
  var listaDeImpresorasLimpias []string
  for _, impresora := range listaDeImpresoras {
    nombreLimpio := strings.TrimRight(impresora, " ")
    if len(nombreLimpio) > 0 && nombreLimpio != "Name" {
      listaDeImpresorasLimpias = append(listaDeImpresorasLimpias, nombreLimpio)
    }
  }
  return listaDeImpresorasLimpias
}

Fabuloso. No olvides importar log, os/exec y strings.

Formatear moneda o dinero en Golang

Introducción

Hoy veremos cómo formatear un número en Go de manera que se pueda representar como moneda o dinero.

En otras palabras, veremos cómo convertir un número (como 1523.625) en una cadena como $1, 523.62.

Si quieres saber cómo hacerlo con VueJS aquí dejo un tutorial para ver cómo filtrar moneda o dinero en VueJS.

Recuerda que debes tener instalado Go, aquí un tutorial.

Formatear dinero en Golang con Accounting

Para formatear los números como si de dinero se tratara, vamos a utilizar una librería inspirada en accounting.js (que es para Javascript) para Go.

Tenemos que instalarla, así que ejecutamos:

go get github.com/leekchan/accounting

Esperamos a que termine de instalar y proseguimos con el código de ejemplo.

Código de ejemplo

El repositorio en GitHub ya proporciona muchos ejemplos, pero aquí escribiré otro. En este caso formatearemos de tal manera que se represente como se hace en mi país (México).

El signo que utilizaremos será el $. De ahí, para separar miles utilizamos la coma y para separar decimales utilizamos el punto.

Vamos a formatear el número 2811.96.

package main

import (
	"fmt"

	"github.com/leekchan/accounting"
)

func main() {
	ac := accounting.Accounting{
		Symbol:    "$", //El símbolo
		Precision: 2,   // ¿Cuántos "centavos" queremos? (también llamado precisión)
		Thousand:  ",", //Separador de miles
		Decimal:   ".", //Separador de decimales

	}
	numero := 2811.96
	numeroComoDinero := ac.FormatMoney(numero)
	fmt.Printf("El número %f fue convertido a %s", numero, numeroComoDinero)
}

Como podemos ver, instanciamos a Accounting. Para crearlo, le pasamos algunas propiedades.

El código está comentado, así que no falta explicar otra cosa. Lo que sí hace falta mencionar es que Thousand y Decimal ya tienen la coma y el punto por defecto, lo puse de esta manera para ejemplificar, por lo que no es necesario que nosotros lo definamos si así estamos bien.

Al ejecutar el código, sale esto:

Una vez instanciado, podemos reutilizarlo para formatear todo lo que deseemos.

Veamos otro ejemplo en donde formateamos e imprimimos un arreglo de números.

El código queda así:

package main

import (
	"fmt"

	"github.com/leekchan/accounting"
)

func main() {
	ac := accounting.Accounting{
		Symbol:    "$", //El símbolo
		Precision: 2,   // ¿Cuántos "centavos" queremos? (también llamado precisión)
		Thousand:  ",", //Separador de miles
		Decimal:   ".", //Separador de decimales

	}
	numeros := []float64{500, 51.63, 0.36, 896.6945, 539853.6625}
	for _, numero := range numeros {
		numeroComoDinero := ac.FormatMoney(numero)
		fmt.Printf("El número %f fue convertido a %s\n", numero, numeroComoDinero)
	}
}

 

Con la siguiente salida:

Finalmente cabe mencionar que el autor de la librería recomienda no utilizar flotantes, y mejor usar big.Float.