我有一个计算直到用户输入上限的完美平方的程序。我的代码是:
"""Print all the perfect squares from zero up to a given maximum."""
import math
def read_bound():
"""Reads the upper bound from the standard input (keyboard).
If the user enters something that is not a positive integer
the function issues an error message and retries
repeatedly"""
upper_bound = None
while upper_bound is None:
line = input("Enter the upper bound: ")
if line.isnumeric() and int(line) >= 0:
upper_bound = int(line)
return upper_bound
else:
print("You must enter a positive number.")
def is_perfect_square(num):
"""Return true if and only if num is a perfect square"""
root = math.sqrt(num)
return int(root) - root == 0
def print_squares(upper_bound, squares):
"""Print a given list of all the squares up to a given upper bound"""
print("The perfect squares up to {} are: ". format(upper_bound))
for square in squares:
print(square, end=' ')
def main():
"""Calling the functions"""
upper_bound = read_bound()
squares = []
for num in range(2, upper_bound + 1):
if is_perfect_square(num):
squares.append(num)
print_squares(upper_bound, squares)
main()
我想略微扩展此程序以包含下限,以便程序计算并打印两个边界lower_bound
和upper_bound
之间的完美正方形。在执行此操作时,我还要概括read_bound()
函数,使其适用于下限和上限,同时仍然按原始程序打印提示符合适的提示字符串。通过将所需的提示字符串传递给read_bound()
函数,我想出了一个可能解决方案的途径,以便主函数变为:
def main():
"""Every home should have one"""
lower_bound = read_bound("Enter the lower bound: ")
upper_bound = read_bound("Enter the upper bound: ")
squares = []
for num in range(lower_bound, upper_bound + 1):
if is_perfect_square(num):
squares.append(num)
print_squares(lower_bound, upper_bound, squares)
这是一个解决方案的有效途径,在我的程序中添加下限同时进行概括吗?如果是这样,我如何调整read_bound()
和print_squares
函数以适应解决方案?
答案 0 :(得分:0)
您可以将代码更改为以下内容:
"""
Print all the perfect squares from zero up to a given maximum.
"""
import math
def read_bound(msg):
"""
Reads a bound from the standard input (keyboard). If the user
enters something that is not a positive integer the function issues an
error message and retries repeatedly
"""
upper_bound = None
while upper_bound is None:
line = input(msg)
if line.isnumeric() and int(line) >= 0:
upper_bound = int(line)
return upper_bound
else:
print("You must enter a positive number.")
def is_perfect_square(num):
"""
Return true if and only if num is a perfect square
"""
root = math.sqrt(num)
return int(root) - root == 0
def print_squares(lower_bound, upper_bound, squares):
"""
Print a given list of all the squares up to a given upper bound
"""
print("The perfect squares between {} and {} are: ". format(lower_bound, upper_bound))
for square in squares:
print(square, end=' ')
print()
def calculate_squares(lower_bound, upper_bound):
return filter(is_perfect_square, range(lower_bound, upper_bound))
def main():
"""
Calling the functions
"""
lower_bound = read_bound("Enter the lower bound: ")
upper_bound = read_bound("Enter the upper bound: ")
print_squares(lower_bound, upper_bound,
calculate_squares(lower_bound, upper_bound + 1))
if __name__ == "__main__":
main()
我将计算正方形的逻辑分成另一个函数calculate_squares
。注意,这个函数表现懒惰,因此不是所有的正方形都存储 - 这通常是可取的。 print_squares
然后逐个使用它们,因此对于非常大的范围,您可能会看到一些实时缓冲打印。另一个变化是它现在使用range(lower_bound, upper_bound)
。它假设upper_bound
是非包含性的,因此在main函数中使用upper_bound + 1
调用它。它使用filter
来“过滤”完美正方形的范围。
read_bound
现在也采用msg
参数,这似乎可以做你想要的。代码执行如下:
Enter the lower bound: 20
Enter the upper bound: 100
The perfect squares between 20 and 100 are: 1
25 36 49 64 81 100
你应该警惕这段代码不会像你想象的非常大的整数一样,例如:
>>> is_perfect_square((1 << 500) + 1)
True
>>> is_perfect_square(1 << 500)
True
这意味着可能会发生这样的事情:
Enter the lower bound: 3273390607896141870013189696827599152216642046043064789483291368096133796404674554883270092325904157150886684127560071009217256545885393053328527589377
Enter the upper bound: 3273390607896141870013189696827599152216642046043064789483291368096133796404674554883270092325904157150886684127560071009217256545885393053328527589387
The perfect squares between 3273390607896141870013189696827599152216642046043064789483291368096133796404674554883270092325904157150886684127560071009217256545885393053328527589377 and 3273390607896141870013189696827599152216642046043064789483291368096133796404674554883270092325904157150886684127560071009217256545885393053328527589387 are:
3273390607896141870013189696827599152216642046043064789483291368096133796404674554883270092325904157150886684127560071009217256545885393053328527589377 3273390607896141870013189696827599152216642046043064789483291368096133796404674554883270092325904157150886684127560071009217256545885393053328527589378 3273390607896141870013189696827599152216642046043064789483291368096133796404674554883270092325904157150886684127560071009217256545885393053328527589379 3273390607896141870013189696827599152216642046043064789483291368096133796404674554883270092325904157150886684127560071009217256545885393053328527589380 3273390607896141870013189696827599152216642046043064789483291368096133796404674554883270092325904157150886684127560071009217256545885393053328527589381 3273390607896141870013189696827599152216642046043064789483291368096133796404674554883270092325904157150886684127560071009217256545885393053328527589382 3273390607896141870013189696827599152216642046043064789483291368096133796404674554883270092325904157150886684127560071009217256545885393053328527589383 3273390607896141870013189696827599152216642046043064789483291368096133796404674554883270092325904157150886684127560071009217256545885393053328527589384 3273390607896141870013189696827599152216642046043064789483291368096133796404674554883270092325904157150886684127560071009217256545885393053328527589385 3273390607896141870013189696827599152216642046043064789483291368096133796404674554883270092325904157150886684127560071009217256545885393053328527589386 3273390607896141870013189696827599152216642046043064789483291368096133796404674554883270092325904157150886684127560071009217256545885393053328527589387
这里你的程序确定两个给定整数之间的每个整数都是一个正方形。
这是由于Python的任意大小整数,但有限大小的浮点数。这里math.sqrt
存在舍入错误,因为Python实际上无法以任何其他方式表示它。考虑到这一点将是棘手的 - 我建议不要从潜在的方块向后工作,而是从整数根到正方形向前工作,虽然这是非常重要的 - 跳转到下限但没有舍入错误的可靠方法很可能是实施起来非常复杂。