Hi all, this is my first post.

A couple days ago, in preparation for a math final, I attempted to code a program which would allow me to solve triangles (law of cosines, sines, etc.). Now that the test is over, I am now interested in getting it working.

``````#This is TRIANGLE SOLVER!!!
#solves triangles, in SSS, ASA, SSA, AAS, SAS
#Written by Jared Miller, 2013, AAST, June 1 2010

import math

#functions

if input("\nAgain?")==("y" or "Y" or "yes" or "Yes" or "YES"):
return True
else:
return False
#math constants

PI=math.pi

#math functions

sq=lambda x: math.sqrt(x)
p2=lambda x: x**2

#trig functions

#trig inverses

asin=lambda x: deg(math.asin(x))
acos=lambda x: deg(math.acos(x))

#trig measurements

deg=lambda x: math.degrees(x)

#laws of cosines and sines

#law of cosines, for angle and side

def lawcosside(a,b,C):
"""Law of cosines, solving side C"""
return sq(p2(a)+p2(b)-2*a*b*cos(C))

def lawcosangle(a,b,c):
"""Law of cosines, solving for angle C"""
return acos((p2(a)+p2(b)-p2(c))/(2*a*b))

#law of sines, for missing angle and side:

def lawsinside(A,a,B):
"""Law of sines, solving for side b"""
return (a*sin(B))/sin(A)

def lawsinangle(a,A,b):
"""Law of sines, solving for angle B"""
return asin((b*sin(A))/a)

#Solving triangles

#Single solution, regular cases

def SSS(a,b,c):
"""Finds angles A, B, C"""
A=lawcosangle(b,c,a)
B=lawcosangle(c,a,b)
C=180-A-B
assert  not A+B+C>182
return {"sides":(a,b,c),"angles":(A,B,C)}

def ASA(A,c,B):
"""Finds sides a, b; and angle C"""
C=180-A-B
a=lawsinside(C,c,A)
b=lawsinside(C,c,B)

assert  not A+B+C>182
return {"sides":(a,b,c),"angles":(A,B,C)}

def SAS(a,B,c):
"""Finds side b and angles A and C"""
b=lawcosside(a,c,B)
A=lawsinangle(b,B,a)
C=180-A-B
assert  not A+B+C>182
return {"sides":(a,b,c),"angles":(A,B,C)}

def AAS(A,B,a):
"""Finds sides b, c; and angle C"""
b=lawsinside(A,a,B)
C=180-A-B
c=lawsinside(A,a,C)
assert not  A+B+C>182
return {"sides":(a,b,c),"angles":(A,B,C)}

#Holy...multiple possible triangles

def SSA(c,a,A):
"""Returns 0,1,or 2 triangles, depending upon the case"""

#height declaration
h=c*sin(A)

#case 1:
#h>a
#0 triangles

if h>a:
return []

#case 2:
#h=a
#1 triangle

elif h==a:
C=90
B=180-A-C
b=lawsinside(A,a,B)
assert not A+B+C>182
return [{"sides":(a,b,c),"angles":(A,B,C)}]

#case 3:
#h<a<c
#2 triangles

elif h<a and a<c:
C1a=lawsinangle(a,A,c)
C2a=180-C1a
if C1a>C2a:
C1,C2=C1a,C2a
else:
C1,C2=C2a,C1a
B1=180-A-C1
B2=180-A-C2

assert  not A1+B1+C1>182
assert  not A2+B2+C2>182

b1=lawsinside(A,a,B1)
b2=lawsinside(A,a,B2)

return [{"sides triangle 1":(a,b1,c),"angles traingle 1":(A,B1,C1)}, {"sides triangle 2":(a,b2,c),"angles triangle 2":(A,B2,C2)}]

#case 4:
#a>=c
#1 triangle

else:
C=lawsinangle(a,A,c)
B=180-A-C
b=lawsinside(A,a,B)
assert not A+B+C>182
return [{"sides":(a,b,c),"angles":(A,B,C)}]

