Python - 旗帜面积
Python - Area of a Flag
正在尝试求解 Building Skills with Python,旗帜区域。我正在尝试解决蓝色区域,但我偏离了大约 2%。此外,当我将其他区域加起来时,总数不等于旗帜本身的面积。我的代码如下:
import math
def area_star(width):
a = 36.00
b = 72.00
radius_star = 0.0308 * width
a_radians = float(a) * float(math.pi) / float(180)
b_radians = float(b) * float(math.pi) / float(180)
a_sin = math.sin(float(a_radians)/float(2))
b_sin = math.sin(float(b_radians)/float(2))
top = a_sin*b_sin
c_radians = float((a+b)*math.pi)/float(180)
c_sin = math.sin(c_radians)
bottom = 0.5 * c_sin
return 5 * float(top)/float(bottom) * radius_star * radius_star
def fifty_stars(width):
return 50 * area_star(width)
def calculate_areas(width):
WIDTH = width
length = 1.9 * WIDTH
width_union = float(7)/float(13) * WIDTH
length_union = 0.76*WIDTH
NUMBER_RED_STRIPES = 7
NUMBER_WHITE_STRIPES = 6
width_strip_denom = NUMBER_RED_STRIPES+NUMBER_WHITE_STRIPES
width_strip = float(1)/float(width_strip_denom)*WIDTH
blue_area = length_union * width_union - fifty_stars(WIDTH)
white_area = 3 * width_strip * (length*length_union)+3*width_strip*length+fifty_stars(WIDTH)
red_area = 4 * width_strip*(length*length_union)+3*width_strip*length
print 'Our width was given as : %f' %WIDTH
print 'Our length calculates as : %f' %length
print 'Width of our union is: %f' %width_union
print 'Length of our union is: %f' %length_union
print 'Area of a star is %f'%area_star(WIDTH)
print 'Area of 50 stars is %f'%fifty_stars(WIDTH)
print 'Area of our flag in total is : %f '%(WIDTH*length)
print 'Actual WHITE AREA is %f'%white_area
print 'Actual RED AREA is %f'%red_area
print 'Expected BLUE AREA is %f' %(WIDTH*length*.1873)
print 'Actual BLUE AREA is %f'%blue_area
print 'SumofallAreas: %f' % (red_area+white_area+blue_area)
calculate_areas(1.0)
我的输出是:
Our hoist was given as : 1.000000
Our length calculates as : 1.900000
Width of our union is: 0.538462
Length of our union is: 0.760000
Area of a star is 0.001812
Area of 50 stars is 0.090587
Area of our flag in total is : 1.900000
Actual WHITE AREA is 0.792126
Actual RED AREA is 0.789231
Expected BLUE AREA is 0.355870
Actual BLUE AREA is 0.318644
SumofallAreas: 1.900000
关于 Float 有什么可以解释差异的吗?还是我的代码本身有问题?
*********根据建议更新代码******************
import math
from fractions import Fraction
def area_star(width):
a = 36.00
b = 72.00
radius_star = 0.0308 * width
a_radians = float(a) * float(math.pi) / float(180)
b_radians = float(b) * float(math.pi) / float(180)
a_sin = math.sin(float(a_radians)/float(2))
b_sin = math.sin(float(b_radians)/float(2))
top = a_sin*b_sin
c_radians = float((a+b)*math.pi)/float(180)
c_sin = math.sin(c_radians)
bottom = 0.5 * c_sin
return 5 * float(top)/float(bottom) * radius_star * radius_star
def fifty_stars(width):
return 50 * area_star(width)
def calculate_areas(width):
hoist = width
fly = hoist * Fraction(19,10)
jack_hoist = Fraction(7,13) * hoist
jack_fly = Fraction(76,100)*hoist
NUMBER_RED_STRIPES = 7
NUMBER_WHITE_STRIPES = 6
width_strip_denom = NUMBER_RED_STRIPES+NUMBER_WHITE_STRIPES
width_strip = Fraction(1,width_strip_denom)*hoist
blue_area = jack_fly * jack_hoist - fifty_stars(hoist)
white_area = 3 * width_strip * (fly-jack_fly)+3*width_strip*fly+fifty_stars(hoist)
red_area = 4 * width_strip*(fly-jack_fly)+3*width_strip*fly
print 'Our hoist was given as : %f' %hoist
print 'Our length calculates as : %f' %fly
print 'Width of our union is: %f' %jack_hoist
print 'Length of our union is: %f' %jack_fly
print 'Area of a star is %f'%area_star(hoist)
print 'Area of 50 stars is %f'%fifty_stars(hoist)
print 'Area of our flag in total is : %f '%(hoist*fly)
print 'Actual WHITE AREA is %f'%white_area
print 'Actual RED AREA is %f'%red_area
print 'Expected BLUE AREA is %f' %(hoist*fly*.1873)
print 'Actual BLUE AREA is %f'%blue_area
print 'SumofallAreas: %f' % (red_area+white_area+blue_area)
calculate_areas(1.0)
Python 已知在处理浮点运算时存在问题。
这里有更多信息给你Floating Point Arithmetic: Issues and Limitations
编辑:
还有一个解决 same/similar 问题的先前堆栈 Python rounding error with float numbers [duplicate]
浮点精度问题不会导致您的计算出现如此大的偏差。您的代码中只有错误。具体来说,根据您的输出,Expected BLUE AREA is 0.355870
和 Actual BLUE AREA is 0.318644
是由使用明显不同的计算造成的。
我可以通过快速查看识别出一个潜在问题:width_union
和 length_union
是否都应该相对于标志的宽度进行计算?
您可能还有其他错误,很难看到整个代码中散落着这么多 "magic numbers"...(例如 float(7)/float(13)
、0.76
)。
首先,在这种情况下引用 'length' 和 'width' 可能会造成混淆;最好使用旗帜学术语 'hoist'(平行于旗杆的维度)和 'fly'(垂直于旗杆的维度)。
其次,您的电话号码已关闭。您将 length*length_union
用于高条纹的飞行,但这是不正确的。另外 length_union
不是苍蝇的比例,而是提升机的比例,它已经乘出来了,所以你不应该再乘它。在任何情况下,您都不需要州的苍蝇,而是条纹的苍蝇,即总苍蝇 减去 州。
我还没有检查你剩下的数学,但如果你使用 length-length_union
而不是 length*length_union
你可能会得到更好的结果。
忽略星星,你得到这些区域,如果这有助于你调试的话。就像在您的代码中一样,1.0 是一面与吊机相同的方形旗帜的面积;因此整个旗帜的面积为 1.9.
red = 513/650 (~ 0.789231)
white stripes only = 228/325 (~ 0.701538)
blue canton + white stars = 133/325 (~ 0.409231)
total = (513 + 228 * 2 + 133 * 2)/650 = 1235/650 = 1.9
星星的因素会将其中一些从蓝色变为白色,但红色(以及所有三个的总和)不应改变。
如果你确实想要更高的精度,你可以切换到使用 fractions
模块的精确有理算术:
from fractions import Fraction
hoist = 1
fly = hoist * Fraction(19,10)
stripe_hoist = hoist * Fraction(1,13)
canton_hoist = 7 * stripe_hoist
canton_fly = fly * Fraction(2, 5)
等等
这是我的计算。原始问题在下面的评论中指出了错误。
注意: from __future__
使除法像 Python 3 一样工作,其中 1/2 = 0.5,而不是 Python 中的 0 2. 这清理了数学。
此外,使用与问题陈述相同的变量可以更轻松地输入和验证公式。我发现 K 的两个版本没有给出相同的答案,所以独立解决了这个问题,发现 5*K
的黄金比例版本得到了与我对恒星面积相同的答案。
from __future__ import division
from math import sin,pi
Wf = 1.0
Lf = 1.9 * Wf
A = Wf * Lf
Wu = 7/13 * Wf
Lu = .76 * Wf
R = .0308 * Wf
Sr = 7
Sw = 6
Ns = 50
Ws = 1/(Sr+Sw) * Wf
a = 36 * pi/180
b = 72 * pi/180
GR = (1 + 5**.5)/2
K = sin(b/2)/GR**2 * (R**2) # Golden ratio version of K was correct, other was wrong.
S = 5 * K
Red = 4 * Ws * (Lf - Lu) + 3 * Ws * Lf
White = 3 * Ws * (Lf - Lu) + 3 * Ws * Lf + Ns * S
Blue = (Lu * Wu) - Ns * S # Error on problem page used (Lu - Wu)
print('Red =',Red)
print('White =',White)
print('Blue =',Blue)
print('total =',Red+White+Blue)
print('Red = {:%}'.format(Red/A))
print('White = {:%}'.format(White/A))
print('Blue = {:%}'.format(Blue/A))
输出:
Red = 0.7892307692307692
White = 0.7547841990012687
Blue = 0.355985031767962
total = 1.9
Red = 41.538462%
White = 39.725484%
Blue = 18.736054%
正在尝试求解 Building Skills with Python,旗帜区域。我正在尝试解决蓝色区域,但我偏离了大约 2%。此外,当我将其他区域加起来时,总数不等于旗帜本身的面积。我的代码如下:
import math
def area_star(width):
a = 36.00
b = 72.00
radius_star = 0.0308 * width
a_radians = float(a) * float(math.pi) / float(180)
b_radians = float(b) * float(math.pi) / float(180)
a_sin = math.sin(float(a_radians)/float(2))
b_sin = math.sin(float(b_radians)/float(2))
top = a_sin*b_sin
c_radians = float((a+b)*math.pi)/float(180)
c_sin = math.sin(c_radians)
bottom = 0.5 * c_sin
return 5 * float(top)/float(bottom) * radius_star * radius_star
def fifty_stars(width):
return 50 * area_star(width)
def calculate_areas(width):
WIDTH = width
length = 1.9 * WIDTH
width_union = float(7)/float(13) * WIDTH
length_union = 0.76*WIDTH
NUMBER_RED_STRIPES = 7
NUMBER_WHITE_STRIPES = 6
width_strip_denom = NUMBER_RED_STRIPES+NUMBER_WHITE_STRIPES
width_strip = float(1)/float(width_strip_denom)*WIDTH
blue_area = length_union * width_union - fifty_stars(WIDTH)
white_area = 3 * width_strip * (length*length_union)+3*width_strip*length+fifty_stars(WIDTH)
red_area = 4 * width_strip*(length*length_union)+3*width_strip*length
print 'Our width was given as : %f' %WIDTH
print 'Our length calculates as : %f' %length
print 'Width of our union is: %f' %width_union
print 'Length of our union is: %f' %length_union
print 'Area of a star is %f'%area_star(WIDTH)
print 'Area of 50 stars is %f'%fifty_stars(WIDTH)
print 'Area of our flag in total is : %f '%(WIDTH*length)
print 'Actual WHITE AREA is %f'%white_area
print 'Actual RED AREA is %f'%red_area
print 'Expected BLUE AREA is %f' %(WIDTH*length*.1873)
print 'Actual BLUE AREA is %f'%blue_area
print 'SumofallAreas: %f' % (red_area+white_area+blue_area)
calculate_areas(1.0)
我的输出是:
Our hoist was given as : 1.000000
Our length calculates as : 1.900000
Width of our union is: 0.538462
Length of our union is: 0.760000
Area of a star is 0.001812
Area of 50 stars is 0.090587
Area of our flag in total is : 1.900000
Actual WHITE AREA is 0.792126
Actual RED AREA is 0.789231
Expected BLUE AREA is 0.355870
Actual BLUE AREA is 0.318644
SumofallAreas: 1.900000
关于 Float 有什么可以解释差异的吗?还是我的代码本身有问题?
*********根据建议更新代码******************
import math
from fractions import Fraction
def area_star(width):
a = 36.00
b = 72.00
radius_star = 0.0308 * width
a_radians = float(a) * float(math.pi) / float(180)
b_radians = float(b) * float(math.pi) / float(180)
a_sin = math.sin(float(a_radians)/float(2))
b_sin = math.sin(float(b_radians)/float(2))
top = a_sin*b_sin
c_radians = float((a+b)*math.pi)/float(180)
c_sin = math.sin(c_radians)
bottom = 0.5 * c_sin
return 5 * float(top)/float(bottom) * radius_star * radius_star
def fifty_stars(width):
return 50 * area_star(width)
def calculate_areas(width):
hoist = width
fly = hoist * Fraction(19,10)
jack_hoist = Fraction(7,13) * hoist
jack_fly = Fraction(76,100)*hoist
NUMBER_RED_STRIPES = 7
NUMBER_WHITE_STRIPES = 6
width_strip_denom = NUMBER_RED_STRIPES+NUMBER_WHITE_STRIPES
width_strip = Fraction(1,width_strip_denom)*hoist
blue_area = jack_fly * jack_hoist - fifty_stars(hoist)
white_area = 3 * width_strip * (fly-jack_fly)+3*width_strip*fly+fifty_stars(hoist)
red_area = 4 * width_strip*(fly-jack_fly)+3*width_strip*fly
print 'Our hoist was given as : %f' %hoist
print 'Our length calculates as : %f' %fly
print 'Width of our union is: %f' %jack_hoist
print 'Length of our union is: %f' %jack_fly
print 'Area of a star is %f'%area_star(hoist)
print 'Area of 50 stars is %f'%fifty_stars(hoist)
print 'Area of our flag in total is : %f '%(hoist*fly)
print 'Actual WHITE AREA is %f'%white_area
print 'Actual RED AREA is %f'%red_area
print 'Expected BLUE AREA is %f' %(hoist*fly*.1873)
print 'Actual BLUE AREA is %f'%blue_area
print 'SumofallAreas: %f' % (red_area+white_area+blue_area)
calculate_areas(1.0)
Python 已知在处理浮点运算时存在问题。
这里有更多信息给你Floating Point Arithmetic: Issues and Limitations
编辑: 还有一个解决 same/similar 问题的先前堆栈 Python rounding error with float numbers [duplicate]
浮点精度问题不会导致您的计算出现如此大的偏差。您的代码中只有错误。具体来说,根据您的输出,Expected BLUE AREA is 0.355870
和 Actual BLUE AREA is 0.318644
是由使用明显不同的计算造成的。
我可以通过快速查看识别出一个潜在问题:width_union
和 length_union
是否都应该相对于标志的宽度进行计算?
您可能还有其他错误,很难看到整个代码中散落着这么多 "magic numbers"...(例如 float(7)/float(13)
、0.76
)。
首先,在这种情况下引用 'length' 和 'width' 可能会造成混淆;最好使用旗帜学术语 'hoist'(平行于旗杆的维度)和 'fly'(垂直于旗杆的维度)。
其次,您的电话号码已关闭。您将 length*length_union
用于高条纹的飞行,但这是不正确的。另外 length_union
不是苍蝇的比例,而是提升机的比例,它已经乘出来了,所以你不应该再乘它。在任何情况下,您都不需要州的苍蝇,而是条纹的苍蝇,即总苍蝇 减去 州。
我还没有检查你剩下的数学,但如果你使用 length-length_union
而不是 length*length_union
你可能会得到更好的结果。
忽略星星,你得到这些区域,如果这有助于你调试的话。就像在您的代码中一样,1.0 是一面与吊机相同的方形旗帜的面积;因此整个旗帜的面积为 1.9.
red = 513/650 (~ 0.789231)
white stripes only = 228/325 (~ 0.701538)
blue canton + white stars = 133/325 (~ 0.409231)
total = (513 + 228 * 2 + 133 * 2)/650 = 1235/650 = 1.9
星星的因素会将其中一些从蓝色变为白色,但红色(以及所有三个的总和)不应改变。
如果你确实想要更高的精度,你可以切换到使用 fractions
模块的精确有理算术:
from fractions import Fraction
hoist = 1
fly = hoist * Fraction(19,10)
stripe_hoist = hoist * Fraction(1,13)
canton_hoist = 7 * stripe_hoist
canton_fly = fly * Fraction(2, 5)
等等
这是我的计算。原始问题在下面的评论中指出了错误。
注意: from __future__
使除法像 Python 3 一样工作,其中 1/2 = 0.5,而不是 Python 中的 0 2. 这清理了数学。
此外,使用与问题陈述相同的变量可以更轻松地输入和验证公式。我发现 K 的两个版本没有给出相同的答案,所以独立解决了这个问题,发现 5*K
的黄金比例版本得到了与我对恒星面积相同的答案。
from __future__ import division
from math import sin,pi
Wf = 1.0
Lf = 1.9 * Wf
A = Wf * Lf
Wu = 7/13 * Wf
Lu = .76 * Wf
R = .0308 * Wf
Sr = 7
Sw = 6
Ns = 50
Ws = 1/(Sr+Sw) * Wf
a = 36 * pi/180
b = 72 * pi/180
GR = (1 + 5**.5)/2
K = sin(b/2)/GR**2 * (R**2) # Golden ratio version of K was correct, other was wrong.
S = 5 * K
Red = 4 * Ws * (Lf - Lu) + 3 * Ws * Lf
White = 3 * Ws * (Lf - Lu) + 3 * Ws * Lf + Ns * S
Blue = (Lu * Wu) - Ns * S # Error on problem page used (Lu - Wu)
print('Red =',Red)
print('White =',White)
print('Blue =',Blue)
print('total =',Red+White+Blue)
print('Red = {:%}'.format(Red/A))
print('White = {:%}'.format(White/A))
print('Blue = {:%}'.format(Blue/A))
输出:
Red = 0.7892307692307692
White = 0.7547841990012687
Blue = 0.355985031767962
total = 1.9
Red = 41.538462%
White = 39.725484%
Blue = 18.736054%