A veces llega algún usuario, al que resulta extremadamente difícil de ayudar, por varias razones...
- La primera es porque tiene conocimientos excesivamente sesgados (de algunas cosas parece tener cierto conocimiento y de otras cosas simples, lagunas completas).
- Quieren que las cosas se ajusten a su modo de hacer, cuando lo inevitable que es que para algo existente sea 'el nuevo' el que deba adaptarse a lo que hay.
- Insisten en lo que creen entender, sin meditar las respuestas que se les dan... pasan por encima (si es que las leen), como aquel que pisa una alfombra que está ahí para ser pisada.
- Muchas más razones, pero no quiero extenderme, ni tampoco pretendo que nadie se sienta ofendido...
El caso es que tú encajas en este tipo de usuarios, donde la dificultad, no radica en lo que se pide (que es relativamente fácil) si no en hacer entender lo que se dice...
Es como dar las respuestas correctas a alguien que luego tomará tu texto, lo traducirá al chino, luego al hebreo, luego al latín luego al ruso, luego al inglés, luego al estonio, luego al portugués y al final de nuevo al español, para luego intentar digerirlo... se perderá todo el sentido tras tanta traducción, siempre sucede de un idioma a otro, luego cuantas más atraviese, más distancia existirá entre el original y la traducción final, de hecho puede que al final, no tenga nada que ver con el original y hasta haya dificultades para saber qué tema trataba.
Intentaré por última vez, arrojar un poco de luz en tu oscuridad y me conformaré solo con que intentes entenderlo, sin más pretensiones, que luego avances a partir de ahí o sigas en tu luna es cosa tuya...
1 - Los paréntesis también son operadores (no los ignores). Igual que '+' es para una operación aritmética y 'and' para una operación lógica, un paréntesis aplica una operación de 'prioridad' (orden de ejecución).
Es una lástima que en prácticamente ningún lenguaje se describa así... como un operador de prioridad. Quizás porque todo parte de un cuerpo matemático, en el que se da por sentado que todo el mundo que pretende aprender algo de programación tiene al menos una base matemática mínima... o dicho de otro modo, que no se considera necesario explicarlo porque se da por sobreentendido.
2 - Es bueno aprender (en realidad si uno estudió, recordar, porque es algo que puede olvidarse), el significado de las propiedades (conceptos mtemáticos): distributivas (que reparten), conmutativas, asociativas (que conecta, que lo une...). Explicadode forma matemática puede llegar a entenderse, o puede ser complejo si se le da todo el cuerpo matemático lleno de término que quien lo oye también desconoce...
Una sencilla forma de entenderlo, es que en programación los operadores lógicos cumplen dichas funciones, y particularmente resultan mucho más fácil de entender (el cuerpo matemático, al final solo es entendible por otros matemáticos, a causa de la excesiva jerga verborreica que se emplea sin ton ni son, ni tregua de ningún tipo en las matemáticas (no en todas partes eso sí), en programación hay cierta licencia, gracias a que hay muchos programadores que son autodidactas.
Tampoco se puede caer en 'describo todo con mi propio lenguaje', porque entonces no nos entenderíamos. Habría tantas formas de llamar a algo como personas y eso tampoco puede ser... ambos extremos incurren en ineficacia.
3 - Los paréntesis... tu pelea.
Cualquier lenguaje por miserable que sea, admitirá paréntesis para resolver la precedencia de operadores (debe importarte nada que un operador sea 'or', 'and' ó '+', '/', o cualquier otro... un operador es un operador sea del tipo que sea y a tí debe bastarte con saber que como tal cualquier operador tiene un valor de precedencia (prioridad en ser resuelto cuando no tiene paréntesis que lo delimite)
Si es tan simple como dices, entonces bárbaro, pero yo no sabía y antes de hacer la prueba menos.
De hecho había planteado este tema a un programador que conozco y me dijo que la interpretación dependía del lenguaje, que no había una respuesta única. Tú mismo también me preguntaste por mi lenguaje como si fuese relevante.
Para ayudarte a entender mejor los paréntesis, voy a partir de exponer un ejemplo práctico asequible de entender para todo el mundo, y luego desde ahí, hacer una traslación al asunto programático, y espero que entonces (al menos), acabes de otorgarle la importancia que merece... y por lo tanto aplicarlo, en vez de querer matarlo (obviarlo).
Mira de construir tu árbol genealógico (basta con 10-20 nombres, es suficiente para darte la idea): Podrás escribir tu nombre y al lado, el de tus hermanos, y encima el de tus padres... tu padre y tu madre también tendrán (se supone) hermanos, luego procede ponerlos, a su vez también cada uno de ellos tendrán ó tuvieron su padre y madre respectivamente...
No importa cuan detallado sea el árbol genealógico, puedes imaginártelo elaborado con flechitas, o mas prosaico en columna, algo similar a esto:
Pedro Eva
Juan Rosa
Fermin Raquel
Antonio
Rosa Fernando
Felipe
Luis Encarna
Daniel Sara
Enrique
Daniela Fabian
Rosa
Joaquin
Evaristo
Maria
Andres Rocio
Ana Martin
Luis
Antonio
Marta Rafael
Ines
Francisco
Miguel Maria
Sonia
Miguel
Felipe
Como se puede entender de un simple vistazo, bajo cada pareja yacen los hijos que tienen, los 'casados' nuevamente tienen pareja, y si tienen hijos bajo ellos aparece la lista.
Veamos como queda si los ponemos en línea:
Pedro Eva Juan Rosa Fermin Raquel Antonio Rosa Fernando Felipe Luis Encarna Daniel Sara Enrique Daniela Fabian Rosa Joaquin Evaristo Maria Andres Rocio Ana Martin Luis Antonio Marta Rafael Ines Francisco Miguel Maria Sonia Miguel FelipeSe pueden poner en columna igualmente:
Pedro
Eva
Juan
Rosa
Fermin
Raquel
Antonio
Rosa
Fernando
Felipe
Luis
Encarna
Daniel
Sara
Enrique
Daniela
Fabian
Rosa
Joaquin
Evaristo
Maria
Andres
Rocio
Ana
Martin
Luis
Antonio
Marta
Rafael
Ines
Francisco
Miguel
Maria
Sonia
Miguel
Felipe
¿Eres capaz en esta lista de determinar quienes son los hijos de quién?. Imposible... Incluso basado en la idea de que detrás de un hombre aparece su pareja (y viceversa), no hay ningún indicador de relación, podría ser hermano y hermana o hermana y hermano....
En cambio, fíjate como en el árbol jerárquico, no hay lugar a dudas quien es hijo de quien.
Bueno, esta lista de nombres equivale a 'tus' expresiones, y la lista jeráquica a una expresión expresada con paréntesis... luego vuelvo a esto... ahora otro ejemplo, de naturaleza más cercana a la programación...
Mira el menú de la calculadora (de win2). Este es su menú (te lo pongo en inglés):
(Menu)
Edit
Copy
Paste
View
Standard
Scientific
-
Hex
Decimal
Octal
Binary
-
Qword
Dword
Word
Byte
-
Digit Grouping
Help
Help topics
-
About Calculator
Nuevamente puede verse con claridad, que ítems están bajo que otros ítems.
nota: Los ítems Qword... aparecen si se seleccionó: binary, Octal ó Hex, si se elige Decimal aparece Grados, Radianes...
Pongámoslo en columna sin indentacion (o en línea da igual):
Menu
Edit
Copy
Paste
View
Standard
Scientific
-
Hex
Decimal
Octal
Binary
-
Qword
Dword
Word
Byte
-
Digit Grouping
Help
Help topics
-
About Calculator
Igualmente cuando se ponen en columna son una lista sin concierto, todos al mismo nivel son hijos de... pero no se oberva ninguna relación más entre ellos, todos del mismo orden.
Se puede mejorar aún el menú jerárquico a base de poner indicadores de inicio y fin... en muchos menús (la mayoría) no se ponen porque al ocupar espacio, aumenta el área visible que ocupan...
...dando algo con sentido que solo inicio, podría ser algo como esto:
Menu
Edit
Portapapeles
Copy
Paste
Fin menu
View
Modelo
Standard
Scientific
Fin grupo
Base numérica
Hex
Decimal
Octal
Binary
Fin grupo
Tipos de datos
Qword
Dword
Word
Byte
Fin grupo
Otros
Digit Grouping
Fin grupo
Help
Ayuda
Help topics
fin grupo
Autoria
About Calculator
Fin grupo
Fin menu
Igualmente podemos proceder con el árbol genealógico, encabezando el padre, y debajo indentado los hijos y terminando con el nombre de la madre (precedido por ejemplo por 2 puntos), a modo de: fin grupo - fin menú.
Si encabeza un hombre, él es el hijo, y por tanto la mujer que cierra los hijos es su cónyuge, en cambio si la lista encabeza por una mujer, es la mujer la descendiente de la familia, y quien cierra la lista de hijos será el hombre, su cónyuge. Si no tienen hijos, solo aparece el nombre del cónyuge...
...a reconstruir el árbol de esta manera:
Pedro
Juan
Fermin
:Raquel
Antonio
Rosa
:Fernando
Felipe
:Rosa
Luis
Daniel
Enrique
Daniela
Rosa
Joaquin
:Fabian
Evaristo
:Sara
:Encarna
Maria
Andres
:Rocio
Ana
Luis
Antonio
Marta
Ines
Francisco
Miguel
Sonia
Miguel
Felipe
:Maria
:Rafael
:Martin
:Eva
Ahora puede parecer un poco más lioso de verlo pero al programarlo se podrá buscar recursivamente, mientras esté un nivel más abajo (a la derecha), es hijo. Mientras se mantiene el nivel se suma, cuando cambia el nivel, si sube se hace otra llamada, como padre el actual, los que se devuelvan serán sus hijos, si baja un nivel, se devuelve la cantidad de hijos -1 (se terminó de contar y el último erá el cónyuge).
Bien, todo esto parece no tener nada que ver con tu problema, pero no es así... pese a quien pese y pese a que muy poca gente lo perciba, las expresiones son árboles jerárquicos... en cambio tus expresiones son solo listas...
Vamos a demostrarlo...
z= A + 3 * 5 - B + W / 5 AND T - 2 + X OR P OR H
Podemos obviar los operadores (nos quedamos con los identificadores y las constantes numéricas)y pongámoslos en columna:
Z
A
3
5
B
W
5
T
2
X
P
HComo se ve es una lista plana, todos al mismo nivel, todos 'hijos' de un supuesto padre... como tus expresiones.
Añadamos paréntesis.... y veremos que pasa...
Supongamos que esta fuera la exresión:
Z = (A + 3) * ((((5 - B) + W) / 5) AND ((T - 2) + X) OR (P OR H))
Ahora pongámoslo en vertical jerárquico (obviando también los operadores, excepto los paréntesis):
Z (
A
3
)
(
(
(
(
5
B
)
W
)
5
)
(
(
T
2
)
X
)
(
P
H
)
)
Et voilá, eliminando los operadores, esto es dejando el único que al caso importa, puedes ver que subyace una jerarquía... la apertura de paréntesis y cierre delimitan la propia jerarquía, el orden de ejecución... el últérrimo hijo de la descendencia, es el primero que debe ser resuelto, luego el padre, luego el abuelo, etc...
Espero que ahora veas claramente adonde lleva no usar paréntesis. Su uso cordina, da sentido específico...
Igual que si indentas un hijo en otra parte supone que les estás asignando un padre distinto (hijo de su hermano, o nieto, o tío de su hermano, o abuleo de su hermano y padre dle suyo propio), del mismo modo colocar un paréntesis en sitio equivocado cambia el sentido (y el resultado) de la expresión... y del mismo modo que un nieto siempre tendrá padres, es adecuado que ciertos operandos estén entre paréntesis... si deben ejecutarse antes.
También se puede ver que un arbol jerárquico puede ser expresado en línea, y mantiene plenamente su sentido, siempre y cuando sea 'canonizado' con cierres y aperturas, que es lo que hemos hecho anteriormente con el menú de la calculadora y con el árbol geneálogico.
Iguala tu expresión a la lista genealógica, sin pies ni cabezas, sin saber quien es padre y quien es hijo.
Te decía en otro mensaje más arriba, que otra forma es separar una expresión en las subexpresiones que las componen, de modo que sean simples... pero eso da bastante trabajo y tampoco limita la posibilidad de error por confusión...
Observa la genealógica:
Pedro Juan Luis Maria andres Ana Eva
El primer cónyuge es el que aparece en primer lugar, el otro cónyuge el último y en medio los hijos.
Pedro Juan Luis Maria andres Ana Eva
Juan Fermin Antonio Rosa Felipe Rosa
Fermin Raquel
Antonio
Rosa Fernando
Felipe
Luis Daniel Encarna
Daniel Enrique Daniela Evaristo Sara
Daniela Rosa joaquin Fabian
Maria
Andres Rocio
Ana Luis antonio Marta Martin
Luis
antonio
Marta Ines Francisco Miguel Rafael
Miguel Sonia Miguel felipe Maria
Es decir desmontando cada expresión con su propios términos, no requiere paréntesis, pero puedes ver como crece la cantidad de expresiones. Una vez resueltas las subexpresiones, pueden volver a crearse nuevas expresiones con los resultados previos... hasta llegar a la raíz (la asignación en programación).
La otra forma como ya he expresado varias veces es la notación polaca (no 'el polaco', ni 'en polaco', no es un idioma notación quiere decir "forma, sistema que se usa para expresar conceptos más o menos abstractos", el tipo que lo ideó era polaco, eso sí...).
Usando la notación polaca, no es ni más ni menos que para poder hacer los cálculos ya directamente sin tener que volver a buscar el orden... losd compiladores lo usan, porque al compilar, lo hará de tal forma que la expresión se vaya ejecutando (correctamente) avanzando hacia adelante, sería una caída de rendimiento si tras compilar, cada vez que se evaluara una expresión tuviera que localizar el orden para ejecutarla correctamente... el compilador lo hace una vez y cuando de traduzca a código máquina, ya estará listo, no requiere posterior toqueteo, solo ejecutar...
Resumiendo, no puedes vivir sin paréntesis, la notación polaca primero debes dominarla, pero si te cuesta entender los paréntesis, no es el momento de intentar profundizar en dicha notación...
Yo creo que tendría que hacer lo inverso: Que el programa genere expresiones en polaco y luego las transforme a normal sin paréntesis. Porque el problema que quería evitar es que las generadas tengan paréntesis, porque no sé cómo hacer eso bien
...
Porque quiero que las expresiones las genere un programa. Hacer que genere Variable1 Comparador1 Variable2 Operador1 y así todo lo que quiera, es fácil, pero si quisiera hacer que ponga paréntesis por ahí no tengo mucha idea
Es que no sé para que lo necesitas... por lo que alcanzo a entender de como te explicas es que tienes alguna función que 'genera' operandos y operadores (ignoro si al azar o si basado en algo específico)... entonces dado lo poco que he leído respcto de lo que intentas hacer, intuyo que tu programa también debe generar los paréntesis, porque como ya te señalé en el punto 1, y como me he extendido en explicaciones a lo largo de la respuesta, son operadores de prioridad, o si quieres jerárquicos (si se entiende como un árbol), cada paréntesis de apertura aumenta (profundiza) la jerarquía y cada cierre la reduce...
Nota como todos los lenguajes tiene términos o símbolos cuyo único objetivo es precisamente jerárquico, abrir o cerrar expresiones, anidamientos, etc... en C por ejemplo, un comedero de cabeza para los principantes es olvidarse de terminas las expresiones convenientemente con ';' en la mayoría d lenguajes, el salto de línea es un indicador explícito de fin de una expresión, en C, una expresión continua en varias líneas hasta qwue encuentre dicho símbolo... (el punto y coma). Cada lenguaje tiene su propia convención, pero tiene dichos delimitadores...
Acordate además que cuando inicié este tema ni siquiera sabía eso del orden de procedencia o sea que para mí era un lío mayor que ahora.
Espero que con los ejemplos explícitos que te he expuesto más arriba, puedas finalmente entender la utilidad de la prioridad, la relación de 'inclusión, pertenencia o jerarquía (es todo lo mismo visto bajo diferente prisma). si para una expresión puede ser complejo entenderlo, en cambi sobre un menú, o más cercano un árbol genealógico, es imposible no entender que si no se define debidamente donde empieza y termina los hijos, la confusión es total... Aquí se ha seguido una forma simple y luego la hemos canonizado (se llama canonizar a no omitir nada aunque sea 'sobreentendido', por ejemplo canonizar la frase 'Trabajo el martes', sería: No trabajo el lunes, trabajo el martes, no trabajo el miércoles, ni el jueves, ni el viernes ni el sábado ni el domingo). los hijos quedan encerados en un nivel (+1) indentado entre el padre y la madre, en realidad, los 2 puntos se pueden omitir, si hay indentación el siguiente que aparezca en el mismo nivel será el cónyuge, pero por claridad a veces conviene añadir símbolos, así de un simple vistazo, se acota rápido... (es decir por comodidad 'humana', no estrictamente necesario matemáticamente hablando).
Hay 3 tipos de notaciones básicas:
Notación de infijo (o normal): Las que solemos usar, porque las entendemos bién al 'leerlas', los operadores aparecen a ambos lados y el operador en medio.
Ejemplos: A + B; (A*B)+(C-(D*E)) <-- nota que los ejemplos son los mismos para los 3, para que veas las diferencias).
Notación de prefijo (o polaca): Los operadores van delante, los operadores detrás.
Ejemplos: +AB; +*ABC-*DE
Notación de sufijo (o postfijo, inversa):Los operandos van delante, los operadores al final.
Ejemplos: AB+; AB*C+DE*-
Lo decía por:...
Ok, sí. Lapsus mío, pero se deduce que si hay tres espacios y he señalado el centro, y un lado, el del lapsus será el otro lado. No tiene más importancia.
XOR no es más complejo que OR ni AND, sino a su mismo nivel...
Tabla de verdad de XOR
----------------------------
0 xor 0 = 0
0 xor 1 = 1
1 xor 0 = 1
1 xor 1 = 0
En resumen es TRUE si solo una de ellas es TRUE. Si se aplica a más de 2 operandos es TRUE, si el número de evaluaciones TRUE es impar, FALSE si son pares...
1 xor 1 xor 1 xor 1 = 0 (4 unos, son pares luego = FALSE)
1 xor 1 xor 1 xor 0 = 1 ( 3 unos, son impares luego es = TRUE)
XOR te puede ahorrar muchas comparaciones..
Me parece más difícil de entender que los otros operadores, pero con lo último que dices tendré que ver.
No creas, es cuestión de práctica...En realidad suple a esta otra expresión:
Z = (Not(A) or B) and (A or Not(B))
Imagina que tienes un un valor para activar y desactivar algo.
Si quieres encenderlo harías algo como:
Si quieres apagarlo:
Pero si simplemente quieres poner el estado opuesto, puedes poner:
Enabled = Enabled xor TRUE
En realidad equivale a:
...pero ojo, el not es válido solo porque estamos trabajando con un valor buleano... un valor buleano es un valor donde todos sus bits se comportan como si fueran un único bit.
En cambio si tienes un valor que noe s buleano, el resultado de XOR y NOT, es muy disitnto... con NOT invierte cada bit por el contrario, con XOR solo se invierte si el bit aparece una sola vez (en A o en B)
Not(0011.1010 ) = 1100.0101
0011.1010 xor
1010.1101
-----xor------
1001.0111
Como se ve da un valor muy distinto a los operandos de origen... Xor en realidad es muy interesante se comporta como una suma o como una resta, según el valor de ambos operandos...
Con práctica y tiempo, que consigas entenderlo bien, XOR se volverá un 'amigo invalorable'...