Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Serapis

#1031
Sí. China dice tener una vacuna lista para probar... Israel dice que le faltan unas semanas, USA ya ha seleccionado a una empresaria como primera 'mona de pruebas', en España (no recuerdo si procedente del CESID), también dicen tener medio listo una vacuna, y en Alemania también tienen a punto unos estudiso (el ridículo TRUMP, quiso cmprarlo por 1.000 millones).

...el caso es que, alguien se atrevería a ponerse una vacuna china????.
Yo de entrada soy antivacunas, y ni me parecería correcto que ningún país (democrático), aceptara una vacuna de China, en todo caso, que den la receta a los científicos, que la estudien y vean su composición, etc... y si procede después de verificada, que los farmacéuticos de cada país lo fabriquen. No es lo mismo una vacuna fabricada por una empresa que fabricada por un gobierno claramente nada democrático.

Vamos, que me suena a "Caballo de Troya".... primero surge de la nada un virus en su país, se expande misteriosamente por todo el mundo al tiempo que en China se controla y luego nos quieren vender una vacuna... pués eso, suena a caballo de Troya total... Cabe preguntarse si han decidido pasar en sus ataques de los ordenadores a la realidad...

El peligro en España, es que como tenemos un gobierno de izquierdas, escuchan a (y quien sabe si hasta bailen al son de) China... Recuerdo haber escuchado ayer a Pedro Sanchez en su comparecencia haber dicho que había hablado con el presi chino... lo cual confirma de algún modo la 'subyugación' tentadora de las indicaciones del gobierno chino...

Para aquellos que parecen que nunca ven nada hasta que caen en el hoyo, quizás sea la hora de preguntarse si delante y detrás de esto, está solo el virus o hay algo más, oculto (política/militar...mente hablando)... A estas alturas de la Humanidad que ha conseguido una comunicación internacional aceptable (nos escuchamos), sería extremadamente peligroso que de repente un país con potencial (sea económico militar o de otra índole), le entraras ganas de la ilusión de la supremacía mundial y viniéramos a tener un nuevo intento 'Hitleriano' en el mundo.
#1032
mmmm... podría hacerse un simulador de contagios de modo que pudieran probarse diferentes sistemas...

...con el tiempo libre que ha surgido inesperadamente, quizás me ponga a hacer uno sencillo.
#1033
Ayer me mandaron un audio de T5, un tipo que a ratos parecía mediollorando... supongo que será éste.

Bueno, hay que decir que la 'verdad está en el filo', eso implica que ambas vertientes son válidas, aunque sean opuestas.
- Por un lado, dar importancia al aunto y proceder a un aíslamiento total para evitar contagios a toda costa. El problema es que esto genera saturación de hospitales si se trarda en dar una respuesta y paraliza la economía de un país. Son las vías que de un modo dsimilar con sus matices han adoptado China, Italia, España y Francia (por ejemplo).
- Por otro lado, negar toda importancia al asunto. Y proceder al aíslamiento exclusivo de los mayores de cierta edad y aquellos que tienen problemas crónicos de salud, que son las posibles víctimas de este virus. Y para el resto, ignorarlo por completo, de hecho contagiarse TODOS lo antes posible, pués cuanto antes se contagie el ultimo contagiable, empieza la cuenta atrás para la 'desaparición' del virus... No todo saldrá tal cual, dentro de los 'contagiables sanos' puede darse alguna muerte inesperada, y probablemente algún que otro ingresado grave. La ventaja de este método, es que afecta a una minoría (los aíslados que son los que preocupan), y el país puede tirar adelante con su economía casi como si nada, el tiempo pandémico en este caso, sería el menor de cualquier tipo, pués posiblemente no requiriese más de 5 semanas desde el inicio hasta su final. Esta vía es la que ha adoptado Inglaterra (aunque desconozco, si lo han hecho conscientemente o por ignorancia y pura cabezonería (Inglaterra es famosa por lleva siempre la contraria al resto del mundo)).

...por eso el alarmismo de este tipo, me resulta hasta cierto punto patético. La gente que muere a causa de la contaminación ambiental cada año, supera en cifras a las que vaya a dejar esta 'gripe china', y nadie se pone de acuerdo para hacer nada. Ni veo a ningún médico llorando ante las cámaras ni mendigando para que  se adopten ciertas medidas, a pesar de que ellos mejor que nadie conocen esas cifras. ...y lo dicho para los muertos por contmainación se aplican para muertos por otras causa EVITABLES, si los gobiernos tomarán medidas sensatas (ni siquiera extraordinaraias, aunque cuanto más tiempo pasa, más se deberán acercar a ese matiz).
Esta gripe ha logrado (caso de españa), que la gente se quede en casa masivamente y el tráfico rodado ha bajado espectacularmente... Vamos que la respuesta de este virus, ha conseguido en torno a la contaminación lo que no se había conseguido de ninguna otra manera (casi estoy por soltar 200 virus más, uno tras otro en el mundo, para mejorar la contaminación y enseñar a la gente a ser más prudente en su forma de vida consumista)...
#1034
Operando con arrays (si es obligatorio), hay opciones más eficientes; por ejemplo:

1 - Si el array de origen estuviere ordenado, no seria preciso más que imprimir el ítem y luego ir saltando los siguientes ítems mientras sean iguales al actual.

2 - Por tanto algo muy eficiente es ordenar primero el array si no lo está, y luego proceder con el paso 1.

3 - Recurrir a un array temporal... Se empieza imprimiento la primera palabra y añadiéndola al array B. Luego cuando se quiere imprimir otra palabra se comprueba si se existe en el array B, si no existe se añade al array B. fiamlemente el array B se imprime que solo contiene palabras únicas (también se puede ir imprimiendo sobre la marcha). Este método es más efectivo cuando el array no está ordenado (y no se permite ordenarlo). Resulta tanto más eficiente, cuando más elevado sea el número de repetidos (ese suceso implica pocos ítems en el array B, entre los que buscar cada vez). Debe descartarse si el array de origen fuera gigante, o si el número de repetidos es muy escaso, pués Descartar este método y forzado a usar arrays, implica usar el propio array en sendos bucles, el externo para el ítem actual, el interno para buscar su existencia en los previos. Tiene la desventaja de precisar un array temporal, ocupando más memoria.

4 - Si al caso, para 3, en vez de usar como estructura (temporal) un array, se permite otro tipo de estructura, que permita añadir los ítems ordenados, mejor, pués la búsqueda en esa estructura 'B', podría hacerse mediante una búsqueda binaria (caso de por ejemplo un árbol binario), o mejor una búsqueda atómica (si la estructura elegida fuera una tabla hash).

Por lo mismo si en origen se permite otras estructuras, siempre será más eficiente una tabla hash que cualquier otro método.

Como entiendo que es un ejercicio de algún centro de enseñanza y se trata de un principiante, queda descartado el uso de estructuras complejas (e imagino que posiblemente incluso quede descartado ordenar el array). Así que en tales circunstancias el caso 3 sería el más eficiente... ya que pone a prueba al estudiante en el uso de arrays y algorítmica, que es lo que en definitiva se persigue con el ejercicio.


#1035
Arranca en el modo 'aprueba de fallos', en las propiedades del hardware localiza 'administrador de dispositivos',  localiza el ítem que refiere a la tarjeta gráfica y 'desinstálalo', luego cuando arranques de nuevo el equipo, el sistema detectará que hay 'hardware nuevo' y buscará los drivers y los reinstalará...
#1036
Dudas Generales / Re: AYUDA CON ESTAFA
16 Marzo 2020, 16:32 PM
Cita de: Agp en 16 Marzo 2020, 13:43 PM
el estafador uso un numero de movil registrado hizo varias llamadas
Sería un estafador "tonto, muy tonto", para hacer llamadas desde un número a su nombre.
¿¿¿no te parece que casi con toda seguridad será un teléfono robado, y que por tanto no aportará ninguna pista conocer quién es el dueño al que robaron el tf.?????
#1037
CitarEl niño puede hacer sus necesidades en un baño tal y como un ser humano. Las mascotas no.
Esto no es cierto.
Tengo gatos y tienen su arenero.

Hace años tenía 2 perros grandotes, también tenía un buen arenero para ellos. Los días de lluvia, los días que tenía que ausentarme demasiadas horas (por trabajo casi siempre), o a su libre albedrío por las noches o en cualquier momento, podían hacer sus necesidades, sin depender de mis horarios.
El asunto es que el arenero para perros tiene que ser enormemente más grande que el de un gato, y requiere igual que el de un gato su limpieza diraria y ubicarlo en una zona que no moleste... como no todas las casa tienen un espacio así (culpa de los malos diseños de las viviendas), puede acondicionarse un cierre acristalado en un espacio junto a una ventana de la casa... pero es más fácil sacarlo a la calle (ya que hay que sacarlo de paseo tambien) y que hagan sus necesidades en la calle (y luego si eso... ni recogen los excrementos).

En mi opinión el diseño de las casas (nuevas o reformadas) debiera incluir por ley un espacio a modo de baño para animalitos... con huecos de ventilación apropiados, peor seguimos tratando a los animales como 'cosas' que no se merecen su espacio propio... Cuando una pareja va a tener un hijo, se pasan meses apañando una habitación que será 'su habitación', cuando alguien va a tener un perro, todo lo que se suele hacer es comprar una correa, un par de comederos y quizás un 'cojín ancho'...

Como el hilo va del coronavirus el hilo, pués aprovecho para dejar mi comentario.
Y coincido plenamente en la inconsciencia en la permisividad del 8M, de hecho la principal razón por la que sea Madrid el principal foco de infectados de España, creo que corresponde precisamente a ese día y los previos de preparativos... el virus ya campaba a sus anchas un mes o más, así que no era preciso prohibir la manifestación simplemente cambiarla de fecha (para cuando fuera posible, julio, agosto... ono, que más da, que lo celebren en sus casa, que no hay mucha diferencia de celebrarlo pasenado).

