viernes, 16 de diciembre de 2011

reCaptcha Bug

This is happening with reCaptcha - I guess is a kind of Bug. Otherwise, they may be having wrong information for using with the OCR software.



Estuve escuchando la charla de Luis von Ahn (creador de reCaptcha) y ahora proyecto de Google.

http://www.ted.com/talks/luis_von_ahn_massive_scale_online_collaboration.html

Donde explica algo que muchos sabemos y es que se usa este famoso sistema para poder ayudar en la digitalización de libros (de la biblioteca digital de Google)

Cómo se hace? Fácil: cuando ingresamos un código, vemos 2 palabras. Una de esas palabras no pudo ser reconocida por el software OCR de Google entonces nos pide ayuda para que la interpretemos nosotros.

La otra palabra está puesta para que el sitio sepa que hay un humano detrás del monitor y no un robot programado para hacer spam o descargar automáticamente, etc.

Bueno, entonces cuando vi esto me pregunté: Qué pasa si yo se cual es la palabra que necesita Google interpretar? Si el software de OCR no supo cuál es, entonces cómo podrá saber que la estoy ingresando bien? Si sabemos esto, entonces podemos terminar haciendo que las digitalizaciones de libros en Google terminen diciendo cualquier cosa!

Y el problema es que es muy fácil saber cuál de las dos palabras es la que no sabe reCaptcha... ¡Es la que está tachada! Porque ellos pueden colocar ese tachón de forma dinámica. La otra palabra es la que el software no pudo interpretar.

Sabiendo esto, me fui a probar lo siguiente: Ingreso cualquier cosa en el lugar de la palabra que no detectó el programa OCR y entonces no solo que me dejará pasar para el paso siguiente sino que le meto basura a la base de datos de Google!

Algunas capturas de eso. Al día de hoy persistía el error. Informé a reCaptcha mediante el email de prensa de Google pero no he recibido respuesta.

Yo creo que es un asunto a tener en cuenta...







jueves, 15 de diciembre de 2011

Cacique - Testeo de Sitios

La verdad es que muy pocas veces me siento alegremente sorprendido por una noticia como esta. Y es que un producto argentino se anuncia como Open Source, siendo una herramienta muy potente y de mucho uso (y lo principal, que no esconde ninguna venta detrás)

No digo "argentino" en un sentido de orgullo, sino porque nosotros en este país no acostumbramos a regalar cosas. Somos una sociedad tan castigada por la mala administración económica y por el ejemplo que nos dan los políticos (robando todo el tiempo frente a nuestras narices sin ir preso o enjuiciado siquiera), que no es raro entender nuestra forma de ser. No la justifico, sino que la trato de entender para saber por qué lado debe venir el cambio.

Bueno, pero regresando a la noticia... Se trata de "Cacique", una aplicación desarrollada por MercadoLibre para testear su propio sitio web.

Este "movimiento" de lanzar semejante herramienta como Open Source creo que se debe a razones de promoción. No se olviden que desde hace un tiempo, MercadoLibre dejó de poner tantas trabas para la compra-venta y creación de nuevas cuentas (recuerdo que tenías que poner tu DNI y debía ser válido, sino no te creaban la cuenta. También tenías que esperar que te llamaran por teléfono y vaya a saber qué otras cosas más) Ahora abrir una cuenta es cosa de todos los días.

Todo esto es porque cada vez tenía menos movimiento (supongo), sino, por qué modificarían algo que les funciona bien?

También veo que si MercadoLibre está siendo asesorado (o por conocimiento propio) de cómo mover una empresa hacia el futuro. Y es un movimiento que funciona: Colocar código Open Source (les suena a Google?)

Y se están asegurando de tener presencia en el mundo. Porque ya las cosas van cambiando y quien no se adapta, muere. Así de simple. Y sino, pregúntenle a los grandes dinosaurios que van muriendo de a poco (BlockBuster, el video club, las disqueras que todavía venden CDs como principal ingreso, etc)

Entiendan que el mundo que se nos viene no tiene lugar para el dinero. Estamos apuntando más para el lado de una Economía Basada en Recursos y no en papel moneda.


Felicitaciones a Mercado Libre y aprovecho para darles las gracias por esta estupenda herramienta!

