Apuntes de programación, algoritmos, pruebas, ejemplos o ejercicios resueltos para practicar o resolución de problemas relacionados con la programación
A continuación me gustaría compartirles una lista de canales de YouTube de programación que me he encontrado y que de algún modo u otro me han sido útiles esperando que también les sirvan a ustedes.
Hace poco me propuse hacer un cambio en mi sitio web para agregar mi portafolio y una versión resumida de mi CV. Y me encontré con que si buscas en google “portafolios de desarrolladores” irónicamente aparecen más artículos sobre que debe llevar tu portafolio que portafolios de colegas desarrolladores 😅; así que les quiero compartir algunos de los portafolios que me encontré.
Hace poco me surgió la necesidad de crear un plugin jQuery en el trabajo, pero la verdad es que es algo que jamás había hecho, aunque si he utilizado muchos a lo largo de mi carrera como desarrollador.
La verdad es que no fue algo muy difícil de hacer, aunque el método que utilice tal ves no sea el más óptimo, pero pude cubrir el requerimiento que tenia.
Código Base
Para crear nuestro plugin debemos utilizar el siguiente “esqueleto” como base, donde “MyPlugin” es el nombre del plugin que estamos desarrollando.
jQuery plugin skeleton
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
(function($){
$.fn.MiPlugin=function(){
returnthis.each(function(){
// Código del plugin
});
};
}(jQuery));
// Ejemplo
$('#nodo').MiPlugin();
Pasando Parámetros
Bien, ahora veremos como pasar parámetros a nuestro plugin. Para ello declararemos una constante con las opciones por defecto del plugin y con la función extend uniremos las opciones recibidas por defecto con las recibidas por parámetro.
Enviar párametros al plugin
JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
(function($){
$.fn.MiPlugin=function(opcionesUsuario){
// Opciones por defecto
constopcionesPorDefault={
opcion1:'opcionPorDefecto1',
opcion2:'opcionPorDefecto2',
debug:false
};
// Se mezclan las opciones por defecto con las del usuario
// Se imprimen en consola los valores de las opciones
if(opciones.debug){
console.log(opciones);
}
});
};
}(jQuery));
Si ejecutamos ahora nuestro plugin con la opción debug en true se imprimirán en consola las opciones que se utilizaran. Como se observa en la siguiente imagen dado que solo especificamos opcion1 y debug en los parámetros son los únicos valores que cambian de valor, opcion2 sigue teniendo el valor por defecto que se definió en el plugin.
Probando Nuestro Plugin
Bien, ahora haremos unos cambios en nuestro código para que nuestro plugin agregue un borde a los elementos seleccionados, quedando de la siguiente manera:
NOTA: Para simplificar el código se ha escrito todo en un solo archivo
// Se imprimen en consola los valores de las opciones
if(opciones.debug){
console.log(opciones);
}
});
};
}(jQuery));
</script>
<body>
<p id="p1">Parrafo 1</p>
<p id="p2">Parrafo 2</p>
</body>
</html>
Opciones por Defecto
Si ejecutamos nuestro plugin sin parámetros tendremos el siguiente resultado, ya que se aplican los valores por defecto.
Utilizando las opciones por defecto
Pasando Opciones por Parámetro
Ahora probemos pasando valores diferentes como parámetro y obtendremos lo siguiente.
Cambiando los valores por defecto
Cambiando el Selector CSS
Cabe mencionar que estamos usando el selector CSS ‘p’, y al haber 2 parrafos se aplica el borde a ambos parrafos, si solo quisiéramos aplicar el estilo al parrafo p1 lo hariamos cambiando el selector por ‘#p1’ y obtendriamos lo siguiente
En algunas ocasiones se necesita probar algún concepto o ver si es posible hacer algo de forma rápida.
Actualmente trabajo bastante con C# y dado que es molesto tener que crear un proyecto solo para probar algo sencillo y ejecutar el mastodonte que es Visual Studio solo para algo tan pequeño, encontré una solucion que se adapta este caso en especifico.
Se trata de dotnetfiddle.net, es un compilador online de C#, permite crear proyectos sencillos de Consola, MVC, Script y Nancy; entre sus opciones también permite seleccionar la versión de C# que queremos usar.
Esta herramienta me gusta bastante porque es bastante sencilla, permite crear snippets de código y probarlos desde el navegador, también puedes generar un enlace para compartirlo o incluso puedes trabajar al mismo tiempo sobre el mismo código con alguien más(esto último no lo he probado aún).
Para muestra un botón, sabia que existian los Extension Methods pero jamás los habia usado y me puse a revisar, ya que necesito formatear objetos DateTime a string pero quiero evitar el tener que escribir ToString(@”yyyy-MM-dd\THH:mm:ss”) cada vez que lo necesito, así que se me ocurrió intentar crear un Extension Method , así aprendia a usarlas y ademas me servia, ya que si en algun momento el formato de fecha que debo usar cambia, solo cambio el formato es la Extension Method.
En ocasiones me ha pasado que al querer actualizar o generar algún ADO.NET Entity Data Model en Visual Studio me ha aparecido este error:
Asi que hoy voy a compartirles la forma en que solucciono este problema.
Cerrar Visual Studio
Ejecutar la siguiente consulta en nuestra base de datos:
1
set globaloptimizer_switch='derived_merge=OFF';
Abrir nuestro proyecto en Visual Studio
Generar o actualizar nuestro modelo
Buscando en internet he visto que se pide que se reinicie el servicio de MySQL, en mi caso no ha sido necesario, antes al contrario, si lo hacia tenia que volver a ejecutar la consulta.
Cabe resaltar que lo he probado con MySQL 5.7.X en conjunto con EF6.
Por internet ronda el meme de que existen 2 tipos de desarrolladores, los que usan el tema claro y los que usan el tema oscuro.
En lo personal creo que me encuentro en la zona gris, donde el tema claro me gusta más pero llega a ser molesto y el tema oscuro me es algo incómodo al haber un contraste más alto entre el texto y el fondo del editor de código.
Recientemente utilizando Android Studio encontré el tema Cyan Light Theme que la verdad me gusto muchísimo y no me molesta en lo absoluto. Puedo trabajar durante el tiempo que sea necesario tranquilamente.
Pero la verdad es que en general paso más tiempo usando Visual Studio y al no haber encontrado un tema con el que me sintiera tan cómodo, decidí hacer mi “propia” versión para Visual Studio.
Cabe resaltar que en lo personal me gusta usar este estilo con el tema “Azul” de Visual Studio (que más bien se ve morado), dando como resultado algo como lo siguiente
Vista previa de Visual Studio con el Tema Cyan Light Theme
En mi trabajo se ofrece un punto de venta a tiendas pequeñas como incentivo para que adquieran los productos que ofrece mi empresa empleadora. Seguramente se estarán preguntando “Pero… ¿porqué usan SQLite para un punto de venta?”, la razón es que esta aplicación no se contempló como un sistema demasiado robusto, más bien buscaba cubrir una necesidad común de forma que fuera llamativo el consumir los productos que ofrece la empresa en la que trabajo.
Pero ya que este punto de venta se convirtió en un medio para hacer llegar anuncios o comunicados directamente a los clientes llegó al punto en que muy de ves en cuando la base de datos se bloqueaba, debido a que SQLite tiene la limitante de que solo soporta una conexión escribiendo en la base de datos. Además de que una de las nuevas funcionalidades que se requería agregar al punto de venta era que soportara múltiples usuarios, por lo que necesitábamos un nuevo motor de base de datos que soportara concurrencia.
Pero además ya existía una base de usuarios algo considerable, por lo que tener el soporte que implicaría cambiarlos a firebird podría requerir de mucho tiempo, así que tampoco era viable migrar a todos los usuarios a firebird, ya que la funcionalidad de múltiples usuarios de momento solo la usaría uno de nuestros clientes. Así que se necesitaba que el punto de venta trabajara con ambas bases de datos (pero solo una a la ves).
¿Porque Firebird 3?
Como dije antes, este punto de venta en realidad no era tan robusto, por lo que tener que agregar el instalador de MySQL que ocupa ~300MB no lo hacia el favorito.
Instalador de MySQL
Así que recordé que hay un punto de venta bastante grande y popular que utiliza Firebird… Microsip, así que revisé y Firebird tiene un tamaño bastante reducido de 12MB y así que se convirtió en la primera opción.
Instalador de Firebird
Descripción del Problema
Al revisar la clase que se encargaba de la persistencia de datos me topé con una clase de más de 6,500 lineas de código y al rededor de 140 funciones. Entonces analizando, la primera opción y la más “simple” seria copiar esta clase, cambiarle el nombre y comenzar a cambiar las consultas SQLite por consultas de Firebird.
POSDatabaseManager (Ejemplo)
Pero considerando que migrar de motor de base de datos no es algo que se deba tomar a la ligera (menos si tienes mas de 6,500 lineas de código y 140 funciones consultando datos). Decidí que además de crear una clase nueva con las consultas a Firebase, tenia que buscar la forma de que me fuera fácil cambiar de SQLite a Firebird.
Así que resumiendo, el problema al que nos enfrentamos a groso modo seria:
Implementar un mecanismo que nos permita que la aplicación pueda trabajar indistintamente tanto con SQLite como con Firebird.
¡Manos a la Obra!
Lo primero que vamos a hacer cambiar el nombre a la clase POSDatabaseManager a SQLiteDatabaseManager.
SQLiteDatabaseManager
Luego crearemos una interfaz llamada IDatabaseManager que implementará SQLiteDatabaseManager y copiamos las firmas de las funciones de SQLiteManager a la interfaz. Quedando de la siguiente manera:
Implementando IDatabaseManager para SQLite
Bien ahora, lo que hay que hacer es cambiar todas las referencias de SQLiteManager en la aplicacion por referencias a IDatabaseManager, compilamos y no debería existir ningún error.
Todo esto no altera el funcionamiento de la aplicación y además ya tenemos todo preparado para comenzar la migración a Firebird. ¿Como lo haremos? pues fácil, crearemos la clase FirebirdDatabaseManager que también implementará la interfaz IDatabaseManager.
Implementando FirebirdDatabaseManager
Ahora, solo resta implementar todas las funciones en la clase FirebirdDatabaseManager con sus respectivas consultas SQL para Firebird.
Bien, ahora, ¿como cambiamos de SQLite a Firebird o viceversa?, ¡Facil!, sería de la siguiente manera:
Con esto ya hemos terminado, ahora solo debemos recordar que cuando vayamos a usar el acceso a la base de datos SIEMPRE debemos utilizar referencias de la interfaz IDatabaseManager, de este modo a la aplicación le será indiferente si esta usando SQLite o Firebird.
Si se necesitara agregar alguna función nueva que acceda a la base de datos se debe declarar en IDatabaseManager de esta panera nos aseguramos de que se implemente tanto en SQLiteDatabaseManager como en FirebirdDatabaseManager.
Recientemente se me presentó la necesidad de desarrollar una aplicación Android, cosa que no había hecho nunca, aunque algo había visto en videos y tutoriales.
La aplicación requería la funcionalidad de “Recordar contraseña” y viendo en internet me topé con que para esto podía utilizar instancias de las clases SharedPreferences.Editor y SharedPreferences para guardar y recuperar datos respectivamente.
Y aunque es fácil de usar, la verdad es que se repetía bastante código y en algunas ocasiones se me olvidó llamar a la función apply() para guardar los cambios, como era de esperarse con alguien que no había hecho nada para Android.
Entonces, después de varias ocasiones en las que no entendía porque no se guardaban las preferencias, decidí hacer una Clase Helper para guardar y leer las preferencias. Lo que conseguí no es ni lo más eficiente ni lo más elegante, pero me funciona y creo que para alguien que antes no había hecho aplicaciones Android y mucho menos algo en Kotlin esta “decente”.
Para esto creé la clase AppPreferences que contiene un enumerado donde se pueden ir agregando las claves(keys) de los campos que vamos a guardar en las preferencias, para tener mejor control y sobre todo a evitar errores al guardar o leer las preferencias.
1
2
3
4
5
6
7
// Ejemplo del enumerado
classAppPreferences{
enumclassPreferences(varvalue:String){
MI_DATO_1("MI_DATO_1"),
MI_DATO_2("MI_DATO_2")
}
}
También dentro de AppPreferences declaré las clases Reader y Writer que fungen como wrapers para instancias de SharedPreferences y SharedPreferences.Editor respectivamente. Para la clase Reader solo hice funciones que simplemente retornan los valores de las preferencias, pero para la clase Writer hice funciones que guardan el dato que deseo almacenar y a su vez llaman a la función apply().
Guardé esta clase en Github Gist por si a alguien más le pudiera servir y/o es gustoso de contribuir a mejorarla, sin más les dejo el código de la clase.
Antes de cualquier cosa, primero debemos entender lo que es un algoritmo. Para ello nos vamos a ayudar de la definición que nos proporciona la RAE, que es la siguiente:
Conjunto ordenado y finito de operaciones que permite hallar la solución de un problema.
De ésta definición podemos destacar 3 características que debe cumplir cualquier algoritmo.
Las instrucciones, operaciones o pasos que seguirá nuestro algoritmo deben tener un orden o secuencia.
Todo algoritmo debe tener un final, es decir que el numero de pasos o instrucciones puede ser tan grande como lo necesitemos pero en algún punto debe detenerse su ejecución, independientemente de sí devuelve algún resultado o no.
Todo algoritmo debe resolver un problema, aunque yo en lo personal lo cambiaría a “Todo algoritmo debe realizar una tarea”, es decir, que cada algoritmo debe tener un propósito, que puede ir desde sumar dos números hasta calcular la trayectoria más corta entre dos lugares, etc, etc.
Aunque por lo general la palabra algoritmo se asocia a computadoras, en nuestro día a día realizamos tareas que ejecutando acciones en un determinado orden, como lo son: Preparar una taza de café, tomar una fotografía con nuestro teléfono celular o incluso conversar con alguien más. Cada una de estas tareas requiere que sigamos un numero finito de pasos y en un orden en específico para poder llevarlas a cabo.