en mi opinión, cuando se detecto el virus en China e informalmente se informó al resto del mundo, la primera reacción del resto de países debió se la restricción total de salida y entrada de vuelos a y desde China, y aquellos países al momento de detectar contagiados en su país decretar el cierre total del país y el confinamiento de sus habitantes... entonces a estas alturas, ya estaríamos libres o casi libres de este problema y sin apenas incidencias... las económicas serías seguramente similares. Esa resistencia a la negación por meras cuestiones económicas, es lo que logrará que la expansión se amundial y absolutamente todos los países van a caer tarde o temprano, porque sin operar todos al únísono, será escalonado, un efecto dominó... pero no se salvará ninguno, solo un retraso de semanas o meses.

Una cuarentena nunca mejor dicho de 40 días en todo el mundo a la vez, hubiera sido menos penoso que ahora cada páis de forma particular, empiece con 15 días y se acaben alargando...

Otra cosa curiosa es que pòne de relieve la falta de previsión de los gobienros antes tales pandemias... creo que todos esperaríamos que por lo menos los gobienros d elas economías más privilegiadas del mundo, tuvieren planes parta este tipo de eventos, pero ya se ve, que los planes a lo sumo constan en un papel y se limita a dar nombres a la situación actual según el estado... en las películas, las plagas siempre son enormemente más 'voraces' y los planes de contingencia (también) siempre están contemplados y hay lo necesario (aunque el guión precisa limitarlo, para cursar la historia), para que no sea un problema trascendental...

En fin, si en vez de una 'gripe extraña', fuera un 'zombificación', donde el infectado hace todo cuanto puede por seguir infectando (aunque sea por enajenación mental), creo que a estas alturas, el planeta estaba perdido...
#1038
Sigo... más o menos desde donde lo dejé...

Cada ítem de un menú por su utilidad puede tener una funcionalidad más acentuada que otro, respecto de alguna característica, lo que viene a indicarnos que hay que considerar diferentes tipos de ítems de menú... Voy a considerar una lista que suele ser habitual, y en casos concretos puede haber otros o descartarse algunos de aquí... es normal. Mi texto debe servir de base a las necesidades de cada uno.., no hay porqué seguirlo a rajatabla.

Básicamente hay 2 categorías de tipos de menús: 'Título' y 'Acción', el primero es el 'conductor', sirve para mantener orden y conducir al usuario... la categoría 'acción' sirve para realizar la acción cuya funcionalidad es la que espera y se ofrece al usuario...
Todos los tipos los encajamos en uno u otra categoría:

* Titulo: Es un tipo que actúa de padre de otros, los ítems que tiene bajo sí son sus hijos. Hay 3 formas de este tipo de menús a la hora de implementarlos y según donde se precise usarlo.
---- Título: Describe sus ítems debajo, cuando se pulsa despliega u oculta los ítems bajo él. En consola es algo más complejo y laborioso de usar... Suele llevar algún indicador tipo flecha arriba/abajo a su derecha para indicar que que al pulsarse despliega/repliega su lista.
---- Submenú: Como el anterior, pero a la hora de desplegar, a sus hijos, los ubica en una nueva ventana. Tratándose de consola, implica dibujar esos ítems que pasan a ser el menú activo. Suele llevar algún indicador tipo flecha derecha, a su derecha para indicar que que al pulsarse despliega su lista. en este tipo de menú el repliege suele hacerse cuando la ventana pierde el foco, al tratarse de consola exige un ítem específico.
---- Delimitador: Es un tipo de ítem que delimita donde terminan los ítems de un tipo dado, por ejemplo, los hijos de un submenú o los ítems de un tipo específico. Como tal puede ser visible o invisible.
A veces es visible y simplemente contiene una línea que aclara al usuario el límite 'físico' de los ítems previso.
Este ítem si se acepta en un menú podría hacer innecesario el campo 'cantidad de hijos', se entendería que un menú empieza en el índice que señale el padre y acaba cuando encuentre un ítem de este tipo. No importa tnto si se usa este método o el otro, siempre que se sea consecuente y se elija uno y solo un método para el caso.
En el caso de consola este mismo puede ser el que una vez pulsado cierre el menú actual y retorno al previo, en este caso el texto debe ser claro 'Volver <' y en caso del menú raíz 'Salir <', nótese la flechita (el sufijo) a la derecha del texto.

