Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
If statement syntax error
-
I’m attempting to rewrite my code to be more efficient and am utilizing a couple of code snippets that a couple of you have supplied. However, in the below code I noticed that the output is 0.0 if both inputs happen to be the same number. I’m not understanding why.
def button3_tapped(sender): hypotenuse = float(v['hypotenuse'].text or 0) short = float(v['short'].text or 0) long = float(v['long'].text or 0) if len([x for x in (hypotenuse, short, long) if x]) != 2: v['mess'].text = "Enter two fields" v['mess'].background_color = 'red' v['mess'].text_color = 'white' return if hypotenuse: if short and not long: v['long'].text = str(math.sqrt(hypotenuse ** 2 - short ** 2)) v['long'].text_color = 'green' elif long and not short: v['short'].text = str(math.sqrt(hypotenuse ** 2 - long ** 2)) v['short'].text_color = 'green' else: v['hypotenuse'].text = str(math.sqrt(short ** 2 + long ** 2)) v['hypotenuse'].text_color = 'green' ```
-
if both inputs happen to be the same number
if hypotenuse: if short: The rules of math say that the hypotenuse must be greater than short. else The rules of math say that the hypotenuse must be greater than long. else: short could be the same number as long # <-- this is the only instance where both inputs could be the same number
if hypotenuse and (short >= hypotenuse or long >= hypotenuse): raise ValueError("Not allowed by the rules of math.")
-
Agreed. It works fine if short and long are the same number, which equals 45 degrees.
-
Here’s what I came up with. It’s much shorter and easier to understand and I GREATLY appreciate all the help and patience.
This version does all the other one did plus more. This version will calculate the other side and angle based on two sides input and can now calculate any side of the triangle based on angle and any one of the three sides.def button3_tapped(sender): hypotenuse = float(v['hypotenuse'].text or 0) short = float(v['short'].text or 0) long = float(v['long'].text or 0) angle = float(v['angle'].text or 0) if len([x for x in (hypotenuse, short, long, angle) if x]) != 2: v['mess'].text = "Enter two fields" v['mess'].background_color = 'red' v['mess'].text_color = 'white' return if hypotenuse and not angle: if short and not long: v['long'].text = str(math.sqrt(hypotenuse ** 2 - short ** 2)) v['long'].text_color = 'green' v['angle'].text = str(math.degrees(math.asin(short / hypotenuse))) v['angle'].text_color = 'green' elif long and not short: v['short'].text = str(math.sqrt(hypotenuse ** 2 - long ** 2)) v['short'].text_color = 'green' v['angle'].text = str(math.degrees(math.acos(long / hypotenuse))) v['angle'].text_color = 'green' else: if not angle: v['hypotenuse'].text = str(math.sqrt(short ** 2 + long ** 2)) v['hypotenuse'].text_color = 'green' v['angle'].text = str(math.degrees(math.atan(short / long))) v['angle'].text_color = 'green' if angle: angle = math.radians(angle) if short and not long and not hypotenuse: v['hypotenuse'].text = str(short / (math.sin(angle))) v['hypotenuse'].text_color = 'green' v['long'].text = str(short / (math.tan(angle))) v['long'].text_color = 'green' elif long and not short and not hypotenuse: v['hypotenuse'].text = str(long / (math.cos(angle))) v['hypotenuse'].text_color = 'green' v['short'].text = str(long * (math.tan(angle))) v['short'].text_color = 'green' elif angle and hypotenuse and not long and not short: v['short'].text = str(hypotenuse * (math.sin(angle))) v['short'].text_color = 'green' v['long'].text = str(hypotenuse * (math.cos(angle))) v['long'].text_color = 'green'
-
Please put the trailing three backticks on a line all by themselves.
-
@ccc
Done -
OK. Now it is time to separate the business logic from the UI representation. We would need to put all the math logic in a function of the form:
def triangle(a, b, hypotenuse=0, angle=45): pass # math logic goes here
Where
triangle(3, 4)
returns(3, 4, 5.0, 45)
Wheretriangle(3, 0)
wouldraise ValueError()
-
It seems to me you could also dispense with most of the long / short specific logic, and just compute the other edge, then figure out which one is the long vs short after the fact.
-
Please explain
def triangle(a, b, hypotenuse=0, angle=45): pass # math logic goes here Where triangle(3, 4) returns (3, 4, 5.0, 45) Where triangle(3, 0) would raise ValueError()
-
This was an invitation for you or someone else to write a function that can take between 2 and 4 parameters and calculate all other variables or raise an exception if there is no possible solution. This function would allow us to isolate all UI operations from all math operations. It would make it easier to test our math operations without the UI and would allow us to easily port the math operations to a different platform.
-
Below will calculate short and long with given hypotenuse and angle but you have to enter zero for short and long input.
import math def triangle(short, long, hypotenuse, angle): pass if hypotenuse and angle: angle = math.radians(angle) print ('Short = ' + str(hypotenuse * (math.sin(angle)))) print ('Long = ' + str(hypotenuse * (math.cos(angle)))) triangle(0,0,10,30)
-
This will calculate any side or angle. But input still has to be zero for unknowns at input.
import math def triangle(short, long, hypotenuse, angle): pass if len([x for x in (hypotenuse, short, long, angle) if x]) == 2: if hypotenuse and angle: angle = math.radians(angle) print ('Short = ' + str(hypotenuse * (math.sin(angle)))) print ('Long = ' + str(hypotenuse * (math.cos(angle)))) elif long and angle: angle = math.radians(angle) print ('Short = ' + str(long * (math.tan(angle)))) print ('Hypotnuse = ' + str(long / (math.cos(angle)))) elif short and angle: angle = math.radians(angle) print ('Long = ' + str(short / (math.tan(angle)))) print ('Hypotnuse = ' + str(short / (math.sin(angle)))) elif hypotenuse and short: print ('Long = ' + str(math.sqrt(hypotenuse ** 2 - short ** 2))) print ('Angle = ' + str(math.degrees(math.asin(short / hypotenuse)))) elif hypotenuse and long: print ('Short = ' + str(math.sqrt(hypotenuse ** 2 - long ** 2))) print ('Angle = ' + str(math.degrees(math.acos(long / hypotenuse)))) elif short and long: print ('Hypotenuse = ' + str(math.sqrt(short ** 2 + long ** 2))) print ('Angle = ' + str(math.degrees(math.atan(short / long)))) else: print ("ERROR") triangle(5,0,10,0)
-
Step 0: drop the
pass
line.
Step 1:if len([x for x in (hypotenuse, short, long, angle) if x]) != 2: raise ValueError("Exactly two parameters must be zero.")
Step 2: change
triangle()
so it never prints but instead returns the answer with the statementreturn short, long, hypotenuse, angle
Step 3: changetriangle(5,0,10,0)
toprint(triangle(5,0,10,0))
.Step 1: is called a fast-fail which is safer and more readable than failing later in the function. Basically is says "I see a bad situation (bad input data) so I am going to raise an exception and stop processing".
-
@ccc, I am sure I just saw you using
count
somewhere:if (hyp, ...).count(0) != 2: raise ...
-
I don’t understand step 2
Step 2: change triangle() so it never prints but instead returns the answer with the statement return short, long, hypotenuse, angle.
Are you wanting me to change....
def triangle(short, long, hypotenuse, angle):Also, changing to print(triangle(5,0,10,0)) adds “none” after returned values
-
def triangle(short, long, hypotenuse, angle): # Your code goes here... # Your code contains no print() calls. return short, long, hypotenuse, angle
-
Your code contains no print() calls, like
if hypotenuse and angle: angle = math.radians(angle) short = hypotenuse * math.sin(angle) long = hypotenuse * math.cos(angle)
-
I still don’t know what you’re wanting. My code has many print calls.
Adding return short, long, hypotenuse, angle where you have it above won’t do anything because it’s part of the last elif. If I add it in line with def Tringle it errors.import math def triangle(short, long, hypotenuse, angle): pass if len([x for x in (hypotenuse, short, long, angle) if x]) == 2: if hypotenuse and angle: angle = math.radians(angle) print ('Short = ' + str(hypotenuse * (math.sin(angle)))) print ('Long = ' + str(hypotenuse * (math.cos(angle)))) elif long and angle: angle = math.radians(angle) print ('Short = ' + str(long * (math.tan(angle)))) print ('Hypotnuse = ' + str(long / (math.cos(angle)))) elif short and angle: angle = math.radians(angle) print ('Long = ' + str(short / (math.tan(angle)))) print ('Hypotnuse = ' + str(short / (math.sin(angle)))) elif hypotenuse and short: print ('Long = ' + str(math.sqrt(hypotenuse ** 2 - short ** 2))) print ('Angle = ' + str(math.degrees(math.asin(short / hypotenuse)))) elif hypotenuse and long: print ('Short = ' + str(math.sqrt(hypotenuse ** 2 - long ** 2))) print ('Angle = ' + str(math.degrees(math.acos(long / hypotenuse)))) elif short and long: print ('Hypotenuse = ' + str(math.sqrt(short ** 2 + long ** 2))) print ('Angle = ' + str(math.degrees(math.atan(short / long)))) else: print ("ERROR") triangle(5,0,10,0)
-
-
I think I understand now. But I can’t get the indentation at “return” to stop erroring.
import math def triangle(short, long, hypotenuse, angle): if len([x for x in (hypotenuse, short, long, angle) if x]) != 2: raise ValueError("Exactly two parameters must be zero.") if hypotenuse and angle: angle = math.radians(angle) print ('Short = ' + str(hypotenuse * (math.sin(angle)))) print ('Long = ' + str(hypotenuse * (math.cos(angle)))) elif long and angle: angle = math.radians(angle) print ('Short = ' + str(long * (math.tan(angle)))) print ('Hypotnuse = ' + str(long / (math.cos(angle)))) elif short and angle: angle = math.radians(angle) print ('Long = ' + str(short / (math.tan(angle)))) print ('Hypotnuse = ' + str(short / (math.sin(angle)))) elif hypotenuse and short: print ('Long = ' + str(math.sqrt(hypotenuse ** 2 - short ** 2))) print ('Angle = ' + str(math.degrees(math.asin(short / hypotenuse)))) elif hypotenuse and long: print ('Short = ' + str(math.sqrt(hypotenuse ** 2 - long ** 2))) print ('Angle = ' + str(math.degrees(math.acos(long / hypotenuse)))) elif short and long: print ('Hypotenuse = ' + str(math.sqrt(short ** 2 + long ** 2))) print ('Angle = ' + str(math.degrees(math.atan(short / long)))) return(short, long, hypotenuse, angle) #triangle(5,0,10,0)