#main program
def main():
"""Start the program"""
again=True
print("""Welcome to the Triangle Solver!

Here, you will be able to solve a triangle in SSS, ASA, SSA, AAS, SAS forms.

Type in a form, and press enter to begin.
""")
while again:
type=input("Form:\t")

#SSS

if type=="SSS":
print("\nYou picked SSS. Type in each number, seperated by a space\n")
nums=input("Numbers:\t").split()
nums=[float(eval(i)) for i in nums]
resultdict=SSS(nums,nums,nums)
resultdict["angles"]=[deg(ang) for ang in resultdict["angles"]]
print("\nsides:\t ", resultdict["sides"], " \nangles:\t ", resultdict["angles"])
#ASA

elif type=="ASA":
print("\nYou picked ASA. Type in each number, seperated by a space\n")
nums=input("Numbers:\t").split()
nums=[float(eval(i)) for i in nums]
resultdict=ASA(nums,nums,nums)
resultdict["angles"]=[deg(ang) for ang in resultdict["angles"]]
print("\nsides:\t ", resultdict["sides"], " \nangles:\t ", resultdict["angles"])

#SSA

elif type=="SSA":
print("\nYou picked SSA. Type in each number, seperated by a space\n")
nums=input("Numbers:\t").split()
nums=[float(eval(i)) for i in nums]
resultlist=SSA(nums,nums,nums)

if len(resultlist)==0:
print("\nThere are no triangles that fit these specifications")
elif len(resultlist)==1:
resultdict=resultlist
resultdict["angles"]=[deg(ang) for ang in resultdict["angles"]]
print("\nsides:\t ", resultdict["sides"], " \nangles:\t ", resultdict["angles"])
else:
resultdict1=resultlist
resultdict1["angles"]=[deg(ang) for ang in resultdict1["angles"]]
resultdict2=resultlist
resultdict2["angles"]=[deg(ang) for ang in resultdict2["angles"]]
print("\nsides:\t ", resultdict1["sides"], " \nangles:\t ", resultdict1["angles"])
print("sides:\t ", resultdict2["sides"], " \nangles:\t ", resultdict2["angles"])
#AAS

elif type=="AAS":
print("\nYou picked AAS. Type in each number, seperated by a space\n")
nums=input("Numbers:\t").split()
nums=[float(eval(i)) for i in nums]
resultdict=AAS(nums,nums,nums)
resultdict["angles"]=[deg(ang) for ang in resultdict["angles"]]
print("\nsides:\t ", resultdict["sides"], " \nangles:\t ", resultdict["angles"])

#SAS

elif type=="SAS":
print("\nYou picked SAS. Type in each number, seperated by a space\n")
nums=input("Numbers:\t").split()
nums=[float(eval(i)) for i in nums]
resultdict=SAS(nums,nums,nums)
resultdict["angles"]=[deg(ang) for ang in resultdict["angles"]]
print("\nsides:\t ", resultdict["sides"], " \nangles:\t ", resultdict["angles"])

#Catch-all for bugs

else:
print("I could not recognize this request.\n")

#start of program
main()``````

When run, the angle measurements return outrageous values in the high 2-4 thousands, and the assert statements are failing. I'm pretty sure there is a more efficient method for parsing and synthesizing the input, but the method I have now works.

Jared

The problem is that you convert twice the angles to degrees. For example the part `if type == "SSS"` should look like

