Iglesia de Temisas |
Iglesia de Temisas |
Con motivo de la celebración del 10º aniversario de Arduino, y del Día de Arduino, presenté en mi blog en inglés Visualino. ¿Que qué es eso? Se trata de una herramienta de programación visual para Arduino, un proyecto que comencé el año pasado y que ha tenido un impulso estos últimos meses, con la ayuda de los colegas de Arduino Gran Canaria.
Para quien no lo conozca, Arduino es un familia de placas con microcontrolador que permiten interactuar con infinidad de sensores y componentes electrónicos. Las placas vienen acompañada de un programa llamado el IDE de Arduino, que hecho sencilla la programación de los microcontroladores. El lenguaje está basado en C/C++ y las funciones son relativamente simples de aprender. Esta facilidad es parte de la revolución. Encender y apagar LEDs y mover robots ahora es bastante simple con Arduino. ¡Pero podría ser aún más fácil! Un pequeño problema al que se suelen enfrentar niños y adultos sin conocimientos previos de programación es que la sintaxis de C/C++ es muy estricta: las llaves y los puntos y comas tienen que estar en su sitio o el programa no funciona. ¿Cómo hacerlo aún más intuitivo? ¡La programación visual al rescate!
Scratch es una plataforma de programación visual para niños muy popular, desarrollada por el MIT. En lugar de teclados y código, los niños utilizan el ratón y bloques para crear los programas como si fueran puzzles. Existe una extensión llamada Scratch for Arduino que permite controlar la placa. Sin embargo, el programa se ejecuta en Scratch, así que la placa de Arduino debe permanecer siempre conectada al PC.
Así que, ¿qué hace Visualino? Pues es un entorno similar a Scratch: permite crear programas para Arduino como un puzzle. Pero además, permite programar directamente la placa de Arduino y por tanto, hace innecesaria la conexión permanente al PC. Además, los bloques generan el código de C/C++ en tiempo real en una ventana. El entorno es similar al del IDE de Arduino, con las mismas opciones principales: Verificar, Subir, Guardar, Cargar y Monitor. Puedes ver cómo se usa Visualino en este vídeo:
Visualino está basado en Google Blockly y en los bitbloqs de bq. Es software libre, multiplatforma y multi-idioma. Requiere la versión 1.6 del IDE de Arduino 1.6, que es el motor que se usa para programar las placas. Puedes descargar la versión beta de Visualino para Ubuntu, Mac y Windows. La documentación con instrucciones de instalación está disponible en español e inglés. El código anda en github.com/vrruiz/visualino. Jordi Binefa contribuyó con la traducción al catalán, y serán bienvenidas las contribuciones para el italiano y portugués.
Hoy mismo me toca realizar una tutoría de Visualino para profesores de secundaria, así que espero que pronto se esté usando en las aulas aquí en casa.
Vete, descárgalo y úsalo. Comentarios y sugerencias bienvenidas. Para estar en contacto, síguenos en twitter.com/visual_ino.
En algunas ocasiones, sentimos la necesidad de saber quien editó determinada línea de un fichero que han tocado varias personas. La mejor forma de saber este dato es con el comando blame de git.
[root@bash]$ git blame /ruta-al-fichero/fichero
Este comando nos devuelve línea por línea quien edito un determinado fichero así como información del momento y commit en el que fue editado.
5a5b7ffd (Juan 2014-04-05 11:23:23 +0100 230) } 5a5b7ffd (Juan 2014-04-05 11:23:23 +0100 231) } b7f005bf (Jaime 2014-05-05 10:15:23 +0100 232) else b7f005bf (Jaime 2014-05-05 10:15:23 +0100 233) { b7f005bf (Jaime 2014-05-05 10:15:23 +0100 234)
Este próximo viernes vamos a realizar el tercer encuentro PyBirras. Las PyBirras son reuniones informales en la que hablamos de programación en general y del lenguaje Python en particular. Y beberemos cervezas artesanales canarias (solo si quieres, no es obligatorio [Pero está muy rica]).
En esta reunión hablaremos de las charlas que más nos impactaron en la última PyConEs, y de algunos desarrollos interesantes hechos en El Anden. Y de la vida, el Universo y lo demás.
La asistencia es totalmente gratuita, pero si que te agradecería que confirmaras la asistencia en este meetup:
http://www.meetup.com/Agile-Canarias/events/220564873/
o vía un twitter a @jileon.
PyBirras Tenerife
Viernes 13 de marzo de 2015
18:30 hasta 20:00
Anden Sin límite
Carretera Cuesta Taco, 67, Santa Cruz de Tenerife
Después del evento proyectaremos, para el que quiera quedarse, el documental Indie Game: The Movie. Y pediremos pizza. Y más cervezas.
Playa de Ojos de Garza |
Barranco del Río |
![]() |
Cascada seca en el Barranco de Agaete |
Roque Palmés |
![]() |
Charco de las Palomas |
Vistas del Roque Nublo, Roque Bentayga y El Teide |
Roque Bentayga |
This is my first post in english. I'm doing this as a way to improve my English. If you see something wrong or strange in this article, I'll be pleased if you point it in the comments. Thank you very much in advance.
Nota: Hay una versión en español de este artículo aquí: Django Tip: Modificar la sentencias SQL generada por un queryset.
The extra method of the queryset objects allows us to add some modifications to the SQL statement it will use. Specifically, extra can be used to add new fields to the Select clause, add Tables or Joins to the From clause, and/or add new conditions to the Order By clause.
Suppose we have the usual sock of items for sale, something like that:
class Item(Model):
id = AutoField(primary_key=True) # I like to specify the Id.
description = CharField(max_length=200)
price = DecimalField(max_digits=12, decimal_places=2)
created_at = DateTimeField(auto_now_add=True)
We can add a calculated field, just to distinct between items with prices below 5 € of items with a higher price (maybe we want to stamp a low-price icon on the result page, for example). We can use the extra method to add a new calculated field, named "low_price", with the following code:
Item.objects.extra(select={'low_price':'pvp < 5.0'}).all()
Under the hood, what we are doing is transforming the Django generated SQL statement from this:
SELECT app_item.*
FROM app_item;
to this:
SELECT app_item.*, (pvp <= 5.0) AS low_price
FROM app_item;
We can add many different calculated fields, either using the dictionary passed as the value of the select parameter, or making several calls to the extra method. For example, if we want to classify the items on three divisions (cheap, under 5€; medium, between 5€ and 100€; and expensive, above 100€), we may do something like this:
Item.objects.extra(select={
'low_price':'pvp < 5.0',
'mid_price':'pvp between 5.0 and 100.0',
'low_price':'pvp > 100.0',
}).all()
or this other way:
Item.objects \
.extra(select={'low_price':'pvp < 5.0'}) \
.extra(select={'mid_price':'pvp between 5.0 and 100.0'}) \
.extra(select={'low_price':'pvp > 100.0'}) \
.all()
Result must be the same in either case.
Reality is that we can get this data with a really simple method on the Itemclass, but in some cases, it could be very useful to make the Database do the calculations for us.
Clearly, we can add subqueries as new fields in the select clause, which increase the possibilities. As an example, suppose our application have a model to store the ratings our clients give to our products, something like this:
class Score(models.Model):
id = AutoField(primary_key=True) # Yes, I know, It's needless...
item = ForeignKey(Item)
rate = SmallIntegerField()
We can do a search over our stock, adding the mean rate of every product, calculated by the database itself:
Item.objects.extra(select={
'mean_rate':'''
SELECT AVG(app_score.rate)
FROM app_score
WHERE app_score.item_id = app_item.id
'''
}).all()
We can do the same in our Django Code, writing a simple method in the Itemclass. But we need a new SQL query to get all the scores of an item, and calculating the average after that.
If we obtain 10 items as a result, for example, we will count up to 11 sql queries to the Database, one for the original search, and one for every item in the result, to get the list of scores. And we have to make the calculation ourself. If we let the Database to make the operation for us, we will count just one SQL query. The difference in performance can be noticeable.
Beware this techniques have a dangerous face: we have linked our code to the Database management system more strongly. That implies more dependencies and more danger. If we use proprietary extensions to the SQL syntax, we got a potential break point. Even a simple call to get the current timestamp -Every Database define his own names: sysdate in Oracle, now() in postgreSQL, current_timestamp in Microsoft SQL Server, to name just a few- will break if we migrate to another database brand.
Nevertheless, it's useful to known that we have this ability. It depends of ourselves to use it or not. Just remember this three little advices:
- Explicit is better than implicit. (Tim Peters)
- Special cases aren't special enough to break the rules ... Although practicality beats purity. (Tim Peters)
- With great power comes great responsibility (Benjamin Parker)
Note: the use of extra to modify the FROM and WHERE clauses is better explained, among other interesting information, in the official docs: Django Query Set API reference - extra.
Note: There is a english version of this post here: Django Tip: Modify the generated SQL statement of a queryset
El método extra de los queryset nos permite realizar algunas modificaciones en las sentencias sql que ejecuta. En concreto nos permite añadir campos a la cláusula SELECT, o tablas y joins a la cláusula FROM, o condiciones a la cláusula ORDER BY.
Supongamos, por ejemplo, que tenemos una tabla de productos a la venta, algo como esto:
class Item(Model):
id = AutoField(primary_key=True) # Me gusta especificar la clave
descripcion = CharField(max_length=200)
pvp = DecimalField(max_digits=12, decimal_places=2)
alta = DateTimeField(auto_now_add=True)
Podemos añadir un campo calculado que nos indique si los precios son inferiores a 5.0 (quizá queremos marcar estos productos en la página con un icono de "low-price", por ejemplo). Para ello, podemos añadir un campo calculado al selectde la query usando extra, como en el siguiente ejemplo:
Item.objects.extra(select={'low_price':'pvp < 5.0'}).all()
Lo que estamos haciendo es que la sentencia SQL generada por Django pase de esto:
SELECT app_item.*
FROM app_item;
a esto:
SELECT app_item.*, (pvp < 5.0) AS low_price
FROM app_item;
Podemos pasar varios campos calculados en el diccionario especificado por el parámetro select, o hacer varias llamadas a extra. Por ejemplo, si queremos clasificar los precios en tres bandas, (baratos, por debajo de 5 euros; medios, entre 5 y 100 euros y caros, por encima de 100 euros), podemos hacerlos así:
Item.objects.extra(select={
'low_price':'pvp < 5.0',
'mid_price':'pvp between 5.0 and 100.0',
'low_price':'pvp > 100.0',
}).all()
O así:
Item.objects \
.extra(select={'low_price':'pvp < 5.0'}) \
.extra(select={'mid_price':'pvp between 5.0 and 100.0'}) \
.extra(select={'low_price':'pvp > 100.0'}) \
.all()
El resultado debería ser el mismo en los dos casos.
Es verdad que podemos realizar este calculo de bandas de precios en un simple método de la clase Item, pero en ocasiones puede sernos útil o necesario que determinadas operaciones las haga la base de datos por nosotros.
Obviamente también podemos pasar subconsultas como campo añadido al select, que nos da aun más posibilidades. Por ejemplo, supongamos que en nuestra aplicación tiene otro modelo con las puntuaciones que nuestros clientes asignan a nuestros artículos, algo como esto:
class Score(models.Model):
id = AutoField(primary_key=True) # Si, ya lo sé, no hace falta...
item = ForeignKey(Item)
rate = SmallIntegerField()
Podemos realizar una consulta sobre artículos e incorporar la puntuación media de cada uno, calculada directamente por el gestor de la base de datos:
Item.objects.extra(select={
'mean_rate':'''
SELECT AVG(app_score.rate)
FROM app_score
WHERE app_score.item_id = app_item.id
'''
}).all()
Si quisiéramos hacerlo desde Django, con un método de la clase Item, por ejemplo, tendríamos que realizar primero una consulta para obtener todas las puntuaciones de un artículo, y luego calcular la media.
Si lo hacemos para una consulta cuyo resultado final fueran 10 artículos, por ejemplo, tendríamos que hemos realizado 11 consultas SQL a la base de datos, haciendo además el cálculo nosotros, por una sola consulta, si los cálculos los realiza el SGBD. La diferencia en rendimiento puede ser considerable.
Estás prácticas también tienen su lado peligroso: hemos vinculado más nuestro código al gestor de base de datos que estamos usando, con las dependencias y peligro que eso conlleva. Si usamos extensiones propietarias de la base de datos para realizar la consulta, aunque sea algo tan simple como utilizar la marca de tiempo de la base de datos (Que cada gestor se empeña en definir de forma diferente, sysdate en Oracle, now() en postgreSQL, current_timestamp en Microsoft SQL Server, por citar solo unos pocos ejemplos), ya tenemos un punto de ruptura si pretendemos migrar de gestor.
En cualquier caso, es útil saber que tenemos esta capacidad, ya depende de nosotros si queremos emplearla o no. Recuerda solo estos tres consejos:
- Explícito mejor que implícito (Tim Peters)
- Los casos especiales no son tan especiales como para romper las reglas ... pero lo práctico vence a lo ideal (Tim Peters)
- Todo gran poder conlleva una gran responsabilidad (Benjamin Parker)
Nota: El uso de extra para modificar las cláusulas FROM y WHERE está explicado, junto con muchas otras cosas interesantes, en la documentación oficial: Django Query Set API reference - extra.
Andén Verde y Roque Faneque al fondo |
Reconozco que tengo un problema con la prensa de este país: No me creo su independencia.
La última patochada son las airadas protestas porque el nuevo gobierno de Grecia no cuenta con mujeres entre sus miembros. Que haya subido el salario mínimo o haya garantizado la electricidad a los más pobres no importa. Peor aun, es populista. Permitidme que os lo diga: ¡Qué falso os queda!
Son preguntas sencillas pero no os preocupéis, ya contesto yo por vosotros: La república Griega y su gobierno os chupa un pie. La igualdad de la mujer os importa tres cominos. La Equidad os la refinfanfinfla pero bien. No sois más hipócritas porque no entrenáis.
En resumen: No cuela.
PD: De propina, un pequeño cuento (after Augusto Monterroso):
Cuando el dinosaurio despertó, Podemos seguía allí.
PD2: Cuando hablo de prensa, no incluyo a artefactos bélicos como La Razón, Libertad Digital y similares, manojos de papeles/bits juntados al tuntún para hacer bulto y mantener la ilusión entre los más adoctrinados, medios comprados (y vendidos) desde su mismo nacimiento. Hablo de cabeceras con bagaje histórico, como El País, ABC o El Mundo (No enlazo porque ahora es delito, se siente). Los que ahora agachan la cabeza y obedecen prestos la voz de su amo, mientras se quejan de que las ventas en papel bajan. Y se pregunta el porqué.
Si quieres actualizar a fedora 21 sin morir en el intento con un yum upgrade sigue estos pasos.
Antes que nada, realiza una copia de seguridad de todos los elementos importantes de tu equipo.
Actualiza los repositorios de yum:
[root@bash]$ yum update
Reinicia tu equipo:
[root@bash]$ reboot
Instala FedUp, el hará todo el trabajo por nosotros:
[root@bash]$ yum install fedup
Empieza el proceso de actualización a Fedora 21:
[root@bash]fedup-cli --network 21 --debuglog /root/fedup-20to21.log
Revisa errores en /root/fedup-20to21.log, existe una opción por si actualizas desde una distro con un entorno como mate o alternativo. Funciona también sin problemas.
Puedes habilitar diferentes repos con la siguiente opción:
--enablerepo REPO
Reinicia de nuevo tu equipo:
[root@bash]$ reboot
En el grub del menú, entra con FedUp:
Esto tardará bastante y realizará toda la actualización de nuestro equipo a Fedora 21, después podremos iniciar sesión en Fedora 21 y continuar como siempre.
Funda de las fichas |
Foto extraída de http://www.talisca.com/ |
¿Te pensabas que los blogs estaban muertos? ¡Jajajaja! [Risa malvada con efecto eco] Tras un par de años de ausencia, se convoca un nuevo Blogs & Gofio. Blogueros, tuiteros, y usuarios de internet de todo tipo están invitados a la reunión informal que celebraremos el próximo viernes 28 de noviembre de 2014 en Las Palmas de Gran Canaria. El lugar será el habitual en las últimas convocatorias en la isla redonda, el restaurante La Barbería de Vegueta y la hora, las 21:00. Como habrá que hacer reserva, por favor, confirma tu asistencia escribiendo un comentario en esta entrada (o en Facebook) a más tardar el viernes a las 12:00.
Reusando las preguntas y respuestas habituales de nuestros compañeros chicharreros:
¡Nos vemos el viernes!
PD: Para el cartel se ha usado la imagen Zomby Army, de Vermyn-N (Creative Commons, Atribución).
Laguna de Valleseco |
Cuando vamos a cambiar el contenido de nuestro dominio a otra dirección, es importante indicar este cambio. De esta forma, tanto los motores de búsqueda como los propios usuarios podrán seguir encontrando la información que desean.
Hay varios métodos para hacer una redirección:
Método 1, HTML:
<meta http-equiv="acción" content="segundos"; url="http://www.neleste.com/nuevaruta" />
Método 2. PHP (para este método, es imprescindible no haber escrito html antes, esto cambiaría las cabeceras del documento):
<?php header ("Location: http://www.neleste.com/nuevaruta"); ?>
Método 3. JavaScript:
<script type="text/javascript"> window.locationf="http://www.neleste.com/nuevaruta"; </script>
Método 4. editar .htaccess (gracias por recordarlo Emilio):
Este método también se puede hacer en los archivos de configuración de apache si tenemos acceso
Redirect /viejaruta/ http://neleste.com/nuevaruta/
Presa de las Gañanías o de Antona |
Bentayga |