Why does math.sqrt result in ValueError: math domain error? - python

What causes the problem?
from math import sqrt
print "a : "
a = float(raw_input())
print "b : "
b = float(raw_input())
print "c : "
c = float(raw_input())
d = (a + b + c)/2
s = sqrt(d*(d-a)*(d-b)*(d-c))
print("a+b+c =", a, b, c)
print("Distr. =", d*2, "Area =", s)
Error:
Traceback (most recent call last):
File "C:/Python27/fájlok/háromszög terület2.py", line 11, in <module>
s = sqrt(d*(d-a)*(d-b)*(d-c))
ValueError: math domain error
See also: Why does math.log result in ValueError: math domain error? for the equivalent problem using math.log; Python math domain error using math.acos function for the equivalent problem using math.acos.

The problem is that the Heron's formula holds good only when the sum of the two numbers are greater than the third. You need to check that explicitly.
A better way as you are using a code to do that is by using Exception handling
try:
s = sqrt(d*(d-a)*(d-b)*(d-c))
print "a+b+c =", a, b, c
print "Distr. =", d*2, "Area =", s
except ValueError:
print "Please enter 3 valid sides"
If you want to do it without try block you can do it as
delta = (d*(d-a)*(d-b)*(d-c))
if delta>0:
s = sqrt(delta)
print "a+b+c =", a, b, c
print "Distr. =", d*2, "Area =", s
else:
print "Please enter 3 valid sides"

sqrt gives that error when you try to use it with a negative number. sqrt(-4) gives that error because the result is a complex number.
For that, you need cmath:
>>> from cmath import sqrt
>>> sqrt(-4)
2j
>>> sqrt(4)
(2+0j)

I got the same error with my code until I used cmath instead of math like aneroid said:
import sys
import random
import cmath
x = random.randint(1, 100)
y = random.randint(1, 100)
a = 2 * x * cmath.sqrt(1 - x * 2 - y * 2)
b = 2 * cmath.sqrt(1 - x * 2 - y * 2)
c = 1 - 2 * (x * 2 + y * 2)
print ( 'The point on the sphere is: ', (a, b, c) )
This way ran my code properly.

Use cmath instead..
import cmath
num=cmath.sqrt(your_number)
print(num)
Now regardless of whether the number is negetive or positive you will get a result...

Related

How to get variable values from a txt file with a specified format?

