mgaitan / preciosa

Inteligencia colectiva contra la inflación
http://preciosdeargentina.com.ar
Other
68 stars 40 forks source link

Diferente UPC para el mismo producto #175

Closed humitos closed 10 years ago

humitos commented 10 years ago

Tengo este mismo turrón en mis manos y veo que tiene un código UPC diferente al que se muestra acá. Sin embargo, es muy parecido:

http://preciosdeargentina.com.ar/481-turrones/8354-turron-de-mani-arcor-25-gr

El que tengo en mis manos es: 7794 0131

¿Puede ser que esté mal cargado o es posible que haya números diferentes para el mismo producto?

mgaitan commented 10 years ago

genio! justo hicimos un datamigration #176 porque nos habiamos dado cuenta que teniamos codigos con upc que "empezaban con un 0"... pero no que podia haber muchos ceros. Ahora Pandres va a corregir eso, gracias a que vos comiste turrón :)

mgaitan commented 10 years ago

chan! acabo de darme cuenta que la diferencia que reportás no es sólo con los ceros sino con el último digito, un 1.

ese ultimo digito en general es un checksum, o sea, un codigo de comprobación. Pero no es tan trivial como no darle bola a los ceros.

humitos commented 10 years ago

sí, en realidad estaba reportando el error en los últimos números y no en los ceros. De hecho, pensé que los ceros adelante era a propósito :)

mgaitan commented 10 years ago

acá tenemos el algoritmo de checksum para UPC.

http://en.wikipedia.org/wiki/Check_digit#UPC

jazzido commented 10 years ago

Según veo en preciosdeargentina.com.ar, los códigos UPC que aparecen tienen 12 o 7 dígitos. Por lo que se dice acá, aparentemente WalMart no muestra el checksum digit.

No hay tantos tipos de códigos EAN/UPC, así que quizás se puede detectar si el UPC informado tiene o no el dígito de checksum y agregarlo si corresponde.

mgaitan commented 10 years ago

:+1: reviso esto

mgaitan commented 10 years ago

houston... tenemos un problema. ¡tenemos upc de todos los tamaños! yo esperaba que fuente de 7/8 (es decir, de 8 sin y con checksum) y de 12/13 (de 13 sin y con checksum). Pero conté y tenemos

In [15]: for largo in range(0, 15):
     print "upc %s -> " % largo, Producto.objects.extra(where=["CHAR_LENGTH(upc) = %s" % largo]).count()
   ....:     
upc 0 ->  0
upc 1 ->  0
upc 2 ->  1
upc 3 ->  3
upc 4 ->  49
upc 5 ->  5
upc 6 ->  0
upc 7 ->  128
upc 8 ->  1
upc 9 ->  3
upc 10 ->  264
upc 11 ->  300
upc 12 ->  8777
upc 13 ->  2398
upc 14 ->  0
jazzido commented 10 years ago

Los UPC menores a 7 dígitos deben ser otro tipo de código (¿Podés sacar una lista de productos con len(upc) < 7?)

De ahí para arriba, quizás sean variaciones de EAN/UPC. O quizás a veces figura el checksum y a veces no. Pienso en voz alta, porque no tengo idea de sistemas de retail :)

mgaitan commented 10 years ago

Muchos de los upc menores a 6 parecen ser productos vendidos a granel, como frutas y verduras. Pero tambien hay productos por ejemplo de la marca "Timos" (¿quien puede ponerle ese nombre a una marca!?) con código de 3 o 4 digitos.

Podemos "blanquear" los upc de estos productos, cierto?

In [37]: for p in Producto.objects.extra(where=["CHAR_LENGTH(upc) <= 6"]):
    print "%s: %s (%s)" % (p, p.upc, p.categoria)
   ....:     
