2017-09-27 23 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實際上無法用其他方式表示它。爲了解決這個問題將是非常棘手 - 我建議,而不是潛在的廣場向後工作,你從整根方形轉發工作,這雖然是平凡的 - 一個可靠的方式來跳轉到下界沒有舍入誤差很可能是實施起來非常複雜。