Si las ecuaciones de segundo grado son un problema clásico de las Matemáticas, también lo son, sin duda, de la Programación. Su resolución se trata de un ejercicio ideal para aquellos que están comenzando a programar, pues implica entrada de datos por teclado, salida por pantalla, cálculos aritméticos y condicionales. ¿Quieres conocer la manera de resolver ecuaciones de segundo grado en Python? Te lo cuento de manera detallada en este artículo.
Suponiendo la ecuación ax² + bx + c = 0:
- Calcula el discriminante:
disc = b * b - 4 * a * c
- Si
disc
es negativo la ecuación no tiene solución - Si
disc
no es negativo, calcula su raíz:raiz = srqt(disc)
- Calcula las soluciones:
x_1 = (-b + raiz) / (2 * a)
yx_2 = (-b - raiz) / (2 * a)
A continuación te cuento paso a paso la manera de resolver ecuaciones cuadráticas parándome en cada detalle para que lo entiendas a la perfección.
Obteniendo los valores de los coeficientes
El primer paso es obtener los valores de los coeficientes. Si bien es cierto que en una aplicación real en la que se necesitase resolver ecuaciones de segundo grado estos coeficientes provendrían de ficheros, bases de datos o de otros módulos de cálculo, en este ejemplo vamos a obtenerlos directamente del usuario, a través del teclado.
Para obtener un valor proporcionado por el usuario puedes utilizar la función input
, que se queda esperando a que el usuario introduzca un valor y pulse la tecla enter. El valor proporcionado por el usuario lo devuelve la función como una cadena de texto que solo tenemos que convertir a número decimal mediante la función float
.
En este caso tendremos que pedir al usuario tres valores, pues tres son los coeficientes que se manejan en una ecuación de segundo grado que, como sabes, tiene la siguiente forma: ax² + bx + c = 0
, siendo x
la incógnita a calcular y a
, b
y c
los coeficientes.
Ten en cuenta que la ecuación de segundo grado no está definida si el coeficiente a
es 0, por lo que podemos asumir que el valor de dicho coeficiente siempre será diferente de 0.
Es posible, además, que el usuario no introduzca valores numéricos cuando se le pidan. Esto sería algo que habría que comprobar en nuestro programa para evitar que se rompa la ejecución del mismo. No lo voy a contar aquí para no hacer este artículo demasiado largo, pero te explico en otro cómo pedir un valor al usuario hasta que sea válido. Siguiendo las indicaciones de dicho artículo podrías comprobar tanto que el coeficiente a
es diferente de 0 como que los valores introducidos son de tipo numérico.
Así, para este programa vamos a suponer que el usuario siempre introduce valores correctos para los coeficientes a
, b
y c
. La manera de solicitarlos sería la siguiente:
a = float(input('Dame el valor del coeficiente a: '))
b = float(input('Dame el valor del coeficiente b: '))
c = float(input('Dame el valor del coeficiente c: '))
Este código muestra por pantalla el mensaje pasado por parámetro a la función input
y se queda esperando a que el usuario introduzca un valor. Una vez es recibido el valor, input
lo devuelve y acto seguido es convertido a tipo float
con la función del mismo nombre y asignado a una variable.
Si te fijas, este código es un poco repetitivo así que vamos a hacer uso de distintas características de Python para evitar dicha repetición. Esta parte es opcional así que si quieres, puedes continuar con el siguiente apartado en donde empezamos a hacer cálculos, pero ten en cuenta que más adelante, donde te presento el código completo hago uso de estas optimizaciones.
Para mejorar este código voy a utilizar las características de comprensión de listas y de desempaquetado.
La compresión de listas nos permite crear una lista de valores, que en nuestro caso serán los tres coeficientes, mediante un bucle de manera muy sencilla en una sola línea. Por otro lado, el desempaquetado nos permitirá sacar los valores de la lista generada y almacenarlos directamente en tres variables.
Te cuento cómo funciona la comprensión de listas en estos dos artículos que tratan sobre el uso de paréntesis, corchetes y llaves en Python y sobre cómo filtrar listas en Python.
Así, puedo generar una lista con tres valores (los tres coeficientes) mediante el siguiente código:
[float(input(f'Dame el coeficiente {coef}: ')) for coef in ('a', 'b', 'c')]
En el código anterior recorro con un bucle for la tupla ('a', 'b', 'c') haciendo un llamada a input
(y su correspondiente llamada a float
) para cada uno de sus valores. Finalmente, los valores obtenidos se almacenan en la lista gracias a la comprensión (fíjate en los corchetes [
y ]
que rodean toda la sentencia.
Te envío todos los días un consejo para que cada día seas mejor en Python.
Siempre sobre Python y programación.
Más de 2500 personas como tú los reciben cada día.
Día que estás fuera, consejo sobre Python que te pierdes.
Antes de suscribirte consulta aquí la
Finalidad de recogida y tratamiento de datos personales: enviarte boletín informativo de Python y comunicaciones comerciales.
Legitimación: tu consentimiento.
Destinatarios: no se ceden a terceros. Los datos se almacenan en los servidores de marketing (GetResponse).
Derechos: podrás ejercer tus derechos de acceso, rectificación, limitación y supresión de datos en info @ codigopiton.com así como presentar una reclamación ante una autoridad de control.
Más información: política de privacidad, encontrarás información adicional sobre la recopilación y el uso de tu información personal.
Ahora es el turno del desempaquetado. Te hablo del desempaquetado de listas, y en general de iterables, en este otro artículo sobre el uso de asterisco * y doble asterisco ** en Python.
Así, si por ejemplo realizo lo siguiente a, b, c = [1, 2, 3]
, es fácil ver que los valores 1,2 y 3 irán a parar respectivamente a las variables a
, b
y c
y en este orden.
Combinando ahora las dos instrucciones anteriores, podemos obtener del usuario los tres coeficientes para nuestra ecuación sin necesidad de repetir código y en una única línea (eso sí, asumiendo, al igual que antes, que los valores introducidos por el usuario serán válidos):
a, b, c = [float(input(f'Dame el coeficiente {coef}: ')) for coef in ('a', 'b', 'c')]
Podríamos, simplemente, quedarnos con la lista y seguir trabajando con los valores almacenados en ella, pero el código resultaría más difícil de leer y menos intuitivo.
Calculando el discriminante
Una vez que tenemos lo valores ya podemos empezar a hacer cálculos. La manera universal de resolver ecuaciones de segundo grado pasa por aplicar la llamada fórmula de Bhaskara que tiene este aspecto:
Si te paras a analizarla puedes ver que hay que calcular la raíz cuadrada de la expresión b² - 4ac
. La raíz cuadrada no está definida para números negativos. Por este motivo, si dicha expresión, que llamaremos discriminante, es un valor negativo, la raíz no se puede calcular y la ecuación de segundo grado no tiene solución real (aunque sí la tiene en el dominio de los números complejos que se escapa del ámbito de este artículo).
Esta es una situación con la que tenemos que lidiar, por tanto, lo primero que debemos hacer es calcular el valor del discriminante, cosa que hacemos de manera muy sencilla:
discriminante = b * b - 4 * a * c
El cálculo del cuadrado de un valor es muy sencillo de obtener multiplicando dicho valor por sí mismo. Así, si queremos obtener el valor de
b
al cuadrado, es decirb²
, podemos hacerb * b
, como puedes ver en el código anterior.Python también dispone de un operador para calcular potencias que es el doble asterisco
**
, de forma que también podrías calcular el cuadrado deb
de la siguiente manera:b ** 2
.
Ecuaciones de segundo grado sin solución
Como te acabo de contar, hay ecuaciones de segundo grado que no tienen solución, cosa que sucede cuando el discriminante es negativo.
Es necesario realizar esta comprobación que, en caso de cumplirse, nos obligará a mostrarle al usuario un mensaje de error indicándole que la ecuación proporcionada no tiene solución.
Esto se hace de manera muy sencilla con un condicional:
discriminante = b * b - 4 * a * c
if discriminante < 0:
print('La ecuación no tiene solución.')
Si el discriminante resulta ser mayor o igual que cero, sí tendremos solución y solo quedará calcularla como vemos a continuación.
Calculando las soluciones (o la solución)
Puede suceder que una ecuación cuadrada tenga dos soluciones diferentes. Esto es posible debido a que el cuadrado de cualquier número es siempre un número positivo ya que un número negativo multiplicado por otro número negativo da como resultado uno positivo. Esto es, existen números diferentes que elevados al cuadrado resultan en el mismo número.
Dicho de otra manera, el resultado de una raíz cuadrada en realidad, son siempre dos, que es la magnitud resultado de la operación con signo positivo y con signo negativo.
Para que quede claro, si hacemos la raíz cuadrada de 4 obtenemos 2. Pero el resultado de la raíz no es solo 2, sino que también es -2, ya que 2² = 4
y (-2)² = 4
.
Esto también tenemos que considerarlo para calcular la solución de la ecuación, de forma que tendremos que obtener dos valores diferentes: uno teniendo en cuenta el resultado positivo de la raíz y otro teniendo en cuenta el negativo.
Para ello, y siempre suponiendo que el discriminante es un número no negativo, podemos calcular las dos soluciones diferentes de la ecuación de la siguiente manera:
raiz = sqrt(discriminante)
x_1 = (-b + raiz) / (2 * a)
x_2 = (-b - raiz) / (2 * a)
Fíjate en que calculo primero el valor positivo de la raíz haciendo uso de la función sqrt
que está ubicada en el módulo math. Recuerda hacer un from math import sqrt
para poder usarla. El motivo de calcularlo previamente, al igual que con anterioridad también he almacenando el valor del discriminante en una variable, es evitar la repetición de código a la hora de calcular las dos soluciones x_1
y x_2
. Así, además, logramos un código más claro, sencillo de leer y menos propenso a errores.
Ahora bien, puede suceder que x_1
y x_2
tengan el mismo valor. Es decir, que la ecuación tiene una única solución (a veces se le llama a esto solución doble). Esto sucede cuando el discriminante es 0 pues el resultado de la raíz también sería 0 y no habría diferencia entre las expresiones para el cálculo de x_1
y x_2
, con lo que resultarían iguales.
15 conceptos fundamentales que necesitas conocer para aprender y dominar Python
Te voy a hacer cuatro regalos (no uno, no dos, no tres, cuatro) que hablan de estos 15 conceptos fundamentales de Python: mi Tutorial Básico Interactivo de Python, una cheat sheet de Python en español: La Hoja de Referencia de Python, una guía de ChatGPT y Python y 30 ejercicios de Python (es un reto para ti).
Estos regalos son exclusivos para los suscriptores de Código Pitón.
Es interesante también distinguir esta situación. Para ello basta con realizar la comprobación de que el discriminante es 0 y así calcular la única solución en ese caso. Puedes hacerlo de la siguiente manera:
raiz = sqrt(discriminante)
x_1 = (-b + raiz) / (2 * a) # calculamos una primera solución
if discriminante != 0: # comprobamos si hay otra solución
x_2 = (-b - raiz) / (2 * a) # calculamos la segunda solución
Solo quedaría ahora mostrar las soluciones por pantalla. Lo vemos a continuación juntando todo el código que ya hemos visto.
Código completo
Vamos a ver cómo queda todo juntando los distintos fragmentos de código que hemos ido viendo y mostrando algunos mensajes por pantalla al usuario. Añado comentarios al código para te quede claro qué se hace en cada línea:
from math import sqrt
# mostramos un mensaje de bienvenida
print('¡Hola! Vamos a resolver una ecuación de segundo grado:')
print(' ax² + bx + c = 0\n')
# pedimos los coeficientes al usuario
a, b, c = [float(input(f'Dame el coeficiente {coef}: ')) for coef in ('a', 'b', 'c')]
# calculamos el discriminante
discriminante = b * b - 4 * a * c
if discriminante < 0: # comprobamos si no existen soluciones reales
print(f'La ecuación no tiene soluciones reales.')
else:
raiz = sqrt(discriminante) # calculamos la raíz
x_1 = (-b + raiz) / (2 * a) # calculamos una primera solución
if discriminante != 0: # comprobamos si hay otra solución
x_2 = (-b - raiz) / (2 * a) # calculamos la segunda solución
print(f'Las soluciones son {x_1} y {x_2}.') # mostramos las dos soluciones
else:
print(f'La única solución es x = {x_1}') # mostramos la única solución
Ya ves que, tras las explicaciones previas, el código completo queda sencillo y conciso. Vamos a ver la traza de algunas ejecuciones para que veas cómo funciona. La primera de ellas es una ejecución en la que la ecuación de segundo grado a resolver tiene dos soluciones diferentes (es decir, el discriminante es mayor que 0):
¡Hola! Vamos a resolver una ecuación de segundo grado:
ax² + bx + c = 0
Dame el coeficiente a: 2.25
Dame el coeficiente b: 1.5
Dame el coeficiente c: -2
Las soluciones son 0.6666666666666666 y -1.3333333333333333.
Vamos a ver ahora un caso en donde solo hay una solución (o solución doble, con el discriminante igual a 0):
¡Hola! Vamos a resolver una ecuación de segundo grado:
ax² + bx + c = 0
Dame el coeficiente a: -2
Dame el coeficiente b: 4
Dame el coeficiente c: -2
La única solución es x = 1.0
Y, finalmente, veremos una traza en la que no existe solución real pues el discriminante es negativo:
¡Hola! Vamos a resolver una ecuación de segundo grado:
ax² + bx + c = 0
Dame el coeficiente a: 1
Dame el coeficiente b: 2
Dame el coeficiente c: 3
La ecuación no tiene soluciones reales.
Creando una función para la resolución de ecuaciones cuadradas
Vamos a encapsular ahora nuestro código dentro de una función que reciba los coeficientes a
, b
y c
y nos devuelva la solución o soluciones de la ecuación. Esto es interesante si necesitamos resolver varias ecuaciones en nuestro programa.
Pensaremos la función para que nos devuelva una lista de valores ya que, como hemos visto, las soluciones reales posibles pueden ser 0, 1 o 2. De esta manera, basta con revisar la longitud de la lista devuelta por nuestra función para conocer el número de soluciones de la ecuación.
Ahora bien, la función no debe mostrar nada por pantalla, de eso nos ocuparemos después de llamar a nuestra función, así que eliminaremos las llamadas a la función print
y sustituiremos las del final por instrucciones para añadir las soluciones calculadas a la lista de soluciones.
Además, como nuestra función ya recibe los valores de los coeficientes como parámetros no necesitamos tampoco hacer llamadas a input
dentro de ella. Veamos el código:
from math import sqrt
def resolver_ecuacion_cuadrada(a, b, c):
soluciones = [] # creamos una lista vacía para las soluciones
discriminante = b * b - 4 * a * c
if discriminante >= 0: # comprobamos si existen soluciones reales
raiz = sqrt(discriminante)
soluciones.append((-b + raiz) / (2 * a)) # calculamos una primera solución
if discriminante != 0:
soluciones.append((-b - raiz) / (2 * a)) # calculamos la segunda solución si existe
return soluciones
Con nuestra nueva función resolver_ecuacion_cuadrada
realizamos una ejecución del código siguiente. Fíjate en que, aunque podríamos solicitar al usuario los valores de los coeficientes como hacíamos previamente, en este caso vamos a proporcionárselos directamente:
soluciones = resolver_ecuacion_cuadrada(1.17, -4.48, -0.5)
print(soluciones)
soluciones = resolver_ecuacion_cuadrada(4, -3, 1)
print(soluciones)
soluciones = resolver_ecuacion_cuadrada(5, 1, 0)
print(soluciones)
Si directamente imprimimos el contenido de la lista de soluciones proporcionado por nuestra función obtenemos lo siguiente, donde puedes observar que para el primer caso tenemos dos soluciones, para el segundo ninguna solución y para el tercero dos soluciones:
[3.9375907690225196, -0.10853093996269035]
[]
[0.0, -0.2]
Comprobando las soluciones
De manera complementaria, realicemos ahora otra función que nos sirva para comprobar si un número es una solución válida, es decir, una x
válida, para una ecuación cuadrada dada.
Para esto, necesitamos definir una función que reciba cuatro parámetros diferentes, donde tres de ellos serán los coeficientes a
, b
y c
y el otro el valor de la x
a comprobar.
Lo que tendrá que hacer esta función será sustituir esos cuatro valores en la expresión general de ecuación cuadrada ax² + bx + c = 0
y comprobar que se cumple la igualdad.
Hay que tener en cuenta que debemos realizar una comparación de números reales. Siempre que tengamos que hacer esto debemos determinar un pequeño margen de error admisible dentro del cual podemos considerar que dos números reales son iguales. Esto es debido a que, por ejemplo, los dos números 1.000000 y 1.000001 son diferentes si los comparamos con el comparador de igualdad ==
, pero en nuestro caso quizá los queramos considerar con números iguales.
Así definiendo la variable margen
como ese pequeño margen de error, por ejemplo, 0.0001 (una diezmilésima), nuestro código tendrá que considerar que dos números cuya resta en valor absoluto (para eliminar el signo negativo del resultado) sea inferior a dicho margen son iguales. Así, y suponiendo los números d
y e
, nuestra comparación ya no será d == e
, sino abs(d - e) <= margen
.
El código de nuestra función para comprobar si una solución es válida quedaría de la siguiente manera:
Día que estás fuera, consejo sobre Python que te pierdes.
Antes de suscribirte consulta aquí la
Finalidad de recogida y tratamiento de datos personales: enviarte boletín informativo de Python y comunicaciones comerciales.
Legitimación: tu consentimiento.
Destinatarios: no se ceden a terceros. Los datos se almacenan en los servidores de marketing (GetResponse).
Derechos: podrás ejercer tus derechos de acceso, rectificación, limitación y supresión de datos en info @ codigopiton.com así como presentar una reclamación ante una autoridad de control.
Más información: política de privacidad, encontrarás información adicional sobre la recopilación y el uso de tu información personal.
def solucion_valida(x, a, b, c, margen=0.0001):
return abs(a * x * x + b * x + c) < margen
En este caso, como el valor a la derecha de la igualdad en la expresión general ax² + bx + c = 0
es 0, nos podemos ahorrar la resta y comprar el valor de la subexpresión a la izquierda de la igualdad con el margen proporcionado.
Fíjate en que le doy un valor por defecto al parámetro margen
para no tener que indicarlo yo en cada llamada a la función solucion_valida
. Puedes aprender más sobre parámetros posicionales y parámetros con nombre en este artículo sobre el uso de asteriscos en Python.
Vamos a probar nuestra función con algunos ejemplos para comprobar su funcionamiento:
print(solucion_valida(3.9375, 1.17, -4.48, -0.5, margen=0.001))
print(solucion_valida(0, 5, 1, 0))
print(solucion_valida(2, 5, 1, 0))
print(solucion_valida(0, 4, -3, 1))
Como puedes ver, en el primer caso varío el margen a mi gusto. En el resto de casos dejo el valor de margen por defecto. El resultado de la ejecución de este código es:
True
True
False
False
Y esto es todo. Espero haber arrojado algo de luz y que haya sido ilustrativo este ejemplo clásico para el aprendizaje de programación.
Te envío todos los días un consejo para que cada día seas mejor en Python.
Siempre sobre Python y programación.
Más de 2500 personas como tú los reciben cada día.
Día que estás fuera, consejo sobre Python que te pierdes.
Antes de suscribirte consulta aquí la
Finalidad de recogida y tratamiento de datos personales: enviarte boletín informativo de Python y comunicaciones comerciales.
Legitimación: tu consentimiento.
Destinatarios: no se ceden a terceros. Los datos se almacenan en los servidores de marketing (GetResponse).
Derechos: podrás ejercer tus derechos de acceso, rectificación, limitación y supresión de datos en info @ codigopiton.com así como presentar una reclamación ante una autoridad de control.
Más información: política de privacidad, encontrarás información adicional sobre la recopilación y el uso de tu información personal.