I am writing a program that solves quadratic equations, with the variables assigned from a .txt file, with this specific format:
The text file will contain lines of comma separated text – each line contains three floating point numbers. The first number is the value for A, the second number is the value for B, and the third number is the value for C.
Now I have my code mostly written out I am just unsure how I would assign these variables from a .txt file. Here is my current code:
print("\nWelcome to the Blockhouse Bay College Quadratic Equation Program")
file = input("\nPlease input text file name: ")
file = file + ".txt"
text_file = open(file, "r")
import math
# function for finding roots
def equationroots( a, b, c):
# calculating discriminant using formula
dis = b * b - 4 * a * c
sqrt_val = math.sqrt(abs(dis))
# checking condition for discriminant
if dis > 0:
print("There are two distinct roots ")
print((-b + sqrt_val)/(2 * a))
print((-b - sqrt_val)/(2 * a))
elif dis == 0:
print("There is one real root")
print(-b / (2 * a))
# when discriminant is less than 0
else:
print("Complex Roots")
print(- b / (2 * a), " + i", sqrt_val)
print(- b / (2 * a), " - i", sqrt_val)
# Driver Program
#<---------------Need these variables assigned to lines from .txt file
a = 1
b = 10
c = -24
# If a is 0, then incorrect equation
if a == 0:
print("Cannot be a quadratic equation if a is zero")
else:
equationroots(a, b, c)
Note: Please note at the start of my code I have asked the user to input the file name, I still need to work on this as I need to create an error message for when the file does not exist. Just ignore this as I can fix that later.
with open('file.txt') as f:
content = f.read()
for line in content.splitlines():
a, b, c = map(float, content.split(','))
Complete program:
print("\nWelcome to the Blockhouse Bay College Quadratic Equation Program")
import math
# function for finding roots
def equationroots( a, b, c):
# calculating discriminant using formula
dis = b * b - 4 * a * c
sqrt_val = math.sqrt(abs(dis))
# checking condition for discriminant
if dis > 0:
print("There are two distinct roots ")
print((-b + sqrt_val)/(2 * a))
print((-b - sqrt_val)/(2 * a))
elif dis == 0:
print("There is one real root")
print(-b / (2 * a))
# when discriminant is less than 0
else:
print("Complex Roots")
print(- b / (2 * a), " + i", sqrt_val)
print(- b / (2 * a), " - i", sqrt_val)
filename = input("\nPlease input text file name: ")
with open(filename + '.txt') as f:
content = f.read()
for line in content.splitlines():
a, b, c = map(float, content.split(','))
# If a is 0, then incorrect equation
if a == 0:
print("Cannot be a quadratic equation if a is zero")
else:
equationroots(a, b, c)
Try this:
I had to move some of your code around, but I left inline comments to explain what I changed. I also included a check to make sure the path exists.
import math # Python convention is to put imports at the top
import os
print("\nWelcome to the Blockhouse Bay College Quadratic Equation Program")
# function for finding roots
def equationroots( a, b, c):
# calculating discriminant using formula
dis = b * b - 4 * a * c
sqrt_val = math.sqrt(abs(dis))
# checking condition for discriminant
if dis > 0:
print("There are two distinct roots ")
print((-b + sqrt_val)/(2 * a))
print((-b - sqrt_val)/(2 * a))
elif dis == 0:
print("There is one real root")
print(-b / (2 * a))
# when discriminant is less than 0
else:
print("Complex Roots")
print(- b / (2 * a), " + i", sqrt_val)
print(- b / (2 * a), " - i", sqrt_val)
file = input("\nPlease input text file name: ")
file = file + ".txt"
if os.path.exists(file): # check if file exists
with open(file, "rt") as text_file: # using a with statement is
# preferred over directly
# opening the file
for line in text_file: # iterate through lines of file
# the next line splits the `line` by "," commas,
# removes whitespace and casts each item to float
a,b,c = [float(i.strip()) for i in line.split(',')]
if a == 0:
print("Cannot be a quadratic equation if a is zero")
else:
equationroots(a, b, c)
else:
# print some message
you could read the file like this:
f = open(file_name,"r")
for line in f.readlines():
a,b,c = map(float,line.split(","))
# now call your function
if a == 0:
print("Cannot be a quadratic equation if a is zero")
else:
equationroots(a, b, c)
we started by opening the file then we iterate over the lines using file.readlines() then for every line we splitted the values and converted all of them to a float using map()

why i am getting "ValueError: math domain error" exception in my code?