``````if type=="SSS":
print("\nYou picked SSS. Type in each number, seperated by a space\n")
nums=input("Numbers:\t").split()
nums=[float(eval(i)) for i in nums]
resultdict=SSS(nums,nums,nums)
# LINE SUPPRESSED
print("\nsides:\t …``````

## All 4 Replies

The problem is that you convert twice the angles to degrees. For example the part `if type == "SSS"` should look like

``````if type=="SSS":
print("\nYou picked SSS. Type in each number, seperated by a space\n")
nums=input("Numbers:\t").split()
nums=[float(eval(i)) for i in nums]
resultdict=SSS(nums,nums,nums)
# LINE SUPPRESSED
print("\nsides:\t ", resultdict["sides"], " \nangles:\t ", resultdict["angles"])``````

Another problem is that you are indenting your code with tab characters instead of spaces. It's a bad habit in python, so PLEASE, configure your editor to insert 4 spaces instead of a tab when you hit the tab key.

Thanks so much!

I fixed the command line bug, and it works perfectly. I've tried upgrading the program to tkinter, and it seems to be riddled with bugs.

``````#triangle solver GUI

from tkinter import *
from math import *

#law of cosines, for angle and side

def lawcosside(a,b,C):
"""Law of cosines, solving side C"""
return (a**2+b**2-2*a*b*cos(C))**.5

def lawcosangle(a,b,c):
"""Law of cosines, solving for angle C"""
return acos((a**2+b**2-c**2)/(2*a*b))

#law of sines, for missing angle and side:

def lawsinside(A,a,B):
"""Law of sines, solving for side b"""
return (a*sin(B))/sin(A)

def lawsinangle(a,A,b):
"""Law of sines, solving for angle B"""
return asin((b*sin(A))/a)

#class for GUI
class Application(Frame):
"""GUI Application for solving triangles"""
def __init__(self,master):
"""Creates Frame as master, forces grid, and holds everything together"""
super(Application, self).__init__(master)
self.grid()
self.create_widgets()

def create_widgets(self):
"""Creates widgets"""
Label(self,
text="Choose type of triangle"
).grid(row=0, column=0, columnspan=6)

#Radio buttons SSS, SAS, ASA, AAS, SSA

self.tri_form=StringVar()
self.tri_form.set(None)

counter=0
tri_list=["SSS","SAS","ASA","AAS","SSA"]

for a in tri_list:
text=a,
variable=self.tri_form,
value=a,
command=self.change_labels
).grid(row=1, column=counter, columnspan=1)
counter+=1

#Entry Inputs

Label(self,
text="Insert inputs:"
).grid(row=2, column=0, columnspan=6)

self.input_1_lbl=Label(self,
text="Side A"
).grid(row=3, column=0, columnspan=1)

self.input_1_entry=Entry(self)
self.input_1_entry.grid(row=3, column=1, columnspan=1)

self.input_2_lbl=Label(self,
text="Side B"
).grid(row=3, column=2, columnspan=1)

self.input_2_entry=Entry(self)
self.input_2_entry.grid(row=3, column=3, columnspan=1)

self.input_3_lbl=Label(self,
text="Side C"
).grid(row=3, column=4, columnspan=1)

self.input_3_entry=Entry(self)
self.input_3_entry.grid(row=3, column=5, columnspan=1)

self.ang_type=StringVar()
self.ang_type.set(None)

variable=self.ang_type,
command=self.calculate_output
).grid(row=4, column=0, columnspan=3)

text="Degrees",
variable=self.ang_type,
value="Degrees",
command=self.calculate_output
).grid(row=4, column=3, columnspan=3)

#Triangle 1:

self.output_1_tri_1_lbl=Label(self,
text="Angle A"
).grid(row=5, column=0, columnspan=1)

self.output1_tri_1_entry=Entry(self)
self.output1_tri_1_entry.grid(row=5, column=1, columnspan=1)

self.output2_tri_1_lbl=Label(self,
text="Angle B"
).grid(row=5, column=2, columnspan=1)

self.output2_tri_1_entry=Entry(self)
self.output2_tri_1_entry.grid(row=5, column=3, columnspan=1)

self.output3_tri_1_lbl=Label(self,
text="Angle C"
).grid(row=5, column=4, columnspan=1)

