none
Interfaz gráfica de una calculadora. RRS feed

  • Pregunta

  • Buenos días,

    Mi compañero Iván y yo, Arnau, hemos decidido dedicar nuestro trabajo de final de bachiller a las calculadoras. En este trabajo hemos aprendido a programar en C++ y tenemos bajos conocimientos en C#. Hemos aprendido este lenguaje de programación para programar la calculadora, crear esta en el ordenador con una interfaz gráfica y posteriormente construirla fisicamente. Ahora nos encontramos en la creación de la interfaz gráfica y hemos empezado a utilizar el programa Visual Studio. De aquí la prengunta: Hemos hecho bien en escoger este programa o deberiamos usar otro? En caso de ser otro: cual? Muchas gracias por su tiempo.

    Atentamente,

    Ivan y Arnau.

    PD: Esta no es nuestra única duda, asi que seguiremos posteando mas de ellas relacionadas con el tema. En caso de atraeros el tema podeis notificarme para tratar de una forma más personal y rápida todas nuestras dudas. Gracias de nuevo.

    lunes, 19 de agosto de 2019 12:12

Todas las respuestas

  • hemos empezado a utilizar el programa Visual Studio. De aquí la prengunta: Hemos hecho bien en escoger este programa o deberiamos usar otro?

    Visual Studio es una excelente eleccion. Es una herramienta potentisima para desarrollo de aplicaciones, desde escribir la interfaz de usuario hasta escribir, probar y depurar el codigo asociado a ella.

    Presumo que el tipo de aplicacion que teneis en mente es UWP, a juzgar por el foro en el que pusisteis la pregunta. Lo digo porque tambien hay otras alternativas que se pueden desarrollar desde Visual Studio, tales como aplicaciones clasicas de tipo WinForms, aplicaciones WPF, aplicaciones Web, aplicaciones para dispositivos moviles (Xamarin), etc. Cada una de ellas usa mecanismos y tecnicas diferentes para desarrollar la interfaz grafica y escribir el codigo que interactua con ella, por lo que es importante elegir desde el principio el tipo de aplicacion.

    lunes, 19 de agosto de 2019 12:31
  • En un principio, para empezar a trabajar la interfaz gráfica hemos optado por lo que seria WinForms ya que no tenemos en mente que sea una UWP. He publicado en este foro el post dado que los asistentes de Windows me recomendaron hacerlo aquí. Es acertado utilizar WinForms? Hemos sido capaces de programar en esta aplicacion hasta operaciones basicas que incluyan dos numeros y un operador pero queremos ir más lejos y tocar operaciones más complejas donde se incluyan encadenaciones de operaciones e incluso parentesis. Dado que ahi la programación se nos escapa ya que, tras tratar de programar este tipo de problema matematico con vectores y con matrices, no hemos conseguido obtener un resultado operativo, es decir, que funcione como es debido. De ese inconveniente decidi contactar con windows ya que ellos tienen una calculadora con parentesis y todo y ellos me redirigieron aqui.

    En definitiva, WinForms es adecuado para el desarrollo de la calculadora? Nos recomiendas alguna otra opcion?; A nivel de programacion, algun consejo para la encadenacion de operaciones y los parentesis?

    Gracias,

    Iván y Arnau

    • Marcado como respuesta ArnauIván lunes, 19 de agosto de 2019 21:10
    • Desmarcado como respuesta ArnauIván lunes, 19 de agosto de 2019 21:10
    lunes, 19 de agosto de 2019 21:06
  • En definitiva, WinForms es adecuado para el desarrollo de la calculadora?

    Sí, es perfectamente adecuado. Winforms es el tipo más "clásico" de aplicación de escritorio. Hace muchos años que existe y es muy estable y bien conocido. Y desde luego, soporta toda la funcionalidad que puede ser requerida por la interfaz de una calculadora.

    A nivel de programacion, algun consejo para la encadenacion de operaciones y los parentesis?

    Utilizad una pila ("Stack"). Según se introducen nuevos niveles de cálculo en la interfaz (determinados por los paréntesis o por la prioridad de operadores, si es que la vais a aplicar), se va empujando a la pila (Push) cada nuevo valor que interviene en el cálculo, y cuando se alcanza un operador que resuelve un cálculo, se saca el resultado anterior (Pop) y se calcula la operación y se vuelve a empujar a la pila. Al final de todos los cálculos, el (único) valor que quede en la pila es el resultado final.

    martes, 20 de agosto de 2019 5:54
  • Entonces a lo que te refieres es a que vayamos añadiendo a una pila los numeros y operadores del cálculo (con el push) hasta que el usuario presione la tecla =, y entonces sacar (con el pop) todo lo de dentro de la pila, hacer el cálculo y mostrar el resultado no?

    Si es así, al poner parentesis en la pila y luego extraerlo, se detectaria directamente la prioridad de operacion o se habria de crear una segunda pila para el calculo interior del parentesis?

    Entiendo el uso que tiene y a lo que te refieres pero no consigo cuadrarlo con el uso del parentesis. Por lo que he entendido, iriamos introduciendo en una pila numeros, operadores y parentesis para proximamente extraerlo todo y hacer el calculo que nos llevara al resultado (y vaciando la pila evidentemente para calculos posteriores).

    martes, 20 de agosto de 2019 17:57
  • Por lo que he entendido, iriamos introduciendo en una pila numeros, operadores y parentesis para proximamente extraerlo todo y hacer el calculo

    No, los paréntesis no se introducen en la pila, y los operadores tampoco. Solo se introducen números en la pila. La presencia de paréntesis sirve para decidir si hay que pasar el resultado a la pila o hay que ejecutar un opeador.

    Por ejemplo, imagina esta secuencia de operaciones:

    ( 1 + 2 ) * ( 3 + 4 )

    Se resuelve así:

    • Meter 1 en la pila.
    • Llamar a la subrutina "sumar".
    • La subrutina lee un nuevo operando, y lo suma a lo que haya en la pila, empujando el resultado a la pila.
    • Llamar a la subrutina "multiplicar".
    • La subrutina lee un nuevo operando, lo multiplica por lo que haya en la pila y el resultado pasa a la pila.
    • Al no haber más datos, se saca lo último que haya en la pila y se presenta como resultado.

    Observa la parte en negrita. "Lee un nuevo operando" es una llamada recursiva al mismo código que estábamos ejecutando, que leerá la parte de (3+4), la ejecutará y dejará el resultado en la pila.

    Así explicado parece complicado, pero se resuelve con sencillez si dibujas los diagramas sintácticos y vas metiendo una subrutina por cada diagrama y un "if" por cada bifurcación. Tienes un ejemplo sobre cómo se usan esos diagramas y el código que los interpreta aquí:

    https://www.scribd.com/document/23194492/Como-crear-un-interprete-de-expresiones-en-NET

    Aunque ese artículo lee la expresión de golpe desde una cadena, se puede adaptar para que los caracteres se vayan leyendo uno por uno desde el teclado de la calculadora.

    martes, 20 de agosto de 2019 18:30
  • No acabamos de entender el funcionamiento al 100% pero se solucionara a base de ponerlo en práctica. Una vez hayamos leído el artículo de los diagramas y intentarlo, en caso de que aun queden dudas, volvere a responderte con estas. Una ultima pregunta, la utilización de la pila resuelve tanto parentesis como priorizacion de operadores o solamente uno de estos.

    Gracias por todo de antemano,

    Iván y Arnau

    miércoles, 21 de agosto de 2019 10:57
  • Sí, con el mecanismo propuesto se requelven las dos cosas. Por ejemplo, si introduces 1+2*3+4 el programa lo interpreta como 1+(2*3)+4 porque la multiplicación tiene prioridad respecto a la suma. Por supuesto, esto lo puedes cambiar si usas diagramas distintos; este es el comportamiento que tienen los que hay en el ejemplo que te enlacé.
    miércoles, 21 de agosto de 2019 11:36
  • Buenas de nuevo,

    Tenemos una nueva duda que trata lo que vienen a ser las constantes pi y e. Cuando hacemos double.Parse sobre la pantalla de la calculadora para pasar el numero pi escrito (aun en string) a numero esta genera un error ya que parece no ser capaz de cambiar la clase de π a numero. Hay alguna solución a este problema?

    Gracias,

    Iván y Arnau

    PD: Hemos dejado un poco de lado lo de priorizar operaciones y el tema de los paréntesis por el momento. En caso de tener alguna duda volveré a contactar contigo. Mil gracias de nuevo por toda tu ayuda ;D

    miércoles, 4 de septiembre de 2019 16:00
  • Cuando hagas estas preguntas tienes que detallar mejor qué es lo que estás haciendo, porque sino es muy difícil responder. Cuando hablas de hacerle un double.Parse al número escrito, ¿cómo está escrito? ¿qué es lo que hay en el string? ¿Pone 3.1415926535? ¿o es 3,1415926535? ¿o pone "pi"? ¿o pone "π"?

    Si es uno de los dos primeros casos, el problema estaría en la coma o punto, que no coincide con el valor predeterminado del CurrentCulture, y se resolvería pasando como argumento un CultureInfo al double.Parse. Pero si es uno de los otros dos, entonces no, no hay manera de que el doube.parse lo entienda. Lo tendrás que verificar tú metiendo un "if" (o un switch) que compare el valor del string.

    miércoles, 4 de septiembre de 2019 17:12
  • Buenas de nuevo,

    Hemos decidido retomar el encadenar operaciones con nuestra calculadora y, a pesar de entender como funciona (almacena la ultima posición leída, operador y numero en diferentes variables y según lo que encuentra lo pushea en la pila o simplemente lo opera con el siguiente). La programación para reconocer los operadores se nos escapa y no conseguimos cuadrarla además de no conseguir entender cuando pusheamos la pila o popeamos un valor en ella para operar con otro.

    En definitiva, conceptualmente lo entendemos pero a la hora de programarlo y darle funcionalidad no somos capaces de hacerlo. Cuando introducimos valores en la pila? Cuando los popeamos? Como funciona intérprete de expresiones?

    Gracias,

    Iván y Arnau

    miércoles, 18 de septiembre de 2019 18:54
  • Tras releer el artículo por cuarta vez con calma y delicadamente he comprendido al 90% su funcionalidad. Cosas como enum, this. y regex no las entiendo aún y por eso escribo este mensaje. Comprendo como mira si el último valor (que va augmentando de 1 en 1) es un factor (parentesis o la variable en ese programa) en caso de no hacerlo hace una especie de return (una de las cosas que no entiendo) a la comprovación de si es un término (*o/) y finalmente en caso de no ser así comprueba si es (+ o -). Hasta ahí bien. Lo que no consigo entender es luego si es capaz de priorizar un 4+5*6 dado que si lee el mas automáticamente pasa a 9*6.

    En definitiva, no acabo de entender esos tres conceptos de programación, si consigue dar la priorización adequadamente y como retorna al void anterior tras comprovar en otro que el valor no esta.

    Siento haber sido tan poco específico en el mensaje anterior.

    Gracias,

    Iván y Arnau

    sábado, 21 de septiembre de 2019 10:01