this is my first time posting here so I'm sorry if I mess anything up or format incorrectly. In an attempt to bring a lot of the very basic stuff I've learned together in Python, I'm trying to make a quadratic equation calculator where you can type in each of your 3 values and be given the horizontal intercepts. However, while this works with some problems, others will give me this message:
"Traceback (most recent call last):
File "quadeq.py", line 18, in <module>
result1 = ((float(ac)) + (sqrt((float(ab)) - (float(aa))))) / (float(ad))
ValueError: math domain error"
I'm pretty sure this is just an error with my math, but it could be a lot of other things too. Thanks much to anyone willing to check this out, it would be much appreciated.
from math import *
print("Please enter each of your values!")
a = input("Enter a value: ")
b = input("Enter b value: ")
c = input("Enter c value: ")
d = -4
aa = float(d) * ((float(a)) * (float(c)))
ab = ((float(b))) * ((float(b)))
ac = 0 - (float(b))
ad = (2) * (float(a))
result1 = ((float(ac)) + (sqrt((float(ab)) - (float(aa))))) / (float(ad))
result2 = ((float(ac)) - (sqrt((float(ab)) - (float(aa))))) / (float(ad))
print("Your values are: " + str(result1) + " and " + str(result2))
you have some corner cases that you need to take in mind:
ZeroDivisionError : since your code includes divisions, you need to cover this.
ValueError : math.sqrt cant accept negative numbers! in such case this will raise ValueError: math domain error
you can use try except to handle these corner case.now you can do it in the operations step (no nned to check inputs with if-else like old days. this is non pythonic!) see below:
import math
print("Please enter each of your values!")
a = input("Enter a value: ")
b = input("Enter b value: ")
c = input("Enter c value: ")
d = -4
aa = float(d) * ((float(a)) * (float(c)))
ab = ((float(b))) * ((float(b)))
ac = 0 - (float(b))
ad = (2) * (float(a))
try:
result1 = ((float(ac)) + (sqrt((float(ab)) - (float(aa))))) / (float(ad))
result2 = ((float(ac)) - (sqrt((float(ab)) - (float(aa))))) / (float(ad))
print("Your values are: " + str(result1) + " and " + str(result2))
except(ZeroDivisionError, ValueError):
#do some work here, e.g tell the user something
print("....")
you have already accounted for subtraction when you substituted d = -4
change this sqrt((float(ab)) - (float(aa)))) to sqrt((float(ab)) + (float(aa))))
also, you should consider using the try-except block because the quadratic equation might have imaginary roots.
on a side note, your code contains a lot of redundant parentheses ;)

printing equation with variables in python