* Acción: En los menús típo Pull-Down, un menú se cierra siempre que se pulse un ítem de 'accion', el código de inmediato deriva a la acción pulsada...
---- Botón: Hace lo que dice. Cuando se pulsa ejecuta una acción y ya. Ejemplo: 'Copiar' (copiaría el textou objeto seleccionado, al objeto al que da soporte.
---- Activación: (Check) Permite que se active o desactive con cada pulsación, alternando entre uno y otro estado. Habitualmente es de tipo buleano y por tanto mantiene solo dos estados. Ejemplo: 'Guardar opciones al salir'. Que viene a indicar que: cuando se cierre la aplicación se consulta el estado de este ítem, y si está activado, se guarde a fichero las modificaciones que se hubieren realizado en la configuración de un programa.
---- Opcion (option/radio button): Cuando se pulsa, se activa previamente desactiva el ítem del mismo grupo que estuviere activo. Requiere pués o bien tener  un indicador de cual estaba activo, o bien ahorrarse el indicador y recorrer sus 'hermanos' para determinar cual estaba activo. Un grupo para consdierarse como tal, debe estar contiguo, es decir ser del mismo tipo, si un menú es demasiado complejo, y hay listas seguidas de estos: podría interponerse algún separador (un menú titulo) o bien un campo grupo y que cada menú del mismo grupo tengan el mismo valor. Ejemplo: una lista de Lunes, Martes .. *Viernes ... donde solo uno a la vez está seleccionado.
---- Vínculo: Es básicamente un botón, pero tiene como sufijo '...' y viene a indicar que es complejo y que se abre una ventana donde hay más opciones. Como botón, su acción será pués abrir dicha ventana... En consola, este tipo no suele tener cabida, pués puede complicar demasiado el tratamiento gráfico...
---- Elección/Scroll: Es un tipo que es idéntico a Activación, excepto que admite múltiples estados, no solo 2. El valor elegido en cada ocasión se hará constar a la derecha. por ejemplo: "Dia de la Semana": 5 - Viernes'. Es fácil comprender que este modelo es un modelo resumido de 'opcion' cuando es posible (sus valores son contiguos y elegibles secuencialmente, y solo uno entre todos puede estar elegido a la vez).
---- Texto: es un tipo de menú que básicamente es un botón, su funcionalidad es la misma, tiene la particularidad extra de que el contenido textual del mismo puede cambiar (el texto, no lo que llamamos su valor) Ejemplo: cuando se abre un fichero, se guarda en una pequeña lista el nombre de los x últimos ficheros distintos abiertos, el contenuido textual así es el nombre dle fichero, durante diseño, puede pués no conocerse siguiqera el texto que tendrá.

Una vez decidido que tipos de menú son los que encajan en nuestro diseño y modificando los que fueren de un tipo pero que se haya elegido otros en su remplazao, hay que ser cogerentes con la decisión para hacer la funcionalidad correcta tanto en diseño como en ejecución.

Finalmente solo faltan las funciones que hacen el trabajo.
La más simple es borrar el menú previo, pero lo normal es que partamos de 0, así que la primera acción sería mostrar el menú base, como usamos un array, el índice 0 del array es la raíz. Luego si abirmos el menú completo, se invocará justo ese índice al empezar...


funcion Main
    CargarItems  // los datos del array se cargan aquí.

    DibujarSubmenu( 0)
fin funcion


Al reusar el menú en otras aplicaciones si somos coherentes con las decisiones tomadas y por tanto el diseño final, lo único que encesitaremos cambiar en futuros proyectos, será precisamente los datos de la función 'CargarItems'
Para no hablar en hueco, vamos a simular un menú ficticio, pero muy real, que no sea demasiado extendo, pero que tenga ejemplos de cada cosa... resulta al caso muy útil el menú de la calculadora: Pongo los ítems en árbol, primeramente solo el texto, para reunir todos y considerarlos en conjunto, cuantos son y cuales, etc... pero véase en cada paso como vamos completando los datos...
(pulsa en la interfaz en 'hex', para cambiar el menú que se muestra en view, pués hay menús ocultos que cambian según la opción elegida, no es necesario complicarlo con grados, radianes...)

----------------------------------
Edit
    Copy
    Paste
View
    Standard
    Scientific
    -
    Hex
    Decimal
    Octal
    Binary
    -
    Qword
    Dword
    Word
    Byte
    -
    Digit Grouping
Help
    Help topics
    -
    About calculator
----------------------------------

Lo primero que se ve es que no haun menú raíz... y faltan menús títulos, porque es algo intuitivo, así mismo, los separadores, no tienen aclaración se deja una vez más a la intuición del usuario entender cada grupo.
Podemos canonizarlos mejor así (señalo a la derecha los ítems añadidos o modificados notoriamente):

----------------------------------
Menu Raiz   <---------
    Edit
        Copy
        Paste
        Volver  <---------
    View
        Tipo     <---------
            Standard
            Scientific
            Volver  <---------
        Base Decimal     <---------
            Hex
            Decimal
            Octal
            Binary
            Volver  <---------
        Tipo de dato     <---------
            Qword
            Dword
            Word
            Byte
            Volver  <---------
        Extra     <---------
            Digit Grouping
            Volver  <---------
        Volver  <---------
    Help
        Help topics
        About     <---------
            About calculator
            Volver  <---------
        Volver  <---------
    Exit  <---------
----------------------------------
1 - Como se ve, de entrada hemos desplazado a la derecha todos los ítems, para añadir el menú raíz.
   El menú raíz, podría ser el índice -1, pero determinados lenguajes no permiten índices negativos, luego el índice 0, también es acorde y lo consideraremos así...
2 - Lo otro que vemos, es que donde habúa un separador lo hemos remplazado por un título, para recoger más debidamente los ítems que tiene debajo, después de todo en consola no es práctico mostrar más de una docena de ítems. De este modo los subítems de cada 'padre' se desplazan a su derecha, y así el menú más grande no tendrá más de 4 ó 5 ítems.
3 - Algo que también se es que al 'canonizar' así el menú, queda suficientemente claro qué ítems son hijos de cual y qué items son padres de otros. Entonces ahora vamos a ir señalando el tipo que es de cada menú, primero los ponemos en una enumeración, y luego indicaremos en la lista de qué tipo es cada uno.
4 - Otra notariedad es que se ha añadido los ítems 'volver'
5 - Finalmente se ve que he añadido un ítem más al menú raíz 'Exit'... que es en el mismo 'volver que en raíz, conviene que tenga ese texto diferente.


Enumeracion TiposDeMenu
    MENU_TIPO_BOTON = 0
    MENU_TIPO_ACTIVACION = 1
    MENU_TIPO_OPCION = 2
    MENU_TIPO_VINCULO = 3
   
    MENU_TIPO_TITULO = 8
    MENU_TIPO_LIMITE = 15
fin enumeracion

Como se ve, no he  hecho constar todos los que decíamos más arriba, cámbiese según uno elija.
Los menús de tipo acción están arriba y los menús de tipo organizador, debajo... estos actúan como separadores, si hubiera un menú más complejo que contuviera demasiados hijos y más de una lista de opciones podría verse útil añadir un MENU_TIPO_SEPARADOR = 9 (por ejemplo), también si uno elige remplazar la funcionalidad del campo 'Hijos', por la cuenta que haya entre 'primerhijo' y un menú tipo separador... (éste sería hijo también de aquel, pero no cuenta sería oculto, no se dibujaría, o bien se dibujaría como una línea '-----------------------'.
Para las explicaciones he elegido que la separación sea con menús tipo título.

Ahora pongamos a la izquierda el tipo de cada menú.
----------------------------------
08 Menu Raiz   
08    Edit
00        Copy
00        Paste
15        Volver 
08    View
08        Tipo     
02            Standard
02            Scientific
15            Volver 
08        Base Decimal     
02            Hex
02            Decimal
02            Octal
02            Binary
15            Volver 
08        Tipo de dato     
02            Qword
02            Dword
02            Word
02            Byte
15            Volver 
08        Extra     
01            Digit Grouping
15            Volver 
15        Volver 
08    Help
00        Help topics
08        About     
03            About calculator
15            Volver 
15         Volver
15    Exit 
----------------------------------

Hay al menos un ejemplo de cada tipo de menú en la enumeración...
Ahora que queda también claro quien es padre y quien hijo de qien, puede indicarse el índice de cada uno. También a la izquierda dle todo, de cada menú. Recordar que cada hijo va contiguo. Se puede, escribir directamente como arriba,  o se pueden ya desmontar en grupos, con su padre encima:
-------------------------------
00 08 Menu Raiz
01 08    Edit
02 08    View
03 08    Help
04 15    Exit
-------------------------------
01 08    Edit
05 00        Copy
06 00        Paste
07 15        Volver 
-------------------------------
02 08    View
08 08        Tipo 
09 08        Base Decimal   
10 08        Tipo de dato   
11 08        Extra
12 15        Volver   
-------------------------------
08 08        Tipo
13 02            Standard
14 02            Scientific
15 15            Volver
-------------------------------
09 08        Base Decimal
16 02            Hex
17 02            Decimal
18 02            Octal
19 02            Binary
20 15            Volver
-------------------------------
10 08        Tipo de dato
21 02            Qword
22 02            Dword
23 02            Word
24 02            Byte
25 15            Volver
-------------------------------
11 08        Extra 
26 01            Digit Grouping
27 15            Volver
-------------------------------
03 08    Help
28 00        Help topics
29 08        About     
30 15        Volver
-------------------------------
29 08        About
31 03            About calculator
32 15            Volver
-------------------------------

Es fácil ver si hay errores, comprobando algunas cosas:
Cada menú de tipo titulo '08', encabeza siempre un submenú, contiene ítems y debe acabar en un tipo limite '15'
Níngún índice puede estar repetido, es decir cada índice aloja solo a un ítem, no equivocarse.
No es imprescindible que vayan seguidos, puede haber índices sin usar entre un submenú y otro, especialmente si uno considera que a futuro pudiera añadir más ítems.
Falta indicar algunas cosas, para cada tipo 'titulo' por ser padre, cual es el índice de su primer hijo así como la cantidad de hijos que tiene. Pondré solo 2 submenús como ejemplo..., dichos valores, los pondremos a la derecha del tipo:, así de momento van:
item = indice tipo numhijos indexprimerhijo texto

-------------------------------
00 08 04 01 Menu Raiz
01 08 03 05    Edit
02 08 05 08    View
03 08 03 28    Help
04 15 00 00    Exit
-------------------------------

Como se ve si no tiene hijos, porque el menú no e spadre el valor será 0, y por lo mismo indexprimerhijo, no importa, pero se pone 0. pogo dos cifras, solo para mantener la verticalidad y con ello una alineación visual adecuada, en el código no precisaos 0 a la derecha.
Otro ejemplo (que a diferencia del previo que casi todos sun subitems son submenús), cuyos hijos no son submenús:

-------------------------------
10 08 05 21        Tipo de dato
21 02 00 00            Qword
22 02 00 00            Dword
23 02 00 00            Word
24 02 00 00            Byte
25 15 00 00            Volver
-------------------------------

Podemos ver la línea BNF de interés:
    item = indice tipo numhijos indexprimerhijo texto
Todavía nos falta fijar algunas cosas, como el estado inicial de algunos ítems si están seleccionados.
Es tan simple como reservar un espacio más a la derecha de esos valores e indicar con '*' el ítem que esté seleccionado y con '-' el ítem que no tenga su estado seleccionado (incluso aunque el tipo no admita un estado de selección)

-------------------------------
10 08 05 21 -        Tipo de dato
21 02 00 00 -            Qword
22 02 00 00 -            Dword
23 02 00 00 *            Word
24 02 00 00 -            Byte
25 15 00 00 -            Volver
-------------------------------
Como se ve, en este submenú, el ítem seleccionado cuan do se dibuje por vez primera el menú, será el 23 'Word'....
Actualizamos la línea que explica cada ítem:
    item = indice tipo numhijos indexprimerhijo seleccionado texto

Y con esto básicamente podemos definir en texto todoel menú. Ahora la función 'CargarItems', podrá entenderse fácilmente:
Devuelve ´la cantidad de ítems que tiene el menú.

entero = funcion CargarItems 
    entero numItems = 33

    Array de ItemMenu Items(0 a numItems -1)

    Items(0 ) = GetItem("0 8 4 1 -:Menu Raiz")
    Items(1 ) = GetItem("1 8 3 5 -:Edit")
    Items(2 ) = GetItem("2 8 5 8 -:View")
    Items(3 ) = GetItem("3 8 3 28 -:Help")
    Items(4 ) = GetItem("4 15 0 0 -:Exit")
        .
        .
        .
    Items(23) = GetItem("23 02 0 0 *:Word")
    Items(24) = GetItem("24 02 0 0 -:Byte")
    Items(25) = GetItem("25 15 0 0 -:Volver <")
    Items(26) = GetItem("26 01 0 0 *:Digit Grouping")
        .
        .
        .
    Items(32) = GetItem("32 15 0 0 -:Volver <")

    devolver numItems
fin funcion



La función 'getitem' toma un string en el formato 'item' y lo convierte en un elemento de la estructura ItemMenu:
item = indice tipo numhijos indexprimerhijo seleccionado texto


ItemMenu = funcion GetItem(string txtItem)
    ItemMenu im
    array partes(0 a 1) = split(txtItem, ":")  // es necesario porque el texto puede tener más de una palabra.
    array string datos()
   

    datos = Split(parte(0), " ")  // crea un array cortando el texto entrado en tantos elementos como espacios haya entre medias...
   
    im.Indice = datos (0).ParseInteger
    im.Tipo =  datos (1).ParseInteger
    si im.Tipo = MENU_TIPO_TITULO
         im.Hijos = datos (2).ParseInteger
         im.PrimerHijo = datos (3).ParseInteger
    sino
        im.Hijos = 0   
        im.PrimerHijo = 0
    fin si
    Si (datos (4) = "*") im.Seleccionado = TRUE
   
    si im.Tipo = MENU_TIPO_LIMITE
        im.Texto = partes(1)  + " < "
    Sino
        im.Texto = partes(1)       
    fin si

    devolver im
fin funcion


Yendo un poquito más lejos, la función 'CargarItems', podría ser más abstracta, y en vez de reterner ahí el texto del menú, leer un fichero que contiene el texto, se lle una línea de cada vez, esa línea es el índice para el array que se va incrementando, si la línea está vacía se omite y se lee la siguiente (por claridad sería adecuado dejar en un fichero líneas en blanco).
Así dicha función recibe como entrada la ruta del fichero a leer, y cada línea será el contenido de 1 ítem. con esto el códig de un menú prácticamente se puede reusar en otros proyectos sin más cambios que señalar la ruta del fichero que contiene el menú deseado que se debe cargar... Si no se quiere que el fichero esté suelto ante la posibilidad de que un usuario lo elimine, se adjunta como recurso al programa...

Como ya queda un mensaje largo, corto, y a ver si mañana saco otro tiempito para explicar por encima las funciones que manejan el menú.
#1039
bueno, todo depende de como te quieras complicar las cosas...

Una solución efectiva ty rápida es ahcer código espaguetti, resuelve el caso, pero solo el presente caso... cada vez que tengas que crear un menú distinto, tendrás que codificcar.

La solución eficaz es hacer funciones abstractas que relaicen exclusivamente la función que señale su nombre y poco más... un puñado de ellas, satisfacen el menú completo por complejo que sea, la única diferencia en cada ocasión son los datos que reciban en cada ocasión el menú...
Es algo más elaborado, pero a futuro, siempre siempre, resulta ser lo más práctico.

Si tan solo es un ejercicio de práctica, es suficiente con lo que has hecho, si lo quieres para algo más, intenta darle la vuelta a la tuerca que te señalo...

Las cosas seguirían un trazo similar a esto:


(nota los elementos entre corchetes son opcionales, el resto obligatorios)
Lineamenu = columnaleftEspacios foco prefijo textoItem [valor] [sufijo]
columnaleftEspacios = "                    " // 20  espacios por ejemplo, al gusto
foco = ("   "|" > ")          // esto es, si tiene el foco, lleva el '>' si no, su espacio. ocupa 3 espacios.
prefijo = ("   "|" x "|" v ")   // nada, item seleccionado, item seleccionado en un grupo exclusivo (donde solo puede haber 1 seleccionado a la vez 'option/radio button').
textoItem = (A-Z, a-z, 0-9, " ")* string que contiene el texto, lógicamente no vale cualquier longitud... no es preciso limitarlo, se enteiende algo entre 1 y quizás 32 caracteres.
valor = otro texto que viene a la derecha dle texto... mismas consideraciones d etamaño que textoItem
sufijo = ("   "|" > "|"...") // similar a foco, pero aparece a la derecha del todo, básicamente indican: nada, contiene un submenú, se despliega/abre otra ventana con más detalles (puede omitirse este último tratándose de consola)

Así cualquier ítem de un menú lleva siempre una cantidad de espacios fijos a su izquierda (pudiera ser 0, si el menú se alinea completamente a la izquierda), le siguen 3 caracteres para señalar que menú tiene el foco, sabemos que esto se cambia con las flechas de cursor up/down (más tarde volvemos a este dato), luego le sigue el texto del menú, opcionalmente el texto puede tener un valor a su derecha (no es oblgatorio, depende del tipo de menú) igualmente el sufijo final es opcional y depende del tipo de menú, básicamente solo es obligatorio para un menú que qctúe como el 'padre' de un submenú'.




Ahota toca reflejar los datos de un menú en una estructura que refleje todas esas propiedades lo más fiel y claro posible:


Estructura ItemMenu
   byte Fila
   // entero Columna    // no es preciso, se marca solo porque resulta tentador que si tiene fila, deba tener columna. no es necesario.
   byte Indice
   string Texto
   buleano Seleccionado
   // buleano enfocado NO... lo pongo solo por que se note que es tentador poner esto, ese dato no precisa portarlo cada ítem es común a todo el menú.
   TipoMenu Tipo
   entero Hijos
   entero PrimerHijo
fin estructura


Explico un poco por encima que es cada campo y para que puede ser útil:
- Fila: Indica el orden en que se dibujara en el menú cuando se dibuje... típicamente el primero empezará en la línea 1 e irá creciendo, puede llegar a omitirse, si un menú rescrebie al existente actualmente, en cambio es necesario si un menú se superpone a otro existente (para consola, no suele ser éste el caso, pero tampoco estorba).
- Texto: Obvimanete cada ítem de un menú lo más llamativo que tiene es el texto que lo describe brevemente. No puede ser un parrafo, es habitual que tenga un tamaño máximo prefijado incluso que se rellene con espacios si no alcanza ese tamaño... eso es algo que ya decidirás  según veas si lo necesitas o se ve mejor, etc...
- Seleccionado: Hay menús que admiten un estado de selección individual y otros que que admiten un ítem seleccionado dentro de un grupo, otros no admiten un estado de selección. Para esos casos donde se precise señalar que está seleccionado a la izquierda del texto se pondrá una ' x ' (nota que hay 2 espacios rodeándolo, tu luego ya decidirás si basta el de su derecha o ninguno...
- Tipo: Aunque todos los items en principio parecen iguales (texto), lo cierto es que la diferenciación entre ellos favorece el tratamiento funcional  al tiempo que simplifica su operatoria y también facilita al usuario entenderlo, suele verse reflejado en como se ve en el menú, aunque no necesariamente. Después de estas explicaciones vamos a ellos.
- Hijos: Un ítem de un menú puede dar acceso a subítems, luego este actúa como padre para aquellos. Puesto que montaremos todos los ítems en un array (no en una lista enlazada ni árbol), necesitamos dos cosas para esto, saber cuantos son y el índice del primero. Obiamente si un ítem no es padre de ninguno, este valor será 0.
Este valor también sirve para saber cuando no es aceptable que el usuario pulse 'down', pués se sabe cuantos ítems tiene el menú activo, por cuanto son exactamente el número de 'hijos'.
- PrimerHijo: índice dle primer hijo, cuando este ítem actúa como padre. Se entiende que los hijos de un ítem están contiguos en el array, el primero de ellos se localiza, pués en este índice.
- Indice: Técnicamente cada ítem no precisa saber que posición ocupa, es una propiedad reflexiva, a la que se le puede sacar sustancia para simplificar determinadas tareas congorme a un diseño más elaborado... lo pongo solo por que sea una pieza a estudiar cuando termines tu menú para ver como usarlo y sacar provecho, de momento, prácticamente se puede ignorar.
+ No está reflejado pero a veces, puede intenresar tener un IndicePadre, así cada ítem apunta expresamente al al menú padre en el que se aloja. estrictamente no es necesario, porque cierto datos son comunes a todo el menú...




Igual que hay una estructura para cada ítem del menú, procede que el propio menú tenga sus propiedades la más importante y clara es precisamente Items:

No es preciso montarlos en una estructura salvo que haya varios menús bailando en una aplicación y entonces sea preciso diferenciar uno de otro.

// Estructura Menu
   Array de ItemMenu Items(0 a ....los que se precisen) // en realidad es raro que sean más de unas pocas decenas.
   entero foco  // -1 cuando ningún menú se ha desplegado.
   entero IndexMenu
   array de bytes Pila(0 a ...3-5)
// fin estructura

Básicamente eso es lo principal del menú. Ahora toca explicar los campos.
Como ya he señalado , no es preciso ponerlos en una estructura si solo hay un único menú.
- Items: Este campo es lo que he tratado de explicar más arriba..
Un menú habitualmente tiene entre 2 y unas pocas decenas de ítems, por lo que un array suele ser más suficiente para reflejar su estructura, especialmente si el menú no es dinámico (se crean y eliminan ítems a necesidad). Si precisa reflejar de alguna manera los submenús. Mas arriba señalaba qe una pción es indicar el IndexPadre para cada ítem, pero hay otra forma más  simple y que es más breve, consiste en usar una pila de llamadas, tal y como es cualquier pila.
- Pila: Cuando se abre el menú, en la pila se añade el ítem 0, que es el menú padre de todo el menú, este es padre de todos los ítems primarios, supongamos que hay 4 ítems primarios, cuando el usuario pulse en uno de los que entre ellos sean también padre de otros, se abrirá su submenú añadiendo el índice de ese pulsado a la pila, y así sucisivamente, cuando se cierra un menú, se retrocede en la pila y ahí está el padre del menú que debe dibujarse, se ve así que esta sencilla pila que apenas tendrá media docena de elementos, satisface por igual el acceso a las diferentes ramas (al regreso), como si de una lista enlazada o un árbol se tratara, pero con la premisa de que es enormemente más simple y rápido de programar y entender... ese mismo 'padre' es el que tiene el foco cuando se despliegue ese menú.
- foco: Solo es para el menú activo, señala el indice relativo (como hijo). El relativo es para contar las veces que el usuario baja o sube en el menú activo, tambien para cuando se pulsa en un ítem del menú activo, sumado al 'IndexMenu', se sabe que índice absoluto en el array es el ítem pulsado.
- IndexMenu: Es el índice del primer hijo en el menú activo (ya se ha dicho que todos los hijos de un padre son correlativos en el array), pueden por tanto ser ubicado en cualquier parte de un array. Y que será el que se pase (sumaod al foco) a una función 'DibujarSubmenu(Index)', que tendrá por efecto, borrar el menú actual y dibujar los hijos de ese índice.




Lo siguiente es considerar los distintos tipos de menú... cada tipo lleva aparejado un comportamiento más o menos igeramente distinto, conviene listar y denotar ese comportamiento para cada uno.

(ahora mismo tengo que salir, continuó más tarde o mañana si no encuentro el tiempo suficiente hoy)
#1040
Programación C/C++ / Re: Problema con codigo
13 Marzo 2020, 23:55 PM
Cuando consideras un array debes pensar si el array comienza en 0 o en 1...
Si tienes 64 casillas y:
A --- Comienza en 0, entonces el rango es: 0-63, 8 filas x 8 columnas 0-7, 0-7
B --- Comienza en 1, entonces el rango es: 1-64, 8 filas x 8 columnas 1-8, 1-8


No obstantes no es preciso hacer ningún bucle ni menos anidado, para localizar una casilla lineal que posición ocupa en el tablero. Es matemática belemental de un chaval de 12 años o menos...

La elección determina el cálculo...  La siguiente funciona correctamente con 'A':
(es muy fáci adaptarlo al caso 'B', pero lo dejo a tu esfuerzo  :silbar: :silbar: )...

fila = (x \ 8)
columna = (x modulo 8)


Ahora si te exigen un bucle sí o sí, implica que el bucle debe tener un valor... luego procede previamente a la petición de una entrada al usuario asignar en sendos bucles el valor:


bucle para fila desde ini a fin  // ini y fin, tu decides  sin son el par 0-7 ó 1-8
  bucle para columna desde ini a fin   //   ídem...
      matriz(fila, columna) = casilla  // ídem, si empieza en 1, asigna dicho valor a casilla antes del bucle
      // o precede la siguiente línea delante de la asignación.
      casilla +=1
  siguiente
siguiente


Ahora puedes solicitar la usuario el valor 'x'...

Y ahora intentas localizarlo en el array:

bucle para fila desde ini a fin  // ini y fin, tu decides  sin son el par 0-7 ó 1-8
  bucle para columna desde ini a fin   //   ídem...
      Si (matriz(fila, columna) = x)     // ídem, x debe tener las mismas consideraciones de rango: 0-63 ó 1-64
           mensaje: "La casilla" + x + "corresponde a la fila: " + fila + " y columna: " + columna
      fin si
  siguiente
siguiente


Como ves el segundo bucle es casi idéntico al primero, pero a diferencia del tuyo, aquí si se usa el array 'matriz' para ver si contiene el valor buscado, en vez de usar 'comparador', que al caso hubiera sido más útil llamarlo 'contador'...