nItemPos()

nItemPos()

Postby antolin » Fri Oct 17, 2014 5:03 pm

Hola Foreros.

Recientemente, implementando una función he dado con un algoritmo muy sencillo que a lo mejor puede ser de utilidad para alguno de vosotros. Se trata del siguiente:
Code: Select all  Expand view
nPos := Int( ( nItem + nTama - 1 ) / nTama )

Al que he llamado nItemPos(), y que se puede implementar, en su forma preprocesada:
Code: Select all  Expand view
#translate nItemPos( <nVar1>, <nVar2> )  =>  Int( ( <nVar1> + <nVar2> - 1 ) / <nVar2> )
 

¿Para qué sirve? Tiene 2 posibles aplicaciones:

1º - Dado un conjunto de elementos, numerados correlativamente, y agrupados en subconjuntos de igual tamaño, permite determinar en qué subconjunto se haya un elemento determinado.
Code: Select all  Expand view
Ejemplo 1: dado el conjunto de los meses, numerados del 1 al 12, si los agrupamos por trimestres, podemos saber a qué trimestre pertence un mes determinado.

Agosto = 8
Trimestre = nItemPos(Agosto,3)  // RESULTADO: 3º trimestre.

Si los agrupamos en cuatrimestres:

Cuatrimestre = nItemPos(Agosto,4)  // RESULTADO: 2º cuatrimestre.

Code: Select all  Expand view
Ejemplo 2: Si tenemos un conjunto de 96 elementos que representamos en pantalla agrupados en 8 columnas de 12 elementos.

Numerados por columnas, podemos saber en que columna estará el elmento nº 57:

01   13   25   37   ..  85
02   14   26   38   ..  86
03   15   27   39   ..  87
04   16   28   40   ..  88
..   ..   ..   ..   ..  ..

nCol = nItemPos(57,12)  // RESULTADO: 5ª columna.


Numerados por filas, podremos saber en que fila estará el elmento nº 57:

01   02   03   04   ..   08
09   10   11   12   ..   16
17   18   19   20   ..   24
25   26   27   28   ..   32
..   ..   ..   ..   ..   ..

nFila = nItemPos(57,8)  // RESULTADO: 8ª fila.

Code: Select all  Expand view
Ejemplo 3: Si tenemos un Listbox cuyo panel mide 667 pixels de alto y cada linea mide 23 pixels de grosor (incluyendo margenes, contenido y grid), podemos saber, cuando pinchamos con el ratón sobre el pixel nRow = 133, sobre qué línea del Listbox hemos pinchado.

nLinea = nItemPos(133,23)  // RESULTADO: 6ª línea

Aquí tengo que tener que hacer un pequeño inciso: se supone que el listbox tiene un contorno (por ejpmlo 1 pixel) y una cabecera (por ejmplo 37 pixel), esos pixels hay que restarlos a nRow porque el primer pixel de la primera línea empieza en el pixel número 38, no en el 0. Por lo que en realidad la línea sobre la que hemos pinchado con el ratón sería la:
Code: Select all  Expand view
nLinea = nItemPos(133-38,23)  // RESULTADO: 5ª línea

Sólo hay que tener en cuanta que todos los subconjuntos deben tener la misma cantidad de elementos, salvo el último que puede ser inferior (no superior)
Code: Select all  Expand view
Ejemplo 4: Tenemos 28 personas montadas en 6 vehículos con capacidad para 5 personas cada uno. Habrá 5 autos con 5 personas cada uno, más un 6º vehículo con sólo 3 viajeros. Si le asignamos un número a cada persona (ordanada y correlativamente), podremos saber en qué vehículo viaja el 11º pasajero:

nAuto = nItemPos(11,5)  // RESULTADO: 3º vehículo

Lógicamente no tenemos necesidad de saber en que vehículo estará el pasajero número 30, porque sólo hay 28 personas, pero si me dirá que el 28º pasajero esta el coche número 6 (que no está completo). Luego, puedo ubicar todos y cada uno de los elementos existentes aunque el último subconjubto no esté lleno. Esto me lleva a la segunda posible utilidad de nItemPos().

2º - Dado un número de elementos cualquiera, me permite determinar cuantos subconjuntos de x elementos se pueden formar con ellos. Puede que el último de esos subconjuntos no esté completo, pero a efectos prácticos, se trata del ultimo subconjunto necesario para ubicar a todos y cada uno de los items sin que se quede ninguno fuera del sistema.
Code: Select all  Expand view
Ejemplo 5: Siguiendo con el ejemplo de los vehículos. Si tengo 37 pasajeros y tengo que transportarlos en vehículos con capacidad para 5 personas cada uno. ¿Cúantos autos necesitaré?

nAutos = nItemPos(37,5)  // RESULTADO: 8 vehículos. (7 llenos y uno con 2 personas)

Code: Select all  Expand view
Ejemplo 6: Retomando nuestro Listbox. Hemos dicho que el panel mide 667 pixels de alto, 628 sin cabecera ni bordes superior e inferior, y que cada línea ocupa 23 pixels. ¿Cúantas líneas van a caber?

nLineas = nItemPos(628,23)  // REULTADO: 28 líneas (27 completas más otra parcialmente escondida)

Si sólo vamos a pintar las líneas completas bastaría con hacer: Int(622/23)
Podemos saber el espacio sobrante:

nPixels = (nItemPos(628,23)*23)-628  // RESULTADO: 16 pixels se quedan fuera
nPixels = 628-(Int(628/23)*23)       // RESULTADO:  7 pixels se quedan dentro

Code: Select all  Expand view
Ejemplo 7: Si el panel del Listbox mide 937 pixels de ancho (sin bordes), podemos saber cuantos columnas de 173 pixels me van a caber:

nCols = nItemPos(967,173)  // RESULTADO: 6  (5 de 173 pixel más la última de sólo 102 pixels)

Como verán es una formula muy sencilla que puede dar mucho de sí.

Espero que os guste

Un saludo.
Peaaaaaso de foro...
antolin
 
Posts: 492
Joined: Thu May 10, 2007 8:30 pm
Location: Sevilla

Re: nItemPos()

Postby horacio » Fri Oct 17, 2014 8:02 pm

Muy interesante este aporte. Muchisimas gracias por compartirlo.

Saludos
horacio
 
Posts: 1358
Joined: Wed Jun 21, 2006 12:39 am
Location: Capital Federal Argentina


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: Google [Bot], Jorge Jaurena and 20 guests