包含大量 cmets 的扩展版本:
# you can import just the functions you want, and
# call them directly like sqrt() instead of math.sqrt()
from math import acos, degrees, sqrt
# functions make it easy to reuse, document and test bits of code
def get_floats(prompt, sep=None):
# A docstring - if you type "help(get_floats)" it will display this.
"""
Prompt until one or more numbers are entered
"""
nums = []
while not nums: # repeat until nums is not empty
string = input(prompt)
try:
# a list comprehension - do something to each item in a list,
# and return the results as another list.
# In this case, each piece of the split string gets converted to float()
nums = [float(s) for s in string.split(sep)]
except ValueError:
# exceptions help you to handle unexpected problems,
# like if someone tries to enter 'banana' when asked for a number
pass
return nums
def dist(p1, p2):
"""
Return Cartesian distance between two points
"""
# zip() is a very useful function for combining several lists in parallel -
# if you call zip(list1, list2, list3) it will give you the first
# item from each list, then the second item from each, etc.
# In this case, we treat each point as a list of coordinates - [x1, y1, z1]
# and when we zip two points we get the coordinates in each dimension:
# zip([x1, y1, z1], [x2, y2, z2]) -> [[x1, x2], [y1, y2], [z1, z2]]
#
# The loop, (b - a) ** 2 for a, b in zip(p1, p2)
# is a generator expression - it's like a list comprehension,
# but it yields a value at a time instead of a whole list at once.
# It is sometimes a little bit slower, but takes less memory.
#
# For each pair of coordinates we square the difference -
# then we sum all of the squares and take the root,
# which gives us Cartesian distance.
#
# The neat thing is, this loop doesn't care how many dimensions you give it -
# it will work on 2d points, or 3d, or 5d. If you give it a pair
# of 27-dimensional points, it will happily return the distance
# in 27-dimensional space.
return sqrt(sum((b - a) ** 2 for a, b in zip(p1, p2)))
def get_angle(a, b, c, use_degrees=True):
"""
Given the lengths of three sides of a triangle,
return the angle opposite side c
"""
# using cosine law
angle = acos((a * a + b * b - c * c) / (2 * a * b))
if use_degrees:
angle = degrees(angle)
return angle
def main():
# get points of a triangle
p1 = get_floats("Enter point 1: ", ",")
p2 = get_floats("Enter point 2: ", ",")
p3 = get_floats("Enter point 3: ", ",")
# get side lengths
a = dist(p2, p3)
b = dist(p1, p3)
c = dist(p1, p2)
# get angles
A = get_angle(b, c, a)
B = get_angle(a, c, b)
C = get_angle(a, b, c)
# show results using string formatting (automatically rounds the result)
print(
"The three angles are {:0.2f}, {:0.2f} and {:0.2f}"
.format(A, B, C)
)
main()