Te rojo timos 25 gr: 1051 (Almacen > Infusiones > Mate cocido)
Uva blanca x kg: 4274 (Frutas y verduras > Frutas > Frutas)
Uva negra x kg: 4270 (Frutas y verduras > Frutas > Frutas)
Uva red globe x kg: 4636 (Frutas y verduras > Frutas > Frutas)
Banana x kg: 4011 (Frutas y verduras > Frutas > Frutas)
Ciruela x kg: 4042 (Frutas y verduras > Frutas > Frutas)
Coco x kilo: 4260 (Frutas y verduras > Frutas > Frutas)
Durazno amarillo x kg: 4038 (Frutas y verduras > Frutas > Frutas)
Frutilla x kg: 4323 (Frutas y verduras > Frutas > Frutas)
Kiwi x kg: 4030 (Frutas y verduras > Frutas > Frutas)
Limon x kg: 4433 (Frutas y verduras > Frutas > Frutas)
Mango x kg: 4959 (Frutas y verduras > Frutas > Frutas)
Manzana red elegida x kg: 4015 (Frutas y verduras > Frutas > Frutas)
Naranja jugo x kg: 4388 (Frutas y verduras > Frutas > Frutas)
Palta hass x kg : 4225 (Frutas y verduras > Frutas > Frutas)
Pera packams x kg: 4410 (Frutas y verduras > Frutas > Frutas)
Pera williams x kg: 4409 (Frutas y verduras > Frutas > Frutas)
Pomelo rojo x kg: 4288 (Frutas y verduras > Frutas > Frutas)
Brocoli x kg: 4060 (Frutas y verduras > Verduras > De hojas)
Coliflor x kg: 4567 (Frutas y verduras > Verduras > De hojas)
Espinaca x kg: 4090 (Frutas y verduras > Verduras > De hojas)
Lechuga capuchina x kg: 4634 (Frutas y verduras > Verduras > De hojas)
Lechuga criolla x kg: 4640 (Frutas y verduras > Verduras > De hojas)
Lechuga morada x kg: 4075 (Frutas y verduras > Verduras > De hojas)
Batata x kg: 4091 (Frutas y verduras > Verduras > Hortalizas)
Berenjena negra x kg: 4081 (Frutas y verduras > Verduras > Hortalizas)
Berenjena violeta x kg: 4601 (Frutas y verduras > Verduras > Hortalizas)
Cebolla x kg: 4093 (Frutas y verduras > Verduras > Hortalizas)
Chaucha balina x kg: 4528 (Frutas y verduras > Verduras > Hortalizas)
Choclo chala x kg: 4078 (Frutas y verduras > Verduras > Hortalizas)
Pimiento rojo x kg: 4088 (Frutas y verduras > Verduras > Hortalizas)
Pimiento verde x kg: 4065 (Frutas y verduras > Verduras > Hortalizas)
Remolacha x kg: 4538 (Frutas y verduras > Verduras > Hortalizas)
Repollo blanco x kg: 4069 (Frutas y verduras > Verduras > Hortalizas)
Tomate perita x kg: 4087 (Frutas y verduras > Verduras > Hortalizas)
Tomate redondo x kg: 4064 (Frutas y verduras > Verduras > Hortalizas)
Zanahoria x kg: 4562 (Frutas y verduras > Verduras > Hortalizas)
Zapallito redondo x kg: 4755 (Frutas y verduras > Verduras > Hortalizas)
Zapallo cabutia x kg: 8167 (Frutas y verduras > Verduras > Hortalizas)
Zapallo coreano x kg: 4759 (Frutas y verduras > Verduras > Hortalizas)
Zapallo plomo x kg: 8165 (Frutas y verduras > Verduras > Hortalizas)
Bolsa salida verde walmart 55x60x20: 5579 (Limpieza > Cocina > Bolsa reutilizable)
Bolsa salida wm verde 45 x 55 x 17: 5586 (Limpieza > Cocina > Bolsa reutilizable)
Bolsa.salida negro walmart 55x60x20: 5580 (Limpieza > Cocina > Bolsa reutilizable)
Mix pimienta villares 50 gr: 12343 (Almacen > Condimentos > Especias)
Pimienta jamaica villares 50 gr: 12344 (Almacen > Condimentos > Especias)
Almendra con cascara villares 250 gr: 12359 (Almacen > Frutas secas > Frutas secas)
Almendra pelada blancanuez 100 gr: 39 (Almacen > Frutas secas > Frutas secas)
Almendra pelada villares 100 gr: 12337 (Almacen > Frutas secas > Frutas secas)
Duraznos medallones villares 200 gr: 1861 (Almacen > Frutas secas > Frutas secas)
Nuez pelada mariposa blancanuez 100gr: 124 (Almacen > Frutas secas > Frutas secas)
Peras williams villares 250 gr: 12332 (Almacen > Frutas secas > Frutas secas)
Te de boldo timos 25 gr: 990 (Almacen > Infusiones > Mate cocido)
Te de cedron timos 25 gr: 992 (Almacen > Infusiones > Mate cocido)
Te de poleo timos 25 gr: 1047 (Almacen > Infusiones > Mate cocido)
Te de tilo timos 25 gr: 1045 (Almacen > Infusiones > Mate cocido)
Te verde timos 25 gr: 1052 (Almacen > Infusiones > Mate cocido)
Te de carqueja timos 25 gr: 1046 (A CLASIFICAR > Infusiones)
jazzido commented 10 years ago