I am trying to print the equation with the variables
I have already tried to put all symbols in quotes
import random
import random
def ask():
a = raw_input("do you want the equation to be easy, medium, or hard: ")
b = int(raw_input("what is the number that you want to be the answer: "))
if(a == "easy"):
d = random.randint(1, 10)
e = random.randint(2, 5)
round(b)
print C = b - d + e - (e/2) + ((d - e) + e/2)
I wanted it to print out the equation with all the variables and symbols
when i type this in i get a syntax error
You cannot print out strings not in quotes. Put the bits you want to print out exactly as written in quotes, and print variables as is. For example:
print 'C =', b, '-', d, '+', e, '-', (e/2), '+', ((d - e/2)
Play around with that and see how you go. You'll want to think about how to do it differently if e.g. d-e/2 is negative.
Also round(b) will do nothing, it does not operate in-place.
try to put your equation in str() first,then print string
so that it will display equation before result.
then print out results
Here's what I think you want as a full solution. It accepts a single equation string as an input It then fills out that equation with the input variables, prints the resulting equation, and then evaluates it to provide a result:
import random
equation = "b - c + e - (e/2) + ((d- e) + e/2)"
b = 12
c = 24
d = random.randint(1, 10)
e = random.randint(2, 5)
# Expand the vlaues into the equation
equation = equation.replace('b', str(b)).replace('c', str(c)).replace('d', str(d)).replace('e', str(e))
# Print the equation
print "C = " + equation
# Evaluate the equation and print the result
C = eval(equation)
print "C = " + str(C)
Sample result:
C = 12 - 24 + 2 - (2/2) + ((6- 2) + 2/2)
C = -6
This code is just a demonstration of what can be done. You could take these ideas and generalize this to expand a map of variable names and values into an arbitrary expression without hard-coding the variable names. The map and equation could come, for example, from a file.

Is there a way to just print the 'y' when your answer is (x, y)?

Is there a way that i can modify this, so my answer only comes out as the 'y' coordinate?? The output I'm looking for is for example 'Triangle Number: 55385'. I'm pretty new to coding, so I don't really understand how to do that. (Python 2.7)
from sympy.solvers import solve
from sympy import Symbol
t = Symbol('t')
e = Symbol('e')
x = Symbol('x')
print "Triangle Number:", solve(t * (t + 1) / 2 - a, t)
print "Pentagonal Number:", solve((e * (3 * (e) - 1) / 2) - a, e)
print "Hexagonal Number:", solve((x * (2 * (x) - 1)) - a, x)
#OUTPUT:
Triangle Number: [-55386, 55385]
Pentagonal Number: [-95930/3, 31977]
Hexagonal Number: [-55385/2, 27693]
Yes, you can request the last entry in the list returned to be printed, instead of the entire sequence:
print "Triangle Number:", solve(t * (t + 1) / 2 - a, t)[-1]
print "Pentagonal Number:", solve((e * (3 * (e) - 1) / 2) - a, e)[-1]
print "Hexagonal Number:", solve((x * (2 * (x) - 1)) - a, x)[-1]
#OUTPUT IS BELOW
Triangle Number: 55385
Pentagonal Number: 31977
Hexagonal Number: 27693
Something you can do to have solve only return the values that fit your criteria for e, x and t is to define them as nonnegative values. Doing this, solve should only return a list with the values for which you may be looking:
>>> e, x, t = symbols('e x t', nonnegative=True, integer=True)
>>> a = 1533776805
>>> solve(t * (t + 1) / 2 - a, t)
[55385]

Showing input prompt in python

I am using IDLE for Python on a Mac OS. I wrote the following in a .py file:
import math
def main():
print "This program finds the real solution to a quadratic"
print
a, b, c = input("Please enter the coefficients (a, b, c): ")
discRoot = math.sqrt(b * b-4 * a * c)
root1 = (-b + discRoot) / (2 * a)
root2 = (-b - discRoot) / (2 * a)
print
print "The solutions are: ", root1, root2
main()
IDLE now permanently displays:
This program finds the real solution to a quadratic
Please enter the coefficients (a, b, c):
When I enter 3 numbers (ex: 1,2,3) IDLE does nothing. When I hit enter IDLE crashes (no crash report).
I quit and restarted but IDLE is now permanemtly displaying the above and won't respond to other files.
There is no real solution to the equation X^2 + 2x + 3 = 0. You will get a ValueError when trying to take the square root of b * b-4 * a * c, which is negative. You should handle this error case somehow. For example, a try/except:
import math
def main():
print "This program finds the real solution to a quadratic"
print
a, b, c = input("Please enter the coefficients (a, b, c): ")
try:
discRoot = math.sqrt(b * b-4 * a * c)
except ValueError:
print "there is no real solution."
return
root1 = (-b + discRoot) / (2 * a)
root2 = (-b - discRoot) / (2 * a)
print
print "The solutions are: ", root1, root2
main()
Or you can detect that the discriminant is negative ahead of time:
import math
def main():
print "This program finds the real solution to a quadratic"
print
a, b, c = input("Please enter the coefficients (a, b, c): ")
discriminant = b * b-4 * a * c
if discriminant < 0:
print "there is no real solution."
return
discRoot = math.sqrt(discriminant)
root1 = (-b + discRoot) / (2 * a)
root2 = (-b - discRoot) / (2 * a)
print
print "The solutions are: ", root1, root2
main()
Result:
This program finds the real solution to a quadratic
Please enter the coefficients (a, b, c): 1,2,3
there is no real solution.
The math module does not support complex numbers. If you replace import math with import cmath and math.sqrt with cmath.sqrt, your script should work like a charm.
EDIT: I just read "This program finds the real solution to a quadratic". Taking into consideration that you only want real roots, you should check for negative discriminants as the Kevin has pointed out.
The reason I see for your program failing is this:
a, b, c = 1, 2, 3
num = b * b - 4 * a * c
print num
It comes out as -8.
You normally can't have a negative number within a square root.
Like what the person above me says, import cmath should work.
http://mail.python.org/pipermail/tutor/2005-July/039461.html
import cmath
a, b, c = 1, 2, 3
num = cmath.sqrt(b * b - 4 * a * c)
print num
= 2.82842712475j

Categories

Resources