Cacique

martes, 13 de diciembre de 2011

Blackberry: Getting Info from the App World


Third-party applications can interface with the BlackBerry App World™ storefront. Using this feature, your application can obtain information about itself, such as the current version that is available and the license key it uses. This is useful for keeping the application current and making sure that it runs on a specific BlackBerry smartphone model. You can also launch the BlackBerry App World and point it directly to the web page for a specific application, making it easier to sell other applications or upgrades to the current application.

To test functionality that is dependent on accessing these properties (such as license validation) before your application is available on BlackBerry App World, you may load values into the properties yourself as part of a wireless installation. For more informationt, see this article.

The following example demonstrates how to interface to the BlackBerry App World. The complete project for this sample can be downloaded here.


package com.rim.samples.AppWorld;

import java.io.*;
import javax.microedition.content.*;
import net.rim.device.api.system.*;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;

/**
 * SampleApplication.java
 *
 * Sample application that shows how an application can
 * interface with BlackBerry App World.
 *
 * Note: For the sake of simplicity, this sample application may
 * not leverage resource bundles and resource strings. However,
 * it is STRONGLY recommended that application developers make
 * use of the localization features available within the
 * BlackBerry development platform to ensure a seamless application
 * experience across a variety of languages and geographies. For more
 * information on localizing your application, please refer to
 * the BlackBerry Java Development Environment Development Guide
 * associated with this release.
 *
 */
public class SampleApplication extends UiApplication {
    /**
     * The App World specific ID of this application.
     */
    private static final String RIM_APP_WORLD_ID = "RIM_APP_WORLD_ID";
    /**
     * A flag (true or false) that specifies whether there is
     * currently an update for this app available.
     */
    private static final String RIM_APP_WORLD_UPDATE_AVAIL = "RIM_APP_WORLD_UPDATE_AVAIL";
    /**
     * The license key for this application, as specified by the
     * App World purchase.
     */
    private static final String RIM_APP_WORLD_LICENSE_KEY = "RIM_APP_WORLD_LICENSE_KEY";
    /**
     * The name of the application, as specified in the App World
     * ISV Portal.
     */
    public static final String RIM_APP_WORLD_NAME = "RIM_APP_WORLD_NAME";
    /**
     * The email address of the purchaser. This will be their
     * PayPal email address.
     */
    public static final String RIM_APP_WORLD_EMAIL = "RIM_APP_WORLD_EMAIL";
    /**
     * The PIN of the purchaser.
     */
    public static final String RIM_APP_WORLD_PIN = "RIM_APP_WORLD_PIN";
    /**
     * The version of the application, as specified in the App
     * World ISV Portal.
     */
    public static final String RIM_APP_WORLD_VERSION = "RIM_APP_WORLD_VERSION";