Tiene sentido, parecen ser códigos internos.

Para el resto, me imagino que hay que implementar un sistemita de reglas: dado un código, decidir su formato y normalizarlo.

mgaitan commented 10 years ago

Houston, tenemos un problemita :)

Ejemplo agarré una sal que tenia en mi cocina cuyo codigo completo es 7792900092683

In [16]: Producto.objects.filter(upc__startswith='779290009268')
Out[16]: [<Producto: Sal entrefina parrille dos anclas 500 gr>, <Producto: Dos Anclas - Parrillera Sal entrefina (Caja 500 Grs)>]

In [17]: Producto.objects.filter(upc__startswith='779290009268')[1]
Out[17]: <Producto: Dos Anclas - Parrillera Sal entrefina (Caja 500 Grs)>

In [18]: Producto.objects.filter(upc__startswith='779290009268')[1].upc
Out[18]: u'7792900092683'

In [19]: Producto.objects.filter(upc__startswith='779290009268')[0].upc
Out[19]: u'779290009268'

Son el mismo producto. Este ultimo código (12 digitos, sin checksum) es el que aparace en el dataset que todavia no metimos a la base.

pero la cosa es más truculenta, porque así como asi ninguno de los 2 codigos resulta válido. Hay que anteponerle un 0.

In [20]: barcode.es_valido('779290009268')
Out[20]: False

In [21]: barcode.es_valido('7792900092683')
Out[21]: False

In [22]: barcode.es_valido('07792900092683')
Out[22]: True

In [23]: barcode.checksum('0779290009268')
Out[23]: '3'

Quien se le anima a este monstruito?

mgaitan commented 10 years ago

Pego de un mensaje de la lista, para referencia.

In [16]: Producto.objects.filter(upc__startswith='4000').values_list('categoria__nombre', flat=True).distinct()
Out[16]: [u'Especiales', u'Fiambres y Embutidos', u'Sillones', u'Automoviles', u'Radio control', u'Accesorios rodados', u'Carpeta escolar', u'Jamon cocido', u'Ejercitadores', u'Caja de herramientas', u'Llantas 15"', u'Ahumados', u'Organizadores', u'Llantas 13"', u'Aromatizadores', u'Cocina', u'Colchones y sommier', u'Accesorios', u'Accesorios para autos', u'Autoestereo', '...(remaining elements truncated)...']

Ejemplo http://www.upcdatabase.com/dummyupc.asp?upc=0400069241572

In [5]: len([(p, p.upc) for p in  Producto.objects.extra(where=["CHAR_LENGTH(upc) = 13"]) if not barcode.es_valido(p.upc)])
Out[5]: 1915
In [6]: len([(p, p.upc) for p in  Producto.objects.extra(where=["CHAR_LENGTH(upc) = 13"]) if barcode.es_valido(p.upc)])
Out[6]: 483
mgaitan commented 10 years ago

las fotitos que tenemos están sacadas de walmart tiene son el upc precedido de un 0. se puede usar como dato?

        {
            "id": 3126, 
            "descripcion": "Cinta adhesiva micropore  9,1 m 3m", 
            "marca": null, 
            "upc": "780507040079", 
            "foto": "productos/0780507040079.jpg"
        },