2017-09-27 74 views
0

我有一个计划,计算完全平方高达上限的用户输入。我的代码是:的Python - 扩大和简化程序

"""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_boundupper_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

你可以更改您的代码是这样的:

""" 
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非包容性,所以在主函数中,它被称为与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实际上无法用其他方式表示它。为了解决这个问题将是非常棘手 - 我建议,而不是潜在的广场向后工作,你从整根方形转发工作,这虽然是平凡的 - 一个可靠的方式来跳转到下界没有舍入误差很可能是实施起来非常复杂。