self.output3_tri_1_entry=Entry(self)
self.output3_tri_1_entry.grid(row=5, column=5, columnspan=1)

#Triangle 2:

self.output_1_tri_2_lbl=Label(self,
text="Nonexistent"
).grid(row=6, column=0, columnspan=1)

self.output1_tri_2_entry=Entry(self)
self.output1_tri_2_entry.grid(row=6, column=1, columnspan=1)

self.output2_tri_2_lbl=Label(self,
text="Nonexistent"
).grid(row=6, column=2, columnspan=1)

self.output2_tri_2_entry=Entry(self)
self.output2_tri_2_entry.grid(row=6, column=3, columnspan=1)

self.output3_tri_2_lbl=Label(self,
text="Nonexistent"
).grid(row=6, column=4, columnspan=1)

self.output3_tri_2_entry=Entry(self)
self.output3_tri_2_entry.grid(row=6, column=5, columnspan=1)

"""
Key for later

Variables

self.tri_form: form of triangle
self.ang_type: angles in radians or degrees

Input:

self.input_x_lbl x is from 1-3: label for input
self.input_x_entry x if from 1-3: entry for input

Output:

self.outputx_tri_y_lbl x is from 1-3, outputs, y is from 1-2, triangles: label
self.outputx_tri_y_entry x is from 1-3, outputs, y is from 1-2, triangles: entry

"""
def change_labels(self):
"""Changes labels of input and output boxes"""
form=self.tri_form.get()

if form=="SSS":
inputlist=["Side a", "Side b", "Side c"]
outputlist=["Angle A", "Angle B", "Angle C"]

elif form=="SAS":
inputlist=["Side a", "Angle B", "Side c"]
outputlist=["Angle A", "Side b", "Angle C"]

elif form=="AAS":
inputlist=["Angle A", "Angle B", "Side a"]
outputlist=["Side c", "Side b", "Angle C"]

elif form=="ASA":
inputlist=["Angle A", "Side c", "Angle B"]
outputlist=["Side a", "Angle C", "Side b"]

elif form=="SSA":
inputlist=["Side c", "Side a", "Angle A"]
outputlist=["Angle C", "Angle B", "Side b"]

self.input_1_lbl.config(text=inputlist)
self.input_2_lbl.config(text=inputlist)
self.input_3_lbl.config(text=inputlist)
self.output_1_tri_1_lbl.config(text=outputlist)
self.output_2_tri_1_lbl.config(text=outputlist)
self.output_3_tri_1_lbl.config(text=outputlist)
self.output_1_tri_2_lbl.config(text="Nonexistent")
self.output_2_tri_2_lbl.config(text="Nonexistent")
self.output_3_tri_2_lbl.config(text="Nonexistent")

counter=1
while counter<=3:
eval("self.input_{0}_entry".format(repr(counter))).delete(0.0, END)
eval("self.output"+repr(counter)+"_tri_1_entry" ).delete(0.0, END)
eval("self.output"+repr(counter)+"_tri_2_entry").delete(0.0, END)
counter+=1

counter=1
if form=="SSA":
while counter<=3:
eval("self.output"+repr(counter)+"_tri_2_lbl").config(text=eval("self.output"+repr(counter)+"_tri_1_lbl")['text'])
counter+=1

def calculate_output(self):
"""Calculates output, using mathematical formulae"""
form=self.tri_form.get()
ang_type=self.ang_type.get()

input_1=float(self.input_1_entry.get())
input_2=float(self.input_2_entry.get())
input_3=float(self.input_3_entry.get())

if form=="SSS":
a,b,c=input_1, input_2, input_3
A,B=lawcosangle(b,c,a),lawcosangle(c,a,b)
C=pi-A-B
if ang_type=="Degrees":
A,B,C=degrees(A),degrees(B),degrees(C)
output_1,output_2,output_3=A,B,C
output_1a,output_2a,output_3a=None,None,None

