tag:blogger.com,1999:blog-44510993180874888912024-03-13T22:54:59.980+01:00Invalid ExpressionBlog dedicado a tecnología y programación. Haremos un repaso los lenguajes de progamación existentes, así como a la historia de los mismos. Miguelhttp://www.blogger.com/profile/16782448155425363883noreply@blogger.comBlogger34125tag:blogger.com,1999:blog-4451099318087488891.post-89873983177768795062021-09-04T13:49:00.000+02:002021-09-04T13:49:05.018+02:00Reseña de "Acelerar" La ciencia del desarrollo Lean y Devops<p>Cuando empiezas a adentrarte en el mundo Devops e investigas un poco, uno de los primeros autores que aparecerá en tu buscador es <a href="https://itrevolution.com/the-idealcast-podcast/" target="_blank">Gene Kim</a>.</p><p>Entre los títulos de Kim, constan grandes referentes como "The Phoenix Project", "The Unicorn Project" y este "Acelerar" o "Accelerate" si lo buscáis en inglés y que es sobre el que os voy a escribir hoy.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-o7DehId3bL8/YTNQ_fGHrUI/AAAAAAAAX3U/9SPWAzqjj-8z6wgG8DuiMUXAgPbVvWesACNcBGAsYHQ/s344/acelerar.jpg" style="margin-left: 1em; margin-right: 1em;"><img alt="Acelerar" border="0" data-original-height="344" data-original-width="229" height="320" src="https://1.bp.blogspot.com/-o7DehId3bL8/YTNQ_fGHrUI/AAAAAAAAX3U/9SPWAzqjj-8z6wgG8DuiMUXAgPbVvWesACNcBGAsYHQ/w213-h320/acelerar.jpg" title="Acelerar" width="213" /></a></div><br /><p style="text-align: justify;">En este libro participan, además, la <a href="https://nicolefv.com/" target="_blank">Dra. Nicole Forsgren</a> y <a href="https://keybase.io/jezhumble" target="_blank">Jez Humble</a>; ambos son reconocidas figuras en el mundo Devops, la investigación y el SRE (Site Reliability Engineering) y, junto con el antes mencionado Gene Kim, nos traen un libro de investigación donde nos presentan como medir el rendimiento de los equipos y en que enfocarse para obtener un rendimiento mayor en el desarrollo y entrega de software.</p><h2 style="text-align: left;">La estructura del libro.</h2><p style="text-align: justify;">Acelerar está estructurado en tres partes bien diferenciadas. En la primera parte, se presentara lo que encontraron en la encuesta. En primer lugar, explica por qué el rendimiento de la entrega de software es importante y cómo impulsar las tareas de medidas de rendimiento organizacional (como la rentabilidad, la productividad y la participación de mercado) además de las medidas no comerciales (como la eficiencia, la eficacia, la satisfacción del cliente y el logro).</p><p style="text-align: justify;">En la segunda parte, resume la ciencia detrás de la investigación y aclara las decisiones de diseño que se toman y los métodos de análisis utilizados. Esto proporciona la base para los resultados que se describen en la mayoría de los textos. También identifican características clave que contribuyen al rendimiento de la entrega de software de una manera estadísticamente significativa y relevante. </p><p style="text-align: justify;">En la tercera parte, concluye con una explicación sobre la gestión del cambio organizacional. Este capítulo ofrece una visión en profundidad de cómo es seguir las capacidades y prácticas descritas en este libro, y lo que puede ofrecer a las organizaciones innovadoras.</p><h2 style="text-align: left;">Mi opinión.</h2><p style="text-align: justify;">"Acelerar" me ha resultado un libro muy revelador en cuanto a como medir el rendimiento de una organización. Es bastante probable que use muchos de sus preceptos en mi trabajo diario. Aunque la segunda parte me ha resultado bastante tediosa al presentar, en mi opinión, demasiados datos estadísticos y de evaluación. Entiendo que este capítulo es importante y le da validez al contenido del libro, yo lo utilizaría más como un recurso de referencia rápida que como de lectura continua.</p><p style="text-align: justify;">En definitiva, "Acelerar" debería estar en la biblioteca de cualquiera que pretenda llevar a cabo una transformación en su organización con objetivo de aumentar el rendimiento del desarrollo de software.</p><p style="text-align: justify;"><span style="text-align: center;">Podéis adquirir el libro mediante mi enlace de afiliado y, de paso, ¡me ayudáis a continuar con el blog!</span></p><p style="text-align: center;"><iframe frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="https://rcm-eu.amazon-adsystem.com/e/cm?ref=tf_til&t=mcpmontero-21&m=amazon&o=30&p=8&l=as1&IS1=1&asins=8441543593&linkId=40e9c56740ac501b852d1e1996edd0be&bc1=ffffff&lt1=_top&fc1=333333&lc1=0066c0&bg1=ffffff&f=ifr" style="height: 240px; width: 120px;">
</iframe> </p><p></p><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><br /></div><br /><br /></div><br /><p></p>Miguelhttp://www.blogger.com/profile/16782448155425363883noreply@blogger.com0tag:blogger.com,1999:blog-4451099318087488891.post-50067698883589842702021-01-01T13:41:00.002+01:002021-01-02T14:32:37.676+01:00Truco Kubernetes - 3 métodos para reiniciar tus pods<p style="text-align: left;"><span style="text-align: justify;">Digamos que uno de los pods de tu cluster está reportando un error. Dependiendo de las políticas de reinicio, Kubernetes podría intentar reiniciar automáticamente el pod y hacerlo funcionar de nuevo. Sin embargo, esto no siempre soluciona el problema.</span></p><p style="text-align: justify;">Si K8s no puede arreglar el problema por si mismo, y no podemos encontrar el origen del error de manera inmediata, reiniciar el pod es la manera mas rápida de hacer que tu aplicación funcione de nuevo.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-KLKK_AtI4nA/X-8Xd1Yq3HI/AAAAAAAAXcs/3tL9bJzYpB4yt4Sgg20ZrFdMqlLoRhB9QCNcBGAsYHQ/s1200/kubernetes-logo.jpg" style="margin-left: 1em; margin-right: 1em;"><img alt="logo kubernetes" border="0" data-original-height="600" data-original-width="1200" height="160" src="https://1.bp.blogspot.com/-KLKK_AtI4nA/X-8Xd1Yq3HI/AAAAAAAAXcs/3tL9bJzYpB4yt4Sgg20ZrFdMqlLoRhB9QCNcBGAsYHQ/w320-h160/kubernetes-logo.jpg" width="320" /></a></div><p style="text-align: justify;">Podrás pensar que una solución es volver a arrancar el ciclo CI/CD de esa aplicación (si lo tienes), pero este puede ser un proceso mas lento de lo deseable y, en cualquier caso, no solucionaría el problema de base, así que a continuación te muestro 3 métodos para reiniciar rápidamente tus pods.</p><h3 style="text-align: left;">Método 1: Rolling Restart</h3><p>Este es el método más rápido. Está disponible desde la 1.15 y consiste en decirle a tu K8s que reinicie un deploy concreto.</p>
<pre class="prettyprint"><code class="language-bash">kubectl rollout restart deployment [deployment_name]</code></pre>
<div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-SD4to3YYkgs/X-8Q3g9xNAI/AAAAAAAAXcI/7NxhvsTjUI4mEeFzJPMyO2rJHjfaPR2BgCNcBGAsYHQ/s705/kubectlrolloutrestart.png" style="margin-left: 1em; margin-right: 1em;"><img alt="Kubectl rollout restart" border="0" data-original-height="326" data-original-width="705" height="296" src="https://1.bp.blogspot.com/-SD4to3YYkgs/X-8Q3g9xNAI/AAAAAAAAXcI/7NxhvsTjUI4mEeFzJPMyO2rJHjfaPR2BgCNcBGAsYHQ/w640-h296/kubectlrolloutrestart.png" width="640" /></a></div><br /><h3 style="text-align: left;">Método 2: Utilizando variables de entorno</h3><p>Otro método es establecer o modificar una variable de entorno para forzar el reinicio del pod y la sincronización de los cambios que has realizado</p><p>Por ejemplo, puedes cambiar la fecha de despliegue (deployment date)</p>
<pre class="prettyprint"><code class="language-bash">kubectl set env deployment [deployment_name] DEPLOY_DATE="$(date)"</code></pre>
<div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-u1DHeMvWtYE/X-8S-b465rI/AAAAAAAAXcU/dLYT2PidJSokZCQrx-HcwIOWGsOsZyVcQCNcBGAsYHQ/s841/kubectlsetenv.png" style="margin-left: 1em; margin-right: 1em;"><img alt="kubectl set env" border="0" data-original-height="275" data-original-width="841" height="210" src="https://1.bp.blogspot.com/-u1DHeMvWtYE/X-8S-b465rI/AAAAAAAAXcU/dLYT2PidJSokZCQrx-HcwIOWGsOsZyVcQCNcBGAsYHQ/w640-h210/kubectlsetenv.png" width="640" /></a></div><br /><h3 style="text-align: left;">Método 3: Escalar el número de replicas</h3><p>Por último podemos usar el comando scale para cambiar el numero de replicas del pod con problemas. Establecerlo a 0 básicamente "apaga" el pod.</p>
<pre class="prettyprint"><code class="language-bash">kubectl scale deployment [deployment_name] --replicas=0</code></pre>
<p>Posteriormente podemos aumentar este número de replicas para hacer que el pod se arranque de nuevo.</p>
<pre class="prettyprint"><code class="language-bash">kubectl scale deployment [deployment_name] --replicas=1</code></pre>
<div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-gOlaSwW3ayo/X-8UhA0iKwI/AAAAAAAAXcg/48aLRV9SL14w2xgMXTRkdv8iwaA0MSmxgCNcBGAsYHQ/s795/kubectlscale.png" style="margin-left: 1em; margin-right: 1em;"><img alt="kubectl scale deployment" border="0" data-original-height="650" data-original-width="795" height="524" src="https://1.bp.blogspot.com/-gOlaSwW3ayo/X-8UhA0iKwI/AAAAAAAAXcg/48aLRV9SL14w2xgMXTRkdv8iwaA0MSmxgCNcBGAsYHQ/w640-h524/kubectlscale.png" width="640" /></a></div><div><br /></div><h3 style="text-align: left;">En conclusión</h3><p style="text-align: justify;">Kubernetes es un sistema extremadamente útil, pero como cualquier otro sistema, no está libre de fallos.</p><p style="text-align: justify;">Cuando ocurren problemas, puedes utilizar uno de los tres métodos enumerados anteriormente para que tu aplicación funcione de manera rápida y segura sin cerrar el servicio para los clientes.</p><p style="text-align: justify;">Después de reiniciar los pods, tendrás tiempo para encontrar y solucionar la verdadera causa del problema.</p><p style="text-align: justify;">¿conoces algún otro método para reiniciar los pods? Compártelo aquí debajo junto con cualquier duda que te surja.</p>Miguelhttp://www.blogger.com/profile/16782448155425363883noreply@blogger.com1tag:blogger.com,1999:blog-4451099318087488891.post-48383755167972769072020-12-23T23:34:00.004+01:002020-12-23T23:48:55.551+01:00Truco JavaScript - 5 métodos para convertir cadenas a números que no sabías<p style="text-align: justify;">Hoy toca un poquito de JavaScript y he pensado que sería interesante mostraros algunas técnicas utilizadas en JS para convertir cadenas en números.</p><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-xNnOLKD2sg0/X-PHlDpUHyI/AAAAAAAAXbc/GtKY19feF9ElBnA7AZ6TUzfzKIrKMPZYQCNcBGAsYHQ/s300/javascript_logo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="300" data-original-width="300" height="142" src="https://1.bp.blogspot.com/-xNnOLKD2sg0/X-PHlDpUHyI/AAAAAAAAXbc/GtKY19feF9ElBnA7AZ6TUzfzKIrKMPZYQCNcBGAsYHQ/w142-h142/javascript_logo.png" width="142" /></a></div><h2 style="text-align: justify;">Convertir cadenas a números.</h2><div style="text-align: justify;">JavaScript provee funciones para transformar fácilmente cadenas a numero primitivos.</div><p></p><ul style="text-align: left;"><li style="text-align: justify;"><span style="background-color: #fce5cd;"><b>.parseInt()</b></span> con una cadena como primer argumento y una base opcional sobre la que quieres convertir la cadena. Siempre devuelve un entero.</li><li style="text-align: justify;"><b style="background-color: #fce5cd;">.parseFloat()</b> desde una cadena devuelve un número en coma flotante equivalente.</li><li style="text-align: justify;"><b style="background-color: #fce5cd;">Math.floor()</b> se utiliza para redondear un flotante al entero más cercano redondeando a la baja.</li><li style="text-align: justify;"><b><span style="background-color: #fce5cd;">Math.ceil()</span> </b>similar al anterior pero redondeando al alza.</li><li style="text-align: justify;"><b style="background-color: #fce5cd;">Operador unario</b> añadiendo un signo positivo + antes de la cadena, se convertirá en número si el formato es correcto.</li><li style="text-align: justify;"><b style="background-color: #fce5cd;">Multiplicación por 1</b> si multiplicamos una cadena por 1, esta se convierte en un número </li></ul><div style="text-align: justify;">Seguramente conocías algunos de estos métodos y otros (como me pasó a mi con Math.floor y Math.ceil) te habrán sorprendido, pero pasemos a los ejemplos</div><div style="text-align: justify;"><br /></div>
<h3 style="text-align: left;">.parseInt()</h3><pre class="prettyprint"><code class="language-js">let str = '353';
let fltStr = '353.56';
let binStr = '7';
let nanStr = 'hola';
parseInt(str); // 353
parseInt(fltStr); // 353
parseInt(binStr, 2); // 111 (Binario)
parseInt(nanStr); // NaN (Not a Number)</code>
</pre>
<h3 style="text-align: left;">.parseFloat()</h3><pre class="prettyprint"><code class="language-js">let str = '100';
let fltStr = '100.21';
let nanStr = 'bye';
parseFloat(str); // 100
parseFloat(fltStr); // 100.21
parseFloat(nanStr); // NaN</code>
</pre>
<h3 style="text-align: left;">Math.floor()</h3><pre class="prettyprint"><code class="language-js">let str = '100';
let fltStr = '99.89';
let nanStr = 'bye';
Math.floor(str); // 100
Math.floor(fltStr); // 99
Math.floor(nanStr); // NaN</code>
</pre>
<h3 style="text-align: left;">Math.ceil()</h3><pre class="prettyprint"><code class="language-js">let str = '100';
let fltStr = '100.21';
let nanStr = 'bye';
Math.ceil(str); // 100
Math.ceil(fltStr); // 101
Math.ceil(nanStr); // NaN</code>
</pre>
<h3 style="text-align: left;">Operador unario</h3><pre class="prettyprint"><code class="language-js">let str = '100';
let fltStr = '100.21';
let nanStr = 'greetings';
+str // 100
+fltStr // 100.21
+nanStr // NaN
+'1000' // 1000
+10.25 // 10.25</code>
</pre>
<h3 style="text-align: left;">Multiplicar por 1</h3><pre class="prettyprint"><code class="language-js">let str = '100';
let fltStr = '100.21';
let nanStr = 'greetings';
str * 1; // 100
fltStr * 1; // 100.21
nanStr * 1; // NaN
'2000' * 1; // 2000
'102.15' * 1; // 102.15</code>
</pre>
<div style="text-align: left;"><p><br /></p></div><div style="text-align: left;"><br /></div><div>Si tienes cualquier duda o comentario recuerda que puedes exponerlo aquí o bien mediante nuestro <a href="http://twitter.com/InvExpression" target="_blank">twitter </a>y <a href="https://www.facebook.com/InvExpression" target="_blank">facebook</a>.</div><div><br /></div><div><br /></div><p></p>Miguelhttp://www.blogger.com/profile/16782448155425363883noreply@blogger.com0tag:blogger.com,1999:blog-4451099318087488891.post-33946382737968129752020-12-22T23:20:00.011+01:002020-12-23T12:21:58.664+01:00ODroid Go Super. Nueva ODroid "Switch" con Ubuntu.<p>Ya se ha anunciado la nueva ODroid Go Super, una "pequeña" vuelta de tuerca a lo que es ODroid Go Advance.</p><p>A muchos nos encanta el aspecto de Nintendo Switch. El cómo se siente en las manos es muy satisfactorio para la mayoría de los que la hemos probado. Si eres de los que les gusta este feeling, pero prefieres jugar en Linux, esta pequeña maravilla te va a encantar.</p><h2 style="text-align: left;">ODroid-Go Super</h2><p>Esta mañana del 22 de diciembre podíamos leer <a href="https://forum.odroid.com/viewtopic.php?f=187&t=41283" target="_blank">el siguiente anuncio</a> en el foro de odroid del que os dejamos este pequeño extracto traducido...</p><p></p><blockquote><p style="text-align: justify;"><i>Anunciamos ODROID-Go en 2018 para celebrar nuestro décimo cumpleaños. En diciembre de 2019, anunciamos ODROID-Go Advance (OGA).</i></p><p style="text-align: justify;"><i>Ahora es el momento de presentar un nuevo dispositivo de juegos para desarrolladores para 2021.</i></p><p style="text-align: justify;"><i>Hemos actualizado el diseño del hardware OGA y lo llamamos OGS (ODROID-Go Super).</i></p><p style="text-align: justify;"><i>El tamaño de la pantalla LCD cambió de 3,5 pulgadas a 5 pulgadas con una cubierta de vidrio templado. La resolución cambió de 480x320 a 854x480 píxeles.</i></p><p style="text-align: justify;"><i>Sabemos que muchos fanáticos de los juegos retro quieren una pantalla con una relación de aspecto de 4:3, pero no pudimos encontrar ningún fabricante de LCD que pueda construir una pantalla de 4 a 5 pulgadas con una relación de 4:3.</i></p><p style="text-align: justify;"><i>La capacidad de la batería también ha aumentado alrededor de un 30%. El OGA tenía una batería de 3000 mAh, mientras que este nuevo OGS tiene una batería de 4000 mAh.</i></p><p style="text-align: justify;"><i>Puede jugar juegos continuamente durante varias horas dependiendo del brillo de la luz de fondo.</i></p><p style="text-align: justify;"><i>Además, se realizaron otros cambios importantes de hardware. Agregamos un segundo joystick analógico y botones de volumen dedicados.</i></p><p style="text-align: justify;"><i>El OGS ahora viene preensamblado en nuestra fábrica en lugar de ser un kit ensamblado de bricolaje.</i></p><p style="text-align: justify;"><i>Dado que no hay una conectividad inalámbrica incorporada, se mejoró la compatibilidad con un USB WIFI + BT.</i></p><p style="text-align: justify;"><i>Finalmente, la ranura para tarjetas micro-SD ha cambiado a tipo push-push (expulsión de resorte) de push-pull.</i></p><p></p></blockquote><p style="text-align: justify;"><br /></p><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-ncBliyp0a6Y/X-JrfWz9wQI/AAAAAAAAXa4/ICFybc0rFsw45mDLqyB4H9hU__4-hBHVwCNcBGAsYHQ/s800/odroid1.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="390" data-original-width="800" height="312" src="https://1.bp.blogspot.com/-ncBliyp0a6Y/X-JrfWz9wQI/AAAAAAAAXa4/ICFybc0rFsw45mDLqyB4H9hU__4-hBHVwCNcBGAsYHQ/w640-h312/odroid1.png" width="640" /></a></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: left;"><div class="separator" style="clear: both; text-align: justify;">ODroid Go Super es una versión más grande y potente del ODroid Go Advance, una computadora de mano de 3.5 pulgadas creada por ODroid en 2019, y el nuevo modelo es claramente mejor en varios aspectos.</div><div class="separator" style="clear: both; text-align: justify;"><br /></div><div class="separator" style="clear: both; text-align: justify;">Tiene una pantalla LCD más grande de 5 pulgadas que funciona a 854 × 480 píxeles (lamentablemente no 4: 3 como los aficionados a los juegos retro tienden a preferir), una batería grande de 4000 mAh (más tiempo de juego) y dos joysticks analógicos en comparación con la Advance que solamente contaba con 1.</div><div class="separator" style="clear: both; text-align: justify;"><br /></div><div class="separator" style="clear: both; text-align: justify;">Dejando a un lado esas diferencias, el Super está construido alrededor del mismo procesador Rockchip RK3326 ARM Cortex-A35 de cuatro núcleos y gráficos ARM Mali-G31 MP2 que la pequeña Advance. Del mismo modo, también se combina con un "modesto" (pudiéramos decir "escaso") 1 GB de memoria DDR3. También hay una cantidad insignificante de almacenamiento interno para albergar el cargador de arranque y el sistema operativo.</div></div><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-k1_dwwwXF4M/X-JrfCsfOqI/AAAAAAAAXaw/7F5gIG7MRaoXDdrVG15MVZybgJeDT-TvwCNcBGAsYHQ/s800/odroid2.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="390" data-original-width="800" height="312" src="https://1.bp.blogspot.com/-k1_dwwwXF4M/X-JrfCsfOqI/AAAAAAAAXaw/7F5gIG7MRaoXDdrVG15MVZybgJeDT-TvwCNcBGAsYHQ/w640-h312/odroid2.png" width="640" /></a></div>A tenor de lo anterior, podemos ver claramente que este dispositivo está lejos de ser el Linux más potente que pudieras llevar en tu bolsillo. Con todo, recuerda que ha sido diseñada para jugar a juegos de videoconsola antiguos y no los últimos lanzamientos. Habrá que esperar a finales de enero para poder comprobar como rinde con los distintos emuladores incluidos en su EmulationStation corriendo sobre Ubuntu 20.04 LTS.<br /><div class="separator" style="clear: both; text-align: center;"><a href="https://1.bp.blogspot.com/-arJBn_EyFn4/X-JrfNaPTwI/AAAAAAAAXa0/fnBchOD8YPIFRYL1k80ow710j2XcAYrRwCNcBGAsYHQ/s800/odroid3.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="390" data-original-width="800" height="157" src="https://1.bp.blogspot.com/-arJBn_EyFn4/X-JrfNaPTwI/AAAAAAAAXa0/fnBchOD8YPIFRYL1k80ow710j2XcAYrRwCNcBGAsYHQ/w290-h157/odroid3.png" width="290" /></a><a href="https://1.bp.blogspot.com/-3e6Nc_z-k1I/X-Jrfp5voWI/AAAAAAAAXa8/G7WwPlZQ5ZInjr1k5aaZH_ocRhQkUDntgCNcBGAsYHQ/s642/odroid4.png" style="clear: left; display: inline; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="390" data-original-width="642" height="178" src="https://1.bp.blogspot.com/-3e6Nc_z-k1I/X-Jrfp5voWI/AAAAAAAAXa8/G7WwPlZQ5ZInjr1k5aaZH_ocRhQkUDntgCNcBGAsYHQ/w292-h178/odroid4.png" width="292" /></a></div><br /><p><br /></p><h3 style="text-align: left;">Características principales:</h3><p></p><ul style="text-align: left;"><li>Pantalla de 5 pulgadas con resolución 854x480</li><li>Batería de 4000mAh</li><li>Doble stick analógico</li><li>Ubuntu 20.04 LTS con EMulationStation como frontend</li><li>1 gb DDR3L</li><li>Control de volumen dedicado</li><li>Soporte para dongle WIFI y BT mejorado. Wifi y BT no incluidos.</li><li>Procesador RockChip RK3326(Quad-Core ARM Cortex-A35 1.3GHz)</li><li>GPU Mali-G31 Dvalin</li><li>Almacenamiento SPI Flash(16Mbytes Boot), Micro SD Card slot(UHS-1 Capable interface)</li><li>Precio aproximado 80$ (portes e impuestos no incluidos)</li></ul><p></p><p><br /></p>Miguelhttp://www.blogger.com/profile/16782448155425363883noreply@blogger.com0tag:blogger.com,1999:blog-4451099318087488891.post-44792195482543036542020-12-21T08:56:00.006+01:002020-12-23T09:43:50.924+01:00Principales cambios de diseño previstos para GNOME 40<p style="text-align: justify;">Los
grandes cambios en la forma en que los usuarios de GNOME Shell abren y
administran aplicaciones y espacios de trabajo están llegando a GNOME
40, que se lanzará la próxima primavera.</p>
<p style="text-align: justify;">Se
planean varios cambios importantes en la experiencia del usuario y el
diseño, todos con el objetivo de mejorar la forma y función de la "<i><span style="font-family: "Courier New";">Activities Overview</span></i>",
también conocido como el espacio de trabajo bajo demanda al que se
accede haciendo clic en el botón de texto "Actividades" en la barra
superior de GNOME Shell.</p><p style="text-align: justify;">“<i style="mso-bidi-font-style: normal;">Después
de meses de exploración del diseño y 6 ejercicios de investigación de
usuarios separados […] el equipo de GNOME Shell tiene un diseño
actualizado para <i><span style="font-family: "Courier New";">Activities Overview</span></i></i>”, explica Allan Day, diseñador de experiencia de usuario en Red Hat y líder de diseño de GNOME.</p><p style="text-align: justify;">Y el nuevo diseño es espectacular.</p><p style="text-align: justify;"></p><div class="separator" style="clear: both; text-align: justify;"><a href="https://1.bp.blogspot.com/--fqJQrV3YHs/X-BPAeRiC4I/AAAAAAAAXaQ/y2Fm5vobdY8J5B0IMU22yNLLZfd8ZYO7wCPcBGAYYCw/s840/gnome-40-design-gif-1.gif" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="504" data-original-width="840" height="384" src="https://1.bp.blogspot.com/--fqJQrV3YHs/X-BPAeRiC4I/AAAAAAAAXaQ/y2Fm5vobdY8J5B0IMU22yNLLZfd8ZYO7wCPcBGAYYCw/w640-h384/gnome-40-design-gif-1.gif" width="640" /></a></div><p style="text-align: justify;"></p><p style="text-align: justify;">El
equipo de escritorio de GNOME ha compartido imágenes conceptuales de
los cambios propuestos. Estas ilustran el cambio en el posicionamiento
espacial que los desarrolladores sienten que se requiere para ofrecer
una "navegación y orientación intuitivas".</p><p style="text-align: justify;">Un escritorio vacío es lo primero que ven los usuarios en una instalación básica de GNOME Shell; <i style="mso-bidi-font-style: normal;">recuerde: Ubuntu incluye una versión personalizada</i>.
No hay señales visibles, salvo los íconos en la barra superior, sobre
dónde iniciar aplicaciones o cómo administrar las ventanas. Un usuario
tiene que "descubrir" el botón Actividades, que también alberga el
tablero, y trabajar el resto desde allí.</p><p style="text-align: justify;">GNOME 40 mejora un poco esta introducción.</p><p style="text-align: justify;"> </p><div class="separator" style="clear: both; text-align: justify;"><a href="https://1.bp.blogspot.com/-7K1F8t1_bpU/X-BPAZPZ9JI/AAAAAAAAXaE/xjXzIeXNFr45rx33O4_KloaiSiHw_FmoACPcBGAYYCw/s750/gnome-40-default-boot-750x450.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="450" data-original-width="750" height="384" src="https://1.bp.blogspot.com/-7K1F8t1_bpU/X-BPAZPZ9JI/AAAAAAAAXaE/xjXzIeXNFr45rx33O4_KloaiSiHw_FmoACPcBGAYYCw/w640-h384/gnome-40-default-boot-750x450.jpg" width="640" /></a></div><div style="text-align: justify;"><br /></div><p style="text-align: justify;">En
lugar de un escritorio en blanco, GNOME 40 recibe a los usuarios con el
modo Actividades, que está repleto de un (nuevo) conmutador de espacio
de trabajo horizontal, un (nuevo) tablero horizontal (o barra de
favoritos), además de una barra de búsqueda visible.</p><p style="text-align: justify;">Cuando
se abre una aplicación (o se hace clic en un espacio de trabajo), la
pantalla se "acerca" para colocar al usuario frente a su tarea / espacio
de trabajo seleccionado. La pantalla Actividades es accesible en
cualquier momento, como ahora.</p><p style="text-align: justify;">Cuando se abren varias aplicaciones, se ve así:</p><div class="separator" style="clear: both; text-align: justify;"><a href="https://1.bp.blogspot.com/-xBAPeVy7N38/X-BPAW5EBrI/AAAAAAAAXaI/XofURK1tqxUlKICJm8Pra85pmu0fGLJ2QCPcBGAYYCw/s1440/gnome-40-redesign-activities.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="896" data-original-width="1440" height="398" src="https://1.bp.blogspot.com/-xBAPeVy7N38/X-BPAW5EBrI/AAAAAAAAXaI/XofURK1tqxUlKICJm8Pra85pmu0fGLJ2QCPcBGAYYCw/w640-h398/gnome-40-redesign-activities.jpg" width="640" /></a></div><div style="text-align: justify;"><br /></div><p style="text-align: justify;">Los cambios clave:</p><p style="margin-left: 36pt; text-align: justify; text-indent: -18pt;"><b><span style="font-family: Symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;"><span style="mso-list: Ignore;">·<span style="font-family: "Times New Roman"; font-feature-settings: normal; font-kerning: auto; font-language-override: normal; font-optical-sizing: auto; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; line-height: normal;"> </span></span></span>Los espacios de trabajo están organizados horizontalmente</b></p><p style="margin-left: 36pt; text-align: justify; text-indent: -18pt;"><b><span style="font-family: Symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;"><span style="mso-list: Ignore;">·<span style="font-family: "Times New Roman"; font-feature-settings: normal; font-kerning: auto; font-language-override: normal; font-optical-sizing: auto; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; line-height: normal;"> </span></span></span>Las ventanas de las aplicaciones tienen íconos para ayudar con la identificación</b></p><p style="margin-left: 36pt; text-align: justify; text-indent: -18pt;"><b><span style="font-family: Symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;"><span style="mso-list: Ignore;">·<span style="font-family: "Times New Roman"; font-feature-settings: normal; font-kerning: auto; font-language-override: normal; font-optical-sizing: auto; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; line-height: normal;"> </span></span></span>El tablero es horizontal, despojado en la parte inferior</b></p><p style="margin-left: 36pt; text-align: justify; text-indent: -18pt;"><b><span style="font-family: Symbol; mso-bidi-font-family: Symbol; mso-fareast-font-family: Symbol;"><span style="mso-list: Ignore;">·<span style="font-family: "Times New Roman"; font-feature-settings: normal; font-kerning: auto; font-language-override: normal; font-optical-sizing: auto; font-size-adjust: none; font-size: 7pt; font-stretch: normal; font-style: normal; font-variant: normal; font-variation-settings: normal; line-height: normal;"> </span></span></span>Soporte para fondos de pantalla por espacio de trabajo</b></p><p style="text-align: justify;">La
interacción sigue siendo tan rica como ahora; los usuarios pueden
arrastrar y soltar ventanas de aplicaciones entre espacios de trabajo (y
presumiblemente crear nuevos espacios de trabajo bajo demanda). Los
títulos de las ventanas aparecerán al pasar el mouse.</p><p style="text-align: justify;">La
cuadrícula "Aplicaciones" se inicia haciendo clic en el icono de
cuadrícula en el tablero. Pero, como gran parte de la interfaz de
usuario, ahora pagina horizontalmente. Los desarrolladores de <b>GNOME </b>han
creado conscientemente una coherencia de navegación que se mantiene
fiel a lo largo de toda la interfaz de usuario de conmutación de
aplicaciones. Izquierda / derecha para moverse, arriba / abajo para
hacer la transición.</p><p style="text-align: justify;">Otras
funciones, como la búsqueda a medida que escribe, el acceso a los
proveedores de búsqueda, el reordenamiento de aplicaciones y las
carpetas de aplicaciones personalizables, permanecen intactas.</p><div class="separator" style="clear: both; text-align: justify;"><a href="https://1.bp.blogspot.com/-nEPkdbUv7Tw/X-BPA7IoZdI/AAAAAAAAXaM/3sO3MUejOpMFQIhQCCfw9r08JW-HU51DACPcBGAYYCw/s1440/gnome-40-redesign-applications-picker.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="896" data-original-width="1440" height="398" src="https://1.bp.blogspot.com/-nEPkdbUv7Tw/X-BPA7IoZdI/AAAAAAAAXaM/3sO3MUejOpMFQIhQCCfw9r08JW-HU51DACPcBGAYYCw/w640-h398/gnome-40-redesign-applications-picker.jpg" width="640" /></a></div><div style="text-align: justify;"><br /></div><p style="text-align: justify;"></p><p style="text-align: justify;">Me tranquiliza ver que el tablero permanece presente en estas nuevas
maquetas. En el pasado, la discusión sobre el diseño de GNOME sugirió
que el dock estaba listo para ser eliminado. Un movimiento tan audaz
hacia la <b>UX </b>sería controvertido, pero los usuarios descontentos,
como ahora, podrían adaptar la experiencia de GNOME Shell para
satisfacer sus propias necesidades y preferencias a través de
extensiones.</p><p style="text-align: justify;">Dicho esto, faltan algunas funciones: en las maquetas
donde las aplicaciones están abiertas, notará que NO se presentan en el
tablero como aplicaciones en ejecución, es decir, con un punto de
estado. ¿Significa esto que Dash ahora se está convirtiendo en una barra
de favoritos y no en una forma de administrar aplicaciones en
ejecución?</p><p style="text-align: justify;"><b>System76 </b>aparentemente estuvo involucrado en la investigación que dio como resultado este plan GNOME 40. Esto no es una sorpresa ya que <b>System76</b> envía una versión modificada del escritorio GNOME Shell en <b>Pop OS</b>,
una distribución que ha ganado muchos aplausos por sus alteraciones y
complementos, y por su flujo de trabajo centrado en el usuario avanzado.</p><p style="text-align: justify;"><b>GNOME 40 se lanzará en marzo de 2021</b>.
Los cambios de diseño que se ven aquí están destinados a esa versión,
pero no se garantiza que se distribuyan. Las cosas pueden, naturalmente,
cambiar a medida que se produce el desarrollo y la implementación.</p><p style="text-align: justify;">Pero si todo va según lo planeado, la experiencia de Actividades rediseñada que se muestra aquí <b>podría aparecer en Ubuntu 21.04</b> 'Hirsute Hippo', que se lanzará a mediados de abril de 2021.</p><p style="text-align: justify;"> </p><p style="text-align: justify;"><a href="https://www.omgubuntu.co.uk/2020/12/gnome-40-major-design-revamp" rel="nofollow" target="_blank">Enlace a la noticia original en inglés </a><br /></p> <p></p>Miguelhttp://www.blogger.com/profile/16782448155425363883noreply@blogger.com0tag:blogger.com,1999:blog-4451099318087488891.post-26595949499915652872016-11-29T16:30:00.001+01:002020-12-22T23:52:44.262+01:00Truco Java - Establecer formato moneda en columna JTable<div style="text-align: justify;">
Hoy os voy a mostrar como poner el formato moneda (currency) en un campo de vuestra JTable.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-mc77aFdXtxU/V2QovCN7qEI/AAAAAAAANig/ycPlkTVqgQgEEVVWP7duunyl5PtOH2JzgCPcB/s1600/Java-icon.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://3.bp.blogspot.com/-mc77aFdXtxU/V2QovCN7qEI/AAAAAAAANig/ycPlkTVqgQgEEVVWP7duunyl5PtOH2JzgCPcB/s1600/Java-icon.png" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
De la misma manera que en el <a href="http://www.invalidexpression.net/2016/11/java-formato-fecha-hora-jtable.html" target="_blank">truco anterior</a>, nos crearemos una clase dentro del paquete componentes de nuestra aplicación heredando de <b>DefaultTableCellRenderer. </b></div>
<br />
<pre class="prettyprint"><code class="language-java">import java.awt.Component;
import java.text.NumberFormat;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
public class CurrencyCellRenderer extends DefaultTableCellRenderer {
private static final NumberFormat FORMAT = NumberFormat.getCurrencyInstance();
@Override
public final Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
final Component result = super.getTableCellRendererComponent(table, value,
isSelected, hasFocus, row, column);
if (value instanceof Number) {
setHorizontalAlignment(JLabel.RIGHT);
setText(FORMAT.format(value));
} else {
setText("");
}
return result;
}
}
</code>
</pre>
La utilización es similar al caso TimestampCellRenderer:<br />
<br />
<pre class="prettyprint"><code class="language-java">public void LlenarTabla(JTable tablaListadoVentas, boolean inicializar) {
DefaultTableModel modeloTabla = new DefaultTableModel (){
@Override //Establecemos todas las celdas como no editables
public boolean isCellEditable(int row, int column) {
return false;
}
};
tablaListadoVentas.setModel(modeloTabla);
modeloTabla.addColumn("Venta");
modeloTabla.addColumn("Id. Cliente");
modeloTabla.addColumn("Nombre");
modeloTabla.addColumn("Id. Empleado");
modeloTabla.addColumn("Nombre");
modeloTabla.addColumn("Fecha y hora");
modeloTabla.addColumn("Nº Artículos");
modeloTabla.addColumn("Importe Total");
Object[] columna = new Object[8];
tablaListadoVentas.getColumnModel().getColumn(5).setCellRenderer(new TimestampCellRenderer());
tablaListadoVentas.getColumnModel().getColumn(7).setCellRenderer(new CurrencyCellRenderer());
</code>
</pre>
<br />
Si tienes cualquier duda o comentario recuerda que puedes exponerlo aquí o bien mediante nuestro <a href="http://twitter.com/InvExpression" target="_blank">twitter </a>y <a href="https://www.facebook.com/InvExpression" target="_blank">facebook</a>.
Miguelhttp://www.blogger.com/profile/16782448155425363883noreply@blogger.com0tag:blogger.com,1999:blog-4451099318087488891.post-46821856461914283472016-11-03T10:04:00.002+01:002020-12-22T13:22:24.310+01:00Truco Java - Establecer formato fecha y hora en columna JTable<div style="text-align: justify;">
El truco que os traigo hoy es producto de una necesidad que me surgió durante la elaboración del proyecto del curso de Java que estoy haciendo. La necesidad vino cuando necesité establecer formato fecha/hora a un campo de un <b>JTable </b>que contenia un valor <b>Timestamp </b>obtenido de <b>MySQL</b>.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-mc77aFdXtxU/V2QovCN7qEI/AAAAAAAANig/ycPlkTVqgQgEEVVWP7duunyl5PtOH2JzgCPcB/s1600/Java-icon.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://3.bp.blogspot.com/-mc77aFdXtxU/V2QovCN7qEI/AAAAAAAANig/ycPlkTVqgQgEEVVWP7duunyl5PtOH2JzgCPcB/s1600/Java-icon.png" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Lo que tenemos que hacer es crearnos una clase (en mi caso estas clases las meto siempre en un paquete llamado "<u>componentes</u>" para tenerlo todo organizado) que herede de <b>DefaultTableCellRenderer </b>y posteriormente utilizarla en nuestra columna de <b>JTable</b>.</div>
<br />
<pre class="prettyprint"><code class="language-java">import java.text.DateFormat;
import java.text.SimpleDateFormat;
import javax.swing.table.DefaultTableCellRenderer;
public class TimestampCellRenderer extends DefaultTableCellRenderer {
DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
public TimestampCellRenderer() {
super();
}
public void setValue(Object value) {
if (formatter == null) {
formatter = DateFormat.getDateInstance();
}
setText((value == null) ? "" : formatter.format(value));
}
}
</code>
</pre>
<br />
<div style="text-align: justify;">
En la linea <b>SimpleDateFormat </b>podemos establecer el formato de fecha y hora que nosotros necesitemos. Se me ocurre como mejora añadir un parametro al <u>constructor</u> para poder pasar la cadena de formato por ejemplo.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
La utilización es sencilla: Suponiendo que nuestro <b>JTable </b>se llame <i>tablaListadoVentas </i>y una vez establecido el modelo de la misma:</div>
<br />
<pre class="prettyprint"><code class="language-java"> public void LlenarTabla(JTable tablaListadoVentas, boolean inicializar) {
DefaultTableModel modeloTabla = new DefaultTableModel (){
@Override //Establecemos todas las celdas como no editables
public boolean isCellEditable(int row, int column) {
return false;
}
};
tablaListadoVentas.setModel(modeloTabla);
modeloTabla.addColumn("Venta");
modeloTabla.addColumn("Id. Cliente");
modeloTabla.addColumn("Nombre");
modeloTabla.addColumn("Id. Empleado");
modeloTabla.addColumn("Nombre");
modeloTabla.addColumn("Fecha y hora");
modeloTabla.addColumn("Nº Artículos");
modeloTabla.addColumn("Importe Total");
Object[] columna = new Object[8];
tablaListadoVentas.getColumnModel().getColumn(5).setCellRenderer(new TimestampCellRenderer());
</code>
</pre>
<br />
<br />
Si tienes cualquier duda o comentario recuerda que puedes exponerlo aquí o bien mediante nuestro <a href="http://twitter.com/InvExpression" target="_blank">twitter </a>y <a href="https://www.facebook.com/InvExpression" target="_blank">facebook</a>.
Miguelhttp://www.blogger.com/profile/16782448155425363883noreply@blogger.com1tag:blogger.com,1999:blog-4451099318087488891.post-76070421576449321812016-10-31T11:00:00.000+01:002016-10-31T15:34:26.389+01:00¿Qué es un ataque DDoS? ¿Cómo podemos evitarlo?<div style="text-align: justify;">
El Viernes 21 de
Octubre de 2016 se produjo el mayor y más importante ataque <b>DDoS </b>de los últimos
años. El ataque fue dirigido hacia los servicios <b>DynDNS</b> y dejo fuera de combate
a decenas de web y servicios como por ejemplo <b>Twitter</b>, <b>Reddit</b>, <b>Github</b>, <b>Amazon</b>,
<b>Spotify</b>…</div>
<div style="margin: 0in; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-1WY9v-qIlYA/WBcIZgIM7eI/AAAAAAAAN7M/16wg22ycqyIYY_ScUpN_VNi12dKzYEBlwCK4B/s1600/recorte620_ddos-attack.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="184" src="https://4.bp.blogspot.com/-1WY9v-qIlYA/WBcIZgIM7eI/AAAAAAAAN7M/16wg22ycqyIYY_ScUpN_VNi12dKzYEBlwCK4B/s320/recorte620_ddos-attack.jpg" width="320" /></a></div>
<div style="margin: 0in; text-align: justify;">
<br /></div>
<div style="margin: 0in; text-align: justify;">
<br /></div>
<div style="margin: 0in; text-align: justify;">
Lo grave del asunto
es que el ataque al parecer fue perpetrado gracias a una vulnerabilidad
existente en dispositivos IoT (Internet de las cosas), como son los
electrodomésticos conectados a la red.</div>
<div style="margin: 0in; text-align: justify;">
<br />
<br />
<h3>
¿Que es un ataque DDos?</h3>
</div>
<div style="margin: 0in; text-align: justify;">
Vayamos por
partes; Un <u>ataque de denegación de
servicio</u> (<b>DoS</b>) es un ataque dirigido hacia una red o sistema de computadoras
que provoca que el mismo deje de responder a los usuarios. Esto ocasiona que el
sistema esté fuera de línea el tiempo que dura el ataque más el tiempo de
<u>restablecimiento del sistema</u> que suele oscilar entre 20 minutos y varias horas
en el peor de los casos. </div>
<div style="margin: 0in; text-align: justify;">
<br /></div>
<div style="margin: 0in; text-align: justify;">
El caso que nos
ocupa es una ampliación de este ataque y sus siglas <b>DDoS </b>corresponden a ataque
de denegación de servicio distribuido o <u>Distributed Denial of Service</u>, en el que
el ataque se lleva a cabo desde cientos o miles de puntos diferentes hacia el mismo
objetivo.</div>
<div style="margin: 0in; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-7gRBdNl6194/WBcIh3KsWyI/AAAAAAAAN7U/RQWdae4BDQs_pga_U8ccY-q03LbE-9YPgCK4B/s1600/ddos-attacks1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="216" src="https://1.bp.blogspot.com/-7gRBdNl6194/WBcIh3KsWyI/AAAAAAAAN7U/RQWdae4BDQs_pga_U8ccY-q03LbE-9YPgCK4B/s320/ddos-attacks1.png" width="320" /></a></div>
<div style="margin: 0in; text-align: justify;">
<br /></div>
<div style="margin: 0in; text-align: justify;">
<br /></div>
<div style="margin: 0in; text-align: justify;">
Existen diferentes
tipos de ataque, pero básicamente se trata de enviar un flujo tal de peticiones
que el sistema no puede atenderlas por lo que acaba <u>tirando el servicio</u> por
seguridad. Otros ataques pueden suponer interrupciones de componentes físicos
de red o incluso alteración de las tablas de enrutamiento.</div>
<div style="margin: 0in; text-align: justify;">
<br />
<br />
<h3>
¿Por qué es tan popular el ataque DDoS?</h3>
</div>
<div style="margin: 0in; text-align: justify;">
Los ataques <b>DDoS </b>se
han vuelto muy populares debido a que el objetivo no tiene por que tener
ninguna vulnerabilidad, ya que son ataques de infraestructura. Por esto
cualquiera podría comprar un pack de ataque <b>DDoS </b>por unos 150€ y mantener fuera
de línea a un rival de <b>League of Legends</b> por ejemplo (Sí, esto ha pasado). Ojo,
antes he mencionado que se ataca desde cientos o miles de ordenadores y es que
estos ordenadores sí que suelen estar afectados por alguna clase de
vulverabilidad (como <b>Mirai</b> en el internet de las cosas) o <b>malware</b>.</div>
<div style="margin: 0in; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-AKLv_ubkKlg/WBcIx-qpTRI/AAAAAAAAN7k/UyB8-bsMz2k1R8MiGP-nB6_2E6vgQoPYwCK4B/s1600/iot.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="188" src="https://2.bp.blogspot.com/-AKLv_ubkKlg/WBcIx-qpTRI/AAAAAAAAN7k/UyB8-bsMz2k1R8MiGP-nB6_2E6vgQoPYwCK4B/s320/iot.jpg" width="320" /></a></div>
<div style="margin: 0in; text-align: justify;">
<br /></div>
<div style="margin: 0in; text-align: justify;">
<h3>
¿Qué se busca con los ataques DDoS?</h3>
</div>
<div style="margin: 0in; text-align: justify;">
Aquí debemos tener
en cuenta los tipos de ataque; estos pueden ser <u>personalizados</u>, los cuales no
tienen mucha repercusión mediática y suelen buscar un objetivo concreto (dejar
fuera de línea a un rival o tirar el servidor del examen de la universidad) o <u>globales</u>,
los cuales buscan una gran repercusión mediática, suelen estar reivindicados
por organizaciones o grupos hacktivistas y sirven para que el mundo les preste
atención.</div>
<div style="margin: 0in; text-align: justify;">
<br /></div>
<div style="margin: 0in; text-align: justify;">
<h3>
¿Como podemos evitar los ataques DDoS?</h3>
</div>
<div style="margin: 0in; text-align: justify;">
No se puede… sin
más, hoy en día es imposible evitar este tipo de ataques debido a que las
causas son los propios mecanismos de seguridad de nuestras infraestructuras
informáticas. Hace unos años podríamos pensar que si todos nuestros ordenadores
estuvieran libres de malware, no podrían
pertenecer a botnets (redes de ordenadores zombies controlados por un mismo
malware y que son capaces de perpetrar ataques DDoS dirigidos) y entonces sería
mucho más complicado realizar estos ataques pero, ay amigos, bienvenidos al
internet de las cosas.</div>
<div style="margin: 0in; text-align: justify;">
<br />
<br />
<h3>
El internet de las cosas y Mirai.</h3>
</div>
<div style="margin: 0in; text-align: justify;">
Actualmente no son
pocos los hogares que disponen de más de un ordenador conectado a internet sin
siquiera darse cuenta. ¿Tienes una <b>SmartTv</b>? ¿un <b>frigorífico </b>conectado a
internet? ¿Un <b>ebook</b>, <b>tablet</b>, <b>videoconsola</b>? ¿Quizá tengas una de esas nuevas
<b>bombillas inteligentes</b> o un <b>Chromecast</b>? ¿Una <b>camara IP</b>? Podría seguir así mucho
rato pero aunque no tengas nada de esto, seguro que tienes un <b>router</b> en casa
¿verdad? ¿Le has cambiado la contraseña? :D</div>
<div style="margin: 0in; text-align: justify;">
¿Por que os cuento
esto? Bueno, todos esos artículos son susceptibles de ser participes en la
mayor botnet jamás creada, Mirai.</div>
<div style="margin: 0in; text-align: justify;">
<br /></div>
<div style="margin: 0in; text-align: justify;">
<b>Mirai </b>es capaz de
convertir <u>sistemas Linux</u> en <b>bots controlados remotamente</b> y además ni siquiera
necesita crackearlos ya que la mayoría de nosotros no se preocupa de cambiar la
contraseña genérica de estos dispositivos. <b>Mirai </b>puede afectar a impresoras, camaras
de vigilancia o routers caseros y hay poco que podamos hacer.</div>
<div style="margin: 0in; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-i2z4j6tC_SI/WBcI2_w-H4I/AAAAAAAAN7s/sjUm3HnbXPg-Yw3E1jdDXMvgp0OZ522JACK4B/s1600/mirai-ddos-trojan-is-the-next-big-threat-for-iot-devices-and-linux-servers-507964-2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://3.bp.blogspot.com/-i2z4j6tC_SI/WBcI2_w-H4I/AAAAAAAAN7s/sjUm3HnbXPg-Yw3E1jdDXMvgp0OZ522JACK4B/s320/mirai-ddos-trojan-is-the-next-big-threat-for-iot-devices-and-linux-servers-507964-2.png" width="313" /></a></div>
<div style="margin: 0in; text-align: justify;">
<br /></div>
<div style="margin: 0in; text-align: justify;">
<br /></div>
<div style="margin: 0in; text-align: justify;">
Este es un problema
que tiene difícil solución y quizá sería un buen momento para plantearnos si
realmente necesitamos tantos dispositivos inteligentes o sería más sensato usar
nuestra inteligencia y dejar de ser tan cómodos.</div>
<div style="margin: 0in; text-align: justify;">
<br /></div>
<div style="margin: 0in; text-align: justify;">
Y tú. ¿Tienes muchos aparatos conectados a internet? </div>
<br />Miguelhttp://www.blogger.com/profile/16782448155425363883noreply@blogger.com0tag:blogger.com,1999:blog-4451099318087488891.post-33699582239051142092016-10-27T15:40:00.004+02:002020-12-22T23:54:43.599+01:00Truco C# - Eliminar / Matar procesos Windows por nombre o id<div style="text-align: justify;">
En este post os voy a enseñar una manera sencilla de eliminar procesos concretos por nombre o id mediante programación. </div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-gwHkzj-47wA/WBBlZVYIIvI/AAAAAAAAN6g/DVlI0B-TpP81Phrvk4E3Ud2YcgSeEU7BwCPcB/s1600/2p4i.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://1.bp.blogspot.com/-gwHkzj-47wA/WBBlZVYIIvI/AAAAAAAAN6g/DVlI0B-TpP81Phrvk4E3Ud2YcgSeEU7BwCPcB/s200/2p4i.png" width="200" /></a></div>
<br />
<div style="text-align: justify;">
Para poder hacer uso de este truco vamos a necesitar añadir <b>System.Diagnostics</b> a nuestro programa ya que haremos uso de la clase Process. Una vez hecho esto vamos a definir 3 métodos, uno para matar procesos por su id de proceso y dos que irán por nombre de proceso; el primero eliminará la primera ocurrencia y el segundo eliminará todos los procesos con el mismo nombre (el proceso <b>"Chrome" </b>puede ser un buen ejemplo para probarlo).</div>
<br />
<h3>
Matar tarea por Id.</h3>
<pre class="prettyprint"><code class="language-cs">
private void KillTaskById(int taskid)
{
try
{
Process proceso = Process.GetProcessById(taskid);
proceso.Kill();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
</code>
</pre>
<br />
<h3>
Matar tarea por Nombre. Primera ocurrencia.</h3>
<pre class="prettyprint"><code class="language-cs"> private void KillTaskByName(string taskName)
{
try
{
Process[] procesos = Process.GetProcessesByName(taskName);
procesos[0].Kill();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
</code>
</pre>
<br />
<h3>
Matar tarea por Nombre. Todas las ocurrencias.</h3>
<pre class="prettyprint"><code class="language-cs">
private void KillAllTasksByName(string taskName)
{
try
{
foreach (Process proceso in Process.GetProcessesByName(taskName))
{
proceso.Kill();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
</code>
</pre>
<br />
Probadlo y dejar en los comentarios que os ha parecido.<br />
<br />
Si tienes cualquier duda o comentario recuerda que puedes exponerlo aquí o bien mediante nuestro <a href="http://twitter.com/InvExpression" target="_blank">twitter </a>y <a href="https://www.facebook.com/InvExpression" target="_blank">facebook</a>.Miguelhttp://www.blogger.com/profile/16782448155425363883noreply@blogger.com4tag:blogger.com,1999:blog-4451099318087488891.post-10116200808851383412016-10-26T10:21:00.002+02:002020-12-22T23:55:19.176+01:00Truco C# - Listar todos los servicios de un webservice<div style="text-align: justify;">
Hacía ya mucho tiempo que no posteaba nada, mas por falta de tiempo que por otra cosa, pero hoy os traigo una nueva entrada con un truco para C#.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-gwHkzj-47wA/WBBlZVYIIvI/AAAAAAAAN6c/PY8ImgY6mNwRwrrtj1Tq9OMPFwdWJqe9QCLcB/s1600/2p4i.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://2.bp.blogspot.com/-gwHkzj-47wA/WBBlZVYIIvI/AAAAAAAAN6c/PY8ImgY6mNwRwrrtj1Tq9OMPFwdWJqe9QCLcB/s200/2p4i.png" width="200" /></a></div>
<div style="text-align: justify;">
Si habéis leido el título ya intuireis de que va el truco de hoy. Se trata, ni más ni menos de cómo obtener la lista de servicios publicados en un webservice.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Para que el método funcione lo único que necesitais es la url de un descriptor de webservice (acabará en ?wsdl o ?singleWSDL) para pasarla como parametro al método GetWsdlMethods que os describo a continuación.</div>
<br />
<br />
<pre class="prettyprint"><code class="language-cs">
private string[] GetWsdlMethods(string wsdlUrl)
{
List<string> services = new List<string>();
try
{
XmlTextReader myStreamReader = new XmlTextReader(wsdlUrl);
ServiceDescription wsdl =
ServiceDescription.Read(myStreamReader);
txtMethods.Clear();
foreach (PortType pt in wsdl.PortTypes)
{
services.Add(string.Format("PortType {0}", pt.Name));
services.Add("\r\n----------------------------------------");
foreach (Operation op in pt.Operations)
{
services.Add(string.Format("\r\n{0}", op.Name));
}
}
}
catch
{
services.Add("ERROR READING WDSL URL");
}
return services.ToArray();
}
</code>
</pre>
<br />
<br />
<br />
Probadlo y dejar en los comentarios que os ha parecido.<br />
<br />
Si tienes cualquier duda o comentario recuerda que puedes exponerlo aquí o bien mediante nuestro <a href="http://twitter.com/InvExpression" target="_blank">twitter </a>y <a href="https://www.facebook.com/InvExpression" target="_blank">facebook</a>.Miguelhttp://www.blogger.com/profile/16782448155425363883noreply@blogger.com0tag:blogger.com,1999:blog-4451099318087488891.post-16017953479620026592016-08-25T08:50:00.000+02:002016-10-26T16:04:46.424+02:00Cómo bloquear / desactivar / eliminar los anuncios de Skype<br />
<br />
<div style="text-align: justify;">
Todos los que usamos Skype nos hemos acostumbrado a convivir con los anuncios que la aplicación nos muestra pero, ¿sabíais que se pueden desactivar de una manera muy sencilla? Sigue leyendo y te explico cómo.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-U6N-1EKExt0/V76TCU0ZTDI/AAAAAAAAN2o/o_x4zrGlWBY6-6II0asa8OpoSpXCBUAOQCLcB/s1600/skype.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="141" src="https://3.bp.blogspot.com/-U6N-1EKExt0/V76TCU0ZTDI/AAAAAAAAN2o/o_x4zrGlWBY6-6II0asa8OpoSpXCBUAOQCLcB/s320/skype.png" width="320" /></a></div>
<br />
<a name='more'></a>Esta solución solamente funcionará para la versión Windows de Skype.<br />
<br />
<ol>
<li>Abrir el panel de control.</li>
<li>Abrir "Opciones de Internet".</li>
<li>Seleccionar la pestaña "Seguridad".</li>
<li>Hacer click en el icono "Sitios Restringidos" y luego en "Sitios" (botón debajo del icono).</li>
<li>Añadir la direccion "https://apps.skype.com/" (sin las comillas) en la caja de texto y pulsar "Agregar".</li>
<li>Cerrar y aplicar los cambios.</li>
<li>Reiniciar Skype</li>
<li>Enjoy!.</li>
</ol>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-xU3Dzzj3zpQ/V76TCOhxFiI/AAAAAAAAN2k/-J__btZ3BKA0cQdmGagq9rXVvczsvTh5gCEw/s1600/SC1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://3.bp.blogspot.com/-xU3Dzzj3zpQ/V76TCOhxFiI/AAAAAAAAN2k/-J__btZ3BKA0cQdmGagq9rXVvczsvTh5gCEw/s320/SC1.png" width="228" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-Rl68q59LU0A/V76TCBmQI4I/AAAAAAAAN2g/bps7kUEE6rQqJGsmE9F8kZozEOte6rlIgCEw/s1600/SC2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://4.bp.blogspot.com/-Rl68q59LU0A/V76TCBmQI4I/AAAAAAAAN2g/bps7kUEE6rQqJGsmE9F8kZozEOte6rlIgCEw/s320/SC2.png" width="230" /></a></div>
<div style="text-align: center;">
<br /></div>
<ol>
</ol>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-ZKXYP811sXU/V76TCMXkOLI/AAAAAAAAN2c/8Xib3Sh3OxA3yYMF8_ffiaBetAv3C1LXQCEw/s1600/SC3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="299" src="https://3.bp.blogspot.com/-ZKXYP811sXU/V76TCMXkOLI/AAAAAAAAN2c/8Xib3Sh3OxA3yYMF8_ffiaBetAv3C1LXQCEw/s320/SC3.png" width="320" /></a></div>
<br />
Si tienes cualquier duda o comentario recuerda que puedes exponerlo aquí o bien mediante nuestro <a href="http://twitter.com/InvExpression" target="_blank">twitter </a>y <a href="https://www.facebook.com/InvExpression" target="_blank">facebook</a>.<br />
<br />
<br />
<span id="goog_1929622206"></span><span id="goog_1929622207"></span>Miguelhttp://www.blogger.com/profile/16782448155425363883noreply@blogger.com0tag:blogger.com,1999:blog-4451099318087488891.post-66060069421796135552016-06-30T13:33:00.003+02:002020-12-22T23:53:13.599+01:00Truco Java - Uso de ListIterator<div style="text-align: justify;">
Hoy más que un truco os voy a poner un ejemplo de utilización de la clase <b>ListIterator</b>. </div>
<div style="text-align: justify;">
<b>ListIterator </b>es un <u>iterador secuencial</u> que posibilita recorrer listas en cualquier sentido. Hay que tener presente que la posición de un iterador no<u> representa ningún valor real de la lista</u>, siempre estará entre dos elementos, al principio o al final.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-mc77aFdXtxU/V2QovCN7qEI/AAAAAAAANig/vd0C_xvxjhgQ0CbMZzyE90M8coLsziCRQCKgB/s1600/Java-icon.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://3.bp.blogspot.com/-mc77aFdXtxU/V2QovCN7qEI/AAAAAAAANig/vd0C_xvxjhgQ0CbMZzyE90M8coLsziCRQCKgB/s1600/Java-icon.png" /></a></div>
<br />
<br />
<div style="text-align: justify;">
En el ejemplo vamos a recorrer un <b>Array </b>de cadenas extrayendo los valores numéricos y posteriormente recorriendo la lista hacia adelante y hacia atrás.</div>
<br />
<pre class="prettyprint"><code class="language-java">
package TrucosIExpression;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.ListIterator;
/**
*
* @author InvalidExpression
*/
public class Truco1 {
/**
* Metodo que extray todos los valores numéricos de un array de cadenas
* y lo devuelve en un ArrayList
* @param cadenas String[] .
* @return ArrayList con valores numericos extraidos.
*/
public ArrayList extraerNumeros(String[] cadenas) {
if (cadenas == null) {
throw new IllegalArgumentException("Parámetro erroneo.");
} else {
ArrayList arrayCadenas = new ArrayList();
arrayCadenas.addAll(Arrays.asList(cadenas));
ListIterator listaIterador;
listaIterador = arrayCadenas.listIterator();
while (listaIterador.hasNext()) {
String cadena = (String) listaIterador.next();
try {
Integer numero = new Integer(cadena);
} catch (NumberFormatException e) {
listaIterador.remove();
}
}
return arrayCadenas;
}
}
/**
* Metodo main.
*
* @param args String[] args.
*/
public static void main(String[] args) {
Truco1 trucoIterator = new Truco1();
String[] cadenas = {"SILLA","5", "1", "4", "MESA",
"8", "ZAPATO", "CERVEZA", "10", "12"};
ArrayList arrayNumeros = trucoIterator.extraerNumeros(cadenas);
ListIterator iterador = arrayNumeros.listIterator();
//Recorremos de principio a fin con hasNext
while (iterador.hasNext()) {
System.out.println(iterador.next());
}
//Recorremos desde el final hasta el principio.
while (iterador.hasPrevious()) {
System.out.println(iterador.previous());
}
}
}
</code>
</pre>
<br />
El resultado de la ejecución de este pequeño programa en NetBeans sería el siguiente:<br />
<br />
<div style="text-align: center;">
<a href="http://2.bp.blogspot.com/-sfDXj3c-NXg/V3UC0giwknI/AAAAAAAANmc/IUFNcKABMTIt60nUnGR8HjiEIlyLRqwAQCK4B/s1600/resultado.png" imageanchor="1"><img border="0" height="242" src="https://2.bp.blogspot.com/-sfDXj3c-NXg/V3UC0giwknI/AAAAAAAANmc/IUFNcKABMTIt60nUnGR8HjiEIlyLRqwAQCK4B/s320/resultado.png" width="320" /></a></div>
<br />
Si necesitáis más información sobre <b>ListIterator </b>podéis encontrarla <a href="https://docs.oracle.com/javase/7/docs/api/java/util/ListIterator.html" target="_blank">aquí</a>.<br />
<br />
Si tienes cualquier duda o comentario recuerda que puedes exponerlo aquí o bien mediante nuestro <a href="http://twitter.com/InvExpression" target="_blank">twitter </a>y <a href="https://www.facebook.com/InvExpression" target="_blank">facebook</a>.Miguelhttp://www.blogger.com/profile/16782448155425363883noreply@blogger.com0tag:blogger.com,1999:blog-4451099318087488891.post-14056520624173761972016-06-28T13:15:00.001+02:002020-12-23T00:00:17.860+01:00Truco Delphi - Enviar emails usando el servicio Gmail de GoogleEn el truco de hoy os voy a enseñar como podéis enviar <u>correos electrónicos</u> desde vuestra aplicación <b>Delphi </b>mediante vuestra cuenta <b>Gmail</b>.<br />
<br />
<div style="text-align: center;">
<a href="http://3.bp.blogspot.com/-iuBk5OIdN8Q/V3JaewDz9qI/AAAAAAAANmE/KA_GaldnnK4r0LF9eX59w-ZkXXTQFwqqQCK4B/s1600/Icon-Gmail-300x300.png"><img border="0" height="200" src="https://3.bp.blogspot.com/-iuBk5OIdN8Q/V3JaewDz9qI/AAAAAAAANmE/KA_GaldnnK4r0LF9eX59w-ZkXXTQFwqqQCK4B/s200/Icon-Gmail-300x300.png" width="200" /></a></div>
<br />
<div style="text-align: justify;">
Para ello vamos a hacer uso de los componentes <b>Indy </b>disponibles en cualquier versión de<b> RAD Studio</b> (en el truco se utiliza la versión <b>XE8</b> pero está testeado en <b>XE5</b> también).</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Vamos a crearnos una función <b>SendGMail </b>con el siguiente código:</div>
<pre class="prettyprint"><code class="language-pascal">
procedure SendGmail(pUsuario, pPassword, pAsunto, pCuerpo, pDestino : string);
var
Smtp : TidSMTP;
ManejadorSSL : TidSSLIOHandlerSocketOpenSSL;
Mensaje: TIdMessage;
begin
ManejadorSSL := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
with ManejadorSSL do
begin
Destination := 'smtp.gmail.com:587';
Host := 'smtp.gmail.com';
MaxLineAction := maException;
Port := 587;
SSLOptions.Method := sslvTLSv1;
SSLOptions.Mode := sslmUnassigned;
SSLOptions.VerifyMode := [];
SSlOptions.VerifyDepth := 0;
end;
Smtp := TIdSMTP.Create( nil );
with Smtp do
begin
IoHandler := ManejadorSSL;
Host := 'smtp.gmail.com';
Port := 25;
Username := pUsuario;
Password := pPassword;
UseTLS := utUseExplicitTLS;
end;
Mensaje := TIdMessage.Create(nil);
with Mensaje do
begin
Clear;
Subject := pAsunto;
Body.Text := pCuerpo;
Recipients.Add;
Recipients.Items[0].Address := pDestino;
end;
Smtp.Connect;
if smtp.Connected then
begin
smtp.Send(Mensaje);
smtp.Disconnect;
end;
FreeAndNil(Smtp);
FreeAndNil(Mensaje);
FreeAndNil(ManejadorSSL);
end;
</code>
</pre>
<br />
<div style="text-align: justify;">
Y ya está, solamente tendremos que llamar a esta función con los parámetros relativos a nuestra cuenta para enviar nuestro correo.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
En lugar de crear los objetos <b>dinámicamente</b>, podéis pegar objetos directamente desde <u>la paleta de componentes</u> en vuestro formulario y ahorraros el <i>create;</i> si lo hacéis dinámicamente no olvidéis incluir en el uses las referencias necesarias:</div>
<br />
<pre class="prettyprint"><code class="language-pascal"> uses
[...] IdMessage, IdIOHandler, IdIOHandlerSocket, IdIOHandlerStack,
IdSSL, IdSSLOpenSSL, IdBaseComponent, IdComponent, IdTCPConnection,
IdTCPClient, IdExplicitTLSClientServerBase, IdMessageClient, IdSMTPBase,
IdSMTP,IdAttachmentFile,IdGlobal;
</code>
</pre>
<br />
<div style="text-align: justify;">
Observaréis que falta la opción de <u>adjuntar algún archivo</u>, pero eso lo vamos a dejar para futuros trucos.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Si tienes cualquier duda o comentario recuerda que puedes exponerlo aquí o bien mediante nuestro <a href="http://twitter.com/InvExpression" target="_blank">twitter </a>y <a href="https://www.facebook.com/InvExpression" target="_blank">facebook</a>.</div>
<div style="text-align: justify;">
<br /></div>Miguelhttp://www.blogger.com/profile/16782448155425363883noreply@blogger.com9tag:blogger.com,1999:blog-4451099318087488891.post-53868880347033814722016-06-23T10:40:00.002+02:002020-12-23T00:01:26.244+01:00Truco Delphi - MessageBox organizados y personalizados.<div style="text-align: justify;">
Si eres, o has sido, programador Delphi, seguramente te has encontrado muchas aplicaciones donde se utiliza la función <b>Showmessage</b>, <b>MessageBox </b>o <b>Messagedlg </b>o incluso todas a la vez de manera desorganizada y no unificada.</div>
<br />
<div style="text-align: center;">
<a href="http://4.bp.blogspot.com/-pr4jFMH7xq0/V2ue9w9fROI/AAAAAAAANls/OcNDdfF0yREocIEf_Eu38-6FU8oJ_FqfwCK4B/s1600/Sin%2Bt%25C3%25ADtulo2.png"><img border="0" height="156" src="https://4.bp.blogspot.com/-pr4jFMH7xq0/V2ue9w9fROI/AAAAAAAANls/OcNDdfF0yREocIEf_Eu38-6FU8oJ_FqfwCK4B/s320/Sin%2Bt%25C3%25ADtulo2.png" width="320" /></a></div>
<div style="text-align: center;">
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
En este truco/post os voy a mostrar como organizar vuestros mensajes de aplicación en una única unidad y como personalizarlos con vuestros propios iconos sin necesidad de crear formularios específicos para ellos.</div>
<br />
<div style="text-align: justify;">
Mi recomendación es que utilicéis siempre <b>MessageBox</b>, por dos motivos:</div>
<ol>
<li style="text-align: justify;"><b>MessageBox </b>es una función de la <b>Api </b>de <b>Windows</b>, por tanto, los textos de los botones estarán localizados al idioma del sistema.</li>
<li style="text-align: justify;">Permite una mayor personalización y control de los mensajes mostrados.</li>
</ol>
<div style="text-align: justify;">
En toda aplicación suelen utilizarse, al menos, tres tipos de mensajes de diálogo con el usuario; Mensajes de <u>error</u>, mensajes de <u>aviso </u>y mensajes de <u>pregunta</u>.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Mi recomendación es que os creéis una unidad donde agrupéis todos esos mensajes de manera que podáis utilizarlos en toda la aplicación, por ejemplo algo así:</div>
<br />
<pre class="prettyprint"><code class="language-pascal">
unit UDialogos;
interface
uses Windows;
procedure MensajeError(owner: HWND; p_texto :string);
procedure MensajeAviso(owner: HWND; p_texto :string);
function Pregunta(owner: HWND; p_texto, p_titulo: string) : boolean;
implementation
procedure MensajeError(owner: HWND; p_texto :string);
begin
MessageBox(owner, pchar(p_texto), 'Error',
MB_ICONERROR or MB_OK or MB_TASKMODAL)
end;
procedure MensajeAviso(owner: HWND; p_texto :string);
begin
MessageBox(owner, pchar(p_texto),'Aviso',
MB_ICONINFORMATION or MB_OK or MB_TASKMODAL )
end;
function Pregunta(owner: HWND; p_texto, p_titulo: string) : boolean;
begin
result := MessageBox(owner, pchar(p_texto), pchar(p_titulo),
MB_ICONQUESTION or MB_YESNO or MB_TASKMODAL) = IDYES
end;
end.
</code>
</pre>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
De esta manera tendremos todos los mensajes localizados en una unidad de nuestra aplicación y a nuestra disposición para cuando los necesitemos.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Es importante utilizar correctamente el parámetro "<i>owner</i>" de esas funciones y pasárles siempre el "<i>Handle</i>" del formulario que llama a la función ("<b>Self.Handle</b>") para que los diálogos sepan delante de quién deben mostrarse.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Si no os gustan los iconos por defecto que muestra <b>Windows</b>, siempre podéis utilizar los vuestros utilizando "<b>MB_USERICON</b>", pero en este caso deberéis utilizar la función <b>MessageBoxIndirect</b>.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Supongamos que tenemos un icono en los recursos de nuestra aplicación llamado '<i>ICONICO</i>' y que queremos mostrarlo en un mensaje de dialogo concreto, escribiríamos lo siguiente:</div>
<br />
<pre class="prettyprint"><code class="language-pascal">
procedure MensajePersonalizado(owner: HWND; p_texto, p_titulo :string);
var
flags : uint;
MsgPars: TMsgBoxParams;
begin
flags := MB_USERICON or MB_OK or MB_DEFBUTTON1 or MB_TASKMODAL;
//Establecemos los parámetros
with MsgPars do
begin
cbSize := SizeOf(MsgPars);
hwndOwner := owner;
hInstance := Sysinit.hInstance;
lpszText := PChar(p_texto);
lpszCaption := pchar(p_titulo );
dwStyle := flags;
lpszIcon := 'ICONICO'; //Nuestro icono en los recursos
dwContextHelpId := 0;
lpfnMsgBoxCallback := nil;
dwLanguageId := LANG_NEUTRAL;
end;
MessageBoxIndirect(MsgPars);
end;
</code>
</pre>
<br />
<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-MRynqJLOJwI/V2uZ9DffSUI/AAAAAAAANlU/uJV33uybN1cfIYYGAbPbj12GFwVvdw9EgCK4B/s1600/Sin%2Bt%25C3%25ADtulo.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="168" src="https://1.bp.blogspot.com/-MRynqJLOJwI/V2uZ9DffSUI/AAAAAAAANlU/uJV33uybN1cfIYYGAbPbj12GFwVvdw9EgCK4B/s400/Sin%2Bt%25C3%25ADtulo.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Una última consideración sobre utilizar <b>MB_OKCANCEL </b>o <b>MB_YESNO</b>. Cualquier flag que incluya <b>OK </b>y/o <b>CANCEL </b>responderá a las teclas "Intro" para el <b>OK </b>y "Escape" para el <b>CANCEL</b>, es decir, si utilizáis <b>MB_YESNO</b>, "<i>intro</i>" y "<i>escape</i>" no funcionarán, si utilizáis <b>MB_OKCANCEL</b>, si que lo harán.</div>
<br />
Si tienes cualquier duda o comentario recuerda que puedes exponerlo aquí o bien mediante nuestro <a href="http://twitter.com/InvExpression" target="_blank">twitter </a>y <a href="https://www.facebook.com/InvExpression" target="_blank">facebook</a>.Miguelhttp://www.blogger.com/profile/16782448155425363883noreply@blogger.com0tag:blogger.com,1999:blog-4451099318087488891.post-2945131666534565682016-06-21T12:02:00.001+02:002016-06-21T12:51:25.494+02:00¿Qué pasaría si todo el mundo fuese capaz de programar? Estamos a punto de averiguarlo.<div class="MsoNormal">
<br /></div>
<div class="MsoNormal" style="text-align: justify;">
Podemos estar entrando en una era en la que cualquiera es
capaz de hacer programas, a pesar de que no sepan programación – al menos no de la
manera en la que la mayoría nosotros lo entendemos ahora mismo.<o:p></o:p></div>
<div class="MsoNormal" style="text-align: justify;">
<br /></div>
<div class="MsoNormal" style="text-align: justify;">
He empezado a jugar con una aplicación para <b>iPad </b>llamada
<b><a href="http://getready.io/" target="_blank">Ready</a></b>, que permite a los más pequeños hacer pequeños juegos, aplicaciones
sencillas, y proyectos digitales creativos. Utiliza una sencilla interfaz <b>“drag-and-drop”</b>
(arrastra y suelta) para crear objetos, cambiar sus propiedades, y hacer que interactúen
entre ellos o con el usuario.<o:p></o:p></div>
<div class="MsoNormal" style="text-align: justify;">
<br /></div>
<div class="MsoNormal" style="text-align: center;">
<a href="http://4.bp.blogspot.com/-7tjJBPrroMI/V2kOwNCA7JI/AAAAAAAANkg/IAE1qzy44dcyJ3BMp_WiL1YNRTWMG9Y-QCK4B/s1600/Create.png" imageanchor="1"><img border="0" height="238" src="https://4.bp.blogspot.com/-7tjJBPrroMI/V2kOwNCA7JI/AAAAAAAANkg/IAE1qzy44dcyJ3BMp_WiL1YNRTWMG9Y-QCK4B/s320/Create.png" width="320" /></a></div>
<div class="MsoNormal" style="text-align: justify;">
<br /></div>
<div class="MsoNormal" style="text-align: justify;">
Crear una pelota, proporcionarle “<b>físicas</b>” para que responda
a la gravedad; convertirla en goma para que “rebote” sobre las superficies;
hacer una barra que se mueva de izquierda a derecha con los cursores; construir
un muro de bloques que desaparecen cuando son golpeados por la pelota y listo…
tenemos un <b>Arkanoid </b>de toda la vida.<o:p></o:p></div>
<div class="MsoNormal" style="text-align: justify;">
<br /></div>
<div class="MsoNormal" style="text-align: justify;">
Lo que <b>WYSISWYG </b>(<i>lo que ves es lo que obtienes</i>) hizo por la
creación de documentos, lo hacerReady por la programación. Pero los efectos
podrían ir más allá que el mero ahorro de tiempo.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<h3>
Programación Drag-and-Drop</h3>
<div class="MsoNormal">
<o:p></o:p></div>
<div class="MsoNormal" style="text-align: justify;">
Ready realmente es un escritorio de <b>Unity</b>, el motor de juego
multiplataforma que a su vez está basado en <b>C</b> y <b>C++</b>. Al permitir a los niños
desarrollar juegos simplemente utilizando <b>drag-and-drop</b> e interfaces <b>if/then</b>,
Ready sitúa a jóvenes desarrolladores un nivel por encima de lo que podríamos
considerar como código “<i>real</i>” – pero sigue permitiéndoles crear desde cero.</div>
<div class="MsoNormal" style="text-align: justify;">
<br /></div>
<div class="MsoNormal">
<o:p></o:p></div>
<div class="MsoNormal" style="text-align: justify;">
Yendo más allá, imagino que los usuarios, con el tiempo, serán
capaces de profundizar lo suficiente para crear sus propios objetos y elementos
– quizá incluso ofreciéndolos a otros en un mercado digital. Piensa en un <b>Minecraft</b>, pero construido desde el principio para ser una plataforma creativa
completamente abierta.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal" style="text-align: center;">
<a href="http://3.bp.blogspot.com/-htoq0nKEdXk/V2kO1p3FQ0I/AAAAAAAANko/-EN6caw5D_Yp53mkquvsSTrLtOkrlYDBQCK4B/s1600/a%252Bk8%252Bm.jpg" imageanchor="1"><img border="0" height="240" src="https://3.bp.blogspot.com/-htoq0nKEdXk/V2kO1p3FQ0I/AAAAAAAANko/-EN6caw5D_Yp53mkquvsSTrLtOkrlYDBQCK4B/s320/a%252Bk8%252Bm.jpg" width="320" /></a></div>
<div class="MsoNormal" style="text-align: center;">
<br /></div>
<h3>
Las buenas ideas son más valoradas que el buen código.</h3>
<div class="MsoNormal">
<o:p></o:p></div>
<div class="MsoNormal" style="text-align: justify;">
Jugar con estas herramientas hace que me pregunte si, dentro
de poco, todos nosotros estaremos desarrollando de esta manera. ¿Podría "<i>Ready</i>" y
otros escritorios similares hacer por la programación lo que hizo <b>Photoshop </b>por
las imágenes o <b>Word </b>por la creación documental?. Si lo hace, entonces la
creación de aplicaciones por “<i>no-programadores</i>” con buenas ideas podría ser
inminente. Aunque el código puede no ser tan elegante ni optimizado como si un
desarrollador lo escribiera desde cero, este tipo de aplicaciones serían
válidas como prototipos.</div>
<h3>
<br />Cuanto más fáciles sean los ordenadores, más se alejan los
usuarios de ser programadores.</h3>
<div class="MsoNormal">
<o:p></o:p></div>
<div class="MsoNormal">
<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal" style="text-align: justify;">
Un conjunto configurable de elementos y objetos como "<i>Ready</i>" puede que no tenga en cuenta las infinitas posibilidades y nuevas innovaciones
de la codificación pura, pero la mayoría de los programas actualmente no usan
ese tipo de innovación de todos modos. Pensemos en <b>Uber</b>. Una aplicación <b>GPS
</b>enlazada a una <b>aplicación de cobros</b> enlazada a una <b>aplicación de citas</b>. Y los
nuevos programadores no van a intentar crear nada tan robusto como una
plataforma de intercambio de ficheros global ni nada parecido.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal" style="text-align: justify;">
Antes de que los más puristas empecéis a atacar el concepto
de una programación que se dirige más hacia <b>PowerPoint </b>que hacia <b>Python</b>, consideremos por un momento que podríamos decir lo mismo sobre cualquier
<u>lenguaje de programación</u>. Después de todo <b>C++</b> o cualquier <u>lenguaje de alto
nivel</u>, pasa a través de un compilador para convertirse en algo que la mayoría
de nosotros es incapaz de leer. Y el programa en sí mismo se asienta sobre un
sistema operativo, y <u>lenguaje ensamblador</u>, e <u>instrucciones máquina</u>, y
arquitectura basada en chips… Puedes considerarte a ti mismo un desarrollador
de software competente sin haber bajado jamás a ese nivel de comprensión.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal" style="text-align: justify;">
Créeme, yo me encuentro entre los puristas, resentidos por
la aparición del <b>Mac </b>y otras interfaces que parecían diseñadas
intencionadamente para hacer la computación “<i>más fácil</i>” simplemente
distanciando a los usuarios de las funciones básicas. <b>Microsoft </b>hizo que
invocásemos a “<i>the wizard</i>” (el mago), como si fuera algo misterioso que las
aplicaciones y sus extensiones acabasen en el directorio correcto. Cuanto más fáciles
sean los ordenadores, más se alejan los usuarios de ser programadores. Echo de
menos mi fichero <b>autoexec.bat</b>…<o:p></o:p></div>
<div class="MsoNormal" style="text-align: justify;">
<br /></div>
<div class="MsoNormal" style="text-align: center;">
<a href="http://4.bp.blogspot.com/-PDxkV563AXs/V2kO5bzD03I/AAAAAAAANkw/iyCLmhwp7wgWxFlQkvvb-NbvknzJp6-4wCK4B/s1600/e%252Bk1.jpg" imageanchor="1"><img border="0" height="240" src="https://4.bp.blogspot.com/-PDxkV563AXs/V2kO5bzD03I/AAAAAAAANkw/iyCLmhwp7wgWxFlQkvvb-NbvknzJp6-4wCK4B/s320/e%252Bk1.jpg" width="320" /></a><br />
<br /></div>
<h3>
Más que un simple ahorro de tiempo.</h3>
<div class="MsoNormal">
<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal" style="text-align: justify;">
“<i>Ready</i>” me hace pensar que la simplificación de las
interfaces de usuario puede, finalmente, ofrecer algo distinto a un simple distanciamiento del código: el poder. La gratificación instantánea de construir
algo en “<i>Ready</i>” proporciona esa sensación de poder – casi como ser el autor de
<b>Hypercard </b>en los primeros días de <b>Macintosh </b>o construir un sitio en <b>WordPress
</b>cuando mi ambición y necesidades superan claramente mis habilidades. Hay un
<i>plug-in</i> de <b>WordPress </b>para casi todo lo que puedo querer hacer en mi sitio.<o:p></o:p></div>
<div class="MsoNormal" style="text-align: justify;">
<br /></div>
<div class="MsoNormal" style="text-align: justify;">
Una cosa es cierta, si la gente no tiene que escribir código, puede
que nunca entiendan cómo funcionan realmente las cosas. Estarán limitados por
las posibilidades ofrecidas por los creadores de las plataformas, a través de
las cuales ensamblarán componentes prefabricados en aplicaciones y otras
experiencias digitales.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal" style="text-align: justify;">
Del mismo modo que dimos la bienvenida a los usuarios de <b>AOL
</b>al Internet real, “<i>Ready</i>” y otras aplicaciones, pueden hacer entrar a legiones
de “<i>desarrolladores civiles</i>” en la industria de los juegos y las aplicaciones.
Con la democracia viene un poco de embrutecimiento. No van a ser maestros en
programación, pero tampoco son maestros en música los compositores que escriben
las canciones de las bandas de garaje. Esta puede ser la realidad creativa “mash-up” hacia la que vamos. <i style="background-color: yellow;"><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial;">(</span><span style="background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; background-position: initial; background-repeat: initial; background-size: initial; color: #222222; font-family: "arial" , sans-serif;">El<span class="apple-converted-space"> </span></span><b>mashup</b></i><span class="apple-converted-space"><i style="background-color: yellow;"> es
un género musical que consiste en la creación de un nuevo tema mediante la
combinación de fragmentos (loops), instrumentos concretos, pistas vocales (a
cappellas) y pistas instrumentales a cachitos o enteras de otros temas
anteriormente ya realizados por otros)</i>.</span> Hay
mucho que aprender si quieres estar al día. Yo era bueno en Pascal, pero hoy en
día los lenguajes de programación son muy duros y puede que no compense lo
suficiente aprenderlos.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<o:p></o:p></div>
<div class="MsoNormal" style="text-align: justify;">
Este puede ser el momento en que finalmente entramos en la
era de “<i>Bandas de Garage</i>” de la creación de aplicaciones y juegos. Las cosas
pueden ponerse complicadas, pero también serán menos comerciales, brillantes y
funcionalmente opacas.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal" style="text-align: justify;">
A pesar de todo, en un mundo en el que escribir código se ha
convertido en una habilidad rara y valiosa, una plataforma como “<i>Ready</i>” permite
a las masas experimentar el poder de la creación.<o:p></o:p></div>
<div class="MsoNormal" style="text-align: justify;">
<br /></div>
<div class="MsoNormal" style="text-align: justify;">
Esa experiencia, por si misma, puede ser más importante que
cualquiera de las aplicaciones que creemos. Cambia la manera en la que
percibimos el panorama digital en el que gastamos gran parte de nuestras vidas.
Ahora mismo todo es software creado por otros, pero con las herramientas
correctas, podría ser el software que imaginemos y creemos por nosotros mismos.<o:p></o:p></div>
<div class="MsoNormal" style="text-align: justify;">
<br /></div>
<div class="MsoNormal" style="text-align: justify;">
Estoy listo para eso.<o:p></o:p></div>
<div class="MsoNormal" style="text-align: justify;">
<br /></div>
<div class="MsoNormal" style="text-align: center;">
<a href="http://2.bp.blogspot.com/-k_UxxKM_G5s/V2kPAIbmZuI/AAAAAAAANk4/bV0LNBHRdpA28tbXfx033mbDPS_8enVuACK4B/s1600/Craft.png" imageanchor="1"><img border="0" height="238" src="https://2.bp.blogspot.com/-k_UxxKM_G5s/V2kPAIbmZuI/AAAAAAAANk4/bV0LNBHRdpA28tbXfx033mbDPS_8enVuACK4B/s320/Craft.png" width="320" /></a></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Artículo por: <b>Douglas Rushkoff.</b> Traducido y adaptado por:
<b>Miguel Montero Gámez.</b><o:p></o:p></div>
<div class="MsoNormal">
Enlace original en inglés: <a href="http://www.digitaltrends.com/features/what-happens-when-anyone-can-code/" target="_blank"><span style="background: white; color: #1155cc; font-family: "arial" , sans-serif; font-size: 9.5pt; line-height: 107%;">http://www.digitaltrends.com/<wbr></wbr>features/what-happens-when-<wbr></wbr>anyone-can-code/</span></a><o:p></o:p></div>
<br />
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<o:p>Si tienes cualquier duda o comentario recuerda que puedes exponerlo aquí o bien mediante nuestro <a href="http://twitter.com/InvExpression" target="_blank">twitter </a>y <a href="https://www.facebook.com/InvExpression" target="_blank">facebook</a>.</o:p></div>
Miguelhttp://www.blogger.com/profile/16782448155425363883noreply@blogger.com0tag:blogger.com,1999:blog-4451099318087488891.post-46728626306796241982016-06-20T10:03:00.001+02:002020-12-22T23:58:41.049+01:00Truco Delphi - Ocultar icono de nuestra aplicación en barra de tareasHoy toca un truco rápido, fácil y para toda la familia que consiste en ocultar el icono de nuestra aplicación de la barra de tareas en <b>Delphi</b>.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-VTFF_7d2jn0/V2ehhdebTdI/AAAAAAAANkE/aeDJxYi21ko1Bu02GQqdktc6swQVpjh3ACK4B/s1600/Three-RAD-logos.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://2.bp.blogspot.com/-VTFF_7d2jn0/V2ehhdebTdI/AAAAAAAANkE/aeDJxYi21ko1Bu02GQqdktc6swQVpjh3ACK4B/s400/Three-RAD-logos.png" /></a></div>
<div style="text-align: center;">
<br /></div>
¿Para que sirve esto? Bueno, eso depende; imaginad que necesitáis hacer una aplicación iconizada en el área de notificaciones (Al lado del reloj) y que queréis que cuando se muestre no aparezca el icono en la barra de tareas (igual que el reloj de <b>Windows</b> por ejemplo).<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-2v65ogP0YFw/V2ehV9NLHeI/AAAAAAAANj8/sYYLUMEGcqAnGX2prmxdtmEALIC8Gh49QCK4B/s1600/56756003-f624-4f18-aa2e-5516c34090d8_0.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://4.bp.blogspot.com/-2v65ogP0YFw/V2ehV9NLHeI/AAAAAAAANj8/sYYLUMEGcqAnGX2prmxdtmEALIC8Gh49QCK4B/s400/56756003-f624-4f18-aa2e-5516c34090d8_0.jpg" /></a></div>
<br />
Para ello solamente tendremos que anular la función <b>CreateParams</b> de la clase <b>TForm</b> para codificar nosotros mismos lo que necesitamos de la siguiente manera:<br />
<pre class="prettyprint"><code class="language-pascal">
TfrmPrincipal = class(TForm)
private
{ Private declarations }
protected
procedure CreateParams(var Params: TCreateParams); override;
public
{ Public declarations }
end;
procedure TfrmPrincipal.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.ExStyle := Params.ExStyle and not WS_EX_APPWINDOW;
Params.WndParent := Application.Handle;
end;
</code>
</pre>
<br />
Si tienes cualquier duda o comentario recuerda que puedes exponerlo aquí o bien mediante nuestro <a href="http://twitter.com/InvExpression" target="_blank">twitter </a>y <a href="https://www.facebook.com/InvExpression" target="_blank">facebook</a>.Miguelhttp://www.blogger.com/profile/16782448155425363883noreply@blogger.com0tag:blogger.com,1999:blog-4451099318087488891.post-36717644774425289282016-06-17T18:54:00.001+02:002020-12-22T23:57:27.960+01:00Truco Java - Añadir imágenes a un JTable desde un campo Blob en MySQL<div style="text-align: justify;">
Hoy hemos realizado una encuesta a través del twitter del blog preguntandoos sobre que lenguaje queríais el siguiente truco y ha ganado <b>JAVA</b>.</div>
<div style="text-align: center;">
</div>
<div style="text-align: center;">
<a href="http://2.bp.blogspot.com/-mc77aFdXtxU/V2QovCN7qEI/AAAAAAAANiI/QOa7GlEs-yAvODKsN1oxwayTtWeR4bdpACK4B/s1600/Java-icon.png" imageanchor="1"><img border="0" src="https://2.bp.blogspot.com/-mc77aFdXtxU/V2QovCN7qEI/AAAAAAAANiI/QOa7GlEs-yAvODKsN1oxwayTtWeR4bdpACK4B/s400/Java-icon.png" /></a></div>
<div style="text-align: center;">
<br /></div>
<div style="text-align: justify;">
Por suerte estoy realizando un master de <b>JAVA </b>ahora mismo y a diario me surgen problemas y dudas que voy solventando y que, seguramente, sean las mismas que tengáis vosotros si estáis empezando con este lenguaje.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-E5lCR4g-jSk/V2QofF0oN7I/AAAAAAAANiA/rD4N_mMipbMOdSWTsumf1fofLnMRMoNBwCK4B/s1600/3caae09bec0b82e4e125d9e1300de94b.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="221" src="https://3.bp.blogspot.com/-E5lCR4g-jSk/V2QofF0oN7I/AAAAAAAANiA/rD4N_mMipbMOdSWTsumf1fofLnMRMoNBwCK4B/s400/3caae09bec0b82e4e125d9e1300de94b.png" width="400" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
En el truco que nos ocupa hoy os voy a enseñar cómo solucioné la cuestión de mostrar un campo de imagen (tipo <b>BLOB </b>en <b>MySQL</b>) en un <b>JTable</b>.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-BLKnw42E-4E/V2QpxOc6BeI/AAAAAAAANiw/2MmDbfRu60cFQhGL0Rhkb_J_IzrjCnzNwCK4B/s1600/c83cbd39ae42a45d3916debe2ece44a3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="272" src="https://1.bp.blogspot.com/-BLKnw42E-4E/V2QpxOc6BeI/AAAAAAAANiw/2MmDbfRu60cFQhGL0Rhkb_J_IzrjCnzNwCK4B/s400/c83cbd39ae42a45d3916debe2ece44a3.png" width="400" /></a></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Os pondré el código que rellena la tabla y luego os <u>destacaré un par de secciones</u> que son las que considero más importantes.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Este es el código en cuestión:</div>
<br />
<pre class="prettyprint"><code class="language-java"> /**
* Procedimiento LlenarTabla
* Utilizando el procedimiento modeloImagen.listImagen,
* se rellena la tabla pasada por parametro.
* @param tablaImagenes
* @throws java.sql.SQLException
* @throws java.io.IOException
*/
public void LlenarTabla(JTable tablaImagenes) throws SQLException, IOException{
DefaultTableModel modeloTabla = new DefaultTableModel() {
@Override //Redefinimos el método getColumnClass
public Class getColumnClass(int column){
switch(column) {
case 0: return Object.class;
case 1: return Object.class;
case 2: return Object.class;
case 3: return ImageIcon.class;
default: return Object.class;
}
}
};
//Establecemos el modelo correspondiente en la JTable
tablaImagenes.setModel(modeloTabla);
//Añadimos las columnas correspondientes
modeloTabla.addColumn("ID IMAGEN");
modeloTabla.addColumn("ES CATEGORIA");
modeloTabla.addColumn("DESCRIPCION");
modeloTabla.addColumn("IMAGEN"); //Esta es la columna [3], es la que
//nos interesa que sea una imagen.
Object[] columna = new Object[4];
ArrayList<imagen> listaImagenes = modeloImagenes.ListarImagenXEsCategoria("","");
int numRegistros = listaImagenes.size();
for (int i = 0; i < numRegistros; i++) {
columna[0] = listaImagenes.get(i).getIdImagen();
columna[1] = listaImagenes.get(i).getEsCategoria();
columna[2] = listaImagenes.get(i).getDescripcion();
//Transformamos el campo blob en ImageIcon
Blob blob = listaImagenes.get(i).getImagen();
int blobLength = (int) blob.length();
byte[] bytes = blob.getBytes(1, blobLength);
blob.free();
BufferedImage img = ImageIO.read(new ByteArrayInputStream(bytes));
ImageIcon icon = new ImageIcon(img);
//Añadimos la imagen a la columna correspondiente
columna[3] = icon;
//Añadimos la fila al modelo
modeloTabla.addRow(columna);
//Establecemos el alto de la fila
tablaImagenes.setRowHeight(i, icon.getIconHeight());
}
}
</code>
</pre>
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div style="text-align: justify;">
No voy a entrar en el detalle de cómo recupero los datos de <b>MySQL </b>ni de cómo se define la clase <b>Imagen </b>(si queréis el código podéis pedírmelo en los comentarios y os lo facilitaré), pero sí quiero que prestéis atención a este código:</div>
<br />
<pre class="prettyprint"><code class="language-java"> DefaultTableModel modeloTabla = new DefaultTableModel() {
@Override //Redefinimos el método getColumnClass
public Class getColumnClass(int column){
switch(column) {
case 0: return Object.class;
case 1: return Object.class;
case 2: return Object.class;
case 3: return ImageIcon.class;
default: return Object.class;
}
}
};
</code>
</pre>
<br />
<div style="text-align: justify;">
Ese fragmento de código define el <b>modelo </b>que utilizará el objeto <b>JTable </b>y sobre el hemos de redefinir el método <b>getColumnClass</b> para que, en la <b>columna </b>[3] nos devuelva un <b>ImageIcon</b>, que es lo que queremos mostrar.
<br />
<br /></div>
<div style="text-align: justify;">
Otra parte importante del código, y que seguro que muchos ya conocéis, es el encargado de convertir el campo <b>BLOB </b>en un <b>ImageIcon</b>.</div>
<pre class="prettyprint"><code class="language-java">
//Transformamos el campo blob en ImageIcon
Blob blob = listaImagenes.get(i).getImagen();
int blobLength = (int) blob.length();
byte[] bytes = blob.getBytes(1, blobLength);
blob.free();
BufferedImage img = ImageIO.read(new ByteArrayInputStream(bytes));
ImageIcon icon = new ImageIcon(img);
</code>
</pre>
<br />
Con estos sencillos pasos podemos obtener el resultado deseado.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="http://4.bp.blogspot.com/-zud083-fkeE/V2QpZMK93WI/AAAAAAAANic/xDT81PLQhQ8vVz2zdPzmYjeh2L_f0EmoACK4B/s1600/f079c6ebaaaee478d3a92c47c28f0176.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="218" src="https://4.bp.blogspot.com/-zud083-fkeE/V2QpZMK93WI/AAAAAAAANic/xDT81PLQhQ8vVz2zdPzmYjeh2L_f0EmoACK4B/s320/f079c6ebaaaee478d3a92c47c28f0176.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Resultado final en una aplicación SWING</td></tr>
</tbody></table>
<div style="text-align: center;">
<br /></div>
Si tienes cualquier duda o comentario recuerda que puedes exponerlo aquí o bien mediante nuestro <a href="http://twitter.com/InvExpression" target="_blank">twitter </a>y <a href="https://www.facebook.com/InvExpression" target="_blank">facebook</a>.
Miguelhttp://www.blogger.com/profile/16782448155425363883noreply@blogger.com2tag:blogger.com,1999:blog-4451099318087488891.post-42579375571064247372016-06-16T11:48:00.001+02:002016-06-20T17:46:20.838+02:00Truco Delphi - Alternar colores de filas en DBGridHoy os presento un pequeño truco que hará que vuestros <b>DBGrids </b>luzcan mucho mejor añadiendo unas pocas lineas de código.<br />
<br />
Lo que tratamos de conseguir es que nuestro <b>DBGrid </b>presente las filas <b>con colores alternos</b> y además que la fila seleccionada se resalte también de manera alterna.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-GSwqoAeAkgg/V2Jz4G9uzzI/AAAAAAAANho/qrLnJPMHxgwnkTQvL1ebi-J1-GtaUhDYgCLcB/s1600/DBGridEasy.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="184" src="https://4.bp.blogspot.com/-GSwqoAeAkgg/V2Jz4G9uzzI/AAAAAAAANho/qrLnJPMHxgwnkTQvL1ebi-J1-GtaUhDYgCLcB/s320/DBGridEasy.jpg" width="320" /></a></div>
<br />
Para conseguir este objetivo debemos escribir la función <b>GridDrawColumnCell </b>como sigue:<br />
<br />
<br />
<pre class="brush: pascal">procedure TfrmPrincipal.GridDrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
const
RowColors: array[Boolean] of TColor = (clSilver, clWhite);
RowSelectedColors: array[Boolean] of TColor = (clHotLight, clHighlight);
var
OddRow: Boolean;
begin
if (Sender is TDBGrid) then
begin
OddRow := Odd(TDBGrid(Sender).DataSource.DataSet.RecNo);
if (gdSelected in State) then
TDBGrid(Sender).Canvas.Brush.Color := RowSelectedColors[OddRow]
else
TDBGrid(Sender).Canvas.Brush.Color := RowColors[OddRow];
TDBGrid(Sender).DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;
end;
</pre>
<br />
<br />
Este procedimiento lo podemos poner en el formulario donde esté el <b>DBGrid </b>o bien en una unidad aparte y luego importarla con el comando <b>Uses</b>. Si incluimos el procedimiento en el formulario, es importante hacerlo como procedimiento de clase:<br />
<br />
<pre class="brush: pascal"> TfrmPrincipal = class(TForm)
{ Otros métodos y propiedades del formulario }
procedure GridDrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
private
{ Private declarations }
public
{ Public declarations }
end;
</pre>
<br />
De esta manera podremos seleccionar el <b>DBGrid </b>y asignar el procedimiento al evento <b>OnDrawColumnCell</b>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-93ow03UpG8c/V2Jz2Py13HI/AAAAAAAANhg/yDPIVxe7QeUOxq09cCwJ2bZQ5Qnw0Fq6QCLcB/s1600/DrawColumnCell.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://3.bp.blogspot.com/-93ow03UpG8c/V2Jz2Py13HI/AAAAAAAANhg/yDPIVxe7QeUOxq09cCwJ2bZQ5Qnw0Fq6QCLcB/s1600/DrawColumnCell.png" /></a></div>
<br />
Si tienes cualquier duda o comentario recuerda que puedes exponerlo aquí o bien mediante nuestro <a href="http://twitter.com/InvExpression" target="_blank">twitter </a>y <a href="https://www.facebook.com/InvExpression" target="_blank">facebook</a>.Miguelhttp://www.blogger.com/profile/16782448155425363883noreply@blogger.com0tag:blogger.com,1999:blog-4451099318087488891.post-31298399905649248982016-06-15T14:14:00.001+02:002016-06-20T17:46:20.816+02:00Truco Delphi - Prevenir la ejecución de más de una instancia de nuestra aplicación (I)<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-xW91d8K70ss/VoqWH3QNBwI/AAAAAAAAM_k/wPlrKVVIYiURUw2OEyg1KhWwSsHsJY0OgCKgB/s1600/cropped-istock_000011998528medium.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="67" src="https://1.bp.blogspot.com/-xW91d8K70ss/VoqWH3QNBwI/AAAAAAAAM_k/wPlrKVVIYiURUw2OEyg1KhWwSsHsJY0OgCKgB/s320/cropped-istock_000011998528medium.jpg" width="320" /></a></div>
<br />
Hace ya bastante tiempo que no posteo, pero eso no quiere decir que me haya olvidado de vosotros.<br />
Como no dispongo de mucho tiempo para continuar con el curso de Lazarus y postear de forma asidua los artículos que tenía previstos, voy a empezar a postear pequeños tips y códigos de ejemplo para resolver pequeños problemas que me surgen en el día a día.<br />
<br />
Hoy quiero mostraros como hacer que vuestra aplicación no se ejecute más de una vez, pero, en lugar de manteniendo la instancia más antigua, haciendo que la nueva instancia tome el control, es decir, que la nueva ejecución sustituya a la antigua.<br />
<br />
Para ello nos vamos a basar en el procedimiento de <b>WinApi GetCurrentProcessId</b>, que nos dará el id de proceso del programa que estamos ejecutando y en el objeto <b>TApplication </b>para obtener el <b>ExeName </b>que será el que buscaremos.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-70K28P8oY5A/VqnX_80nQgI/AAAAAAAANEY/fFFODX_Vnq8NACqqtmBpIVtjni5GxPgxwCKgB/s1600/delphi.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://2.bp.blogspot.com/-70K28P8oY5A/VqnX_80nQgI/AAAAAAAANEY/fFFODX_Vnq8NACqqtmBpIVtjni5GxPgxwCKgB/s1600/delphi.gif" /></a></div>
<br />
<br />
Básicamente lo que pretendemos es terminar cualquier proceso que se llame como el nuestro, pero que no sea el nuestro :D<br />
<br />
<br />
Añadimos el siguiente código en el evento <b>OnCreate </b>de nuestro formulario principal.
<br />
<br />
<pre class="brush: pascal">procedure TfrmPrincipal.FormCreate(Sender: TObject);
begin
FProcessID := GetCurrentProcessId;
FExeName := ExtractFileName(Application.ExeName);
CerrarInstancias;
end;
</pre>
<br />
Este es el código que recorrerá todos los procesos de <b>Windows </b>y eliminará las instancias que existan de nuestra aplicación excepto la actual.
<br />
<br />
<pre class="brush: pascal">procedure TfrmPrincipal.CerrarInstancias;
const
PROCESS_TERMINATE = $0001;
var
ContinueLoop: BOOL;
FSnapshotHandle: THandle;
FProcessEntry32: TProcessEntry32;
begin
FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
while Integer(ContinueLoop) <> 0 do
begin
if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) =
UpperCase(FExeName)) or
(UpperCase(FProcessEntry32.szExeFile) =
UpperCase(FExeName))) and
(FProcessEntry32.th32ProcessID <> FProcessID)
then
begin
TerminateProcess(OpenProcess(PROCESS_TERMINATE,
BOOL(0),
FProcessEntry32.th32ProcessID),
0);
end;
ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
end;
CloseHandle(FSnapshotHandle);
end;
</pre>
<br />
Mas adelante pondré otras maneras de prevenir la ejecución de más de una instancia de nuestras aplicaciones.
Miguelhttp://www.blogger.com/profile/16782448155425363883noreply@blogger.com0tag:blogger.com,1999:blog-4451099318087488891.post-25336353671654662572016-03-31T11:53:00.000+02:002016-06-20T17:46:20.804+02:00Hola Mundo multilingüe<h2>
¡Hola Mundo!</h2>
<div style="text-align: justify;">
Aprovechando que he implementado <a href="http://alexgorbatchev.com/SyntaxHighlighter" target="_blank"><b>SyntaxHighLighter</b> </a>en el blog, vamos a hacer un repaso por la mayoría de lenguajes de programación haciendo lo primero que debería hacer todo programador que empieza con un nuevo lenguaje de programación; el programa <b>"Hola Mundo"</b></div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Espero que os guste el formato. A partir de ahora empezaré a incluir entradas con tips de programación en diferentes lenguaje y <i>rutinas interesantes</i> para que las tengamos todos a mano.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-9EJ1uJws5l8/Vv0EjL6yuyI/AAAAAAAANcQ/Xjn9MoQKLeEfNZwyDPkV_ouY48y1YEjeQ/s1600/helloworld.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="124" src="https://2.bp.blogspot.com/-9EJ1uJws5l8/Vv0EjL6yuyI/AAAAAAAANcQ/Xjn9MoQKLeEfNZwyDPkV_ouY48y1YEjeQ/s320/helloworld.gif" width="320" /></a></div>
<h3>
ColdFusion
</h3>
<pre class="brush: coldfusion"><html>
<head>
<title>Test</title>
</head>
<body>
<cfset message = "¡Hola Mundo!">
<cfoutput>#message#</cfoutput>
</body>
</html>
</pre>
<br />
<h3>
C#
</h3>
<pre class="brush: csharp">using System;
namespace HelloWorld
{
class Hello
{
static void Main()
{
Console.WriteLine("¡Hola Mundo!");
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
</pre>
<br />
<h3>
C++
</h3>
<pre class="brush: cpp">#include <iostream>
int main()
{
std::cout << "¡Hola Mundo!" << std::endl;
return 0;
}
</pre>
<br />
<h3>
Delphi/Pascal
</h3>
<pre class="brush: pascal">program Hello;
begin
writeln ('¡Hola Mundo!');
readln
end.
</pre>
<br />
<h3>
JavaScript
</h3>
<pre class="brush: jscript"><!DOCTYPE HTML>
<html>
<body>
<p>Header...</p>
<script>
alert('¡Hola Mundo!')
</script>
<p>...Footer</p>
</body>
</html>
</pre>
<br />
Java
<br />
<pre class="brush: java">public class HelloWorld {
public static void main(String[] args) {
System.out.println("¡Hola Mundo!");
}
}
</pre>
<br />
<h3>
Perl
</h3>
<pre class="brush: perl"> #!/usr/bin/env perl
use v5.10.0;
use warnings;
use strict;
say "¡Hola Mundo!";</pre>
<br />
<h3>
Php
</h3>
<pre class="brush: php"><html>
<head>
<title>Test</title>
</head>
<body>
<?php
$message = "¡Hola Mundo!";
echo $message;
?>
</body>
</html>
</pre>
<br />
<h3>
PowerShell
</h3>
<pre class="brush: powershell">$strString = "¡Hola Mundo!"
write-host $strString
</pre>
<br />
<h3>
Python
</h3>
<pre class="brush: python">print("¡Hola Mundo!")</pre>
<br />
<h3>
Ruby
</h3>
<pre class="brush: ruby">puts '¡Hola Mundo!'</pre>
<br />
<h3>
Visual Basic
</h3>
<pre class="brush: vb">Module Hello
Sub Main()
MsgBox("¡Hola Mundo!")
End Sub
End Module
</pre>
<br />Miguelhttp://www.blogger.com/profile/16782448155425363883noreply@blogger.com0tag:blogger.com,1999:blog-4451099318087488891.post-87067863449047643752016-03-28T17:13:00.000+02:002016-06-20T17:46:20.880+02:00Juegos para programar: Lightbot: Code HourHace ya varias semanas desde la última entrada y varias más desde el primer artículo sobre <b><a href="http://www.invalidexpression.net/2016/02/juegos-para-programar-bit-by-bit.html" target="_blank">"Juegos para programar"</a>.</b> Lo cierto es que he estado bastante ocupado con el <i>Master de Java, Semana Santa, Vacaciones, etc</i>... pero aquí estamos de nuevo para volver a bloguear más a menudo.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/s_n-sqep3MRkLuO85n3l0_8nba1Z4XcT7L0AryF2YRt5I2WOn5_eyG1jxn5aIpoMPQ=w300-rw" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://4.bp.blogspot.com/s_n-sqep3MRkLuO85n3l0_8nba1Z4XcT7L0AryF2YRt5I2WOn5_eyG1jxn5aIpoMPQ=w300-rw" width="200" /></a></div>
<br />
<h3>
LightBot: Code Hour</h3>
Hoy os traemos un juego que hará las delicias de los pequeños y no tan pequeños. Se llama <b><a href="https://play.google.com/store/apps/details?id=com.lightbot.lightbothoc" rel="nofollow" target="_blank">LightBot: Code Hour.</a></b> Este pequeño juego es gratuito y nos ofrece una <b>secuencia de puzzles</b> que irán creciendo en dificultad y que nos acercarán a temas tan propios de la programación como los <b>procedimientos</b> y los<b> bucles.</b><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-s-OseR4vyu4/VvlFmiEi5cI/AAAAAAAANbc/t9rnK-IBebE92n5cb4SdGm4WeyfVlbBOQ/s1600/Screenshot_2016-03-28-11-50-03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="179" src="https://4.bp.blogspot.com/-s-OseR4vyu4/VvlFmiEi5cI/AAAAAAAANbc/t9rnK-IBebE92n5cb4SdGm4WeyfVlbBOQ/s320/Screenshot_2016-03-28-11-50-03.png" width="320" /></a></div>
<br />
<h3>
¿En que consiste?</h3>
El juego consiste en dirigir nuestro <b>LightBot</b> hacia una serie de<b> cuadrículas azules</b>, distribuidas por un tablero, y encendiendo una bombilla sobre ellos. La gracia del asunto es que tenemos un<b> número máximo de acciones</b> que podemos llevar a cabo para acabar cada una de las fases.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/--T5b-x9maPM/VvlGytN-yoI/AAAAAAAANbk/6AC4ggmY838juftJ93Tfet5SOnfTEjmYw/s1600/Screenshot_2016-03-28-11-48-37.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="https://4.bp.blogspot.com/--T5b-x9maPM/VvlGytN-yoI/AAAAAAAANbk/6AC4ggmY838juftJ93Tfet5SOnfTEjmYw/s320/Screenshot_2016-03-28-11-48-37.png" width="320" /></a></div>
<div style="text-align: justify;">
<br /></div>
<br />
Tendréis la posibilidad de seleccionar el <b>idioma</b> que queráis (entre ellos el<i> español</i>) y el <b>género</b> de vuestro <b>LightBot</b>.<br />
<br />
El juego <i>puede resultar algo corto,</i> pero si tenemos en cuenta que es <u>gratuito</u> y a quién va dirigido, no me cabe duda de que será muy interesante para los más pequeños.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-PTgQlIZhV90/VvlHMRXyDDI/AAAAAAAANbs/W9gWK5fw0-Ufr4boF_y54OecNxPHfwNWw/s1600/Screenshot_2016-03-28-11-49-26.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="https://3.bp.blogspot.com/-PTgQlIZhV90/VvlHMRXyDDI/AAAAAAAANbs/W9gWK5fw0-Ufr4boF_y54OecNxPHfwNWw/s320/Screenshot_2016-03-28-11-49-26.png" width="320" /></a></div>
<div style="text-align: justify;">
<br /></div>
<br />
<h3>
Otras versiones</h3>
Si os quedáis con ganas de más, tenéis disponibles dos versiones adicionales de LightBot, una <b>de 4 a 8 años </b>y otra para edades <b>de 9 en adelante</b>. Desafortunadamente estas versiones ya son de pago y su precio oscila<u> entre los 2,99€ y los 3,18€</u> dependiendo de la versión y la plataforma.<br />
<br />
Además tenéis una versión de navegador <a href="https://lightbot.com/hocflash.html" rel="nofollow" target="_blank">a la que podéis acceder desde aquí </a>y jugar gratuitamente<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-dsA2mcT8GeM/VvlH4phc2QI/AAAAAAAANb4/Zrhz0qovvOMOi79I6Q6LYhZ1wjI0ZMSLg/s1600/a88bd8cc531416445745bdf8631844dc.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="152" src="https://2.bp.blogspot.com/-dsA2mcT8GeM/VvlH4phc2QI/AAAAAAAANb4/Zrhz0qovvOMOi79I6Q6LYhZ1wjI0ZMSLg/s320/a88bd8cc531416445745bdf8631844dc.png" width="320" /></a></div>
<br />
Espero que os haya gustado este post y que me dejéis en los comentarios si queréis que hable sobre algún juego concreto que consideréis interesante para esta temática y lo incluiré sin problemas.<br />
<br />Miguelhttp://www.blogger.com/profile/16782448155425363883noreply@blogger.com0tag:blogger.com,1999:blog-4451099318087488891.post-9380261206055155322016-03-02T09:26:00.001+01:002016-06-20T17:46:20.893+02:00Retrospectiva. Febrero 2016<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-bJ7ZA0s9bdE/Vq--nyEos6I/AAAAAAAANFw/Qsvp3STFZ_8/s1600/noftrdimg-1006x250.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="155" src="https://3.bp.blogspot.com/-bJ7ZA0s9bdE/Vq--nyEos6I/AAAAAAAANFw/Qsvp3STFZ_8/s640/noftrdimg-1006x250.jpg" width="640" /></a></div>
<div style="font-size: 11pt; margin: 0in;">
<br /></div>
<div style="font-size: 11pt; margin: 0in;">
<br /></div>
<div style="font-size: 11pt; margin: 0in; text-align: justify;">
<span style="font-family: inherit;">Ya
estamos en Marzo y, de la misma manera que el mes pasado y como haremos todos
los meses, toca hacer una retrospectiva sobre el mes que acaba de pasar.</span></div>
<div style="font-size: 11pt; margin: 0in; text-align: justify;">
<br /></div>
<div style="font-size: 11pt; margin: 0in; text-align: justify;">
<span style="font-family: inherit;">A
veces las cosas no salen como uno quiere, unas veces debido a imprevistos y otras
(la mayoría) por errores de estimación o planificación. Este mes en el blog
hemos tenido un poco de todo: Por un lado, como algunos ya sabéis, estoy
viviendo en <b>Mallorca</b>, pero mi familia está en <b>Almería</b>. Esto implica que,
aproximadamente, cada dos semana estoy yendo a ver a mi mujer y a mis hijas, y
este mes no había tenido en cuenta estos viajes para la planificación del blog.
En realidad esto no supone ningún problema ya que he decidido tomarme este blog
como lo que es,<b> mi hobbie</b>, así que no pienso agobiarme por no publicar un post
durante la semana ni nada por el estilo. Por otro lado muchos que me seguís en
las redes sociales sabréis que he empezado un curso experto de Java,<b> (J2SE,
J2EE y Android)</b> y el tiempo que me va a consumir su realización.</span></div>
<div style="font-size: 11pt; margin: 0in; text-align: justify;">
<br /></div>
<div style="font-size: 11pt; margin: 0in; text-align: justify;">
<span style="font-family: inherit;">En
la<a href="http://www.invalidexpression.net/2016/02/retrospectiva-enero-2016.html" target="_blank"> retrospectiva de Enero</a> os comentaba que intentaría subir a <b>9 los post
durante este Febrero</b>; esto no ha podido ser así debido a lo que os comentaba un
poco más arriba. También quería seguir añadiendo mejoras al blog que han tenido
que posponerse para este mes. Lo que si ha podido empezar es el curso de Delphi
sobre Lazarus cuyos dos primeros capítulos tenéis aquí:</span></div>
<div style="font-size: 11pt; margin: 0in;">
<br /></div>
<ul style="direction: ltr; margin-bottom: 0in; margin-left: .375in; margin-top: 0in; unicode-bidi: embed;" type="disc">
<li style="margin-bottom: 0px; margin-top: 0px; vertical-align: middle;"><span style="font-size: 11pt;"><a href="https://www.blogger.com/Ya%20estamos%20en%20Marzo%20y,%20de%20la%20misma%20manera%20que%20el%20mes%20pasado%20y%20como%20haremos%20todos%20los%20meses,%20toca%20hacer%20una%20retrospectiva%20sobre%20el%20mes%20que%20acaba%20de%20pasar.%20%20%20A%20veces%20las%20cosas%20no%20salen%20como%20uno%20quiere,%20a%20veces%20debido%20a%20imprevistos%20y%20otras%20(la%20mayor%C3%ADa)%20por%20errores%20de%20estimaci%C3%B3n%20o%20planificaci%C3%B3n.%20Este%20mes%20en%20el%20blog%20hemos%20tenido%20un%20poco%20de%20todo:%20Por%20un%20lado,%20como%20algunos%20ya%20sab%C3%A9is,%20estoy%20viviendo%20en%20Mallorca,%20pero%20mi%20familia%20est%C3%A1%20en%20Almer%C3%ADa.%20Esto%20implica%20que,%20aproximadamente,%20cada%20dos%20semana%20estoy%20yendo%20a%20ver%20a%20mi%20mujer%20y%20a%20mis%20hijas,%20y%20este%20mes%20no%20hab%C3%ADa%20tenido%20en%20cuenta%20estos%20viajes%20para%20la%20planificaci%C3%B3n%20del%20blog.%20En%20realidad%20esto%20no%20supone%20ning%C3%BAn%20problema%20ya%20que%20he%20decidido%20tomarme%20este%20blog%20como%20lo%20que%20es,%20mi%20hobbie,%20as%C3%AD%20que%20no%20pienso%20agobiarme%20por%20no%20publicar%20un%20post%20durante%20la%20semana%20ni%20nada%20por%20el%20estilo.%20Por%20otro%20lado%20muchos%20que%20me%20segu%C3%ADs%20en%20las%20redes%20sociales%20sabr%C3%A9is%20que%20he%20empezado%20un%20curso%20experto%20de%20Java,%20(J2SE,%20J2EE%20y%20Android)%20y%20el%20tiempo%20que%20me%20va%20a%20consumir%20su%20realizaci%C3%B3n.%20%20%20En%20la%20retrospectiva%20de%20Enero%20os%20comentaba%20que%20intentar%C3%ADa%20subir%20a%209%20los%20post%20durante%20este%20Febrero;%20esto%20no%20ha%20podido%20ser%20as%C3%AD%20debido%20a%20lo%20que%20os%20comentaba%20un%20poco%20m%C3%A1s%20arriba.%20Tambi%C3%A9n%20quer%C3%ADa%20seguir%20a%C3%B1adiendo%20mejoras%20al%20blog%20que%20han%20tenido%20que%20posponerse%20para%20este%20mes.%20Lo%20que%20si%20ha%20podido%20empezar%20es%20el%20curso%20de%20Delphi%20sobre%20Lazarus%20cuyos%20dos%20primeros%20cap%C3%ADtulos%20ten%C3%A9is%20aqu%C3%AD:" target="_blank"><span style="font-family: inherit;">Capítulo 1: Introducción</span></a></span></li>
<li style="margin-bottom: 0px; margin-top: 0px; vertical-align: middle;"><span style="font-size: 11pt;"><a href="http://www.invalidexpression.net/2016/02/curso-de-delphi-capitulo-2-primera.html" target="_blank"><span style="font-family: inherit;">Capítulo 2: Primera aplicación</span></a></span></li>
</ul>
<div style="font-size: 11pt; margin: 0in;">
<br /></div>
<div style="font-size: 11pt; margin: 0in; text-align: justify;">
<span style="font-family: inherit;">Esta misma semana
tendréis el<b> siguiente capítulo disponible.</b> Si no queréis perderos nada os
recomiendo que os suscribáis al canal de <a href="https://www.youtube.com/invalidexpression" target="_blank">youtube </a>así como al<a href="http://feeds.feedburner.com/invalidexpression" target="_blank"> feed de este blog</a>,
pero eso ya es cosa vuestra (aunque os lo agradecería enormemente).</span></div>
<div style="font-size: 11pt; margin: 0in; text-align: justify;">
<br /></div>
<div style="font-size: 11pt; margin: 0in; text-align: justify;">
<span style="font-family: inherit;">Para este <b>mes de
Marzo</b> voy a ser bastante conservador en cuanto objetivos. Voy a plantearme
hacer entre <i>7-9 entradas de las cuales 4 serán capítulos del curso de <b>Delphi</b>,</i>
de manera que me quede tiempo suficiente para continuar mi curso de Delphi.
Incluiré las mejoras que tenía pensadas para Febrero y añadiré una <b>página
destinada a los cursos</b> y <b>otra destinada a una recopilación de blogs</b> que suelo
leer y que me parecen interesantes.</span></div>
<div style="font-size: 11pt; margin: 0in; text-align: justify;">
<br /></div>
<div style="font-size: 11pt; margin: 0in; text-align: justify;">
<span style="font-family: inherit;">Sin más, me despido
hasta el próximo post. </span></div>
<div style="font-size: 11pt; margin: 0in;">
<br /></div>
<br />
<div style="font-size: 11pt; margin: 0in;">
<span style="font-family: inherit;">Code Safe…</span></div>
Miguelhttp://www.blogger.com/profile/16782448155425363883noreply@blogger.com0tag:blogger.com,1999:blog-4451099318087488891.post-42424640246388841432016-02-28T20:19:00.000+01:002016-06-20T17:46:20.834+02:00Juegos para programar: Bit by Bit<div style="text-align: justify;">
Siempre he dicho que la programación <u>es un ejercicio mental</u>, independiente del lenguaje utilizado. Programar es el medio para resolver problemas utilizando un lenguaje de programación apropiado, por eso en la carrera de ingeniería informática se enseñan<i> matemáticas, lógica, algorítmia</i>, etc.</div>
<br />
<div style="text-align: justify;">
Creo que es de vital importancia, si sois padres, que enseñéis a vuestros hijos/as a <b>pensar por si mismos, a sacar conclusiones, deducir, planificar y ejecutar</b>. Hay muchas maneras de hacerlo: juegos de estrategia como el ajedrez o juegos de construcción tipo Lego, Tente, Megablocks, son un buen ejemplo. Estos juegos ayudan a los más pequeños a desarrollar su inteligencia visio-espacial y deductiva.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Hoy en día con la tecnología disponible, son muchas las opciones que tenemos al alcance de la mano. Con esta <b>serie de entradas semanales</b> pretendo acercaros los juegos y aplicaciones, tanto para <b>Android </b>como para <b>PC/navegador</b> que considero interesantes para el desarrollo de los más pequeños. Recordad que <b>siempre es recomendable estar con ellos mientras usan cualquier dispositivo conectado a internet,</b> de forma que vosotros los controléis en todo momento y de esa manera, además, compartáis un buen rato jugando, aunque sea con una "<i>maquinita</i>".</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-xoOdoqzzYpM/VtNEVEmRpfI/AAAAAAAANZk/b_Jvo3_HCMU/s1600/icon175x175.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://4.bp.blogspot.com/-xoOdoqzzYpM/VtNEVEmRpfI/AAAAAAAANZk/b_Jvo3_HCMU/s1600/icon175x175.png" /></a></div>
<br />
<h3>
Bit by Bit: Programming game:</h3>
<br />
<div style="text-align: justify;">
El juego que os quiero presentar hoy es <a href="https://play.google.com/store/apps/details?id=com.rikaiGames.BitByBitGame" target="_blank">Bit by Bit: Programming game</a>. Podréis encontrarlo en <b>Play Stor</b>e y la mecánica es tan simple que os sorprenderá. Se trata de una serie de puzzles predefinidos que tenemos que ir resolviendo para poder pasar de nivel. Para la resolución de estos puzzles tendremos que <b>utilizar distintos objetos</b> (serán diferentes para cada nivel) para llevar a los <i>Bits</i> de diferentes colores a su correspondiente destino. </div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-bcuOw4SvXN8/VtNEVMj_NzI/AAAAAAAANZs/IpFsSDy5Dnk/s1600/bit-by-bit-programming-game-17e911-h900.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://2.bp.blogspot.com/-bcuOw4SvXN8/VtNEVMj_NzI/AAAAAAAANZs/IpFsSDy5Dnk/s320/bit-by-bit-programming-game-17e911-h900.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Parece fácil ¿no?. De hecho lo es. Aunque se irá complicando con el paso de los niveles, la curva es bastante aceptable, y niños a partir de <u>5-6 años</u> no encontrarán demasiados problemas en resolver los primeros niveles una vez hayan aprendido la mecánica.</div>
<div style="text-align: justify;">
<br /></div>
<h3>
<br />¿Por que es interesante este juego?</h3>
<br />
<div style="text-align: justify;">
Este juego ha sido desarrollado con ayuda de niños, padres y especialistas en educación y, mientras juegan, los más peques aprenderán cosas como:</div>
<ul>
<li style="text-align: justify;">Planificación</li>
<li style="text-align: justify;">Creatividad en la resolución de problemas</li>
<li style="text-align: justify;">Pensamiento analítico y lógico</li>
</ul>
<div style="text-align: justify;">
Os recomiendo que lo probéis, os va a gustar. Solamente tiene una pega que comprobaréis después de la primera partida, la publicidad. Después de cada nivel el juego<b> nos mostrará un vídeo publicitario bastante molesto</b>. La manera de evitar esto es activando el <b>modo avión</b> y dejando nuestro dispositivo completamente <b>offline</b>. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Me sorprende las pocas descargas que tiene este juego y creo que es debido a una mala campaña de marqueting. Imagino que con el tiempo añadirán mas niveles y pondrán la opción de comprarlo para no tener esa molesta publicidad, siempre y cuando tengan descargas suficientes.</div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-QZfDxKKyZi4/VtNEVJy54kI/AAAAAAAANZo/ony39JRt1RA/s1600/bit-by-bit-programming-game-41c139-h900.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://2.bp.blogspot.com/-QZfDxKKyZi4/VtNEVJy54kI/AAAAAAAANZo/ony39JRt1RA/s320/bit-by-bit-programming-game-41c139-h900.jpg" width="320" /></a></div>
<br />
Si conocéis juegos de estas<i> características </i>y <i>queréis compartirlos</i>, podéis dejarme vuestros comentarios debajo del post o directamente mencionándome en mi cuenta de <a href="https://twitter.com/srmiguelmontero" target="_blank">twitter </a>y los tendré en cuenta para futuros posts.Miguelhttp://www.blogger.com/profile/16782448155425363883noreply@blogger.com4tag:blogger.com,1999:blog-4451099318087488891.post-60187314872358636152016-02-19T20:35:00.001+01:002016-06-20T17:46:20.863+02:00Historia del ratón (Mouse)<div style="text-align: justify;">
Mucho ha llovido desde los tiempos en los que teníamos que limpiar los rodillos de nuestro ratón, lustrar la bola y limpiar la alfombrilla. Muchos pensaréis que la historia del ratón empieza con esos dispositivos toscos, con 2 botones (en el mejor de los casos) y cuya precisión dependía, en gran medida, de lo limpias que mantuvieras tu mesa y tus manos, pero hay mucho más.</div>
<div>
<br /></div>
<h3>
Un poco de historia.</h3>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-DMcHx4YlHhQ/Vsdmfy163iI/AAAAAAAANYY/KVPSxTtM1Hg/s1600/douglas-engelbart-first-mouse-invention.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="194" src="https://3.bp.blogspot.com/-DMcHx4YlHhQ/Vsdmfy163iI/AAAAAAAANYY/KVPSxTtM1Hg/s320/douglas-engelbart-first-mouse-invention.jpg" width="320" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<div style="text-align: justify;">
El <b>X-Y Position Indicator for a Display System</b> (nombre inicial del dispositivo) fue diseñado por <i>Douglas Engelbart</i> y <i>Bill English</i> en el <b>Stanford Research Institute</b> (universidad de <b>Stanford</b>) durante los años 60. </div>
</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Fue el <b>9 de diciembre de 1968</b> donde se presentó el primer modelo oficial al público en <i>San Francisco</i>. Esta presentación, que duró hora y media, mostraba entornos gráficos con sistemas de ventanas y como mover el cursor mediante el <b>PIDS </b>para interactuar con ellas. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
A pesar de lo revolucionario del dispositivo, la informática del momento no estaba preparada para adoptar un dispositivo como ese. No fue hasta el<b> 27 de abril de 1981</b> cuando se lanzó la<b> Xerox Star 8010</b>, una potente estación de trabajo que incluía una interfaz gráfica que dependía enteramente de este dispositivo. Aunque era un avance el dispositivo seguía siendo muy caro. Una versión 2 años después por parte de <b>Microsoft</b>, con un precio de <i>195 dolares</i>, pasó totalmente desapercibida. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Si el ratón estaba destinado a ser un periférico disponible en cada hogar, debía costar <i>entre los 10 y los 35 dólares</i>. Eso fue lo que pensó <b>Steve Jobs</b> cuando pidió a un grupo de jóvenes el desarrollo de un periférico, fiable, barato y cuya producción pudiera realizarse en serie. En <b>1984</b> apareció la computadora <b>Macintosh</b> que sería la llamada a popularizar este periférico que nos recordaba a todos a un ratón.</div>
<div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://4.bp.blogspot.com/-yC02FpJUXxg/VsdnK_KveRI/AAAAAAAANYg/HPnDv09v5Lc/s1600/Apple_Macintosh_Plus_mouse.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://4.bp.blogspot.com/-yC02FpJUXxg/VsdnK_KveRI/AAAAAAAANYg/HPnDv09v5Lc/s320/Apple_Macintosh_Plus_mouse.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Ratón Macintosh</td></tr>
</tbody></table>
<br /></div>
<div>
<h3>
El funcionamiento.</h3>
</div>
<div>
<div style="text-align: justify;">
<br /></div>
</div>
<div>
<div style="text-align: justify;">
Aunque los ratones han evolucionado muchísimo desde sus primeras versiones de bola (mecánicos), la esencia sigue siendo la misma. El dispositivo <b>debe capturar y transmitir los movimientos del usuario al ordenador</b> para reflejar este movimiento en la pantalla. Una vez metidos en materia nos encontramos ratones de <i>bola</i>, <i>opticos </i>y <i>laser </i>en su versión <i>wired </i>(con cable) o <i>wireless</i>, <i>gaming </i>o de <i>oficina</i>, de gama alta o de gama baja. Los hay para todos los gustos y colores.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
No voy a entrar en mucho detalle sobre como funciona un ratón internamente, pero para los más curiosos os dejo un vídeo que os explicará el <b>funcionamiento de un ratón laser</b>.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/n_EdKmgdamI/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/n_EdKmgdamI?feature=player_embedded" width="320"></iframe></div>
<br /></div>
<div>
<br /></div>
<div>
<h3>
<br />Los incomprendidos.</h3>
</div>
<div>
<br /></div>
<div>
Lo cierto es que no sabía muy bien como titular a esta sección. La iba a llamar "Los grandes fiascos", pero eso sería ser demasiado cruel y quizás injusto; creo que incomprendidos define mucho mejor a los dispositivos o sistemas que voy a mencionar a continuación.<br />
<br />
<div style="text-align: justify;">
Hemos hablado de que hay dispositivos <i>wired </i>o <i>wireless</i>, pues bien, no se si sabéis (quizá alguno incluso lo haya tenido en sus tiempos de <b>386</b> o <b>486</b>) que había ratones wireless por infrarrojos. Por suerte para nosotros en los años siguientes se desarrollo la conexión por radiofrecuencia y más adelante la bluetooth (aunque esta no es que esté demasiado extendida), pero a lo que vamos; imaginaros lo que era tener que estar constantemente pendiente de donde estaba la base receptora para que el ratón no perdiese la conexión... era un infierno.</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://3.bp.blogspot.com/-WpO9a2NNhYE/VsdpL16FE6I/AAAAAAAANYw/lMSG1hM612U/s1600/15011f8dc57b5b75392a3a50ece3964d.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://3.bp.blogspot.com/-WpO9a2NNhYE/VsdpL16FE6I/AAAAAAAANYw/lMSG1hM612U/s320/15011f8dc57b5b75392a3a50ece3964d.jpg" width="255" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Raton Cordless Infrarrojo JVC</td></tr>
</tbody></table>
<br /></div>
<div>
<br /></div>
<div>
<div style="text-align: justify;">
Otro de los incomprendidos, aunque se utiliza bastante en la navegación marítima es el <b>trackball</b>. Este dispositivo, a diferencia del ratón convencional, tiene la bola en la parte superior de tal manera que el usuario puede moverla en lugar de tener que desplazar el dispositivo por una superficie. Es ideal si no disponemos de demasiado espacio pero es bastante incomodo de utilizar si ya te has acostumbrado a un ratón convencional.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://1.bp.blogspot.com/-AUl0HzN43nc/VsdmgF_AoAI/AAAAAAAANYk/DcJtv8FmZvc/s1600/hack-your-old-computer-mouse-into-retro-wireless-bluetooth-mouse.w654.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="208" src="https://1.bp.blogspot.com/-AUl0HzN43nc/VsdmgF_AoAI/AAAAAAAANYk/DcJtv8FmZvc/s320/hack-your-old-computer-mouse-into-retro-wireless-bluetooth-mouse.w654.jpg" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">TrackBall</td></tr>
</tbody></table>
<br /></div>
</div>
<div>
<br /></div>
<div>
<h3>
El futuro.</h3>
</div>
<div>
<br />
<div style="text-align: justify;">
Como se suele decir, el futuro ya está aquí. Lo vemos a diario con nuevos modelos con más funciones, con baterías que duran hasta 3 años como el caso del <b>Dendro </b>de<b> </b><i>Hiditec</i> (el ratón detecta cuando el usuario posa la mano encima para activarse); ratones como el<b> Magic Mouse</b> de <i>Apple</i>, que carece de botones, o auténticas monstruosidades gaming como el <b>Saitek</b>.</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://3.bp.blogspot.com/-jGrBopD1LuM/VsdmfQ2QiHI/AAAAAAAANYk/foRHzbF6gRY/s1600/Saitek-Cyborg-R.A.T.-9.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="191" src="https://3.bp.blogspot.com/-jGrBopD1LuM/VsdmfQ2QiHI/AAAAAAAANYk/foRHzbF6gRY/s320/Saitek-Cyborg-R.A.T.-9.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Ratón MadCatz SayTek</td></tr>
</tbody></table>
<br /></div>
<div>
Si me preguntáis a mi cual creo que será el futuro de estos dispositivos os lo diré claramente... desaparecer, no será hoy ni mañana, pero estamos viendo una tendencia muy fuerte hacia lo táctil y hacia lo virtual. Ya hay dispositivos como el <b>TrackIR </b>que detectan el movimiento de la cabeza y que permiten una inmersión total en <i>videojuegos de simulación</i>. Yo creo que el futuro pasa por un dispositivo que nos permita tener la mano libre, de forma que simplemente con el movimiento de la <i>cabeza, ojos</i> o, quien sabe, incluso <i>pensamiento</i>, permita interactuar con nuestros ordenadores de la misma manera, o mejor, que lo hacemos hoy en día.<br />
<br />
Os dejo con un vídeo sobre que es y como funciona el <b>TrackIR </b>para que os hagáis una idea de lo que viene.</div>
<div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/vHBMn1vLTAo/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/vHBMn1vLTAo?feature=player_embedded" width="320"></iframe></div>
<br />
<br />
<blockquote class="tr_bq" style="text-align: center;">
<i><span style="background-color: white; font-family: "verdana" , "geneva" , sans-serif; font-size: 15px; line-height: 26px;">"La tecnología es sólo una herramienta. En términos de llevar a los niños a trabajar juntos y motivarlos, el profesor es el más importante."</span><span style="background-color: white; font-family: "verdana" , "geneva" , sans-serif; font-size: 15px; line-height: 26px;"><br /></span><span style="background-color: white; font-family: "verdana" , "geneva" , sans-serif; font-size: 15px; line-height: 26px;"><b>Bill Gates</b></span></i></blockquote>
<br /></div>
<div>
<br /></div>
Miguelhttp://www.blogger.com/profile/16782448155425363883noreply@blogger.com2tag:blogger.com,1999:blog-4451099318087488891.post-48241812644687792192016-02-14T11:40:00.001+01:002016-12-10T12:17:36.992+01:00Curso de Delphi - Capítulo 1. Introducción<div style="text-align: justify;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-6RE5ufKZ0iw/Vq58MknL58I/AAAAAAAANFg/5QkN24ujXiA/s1600/lazarus_logo.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="91" src="https://2.bp.blogspot.com/-6RE5ufKZ0iw/Vq58MknL58I/AAAAAAAANFg/5QkN24ujXiA/s320/lazarus_logo.jpg" width="320" /></a></div>
<br />
¡Muy buenas a todos! Ya tocaba ir empezando el curso de <b>Delphi </b>sobre el <b>IDE Lazarus</b>, así que aquí tenéis el primer vídeo con la <i>presentación del curso</i> y la <i>introducción al IDE</i> que utilizaremos para llevarlo a cabo.</div>
<div style="text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/s_vi/mwvmS9Bwono/default.jpg?sqp=CNSwgbYF&rs=AOn4CLD3FJ4PMxC5NjCv0jZsCJY5G_V0Fw" frameborder="0" height="266" src="https://www.youtube.com/embed/mwvmS9Bwono?feature=player_embedded" width="320"></iframe></div>
<br />
<div style="text-align: justify;">
No obstante os dejo aquí el contenido que desarrollaremos en este primer <b>sprint </b>del curso para que lo tengáis a la mano. </div>
<br />
<ul>
<li>Un vistazo al <b>IDE </b>de <b>Lazarus</b>.</li>
<li>Estructura de un proyecto <b>Delphi/Lazarus</b></li>
<li>Nuestro primer programa</li>
<li>Tipos de datos. Variables y constantes</li>
<li>Estructuras de control</li>
<li>Procedimientos y funciones</li>
<li>Objetos. Una breve introducción</li>
<li>Formularios</li>
</ul>
<br />
<div style="text-align: justify;">
También crearé una sección de páginas fuera de las entradas típicas de <b>blogger </b>para estructurar el contenido de una manera más eficiente y que, de esa manera, tengáis un mejor acceso al mismo.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
No os olvidéis de compartir el post, <b>darle like al vídeo</b> y todas esas cosas que sirven para hacerme ric... digooo para que más gente lo vea :D<br />
<br />
<b>Capítulos:</b><br />
<div>
<ul>
<li><a href="http://www.invalidexpression.net/2016/02/curso-de-delphi-capitulo-1-introduccion.html" target="_blank">Capítulo 1. Introducción</a></li>
<li><a href="http://www.invalidexpression.net/2016/02/curso-de-delphi-capitulo-2-primera.html" target="_blank">Capítulo 2. Primera aplicación</a></li>
<li><a href="http://www.invalidexpression.net/2016/04/curso-de-delphi-capitulo-3-variables-y.html" target="_blank">Capítulo 3. Variables y Constantes</a></li>
<li><a href="http://www.invalidexpression.net/2016/12/curso-de-delphi-capitulo-4-condicionales.html" target="_blank">Capítulo 4. Condicionales </a></li>
</ul>
</div>
</div>
Miguelhttp://www.blogger.com/profile/16782448155425363883noreply@blogger.com0