    private MainScreen screen;
    private BasicEditField contentIdField;
    public SampleApplication() {

        // Get name of your app
        String myAppName = ApplicationDescriptor.currentApplicationDescriptor().getName();
        // It must be exact name of your application as
        // registered with the App World ISV portal
        //String myAppName = "AppName:Vendor";

        // If you are targeting 4.3+, use this:
        CodeModuleGroup group = CodeModuleGroupManager.load( myAppName );

        // On 4.2 you would need to use the following:
        /*
        CodeModuleGroup group = null;
        if( myAppName != null ) {
            CodeModuleGroup[] groups = CodeModuleGroupManager.loadAll();
            if( groups != null ) {
                for( int i = 0; i < groups.length; ++i ) {
                    if( groups[ i ].containsModule( myAppName ) ) {
                        group = groups[ i ];
                        break;
                    }
                }
            }
        } else {
            myAppName = "unknown";
        }
        */

        // Pull out the App World data from the CodeModuleGroup
        final String key = group == null ? "unknown" : group.getProperty( RIM_APP_WORLD_LICENSE_KEY );
        final String update = group == null ? "unknown" : group.getProperty( RIM_APP_WORLD_UPDATE_AVAIL );
        final String myContentId = group == null ? "" : group.getProperty( RIM_APP_WORLD_ID );
        final String name = group == null ? "unknown" : group.getProperty( RIM_APP_WORLD_NAME );
        final String email = group == null ? "unknown" : group.getProperty( RIM_APP_WORLD_EMAIL );
        final String pin = group == null ? "unknown" : group.getProperty( RIM_APP_WORLD_PIN );
        final String version = group == null ? "unknown" : group.getProperty( RIM_APP_WORLD_VERSION );
        screen = new MainScreen() {
            public boolean isDirty() {
                return false;
            }
        };

        //Display the data on the screen
        VerticalFieldManager manager = new VerticalFieldManager();
        screen.add( manager );
        manager.add( new BasicEditField( "App Name : ", myAppName, 100, Field.READONLY ) );
        manager.add( new BasicEditField( "License Key : ", key, 100, Field.READONLY ) );
        manager.add( new BasicEditField( "Update Available : ", update, 100, Field.READONLY ) );
        manager.add( new BasicEditField( "Name : ", name, 100, Field.READONLY ) );
        manager.add( new BasicEditField( "Email : ", email, 100, Field.READONLY ) );
        manager.add( new BasicEditField( "PIN : ", pin, 100, Field.READONLY ) );
         manager.add( new BasicEditField( "Version : ", version, 100, Field.READONLY ) );
        manager.add( new SeparatorField() );

        //Create the resources needed to launch the App World
        //pointing at our app's page
        contentIdField = new BasicEditField( "Content ID : ", myContentId );
        manager.add( contentIdField );
        ButtonField button = new ButtonField( "Open BlackBerry App World", ButtonField.CONSUME_CLICK );
        button.setChangeListener( new FieldChangeListener() {
            public void fieldChanged( Field field, int context ) {
                try {
                    openAppWorld( contentIdField.getText() );
                } catch( final Exception e ) {
                    SampleApplication.this.invokeLater( new Runnable() {
                        public void run() {
                            Dialog.alert( "Problems opening App World: " + e.getMessage() );
                        }
                    } );
                }
            }
        } );
        manager.add( button );
        pushScreen( screen );
    }

    /***
     * openAppWorld
     * <p>
     * Opens the App World pointing to a specific application. <p>
     * Note: This method takes advantage of
     * javax.microedition.content, which was introduced in 4.3.
     * There is no way to open the BlackBerry App World on an older OS.
     * <p>
     * @param myContentId App World ID of application to open.
     * @throws IllegalArgumentException if myContentId is invalid
     * @throws ContentHandlerException if App World is not installed
     * @throws SecurityException if access is not permitted
     * @throws IOException if access to the registry fails
     */

    protected void openAppWorld( String myContentId ) throws IllegalArgumentException, ContentHandlerException,
            SecurityException, IOException {
        Registry registry = Registry.getRegistry( SampleApplication.class.getName() );
        Invocation invocation = new Invocation( null, null, "net.rim.bb.appworld.Content", true, ContentHandler.ACTION_OPEN );
        invocation.setArgs( new String[] { myContentId } );
        boolean mustExit = registry.invoke( invocation );
        if( mustExit ) // For strict compliance - this should never happen on a BlackBerry
            screen.close();

        // Please note that this response won't be generated
        // until the BlackBerry App World exits
        // This method will block until that time
        Invocation response = registry.getResponse( true );
        if( response.getStatus() != Invocation.OK )
            Dialog.alert( "Problem invoking BlackBerry App World. Error code " + response.getStatus() );
        else
            Dialog.inform( "BlackBerry App World successfully opened." );
    }

    public static void main( String[] args ) {
        new SampleApplication().enterEventDispatcher();
    }
}

sábado, 3 de diciembre de 2011

Conditional Loading for Responsive Designs

Loading content on small devices is something you must consider for giving a great user experience on your site.

So, this "24 ways" entry explains how you can handle that by checking the screen width > 640 and stopping excessive data. You should only put a link to do the job.

24 ways: Conditional Loading for Responsive Designs

viernes, 2 de diciembre de 2011

RIM - BlackBerry - COD size

http://supportforums.blackberry.com/t5/Java-Development/The-maximum-size-of-a-BlackBerry-smartphone-application/ta-p/502534
Extracto:

"The limit for the number of sibling COD files that can exist within a single application is 127.  This means that the maximum theoretical size limit for an application would be 16256 KB, which consists of 8128 KB of application data and 8128 KB of resource data. "