elif form=="SAS":
a,B,c=input_1,input_2,input_3
if ang_type=="Degrees":
b,A=lawcosside(a,c,B),lawsinside(b,B,a)
C=pi-A-B
if ang_type=="Degrees":
A,B,C=degrees(A),degrees(B),degrees(C)
output_1,output_2,output_3=A,b,C
output_1a,output_2a,output_3a=None,None,None

elif form=="AAS":
A,B,a=input_1,input_2,input_3
if ang_type=="Degrees":
b,c=lawsinside(A,a,B),lawsinside(A,a,C)
C=pi-A-B
if ang_type=="Degrees":
A,B,C=degrees(A),degrees(B),degrees(C)
output_1,output_2,output_3=c, b, C
output_1a,output_2a,output_3a=None,None,None

elif form=="ASA":
A,c,B=input_1,input_2, input_3
if ang_type=="Degrees":
a,b,C=lawsinside(C,c,A),lawsinside(C,c,B),(pi-A-B)
if ang_type=="Degrees":
A,B,C=degrees(A),degrees(B),degrees(C)
output_1,output_2,output_3=a,C,b
output_1a,output_2a,output_3a=None,None,None

elif form=="SSA":
c,a,A=input_1,input_2,input_3
if ang_type=="Degrees":
h=c*sin(A)

#case 1
#h>a
#0 triangles
if h<a:
output_1,output_2,output_3=None,None,None
output_1a,output_2a,output_3a=None,None,None

#case 2
#h=a
#1 triangle
elif h==a:
C=pi
B=pi-A-C
b=lawsinside(A,a,B)
if ang_type=="Degrees":
C,B=degrees(C),degrees(B)
output_1,output_2,output_3=C,B,b
output_1a,output_2a,output_3a=None,None,None

#case 3
#h<a<c
#2 triangles
elif h<a and a<c:
C1a=lawsinangle(a,A,c)
C2a=pi-C1a
if C1a>C2a:
C1,C2=C1a,C2a
else:
C1,C2=C2a,C1a
B1=pi-A-C1
B2=pi-A-C2
b1=lawsinside(A,a,B1)
b2=lawsinside(A,a,B2)
if ang_type=="Degrees":
B1,B2,C1,C2=degrees(B1),degrees(B2),degrees(C1),degrees(C2)
output_1,output_2,output_3=C1,B1,b1
output_1a,output_2a,output_3a=C2,B2,b2

#case 4
#a>=c
#1 triangle
elif a>=c:
C=lawsinangle(a,A,c)
B=pi-A-C
b=lawsinside(A,a,B)
if ang_type=="Degrees":
C,B=degrees(C),degrees(B)
output_1,output_2,output_3=C,B,b
output_1a,output_2a,output_3a=None,None,None

self.output_1,self.output_2,self.output_3,self.output_1a,self.output_2a,self.output_3a=output_1,output_2,output_3,output_1a,output_2a,output_3a
self.display_output()

def display_output(self):
"""Displays output, based on calculations from calculate_output"""

for a in [self.output_1,self.output_2,self.output_3,self.output_1a,self.output_2a,self.output_3a]:
if a==None:
a="Nonexistent"
self.output1_tri1_entry.insert(0.0,self.output_1)
self.output2_tri1_entry.insert(0.0,self.output_2)
self.output3_tri1_entry.insert(0.0,self.output_3)
self.output1_tri2_entry.insert(0.0,self.output_1a)
self.output2_tri2_entry.insert(0.0,self.output_2a)
self.output3_tri2_entry.insert(0.0,self.output_3a)

#Starts Gui

root=Tk()
root.title=("Triangle solver 2.0")
app=Application(root)
root.mainloop()``````

At least you should store label before doing .grid:

``````self.input_1_lbl=Label(self,
text="Side A"
).grid(row=3, column=0, columnspan=1)
print('Created', self.input_1_lbl)``````

Output

``Created None``
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts learning and sharing knowledge.