LinkedIn APIs T&Cs y legalidad
O "shenanigams para que nadie use nuestro sistema"
Por un desarrollo propio me encuentro investigando las APIs de integración a LinkedIn, específicamente para buscar información de gente, publicar ofertas de trabajo y obtener información de las mismas. Por supuesto, me interesan las APIs porque la aplicación que estoy desarrollando involucra más que solo esas partes, y por tanto, la información debe estar correlacionada. Suena razonable, ¿verdad?
El departamento legal de LinkedIn parece opinar distinto.
El último punto de mi registro de clave API son los T&Cs (Terms & Conditions), que especifica claramente qué cosas se pueden y no se pueden hacer con la API. Veamos un poco de ellas. Los pueden acceder aquí: LinkedIn API Terms of Use.
LinkedIn reserves the right, from time to time, with or without notice to you, to change these Terms in our sole and absolute discretion. The most current version of these Terms can be reviewed on the LinkedIn developer portal at anytime and supersedes all previous versions. By using the LinkedIn APIs after changes are made to the Terms, you agree to be bound by such changes. Your only recourse if you disagree with the Terms, or changes to the Terms, is to discontinue your use of the APIs. Accordingly, we recommend you review these Terms periodically.
Este punto, en un primerísimo párrafo cinco (al 23 de Junio de 2012) ya es aberrante. ¿Qué tan cómodos se sienten ustedes firmando cheques en blanco? Yo, sinceramente, nada. Esto es lo mismo: LinkedIn puede hacer uso de nuestra alma si les da la gana, y como nuestra aplicación sigue haciendo uso de las APIs, ellos son dueños de nuestro culo porque ese request HTTP significó “acepto cualquier cosa que digan los T&Cs”. Para hacerlo más interesante, no hay fase de aceptación, y pueden hacer cambios sin o sin notificación.
Como extra me causa gracia el “from time to time”. Está tan mal puesto en la frase que puede entenderse como “podemos cambiarlo de tanto en tanto”, o como “nos reservamos el derecho de tanto en tanto”. Me pregunto si este texto tuvo revisiones.
1.3 APIs License Grant. Subject to the terms and conditions in these Terms, we grant you a limited, non-exclusive, non-assignable or non-transferable license under LinkedIn’s intellectual property rights during the Term to use the APIs to develop, test, and support your Application, and to distribute or allow access to your integration of the APIs within your Application to end users of your Application. You have no right to distribute or allow access to the stand-alone APIs.
En ningún momento se define legalmente quién es “you”, es decir que se entiende a la persona que está firmando esto. Curiosamente, el formulario de registro habla de administradores de aplicaciones, desarrolladores y perfiles. ¿Significa esto que you somos “nosotros”? ¿O significa que por el hecho de sumar a una segunda persona ya estamos en falta? No importa realmente, si a LinkedIn le da por aclarar algo que a nosotros no nos convenga, ya firmamos nuestro cheque en blanco.
1.5 Restrictions. In addition to other restrictions contained in these Terms, you agree not to do any of the following, unless expressly permitted by LinkedIn in these Terms or in writing by LinkedIn:
(…)
f. Require your users to obtain their own Access Code to use your Application.
g. Use your Developer Account or Access Codes to build and/or distribute enterprise applications outside your own company (e.g. use the APIs to build an Application that you distribute to other companies).
¡Good bye open source! No podemos distribuir una aplicación que tenga integración con LinkedIn porque estamos forzando a usuarios a generar un código de acceso a APIs. Sigamos el razonamiento: hacemos una aplicación redistribuíble que está integrada a LinkedIn, pero no podemos dar nuestros códigos por lo especificado en el punto 1.3. Curiosamente, tampoco podemos pedir que alguien use su propio código porque violamos la sección 1.5.f-g. Way to go, LinkedIn.
h. Request or publish information impersonating a LinkedIn user, misrepresent any user or other third party in requesting or publishing information;
Definición muy vaga para ser legal: misrepresenting. Digamos que si a un usuario no le gustó la forma en que está escrita una frase, ¿nos convierte a nosotros en violadores de los términos y condiciones de LinkedIn? Por supuesto que podemos tener una confirmación previa para que el usuario haga lo que le da la gana, pero si es así, ¿qué valor agregado tenemos? Y si no tenemos valor agregado… ya les digo qué pasa.
m. Store LinkedIn user data other than the Member Token or OAuth Token for any LinkedIn user, with the exception of a user’s profile data when given explicit permission by the owner of the profile as set forth in 3.4, below. User profile data obtained in accordance with this section and 3.4 below may not be updated without the user’s subsequent consent;
Sooo, no hay correlación de datos. Nuestra aplicación no puede guardar nada de nuestro usuario, y nada de terceros si se necesitara, incluso información que fue dada en entornos públicos. Supongo que podríamos escanear el sitio de LinkedIn sin hacer uso de la API, ¿verdad? Sigamos leyendo…
n. Use the APIs or Brand Features for any illegal, unauthorized or otherwise improper purposes,** or in any manner that would violate these Terms** (or any document incorporated into the Terms), or breach any laws or regulations, or violate any rights of third parties, or expose LinkedIn or its members to legal liability in your use of the APIs;
(énfasis mío.) Los Términos y Condiciones de uso nos impiden violar los términos y condiciones de uso. ¡Muy inteligente, LinkedIn!
o. Combine content from the APIs with other LinkedIn data obtained through scraping or any other means outside the official LinkedIn APIs. This includes acquiring LinkedIn data from third parties;
Nope, no se puede usar el sitio. Tampoco se pueden combinar datos de las APIs con el resto de los datos. Estamos limitados a usar la API, pero no podemos almacenar lo que la API nos devuelve. Bueno, el requerimiento anterior decía “lo mínimo posible para que la aplicación funcione”, quizá yo estoy exagerando.
u. Use the Content for generating advertising, messages, promotions, offers, or for any other purpose other than, and solely to the extent necessary for, allowing end users to use the returned Content in your Application;
Oops, qué lástima que no se pueda publicar contenido. Una lástima porque ya no sé qué vamos a hacer con las APIs de publicación de estados, de publicación de trabajo o de compartir contenido. Una lástima.
x. Use the APIs in an Application that competes with products or services offered by us;
Estoy sospechando a este punto que no podemos entonces desarrollar aplicaciones que hagan algo distinto de lo que hace LinkedIn (ver más adelante sobre las restricciones de uso de los datos), pero si hace lo mismo entonces tampoco está permitido, porque estamos compitiendo. ¿Qué opción nos deja LinkedIn? Ninguna, sea como sea que utilicemos esta API, estamos ligados a violar los términos de uso (que también está prohibido por los términos de uso).
z. Use any robot, spider, site search/retrieval Application, or other device to retrieve or index any portion of LinkedIn services or collect information about users for any unauthorized purpose;
Como decíamos, confirmando que no se puede obtener información del sitio.
1.6 Support and Modifications. We may provide you with support or modifications for the APIs in our sole discretion. We may terminate the provision of such support or modifications to you at any time without notice or liability to you. We may release subsequent versions of the APIs and require that you use such subsequent versions. Your continued use of the APIs following a subsequent release will be deemed your acceptance of modifications.
Traducción: “no garantizamos que funcionen en el futuro, nos importa poco lo que ustedes hayan hecho”.
1.7 Fees. The APIs are currently provided for free, but LinkedIn reserves the right to charge for the APIs in the future. If we do charge a fee for use of the APIs or any developer tools and features, you do not have any obligation to continue to use the LinkedIn’s developer resources.
Traducción: “no garantizamos que vayan a ser gratis”.
1.9 Usage Limitations. LinkedIn may limit the number of network calls that your Application may make via the APIs, and/or the maximum Content that may be accessed, or anything else about the APIs and the Content it accesses as LinkedIn deems appropriate in its sole discretion. The usage limitations can be found in the LinkedIn developer portal at http://developer.linkedin.com/. LinkedIn may change such usage limits at any time. In addition to its other rights under these Terms, LinkedIn may utilize technical measures to prevent over-usage and/or stop usage of the APIs by an Application after any usage limitations are exceeded. If no limits are stated in the Platform Guidelines, you nevertheless agree to use the APIs in a manner that, as determined by us in our sole discretion, exceeds reasonable request volume or constitutes excessive or abusive usage.
Esto tiene dos partes. La primera, como ya habrán leído, aclara que ellos van a hacer lo que mejor les parezca con los límites de uso. La segunda, que me parece ridículamente absurda en un contrato legal: “estás de acuerdo en usar las APIs de una forma que nosotros queramos, pero no te diremos cómo”. Es realmente irrisorio que consideren esto parte de algo expuesto públicamente.
2 Proprietary Rights
2.1 LinkedIn Property. As between you and us, we own all rights, title, and interest, including without limitation all intellectual property rights, in and to, the (i) APIs, and all elements, components, and executables of the APIs; (ii) the Content available from the APIs; (iii) our Website; and (iv) our Brand Features (collectively, the “LinkedIn Materials”). Except for the express licenses granted in these Terms, LinkedIn does not grant you any right, title or interest in the LinkedIn Materials. You agree to take such actions, including, without limitation, execution of affidavits or other documents, as LinkedIn may reasonably request to effect, perfect or confirm LinkedIn’s rights to the LinkedIn Materials.
¿Significa esto que toda la información que recuperemos a través de las APIs son propiedad de LinkedIn? Sí. Incluyendo información de tu usuario, mí usuario, y la información que públicamente se encuentra disponible allí. Cabe aclarar que esta es una directa contradicción del acuerdo de usuario, en donde dice:
- License and warranty for your submissions to LinkedIn.
You own the information you provide LinkedIn under this Agreement, and may request its deletion at any time, unless you have shared information or content with others and they have not deleted it, or it was copied or stored by other users. Additionally, you grant LinkedIn a nonexclusive, irrevocable, worldwide, perpetual, unlimited, assignable, sublicenseable, fully paid up and royalty-free right to us to copy, prepare derivative works of, improve, distribute, publish, remove, retain, add, process, analyze, use and commercialize, in any way now known or in the future discovered, any information you provide, directly or indirectly to LinkedIn, including, but not limited to, any user generated content, ideas, concepts, techniques or data to the services, you submit to LinkedIn, without any further consent, notice and/or compensation to you or to any third parties. Any information you submit to us is at your own risk of loss as noted in Sections 2 and 3 of this Agreement.
(énfasis mío.) Cabe aclarar que cambiar el copyright por completo está fuera de estos términos. En fin, continuemos con el documento original:
3.4 Data Storage and Conversion Limits.
3.4.1 Prohibition on Copying and Storage. You may not copy, store or cache any Content returned or received through the APIs, including data about users, longer than the current usage session of the user for which it was obtained, except for the alphanumeric user IDs (Member Tokens) which we provide you for identifying users or any individual member’s authentication token (OAuth Token) which we provide you when a LinkedIn user authenticates your Application to his LinkedIn account.
(…)
3.4.3 Exception to Storage and Conversion Limits with User Consent. The restrictions of this section do not apply to user profile data received through a one-time call through the APIs that a user explicitly permits you to collect and store, provided that you obtain the user’s consent through the technical and user-interface specifications provided by LinkedIn, and that any subsequent update to the profile data only be done with the user’s explicit consent. PLEASE NOTE: a) User profile data does not include information about a user’s connections, which may not be copied or stored; and b) you may only use stored profile data for the benefit of the LinkedIn user that granted you permission to access it.
Fuck! Nada, de NADA podemos hacer con las APIs. Nuestra aplicación debería ser explícitamente entonces una interfaz para usar LinkedIn. Pero, si analizamos, por los puntos de competencia, no podemos ofrecer servicios similares, y si no podemos correlacionar datos, entonces ¿qué podemos hacer? Mostrar una interfaz distinta para hacer lo mismo que hace LinkedIn, pero entonces seríamos competidores y eso tampoco está permitido.
Haber leído estos términos y condiciones me decepciona mucho. Tenía la esperanza de usar estas APIs para algo interesante y realmente parecen estar bien construidas, de forma que son simples de usar y tienen muchas opciones interesantes. Desafortunadamente, me encuentro en un hueco legal que no puedo evitar. Invito a abogados o a especialistas en el tema corregir cualquier error que yo haya podido cometer, pero mi interpretación de esta licencia es que, haga lo que haga, voy a caer en una violación de la misma.
Me pregunto siquiera como empresas serias pueden considerar tener este tipo de acuerdos legales expuestos de forma pública. El concepto de protegerse de absolutamente todo y no dar ningún tipo de garantía debería espantarnos terriblemente a todos y negarnos a usar estas cosas hasta que el acuerdo sea razonable. Por supuesto, esto se torna monopólico porque todos lo hacen y entonces les damos nuestra alma con tal de estar a la par con otras organizaciones que tienen integraciones con X cantidad de servicios.
“¡Pero no pasa nada!”, seguro algunos pensarán. A ellos les pregunto: si se olvidan la tarjeta de crédito en un club en donde todos son muy buena onda y “nunca pasa nada”, ¿la reportan como robada? Si la respuesta fue sí, entonces ya tienen su respuesta.
Lo lamento LinkedIn, pero tu departamento legal me mantuvo alejado. Desmientan lo que digo, realmente quiero que me hagan ver que estoy equivocado.
Soy un zorrinito decepcionado.
Barras de progreso y velocidad aparente
La gran diferencia del detalle
Indicando progreso
Hemos visto como a través de los años las interfaces de los sistemas operativos y las distintas aplicaciones (también las web) han evolucionado y cambiado radicalmente su aspecto visual. Muchos más colores, formas redondeadas, animaciones y feedback que nos indica qué está pasando a cada momento.
Uno de los elementos que más cambio ha tenido son los indicadores de progreso. Desde las líneas que giraban simulando un progreso, usando los caracteres -, /, | y \ en una consola, hasta el uso de caracteres Unicode con barritas que se iban llenando, hasta las hermosas interfaces de hoy de colores y animaciones. |
Cabe aclarar que los indicadores de progreso vienen en dos sabores. Uno de ellos es el indicador de progreso indeterminado, el cual indica que hay un progreso ocurriendo de fondo en nuestra aplicación, pero sin indicar qué tan cerca estamos de terminar esa operación. Muchos de estos hemos visto en Youtube y distintas páginas que hacen uso de ajax. Wikimedia tiene una linda galería de estos, pero para ejemplo, aquí tienen uno:
El otro tipo de indicador es la barra de progreso propiamente dicha. Esta barra es el concepto básico que indica un límite en donde el trabajo ha sido terminado y nuestra posición respecto de completar esa tarea. Una búsqueda en Google Images devuelve muchas, muchas imágenes para saber de qué estamos hablando, y mejor aún, PrettyLoaded es un sitio (Flash) con una galería continua de pre-loaders que reutilizan este concepto con distintas formas.
Jugando con la mente
Ahora, asumiendo que una tarea siempre tarda el mismo tiempo, el indicador de progreso puede hacer una diferencia en la velocidad aparente que como usuarios percibimos, y podría ser bien la diferencia entre cancelar una descarga que signifique una compra o esperar unos pocos segundos más. Esta velocidad percibida es también llamada velocidad aparente, y si bien está relacionada a la velocidad real, hay otros factores que pueden hacerla aparentemente mayor o menor.
La velocidad aparente se encuentra afectada por muchos factores, como bien publicó Anthony, de UXMovement, en el artículo llamado How to Make Progress Bars Feel Faster to Users. A diferencia de muchos artículos que se encuentran en la internet, este está respaldado por estudios de la gente de Carnegie Mellon University, de los Laboratorios de Investigación de AT&T, y de la Universidad de New York. (Los links están al final del mismo.)
Las características que mencionan aquí son las siguientes:
Animación en sentido contrario
Una característica de las nuevas interfaces ha sido la capacidad de entrelazar imágenes en estos mismos indicadores. Muchas veces es una forma de demostrar que la aplicación sigue funcionando aunque la barra de progreso mantenga su posición, de la misma forma que el caracter que giraba nos indicaba también que el programa seguía funcionando. Sin embargo, el tipo de animación también puede tener un efecto sobre la velocidad aparente del progreso general.
Y lo que han descubierto es que cuando esta animación se mueve en sentido contrario a la dirección de progreso de la barra, la sensación de velocidad es mayor.
Utilizar pulsaciones frecuentes
Los indicadores de progreso (tanto barras como indeterminados) pueden hacer uso de pulsaciones como parte de la animación. Esto es más común en las barras de progreso, en donde todo el color de la barra es cambiado por un momento y vuelve a su estado normal, repitiendo esta acción cada tanto tiempo, dando la sensación de una pulsación.
Los estudios demostraron que mientras más frecuentes son estas pulsaciones, mayor es la velocidad aparente. Por supuesto, puede que no resulte agradable al ojo del usuario si es demasiado frecuente. Un truco extra también mencionado es que a medida que nuestra barra está avanzando, la frecuencia de las pulsaciones puede ir aumentando, también generando la sensación de un aumento en velocidad, incluso aunque realmente no sea tal.
Acelerar el progreso
Supongamos por un momento que el progreso de nuestra tarea es fijo, y que cada tantas unidades de tiempo, siempre tendremos tantas otras unidades de avance en nuestro progreso. Mantener esa monotonía de avance es, si bien realista, no la mejor opción para dar la sensación de progreso. Según mencionan los estudios, incrementar la velocidad del progreso hacia el final genera una sensación de menor tiempo insumido en la tarea en general, incluso aunque los tiempos suma sean los mismos.
Recuerdo haber leído que entre Windows Vista y Windows 7, este había sido uno de los cambios de interfaz en el momento de copia de archivos, a pesar que la estrategia de copia de archivos no había cambiado, y la diferencia era notable. Desafortunadamente, no logro encontrar el artículo en donde originalmente leí eso.
Evitar pausas al final
La pausa final, que ocurre muy comunmente si se está haciendo un procesamiento al final de la tarea, arruina la sensación completa de velocidad que el proceso había ganado. Por supuesto, seguramente estemos en un punto en donde el usuario ya no decide cancelar la acción, pero con ella hemos logrado arruinar la sensación de un proceso rápido que el usuario sentía. Esta puede ser la diferencia entre volver a usar nuestro sistema o no en un futuro, así que cuidado.
Los estudios originales son:
- Faster Progress Bars: Manipulating Perceived Duration with Visual Augmentations
- Rethinking the Progress Bar
Soy un zorrinito con progreso.
Carat
Debugging de energía colaborativa
Desde el feed de i.MicroSiervos me llega la noticia de Carat, un sistema que nos aconseja sobre maneras para hacer que nuestro dispositivo móvil haga mejor uso de su batería y dure más.
Está disponible tanto para Android como para iOS, y lo más curioso es que la fuente de información es puramente colaborativa. Es el mismo uso de los dispositivos que sirve como fuente de información para identificar las características que insumen más batería para que de esa forma se pueda desrecomendar su uso a quienes no la utilizan activamente. De esta forma, mientras más uso se haga de la aplicación, más información habrá para utilizar.
La versión de iPhone no está tan preparada en cuanto a interfaz gráfica, pero es totalmente funcional y ya está dando buenos consejos sobre cómo mejorar la calidad de vida de nuestra batería (y nuestro battery-lifecycle). La de Android se ve más bonita en cuanto a interfaz y la funcionalidad es básicamente la misma que la de iPhone.
Este sistema está desarrollado por el AMP Lab (Algorithms, Machines and People Laboratory) de la Universidad de Berkeley, en un pequeño grupo de cinco personas. Sin embargo, el proyecto es open source y se puede encontrar en GitHub, para hacer un fork y ayudar a trabajar sobre él.
Soy un zorrinito ahorrador.
Blockly
Un lenguaje de programación visual
Blockly es una apuesta de Google para enseñar programación desde los bloques más básicos con esa misma aproximación: bloques.
Gracias a la novedad visual (y la autogeneración de código que ocurre por detrás) se puede programar fácilmente con encajar piezas de rompecabezas, de forma muy intuitiva. Lo que nos demuestra es que se ahorraron la complejidad de la sintaxis de un sistema reemplazándola por un rompecabezas, que vuelve el conocimiento de sintaxis en un juego.
Existen tres demos para Blockly actualmente:
- Maze, nos impone el desafío de resolver un laberinto con instrucciones simples
- Code, nos permite ver un poco detrás de la cortina y observar como Blockly puede generar código en otros lenguajes.
- RTL es un demo de cómo se vería la interfaz de derecha a izquierda.
Parecería por estas características no se trata sólo de un intento de educación, sino también la capacidad de extender aplicaciones propias de una forma visual y fácil de comprender. Imaginen permitirle a los usuarios de un sistema “programar” cómo debe comportarse el sistema en determinados casos. Realmente es una opción muy poderosa de extensibilidad, sin requerir la complejidad de saber programar.
Soy un zorrinito en bloques.
on{X}
Automatizando nuestra vida, un teléfono a la vez
De parte de MicroSiervos me entero que Microsoft está desarrollando un sistema de macros basadas en eventos para teléfonos móbiles. El proyecto se llama on{X} y aquellos que conozcan IfTTT verán una gran similaridad.
El sistema se basa en eventos porque los macros se disparan según determinadas situaciones se presenten. Ver las recetas pre-armadas ya les dará una idea:
- Lanzar la aplicación de música cuando estoy caminando.
- Cuando llegue a casa, recuérdame comprar leche.
- Recuérdame ir al gimnasio si no he ido por 3 días.
- Enviar el mensaje “voy para allá” a mi esposa cuando salgo del trabajo.
- Cuando mi novio me pregunta “dónde?”, responder automáticamente con mi localización.
Como esas, se pueden hacer muchas, ya que el código detrás de ella es simple JavaScript, lo que permitirá que una gran comunidad comience a construir sobre ellas. En este momento solo funciona para teléfonos Android (Microsoft, really?) pero esperemos que pronto se extienda el soporte. Todavía la comunidad en los foros y el blog están algo vacíos, pero nuevamente, es algo muy reciente todavía.
Yo realmente pienso que esta idea puede despegar.
Soy un zorrinito automatizado.
La belleza entra por los ojos
Una historia real
Una muy bonita anécdota que tenemos para contar cómo nuestro trabajo en User Experience comienza a dar sus frutos es una historia que a César le gusta contar, específicamente por la fuerza que esta historia tiene.
La historia comienza con MakingSense trabajando en una propuesta para un cliente nuevo. Siendo nuevos en nuestras tratativas con esta empresa (una empresa con altos estándares de seguridad), queremos realmente mostrar lo mejor que tenemos. La aplicación que debíamos realizar era desafiante desde el concepto que trataba, porque involucraba mucha seguridad, muchas tecnologías nuevas y muchas características que ayudan al usuario pero hacen difícil de congeniar con las anteriormente mencionadas. Nuestros arquitectos trabajaron en resolver ese problema pero las propuestas siempre resultaron más concretas cuando se puede ver el resultado final.
Entonces también se invirtió mucho en la zona de User Experience de esta propuesta. Sabrán ustedes que estamos haciendo presión sobre este tema últimamente (y si andan leyendo por aquí, seguramente lo habrán notado). Creemos que el UX es un factor de valor agregado, creemos que cuando todo lo demás está bien hecho, este marca una diferencia increíble.
De vuelta en la historia, el equipo de MakingSense trabajó en hacer un buen pre-diseño de user experience, lo que involucraba el desarrollo de flujos de usuario, screenshots de cómo podría llegar a verse el producto, muchos mockups y pequeños prototipos que nunca vieron la luz, pruebas de concepto, etc. Cuando uno trabaja para un proyecto que no es proyecto aún, sabe que está en riesgo. Sabe que si no se concreta la oportunidad, fue tiempo y dinero perdido.
El día de la propuesta se acercaba y las gotitas de sudor iban siendo más comunes en la frente de los involucrados. Se hizo muchisimo hincapié en esos screenshots, se cuidó hasta el ultimo detalle, se hicieron varias rondas del desarrollo del UI (interaction design, wireframes, IA) hasta llegar al diseño final con el que se estaba listo para presentar.
Finalmente, el día llegó.
César asistió a esa reunión en donde nos presentábamos de manera formal con nuestro cliente (aunque ya había habido tratativas informales anteriormente) y pusimos el proyecto sobre la mesa. Se explicó por qué MakingSense era apropiado para hacer el proyecto, se explicó qué teníamos en mente para solucionar su problema, y se mostraban algunas pantallas que ejemplificaban cómo podría haber quedado el sistema terminado.
En ese momento de la reunión la tensión subió. El arquitecto que pertenecía al cliente interrumpió la conversación, dijo “Esperen”, y se fue de la habitación. En menos de dos minutos estaba de vuelta con alguien más, y lo presentó como el CEO de la empresa.
“Quiero que él vea lo que ustedes pensaron”, nos explicó. “Estas pantallas son más de lo que teníamos en mente, definitivamente queremos que esto se vea así, y que de ahora en adelante, todo lo que hagamos sea así.”
Traduciendo la experiencia, ellos sabían lo que querían que el sistema haga. No sabían la diferencia que se podía hacer con UX, no sabían que se podía brindar una experiencia totalmente nueva y agradable, especialmente cuando los sistemas tienen muchos requerimientos de seguridad, o cuando la complejidad son los árboles que no dejan ver el bosque.
La propuesta se convirtió en proyecto y el cliente se convirtió en partner, y hemos trabajado juntos para lograr maravillosos productos.
Naturaleza y ciencias
Sobre el punto en donde dos mundos se tocan
¿Puede la naturaleza ser un modelo de cómo resolver problemas de las ciencias? La pregunta tiene una respuesta obvia. Sabemos que sí, sabemos que muchos procesos pueden copiarse desde la naturaleza para mejorar la forma en la que resolvemos determinados problemas. Desafortunadamente, muchas veces, determinadas áreas de las ciencias quedan fuera porque la relación con el mundo natural está algo alejado. Por ejemplo, las ciencias de la computación o la aritmética.
Sin embargo, hay gente que sabe ver ese tipo de relaciones. Por ejemplo, el caso de micahoover, quién se preguntaba qué algoritmo de búsqueda realizan los relámpagos al caer. Y parecería que, curiosamente, es una búsqueda de tipo simulación Monte Carlo (Monte Carlo Search: A New Framework for Game UI [PDF]).
O el caso de Vihart, quien tiene una serie de videos hablando sobre Doodling in Math: Spirals, Fibonacci and Being a Plant (Part 1, Part 2, Part 3), en donde nos cuenta, desde el punto de vista de una planta, cómo maximizar el consumo de luz solar sin que nuestras hojas nos tapen otras hojas y cómo la serie de Fibonacci y las espirales son la forma de lograrlo.
Estos son dos ejemplos de muchos otros que deben haber ahí afuera (los invito a contarme de más si los conocen)
Soy un zorrinito natural.
The Noun Project
Iconos minimalistas para todas las ocasiones
The Noun Project es una colección de iconos minimalistas, la gran mayoría libres para usar. Cada imagen tiene asociada un sustantivo que lo describe, y por lo general la imagen es una buena representación de esa palabra. Disponible tanto en inglés como en español para buscar, esta galería de imágenes nos permite inspirarnos como diseñadores y conseguir una buena cantidad de iconos para nuestros sistemas de necesitarlos.
También existe una visualización por categorías que nos permite interiorizarnos en alguna de ellas en particular, que puede estar asociada a nuestra necesidad.
Soy un zorrinito iconizado.
Front-end code standards
Una aproximación de best practices
Acabo de leer el artículo de IsoBar Front-end Code Standards & Best Practices. El artículo cubre de forma extensiva varias de las tecnologías utilizadas, con las sugerencias que esta empresa utiliza interamente. Cubre varios aspectos del uso de HTML (y algunas nuevas características de HTML5), CSS (y algunas nuevas características de CSS3), JavaScript, Performance, e integración cross-browser.
Personalmente no me siento de acuerdo con la totalidad de los items mencionados, pero creo que como punto de partida es muy bueno. Tienen una buena cantidad de referencias al por qué conviene hacer las cosas de la forma que ahí están explicadas, y muchas veces las razones son totalmente válidas. Muchas veces también se pesan pros y contras de cada aproximación, lo cual ayuda a tomar una decisión educada del proceso que elijamos seguir.
Soy un zorrinito front-end.
Pruebas con VS11: Día dos
async y await
Continuando con mi serie de posts e investigación sobre lo que VS11 ofrece (Parte 1), quisiera tomar una aproximación separada. Si bien la exploración es interesante, es poco apropiada cuando uno quiere aprovechar el tiempo.
Es por eso que comencé con las referencias en MSDN sobre qué hay de nuevo en VS11, que seguiremos de a partes. Pero a la vez quiero cumplir con mi promesa, por lo cual, si comenzamos sobre qué hay de nuevo en el lenguaje C# (lo siento VB, lo siento C++, soy del bando de C#), nos encontramos con la excusa para cumplir lo prometido.
Características nuevas de C#: await y async
Esto, bien sabemos, no es algo propio de VS11, sino de C# 5.0, que va de la mano con VS11 y .NET 4.5. Como MSDN lo indica, una de las primeras características es la habilidad de construir fácilmente código asíncrono. “We have to go deeper…“
Cabe aclarar que ya existía la posibilidad de escribir código asíncrono. Los callbacks y el multithreading no es nada nuevo, aunque esto es ligeramente distinto, ya que simplifican un poco la idea y esconden el trabajo sucio. Sin duda se logrará que en el futuro mucha gente no sepa cómo funciona los métodos asíncronos por detrás pero esconder complejidad es un buen paso para permitir innovación.
Digamos que tenemos un programa que factoriza números grandes, porque logramos un trabajo de criptoanalista para el FBI. Nuestro método recibe un parámetro long y nos devuelve un ISet<long>
con el conjunto de factores primos que conforman este número original. Dejando de lado la matemática, sabemos que este proceso toma un rato en ejecutarse y queremos que nuestro programa lo trate de forma asíncrona. ¿Cómo se haría este trabajo de la forma tradicional?
Básicamente deberíamos definir un método que sirva de callback. El callback (también llamado continuación) es un método que el thread que trabaja en la tarea llama cuando termina para avisar que su trabajo terminó. De esta forma, podemos preparar nuestra tarea, enviarla a ejecutar, hacer otras cosas en el intermedio y ejecutar código extra cuando la tarea termina, como por ejemplo, trabajar con los resultados.
(Ejemplo del código en Gist.GitHub: Async without async)
Esta aproximación tiene un problema muy claro: la complejidad. Estamos de acuerdo con que el código de FactorNumber debería estar separado en su propio método, pero la continuación de la llamada a FactorNumber y el resto de esa lógica son parte de una misma operación. El hecho de que estén separados en el código no es más que una obligación que debemos cumplir por las restricciones del framework para la instanciación de threads.
Las palabras clave async y await resuelven este problema.
Aquí podemos notar que la estructura del código ha cambiado un poco para dar soporte a esta característica. Por un lado, tuvimos que aislar el código que interactuará con métodos asíncronos, ya que los mismos deben devolver un tipo Task. Esto es porque devuelven un identificador de la tarea que está corriendo en background. En nuestro caso en particular, este será StartWork(), pero no estamos haciendo uso de su Task.
StartWork, siendo asíncrono, se ejecutará a la vez del resto del código, ya que no será bloqueante. Por tanto, el próximo Console.WriteLine se ejecutará, muy seguramente, al mismo tiempo que el procesamiento de StartWork ocurre. Dicho procesamiento hace una llamada bloqueante a FactorNumber, es decir, espera a que FactorNumber termine (lo cual nos permitió convertir la llamada en síncrona) y una vez que tenemos el resultado, se escribirá en consola. No era realmente necesario convertir esta llamada en síncrona de esa forma, una simple llamada a FactorNumber hubiera sido suficiente, pero de esta forma demostré que si bien el sistema espera por su respuesta suspendiendo el thread actual, sigue siendo asíncrono internamente. Eso significa que está ejecutando toda la tarea de callback que vimos antes de forma interna, y ahora nuestro código se lee fácilmente de arriba a abajo.
Confieso que debo trabajar un poco más en esto para no ensuciar tanto el código, pero por ahora parecería que el uso de las keywords exige modificar los valores de retorno y por tanto las llamadas a esos métodos deben ejecutarse de forma distinta. Eso no me agrada, porque inclina un poco la complejidad innecesaria para usar esto, pero sigue siendo una ventaja sobre la solución original.